UNPKG

14.2 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var Redux = require('redux');
6
7function _interopNamespace(e) {
8 if (e && e.__esModule) return e;
9 var n = Object.create(null);
10 if (e) {
11 Object.keys(e).forEach(function (k) {
12 if (k !== 'default') {
13 var d = Object.getOwnPropertyDescriptor(e, k);
14 Object.defineProperty(n, k, d.get ? d : {
15 enumerable: true,
16 get: function () { return e[k]; }
17 });
18 }
19 });
20 }
21 n["default"] = e;
22 return n;
23}
24
25var Redux__namespace = /*#__PURE__*/_interopNamespace(Redux);
26
27function _extends() {
28 _extends = Object.assign || function (target) {
29 for (var i = 1; i < arguments.length; i++) {
30 var source = arguments[i];
31
32 for (var key in source) {
33 if (Object.prototype.hasOwnProperty.call(source, key)) {
34 target[key] = source[key];
35 }
36 }
37 }
38
39 return target;
40 };
41
42 return _extends.apply(this, arguments);
43}
44
45function createReduxStore(bag) {
46 var _bag$reduxConfig;
47
48 bag.models.forEach(function (model) {
49 return createModelReducer(bag, model);
50 });
51 var rootReducer = createRootReducer(bag);
52 var middlewares = Redux__namespace.applyMiddleware.apply(Redux__namespace, bag.reduxConfig.middlewares);
53 var enhancers = bag.reduxConfig.devtoolComposer ? (_bag$reduxConfig = bag.reduxConfig).devtoolComposer.apply(_bag$reduxConfig, bag.reduxConfig.enhancers.concat([middlewares])) : composeEnhancersWithDevtools(bag.reduxConfig.devtoolOptions).apply(void 0, bag.reduxConfig.enhancers.concat([middlewares]));
54 var createStore = bag.reduxConfig.createStore || Redux__namespace.createStore;
55 var bagInitialState = bag.reduxConfig.initialState;
56 var initialState = bagInitialState === undefined ? {} : bagInitialState;
57 return createStore(rootReducer, initialState, enhancers);
58}
59function createModelReducer(bag, model) {
60 var modelReducers = {};
61 var modelReducerKeys = Object.keys(model.reducers);
62 modelReducerKeys.forEach(function (reducerKey) {
63 var actionName = isAlreadyActionName(reducerKey) ? reducerKey : model.name + "/" + reducerKey;
64 modelReducers[actionName] = model.reducers[reducerKey];
65 });
66
67 var combinedReducer = function combinedReducer(state, action) {
68 if (state === void 0) {
69 state = model.state;
70 }
71
72 if (action.type in modelReducers) {
73 return modelReducers[action.type](state, action.payload, action.meta);
74 }
75
76 return state;
77 };
78
79 var modelBaseReducer = model.baseReducer;
80 var reducer = !modelBaseReducer ? combinedReducer : function (state, action) {
81 if (state === void 0) {
82 state = model.state;
83 }
84
85 return combinedReducer(modelBaseReducer(state, action), action);
86 };
87 bag.forEachPlugin('onReducer', function (onReducer) {
88 reducer = onReducer(reducer, model.name, bag) || reducer;
89 });
90 bag.reduxConfig.reducers[model.name] = reducer;
91}
92function createRootReducer(bag) {
93 var rootReducers = bag.reduxConfig.rootReducers;
94 var mergedReducers = mergeReducers(bag.reduxConfig);
95 var rootReducer = mergedReducers;
96
97 if (rootReducers && Object.keys(rootReducers).length) {
98 rootReducer = function rootReducer(state, action) {
99 var actionRootReducer = rootReducers[action.type];
100
101 if (actionRootReducer) {
102 return mergedReducers(actionRootReducer(state, action), action);
103 }
104
105 return mergedReducers(state, action);
106 };
107 }
108
109 bag.forEachPlugin('onRootReducer', function (onRootReducer) {
110 rootReducer = onRootReducer(rootReducer, bag) || rootReducer;
111 });
112 return rootReducer;
113}
114
115function mergeReducers(reduxConfig) {
116 var combineReducers = reduxConfig.combineReducers || Redux__namespace.combineReducers;
117
118 if (!Object.keys(reduxConfig.reducers).length) {
119 return function (state) {
120 return state;
121 };
122 }
123
124 return combineReducers(reduxConfig.reducers);
125}
126
127function composeEnhancersWithDevtools(devtoolOptions) {
128 if (devtoolOptions === void 0) {
129 devtoolOptions = {};
130 }
131
132 return !devtoolOptions.disabled && typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__(devtoolOptions) : Redux__namespace.compose;
133}
134
135function isAlreadyActionName(reducerKey) {
136 return reducerKey.indexOf('/') > -1;
137}
138
139var isObject = function isObject(obj) {
140 return typeof obj === 'object' && obj !== null && !Array.isArray(obj);
141};
142var ifDefinedIsFunction = function ifDefinedIsFunction(func) {
143 return !func || typeof func === 'function';
144};
145
146var validate = function validate(runValidations) {
147 {
148 var validations = runValidations();
149 var errors = [];
150 validations.forEach(function (validation) {
151 var isInvalid = validation[0];
152 var errorMessage = validation[1];
153
154 if (isInvalid) {
155 errors.push(errorMessage);
156 }
157 });
158
159 if (errors.length > 0) {
160 throw new Error(errors.join(', '));
161 }
162 }
163};
164
165var validateConfig = function validateConfig(config) {
166 validate(function () {
167 return [[!Array.isArray(config.plugins), 'init config.plugins must be an array'], [!isObject(config.models), 'init config.models must be an object'], [!isObject(config.redux.reducers), 'init config.redux.reducers must be an object'], [!Array.isArray(config.redux.middlewares), 'init config.redux.middlewares must be an array'], [!Array.isArray(config.redux.enhancers), 'init config.redux.enhancers must be an array of functions'], [!ifDefinedIsFunction(config.redux.combineReducers), 'init config.redux.combineReducers must be a function'], [!ifDefinedIsFunction(config.redux.createStore), 'init config.redux.createStore must be a function']];
168 });
169};
170var validateModel = function validateModel(model) {
171 validate(function () {
172 return [[!model, 'model config is required'], [typeof model.name !== 'string', 'model "name" [string] is required'], [model.state === undefined && model.baseReducer === undefined, 'model "state" is required'], [!ifDefinedIsFunction(model.baseReducer), 'model "baseReducer" must be a function']];
173 });
174};
175var validatePlugin = function validatePlugin(plugin) {
176 validate(function () {
177 return [[!ifDefinedIsFunction(plugin.onStoreCreated), 'Plugin onStoreCreated must be a function'], [!ifDefinedIsFunction(plugin.onModel), 'Plugin onModel must be a function'], [!ifDefinedIsFunction(plugin.onReducer), 'Plugin onReducer must be a function'], [!ifDefinedIsFunction(plugin.onRootReducer), 'Plugin onRootReducer must be a function'], [!ifDefinedIsFunction(plugin.createMiddleware), 'Plugin createMiddleware must be a function']];
178 });
179};
180var validateModelReducer = function validateModelReducer(modelName, reducers, reducerName) {
181 validate(function () {
182 return [[!!reducerName.match(/\/.+\//), "Invalid reducer name (" + modelName + "/" + reducerName + ")"], [typeof reducers[reducerName] !== 'function', "Invalid reducer (" + modelName + "/" + reducerName + "). Must be a function"]];
183 });
184};
185var validateModelEffect = function validateModelEffect(modelName, effects, effectName) {
186 validate(function () {
187 return [[!!effectName.match(/\//), "Invalid effect name (" + modelName + "/" + effectName + ")"], [typeof effects[effectName] !== 'function', "Invalid effect (" + modelName + "/" + effectName + "). Must be a function"]];
188 });
189};
190
191var createActionDispatcher = function createActionDispatcher(rematch, modelName, actionName, isEffect) {
192 return Object.assign(function (payload, meta) {
193 var action = {
194 type: modelName + "/" + actionName
195 };
196
197 if (typeof payload !== 'undefined') {
198 action.payload = payload;
199 }
200
201 if (typeof meta !== 'undefined') {
202 action.meta = meta;
203 }
204
205 return rematch.dispatch(action);
206 }, {
207 isEffect: isEffect
208 });
209};
210
211var createReducerDispatcher = function createReducerDispatcher(rematch, model) {
212 var modelDispatcher = rematch.dispatch[model.name];
213 var modelReducersKeys = Object.keys(model.reducers);
214 modelReducersKeys.forEach(function (reducerName) {
215 validateModelReducer(model.name, model.reducers, reducerName);
216 modelDispatcher[reducerName] = createActionDispatcher(rematch, model.name, reducerName, false);
217 });
218};
219var createEffectDispatcher = function createEffectDispatcher(rematch, bag, model) {
220 var modelDispatcher = rematch.dispatch[model.name];
221 var effects = {};
222
223 if (model.effects) {
224 effects = typeof model.effects === 'function' ? model.effects(rematch.dispatch) : model.effects;
225 }
226
227 var effectKeys = Object.keys(effects);
228 effectKeys.forEach(function (effectName) {
229 validateModelEffect(model.name, effects, effectName);
230 bag.effects[model.name + "/" + effectName] = effects[effectName].bind(modelDispatcher);
231 modelDispatcher[effectName] = createActionDispatcher(rematch, model.name, effectName, true);
232 });
233};
234
235function createRematchBag(config) {
236 return {
237 models: createNamedModels(config.models),
238 reduxConfig: config.redux,
239 forEachPlugin: function forEachPlugin(method, fn) {
240 config.plugins.forEach(function (plugin) {
241 if (plugin[method]) {
242 fn(plugin[method]);
243 }
244 });
245 },
246 effects: {}
247 };
248}
249
250function createNamedModels(models) {
251 return Object.keys(models).map(function (modelName) {
252 var model = createNamedModel(modelName, models[modelName]);
253 validateModel(model);
254 return model;
255 });
256}
257
258function createNamedModel(name, model) {
259 return _extends({
260 name: name,
261 reducers: {}
262 }, model);
263}
264
265function createRematchStore(config) {
266 var bag = createRematchBag(config);
267 bag.reduxConfig.middlewares.push(createEffectsMiddleware(bag));
268 bag.forEachPlugin('createMiddleware', function (createMiddleware) {
269 bag.reduxConfig.middlewares.push(createMiddleware(bag));
270 });
271 var reduxStore = createReduxStore(bag);
272
273 var rematchStore = _extends({}, reduxStore, {
274 name: config.name,
275 addModel: function addModel(model) {
276 validateModel(model);
277 createModelReducer(bag, model);
278 prepareModel(rematchStore, model);
279 enhanceModel(rematchStore, bag, model);
280 reduxStore.replaceReducer(createRootReducer(bag));
281 reduxStore.dispatch({
282 type: '@@redux/REPLACE'
283 });
284 }
285 });
286
287 addExposed(rematchStore, config.plugins);
288 bag.models.forEach(function (model) {
289 return prepareModel(rematchStore, model);
290 });
291 bag.models.forEach(function (model) {
292 return enhanceModel(rematchStore, bag, model);
293 });
294 bag.forEachPlugin('onStoreCreated', function (onStoreCreated) {
295 rematchStore = onStoreCreated(rematchStore, bag) || rematchStore;
296 });
297 return rematchStore;
298}
299
300function createEffectsMiddleware(bag) {
301 return function (store) {
302 return function (next) {
303 return function (action) {
304 if (action.type in bag.effects) {
305 next(action);
306 return bag.effects[action.type](action.payload, store.getState(), action.meta);
307 }
308
309 return next(action);
310 };
311 };
312 };
313}
314
315function prepareModel(rematchStore, model) {
316 var modelDispatcher = {};
317 rematchStore.dispatch["" + model.name] = modelDispatcher;
318 createReducerDispatcher(rematchStore, model);
319}
320
321function enhanceModel(rematchStore, bag, model) {
322 createEffectDispatcher(rematchStore, bag, model);
323 bag.forEachPlugin('onModel', function (onModel) {
324 onModel(model, rematchStore);
325 });
326}
327
328function addExposed(store, plugins) {
329 plugins.forEach(function (plugin) {
330 if (!plugin.exposed) return;
331 var pluginKeys = Object.keys(plugin.exposed);
332 pluginKeys.forEach(function (key) {
333 if (!plugin.exposed) return;
334 var exposedItem = plugin.exposed[key];
335 var isExposedFunction = typeof exposedItem === 'function';
336 store[key] = isExposedFunction ? function () {
337 for (var _len = arguments.length, params = new Array(_len), _key = 0; _key < _len; _key++) {
338 params[_key] = arguments[_key];
339 }
340
341 return exposedItem.apply(void 0, [store].concat(params));
342 } : Object.create(plugin.exposed[key]);
343 });
344 });
345}
346
347var count = 0;
348function createConfig(initConfig) {
349 var _initConfig$name, _initConfig$redux$dev, _initConfig$redux;
350
351 var storeName = (_initConfig$name = initConfig.name) != null ? _initConfig$name : "Rematch Store " + count;
352 count += 1;
353 var config = {
354 name: storeName,
355 models: initConfig.models || {},
356 plugins: initConfig.plugins || [],
357 redux: _extends({
358 reducers: {},
359 rootReducers: {},
360 enhancers: [],
361 middlewares: []
362 }, initConfig.redux, {
363 devtoolOptions: _extends({
364 name: storeName
365 }, (_initConfig$redux$dev = (_initConfig$redux = initConfig.redux) == null ? void 0 : _initConfig$redux.devtoolOptions) != null ? _initConfig$redux$dev : {})
366 })
367 };
368 validateConfig(config);
369 config.plugins.forEach(function (plugin) {
370 if (plugin.config) {
371 config.models = merge(config.models, plugin.config.models);
372
373 if (plugin.config.redux) {
374 config.redux.initialState = merge(config.redux.initialState, plugin.config.redux.initialState);
375 config.redux.reducers = merge(config.redux.reducers, plugin.config.redux.reducers);
376 config.redux.rootReducers = merge(config.redux.rootReducers, plugin.config.redux.reducers);
377 config.redux.enhancers = [].concat(config.redux.enhancers, plugin.config.redux.enhancers || []);
378 config.redux.middlewares = [].concat(config.redux.middlewares, plugin.config.redux.middlewares || []);
379 config.redux.combineReducers = config.redux.combineReducers || plugin.config.redux.combineReducers;
380 config.redux.createStore = config.redux.createStore || plugin.config.redux.createStore;
381 }
382 }
383
384 validatePlugin(plugin);
385 });
386 return config;
387}
388
389function merge(original, extra) {
390 return extra ? _extends({}, extra, original) : original;
391}
392
393var init = function init(initConfig) {
394 var config = createConfig(initConfig || {});
395 return createRematchStore(config);
396};
397var createModel = function createModel() {
398 return function (mo) {
399 return mo;
400 };
401};
402var index = {
403 init: init,
404 createModel: createModel
405};
406
407exports.createModel = createModel;
408exports["default"] = index;
409exports.init = init;
410//# sourceMappingURL=core.cjs.development.js.map