forked from angular-redux/ng-redux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconnector.js
91 lines (72 loc) · 2.74 KB
/
connector.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
import shallowEqual from '../utils/shallowEqual';
import wrapActionCreators from '../utils/wrapActionCreators';
import invariant from 'invariant';
import isPlainObject from 'lodash/isPlainObject';
import isFunction from 'lodash/isFunction';
import isObject from 'lodash/isObject';
const assign = Object.assign;
const defaultMapStateToTarget = () => ({});
const defaultMapDispatchToTarget = dispatch => ({dispatch});
export default function Connector(store) {
return (mapStateToTarget, mapDispatchToTarget) => {
let finalMapStateToTarget = mapStateToTarget || defaultMapStateToTarget;
const finalMapDispatchToTarget = isObject(mapDispatchToTarget) && !isFunction(mapDispatchToTarget) ?
wrapActionCreators(mapDispatchToTarget) :
mapDispatchToTarget || defaultMapDispatchToTarget;
invariant(
isFunction(finalMapStateToTarget),
'mapStateToTarget must be a Function. Instead received %s.', finalMapStateToTarget
);
invariant(
isObject(finalMapDispatchToTarget) || isFunction(finalMapDispatchToTarget),
'mapDispatchToTarget must be a plain Object or a Function. Instead received %s.', finalMapDispatchToTarget
);
let slice = getStateSlice(store.getState(), finalMapStateToTarget, false);
const isFactory = isFunction(slice);
if (isFactory) {
finalMapStateToTarget = slice;
slice = getStateSlice(store.getState(), finalMapStateToTarget);
}
const boundActionCreators = finalMapDispatchToTarget(store.dispatch);
return (target) => {
invariant(
isFunction(target) || isObject(target),
'The target parameter passed to connect must be a Function or a object.'
);
//Initial update
updateTarget(target, slice, boundActionCreators);
const unsubscribe = store.subscribe(() => {
const nextSlice = getStateSlice(store.getState(), finalMapStateToTarget);
if (!shallowEqual(slice, nextSlice)) {
updateTarget(target, nextSlice, boundActionCreators, slice);
slice = nextSlice;
}
});
return unsubscribe;
}
}
}
function updateTarget(target, StateSlice, dispatch, prevStateSlice) {
if(isFunction(target)) {
target(StateSlice, dispatch, prevStateSlice);
} else {
assign(target, StateSlice, dispatch);
}
}
function getStateSlice(state, mapStateToScope, shouldReturnObject = true) {
const slice = mapStateToScope(state);
if (shouldReturnObject) {
invariant(
isPlainObject(slice),
'`mapStateToScope` must return an object. Instead received %s.',
slice
);
} else {
invariant(
isPlainObject(slice) || isFunction(slice),
'`mapStateToScope` must return an object or a function. Instead received %s.',
slice
);
}
return slice;
}