pinia-plugin-subscription 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pinia-plugin-subscription.js","sources":["../src/utils/deep-clone.ts","../src/factories/state-snapshot.ts","../src/core/RollbackStateSnapshotsHandler.ts","../src/core/PluginSubscription.ts"],"sourcesContent":["/**\n * Deeply clones the provided value, handling objects, arrays, maps, and sets. Uses `structuredClone` if available, otherwise falls back to a manual deep clone.\n * @template T The type of the value to deep clone.\n * @param value The value to deep clone.\n * @returns A deep clone of the provided value.\n */\nexport function deepClone<T>(value: T): T {\n if (typeof structuredClone === 'function') {\n try {\n return structuredClone(value)\n } catch {\n // fall through to the safe manual clone below\n }\n }\n\n if (value === null || typeof value !== 'object') {\n return value\n }\n\n if (value instanceof Map) {\n return new Map(\n Array.from(value.entries(), ([key, entryValue]) => [deepClone(key), deepClone(entryValue)])\n ) as T\n }\n\n if (value instanceof Set) {\n return new Set(Array.from(value.values(), entryValue => deepClone(entryValue))) as T\n }\n\n if (Array.isArray(value)) {\n return value.map(item => deepClone(item)) as T\n }\n\n if (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null) {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, item]) => [key, deepClone(item)])\n ) as T\n }\n\n const clonedObject = Object.create(Object.getPrototypeOf(value)) as Record<string, unknown>\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n clonedObject[key] = deepClone(item)\n }\n\n return clonedObject as T\n}","import { toRaw } from 'vue'\nimport { deepClone } from '../utils/deep-clone'\n\nimport type { StateTree } from 'pinia'\nimport type { CreateStateSnapshotKeys } from '../types/plugin'\n\n\nexport function createStateSnapshot(state: StateTree, keys: CreateStateSnapshotKeys = 'all') {\n if (Array.isArray(keys)) {\n const clonedState: Partial<StateTree> = {}\n for (const key of keys) {\n if (key in state) {\n clonedState[key] = deepClone(toRaw(state[key]))\n }\n }\n return clonedState\n }\n\n if (keys !== 'all') {\n throw new Error(`Invalid keys parameter: ${keys}`)\n }\n\n return deepClone(toRaw(state))\n}","import { createStateSnapshot } from \"../factories/state-snapshot\"\nimport { getActionStoreKey, hasDeniedFirstChar } from '../utils/store'\n\nimport type { PiniaPluginContext, StateTree, Store } from 'pinia'\nimport type { AnyObject } from '../types'\nimport type { CreateStateSnapshotKeys } from '../types/plugin'\nimport type { RollbackActionParams } from '../types/store'\n\n\n/**\n * Handles rollback state snapshots for Pinia stores.\n * This class provides methods to add rollback actions to stores,\n * create rollback snapshots, and manage the state snapshots internally.\n */\nexport default class RollbackStateSnapshotsHandler {\n private _stateSnapshots: Map<symbol, StateTree> = new Map()\n private _storeHasRollbackSnapshots: Set<string> = new Set()\n private _storeRollbackSnapshotsParams: Map<string, CreateStateSnapshotKeys> = new Map()\n\n\n /**\n * Adds a rollback action to the given store.\n * This method extends the store with a $rollbackAfterFailure function that handles rollback logic for actions.\n * The action arguments are forwarded through apply(), so they must be provided as a single array.\n * @param {Store} store The store to which the rollback action will be added.\n * @returns void\n */\n addRollbackAction(store: Store): void {\n if (typeof store.$rollbackAfterFailure === 'function') {\n return\n }\n\n store.$rollbackAfterFailure = async ({ action, stateKeys }: RollbackActionParams, args: any[] = []) => {\n const actionFn = (store as AnyObject)[action]\n if (typeof actionFn !== 'function' || hasDeniedFirstChar(action)) {\n return\n }\n\n const keys: CreateStateSnapshotKeys = !stateKeys || stateKeys.length === 0 ? 'all' : stateKeys\n\n const snapshotKey = this.saveStateSnapshot(store, action, keys)\n try {\n await actionFn.apply(store, args)\n } catch (error) {\n this.patchStore(snapshotKey, store)\n throw error\n } finally {\n this.removeStateSnapshot(snapshotKey)\n }\n }\n }\n\n /**\n * Creates a rollback snapshot for the specified action and store.\n * This snapshot can be used to restore the store's state in case of an error during the action execution.\n * @param {string} actionName The name of the action for which the rollback snapshot is created.\n * @param {Store} store The Pinia store instance.\n * @returns An object containing `after` and `onError` callbacks for handling the rollback, or `undefined` if no snapshot is created.\n */\n createOnActionCallbacks(\n actionName: string,\n store: Store\n ): {\n after: () => void,\n onError: () => void\n } | undefined {\n const stateKeys = this._storeRollbackSnapshotsParams.get(\n getActionStoreKey(actionName, store)\n )\n\n if (!stateKeys || stateKeys.length === 0) {\n return\n }\n\n const snapshotKey = this.saveStateSnapshot(store, actionName, stateKeys)\n\n return {\n after: () => { this.removeStateSnapshot(snapshotKey) },\n onError: () => {\n this.patchStore(snapshotKey, store)\n this.removeStateSnapshot(snapshotKey)\n }\n }\n }\n\n /**\n * Initializes the rollback state snapshots handler from the given Pinia plugin context.\n * This method extracts the rollback snapshot parameters from the store options and stores them internally.\n * @param {PiniaPluginContext} param0 The Pinia plugin context containing the store and its options.\n * @returns void\n */\n initFromPluginContext({ options, store }: PiniaPluginContext) {\n const rollbackSnapshotParams = options?.storeOptions?.rollbackAfterFailure as Record<string, CreateStateSnapshotKeys>\n if (rollbackSnapshotParams && !this._storeHasRollbackSnapshots.has(store.$id)) {\n Object.keys(rollbackSnapshotParams).forEach(key => {\n this._storeRollbackSnapshotsParams.set(\n getActionStoreKey(key, store),\n rollbackSnapshotParams[key]\n )\n })\n this._storeHasRollbackSnapshots.add(store.$id)\n }\n this.addRollbackAction(store)\n }\n\n /**\n * Clears all rollback tracking data for the given store.\n * Must be called when the store is disposed to avoid memory leaks with dynamically created stores.\n * @param {Store} store The disposed Pinia store instance.\n * @returns void\n */\n clearStoreTracking(store: Store): void {\n const suffix = `-${store.$id}`\n\n for (const key of Array.from(this._storeRollbackSnapshotsParams.keys())) {\n if (key.endsWith(suffix)) {\n this._storeRollbackSnapshotsParams.delete(key)\n }\n }\n\n this._storeHasRollbackSnapshots.delete(store.$id)\n\n for (const snapshotKey of Array.from(this._stateSnapshots.keys())) {\n if (snapshotKey.description?.startsWith(`${store.$id}:`)) {\n this._stateSnapshots.delete(snapshotKey)\n }\n }\n }\n\n private patchStore(snapshotKey: symbol, store: Store): void {\n const stateSnapshot = this._stateSnapshots.get(snapshotKey)\n if (!stateSnapshot) {\n return\n }\n\n try {\n store.$patch(stateSnapshot)\n } catch (error) {\n console.error(`Failed to patch store with snapshot ${String(snapshotKey)}`, error)\n }\n }\n\n /**\n * Removes a state snapshot identified by the given snapshot key from the internal state snapshot tracking.\n * @param snapshotKey The key of the state snapshot to be removed.\n * @returns void\n */\n private removeStateSnapshot(snapshotKey?: symbol): void {\n if (!snapshotKey) {\n return\n }\n\n this._stateSnapshots.delete(snapshotKey)\n }\n\n /**\n * Saves the current state snapshot for a given store and action.\n * @param store The Pinia store instance.\n * @param actionName The name of the action being executed.\n * @param stateKeys The state keys to include in the snapshot, or 'all' for the full state.\n * @returns A unique symbol key representing the saved snapshot.\n */\n private saveStateSnapshot(store: Store, actionName: string, stateKeys: CreateStateSnapshotKeys): symbol {\n const stateSnapshot = createStateSnapshot(\n store.$state,\n stateKeys\n )\n\n const snapshotKey = Symbol(`${store.$id}:${actionName}`)\n this._stateSnapshots.set(snapshotKey, stateSnapshot)\n return snapshotKey\n }\n\n /**\n * Checks if the given store has rollback snapshots.\n * @param store The Pinia store instance.\n * @returns True if the store has rollback snapshots, false otherwise.\n */\n storeHasRollbackSnapshots(store: Store): boolean {\n return this._storeHasRollbackSnapshots.has(store.$id)\n }\n}","import Debug from \"../system/Debug\"\nimport RollbackStateSnapshotsHandler from \"./RollbackStateSnapshotsHandler\"\nimport { deepClone } from '../utils/deep-clone'\nimport { getActionStoreKey } from '../utils/store'\nimport { PluginConsole } from \"../system/log\"\nimport { isEmpty } from \"../utils/validation\"\n\nimport type { PiniaPluginContext, StateTree, Store, SubscriptionCallbackMutation } from \"pinia\"\nimport type { AnyObject } from \"../types\"\nimport type {\n PluginExecutionOptions,\n PluginHydrationScheduler,\n PluginRuntimeEnvironment,\n PluginSubscriber,\n PluginSubscription as PluginSubscriptionDefinition,\n PluginSubscriptionOptions,\n PluginSubscriptions,\n StoreMutationSubscription,\n StoreOnActionAfterCallbackParameter,\n StoreOnActionSubscriptionCallback\n} from \"../types/plugin\"\n\n\nconst className = 'PluginSubscription'\nconst defaultPluginExecution: Required<PluginExecutionOptions> = {\n environment: 'both',\n hydration: 'immediate'\n}\n\nfunction defaultHydrationScheduler(callback: () => void): void {\n if (typeof window !== 'undefined' && typeof window.requestAnimationFrame === 'function') {\n window.requestAnimationFrame(() => globalThis.setTimeout(callback, 0))\n return\n }\n\n globalThis.setTimeout(callback, 0)\n}\n\nfunction isPluginSubscriptionOptions(\n value: PluginSubscriptionOptions | string[] | undefined\n): value is PluginSubscriptionOptions {\n return value !== undefined && !Array.isArray(value)\n}\n\n\nexport default class PluginSubscription extends Debug {\n protected _className: string = className\n private _hydrationScheduler: PluginHydrationScheduler\n private _onActionSubscriptions: StoreOnActionSubscriptionCallback[] = []\n private _onActionAfterSubscriptions: Record<string, StoreOnActionAfterCallbackParameter[]> = {}\n private _onActionOnErrorSubscriptions: Record<string, Array<(error: unknown) => void>> = {}\n private _options?: PluginSubscriptionOptions\n private _pluginDebug?: string[]\n private _resetStoreCallback: Function[] = []\n private _storeRollbackSnapshotsHandler: RollbackStateSnapshotsHandler = new RollbackStateSnapshotsHandler()\n private _subscribers: PluginSubscriber[] = []\n private _subscribersDelivered: Set<string> = new Set()\n private _subscribersScheduled: Set<string> = new Set()\n private _subscriptions: PluginSubscriptions[] = []\n private _subscriptionsDelivered: Set<string> = new Set()\n private _subscriptionsScheduled: Set<string> = new Set()\n\n set subscribers(subscribers: PluginSubscriber[]) {\n this._subscribers = subscribers\n }\n\n get subscriptions(): PluginSubscriptions[] | undefined {\n if (!isEmpty(this._subscriptions)) {\n return this._subscriptions\n }\n }\n\n constructor(\n subscribers: PluginSubscriber[],\n debugOrOptions?: PluginSubscriptionOptions | string[],\n pluginOptions?: PluginSubscriptionOptions\n ) {\n const debug = Array.isArray(debugOrOptions) ? debugOrOptions : undefined\n const options = isPluginSubscriptionOptions(debugOrOptions) ? debugOrOptions : pluginOptions\n\n super(Array.isArray(debug) && !!debug?.includes(className), PluginConsole)\n this._hydrationScheduler = options?.hydrationScheduler ?? defaultHydrationScheduler\n this._options = options\n this._pluginDebug = Array.isArray(debug) ? debug : undefined\n this._subscribers = subscribers\n }\n\n\n private addOnActionAfterCallback(actionName: string, store: Store, callback: StoreOnActionAfterCallbackParameter): void {\n const key = getActionStoreKey(actionName, store)\n if (!this._onActionAfterSubscriptions[key]) {\n this._onActionAfterSubscriptions[key] = []\n }\n this._onActionAfterSubscriptions[key]?.push(callback)\n }\n\n private addOnActionOnErrorCallback(actionName: string, store: Store, callback: (error: unknown) => void): void {\n const key = getActionStoreKey(actionName, store)\n if (!this._onActionOnErrorSubscriptions[key]) {\n this._onActionOnErrorSubscriptions[key] = []\n }\n this._onActionOnErrorSubscriptions[key]?.push(callback)\n }\n\n private addResetStoreCallback(callback: Function): void {\n this._resetStoreCallback.push(callback)\n }\n\n private clearOnActionCallbacksSubscriptions(storageKey: string): void {\n delete this._onActionAfterSubscriptions[storageKey]\n delete this._onActionOnErrorSubscriptions[storageKey]\n }\n\n private clearStoreTracking(store: Store): void {\n const suffix = `-${store.$id}`\n\n for (const key of Array.from(this._subscribersDelivered)) {\n if (key.endsWith(suffix)) {\n this._subscribersDelivered.delete(key)\n }\n }\n\n for (const key of Array.from(this._subscribersScheduled)) {\n if (key.endsWith(suffix)) {\n this._subscribersScheduled.delete(key)\n }\n }\n\n for (const key of Array.from(this._subscriptionsDelivered)) {\n if (key.endsWith(suffix)) {\n this._subscriptionsDelivered.delete(key)\n }\n }\n\n for (const key of Array.from(this._subscriptionsScheduled)) {\n if (key.endsWith(suffix)) {\n this._subscriptionsScheduled.delete(key)\n }\n }\n\n for (const key of Object.keys(this._onActionAfterSubscriptions)) {\n if (key.endsWith(suffix)) {\n delete this._onActionAfterSubscriptions[key]\n }\n }\n\n for (const key of Object.keys(this._onActionOnErrorSubscriptions)) {\n if (key.endsWith(suffix)) {\n delete this._onActionOnErrorSubscriptions[key]\n }\n }\n }\n\n /**\n * Creates a callback collector for the specified action and store.\n * @param actionName The name of the action to collect callbacks for.\n * @param store The store instance associated with the action.\n * @returns A function that collects callbacks for the specified action and store.\n */\n private createOnActionAfterCallbackCollector(actionName: string, store: Store) {\n return (callback: StoreOnActionAfterCallbackParameter) => {\n this.addOnActionAfterCallback(actionName, store, callback)\n }\n }\n\n /**\n * Creates a callback collector for the specified action and store that handles errors.\n * @param actionName The name of the action to collect error callbacks for.\n * @param store The store instance associated with the action.\n * @returns A function that collects error callbacks for the specified action and store.\n */\n private createOnActionOnErrorCallbackCollector(actionName: string, store: Store) {\n return (callback: (error: unknown) => void) => {\n this.addOnActionOnErrorCallback(actionName, store, callback)\n }\n }\n\n /**\n * Rolls back the state snapshot for a given action if an error occurs, and removes the snapshot after the action completes or fails.\n * @param actionName The name of the action being executed.\n * @param store The Pinia store instance.\n * @returns void\n */\n private createRollbackSnapshot(\n actionName: string,\n store: Store\n ) {\n const {\n after,\n onError\n } = this._storeRollbackSnapshotsHandler.createOnActionCallbacks(\n actionName,\n store\n ) ?? {}\n\n if (!after || !onError) {\n return\n }\n\n this.addOnActionAfterCallback(actionName, store, after)\n this.addOnActionOnErrorCallback(actionName, store, onError)\n }\n\n private defineCurrentEnvironment(): PluginRuntimeEnvironment {\n return this._options?.runtimeEnvironment\n ?? (typeof window === 'undefined' ? 'server' : 'client')\n }\n\n private definePluginDebug(subscriber: PluginSubscriber): boolean {\n return !!this._pluginDebug?.includes(subscriber.name)\n }\n\n private definePluginExecution(subscriber: PluginSubscriber): Required<PluginExecutionOptions> {\n return {\n ...defaultPluginExecution,\n ...(this._options?.execution ?? {}),\n ...(subscriber.execution ?? {}),\n ...(this._options?.subscriberExecution?.[subscriber.name] ?? {}),\n }\n }\n\n private defineHydrationScheduler(subscriber: PluginSubscriber | PluginSubscriptionDefinition['subscription']): PluginHydrationScheduler {\n return subscriber.hydrationScheduler ?? this._hydrationScheduler\n }\n\n private defineSubscriberKey(subscriber: PluginSubscriber, store: Store): string {\n return `${subscriber.name}-${store.$id}`\n }\n\n private defineSubscriptionKey(pluginName: string, store: Store): string {\n return `${pluginName}-${store.$id}`\n }\n\n private executeResetStoreCallbacks(store: Store): void {\n this._resetStoreCallback.forEach(callback => callback(store))\n }\n\n /**\n * Executes the store's onAction subscription for the given plugin subscriber.\n * @param store The Pinia store instance.\n * @param subscriber The plugin subscriber.\n * @returns void\n */\n private executeStoreOnActionSubscription(store: Store): void {\n const onActionSubscriptions = this._onActionSubscriptions\n const hasRollbackSnapshots = this._storeRollbackSnapshotsHandler.storeHasRollbackSnapshots(store)\n\n if (!onActionSubscriptions?.length && !hasRollbackSnapshots) {\n return\n }\n\n store.$onAction(({ after, args, name, onError }) => {\n const storageKey = getActionStoreKey(name, store)\n this.debugLog(`storeOnActionSubscription ${storageKey}`, { args, name, store })\n\n if (hasRollbackSnapshots) {\n this.createRollbackSnapshot(name, store)\n }\n\n if (onActionSubscriptions?.length) {\n onActionSubscriptions.forEach(callback => callback({\n after: this.createOnActionAfterCallbackCollector(name, store),\n args,\n name,\n onError: this.createOnActionOnErrorCallbackCollector(name, store)\n }))\n }\n\n const afterCallbacks = this._onActionAfterSubscriptions[storageKey]\n const onErrorCallbacks = this._onActionOnErrorSubscriptions[storageKey]\n\n this.clearOnActionCallbacksSubscriptions(storageKey)\n\n if (afterCallbacks?.length) {\n after((result) => {\n afterCallbacks.forEach(callback => callback(result))\n })\n }\n if (onErrorCallbacks?.length) {\n onError((error) => {\n onErrorCallbacks.forEach(callback => callback(error))\n })\n }\n })\n }\n\n private executeSubscriber(context: PiniaPluginContext, subscriber: PluginSubscriber): void {\n const subscriberKey = this.defineSubscriberKey(subscriber, context.store)\n const debug = this.definePluginDebug(subscriber)\n\n if (this._subscribersDelivered.has(subscriberKey)) {\n return\n }\n\n if (\n !subscriber.invoke(\n context,\n debug\n )) {\n return\n }\n\n this._subscribersDelivered.add(subscriberKey)\n\n let hydrateResult: void | Promise<void>\n\n try {\n hydrateResult = subscriber.hydrate?.(context, debug)\n } catch (error) {\n this.logError(error, context.store, context.options)\n return\n }\n\n const runAfterHydration = () => {\n try {\n const afterHydration = subscriber.afterHydration?.(context, debug)\n if (afterHydration && typeof (afterHydration as Promise<void>).then === 'function') {\n ; (afterHydration as Promise<void>).catch(error => this.logError(error, context.store, context.options))\n }\n } catch (error) {\n this.logError(error, context.store, context.options)\n }\n }\n\n if (hydrateResult && typeof (hydrateResult as Promise<void>).then === 'function') {\n ; (hydrateResult as Promise<void>)\n .then(() => runAfterHydration())\n .catch(error => this.logError(error, context.store, context.options))\n } else {\n runAfterHydration()\n }\n\n if (subscriber.subscriptions) {\n this.subscriptionDelivery(context, subscriber.subscriptions)\n }\n\n if (subscriber.storeMutationSubscription) {\n this.storeMutationSubscription(subscriber.storeMutationSubscription)\n }\n\n this.storeOnActionSubscription(subscriber)\n\n if (subscriber.resetStoreCallback) {\n this.addResetStoreCallback(subscriber.resetStoreCallback)\n }\n }\n\n private executeSubscriberSafely(context: PiniaPluginContext, subscriber: PluginSubscriber): void {\n try {\n this.executeSubscriber(context, subscriber)\n } catch (e) {\n this.logError(e, context.store, context.options)\n }\n }\n\n plugin({ store, options }: PiniaPluginContext) {\n if (!this._subscribers.length) {\n return\n }\n\n this.debugLog(`plugin() - ${store.$id}`, [\n 'subscriber:', this._subscribers,\n 'store:', store,\n 'options:', options\n ])\n\n try {\n this._subscribers.forEach(\n subscriber => {\n const subscriberKey = this.defineSubscriberKey(subscriber, store)\n const execution = this.definePluginExecution(subscriber)\n\n if (\n this._subscribersDelivered.has(subscriberKey)\n || this._subscribersScheduled.has(subscriberKey)\n ) {\n return\n }\n\n if (!this.shouldInvokePlugin(execution)) {\n return\n }\n\n if (this.shouldScheduleAfterHydration(execution)) {\n this.queueSubscriberExecution({ store, options } as PiniaPluginContext, subscriber, subscriberKey)\n return\n }\n\n this.executeSubscriber({ store, options } as PiniaPluginContext, subscriber)\n }\n )\n\n this.rewriteResetStore({ store } as PiniaPluginContext, store.$state)\n this._storeRollbackSnapshotsHandler.initFromPluginContext({ store, options } as PiniaPluginContext)\n this.executeStoreOnActionSubscription(store)\n this.registerStoreCleanup(store)\n } catch (e) {\n this.logError(e, store, options)\n }\n }\n\n private queueSubscriberExecution(\n context: PiniaPluginContext,\n subscriber: PluginSubscriber,\n subscriberKey: string\n ): void {\n const scheduler = this.defineHydrationScheduler(subscriber)\n\n this._subscribersScheduled.add(subscriberKey)\n scheduler(() => {\n this._subscribersScheduled.delete(subscriberKey)\n this.executeSubscriberSafely(context, subscriber)\n })\n }\n\n private registerStoreCleanup(store: Store): void {\n this._onActionSubscriptions = []\n if (typeof store.$dispose !== 'function') {\n return\n }\n\n const dispose = store.$dispose.bind(store)\n const scopedStore = store as AnyObject\n\n if (scopedStore.__piniaPluginSubscriptionDisposed) {\n return\n }\n\n scopedStore.__piniaPluginSubscriptionDisposed = true\n store.$dispose = () => {\n this.clearStoreTracking(store)\n this._storeRollbackSnapshotsHandler.clearStoreTracking(store)\n return dispose()\n }\n }\n\n private rewriteResetStore({ store }: PiniaPluginContext, initState: StateTree): void {\n const safeState = deepClone(initState)\n\n store.$reset = () => {\n this.debugLog('rewriteResetStore()', { initState: safeState, store })\n\n this.executeResetStoreCallbacks(store)\n\n store.$patch(deepClone(safeState))\n }\n }\n\n private shouldInvokePlugin(execution: Required<PluginExecutionOptions>): boolean {\n const currentEnvironment = this.defineCurrentEnvironment()\n\n return execution.environment === 'both' || execution.environment === currentEnvironment\n }\n\n private shouldScheduleAfterHydration(execution: Required<PluginExecutionOptions>): boolean {\n return this.defineCurrentEnvironment() === 'client' && execution.hydration === 'defer'\n }\n\n private storeOnActionSubscription(subscriber: PluginSubscriber): void {\n const { store, callback } = subscriber?.storeOnActionSubscription?.() ?? {}\n\n if (!store || !callback) {\n return\n }\n\n this._onActionSubscriptions.push(callback)\n }\n\n private storeMutationSubscription(subscription: StoreMutationSubscription): void {\n const { store, callback } = subscription()\n\n store.$subscribe((mutation: SubscriptionCallbackMutation<StateTree>) => {\n this.debugLog(`$subscribe ${store.$id}`, { mutation, store })\n callback(mutation)\n })\n }\n\n private subscriptionDelivery(\n context: PiniaPluginContext,\n pluginSubscriptions: PluginSubscriptions\n ): void {\n Object.entries(pluginSubscriptions).forEach(([pluginName, pluginSubscription]) => {\n const subscriptionKey = this.defineSubscriptionKey(pluginName, context.store)\n const execution = this.definePluginExecution(pluginSubscription.subscription)\n\n if (\n this._subscriptionsDelivered.has(subscriptionKey)\n || this._subscriptionsScheduled.has(subscriptionKey)\n ) {\n return\n }\n\n if (!this.shouldInvokePlugin(execution)) {\n return\n }\n\n if (this.shouldScheduleAfterHydration(execution)) {\n const scheduler = this.defineHydrationScheduler(pluginSubscription.subscription)\n\n this._subscriptionsScheduled.add(subscriptionKey)\n scheduler(() => {\n this._subscriptionsScheduled.delete(subscriptionKey)\n this.subscriptionDeliverySafely(context, pluginName, pluginSubscription)\n })\n return\n }\n\n this.subscriptionDeliverySafely(context, pluginName, pluginSubscription)\n })\n }\n\n private subscriptionDeliverySafely(\n { store, options }: PiniaPluginContext,\n pluginName: string,\n pluginSubscription: PluginSubscriptionDefinition\n ): void {\n try {\n if (this._subscriptionsDelivered.has(this.defineSubscriptionKey(pluginName, store))) {\n return\n }\n\n const { subscription, subscriptionOptions, stores } = pluginSubscription\n\n this.debugLog(`subscriptionDelivery() - store: ${store.$id}`, [\n 'pluginName:', pluginName,\n 'subscription:', subscription,\n 'options:', pluginSubscription,\n 'stores:', stores\n ])\n\n const pluginOptions = {\n storeOptions: { ...((options as AnyObject)?.storeOptions ?? {}), ...subscriptionOptions }\n } as AnyObject\n\n subscription.invoke(\n { store, options: { ...options, ...pluginOptions } } as PiniaPluginContext,\n this.debug\n )\n this._subscriptionsDelivered.add(this.defineSubscriptionKey(pluginName, store))\n\n if (!isEmpty(stores)) {\n stores?.forEach(\n store => subscription.invoke(\n {\n store,\n options: {\n ...options,\n ...pluginOptions,\n ...((store as AnyObject)?.storeOptions ?? {})\n }\n } as PiniaPluginContext,\n this.debug\n )\n )\n }\n } catch (e) {\n this.logError(`subscriptionDelivery()`, e, store, options)\n }\n }\n}"],"names":["deepClone","value","key","entryValue","item","clonedObject","createStateSnapshot","state","keys","clonedState","toRaw","RollbackStateSnapshotsHandler","__publicField","store","action","stateKeys","args","actionFn","hasDeniedFirstChar","snapshotKey","error","actionName","getActionStoreKey","options","rollbackSnapshotParams","suffix","stateSnapshot","className","defaultPluginExecution","defaultHydrationScheduler","callback","isPluginSubscriptionOptions","PluginSubscription","Debug","subscribers","debugOrOptions","pluginOptions","debug","PluginConsole","storageKey","after","onError","subscriber","pluginName","onActionSubscriptions","hasRollbackSnapshots","name","afterCallbacks","onErrorCallbacks","result","context","subscriberKey","hydrateResult","runAfterHydration","afterHydration","e","execution","scheduler","dispose","scopedStore","initState","safeState","currentEnvironment","subscription","mutation","pluginSubscriptions","pluginSubscription","subscriptionKey","subscriptionOptions","stores","isEmpty","store2","createPlugin","createHydrationPlugin","hydrationPlugin"],"mappings":";;;;;;AAMO,SAASA,EAAaC,GAAa;AACtC,MAAI,OAAO,mBAAoB;AAC3B,QAAI;AACA,aAAO,gBAAgBA,CAAK;AAAA,IAChC,QAAQ;AAAA,IAER;AAGJ,MAAIA,MAAU,QAAQ,OAAOA,KAAU;AACnC,WAAOA;AAGX,MAAIA,aAAiB;AACjB,WAAO,IAAI;AAAA,MACP,MAAM,KAAKA,EAAM,QAAA,GAAW,CAAC,CAACC,GAAKC,CAAU,MAAM,CAACH,EAAUE,CAAG,GAAGF,EAAUG,CAAU,CAAC,CAAC;AAAA,IAAA;AAIlG,MAAIF,aAAiB;AACjB,WAAO,IAAI,IAAI,MAAM,KAAKA,EAAM,OAAA,GAAU,CAAAE,MAAcH,EAAUG,CAAU,CAAC,CAAC;AAGlF,MAAI,MAAM,QAAQF,CAAK;AACnB,WAAOA,EAAM,IAAI,CAAAG,MAAQJ,EAAUI,CAAI,CAAC;AAG5C,MAAI,OAAO,eAAeH,CAAK,MAAM,OAAO,aAAa,OAAO,eAAeA,CAAK,MAAM;AACtF,WAAO,OAAO;AAAA,MACV,OAAO,QAAQA,CAAgC,EAAE,IAAI,CAAC,CAACC,GAAKE,CAAI,MAAM,CAACF,GAAKF,EAAUI,CAAI,CAAC,CAAC;AAAA,IAAA;AAIpG,QAAMC,IAAe,OAAO,OAAO,OAAO,eAAeJ,CAAK,CAAC;AAC/D,aAAW,CAACC,GAAKE,CAAI,KAAK,OAAO,QAAQH,CAAgC;AACrE,IAAAI,EAAaH,CAAG,IAAIF,EAAUI,CAAI;AAGtC,SAAOC;AACX;ACtCO,SAASC,EAAoBC,GAAkBC,IAAgC,OAAO;AACzF,MAAI,MAAM,QAAQA,CAAI,GAAG;AACrB,UAAMC,IAAkC,CAAA;AACxC,eAAWP,KAAOM;AACd,MAAIN,KAAOK,MACPE,EAAYP,CAAG,IAAIF,EAAUU,EAAMH,EAAML,CAAG,CAAC,CAAC;AAGtD,WAAOO;AAAA,EACX;AAEA,MAAID,MAAS;AACT,UAAM,IAAI,MAAM,2BAA2BA,CAAI,EAAE;AAGrD,SAAOR,EAAUU,EAAMH,CAAK,CAAC;AACjC;ACTA,MAAqBI,EAA8B;AAAA,EAAnD;AACY,IAAAC,EAAA,6CAA8C,IAAA;AAC9C,IAAAA,EAAA,wDAA8C,IAAA;AAC9C,IAAAA,EAAA,2DAA0E,IAAA;AAAA;AAAA,EAAI,kBAAAC,GAAA;AAAA,IAAA,OAAAA,EAAA,yBAAA,eAAAA,EAAA,wBAAA,OAAA,EAAA,QAAAC,GAAA,WAAAC,EAAA,GAAAC,IAAA,CAAA,MAAA;AAAA,YAAAC,IAAAJ,EAAAC,CAAA;AAUtF,UAAA,OAAAG,KAAsC,cAAAC,EAAAJ,CAAA;AAC9B;AAEJ,YAAAN,IAAA,CAAAO,KAAAA,EAAA,WAAA,IAAA,QAAAA,GAEMI,IAAA,KAAA,kBAAiCN,GAAQC,GAAmCN,CAAA;AAC9E;AACA,cAAIS,EAAO,MAAAJ,GAAaG,CAAA;AAAA,MACpB,SAAAI,GAAA;AACJ,mBAAA,WAAAD,GAAAN,CAAA,GAEMO;AAAA,MAEN,UAAA;AACA,aAAI,oBAAAD,CAAA;AAAA,MACA;AAAA,IAAgC;AAAA,EAEhC;AAAA,EACM,wBACRE,GAAAR,GAAA;AACE,UAAAE,IAAK,KAAA,8BAA+B;AAAA,MACxCO,EAAAD,GAAAR,CAAA;AAAA,IACJ;AACJ,QAAA,CAAAE,KAAAA,EAAA,WAAA;AAAA;AAAA,UAAAI,IAAA,KAAA,kBAAAN,GAAAQ,GAAAN,CAAA;AAAA,WAAA;AAAA,MAAA,OAAA,MAAA;AAAA,aAAA,oBAAAI,CAAA;AAAA,MAAA;AAAA,MASA,SAAA,MAAA;aAOU,cAAiBN,CAAA,GACnB,KAAA,oBAAkBM,CAAiB;AAAA,MACvC;AAAA,IAEA;AAAA,EACI;AAAA,EAGJ,sBAAoB,EAAA,SAAAI,GAAK,OAAAV,EAAA,GAAA;AAEzB,UAAAW,IAAOD,GAAA,cAAA;AAAA,IACHC,KAAa,CAAA,KAAA,2BAAA,IAAAX,EAAA,GAAA,MAAE,OAAK,KAAAW,WAA+B,CAAAtB,MAAA;AAAE,WAAA,8BAAA;AAAA,QACrDoB,EAAepB,GAAAW,CAAA;AAAA,UACKX;MAChB;AAAA,IACJ,CAAA,GACJ,KAAA,2BAAA,IAAAW,EAAA,GAAA,IACJ,KAAA,kBAAAA,CAAA;AAAA,EAAA;AAAA,EAAA,mBAAAA,GAAA;AAAA,UAAAY,IAAA,IAAAZ,EAAA,GAAA;AAAA,eAAAX,KAAA,MAAA,KAAA,KAAA,8BAAA,KAAA,CAAA;iBAQAuB,WACU,qCAAkCvB,CAAA;AAGhC,SAAA,2BAAK,OAA8BW,EAAA,GAAA;AAAA,eAC/BM,KAAkB,WAAU,KAAA,gBAAA,KAAA,CAAA;AAAA,MAC5BA,EAAA,aAAuB,WAAG,GAAAN,EAAA,GAAA,GAAA,KAAA,KAC9B,gBAAA,OAAAM,CAAA;AAAA,EAEyC;AAAA,EAEjD,WAAKA,MAAuB;AAChC,UAAAO,IAAA,KAAA,gBAAA,IAAAP,CAAA;AAAA,QAAAO;AAAA,UAAA;AAAA,QAAAb,EAAA,OAAAa,CAAA;AAAA,MAAA,SAAAN,GAAA;AAQA,gBAAA,6CAAuC,OAAAD,CAAA,CAAA,IAAAC,CAAA;AAAA,MACnC;AAAA,EAEA;AAAA,EAEQ,oBAAKD,GAAA;AAAwC,IACjDA,KAKJ,KAAA,gBAAW,QAA0B;AAAA,EACjC;AAAA,EAC2C,kBAC3CN,GAAAQ,GAAAN,GAAA;AACJ,UAAAW,IAAApB;AAAA,MACJO,EAAA;AAAA,MAEQE;AAAA,IACJ,GACKI,IAAe,uBAAA,GAAAN,EAAA,GAAA,IAAAQ,CAAA,EAAA;AAChB,gBAAA,gBAAA,IAAAF,GAAAO,CAAA,GACJP;AAAA,EAEA;AAAA,EAC8B,0BACdN,GAAA;AACZ,WAAA,KAAQ,2BAAM,IAAAA,EAAA,GAAA;AAAA,EAAmE;AACrF;AACJ,MAAAc,IAAA,sBAAAC,IAAA;AAAA,EAAA,aAAA;AAAA,EAAA,WAAA;AAAA;AAQI,SAAKC,EAAaC,GAAA;AACd,MAAA,OAAA,SAAA,OAAA,OAAA,OAAA,yBAAA,YAAA;AACJ,WAAA,sBAAA,MAAA,WAAA,WAAAA,GAAA,CAAA,CAAA;AAEA;AAAA,EACJ;AAAA,aAAA,WAAAA,GAAA,CAAA;AAAA;AAAA,SAAAC,EAAA9B,GAAA;AAAA,SAAAA,MAAA,UAAA,CAAA,MAAA,QAAAA,CAAA;AAAA;AAAA,MAAA+B,UAAAC,EAAA;AAAA,EC/HA,YAAWC,GAAAC,GAAAC,GAAA;AACf,UAAAC,IAAA,MAAA,QAAAF,CAAA,IAAAA,IAAA,QAESZ,IAAAQ,EAAsDI,CAAA,IAAAA,IAAAC;AAC3D,UAAI,MAAO,QAAWC,CAAA,KAAA,CAAA,CAAAA,GAAe,SAAOV,CAAO,GAAAW;AD2HnD,IAAA1B,EAAA,oBAAAe;AASQ,IAAAf,EAAA;AACJ,IAAAA,EAAA,gCAAsB,CAAA;AAAA,IAAAA,EAAA,qCACZ,CAAA;AAAA,IAAAA,EAAA,uCACN,CAAA;AAAA,IAAAA,EAAA;AAGJ,IAAAA,EAAA;AACA,IAAAA,EAAA,6BAAK,CAAgB;AACrB,IAAAA,EAAA,wCAAO,IAAAD,EAAA;AACX,IAAAC,EAAA,sBAAA,CAAA;AAAA,IAAAA,EAAA,+BAAA,oBAAA,IAAA;AAAA,IAAAA,EAAA,+BAAA,oBAAA,IAAA;AAAA,IAAAA,EAAA,wBAAA,CAAA;AAAA,IAAAA,EAAA,iCAAA,oBAAA,IAAA;AAAA,IAAAA,EAAA,iCAAA,oBAAA,IAAA;AC5II,SAAA,sBAAOW,GAA4B,sBAAsBM,GACzD,KAAA,WAAAN,GACJ,KAAA,eAAA,MAAA,QAAAc,CAAA,IAAAA,IAAA,4BAEsBH;AAAA,EAC1B;AAAA,ED8II,IAAA,YAAAA,GAA0B;AACtB,SAAA,eAAYA;AAAA,EAChB;AAAA,EACJ,IAAA,gBAAA;;AC9JM,aAAA,KAAY;AAAA,EAEd;AAAA,EAaJ,yBAASb,GACLR,GACkCiB,GAAA;AAClC,UAAO5B,IAAAoB,EAAwBD,GAAcR,CAAK;AACtD,IAAA,KAAA,4BAAAX,CAAA,MAGqB,KAAA,4BAAiCA,CAAA,IAAA,CAAA,IAE1C,KAAA,4BAAAA,CAAA,GAAA,KAAA4B,CAAA;AAAA,EACA;AAAA,EACA,8BAAsFjB,GAAAiB,GAAA;AACtF,UAAA5B,IAAAoB,EAAiFD,GAACR,CAAA;AAClF,IAAA,KAAA,8BAAAX,CAAA,MACA,KAAA,8BAAAA,CAAA,IAAA,CAAA,IAEA,KAAA,8BAAoEA,CAAA,GAAA,KAAA4B,CAAA;AAAA,EACpE;AAAA,EACA,sBAAAA,GAAA;AACA,SAAA,oBAAA,KAAAA;EACA;AAAA,EACA,oCAAAS,GAA2C;AAC3C,WAAA,KAAA,6BAA+C,GAEvD,OAAI,KAAA,8BAA6CA,CAAA;AAAA,EAC7C;AAAA,EACJ,mBAAA1B,GAAA;AAEA,cAAI,IAAmDA,EAAA,GAAA;AACnD,eAAKX,KAAa,MAAA,KAAA,KAAc,qBAAG;AAC/B,MAAAA,EAAO,SAAKuB,CAAA,KAChB,KAAA,sBAAA,OAAAvB,CAAA;AAQA,eAAMA,KAAQ,MAAM,KAAQ,KAAA,qBAAkB;AAC9C,MAAMA,EAAA,SAAUuB,CAAA,UAEV,sBAAyB,QAAQ;AAGvC,eAAKvB,KAAA,MAAe,KAAM,KAAQ,uBAAiB;AACnD,MAAKA,EAAA,SAAAuB,CAAe,KACxB,KAAA,wBAAA,OAAAvB,CAAA;AAKI,2DAA4C;AACxC,MAAAA,EAAK,SAAAuB,CAAA,KACT,KAAA,wBAAA,OAAAvB,CAAA;2BAI+B,KAAA,KAAA,2BAA4E;AAC3G,MAAMA,EAAA,SAAMuB,CAAA,KACR,wCAAuCvB,CAAG;AAG9C,eAAKA,KAAA,OAAA,KAAA,KAA8B,6BAAmB;AAC1D,MAAAA,EAAA,SAAAuB,CAAA,KAEQ,OAAA,KAAA,8BAAgDvB,CAAA;AAAA,EAIhD;AAAA,EAEJ,qCAAYmB,MAAwC;AACxD,WAAA,CAAAS,MAAA;AAEQ,WAAA,yBAAuCT,GAAAR,GAAAiB,CAAA;AAAA,IAC3C;AAAA,EAEA;AAAA,EAEQ,0CAAqCjB,GAAA;AAAA,WACzC,CAAAiB,MAAA;AACJ,WAAA,2BAAAT,GAAAR,GAAAiB,CAAA;AAAA,IAEA;AAAA,EACI;AAAA,EACyC,uBACzCT,GAAAR,GAAA;AACJ,UAAA;AAAA,MAEA,OAAA2B;AAAA,MACI,SAAAC;AAAA,IACI,IAAA,KAAK,+BAA+B;AAAA,MACxCpB;AAAA,MACJR;AAAA,IAEA,KAAA,CAAA;AACI,iBAGJ,KAAA,yBAAAQ,GAAAR,GAAA2B,CAAA,GAEA,KAAA,2BAA8BnB,GAAKR,GAAA4B,CAAA;AAAA,EAC/B;AAAA,EACI,2BAAY;AAA+B,WAC/C,KAAA,UAAA,uBAAA,OAAA,SAAA,MAAA,WAAA;AAAA,EAAA;AAAA,EAGJ,kBAAWC,GAAc;AACrB,WAAI,CAAA,CAAA,mBAAsB,SAAAA,EAAA,IAAA;AAAA,EACtB;AAAA,EAA6C,sBACjDA,GAAA;AACJ,WAAA;AAAA,MACJ,GAAAd;AAAA,MAAA,GAAA,KAAA,UAAA,aAAA,CAAA;AAAA,MAAA,GAAAc,EAAA,aAAA,CAAA;AAAA,MAAA,GAAA,KAAA,UAAA,sBAAAA,EAAA,IAAA,KAAA,CAAA;AAAA,IAAA;AAAA,EAAA;AAAA,EAAA,yBAAAA,GAAA;AAQQ,WAAAA,EAAA,sBAAqC;EACzC;AAAA,EACI,oBAAKA,GAAA7B;AACT,WAAA,GAAA6B,EAAA,IAAA,IAAA7B,EAAA,GAAA;AAAA,EACJ;AAAA,EAAA,sBAAA8B,GAAA9B,GAAA;AAAA,WAAA,GAAA8B,CAAA,IAAA9B,EAAA,GAAA;AAAA,EAAA;AAAA,EAAA,2BAAAA,GAAA;AAAA,SAAA,oBAAA,QAAA,CAAAiB,MAAAA,EAAAjB,CAAA,CAAA;AAAA,EAAA;AAAA,EASI,iCAA+CA,GAAA;AAC3C,UAAA+B,IAAK,6BACTC,IAAA,KAAA,+BAAA,0BAAAhC,CAAA;AACJ,IAAA,CAAA+B,GAAA,UAAA,CAAAC,KAAAhC,EAAA,UAAA,CAAA,EAAA,OAAA2B,GAAA,MAAAxB,GAAA,MAAA8B,GAAA,SAAAL,EAAA,MAAA;AAAA,YAAAF,IAAAjB,EAAAwB,GAAAjC,CAAA;AAAA,WAAA,SAAA,6BAAA0B,CAAA,IAAA,EAAA,MAAAvB,GAAA,MAAA8B,GAAA,OAAAjC,EAAA,CAAA,GAAAgC,KAQQ,KAAA,0BAEJhC,CACF,GAEM+B,GAAA,UACAA,EAAA,QAAA,CAAAd,MAAAA,EAAA;AAAA,QACA,OAAK,KAAA,qCAA+BgB,GAAAjC,CAAA;AAAA,QACpC,MAAAG;AAAA,QACA,MAAA8B;AAAA,QACC,SAAC,KAAA,uCAAAA,GAAAjC,CAAA;AAAA,MAEF,CAAC,CAAA;AAEL,YAAAkC,IAAA,KAAA,4BAAAR,CAAA,GAEKS,IAAA,mCAAiDT,CAAA;AACtD,WAAK,oCAA2BA,CAAmB,GACvDQ,GAAA,mBAEQ;AACJ,QAAAA,UAAsB,CAAAjB,MAAAA,EACPmB,CAAA;MACnB,CAAA,GAGID,GAAc,UAClBP,EAAA,CAAArB,MAAA;AAEQ,QAAA4B,EAAsB,QAAA,CAAgElB,MAAAA,EAAAV,CAAA,CAAA;AAAA,MAC1F,CAAA;AAAA,IACO,CAAA;AAAA,EAC8B;AAAA,EACJ,kBACpB8B,GAAUR,GAAA;AAA2C,UAClES,IAAA,KAAA,oBAAAT,GAAAQ,EAAA,KAAA,GACJb,IAAA,KAAA,kBAAAK,CAAA;AAMQ,QAJA,KAAA,sBAAyB,IAAuGS,CAAA,KAIhI,CAAAT,EAAA;AAAA,MACJQ;AAAA,MACJb;AAAA,IAEQ;AACJ;AAGI,SAAA,sBAA2B,IAAAc,CAAoB;AACnD,QAAAC;AACJ,QAAA;AAAA,MAAAA,IAAAV,EAAA,UAAAQ,GAAAb,CAAA;AAAA,IAAA,SAAAjB,GAAA;AAAA,WAAA,SAAAA,GAAA8B,EAAA,OAAAA,EAAA,OAAA;AAAA;AAAA,IAAA;AAAA,UAAAG,IAAA,MAAA;AAQQ,UAAA;AACJ,cAAMC,MAA6B,iBAAAJ,GAAAb,CAAA;AACnC,QAAMiB,KAAA,OAAuBA,wBAGzBA,EAAA,MAAA,CAAAlC,MAAA,KAAA,SAAAA,GAAA8B,EAAA,OAAAA,EAAA,OAAA,CAAA;AAAA,MAGJ,SAAM9B,GAAW;AACb,sBAAMA,GAAa8B,EAAA,OAAkBA,SAAW;AAAA,MAChD;AAAA,IAEA;AACI,IAAAE,KAAK,OAAAA,UAAkC,aAC3CA,EAAA,KAAA,MAAAC,EAAA,CAAA,EAAA,MAAA,CAAAjC,MAAA,KAAA,SAAAA,GAAA8B,EAAA,OAAAA,EAAA,OAAA,CAAA,IAGIG,EAAA,GACgEX,EAC5D,iBAAA,KACA,qBAAAQ,GAAAR,EAAA,aAAA,GACgEA,EAClE,6BACN,KAAA,0BAAAA,EAAA,yBAAA,GAGA,KAAA,0BAAyBA,CAAK,GAE9BA,EAAK,sBAEL,KAAI,sBAAgBA,EAAQ,kBAAA;AAAA,EAEpB;AAAA,EAAmD,wBACtDQ,GAAAR,GAAA;AAAA,QACL;AACA,WAAI,kBAAkBQ,GAAQR,CAAA;AAAA,IAC1B,SAAAa,GAAQ;AACJ,WAAA,SAAAA,GAAAL,EAAiB,OAAQA,EAAA,OAAY;AAAA,IAAe;AAAA,EACvD;AAAA,EACL,OACH,EAAA,OAAArC,GAAA,SAAAU,EAAA,GAAA;AACL,QAAA,KAAA,aAAA,QAII;AAAA,WAAA,SAAc,cAAKV,EAAA,GAAkB;QAErC;AAAA,QACI,KAAA;AAAA,QACJ;AAAA,QAEAA;AAAA,QAEQ;AAAA,QACAU;AAAA,MAAA,CACJ;AACA,UAAA;AACJ,aAAA,aAAA;AAAA,UAEA,CAAKmB,MAAA;AAED,kBAAAS,IAAA,KAAA,oBAAAT,GAAA7B,CAAA,GAEA2C,IAAA,KAAA,sBAAAd,CAAA;AACA,gBAAA,OAAA,sBAA2B,IAAUS,CAAc,KAAA,KAAA,sBAAA,IAAAA,CAAA,MAGnD,KAAA,mBAAAK,CAAA,GAII;AAAA,kBAAA,KAAA,6BAAAA,CAAA,GAAA;AACA,qBAAM,yBAA4B,uBAAiB,GAAAd,GAAcS,CAAA;AAC7D;AAAA,cACA;AAAG,mBAAA,kBAAuC,EAAA,OAAAtC,GAAS,SAAAU,EAAK,GAAAmB,CAAgB;AAAA;AAAA,UAC5E;AAAA,QACJ,GACI,KAAA,kBAAqB,EAAA,OAAA7B,EAAQ,GAAAA,EAAO,MAAQ,GAChD,KAAA,+BAAA,sBAAA,EAAA,OAAAA,GAAA,SAAAU,EAAA,CAAA,GACJ,KAAA,iCAAAV,CAAA,GAEA,0BAA6BA;MACvB,SAAC0C,GAAA;AAGP,aAAO,SAAAA,GAAA1C,GAAAU,CAAA;AAAA,MACH;AAAA;AAAA,EAAkB;AAAA,EAGtB,yBAAe2B,GAAeR,GAAAS,GAAA;AAC1B,UAAAM,IAAK,KAAA,yBAAyCf,CAAA;AAClD,SAAA,sBAAA,IAAAS,CAAA,GAEAM,EAAI,MAAW;AACX,WAAK,sBAAA,OAA0BN,IACnC,KAAA,wBAAAD,GAAAR,CAAA;AAAA,IAEA,CAAA;AAAA,EAEA;AAAA,EACI,qBAAK7B,GAAA;AAEb,QADI,KAAA,yBAAA,CAAA,GACJ,OAAAA,EAAA,YAAA;AAEQ;AAEA,UAAA6C,IAAK7C,EAAA,SAAkB,aACfA;AACR,IAAA8C,EAAc,wCAIb,oCAAsC,IAC3C9C,EAAK,WAAK,OACN,KAAA,mBAAAA,CAAA,GACJ,KAAA,+BAAA,mBAAAA,CAAA,GAEK6C,EAAS;AAAA,EACV;AAAA,EAAoB,kBACpB,EAAA,OAAA7C,EAAA,GAAA+C,GAAA;AAAA,UAAUC,IAAA7D,EAAA4D,CAAA;AAAA,IAAA/C,EACV,SAAA,MAAA;AAAY,WAAA,SAAA,uBAAA,EAAA,WAAAgD,GAAA,OAAAhD,EAAA,CAAA,GACf,KAAA,2BAAAA,CAAA,GAEDA,EAAI,OAAAb,EAAA6D,CAAA,CAAA;AAAA,IACA;AAAA,EAAkB;AAAA,EAEV,mBAAML,GAAgB;AACtB,UAAAM,IAAkB,KAAK;AAEvB,uCACmCN,EAAA,gBACvBM;AAAA,EAER;AAAA,EAAA,6BACJN,GAAA;AAEA,WAAA,KAAK,yBAAwB,MAAA,YAAYA,EAAA,cAAA;AAAA,EACrC;AAAA,EAAA,0BACJd,GAAA;AAEA,UAAA,YAAS,UAAAZ,qCAAyC,KAAA,CAAA;AAC9C,IAAA,CAAAjB,KAAK,CAAAiB,KAIT,KAAA,uBAAK,KAAoBA,CAAO;AAAA,EAA2C;AAAA,EAC/E,0BACJiC,GAAA;AAEA,UAAA,EAAK,OAAAlD,GAAA,UAAAiB,EAAA,IAAoBiC;AACzB,IAAAlD,EAAA,WAAK,CAAAmD,MAAA;AACL,WAAK,SAAA,cAAAnD,EAAA,SAAsC,UAAAmD,GAAA,OAAAnD,EAAA,CAAA,GAC3CiB,EAAKkC,CAAA;AAAA,IACT;EACI;AAAA,EAA+B,qBACnCd,GAAAe,GAAA;AACJ,WAAA,QAAAA,CAAA,EAAA,QAAA,CAAA,CAAAtB,GAAAuB,CAAA,MAAA;gBAGI,8BAGIhB,EAAA,KAAA,OACc,KAAK,sBAAAgB,EAAmC,YAAA;UAErD,OAAA,6BAAuC,KAAA,KAAA,wBAAA,IAAAC,CAAA,MAGnC,KAAA,mBAAwBX,CAAS,GAItC;AAAA,YAAA,KAAA,6BAAyCA,CAAA,GAAA;AAC7C,gBAAKC,IAAA,8BAA0BS,EAAA,YAAA;AAC3B,eAAA,6BAAsC,GACtCT,EAAA,MAAA;AACJ,iBAAA,wBAAA,OAAAU,CAAA,GAEM,KAAA,2BAA8BjB,GAAKP,GAAAuB,CAAA;AAAA,UACzC,CAAA;AAEI;AAAA,QACA;AACJ,aAAA,2BAAAhB,GAAAP,GAAAuB,CAAA;AAAA;AAAA,IAEA,CAAA;AAAA,EACA;AAAA,EACI,uCAA6B,SAAA3C,EAAA,GAAAoB,GAAAuB,GAAA;AAC7B;AACA,UAAA,6BAAe,IAAA,KAAA,sBAAAvB,GAAA9B,CAAA,CAAA;AACnB;+BAGwB,qBAAAuD,GAAyD,QAAAC,EAAA,IAAAH;WAC3E,SAAA,mCAA+BrD,EAAA,GAAA,IAAA;AAAA,QAErC;AAAA,QACI8B;AAAA,QAEA;AAAA,QAEAoB;AAAA,QACJ;AAAA,QACJG;AAAA,QAEQ;AAAA;MAGJ,CAAA;AACJ,YAAA9B,IAAA;AAAA,QAEQ,cAAA,EAAA,GAAAb,GAA6B,gBAAsD,CAAA,GAAA,GAAA6C,EAAA;AAAA,MACvF;AACJ,MAAAL,EAAA;AAAA,QAEQ,EAAA,OAAAlD,GAAA,SAAA,EAA0B,GAAAU,GAAoC,GAAAa,EAAA,EAAA;AAAA,QAClE,KAAQ;AAAA,SAGJ,KAAA,wBAAA,IAAA,KAAA,sBAAAO,GAAA9B,CAAA,CAAA,GACJyD,EAAAD,CAAA,KAEAA,GAAK;AAAA,QACT,CAAAE,MAAAR,EAAA;AAAA,UAEQ;AAAA,YACI;YAEF;cACG,GAAAxC;AAAA,cACI,GAAAa;AAAA,cACZ,GAAAmC,GAAA,gBAAA,CAAA;AAAA,YACL;AAAA,UAEQ;AAAA,UAIG,KAAA;AAAA,QACH;AAAA,MACA;AAAA,IAMI,SAAAhB,GAAA;AACJ,WAAA,SAAA,0BAAAA,GAAA1C,GAAAU,CAAA;AAAA,IAEA;AAAA,EACI;AAAA;AAIA,SAAAiD,EAAMtC;AAEN,QAAAgC,IAAK,IAAAlC,KAA2CK,CAAA;AAChD,SAAA6B,EAAgB,OAAA,KAAAA,CAAA;AACZ;AACuE,SAC1EO,EAAAvC,GAAAX,GAAA;AACD,QAAAmD,IAAA,IAAA1C,EAAAE,GAAAX,GAAA,OAAA;AAAA,IAAA,WACJA,GAAA;AAAA,IAEA,oBAAKA,GAAA;AAAA,IACT,oBAACA,GAAA;AAAA,IACL,qBAAAA,GAAA;AAAA,EAEQ,CAAA;AAKJ,SAAImD,EAAA,OAAA,KAAAA,CAAA;AACA;"}
@@ -1,9 +1,17 @@
1
1
  import type { PiniaPlugin } from "pinia";
2
2
  import type { PluginSubscriber } from "../types/plugin";
3
- import type { StoreOptions } from "../types/store";
3
+ import type { RollbackActionParams, StoreOptions } from "../types/store";
4
4
  export declare function createPlugin(subscribers: PluginSubscriber[], debug?: string[]): PiniaPlugin;
5
5
  declare module 'pinia' {
6
6
  interface PiniaCustomProperties {
7
+ /**
8
+ * Executes an action and restores the previous state snapshot if it fails.
9
+ * Added to every store when the plugin is active.
10
+ *
11
+ * @param params The action name and the state keys to snapshot.
12
+ * @param args The action arguments, passed as a single array (forwarded via `apply`).
13
+ */
14
+ $rollbackAfterFailure: (params: RollbackActionParams, args?: any[]) => Promise<void>;
7
15
  }
8
16
  interface DefineStoreOptionsBase<S, Store> {
9
17
  storeOptions?: StoreOptions;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Compile-only contract for the centralized store-options extension point.
3
+ * Simulates a subscriber plugin augmenting the contract through interface
4
+ * merging, instead of redeclaring pinia's `DefineStoreOptionsBase` (which
5
+ * would raise TS2717 on type mismatch in consumer projects).
6
+ */
7
+ declare module '../types' {
8
+ interface StoreOptionsExtensions {
9
+ testExtension?: string;
10
+ }
11
+ }
12
+ export {};
@@ -19,7 +19,7 @@ export type ConsoleStyleDefinition = StyleDefinition;
19
19
  export type ConsoleStyleDefinitionKeys = StyleDefinitionKeys;
20
20
  export type ConsoleStyleDefinitions = StyleDefinitions;
21
21
  export type { List, ListTypes, ListTypesMap, PartialList } from './list';
22
- export type { CustomStore, DefineAStoreSetupContext, DefineAStoreSetupExtensions, EmptyExtensions, PluginStoreOptions, StatePropertyValue, StoreOptions, StoreOptionsPropertyValue } from './store';
22
+ export type { CustomStore, DefineAStoreDefinition, DefineAStoreSetupContext, DefineAStoreSetupExtensions, EmptyExtensions, PluginStoreOptions, StatePropertyValue, StoreOptions, StoreOptionsExtensions, StoreOptionsPropertyValue } from './store';
23
23
  export type { NativePiniaSubscription, NativePiniaSubscriptionReturn, PluginExecutionEnvironment, PluginExecutionOptions, PluginHydrationScheduler, PluginHydrationTiming, PluginRuntimeEnvironment, PluginSubscriber, PluginSubscription, PluginSubscriptionOptions, PluginSubscriptions, StoreMutationSubscription, StoreMutationSubscriptionCallback, StoreMutationSubscriptionReturn, StoreOnActionCallbackParameters, StoreOnActionSubscription, StoreOnActionSubscriptionCallback, StoreOnActionSubscriptionReturn, } from './plugin';
24
24
  export interface PluginSubscriberInterface {
25
25
  console?: Console;
@@ -1,6 +1,7 @@
1
1
  import type { PiniaPluginContext, StateTree, Store, SubscriptionCallbackMutation } from "pinia";
2
2
  import type { StoreOptions } from "./store";
3
3
  import type { Console, PluginSubscriberInterface } from ".";
4
+ export type CreateStateSnapshotKeys = (keyof StateTree)[] | 'all';
4
5
  export type PluginHydrationScheduler = (callback: () => void) => void;
5
6
  export type PluginHydrationTiming = 'defer' | 'immediate';
6
7
  export type PluginRuntimeEnvironment = 'client' | 'server';
@@ -33,11 +34,13 @@ export interface NativePiniaSubscriptionReturn<Callback> {
33
34
  store: Store;
34
35
  callback: Callback;
35
36
  }
37
+ export type StoreOnActionAfterCallbackParameter = (callback: (result?: unknown) => void) => void;
38
+ export type StoreOnActionOnErrorCallbackParameter = (callback: (error: unknown) => void) => void;
36
39
  export interface StoreOnActionCallbackParameters {
37
- after: Function;
40
+ after: StoreOnActionAfterCallbackParameter;
38
41
  args: any[] | object;
39
42
  name: string;
40
- onError?: Error | unknown;
43
+ onError?: StoreOnActionOnErrorCallbackParameter;
41
44
  }
42
45
  export interface PluginSubscription {
43
46
  stores?: Store[];
@@ -1,7 +1,27 @@
1
1
  import type { AnyObject } from ".";
2
- import type { PiniaCustomProperties, Store, StoreDefinition } from "pinia";
2
+ import type { CreateStateSnapshotKeys } from "./plugin";
3
+ import type { Pinia, PiniaCustomProperties, StateTree, Store, StoreDefinition, StoreGeneric } from "pinia";
3
4
  import type { Ref } from "vue";
4
5
  export type CustomStore<TStore, TState> = Store & TStore & TState & PiniaCustomProperties & StoreDefinition;
6
+ /**
7
+ * Store definition returned by `defineAStore`/`defineAStoreCtx` when explicit
8
+ * store/state types are provided, e.g. for stores augmented by plugins with
9
+ * members not returned by the setup function.
10
+ *
11
+ * The call signature exposes `TStore` (actions/getters) and `TState` (state)
12
+ * with precise typings so IDEs list store members and display action
13
+ * prototypes. It extends pinia's `StoreDefinition` to stay assignable
14
+ * wherever a standard store definition is expected.
15
+ */
16
+ export interface DefineAStoreDefinition<TStore, TState, Id extends string = string> extends StoreDefinition<Id, StateTree & TState> {
17
+ /**
18
+ * Returns a store, creates it if necessary.
19
+ *
20
+ * @param pinia - Pinia instance to retrieve the store
21
+ * @param hot - dev only hot module replacement
22
+ */
23
+ (pinia?: Pinia | null, hot?: StoreGeneric): Store<Id, StateTree & TState> & TStore;
24
+ }
5
25
  export type EmptyExtensions = Record<never, never>;
6
26
  export interface DefineAStoreSetupExtensions<TEnhancedStore> {
7
27
  /**
@@ -20,8 +40,29 @@ export type OptionBaseProperty = string | number | boolean | null | undefined |
20
40
  export interface PluginStoreOptions {
21
41
  storeOptions: StoreOptions;
22
42
  }
43
+ export interface RollbackActionParams {
44
+ action: string;
45
+ stateKeys?: CreateStateSnapshotKeys;
46
+ }
47
+ export type RollbackAfterFailureParams = {
48
+ [key: string]: CreateStateSnapshotKeys;
49
+ };
23
50
  export type StatePropertyValue = StdStatePropertyValue | Ref<StdStatePropertyValue> | StdStatePropertyValue[] | Ref<StdStatePropertyValue[]> | Ref<StdStatePropertyValue>[];
24
51
  type StdStatePropertyValue = AnyObject | boolean | null | number | string | undefined;
25
- export type StoreOptions = Record<string, StoreOptionsPropertyValue>;
52
+ /**
53
+ * Centralized extension point for per-store plugin options.
54
+ *
55
+ * Subscriber plugins MUST NOT redeclare pinia's `DefineStoreOptionsBase`:
56
+ * merging a `storeOptions` property with a different (even compatible) type
57
+ * raises TS2717 in consumer code. Instead, they augment this interface via
58
+ * `declare module 'pinia-plugin-subscription/types'`, which merges safely as
59
+ * long as each plugin declares its own optional keys.
60
+ */
61
+ export interface StoreOptionsExtensions {
62
+ }
63
+ export interface StoreOptions extends StoreOptionsExtensions {
64
+ [key: string]: StoreOptionsPropertyValue;
65
+ rollbackAfterFailure?: RollbackAfterFailureParams;
66
+ }
26
67
  export type StoreOptionsPropertyValue = OptionBaseProperty | OptionBaseProperty[] | ObjectBaseProperty | ObjectBaseProperty[];
27
68
  export {};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Deeply clones the provided value, handling objects, arrays, maps, and sets. Uses `structuredClone` if available, otherwise falls back to a manual deep clone.
3
+ * @template T The type of the value to deep clone.
4
+ * @param value The value to deep clone.
5
+ * @returns A deep clone of the provided value.
6
+ */
7
+ export declare function deepClone<T>(value: T): T;
@@ -1,25 +1,94 @@
1
- import type { DefineStoreOptions, StateTree, StoreDefinition } from "pinia";
1
+ import type { DefineStoreOptions, SetupStoreDefinition, StateTree, Store, StoreDefinition, _GettersTree } from "pinia";
2
2
  import type { AnyObject } from "../types";
3
- import type { DefineAStoreSetupContext, EmptyExtensions, PluginStoreOptions, StoreOptions } from "../types/store";
3
+ import type { DefineAStoreDefinition, DefineAStoreSetupContext, EmptyExtensions, PluginStoreOptions, StoreOptions } from "../types/store";
4
4
  export declare const itemState: {
5
5
  '@id': undefined;
6
6
  id: undefined;
7
7
  };
8
- type DefineAStoreSetup<TEnhancedStore, TExtraExtensions extends Record<string, unknown> = EmptyExtensions> = (ctx: DefineAStoreSetupContext<TEnhancedStore, TExtraExtensions>) => AnyObject;
9
- export declare function defineAStore<Sto, Sta>(id: string, storeDefinition: Omit<DefineStoreOptions<string, StateTree & Sta, AnyObject, Partial<Sto>>, 'id'> | ((ctx?: DefineAStoreSetupContext<AnyObject>) => AnyObject), options?: StoreOptions): StoreDefinition & Sta & Sto;
10
- export declare function defineAStoreCtx<Sto, Sta, TExtraExtensions extends Record<string, unknown> = EmptyExtensions>(id: string, storeDefinition: DefineAStoreSetup<Sto & Sta, TExtraExtensions>, options?: StoreOptions): StoreDefinition & Sta & Sto;
11
- export declare function defineAStoreSetup(id: string, storeDefinition: DefineAStoreSetup<AnyObject>, options: PluginStoreOptions): StoreDefinition<string, Pick<AnyObject, keyof AnyObject>, Pick<AnyObject, keyof AnyObject>, Pick<AnyObject, keyof AnyObject>>;
12
- export declare function defineAStoreOptionApi(id: string, storeDefinition: AnyObject, options?: PluginStoreOptions): StoreDefinition<string, {}, {}, {}>;
8
+ type DefineAStoreSetup<SS, TExtraExtensions extends Record<string, unknown> = EmptyExtensions> = (ctx: DefineAStoreSetupContext<SS, TExtraExtensions>) => SS;
9
+ /**
10
+ * Define a store with the setup API. State, getters and actions are inferred
11
+ * from the setup function return, exactly like pinia's `defineStore`, so
12
+ * store members are listed by IDEs and action prototypes are preserved.
13
+ * @template Id The type of the store identifier.
14
+ * @template SS The type of the setup function return.
15
+ * @param id The unique identifier for the store.
16
+ * @param storeDefinition The setup function defining the store.
17
+ * @param options Optional store options.
18
+ * @returns The defined store.
19
+ */
20
+ export declare function defineAStore<Id extends string, SS>(id: Id, storeDefinition: (ctx?: DefineAStoreSetupContext<AnyObject>) => SS, options?: StoreOptions): SetupStoreDefinition<Id, SS>;
21
+ /**
22
+ * Define a store with the options API, mirroring pinia's `defineStore` inference.
23
+ * @template Id The type of the store identifier.
24
+ * @template S The type of the store's state.
25
+ * @template G The type of the store's getters.
26
+ * @template A The type of the store's actions.
27
+ * @param id The unique identifier for the store.
28
+ * @param storeDefinition The store options definition.
29
+ * @param options Optional store options.
30
+ * @returns The defined store.
31
+ */
32
+ export declare function defineAStore<Id extends string, S extends StateTree = {}, G extends _GettersTree<S> = {}, A = {}>(id: Id, storeDefinition: Omit<DefineStoreOptions<Id, S, G, A>, 'id'>, options?: StoreOptions): StoreDefinition<Id, S, G, A>;
33
+ /**
34
+ * Define a store with explicit store/state types, e.g. when plugins augment
35
+ * the store with members not returned by the setup function.
36
+ * @template Sto The type of the store.
37
+ * @template Sta The type of the store's state.
38
+ * @param id The unique identifier for the store.
39
+ * @param storeDefinition The store definition, either as an options object or a setup function.
40
+ * @param options Optional store options.
41
+ * @returns The defined store.
42
+ */
43
+ export declare function defineAStore<Sto, Sta>(id: string, storeDefinition: Omit<DefineStoreOptions<string, StateTree & Sta, AnyObject, Partial<Sto>>, 'id'> | ((ctx?: DefineAStoreSetupContext<Sto & Sta>) => AnyObject), options?: StoreOptions): DefineAStoreDefinition<Sto, Sta>;
44
+ /**
45
+ * Define a store with a required, fully typed setup context. State, getters
46
+ * and actions are inferred from the setup function return.
47
+ * @template Id The type of the store identifier.
48
+ * @template SS The type of the setup function return.
49
+ * @template TExtraExtensions The type of the store's extra extensions.
50
+ * @param id The unique identifier for the store.
51
+ * @param storeDefinition The setup function defining the store.
52
+ * @param options Optional store options.
53
+ * @returns The defined store with setup context.
54
+ */
55
+ export declare function defineAStoreCtx<Id extends string, SS, TExtraExtensions extends Record<string, unknown> = EmptyExtensions>(id: Id, storeDefinition: (ctx: DefineAStoreSetupContext<AnyObject, TExtraExtensions>) => SS, options?: StoreOptions): SetupStoreDefinition<Id, SS>;
56
+ /**
57
+ * Define a store with a setup context and explicit store/state types, e.g.
58
+ * when plugins augment the store with members not returned by the setup function.
59
+ * @template Sto The type of the store.
60
+ * @template Sta The type of the store's state.
61
+ * @template TExtraExtensions The type of the store's extra extensions.
62
+ * @param id The unique identifier for the store.
63
+ * @param storeDefinition The setup function defining the store.
64
+ * @param options Optional store options.
65
+ * @returns The defined store with setup context.
66
+ */
67
+ export declare function defineAStoreCtx<Sto, Sta, TExtraExtensions extends Record<string, unknown> = EmptyExtensions>(id: string, storeDefinition: (ctx: DefineAStoreSetupContext<Sto & Sta, TExtraExtensions>) => AnyObject, options?: StoreOptions): DefineAStoreDefinition<Sto, Sta>;
68
+ export declare function defineAStoreSetup<Id extends string, SS>(id: Id, storeDefinition: DefineAStoreSetup<SS>, options: PluginStoreOptions): SetupStoreDefinition<Id, SS>;
69
+ export declare function defineAStoreOptionApi<Id extends string, S extends StateTree = {}, G extends _GettersTree<S> = {}, A = {}>(id: Id, storeDefinition: Omit<DefineStoreOptions<Id, S, G, A>, 'id'>, options?: PluginStoreOptions): StoreDefinition<Id, S, G, A>;
70
+ /**
71
+ * Check if a property has a denied first character : ['_', '$'].
72
+ * @param property The property name to check.
73
+ * @returns True if the property has a denied first character, false otherwise.
74
+ */
13
75
  export declare function hasDeniedFirstChar(property: string): boolean;
14
- export declare function getDefineAStoreSetupContext(store: AnyObject): DefineAStoreSetupContext<AnyObject> | undefined;
76
+ /**
77
+ * Get the setup context associated with a store instance (or pending store id).
78
+ * @param store The store instance, or an object exposing the store `$id`.
79
+ * @returns The setup context when the store was defined with `enhancedStore` enabled, undefined otherwise.
80
+ */
81
+ export declare function getDefineAStoreSetupContext(store: object): DefineAStoreSetupContext<AnyObject> | undefined;
15
82
  /**
16
83
  * Get the enhanced store from the context.
84
+ * @template TEnhancedStore The type of the enhanced store.
17
85
  * @param ctx The context containing the extensions.
18
86
  * @returns The enhanced store casted to the specified types.
19
87
  */
20
88
  export declare function getEnhancedStore<TEnhancedStore>(ctx: DefineAStoreSetupContext<TEnhancedStore>): TEnhancedStore;
21
89
  /**
22
90
  * Set the enhanced store in context with deprecated alias support.
91
+ * @template TEnhancedStore The type of the enhanced store.
23
92
  * @param ctx The context containing the extensions.
24
93
  * @param store The store to expose as enhancement.
25
94
  */
@@ -28,4 +97,11 @@ export declare function setEnhancedStore<TEnhancedStore>(ctx: DefineAStoreSetupC
28
97
  * @deprecated Use getEnhancedStore instead.
29
98
  */
30
99
  export declare function getExtendingStore<TEnhancedStore>(ctx: DefineAStoreSetupContext<TEnhancedStore>): TEnhancedStore;
100
+ /**
101
+ * Get the storage key for a given action and store combination.
102
+ * @param actionName The name of the action.
103
+ * @param store The Pinia store instance.
104
+ * @returns The storage key for the action and store combination.
105
+ */
106
+ export declare function getActionStoreKey(actionName: string, store: Store): string;
31
107
  export {};