pinia-plugin-subscription 0.1.5 → 0.1.6-beta.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.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.1.6]
9
+
10
+ ### Added
11
+ - Added `execution` and `hydrationScheduler` support on `PluginSubscriber` / `PluginSubscriberInterface`.
12
+ - Added `createHydrationPlugin()` as the dedicated Nuxt / SSR hydration helper.
13
+ - Added `PluginSubscriptionOptions` for hydration-specific runtime overrides without changing the default `createPlugin()` API.
14
+
15
+ ### Changed
16
+ - The execution policy now defaults to the subscriber itself, with framework-specific overrides available only through the hydration helper.
17
+ - `PluginSubscription` resolves hydration timing from the subscriber before falling back to the global runtime scheduler.
18
+
19
+ ### Fixed
20
+ - Avoided SSR hydration crashes by allowing client-only Pinia plugins to be skipped on the server or deferred on the client.
21
+
22
+ ## [0.1.5]
23
+
24
+ Minor change
25
+
26
+
8
27
  ## [0.1.4]
9
28
 
10
29
  ### Added
@@ -15,9 +34,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
15
34
  ### Changed
16
35
  - `getDefineAStoreSetupContext()` now falls back to store ID lookup during plugin execution timing.
17
36
  - `defineAStoreSetup()` now stores setup contexts only for stores with `storeOptions.enhancedStore = true`.
37
+ - `defineAStoreSetup()` now removes ID-indexed setup contexts after weak-map registration and on store disposal.
38
+ - `defineAStoreSetup()` now logs setup-context map size transitions when `storeOptions.debug = true`.
18
39
  - Public exports now include `defineAStoreCtx`, `getEnhancedStore`, and `setEnhancedStore`.
19
40
  - GitHub Actions now publishes GitHub pre-releases to npm with the `beta` dist-tag.
20
41
 
42
+ ### Added
43
+ - Added a Vitest performance-oriented test for setup-context tracking behavior with and without `enhancedStore`.
44
+
21
45
  ### Deprecated
22
46
  - `ctx.extensions.extending` is deprecated. Use `ctx.extensions.enhancedStore`.
23
47
  - `getExtendingStore()` is deprecated. Use `getEnhancedStore()`.
