npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

composable-reducer

v0.2.0

Published

Create composable reducers on the fly from objects

Downloads

2

Readme

🧱 composable-reducer Release Version

Create composable reducers on the fly from objects

Test Results Coverage Status License Type

First and foremost, composableReducer is a helper that lets developers create reducers on the fly from objects and their key => value pairs, where keys are the dispatch types, thus reducing the boilerplate you have to write while creating reducers to use with React's useReducer hook.

Each function returns only the piece of state it wants to modify. I call these micro-reducers.

Each micro-reducer can be used inside a composed-reducer (hah! composable-reducer, who would've guessed?) creating a chain. These are just reducers that when called call their micro-reducers in the order they're defined. Every micro-reducer receives the full state mixed with the updated bits created by the previous micro-reducers, this way every micro-reducer can have access to an up-to-date state.

Throw in the mix the possibility to define aliases for micro-reducers and composed-reducers, the possibility to pass static arguments around (e.g. addOne: 'add({ "amount": 1 })', where add is just a micro-reducer), and you have a pretty powerful utility in your hands☝🏼. The best part about the static-arguments thing? They have the highest priority (i.e. they can't be overridden), can be used in aliases for composed-reducers, and are thrown away after being used, so they don't pollute your micro-reducer chain!

☝🏼: Seriously, you can extract all the business logic from a component and add features just by adding micro-reducers and composed-reducers, give it a try!

Features

  • Create a reducer on the fly from an object's keys and values.
  • Define composed-reducers using micro-reducers.
  • Create aliases for reducers, even for the composed ones.
  • Use static arguments for aliases and elements of composed reducers.
  • Throws an error at reducer-build-time if aliases mismatch.
  • Throws an error when a dispatch type is not recognized.

Install

$ npm install composable-reducer

Or if you prefer using Yarn:

$ yarn add composable-reducer

Usage

import { composableReducer } from "composable-reducer"

const reducer = composableReducer({
  setDiscountPercentage: (_, { percentage }) => ({
    percentage,
  }),
  percentage: ({ percentage, price }) => ({
    discount: (percentage / 100) * price,
  }),
  decrease: ({ discount, price }) => ({
    discountedPrice: price - discount,
  }),
  setLabel: (_, { label }) => ({
    label,
  }),
  setDiscountedPrice: [
    "setDiscountPercentage",
    "percentage",
    "decrease",
    'setLabel({ "label": "Sales!" })',
  ],
})

reducer({ price: 50 }, { type: "setDiscountedPrice", percentage: 20 })

// => { price: 50, percentage: 20, discount: 10, discountedPrice: 40, label: 'Sales!' }

const Component = ({ price }) => {
  const [{ price, discountedPrice = price }, dispatch] = useReducer(reducer, {
    price: price,
  })

  useTimeout(
    () => dispatch({ type: "setDiscountedPrice", percentage: 20 }),
    5000
  )

  return (
    <>
      {discountedPrice < price && <del>{price}</del>} {discountedPrice}
    </>
  )
}

API

composableReducer(object, options)

Create a reducer from object by using its key => value pairs, where keys are the dispatch types and values are their handlers. Read more about micro-reducers and composed-reducers above.

object

Type: object

options

Type: object

options.actionKey

Type: string

Default Value: "type"

The dispatch property that should be used to distinguish between different dispatches, by default it's "type", e.g. dispatch({ type: 'add' }).

Browser support

The latest version of Chrome, Firefox, Safari, and Edge. I think that Edge 12 is the lowest you can go.