UNPKG

32.8 kBJavaScriptView Raw
1/**
2 * vuex v4.0.0-alpha.1
3 * (c) 2020 Evan You
4 * @license MIT
5 */
6(function (global, factory) {
7 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue')) :
8 typeof define === 'function' && define.amd ? define(['vue'], factory) :
9 (global = global || self, global.Vuex = factory(global.Vue));
10}(this, function (vue) { 'use strict';
11
12 var storeKey = 'store';
13
14 function useStore (key) {
15 if ( key === void 0 ) key = null;
16
17 return vue.inject(key !== null ? key : storeKey)
18 }
19
20 function applyMixin (app, store, injectKey) {
21 app.provide(injectKey || storeKey, store);
22
23 // TODO: Refactor this to use `provide/inject`. It's currently
24 // not possible because Vue 3 doesn't work with `$` prefixed
25 // `provide/inject` at the moment.
26 app.mixin({
27 beforeCreate: function beforeCreate () {
28 if (!this.parent) {
29 this.$store = typeof store === 'function' ? store() : store;
30 } else {
31 this.$store = this.parent.$options.$store;
32 }
33 }
34 });
35 }
36
37 var target = typeof window !== 'undefined'
38 ? window
39 : typeof global !== 'undefined'
40 ? global
41 : {};
42 var devtoolHook = target.__VUE_DEVTOOLS_GLOBAL_HOOK__;
43
44 function devtoolPlugin (store) {
45 if (!devtoolHook) { return }
46
47 store._devtoolHook = devtoolHook;
48
49 devtoolHook.emit('vuex:init', store);
50
51 devtoolHook.on('vuex:travel-to-state', function (targetState) {
52 store.replaceState(targetState);
53 });
54
55 store.subscribe(function (mutation, state) {
56 devtoolHook.emit('vuex:mutation', mutation, state);
57 });
58 }
59
60 /**
61 * Get the first item that pass the test
62 * by second argument function
63 *
64 * @param {Array} list
65 * @param {Function} f
66 * @return {*}
67 */
68
69 /**
70 * forEach for object
71 */
72 function forEachValue (obj, fn) {
73 Object.keys(obj).forEach(function (key) { return fn(obj[key], key); });
74 }
75
76 function isObject (obj) {
77 return obj !== null && typeof obj === 'object'
78 }
79
80 function isPromise (val) {
81 return val && typeof val.then === 'function'
82 }
83
84 function assert (condition, msg) {
85 if (!condition) { throw new Error(("[vuex] " + msg)) }
86 }
87
88 function partial (fn, arg) {
89 return function () {
90 return fn(arg)
91 }
92 }
93
94 // Base data struct for store's module, package with some attribute and method
95 var Module = function Module (rawModule, runtime) {
96 this.runtime = runtime;
97 // Store some children item
98 this._children = Object.create(null);
99 // Store the origin module object which passed by programmer
100 this._rawModule = rawModule;
101 var rawState = rawModule.state;
102
103 // Store the origin module's state
104 this.state = (typeof rawState === 'function' ? rawState() : rawState) || {};
105 };
106
107 var prototypeAccessors = { namespaced: { configurable: true } };
108
109 prototypeAccessors.namespaced.get = function () {
110 return !!this._rawModule.namespaced
111 };
112
113 Module.prototype.addChild = function addChild (key, module) {
114 this._children[key] = module;
115 };
116
117 Module.prototype.removeChild = function removeChild (key) {
118 delete this._children[key];
119 };
120
121 Module.prototype.getChild = function getChild (key) {
122 return this._children[key]
123 };
124
125 Module.prototype.update = function update (rawModule) {
126 this._rawModule.namespaced = rawModule.namespaced;
127 if (rawModule.actions) {
128 this._rawModule.actions = rawModule.actions;
129 }
130 if (rawModule.mutations) {
131 this._rawModule.mutations = rawModule.mutations;
132 }
133 if (rawModule.getters) {
134 this._rawModule.getters = rawModule.getters;
135 }
136 };
137
138 Module.prototype.forEachChild = function forEachChild (fn) {
139 forEachValue(this._children, fn);
140 };
141
142 Module.prototype.forEachGetter = function forEachGetter (fn) {
143 if (this._rawModule.getters) {
144 forEachValue(this._rawModule.getters, fn);
145 }
146 };
147
148 Module.prototype.forEachAction = function forEachAction (fn) {
149 if (this._rawModule.actions) {
150 forEachValue(this._rawModule.actions, fn);
151 }
152 };
153
154 Module.prototype.forEachMutation = function forEachMutation (fn) {
155 if (this._rawModule.mutations) {
156 forEachValue(this._rawModule.mutations, fn);
157 }
158 };
159
160 Object.defineProperties( Module.prototype, prototypeAccessors );
161
162 var ModuleCollection = function ModuleCollection (rawRootModule) {
163 // register root module (Vuex.Store options)
164 this.register([], rawRootModule, false);
165 };
166
167 ModuleCollection.prototype.get = function get (path) {
168 return path.reduce(function (module, key) {
169 return module.getChild(key)
170 }, this.root)
171 };
172
173 ModuleCollection.prototype.getNamespace = function getNamespace (path) {
174 var module = this.root;
175 return path.reduce(function (namespace, key) {
176 module = module.getChild(key);
177 return namespace + (module.namespaced ? key + '/' : '')
178 }, '')
179 };
180
181 ModuleCollection.prototype.update = function update$1 (rawRootModule) {
182 update([], this.root, rawRootModule);
183 };
184
185 ModuleCollection.prototype.register = function register (path, rawModule, runtime) {
186 var this$1 = this;
187 if ( runtime === void 0 ) runtime = true;
188
189 {
190 assertRawModule(path, rawModule);
191 }
192
193 var newModule = new Module(rawModule, runtime);
194 if (path.length === 0) {
195 this.root = newModule;
196 } else {
197 var parent = this.get(path.slice(0, -1));
198 parent.addChild(path[path.length - 1], newModule);
199 }
200
201 // register nested modules
202 if (rawModule.modules) {
203 forEachValue(rawModule.modules, function (rawChildModule, key) {
204 this$1.register(path.concat(key), rawChildModule, runtime);
205 });
206 }
207 };
208
209 ModuleCollection.prototype.unregister = function unregister (path) {
210 var parent = this.get(path.slice(0, -1));
211 var key = path[path.length - 1];
212 if (!parent.getChild(key).runtime) { return }
213
214 parent.removeChild(key);
215 };
216
217 function update (path, targetModule, newModule) {
218 {
219 assertRawModule(path, newModule);
220 }
221
222 // update target module
223 targetModule.update(newModule);
224
225 // update nested modules
226 if (newModule.modules) {
227 for (var key in newModule.modules) {
228 if (!targetModule.getChild(key)) {
229 {
230 console.warn(
231 "[vuex] trying to add a new module '" + key + "' on hot reloading, " +
232 'manual reload is needed'
233 );
234 }
235 return
236 }
237 update(
238 path.concat(key),
239 targetModule.getChild(key),
240 newModule.modules[key]
241 );
242 }
243 }
244 }
245
246 var functionAssert = {
247 assert: function (value) { return typeof value === 'function'; },
248 expected: 'function'
249 };
250
251 var objectAssert = {
252 assert: function (value) { return typeof value === 'function' ||
253 (typeof value === 'object' && typeof value.handler === 'function'); },
254 expected: 'function or object with "handler" function'
255 };
256
257 var assertTypes = {
258 getters: functionAssert,
259 mutations: functionAssert,
260 actions: objectAssert
261 };
262
263 function assertRawModule (path, rawModule) {
264 Object.keys(assertTypes).forEach(function (key) {
265 if (!rawModule[key]) { return }
266
267 var assertOptions = assertTypes[key];
268
269 forEachValue(rawModule[key], function (value, type) {
270 assert(
271 assertOptions.assert(value),
272 makeAssertionMessage(path, key, type, value, assertOptions.expected)
273 );
274 });
275 });
276 }
277
278 function makeAssertionMessage (path, key, type, value, expected) {
279 var buf = key + " should be " + expected + " but \"" + key + "." + type + "\"";
280 if (path.length > 0) {
281 buf += " in module \"" + (path.join('.')) + "\"";
282 }
283 buf += " is " + (JSON.stringify(value)) + ".";
284 return buf
285 }
286
287 // let Vue // bind on install
288
289 function createStore (options) {
290 return new Store(options)
291 }
292
293 var Store = function Store (options) {
294 var this$1 = this;
295 if ( options === void 0 ) options = {};
296
297 // TODO: Bring back this one if needed.
298 //
299 // Auto install if it is not done yet and `window` has `Vue`.
300 // To allow users to avoid auto-installation in some cases,
301 // this code should be placed here. See #731
302 // if (!Vue && typeof window !== 'undefined' && window.Vue) {
303 // install(window.Vue)
304 // }
305
306 {
307 // TODO: Maybe we can remove this depending on the new implementation.
308 // assert(Vue, `must call Vue.use(Vuex) before creating a store instance.`)
309 assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");
310 assert(this instanceof Store, "store must be called with the new operator.");
311 }
312
313 var plugins = options.plugins; if ( plugins === void 0 ) plugins = [];
314 var strict = options.strict; if ( strict === void 0 ) strict = false;
315
316 // store internal state
317 this._committing = false;
318 this._actions = Object.create(null);
319 this._actionSubscribers = [];
320 this._mutations = Object.create(null);
321 this._wrappedGetters = Object.create(null);
322 this._modules = new ModuleCollection(options);
323 this._modulesNamespaceMap = Object.create(null);
324 this._subscribers = [];
325 this._makeLocalGettersCache = Object.create(null);
326
327 // bind commit and dispatch to self
328 var store = this;
329 var ref = this;
330 var dispatch = ref.dispatch;
331 var commit = ref.commit;
332 this.dispatch = function boundDispatch (type, payload) {
333 return dispatch.call(store, type, payload)
334 };
335 this.commit = function boundCommit (type, payload, options) {
336 return commit.call(store, type, payload, options)
337 };
338
339 // strict mode
340 this.strict = strict;
341
342 var state = this._modules.root.state;
343
344 // init root module.
345 // this also recursively registers all sub-modules
346 // and collects all module getters inside this._wrappedGetters
347 installModule(this, state, [], this._modules.root);
348
349 // initialize the store vm, which is responsible for the reactivity
350 // (also registers _wrappedGetters as computed properties)
351 resetStoreVM(this, state);
352
353 // apply plugins
354 plugins.forEach(function (plugin) { return plugin(this$1); });
355
356 var useDevtools = options.devtools !== undefined ? options.devtools : /* Vue.config.devtools */ true;
357 if (useDevtools) {
358 devtoolPlugin(this);
359 }
360 };
361
362 var prototypeAccessors$1 = { state: { configurable: true } };
363
364 Store.prototype.install = function install (app, injectKey) {
365 // TODO: Removing double install check for now. Maybe we can bring this
366 // feature back again if needed.
367 //
368 // if (Vue && _Vue === Vue) {
369 // if ("development" !== 'production') {
370 // console.error(
371 // '[vuex] already installed. Vue.use(Vuex) should be called only once.'
372 // )
373 // }
374 // return
375 // }
376 // Vue = _Vue
377
378 applyMixin(app, this, injectKey);
379 };
380
381 prototypeAccessors$1.state.get = function () {
382 return this._vm._data.$$state
383 };
384
385 prototypeAccessors$1.state.set = function (v) {
386 {
387 assert(false, "use store.replaceState() to explicit replace store state.");
388 }
389 };
390
391 Store.prototype.commit = function commit (_type, _payload, _options) {
392 var this$1 = this;
393
394 // check object-style commit
395 var ref = unifyObjectStyle(_type, _payload, _options);
396 var type = ref.type;
397 var payload = ref.payload;
398 var options = ref.options;
399
400 var mutation = { type: type, payload: payload };
401 var entry = this._mutations[type];
402 if (!entry) {
403 {
404 console.error(("[vuex] unknown mutation type: " + type));
405 }
406 return
407 }
408 this._withCommit(function () {
409 entry.forEach(function commitIterator (handler) {
410 handler(payload);
411 });
412 });
413
414 this._subscribers
415 .slice() // shallow copy to prevent iterator invalidation if subscriber synchronously calls unsubscribe
416 .forEach(function (sub) { return sub(mutation, this$1.state); });
417
418 if (
419 options && options.silent
420 ) {
421 console.warn(
422 "[vuex] mutation type: " + type + ". Silent option has been removed. " +
423 'Use the filter functionality in the vue-devtools'
424 );
425 }
426 };
427
428 Store.prototype.dispatch = function dispatch (_type, _payload) {
429 var this$1 = this;
430
431 // check object-style dispatch
432 var ref = unifyObjectStyle(_type, _payload);
433 var type = ref.type;
434 var payload = ref.payload;
435
436 var action = { type: type, payload: payload };
437 var entry = this._actions[type];
438 if (!entry) {
439 {
440 console.error(("[vuex] unknown action type: " + type));
441 }
442 return
443 }
444
445 try {
446 this._actionSubscribers
447 .slice() // shallow copy to prevent iterator invalidation if subscriber synchronously calls unsubscribe
448 .filter(function (sub) { return sub.before; })
449 .forEach(function (sub) { return sub.before(action, this$1.state); });
450 } catch (e) {
451 {
452 console.warn("[vuex] error in before action subscribers: ");
453 console.error(e);
454 }
455 }
456
457 var result = entry.length > 1
458 ? Promise.all(entry.map(function (handler) { return handler(payload); }))
459 : entry[0](payload);
460
461 return result.then(function (res) {
462 try {
463 this$1._actionSubscribers
464 .filter(function (sub) { return sub.after; })
465 .forEach(function (sub) { return sub.after(action, this$1.state); });
466 } catch (e) {
467 {
468 console.warn("[vuex] error in after action subscribers: ");
469 console.error(e);
470 }
471 }
472 return res
473 })
474 };
475
476 Store.prototype.subscribe = function subscribe (fn) {
477 return genericSubscribe(fn, this._subscribers)
478 };
479
480 Store.prototype.subscribeAction = function subscribeAction (fn) {
481 var subs = typeof fn === 'function' ? { before: fn } : fn;
482 return genericSubscribe(subs, this._actionSubscribers)
483 };
484
485 Store.prototype.watch = function watch$1 (getter, cb, options) {
486 var this$1 = this;
487
488 {
489 assert(typeof getter === 'function', "store.watch only accepts a function.");
490 }
491 return vue.watch(function () { return getter(this$1.state, this$1.getters); }, cb, Object.assign({}, options))
492 };
493
494 Store.prototype.replaceState = function replaceState (state) {
495 var this$1 = this;
496
497 this._withCommit(function () {
498 this$1._vm._data.$$state = state;
499 });
500 };
501
502 Store.prototype.registerModule = function registerModule (path, rawModule, options) {
503 if ( options === void 0 ) options = {};
504
505 if (typeof path === 'string') { path = [path]; }
506
507 {
508 assert(Array.isArray(path), "module path must be a string or an Array.");
509 assert(path.length > 0, 'cannot register the root module by using registerModule.');
510 }
511
512 this._modules.register(path, rawModule);
513 installModule(this, this.state, path, this._modules.get(path), options.preserveState);
514 // reset store to update getters...
515 resetStoreVM(this, this.state);
516 };
517
518 Store.prototype.unregisterModule = function unregisterModule (path) {
519 var this$1 = this;
520
521 if (typeof path === 'string') { path = [path]; }
522
523 {
524 assert(Array.isArray(path), "module path must be a string or an Array.");
525 }
526
527 this._modules.unregister(path);
528 this._withCommit(function () {
529 var parentState = getNestedState(this$1.state, path.slice(0, -1));
530 delete parentState[path[path.length - 1]];
531 });
532 resetStore(this);
533 };
534
535 Store.prototype.hotUpdate = function hotUpdate (newOptions) {
536 this._modules.update(newOptions);
537 resetStore(this, true);
538 };
539
540 Store.prototype._withCommit = function _withCommit (fn) {
541 var committing = this._committing;
542 this._committing = true;
543 fn();
544 this._committing = committing;
545 };
546
547 Object.defineProperties( Store.prototype, prototypeAccessors$1 );
548
549 function genericSubscribe (fn, subs) {
550 if (subs.indexOf(fn) < 0) {
551 subs.push(fn);
552 }
553 return function () {
554 var i = subs.indexOf(fn);
555 if (i > -1) {
556 subs.splice(i, 1);
557 }
558 }
559 }
560
561 function resetStore (store, hot) {
562 store._actions = Object.create(null);
563 store._mutations = Object.create(null);
564 store._wrappedGetters = Object.create(null);
565 store._modulesNamespaceMap = Object.create(null);
566 var state = store.state;
567 // init all modules
568 installModule(store, state, [], store._modules.root, true);
569 // reset vm
570 resetStoreVM(store, state, hot);
571 }
572
573 function resetStoreVM (store, state, hot) {
574 var oldVm = store._vm;
575
576 // bind store public getters
577 store.getters = {};
578 // reset local getters cache
579 store._makeLocalGettersCache = Object.create(null);
580 var wrappedGetters = store._wrappedGetters;
581 var computedObj = {};
582 forEachValue(wrappedGetters, function (fn, key) {
583 // TODO: Refactor following code and comment. We can simplify many things
584 // using computed function.
585 //
586 // use computed to leverage its lazy-caching mechanism
587 // direct inline function use will lead to closure preserving oldVm.
588 // using partial to return function with only arguments preserved in closure environment.
589 computedObj[key] = partial(fn, store);
590 Object.defineProperty(store.getters, key, {
591 get: function () { return vue.computed(function () { return computedObj[key](); }).value; },
592 enumerable: true // for local getters
593 });
594 });
595
596 // TODO: Bring back this if it's still needed.
597 //
598 // use a Vue instance to store the state tree
599 // suppress warnings just in case the user has added
600 // some funky global mixins
601 // const silent = Vue.config.silent
602 // Vue.config.silent = true
603
604 // TODO: Refactor the code and remove this comment.
605 //
606 // New impl with reactive. Defining redundunt keys to make it as close as
607 // the old impl api.
608 store._vm = vue.reactive({
609 _data: {
610 $$state: state
611 }
612 });
613
614 // TODO: Bring back maybe?
615 //
616 // Vue.config.silent = silent
617
618 // enable strict mode for new vm
619 if (store.strict) {
620 enableStrictMode(store);
621 }
622
623 if (oldVm) {
624 if (hot) {
625 // dispatch changes in all subscribed watchers
626 // to force getter re-evaluation for hot reloading.
627 store._withCommit(function () {
628 oldVm._data.$$state = null;
629 });
630 }
631 // TODO: I think we don't need this anymore since we're not using vm?
632 // Vue.nextTick(() => oldVm.$destroy())
633 }
634 }
635
636 function installModule (store, rootState, path, module, hot) {
637 var isRoot = !path.length;
638 var namespace = store._modules.getNamespace(path);
639
640 // register in namespace map
641 if (module.namespaced) {
642 if (store._modulesNamespaceMap[namespace] && "development" !== 'production') {
643 console.error(("[vuex] duplicate namespace " + namespace + " for the namespaced module " + (path.join('/'))));
644 }
645 store._modulesNamespaceMap[namespace] = module;
646 }
647
648 // set state
649 if (!isRoot && !hot) {
650 var parentState = getNestedState(rootState, path.slice(0, -1));
651 var moduleName = path[path.length - 1];
652 store._withCommit(function () {
653 {
654 if (moduleName in parentState) {
655 console.warn(
656 ("[vuex] state field \"" + moduleName + "\" was overridden by a module with the same name at \"" + (path.join('.')) + "\"")
657 );
658 }
659 }
660 parentState[moduleName] = module.state;
661 });
662 }
663
664 var local = module.context = makeLocalContext(store, namespace, path);
665
666 module.forEachMutation(function (mutation, key) {
667 var namespacedType = namespace + key;
668 registerMutation(store, namespacedType, mutation, local);
669 });
670
671 module.forEachAction(function (action, key) {
672 var type = action.root ? key : namespace + key;
673 var handler = action.handler || action;
674 registerAction(store, type, handler, local);
675 });
676
677 module.forEachGetter(function (getter, key) {
678 var namespacedType = namespace + key;
679 registerGetter(store, namespacedType, getter, local);
680 });
681
682 module.forEachChild(function (child, key) {
683 installModule(store, rootState, path.concat(key), child, hot);
684 });
685 }
686
687 /**
688 * make localized dispatch, commit, getters and state
689 * if there is no namespace, just use root ones
690 */
691 function makeLocalContext (store, namespace, path) {
692 var noNamespace = namespace === '';
693
694 var local = {
695 dispatch: noNamespace ? store.dispatch : function (_type, _payload, _options) {
696 var args = unifyObjectStyle(_type, _payload, _options);
697 var payload = args.payload;
698 var options = args.options;
699 var type = args.type;
700
701 if (!options || !options.root) {
702 type = namespace + type;
703 if (!store._actions[type]) {
704 console.error(("[vuex] unknown local action type: " + (args.type) + ", global type: " + type));
705 return
706 }
707 }
708
709 return store.dispatch(type, payload)
710 },
711
712 commit: noNamespace ? store.commit : function (_type, _payload, _options) {
713 var args = unifyObjectStyle(_type, _payload, _options);
714 var payload = args.payload;
715 var options = args.options;
716 var type = args.type;
717
718 if (!options || !options.root) {
719 type = namespace + type;
720 if (!store._mutations[type]) {
721 console.error(("[vuex] unknown local mutation type: " + (args.type) + ", global type: " + type));
722 return
723 }
724 }
725
726 store.commit(type, payload, options);
727 }
728 };
729
730 // getters and state object must be gotten lazily
731 // because they will be changed by vm update
732 Object.defineProperties(local, {
733 getters: {
734 get: noNamespace
735 ? function () { return store.getters; }
736 : function () { return makeLocalGetters(store, namespace); }
737 },
738 state: {
739 get: function () { return getNestedState(store.state, path); }
740 }
741 });
742
743 return local
744 }
745
746 function makeLocalGetters (store, namespace) {
747 if (!store._makeLocalGettersCache[namespace]) {
748 var gettersProxy = {};
749 var splitPos = namespace.length;
750 Object.keys(store.getters).forEach(function (type) {
751 // skip if the target getter is not match this namespace
752 if (type.slice(0, splitPos) !== namespace) { return }
753
754 // extract local getter type
755 var localType = type.slice(splitPos);
756
757 // Add a port to the getters proxy.
758 // Define as getter property because
759 // we do not want to evaluate the getters in this time.
760 Object.defineProperty(gettersProxy, localType, {
761 get: function () { return store.getters[type]; },
762 enumerable: true
763 });
764 });
765 store._makeLocalGettersCache[namespace] = gettersProxy;
766 }
767
768 return store._makeLocalGettersCache[namespace]
769 }
770
771 function registerMutation (store, type, handler, local) {
772 var entry = store._mutations[type] || (store._mutations[type] = []);
773 entry.push(function wrappedMutationHandler (payload) {
774 handler.call(store, local.state, payload);
775 });
776 }
777
778 function registerAction (store, type, handler, local) {
779 var entry = store._actions[type] || (store._actions[type] = []);
780 entry.push(function wrappedActionHandler (payload) {
781 var res = handler.call(store, {
782 dispatch: local.dispatch,
783 commit: local.commit,
784 getters: local.getters,
785 state: local.state,
786 rootGetters: store.getters,
787 rootState: store.state
788 }, payload);
789 if (!isPromise(res)) {
790 res = Promise.resolve(res);
791 }
792 if (store._devtoolHook) {
793 return res.catch(function (err) {
794 store._devtoolHook.emit('vuex:error', err);
795 throw err
796 })
797 } else {
798 return res
799 }
800 });
801 }
802
803 function registerGetter (store, type, rawGetter, local) {
804 if (store._wrappedGetters[type]) {
805 {
806 console.error(("[vuex] duplicate getter key: " + type));
807 }
808 return
809 }
810 store._wrappedGetters[type] = function wrappedGetter (store) {
811 return rawGetter(
812 local.state, // local state
813 local.getters, // local getters
814 store.state, // root state
815 store.getters // root getters
816 )
817 };
818 }
819
820 function enableStrictMode (store) {
821 vue.watch(function () { return store._vm._data.$$state; }, function () {
822 {
823 assert(store._committing, "do not mutate vuex store state outside mutation handlers.");
824 }
825 }, { deep: true, flush: 'sync' });
826 }
827
828 function getNestedState (state, path) {
829 return path.reduce(function (state, key) { return state[key]; }, state)
830 }
831
832 function unifyObjectStyle (type, payload, options) {
833 if (isObject(type) && type.type) {
834 options = payload;
835 payload = type;
836 type = type.type;
837 }
838
839 {
840 assert(typeof type === 'string', ("expects string as the type, but found " + (typeof type) + "."));
841 }
842
843 return { type: type, payload: payload, options: options }
844 }
845
846 /**
847 * Reduce the code which written in Vue.js for getting the state.
848 * @param {String} [namespace] - Module's namespace
849 * @param {Object|Array} states # Object's item can be a function which accept state and getters for param, you can do something for state and getters in it.
850 * @param {Object}
851 */
852 var mapState = normalizeNamespace(function (namespace, states) {
853 var res = {};
854 if (!isValidMap(states)) {
855 console.error('[vuex] mapState: mapper parameter must be either an Array or an Object');
856 }
857 normalizeMap(states).forEach(function (ref) {
858 var key = ref.key;
859 var val = ref.val;
860
861 res[key] = function mappedState () {
862 var state = this.$store.state;
863 var getters = this.$store.getters;
864 if (namespace) {
865 var module = getModuleByNamespace(this.$store, 'mapState', namespace);
866 if (!module) {
867 return
868 }
869 state = module.context.state;
870 getters = module.context.getters;
871 }
872 return typeof val === 'function'
873 ? val.call(this, state, getters)
874 : state[val]
875 };
876 // mark vuex getter for devtools
877 res[key].vuex = true;
878 });
879 return res
880 });
881
882 /**
883 * Reduce the code which written in Vue.js for committing the mutation
884 * @param {String} [namespace] - Module's namespace
885 * @param {Object|Array} mutations # Object's item can be a function which accept `commit` function as the first param, it can accept anthor params. You can commit mutation and do any other things in this function. specially, You need to pass anthor params from the mapped function.
886 * @return {Object}
887 */
888 var mapMutations = normalizeNamespace(function (namespace, mutations) {
889 var res = {};
890 if (!isValidMap(mutations)) {
891 console.error('[vuex] mapMutations: mapper parameter must be either an Array or an Object');
892 }
893 normalizeMap(mutations).forEach(function (ref) {
894 var key = ref.key;
895 var val = ref.val;
896
897 res[key] = function mappedMutation () {
898 var args = [], len = arguments.length;
899 while ( len-- ) args[ len ] = arguments[ len ];
900
901 // Get the commit method from store
902 var commit = this.$store.commit;
903 if (namespace) {
904 var module = getModuleByNamespace(this.$store, 'mapMutations', namespace);
905 if (!module) {
906 return
907 }
908 commit = module.context.commit;
909 }
910 return typeof val === 'function'
911 ? val.apply(this, [commit].concat(args))
912 : commit.apply(this.$store, [val].concat(args))
913 };
914 });
915 return res
916 });
917
918 /**
919 * Reduce the code which written in Vue.js for getting the getters
920 * @param {String} [namespace] - Module's namespace
921 * @param {Object|Array} getters
922 * @return {Object}
923 */
924 var mapGetters = normalizeNamespace(function (namespace, getters) {
925 var res = {};
926 if (!isValidMap(getters)) {
927 console.error('[vuex] mapGetters: mapper parameter must be either an Array or an Object');
928 }
929 normalizeMap(getters).forEach(function (ref) {
930 var key = ref.key;
931 var val = ref.val;
932
933 // The namespace has been mutated by normalizeNamespace
934 val = namespace + val;
935 res[key] = function mappedGetter () {
936 if (namespace && !getModuleByNamespace(this.$store, 'mapGetters', namespace)) {
937 return
938 }
939 if (!(val in this.$store.getters)) {
940 console.error(("[vuex] unknown getter: " + val));
941 return
942 }
943 return this.$store.getters[val]
944 };
945 // mark vuex getter for devtools
946 res[key].vuex = true;
947 });
948 return res
949 });
950
951 /**
952 * Reduce the code which written in Vue.js for dispatch the action
953 * @param {String} [namespace] - Module's namespace
954 * @param {Object|Array} actions # Object's item can be a function which accept `dispatch` function as the first param, it can accept anthor params. You can dispatch action and do any other things in this function. specially, You need to pass anthor params from the mapped function.
955 * @return {Object}
956 */
957 var mapActions = normalizeNamespace(function (namespace, actions) {
958 var res = {};
959 if (!isValidMap(actions)) {
960 console.error('[vuex] mapActions: mapper parameter must be either an Array or an Object');
961 }
962 normalizeMap(actions).forEach(function (ref) {
963 var key = ref.key;
964 var val = ref.val;
965
966 res[key] = function mappedAction () {
967 var args = [], len = arguments.length;
968 while ( len-- ) args[ len ] = arguments[ len ];
969
970 // get dispatch function from store
971 var dispatch = this.$store.dispatch;
972 if (namespace) {
973 var module = getModuleByNamespace(this.$store, 'mapActions', namespace);
974 if (!module) {
975 return
976 }
977 dispatch = module.context.dispatch;
978 }
979 return typeof val === 'function'
980 ? val.apply(this, [dispatch].concat(args))
981 : dispatch.apply(this.$store, [val].concat(args))
982 };
983 });
984 return res
985 });
986
987 /**
988 * Rebinding namespace param for mapXXX function in special scoped, and return them by simple object
989 * @param {String} namespace
990 * @return {Object}
991 */
992 var createNamespacedHelpers = function (namespace) { return ({
993 mapState: mapState.bind(null, namespace),
994 mapGetters: mapGetters.bind(null, namespace),
995 mapMutations: mapMutations.bind(null, namespace),
996 mapActions: mapActions.bind(null, namespace)
997 }); };
998
999 /**
1000 * Normalize the map
1001 * normalizeMap([1, 2, 3]) => [ { key: 1, val: 1 }, { key: 2, val: 2 }, { key: 3, val: 3 } ]
1002 * normalizeMap({a: 1, b: 2, c: 3}) => [ { key: 'a', val: 1 }, { key: 'b', val: 2 }, { key: 'c', val: 3 } ]
1003 * @param {Array|Object} map
1004 * @return {Object}
1005 */
1006 function normalizeMap (map) {
1007 if (!isValidMap(map)) {
1008 return []
1009 }
1010 return Array.isArray(map)
1011 ? map.map(function (key) { return ({ key: key, val: key }); })
1012 : Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); })
1013 }
1014
1015 /**
1016 * Validate whether given map is valid or not
1017 * @param {*} map
1018 * @return {Boolean}
1019 */
1020 function isValidMap (map) {
1021 return Array.isArray(map) || isObject(map)
1022 }
1023
1024 /**
1025 * Return a function expect two param contains namespace and map. it will normalize the namespace and then the param's function will handle the new namespace and the map.
1026 * @param {Function} fn
1027 * @return {Function}
1028 */
1029 function normalizeNamespace (fn) {
1030 return function (namespace, map) {
1031 if (typeof namespace !== 'string') {
1032 map = namespace;
1033 namespace = '';
1034 } else if (namespace.charAt(namespace.length - 1) !== '/') {
1035 namespace += '/';
1036 }
1037 return fn(namespace, map)
1038 }
1039 }
1040
1041 /**
1042 * Search a special module from store by namespace. if module not exist, print error message.
1043 * @param {Object} store
1044 * @param {String} helper
1045 * @param {String} namespace
1046 * @return {Object}
1047 */
1048 function getModuleByNamespace (store, helper, namespace) {
1049 var module = store._modulesNamespaceMap[namespace];
1050 if (!module) {
1051 console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace));
1052 }
1053 return module
1054 }
1055
1056 var index = {
1057 version: '4.0.0-alpha.1',
1058 createStore: createStore,
1059 Store: Store,
1060 useStore: useStore,
1061 mapState: mapState,
1062 mapMutations: mapMutations,
1063 mapGetters: mapGetters,
1064 mapActions: mapActions,
1065 createNamespacedHelpers: createNamespacedHelpers
1066 };
1067
1068 return index;
1069
1070}));