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

automata-reducer

v3.2.1

Published

a tiny (< 0.5kb gzip) finite-state-machine that switches reducers

Downloads

39

Readme

automata-reducer

NPM

a tiny (< 0.5kb gzip) finite-state-machine that switches reducers. no dependencies.

since version 3.0, an optional functional operator may be supplied to the factory. that operator is applied to the automata reducer only for known events, i.e. events for which a reducer or list of reducers is defined in the automata spec. unknown events trigger a default value reducer for proper initialization. this is useful for e.g. efficiently applying the automata reducer through a cursor (lense): for example, to apply an automata to a single todo instance in a list of todo instances for relevent events only.

example

see this example in this directory. run this example in your browser.

import createAutomataReducer, { AutomataSpec, StandardAction } from 'automata-reducer'
import { propCursor } from 'basic-cursors'
import actions from './actions'
import logger from './console'
const log = logger()

interface State {
  state: AutomataState
  value: number
}

type AutomataState = 'init' | 'idle'

const inValue = propCursor('value')

const automata: AutomataSpec<AutomataState,State> = {
  init: {
    IDLE: 'idle',
    INCREMENT: [inValue(increment), 'idle']
  },
  idle: {
    RESET: ['init', inValue(reset)],
    INCREMENT: inValue(increment)
  }
}

function increment (value: number = 0, { payload }: StandardAction<number>) {
  return value + +payload
}

function reset (): number {
  return 0
}

const reducer = createAutomataReducer(automata, 'init')

const idle = reducer(void 0, actions.IDLE())
log('IDLE(): %O', idle) // IDLE(): {"state":"idle"}
const fourtytwo = reducer(idle, actions.INCREMENT(42))
log('INCREMENT(42): %O', fourtytwo) // INCREMENT(42): {"state":"idle","value":42}
const init = reducer(fourtytwo, actions.RESET())
log('RESET(): %O', init) // RESET(): {"state":"init","value":0}

API v3.2

as demonstrated in the above example, for each automata state, the automata spec defines a single reducer or a list of reducers for each action (or event) relevant to that state.

  • a string is replaced by a reducer of the automata's state that sets the latter to that string.
  • reducers listed in an array are executed sequentially, from right to left (last to first).

when combined with a propCursor from the basic-cursors module which applies a reducer to a named property of the state object, and only updates the state if the reducer returns a different value, reducers can be minimized to very simple functions, resulting in a self-documenting the automata spec, such as in the above example.

export declare type AutomataSpec<
  X extends string | number,
  S = any,
  P = any,
  A = StandardAction<P>
> = { [state in X]: ReducerSpec<X, S, P, A> }

export interface ReducerSpec<
  X extends string | number,
  S = any,
  P = any,
  A = StandardAction<P>
> {
  [type: string]: (Reducer<S, P, A> | X)[] | Reducer<S, P, A> | X
}

export declare type Reducer<S, P = any, A = StandardAction<P>> = (
  state?: S,
  action?: A
) => S

export interface StandardAction<P = any> {
  type: string
  payload?: P
}

export interface AutomataReducerOptions<
  X extends string | number = string,
  K extends string | number = 'state',
  I extends { [key in K]: X } = { [key in K]: X },
  O = I,
  P = any
> {
  key: K
  toStandardAction: ActionStandardizer<P>
  operator: Operator<I, O>
}

export declare type ActionStandardizer<P = any> = <A>(
  action: A
) => StandardAction<P>

export declare type Operator<I = {}, O = I> = (
  fn: (i: I, ...args: any[]) => I
) => (o: O, ...args: any[]) => O

export default function createAutomataReducer<
  X extends string | number,
  K extends string | number = 'state',
  I extends { [key in K]: X } = { [key in K]: X },
  O = I,
  P = any,
  A = StandardAction<P>
> (
  automata: AutomataSpec<X, I, P, A>,
  init: X,
  opts?: Partial<AutomataReducerOptions<X, K, I, O, P>> | string
): Reducer<O, P, A>

for a detailed specification of this API, run the unit tests in your browser.

TypeScript

although this library is written in TypeScript, it may also be imported into plain JavaScript code: modern code editors will still benefit from the available type definition, e.g. for helpful code completion.

License

Copyright 2018 Stéphane M. Catala

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and Limitations under the License.