-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.js
105 lines (80 loc) · 2.15 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
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
export const ONCE = '@redux-when/once';
export const WHEN = '@redux-when/when';
export const CANCEL = '@redux-when/cancel';
export function once(condition, createAction) {
return {
type: ONCE,
payload: {
condition,
createAction
}
};
}
export function when(condition, createAction) {
return {
type: WHEN,
payload: {
condition,
createAction
}
};
}
export function cancel(token) {
return {
type: CANCEL,
payload: token
};
}
export default store => {
const waiting = [];
let lastToken = 0;
return next => action => {
const {type, payload} = action;
if (type === ONCE || type === WHEN) {
//dispatch the action immediately if the condition is met
const state = store.getState();
if (payload.condition(state, action)) {
next(payload.createAction(action));
if (type === ONCE) {
return null;
}
}
const token = ++lastToken;
//attach the token
action.meta = {token};
//delay the action
waiting.push(action);
return token;
} else if (type === CANCEL) {
//if we can find the token, remove it
const index = waiting.findIndex(when => when.meta.token === action.payload);
if (index !== -1) {
waiting.splice(index, 1);
}
return null;
} else {
//finish dispatching the action
const result = next(action);
//get the updated state
const state = store.getState();
// dispatch items in order
let length = waiting.length;
for (let index=0; index<length; ++index) {
const when = waiting[index];
//check if the condition is met
if (when.payload.condition(state, action)) {
//remove the delayed action
if (when.type === ONCE) {
waiting.splice(index, 1);
// adjust index and length to cater for deleted items
index = index - 1;
length = length - 1;
}
//dispatch the delayed action
store.dispatch(when.payload.createAction(action));
}
}
return result;
}
}
};