xstream-store

A redux-like store module for xstream inspired by redux.
Take the pain out of handling side-effects with the power of observables. Eliminate
the need for use of middleware such as redux-thunk
, and side-effect handlers such
as redux-saga
.
Install
$ npm i xstream-store xstream
Example
View the source in examples/
:
$ node examples/counter
Usage
const ADD_TYPE = 'add';
const addActionCreator = value => ({
type: ADD_TYPE,
value,
});
const RESET_TYPE = 'reset';
const resetAction = {
type: RESET_TYPE,
};
const initialState = {value: 0};
const counter$Creator = select =>
xs
.merge(
select(ADD_TYPE).map(action => state => ({
...state,
value: state.value + action.value,
})),
select(RESET).map(_ => _ => initialState)
)
.startWith(() => initialState);
const counterEffectsCreator = (select, dispatch) => {
const action$ = select();
const addAction$ = select(ADD_TYPE);
const reset$ = select(RESET_TYPE);
action$.addListener({
next(action) {
console.log('I log on every action', action);
}
})
add$.addListener({
next(action) {
console.log('I log every add action', action);
if (action.value > 3) {
dispatch(resetAction);
}
}
})
reset$.addListener({
next() {
console.log('Counter reset!');
}
})
};
export {
addAction,
counter$Creator,
counterEffectsCreator,
}
import createStore from 'xstream-store';
import {
addActionCreator,
counterEffectsCreator,
counterStreamCreators
} from './my-streamed-counter'
const add1Action = addActionCreator(1);
const streamCreatorMap = {
counter: counterStreamCreator,
}
const effectCreators = [
counterEffectsCreator,
];
const store = createStore(streamCreatorMap, effectCreators);
store.state$.addListener({
next(state) { console.log(`entire state: ${state}`) },
});
const counterState = store.state$
.map(({counter}) => counter)
.addListener({
next(counterState) {
console.log(`counter state: ${state}`)
}
});
store.dispatch(add1Action);
store.dispatch(add1Action);
createStore
xstream-store
exports a single function, createStore
. createStore
returns an object containing the initial state of the store, a stream of the current state, and a dispatch function for updating values in the store
const streamCreatorMap = {
counter: myCounterStreamCeator
};
const effectCreators = [
myCounterEffectCreator
];
const {dispatch, state$, initialState} = createStore(streamCreatorMap, effectCreators);
streamCreatorMap | obj: { [name]: streamCreator, } | true | An object mapping each streamCreator to a key on the store |
effectCreators | [effectCreator] | false | An array of effect creators. xstream-store will map over each effect creator, passing in a select function for filtering actions within the effect creator, and a dispatch action for dispatching actions from within the effect creator |
state$
The state stream returned by createStore
. Create subscribers to state$
to respond to changes to state:
state$.map(({counter}) => counter)
.subscribe({
next(counter) {
}
});
dispatch
Dispatch actions to update the state of your store:
const incrementAction = {type: 'increment'}
const addActionCreator = n => ({
type: 'add',
value: n,
});
dispatch(incrementAction);
dispatch(addActionCreator(5))
initialState
The initial state of the entire store, as defined by the initial state of each stream creator.
Actions
Stream Creator
select
Effects Creator
select
dispatch
Related Libraries
Todo
License
MIT