Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/guillaumearm/redux-fun
:wrench: - Redux functional programming utilities
https://github.com/guillaumearm/redux-fun
fp functional-programming handler middleware reducer redux selector updater
Last synced: about 2 months ago
JSON representation
:wrench: - Redux functional programming utilities
- Host: GitHub
- URL: https://github.com/guillaumearm/redux-fun
- Owner: guillaumearm
- License: mit
- Created: 2017-12-30T14:17:41.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2020-06-02T18:15:22.000Z (over 4 years ago)
- Last Synced: 2024-10-25T08:13:43.591Z (about 2 months ago)
- Topics: fp, functional-programming, handler, middleware, reducer, redux, selector, updater
- Language: JavaScript
- Homepage:
- Size: 5.13 MB
- Stars: 2
- Watchers: 2
- Forks: 0
- Open Issues: 24
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# redux-fun :wrench:
[![CircleCI branch](https://img.shields.io/circleci/project/github/guillaumearm/redux-fun/master.svg)](https://circleci.com/gh/guillaumearm/redux-fun)
[![codecov](https://codecov.io/gh/guillaumearm/redux-fun/branch/master/graph/badge.svg)](https://codecov.io/gh/guillaumearm/redux-fun)
[![npm](https://img.shields.io/npm/v/redux-fun.svg)](https://www.npmjs.com/package/redux-fun)
[![Greenkeeper badge](https://badges.greenkeeper.io/guillaumearm/redux-fun.svg)](https://greenkeeper.io/)
[![NSP Status](https://nodesecurity.io/orgs/trapcodien/projects/b0aa847e-a5c4-4758-9aab-d4e23d15d3d1/badge)](https://nodesecurity.io/orgs/trapcodien/projects/b0aa847e-a5c4-4758-9aab-d4e23d15d3d1)
[![dependencies Status](https://david-dm.org/guillaumearm/redux-fun/status.svg)](https://david-dm.org/guillaumearm/redux-fun)
[![devDependencies Status](https://david-dm.org/guillaumearm/redux-fun/dev-status.svg)](https://david-dm.org/guillaumearm/redux-fun?type=dev)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/guillaumearm/redux-fun/blob/master/CONTRIBUTING.md)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
[![Join the chat at https://gitter.im/redux-fun/Lobby](https://badges.gitter.im/redux-fun/Lobby.svg)](https://gitter.im/redux-fun/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)Redux functional programming utilities
## Install
```bash
$ npm install --save redux-fun
```## Documentation
### Reducers
##### Compose reducers
```js
const { composeReducers, pipeReducers } = require('redux-fun');const reducer_1 = composeReducers(r3, r2, r1);
const reducer_2 = pipeReducers(r1, r2, r3);
```##### Convert updaters
```js
const { toReducer } = require('redux-fun');
const updater = (action) => state => state;
const reducer = toReducer(updater);
```----------------------
### Updaters
##### updater with initial state
```js
const { withDefaultState } = require('redux-fun');// normal
const updater_1 = withDefaultState({}, action => state => state);// curried
const updater_2 = withDefaultState({})(action => state => state);
```
----------------------### Middlewares
##### Compose middlewares
```js
const { composeMiddlewares, pipeMiddlewares } = require('redux-fun');const middleware_1 = composeMiddlewares(m3, m2, m1);
const middleware_2 = pipeMiddlewares(m1, m2, m3);
```##### Preserve async flow (deprecated)
Use preserveAsyncSeries instead##### Preserve async series
Respect the dispatch order with async middleware
```js
const { preserveAsyncSeries } = require('redux-fun');
const middleware_1 = preserveAsyncSeries('ACTION_TYPE')
const middleware_2 = preserveAsyncSeries(['ACTION_TYPE_1', 'ACTION_TYPE_2'])
```
----------------------### Handlers
A [Handler](https://github.com/guillaumearm/handle-io/#handlers) from the [handle-io](https://github.com/guillaumearm/handle-io) library can be tranformed into redux middleware using [createHandleIOMiddleware](https://github.com/guillaumearm/redux-fun#createhandleiomiddleware) function.#### Redux Handlers
A `redux handler` run every time an action was dispatched.
It takes two arguments:
- **action**
- **reduxHandleIOApi**The **reduxHandleIOApi** object provides 3 [IOs](https://github.com/guillaumearm/handle-io/#io) functions :
- **getState**
- **dispatch**
- **next**Please see [handle-io documentation](https://github.com/guillaumearm/handle-io/#readme) for more details.
**e.g.**
```js
const { io, handler } = require('handle-io');const sleep = io(s => new Promise(resolve => setTimeout(resolve, s * 1000)));
// delayed action example
const myHandler1 = handler(function*(action, { next }) {
yield sleep(1);
return yield next(action);
});// preserve dispatch order
const myHandler2 = handler(function*(action, { next, dispatch }) {
const nexted = yield next(action);
yield dispatch({ type: 'DUMMY_ACTION' });
return nexted;
});// print state
const log = io(console.log);
const myHandler3 = handler(function*(action, { next, getState }) {
const nexted = yield next(action);
const state = yield getState();
yield log(state);
return nexted;
})
```**Note:** A `redux handler` acts as an async middleware.
#### testReduxHandler
`testReduxHandler` is an extension of [handle-io#testHandler](https://github.com/guillaumearm/handle-io/#test-side-effects-orchestration-without-pain)
it adds 3 **match\*()** methods:
- **.matchNext()** - 2 arguments:
- next argument **(assert)**
- next return **(mock)**
- **.matchDispatch()** - 2 arguments:
- dispatch argument **(assert)**
- dispatch return **(mock)**
- **.matchGetState()** - 1 argument:
- getState return **(mock)****e.g.**
```js
const { handler } = require('handle-io');
const { testReduxHandler } = require('redux-fun');const createDummyAction = (payload) => { type: 'DUMMY_ACTION', payload }
const myAction = { type: 'MY_ACTION', payload: {} };const myHandler4 = handler(function*(action, { dispatch, getState, next }) {
const { value } = yield getState();
yield dispatch(createDummyAction(value));
return yield next(myAction);
})testReduxHandler(myHandler4, myAction)
.matchGetState({ value: 42 })
.matchDispatch(createDummyAction(42))
.matchNext(myAction, 'returned value')
.shouldReturn('returned value')
.run()
```#### createHandleIOMiddleware
**usage:**
```js
const { createHandleIOMiddleware } = require('redux-fun');
const handleIOMiddleware = createHandleIOMiddleware(myHandler1, myHandler2, myHandler3, myHandler4)
```----------------------
### Selectors##### Bind selectors
```js
const { bindSelectors } = require('redux-fun');const selectors = {
getUsers: (state) => state.users,
getUser: (state, { id }) => state.users[id],
}const boundSelectors = bindSelectors(selectors, store.getState);
const user = boundSelectors.getUser({ id: 1 });
```##### getOwnProp
`getOwnProp` is very useful to use with createSelector from [reselect](https://github.com/reactjs/reselect)
```js
const { createSelector } = require('reselect');
const { getOwnProp } = require('redux-fun');const getUsers = (state = {}) => state.users || {}
const getUserByName = createSelector(
getUsers,
getOwnProp('fullName'),
(users, fullName) => users[fullName]
)getUserByName({ users: { user1: true } }, { fullName: 'user1' }); // => true
```
----------------------