-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
70 lines (61 loc) · 1.59 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
let i = 0;
const ACTION_ADD = 'cache/ADD';
const ACTION_INVALIDATE = 'cache/INVALIDATE';
// Reducer for the Redux store
function cacheReducer (state, action) {
switch (action.type) {
case ACTION_ADD:
return Object.assign({}, state, {
[action.payload.key]: action.payload.data
});
break;
case ACTION_INVALIDATE:
if (action.payload && action.payload.key) {
return Object.assign({}, state, {
[action.payload.key]: undefined
});
}
// If no key is provided just clear everything!
return {};
default:
return {};
}
}
function createFetcher (store, method, hash = (i) => i) {
let cacheKey = ++i;
function fetch () {
const key = `${cacheKey}--${hash.apply(this, arguments)}`;
const fromCache = store.getState().cache[key];
if (!fromCache) {
throw method.apply(this, arguments).then((response) => {
return new Promise((resolve) => {
store.dispatch({
type: ACTION_ADD,
payload: {
key,
data: response
}
});
// The good ol' Redux workaround to make things async 😅
// This will ensure that the promise resolves on the next tick,
// where Redux will have updated the store correctly
setTimeout(resolve, 0);
});
});
}
return fromCache;
}
fetch.invalidate = function invalidate (key) {
store.dispatch({
type: ACTION_INVALIDATE,
payload: {
key
}
});
};
return fetch;
}
module.exports = {
createFetcher,
cacheReducer
};