valtio-define 1.1.4 → 1.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.
package/README.OLD.md ADDED
@@ -0,0 +1,391 @@
1
+ # valtio-define
2
+
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+ [![bundle][bundle-src]][bundle-href]
6
+ [![JSDocs][jsdocs-src]][jsdocs-href]
7
+ [![coverage][coverage-src]][coverage-href]
8
+ [![License][license-src]][license-href]
9
+
10
+ ⚡ Quickly create a fully functional and robust [Valtio](https://valtio.dev) factory
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ pnpm add valtio-define
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ### Basic Store
21
+
22
+ Create a reactive store with state and actions. The store provides a simple and intuitive API for managing state in React applications, built on top of Valtio.
23
+
24
+ ```tsx
25
+ import { defineStore, useStore } from 'valtio-define'
26
+
27
+ const store = defineStore({
28
+ state: () => ({ count: 0 }),
29
+ actions: {
30
+ increment() {
31
+ this.count++
32
+ },
33
+ },
34
+ })
35
+
36
+ function Counter() {
37
+ const { count } = useStore(store)
38
+ return (
39
+ <div>
40
+ <button onClick={store.increment}>Increment</button>
41
+ <div>{count}</div>
42
+ </div>
43
+ )
44
+ }
45
+ ```
46
+
47
+ ### With Getters
48
+
49
+ Getters are computed properties that automatically update when their dependencies change. They provide a clean way to derive state without manually tracking dependencies.
50
+
51
+ ```tsx
52
+ const store = defineStore({
53
+ state: () => ({ count: 0 }),
54
+ getters: {
55
+ doubled() {
56
+ return this.count * 2
57
+ },
58
+ },
59
+ actions: {
60
+ increment() {
61
+ this.count++
62
+ },
63
+ },
64
+ })
65
+
66
+ function Counter() {
67
+ const state = useStore(store)
68
+ return (
69
+ <div>
70
+ <div>
71
+ Count:
72
+ {state.count}
73
+ </div>
74
+ <div>
75
+ Doubled:
76
+ {state.doubled}
77
+ </div>
78
+ <button onClick={store.increment}>Increment</button>
79
+ </div>
80
+ )
81
+ }
82
+ ```
83
+
84
+ ### Persistence
85
+
86
+ The persistence plugin allows you to persist store state to storage (e.g., localStorage).
87
+
88
+ First, register the persist plugin:
89
+
90
+ ```tsx
91
+ import valtio from 'valtio-define'
92
+ import { persist } from 'valtio-define/plugins'
93
+
94
+ // Register the persist plugin globally
95
+ valtio.use(persist())
96
+ ```
97
+
98
+ Then use it in your store:
99
+
100
+ ```tsx
101
+ import { defineStore } from 'valtio-define'
102
+
103
+ const store = defineStore({
104
+ state: () => ({ count: 0 }),
105
+ actions: {
106
+ increment() {
107
+ this.count++
108
+ },
109
+ },
110
+ persist: {
111
+ key: 'my-store',
112
+ storage: localStorage,
113
+ paths: ['count'], // Only persist 'count', or omit to persist all state
114
+ },
115
+ })
116
+ ```
117
+
118
+ If `persist` is `true`, it will use `structure-id` to generate a unique key for the store automatically.
119
+
120
+ ```tsx
121
+ const store = defineStore({
122
+ state: () => ({ count: 0 }),
123
+ persist: true, // Auto-generates key using structure-id
124
+ })
125
+ ```
126
+
127
+ You can pass `hydrate` when registering the plugin (default `true`). When `true`, state is hydrated from storage as soon as the store is created. Set `hydrate: false` when you need to avoid running persistence during server-side rendering, and manually mount persist in your App entry instead:
128
+
129
+ ```tsx
130
+ // Register with hydrate: false
131
+ store.use(persist({ hydrate: false }))
132
+
133
+ // In your App (client entry), after store is used:
134
+ useEffect(() => store.$persist.mount(), [])
135
+ ```
136
+
137
+ ### Subscribe to Changes
138
+
139
+ ```tsx
140
+ const store = defineStore({
141
+ state: () => ({ count: 0 }),
142
+ actions: {
143
+ increment() {
144
+ this.count++
145
+ },
146
+ },
147
+ })
148
+
149
+ // Subscribe to state changes
150
+ const unsubscribe = store.$subscribe((state) => {
151
+ console.log('State changed:', state)
152
+ })
153
+
154
+ // Subscribe to specific key changes
155
+ const unsubscribeKey = store.$subscribeKey('count', (value) => {
156
+ console.log('Count changed:', value)
157
+ })
158
+ ```
159
+
160
+ ### Patch State
161
+
162
+ ```tsx
163
+ // Patch with object
164
+ store.$patch({ count: 10 })
165
+
166
+ // Patch with function
167
+ store.$patch((state) => {
168
+ state.count += 5
169
+ })
170
+ ```
171
+
172
+ ### Signal (JSX Component)
173
+
174
+ ```tsx
175
+ function App() {
176
+ return (
177
+ <div>
178
+ Count:
179
+ {' '}
180
+ {store.$signal(state => state.count)}
181
+ </div>
182
+ )
183
+ }
184
+ ```
185
+
186
+ ### Store to State Hooks
187
+
188
+ Convert store state to React hooks similar to `useState`. This provides a more React-idiomatic way to access and update store state.
189
+
190
+ #### `storeToState(store, key)`
191
+
192
+ Returns a tuple `[state, setter]` for a single store key, similar to React's `useState`.
193
+
194
+ ```tsx
195
+ import { defineStore, storeToState } from 'valtio-define'
196
+
197
+ const store = defineStore({
198
+ state: { count: 0, name: 'test' },
199
+ })
200
+
201
+ function Counter() {
202
+ const [count, setCount] = storeToState(store, 'count')
203
+ const [name, setName] = storeToState(store, 'name')
204
+
205
+ return (
206
+ <div>
207
+ <button onClick={() => setCount(count + 1)}>Increment</button>
208
+ <button onClick={() => setCount(prev => prev + 1)}>Increment (functional)</button>
209
+ <div>
210
+ Count:
211
+ {count}
212
+ </div>
213
+ <div>
214
+ Name:
215
+ {name}
216
+ </div>
217
+ </div>
218
+ )
219
+ }
220
+ ```
221
+
222
+ **Parameters:**
223
+ - `store`: Store instance created by `defineStore`
224
+ - `key`: Key of the state property to access
225
+
226
+ **Returns:** `[state, setter]` tuple where:
227
+ - `state`: Current value of the state property
228
+ - `setter`: Function to update the state (accepts value or updater function)
229
+
230
+ #### `storeToStates(store)`
231
+
232
+ Returns an object with all store keys mapped to `[state, setter]` tuples.
233
+
234
+ ```tsx
235
+ function Component() {
236
+ const {
237
+ count: [count, setCount],
238
+ name: [name, setName],
239
+ user: [user, setUser],
240
+ } = storeToStates(store)
241
+
242
+ return (
243
+ <div>
244
+ <button onClick={() => setCount(count + 1)}>Increment</button>
245
+ <div>
246
+ Count:
247
+ {count}
248
+ </div>
249
+ <div>
250
+ Name:
251
+ {name}
252
+ </div>
253
+ <div>
254
+ User:
255
+ {user.name}
256
+ </div>
257
+ </div>
258
+ )
259
+ }
260
+ ```
261
+
262
+ **Parameters:**
263
+ - `store`: Store instance created by `defineStore`
264
+
265
+ **Returns:** Object where each key maps to a `[state, setter]` tuple
266
+
267
+ ## API
268
+
269
+ ### `defineStore(store)`
270
+
271
+ Creates a store with state, actions, and getters.
272
+
273
+ **Parameters:**
274
+ - `store.state`: Initial state object or factory function
275
+ - `store.actions`: Object containing action methods
276
+ - `store.getters`: Object containing getter methods
277
+ - `store.persist`: Persistence plugin configuration (boolean or object) - see [Persistence Plugin](#persistence)
278
+
279
+ **Returns:** Store instance with reactive state and actions
280
+
281
+ ### `useStore(store)`
282
+
283
+ React hook that returns a snapshot of the store state.
284
+
285
+ **Parameters:**
286
+ - `store`: Store instance created by `defineStore`
287
+
288
+ **Returns:** Snapshot of the store state
289
+
290
+ ### `storeToState(store, key)`
291
+
292
+ React hook that returns a `[state, setter]` tuple for a single store key, similar to React's `useState`.
293
+
294
+ **Parameters:**
295
+ - `store`: Store instance created by `defineStore`
296
+ - `key`: Key of the state property to access
297
+
298
+ **Returns:** `[state, setter]` tuple where:
299
+ - `state`: Current value of the state property
300
+ - `setter`: Function to update the state (accepts value or updater function like `setState(value)` or `setState(prev => newValue)`)
301
+
302
+ ### `storeToStates(store)`
303
+
304
+ React hook that returns an object with all store keys mapped to `[state, setter]` tuples.
305
+
306
+ **Parameters:**
307
+ - `store`: Store instance created by `defineStore`
308
+
309
+ **Returns:** Object where each key maps to a `[state, setter]` tuple, preserving the correct type for each property
310
+
311
+ ### Plugins
312
+
313
+ Plugins allow you to extend store functionality. You can use plugins globally or per-store.
314
+
315
+ #### Global Plugin Registration
316
+
317
+ ```tsx
318
+ import valtio from 'valtio-define'
319
+ import { persist } from 'valtio-define/plugins'
320
+
321
+ // Register plugin globally - applies to all stores
322
+ valtio.use(persist())
323
+ ```
324
+
325
+ #### Per-Store Plugin Registration
326
+
327
+ ```tsx
328
+ import { defineStore } from 'valtio-define'
329
+ import { persist } from 'valtio-define/plugins'
330
+
331
+ const store = defineStore({
332
+ state: () => ({ count: 0 }),
333
+ })
334
+
335
+ // Register plugin for this specific store
336
+ store.use(persist())
337
+ ```
338
+
339
+ #### Creating Custom Plugins
340
+
341
+ ```tsx
342
+ import type { Plugin } from 'valtio-define'
343
+
344
+ function myPlugin() {
345
+ ({ store, options }: PluginContext) => {
346
+ // Access store methods
347
+ store.$subscribe((state) => {
348
+ console.log('State changed:', state)
349
+ })
350
+
351
+ // Access store options
352
+ if (options.someOption) {
353
+ // Do something
354
+ }
355
+ }
356
+ }
357
+
358
+ declare module 'valtio-define' {
359
+ export interface StoreDefine<S extends object, A extends ActionsTree, G extends Getters<any>> {
360
+ myPlugin?: {
361
+ someOption?: boolean
362
+ }
363
+ }
364
+ }
365
+
366
+ // Use the plugin
367
+ use(myPlugin())
368
+ ```
369
+
370
+ **Plugin Context:**
371
+ - `context.store`: The store instance with all methods (`$state`, `$patch`, `$subscribe`, etc.)
372
+ - `context.options`: The original store definition options
373
+
374
+ ## License
375
+
376
+ [MIT](./LICENSE) License © [Hairyf](https://github.com/hairyf)
377
+
378
+ <!-- Badges -->
379
+
380
+ [npm-version-src]: https://img.shields.io/npm/v/valtio-define?style=flat&colorA=080f12&colorB=1fa669
381
+ [npm-version-href]: https://npmjs.com/package/valtio-define
382
+ [npm-downloads-src]: https://img.shields.io/npm/dm/valtio-define?style=flat&colorA=080f12&colorB=1fa669
383
+ [npm-downloads-href]: https://npmjs.com/package/valtio-define
384
+ [bundle-src]: https://img.shields.io/bundlephobia/minzip/valtio-define?style=flat&colorA=080f12&colorB=1fa669&label=minzip
385
+ [bundle-href]: https://bundlephobia.com/result?p=valtio-define
386
+ [license-src]: https://img.shields.io/github/license/hairyf/valtio-define.svg?style=flat&colorA=080f12&colorB=1fa669
387
+ [license-href]: https://github.com/hairyf/valtio-define/blob/main/LICENSE
388
+ [jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
389
+ [jsdocs-href]: https://www.jsdocs.io/package/valtio-define
390
+ [coverage-src]: https://codecov.io/gh/hairyf/valtio-define/graph/badge.svg?token=PG5YIEEEHJ
391
+ [coverage-href]: https://codecov.io/gh/hairyf/valtio-define
package/README.md CHANGED
@@ -1,25 +1,25 @@
1
- # valtio-define
1
+ ![image](./logo.svg)
2
2
 
3
3
  [![npm version][npm-version-src]][npm-version-href]
4
4
  [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
5
  [![bundle][bundle-src]][bundle-href]
6
6
  [![JSDocs][jsdocs-src]][jsdocs-href]
7
7
  [![coverage][coverage-src]][coverage-href]
8
- [![License][license-src]][license-href]
8
+ [![License][license-src]][license-href].
9
9
 
10
- Quickly create a fully functional and robust [Valtio](https://valtio.dev) factory
10
+ ⚡️ **valtio-define** is a lightweight factory for creating fully functional, robust [Valtio](https://valtio.dev) stores. It simplifies state management in React by providing a structured API for state, actions, and computed getters.
11
11
 
12
- ## Installation
12
+ ## 📦 Installation
13
13
 
14
14
  ```bash
15
15
  pnpm add valtio-define
16
16
  ```
17
17
 
18
- ## Usage
18
+ ## 🚀 Quick Start
19
19
 
20
20
  ### Basic Store
21
21
 
22
- Create a reactive store with state and actions. The store provides a simple and intuitive API for managing state in React applications, built on top of Valtio.
22
+ `defineStore` allows you to encapsulate state and logic in one place. Use `useStore` to consume the reactive state in your components.
23
23
 
24
24
  ```tsx
25
25
  import { defineStore, useStore } from 'valtio-define'
@@ -28,6 +28,7 @@ const store = defineStore({
28
28
  state: () => ({ count: 0 }),
29
29
  actions: {
30
30
  increment() {
31
+ // 'this' refers to the reactive state
31
32
  this.count++
32
33
  },
33
34
  },
@@ -35,18 +36,22 @@ const store = defineStore({
35
36
 
36
37
  function Counter() {
37
38
  const { count } = useStore(store)
39
+
38
40
  return (
39
41
  <div>
42
+ <div>
43
+ Count:
44
+ {count}
45
+ </div>
40
46
  <button onClick={store.increment}>Increment</button>
41
- <div>{count}</div>
42
47
  </div>
43
48
  )
44
49
  }
45
50
  ```
46
51
 
47
- ### With Getters
52
+ ### Derived State (Getters)
48
53
 
49
- Getters are computed properties that automatically update when their dependencies change. They provide a clean way to derive state without manually tracking dependencies.
54
+ Getters are **computed properties**. They automatically re-evaluate when their dependencies change, providing a clean way to derive data.
50
55
 
51
56
  ```tsx
52
57
  const store = defineStore({
@@ -62,314 +67,153 @@ const store = defineStore({
62
67
  },
63
68
  },
64
69
  })
65
-
66
- function Counter() {
67
- const state = useStore(store)
68
- return (
69
- <div>
70
- <div>
71
- Count:
72
- {state.count}
73
- </div>
74
- <div>
75
- Doubled:
76
- {state.doubled}
77
- </div>
78
- <button onClick={store.increment}>Increment</button>
79
- </div>
80
- )
81
- }
82
70
  ```
83
71
 
84
- ### Persistence
85
-
86
- The persistence plugin allows you to persist store state to storage (e.g., localStorage).
72
+ -----
87
73
 
88
- First, register the persist plugin:
74
+ ## 🛠 Advanced Features
89
75
 
90
- ```tsx
91
- import valtio from 'valtio-define'
92
- import { persist } from 'valtio-define/plugins'
93
-
94
- // Register the persist plugin globally
95
- valtio.use(persist())
96
- ```
76
+ ### The Power of `this`
97
77
 
98
- Then use it in your store:
78
+ Inside `actions` and `getters`, `this` provides full access to the store's state, other actions, and other getters. This type safety across the entire store.
99
79
 
100
80
  ```tsx
101
- import { defineStore } from 'valtio-define'
102
-
103
81
  const store = defineStore({
104
- state: () => ({ count: 0 }),
82
+ state: () => ({
83
+ count: 0,
84
+ }),
105
85
  actions: {
106
- increment() {
107
- this.count++
86
+ // Autocompletion and typings for the whole store ✨
87
+ currentDoubledOne() {
88
+ return this.doublePlusOne
108
89
  },
109
90
  },
110
- persist: {
111
- key: 'my-store',
112
- storage: localStorage,
113
- paths: ['count'], // Only persist 'count', or omit to persist all state
91
+ getters: {
92
+ doubled() {
93
+ return this.count * 2
94
+ },
95
+ // Note: The return type **must** be explicitly set for complex getters
96
+ doublePlusOne() {
97
+ // Access other getters via 'this'
98
+ return this.doubled + 1
99
+ },
114
100
  },
115
101
  })
116
102
  ```
117
103
 
118
- If `persist` is `true`, it will use `structure-id` to generate a unique key for the store automatically.
104
+ ### Persistence
119
105
 
120
- ```tsx
121
- const store = defineStore({
122
- state: () => ({ count: 0 }),
123
- persist: true, // Auto-generates key using structure-id
124
- })
125
- ```
106
+ Save and restore your store state using the `persist` plugin.
126
107
 
127
- You can pass `hydrate` when registering the plugin (default `true`). When `true`, state is hydrated from storage as soon as the store is created. Set `hydrate: false` when you need to avoid running persistence during server-side rendering, and manually mount persist in your App entry instead:
108
+ 1. **Global Registration:**
128
109
 
129
- ```tsx
130
- // Register with hydrate: false
131
- store.use(persist({ hydrate: false }))
110
+ ```tsx
111
+ import valtio from 'valtio-define'
112
+ import { persist } from 'valtio-define/plugins'
132
113
 
133
- // In your App (client entry), after store is used:
134
- useEffect(() => store.$persist.mount(), [])
135
- ```
114
+ valtio.use(persist())
115
+ ```
136
116
 
137
- ### Subscribe to Changes
117
+ 2. **Store Configuration:**
138
118
 
139
- ```tsx
140
- const store = defineStore({
141
- state: () => ({ count: 0 }),
142
- actions: {
143
- increment() {
144
- this.count++
145
- },
146
- },
147
- })
119
+ ```tsx
120
+ const store = defineStore({
121
+ state: () => ({ count: 0 }),
122
+ persist: {
123
+ key: 'my-app-storage',
124
+ storage: localStorage,
125
+ paths: ['count'], // Optional: Persist specific keys only
126
+ },
127
+ })
128
+ ```
148
129
 
149
- // Subscribe to state changes
150
- const unsubscribe = store.$subscribe((state) => {
151
- console.log('State changed:', state)
152
- })
130
+ > **Tip:** If you set `persist: true`, a unique key is automatically generated using `structure-id`.
153
131
 
154
- // Subscribe to specific key changes
155
- const unsubscribeKey = store.$subscribeKey('count', (value) => {
156
- console.log('Count changed:', value)
157
- })
158
- ```
132
+ ### Manual Hydration (SSR Friendly)
159
133
 
160
- ### Patch State
134
+ To avoid hydration mismatches during Server-Side Rendering, disable automatic hydration and mount it in a `useEffect`.
161
135
 
162
136
  ```tsx
163
- // Patch with object
164
- store.$patch({ count: 10 })
137
+ // Register with hydrate disabled
138
+ store.use(persist({ hydrate: false }))
165
139
 
166
- // Patch with function
167
- store.$patch((state) => {
168
- state.count += 5
169
- })
140
+ // In your Client Entry / App Root
141
+ useEffect(() => {
142
+ store.$persist.mount()
143
+ }, [])
170
144
  ```
171
145
 
172
- ### Signal (JSX Component)
173
-
174
- ```tsx
175
- function App() {
176
- return (
177
- <div>
178
- Count:
179
- {' '}
180
- {store.$signal(state => state.count)}
181
- </div>
182
- )
183
- }
184
- ```
146
+ ### React-Idiomatic State Hooks
185
147
 
186
- ### Store to State Hooks
187
-
188
- Convert store state to React hooks similar to `useState`. This provides a more React-idiomatic way to access and update store state.
189
-
190
- #### `storeToState(store, key)`
191
-
192
- Returns a tuple `[state, setter]` for a single store key, similar to React's `useState`.
148
+ If you prefer the `useState` syntax, use `storeToState` or `storeToStates`. These return `[state, setter]` tuples.
193
149
 
194
150
  ```tsx
195
- import { defineStore, storeToState } from 'valtio-define'
196
-
197
- const store = defineStore({
198
- state: { count: 0, name: 'test' },
199
- })
200
-
201
- function Counter() {
202
- const [count, setCount] = storeToState(store, 'count')
151
+ function Profile() {
152
+ // Access a single key
203
153
  const [name, setName] = storeToState(store, 'name')
204
154
 
205
- return (
206
- <div>
207
- <button onClick={() => setCount(count + 1)}>Increment</button>
208
- <button onClick={() => setCount(prev => prev + 1)}>Increment (functional)</button>
209
- <div>
210
- Count:
211
- {count}
212
- </div>
213
- <div>
214
- Name:
215
- {name}
216
- </div>
217
- </div>
218
- )
219
- }
220
- ```
221
-
222
- **Parameters:**
223
- - `store`: Store instance created by `defineStore`
224
- - `key`: Key of the state property to access
225
-
226
- **Returns:** `[state, setter]` tuple where:
227
- - `state`: Current value of the state property
228
- - `setter`: Function to update the state (accepts value or updater function)
229
-
230
- #### `storeToStates(store)`
231
-
232
- Returns an object with all store keys mapped to `[state, setter]` tuples.
233
-
234
- ```tsx
235
- function Component() {
155
+ // Access all keys as hooks
236
156
  const {
237
- count: [count, setCount],
238
- name: [name, setName],
239
- user: [user, setUser],
157
+ count: [count, setCount]
240
158
  } = storeToStates(store)
241
159
 
242
- return (
243
- <div>
244
- <button onClick={() => setCount(count + 1)}>Increment</button>
245
- <div>
246
- Count:
247
- {count}
248
- </div>
249
- <div>
250
- Name:
251
- {name}
252
- </div>
253
- <div>
254
- User:
255
- {user.name}
256
- </div>
257
- </div>
258
- )
160
+ return <input value={name} onChange={e => setName(e.target.value)} />
259
161
  }
260
162
  ```
261
163
 
262
- **Parameters:**
263
- - `store`: Store instance created by `defineStore`
264
-
265
- **Returns:** Object where each key maps to a `[state, setter]` tuple
266
-
267
- ## API
268
-
269
- ### `defineStore(store)`
270
-
271
- Creates a store with state, actions, and getters.
272
-
273
- **Parameters:**
274
- - `store.state`: Initial state object or factory function
275
- - `store.actions`: Object containing action methods
276
- - `store.getters`: Object containing getter methods
277
- - `store.persist`: Persistence plugin configuration (boolean or object) - see [Persistence Plugin](#persistence)
278
-
279
- **Returns:** Store instance with reactive state and actions
280
-
281
- ### `useStore(store)`
282
-
283
- React hook that returns a snapshot of the store state.
284
-
285
- **Parameters:**
286
- - `store`: Store instance created by `defineStore`
287
-
288
- **Returns:** Snapshot of the store state
164
+ -----
289
165
 
290
- ### `storeToState(store, key)`
166
+ ## 🛰 Store API
291
167
 
292
- React hook that returns a `[state, setter]` tuple for a single store key, similar to React's `useState`.
168
+ Every store instance created with `defineStore` includes built-in utility methods:
293
169
 
294
- **Parameters:**
295
- - `store`: Store instance created by `defineStore`
296
- - `key`: Key of the state property to access
170
+ * **`$patch(obj | fn)`**: Bulk update the state.
171
+ * **`$subscribe(callback)`**: Watch the entire store for changes.
172
+ * **`$subscribeKey(key, callback)`**: Watch a specific property.
173
+ * **`$signal(selector)`**: Use a selector function inside JSX for fine-grained reactivity.
297
174
 
298
- **Returns:** `[state, setter]` tuple where:
299
- - `state`: Current value of the state property
300
- - `setter`: Function to update the state (accepts value or updater function like `setState(value)` or `setState(prev => newValue)`)
175
+ -----
301
176
 
302
- ### `storeToStates(store)`
177
+ ## 🔌 Plugins
303
178
 
304
- React hook that returns an object with all store keys mapped to `[state, setter]` tuples.
179
+ ### Global vs. Per-Store
305
180
 
306
- **Parameters:**
307
- - `store`: Store instance created by `defineStore`
308
-
309
- **Returns:** Object where each key maps to a `[state, setter]` tuple, preserving the correct type for each property
310
-
311
- ### Plugins
312
-
313
- Plugins allow you to extend store functionality. You can use plugins globally or per-store.
314
-
315
- #### Global Plugin Registration
181
+ Plugins can be applied to all stores or restricted to a single instance.
316
182
 
317
183
  ```tsx
318
- import valtio from 'valtio-define'
319
- import { persist } from 'valtio-define/plugins'
184
+ // Global
185
+ valtio.use(myPlugin())
320
186
 
321
- // Register plugin globally - applies to all stores
322
- valtio.use(persist())
187
+ // Local
188
+ const store = defineStore({ /* ... */ })
189
+ store.use(myPlugin())
323
190
  ```
324
191
 
325
- #### Per-Store Plugin Registration
192
+ ### Creating a Custom Plugin
326
193
 
327
- ```tsx
328
- import { defineStore } from 'valtio-define'
329
- import { persist } from 'valtio-define/plugins'
330
-
331
- const store = defineStore({
332
- state: () => ({ count: 0 }),
333
- })
334
-
335
- // Register plugin for this specific store
336
- store.use(persist())
337
- ```
338
-
339
- #### Creating Custom Plugins
194
+ Extend functionality by accessing the `store` instance and `options` through the plugin context.
340
195
 
341
196
  ```tsx
342
197
  import type { Plugin } from 'valtio-define'
343
198
 
344
- function myPlugin() {
345
- ({ store, options }: PluginContext) => {
346
- // Access store methods
199
+ function loggerPlugin(): Plugin {
200
+ return ({ store, options }) => {
347
201
  store.$subscribe((state) => {
348
- console.log('State changed:', state)
202
+ console.log('Update:', state)
349
203
  })
350
-
351
- // Access store options
352
- if (options.someOption) {
353
- // Do something
354
- }
355
204
  }
356
205
  }
357
206
 
358
207
  declare module 'valtio-define' {
359
- export interface StoreDefine<S extends object, A extends ActionsTree, G extends Getters<any>> {
360
- myPlugin?: {
208
+ export interface StoreDefineOptions<S extends object> {
209
+ $myPlugin?: {
361
210
  someOption?: boolean
362
211
  }
363
212
  }
364
213
  }
365
-
366
- // Use the plugin
367
- use(myPlugin())
368
214
  ```
369
215
 
370
- **Plugin Context:**
371
- - `context.store`: The store instance with all methods (`$state`, `$patch`, `$subscribe`, etc.)
372
- - `context.options`: The original store definition options
216
+ -----
373
217
 
374
218
  ## License
375
219
 
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as GettersReturnType, c as PluginContext, d as StoreDefine, f as StoreDefineOptions, h as SubscribeKey, i as Getters, l as Signal, m as Subscribe, n as ActionsOmitThisParameter, o as Patch, p as StoreOptions, r as ActionsTree, s as Plugin, t as Actions, u as Store } from "./types-BA_0y5TQ.mjs";
1
+ import { a as GettersReturnType, c as PluginContext, d as StoreDefine, f as StoreDefineOptions, h as SubscribeKey, i as Getters, l as Signal, m as Subscribe, n as ActionsOmitThisParameter, o as Patch, p as StoreOptions, r as ActionsTree, s as Plugin, t as Actions, u as Store } from "./types-CqDu3QIJ.mjs";
2
2
  import { Snapshot } from "valtio";
3
3
  import { Dispatch, SetStateAction } from "react";
4
4
 
@@ -35,7 +35,7 @@ declare function use(plugin: Plugin): void;
35
35
  *
36
36
  * ```
37
37
  */
38
- declare function defineStore<S extends object, A extends Actions<S>, G extends Getters<S>>(define: StoreDefine<S, A, G>): Store<S, A, G>;
38
+ declare function defineStore<S extends object = {}, A extends Actions<S> = {}, G extends Getters<S> = {}>(define: StoreDefine<S, A, G>): Store<S, A, G>;
39
39
  //#endregion
40
40
  //#region src/hooks.d.ts
41
41
  interface UseStoreOptions {
@@ -1,4 +1,4 @@
1
- import { s as Plugin } from "../../types-BA_0y5TQ.mjs";
1
+ import { s as Plugin } from "../../types-CqDu3QIJ.mjs";
2
2
  import { PersistentOptions, PersistentStore } from "./types.mjs";
3
3
 
4
4
  //#region src/plugins/persist/index.d.ts
@@ -7,10 +7,10 @@ type Getters<S = any> = Record<string, (this: S) => any>;
7
7
  type ActionsOmitThisParameter<A extends Actions<any>> = { [K in keyof A]: (...args: Parameters<A[K]>) => ReturnType<A[K]> };
8
8
  type GettersReturnType<G extends Getters<any>> = { [K in keyof G]: ReturnType<G[K]> };
9
9
  interface StoreDefineOptions<S> {}
10
- interface StoreDefine<S extends object, A, G extends Getters<any>> extends StoreDefineOptions<S> {
10
+ interface StoreDefine<S extends object, A extends object, G extends Getters<any>> extends StoreDefineOptions<S> {
11
11
  state: (() => S) | S;
12
- actions?: A & ThisType<A & S>;
13
- getters?: G & ThisType<S>;
12
+ actions?: A & ThisType<A & S & GettersReturnType<G>>;
13
+ getters?: G & ThisType<S & GettersReturnType<G>>;
14
14
  }
15
15
  interface Signal<S, G extends Getters<S>> {
16
16
  <T>(fn: (state: S & GettersReturnType<G>) => T): ReactElement;
@@ -27,7 +27,7 @@ interface Patch<S, G extends Getters<S>> {
27
27
  (patch: Partial<S> | ((state: S & GettersReturnType<G>) => void)): void;
28
28
  }
29
29
  interface StoreOptions {}
30
- type Store<S, A extends Actions<S> = Actions<S>, G extends Getters<S> = Getters<S>> = {
30
+ type Store<S, A extends Actions<S> = {}, G extends Getters<S> = {}> = {
31
31
  $subscribe: Subscribe<S, G>;
32
32
  $subscribeKey: SubscribeKey<S, G>;
33
33
  $patch: Patch<S, G>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "valtio-define",
3
3
  "type": "module",
4
- "version": "1.1.4",
4
+ "version": "1.2.0",
5
5
  "description": "⚡quickly create a fully functional and robust Valtio factory",
6
6
  "author": "Hairyf <wwu710632@gmail.com>",
7
7
  "license": "MIT",