UNPKG

yax

Version:

Yet another store using redux. (Inspired by vuex and dva)

160 lines (124 loc) 4.14 kB
import _extends from "@babel/runtime/helpers/extends"; import { createStore, applyMiddleware, compose } from 'redux'; import ModuleCollection from './module/module-collection'; import { isObject, isPromise, getNestedState, assert } from './util'; export default function yax(options, enhancer) { if (options === void 0) { options = {}; } var _actions = {}; var _modules = new ModuleCollection(options); // init root module. // this also recursively registers all sub-modules _installModule([], _modules.root); var middleware = function middleware() { return function (next) { return function (action) { if (isObject(action)) { var type = action.type, payload = action.payload; var entry = _actions[type]; if (entry) { return entry.length > 1 ? Promise.all(entry.map(function (handler) { return handler(payload); })) : entry[0](payload); } } return next(action); }; }; }; var rootMW = applyMiddleware(middleware); var _store = createStore(_modules.makeReducers(), options.state || {}, enhancer ? compose(enhancer, rootMW) : rootMW); function registerModule(path, rawModule) { if (typeof path === 'string') path = [path]; assert(Array.isArray(path), "module path must be a string or an Array."); _modules.register(path, rawModule); _installModule(path, _modules.get(path)); _resetReducers(); } function unregisterModule(path) { if (typeof path === 'string') path = [path]; assert(Array.isArray(path), "module path must be a string or an Array."); _modules.unregister(path); _resetStore(); _store.dispatch({ type: '@@yax/unregister', path: path }); } return _extends({ registerModule: registerModule, unregisterModule: unregisterModule }, _store); /** * Private Methods */ // make localized dispatch, commit and state function _makeLocalContext(namespace, path) { var wrapFn = function wrapFn(type, payload, isRoot) { var action = { type: type, payload: payload }; if (isObject(type) && type.type) { isRoot = payload; action = type; } action.type = isRoot ? action.type : namespace + action.type; // redux dispatch return _store.dispatch(action); }; var local = { dispatch: wrapFn, commit: wrapFn, select: function select(fn) { // redux state var rootState = _store.getState(); var state = getNestedState(rootState, path); return fn ? fn(state, rootState) : state; } }; return local; } function _registerAction(type, handler, local) { var entry = _actions[type] || (_actions[type] = []); entry.push(function wrappedActionHandler(payload) { var res = handler({ dispatch: local.dispatch, commit: local.commit, select: local.select }, payload); if (!isPromise(res)) { res = Promise.resolve(res); } return res; }); } function _installModule(path, module) { var namespace = _modules.getNamespace(path); var local = module.context = _makeLocalContext(namespace, path); module.cleanReducers(); module.forEachReducer(function (reducer, key) { var actionType = namespace + key; module.addReducer(actionType, reducer); }); module.forEachAction(function (action, key) { var actionType = namespace + key; _registerAction(actionType, action, local); }); module.forEachChild(function (child, key) { _installModule(path.concat(key), child); }); } function _resetReducers() { var reducer = _modules.makeReducers(); _store.replaceReducer(reducer); } function _resetStore() { _actions = {}; // init all modules _installModule([], _modules.root); _resetReducers(); } } export { combineReducers, bindActionCreators, applyMiddleware, compose } from 'redux'; export { composeReducers, mapReducers } from './util'; export { mapState, mapActions } from './helpers';