forked from angular-redux/ng-redux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathngRedux.js
99 lines (76 loc) · 3.13 KB
/
ngRedux.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
import Connector from './connector';
import invariant from 'invariant';
import {createStore, applyMiddleware, compose, combineReducers} from 'redux';
import digestMiddleware from './digestMiddleware';
import providedStoreMiddleware from './providedStoreMiddleware';
import wrapStore from './storeWrapper';
import curry from 'lodash.curry';
import isFunction from 'lodash.isfunction';
import map from 'lodash.map';
const isArray = Array.isArray;
const typeIs = curry((type, val) => typeof val === type);
const isObject = typeIs('object');
const isString = typeIs('string');
const assign = Object.assign;
export default function ngReduxProvider() {
let _reducer = undefined;
let _middlewares = undefined;
let _storeEnhancers = undefined;
let _initialState = undefined;
let _reducerIsObject = undefined;
let _providedStore = undefined;
this.provideStore = (store) => {
_providedStore = store;
_reducer = (state, action) => action.payload;
_middlewares = [providedStoreMiddleware(_providedStore)];
}
this.createStoreWith = (reducer, middlewares, storeEnhancers, initialState) => {
invariant(
isFunction(reducer) || isObject(reducer),
'The reducer parameter passed to createStoreWith must be a Function or an Object. Instead received %s.',
typeof reducer
);
invariant(
!storeEnhancers || isArray(storeEnhancers),
'The storeEnhancers parameter passed to createStoreWith must be an Array. Instead received %s.',
typeof storeEnhancers
);
_reducer = reducer;
_reducerIsObject = isObject(reducer);
_storeEnhancers = storeEnhancers
_middlewares = middlewares || [];
_initialState = initialState;
};
this.$get = ($injector) => {
const resolveMiddleware = middleware => isString(middleware)
? $injector.get(middleware)
: middleware;
const resolvedMiddleware = map(_middlewares, resolveMiddleware);
const resolveStoreEnhancer = storeEnhancer => isString(storeEnhancer)
? $injector.get(storeEnhancer)
: storeEnhancer;
const resolvedStoreEnhancer = map(_storeEnhancers, resolveStoreEnhancer);
if(_reducerIsObject) {
const getReducerKey = key => isString(_reducer[key])
? $injector.get(_reducer[key])
: _reducer[key];
const resolveReducerKey = (result, key) => assign({}, result,
{ [key]: getReducerKey(key) }
);
const reducersObj = Object
.keys(_reducer)
.reduce(resolveReducerKey, {});
_reducer = combineReducers(reducersObj);
}
const finalCreateStore = resolvedStoreEnhancer ? compose(...resolvedStoreEnhancer)(createStore) : createStore;
//digestMiddleware needs to be the last one.
resolvedMiddleware.push(digestMiddleware($injector.get('$rootScope')));
const store = _initialState
? applyMiddleware(...resolvedMiddleware)(finalCreateStore)(_reducer, _initialState)
: applyMiddleware(...resolvedMiddleware)(finalCreateStore)(_reducer);
const mergedStore = assign({}, store, { connect: Connector(store) });
if (_providedStore) wrapStore(_providedStore, mergedStore)
return mergedStore;
};
this.$get.$inject = ['$injector'];
}