Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

vuex

Package Overview
Dependencies
Maintainers
1
Versions
62
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vuex - npm Package Compare versions

Comparing version 1.0.0-rc.2 to 2.0.0-rc.1

src/helpers.js

835

dist/vuex.js
/*!
* Vuex v1.0.0-rc.2
* Vuex v2.0.0-rc.1
* (c) 2016 Evan You

@@ -12,117 +12,2 @@ * Released under the MIT License.

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
/**
* Merge an array of objects into one.
*
* @param {Array<Object>} arr
* @return {Object}
*/
function mergeObjects(arr) {
return arr.reduce(function (prev, obj) {
Object.keys(obj).forEach(function (key) {
var existing = prev[key];
if (existing) {
// allow multiple mutation objects to contain duplicate
// handlers for the same mutation type
if (Array.isArray(existing)) {
prev[key] = existing.concat(obj[key]);
} else {
prev[key] = [existing].concat(obj[key]);
}
} else {
prev[key] = obj[key];
}
});
return prev;
}, {});
}
/**
* Check whether the given value is Object or not
*
* @param {*} obj
* @return {Boolean}
*/
function isObject(obj) {
return obj !== null && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object';
}
/**
* Get state sub tree by given keys.
*
* @param {Object} state
* @param {Array<String>} nestedKeys
* @return {Object}
*/
function getNestedState(state, nestedKeys) {
return nestedKeys.reduce(function (state, key) {
return state[key];
}, state);
}
/**
* Hacks to get access to Vue internals.
* Maybe we should expose these...
*/
var Watcher = void 0;
function getWatcher(vm) {
if (!Watcher) {
var noop = function noop() {};
var unwatch = vm.$watch(noop, noop);
Watcher = vm._watchers[0].constructor;
unwatch();
}
return Watcher;
}
var Dep = void 0;
function getDep(vm) {
if (!Dep) {
Dep = vm._data.__ob__.dep.constructor;
}
return Dep;
}
var hook = typeof window !== 'undefined' && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;

@@ -144,3 +29,3 @@

