UNPKG

vuex-local

Version:

Local state management within Vuex

217 lines (208 loc) 7.57 kB
/*! * vuex-local v0.2.0 * https://github.com/ktsn/vuex-local * * @license * Copyright (c) 2016-present katashin * Released under the MIT license * https://github.com/ktsn/vuex-local/blob/master/LICENSE */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.VuexLocal = {}))); }(this, (function (exports) { 'use strict'; var modulePrefix = 'local'; function localKey(key, moduleName) { return [modulePrefix, moduleName, key].join('/'); } function mapKeys(obj, f) { var res = {}; Object.keys(obj).forEach(function (key) { res[f(obj[key], key)] = obj[key]; }); return res; } function mapValues(obj, f) { var res = {}; Object.keys(obj).forEach(function (key) { res[key] = f(obj[key], key); }); return res; } function isObject(value) { return value !== null && typeof value === 'object'; } function warn(message) { console.error('[vuex-local] ' + message); } function assert(condition, message) { if (!condition) { throw new Error('[vuex-local] ' + message); } } function registerLocalModule(store, modulePath, module) { var state = module.state, _a = module.getters, getters = _a === void 0 ? {} : _a, _b = module.actions, actions = _b === void 0 ? {} : _b, _c = module.mutations, mutations = _c === void 0 ? {} : _c; var name = modulePath[modulePath.length - 1]; store.registerModule(modulePath, { state: state, getters: mapLocalKeys(mapLocalGetters(getters, name), name), actions: mapLocalKeys(mapLocalActions(actions, getters, name), name), mutations: mapLocalKeys(mutations, name) }); } function unregisterLocalModule(store, modulePath) { store.unregisterModule(modulePath); } function mapLocalKeys(obj, moduleName) { return mapKeys(obj, function (_, key) { return localKey(key, moduleName); }); } function mapLocalGetters(getters, moduleName) { return mapValues(getters, function (getter) { return function wrappedGetter(state, rootGetters, rootState) { var localGetters = makeLocalGetters(Object.keys(getters), rootGetters, moduleName); return getter(state, localGetters, rootState, rootGetters); }; }); } function mapLocalActions(actions, getters, moduleName) { return mapValues(actions, function (action) { return function wrappedAction(context, payload) { // overwrite commit and dispatch to convert // action and mutation type to prefixed format var commit = context.commit, dispatch = context.dispatch; context.commit = function localCommit(type, payload, options) { if (options === void 0) { options = {}; } if (typeof type === 'object') { options = payload; type = type.type; payload = type; } return commit(options.root ? type : localKey(type, moduleName), payload, options); }; context.dispatch = function localDispatch(type, payload, options) { if (options === void 0) { options = {}; } if (typeof type === 'object') { options = payload; type = type.type; payload = type; } return dispatch(options.root ? type : localKey(type, moduleName), payload, options); }; // expose real getters object as rootGetters var rootGetters = context.getters; context.rootGetters = rootGetters; context.getters = makeLocalGetters(Object.keys(getters), rootGetters, moduleName); // execute original action action(context, payload); }; }); } function makeLocalGetters(getterKeys, getters, moduleName) { var localGetters = {}; getterKeys.forEach(function (key) { Object.defineProperty(localGetters, key, { get: function () { return getters[localKey(key, moduleName)]; } }); }); return localGetters; } function mapLocalModule(vm, modulePath, module) { mapState(vm, module.state, modulePath); var moduleName = modulePath[modulePath.length - 1]; if (module.getters) { mapGetters(vm, module.getters, moduleName); } if (module.actions) { mapActions(vm, module.actions, moduleName); } if (module.mutations) { mapMutations(vm, module.mutations, moduleName); } } function getSubState(state, path) { return path.reduce(function (sub, key) { return sub[key]; }, state); } function mapState(vm, state, path) { Object.keys(state).forEach(function (key) { Object.defineProperty(vm, key, { enumerable: true, configurable: true, get: function () { return getSubState(vm.$store.state, path)[key]; } }); }); } function mapGetters(vm, getters, moduleName) { Object.keys(getters).forEach(function (key) { Object.defineProperty(vm, key, { enumerable: true, configurable: true, get: function () { return vm.$store.getters[localKey(key, moduleName)]; } }); }); } function mapActions(vm, actions, moduleName) { Object.keys(actions).forEach(function (key) { vm[key] = function (payload) { return vm.$store.dispatch(localKey(key, moduleName), payload); }; }); } function mapMutations(vm, mutations, moduleName) { Object.keys(mutations).forEach(function (key) { vm[key] = function (payload) { vm.$store.commit(localKey(key, moduleName), payload); }; }); } function applyMixin(Vue, options) { var _a = options.parentModulePath, parentModulePath = _a === void 0 ? [] : _a; Vue.mixin({ created: function () { if (!this.$options.local) return; assert(this.$store, 'store must be injected'); ensureParent(this.$store, parentModulePath); var localModule = this.$options.local.call(this); var name = localModule.name; assert(typeof name === 'string', 'local module name must be string'); assert(name !== '', 'local module name cannot be empty'); assert(isObject(localModule.state), 'state must be object'); var modulePath = this._localModulePath = parentModulePath.concat(name); registerLocalModule(this.$store, modulePath, localModule); // map the local module to this vm mapLocalModule(this, modulePath, localModule); }, beforeDestroy: function () { if (!this.$options.local) return; unregisterLocalModule(this.$store, this._localModulePath); } }); } function ensureParent(store, parentPath) { var state = store.state; var currentPath = []; parentPath.forEach(function (key) { state = state[key]; currentPath.push(key); if (typeof state === 'undefined') { store.registerModule(currentPath, {}); } }); } var Vue; function install(API, options) { if (options === void 0) { options = {}; } if (Vue) { warn('already installed'); return; } Vue = API; applyMixin(Vue, options); } exports.install = install; Object.defineProperty(exports, '__esModule', { value: true }); })));