UNPKG

anew

Version:

React and Redux Framework with additional power.

329 lines (254 loc) 12.5 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _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; }; exports.default = createStore; var _redux = require('redux'); var _reselect = require('reselect'); var _invariant = require('invariant'); var _invariant2 = _interopRequireDefault(_invariant); var _createBatch = require('./utils/createBatch'); var _createBatch2 = _interopRequireDefault(_createBatch); var _createReducer = require('./utils/createReducer'); var _createReducer2 = _interopRequireDefault(_createReducer); var _createReduxAnewProps = require('./utils/createReduxAnewProps'); var _createReduxAnewProps2 = _interopRequireDefault(_createReduxAnewProps); var _createSetState = require('./utils/createSetState'); var _createSetState2 = _interopRequireDefault(_createSetState); var _createAnewSelectorHOC = require('./utils/createAnewSelectorHOC'); var _createAnewSelectorHOC2 = _interopRequireDefault(_createAnewSelectorHOC); var _createPersistStore = require('./utils/createPersistStore'); var _createPersistStore2 = _interopRequireDefault(_createPersistStore); var _validateFunctionProperty = require('./utils/validateFunctionProperty'); var _validateFunctionProperty2 = _interopRequireDefault(_validateFunctionProperty); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var takenReducerNames = ["done"]; function createStore(_ref) { var _ref$name = _ref.name, name = _ref$name === undefined ? 'store' : _ref$name, _ref$state = _ref.state, state = _ref$state === undefined ? {} : _ref$state, _ref$reducers = _ref.reducers, reducers = _ref$reducers === undefined ? {} : _ref$reducers, _ref$effects = _ref.effects, effects = _ref$effects === undefined ? {} : _ref$effects, _ref$actions = _ref.actions, actions = _ref$actions === undefined ? {} : _ref$actions, _ref$selectors = _ref.selectors, selectors = _ref$selectors === undefined ? {} : _ref$selectors, persist = _ref.persist, reducer = _ref.reducer, enhancer = _ref.enhancer; (0, _validateFunctionProperty2.default)(name, 'store creation'); /** * Create Object to preserve reference */ var anewStore = { name: name, state: state, reducers: reducers, actions: actions, selectors: selectors, effects: _extends({}, effects), batches: [] /** * Create setState method for an immutable state updates. * This also set this anewStore as the conext */ };anewStore.setState = (0, _createSetState2.default)(anewStore); /** * Reduce state to new value after dispatching an action * @param { Object } reduxState Redux State Object (Not Used) * @param { String } options.type Redux Type * @param { String } options.payload Redux Payload * @param { Object } options.state Application Combined State * @param { Object } options.actions Chain of actions to dispatch * @return { Object } Updated Anew State Object */ var anewReducer = (0, _createReducer2.default)(anewStore, reducer, persist); /** * Redux Store * @type { Object } */ var store = (0, _redux.createStore)(anewReducer, anewStore.state, enhancer); var reduxStore = persist ? (0, _createPersistStore2.default)(store) : store; /** * Create anew specific store props * @type { Object } */ reduxStore.anew = (0, _createReduxAnewProps2.default)(anewStore, anewReducer); /** * Extend Dispatcher to include reducers, effects, and batch. * * Reducers: are pure functions that reduce the state to a shallow clone of * the previous state with modification. The state object is updated via * the dispatch method. Reducers receive the state object and a payload list as parameters. * A reducer defined within the store that lives under an outside namespace receive both * the active and outside namespace state objects and a payload list as parameters. * * Effects: are pure functions that fire regular/batched dispatches. They are useful for * executing async logic. The context is bound to the anewStore object. Effects receive the * store object and a payload list as parameters. * * Actions: are pure functions that return an action object. They are mainly used for * user defined reducers that have user defined action types. This can be useful for * using with pacakges that follow the standard redux api, such as `react-router-redux`. * Actions receive a payload list as parameters. * * Batch: is a dispatch method for executing mutluple dispatches (reducers) via one dispatch * call. This prevents the need for components to re-render for each dispatch fired. Batch * also includes a done method which is used to mark the completion of a batch. The done method * syncs the anewStore state object with the reduxStore state object and clears the * batch registry. * */ reduxStore.dispatch.reducers = {}; reduxStore.dispatch.effects = {}; reduxStore.dispatch.actions = {}; reduxStore.dispatch.batch = (0, _createBatch2.default)(reduxStore); /** * Transfer redux store dispatch methods. * Avoid referencing for dispatch and batch as their references * will be updated when stores are combined. */ anewStore.dispatch = function (action) { return reduxStore.dispatch(action); }; anewStore.batch = function (batch) { return reduxStore.dispatch.batch(batch); }; anewStore.batch.done = reduxStore.dispatch.batch.done; /** * Trasfer redux store getState methods */ anewStore.select = {}; /** * Populate getState selectors */ var selectorKeys = Object.keys(selectors); var selectorParams = { select: anewStore.select, create: (0, _createAnewSelectorHOC2.default)(anewStore, reduxStore) }; var _loop = function _loop(i, selectorsLen) { var selectorName = selectorKeys[i]; (0, _validateFunctionProperty2.default)(selectorName, name); var selectorCreator = selectors[selectorName]; function selectorWithParams() { if (!selectorParams.core && reduxStore.anew.core) { selectorParams.core = reduxStore.anew.core.getState; } var selector = selectorCreator(selectorParams); var _selector = selector.apply(undefined, arguments), ref = _selector.ref, value = _selector.value; reduxStore.getState[selectorName] = ref; anewStore.select[selectorName] = ref; return value; } reduxStore.getState[selectorName] = selectorWithParams; anewStore.select[selectorName] = selectorWithParams; }; for (var i = 0, selectorsLen = selectorKeys.length; i < selectorsLen; i++) { _loop(i, selectorsLen); } /** * Populate dispatch reducers */ var reducerKeys = Object.keys(reducers); var _loop2 = function _loop2(i, reducersLen) { var reducerName = reducerKeys[i]; (0, _invariant2.default)(takenReducerNames.indexOf(reducerName) === -1, '"' + reducerName + ' is a reserved word. Please choose a different name " ' + ('for "' + reducerName + '" in "' + name + '"')); var reducer = reducers[reducerName]; var reducerType = typeof reducer === 'undefined' ? 'undefined' : _typeof(reducer); var isFunction = reducerType === 'function'; var isObject = reducerType === 'object'; (0, _invariant2.default)(isFunction || isObject, 'Store reducers can be functions or objects ' + ('Recieved "' + reducerType + '" ') + ('for "' + reducerName + '" in "' + name + '"')); if (isFunction) { reduxStore.dispatch.reducers[reducerName] = function () { for (var _len = arguments.length, payload = Array(_len), _key = 0; _key < _len; _key++) { payload[_key] = arguments[_key]; } return reduxStore.dispatch({ type: anewStore.name + ':' + reducerName, payload: payload }); }; reduxStore.dispatch.batch[reducerName] = function () { for (var _len2 = arguments.length, payload = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { payload[_key2] = arguments[_key2]; } var batch = { type: anewStore.name + ':' + reducerName, payload: payload }; reduxStore.anew.getBatches().push(batch); return batch; }; anewStore.dispatch[reducerName] = reduxStore.dispatch.reducers[reducerName]; anewStore.batch[reducerName] = reduxStore.dispatch.batch[reducerName]; } }; for (var i = 0, reducersLen = reducerKeys.length; i < reducersLen; i++) { _loop2(i, reducersLen); } /** * Populate dispatch actions * Referencing anewStore.dispatch so when reduxStore.dispatch changes * during combination */ reduxStore.dispatch.actions = (0, _redux.bindActionCreators)(anewStore.actions, anewStore.dispatch); anewStore.actions = reduxStore.dispatch.actions; /** * Populate dispatch effects */ var effectKeys = Object.keys(effects); var effectParams = { actions: anewStore.actions, batch: anewStore.batch, dispatch: anewStore.dispatch, effects: anewStore.effects, select: anewStore.select }; var _loop3 = function _loop3(i, effectsLen) { var effectName = effectKeys[i]; var effect = effects[effectName]; var effectType = typeof effect === 'undefined' ? 'undefined' : _typeof(effect); (0, _invariant2.default)(effectType === 'function', 'Store effects can only be functions ' + ('Recieved "' + effectType + '" ') + ('for "' + effectName + '" in "' + anewStore.name + '"')); function effectWithParams() { if (!effectParams.persistor && reduxStore.dispatch.persistor) { effectParams.persistor = reduxStore.dispatch.persistor; } if (!effectParams.core && reduxStore.anew.core) { var _reduxStore$anew$core = reduxStore.anew.core, getState = _reduxStore$anew$core.getState, _reduxStore$anew$core2 = _reduxStore$anew$core.dispatch, _reducers = _reduxStore$anew$core2.reducers, _effects = _reduxStore$anew$core2.effects, _actions = _reduxStore$anew$core2.actions, batch = _reduxStore$anew$core2.batch; effectParams.core = { select: getState, dispatch: _reducers, batch: batch, effects: _effects, actions: _actions }; } function effectsBinded() { for (var _len3 = arguments.length, payload = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { payload[_key3] = arguments[_key3]; } return effect.apply(undefined, [effectParams].concat(payload)); } reduxStore.dispatch.effects[effectName] = effectsBinded; anewStore.effects[effectName] = effectsBinded; return effectsBinded.apply(undefined, arguments); } reduxStore.dispatch.effects[effectName] = effectWithParams; anewStore.effects[effectName] = effectWithParams; }; for (var i = 0, effectsLen = effectKeys.length; i < effectsLen; i++) { _loop3(i, effectsLen); } return reduxStore; }