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

redux-actions-sequences

v1.1.19

Published

Make sequences of actions trigger a new action

Downloads

20

Readme

redux-actions-sequences

NPM Build StatusDependencies

redux-actions-sequences is a library that that makes defined sequences of redux actions trigger a new action. Sequence can be comprised of a single action (simple, exact), a series of the same action repeated n times (times, timesStrict), an order-dependent series of actions (queue, queueStrict), order-indenendent (all), just one of from the given list (any), or their superposition.

Elemental block of the sequence description is an instance of a FSA-compliant action, an action creator function (by redux-actions), a string that represents the type of an action, or an exact object-based description of the action (if used with exact; four wildcard values are provided for this case: present/ missing, truthy/falsey to better describe an expected action's properties). Or just another sequence. Which means, sequence definitions can be nested.

Sequences are built using a helper object lent in a callback inside a dispatchActionWhen call. See examples below.

Installation

$ npm install --save redux-actions-sequences

or

$ yarn add redux-actions-sequences

Usage

Register default export as a middleware:


// Imports:
import sequential from 'redux-actions-sequences';
import thunk from 'redux-thunk';

// Register middleware:

const middleware = [ sequential, thunk /* ... */ ];

const createStoreWithMiddleware =
    applyMiddleware(...middleware)(createStore);

const store = createStoreWithMiddleware(reducer, initialState);

Define action sequences:

These lines will be referred to in the examples:


// Imports:

import { dispatchActionWhen } from 'redux-actions-sequences';

// may use 'redux-actions' to streamline action creation
// such action creators can be toString()-ed to get their type
// redux-actions-sequences accepts both strings (as action types), 
// FSA-actions, and FSA-action creators:
import { createAction } from 'redux-actions';

// Actions to wait for:
const appLoading = 'APP_LOADING'; // createAction('APP_LOADING');
const appLoaded = { type: 'APP_LOADED' }; //  createAction('APP_LOADED');
const appLoadingPulse = createAction('APP_PULSE');
const fetchSets = createAction('FETCH_SETS');

// Actions to dispatch if sequences are met:
const reactionOne = 'REACTION_ONE';
const reactionTwo = { type: 'REACTION_TWO' };
const reactionThree = createAction('REACTION_THREE');

// Thunked action (receives unregister() callback to control further
// occurences)
const reactionFour = (unregister) => (dispatch, getState) => {
  const starsAreRight = Math.random() < .5; // or getState()... something
  if (starsAreRight) {
    unregister();
    dispatch(reactionThree());
  }
};

const reactionFive = createAction('REACTION_FIVE');

How to define a sequence:

To define a sequence of actions you are interested in, you need to call an exported dispatchActionWhen(reaction, sequenceBuilderFunction). The result is a dispatch-able action creator function which, when dispatched, will start listening for the FSA actions.

Once they match the described pattern, the sequence will dispatch the reaction action, represented as a string, a plain-object FSA-compliant action, or a function (action creator or async action).

sequenceBuilderFunction is a function which accepts a single parameter - sequence builder API lent by the library. Calling its methods one can construct a variety of quite complex structures of expectations of the actions dispatched around the application. I suggest using destructuring assignment of the builder API parameter, as shown in the examples below.

Reactions:

Once triggered, a reaction object has standard properties aside from type: payload and meta.

payload has a property actions which contains the actions that triggered it, meta has a property unregister which is a handle to unregister the sequence definition.

A function-based reaction (thunked action or actionCreator) is called with a single object-type parameter with properties: unregister, actions, and action (the last action that caused the whole sequence to trigger).

Sequence Builder API Reference:


const builderAPI = {
    simple,       
    exact,        // (action plain-object) object props may be with 
                  // values 'present','missing', etc.
    once,         // top-level only
    times,        // (sequence, count)
    timesStrict,  // (sequence, count)
    all,          // array of sequences
    any,          // array of sequences
    queue,        // array of sequences
    queueStrict,  // array of sequences
    
    // For exact() object construction
    present,
    missing,
    truthy,
    falsey
}

Examples:


// Create sequences: 

// sequence1 is a thunked action (consumable by `redux-thunk` middleware)
// it says that `reactionOne` will get dispatched each time the `redux-actions-sequences`
// detects that these actions have been fired in this order (queue),
// once detected and reactionOne dispatched, this sequence will self-unregister
// thanks to `once()`, no further actions that match the 
// sequence will be looked for.
export const sequence1 = dispatchActionWhen(reactionOne, ({
      once, queue
    }) => once(queue([
      appLoading, // a string, action's type
      appLoadingPulse, // several identical actions to wait for
      appLoadingPulse,
      appLoadingPulse,
      appLoadingPulse,
      appLoadingPulse,
      appLoadingPulse,
      appLoadingPulse
    ])));

// previous example is equivalent to this one. 7 identical actions can be
// repaced by a times(..) sequence, which in turn, may be treated as 
// another action we expect to happen
export const sequence2 = dispatchActionWhen(reactionOne, ({
  once, queue, times, simple
}) => once(queue([
  simple(appLoading),
  times(appLoadingPulse, 7)
])));

// reactionTwo will only get dispatched when *all* three of these
// get to be dispatched: appLoading, appLoadingPulse - 7 times, fetchSets
// irrelevant of their order. Then the sequence3 gets rewound
export const sequence3 = dispatchActionWhen(reactionTwo, ({
  all, simple, times
}) => 
  all([
    simple(appLoading),
    times(appLoadingPulse, 7),
    simple(fetchSets)
  ]));

// will execute until unregister() in thunked action is called
export const sequence4 = dispatchActionWhen(reactionFour, ({ any }) =>
  any([
    fetchSets,
    appLoaded
  ]));

// `exact()` object structure expectation construction
export const sequence5 = dispatchActionWhen(reactionFive, ({ 
    exact, present, missing, truthy, falsey 
  }) => exact({
      type: 'DATA_FETCH',
      payload: present,
      error: falsey,
      meta: missing
    })
  );

Defined sequences are not active until they are dispatched:


// Start using them by wrapping in a dispatch() call:
// Elsewhere:

const unregisterSequence2 = dispatch(sequence2); // effect is the same as dispatch(sequence1) 

const unregisterSequence3 = dispatch(sequence3); // will eventually dispatch reactionTwo, and stop
 
const unregisterSequence4 = dispatch(sequence4); // will eventually dispatch thunked actionFour

The result of dispatching is a function to unregister the sequence:


unregisterSequence2();
unregisterSequence3();
unregisterSequence4();

Note, sequences are funstions so in order to dispatch them without errors you will need to have redux-thunk set up as a middleware.

Dependencies:

Works along with these packages:

  • "redux"
  • "redux-thunk"
  • "redux-actions"

See also

Contributing

Please use the issues page to report a bug or request a feature.

Stay in Touch

License

MIT

Author

Andrew Revinsky