vuex-local
Version:
Local state management within Vuex
211 lines (203 loc) • 7.31 kB
JavaScript
/*!
* 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
*/
;
Object.defineProperty(exports, '__esModule', { value: true });
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;