function override (Vue) {
function applyMixin (Vue) {
var version = Number(Vue.version.split('.')[0]);

@@ -171,210 +56,142 @@

var options = this.$options;
var store = options.store;
var vuex = options.vuex;
// store injection
if (store) {
this.$store = store;
if (options.store) {
this.$store = options.store;
} else if (options.parent && options.parent.$store) {
this.$store = options.parent.$store;
}
// vuex option handling
if (vuex) {
if (!this.$store) {
console.warn('[vuex] store not injected. make sure to ' + 'provide the store option in your root component.');
}
var state = vuex.state;
var actions = vuex.actions;
var getters = vuex.getters;
// handle deprecated state option
}
}
if (state && !getters) {
console.warn('[vuex] vuex.state option will been deprecated in 1.0. ' + 'Use vuex.getters instead.');
getters = state;
function mapGetters(getters) {
var res = {};
normalizeMap(getters).forEach(function (_ref) {
var key = _ref.key;
var val = _ref.val;
res[key] = function mappedGetter() {
if (!(val in this.$store.getters)) {
console.error("[vuex] unknown getter: " + val);
}
// getters
if (getters) {
options.computed = options.computed || {};
for (var key in getters) {
defineVuexGetter(this, key, getters[key]);
}
}
// actions
if (actions) {
options.methods = options.methods || {};
for (var _key in actions) {
options.methods[_key] = makeBoundAction(this.$store, actions[_key], _key);
}
}
}
}
return this.$store.getters[val];
};
});
return res;
}
/**
* Setter for all getter properties.
*/
function mapActions(actions) {
var res = {};
normalizeMap(actions).forEach(function (_ref2) {
var key = _ref2.key;
var val = _ref2.val;
function setter() {
throw new Error('vuex getter properties are read-only.');
}
res[key] = function mappedAction() {
var _$store;
/**
* Define a Vuex getter on an instance.
*
* @param {Vue} vm
* @param {String} key
* @param {Function} getter
*/
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
function defineVuexGetter(vm, key, getter) {
if (typeof getter !== 'function') {
console.warn('[vuex] Getter bound to key \'vuex.getters.' + key + '\' is not a function.');
} else {
Object.defineProperty(vm, key, {
enumerable: true,
configurable: true,
get: makeComputedGetter(vm.$store, getter),
set: setter
});
}
}
return (_$store = this.$store).dispatch.apply(_$store, [val].concat(args));
};
});
return res;
}
/**
* Make a computed getter, using the same caching mechanism of computed
* properties. In addition, it is cached on the raw getter function using
* the store's unique cache id. This makes the same getter shared
* across all components use the same underlying watcher, and makes
* the getter evaluated only once during every flush.
*
* @param {Store} store
* @param {Function} getter
*/
function normalizeMap(map) {
return Array.isArray(map) ? map.map(function (key) {
return { key: key, val: key };
}) : Object.keys(map).map(function (key) {
return { key: key, val: map[key] };
});
}
function makeComputedGetter(store, getter) {
var id = store._getterCacheId;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
// cached
if (getter[id]) {
return getter[id];
}
var vm = store._vm;
var Watcher = getWatcher(vm);
var Dep = getDep(vm);
var watcher = new Watcher(vm, function (vm) {
return getter(vm.state);
}, null, { lazy: true });
var computedGetter = function computedGetter() {
if (watcher.dirty) {
watcher.evaluate();
}
if (Dep.target) {
watcher.depend();
}
return watcher.value;
};
getter[id] = computedGetter;
return computedGetter;
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
/**
* Make a bound-to-store version of a raw action function.
*
* @param {Store} store
* @param {Function} action
* @param {String} key
*/
function makeBoundAction(store, action, key) {
if (typeof action !== 'function') {
console.warn('[vuex] Action bound to key \'vuex.actions.' + key + '\' is not a function.');
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
return function vuexBoundAction() {
for (var _len = arguments.length, args = Array(_len), _key2 = 0; _key2 < _len; _key2++) {
args[_key2] = arguments[_key2];
}
return action.call.apply(action, [this, store].concat(args));
};
}
// option merging
var merge = Vue.config.optionMergeStrategies.computed;
Vue.config.optionMergeStrategies.vuex = function (toVal, fromVal) {
if (!toVal) return fromVal;
if (!fromVal) return toVal;
return {
getters: merge(toVal.getters, fromVal.getters),
state: merge(toVal.state, fromVal.state),
actions: merge(toVal.actions, fromVal.actions)
};
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}
}();
var Vue = void 0;
var uid = 0;
var Vue = void 0; // bind on install
var Store = function () {
/**
* @param {Object} options
* - {Object} state
* - {Object} actions
* - {Object} mutations
* - {Array} plugins
* - {Boolean} strict
*/
function Store() {
var _this = this;
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var _ref$state = _ref.state;
var state = _ref$state === undefined ? {} : _ref$state;
var _ref$mutations = _ref.mutations;
var mutations = _ref$mutations === undefined ? {} : _ref$mutations;
var _ref$modules = _ref.modules;
var modules = _ref$modules === undefined ? {} : _ref$modules;
var _ref$plugins = _ref.plugins;
var plugins = _ref$plugins === undefined ? [] : _ref$plugins;
var _ref$strict = _ref.strict;
var strict = _ref$strict === undefined ? false : _ref$strict;
var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
classCallCheck(this, Store);
this._getterCacheId = 'vuex_store_' + uid++;
this._dispatching = false;
this._rootMutations = this._mutations = mutations;
this._modules = modules;
if (!Vue) {
throw new Error('[vuex] must call Vue.use(Vuex) before creating a store instance.');
}
if (typeof Promise === 'undefined') {
throw new Error('[vuex] vuex requires a Promise polyfill in this browser.');
}
var _options$state = options.state;
var state = _options$state === undefined ? {} : _options$state;
var _options$modules = options.modules;
var modules = _options$modules === undefined ? {} : _options$modules;
var _options$plugins = options.plugins;
var plugins = _options$plugins === undefined ? [] : _options$plugins;
var _options$strict = options.strict;
var strict = _options$strict === undefined ? false : _options$strict;
// store internal state
this._options = options;
this._committing = false;
this._actions = Object.create(null);
this._mutations = Object.create(null);
this._subscribers = [];
// bind dispatch to self
// bind commit and dispatch to self
var store = this;
var dispatch = this.dispatch;
this.dispatch = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var commit = this.commit;
dispatch.apply(_this, args);
this.dispatch = function boundDispatch(type, payload) {
return dispatch.call(store, type, payload);
};
// use a Vue instance to store the state tree
// suppress warnings just in case the user has added
// some funky global mixins
if (!Vue) {
throw new Error('[vuex] must call Vue.use(Vuex) before creating a store instance.');
}
var silent = Vue.config.silent;
Vue.config.silent = true;
this._vm = new Vue({
data: {
state: state
}
});
Vue.config.silent = silent;
this._setupModuleState(state, modules);
this._setupModuleMutations(modules);
// add extra warnings in strict mode
if (strict) {
this._setupMutationCheck();
}
this.commit = function boundCommit(type, payload) {
return commit.call(store, type, payload);
};
// init state and getters
var getters = extractModuleGetters(options.getters, modules);
initStoreState(this, state, getters);
// apply root module
this.module([], options);
// strict mode
if (strict) enableStrictMode(this);
// apply plugins
devtoolPlugin(this);
plugins.forEach(function (plugin) {
plugins.concat(devtoolPlugin).forEach(function (plugin) {
return plugin(_this);

@@ -384,104 +201,131 @@ });

/**
* Getter for the entire state tree.
* Read only.
*
* @return {Object}
*/
createClass(Store, [{
key: 'replaceState',
/**
* Replace root state.
*
* @param {Object} state
*/
value: function replaceState(state) {
this._dispatching = true;
this._committing = true;
this._vm.state = state;
this._dispatching = false;
this._committing = false;
}
/**
* Dispatch an action.
*
* @param {String} type
*/
}, {
key: 'dispatch',
value: function dispatch(type) {
key: 'module',
value: function module(path, _module, hot) {
var _this2 = this;
for (var _len2 = arguments.length, payload = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
payload[_key2 - 1] = arguments[_key2];
if (typeof path === 'string') path = [path];
if (!Array.isArray(path)) {
throw new Error('[vuex] module path must be a string or an Array.');
}
var silent = false;
var isObjectStyleDispatch = false;
// compatibility for object actions, e.g. FSA
if ((typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object' && type.type && arguments.length === 1) {
isObjectStyleDispatch = true;
payload = type;
if (type.silent) silent = true;
type = type.type;
var isRoot = !path.length;
var state = _module.state;
var actions = _module.actions;
var mutations = _module.mutations;
var modules = _module.modules;
// set state
if (!isRoot && !hot) {
var parentState = getNestedState(this.state, path.slice(0, -1));
if (!parentState) debugger;
var moduleName = path[path.length - 1];
Vue.set(parentState, moduleName, state || {});
}
var handler = this._mutations[type];
var state = this.state;
if (handler) {
this._dispatching = true;
// apply the mutation
if (Array.isArray(handler)) {
handler.forEach(function (h) {
isObjectStyleDispatch ? h(state, payload) : h.apply(undefined, [state].concat(toConsumableArray(payload)));
});
} else {
isObjectStyleDispatch ? handler(state, payload) : handler.apply(undefined, [state].concat(toConsumableArray(payload)));
}
this._dispatching = false;
if (!silent) {
(function () {
var mutation = isObjectStyleDispatch ? payload : { type: type, payload: payload };
_this2._subscribers.forEach(function (sub) {
return sub(mutation, state);
});
})();
}
} else {
console.warn('[vuex] Unknown mutation: ' + type);
if (mutations) {
Object.keys(mutations).forEach(function (key) {
_this2.mutation(key, mutations[key], path);
});
}
if (actions) {
Object.keys(actions).forEach(function (key) {
_this2.action(key, actions[key], path);
});
}
if (modules) {
Object.keys(modules).forEach(function (key) {
_this2.module(path.concat(key), modules[key], hot);
});
}
}
}, {
key: 'mutation',
value: function mutation(type, handler) {
var path = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];
/**
* Watch state changes on the store.
* Same API as Vue's $watch, except when watching a function,
* the function gets the state as the first argument.
*
* @param {Function} fn
* @param {Function} cb
* @param {Object} [options]
*/
var entry = this._mutations[type] || (this._mutations[type] = []);
var store = this;
entry.push(function wrappedMutationHandler(payload) {
handler(getNestedState(store.state, path), payload);
});
}
}, {
key: 'action',
value: function action(type, handler) {
var path = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];
var entry = this._actions[type] || (this._actions[type] = []);
var store = this;
var dispatch = this.dispatch;
var commit = this.commit;
entry.push(function wrappedActionHandler(payload, cb) {
var res = handler({
dispatch: dispatch,
commit: commit,
state: getNestedState(store.state, path)
}, payload, cb);
if (!isPromise(res)) {
res = Promise.resolve(res);
}
return res.catch(function (err) {
console.error('[vuex] error in Promise returned from action "' + type + '":');
console.error(err);
});
});
}
}, {
key: 'watch',
value: function watch(fn, cb, options) {
key: 'commit',
value: function commit(type, payload) {
var _this3 = this;
if (typeof fn !== 'function') {
console.error('Vuex store.watch only accepts function.');
// check object-style commit
var mutation = void 0;
if (isObject(type) && type.type) {
payload = mutation = type;
type = type.type;
} else {
mutation = { type: type, payload: payload };
}
var entry = this._mutations[type];
if (!entry) {
console.error('[vuex] unknown mutation type: ' + type);
return;
}
return this._vm.$watch(function () {
return fn(_this3.state);
}, cb, options);
this._committing = true;
entry.forEach(function commitIterator(handler) {
handler(payload);
});
this._committing = false;
if (!payload || !payload.silent) {
this._subscribers.forEach(function (sub) {
return sub(mutation, _this3.state);
});
}
}
/**
* Subscribe to state changes. Fires after every mutation.
*/
}, {
key: 'dispatch',
value: function dispatch(type, payload) {
var entry = this._actions[type];
if (!entry) {
debugger;
console.error('[vuex] unknown action type: ' + type);
return;
}
return entry.length > 1 ? Promise.all(entry.map(function (handler) {
return handler(payload);
})) : entry[0](payload);
}
}, {
key: 'subscribe',

@@ -500,136 +344,44 @@ value: function subscribe(fn) {

}
/**
* Hot update mutations & modules.
*
* @param {Object} options
* - {Object} [mutations]
* - {Object} [modules]
*/
}, {
key: 'hotUpdate',
value: function hotUpdate() {
var _ref2 = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var mutations = _ref2.mutations;
var modules = _ref2.modules;
this._rootMutations = this._mutations = mutations || this._rootMutations;
this._setupModuleMutations(modules || this._modules);
}
/**
* Attach sub state tree of each module to the root tree.
*
* @param {Object} state
* @param {Object} modules
*/
}, {
key: '_setupModuleState',
value: function _setupModuleState(state, modules) {
value: function hotUpdate(newOptions) {
var _this4 = this;
if (!isObject(modules)) return;
Object.keys(modules).forEach(function (key) {
var module = modules[key];
// set this module's state
Vue.set(state, key, module.state || {});
// retrieve nested modules
_this4._setupModuleState(state[key], module.modules);
});
}
/**
* Bind mutations for each module to its sub tree and
* merge them all into one final mutations map.
*
* @param {Object} updatedModules
*/
}, {
key: '_setupModuleMutations',
value: function _setupModuleMutations(updatedModules) {
var modules = this._modules;
Object.keys(updatedModules).forEach(function (key) {
modules[key] = updatedModules[key];
});
var updatedMutations = this._createModuleMutations(modules, []);
this._mutations = mergeObjects([this._rootMutations].concat(toConsumableArray(updatedMutations)));
}
/**
* Helper method for _setupModuleMutations.
* The method retrieve nested sub modules and
* bind each mutations to its sub tree recursively.
*
* @param {Object} modules
* @param {Array<String>} nestedKeys
* @return {Array<Object>}
*/
}, {
key: '_createModuleMutations',
value: function _createModuleMutations(modules, nestedKeys) {
var _this5 = this;
if (!isObject(modules)) return [];
return Object.keys(modules).map(function (key) {
var module = modules[key];
var newNestedKeys = nestedKeys.concat(key);
// retrieve nested modules
var nestedMutations = _this5._createModuleMutations(module.modules, newNestedKeys);
if (!module || !module.mutations) {
return mergeObjects(nestedMutations);
this._actions = Object.create(null);
this._mutations = Object.create(null);
var options = this._options;
if (newOptions.actions) {
options.actions = newOptions.actions;
}
if (newOptions.mutations) {
options.mutations = newOptions.mutations;
}
if (newOptions.modules) {
for (var key in newOptions.modules) {
options.modules[key] = newOptions.modules[key];
}
}
this.module([], options, true);
// bind mutations to sub state tree
var mutations = {};
Object.keys(module.mutations).forEach(function (name) {
var original = module.mutations[name];
mutations[name] = function (state) {
for (var _len3 = arguments.length, args = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
args[_key3 - 1] = arguments[_key3];
}
original.apply(undefined, [getNestedState(state, newNestedKeys)].concat(args));
};
});
// merge mutations of this module and nested modules
return mergeObjects([mutations].concat(toConsumableArray(nestedMutations)));
});
// update getters
var getters = extractModuleGetters(newOptions.getters, newOptions.modules);
if (Object.keys(getters).length) {
(function () {
var oldVm = _this4._vm;
initStoreState(_this4, _this4.state, getters);
if (_this4.strict) {
enableStrictMode(_this4);
}
// dispatch changes in all subscribed watchers
// to force getter re-evaluation.
_this4._committing = true;
oldVm.state = null;
_this4._committing = false;
Vue.nextTick(function () {
return oldVm.$destroy();
});
})();
}
}
/**
* Setup mutation check: if the vuex instance's state is mutated
* outside of a mutation handler, we throw en error. This effectively
* enforces all mutations to the state to be trackable and hot-reloadble.
* However, this comes at a run time cost since we are doing a deep
* watch on the entire state tree, so it is only enalbed with the
* strict option is set to true.
*/
}, {
key: '_setupMutationCheck',
value: function _setupMutationCheck() {
var _this6 = this;
var Watcher = getWatcher(this._vm);
/* eslint-disable no-new */
new Watcher(this._vm, 'state', function () {
if (!_this6._dispatching) {
throw new Error('[vuex] Do not mutate vuex store state outside mutation handlers.');
}
}, { deep: true, sync: true });
/* eslint-enable no-new */
}
}, {
key: 'state',

@@ -646,9 +398,86 @@ get: function get() {

function initStoreState(store, state, getters) {
// bind getters
store.getters = {};
var computed = {};
Object.keys(getters).forEach(function (key) {
var fn = getters[key];
// use computed to leverage its lazy-caching mechanism
computed[key] = function () {
return fn(store._vm.state);
};
Object.defineProperty(store.getters, key, {
get: function get() {
return store._vm[key];
}
});
});
// use a Vue instance to store the state tree
// suppress warnings just in case the user has added
// some funky global mixins
var silent = Vue.config.silent;
Vue.config.silent = true;
store._vm = new Vue({
data: { state: state },
computed: computed
});
Vue.config.silent = silent;
}
function extractModuleGetters() {
var getters = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
var modules = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var path = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];
if (!modules) return getters;
Object.keys(modules).forEach(function (key) {
var module = modules[key];
var modulePath = path.concat(key);
if (module.getters) {
Object.keys(module.getters).forEach(function (getterKey) {
var rawGetter = module.getters[getterKey];
if (getters[getterKey]) {
console.error('[vuex] duplicate getter key: ' + getterKey);
return;
}
getters[getterKey] = function wrappedGetter(state) {
return rawGetter(getNestedState(state, modulePath));
};
});
}
extractModuleGetters(getters, module.modules, modulePath);
});
return getters;
}
function enableStrictMode(store) {
store._vm.$watch('state', function () {
if (!store._committing) {
throw new Error('[vuex] Do not mutate vuex store state outside mutation handlers.');
}
}, { deep: true, sync: true });
}
function isObject(obj) {
return obj !== null && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object';
}
function isPromise(val) {
return val && typeof val.then === 'function';
}
function getNestedState(state, path) {
return path.reduce(function (state, key) {
return state[key];
}, state);
}
function install(_Vue) {
if (Vue) {
console.warn('[vuex] already installed. Vue.use(Vuex) should be called only once.');
console.error('[vuex] already installed. Vue.use(Vuex) should be called only once.');
return;
}
Vue = _Vue;
override(Vue);
applyMixin(Vue);
}

@@ -663,3 +492,5 @@

Store: Store,
install: install
install: install,
mapGetters: mapGetters,
mapActions: mapActions
};

@@ -666,0 +497,0 @@

/*!
* Vuex v1.0.0-rc.2
* Vuex v2.0.0-rc.1
* (c) 2016 Evan You
* Released under the MIT License.
*/
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Vuex=e()}(this,function(){"use strict";function t(t){return t.reduce(function(t,e){return Object.keys(e).forEach(function(n){var o=t[n];o?Array.isArray(o)?t[n]=o.concat(e[n]):t[n]=[o].concat(e[n]):t[n]=e[n]}),t},{})}function e(t){return null!==t&&"object"===("undefined"==typeof t?"undefined":s(t))}function n(t,e){return e.reduce(function(t,e){return t[e]},t)}function o(t){if(!d){var e=function(){},n=t.$watch(e,e);d=t._watchers[0].constructor,n()}return d}function i(t){return v||(v=t._data.__ob__.dep.constructor),v}function r(t){h&&(h.emit("vuex:init",t),h.on("vuex:travel-to-state",function(e){t.replaceState(e)}),t.subscribe(function(t,e){h.emit("vuex:mutation",t,e)}))}function u(t){function e(){var t=this.$options,e=t.store,n=t.vuex;if(e?this.$store=e:t.parent&&t.parent.$store&&(this.$store=t.parent.$store),n){this.$store||console.warn("[vuex] store not injected. make sure to provide the store option in your root component.");var o=n.state,i=n.actions,u=n.getters;if(o&&!u&&(console.warn("[vuex] vuex.state option will been deprecated in 1.0. Use vuex.getters instead."),u=o),u){t.computed=t.computed||{};for(var s in u)r(this,s,u[s])}if(i){t.methods=t.methods||{};for(var c in i)t.methods[c]=a(this.$store,i[c],c)}}}function n(){throw new Error("vuex getter properties are read-only.")}function r(t,e,o){"function"!=typeof o?console.warn("[vuex] Getter bound to key 'vuex.getters."+e+"' is not a function."):Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:u(t.$store,o),set:n})}function u(t,e){var n=t._getterCacheId;if(e[n])return e[n];var r=t._vm,u=o(r),a=i(r),s=new u(r,function(t){return e(t.state)},null,{lazy:!0}),c=function(){return s.dirty&&s.evaluate(),a.target&&s.depend(),s.value};return e[n]=c,c}function a(t,e,n){return"function"!=typeof e&&console.warn("[vuex] Action bound to key 'vuex.actions."+n+"' is not a function."),function(){for(var n=arguments.length,o=Array(n),i=0;i<n;i++)o[i]=arguments[i];return e.call.apply(e,[this,t].concat(o))}}var s=Number(t.version.split(".")[0]);if(s>=2){var c=t.config._lifecycleHooks.indexOf("init")>-1;t.mixin(c?{init:e}:{beforeCreate:e})}else!function(){var n=t.prototype._init;t.prototype._init=function(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];t.init=t.init?[e].concat(t.init):e,n.call(this,t)}}();var f=t.config.optionMergeStrategies.computed;t.config.optionMergeStrategies.vuex=function(t,e){return t?e?{getters:f(t.getters,e.getters),state:f(t.state,e.state),actions:f(t.actions,e.actions)}:t:e}}function a(t){return p?void console.warn("[vuex] already installed. Vue.use(Vuex) should be called only once."):(p=t,void u(p))}var s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},c=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},f=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),l=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e<t.length;e++)n[e]=t[e];return n}return Array.from(t)},d=void 0,v=void 0,h="undefined"!=typeof window&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,p=void 0,y=0,_=function(){function i(){var t=this,e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],n=e.state,o=void 0===n?{}:n,u=e.mutations,a=void 0===u?{}:u,s=e.modules,f=void 0===s?{}:s,l=e.plugins,d=void 0===l?[]:l,v=e.strict,h=void 0!==v&&v;c(this,i),this._getterCacheId="vuex_store_"+y++,this._dispatching=!1,this._rootMutations=this._mutations=a,this._modules=f,this._subscribers=[];var _=this.dispatch;if(this.dispatch=function(){for(var e=arguments.length,n=Array(e),o=0;o<e;o++)n[o]=arguments[o];_.apply(t,n)},!p)throw new Error("[vuex] must call Vue.use(Vuex) before creating a store instance.");var m=p.config.silent;p.config.silent=!0,this._vm=new p({data:{state:o}}),p.config.silent=m,this._setupModuleState(o,f),this._setupModuleMutations(f),h&&this._setupMutationCheck(),r(this),d.forEach(function(e){return e(t)})}return f(i,[{key:"replaceState",value:function(t){this._dispatching=!0,this._vm.state=t,this._dispatching=!1}},{key:"dispatch",value:function(t){for(var e=this,n=arguments.length,o=Array(n>1?n-1:0),i=1;i<n;i++)o[i-1]=arguments[i];var r=!1,u=!1;"object"===("undefined"==typeof t?"undefined":s(t))&&t.type&&1===arguments.length&&(u=!0,o=t,t.silent&&(r=!0),t=t.type);var a=this._mutations[t],c=this.state;a?(this._dispatching=!0,Array.isArray(a)?a.forEach(function(t){u?t(c,o):t.apply(void 0,[c].concat(l(o)))}):u?a(c,o):a.apply(void 0,[c].concat(l(o))),this._dispatching=!1,r||!function(){var n=u?o:{type:t,payload:o};e._subscribers.forEach(function(t){return t(n,c)})}()):console.warn("[vuex] Unknown mutation: "+t)}},{key:"watch",value:function(t,e,n){var o=this;return"function"!=typeof t?void console.error("Vuex store.watch only accepts function."):this._vm.$watch(function(){return t(o.state)},e,n)}},{key:"subscribe",value:function(t){var e=this._subscribers;return e.indexOf(t)<0&&e.push(t),function(){var n=e.indexOf(t);n>-1&&e.splice(n,1)}}},{key:"hotUpdate",value:function(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],e=t.mutations,n=t.modules;this._rootMutations=this._mutations=e||this._rootMutations,this._setupModuleMutations(n||this._modules)}},{key:"_setupModuleState",value:function(t,n){var o=this;e(n)&&Object.keys(n).forEach(function(e){var i=n[e];p.set(t,e,i.state||{}),o._setupModuleState(t[e],i.modules)})}},{key:"_setupModuleMutations",value:function(e){var n=this._modules;Object.keys(e).forEach(function(t){n[t]=e[t]});var o=this._createModuleMutations(n,[]);this._mutations=t([this._rootMutations].concat(l(o)))}},{key:"_createModuleMutations",value:function(o,i){var r=this;return e(o)?Object.keys(o).map(function(e){var u=o[e],a=i.concat(e),s=r._createModuleMutations(u.modules,a);if(!u||!u.mutations)return t(s);var c={};return Object.keys(u.mutations).forEach(function(t){var e=u.mutations[t];c[t]=function(t){for(var o=arguments.length,i=Array(o>1?o-1:0),r=1;r<o;r++)i[r-1]=arguments[r];e.apply(void 0,[n(t,a)].concat(i))}}),t([c].concat(l(s)))}):[]}},{key:"_setupMutationCheck",value:function(){var t=this,e=o(this._vm);new e(this._vm,"state",function(){if(!t._dispatching)throw new Error("[vuex] Do not mutate vuex store state outside mutation handlers.")},{deep:!0,sync:!0})}},{key:"state",get:function(){return this._vm.state},set:function(t){throw new Error("[vuex] Use store.replaceState() to explicit replace store state.")}}]),i}();"undefined"!=typeof window&&window.Vue&&a(window.Vue);var m={Store:_,install:a};return m});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Vuex=e()}(this,function(){"use strict";function t(t){v&&(v.emit("vuex:init",t),v.on("vuex:travel-to-state",function(e){t.replaceState(e)}),t.subscribe(function(t,e){v.emit("vuex:mutation",t,e)}))}function e(t){function e(){var t=this.$options;t.store?this.$store=t.store:t.parent&&t.parent.$store&&(this.$store=t.parent.$store)}var n=Number(t.version.split(".")[0]);if(n>=2){var o=t.config._lifecycleHooks.indexOf("init")>-1;t.mixin(o?{init:e}:{beforeCreate:e})}else!function(){var n=t.prototype._init;t.prototype._init=function(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];t.init=t.init?[e].concat(t.init):e,n.call(this,t)}}()}function n(t){var e={};return i(t).forEach(function(t){var n=t.key,o=t.val;e[n]=function(){return o in this.$store.getters||console.error("[vuex] unknown getter: "+o),this.$store.getters[o]}}),e}function o(t){var e={};return i(t).forEach(function(t){var n=t.key,o=t.val;e[n]=function(){for(var t,e=arguments.length,n=Array(e),i=0;i<e;i++)n[i]=arguments[i];return(t=this.$store).dispatch.apply(t,[o].concat(n))}}),e}function i(t){return Array.isArray(t)?t.map(function(t){return{key:t,val:t}}):Object.keys(t).map(function(e){return{key:e,val:t[e]}})}function r(t,e,n){t.getters={};var o={};Object.keys(n).forEach(function(e){var i=n[e];o[e]=function(){return i(t._vm.state)},Object.defineProperty(t.getters,e,{get:function(){return t._vm[e]}})});var i=y.config.silent;y.config.silent=!0,t._vm=new y({data:{state:e},computed:o}),y.config.silent=i}function s(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],e=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],n=arguments.length<=2||void 0===arguments[2]?[]:arguments[2];return e?(Object.keys(e).forEach(function(o){var i=e[o],r=n.concat(o);i.getters&&Object.keys(i.getters).forEach(function(e){var n=i.getters[e];return t[e]?void console.error("[vuex] duplicate getter key: "+e):void(t[e]=function(t){return n(f(t,r))})}),s(t,i.modules,r)}),t):t}function u(t){t._vm.$watch("state",function(){if(!t._committing)throw new Error("[vuex] Do not mutate vuex store state outside mutation handlers.")},{deep:!0,sync:!0})}function c(t){return null!==t&&"object"===("undefined"==typeof t?"undefined":h(t))}function a(t){return t&&"function"==typeof t.then}function f(t,e){return e.reduce(function(t,e){return t[e]},t)}function l(t){return y?void console.error("[vuex] already installed. Vue.use(Vuex) should be called only once."):(y=t,void e(y))}var v="undefined"!=typeof window&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},m=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},d=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),y=void 0,p=function(){function e(){var n=this,o=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];if(m(this,e),!y)throw new Error("[vuex] must call Vue.use(Vuex) before creating a store instance.");if("undefined"==typeof Promise)throw new Error("[vuex] vuex requires a Promise polyfill in this browser.");var i=o.state,c=void 0===i?{}:i,a=o.modules,f=void 0===a?{}:a,l=o.plugins,v=void 0===l?[]:l,h=o.strict,d=void 0!==h&&h;this._options=o,this._committing=!1,this._actions=Object.create(null),this._mutations=Object.create(null),this._subscribers=[];var p=this,g=this.dispatch,b=this.commit;this.dispatch=function(t,e){return g.call(p,t,e)},this.commit=function(t,e){return b.call(p,t,e)};var _=s(o.getters,f);r(this,c,_),this.module([],o),d&&u(this),v.concat(t).forEach(function(t){return t(n)})}return d(e,[{key:"replaceState",value:function(t){this._committing=!0,this._vm.state=t,this._committing=!1}},{key:"module",value:function(t,e,n){var o=this;if("string"==typeof t&&(t=[t]),!Array.isArray(t))throw new Error("[vuex] module path must be a string or an Array.");var i=!t.length,r=e.state,s=e.actions,u=e.mutations,c=e.modules;if(!i&&!n){var a=f(this.state,t.slice(0,-1)),l=t[t.length-1];y.set(a,l,r||{})}u&&Object.keys(u).forEach(function(e){o.mutation(e,u[e],t)}),s&&Object.keys(s).forEach(function(e){o.action(e,s[e],t)}),c&&Object.keys(c).forEach(function(e){o.module(t.concat(e),c[e],n)})}},{key:"mutation",value:function(t,e){var n=arguments.length<=2||void 0===arguments[2]?[]:arguments[2],o=this._mutations[t]||(this._mutations[t]=[]),i=this;o.push(function(t){e(f(i.state,n),t)})}},{key:"action",value:function(t,e){var n=arguments.length<=2||void 0===arguments[2]?[]:arguments[2],o=this._actions[t]||(this._actions[t]=[]),i=this,r=this.dispatch,s=this.commit;o.push(function(o,u){var c=e({dispatch:r,commit:s,state:f(i.state,n)},o,u);return a(c)||(c=Promise.resolve(c)),c["catch"](function(e){console.error('[vuex] error in Promise returned from action "'+t+'":'),console.error(e)})})}},{key:"commit",value:function(t,e){var n=this,o=void 0;c(t)&&t.type?(e=o=t,t=t.type):o={type:t,payload:e};var i=this._mutations[t];return i?(this._committing=!0,i.forEach(function(t){t(e)}),this._committing=!1,void(e&&e.silent||this._subscribers.forEach(function(t){return t(o,n.state)}))):void console.error("[vuex] unknown mutation type: "+t)}},{key:"dispatch",value:function(t,e){var n=this._actions[t];return n?n.length>1?Promise.all(n.map(function(t){return t(e)})):n[0](e):void console.error("[vuex] unknown action type: "+t)}},{key:"subscribe",value:function(t){var e=this._subscribers;return e.indexOf(t)<0&&e.push(t),function(){var n=e.indexOf(t);n>-1&&e.splice(n,1)}}},{key:"hotUpdate",value:function(t){var e=this;this._actions=Object.create(null),this._mutations=Object.create(null);var n=this._options;if(t.actions&&(n.actions=t.actions),t.mutations&&(n.mutations=t.mutations),t.modules)for(var o in t.modules)n.modules[o]=t.modules[o];this.module([],n,!0);var i=s(t.getters,t.modules);Object.keys(i).length&&!function(){var t=e._vm;r(e,e.state,i),e.strict&&u(e),e._committing=!0,t.state=null,e._committing=!1,y.nextTick(function(){return t.$destroy()})}()}},{key:"state",get:function(){return this._vm.state},set:function(t){throw new Error("[vuex] Use store.replaceState() to explicit replace store state.")}}]),e}();"undefined"!=typeof window&&window.Vue&&l(window.Vue);var g={Store:p,install:l,mapGetters:n,mapActions:o};return g});
{
"name": "vuex",
"version": "1.0.0-rc.2",
"version": "2.0.0-rc.1",
"description": "state management for Vue.js",

@@ -19,3 +19,3 @@ "main": "dist/vuex.js",

"build-examples": "BABEL_ENV=development webpack --config examples/webpack.build-all.config.js",
"unit": "BABEL_ENV=development mocha test/unit/test.js --compilers js:babel-core/register",
"unit": "BABEL_ENV=development mocha test/unit/test.js --compilers js:babel-core/register 2>/dev/null",
"pree2e": "npm run build-examples",

@@ -22,0 +22,0 @@ "e2e": "casperjs test --concise ./test/e2e",

@@ -1,42 +0,9 @@

import {
mergeObjects, isObject,
getNestedState, getWatcher
} from './util'
import devtoolPlugin from './plugins/devtool'
import override from './override'
import applyMixin from './mixin'
import { mapGetters, mapActions } from './helpers'
let Vue
let uid = 0
let Vue // bind on install
class Store {
/**
* @param {Object} options
* - {Object} state
* - {Object} actions
* - {Object} mutations
* - {Array} plugins
* - {Boolean} strict
*/
constructor ({
state = {},
mutations = {},
modules = {},
plugins = [],
strict = false
} = {}) {
this._getterCacheId = 'vuex_store_' + uid++
this._dispatching = false
this._rootMutations = this._mutations = mutations
this._modules = modules
this._subscribers = []
// bind dispatch to self
const dispatch = this.dispatch
this.dispatch = (...args) => {
dispatch.apply(this, args)
}
// use a Vue instance to store the state tree
// suppress warnings just in case the user has added
// some funky global mixins
constructor (options = {}) {
if (!Vue) {

@@ -47,28 +14,47 @@ throw new Error(

}
const silent = Vue.config.silent
Vue.config.silent = true
this._vm = new Vue({
data: {
state
}
})
Vue.config.silent = silent
this._setupModuleState(state, modules)
this._setupModuleMutations(modules)
// add extra warnings in strict mode
if (strict) {
this._setupMutationCheck()
if (typeof Promise === 'undefined') {
throw new Error(
'[vuex] vuex requires a Promise polyfill in this browser.'
)
}
const {
state = {},
modules = {},
plugins = [],
strict = false
} = options
// store internal state
this._options = options
this._committing = false
this._actions = Object.create(null)
this._mutations = Object.create(null)
this._subscribers = []
// bind commit and dispatch to self
const store = this
const { dispatch, commit } = this
this.dispatch = function boundDispatch (type, payload) {
return dispatch.call(store, type, payload)
}
this.commit = function boundCommit (type, payload) {
return commit.call(store, type, payload)
}
// init state and getters
const getters = extractModuleGetters(options.getters, modules)
initStoreState(this, state, getters)
// apply root module
this.module([], options)
// strict mode
if (strict) enableStrictMode(this)
// apply plugins
devtoolPlugin(this)
plugins.forEach(plugin => plugin(this))
plugins.concat(devtoolPlugin).forEach(plugin => plugin(this))
}
/**
* Getter for the entire state tree.
* Read only.
*
* @return {Object}
*/
get state () {

@@ -82,80 +68,113 @@ return this._vm.state

/**
* Replace root state.
*
* @param {Object} state
*/
replaceState (state) {
this._dispatching = true
this._committing = true
this._vm.state = state
this._dispatching = false
this._committing = false
}
/**
* Dispatch an action.
*
* @param {String} type
*/
module (path, module, hot) {
if (typeof path === 'string') path = [path]
if (!Array.isArray(path)) {
throw new Error('[vuex] module path must be a string or an Array.')
}
dispatch (type, ...payload) {
let silent = false
let isObjectStyleDispatch = false
// compatibility for object actions, e.g. FSA
if (typeof type === 'object' && type.type && arguments.length === 1) {
isObjectStyleDispatch = true
payload = type
if (type.silent) silent = true
type = type.type
const isRoot = !path.length
const {
state,
actions,
mutations,
modules
} = module
// set state
if (!isRoot && !hot) {
const parentState = getNestedState(this.state, path.slice(0, -1))
if (!parentState) debugger
const moduleName = path[path.length - 1]
Vue.set(parentState, moduleName, state || {})
}
const handler = this._mutations[type]
const state = this.state
if (handler) {
this._dispatching = true
// apply the mutation
if (Array.isArray(handler)) {
handler.forEach(h => {
isObjectStyleDispatch
? h(state, payload)
: h(state, ...payload)
})
} else {
isObjectStyleDispatch
? handler(state, payload)
: handler(state, ...payload)
if (mutations) {
Object.keys(mutations).forEach(key => {
this.mutation(key, mutations[key], path)
})
}
if (actions) {
Object.keys(actions).forEach(key => {
this.action(key, actions[key], path)
})
}
if (modules) {
Object.keys(modules).forEach(key => {
this.module(path.concat(key), modules[key], hot)
})
}
}
mutation (type, handler, path = []) {
const entry = this._mutations[type] || (this._mutations[type] = [])
const store = this
entry.push(function wrappedMutationHandler (payload) {
handler(getNestedState(store.state, path), payload)
})
}
action (type, handler, path = []) {
const entry = this._actions[type] || (this._actions[type] = [])
const store = this
const { dispatch, commit } = this
entry.push(function wrappedActionHandler (payload, cb) {
let res = handler({
dispatch,
commit,
state: getNestedState(store.state, path)
}, payload, cb)
if (!isPromise(res)) {
res = Promise.resolve(res)
}
this._dispatching = false
if (!silent) {
const mutation = isObjectStyleDispatch
? payload
: { type, payload }
this._subscribers.forEach(sub => sub(mutation, state))
}
return res.catch(err => {
console.error(`[vuex] error in Promise returned from action "${type}":`)
console.error(err)
})
})
}
commit (type, payload) {
// check object-style commit
let mutation
if (isObject(type) && type.type) {
payload = mutation = type
type = type.type
} else {
console.warn(`[vuex] Unknown mutation: ${type}`)
mutation = { type, payload }
}
const entry = this._mutations[type]
if (!entry) {
console.error(`[vuex] unknown mutation type: ${type}`)
return
}
this._committing = true
entry.forEach(function commitIterator (handler) {
handler(payload)
})
this._committing = false
if (!payload || !payload.silent) {
this._subscribers.forEach(sub => sub(mutation, this.state))
}
}
/**
* Watch state changes on the store.
* Same API as Vue's $watch, except when watching a function,
* the function gets the state as the first argument.
*
* @param {Function} fn
* @param {Function} cb
* @param {Object} [options]
*/
watch (fn, cb, options) {
if (typeof fn !== 'function') {
console.error('Vuex store.watch only accepts function.')
dispatch (type, payload) {
const entry = this._actions[type]
if (!entry) {
debugger
console.error(`[vuex] unknown action type: ${type}`)
return
}
return this._vm.$watch(() => fn(this.state), cb, options)
return entry.length > 1
? Promise.all(entry.map(handler => handler(payload)))
: entry[0](payload)
}
/**
* Subscribe to state changes. Fires after every mutation.
*/
subscribe (fn) {

@@ -174,119 +193,109 @@ const subs = this._subscribers

/**
* Hot update mutations & modules.
*
* @param {Object} options
* - {Object} [mutations]
* - {Object} [modules]
*/
hotUpdate (newOptions) {
this._actions = Object.create(null)
this._mutations = Object.create(null)
const options = this._options
if (newOptions.actions) {
options.actions = newOptions.actions
}
if (newOptions.mutations) {
options.mutations = newOptions.mutations
}
if (newOptions.modules) {
for (const key in newOptions.modules) {
options.modules[key] = newOptions.modules[key]
}
}
this.module([], options, true)
hotUpdate ({ mutations, modules } = {}) {
this._rootMutations = this._mutations = mutations || this._rootMutations
this._setupModuleMutations(modules || this._modules)
// update getters
const getters = extractModuleGetters(newOptions.getters, newOptions.modules)
if (Object.keys(getters).length) {
const oldVm = this._vm
initStoreState(this, this.state, getters)
if (this.strict) {
enableStrictMode(this)
}
// dispatch changes in all subscribed watchers
// to force getter re-evaluation.
this._committing = true
oldVm.state = null
this._committing = false
Vue.nextTick(() => oldVm.$destroy())
}
}
}
/**
* Attach sub state tree of each module to the root tree.
*
* @param {Object} state
* @param {Object} modules
*/
_setupModuleState (state, modules) {
if (!isObject(modules)) return
Object.keys(modules).forEach(key => {
const module = modules[key]
// set this module's state
Vue.set(state, key, module.state || {})
// retrieve nested modules
this._setupModuleState(state[key], module.modules)
function initStoreState (store, state, getters) {
// bind getters
store.getters = {}
const computed = {}
Object.keys(getters).forEach(key => {
const fn = getters[key]
// use computed to leverage its lazy-caching mechanism
computed[key] = () => fn(store._vm.state)
Object.defineProperty(store.getters, key, {
get: () => store._vm[key]
})
}
})
/**
* Bind mutations for each module to its sub tree and
* merge them all into one final mutations map.
*
* @param {Object} updatedModules
*/
// use a Vue instance to store the state tree
// suppress warnings just in case the user has added
// some funky global mixins
const silent = Vue.config.silent
Vue.config.silent = true
store._vm = new Vue({
data: { state },
computed
})
Vue.config.silent = silent
}
_setupModuleMutations (updatedModules) {
const modules = this._modules
Object.keys(updatedModules).forEach(key => {
modules[key] = updatedModules[key]
})
const updatedMutations = this._createModuleMutations(modules, [])
this._mutations = mergeObjects([this._rootMutations, ...updatedMutations])
}
/**
* Helper method for _setupModuleMutations.
* The method retrieve nested sub modules and
* bind each mutations to its sub tree recursively.
*
* @param {Object} modules
* @param {Array<String>} nestedKeys
* @return {Array<Object>}
*/
_createModuleMutations (modules, nestedKeys) {
if (!isObject(modules)) return []
return Object.keys(modules).map(key => {
const module = modules[key]
const newNestedKeys = nestedKeys.concat(key)
// retrieve nested modules
const nestedMutations = this._createModuleMutations(module.modules, newNestedKeys)
if (!module || !module.mutations) {
return mergeObjects(nestedMutations)
}
// bind mutations to sub state tree
const mutations = {}
Object.keys(module.mutations).forEach(name => {
const original = module.mutations[name]
mutations[name] = (state, ...args) => {
original(getNestedState(state, newNestedKeys), ...args)
function extractModuleGetters (getters = {}, modules = {}, path = []) {
if (!modules) return getters
Object.keys(modules).forEach(key => {
const module = modules[key]
const modulePath = path.concat(key)
if (module.getters) {
Object.keys(module.getters).forEach(getterKey => {
const rawGetter = module.getters[getterKey]
if (getters[getterKey]) {
console.error(`[vuex] duplicate getter key: ${getterKey}`)
return
}
getters[getterKey] = function wrappedGetter (state) {
return rawGetter(getNestedState(state, modulePath))
}
})
}
extractModuleGetters(getters, module.modules, modulePath)
})
return getters
}
// merge mutations of this module and nested modules
return mergeObjects([
mutations,
...nestedMutations
])
})
}
function enableStrictMode (store) {
store._vm.$watch('state', () => {
if (!store._committing) {
throw new Error(
'[vuex] Do not mutate vuex store state outside mutation handlers.'
)
}
}, { deep: true, sync: true })
}
/**
* Setup mutation check: if the vuex instance's state is mutated
* outside of a mutation handler, we throw en error. This effectively
* enforces all mutations to the state to be trackable and hot-reloadble.
* However, this comes at a run time cost since we are doing a deep
* watch on the entire state tree, so it is only enalbed with the
* strict option is set to true.
*/
function isObject (obj) {
return obj !== null && typeof obj === 'object'
}
_setupMutationCheck () {
const Watcher = getWatcher(this._vm)
/* eslint-disable no-new */
new Watcher(this._vm, 'state', () => {
if (!this._dispatching) {
throw new Error(
'[vuex] Do not mutate vuex store state outside mutation handlers.'
)
}
}, { deep: true, sync: true })
/* eslint-enable no-new */
}
function isPromise (val) {
return val && typeof val.then === 'function'
}
function getNestedState (state, path) {
return path.reduce((state, key) => state[key], state)
}
function install (_Vue) {
if (Vue) {
console.warn(
console.error(
'[vuex] already installed. Vue.use(Vuex) should be called only once.'

@@ -297,3 +306,3 @@ )

Vue = _Vue
override(Vue)
applyMixin(Vue)
}

@@ -308,3 +317,5 @@

Store,
install
install,
mapGetters,
mapActions
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc