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-shunt

v0.0.5

Published

A redux store enhancer which diverts control of state from the store

Downloads

4

Readme

Redux Shunt

Version Coverage Build Status

Redux shunt is a store enhancer which prevents the store's state from updating when an action is dispatched to it. Instead, both the action and the result of the reducers processing that action (what would have been the new state) are provided to a callback.

Additionally, redux shunt exposes an additional method on the store, setState, which sets the store's entire state tree and notifies its listeners.

Installation:

npm install --save redux-shunt

Why Do I Need This?

Redux shunt breaks your redux store, so if you use it haphazardly you will most likely be disappointed!

The use-case for redux shunt is when you want to encapsulate an entire redux store, and use something else (like another redux store) as its source of truth.

Example usage

Let's say for example we have a redux app, SubApp, which has a simple state tree:

interface SubAppState {
    foo: boolean;
    bar: boolean;
}

Say we have another redux app, MainApp, in which we want to incorporate SubApp:

interface MainAppState {
    baz: boolean;
    subAppState: SubAppState;
}

const mainAppInitialState = {
    baz: true;
    subAppState: {
        foo: true,
        bar: true
    }
}

Additionally, we want baz of MainApp's state to always be equal to bar from SubApp and vice versa. Other than that, don't really want to worry about SubApp's internals.

Assuming we have an action "SUB_APP_UPDATE" which provides SubApp's new state as the payload each time it should be updated, we can write our reducer for MainApp like this:

const mainAppReducer = (state: MainAppState, action: AnyAction) => {
    switch (action.type) {
        case 'SUB_APP_UPDATE':
            return {
                baz: action.payload.bar,
                subAppState: action.payload
            };
        case 'TOGGLE_BAZ':
            return {
                baz: !state.baz,
                subAppState: { ...state.subAppState, bar: !state.baz }
            };
        default:
            return state;
    }
}

The problems here are:

  1. How do we dispatch an action to MainApp each time SubApp's state should update?
  2. How do we ensure that MainApp takes full responsibility for the state of SubApp, and becomes its source of truth?

This is where redux shunt comes in!

We can shunt updates to SubApp's state so that they are processed through MainApp like so:

import { createStore } from 'redux';
import shunt from 'redux-shunt';
import { subAppReducer } from './subApp/internals/dontknow/dontcare';

// create normal store for the main app
const mainAppStore = createStore(mainAppReducer, mainAppInitialState);

// sub app's initial state comes from the main app's state tree
const subAppInitialState = mainAppStore.getState().subAppState;

// create a shunted store for the sub app, providing a callback to handle state updates
const subAppStore = shunt<SubAppState>(recipient)(createStore)(subAppReducer, subAppInitialState)

// refer to the real source of truth (MainApp) for the sub app's state
mainAppStore.subscribe(updateSubApp);

function recipient(action: AnyAction, state: SubAppState) {
    // lift the new sub app state into the main app's state tree
    mainAppStore.dispatch({
        type: 'SUB_APP_UPDATE',
        payload: state
    });
}

function updateSubApp() {
    const newSubAppState = mainAppStore.getState().subAppState;

    // sub app's state is only really updated, and its listeners notified, when the state changes in MainApp
    subAppStore.setState(newSubAppState);
}

That's it! SubApp is now a component of MainApp, and MainApp's store is our single source of truth. Later you can follow the same pattern to use MainApp as a component of an even larger app.

Contributions

Anyone is welcome to contribute to this package. My only "rule" is that your contribution must either pass the existing unit tests, or include additional unit tests to cover new functionality.

Here are some commands that may be helpful for development:

  • npm test: Runs the unit tests
  • npm run build: Builds the library

License

MIT