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