1 | var ActionTypes = {
|
2 | INIT: "@@redux/INIT"
|
3 | };
|
4 |
|
5 | export function createStore(reducer, preloadedState, enhancer) {
|
6 | if (typeof preloadedState === "function" && typeof enhancer === "undefined") {
|
7 | enhancer = preloadedState;
|
8 | preloadedState = undefined;
|
9 | }
|
10 |
|
11 | if (typeof enhancer !== "undefined") {
|
12 | if (typeof enhancer !== "function") {
|
13 | throw new Error("Expected the enhancer to be a function.");
|
14 | }
|
15 |
|
16 | return enhancer(createStore)(reducer, preloadedState);
|
17 | }
|
18 |
|
19 | if (typeof reducer !== "function") {
|
20 | throw new Error("Expected the reducer to be a function.");
|
21 | }
|
22 |
|
23 | var currentReducer = reducer;
|
24 | var currentState = preloadedState;
|
25 | var currentListeners = [];
|
26 | var nextListeners = currentListeners;
|
27 | var isDispatching = false;
|
28 |
|
29 | function ensureCanMutateNextListeners() {
|
30 | if (nextListeners === currentListeners) {
|
31 | nextListeners = currentListeners.slice();
|
32 | }
|
33 | }
|
34 |
|
35 | function getState() {
|
36 | return currentState;
|
37 | }
|
38 |
|
39 | function subscribe(listener) {
|
40 | if (typeof listener !== "function") {
|
41 | throw new Error("Expected listener to be a function.");
|
42 | }
|
43 |
|
44 | var isSubscribed = true;
|
45 |
|
46 | ensureCanMutateNextListeners();
|
47 | nextListeners.push(listener);
|
48 |
|
49 | return function unsubscribe() {
|
50 | if (!isSubscribed) {
|
51 | return;
|
52 | }
|
53 |
|
54 | isSubscribed = false;
|
55 |
|
56 | ensureCanMutateNextListeners();
|
57 | var index = nextListeners.indexOf(listener);
|
58 | nextListeners.splice(index, 1);
|
59 | };
|
60 | }
|
61 |
|
62 | function dispatch(action) {
|
63 | if (!isPlainObject(action)) {
|
64 | throw new Error(
|
65 | "Actions must be plain objects. " +
|
66 | "Use custom middleware for async actions."
|
67 | );
|
68 | }
|
69 |
|
70 | if (typeof action.type === "undefined") {
|
71 | throw new Error(
|
72 | 'Actions may not have an undefined "type" property. ' +
|
73 | "Have you misspelled a constant?"
|
74 | );
|
75 | }
|
76 |
|
77 | if (isDispatching) {
|
78 | throw new Error("Reducers may not dispatch actions.");
|
79 | }
|
80 |
|
81 | try {
|
82 | isDispatching = true;
|
83 | currentState = currentReducer(currentState, action);
|
84 | } finally {
|
85 | isDispatching = false;
|
86 | }
|
87 |
|
88 | var listeners = (currentListeners = nextListeners);
|
89 | for (var i = 0; i < listeners.length; i++) {
|
90 | var listener = listeners[i];
|
91 | listener();
|
92 | }
|
93 |
|
94 | return action;
|
95 | }
|
96 |
|
97 | function replaceReducer(nextReducer) {
|
98 | if (typeof nextReducer !== "function") {
|
99 | throw new Error("Expected the nextReducer to be a function.");
|
100 | }
|
101 |
|
102 | currentReducer = nextReducer;
|
103 | dispatch({ type: ActionTypes.INIT });
|
104 | }
|
105 |
|
106 |
|
107 |
|
108 |
|
109 | dispatch({ type: ActionTypes.INIT });
|
110 |
|
111 | return {
|
112 | dispatch: dispatch,
|
113 | subscribe: subscribe,
|
114 | getState: getState,
|
115 | replaceReducer: replaceReducer
|
116 | };
|
117 | }
|
118 |
|
119 | function warning(message) {
|
120 |
|
121 | if (typeof console !== "undefined" && typeof console.error === "function") {
|
122 | console.error(message);
|
123 | }
|
124 |
|
125 | try {
|
126 |
|
127 |
|
128 |
|
129 | throw new Error(message);
|
130 |
|
131 | } catch (e) {}
|
132 |
|
133 | }
|
134 |
|
135 | function getUndefinedStateErrorMessage(key, action) {
|
136 | var actionType = action && action.type;
|
137 | var actionName =
|
138 | (actionType && '"' + actionType.toString() + '"') || "an action";
|
139 |
|
140 | return (
|
141 | "Given action " +
|
142 | actionName +
|
143 | ', reducer "' +
|
144 | key +
|
145 | '" returned undefined. ' +
|
146 | "To ignore an action, you must explicitly return the previous state. " +
|
147 | "If you want this reducer to hold no value, you can return null instead of undefined."
|
148 | );
|
149 | }
|
150 |
|
151 | function getUnexpectedStateShapeWarningMessage(
|
152 | inputState,
|
153 | reducers,
|
154 | action,
|
155 | unexpectedKeyCache
|
156 | ) {
|
157 | var reducerKeys = Object.keys(reducers);
|
158 | var argumentName =
|
159 | action && action.type === ActionTypes.INIT
|
160 | ? "preloadedState argument passed to createStore"
|
161 | : "previous state received by the reducer";
|
162 |
|
163 | if (reducerKeys.length === 0) {
|
164 | return (
|
165 | "Store does not have a valid reducer. Make sure the argument passed " +
|
166 | "to combineReducers is an object whose values are reducers."
|
167 | );
|
168 | }
|
169 |
|
170 | if (!isPlainObject(inputState)) {
|
171 | return (
|
172 | "The " +
|
173 | argumentName +
|
174 | ' has unexpected type of "' +
|
175 | {}.toString.call(inputState).match(/\s([a-z|A-Z]+)/)[1] +
|
176 | '". Expected argument to be an object with the following ' +
|
177 | ('keys: "' + reducerKeys.join('", "') + '"')
|
178 | );
|
179 | }
|
180 |
|
181 | var unexpectedKeys = Object.keys(inputState).filter(function(key) {
|
182 | return !reducers.hasOwnProperty(key) && !unexpectedKeyCache[key];
|
183 | });
|
184 |
|
185 | unexpectedKeys.forEach(function(key) {
|
186 | unexpectedKeyCache[key] = true;
|
187 | });
|
188 |
|
189 | if (unexpectedKeys.length > 0) {
|
190 | return (
|
191 | "Unexpected " +
|
192 | (unexpectedKeys.length > 1 ? "keys" : "key") +
|
193 | " " +
|
194 | ('"' +
|
195 | unexpectedKeys.join('", "') +
|
196 | '" found in ' +
|
197 | argumentName +
|
198 | ". ") +
|
199 | "Expected to find one of the known reducer keys instead: " +
|
200 | ('"' + reducerKeys.join('", "') + '". Unexpected keys will be ignored.')
|
201 | );
|
202 | }
|
203 | }
|
204 |
|
205 | function assertReducerShape(reducers) {
|
206 | Object.keys(reducers).forEach(function(key) {
|
207 | var reducer = reducers[key];
|
208 | var initialState = reducer(undefined, { type: ActionTypes.INIT });
|
209 |
|
210 | if (typeof initialState === "undefined") {
|
211 | throw new Error(
|
212 | 'Reducer "' +
|
213 | key +
|
214 | '" returned undefined during initialization. ' +
|
215 | "If the state passed to the reducer is undefined, you must " +
|
216 | "explicitly return the initial state. The initial state may " +
|
217 | "not be undefined. If you don't want to set a value for this reducer, " +
|
218 | "you can use null instead of undefined."
|
219 | );
|
220 | }
|
221 |
|
222 | var type =
|
223 | "@@redux/PROBE_UNKNOWN_ACTION_" +
|
224 | Math.random()
|
225 | .toString(36)
|
226 | .substring(7)
|
227 | .split("")
|
228 | .join(".");
|
229 | if (typeof reducer(undefined, { type: type }) === "undefined") {
|
230 | throw new Error(
|
231 | 'Reducer "' +
|
232 | key +
|
233 | '" returned undefined when probed with a random type. ' +
|
234 | ("Don't try to handle " +
|
235 | ActionTypes.INIT +
|
236 | ' or other actions in "redux/*" ') +
|
237 | "namespace. They are considered private. Instead, you must return the " +
|
238 | "current state for any unknown actions, unless it is undefined, " +
|
239 | "in which case you must return the initial state, regardless of the " +
|
240 | "action type. The initial state may not be undefined, but can be null."
|
241 | );
|
242 | }
|
243 | });
|
244 | }
|
245 |
|
246 | export function combineReducers(reducers) {
|
247 | var reducerKeys = Object.keys(reducers);
|
248 | var finalReducers = {};
|
249 | for (var i = 0; i < reducerKeys.length; i++) {
|
250 | var key = reducerKeys[i];
|
251 |
|
252 | {
|
253 | if (typeof reducers[key] === "undefined") {
|
254 | warning('No reducer provided for key "' + key + '"');
|
255 | }
|
256 | }
|
257 |
|
258 | if (typeof reducers[key] === "function") {
|
259 | finalReducers[key] = reducers[key];
|
260 | }
|
261 | }
|
262 | var finalReducerKeys = Object.keys(finalReducers);
|
263 |
|
264 | var unexpectedKeyCache = void 0;
|
265 | {
|
266 | unexpectedKeyCache = {};
|
267 | }
|
268 |
|
269 | var shapeAssertionError = void 0;
|
270 | try {
|
271 | assertReducerShape(finalReducers);
|
272 | } catch (e) {
|
273 | shapeAssertionError = e;
|
274 | }
|
275 |
|
276 | return function combination() {
|
277 | var state =
|
278 | arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
279 | var action = arguments[1];
|
280 |
|
281 | if (shapeAssertionError) {
|
282 | throw shapeAssertionError;
|
283 | }
|
284 |
|
285 | {
|
286 | var warningMessage = getUnexpectedStateShapeWarningMessage(
|
287 | state,
|
288 | finalReducers,
|
289 | action,
|
290 | unexpectedKeyCache
|
291 | );
|
292 | if (warningMessage) {
|
293 | warning(warningMessage);
|
294 | }
|
295 | }
|
296 |
|
297 | var hasChanged = false;
|
298 | var nextState = {};
|
299 | for (var _i = 0; _i < finalReducerKeys.length; _i++) {
|
300 | var _key = finalReducerKeys[_i];
|
301 | var reducer = finalReducers[_key];
|
302 | var previousStateForKey = state[_key];
|
303 | var nextStateForKey = reducer(previousStateForKey, action);
|
304 | if (typeof nextStateForKey === "undefined") {
|
305 | var errorMessage = getUndefinedStateErrorMessage(_key, action);
|
306 | throw new Error(errorMessage);
|
307 | }
|
308 | nextState[_key] = nextStateForKey;
|
309 | hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
|
310 | }
|
311 | return hasChanged ? nextState : state;
|
312 | };
|
313 | }
|
314 |
|
315 | function bindActionCreator(actionCreator, dispatch) {
|
316 | return function() {
|
317 | return dispatch(actionCreator.apply(undefined, arguments));
|
318 | };
|
319 | }
|
320 |
|
321 | export function bindActionCreators(actionCreators, dispatch) {
|
322 | if (typeof actionCreators === "function") {
|
323 | return bindActionCreator(actionCreators, dispatch);
|
324 | }
|
325 |
|
326 | if (typeof actionCreators !== "object" || actionCreators === null) {
|
327 | throw new Error(
|
328 | "bindActionCreators expected an object or a function, instead received " +
|
329 | (actionCreators === null ? "null" : typeof actionCreators) +
|
330 | ". " +
|
331 | 'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?'
|
332 | );
|
333 | }
|
334 |
|
335 | var keys = Object.keys(actionCreators);
|
336 | var boundActionCreators = {};
|
337 | for (var i = 0; i < keys.length; i++) {
|
338 | var key = keys[i];
|
339 | var actionCreator = actionCreators[key];
|
340 | if (typeof actionCreator === "function") {
|
341 | boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);
|
342 | }
|
343 | }
|
344 | return boundActionCreators;
|
345 | }
|
346 |
|
347 | export function compose() {
|
348 | for (
|
349 | var _len = arguments.length, funcs = Array(_len), _key = 0;
|
350 | _key < _len;
|
351 | _key++
|
352 | ) {
|
353 | funcs[_key] = arguments[_key];
|
354 | }
|
355 |
|
356 | if (funcs.length === 0) {
|
357 | return function(arg) {
|
358 | return arg;
|
359 | };
|
360 | }
|
361 |
|
362 | if (funcs.length === 1) {
|
363 | return funcs[0];
|
364 | }
|
365 |
|
366 | return funcs.reduce(function(a, b) {
|
367 | return function() {
|
368 | return a(b.apply(undefined, arguments));
|
369 | };
|
370 | });
|
371 | }
|
372 |
|
373 | export function applyMiddleware() {
|
374 | for (
|
375 | var _len = arguments.length, middlewares = Array(_len), _key = 0;
|
376 | _key < _len;
|
377 | _key++
|
378 | ) {
|
379 | middlewares[_key] = arguments[_key];
|
380 | }
|
381 |
|
382 | return function(createStore) {
|
383 | return function(reducer, preloadedState, enhancer) {
|
384 | var store = createStore(reducer, preloadedState, enhancer);
|
385 | var _dispatch = store.dispatch;
|
386 | var chain = [];
|
387 |
|
388 | var middlewareAPI = {
|
389 | getState: store.getState,
|
390 | dispatch: function dispatch(action) {
|
391 | return _dispatch(action);
|
392 | }
|
393 | };
|
394 | chain = middlewares.map(function(middleware) {
|
395 | return middleware(middlewareAPI);
|
396 | });
|
397 | _dispatch = compose.apply(undefined, chain)(store.dispatch);
|
398 |
|
399 | return Object.assign({}, store, {
|
400 | dispatch: _dispatch
|
401 | });
|
402 | };
|
403 | };
|
404 | }
|