Skip to content

Instantly share code, notes, and snippets.

@shakyShane
Forked from anonymous/readme.md
Created March 20, 2017 17:14
Show Gist options
  • Save shakyShane/90259c76c186c7d7810b7dd96cc02418 to your computer and use it in GitHub Desktop.
Save shakyShane/90259c76c186c7d7810b7dd96cc02418 to your computer and use it in GitHub Desktop.

staunch

loyal, firm, and dependable - solid or substantial in construction

Staunch is a highly opinionated Redux-style state management system for large-scale apps. Powered by ImmutableJS & RxJS - plug it into any codebase.

Install

Note, RxJS & ImmutableJS are requirements, you'll need to install them separately.

yarn add rx immutable staunch-store

npm i rx immutable staunch-store --save

Features

Combining the power of ImmutableJS and RxJS enables some pretty incredible features.

  • Changes feed for entire store, or any part of the state object. No joke, just specify which 'path' on the tree tree you're interested in.

    // listen to the entire state tree for changes store.changes().subscribe(state => console.log('updated state', state))

    // listen to just the 'user' section of the state store.changes('user').subscribe(user => console.log('updated state', user))

Example 1 - Redux style

import { createStore } from 'staunch-store';
import { fromJS } from 'immutable';

/**
 * Create a store with 1 or many reducers (like combineReducers)
 */
const store = createStore({}, {
    user: function userReducer (user = fromJS({auth: false}), action) {
          switch(action.type) {
              case 'USER_AUTH':
                  return user.set('auth', action.payload);
              default:
                  return user;
          }
    }
});

Example 2 - Effects built-in

import { createStore } from 'staunch-store';

/**
 * Create a store
 */
const store = createStore();

/**
 * Define a 'user' reducer
 */
function userReducer (user, action) {
    
    switch(action.type) {
        case 'USER_FETCH':
            return user.set('loading', true);
        default:
            return user;
    }
}

/**
 * When USER_FETCH is fired, triggered an ajax request, 
 * mapping the result (or error) to other actions that
 * affect the state
 */
function userEffect(action$) {
    return action$.ofType('USER_FETCH')
        .flatMapLatest(({action, state}) => {
            return fetch(action.payload.url).then(x => x.json())
        })
        .map(result => {
            return userFetchSuccess(result)
        })
        .catch(err => {
            return Rx.Observable.of(userFetchError(err));
        })
}

/**
 * Now register the reducer, with some default state
 */
store.register({
    state: {
        // some some default state here, 
        // this will automatically be converted into
        // an immutable map
        user: {auth: false}
    },
    reducers: userReducer,
    effects: userEffect
});

/**
 * Now fire the USER_AUTH action
 */
store.dispatch({type: 'USER_AUTH'});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment