pinia-plugin-subscription 0.0.0-beta.9 → 0.0.1

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/README.md CHANGED
@@ -1,140 +1,120 @@
1
1
  # pinia-plugin-subscription
2
2
 
3
- ![Pinia](https://img.shields.io/badge/Pinia-2.x-blue?logo=pinia) ![Vue](https://img.shields.io/badge/Vue-3.x-brightgreen?logo=vue.js) ![Nuxt](https://img.shields.io/badge/Nuxt-3.x-00C58E?logo=nuxt.js) ![Vitest](https://img.shields.io/badge/Vitest-tested-brightgreen?logo=vitest)
4
-
5
3
  Pinia plugin for Vue.js that helps building Pinia plugins by centralizing subscriber registration and providing a `Store` base class for store helpers.
6
4
 
7
5
  This project provides:
8
6
  - a lightweight mechanism to declare "subscribers" that are invoked when stores are registered or updated by Pinia;
9
7
  - a `Store` base class (helper wrapper) to ease interacting with Pinia stores from subscribers or other plugin code;
10
- - an API to create a Pinia plugin from a list of subscribers.
8
+ - an API to create a Pinia plugin from a list of subscribers;
9
+ - the $reset method to all stores modified by the plugin.
11
10
 
12
11
  The main goal is to offer a clear API for writing reusable Pinia plugins and to make it easy to extend stores from plugin code.
13
12
 
14
- ### Basic usage
13
+ ## Installation
15
14
 
16
- 1. Import the plugin factory and register your subscribers with Pinia:
15
+ Ensure Pinia is installed, then register the plugin in your `main.ts`:
17
16
 
18
17
  ```typescript
19
- // main.ts
20
18
  import { createApp } from 'vue'
21
19
  import { createPinia } from 'pinia'
22
20
  import { createPlugin } from 'pinia-plugin-subscription'
23
- import myStoreSubscriber from './src/core/my-store'
21
+ import { myStoreSubscriber } from './src/core/my-store'
24
22
  import App from './App.vue'
25
23
 
26
24
  const app = createApp(App)
27
25
  const pinia = createPinia()
28
26
 
29
- // Register plugin (subscribers array, debug flag)
30
- pinia.use(createPlugin([myStoreSubscriber]))
27
+ // Register plugin (subscribers array, debug mode)
28
+ pinia.use(createPlugin([myStoreSubscriber], true))
31
29
 
32
30
  app.use(pinia)
33
31
  app.mount('#app')
34
32
  ```
35
33
 
36
- 2. A subscriber example using a `Store` subclass:
34
+ ## Usage — Examples
35
+
36
+ **1) Subscriber using a `Store` subclass:**
37
37
 
38
38
  ```typescript
39
- // src/core/my-store.ts
39
+ import PluginSubscriber from 'pinia-plugin-subscription'
40
40
  import { Store } from 'pinia-plugin-subscription'
41
41
 
42
- class MyStore extends Store {
42
+ class MyPlugin extends Store {
43
+ protected static override _requiredKeys?: string[] | undefined = ['my-plugin-option']
44
+
43
45
  constructor(store, options, debug = false) {
44
46
  super(store, options, debug)
45
47
  this.doSomething()
46
48
  }
49
+ }
47
50
 
48
- private doSomething() {
49
- try {
50
- console.log('store', this.store)
51
- console.log('state', this.state)
52
- console.log('store options', this.options)
53
-
54
- // conditionaly property added
55
- if(
56
- (!this.stateHas('myProperty') || this.getStatePropertyValue('myProperty') === 'old-value')
57
- && this.storeHas('myAction')
58
- ){
59
- this.addToState('myProperty', 'new-value')
60
- }
61
- } catch(e) {
62
- this.debugLog(e)
63
- }
51
+ class MyPluginSubscriber extends PluginSubscriber<MyPlugin> {
52
+ constructor() {
53
+ super('my-plugin', MyPlugin.customizeStore.bind(MyPlugin))
64
54
  }
65
55
  }
66
56
 
67
- export const myStoreSubscriber = {
57
+ export const myStoreSubscriber = new MyPluginSubscriber()
58
+ ```
59
+
60
+ **2) Simple subscriber implementing `PluginSubscriberInterface`:**
61
+
62
+ ```typescript
63
+ import type { PluginSubscriberInterface } from 'pinia-plugin-subscription'
64
+
65
+ export const myStoreSubscriber: PluginSubscriberInterface = {
66
+ name: 'my-plugin',
67
+
68
68
  invoke: (context, debug) => {
69
- // create an instance of the Store subclass when options.storeOptions is present
70
- const myStore = MyStore.customizeStore(context.store, context.options, debug)
71
- if (!myStore) return
69
+ // context contains `store`, `options`, `pinia`
70
+ console.log('store registered', context.store.$id)
72
71
 
73
- //Execute logic if store is augmented by plugin
74
- doAnotherthing(myStore)
72
+ return true
75
73
  },
74
+
76
75
  resetStoreCallback: (store) => {
77
- console.log('[subscriber] store reset:', store?.$id)
76
+ console.log('store reset:', store.$id)
78
77
  }
79
78
  }
80
79
  ```
81
80
 
82
- ### Advanced usage
83
-
84
- #### Debug mode
85
-
86
- Enable debug mode to log store changes and internal actions:
87
-
88
- ```typescript
89
- pinia.use(createPlugin([subscriber], true))
90
- ```
81
+ ## Advanced Features
91
82
 
92
- #### Reset store callbacks
83
+ - **Debug mode:** Pass `true` as the second argument to `createPlugin` to enable detailed logging and plugin filtering.
84
+ - **Reset callbacks:** Define `resetStoreCallback` to run custom logic when a store is reset.
93
85
 
94
- Subscribers may define `resetStoreCallback` to run custom logic when a store reset is handled by the plugin.
86
+ ## API Reference
95
87
 
96
- ```typescript
97
- const subscriber = {
98
- invoke: (context, debug) => {
99
- console.log('Store changed:', context.store.$state)
100
- },
101
- resetStoreCallback: (store) => {
102
- console.log('Store reset:', store.$id)
103
- }
104
- }
105
- ```
88
+ ### `createPlugin(subscribers: PluginSubscriber[], debug?: boolean): PiniaPlugin`
106
89
 
107
- ## API
90
+ Creates and returns a Pinia plugin from the provided `subscribers`. Each subscriber is invoked when a store is registered.
108
91
 
109
- ### `createPlugin(subscribers: PluginSubscriber[], debug?: boolean): PiniaPlugin`
92
+ ### `PluginSubscriberInterface`
110
93
 
111
- Creates a Pinia plugin from the provided `subscribers` and optional `debug` flag. Each subscriber will be invoked with the Pinia plugin context when a store is registered.
94
+ An object with at least an `invoke(context: PiniaPluginContext, debug?: boolean)` method, plus optional properties:
112
95
 
113
- ### `PluginSubscriber`
96
+ - `resetStoreCallback?: (store?: any) => void`
97
+ - `storeOnActionSubscription?: { store, callback }` (getter)
98
+ - `storeMutationSubscription?: { store, callback }` (getter)
99
+ - `subscriptions?: Record<string, Function>` (plugin-specific subscription functions)
114
100
 
115
- The `PluginSubscriber` interface has been extended: it's still an object with at least an `invoke(context: PiniaPluginContext, debug?: boolean)` method, but it can now expose several useful properties for plugins:
101
+ ## The `PluginSubscriber` Abstract Class
116
102
 
117
- - **`resetStoreCallback?: (store?: Store) => void`**: callback invoked when the store is reset.
118
- - **`storeOnActionSubscription?: StoreOnActionSubscription`**: provides a native Pinia `onAction` subscription via a getter returning `{ store, callback }`.
119
- - **`storeMutationSubscription?: StoreMutationSubscription`**: provides a native mutation subscription (`store.$subscribe`) via a getter returning `{ store, callback }`.
120
- - **`subscriptions: PluginSubscriptions | undefined`**: an object listing plugin-specific subscription functions (see `Store.addSubscription`).
103
+ The project provides an abstract `PluginSubscriber` implementation (see [src/plugins/pluginSubscriber.ts](src/plugins/pluginSubscriber.ts)) to simplify creating reusable subscribers.
121
104
 
122
- These additions make it easier for subscribers to integrate with Pinia's native event cycle and to expose reusable extension points.
105
+ **Typical usage:**
123
106
 
124
- ## The `PluginSubscriber` class (abstract)
125
-
126
- The project provides an abstract `PluginSubscriber` implementation ([src/plugins/pluginSubscriber.ts](src/plugins/pluginSubscriber.ts)) that makes it easy to create reusable subscribers:
127
-
128
- - Constructor: `new PluginSubscriber(pluginName: string, createInstanceFunction: CreateInstance)`
129
- - Main behavior: in `invoke(context, debug)` the class creates a helper instance (`Store` or subclass) via the `createInstanceFunction` (typically `MyStore.customizeStore`) and exposes on the instance:
130
- - `subscriptions` (from `store.getSubscriptions()`)
131
- - `storeMutationSubscription` (from `store.storeSubscribe`)
132
- - `storeOnActionSubscription` (from `store.onAction`)
133
- - optionally a `pluginCreated(store)` hook called after initialization
107
+ - The subscriber instantiates a `Store` (or subclass) via a factory (`MyStore.customizeStore`).
108
+ - The instance exposes:
109
+ - `subscriptions` (from `getSubscriptions()`)
110
+ - `storeMutationSubscription` (from `storeSubscribe`)
111
+ - `storeOnActionSubscription` (from `onAction`)
112
+ - optional `pluginCreated(store)` hook called after initialization
134
113
 
114
+ **Example:**
135
115
 
136
116
  ```typescript
137
- import PluginSubscriber from './src/plugins/pluginSubscriber'
117
+ import PluginSubscriber from 'pinia-plugin-subscription'
138
118
  import StoreExtension from './src/extending-pinia-store/core/StoreExtension'
139
119
  import { addStore } from './src/extending-pinia-store/plugins/stores'
140
120
 
@@ -148,34 +128,25 @@ class ExtendingStoreSubscriber extends PluginSubscriber<StoreExtension> {
148
128
  export const extendingStoreSubscriber = new ExtendingStoreSubscriber()
149
129
  ```
150
130
 
151
- Here `ExtendingStoreSubscriber` provides a `createInstanceFunction` that returns a `StoreExtension` instance if `options.storeOptions` is present, and sets a `pluginCreated` hook (here `addStore`) to run plugin-specific logic once the instance is ready.
152
-
153
- ## The `Store` class (summary)
131
+ ## The `Store` Class — Summary
154
132
 
155
- The `Store` class (in [src/core/Store.ts](src/core/Store.ts)) is a base wrapper around a `PiniaStore` exposing helpers:
133
+ The `Store` class (see [src/core/Store.ts](src/core/Store.ts)) is a wrapper around a `PiniaStore` providing:
156
134
 
157
- - Properties: `debug`, `options`, `state`, `store`.
158
- - Useful methods:
159
- - `addToState(name, value?)`: adds a property to the store state and exposes it as a `Ref` on the store when appropriate.
160
- - `addSubscription(pluginName, subscription)`: registers a plugin-specific subscription function (accessible via `getSubscriptions`).
161
- - `getSubscriptions()`: returns subscriptions registered with `addSubscription` (or `undefined`).
162
- - `storeSubscribe` (getter/setter): exposes a mutation subscription callback (`store.$subscribe`) as a factory returning `{ store, callback }`.
163
- - `onAction` (getter/setter): exposes a Pinia `onAction` callback in the same form.
164
- - `static customizeStore(store, options, debug?)`: instantiate the class (or subclass) when `options.storeOptions` is present.
165
- - `debugLog(message, args)`: conditional logging when `debug` is true.
166
- - `hasDeniedFirstChar(property)`, `getOption(...)`, `getValue(value)`, `getStatePropertyValue(...)`.
167
- - `isOptionApi()`: true when the store uses Pinia Options API.
135
+ - **Properties:** `debug`, `options`, `state`, `store`.
136
+ - **Useful methods:**
137
+ - `addToState(name, value?)` — adds a property to store state and exposes it as a `Ref` when appropriate.
138
+ - `addSubscription(pluginName, subscription)` — registers a plugin-specific subscription function.
139
+ - `getSubscriptions()` — returns registered subscriptions.
140
+ - `storeSubscribe` (getter/setter) — factory for `store.$subscribe` ({ store, callback }).
141
+ - `onAction` (getter/setter) — factory for `onAction` ({ store, callback }).
142
+ - `static customizeStore(store, options, debug?)` — recommended factory for class instantiation.
143
+ - `debugLog(message, args)` — conditional logging.
144
+ - Helpers: `stateHas()`, `storeHas()`, `getValue()`.
168
145
 
169
- Other small helpers exposed: `stateHas(property)`, `storeHas(property)` and `getValue` to retrieve the real value of a `Ref` or a raw value.
146
+ ## Testing
170
147
 
171
- `Store.customizeStore(...)` is the recommended entry point used by subscribers to create store helper instances.
172
-
173
-
174
- ## Testing
148
+ This plugin is tested with Vitest. Coverage reports are available in the `coverage/` directory.
175
149
 
176
- This plugin is tested with Vitest. Coverage (from the included coverage report at [coverage/index.html](coverage/index.html)):
150
+ ## License
177
151
 
178
- - Statements: **97.64%** (83/85)
179
- - Branches: **86.53%** (45/52)
180
- - Functions: **100%** (38/38)
181
- - Lines: **97.59%** (81/83)
152
+ MIT