UNPKG

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