-
Notifications
You must be signed in to change notification settings - Fork 174
/
PaginatedStoreUtils.js
111 lines (91 loc) · 2.44 KB
/
PaginatedStoreUtils.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
106
107
108
109
110
111
import { createStore } from './StoreUtils';
import PaginatedList from '../utils/PaginatedList';
import invariant from 'react/lib/invariant';
const PROXIED_PAGINATED_LIST_METHODS = [
'getIds', 'getPageCount', 'getNextPageUrl',
'isExpectingPage', 'isLastPage'
];
function createListStoreSpec({ getList, callListMethod }) {
const spec = { getList };
PROXIED_PAGINATED_LIST_METHODS.forEach(method => {
spec[method] = (...args) => {
return callListMethod(method, args);
};
});
return spec;
}
/**
* Creates a simple paginated store that represents a global list (e.g. feed).
*/
export function createListStore(spec) {
const list = new PaginatedList();
const getList = () => list;
const callListMethod = (method, args) => {
return list[method].call(list, args);
};
return createStore(
Object.assign(createListStoreSpec({
getList,
callListMethod
}), spec)
);
}
/**
* Creates an indexed paginated store that represents a one-many
* relationship (e.g. user's posts). Expects foreign key ID to be
* passed as first parameter to store methods.
*/
export function createIndexedListStore(spec) {
const lists = {};
const prefix = 'ID_';
const getList = (id) => {
const key = prefix + id;
if (!lists[key]) {
lists[key] = new PaginatedList();
}
return lists[key];
};
const callListMethod = (method, args) => {
const id = args.shift();
invariant(
typeof id !== 'undefined',
'Indexed pagination store methods expect ID as first parameter.'
);
const list = getList(id);
return list[method].call(list, args);
};
return createStore(
Object.assign(createListStoreSpec({
getList,
callListMethod
}), spec)
);
}
/**
* Creates a handler that responds to list store pagination actions.
*/
export function createListActionHandler(types) {
const { request, failure, success } = types;
invariant(request, 'Pass a valid request action type.');
invariant(failure, 'Pass a valid failure action type.');
invariant(success, 'Pass a valid success action type.');
return (action, list, emitChange) => {
switch (action.type) {
case request:
list.expectPage();
emitChange();
break;
case failure:
list.cancelPage();
emitChange();
break;
case success:
list.receivePage(
action.response.result,
action.response.nextPageUrl
);
emitChange();
break;
}
};
}