UNPKG

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