forked from topcoder-platform/community-app
-
Notifications
You must be signed in to change notification settings - Fork 0
/
redux.js
73 lines (65 loc) · 2.09 KB
/
redux.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/**
* Redux-related helpers.
*/
import _ from 'lodash';
/**
* Given any Flux Standard Action (FSA) with promise as the payload, it returns
* a promise which resolves into the FSA result object.
* @param {Object} action
* @return Promise which resolves to the operation result.
*/
export function toFSA(action) {
return action.payload.then(data => ({
...action,
payload: data,
}), error => ({
...action,
payload: error,
error: true,
}));
}
/**
* Given a mapping between reducer names and their promises, this function
* waits till resolution of all promises and returns the mapping between
* reducer names and the resolved reducers.
* @param {Object} promises Object with promises of reducers.
* @return Object with reducers.
*/
export function resolveReducers(promises) {
return Promise.all(_.values(promises)).then((reducers) => {
const map = {};
_.keys(promises).forEach((key, index) => {
map[key] = reducers[index];
});
return map;
});
}
/**
* Reduce multiple reducers into a single reducer from left to right.
* Function-type reducers will be called directly with current state, and action
* Object type reducers (eg: `{submissions: (state, action) => {}}`)
* will be called with the state's slice corresponding to object's key
* eg: `{submissions}` will be called with `submissions(state.submissions, action)`
*
* @params {function|Object} the reducers to be combined
* @return function the unified reducer
*/
/* TODO: Can we simplify this function? */
export function combine(...reducers) {
return (state, action) => {
const nextState = {};
const mergeState = Object.assign.bind(Object, nextState);
reducers.forEach((reducer) => {
if (typeof reducer === 'function') {
return mergeState(reducer(state, action));
}
Object.keys(reducer).forEach((slice) => {
mergeState({ [slice]: reducer[slice]((state || {})[slice], action) });
});
return undefined;
});
return nextState;
};
}
/* We don't any `main` function in this module to export it by default. */
export default undefined;