package/README.md CHANGED
@@ -83,13 +83,58 @@ export const myStoreSubscriber: PluginSubscriberInterface = {
83
83
 
84
84
  - **Debug mode:** Specifies the name of the plugin(s) to debug as the second argument to `createPlugin` to enable detailed logging.
85
85
  - **Reset callbacks:** Define `resetStoreCallback` to run custom logic when a store is reset.
86
+ - **SSR and hydration control:** Configure whether each subscribed plugin runs on the server, the client, or only after client hydration.
86
87
 
87
88
  ## API Reference
88
89
 
89
- ### `createPlugin(subscribers: PluginSubscriber[], debug?: boolean): PiniaPlugin`
90
+ ### `createPlugin(subscribers: PluginSubscriber[], debug?: string[]): PiniaPlugin`
90
91
 
91
92
  Creates and returns a Pinia plugin from the provided `subscribers`. Each subscriber is invoked when a store is registered.
92
93
 
94
+ ### `createHydrationPlugin(subscribers: PluginSubscriber[], options?: PluginSubscriptionOptions): PiniaPlugin`
95
+
96
+ Creates a Pinia plugin dedicated to SSR / Nuxt hydration orchestration. This helper is useful when a store plugin needs a runtime-specific scheduler or environment override without forcing every app to re-declare the plugin’s execution policy.
97
+
98
+ ```typescript
99
+ import { createHydrationPlugin, PLUGIN_NAME as PPS } from 'pinia-plugin-subscription'
100
+
101
+ pinia.use(createHydrationPlugin([
102
+ persistedStateSubscriber
103
+ ], {
104
+ debug: [PPS],
105
+ hydrationScheduler: (run) => {
106
+ nextTick(() => run())
107
+ }
108
+ }))
109
+ ```
110
+
111
+ ### SSR / Nuxt hydration control
112
+
113
+ The source of truth for hydration policy stays on the subscriber itself. For example, a client-only plugin should declare its execution directly:
114
+
115
+ ```typescript
116
+ export const persistedStateSubscriber: PluginSubscriberInterface = {
117
+ name: 'persisted-state',
118
+ execution: {
119
+ environment: 'client',
120
+ hydration: 'defer',
121
+ },
122
+ hydrationScheduler: (run) => {
123
+ nextTick(() => run())
124
+ },
125
+ invoke: (context, debug) => {
126
+ // ...
127
+ return true
128
+ }
129
+ }
130
+ ```
131
+
132
+ Available execution options:
133
+
134
+ - `environment: 'both' | 'client' | 'server'` — controls where the subscriber is allowed to run.
135
+ - `hydration: 'immediate' | 'defer'` — on the client, `defer` schedules execution after hydration.
136
+ - `hydrationScheduler` can be provided either on a subscriber or via `createHydrationPlugin()` to override the execution timing when needed.
137
+
93
138
  ### `defineAStoreCtx(id, setup, options?)`
94
139
 
95
140
  Use actions or access the state, added by one or more plugins, when defining the store.
@@ -112,11 +157,14 @@ export const useMyStore = defineAStoreCtx('myStore', (ctx) => {
112
157
  - `enhancedStore`
113
158
 
114
159
  The setup context is indexed internally only when `storeOptions.enhancedStore` is set to `true` (this is enabled automatically by `defineAStoreCtx`).
160
+ The temporary lookup by store id is now cleaned as soon as the weak-map association is established (and on store dispose), which limits map growth over time.
161
+ When `storeOptions.debug` is `true`, setup-context map size transitions are logged for observability.
115
162
 
116
163
  ### `PluginSubscriberInterface`
117
164
 
118
165
  An object with at least an `invoke(context: PiniaPluginContext, debug?: boolean)` method, plus optional properties:
119
166
 
167
+ - `execution?: { environment?: 'both' | 'client' | 'server'; hydration?: 'immediate' | 'defer' }`
120
168
  - `resetStoreCallback?: (store?: any) => void`
121
169
  - `storeOnActionSubscription?: { store, callback }` (getter)
122
170
  - `storeMutationSubscription?: { store, callback }` (getter)
@@ -145,6 +193,18 @@ import { addStore } from './src/extending-pinia-store/plugins/stores'
145
193
  class ExtendingStoreSubscriber extends PluginSubscriber<StoreExtension> {
146
194
  constructor() {
147
195
  super('extendsPiniaStore', StoreExtension.customizeStore.bind(StoreExtension))
196
+
197
+ // Controls when this subscriber may run and whether it should wait for hydration on the client.
198
+ this.execution = {
199
+ environment: 'client',
200
+ hydration: 'defer',
201
+ }
202
+
203
+ // Optional framework-specific scheduler for deferred execution.
204
+ this.hydrationScheduler = (run) => {
205
+ nextTick(() => run())
206
+ }
207
+
148
208
  this.pluginCreated = addStore
149
209
  }
150
210
  }
@@ -152,6 +212,12 @@ class ExtendingStoreSubscriber extends PluginSubscriber<StoreExtension> {
152
212
  export const extendingStoreSubscriber = new ExtendingStoreSubscriber()
153
213
  ```
154
214
 
215
+ This example shows the recommended pattern for SSR / Nuxt-safe plugins:
216
+
217
+ - `execution.environment` restricts the subscriber to `'both'`, `'client'`, or `'server'`
218
+ - `execution.hydration` is `'immediate'` by default and can be set to `'defer'` when the plugin must wait for client hydration
219
+ - `hydrationScheduler` lets you override the runtime scheduling behavior, for example with Nuxt/Vue `nextTick()`
220
+
155
221
  ## The `Store` Class — Summary
156
222
 
157
223
  The `Store` class (see [src/core/Store.ts](src/core/Store.ts)) is a wrapper around a `PiniaStore` providing: