vuex-class-modules
Version:
Typescript class decorators for class-style vuex modules.
240 lines (239 loc) • 10.7 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.VuexClassModuleFactory = void 0;
var VuexModule_1 = require("./VuexModule");
var VuexClassModuleFactory = /** @class */ (function () {
function VuexClassModuleFactory(classModule, instance, moduleOptions) {
this.definition = {
state: {},
moduleRefs: {},
getters: {},
mutations: {},
actions: {},
localFunctions: {}
};
this.moduleOptions = moduleOptions;
this.instance = instance;
this.registerOptions = instance.__options;
this.init(classModule);
}
VuexClassModuleFactory.prototype.init = function (classModule) {
// state
for (var _i = 0, _a = Object.keys(this.instance); _i < _a.length; _i++) {
var key = _a[_i];
var val = this.instance[key];
if (key !== "__options" && this.instance.hasOwnProperty(key)) {
if (val instanceof VuexModule_1.VuexModule) {
this.definition.moduleRefs[key] = val;
}
else {
this.definition.state[key] = this.instance[key];
}
}
}
var actionKeys = Object.keys(classModule.__actions || {});
var mutationKeys = Object.keys(classModule.__mutations || {});
var isAction = function (key) { return actionKeys.indexOf(key) !== -1; };
var isMutation = function (key) { return mutationKeys.indexOf(key) !== -1; };
for (var _b = 0, _c = getModulePrototypes(classModule); _b < _c.length; _b++) {
var module_1 = _c[_b];
for (var _d = 0, _e = Object.getOwnPropertyNames(module_1.prototype); _d < _e.length; _d++) {
var key = _e[_d];
var descriptor = Object.getOwnPropertyDescriptor(module_1.prototype, key);
var isGetter = !!descriptor.get;
if (isGetter && !(key in this.definition.getters)) {
this.definition.getters[key] = descriptor.get;
}
if (isAction(key) && !(key in this.definition.actions) && descriptor.value) {
this.definition.actions[key] = module_1.prototype[key];
}
if (isMutation(key) && !(key in this.definition.mutations) && descriptor.value) {
this.definition.mutations[key] = module_1.prototype[key];
}
var isHelperFunction = descriptor.value &&
typeof module_1.prototype[key] === "function" &&
!isAction(key) &&
!isMutation(key) &&
key !== "constructor";
if (isHelperFunction && !(key in this.definition.localFunctions)) {
this.definition.localFunctions[key] = module_1.prototype[key];
}
}
}
};
VuexClassModuleFactory.prototype.registerVuexModule = function () {
var _a;
var _this = this;
var vuexModule = {
state: this.definition.state,
getters: {},
mutations: {},
actions: {},
namespaced: true
};
// getters
mapValues(vuexModule.getters, this.definition.getters, function (getter) {
return function (state, getters) {
var thisObj = _this.buildThisProxy({ state: state, getters: getters });
return getter.call(thisObj);
};
});
// mutations
mapValues(vuexModule.mutations, this.definition.mutations, function (mutation) {
return function (state, payload) {
var thisObj = _this.buildThisProxy({
state: state,
stateSetter: function (stateField, val) {
state[stateField] = val;
}
});
mutation.call(thisObj, payload);
};
});
if (this.moduleOptions.generateMutationSetters) {
var _loop_1 = function (stateKey) {
var mutation = function (state, payload) {
state[stateKey] = payload;
};
vuexModule.mutations[this_1.getMutationSetterName(stateKey)] = mutation;
};
var this_1 = this;
for (var _i = 0, _b = Object.keys(this.definition.state); _i < _b.length; _i++) {
var stateKey = _b[_i];
_loop_1(stateKey);
}
}
// actions
mapValues(vuexModule.actions, this.definition.actions, function (action) {
return function (context, payload) {
var proxyDefinition = __assign(__assign({}, context), { stateSetter: _this.moduleOptions.generateMutationSetters
? function (field, val) {
context.commit(_this.getMutationSetterName(field), val);
}
: undefined });
var thisObj = _this.buildThisProxy(proxyDefinition);
return action.call(thisObj, payload);
};
});
// register module
var _c = this.registerOptions, store = _c.store, name = _c.name;
if (store.state[name]) {
if (VuexModule_1.VuexModule.__useHotUpdate || (typeof module !== "undefined" && module.hot)) {
store.hotUpdate({
modules: (_a = {},
_a[name] = vuexModule,
_a)
});
}
else {
throw Error("[vuex-class-module]: A module with name '" + name + "' already exists.");
}
}
else {
store.registerModule(this.registerOptions.name, vuexModule);
}
};
VuexClassModuleFactory.prototype.buildAccessor = function () {
var _this = this;
var _a = this.registerOptions, store = _a.store, name = _a.name;
var stateSetter = this.moduleOptions.generateMutationSetters
? function (field, val) {
store.commit(name + "/" + _this.getMutationSetterName(field), val);
}
: undefined;
var accessorModule = this.buildThisProxy(__assign(__assign({}, store), { state: store.state[name], stateSetter: stateSetter, useNamespaceKey: true, excludeModuleRefs: true, excludeLocalFunctions: true }));
// watch API
accessorModule.$watch = function (fn, callback, options) {
return store.watch(function (state, getters) {
return fn(_this.buildThisProxy({
state: state[name],
getters: getters,
useNamespaceKey: true
}));
}, callback, options);
};
Object.setPrototypeOf(accessorModule, Object.getPrototypeOf(this.instance));
Object.freeze(accessorModule);
return accessorModule;
};
VuexClassModuleFactory.prototype.buildThisProxy = function (proxyDefinition) {
var obj = {};
if (proxyDefinition.state) {
mapValuesToProperty(obj, this.definition.state, function (key) { return proxyDefinition.state[key]; }, proxyDefinition.stateSetter
? function (key, val) { return proxyDefinition.stateSetter(key, val); }
: function () {
throw Error("[vuex-class-module]: Cannot modify state outside mutations.");
});
}
if (!proxyDefinition.excludeModuleRefs) {
mapValues(obj, this.definition.moduleRefs, function (val) { return val; });
}
var namespaceKey = proxyDefinition.useNamespaceKey ? this.registerOptions.name + "/" : "";
if (proxyDefinition.getters) {
mapValuesToProperty(obj, this.definition.getters, function (key) { return proxyDefinition.getters["" + namespaceKey + key]; });
}
if (proxyDefinition.commit) {
mapValues(obj, this.definition.mutations, function (mutation, key) {
return function (payload) { return proxyDefinition.commit("" + namespaceKey + key, payload); };
});
}
if (proxyDefinition.dispatch) {
mapValues(obj, this.definition.actions, function (action, key) {
return function (payload) { return proxyDefinition.dispatch("" + namespaceKey + key, payload); };
});
}
if (!proxyDefinition.excludeLocalFunctions) {
mapValues(obj, this.definition.localFunctions, function (localFunction) {
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return localFunction.apply(obj, args);
};
});
}
return obj;
};
VuexClassModuleFactory.prototype.getMutationSetterName = function (stateKey) {
return "set__" + stateKey;
};
return VuexClassModuleFactory;
}());
exports.VuexClassModuleFactory = VuexClassModuleFactory;
function mapValues(target, source, mapFunc) {
for (var _i = 0, _a = Object.keys(source); _i < _a.length; _i++) {
var key = _a[_i];
target[key] = mapFunc(source[key], key);
}
}
function mapValuesToProperty(target, source, get, set) {
var _loop_2 = function (key) {
Object.defineProperty(target, key, {
get: function () { return get(key); },
set: set ? function (val) { return set(key, val); } : undefined
});
};
for (var _i = 0, _a = Object.keys(source); _i < _a.length; _i++) {
var key = _a[_i];
_loop_2(key);
}
}
function getModulePrototypes(module) {
var prototypes = [];
for (var prototype = module; prototype && prototype !== VuexModule_1.VuexModule; prototype = Object.getPrototypeOf(prototype)) {
prototypes.push(prototype);
}
return prototypes;
}