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

molecular-js

v0.0.2

Published

utilities to faciliate modular state management with Redux, ImmutableJS and Reselect

Downloads

23

Readme

Molecular-js

What is it?

Molecular is a set of utilities to ease the development of modular state management patterns with Redux (also known as ducks). Molecular assumes the usage of at least Redux, Reselect and Immutable-js. You may also find a molecular reference app skeleton with additional information on modular state management and how it may look in an application.

Installation

npm install molecular-js --save

Usage

Enhanced Reducer Creation

Vanilla reducers expose a few problems that Molecular attempts to solve; as noted below.

Consolidate Switch Statement Logic

A vanilla reducer may look something like:

// Reducer.js

export default (state, action) => {
    switch(action.type) {
         case 'actionType1':
            // do something
            return state;
         case 'actionType2':
            // do something
            return state;
         default:
            return state;
    }
};

However, the logic to determine which action's reducer function to utilize is duplicated across every reducer. Molecular provides a createReducer function that handles this logic in a centralized place.

// Reducer.js
import {createReducer} from 'molecular-js';

// Action reducers
const actionReducers = {
    'actionType1': (state, action) => state,
    'actionType2': (state, action) => state
};
const defaultState = {};

export default createReducer(actionReducers, defaultState);

Proper Merging of Mixture of POJO/Immutable Default and Initial State

When creating a reducer, it is wise to provide it with a default state; which may or may not be an immutable structure. When seeding the store, data from the server is provided as a POJO. Molecular's createReducer will accept the mixture of POJO and immutable structures and always seed the store with the output of an immutable structure.

// State Atom Reducer
import {Map, Set} from 'immutable';
import {createReducer} from 'molecular-js';

const actionReducers = {
    'actionType1': (state, action) => state // state is immutable
};
const defaultState = new Map({
    items: new Set()
});
export default createReducer(actionReducers, defaultState);

// Store Creation
const initialState = {
    stateAtom: 
        items: [
            {id: 'Item:1'},
            {id: 'Item:2'},
        ]
};
const store = createStore(reducer, initialState);

Immutable Store, POJO UI

Storing data in the Redux store as immutable structures has one potential downside: do the consumers of state accept immutable structures or POJOs? Forcing the UI to accept immutable structures will make the UI less portable and tightly coupled to Immutable-js. One alternative is to call .toJS() on selected state before consuming it in the UI. Although this allows your UI to consume POJOs (and thus be portable), it means that every state change has the potential to deep copy the entirety of the selected state graph.

A solution to this problem is to store data as Immutable Records. This allows the UI to access the immutable structure in the same way it would a POJO. When seeding the store with an initial state, you may optionally provide a Record definition (with data defaults) for each reducer's state atom.

const initialState = {
    stateAtom: {
        items: [
            {
                id: 'Item:1',
                name: 'Item name'
            }
        ],
        '@meta': {
            items: {
                id: 'Item:NULL',
                name: null
            }
        }
    }
};

// is equivalent to:
new Map({
    items: new List([
        new (Record({id: 'Item:NULL', name: null})({id: 'Item:1', name: 'Item name'})
    ]),
    '@meta': new Map({
        items: new Map({
            id: 'Item:NULL',
            name: null
        })
    })
});

Automatic Record Creation in Action Reducers

If @meta definitions are provided in the initial state for a state atom, then all of the data for the associated definition key will be Immutable Records. Molecular-js provides a mechanism to take POJOs and use the state's provided @meta definition to create a Record.

// Action Reducer
import {getRecordCreator} from 'molecular-js';

export default {
    'actionType1': (state, action) => {
        const createRecord = getRecordCreator(state);
        return state.updateIn(['items'], (list) => list.concat([
                createRecord('items', action.payload)
            ])
        );
    }
};