1
1
import isPlainObject from 'lodash/isPlainObject'
2
- import warning from './utils/warning'
3
2
import $$observable from 'symbol-observable'
4
3
5
4
export var ActionTypes = {
6
5
INIT : '@@redux/INIT'
7
6
}
8
7
9
- function createBasicStore ( reducer , initialState , onChange ) {
8
+ function createStoreBase ( reducer , initialState , onChange ) {
10
9
var currentState = initialState
11
10
var isDispatching = false
12
11
@@ -30,58 +29,70 @@ function createBasicStore(reducer, initialState, onChange) {
30
29
if ( isDispatching ) {
31
30
throw new Error ( 'Reducers may not dispatch actions.' )
32
31
}
32
+
33
33
try {
34
34
isDispatching = true
35
35
currentState = reducer ( currentState , action )
36
36
} finally {
37
37
isDispatching = false
38
38
}
39
+
39
40
onChange ( )
40
41
return action
41
42
}
42
43
43
44
return {
44
45
dispatch,
45
- getState,
46
+ getState
46
47
}
47
48
}
48
49
49
- export default function createEnhancedStore ( reducer , initialState , enhancer ) {
50
+ export default function createStore ( reducer , initialState , enhancer ) {
50
51
if ( typeof reducer !== 'function' ) {
51
52
throw new Error ( 'Expected the reducer to be a function.' )
52
53
}
53
54
if ( typeof initialState === 'function' && typeof enhancer === 'undefined' ) {
54
55
enhancer = initialState
55
56
initialState = undefined
56
57
}
57
- var createStore = createBasicStore
58
- if ( typeof enhancer !== 'undefined' ) {
59
- if ( typeof enhancer !== 'function' ) {
60
- throw new Error ( 'Expected the enhancer to be a function.' )
61
- }
62
- createStore = enhancer ( createBasicStore )
58
+ if ( typeof enhancer !== 'undefined' && typeof enhancer !== 'function' ) {
59
+ throw new Error ( 'Expected the enhancer to be a function.' )
63
60
}
64
61
65
- var store
62
+ enhancer = enhancer || ( x => x )
63
+ var createFinalStoreBase = enhancer ( createStoreBase )
64
+
65
+ var storeBase
66
66
var currentListeners = [ ]
67
67
var nextListeners = currentListeners
68
68
69
+ function onChange ( ) {
70
+ var listeners = currentListeners = nextListeners
71
+ for ( var i = 0 ; i < listeners . length ; i ++ ) {
72
+ listeners [ i ] ( )
73
+ }
74
+ }
75
+
69
76
function ensureCanMutateNextListeners ( ) {
70
77
if ( nextListeners === currentListeners ) {
71
78
nextListeners = currentListeners . slice ( )
72
79
}
73
80
}
81
+
74
82
function subscribe ( listener ) {
75
83
if ( typeof listener !== 'function' ) {
76
84
throw new Error ( 'Expected listener to be a function.' )
77
85
}
86
+
78
87
var isSubscribed = true
79
88
ensureCanMutateNextListeners ( )
80
89
nextListeners . push ( listener )
90
+
81
91
return function unsubscribe ( ) {
82
92
if ( ! isSubscribed ) {
83
93
return
84
94
}
95
+
85
96
isSubscribed = false
86
97
ensureCanMutateNextListeners ( )
87
98
var index = nextListeners . indexOf ( listener )
@@ -90,18 +101,21 @@ export default function createEnhancedStore(reducer, initialState, enhancer) {
90
101
}
91
102
92
103
function dispatch ( action ) {
93
- return store . dispatch ( action )
104
+ return storeBase . dispatch ( action )
94
105
}
95
106
96
- function onChange ( ) {
97
- var listeners = currentListeners = nextListeners
98
- for ( var i = 0 ; i < listeners . length ; i ++ ) {
99
- listeners [ i ] ( )
100
- }
107
+ function getState ( ) {
108
+ return storeBase . getState ( )
101
109
}
102
110
103
- function getState ( ) {
104
- return store . getState ( )
111
+ function replaceReducer ( nextReducer ) {
112
+ if ( typeof nextReducer !== 'function' ) {
113
+ throw new Error ( 'Expected the nextReducer to be a function.' )
114
+ }
115
+
116
+ var nextInitialState = storeBase ? getState ( ) : initialState
117
+ storeBase = createFinalStoreBase ( nextReducer , nextInitialState , onChange )
118
+ dispatch ( { type : ActionTypes . INIT } )
105
119
}
106
120
107
121
function observable ( ) {
@@ -126,15 +140,6 @@ export default function createEnhancedStore(reducer, initialState, enhancer) {
126
140
}
127
141
}
128
142
129
- function replaceReducer ( nextReducer ) {
130
- if ( typeof nextReducer !== 'function' ) {
131
- throw new Error ( 'Expected the nextReducer to be a function.' )
132
- }
133
-
134
- store = createStore ( nextReducer , store ? getState ( ) : initialState , onChange )
135
- dispatch ( { type : ActionTypes . INIT } )
136
- }
137
-
138
143
replaceReducer ( reducer )
139
144
140
145
return {
@@ -144,4 +149,4 @@ export default function createEnhancedStore(reducer, initialState, enhancer) {
144
149
replaceReducer,
145
150
[ $$observable ] : observable
146
151
}
147
- }
152
+ }
0 commit comments