State management library; works like redux but with option for many stores, side effects, Promises and other practical things.
Library includes:
- createStore(key, reducerOrSpec, actionsOrSelectors)
- dispatch(action)
- getStores()
- getReducer()
- getState()
- promiseAction(type, data)
- replaceState(state)
- subscribe(cb)
npm install --save fluxury
import {
createStore,
dispatch,
getStores,
getState,
promiseAction,
replaceState,
subscribe
} from "fluxury";
// creates a key="A" in the root store, connected to a reducer function.
let storeA = createStore(
"a1",
(state = 0, action) => (action.type === "setA" ? action.data : state)
);
let storeB = createStore(
"b1",
(state = 0, action) => (action.type === "setB" ? action.data : state)
);
// Store with dependencies on state in storeA and storeB.
let storeC = createStore("c1", (state = 0, action, waitFor) => {
// Ensure storeA and storeB reducers run prior to continuing.
waitFor([storeA.dispatchToken, storeB.dispatchToken]);
// Side effect! Get state from other stores.
return storeA.getState() + storeB.getState();
});
subscribe((...args) => console.log("action", ...args));
dispatch("setA", 2);
dispatch("setB", 2);
getState(); // -> { a1: 2, b1: 2, c1: 4 }
This library depends on a modern JavaScript runtime. Load a polyfill like in core-js or babel-polyfill to support old browsers.
Manually install required polyfills with core-js:
require("core-js/fn/promise");
require("core-js/fn/object/assign");
require("core-js/fn/object/freeze");
require("core-js/fn/object/keys");
A store responds to actions by returning the next state.
const inc = 'inc'
import {createStore} from 'fluxury';
// a simple counting store
var store = createStore( "count", (state=0, action) => {
switch (action.type)
case inc:
return state + 1;
case incN:
return state + action.data;
default:
return state;
}, {
inc: (state) => dispatch('inc'),
incN: (state, count) => dispatch('incN', count),
})
// the store includes a reference to dispatch
store.dispatch('inc')
// optionally, define action creators into the store.
store.inc()
Optionally, you may define a store with a specification.
const inc = "inc";
import { createStore } from "fluxury";
// a simple counting store
var countStore = createStore("count", {
// life-cycle method for initialization.
getInitialState: () => 0,
// handles { type: 'inc' }
inc: state => state + 1,
// handles { type: 'incN' }
incN: (state, n) => state + n
});
// object spec makes action creators automatically...
countStore.inc();
countStore.incN(10);
The entry point to effecting state changes in the app is when an action is dispatch.
Dispatch accepts action as object, promise, or type/data; returns promise.
// Import the dispatch function.
var { dispatch } = require( 'fluxury' )
// Dispatch action as object
dispatch( { type: 'openPath', '/user/new' } )
.then( action => console.log('Going', action.data) )
// Dispatch action as promise
dispatch( Promise.resolve({ type: 'get', mode: 'off the juice' }) )
// Dispatch action with type:string and data:object.
dispatch( 'loadSettings', { a: 1, b: 2 } )
Here is a list of store properties that are part of the public API.
name | comment |
---|---|
name | The name of the store |
dispatch | Access to dispatch function |
dispatchToken | A number used to identity the store |
subscribe | A function to tegister a listener |
getState | A function to access state |
setState | Replace the store's state |
replaceReducer | Replace the store's reducer |
Returns an object with the name as key and store as value.
Rehydrate the root state.
replaceState({
MyCountStore: 1
});
Listen to changes to all stores. This will trigger once each time createStore or dispatch is invoked.
Please note that action will be undefined when createStore is invoked.
var unsubscribe = subscribe( (state, action) => {
// got change
})
// stop listening
unsubscribe()
Return app's reducer function, use with Redux.