UNPKG

@rematch/core

Version:
411 lines (354 loc) 14.2 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var Redux = require('redux'); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return n; } var Redux__namespace = /*#__PURE__*/_interopNamespace(Redux); function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function createReduxStore(bag) { var _bag$reduxConfig; bag.models.forEach(function (model) { return createModelReducer(bag, model); }); var rootReducer = createRootReducer(bag); var middlewares = Redux__namespace.applyMiddleware.apply(Redux__namespace, bag.reduxConfig.middlewares); 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])); var createStore = bag.reduxConfig.createStore || Redux__namespace.createStore; var bagInitialState = bag.reduxConfig.initialState; var initialState = bagInitialState === undefined ? {} : bagInitialState; return createStore(rootReducer, initialState, enhancers); } function createModelReducer(bag, model) { var modelReducers = {}; var modelReducerKeys = Object.keys(model.reducers); modelReducerKeys.forEach(function (reducerKey) { var actionName = isAlreadyActionName(reducerKey) ? reducerKey : model.name + "/" + reducerKey; modelReducers[actionName] = model.reducers[reducerKey]; }); var combinedReducer = function combinedReducer(state, action) { if (state === void 0) { state = model.state; } if (action.type in modelReducers) { return modelReducers[action.type](state, action.payload, action.meta); } return state; }; var modelBaseReducer = model.baseReducer; var reducer = !modelBaseReducer ? combinedReducer : function (state, action) { if (state === void 0) { state = model.state; } return combinedReducer(modelBaseReducer(state, action), action); }; bag.forEachPlugin('onReducer', function (onReducer) { reducer = onReducer(reducer, model.name, bag) || reducer; }); bag.reduxConfig.reducers[model.name] = reducer; } function createRootReducer(bag) { var rootReducers = bag.reduxConfig.rootReducers; var mergedReducers = mergeReducers(bag.reduxConfig); var rootReducer = mergedReducers; if (rootReducers && Object.keys(rootReducers).length) { rootReducer = function rootReducer(state, action) { var actionRootReducer = rootReducers[action.type]; if (actionRootReducer) { return mergedReducers(actionRootReducer(state, action), action); } return mergedReducers(state, action); }; } bag.forEachPlugin('onRootReducer', function (onRootReducer) { rootReducer = onRootReducer(rootReducer, bag) || rootReducer; }); return rootReducer; } function mergeReducers(reduxConfig) { var combineReducers = reduxConfig.combineReducers || Redux__namespace.combineReducers; if (!Object.keys(reduxConfig.reducers).length) { return function (state) { return state; }; } return combineReducers(reduxConfig.reducers); } function composeEnhancersWithDevtools(devtoolOptions) { if (devtoolOptions === void 0) { devtoolOptions = {}; } return !devtoolOptions.disabled && typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__(devtoolOptions) : Redux__namespace.compose; } function isAlreadyActionName(reducerKey) { return reducerKey.indexOf('/') > -1; } var isObject = function isObject(obj) { return typeof obj === 'object' && obj !== null && !Array.isArray(obj); }; var ifDefinedIsFunction = function ifDefinedIsFunction(func) { return !func || typeof func === 'function'; }; var validate = function validate(runValidations) { { var validations = runValidations(); var errors = []; validations.forEach(function (validation) { var isInvalid = validation[0]; var errorMessage = validation[1]; if (isInvalid) { errors.push(errorMessage); } }); if (errors.length > 0) { throw new Error(errors.join(', ')); } } }; var validateConfig = function validateConfig(config) { validate(function () { 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']]; }); }; var validateModel = function validateModel(model) { validate(function () { 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']]; }); }; var validatePlugin = function validatePlugin(plugin) { validate(function () { 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']]; }); }; var validateModelReducer = function validateModelReducer(modelName, reducers, reducerName) { validate(function () { return [[!!reducerName.match(/\/.+\//), "Invalid reducer name (" + modelName + "/" + reducerName + ")"], [typeof reducers[reducerName] !== 'function', "Invalid reducer (" + modelName + "/" + reducerName + "). Must be a function"]]; }); }; var validateModelEffect = function validateModelEffect(modelName, effects, effectName) { validate(function () { return [[!!effectName.match(/\//), "Invalid effect name (" + modelName + "/" + effectName + ")"], [typeof effects[effectName] !== 'function', "Invalid effect (" + modelName + "/" + effectName + "). Must be a function"]]; }); }; var createActionDispatcher = function createActionDispatcher(rematch, modelName, actionName, isEffect) { return Object.assign(function (payload, meta) { var action = { type: modelName + "/" + actionName }; if (typeof payload !== 'undefined') { action.payload = payload; } if (typeof meta !== 'undefined') { action.meta = meta; } return rematch.dispatch(action); }, { isEffect: isEffect }); }; var createReducerDispatcher = function createReducerDispatcher(rematch, model) { var modelDispatcher = rematch.dispatch[model.name]; var modelReducersKeys = Object.keys(model.reducers); modelReducersKeys.forEach(function (reducerName) { validateModelReducer(model.name, model.reducers, reducerName); modelDispatcher[reducerName] = createActionDispatcher(rematch, model.name, reducerName, false); }); }; var createEffectDispatcher = function createEffectDispatcher(rematch, bag, model) { var modelDispatcher = rematch.dispatch[model.name]; var effects = {}; if (model.effects) { effects = typeof model.effects === 'function' ? model.effects(rematch.dispatch) : model.effects; } var effectKeys = Object.keys(effects); effectKeys.forEach(function (effectName) { validateModelEffect(model.name, effects, effectName); bag.effects[model.name + "/" + effectName] = effects[effectName].bind(modelDispatcher); modelDispatcher[effectName] = createActionDispatcher(rematch, model.name, effectName, true); }); }; function createRematchBag(config) { return { models: createNamedModels(config.models), reduxConfig: config.redux, forEachPlugin: function forEachPlugin(method, fn) { config.plugins.forEach(function (plugin) { if (plugin[method]) { fn(plugin[method]); } }); }, effects: {} }; } function createNamedModels(models) { return Object.keys(models).map(function (modelName) { var model = createNamedModel(modelName, models[modelName]); validateModel(model); return model; }); } function createNamedModel(name, model) { return _extends({ name: name, reducers: {} }, model); } function createRematchStore(config) { var bag = createRematchBag(config); bag.reduxConfig.middlewares.push(createEffectsMiddleware(bag)); bag.forEachPlugin('createMiddleware', function (createMiddleware) { bag.reduxConfig.middlewares.push(createMiddleware(bag)); }); var reduxStore = createReduxStore(bag); var rematchStore = _extends({}, reduxStore, { name: config.name, addModel: function addModel(model) { validateModel(model); createModelReducer(bag, model); prepareModel(rematchStore, model); enhanceModel(rematchStore, bag, model); reduxStore.replaceReducer(createRootReducer(bag)); reduxStore.dispatch({ type: '@@redux/REPLACE' }); } }); addExposed(rematchStore, config.plugins); bag.models.forEach(function (model) { return prepareModel(rematchStore, model); }); bag.models.forEach(function (model) { return enhanceModel(rematchStore, bag, model); }); bag.forEachPlugin('onStoreCreated', function (onStoreCreated) { rematchStore = onStoreCreated(rematchStore, bag) || rematchStore; }); return rematchStore; } function createEffectsMiddleware(bag) { return function (store) { return function (next) { return function (action) { if (action.type in bag.effects) { next(action); return bag.effects[action.type](action.payload, store.getState(), action.meta); } return next(action); }; }; }; } function prepareModel(rematchStore, model) { var modelDispatcher = {}; rematchStore.dispatch["" + model.name] = modelDispatcher; createReducerDispatcher(rematchStore, model); } function enhanceModel(rematchStore, bag, model) { createEffectDispatcher(rematchStore, bag, model); bag.forEachPlugin('onModel', function (onModel) { onModel(model, rematchStore); }); } function addExposed(store, plugins) { plugins.forEach(function (plugin) { if (!plugin.exposed) return; var pluginKeys = Object.keys(plugin.exposed); pluginKeys.forEach(function (key) { if (!plugin.exposed) return; var exposedItem = plugin.exposed[key]; var isExposedFunction = typeof exposedItem === 'function'; store[key] = isExposedFunction ? function () { for (var _len = arguments.length, params = new Array(_len), _key = 0; _key < _len; _key++) { params[_key] = arguments[_key]; } return exposedItem.apply(void 0, [store].concat(params)); } : Object.create(plugin.exposed[key]); }); }); } var count = 0; function createConfig(initConfig) { var _initConfig$name, _initConfig$redux$dev, _initConfig$redux; var storeName = (_initConfig$name = initConfig.name) != null ? _initConfig$name : "Rematch Store " + count; count += 1; var config = { name: storeName, models: initConfig.models || {}, plugins: initConfig.plugins || [], redux: _extends({ reducers: {}, rootReducers: {}, enhancers: [], middlewares: [] }, initConfig.redux, { devtoolOptions: _extends({ name: storeName }, (_initConfig$redux$dev = (_initConfig$redux = initConfig.redux) == null ? void 0 : _initConfig$redux.devtoolOptions) != null ? _initConfig$redux$dev : {}) }) }; validateConfig(config); config.plugins.forEach(function (plugin) { if (plugin.config) { config.models = merge(config.models, plugin.config.models); if (plugin.config.redux) { config.redux.initialState = merge(config.redux.initialState, plugin.config.redux.initialState); config.redux.reducers = merge(config.redux.reducers, plugin.config.redux.reducers); config.redux.rootReducers = merge(config.redux.rootReducers, plugin.config.redux.reducers); config.redux.enhancers = [].concat(config.redux.enhancers, plugin.config.redux.enhancers || []); config.redux.middlewares = [].concat(config.redux.middlewares, plugin.config.redux.middlewares || []); config.redux.combineReducers = config.redux.combineReducers || plugin.config.redux.combineReducers; config.redux.createStore = config.redux.createStore || plugin.config.redux.createStore; } } validatePlugin(plugin); }); return config; } function merge(original, extra) { return extra ? _extends({}, extra, original) : original; } var init = function init(initConfig) { var config = createConfig(initConfig || {}); return createRematchStore(config); }; var createModel = function createModel() { return function (mo) { return mo; }; }; var index = { init: init, createModel: createModel }; exports.createModel = createModel; exports["default"] = index; exports.init = init; //# sourceMappingURL=core.cjs.development.js.map