pinia-plugin-subscription 0.0.0-beta.2 → 0.0.0-beta.20
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 +78 -100
- package/dist/pinia-plugin-subscription.js +618 -515
- package/dist/pinia-plugin-subscription.umd.cjs +5 -5
- package/dist/types/index.d.ts +78 -17
- package/dist/types/log.d.ts +8 -0
- package/dist/types/plugin.d.ts +12 -5
- package/dist/types/store.d.ts +1 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,140 +1,118 @@
|
|
|
1
1
|
# pinia-plugin-subscription
|
|
2
2
|
|
|
3
|
-
   
|
|
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
|
-
|
|
13
|
+
## Installation
|
|
15
14
|
|
|
16
|
-
|
|
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
|
|
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
|
-
|
|
34
|
+
## Usage — Examples
|
|
35
|
+
|
|
36
|
+
**1) Subscriber using a `Store` subclass:**
|
|
37
37
|
|
|
38
38
|
```typescript
|
|
39
|
-
|
|
39
|
+
import PluginSubscriber from 'pinia-plugin-subscription'
|
|
40
40
|
import { Store } from 'pinia-plugin-subscription'
|
|
41
41
|
|
|
42
|
-
class
|
|
42
|
+
class MyPlugin extends Store {
|
|
43
43
|
constructor(store, options, debug = false) {
|
|
44
44
|
super(store, options, debug)
|
|
45
45
|
this.doSomething()
|
|
46
46
|
}
|
|
47
|
+
}
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
}
|
|
49
|
+
class MyPluginSubscriber extends PluginSubscriber<MyPlugin> {
|
|
50
|
+
constructor() {
|
|
51
|
+
super('my-plugin', MyPlugin.customizeStore.bind(MyPlugin))
|
|
64
52
|
}
|
|
65
53
|
}
|
|
66
54
|
|
|
67
|
-
export const myStoreSubscriber =
|
|
55
|
+
export const myStoreSubscriber = new MyPluginSubscriber()
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**2) Simple subscriber implementing `PluginSubscriberInterface`:**
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import type { PluginSubscriberInterface } from 'pinia-plugin-subscription'
|
|
62
|
+
|
|
63
|
+
export const myStoreSubscriber: PluginSubscriberInterface = {
|
|
64
|
+
name: 'my-plugin',
|
|
65
|
+
|
|
68
66
|
invoke: (context, debug) => {
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
if (!myStore) return
|
|
67
|
+
// context contains `store`, `options`, `pinia`
|
|
68
|
+
console.log('store registered', context.store.$id)
|
|
72
69
|
|
|
73
|
-
|
|
74
|
-
doAnotherthing(myStore)
|
|
70
|
+
return true
|
|
75
71
|
},
|
|
72
|
+
|
|
76
73
|
resetStoreCallback: (store) => {
|
|
77
|
-
console.log('
|
|
74
|
+
console.log('store reset:', store.$id)
|
|
78
75
|
}
|
|
79
76
|
}
|
|
80
77
|
```
|
|
81
78
|
|
|
82
|
-
|
|
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
|
-
```
|
|
79
|
+
## Advanced Features
|
|
91
80
|
|
|
92
|
-
|
|
81
|
+
- **Debug mode:** Pass `true` as the second argument to `createPlugin` to enable detailed logging and plugin filtering.
|
|
82
|
+
- **Reset callbacks:** Define `resetStoreCallback` to run custom logic when a store is reset.
|
|
93
83
|
|
|
94
|
-
|
|
84
|
+
## API Reference
|
|
95
85
|
|
|
96
|
-
|
|
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
|
-
```
|
|
86
|
+
### `createPlugin(subscribers: PluginSubscriber[], debug?: boolean): PiniaPlugin`
|
|
106
87
|
|
|
107
|
-
|
|
88
|
+
Creates and returns a Pinia plugin from the provided `subscribers`. Each subscriber is invoked when a store is registered.
|
|
108
89
|
|
|
109
|
-
|
|
90
|
+
### `PluginSubscriberInterface`
|
|
110
91
|
|
|
111
|
-
|
|
92
|
+
An object with at least an `invoke(context: PiniaPluginContext, debug?: boolean)` method, plus optional properties:
|
|
112
93
|
|
|
113
|
-
|
|
94
|
+
- `resetStoreCallback?: (store?: any) => void`
|
|
95
|
+
- `storeOnActionSubscription?: { store, callback }` (getter)
|
|
96
|
+
- `storeMutationSubscription?: { store, callback }` (getter)
|
|
97
|
+
- `subscriptions?: Record<string, Function>` (plugin-specific subscription functions)
|
|
114
98
|
|
|
115
|
-
The `PluginSubscriber`
|
|
99
|
+
## The `PluginSubscriber` Abstract Class
|
|
116
100
|
|
|
117
|
-
|
|
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`).
|
|
101
|
+
The project provides an abstract `PluginSubscriber` implementation (see [src/plugins/pluginSubscriber.ts](src/plugins/pluginSubscriber.ts)) to simplify creating reusable subscribers.
|
|
121
102
|
|
|
122
|
-
|
|
103
|
+
**Typical usage:**
|
|
123
104
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
- `subscriptions` (from `store.getSubscriptions()`)
|
|
131
|
-
- `storeMutationSubscription` (from `store.storeSubscribe`)
|
|
132
|
-
- `storeOnActionSubscription` (from `store.onAction`)
|
|
133
|
-
- optionally a `pluginCreated(store)` hook called after initialization
|
|
105
|
+
- The subscriber instantiates a `Store` (or subclass) via a factory (`MyStore.customizeStore`).
|
|
106
|
+
- The instance exposes:
|
|
107
|
+
- `subscriptions` (from `getSubscriptions()`)
|
|
108
|
+
- `storeMutationSubscription` (from `storeSubscribe`)
|
|
109
|
+
- `storeOnActionSubscription` (from `onAction`)
|
|
110
|
+
- optional `pluginCreated(store)` hook called after initialization
|
|
134
111
|
|
|
112
|
+
**Example:**
|
|
135
113
|
|
|
136
114
|
```typescript
|
|
137
|
-
import PluginSubscriber from '
|
|
115
|
+
import PluginSubscriber from 'pinia-plugin-subscription'
|
|
138
116
|
import StoreExtension from './src/extending-pinia-store/core/StoreExtension'
|
|
139
117
|
import { addStore } from './src/extending-pinia-store/plugins/stores'
|
|
140
118
|
|
|
@@ -148,34 +126,34 @@ class ExtendingStoreSubscriber extends PluginSubscriber<StoreExtension> {
|
|
|
148
126
|
export const extendingStoreSubscriber = new ExtendingStoreSubscriber()
|
|
149
127
|
```
|
|
150
128
|
|
|
151
|
-
|
|
129
|
+
## The `Store` Class — Summary
|
|
152
130
|
|
|
153
|
-
|
|
131
|
+
The `Store` class (see [src/core/Store.ts](src/core/Store.ts)) is a wrapper around a `PiniaStore` providing:
|
|
154
132
|
|
|
155
|
-
|
|
133
|
+
- **Properties:** `debug`, `options`, `state`, `store`.
|
|
134
|
+
- **Useful methods:**
|
|
135
|
+
- `addToState(name, value?)` — adds a property to store state and exposes it as a `Ref` when appropriate.
|
|
136
|
+
- `addSubscription(pluginName, subscription)` — registers a plugin-specific subscription function.
|
|
137
|
+
- `getSubscriptions()` — returns registered subscriptions.
|
|
138
|
+
- `storeSubscribe` (getter/setter) — factory for `store.$subscribe` ({ store, callback }).
|
|
139
|
+
- `onAction` (getter/setter) — factory for `onAction` ({ store, callback }).
|
|
140
|
+
- `static customizeStore(store, options, debug?)` — recommended factory for class instantiation.
|
|
141
|
+
- `debugLog(message, args)` — conditional logging.
|
|
142
|
+
- Helpers: `stateHas()`, `storeHas()`, `getValue()`.
|
|
156
143
|
|
|
157
|
-
|
|
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.
|
|
144
|
+
## Testing
|
|
168
145
|
|
|
169
|
-
|
|
146
|
+
This plugin is tested with Vitest. Coverage reports are available in the `coverage/` directory:
|
|
170
147
|
|
|
171
|
-
|
|
148
|
+
- Statements: **97.64%** (83/85)
|
|
149
|
+
- Branches: **86.53%** (45/52)
|
|
150
|
+
- Functions: **100%** (38/38)
|
|
151
|
+
- Lines: **97.59%** (81/83)
|
|
172
152
|
|
|
173
|
-
|
|
174
|
-
|
|
153
|
+
## Contributing
|
|
154
|
+
|
|
155
|
+
Pull requests are welcome. Please respect the project's coding style and add tests for new features.
|
|
175
156
|
|
|
176
|
-
|
|
157
|
+
## License
|
|
177
158
|
|
|
178
|
-
|
|
179
|
-
- Branches: **86.53%** (45/52)
|
|
180
|
-
- Functions: **100%** (38/38)
|
|
181
|
-
- Lines: **97.59%** (81/83)
|
|
159
|
+
MIT
|