https://github.com/fixate/xstream-store
A redux-like store module for xstream
https://github.com/fixate/xstream-store
Last synced: 2 months ago
JSON representation
A redux-like store module for xstream
- Host: GitHub
- URL: https://github.com/fixate/xstream-store
- Owner: fixate
- License: mit
- Created: 2018-05-28T06:44:56.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2018-08-17T13:50:27.000Z (over 6 years ago)
- Last Synced: 2025-02-05T03:14:28.101Z (3 months ago)
- Language: TypeScript
- Size: 160 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# xstream-store
[](https://travis-ci.org/fixate/xstream-store)
[](https://badge.fury.io/js/xstream-store)
[](https://codecov.io/gh/fixate/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/`:
```bash
$ node examples/counter
```## Usage
```javascript
// my-streamed-counter.jsconst 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 =>
// our counter stream that only receives `counter` state
xs
.merge(
select(ADD_TYPE).map(action => state => ({
...state,
value: state.value + action.value,
})),
select(RESET).map(_ => _ => initialState)
)
// provide initialState in a callback
.startWith(() => initialState);const counterEffectsCreator = (select, dispatch) => {
// a stream of all actions
const action$ = select();
// a stream of add actions
const addAction$ = select(ADD_TYPE);
// a stream of reset actions
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);// dispatch a reset when our counter's value is greater than 3
if (action.value > 3) {
dispatch(resetAction);
}
}
})reset$.addListener({
next() {
console.log('Counter reset!');
}
})
};export {
addAction,
counter$Creator,
counterEffectsCreator,
}
``````javascript
// store.js
import createStore from 'xstream-store';
import {
addActionCreator,
counterEffectsCreator,
counterStreamCreators
} from './my-streamed-counter'const add1Action = addActionCreator(1);
const streamCreatorMap = {
counter: counterStreamCreator,
}const effectCreators = [
counterEffectsCreator,
// fooEffectsCreator
];const store = createStore(streamCreatorMap, effectCreators);
// subscribe to your state stream
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}`)
}
});// dispatch actions
store.dispatch(add1Action);
// entire state: {counter: { value: 1 }}
// counter state: { value: 1 }store.dispatch(add1Action);
// entire state: {counter: { value: 2 }}
// counter state: { value: 2 }
```### `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
```javascript
const streamCreatorMap = {
counter: myCounterStreamCeator
};const effectCreators = [
myCounterEffectCreator
];const {dispatch, state$, initialState} = createStore(streamCreatorMap, effectCreators);
```| Parameter | Type | Required | Description |
|------------------|-----------------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 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:
```javascript
state$.map(({counter}) => counter)
.subscribe({
next(counter) {
// do something with latest counter value
}
});
```#### `dispatch`
Dispatch actions to update the state of your store:
```javascript
const incrementAction = {type: 'increment'}
const addActionCreator = n => ({
type: 'add',
value: n,
});// increment counter value
dispatch(incrementAction);// add 5 to counter value
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
- [xstream-store-resource](https://github.com/fixate/xstream-store-resource) - easily generate streams for asynchronous requests
- [react-xstream-store](https://github.com/fixate/react-xstream-store) - connect React components to an xstream store## Todo
- [ ] add usage
## License
MIT