-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.js
59 lines (53 loc) · 1.5 KB
/
index.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
import { isFSA } from 'flux-standard-action';
import { combineReducers } from 'redux';
const updateEntity = (state, entities) => {
return Object.assign({}, state, entities);
};
const updateEntities = (state, key, entities) => {
return Object.assign({}, state, {
[key]: updateEntity(state[key], entities[key]),
});
};
const defaultDataResolver = action => {
if (isFSA(action)) {
const { payload } = action;
if (payload && !payload.error && payload.entities) {
return payload.entities;
}
return null;
}
return action.entities;
};
const noOpReducer = (state = null) => state;
const resolveAction = (reducers = {}, state, action) => {
const baseReducers = Object.keys(state)
.filter(key => !Object.keys(reducers).includes(key))
.reduce((acc, curr) => {
return {
...acc,
[curr]: noOpReducer,
};
}, {});
const mergedReducers = Object.assign({}, baseReducers, reducers);
if (Object.keys(mergedReducers).length) {
return combineReducers(Object.assign({}, baseReducers, reducers))(
state,
action
);
}
return state;
};
export default (
reducers,
{ dataResolver } = { dataResolver: defaultDataResolver }
) => (state = {}, action) => {
let newState = state;
const entities = dataResolver(action);
if (entities && typeof entities === 'object') {
newState = Object.keys(entities).reduce(
(acc, key) => updateEntities(acc, key, entities),
newState
);
}
return resolveAction(reducers, newState, action);
};