Localisation updates from https://translatewiki.net.
[mediawiki.git] / resources / lib / pinia / pinia.iife.js
blob2bdc4216d7ad174629335b5c7af51807669b1b0f
1 /*!
2   * pinia v2.0.16
3   * (c) 2022 Eduardo San Martin Morote
4   * @license MIT
5   */
6 var Pinia = (function (exports, vueDemi) {
7   'use strict';
9   /**\r
10    * setActivePinia must be called to handle SSR at the top of functions like\r
11    * `fetch`, `setup`, `serverPrefetch` and others\r
12    */\r
13   let activePinia;\r
14   /**\r
15    * Sets or unsets the active pinia. Used in SSR and internally when calling\r
16    * actions and getters\r
17    *\r
18    * @param pinia - Pinia instance\r
19    */\r
20   const setActivePinia = (pinia) => (activePinia = pinia);\r
21   /**\r
22    * Get the currently active pinia if there is any.\r
23    */\r
24   const getActivePinia = () => (vueDemi.getCurrentInstance() && vueDemi.inject(piniaSymbol)) || activePinia;\r
25   const piniaSymbol = (Symbol('pinia') );
27   function getDevtoolsGlobalHook() {
28       return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__;
29   }
30   function getTarget() {
31       // @ts-ignore
32       return (typeof navigator !== 'undefined' && typeof window !== 'undefined')
33           ? window
34           : typeof global !== 'undefined'
35               ? global
36               : {};
37   }
38   const isProxyAvailable = typeof Proxy === 'function';
40   const HOOK_SETUP = 'devtools-plugin:setup';
41   const HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set';
43   let supported;
44   let perf;
45   function isPerformanceSupported() {
46       var _a;
47       if (supported !== undefined) {
48           return supported;
49       }
50       if (typeof window !== 'undefined' && window.performance) {
51           supported = true;
52           perf = window.performance;
53       }
54       else if (typeof global !== 'undefined' && ((_a = global.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) {
55           supported = true;
56           perf = global.perf_hooks.performance;
57       }
58       else {
59           supported = false;
60       }
61       return supported;
62   }
63   function now() {
64       return isPerformanceSupported() ? perf.now() : Date.now();
65   }
67   class ApiProxy {
68       constructor(plugin, hook) {
69           this.target = null;
70           this.targetQueue = [];
71           this.onQueue = [];
72           this.plugin = plugin;
73           this.hook = hook;
74           const defaultSettings = {};
75           if (plugin.settings) {
76               for (const id in plugin.settings) {
77                   const item = plugin.settings[id];
78                   defaultSettings[id] = item.defaultValue;
79               }
80           }
81           const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`;
82           let currentSettings = Object.assign({}, defaultSettings);
83           try {
84               const raw = localStorage.getItem(localSettingsSaveId);
85               const data = JSON.parse(raw);
86               Object.assign(currentSettings, data);
87           }
88           catch (e) {
89               // noop
90           }
91           this.fallbacks = {
92               getSettings() {
93                   return currentSettings;
94               },
95               setSettings(value) {
96                   try {
97                       localStorage.setItem(localSettingsSaveId, JSON.stringify(value));
98                   }
99                   catch (e) {
100                       // noop
101                   }
102                   currentSettings = value;
103               },
104               now() {
105                   return now();
106               },
107           };
108           if (hook) {
109               hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => {
110                   if (pluginId === this.plugin.id) {
111                       this.fallbacks.setSettings(value);
112                   }
113               });
114           }
115           this.proxiedOn = new Proxy({}, {
116               get: (_target, prop) => {
117                   if (this.target) {
118                       return this.target.on[prop];
119                   }
120                   else {
121                       return (...args) => {
122                           this.onQueue.push({
123                               method: prop,
124                               args,
125                           });
126                       };
127                   }
128               },
129           });
130           this.proxiedTarget = new Proxy({}, {
131               get: (_target, prop) => {
132                   if (this.target) {
133                       return this.target[prop];
134                   }
135                   else if (prop === 'on') {
136                       return this.proxiedOn;
137                   }
138                   else if (Object.keys(this.fallbacks).includes(prop)) {
139                       return (...args) => {
140                           this.targetQueue.push({
141                               method: prop,
142                               args,
143                               resolve: () => { },
144                           });
145                           return this.fallbacks[prop](...args);
146                       };
147                   }
148                   else {
149                       return (...args) => {
150                           return new Promise(resolve => {
151                               this.targetQueue.push({
152                                   method: prop,
153                                   args,
154                                   resolve,
155                               });
156                           });
157                       };
158                   }
159               },
160           });
161       }
162       async setRealTarget(target) {
163           this.target = target;
164           for (const item of this.onQueue) {
165               this.target.on[item.method](...item.args);
166           }
167           for (const item of this.targetQueue) {
168               item.resolve(await this.target[item.method](...item.args));
169           }
170       }
171   }
173   function setupDevtoolsPlugin(pluginDescriptor, setupFn) {
174       const descriptor = pluginDescriptor;
175       const target = getTarget();
176       const hook = getDevtoolsGlobalHook();
177       const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy;
178       if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) {
179           hook.emit(HOOK_SETUP, pluginDescriptor, setupFn);
180       }
181       else {
182           const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null;
183           const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || [];
184           list.push({
185               pluginDescriptor: descriptor,
186               setupFn,
187               proxy,
188           });
189           if (proxy)
190               setupFn(proxy.proxiedTarget);
191       }
192   }
194   function isPlainObject(\r
195   // eslint-disable-next-line @typescript-eslint/no-explicit-any\r
196   o) {\r
197       return (o &&\r
198           typeof o === 'object' &&\r
199           Object.prototype.toString.call(o) === '[object Object]' &&\r
200           typeof o.toJSON !== 'function');\r
201   }\r
202   // type DeepReadonly<T> = { readonly [P in keyof T]: DeepReadonly<T[P]> }\r
203   // TODO: can we change these to numbers?\r
204   /**\r
205    * Possible types for SubscriptionCallback\r
206    */\r
207   exports.MutationType = void 0;\r
208   (function (MutationType) {\r
209       /**\r
210        * Direct mutation of the state:\r
211        *\r
212        * - `store.name = 'new name'`\r
213        * - `store.$state.name = 'new name'`\r
214        * - `store.list.push('new item')`\r
215        */\r
216       MutationType["direct"] = "direct";\r
217       /**\r
218        * Mutated the state with `$patch` and an object\r
219        *\r
220        * - `store.$patch({ name: 'newName' })`\r
221        */\r
222       MutationType["patchObject"] = "patch object";\r
223       /**\r
224        * Mutated the state with `$patch` and a function\r
225        *\r
226        * - `store.$patch(state => state.name = 'newName')`\r
227        */\r
228       MutationType["patchFunction"] = "patch function";\r
229       // maybe reset? for $state = {} and $reset\r
230   })(exports.MutationType || (exports.MutationType = {}));
232   const IS_CLIENT = typeof window !== 'undefined';
234   /*\r
235    * FileSaver.js A saveAs() FileSaver implementation.\r
236    *\r
237    * Originally by Eli Grey, adapted as an ESM module by Eduardo San Martin\r
238    * Morote.\r
239    *\r
240    * License : MIT\r
241    */\r
242   // The one and only way of getting global scope in all environments\r
243   // https://stackoverflow.com/q/3277182/1008999\r
244   const _global = /*#__PURE__*/ (() => typeof window === 'object' && window.window === window\r
245       ? window\r
246       : typeof self === 'object' && self.self === self\r
247           ? self\r
248           : typeof global === 'object' && global.global === global\r
249               ? global\r
250               : typeof globalThis === 'object'\r
251                   ? globalThis\r
252                   : { HTMLElement: null })();\r
253   function bom(blob, { autoBom = false } = {}) {\r
254       // prepend BOM for UTF-8 XML and text/* types (including HTML)\r
255       // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\r
256       if (autoBom &&\r
257           /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {\r
258           return new Blob([String.fromCharCode(0xfeff), blob], { type: blob.type });\r
259       }\r
260       return blob;\r
261   }\r
262   function download(url, name, opts) {\r
263       const xhr = new XMLHttpRequest();\r
264       xhr.open('GET', url);\r
265       xhr.responseType = 'blob';\r
266       xhr.onload = function () {\r
267           saveAs(xhr.response, name, opts);\r
268       };\r
269       xhr.onerror = function () {\r
270           console.error('could not download file');\r
271       };\r
272       xhr.send();\r
273   }\r
274   function corsEnabled(url) {\r
275       const xhr = new XMLHttpRequest();\r
276       // use sync to avoid popup blocker\r
277       xhr.open('HEAD', url, false);\r
278       try {\r
279           xhr.send();\r
280       }\r
281       catch (e) { }\r
282       return xhr.status >= 200 && xhr.status <= 299;\r
283   }\r
284   // `a.click()` doesn't work for all browsers (#465)\r
285   function click(node) {\r
286       try {\r
287           node.dispatchEvent(new MouseEvent('click'));\r
288       }\r
289       catch (e) {\r
290           const evt = document.createEvent('MouseEvents');\r
291           evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);\r
292           node.dispatchEvent(evt);\r
293       }\r
294   }\r
295   const _navigator = \r
296    typeof navigator === 'object' ? navigator : { userAgent: '' };\r
297   // Detect WebView inside a native macOS app by ruling out all browsers\r
298   // We just need to check for 'Safari' because all other browsers (besides Firefox) include that too\r
299   // https://www.whatismybrowser.com/guides/the-latest-user-agent/macos\r
300   const isMacOSWebView = /*#__PURE__*/ (() => /Macintosh/.test(_navigator.userAgent) &&\r
301       /AppleWebKit/.test(_navigator.userAgent) &&\r
302       !/Safari/.test(_navigator.userAgent))();\r
303   const saveAs = !IS_CLIENT\r
304       ? () => { } // noop\r
305       : // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView or mini program\r
306           typeof HTMLAnchorElement !== 'undefined' &&\r
307               'download' in HTMLAnchorElement.prototype &&\r
308               !isMacOSWebView\r
309               ? downloadSaveAs\r
310               : // Use msSaveOrOpenBlob as a second approach\r
311                   'msSaveOrOpenBlob' in _navigator\r
312                       ? msSaveAs\r
313                       : // Fallback to using FileReader and a popup\r
314                           fileSaverSaveAs;\r
315   function downloadSaveAs(blob, name = 'download', opts) {\r
316       const a = document.createElement('a');\r
317       a.download = name;\r
318       a.rel = 'noopener'; // tabnabbing\r
319       // TODO: detect chrome extensions & packaged apps\r
320       // a.target = '_blank'\r
321       if (typeof blob === 'string') {\r
322           // Support regular links\r
323           a.href = blob;\r
324           if (a.origin !== location.origin) {\r
325               if (corsEnabled(a.href)) {\r
326                   download(blob, name, opts);\r
327               }\r
328               else {\r
329                   a.target = '_blank';\r
330                   click(a);\r
331               }\r
332           }\r
333           else {\r
334               click(a);\r
335           }\r
336       }\r
337       else {\r
338           // Support blobs\r
339           a.href = URL.createObjectURL(blob);\r
340           setTimeout(function () {\r
341               URL.revokeObjectURL(a.href);\r
342           }, 4e4); // 40s\r
343           setTimeout(function () {\r
344               click(a);\r
345           }, 0);\r
346       }\r
347   }\r
348   function msSaveAs(blob, name = 'download', opts) {\r
349       if (typeof blob === 'string') {\r
350           if (corsEnabled(blob)) {\r
351               download(blob, name, opts);\r
352           }\r
353           else {\r
354               const a = document.createElement('a');\r
355               a.href = blob;\r
356               a.target = '_blank';\r
357               setTimeout(function () {\r
358                   click(a);\r
359               });\r
360           }\r
361       }\r
362       else {\r
363           // @ts-ignore: works on windows\r
364           navigator.msSaveOrOpenBlob(bom(blob, opts), name);\r
365       }\r
366   }\r
367   function fileSaverSaveAs(blob, name, opts, popup) {\r
368       // Open a popup immediately do go around popup blocker\r
369       // Mostly only available on user interaction and the fileReader is async so...\r
370       popup = popup || open('', '_blank');\r
371       if (popup) {\r
372           popup.document.title = popup.document.body.innerText = 'downloading...';\r
373       }\r
374       if (typeof blob === 'string')\r
375           return download(blob, name, opts);\r
376       const force = blob.type === 'application/octet-stream';\r
377       const isSafari = /constructor/i.test(String(_global.HTMLElement)) || 'safari' in _global;\r
378       const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);\r
379       if ((isChromeIOS || (force && isSafari) || isMacOSWebView) &&\r
380           typeof FileReader !== 'undefined') {\r
381           // Safari doesn't allow downloading of blob URLs\r
382           const reader = new FileReader();\r
383           reader.onloadend = function () {\r
384               let url = reader.result;\r
385               if (typeof url !== 'string') {\r
386                   popup = null;\r
387                   throw new Error('Wrong reader.result type');\r
388               }\r
389               url = isChromeIOS\r
390                   ? url\r
391                   : url.replace(/^data:[^;]*;/, 'data:attachment/file;');\r
392               if (popup) {\r
393                   popup.location.href = url;\r
394               }\r
395               else {\r
396                   location.assign(url);\r
397               }\r
398               popup = null; // reverse-tabnabbing #460\r
399           };\r
400           reader.readAsDataURL(blob);\r
401       }\r
402       else {\r
403           const url = URL.createObjectURL(blob);\r
404           if (popup)\r
405               popup.location.assign(url);\r
406           else\r
407               location.href = url;\r
408           popup = null; // reverse-tabnabbing #460\r
409           setTimeout(function () {\r
410               URL.revokeObjectURL(url);\r
411           }, 4e4); // 40s\r
412       }\r
413   }
415   /**\r
416    * Shows a toast or console.log\r
417    *\r
418    * @param message - message to log\r
419    * @param type - different color of the tooltip\r
420    */\r
421   function toastMessage(message, type) {\r
422       const piniaMessage = '🍍 ' + message;\r
423       if (typeof __VUE_DEVTOOLS_TOAST__ === 'function') {\r
424           __VUE_DEVTOOLS_TOAST__(piniaMessage, type);\r
425       }\r
426       else if (type === 'error') {\r
427           console.error(piniaMessage);\r
428       }\r
429       else if (type === 'warn') {\r
430           console.warn(piniaMessage);\r
431       }\r
432       else {\r
433           console.log(piniaMessage);\r
434       }\r
435   }\r
436   function isPinia(o) {\r
437       return '_a' in o && 'install' in o;\r
438   }
440   function checkClipboardAccess() {\r
441       if (!('clipboard' in navigator)) {\r
442           toastMessage(`Your browser doesn't support the Clipboard API`, 'error');\r
443           return true;\r
444       }\r
445   }\r
446   function checkNotFocusedError(error) {\r
447       if (error instanceof Error &&\r
448           error.message.toLowerCase().includes('document is not focused')) {\r
449           toastMessage('You need to activate the "Emulate a focused page" setting in the "Rendering" panel of devtools.', 'warn');\r
450           return true;\r
451       }\r
452       return false;\r
453   }\r
454   async function actionGlobalCopyState(pinia) {\r
455       if (checkClipboardAccess())\r
456           return;\r
457       try {\r
458           await navigator.clipboard.writeText(JSON.stringify(pinia.state.value));\r
459           toastMessage('Global state copied to clipboard.');\r
460       }\r
461       catch (error) {\r
462           if (checkNotFocusedError(error))\r
463               return;\r
464           toastMessage(`Failed to serialize the state. Check the console for more details.`, 'error');\r
465           console.error(error);\r
466       }\r
467   }\r
468   async function actionGlobalPasteState(pinia) {\r
469       if (checkClipboardAccess())\r
470           return;\r
471       try {\r
472           pinia.state.value = JSON.parse(await navigator.clipboard.readText());\r
473           toastMessage('Global state pasted from clipboard.');\r
474       }\r
475       catch (error) {\r
476           if (checkNotFocusedError(error))\r
477               return;\r
478           toastMessage(`Failed to deserialize the state from clipboard. Check the console for more details.`, 'error');\r
479           console.error(error);\r
480       }\r
481   }\r
482   async function actionGlobalSaveState(pinia) {\r
483       try {\r
484           saveAs(new Blob([JSON.stringify(pinia.state.value)], {\r
485               type: 'text/plain;charset=utf-8',\r
486           }), 'pinia-state.json');\r
487       }\r
488       catch (error) {\r
489           toastMessage(`Failed to export the state as JSON. Check the console for more details.`, 'error');\r
490           console.error(error);\r
491       }\r
492   }\r
493   let fileInput;\r
494   function getFileOpener() {\r
495       if (!fileInput) {\r
496           fileInput = document.createElement('input');\r
497           fileInput.type = 'file';\r
498           fileInput.accept = '.json';\r
499       }\r
500       function openFile() {\r
501           return new Promise((resolve, reject) => {\r
502               fileInput.onchange = async () => {\r
503                   const files = fileInput.files;\r
504                   if (!files)\r
505                       return resolve(null);\r
506                   const file = files.item(0);\r
507                   if (!file)\r
508                       return resolve(null);\r
509                   return resolve({ text: await file.text(), file });\r
510               };\r
511               // @ts-ignore: TODO: changed from 4.3 to 4.4\r
512               fileInput.oncancel = () => resolve(null);\r
513               fileInput.onerror = reject;\r
514               fileInput.click();\r
515           });\r
516       }\r
517       return openFile;\r
518   }\r
519   async function actionGlobalOpenStateFile(pinia) {\r
520       try {\r
521           const open = await getFileOpener();\r
522           const result = await open();\r
523           if (!result)\r
524               return;\r
525           const { text, file } = result;\r
526           pinia.state.value = JSON.parse(text);\r
527           toastMessage(`Global state imported from "${file.name}".`);\r
528       }\r
529       catch (error) {\r
530           toastMessage(`Failed to export the state as JSON. Check the console for more details.`, 'error');\r
531           console.error(error);\r
532       }\r
533   }
535   function formatDisplay(display) {\r
536       return {\r
537           _custom: {\r
538               display,\r
539           },\r
540       };\r
541   }\r
542   const PINIA_ROOT_LABEL = '🍍 Pinia (root)';\r
543   const PINIA_ROOT_ID = '_root';\r
544   function formatStoreForInspectorTree(store) {\r
545       return isPinia(store)\r
546           ? {\r
547               id: PINIA_ROOT_ID,\r
548               label: PINIA_ROOT_LABEL,\r
549           }\r
550           : {\r
551               id: store.$id,\r
552               label: store.$id,\r
553           };\r
554   }\r
555   function formatStoreForInspectorState(store) {\r
556       if (isPinia(store)) {\r
557           const storeNames = Array.from(store._s.keys());\r
558           const storeMap = store._s;\r
559           const state = {\r
560               state: storeNames.map((storeId) => ({\r
561                   editable: true,\r
562                   key: storeId,\r
563                   value: store.state.value[storeId],\r
564               })),\r
565               getters: storeNames\r
566                   .filter((id) => storeMap.get(id)._getters)\r
567                   .map((id) => {\r
568                   const store = storeMap.get(id);\r
569                   return {\r
570                       editable: false,\r
571                       key: id,\r
572                       value: store._getters.reduce((getters, key) => {\r
573                           getters[key] = store[key];\r
574                           return getters;\r
575                       }, {}),\r
576                   };\r
577               }),\r
578           };\r
579           return state;\r
580       }\r
581       const state = {\r
582           state: Object.keys(store.$state).map((key) => ({\r
583               editable: true,\r
584               key,\r
585               value: store.$state[key],\r
586           })),\r
587       };\r
588       // avoid adding empty getters\r
589       if (store._getters && store._getters.length) {\r
590           state.getters = store._getters.map((getterName) => ({\r
591               editable: false,\r
592               key: getterName,\r
593               value: store[getterName],\r
594           }));\r
595       }\r
596       if (store._customProperties.size) {\r
597           state.customProperties = Array.from(store._customProperties).map((key) => ({\r
598               editable: true,\r
599               key,\r
600               value: store[key],\r
601           }));\r
602       }\r
603       return state;\r
604   }\r
605   function formatEventData(events) {\r
606       if (!events)\r
607           return {};\r
608       if (Array.isArray(events)) {\r
609           // TODO: handle add and delete for arrays and objects\r
610           return events.reduce((data, event) => {\r
611               data.keys.push(event.key);\r
612               data.operations.push(event.type);\r
613               data.oldValue[event.key] = event.oldValue;\r
614               data.newValue[event.key] = event.newValue;\r
615               return data;\r
616           }, {\r
617               oldValue: {},\r
618               keys: [],\r
619               operations: [],\r
620               newValue: {},\r
621           });\r
622       }\r
623       else {\r
624           return {\r
625               operation: formatDisplay(events.type),\r
626               key: formatDisplay(events.key),\r
627               oldValue: events.oldValue,\r
628               newValue: events.newValue,\r
629           };\r
630       }\r
631   }\r
632   function formatMutationType(type) {\r
633       switch (type) {\r
634           case exports.MutationType.direct:\r
635               return 'mutation';\r
636           case exports.MutationType.patchFunction:\r
637               return '$patch';\r
638           case exports.MutationType.patchObject:\r
639               return '$patch';\r
640           default:\r
641               return 'unknown';\r
642       }\r
643   }
645   // timeline can be paused when directly changing the state\r
646   let isTimelineActive = true;\r
647   const componentStateTypes = [];\r
648   const MUTATIONS_LAYER_ID = 'pinia:mutations';\r
649   const INSPECTOR_ID = 'pinia';\r
650   /**\r
651    * Gets the displayed name of a store in devtools\r
652    *\r
653    * @param id - id of the store\r
654    * @returns a formatted string\r
655    */\r
656   const getStoreType = (id) => '🍍 ' + id;\r
657   /**\r
658    * Add the pinia plugin without any store. Allows displaying a Pinia plugin tab\r
659    * as soon as it is added to the application.\r
660    *\r
661    * @param app - Vue application\r
662    * @param pinia - pinia instance\r
663    */\r
664   function registerPiniaDevtools(app, pinia) {\r
665       setupDevtoolsPlugin({\r
666           id: 'dev.esm.pinia',\r
667           label: 'Pinia 🍍',\r
668           logo: 'https://pinia.vuejs.org/logo.svg',\r
669           packageName: 'pinia',\r
670           homepage: 'https://pinia.vuejs.org',\r
671           componentStateTypes,\r
672           app,\r
673       }, (api) => {\r
674           if (typeof api.now !== 'function') {\r
675               toastMessage('You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html.');\r
676           }\r
677           api.addTimelineLayer({\r
678               id: MUTATIONS_LAYER_ID,\r
679               label: `Pinia 🍍`,\r
680               color: 0xe5df88,\r
681           });\r
682           api.addInspector({\r
683               id: INSPECTOR_ID,\r
684               label: 'Pinia 🍍',\r
685               icon: 'storage',\r
686               treeFilterPlaceholder: 'Search stores',\r
687               actions: [\r
688                   {\r
689                       icon: 'content_copy',\r
690                       action: () => {\r
691                           actionGlobalCopyState(pinia);\r
692                       },\r
693                       tooltip: 'Serialize and copy the state',\r
694                   },\r
695                   {\r
696                       icon: 'content_paste',\r
697                       action: async () => {\r
698                           await actionGlobalPasteState(pinia);\r
699                           api.sendInspectorTree(INSPECTOR_ID);\r
700                           api.sendInspectorState(INSPECTOR_ID);\r
701                       },\r
702                       tooltip: 'Replace the state with the content of your clipboard',\r
703                   },\r
704                   {\r
705                       icon: 'save',\r
706                       action: () => {\r
707                           actionGlobalSaveState(pinia);\r
708                       },\r
709                       tooltip: 'Save the state as a JSON file',\r
710                   },\r
711                   {\r
712                       icon: 'folder_open',\r
713                       action: async () => {\r
714                           await actionGlobalOpenStateFile(pinia);\r
715                           api.sendInspectorTree(INSPECTOR_ID);\r
716                           api.sendInspectorState(INSPECTOR_ID);\r
717                       },\r
718                       tooltip: 'Import the state from a JSON file',\r
719                   },\r
720               ],\r
721           });\r
722           api.on.inspectComponent((payload, ctx) => {\r
723               const proxy = (payload.componentInstance &&\r
724                   payload.componentInstance.proxy);\r
725               if (proxy && proxy._pStores) {\r
726                   const piniaStores = payload.componentInstance.proxy._pStores;\r
727                   Object.values(piniaStores).forEach((store) => {\r
728                       payload.instanceData.state.push({\r
729                           type: getStoreType(store.$id),\r
730                           key: 'state',\r
731                           editable: true,\r
732                           value: store._isOptionsAPI\r
733                               ? {\r
734                                   _custom: {\r
735                                       value: store.$state,\r
736                                       actions: [\r
737                                           {\r
738                                               icon: 'restore',\r
739                                               tooltip: 'Reset the state of this store',\r
740                                               action: () => store.$reset(),\r
741                                           },\r
742                                       ],\r
743                                   },\r
744                               }\r
745                               : store.$state,\r
746                       });\r
747                       if (store._getters && store._getters.length) {\r
748                           payload.instanceData.state.push({\r
749                               type: getStoreType(store.$id),\r
750                               key: 'getters',\r
751                               editable: false,\r
752                               value: store._getters.reduce((getters, key) => {\r
753                                   try {\r
754                                       getters[key] = store[key];\r
755                                   }\r
756                                   catch (error) {\r
757                                       // @ts-expect-error: we just want to show it in devtools\r
758                                       getters[key] = error;\r
759                                   }\r
760                                   return getters;\r
761                               }, {}),\r
762                           });\r
763                       }\r
764                   });\r
765               }\r
766           });\r
767           api.on.getInspectorTree((payload) => {\r
768               if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {\r
769                   let stores = [pinia];\r
770                   stores = stores.concat(Array.from(pinia._s.values()));\r
771                   payload.rootNodes = (payload.filter\r
772                       ? stores.filter((store) => '$id' in store\r
773                           ? store.$id\r
774                               .toLowerCase()\r
775                               .includes(payload.filter.toLowerCase())\r
776                           : PINIA_ROOT_LABEL.toLowerCase().includes(payload.filter.toLowerCase()))\r
777                       : stores).map(formatStoreForInspectorTree);\r
778               }\r
779           });\r
780           api.on.getInspectorState((payload) => {\r
781               if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {\r
782                   const inspectedStore = payload.nodeId === PINIA_ROOT_ID\r
783                       ? pinia\r
784                       : pinia._s.get(payload.nodeId);\r
785                   if (!inspectedStore) {\r
786                       // this could be the selected store restored for a different project\r
787                       // so it's better not to say anything here\r
788                       return;\r
789                   }\r
790                   if (inspectedStore) {\r
791                       payload.state = formatStoreForInspectorState(inspectedStore);\r
792                   }\r
793               }\r
794           });\r
795           api.on.editInspectorState((payload, ctx) => {\r
796               if (payload.app === app && payload.inspectorId === INSPECTOR_ID) {\r
797                   const inspectedStore = payload.nodeId === PINIA_ROOT_ID\r
798                       ? pinia\r
799                       : pinia._s.get(payload.nodeId);\r
800                   if (!inspectedStore) {\r
801                       return toastMessage(`store "${payload.nodeId}" not found`, 'error');\r
802                   }\r
803                   const { path } = payload;\r
804                   if (!isPinia(inspectedStore)) {\r
805                       // access only the state\r
806                       if (path.length !== 1 ||\r
807                           !inspectedStore._customProperties.has(path[0]) ||\r
808                           path[0] in inspectedStore.$state) {\r
809                           path.unshift('$state');\r
810                       }\r
811                   }\r
812                   else {\r
813                       // Root access, we can omit the `.value` because the devtools API does it for us\r
814                       path.unshift('state');\r
815                   }\r
816                   isTimelineActive = false;\r
817                   payload.set(inspectedStore, path, payload.state.value);\r
818                   isTimelineActive = true;\r
819               }\r
820           });\r
821           api.on.editComponentState((payload) => {\r
822               if (payload.type.startsWith('🍍')) {\r
823                   const storeId = payload.type.replace(/^🍍\s*/, '');\r
824                   const store = pinia._s.get(storeId);\r
825                   if (!store) {\r
826                       return toastMessage(`store "${storeId}" not found`, 'error');\r
827                   }\r
828                   const { path } = payload;\r
829                   if (path[0] !== 'state') {\r
830                       return toastMessage(`Invalid path for store "${storeId}":\n${path}\nOnly state can be modified.`);\r
831                   }\r
832                   // rewrite the first entry to be able to directly set the state as\r
833                   // well as any other path\r
834                   path[0] = '$state';\r
835                   isTimelineActive = false;\r
836                   payload.set(store, path, payload.state.value);\r
837                   isTimelineActive = true;\r
838               }\r
839           });\r
840       });\r
841   }\r
842   function addStoreToDevtools(app, store) {\r
843       if (!componentStateTypes.includes(getStoreType(store.$id))) {\r
844           componentStateTypes.push(getStoreType(store.$id));\r
845       }\r
846       setupDevtoolsPlugin({\r
847           id: 'dev.esm.pinia',\r
848           label: 'Pinia 🍍',\r
849           logo: 'https://pinia.vuejs.org/logo.svg',\r
850           packageName: 'pinia',\r
851           homepage: 'https://pinia.vuejs.org',\r
852           componentStateTypes,\r
853           app,\r
854           settings: {\r
855               logStoreChanges: {\r
856                   label: 'Notify about new/deleted stores',\r
857                   type: 'boolean',\r
858                   defaultValue: true,\r
859               },\r
860               // useEmojis: {\r
861               //   label: 'Use emojis in messages ⚡️',\r
862               //   type: 'boolean',\r
863               //   defaultValue: true,\r
864               // },\r
865           },\r
866       }, (api) => {\r
867           // gracefully handle errors\r
868           const now = typeof api.now === 'function' ? api.now.bind(api) : Date.now;\r
869           store.$onAction(({ after, onError, name, args }) => {\r
870               const groupId = runningActionId++;\r
871               api.addTimelineEvent({\r
872                   layerId: MUTATIONS_LAYER_ID,\r
873                   event: {\r
874                       time: now(),\r
875                       title: '🛫 ' + name,\r
876                       subtitle: 'start',\r
877                       data: {\r
878                           store: formatDisplay(store.$id),\r
879                           action: formatDisplay(name),\r
880                           args,\r
881                       },\r
882                       groupId,\r
883                   },\r
884               });\r
885               after((result) => {\r
886                   activeAction = undefined;\r
887                   api.addTimelineEvent({\r
888                       layerId: MUTATIONS_LAYER_ID,\r
889                       event: {\r
890                           time: now(),\r
891                           title: '🛬 ' + name,\r
892                           subtitle: 'end',\r
893                           data: {\r
894                               store: formatDisplay(store.$id),\r
895                               action: formatDisplay(name),\r
896                               args,\r
897                               result,\r
898                           },\r
899                           groupId,\r
900                       },\r
901                   });\r
902               });\r
903               onError((error) => {\r
904                   activeAction = undefined;\r
905                   api.addTimelineEvent({\r
906                       layerId: MUTATIONS_LAYER_ID,\r
907                       event: {\r
908                           time: now(),\r
909                           logType: 'error',\r
910                           title: '💥 ' + name,\r
911                           subtitle: 'end',\r
912                           data: {\r
913                               store: formatDisplay(store.$id),\r
914                               action: formatDisplay(name),\r
915                               args,\r
916                               error,\r
917                           },\r
918                           groupId,\r
919                       },\r
920                   });\r
921               });\r
922           }, true);\r
923           store._customProperties.forEach((name) => {\r
924               vueDemi.watch(() => vueDemi.unref(store[name]), (newValue, oldValue) => {\r
925                   api.notifyComponentUpdate();\r
926                   api.sendInspectorState(INSPECTOR_ID);\r
927                   if (isTimelineActive) {\r
928                       api.addTimelineEvent({\r
929                           layerId: MUTATIONS_LAYER_ID,\r
930                           event: {\r
931                               time: now(),\r
932                               title: 'Change',\r
933                               subtitle: name,\r
934                               data: {\r
935                                   newValue,\r
936                                   oldValue,\r
937                               },\r
938                               groupId: activeAction,\r
939                           },\r
940                       });\r
941                   }\r
942               }, { deep: true });\r
943           });\r
944           store.$subscribe(({ events, type }, state) => {\r
945               api.notifyComponentUpdate();\r
946               api.sendInspectorState(INSPECTOR_ID);\r
947               if (!isTimelineActive)\r
948                   return;\r
949               // rootStore.state[store.id] = state\r
950               const eventData = {\r
951                   time: now(),\r
952                   title: formatMutationType(type),\r
953                   data: {\r
954                       store: formatDisplay(store.$id),\r
955                       ...formatEventData(events),\r
956                   },\r
957                   groupId: activeAction,\r
958               };\r
959               // reset for the next mutation\r
960               activeAction = undefined;\r
961               if (type === exports.MutationType.patchFunction) {\r
962                   eventData.subtitle = '⤵️';\r
963               }\r
964               else if (type === exports.MutationType.patchObject) {\r
965                   eventData.subtitle = '🧩';\r
966               }\r
967               else if (events && !Array.isArray(events)) {\r
968                   eventData.subtitle = events.type;\r
969               }\r
970               if (events) {\r
971                   eventData.data['rawEvent(s)'] = {\r
972                       _custom: {\r
973                           display: 'DebuggerEvent',\r
974                           type: 'object',\r
975                           tooltip: 'raw DebuggerEvent[]',\r
976                           value: events,\r
977                       },\r
978                   };\r
979               }\r
980               api.addTimelineEvent({\r
981                   layerId: MUTATIONS_LAYER_ID,\r
982                   event: eventData,\r
983               });\r
984           }, { detached: true, flush: 'sync' });\r
985           const hotUpdate = store._hotUpdate;\r
986           store._hotUpdate = vueDemi.markRaw((newStore) => {\r
987               hotUpdate(newStore);\r
988               api.addTimelineEvent({\r
989                   layerId: MUTATIONS_LAYER_ID,\r
990                   event: {\r
991                       time: now(),\r
992                       title: '🔥 ' + store.$id,\r
993                       subtitle: 'HMR update',\r
994                       data: {\r
995                           store: formatDisplay(store.$id),\r
996                           info: formatDisplay(`HMR update`),\r
997                       },\r
998                   },\r
999               });\r
1000               // update the devtools too\r
1001               api.notifyComponentUpdate();\r
1002               api.sendInspectorTree(INSPECTOR_ID);\r
1003               api.sendInspectorState(INSPECTOR_ID);\r
1004           });\r
1005           const { $dispose } = store;\r
1006           store.$dispose = () => {\r
1007               $dispose();\r
1008               api.notifyComponentUpdate();\r
1009               api.sendInspectorTree(INSPECTOR_ID);\r
1010               api.sendInspectorState(INSPECTOR_ID);\r
1011               api.getSettings().logStoreChanges &&\r
1012                   toastMessage(`Disposed "${store.$id}" store 🗑`);\r
1013           };\r
1014           // trigger an update so it can display new registered stores\r
1015           api.notifyComponentUpdate();\r
1016           api.sendInspectorTree(INSPECTOR_ID);\r
1017           api.sendInspectorState(INSPECTOR_ID);\r
1018           api.getSettings().logStoreChanges &&\r
1019               toastMessage(`"${store.$id}" store installed 🆕`);\r
1020       });\r
1021   }\r
1022   let runningActionId = 0;\r
1023   let activeAction;\r
1024   /**\r
1025    * Patches a store to enable action grouping in devtools by wrapping the store with a Proxy that is passed as the\r
1026    * context of all actions, allowing us to set `runningAction` on each access and effectively associating any state\r
1027    * mutation to the action.\r
1028    *\r
1029    * @param store - store to patch\r
1030    * @param actionNames - list of actionst to patch\r
1031    */\r
1032   function patchActionForGrouping(store, actionNames) {\r
1033       // original actions of the store as they are given by pinia. We are going to override them\r
1034       const actions = actionNames.reduce((storeActions, actionName) => {\r
1035           // use toRaw to avoid tracking #541\r
1036           storeActions[actionName] = vueDemi.toRaw(store)[actionName];\r
1037           return storeActions;\r
1038       }, {});\r
1039       for (const actionName in actions) {\r
1040           store[actionName] = function () {\r
1041               // setActivePinia(store._p)\r
1042               // the running action id is incremented in a before action hook\r
1043               const _actionId = runningActionId;\r
1044               const trackedStore = new Proxy(store, {\r
1045                   get(...args) {\r
1046                       activeAction = _actionId;\r
1047                       return Reflect.get(...args);\r
1048                   },\r
1049                   set(...args) {\r
1050                       activeAction = _actionId;\r
1051                       return Reflect.set(...args);\r
1052                   },\r
1053               });\r
1054               return actions[actionName].apply(trackedStore, arguments);\r
1055           };\r
1056       }\r
1057   }\r
1058   /**\r
1059    * pinia.use(devtoolsPlugin)\r
1060    */\r
1061   function devtoolsPlugin({ app, store, options }) {\r
1062       // HMR module\r
1063       if (store.$id.startsWith('__hot:')) {\r
1064           return;\r
1065       }\r
1066       // detect option api vs setup api\r
1067       if (options.state) {\r
1068           store._isOptionsAPI = true;\r
1069       }\r
1070       // only wrap actions in option-defined stores as this technique relies on\r
1071       // wrapping the context of the action with a proxy\r
1072       if (typeof options.state === 'function') {\r
1073           patchActionForGrouping(\r
1074           // @ts-expect-error: can cast the store...\r
1075           store, Object.keys(options.actions));\r
1076           const originalHotUpdate = store._hotUpdate;\r
1077           // Upgrade the HMR to also update the new actions\r
1078           vueDemi.toRaw(store)._hotUpdate = function (newStore) {\r
1079               originalHotUpdate.apply(this, arguments);\r
1080               patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions));\r
1081           };\r
1082       }\r
1083       addStoreToDevtools(app, \r
1084       // FIXME: is there a way to allow the assignment from Store<Id, S, G, A> to StoreGeneric?\r
1085       store);\r
1086   }
1088   /**\r
1089    * Creates a Pinia instance to be used by the application\r
1090    */\r
1091   function createPinia() {\r
1092       const scope = vueDemi.effectScope(true);\r
1093       // NOTE: here we could check the window object for a state and directly set it\r
1094       // if there is anything like it with Vue 3 SSR\r
1095       const state = scope.run(() => vueDemi.ref({}));\r
1096       let _p = [];\r
1097       // plugins added before calling app.use(pinia)\r
1098       let toBeInstalled = [];\r
1099       const pinia = vueDemi.markRaw({\r
1100           install(app) {\r
1101               // this allows calling useStore() outside of a component setup after\r
1102               // installing pinia's plugin\r
1103               setActivePinia(pinia);\r
1104               if (!vueDemi.isVue2) {\r
1105                   pinia._a = app;\r
1106                   app.provide(piniaSymbol, pinia);\r
1107                   app.config.globalProperties.$pinia = pinia;\r
1108                   /* istanbul ignore else */\r
1109                   if (IS_CLIENT) {\r
1110                       registerPiniaDevtools(app, pinia);\r
1111                   }\r
1112                   toBeInstalled.forEach((plugin) => _p.push(plugin));\r
1113                   toBeInstalled = [];\r
1114               }\r
1115           },\r
1116           use(plugin) {\r
1117               if (!this._a && !vueDemi.isVue2) {\r
1118                   toBeInstalled.push(plugin);\r
1119               }\r
1120               else {\r
1121                   _p.push(plugin);\r
1122               }\r
1123               return this;\r
1124           },\r
1125           _p,\r
1126           // it's actually undefined here\r
1127           // @ts-expect-error\r
1128           _a: null,\r
1129           _e: scope,\r
1130           _s: new Map(),\r
1131           state,\r
1132       });\r
1133       // pinia devtools rely on dev only features so they cannot be forced unless\r
1134       // the dev build of Vue is used\r
1135       // We also don't need devtools in test mode\r
1136       if (IS_CLIENT && !false) {\r
1137           pinia.use(devtoolsPlugin);\r
1138       }\r
1139       return pinia;\r
1140   }
1142   /**\r
1143    * Checks if a function is a `StoreDefinition`.\r
1144    *\r
1145    * @param fn - object to test\r
1146    * @returns true if `fn` is a StoreDefinition\r
1147    */\r
1148   const isUseStore = (fn) => {\r
1149       return typeof fn === 'function' && typeof fn.$id === 'string';\r
1150   };\r
1151   /**\r
1152    * Mutates in place `newState` with `oldState` to _hot update_ it. It will\r
1153    * remove any key not existing in `newState` and recursively merge plain\r
1154    * objects.\r
1155    *\r
1156    * @param newState - new state object to be patched\r
1157    * @param oldState - old state that should be used to patch newState\r
1158    * @returns - newState\r
1159    */\r
1160   function patchObject(newState, oldState) {\r
1161       // no need to go through symbols because they cannot be serialized anyway\r
1162       for (const key in oldState) {\r
1163           const subPatch = oldState[key];\r
1164           // skip the whole sub tree\r
1165           if (!(key in newState)) {\r
1166               continue;\r
1167           }\r
1168           const targetValue = newState[key];\r
1169           if (isPlainObject(targetValue) &&\r
1170               isPlainObject(subPatch) &&\r
1171               !vueDemi.isRef(subPatch) &&\r
1172               !vueDemi.isReactive(subPatch)) {\r
1173               newState[key] = patchObject(targetValue, subPatch);\r
1174           }\r
1175           else {\r
1176               // objects are either a bit more complex (e.g. refs) or primitives, so we\r
1177               // just set the whole thing\r
1178               if (vueDemi.isVue2) {\r
1179                   vueDemi.set(newState, key, subPatch);\r
1180               }\r
1181               else {\r
1182                   newState[key] = subPatch;\r
1183               }\r
1184           }\r
1185       }\r
1186       return newState;\r
1187   }\r
1188   /**\r
1189    * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications.\r
1190    *\r
1191    * @example\r
1192    * ```js\r
1193    * const useUser = defineStore(...)\r
1194    * if (import.meta.hot) {\r
1195    *   import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot))\r
1196    * }\r
1197    * ```\r
1198    *\r
1199    * @param initialUseStore - return of the defineStore to hot update\r
1200    * @param hot - `import.meta.hot`\r
1201    */\r
1202   function acceptHMRUpdate(initialUseStore, hot) {\r
1203       return (newModule) => {\r
1204           const pinia = hot.data.pinia || initialUseStore._pinia;\r
1205           if (!pinia) {\r
1206               // this store is still not used\r
1207               return;\r
1208           }\r
1209           // preserve the pinia instance across loads\r
1210           hot.data.pinia = pinia;\r
1211           // console.log('got data', newStore)\r
1212           for (const exportName in newModule) {\r
1213               const useStore = newModule[exportName];\r
1214               // console.log('checking for', exportName)\r
1215               if (isUseStore(useStore) && pinia._s.has(useStore.$id)) {\r
1216                   // console.log('Accepting update for', useStore.$id)\r
1217                   const id = useStore.$id;\r
1218                   if (id !== initialUseStore.$id) {\r
1219                       console.warn(`The id of the store changed from "${initialUseStore.$id}" to "${id}". Reloading.`);\r
1220                       // return import.meta.hot.invalidate()\r
1221                       return hot.invalidate();\r
1222                   }\r
1223                   const existingStore = pinia._s.get(id);\r
1224                   if (!existingStore) {\r
1225                       console.log(`[Pinia]: skipping hmr because store doesn't exist yet`);\r
1226                       return;\r
1227                   }\r
1228                   useStore(pinia, existingStore);\r
1229               }\r
1230           }\r
1231       };\r
1232   }
1234   const noop = () => { };\r
1235   function addSubscription(subscriptions, callback, detached, onCleanup = noop) {\r
1236       subscriptions.push(callback);\r
1237       const removeSubscription = () => {\r
1238           const idx = subscriptions.indexOf(callback);\r
1239           if (idx > -1) {\r
1240               subscriptions.splice(idx, 1);\r
1241               onCleanup();\r
1242           }\r
1243       };\r
1244       if (!detached && vueDemi.getCurrentInstance()) {\r
1245           vueDemi.onUnmounted(removeSubscription);\r
1246       }\r
1247       return removeSubscription;\r
1248   }\r
1249   function triggerSubscriptions(subscriptions, ...args) {\r
1250       subscriptions.slice().forEach((callback) => {\r
1251           callback(...args);\r
1252       });\r
1253   }
1255   function mergeReactiveObjects(target, patchToApply) {\r
1256       // no need to go through symbols because they cannot be serialized anyway\r
1257       for (const key in patchToApply) {\r
1258           if (!patchToApply.hasOwnProperty(key))\r
1259               continue;\r
1260           const subPatch = patchToApply[key];\r
1261           const targetValue = target[key];\r
1262           if (isPlainObject(targetValue) &&\r
1263               isPlainObject(subPatch) &&\r
1264               target.hasOwnProperty(key) &&\r
1265               !vueDemi.isRef(subPatch) &&\r
1266               !vueDemi.isReactive(subPatch)) {\r
1267               target[key] = mergeReactiveObjects(targetValue, subPatch);\r
1268           }\r
1269           else {\r
1270               // @ts-expect-error: subPatch is a valid value\r
1271               target[key] = subPatch;\r
1272           }\r
1273       }\r
1274       return target;\r
1275   }\r
1276   const skipHydrateSymbol = Symbol('pinia:skipHydration')\r
1277       ;\r
1278   const skipHydrateMap = /*#__PURE__*/ new WeakMap();\r
1279   /**\r
1280    * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a\r
1281    * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store.\r
1282    *\r
1283    * @param obj - target object\r
1284    * @returns obj\r
1285    */\r
1286   function skipHydrate(obj) {\r
1287       return vueDemi.isVue2\r
1288           ? // in @vue/composition-api, the refs are sealed so defineProperty doesn't work...\r
1289               /* istanbul ignore next */ skipHydrateMap.set(obj, 1) && obj\r
1290           : Object.defineProperty(obj, skipHydrateSymbol, {});\r
1291   }\r
1292   function shouldHydrate(obj) {\r
1293       return vueDemi.isVue2\r
1294           ? /* istanbul ignore next */ !skipHydrateMap.has(obj)\r
1295           : !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol);\r
1296   }\r
1297   const { assign } = Object;\r
1298   function isComputed(o) {\r
1299       return !!(vueDemi.isRef(o) && o.effect);\r
1300   }\r
1301   function createOptionsStore(id, options, pinia, hot) {\r
1302       const { state, actions, getters } = options;\r
1303       const initialState = pinia.state.value[id];\r
1304       let store;\r
1305       function setup() {\r
1306           if (!initialState && (!hot)) {\r
1307               /* istanbul ignore if */\r
1308               if (vueDemi.isVue2) {\r
1309                   vueDemi.set(pinia.state.value, id, state ? state() : {});\r
1310               }\r
1311               else {\r
1312                   pinia.state.value[id] = state ? state() : {};\r
1313               }\r
1314           }\r
1315           // avoid creating a state in pinia.state.value\r
1316           const localState = hot\r
1317               ? // use ref() to unwrap refs inside state TODO: check if this is still necessary\r
1318                   vueDemi.toRefs(vueDemi.ref(state ? state() : {}).value)\r
1319               : vueDemi.toRefs(pinia.state.value[id]);\r
1320           return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => {\r
1321               if (name in localState) {\r
1322                   console.warn(`[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name}" in store "${id}".`);\r
1323               }\r
1324               computedGetters[name] = vueDemi.markRaw(vueDemi.computed(() => {\r
1325                   setActivePinia(pinia);\r
1326                   // it was created just before\r
1327                   const store = pinia._s.get(id);\r
1328                   // allow cross using stores\r
1329                   /* istanbul ignore next */\r
1330                   if (vueDemi.isVue2 && !store._r)\r
1331                       return;\r
1332                   // @ts-expect-error\r
1333                   // return getters![name].call(context, context)\r
1334                   // TODO: avoid reading the getter while assigning with a global variable\r
1335                   return getters[name].call(store, store);\r
1336               }));\r
1337               return computedGetters;\r
1338           }, {}));\r
1339       }\r
1340       store = createSetupStore(id, setup, options, pinia, hot, true);\r
1341       store.$reset = function $reset() {\r
1342           const newState = state ? state() : {};\r
1343           // we use a patch to group all changes into one single subscription\r
1344           this.$patch(($state) => {\r
1345               assign($state, newState);\r
1346           });\r
1347       };\r
1348       return store;\r
1349   }\r
1350   function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) {\r
1351       let scope;\r
1352       const optionsForPlugin = assign({ actions: {} }, options);\r
1353       /* istanbul ignore if */\r
1354       // @ts-expect-error: active is an internal property\r
1355       if (!pinia._e.active) {\r
1356           throw new Error('Pinia destroyed');\r
1357       }\r
1358       // watcher options for $subscribe\r
1359       const $subscribeOptions = {\r
1360           deep: true,\r
1361           // flush: 'post',\r
1362       };\r
1363       /* istanbul ignore else */\r
1364       if (!vueDemi.isVue2) {\r
1365           $subscribeOptions.onTrigger = (event) => {\r
1366               /* istanbul ignore else */\r
1367               if (isListening) {\r
1368                   debuggerEvents = event;\r
1369                   // avoid triggering this while the store is being built and the state is being set in pinia\r
1370               }\r
1371               else if (isListening == false && !store._hotUpdating) {\r
1372                   // let patch send all the events together later\r
1373                   /* istanbul ignore else */\r
1374                   if (Array.isArray(debuggerEvents)) {\r
1375                       debuggerEvents.push(event);\r
1376                   }\r
1377                   else {\r
1378                       console.error('🍍 debuggerEvents should be an array. This is most likely an internal Pinia bug.');\r
1379                   }\r
1380               }\r
1381           };\r
1382       }\r
1383       // internal state\r
1384       let isListening; // set to true at the end\r
1385       let isSyncListening; // set to true at the end\r
1386       let subscriptions = vueDemi.markRaw([]);\r
1387       let actionSubscriptions = vueDemi.markRaw([]);\r
1388       let debuggerEvents;\r
1389       const initialState = pinia.state.value[$id];\r
1390       // avoid setting the state for option stores if it is set\r
1391       // by the setup\r
1392       if (!isOptionsStore && !initialState && (!hot)) {\r
1393           /* istanbul ignore if */\r
1394           if (vueDemi.isVue2) {\r
1395               vueDemi.set(pinia.state.value, $id, {});\r
1396           }\r
1397           else {\r
1398               pinia.state.value[$id] = {};\r
1399           }\r
1400       }\r
1401       const hotState = vueDemi.ref({});\r
1402       // avoid triggering too many listeners\r
1403       // https://github.com/vuejs/pinia/issues/1129\r
1404       let activeListener;\r
1405       function $patch(partialStateOrMutator) {\r
1406           let subscriptionMutation;\r
1407           isListening = isSyncListening = false;\r
1408           // reset the debugger events since patches are sync\r
1409           /* istanbul ignore else */\r
1410           {\r
1411               debuggerEvents = [];\r
1412           }\r
1413           if (typeof partialStateOrMutator === 'function') {\r
1414               partialStateOrMutator(pinia.state.value[$id]);\r
1415               subscriptionMutation = {\r
1416                   type: exports.MutationType.patchFunction,\r
1417                   storeId: $id,\r
1418                   events: debuggerEvents,\r
1419               };\r
1420           }\r
1421           else {\r
1422               mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator);\r
1423               subscriptionMutation = {\r
1424                   type: exports.MutationType.patchObject,\r
1425                   payload: partialStateOrMutator,\r
1426                   storeId: $id,\r
1427                   events: debuggerEvents,\r
1428               };\r
1429           }\r
1430           const myListenerId = (activeListener = Symbol());\r
1431           vueDemi.nextTick().then(() => {\r
1432               if (activeListener === myListenerId) {\r
1433                   isListening = true;\r
1434               }\r
1435           });\r
1436           isSyncListening = true;\r
1437           // because we paused the watcher, we need to manually call the subscriptions\r
1438           triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]);\r
1439       }\r
1440       /* istanbul ignore next */\r
1441       const $reset = () => {\r
1442               throw new Error(`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`);\r
1443           }\r
1444           ;\r
1445       function $dispose() {\r
1446           scope.stop();\r
1447           subscriptions = [];\r
1448           actionSubscriptions = [];\r
1449           pinia._s.delete($id);\r
1450       }\r
1451       /**\r
1452        * Wraps an action to handle subscriptions.\r
1453        *\r
1454        * @param name - name of the action\r
1455        * @param action - action to wrap\r
1456        * @returns a wrapped action to handle subscriptions\r
1457        */\r
1458       function wrapAction(name, action) {\r
1459           return function () {\r
1460               setActivePinia(pinia);\r
1461               const args = Array.from(arguments);\r
1462               const afterCallbackList = [];\r
1463               const onErrorCallbackList = [];\r
1464               function after(callback) {\r
1465                   afterCallbackList.push(callback);\r
1466               }\r
1467               function onError(callback) {\r
1468                   onErrorCallbackList.push(callback);\r
1469               }\r
1470               // @ts-expect-error\r
1471               triggerSubscriptions(actionSubscriptions, {\r
1472                   args,\r
1473                   name,\r
1474                   store,\r
1475                   after,\r
1476                   onError,\r
1477               });\r
1478               let ret;\r
1479               try {\r
1480                   ret = action.apply(this && this.$id === $id ? this : store, args);\r
1481                   // handle sync errors\r
1482               }\r
1483               catch (error) {\r
1484                   triggerSubscriptions(onErrorCallbackList, error);\r
1485                   throw error;\r
1486               }\r
1487               if (ret instanceof Promise) {\r
1488                   return ret\r
1489                       .then((value) => {\r
1490                       triggerSubscriptions(afterCallbackList, value);\r
1491                       return value;\r
1492                   })\r
1493                       .catch((error) => {\r
1494                       triggerSubscriptions(onErrorCallbackList, error);\r
1495                       return Promise.reject(error);\r
1496                   });\r
1497               }\r
1498               // allow the afterCallback to override the return value\r
1499               triggerSubscriptions(afterCallbackList, ret);\r
1500               return ret;\r
1501           };\r
1502       }\r
1503       const _hmrPayload = /*#__PURE__*/ vueDemi.markRaw({\r
1504           actions: {},\r
1505           getters: {},\r
1506           state: [],\r
1507           hotState,\r
1508       });\r
1509       const partialStore = {\r
1510           _p: pinia,\r
1511           // _s: scope,\r
1512           $id,\r
1513           $onAction: addSubscription.bind(null, actionSubscriptions),\r
1514           $patch,\r
1515           $reset,\r
1516           $subscribe(callback, options = {}) {\r
1517               const removeSubscription = addSubscription(subscriptions, callback, options.detached, () => stopWatcher());\r
1518               const stopWatcher = scope.run(() => vueDemi.watch(() => pinia.state.value[$id], (state) => {\r
1519                   if (options.flush === 'sync' ? isSyncListening : isListening) {\r
1520                       callback({\r
1521                           storeId: $id,\r
1522                           type: exports.MutationType.direct,\r
1523                           events: debuggerEvents,\r
1524                       }, state);\r
1525                   }\r
1526               }, assign({}, $subscribeOptions, options)));\r
1527               return removeSubscription;\r
1528           },\r
1529           $dispose,\r
1530       };\r
1531       /* istanbul ignore if */\r
1532       if (vueDemi.isVue2) {\r
1533           // start as non ready\r
1534           partialStore._r = false;\r
1535       }\r
1536       const store = vueDemi.reactive(assign(IS_CLIENT\r
1537           ? // devtools custom properties\r
1538               {\r
1539                   _customProperties: vueDemi.markRaw(new Set()),\r
1540                   _hmrPayload,\r
1541               }\r
1542           : {}, partialStore\r
1543       // must be added later\r
1544       // setupStore\r
1545       ));\r
1546       // store the partial store now so the setup of stores can instantiate each other before they are finished without\r
1547       // creating infinite loops.\r
1548       pinia._s.set($id, store);\r
1549       // TODO: idea create skipSerialize that marks properties as non serializable and they are skipped\r
1550       const setupStore = pinia._e.run(() => {\r
1551           scope = vueDemi.effectScope();\r
1552           return scope.run(() => setup());\r
1553       });\r
1554       // overwrite existing actions to support $onAction\r
1555       for (const key in setupStore) {\r
1556           const prop = setupStore[key];\r
1557           if ((vueDemi.isRef(prop) && !isComputed(prop)) || vueDemi.isReactive(prop)) {\r
1558               // mark it as a piece of state to be serialized\r
1559               if (hot) {\r
1560                   vueDemi.set(hotState.value, key, vueDemi.toRef(setupStore, key));\r
1561                   // createOptionStore directly sets the state in pinia.state.value so we\r
1562                   // can just skip that\r
1563               }\r
1564               else if (!isOptionsStore) {\r
1565                   // in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created\r
1566                   if (initialState && shouldHydrate(prop)) {\r
1567                       if (vueDemi.isRef(prop)) {\r
1568                           prop.value = initialState[key];\r
1569                       }\r
1570                       else {\r
1571                           // probably a reactive object, lets recursively assign\r
1572                           mergeReactiveObjects(prop, initialState[key]);\r
1573                       }\r
1574                   }\r
1575                   // transfer the ref to the pinia state to keep everything in sync\r
1576                   /* istanbul ignore if */\r
1577                   if (vueDemi.isVue2) {\r
1578                       vueDemi.set(pinia.state.value[$id], key, prop);\r
1579                   }\r
1580                   else {\r
1581                       pinia.state.value[$id][key] = prop;\r
1582                   }\r
1583               }\r
1584               /* istanbul ignore else */\r
1585               {\r
1586                   _hmrPayload.state.push(key);\r
1587               }\r
1588               // action\r
1589           }\r
1590           else if (typeof prop === 'function') {\r
1591               // @ts-expect-error: we are overriding the function we avoid wrapping if\r
1592               const actionValue = hot ? prop : wrapAction(key, prop);\r
1593               // this a hot module replacement store because the hotUpdate method needs\r
1594               // to do it with the right context\r
1595               /* istanbul ignore if */\r
1596               if (vueDemi.isVue2) {\r
1597                   vueDemi.set(setupStore, key, actionValue);\r
1598               }\r
1599               else {\r
1600                   // @ts-expect-error\r
1601                   setupStore[key] = actionValue;\r
1602               }\r
1603               /* istanbul ignore else */\r
1604               {\r
1605                   _hmrPayload.actions[key] = prop;\r
1606               }\r
1607               // list actions so they can be used in plugins\r
1608               // @ts-expect-error\r
1609               optionsForPlugin.actions[key] = prop;\r
1610           }\r
1611           else {\r
1612               // add getters for devtools\r
1613               if (isComputed(prop)) {\r
1614                   _hmrPayload.getters[key] = isOptionsStore\r
1615                       ? // @ts-expect-error\r
1616                           options.getters[key]\r
1617                       : prop;\r
1618                   if (IS_CLIENT) {\r
1619                       const getters = \r
1620                       // @ts-expect-error: it should be on the store\r
1621                       setupStore._getters || (setupStore._getters = vueDemi.markRaw([]));\r
1622                       getters.push(key);\r
1623                   }\r
1624               }\r
1625           }\r
1626       }\r
1627       // add the state, getters, and action properties\r
1628       /* istanbul ignore if */\r
1629       if (vueDemi.isVue2) {\r
1630           Object.keys(setupStore).forEach((key) => {\r
1631               vueDemi.set(store, key, \r
1632               // @ts-expect-error: valid key indexing\r
1633               setupStore[key]);\r
1634           });\r
1635       }\r
1636       else {\r
1637           assign(store, setupStore);\r
1638           // allows retrieving reactive objects with `storeToRefs()`. Must be called after assigning to the reactive object.\r
1639           // Make `storeToRefs()` work with `reactive()` #799\r
1640           assign(vueDemi.toRaw(store), setupStore);\r
1641       }\r
1642       // use this instead of a computed with setter to be able to create it anywhere\r
1643       // without linking the computed lifespan to wherever the store is first\r
1644       // created.\r
1645       Object.defineProperty(store, '$state', {\r
1646           get: () => (hot ? hotState.value : pinia.state.value[$id]),\r
1647           set: (state) => {\r
1648               /* istanbul ignore if */\r
1649               if (hot) {\r
1650                   throw new Error('cannot set hotState');\r
1651               }\r
1652               $patch(($state) => {\r
1653                   assign($state, state);\r
1654               });\r
1655           },\r
1656       });\r
1657       // add the hotUpdate before plugins to allow them to override it\r
1658       /* istanbul ignore else */\r
1659       {\r
1660           store._hotUpdate = vueDemi.markRaw((newStore) => {\r
1661               store._hotUpdating = true;\r
1662               newStore._hmrPayload.state.forEach((stateKey) => {\r
1663                   if (stateKey in store.$state) {\r
1664                       const newStateTarget = newStore.$state[stateKey];\r
1665                       const oldStateSource = store.$state[stateKey];\r
1666                       if (typeof newStateTarget === 'object' &&\r
1667                           isPlainObject(newStateTarget) &&\r
1668                           isPlainObject(oldStateSource)) {\r
1669                           patchObject(newStateTarget, oldStateSource);\r
1670                       }\r
1671                       else {\r
1672                           // transfer the ref\r
1673                           newStore.$state[stateKey] = oldStateSource;\r
1674                       }\r
1675                   }\r
1676                   // patch direct access properties to allow store.stateProperty to work as\r
1677                   // store.$state.stateProperty\r
1678                   vueDemi.set(store, stateKey, vueDemi.toRef(newStore.$state, stateKey));\r
1679               });\r
1680               // remove deleted state properties\r
1681               Object.keys(store.$state).forEach((stateKey) => {\r
1682                   if (!(stateKey in newStore.$state)) {\r
1683                       vueDemi.del(store, stateKey);\r
1684                   }\r
1685               });\r
1686               // avoid devtools logging this as a mutation\r
1687               isListening = false;\r
1688               isSyncListening = false;\r
1689               pinia.state.value[$id] = vueDemi.toRef(newStore._hmrPayload, 'hotState');\r
1690               isSyncListening = true;\r
1691               vueDemi.nextTick().then(() => {\r
1692                   isListening = true;\r
1693               });\r
1694               for (const actionName in newStore._hmrPayload.actions) {\r
1695                   const action = newStore[actionName];\r
1696                   vueDemi.set(store, actionName, wrapAction(actionName, action));\r
1697               }\r
1698               // TODO: does this work in both setup and option store?\r
1699               for (const getterName in newStore._hmrPayload.getters) {\r
1700                   const getter = newStore._hmrPayload.getters[getterName];\r
1701                   const getterValue = isOptionsStore\r
1702                       ? // special handling of options api\r
1703                           vueDemi.computed(() => {\r
1704                               setActivePinia(pinia);\r
1705                               return getter.call(store, store);\r
1706                           })\r
1707                       : getter;\r
1708                   vueDemi.set(store, getterName, getterValue);\r
1709               }\r
1710               // remove deleted getters\r
1711               Object.keys(store._hmrPayload.getters).forEach((key) => {\r
1712                   if (!(key in newStore._hmrPayload.getters)) {\r
1713                       vueDemi.del(store, key);\r
1714                   }\r
1715               });\r
1716               // remove old actions\r
1717               Object.keys(store._hmrPayload.actions).forEach((key) => {\r
1718                   if (!(key in newStore._hmrPayload.actions)) {\r
1719                       vueDemi.del(store, key);\r
1720                   }\r
1721               });\r
1722               // update the values used in devtools and to allow deleting new properties later on\r
1723               store._hmrPayload = newStore._hmrPayload;\r
1724               store._getters = newStore._getters;\r
1725               store._hotUpdating = false;\r
1726           });\r
1727           const nonEnumerable = {\r
1728               writable: true,\r
1729               configurable: true,\r
1730               // avoid warning on devtools trying to display this property\r
1731               enumerable: false,\r
1732           };\r
1733           if (IS_CLIENT) {\r
1734               ['_p', '_hmrPayload', '_getters', '_customProperties'].forEach((p) => {\r
1735                   Object.defineProperty(store, p, {\r
1736                       value: store[p],\r
1737                       ...nonEnumerable,\r
1738                   });\r
1739               });\r
1740           }\r
1741       }\r
1742       /* istanbul ignore if */\r
1743       if (vueDemi.isVue2) {\r
1744           // mark the store as ready before plugins\r
1745           store._r = true;\r
1746       }\r
1747       // apply all plugins\r
1748       pinia._p.forEach((extender) => {\r
1749           /* istanbul ignore else */\r
1750           if (IS_CLIENT) {\r
1751               const extensions = scope.run(() => extender({\r
1752                   store,\r
1753                   app: pinia._a,\r
1754                   pinia,\r
1755                   options: optionsForPlugin,\r
1756               }));\r
1757               Object.keys(extensions || {}).forEach((key) => store._customProperties.add(key));\r
1758               assign(store, extensions);\r
1759           }\r
1760           else {\r
1761               assign(store, scope.run(() => extender({\r
1762                   store,\r
1763                   app: pinia._a,\r
1764                   pinia,\r
1765                   options: optionsForPlugin,\r
1766               })));\r
1767           }\r
1768       });\r
1769       if (store.$state &&\r
1770           typeof store.$state === 'object' &&\r
1771           typeof store.$state.constructor === 'function' &&\r
1772           !store.$state.constructor.toString().includes('[native code]')) {\r
1773           console.warn(`[🍍]: The "state" must be a plain object. It cannot be\n` +\r
1774               `\tstate: () => new MyClass()\n` +\r
1775               `Found in store "${store.$id}".`);\r
1776       }\r
1777       // only apply hydrate to option stores with an initial state in pinia\r
1778       if (initialState &&\r
1779           isOptionsStore &&\r
1780           options.hydrate) {\r
1781           options.hydrate(store.$state, initialState);\r
1782       }\r
1783       isListening = true;\r
1784       isSyncListening = true;\r
1785       return store;\r
1786   }\r
1787   function defineStore(\r
1788   // TODO: add proper types from above\r
1789   idOrOptions, setup, setupOptions) {\r
1790       let id;\r
1791       let options;\r
1792       const isSetupStore = typeof setup === 'function';\r
1793       if (typeof idOrOptions === 'string') {\r
1794           id = idOrOptions;\r
1795           // the option store setup will contain the actual options in this case\r
1796           options = isSetupStore ? setupOptions : setup;\r
1797       }\r
1798       else {\r
1799           options = idOrOptions;\r
1800           id = idOrOptions.id;\r
1801       }\r
1802       function useStore(pinia, hot) {\r
1803           const currentInstance = vueDemi.getCurrentInstance();\r
1804           pinia =\r
1805               // in test mode, ignore the argument provided as we can always retrieve a\r
1806               // pinia instance with getActivePinia()\r
1807               (pinia) ||\r
1808                   (currentInstance && vueDemi.inject(piniaSymbol));\r
1809           if (pinia)\r
1810               setActivePinia(pinia);\r
1811           if (!activePinia) {\r
1812               throw new Error(`[🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?\n` +\r
1813                   `\tconst pinia = createPinia()\n` +\r
1814                   `\tapp.use(pinia)\n` +\r
1815                   `This will fail in production.`);\r
1816           }\r
1817           pinia = activePinia;\r
1818           if (!pinia._s.has(id)) {\r
1819               // creating the store registers it in `pinia._s`\r
1820               if (isSetupStore) {\r
1821                   createSetupStore(id, setup, options, pinia);\r
1822               }\r
1823               else {\r
1824                   createOptionsStore(id, options, pinia);\r
1825               }\r
1826               /* istanbul ignore else */\r
1827               {\r
1828                   // @ts-expect-error: not the right inferred type\r
1829                   useStore._pinia = pinia;\r
1830               }\r
1831           }\r
1832           const store = pinia._s.get(id);\r
1833           if (hot) {\r
1834               const hotId = '__hot:' + id;\r
1835               const newStore = isSetupStore\r
1836                   ? createSetupStore(hotId, setup, options, pinia, true)\r
1837                   : createOptionsStore(hotId, assign({}, options), pinia, true);\r
1838               hot._hotUpdate(newStore);\r
1839               // cleanup the state properties and the store from the cache\r
1840               delete pinia.state.value[hotId];\r
1841               pinia._s.delete(hotId);\r
1842           }\r
1843           // save stores in instances to access them devtools\r
1844           if (IS_CLIENT &&\r
1845               currentInstance &&\r
1846               currentInstance.proxy &&\r
1847               // avoid adding stores that are just built for hot module replacement\r
1848               !hot) {\r
1849               const vm = currentInstance.proxy;\r
1850               const cache = '_pStores' in vm ? vm._pStores : (vm._pStores = {});\r
1851               cache[id] = store;\r
1852           }\r
1853           // StoreGeneric cannot be casted towards Store\r
1854           return store;\r
1855       }\r
1856       useStore.$id = id;\r
1857       return useStore;\r
1858   }
1860   let mapStoreSuffix = 'Store';\r
1861   /**\r
1862    * Changes the suffix added by `mapStores()`. Can be set to an empty string.\r
1863    * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization\r
1864    * interface if you are using TypeScript.\r
1865    *\r
1866    * @param suffix - new suffix\r
1867    */\r
1868   function setMapStoreSuffix(suffix // could be 'Store' but that would be annoying for JS\r
1869   ) {\r
1870       mapStoreSuffix = suffix;\r
1871   }\r
1872   /**\r
1873    * Allows using stores without the composition API (`setup()`) by generating an\r
1874    * object to be spread in the `computed` field of a component. It accepts a list\r
1875    * of store definitions.\r
1876    *\r
1877    * @example\r
1878    * ```js\r
1879    * export default {\r
1880    *   computed: {\r
1881    *     // other computed properties\r
1882    *     ...mapStores(useUserStore, useCartStore)\r
1883    *   },\r
1884    *\r
1885    *   created() {\r
1886    *     this.userStore // store with id "user"\r
1887    *     this.cartStore // store with id "cart"\r
1888    *   }\r
1889    * }\r
1890    * ```\r
1891    *\r
1892    * @param stores - list of stores to map to an object\r
1893    */\r
1894   function mapStores(...stores) {\r
1895       if (Array.isArray(stores[0])) {\r
1896           console.warn(`[🍍]: Directly pass all stores to "mapStores()" without putting them in an array:\n` +\r
1897               `Replace\n` +\r
1898               `\tmapStores([useAuthStore, useCartStore])\n` +\r
1899               `with\n` +\r
1900               `\tmapStores(useAuthStore, useCartStore)\n` +\r
1901               `This will fail in production if not fixed.`);\r
1902           stores = stores[0];\r
1903       }\r
1904       return stores.reduce((reduced, useStore) => {\r
1905           // @ts-expect-error: $id is added by defineStore\r
1906           reduced[useStore.$id + mapStoreSuffix] = function () {\r
1907               return useStore(this.$pinia);\r
1908           };\r
1909           return reduced;\r
1910       }, {});\r
1911   }\r
1912   /**\r
1913    * Allows using state and getters from one store without using the composition\r
1914    * API (`setup()`) by generating an object to be spread in the `computed` field\r
1915    * of a component.\r
1916    *\r
1917    * @param useStore - store to map from\r
1918    * @param keysOrMapper - array or object\r
1919    */\r
1920   function mapState(useStore, keysOrMapper) {\r
1921       return Array.isArray(keysOrMapper)\r
1922           ? keysOrMapper.reduce((reduced, key) => {\r
1923               reduced[key] = function () {\r
1924                   return useStore(this.$pinia)[key];\r
1925               };\r
1926               return reduced;\r
1927           }, {})\r
1928           : Object.keys(keysOrMapper).reduce((reduced, key) => {\r
1929               // @ts-expect-error\r
1930               reduced[key] = function () {\r
1931                   const store = useStore(this.$pinia);\r
1932                   const storeKey = keysOrMapper[key];\r
1933                   // for some reason TS is unable to infer the type of storeKey to be a\r
1934                   // function\r
1935                   return typeof storeKey === 'function'\r
1936                       ? storeKey.call(this, store)\r
1937                       : store[storeKey];\r
1938               };\r
1939               return reduced;\r
1940           }, {});\r
1941   }\r
1942   /**\r
1943    * Alias for `mapState()`. You should use `mapState()` instead.\r
1944    * @deprecated use `mapState()` instead.\r
1945    */\r
1946   const mapGetters = mapState;\r
1947   /**\r
1948    * Allows directly using actions from your store without using the composition\r
1949    * API (`setup()`) by generating an object to be spread in the `methods` field\r
1950    * of a component.\r
1951    *\r
1952    * @param useStore - store to map from\r
1953    * @param keysOrMapper - array or object\r
1954    */\r
1955   function mapActions(useStore, keysOrMapper) {\r
1956       return Array.isArray(keysOrMapper)\r
1957           ? keysOrMapper.reduce((reduced, key) => {\r
1958               // @ts-expect-error\r
1959               reduced[key] = function (...args) {\r
1960                   return useStore(this.$pinia)[key](...args);\r
1961               };\r
1962               return reduced;\r
1963           }, {})\r
1964           : Object.keys(keysOrMapper).reduce((reduced, key) => {\r
1965               // @ts-expect-error\r
1966               reduced[key] = function (...args) {\r
1967                   return useStore(this.$pinia)[keysOrMapper[key]](...args);\r
1968               };\r
1969               return reduced;\r
1970           }, {});\r
1971   }\r
1972   /**\r
1973    * Allows using state and getters from one store without using the composition\r
1974    * API (`setup()`) by generating an object to be spread in the `computed` field\r
1975    * of a component.\r
1976    *\r
1977    * @param useStore - store to map from\r
1978    * @param keysOrMapper - array or object\r
1979    */\r
1980   function mapWritableState(useStore, keysOrMapper) {\r
1981       return Array.isArray(keysOrMapper)\r
1982           ? keysOrMapper.reduce((reduced, key) => {\r
1983               // @ts-ignore\r
1984               reduced[key] = {\r
1985                   get() {\r
1986                       return useStore(this.$pinia)[key];\r
1987                   },\r
1988                   set(value) {\r
1989                       // it's easier to type it here as any\r
1990                       return (useStore(this.$pinia)[key] = value);\r
1991                   },\r
1992               };\r
1993               return reduced;\r
1994           }, {})\r
1995           : Object.keys(keysOrMapper).reduce((reduced, key) => {\r
1996               // @ts-ignore\r
1997               reduced[key] = {\r
1998                   get() {\r
1999                       return useStore(this.$pinia)[keysOrMapper[key]];\r
2000                   },\r
2001                   set(value) {\r
2002                       // it's easier to type it here as any\r
2003                       return (useStore(this.$pinia)[keysOrMapper[key]] = value);\r
2004                   },\r
2005               };\r
2006               return reduced;\r
2007           }, {});\r
2008   }
2010   /**\r
2011    * Creates an object of references with all the state, getters, and plugin-added\r
2012    * state properties of the store. Similar to `toRefs()` but specifically\r
2013    * designed for Pinia stores so methods and non reactive properties are\r
2014    * completely ignored.\r
2015    *\r
2016    * @param store - store to extract the refs from\r
2017    */\r
2018   function storeToRefs(store) {\r
2019       // See https://github.com/vuejs/pinia/issues/852\r
2020       // It's easier to just use toRefs() even if it includes more stuff\r
2021       if (vueDemi.isVue2) {\r
2022           // @ts-expect-error: toRefs include methods and others\r
2023           return vueDemi.toRefs(store);\r
2024       }\r
2025       else {\r
2026           store = vueDemi.toRaw(store);\r
2027           const refs = {};\r
2028           for (const key in store) {\r
2029               const value = store[key];\r
2030               if (vueDemi.isRef(value) || vueDemi.isReactive(value)) {\r
2031                   // @ts-expect-error: the key is state or getter\r
2032                   refs[key] =\r
2033                       // ---\r
2034                       vueDemi.toRef(store, key);\r
2035               }\r
2036           }\r
2037           return refs;\r
2038       }\r
2039   }
2041   /**\r
2042    * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need\r
2043    * this plugin if you are using Nuxt.js**. Use the `buildModule` instead:\r
2044    * https://pinia.vuejs.org/ssr/nuxt.html.\r
2045    *\r
2046    * @example\r
2047    * ```js\r
2048    * import Vue from 'vue'\r
2049    * import { PiniaVuePlugin, createPinia } from 'pinia'\r
2050    *\r
2051    * Vue.use(PiniaVuePlugin)\r
2052    * const pinia = createPinia()\r
2053    *\r
2054    * new Vue({\r
2055    *   el: '#app',\r
2056    *   // ...\r
2057    *   pinia,\r
2058    * })\r
2059    * ```\r
2060    *\r
2061    * @param _Vue - `Vue` imported from 'vue'.\r
2062    */\r
2063   const PiniaVuePlugin = function (_Vue) {\r
2064       // Equivalent of\r
2065       // app.config.globalProperties.$pinia = pinia\r
2066       _Vue.mixin({\r
2067           beforeCreate() {\r
2068               const options = this.$options;\r
2069               if (options.pinia) {\r
2070                   const pinia = options.pinia;\r
2071                   // HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/main/src/apis/inject.ts#L31\r
2072                   /* istanbul ignore else */\r
2073                   if (!this._provided) {\r
2074                       const provideCache = {};\r
2075                       Object.defineProperty(this, '_provided', {\r
2076                           get: () => provideCache,\r
2077                           set: (v) => Object.assign(provideCache, v),\r
2078                       });\r
2079                   }\r
2080                   this._provided[piniaSymbol] = pinia;\r
2081                   // propagate the pinia instance in an SSR friendly way\r
2082                   // avoid adding it to nuxt twice\r
2083                   /* istanbul ignore else */\r
2084                   if (!this.$pinia) {\r
2085                       this.$pinia = pinia;\r
2086                   }\r
2087                   pinia._a = this;\r
2088                   if (IS_CLIENT) {\r
2089                       // this allows calling useStore() outside of a component setup after\r
2090                       // installing pinia's plugin\r
2091                       setActivePinia(pinia);\r
2092                       {\r
2093                           registerPiniaDevtools(pinia._a, pinia);\r
2094                       }\r
2095                   }\r
2096               }\r
2097               else if (!this.$pinia && options.parent && options.parent.$pinia) {\r
2098                   this.$pinia = options.parent.$pinia;\r
2099               }\r
2100           },\r
2101           destroyed() {\r
2102               delete this._pStores;\r
2103           },\r
2104       });\r
2105   };
2107   exports.PiniaVuePlugin = PiniaVuePlugin;
2108   exports.acceptHMRUpdate = acceptHMRUpdate;
2109   exports.createPinia = createPinia;
2110   exports.defineStore = defineStore;
2111   exports.getActivePinia = getActivePinia;
2112   exports.mapActions = mapActions;
2113   exports.mapGetters = mapGetters;
2114   exports.mapState = mapState;
2115   exports.mapStores = mapStores;
2116   exports.mapWritableState = mapWritableState;
2117   exports.setActivePinia = setActivePinia;
2118   exports.setMapStoreSuffix = setMapStoreSuffix;
2119   exports.skipHydrate = skipHydrate;
2120   exports.storeToRefs = storeToRefs;
2122   Object.defineProperty(exports, '__esModule', { value: true });
2124   return exports;
2126 })({}, VueDemi);