Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 1576c8d

Browse files
committedMay 9, 2018
Merge branch 'advanced-tools-for-redux' into develop
2 parents c1ef322 + b6c431b commit 1576c8d

File tree

6 files changed

+227
-0
lines changed

6 files changed

+227
-0
lines changed
 

‎__tests__/__snapshots__/index.js.snap

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ Object {
1111
"MetaTags": [Function],
1212
"NavLink": [Function],
1313
"ScalableRect": [Function],
14+
"actions": Object {
15+
"collection": Object {
16+
"addItems": [Function],
17+
"bookItems": [Function],
18+
"clean": [Function],
19+
"freeItems": [Function],
20+
"loadItemDone": [Function],
21+
"loadItemInit": [Function],
22+
},
23+
},
1424
"client": [Function],
1525
"config": undefined,
1626
"isomorphy": Object {
@@ -20,6 +30,9 @@ Object {
2030
"isProdBuild": [Function],
2131
"isServerSide": [Function],
2232
},
33+
"reducers": Object {
34+
"collection": [Function],
35+
},
2336
"redux": Object {
2437
"combineReducers": [Function],
2538
"createActions": [Function],
@@ -130,6 +143,16 @@ Object {
130143
"MetaTags": [Function],
131144
"NavLink": [Function],
132145
"ScalableRect": [Function],
146+
"actions": Object {
147+
"collection": Object {
148+
"addItems": [Function],
149+
"bookItems": [Function],
150+
"clean": [Function],
151+
"freeItems": [Function],
152+
"loadItemDone": [Function],
153+
"loadItemInit": [Function],
154+
},
155+
},
133156
"client": [Function],
134157
"config": Config {
135158
"SECRET": Object {
@@ -144,6 +167,9 @@ Object {
144167
"isProdBuild": [Function],
145168
"isServerSide": [Function],
146169
},
170+
"reducers": Object {
171+
"collection": [Function],
172+
},
147173
"redux": Object {
148174
"combineReducers": [Function],
149175
"createActions": [Function],

‎src/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import actions from 'actions';
12
import AppChunk from 'containers/AppChunk';
23
import Avatar from 'components/Avatar';
34
import Button from 'components/Button';
@@ -6,6 +7,7 @@ import DevTools from 'components/DevTools';
67
import Link from 'components/Link';
78
import MetaTags from 'components/MetaTags';
89
import NavLink from 'components/NavLink';
10+
import reducers from 'reducers';
911
import ScalableRect from 'components/ScalableRect';
1012
import * as utils from 'utils';
1113

@@ -17,6 +19,7 @@ const server = utils.isomorphy.isServerSide() ?
1719
requireWeak('topcoder-react-utils/dist/server') : null;
1820

1921
module.exports = {
22+
actions,
2023
AppChunk,
2124
Avatar,
2225
Button,
@@ -26,6 +29,7 @@ module.exports = {
2629
NavLink,
2730
MetaTags,
2831
ScalableRect,
32+
reducers,
2933
server,
3034
...utils,
3135
};

‎src/shared/actions/collection.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* Proof-of-concept code. Will be documented once stable. In case of any
3+
* questions before that, feel free to contact `birdofpreyru`.
4+
*/
5+
6+
import _ from 'lodash';
7+
import * as redux from 'utils/redux';
8+
9+
/**
10+
* Adds items to the collection.
11+
* @param {Object} index Item ID > item mapping for the items to add.
12+
* @return {Object}
13+
*/
14+
function addItems(index) {
15+
return { index, timestamp: Date.now() };
16+
}
17+
18+
/**
19+
* Increments counters of item references.
20+
* @param {String|String[]} ids
21+
* @param {Number} factor Optional.
22+
* @return {String[]}
23+
*/
24+
function bookItems(ids, factor = 1) {
25+
return { factor, ids: _.isArray(ids) ? ids : [ids] };
26+
}
27+
28+
/**
29+
* Removes from the state all unuzed items with timestamps older than maxage.
30+
* @param {Number} timestamp
31+
*/
32+
function clean(timestamp) {
33+
return timestamp;
34+
}
35+
36+
/**
37+
* Decreases counters of item references.
38+
* @param {String|String[]} ids
39+
* @param {Number} factor Optional.
40+
* @return {String[]}
41+
*/
42+
function freeItems(ids, factor = 1) {
43+
return { factor, ids: _.isArray(ids) ? ids : [ids] };
44+
}
45+
46+
/**
47+
* Inits loading of an item.
48+
* @param {String} operationId
49+
* @param {String} itemId
50+
* @return {Object}
51+
*/
52+
function loadItemInit(operationId, itemId) {
53+
return { itemId, operationId };
54+
}
55+
56+
/**
57+
* Finalizes loading of an item.
58+
* @param {String} operationId
59+
* @param {String} itemId
60+
* @param {Any} item
61+
* @return {Object}
62+
*/
63+
function loadItemDone(operationId, itemId, item) {
64+
return {
65+
item,
66+
itemId,
67+
operationId,
68+
timestamp: Date.now(),
69+
};
70+
}
71+
72+
export default redux.createActions({
73+
COLLECTION: {
74+
ADD_ITEMS: addItems,
75+
BOOK_ITEMS: bookItems,
76+
CLEAN: clean,
77+
FREE_ITEMS: freeItems,
78+
LOAD_ITEM_INIT: loadItemInit,
79+
LOAD_ITEM_DONE: loadItemDone,
80+
},
81+
});

‎src/shared/actions/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import collection from './collection';
2+
3+
export default {
4+
...collection,
5+
};

‎src/shared/reducers/collection.js

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/**
2+
* Proof-of-concept code. Will be documented once stable. In case of any
3+
* questions before that, feel free to contact `birdofpreyru`.
4+
*/
5+
6+
import _ from 'lodash';
7+
import actions from 'actions/collection';
8+
import * as redux from 'utils/redux';
9+
10+
/**
11+
* Inits, or replaces by its clone, the slot indexed under the specified id.
12+
* Returns the new slot indexed by that id.
13+
*
14+
* BEWARE: It mutates the index.
15+
*
16+
* @param {Object} index
17+
* @param {String} id
18+
* @return {Object}
19+
*/
20+
function prepare(index, id) {
21+
let slot = index[id];
22+
slot = slot ? _.clone(slot) : {
23+
item: null,
24+
loadingOperationId: '',
25+
numRefs: 0,
26+
timestamp: 0,
27+
};
28+
index[id] = slot; // eslint-disable-line no-param-reassign
29+
return slot;
30+
}
31+
32+
function onAddItems(state, action) {
33+
const { index, timestamp } = action.payload;
34+
const result = _.clone(state);
35+
_.forOwn(index, (item, id) => {
36+
const slot = prepare(result, id);
37+
slot.timestamp = timestamp;
38+
slot.item = item;
39+
});
40+
return result;
41+
}
42+
43+
function onBookItems(state, { payload: { factor, ids } }) {
44+
const result = _.clone(state);
45+
ids.forEach((id) => {
46+
prepare(result, id).numRefs += factor;
47+
});
48+
return result;
49+
}
50+
51+
function onClean(state, { payload }) {
52+
const result = _.clone(state);
53+
_.forOwn(state, (item, id) => {
54+
const slot = state[id];
55+
if (slot.numRefs || slot.loadingOperationId
56+
|| slot.timestamp > payload) return;
57+
delete result[id];
58+
});
59+
return result;
60+
}
61+
62+
function onFreeItems(state, { payload: { factor, ids } }) {
63+
const result = _.clone(state);
64+
ids.forEach((id) => {
65+
prepare(result, id).numRefs -= factor;
66+
});
67+
return result;
68+
}
69+
70+
function onLoadItemInit(state, { payload }) {
71+
const { itemId, operationId } = payload;
72+
const result = _.clone(state);
73+
const slot = prepare(result, itemId);
74+
slot.loadingOperationId = operationId;
75+
return result;
76+
}
77+
78+
function onLoadItemDone(state, { payload }) {
79+
const {
80+
item,
81+
itemId,
82+
operationId,
83+
timestamp,
84+
} = payload;
85+
const slot = state[itemId];
86+
if (!slot || slot.loadingOperationId !== operationId) return state;
87+
return {
88+
...state,
89+
[itemId]: {
90+
...slot,
91+
item,
92+
loadingOperationId: '',
93+
timestamp,
94+
},
95+
};
96+
}
97+
98+
const a = actions.collection;
99+
export default redux.handleActions({
100+
[a.addItems]: onAddItems,
101+
[a.bookItems]: onBookItems,
102+
[a.clean]: onClean,
103+
[a.freeItems]: onFreeItems,
104+
[a.loadItemInit]: onLoadItemInit,
105+
[a.loadItemDone]: onLoadItemDone,
106+
}, {});

‎src/shared/reducers/index.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import collection from './collection';
2+
3+
export default {
4+
collection,
5+
};

0 commit comments

Comments
 (0)
Please sign in to comment.