valtio-define 1.1.5 → 1.2.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 +116 -240
- package/dist/index.d.mts +10 -7
- package/dist/index.mjs +1 -1
- package/dist/plugins/index.d.mts +2 -2
- package/dist/plugins/persist/index.d.mts +2 -5
- package/dist/plugins/persist/index.mjs +1 -1
- package/dist/plugins/persist/types.d.mts +8 -1
- package/dist/{types-BW_uQuTb.d.mts → types-CqDu3QIJ.d.mts} +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,25 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+

|
|
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
|
-
|
|
10
|
+
⚡️ **valtio-define** is a lightweight factory for creating fully functional, robust [Valtio](https://github.com/pmndrs/valtio) 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
|
-
|
|
18
|
+
<details>
|
|
19
|
+
<summary>Are you an AI?</summary>
|
|
20
|
+
|
|
21
|
+
You can run <code>npx skills add hairyf/valtio-define --skill valtio-define -y</code> to install the skills!
|
|
22
|
+
|
|
23
|
+
Remember to ask your owner which <a href="https://github.com/vercel-labs/skills?tab=readme-ov-file#supported-agents">Agents</a> need to be supported (using the <code>--agent</code> parameter of skills) to avoid installing too many default <code>agents</code> directories.
|
|
24
|
+
|
|
25
|
+
</details>
|
|
26
|
+
|
|
27
|
+
## 🚀 Quick Start
|
|
28
|
+
|
|
19
29
|
|
|
20
30
|
### Basic Store
|
|
21
31
|
|
|
22
|
-
|
|
32
|
+
`defineStore` allows you to encapsulate state and logic in one place. Use `useStore` to consume the reactive state in your components.
|
|
23
33
|
|
|
24
34
|
```tsx
|
|
25
35
|
import { defineStore, useStore } from 'valtio-define'
|
|
@@ -28,6 +38,7 @@ const store = defineStore({
|
|
|
28
38
|
state: () => ({ count: 0 }),
|
|
29
39
|
actions: {
|
|
30
40
|
increment() {
|
|
41
|
+
// 'this' refers to the reactive state
|
|
31
42
|
this.count++
|
|
32
43
|
},
|
|
33
44
|
},
|
|
@@ -35,18 +46,22 @@ const store = defineStore({
|
|
|
35
46
|
|
|
36
47
|
function Counter() {
|
|
37
48
|
const { count } = useStore(store)
|
|
49
|
+
|
|
38
50
|
return (
|
|
39
51
|
<div>
|
|
52
|
+
<div>
|
|
53
|
+
Count:
|
|
54
|
+
{count}
|
|
55
|
+
</div>
|
|
40
56
|
<button onClick={store.increment}>Increment</button>
|
|
41
|
-
<div>{count}</div>
|
|
42
57
|
</div>
|
|
43
58
|
)
|
|
44
59
|
}
|
|
45
60
|
```
|
|
46
61
|
|
|
47
|
-
###
|
|
62
|
+
### Derived State (Getters)
|
|
48
63
|
|
|
49
|
-
Getters are computed properties
|
|
64
|
+
Getters are **computed properties**. They automatically re-evaluate when their dependencies change, providing a clean way to derive data.
|
|
50
65
|
|
|
51
66
|
```tsx
|
|
52
67
|
const store = defineStore({
|
|
@@ -62,314 +77,175 @@ const store = defineStore({
|
|
|
62
77
|
},
|
|
63
78
|
},
|
|
64
79
|
})
|
|
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
80
|
```
|
|
83
81
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
The persistence plugin allows you to persist store state to storage (e.g., localStorage).
|
|
87
|
-
|
|
88
|
-
First, register the persist plugin:
|
|
82
|
+
-----
|
|
89
83
|
|
|
90
|
-
|
|
91
|
-
import valtio from 'valtio-define'
|
|
92
|
-
import { persist } from 'valtio-define/plugins'
|
|
84
|
+
## 🛠 Advanced Features
|
|
93
85
|
|
|
94
|
-
|
|
95
|
-
valtio.use(persist())
|
|
96
|
-
```
|
|
86
|
+
### The Power of `this`
|
|
97
87
|
|
|
98
|
-
|
|
88
|
+
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
89
|
|
|
100
90
|
```tsx
|
|
101
|
-
import { defineStore } from 'valtio-define'
|
|
102
|
-
|
|
103
91
|
const store = defineStore({
|
|
104
|
-
state: () => ({
|
|
92
|
+
state: () => ({
|
|
93
|
+
count: 0,
|
|
94
|
+
}),
|
|
105
95
|
actions: {
|
|
106
|
-
|
|
107
|
-
|
|
96
|
+
// Autocompletion and typings for the whole store ✨
|
|
97
|
+
currentDoubledOne() {
|
|
98
|
+
return this.doublePlusOne
|
|
108
99
|
},
|
|
109
100
|
},
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
101
|
+
getters: {
|
|
102
|
+
doubled() {
|
|
103
|
+
return this.count * 2
|
|
104
|
+
},
|
|
105
|
+
// Note: The return type **must** be explicitly set for complex getters
|
|
106
|
+
doublePlusOne() {
|
|
107
|
+
// Access other getters via 'this'
|
|
108
|
+
return this.doubled + 1
|
|
109
|
+
},
|
|
114
110
|
},
|
|
115
111
|
})
|
|
116
112
|
```
|
|
117
113
|
|
|
118
|
-
|
|
114
|
+
### Persistence
|
|
119
115
|
|
|
120
|
-
|
|
121
|
-
const store = defineStore({
|
|
122
|
-
state: () => ({ count: 0 }),
|
|
123
|
-
persist: true, // Auto-generates key using structure-id
|
|
124
|
-
})
|
|
125
|
-
```
|
|
116
|
+
Save and restore your store state using the `persist` plugin.
|
|
126
117
|
|
|
127
|
-
|
|
118
|
+
1. **Global Registration:**
|
|
128
119
|
|
|
129
|
-
```tsx
|
|
130
|
-
|
|
131
|
-
|
|
120
|
+
```tsx
|
|
121
|
+
import valtio from 'valtio-define'
|
|
122
|
+
import { persist } from 'valtio-define/plugins'
|
|
132
123
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
```
|
|
124
|
+
valtio.use(persist())
|
|
125
|
+
```
|
|
136
126
|
|
|
137
|
-
|
|
127
|
+
2. **Store Configuration:**
|
|
138
128
|
|
|
139
|
-
```tsx
|
|
140
|
-
const store = defineStore({
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
})
|
|
129
|
+
```tsx
|
|
130
|
+
const store = defineStore({
|
|
131
|
+
state: () => ({ count: 0 }),
|
|
132
|
+
persist: {
|
|
133
|
+
key: 'my-app-storage',
|
|
134
|
+
storage: localStorage,
|
|
135
|
+
paths: ['count'], // Optional: Persist specific keys only
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
```
|
|
148
139
|
|
|
149
|
-
|
|
150
|
-
const unsubscribe = store.$subscribe((state) => {
|
|
151
|
-
console.log('State changed:', state)
|
|
152
|
-
})
|
|
140
|
+
> **Tip:** If you set `persist: true`, a unique key is automatically generated using `structure-id`.
|
|
153
141
|
|
|
154
|
-
|
|
155
|
-
const unsubscribeKey = store.$subscribeKey('count', (value) => {
|
|
156
|
-
console.log('Count changed:', value)
|
|
157
|
-
})
|
|
158
|
-
```
|
|
142
|
+
### Manual Hydration (SSR Friendly)
|
|
159
143
|
|
|
160
|
-
|
|
144
|
+
To avoid hydration mismatches during Server-Side Rendering, disable automatic hydration and mount it in a `useEffect`.
|
|
161
145
|
|
|
162
146
|
```tsx
|
|
163
|
-
//
|
|
164
|
-
store
|
|
147
|
+
// Register with hydrate disabled
|
|
148
|
+
store.use(persist({ hydrate: false }))
|
|
165
149
|
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
})
|
|
150
|
+
// In your Client Entry / App Root
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
store.$persist.mount()
|
|
153
|
+
}, [])
|
|
170
154
|
```
|
|
171
155
|
|
|
172
|
-
###
|
|
156
|
+
### React-Idiomatic State Hooks
|
|
173
157
|
|
|
174
|
-
|
|
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`.
|
|
158
|
+
If you prefer the `useState` syntax, use `storeToState` or `storeToStates`. These return `[state, setter]` tuples.
|
|
193
159
|
|
|
194
160
|
```tsx
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const store = defineStore({
|
|
198
|
-
state: { count: 0, name: 'test' },
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
function Counter() {
|
|
202
|
-
const [count, setCount] = storeToState(store, 'count')
|
|
161
|
+
function Profile() {
|
|
162
|
+
// Access a single key
|
|
203
163
|
const [name, setName] = storeToState(store, 'name')
|
|
204
164
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
{count}
|
|
212
|
-
</div>
|
|
213
|
-
<div>
|
|
214
|
-
Name:
|
|
215
|
-
{name}
|
|
216
|
-
</div>
|
|
217
|
-
</div>
|
|
218
|
-
)
|
|
165
|
+
// Access all keys as hooks
|
|
166
|
+
const {
|
|
167
|
+
count: [count, setCount]
|
|
168
|
+
} = storeToStates(store)
|
|
169
|
+
|
|
170
|
+
return <input value={name} onChange={e => setName(e.target.value)} />
|
|
219
171
|
}
|
|
220
172
|
```
|
|
221
173
|
|
|
222
|
-
|
|
223
|
-
- `store`: Store instance created by `defineStore`
|
|
224
|
-
- `key`: Key of the state property to access
|
|
174
|
+
### Controlled inputs may lose caret position
|
|
225
175
|
|
|
226
|
-
|
|
227
|
-
- `state`: Current value of the state property
|
|
228
|
-
- `setter`: Function to update the state (accepts value or updater function)
|
|
176
|
+
Ref: https://github.com/pmndrs/valtio/issues/270
|
|
229
177
|
|
|
230
|
-
|
|
178
|
+
This happens because Valtio batches state updates causing React to re-render after the input event. React resets the DOM value and loses the caret position.
|
|
231
179
|
|
|
232
|
-
|
|
180
|
+
Use `{ sync: true }` to update synchronously and preserve the caret:
|
|
233
181
|
|
|
234
182
|
```tsx
|
|
235
|
-
function
|
|
236
|
-
const {
|
|
237
|
-
|
|
238
|
-
name: [name, setName],
|
|
239
|
-
user: [user, setUser],
|
|
240
|
-
} = storeToStates(store)
|
|
183
|
+
function Input() {
|
|
184
|
+
const { text } = useStore(store, { sync: true })
|
|
185
|
+
// const [text, setText] = storeToState(store, 'text', { sync: true })
|
|
241
186
|
|
|
242
187
|
return (
|
|
243
|
-
<
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
{count}
|
|
248
|
-
</div>
|
|
249
|
-
<div>
|
|
250
|
-
Name:
|
|
251
|
-
{name}
|
|
252
|
-
</div>
|
|
253
|
-
<div>
|
|
254
|
-
User:
|
|
255
|
-
{user.name}
|
|
256
|
-
</div>
|
|
257
|
-
</div>
|
|
188
|
+
<input
|
|
189
|
+
onChange={e => store.text = e.target.value}
|
|
190
|
+
value={text}
|
|
191
|
+
/>
|
|
258
192
|
)
|
|
259
193
|
}
|
|
260
194
|
```
|
|
261
195
|
|
|
262
|
-
|
|
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
|
|
196
|
+
-----
|
|
289
197
|
|
|
290
|
-
|
|
198
|
+
## 🛰 Store API
|
|
291
199
|
|
|
292
|
-
|
|
200
|
+
Every store instance created with `defineStore` includes built-in utility methods:
|
|
293
201
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
202
|
+
* **`$patch(obj | fn)`**: Bulk update the state.
|
|
203
|
+
* **`$subscribe(callback)`**: Watch the entire store for changes.
|
|
204
|
+
* **`$subscribeKey(key, callback)`**: Watch a specific property.
|
|
205
|
+
* **`$signal(selector)`**: Use a selector function inside JSX for fine-grained reactivity.
|
|
297
206
|
|
|
298
|
-
|
|
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)`)
|
|
207
|
+
-----
|
|
301
208
|
|
|
302
|
-
|
|
209
|
+
## 🔌 Plugins
|
|
303
210
|
|
|
304
|
-
|
|
211
|
+
### Global vs. Per-Store
|
|
305
212
|
|
|
306
|
-
|
|
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
|
|
213
|
+
Plugins can be applied to all stores or restricted to a single instance.
|
|
316
214
|
|
|
317
215
|
```tsx
|
|
318
|
-
|
|
319
|
-
|
|
216
|
+
// Global
|
|
217
|
+
valtio.use(myPlugin())
|
|
320
218
|
|
|
321
|
-
//
|
|
322
|
-
|
|
219
|
+
// Local
|
|
220
|
+
const store = defineStore({ /* ... */ })
|
|
221
|
+
store.use(myPlugin())
|
|
323
222
|
```
|
|
324
223
|
|
|
325
|
-
|
|
224
|
+
### Creating a Custom Plugin
|
|
326
225
|
|
|
327
|
-
|
|
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
|
|
226
|
+
Extend functionality by accessing the `store` instance and `options` through the plugin context.
|
|
340
227
|
|
|
341
228
|
```tsx
|
|
342
229
|
import type { Plugin } from 'valtio-define'
|
|
343
230
|
|
|
344
|
-
function
|
|
345
|
-
({ store, options }
|
|
346
|
-
// Access store methods
|
|
231
|
+
function loggerPlugin(): Plugin {
|
|
232
|
+
return ({ store, options }) => {
|
|
347
233
|
store.$subscribe((state) => {
|
|
348
|
-
console.log('
|
|
234
|
+
console.log('Update:', state)
|
|
349
235
|
})
|
|
350
|
-
|
|
351
|
-
// Access store options
|
|
352
|
-
if (options.someOption) {
|
|
353
|
-
// Do something
|
|
354
|
-
}
|
|
355
236
|
}
|
|
356
237
|
}
|
|
357
238
|
|
|
358
239
|
declare module 'valtio-define' {
|
|
359
|
-
export interface
|
|
360
|
-
myPlugin?: {
|
|
240
|
+
export interface StoreDefineOptions<S extends object> {
|
|
241
|
+
$myPlugin?: {
|
|
361
242
|
someOption?: boolean
|
|
362
243
|
}
|
|
363
244
|
}
|
|
364
245
|
}
|
|
365
|
-
|
|
366
|
-
// Use the plugin
|
|
367
|
-
use(myPlugin())
|
|
368
246
|
```
|
|
369
247
|
|
|
370
|
-
|
|
371
|
-
- `context.store`: The store instance with all methods (`$state`, `$patch`, `$subscribe`, etc.)
|
|
372
|
-
- `context.options`: The original store definition options
|
|
248
|
+
-----
|
|
373
249
|
|
|
374
250
|
## License
|
|
375
251
|
|
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-
|
|
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
|
|
|
@@ -38,18 +38,21 @@ declare function use(plugin: Plugin): void;
|
|
|
38
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
|
+
declare function useStore<S extends object, A extends Actions<S>, G extends Getters<S>>(store: Store<S, A, G>, options?: {
|
|
42
42
|
sync?: boolean;
|
|
43
|
-
}
|
|
44
|
-
declare function useStore<S extends object, A extends Actions<S>, G extends Getters<S>>(store: Store<S, A, G>, options?: UseStoreOptions): Snapshot<S & GettersReturnType<G> & A>;
|
|
43
|
+
}): Snapshot<S & GettersReturnType<G> & A>;
|
|
45
44
|
//#endregion
|
|
46
45
|
//#region src/utils.d.ts
|
|
47
|
-
declare function storeToState<S extends object, K extends keyof S>(store: Store<S>, key: K
|
|
48
|
-
|
|
46
|
+
declare function storeToState<S extends object, K extends keyof S>(store: Store<S>, key: K, options?: {
|
|
47
|
+
sync?: boolean;
|
|
48
|
+
}): [S[K], Dispatch<SetStateAction<S[K]>>];
|
|
49
|
+
declare function storeToStates<S extends object>(store: Store<S>, options?: {
|
|
50
|
+
sync?: boolean;
|
|
51
|
+
}): { [K in keyof S]: [S[K], Dispatch<SetStateAction<S[K]>>] };
|
|
49
52
|
//#endregion
|
|
50
53
|
//#region src/index.d.ts
|
|
51
54
|
declare const _default: {
|
|
52
55
|
use: typeof use;
|
|
53
56
|
};
|
|
54
57
|
//#endregion
|
|
55
|
-
export { Actions, ActionsOmitThisParameter, ActionsTree, Getters, GettersReturnType, Patch, Plugin, PluginContext, Signal, Store, StoreDefine, StoreDefineOptions, StoreOptions, Subscribe, SubscribeKey,
|
|
58
|
+
export { Actions, ActionsOmitThisParameter, ActionsTree, Getters, GettersReturnType, Patch, Plugin, PluginContext, Signal, Store, StoreDefine, StoreDefineOptions, StoreOptions, Subscribe, SubscribeKey, _default as default, defineStore, plugins, storeToState, storeToStates, use, useStore };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{proxy as e,ref as t,subscribe as n,useSnapshot as r}from"valtio";import{createElement as i}from"react";import{subscribeKey as a}from"valtio/utils";const o=e([]);function s(e){o.push(e)}function c(s){let c=typeof s.state==`function`?s.state():s.state,u=s.getters||{},d=s.actions||{},f=e(c),p={},m={},h=new WeakSet;for(let e in d)p[e]=t(d[e].bind(f)),f[e]=p[e];for(let e in u)l(f,e,()=>u[e].call(f)),l(m,e,()=>f[e]);function g(e){return n(f,t=>e(f,t))}function _(e,t){return a(f,e,e=>t(e),!0)}function v(e){typeof e==`function`?e(f):Object.assign(f,e)}function y(e){return i(()=>e(r(f)))}function b(e){o.push(e),C(e)}let x={$subscribe:g,$subscribeKey:_,$patch:v,$state:f,$actions:p,$getters:m,$signal:y,use:b},S=new Proxy(x,{get(e,t){return t in p?p[t]:t in e?e[t]:f[t]},has(e,t){return t in e||t in p||t in f},set(e,t,n){return t in f?f[t]=n:e[t]=n,!0}});function C(e){h.has(e)||(h.add(e),e({store:S,options:s}))}for(let e of o)C(e);return n(o,()=>{for(let e of o)C(e)}),S}function l(e,t,n){Object.defineProperty(e,t,{get:n,enumerable:!0})}function u(e,t){return r(e.$state,t)}function d(e,t){let
|
|
1
|
+
import{proxy as e,ref as t,subscribe as n,useSnapshot as r}from"valtio";import{createElement as i}from"react";import{subscribeKey as a}from"valtio/utils";const o=e([]);function s(e){o.push(e)}function c(s){let c=typeof s.state==`function`?s.state():s.state,u=s.getters||{},d=s.actions||{},f=e(c),p={},m={},h=new WeakSet;for(let e in d)p[e]=t(d[e].bind(f)),f[e]=p[e];for(let e in u)l(f,e,()=>u[e].call(f)),l(m,e,()=>f[e]);function g(e){return n(f,t=>e(f,t))}function _(e,t){return a(f,e,e=>t(e),!0)}function v(e){typeof e==`function`?e(f):Object.assign(f,e)}function y(e){return i(()=>e(r(f)))}function b(e){o.push(e),C(e)}let x={$subscribe:g,$subscribeKey:_,$patch:v,$state:f,$actions:p,$getters:m,$signal:y,use:b},S=new Proxy(x,{get(e,t){return t in p?p[t]:t in e?e[t]:f[t]},has(e,t){return t in e||t in p||t in f},set(e,t,n){return t in f?f[t]=n:e[t]=n,!0}});function C(e){h.has(e)||(h.add(e),e({store:S,options:s}))}for(let e of o)C(e);return n(o,()=>{for(let e of o)C(e)}),S}function l(e,t,n){Object.defineProperty(e,t,{get:n,enumerable:!0})}function u(e,t){return r(e.$state,t)}function d(e,t,n){let r=u(e,n);function i(n){typeof n==`function`?e.$patch(e=>{e[t]=n(e[t])}):e.$patch(e=>{e[t]=n})}return[r[t],i]}function f(e,t){return Object.fromEntries(Object.keys(e.$state).map(n=>[n,d(e,n,t)]))}var p={use:s};export{p as default,c as defineStore,o as plugins,d as storeToState,f as storeToStates,s as use,u as useStore};
|
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { PersistentMountOptions,
|
|
2
|
-
export { PersistentMountOptions,
|
|
1
|
+
import { PersistentMountOptions, persist } from "./persist/index.mjs";
|
|
2
|
+
export { PersistentMountOptions, persist };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { s as Plugin } from "../../types-
|
|
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
|
|
@@ -8,9 +8,6 @@ interface PersistentMountOptions {
|
|
|
8
8
|
*/
|
|
9
9
|
hydrate?: boolean;
|
|
10
10
|
}
|
|
11
|
-
interface StorePersistentOptions {
|
|
12
|
-
mount: () => void;
|
|
13
|
-
}
|
|
14
11
|
declare function persist({
|
|
15
12
|
hydrate
|
|
16
13
|
}?: PersistentMountOptions): Plugin;
|
|
@@ -21,4 +18,4 @@ declare module 'valtio-define' {
|
|
|
21
18
|
interface StoreOptions extends PersistentStore {}
|
|
22
19
|
}
|
|
23
20
|
//#endregion
|
|
24
|
-
export { PersistentMountOptions,
|
|
21
|
+
export { PersistentMountOptions, persist };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{subscribe as e}from"valtio";import{get as t,set as n}from"@hairy/utils";import{destr as r}from"destr";import{generateStructureId as i}from"structure-id";function a({hydrate:a=!0}={}){return o=>{let{persist:s,getters:c}=o.options,{$state:l}=o.store;if(
|
|
1
|
+
import{subscribe as e}from"valtio";import{get as t,set as n}from"@hairy/utils";import{destr as r}from"destr";import{generateStructureId as i}from"structure-id";function a({hydrate:a=!0}={}){return o=>{let{persist:s,getters:c}=o.options,{$state:l}=o.store;if(o.store.$persist?.unmount?.(),!s)return;let u=s===!0?{}:s,d=u.key||i(l),f=u.storage??(typeof localStorage<`u`?localStorage:void 0);if(!f?.getItem||!f?.setItem)return;let p=o.store.$persist?.meta??{mounted:!1,hydrated:!1};function m(e){let t=r(e);t&&typeof t==`object`&&(Object.keys(c||{}).forEach(e=>Reflect.deleteProperty(t,e)),Object.assign(l,t)),p.hydrated=!0}function h(){p.mounted=!0;let e=f.getItem(d);e instanceof Promise?e.then(m):m(e)}function g(){p.unsubscribe?.(),p.unsubscribe=void 0}function _(){g(),p.unsubscribe=e(l,()=>{if(!p.hydrated)return;let e=(u.paths||Object.keys(l)).reduce((e,r)=>n(e,r,t(l,r)),{});f.setItem(d,JSON.stringify(e))})}o.store.$persist={mount:h,unmount:g,meta:p},a&&!p.mounted&&h(),_()}}export{a as persist};
|
|
@@ -12,10 +12,17 @@ interface PersistentOptions<S extends object> {
|
|
|
12
12
|
storage?: Storage;
|
|
13
13
|
paths?: DeepKeys<S>[];
|
|
14
14
|
}
|
|
15
|
+
interface PersistentMeta {
|
|
16
|
+
mounted: boolean;
|
|
17
|
+
hydrated: boolean;
|
|
18
|
+
unsubscribe?: () => void;
|
|
19
|
+
}
|
|
15
20
|
interface PersistentStore {
|
|
16
21
|
$persist: {
|
|
17
22
|
mount: () => void;
|
|
23
|
+
unmount: () => void;
|
|
24
|
+
meta: PersistentMeta;
|
|
18
25
|
};
|
|
19
26
|
}
|
|
20
27
|
//#endregion
|
|
21
|
-
export { DeepKeys, PersistentOptions, PersistentStore, Storage };
|
|
28
|
+
export { DeepKeys, PersistentMeta, PersistentOptions, PersistentStore, Storage };
|
|
@@ -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
|
|
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