-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.js
90 lines (82 loc) · 2.59 KB
/
main.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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
export { default as combine } from "./utils/combine";
export {
array_append,
array_prepend,
array_remove_all,
array_remove_index,
array_set,
boolean_set,
boolean_toggle,
number_transform,
number_increment,
number_decrement,
simple_reducer,
default_state
} from "./reducers/index";
export { redup } from "./annotations/index";
export function create_reducer(tree, options = {}, cache = {}, nested = []) {
function create_reducer_ret(prevState = {}, action) {
const cacheHasKey = key => cache && cache[key];
const optionsCopy = Object.assign({}, options);
if (!("useCache" in optionsCopy)) {
optionsCopy.useCache = true;
}
const isObject = obj =>
obj === Object(obj) &&
Object.prototype.toString.call(obj) !== "[object Array]";
if (!tree || !isObject(tree)) {
throw new Error("Invalid tree");
}
const callReducers = nested => (prev, cur) => {
if (typeof cur === "function") {
//Lazy load items into cache
if (cur.reduxdecorator_key && optionsCopy.useCache) {
cur.reduxdecorator_property = [...nested];
cache[cur.reduxdecorator_key] = cur;
}
return cur(prev, action);
} else {
return prev;
}
};
if (
cacheHasKey(action.type) &&
typeof cache[action.type] === "function" &&
"reduxdecorator_property" in cache[action.type] &&
optionsCopy.useCache
) {
const reducer = cache[action.type];
if (!("reduxdecorator_property" in reducer)) {
throw new Error("Missing reduxdecorator_property");
}
const properties = reducer.reduxdecorator_property;
const last = properties[properties.length - 1];
const nextToLast = properties[properties.length - 2];
if (properties.length == 1) {
prevState[properties[0]] = reducer(prevState[properties[0]], action);
} else {
let current = null;
for (let i = 0; i < properties.length - 1; i++) {
current = prevState[properties[i]];
}
current[last] = reducer(current[last], action);
}
} else {
for (let key in tree) {
const val = tree[key];
nested[nested.length] = key;
if (isObject(val)) {
prevState[key] = prevState[key] || {};
create_reducer(val, options, cache, nested)(prevState[key], action);
} else if (Array.isArray(val)) {
prevState[key] = val.reduce(callReducers(nested), prevState[key]);
} else {
prevState[key] = val;
}
nested = [];
}
}
return prevState;
}
return create_reducer_ret;
}