UNPKG

42.7 kBJavaScriptView Raw
1/*!
2 * vuex v4.1.0
3 * (c) 2022 Evan You
4 * @license MIT
5 */
6import { inject, effectScope, reactive, watch, computed } from 'vue';
7import { setupDevtoolsPlugin } from '@vue/devtools-api';
8
9var storeKey = 'store';
10
11function useStore (key) {
12 if ( key === void 0 ) key = null;
13
14 return inject(key !== null ? key : storeKey)
15}
16
17/**
18 * Get the first item that pass the test
19 * by second argument function
20 *
21 * @param {Array} list
22 * @param {Function} f
23 * @return {*}
24 */
25function find (list, f) {
26 return list.filter(f)[0]
27}
28
29/**
30 * Deep copy the given object considering circular structure.
31 * This function caches all nested objects and its copies.
32 * If it detects circular structure, use cached copy to avoid infinite loop.
33 *
34 * @param {*} obj
35 * @param {Array<Object>} cache
36 * @return {*}
37 */
38function deepCopy (obj, cache) {
39 if ( cache === void 0 ) cache = [];
40
41 // just return if obj is immutable value
42 if (obj === null || typeof obj !== 'object') {
43 return obj
44 }
45
46 // if obj is hit, it is in circular structure
47 var hit = find(cache, function (c) { return c.original === obj; });
48 if (hit) {
49 return hit.copy
50 }
51
52 var copy = Array.isArray(obj) ? [] : {};
53 // put the copy into cache at first
54 // because we want to refer it in recursive deepCopy
55 cache.push({
56 original: obj,
57 copy: copy
58 });
59
60 Object.keys(obj).forEach(function (key) {
61 copy[key] = deepCopy(obj[key], cache);
62 });
63
64 return copy
65}
66
67/**
68 * forEach for object
69 */
70function forEachValue (obj, fn) {
71 Object.keys(obj).forEach(function (key) { return fn(obj[key], key); });
72}
73
74function isObject (obj) {
75 return obj !== null && typeof obj === 'object'
76}
77
78function isPromise (val) {
79 return val && typeof val.then === 'function'
80}
81
82function assert (condition, msg) {
83 if (!condition) { throw new Error(("[vuex] " + msg)) }
84}
85
86function partial (fn, arg) {
87 return function () {
88 return fn(arg)
89 }
90}
91
92function genericSubscribe (fn, subs, options) {
93 if (subs.indexOf(fn) < 0) {
94 options && options.prepend
95 ? subs.unshift(fn)
96 : subs.push(fn);
97 }
98 return function () {
99 var i = subs.indexOf(fn);
100 if (i > -1) {
101 subs.splice(i, 1);
102 }
103 }
104}
105
106function resetStore (store, hot) {
107 store._actions = Object.create(null);
108 store._mutations = Object.create(null);
109 store._wrappedGetters = Object.create(null);
110 store._modulesNamespaceMap = Object.create(null);
111 var state = store.state;
112 // init all modules
113 installModule(store, state, [], store._modules.root, true);
114 // reset state
115 resetStoreState(store, state, hot);
116}
117
118function resetStoreState (store, state, hot) {
119 var oldState = store._state;
120 var oldScope = store._scope;
121
122 // bind store public getters
123 store.getters = {};
124 // reset local getters cache
125 store._makeLocalGettersCache = Object.create(null);
126 var wrappedGetters = store._wrappedGetters;
127 var computedObj = {};
128 var computedCache = {};
129
130 // create a new effect scope and create computed object inside it to avoid
131 // getters (computed) getting destroyed on component unmount.
132 var scope = effectScope(true);
133
134 scope.run(function () {
135 forEachValue(wrappedGetters, function (fn, key) {
136 // use computed to leverage its lazy-caching mechanism
137 // direct inline function use will lead to closure preserving oldState.
138 // using partial to return function with only arguments preserved in closure environment.
139 computedObj[key] = partial(fn, store);
140 computedCache[key] = computed(function () { return computedObj[key](); });
141 Object.defineProperty(store.getters, key, {
142 get: function () { return computedCache[key].value; },
143 enumerable: true // for local getters
144 });
145 });
146 });
147
148 store._state = reactive({
149 data: state
150 });
151
152 // register the newly created effect scope to the store so that we can
153 // dispose the effects when this method runs again in the future.
154 store._scope = scope;
155
156 // enable strict mode for new state
157 if (store.strict) {
158 enableStrictMode(store);
159 }
160
161 if (oldState) {
162 if (hot) {
163 // dispatch changes in all subscribed watchers
164 // to force getter re-evaluation for hot reloading.
165 store._withCommit(function () {
166 oldState.data = null;
167 });
168 }
169 }
170
171 // dispose previously registered effect scope if there is one.
172 if (oldScope) {
173 oldScope.stop();
174 }
175}
176
177function installModule (store, rootState, path, module, hot) {
178 var isRoot = !path.length;
179 var namespace = store._modules.getNamespace(path);
180
181 // register in namespace map
182 if (module.namespaced) {
183 if (store._modulesNamespaceMap[namespace] && true) {
184 console.error(("[vuex] duplicate namespace " + namespace + " for the namespaced module " + (path.join('/'))));
185 }
186 store._modulesNamespaceMap[namespace] = module;
187 }
188
189 // set state
190 if (!isRoot && !hot) {
191 var parentState = getNestedState(rootState, path.slice(0, -1));
192 var moduleName = path[path.length - 1];
193 store._withCommit(function () {
194 {
195 if (moduleName in parentState) {
196 console.warn(
197 ("[vuex] state field \"" + moduleName + "\" was overridden by a module with the same name at \"" + (path.join('.')) + "\"")
198 );
199 }
200 }
201 parentState[moduleName] = module.state;
202 });
203 }
204
205 var local = module.context = makeLocalContext(store, namespace, path);
206
207 module.forEachMutation(function (mutation, key) {
208 var namespacedType = namespace + key;
209 registerMutation(store, namespacedType, mutation, local);
210 });
211
212 module.forEachAction(function (action, key) {
213 var type = action.root ? key : namespace + key;
214 var handler = action.handler || action;
215 registerAction(store, type, handler, local);
216 });
217
218 module.forEachGetter(function (getter, key) {
219 var namespacedType = namespace + key;
220 registerGetter(store, namespacedType, getter, local);
221 });
222
223 module.forEachChild(function (child, key) {
224 installModule(store, rootState, path.concat(key), child, hot);
225 });
226}
227
228/**
229 * make localized dispatch, commit, getters and state
230 * if there is no namespace, just use root ones
231 */
232function makeLocalContext (store, namespace, path) {
233 var noNamespace = namespace === '';
234
235 var local = {
236 dispatch: noNamespace ? store.dispatch : function (_type, _payload, _options) {
237 var args = unifyObjectStyle(_type, _payload, _options);
238 var payload = args.payload;
239 var options = args.options;
240 var type = args.type;
241
242 if (!options || !options.root) {
243 type = namespace + type;
244 if (!store._actions[type]) {
245 console.error(("[vuex] unknown local action type: " + (args.type) + ", global type: " + type));
246 return
247 }
248 }
249
250 return store.dispatch(type, payload)
251 },
252
253 commit: noNamespace ? store.commit : function (_type, _payload, _options) {
254 var args = unifyObjectStyle(_type, _payload, _options);
255 var payload = args.payload;
256 var options = args.options;
257 var type = args.type;
258
259 if (!options || !options.root) {
260 type = namespace + type;
261 if (!store._mutations[type]) {
262 console.error(("[vuex] unknown local mutation type: " + (args.type) + ", global type: " + type));
263 return
264 }
265 }
266
267 store.commit(type, payload, options);
268 }
269 };
270
271 // getters and state object must be gotten lazily
272 // because they will be changed by state update
273 Object.defineProperties(local, {
274 getters: {
275 get: noNamespace
276 ? function () { return store.getters; }
277 : function () { return makeLocalGetters(store, namespace); }
278 },
279 state: {
280 get: function () { return getNestedState(store.state, path); }
281 }
282 });
283
284 return local
285}
286
287function makeLocalGetters (store, namespace) {
288 if (!store._makeLocalGettersCache[namespace]) {
289 var gettersProxy = {};
290 var splitPos = namespace.length;
291 Object.keys(store.getters).forEach(function (type) {
292 // skip if the target getter is not match this namespace
293 if (type.slice(0, splitPos) !== namespace) { return }
294
295 // extract local getter type
296 var localType = type.slice(splitPos);
297
298 // Add a port to the getters proxy.
299 // Define as getter property because
300 // we do not want to evaluate the getters in this time.
301 Object.defineProperty(gettersProxy, localType, {
302 get: function () { return store.getters[type]; },
303 enumerable: true
304 });
305 });
306 store._makeLocalGettersCache[namespace] = gettersProxy;
307 }
308
309 return store._makeLocalGettersCache[namespace]
310}
311
312function registerMutation (store, type, handler, local) {
313 var entry = store._mutations[type] || (store._mutations[type] = []);
314 entry.push(function wrappedMutationHandler (payload) {
315 handler.call(store, local.state, payload);
316 });
317}
318
319function registerAction (store, type, handler, local) {
320 var entry = store._actions[type] || (store._actions[type] = []);
321 entry.push(function wrappedActionHandler (payload) {
322 var res = handler.call(store, {
323 dispatch: local.dispatch,
324 commit: local.commit,
325 getters: local.getters,
326 state: local.state,
327 rootGetters: store.getters,
328 rootState: store.state
329 }, payload);
330 if (!isPromise(res)) {
331 res = Promise.resolve(res);
332 }
333 if (store._devtoolHook) {
334 return res.catch(function (err) {
335 store._devtoolHook.emit('vuex:error', err);
336 throw err
337 })
338 } else {
339 return res
340 }
341 });
342}
343
344function registerGetter (store, type, rawGetter, local) {
345 if (store._wrappedGetters[type]) {
346 {
347 console.error(("[vuex] duplicate getter key: " + type));
348 }
349 return
350 }
351 store._wrappedGetters[type] = function wrappedGetter (store) {
352 return rawGetter(
353 local.state, // local state
354 local.getters, // local getters
355 store.state, // root state
356 store.getters // root getters
357 )
358 };
359}
360
361function enableStrictMode (store) {
362 watch(function () { return store._state.data; }, function () {
363 {
364 assert(store._committing, "do not mutate vuex store state outside mutation handlers.");
365 }
366 }, { deep: true, flush: 'sync' });
367}
368
369function getNestedState (state, path) {
370 return path.reduce(function (state, key) { return state[key]; }, state)
371}
372
373function unifyObjectStyle (type, payload, options) {
374 if (isObject(type) && type.type) {
375 options = payload;
376 payload = type;
377 type = type.type;
378 }
379
380 {
381 assert(typeof type === 'string', ("expects string as the type, but found " + (typeof type) + "."));
382 }
383
384 return { type: type, payload: payload, options: options }
385}
386
387var LABEL_VUEX_BINDINGS = 'vuex bindings';
388var MUTATIONS_LAYER_ID = 'vuex:mutations';
389var ACTIONS_LAYER_ID = 'vuex:actions';
390var INSPECTOR_ID = 'vuex';
391
392var actionId = 0;
393
394function addDevtools (app, store) {
395 setupDevtoolsPlugin(
396 {
397 id: 'org.vuejs.vuex',
398 app: app,
399 label: 'Vuex',
400 homepage: 'https://next.vuex.vuejs.org/',
401 logo: 'https://vuejs.org/images/icons/favicon-96x96.png',
402 packageName: 'vuex',
403 componentStateTypes: [LABEL_VUEX_BINDINGS]
404 },
405 function (api) {
406 api.addTimelineLayer({
407 id: MUTATIONS_LAYER_ID,
408 label: 'Vuex Mutations',
409 color: COLOR_LIME_500
410 });
411
412 api.addTimelineLayer({
413 id: ACTIONS_LAYER_ID,
414 label: 'Vuex Actions',
415 color: COLOR_LIME_500
416 });
417
418 api.addInspector({
419 id: INSPECTOR_ID,
420 label: 'Vuex',
421 icon: 'storage',
422 treeFilterPlaceholder: 'Filter stores...'
423 });
424
425 api.on.getInspectorTree(function (payload) {
426 if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
427 if (payload.filter) {
428 var nodes = [];
429 flattenStoreForInspectorTree(nodes, store._modules.root, payload.filter, '');
430 payload.rootNodes = nodes;
431 } else {
432 payload.rootNodes = [
433 formatStoreForInspectorTree(store._modules.root, '')
434 ];
435 }
436 }
437 });
438
439 api.on.getInspectorState(function (payload) {
440 if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
441 var modulePath = payload.nodeId;
442 makeLocalGetters(store, modulePath);
443 payload.state = formatStoreForInspectorState(
444 getStoreModule(store._modules, modulePath),
445 modulePath === 'root' ? store.getters : store._makeLocalGettersCache,
446 modulePath
447 );
448 }
449 });
450
451 api.on.editInspectorState(function (payload) {
452 if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {
453 var modulePath = payload.nodeId;
454 var path = payload.path;
455 if (modulePath !== 'root') {
456 path = modulePath.split('/').filter(Boolean).concat( path);
457 }
458 store._withCommit(function () {
459 payload.set(store._state.data, path, payload.state.value);
460 });
461 }
462 });
463
464 store.subscribe(function (mutation, state) {
465 var data = {};
466
467 if (mutation.payload) {
468 data.payload = mutation.payload;
469 }
470
471 data.state = state;
472
473 api.notifyComponentUpdate();
474 api.sendInspectorTree(INSPECTOR_ID);
475 api.sendInspectorState(INSPECTOR_ID);
476
477 api.addTimelineEvent({
478 layerId: MUTATIONS_LAYER_ID,
479 event: {
480 time: Date.now(),
481 title: mutation.type,
482 data: data
483 }
484 });
485 });
486
487 store.subscribeAction({
488 before: function (action, state) {
489 var data = {};
490 if (action.payload) {
491 data.payload = action.payload;
492 }
493 action._id = actionId++;
494 action._time = Date.now();
495 data.state = state;
496
497 api.addTimelineEvent({
498 layerId: ACTIONS_LAYER_ID,
499 event: {
500 time: action._time,
501 title: action.type,
502 groupId: action._id,
503 subtitle: 'start',
504 data: data
505 }
506 });
507 },
508 after: function (action, state) {
509 var data = {};
510 var duration = Date.now() - action._time;
511 data.duration = {
512 _custom: {
513 type: 'duration',
514 display: (duration + "ms"),
515 tooltip: 'Action duration',
516 value: duration
517 }
518 };
519 if (action.payload) {
520 data.payload = action.payload;
521 }
522 data.state = state;
523
524 api.addTimelineEvent({
525 layerId: ACTIONS_LAYER_ID,
526 event: {
527 time: Date.now(),
528 title: action.type,
529 groupId: action._id,
530 subtitle: 'end',
531 data: data
532 }
533 });
534 }
535 });
536 }
537 );
538}
539
540// extracted from tailwind palette
541var COLOR_LIME_500 = 0x84cc16;
542var COLOR_DARK = 0x666666;
543var COLOR_WHITE = 0xffffff;
544
545var TAG_NAMESPACED = {
546 label: 'namespaced',
547 textColor: COLOR_WHITE,
548 backgroundColor: COLOR_DARK
549};
550
551/**
552 * @param {string} path
553 */
554function extractNameFromPath (path) {
555 return path && path !== 'root' ? path.split('/').slice(-2, -1)[0] : 'Root'
556}
557
558/**
559 * @param {*} module
560 * @return {import('@vue/devtools-api').CustomInspectorNode}
561 */
562function formatStoreForInspectorTree (module, path) {
563 return {
564 id: path || 'root',
565 // all modules end with a `/`, we want the last segment only
566 // cart/ -> cart
567 // nested/cart/ -> cart
568 label: extractNameFromPath(path),
569 tags: module.namespaced ? [TAG_NAMESPACED] : [],
570 children: Object.keys(module._children).map(function (moduleName) { return formatStoreForInspectorTree(
571 module._children[moduleName],
572 path + moduleName + '/'
573 ); }
574 )
575 }
576}
577
578/**
579 * @param {import('@vue/devtools-api').CustomInspectorNode[]} result
580 * @param {*} module
581 * @param {string} filter
582 * @param {string} path
583 */
584function flattenStoreForInspectorTree (result, module, filter, path) {
585 if (path.includes(filter)) {
586 result.push({
587 id: path || 'root',
588 label: path.endsWith('/') ? path.slice(0, path.length - 1) : path || 'Root',
589 tags: module.namespaced ? [TAG_NAMESPACED] : []
590 });
591 }
592 Object.keys(module._children).forEach(function (moduleName) {
593 flattenStoreForInspectorTree(result, module._children[moduleName], filter, path + moduleName + '/');
594 });
595}
596
597/**
598 * @param {*} module
599 * @return {import('@vue/devtools-api').CustomInspectorState}
600 */
601function formatStoreForInspectorState (module, getters, path) {
602 getters = path === 'root' ? getters : getters[path];
603 var gettersKeys = Object.keys(getters);
604 var storeState = {
605 state: Object.keys(module.state).map(function (key) { return ({
606 key: key,
607 editable: true,
608 value: module.state[key]
609 }); })
610 };
611
612 if (gettersKeys.length) {
613 var tree = transformPathsToObjectTree(getters);
614 storeState.getters = Object.keys(tree).map(function (key) { return ({
615 key: key.endsWith('/') ? extractNameFromPath(key) : key,
616 editable: false,
617 value: canThrow(function () { return tree[key]; })
618 }); });
619 }
620
621 return storeState
622}
623
624function transformPathsToObjectTree (getters) {
625 var result = {};
626 Object.keys(getters).forEach(function (key) {
627 var path = key.split('/');
628 if (path.length > 1) {
629 var target = result;
630 var leafKey = path.pop();
631 path.forEach(function (p) {
632 if (!target[p]) {
633 target[p] = {
634 _custom: {
635 value: {},
636 display: p,
637 tooltip: 'Module',
638 abstract: true
639 }
640 };
641 }
642 target = target[p]._custom.value;
643 });
644 target[leafKey] = canThrow(function () { return getters[key]; });
645 } else {
646 result[key] = canThrow(function () { return getters[key]; });
647 }
648 });
649 return result
650}
651
652function getStoreModule (moduleMap, path) {
653 var names = path.split('/').filter(function (n) { return n; });
654 return names.reduce(
655 function (module, moduleName, i) {
656 var child = module[moduleName];
657 if (!child) {
658 throw new Error(("Missing module \"" + moduleName + "\" for path \"" + path + "\"."))
659 }
660 return i === names.length - 1 ? child : child._children
661 },
662 path === 'root' ? moduleMap : moduleMap.root._children
663 )
664}
665
666function canThrow (cb) {
667 try {
668 return cb()
669 } catch (e) {
670 return e
671 }
672}
673
674// Base data struct for store's module, package with some attribute and method
675var Module = function Module (rawModule, runtime) {
676 this.runtime = runtime;
677 // Store some children item
678 this._children = Object.create(null);
679 // Store the origin module object which passed by programmer
680 this._rawModule = rawModule;
681 var rawState = rawModule.state;
682
683 // Store the origin module's state
684 this.state = (typeof rawState === 'function' ? rawState() : rawState) || {};
685};
686
687var prototypeAccessors$1 = { namespaced: { configurable: true } };
688
689prototypeAccessors$1.namespaced.get = function () {
690 return !!this._rawModule.namespaced
691};
692
693Module.prototype.addChild = function addChild (key, module) {
694 this._children[key] = module;
695};
696
697Module.prototype.removeChild = function removeChild (key) {
698 delete this._children[key];
699};
700
701Module.prototype.getChild = function getChild (key) {
702 return this._children[key]
703};
704
705Module.prototype.hasChild = function hasChild (key) {
706 return key in this._children
707};
708
709Module.prototype.update = function update (rawModule) {
710 this._rawModule.namespaced = rawModule.namespaced;
711 if (rawModule.actions) {
712 this._rawModule.actions = rawModule.actions;
713 }
714 if (rawModule.mutations) {
715 this._rawModule.mutations = rawModule.mutations;
716 }
717 if (rawModule.getters) {
718 this._rawModule.getters = rawModule.getters;
719 }
720};
721
722Module.prototype.forEachChild = function forEachChild (fn) {
723 forEachValue(this._children, fn);
724};
725
726Module.prototype.forEachGetter = function forEachGetter (fn) {
727 if (this._rawModule.getters) {
728 forEachValue(this._rawModule.getters, fn);
729 }
730};
731
732Module.prototype.forEachAction = function forEachAction (fn) {
733 if (this._rawModule.actions) {
734 forEachValue(this._rawModule.actions, fn);
735 }
736};
737
738Module.prototype.forEachMutation = function forEachMutation (fn) {
739 if (this._rawModule.mutations) {
740 forEachValue(this._rawModule.mutations, fn);
741 }
742};
743
744Object.defineProperties( Module.prototype, prototypeAccessors$1 );
745
746var ModuleCollection = function ModuleCollection (rawRootModule) {
747 // register root module (Vuex.Store options)
748 this.register([], rawRootModule, false);
749};
750
751ModuleCollection.prototype.get = function get (path) {
752 return path.reduce(function (module, key) {
753 return module.getChild(key)
754 }, this.root)
755};
756
757ModuleCollection.prototype.getNamespace = function getNamespace (path) {
758 var module = this.root;
759 return path.reduce(function (namespace, key) {
760 module = module.getChild(key);
761 return namespace + (module.namespaced ? key + '/' : '')
762 }, '')
763};
764
765ModuleCollection.prototype.update = function update$1 (rawRootModule) {
766 update([], this.root, rawRootModule);
767};
768
769ModuleCollection.prototype.register = function register (path, rawModule, runtime) {
770 var this$1$1 = this;
771 if ( runtime === void 0 ) runtime = true;
772
773 {
774 assertRawModule(path, rawModule);
775 }
776
777 var newModule = new Module(rawModule, runtime);
778 if (path.length === 0) {
779 this.root = newModule;
780 } else {
781 var parent = this.get(path.slice(0, -1));
782 parent.addChild(path[path.length - 1], newModule);
783 }
784
785 // register nested modules
786 if (rawModule.modules) {
787 forEachValue(rawModule.modules, function (rawChildModule, key) {
788 this$1$1.register(path.concat(key), rawChildModule, runtime);
789 });
790 }
791};
792
793ModuleCollection.prototype.unregister = function unregister (path) {
794 var parent = this.get(path.slice(0, -1));
795 var key = path[path.length - 1];
796 var child = parent.getChild(key);
797
798 if (!child) {
799 {
800 console.warn(
801 "[vuex] trying to unregister module '" + key + "', which is " +
802 "not registered"
803 );
804 }
805 return
806 }
807
808 if (!child.runtime) {
809 return
810 }
811
812 parent.removeChild(key);
813};
814
815ModuleCollection.prototype.isRegistered = function isRegistered (path) {
816 var parent = this.get(path.slice(0, -1));
817 var key = path[path.length - 1];
818
819 if (parent) {
820 return parent.hasChild(key)
821 }
822
823 return false
824};
825
826function update (path, targetModule, newModule) {
827 {
828 assertRawModule(path, newModule);
829 }
830
831 // update target module
832 targetModule.update(newModule);
833
834 // update nested modules
835 if (newModule.modules) {
836 for (var key in newModule.modules) {
837 if (!targetModule.getChild(key)) {
838 {
839 console.warn(
840 "[vuex] trying to add a new module '" + key + "' on hot reloading, " +
841 'manual reload is needed'
842 );
843 }
844 return
845 }
846 update(
847 path.concat(key),
848 targetModule.getChild(key),
849 newModule.modules[key]
850 );
851 }
852 }
853}
854
855var functionAssert = {
856 assert: function (value) { return typeof value === 'function'; },
857 expected: 'function'
858};
859
860var objectAssert = {
861 assert: function (value) { return typeof value === 'function' ||
862 (typeof value === 'object' && typeof value.handler === 'function'); },
863 expected: 'function or object with "handler" function'
864};
865
866var assertTypes = {
867 getters: functionAssert,
868 mutations: functionAssert,
869 actions: objectAssert
870};
871
872function assertRawModule (path, rawModule) {
873 Object.keys(assertTypes).forEach(function (key) {
874 if (!rawModule[key]) { return }
875
876 var assertOptions = assertTypes[key];
877
878 forEachValue(rawModule[key], function (value, type) {
879 assert(
880 assertOptions.assert(value),
881 makeAssertionMessage(path, key, type, value, assertOptions.expected)
882 );
883 });
884 });
885}
886
887function makeAssertionMessage (path, key, type, value, expected) {
888 var buf = key + " should be " + expected + " but \"" + key + "." + type + "\"";
889 if (path.length > 0) {
890 buf += " in module \"" + (path.join('.')) + "\"";
891 }
892 buf += " is " + (JSON.stringify(value)) + ".";
893 return buf
894}
895
896function createStore (options) {
897 return new Store(options)
898}
899
900var Store = function Store (options) {
901 var this$1$1 = this;
902 if ( options === void 0 ) options = {};
903
904 {
905 assert(typeof Promise !== 'undefined', "vuex requires a Promise polyfill in this browser.");
906 assert(this instanceof Store, "store must be called with the new operator.");
907 }
908
909 var plugins = options.plugins; if ( plugins === void 0 ) plugins = [];
910 var strict = options.strict; if ( strict === void 0 ) strict = false;
911 var devtools = options.devtools;
912
913 // store internal state
914 this._committing = false;
915 this._actions = Object.create(null);
916 this._actionSubscribers = [];
917 this._mutations = Object.create(null);
918 this._wrappedGetters = Object.create(null);
919 this._modules = new ModuleCollection(options);
920 this._modulesNamespaceMap = Object.create(null);
921 this._subscribers = [];
922 this._makeLocalGettersCache = Object.create(null);
923
924 // EffectScope instance. when registering new getters, we wrap them inside
925 // EffectScope so that getters (computed) would not be destroyed on
926 // component unmount.
927 this._scope = null;
928
929 this._devtools = devtools;
930
931 // bind commit and dispatch to self
932 var store = this;
933 var ref = this;
934 var dispatch = ref.dispatch;
935 var commit = ref.commit;
936 this.dispatch = function boundDispatch (type, payload) {
937 return dispatch.call(store, type, payload)
938 };
939 this.commit = function boundCommit (type, payload, options) {
940 return commit.call(store, type, payload, options)
941 };
942
943 // strict mode
944 this.strict = strict;
945
946 var state = this._modules.root.state;
947
948 // init root module.
949 // this also recursively registers all sub-modules
950 // and collects all module getters inside this._wrappedGetters
951 installModule(this, state, [], this._modules.root);
952
953 // initialize the store state, which is responsible for the reactivity
954 // (also registers _wrappedGetters as computed properties)
955 resetStoreState(this, state);
956
957 // apply plugins
958 plugins.forEach(function (plugin) { return plugin(this$1$1); });
959};
960
961var prototypeAccessors = { state: { configurable: true } };
962
963Store.prototype.install = function install (app, injectKey) {
964 app.provide(injectKey || storeKey, this);
965 app.config.globalProperties.$store = this;
966
967 var useDevtools = this._devtools !== undefined
968 ? this._devtools
969 : true ;
970
971 if (useDevtools) {
972 addDevtools(app, this);
973 }
974};
975
976prototypeAccessors.state.get = function () {
977 return this._state.data
978};
979
980prototypeAccessors.state.set = function (v) {
981 {
982 assert(false, "use store.replaceState() to explicit replace store state.");
983 }
984};
985
986Store.prototype.commit = function commit (_type, _payload, _options) {
987 var this$1$1 = this;
988
989 // check object-style commit
990 var ref = unifyObjectStyle(_type, _payload, _options);
991 var type = ref.type;
992 var payload = ref.payload;
993 var options = ref.options;
994
995 var mutation = { type: type, payload: payload };
996 var entry = this._mutations[type];
997 if (!entry) {
998 {
999 console.error(("[vuex] unknown mutation type: " + type));
1000 }
1001 return
1002 }
1003 this._withCommit(function () {
1004 entry.forEach(function commitIterator (handler) {
1005 handler(payload);
1006 });
1007 });
1008
1009 this._subscribers
1010 .slice() // shallow copy to prevent iterator invalidation if subscriber synchronously calls unsubscribe
1011 .forEach(function (sub) { return sub(mutation, this$1$1.state); });
1012
1013 if (
1014 options && options.silent
1015 ) {
1016 console.warn(
1017 "[vuex] mutation type: " + type + ". Silent option has been removed. " +
1018 'Use the filter functionality in the vue-devtools'
1019 );
1020 }
1021};
1022
1023Store.prototype.dispatch = function dispatch (_type, _payload) {
1024 var this$1$1 = this;
1025
1026 // check object-style dispatch
1027 var ref = unifyObjectStyle(_type, _payload);
1028 var type = ref.type;
1029 var payload = ref.payload;
1030
1031 var action = { type: type, payload: payload };
1032 var entry = this._actions[type];
1033 if (!entry) {
1034 {
1035 console.error(("[vuex] unknown action type: " + type));
1036 }
1037 return
1038 }
1039
1040 try {
1041 this._actionSubscribers
1042 .slice() // shallow copy to prevent iterator invalidation if subscriber synchronously calls unsubscribe
1043 .filter(function (sub) { return sub.before; })
1044 .forEach(function (sub) { return sub.before(action, this$1$1.state); });
1045 } catch (e) {
1046 {
1047 console.warn("[vuex] error in before action subscribers: ");
1048 console.error(e);
1049 }
1050 }
1051
1052 var result = entry.length > 1
1053 ? Promise.all(entry.map(function (handler) { return handler(payload); }))
1054 : entry[0](payload);
1055
1056 return new Promise(function (resolve, reject) {
1057 result.then(function (res) {
1058 try {
1059 this$1$1._actionSubscribers
1060 .filter(function (sub) { return sub.after; })
1061 .forEach(function (sub) { return sub.after(action, this$1$1.state); });
1062 } catch (e) {
1063 {
1064 console.warn("[vuex] error in after action subscribers: ");
1065 console.error(e);
1066 }
1067 }
1068 resolve(res);
1069 }, function (error) {
1070 try {
1071 this$1$1._actionSubscribers
1072 .filter(function (sub) { return sub.error; })
1073 .forEach(function (sub) { return sub.error(action, this$1$1.state, error); });
1074 } catch (e) {
1075 {
1076 console.warn("[vuex] error in error action subscribers: ");
1077 console.error(e);
1078 }
1079 }
1080 reject(error);
1081 });
1082 })
1083};
1084
1085Store.prototype.subscribe = function subscribe (fn, options) {
1086 return genericSubscribe(fn, this._subscribers, options)
1087};
1088
1089Store.prototype.subscribeAction = function subscribeAction (fn, options) {
1090 var subs = typeof fn === 'function' ? { before: fn } : fn;
1091 return genericSubscribe(subs, this._actionSubscribers, options)
1092};
1093
1094Store.prototype.watch = function watch$1 (getter, cb, options) {
1095 var this$1$1 = this;
1096
1097 {
1098 assert(typeof getter === 'function', "store.watch only accepts a function.");
1099 }
1100 return watch(function () { return getter(this$1$1.state, this$1$1.getters); }, cb, Object.assign({}, options))
1101};
1102
1103Store.prototype.replaceState = function replaceState (state) {
1104 var this$1$1 = this;
1105
1106 this._withCommit(function () {
1107 this$1$1._state.data = state;
1108 });
1109};
1110
1111Store.prototype.registerModule = function registerModule (path, rawModule, options) {
1112 if ( options === void 0 ) options = {};
1113
1114 if (typeof path === 'string') { path = [path]; }
1115
1116 {
1117 assert(Array.isArray(path), "module path must be a string or an Array.");
1118 assert(path.length > 0, 'cannot register the root module by using registerModule.');
1119 }
1120
1121 this._modules.register(path, rawModule);
1122 installModule(this, this.state, path, this._modules.get(path), options.preserveState);
1123 // reset store to update getters...
1124 resetStoreState(this, this.state);
1125};
1126
1127Store.prototype.unregisterModule = function unregisterModule (path) {
1128 var this$1$1 = this;
1129
1130 if (typeof path === 'string') { path = [path]; }
1131
1132 {
1133 assert(Array.isArray(path), "module path must be a string or an Array.");
1134 }
1135
1136 this._modules.unregister(path);
1137 this._withCommit(function () {
1138 var parentState = getNestedState(this$1$1.state, path.slice(0, -1));
1139 delete parentState[path[path.length - 1]];
1140 });
1141 resetStore(this);
1142};
1143
1144Store.prototype.hasModule = function hasModule (path) {
1145 if (typeof path === 'string') { path = [path]; }
1146
1147 {
1148 assert(Array.isArray(path), "module path must be a string or an Array.");
1149 }
1150
1151 return this._modules.isRegistered(path)
1152};
1153
1154Store.prototype.hotUpdate = function hotUpdate (newOptions) {
1155 this._modules.update(newOptions);
1156 resetStore(this, true);
1157};
1158
1159Store.prototype._withCommit = function _withCommit (fn) {
1160 var committing = this._committing;
1161 this._committing = true;
1162 fn();
1163 this._committing = committing;
1164};
1165
1166Object.defineProperties( Store.prototype, prototypeAccessors );
1167
1168/**
1169 * Reduce the code which written in Vue.js for getting the state.
1170 * @param {String} [namespace] - Module's namespace
1171 * @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.
1172 * @param {Object}
1173 */
1174var mapState = normalizeNamespace(function (namespace, states) {
1175 var res = {};
1176 if (!isValidMap(states)) {
1177 console.error('[vuex] mapState: mapper parameter must be either an Array or an Object');
1178 }
1179 normalizeMap(states).forEach(function (ref) {
1180 var key = ref.key;
1181 var val = ref.val;
1182
1183 res[key] = function mappedState () {
1184 var state = this.$store.state;
1185 var getters = this.$store.getters;
1186 if (namespace) {
1187 var module = getModuleByNamespace(this.$store, 'mapState', namespace);
1188 if (!module) {
1189 return
1190 }
1191 state = module.context.state;
1192 getters = module.context.getters;
1193 }
1194 return typeof val === 'function'
1195 ? val.call(this, state, getters)
1196 : state[val]
1197 };
1198 // mark vuex getter for devtools
1199 res[key].vuex = true;
1200 });
1201 return res
1202});
1203
1204/**
1205 * Reduce the code which written in Vue.js for committing the mutation
1206 * @param {String} [namespace] - Module's namespace
1207 * @param {Object|Array} mutations # Object's item can be a function which accept `commit` function as the first param, it can accept another params. You can commit mutation and do any other things in this function. specially, You need to pass anthor params from the mapped function.
1208 * @return {Object}
1209 */
1210var mapMutations = normalizeNamespace(function (namespace, mutations) {
1211 var res = {};
1212 if (!isValidMap(mutations)) {
1213 console.error('[vuex] mapMutations: mapper parameter must be either an Array or an Object');
1214 }
1215 normalizeMap(mutations).forEach(function (ref) {
1216 var key = ref.key;
1217 var val = ref.val;
1218
1219 res[key] = function mappedMutation () {
1220 var args = [], len = arguments.length;
1221 while ( len-- ) args[ len ] = arguments[ len ];
1222
1223 // Get the commit method from store
1224 var commit = this.$store.commit;
1225 if (namespace) {
1226 var module = getModuleByNamespace(this.$store, 'mapMutations', namespace);
1227 if (!module) {
1228 return
1229 }
1230 commit = module.context.commit;
1231 }
1232 return typeof val === 'function'
1233 ? val.apply(this, [commit].concat(args))
1234 : commit.apply(this.$store, [val].concat(args))
1235 };
1236 });
1237 return res
1238});
1239
1240/**
1241 * Reduce the code which written in Vue.js for getting the getters
1242 * @param {String} [namespace] - Module's namespace
1243 * @param {Object|Array} getters
1244 * @return {Object}
1245 */
1246var mapGetters = normalizeNamespace(function (namespace, getters) {
1247 var res = {};
1248 if (!isValidMap(getters)) {
1249 console.error('[vuex] mapGetters: mapper parameter must be either an Array or an Object');
1250 }
1251 normalizeMap(getters).forEach(function (ref) {
1252 var key = ref.key;
1253 var val = ref.val;
1254
1255 // The namespace has been mutated by normalizeNamespace
1256 val = namespace + val;
1257 res[key] = function mappedGetter () {
1258 if (namespace && !getModuleByNamespace(this.$store, 'mapGetters', namespace)) {
1259 return
1260 }
1261 if (!(val in this.$store.getters)) {
1262 console.error(("[vuex] unknown getter: " + val));
1263 return
1264 }
1265 return this.$store.getters[val]
1266 };
1267 // mark vuex getter for devtools
1268 res[key].vuex = true;
1269 });
1270 return res
1271});
1272
1273/**
1274 * Reduce the code which written in Vue.js for dispatch the action
1275 * @param {String} [namespace] - Module's namespace
1276 * @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.
1277 * @return {Object}
1278 */
1279var mapActions = normalizeNamespace(function (namespace, actions) {
1280 var res = {};
1281 if (!isValidMap(actions)) {
1282 console.error('[vuex] mapActions: mapper parameter must be either an Array or an Object');
1283 }
1284 normalizeMap(actions).forEach(function (ref) {
1285 var key = ref.key;
1286 var val = ref.val;
1287
1288 res[key] = function mappedAction () {
1289 var args = [], len = arguments.length;
1290 while ( len-- ) args[ len ] = arguments[ len ];
1291
1292 // get dispatch function from store
1293 var dispatch = this.$store.dispatch;
1294 if (namespace) {
1295 var module = getModuleByNamespace(this.$store, 'mapActions', namespace);
1296 if (!module) {
1297 return
1298 }
1299 dispatch = module.context.dispatch;
1300 }
1301 return typeof val === 'function'
1302 ? val.apply(this, [dispatch].concat(args))
1303 : dispatch.apply(this.$store, [val].concat(args))
1304 };
1305 });
1306 return res
1307});
1308
1309/**
1310 * Rebinding namespace param for mapXXX function in special scoped, and return them by simple object
1311 * @param {String} namespace
1312 * @return {Object}
1313 */
1314var createNamespacedHelpers = function (namespace) { return ({
1315 mapState: mapState.bind(null, namespace),
1316 mapGetters: mapGetters.bind(null, namespace),
1317 mapMutations: mapMutations.bind(null, namespace),
1318 mapActions: mapActions.bind(null, namespace)
1319}); };
1320
1321/**
1322 * Normalize the map
1323 * normalizeMap([1, 2, 3]) => [ { key: 1, val: 1 }, { key: 2, val: 2 }, { key: 3, val: 3 } ]
1324 * normalizeMap({a: 1, b: 2, c: 3}) => [ { key: 'a', val: 1 }, { key: 'b', val: 2 }, { key: 'c', val: 3 } ]
1325 * @param {Array|Object} map
1326 * @return {Object}
1327 */
1328function normalizeMap (map) {
1329 if (!isValidMap(map)) {
1330 return []
1331 }
1332 return Array.isArray(map)
1333 ? map.map(function (key) { return ({ key: key, val: key }); })
1334 : Object.keys(map).map(function (key) { return ({ key: key, val: map[key] }); })
1335}
1336
1337/**
1338 * Validate whether given map is valid or not
1339 * @param {*} map
1340 * @return {Boolean}
1341 */
1342function isValidMap (map) {
1343 return Array.isArray(map) || isObject(map)
1344}
1345
1346/**
1347 * 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.
1348 * @param {Function} fn
1349 * @return {Function}
1350 */
1351function normalizeNamespace (fn) {
1352 return function (namespace, map) {
1353 if (typeof namespace !== 'string') {
1354 map = namespace;
1355 namespace = '';
1356 } else if (namespace.charAt(namespace.length - 1) !== '/') {
1357 namespace += '/';
1358 }
1359 return fn(namespace, map)
1360 }
1361}
1362
1363/**
1364 * Search a special module from store by namespace. if module not exist, print error message.
1365 * @param {Object} store
1366 * @param {String} helper
1367 * @param {String} namespace
1368 * @return {Object}
1369 */
1370function getModuleByNamespace (store, helper, namespace) {
1371 var module = store._modulesNamespaceMap[namespace];
1372 if (!module) {
1373 console.error(("[vuex] module namespace not found in " + helper + "(): " + namespace));
1374 }
1375 return module
1376}
1377
1378// Credits: borrowed code from fcomb/redux-logger
1379
1380function createLogger (ref) {
1381 if ( ref === void 0 ) ref = {};
1382 var collapsed = ref.collapsed; if ( collapsed === void 0 ) collapsed = true;
1383 var filter = ref.filter; if ( filter === void 0 ) filter = function (mutation, stateBefore, stateAfter) { return true; };
1384 var transformer = ref.transformer; if ( transformer === void 0 ) transformer = function (state) { return state; };
1385 var mutationTransformer = ref.mutationTransformer; if ( mutationTransformer === void 0 ) mutationTransformer = function (mut) { return mut; };
1386 var actionFilter = ref.actionFilter; if ( actionFilter === void 0 ) actionFilter = function (action, state) { return true; };
1387 var actionTransformer = ref.actionTransformer; if ( actionTransformer === void 0 ) actionTransformer = function (act) { return act; };
1388 var logMutations = ref.logMutations; if ( logMutations === void 0 ) logMutations = true;
1389 var logActions = ref.logActions; if ( logActions === void 0 ) logActions = true;
1390 var logger = ref.logger; if ( logger === void 0 ) logger = console;
1391
1392 return function (store) {
1393 var prevState = deepCopy(store.state);
1394
1395 if (typeof logger === 'undefined') {
1396 return
1397 }
1398
1399 if (logMutations) {
1400 store.subscribe(function (mutation, state) {
1401 var nextState = deepCopy(state);
1402
1403 if (filter(mutation, prevState, nextState)) {
1404 var formattedTime = getFormattedTime();
1405 var formattedMutation = mutationTransformer(mutation);
1406 var message = "mutation " + (mutation.type) + formattedTime;
1407
1408 startMessage(logger, message, collapsed);
1409 logger.log('%c prev state', 'color: #9E9E9E; font-weight: bold', transformer(prevState));
1410 logger.log('%c mutation', 'color: #03A9F4; font-weight: bold', formattedMutation);
1411 logger.log('%c next state', 'color: #4CAF50; font-weight: bold', transformer(nextState));
1412 endMessage(logger);
1413 }
1414
1415 prevState = nextState;
1416 });
1417 }
1418
1419 if (logActions) {
1420 store.subscribeAction(function (action, state) {
1421 if (actionFilter(action, state)) {
1422 var formattedTime = getFormattedTime();
1423 var formattedAction = actionTransformer(action);
1424 var message = "action " + (action.type) + formattedTime;
1425
1426 startMessage(logger, message, collapsed);
1427 logger.log('%c action', 'color: #03A9F4; font-weight: bold', formattedAction);
1428 endMessage(logger);
1429 }
1430 });
1431 }
1432 }
1433}
1434
1435function startMessage (logger, message, collapsed) {
1436 var startMessage = collapsed
1437 ? logger.groupCollapsed
1438 : logger.group;
1439
1440 // render
1441 try {
1442 startMessage.call(logger, message);
1443 } catch (e) {
1444 logger.log(message);
1445 }
1446}
1447
1448function endMessage (logger) {
1449 try {
1450 logger.groupEnd();
1451 } catch (e) {
1452 logger.log('—— log end ——');
1453 }
1454}
1455
1456function getFormattedTime () {
1457 var time = new Date();
1458 return (" @ " + (pad(time.getHours(), 2)) + ":" + (pad(time.getMinutes(), 2)) + ":" + (pad(time.getSeconds(), 2)) + "." + (pad(time.getMilliseconds(), 3)))
1459}
1460
1461function repeat (str, times) {
1462 return (new Array(times + 1)).join(str)
1463}
1464
1465function pad (num, maxLength) {
1466 return repeat('0', maxLength - num.toString().length) + num
1467}
1468
1469var index = {
1470 version: '4.1.0',
1471 Store: Store,
1472 storeKey: storeKey,
1473 createStore: createStore,
1474 useStore: useStore,
1475 mapState: mapState,
1476 mapMutations: mapMutations,
1477 mapGetters: mapGetters,
1478 mapActions: mapActions,
1479 createNamespacedHelpers: createNamespacedHelpers,
1480 createLogger: createLogger
1481};
1482
1483export default index;
1484export { Store, createLogger, createNamespacedHelpers, createStore, mapActions, mapGetters, mapMutations, mapState, storeKey, useStore };