@yakocloud/state-vocab 2.3.6 → 2.4.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 +157 -71
- package/dist/state-vocab.cjs.js +4 -4
- package/dist/state-vocab.es.js +223 -228
- package/dist/types/main.d.ts +1 -0
- package/dist/types/main.utils.d.ts +2 -0
- package/dist/types/state.d.ts +5 -5
- package/dist/types/state.utils.d.ts +0 -4
- package/package.json +17 -1
package/README.md
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
# @yakocloud/state-vocab
|
|
2
2
|
|
|
3
|
-
A lightweight React state management library that synchronizes component state with any `Storage`-compatible (localStorage, sessionStorage, custom).
|
|
3
|
+
A lightweight React state management library that synchronizes component state with any `Storage`-compatible backend (localStorage, sessionStorage, custom).
|
|
4
4
|
|
|
5
5
|
## Why use state-vocab?
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
Most state managers treat persistence as an afterthought — you manage state first, then manually sync it to localStorage. **state-vocab flips this**: storage is defined upfront alongside the state itself, and synchronization is automatic.
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
**Storage-first by design.** Every state node declares its backend at definition time — localStorage, sessionStorage, or any custom adapter. No `useEffect(() => localStorage.setItem(...), [value])` scattered across components.
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
```ts
|
|
12
|
-
// declare once — works everywhere
|
|
13
12
|
const storage = setupStorage({
|
|
14
13
|
theme: defineState({ storage: localStorage, defaultValue: 'Dark' }),
|
|
15
14
|
session: defineState({ storage: () => sessionStorage }),
|
|
16
15
|
inMemory: defineState({ defaultValue: 0 }),
|
|
17
16
|
})
|
|
18
17
|
```
|
|
19
|
-
|
|
18
|
+
|
|
20
19
|
**Bring your own backend.** The `storage` option accepts any object implementing the [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Storage). Point state directly at a server, IndexedDB wrapper, or encrypted store — no extra adapters needed.
|
|
21
|
-
|
|
20
|
+
|
|
22
21
|
```ts
|
|
23
22
|
defineState({
|
|
24
23
|
storage: {
|
|
25
24
|
getItem: (key) => api.get(key),
|
|
26
25
|
setItem: (key, value) => api.set(key, value),
|
|
27
26
|
removeItem: (key) => api.delete(key),
|
|
28
|
-
|
|
27
|
+
length: 0,
|
|
28
|
+
clear: () => {},
|
|
29
|
+
key: () => null,
|
|
29
30
|
}
|
|
30
31
|
})
|
|
31
32
|
```
|
|
32
|
-
|
|
33
|
-
**No prop drilling.** State lives in a shared `storage` object imported directly into any component. No need to pass values down through layers of props or lift state up to a common ancestor
|
|
34
|
-
|
|
33
|
+
|
|
34
|
+
**No prop drilling.** State lives in a shared `storage` object imported directly into any component. No need to pass values down through layers of props or lift state up to a common ancestor.
|
|
35
|
+
|
|
35
36
|
```tsx
|
|
36
37
|
// ❌ without state-vocab — thread props through every layer
|
|
37
38
|
function Page({ theme, onThemeChange }) {
|
|
@@ -43,35 +44,67 @@ function Sidebar({ theme, onThemeChange }) {
|
|
|
43
44
|
function ThemeToggle({ theme, onThemeChange }) {
|
|
44
45
|
return <button onClick={() => onThemeChange('Dark')}>{theme}</button>
|
|
45
46
|
}
|
|
46
|
-
|
|
47
|
+
|
|
47
48
|
// ✅ with state-vocab — import storage, use directly
|
|
48
49
|
function ThemeToggle() {
|
|
49
50
|
const [theme, setTheme] = storage.preference.theme.useState()
|
|
50
51
|
return <button onClick={() => setTheme('Dark')}>{theme}</button>
|
|
51
52
|
}
|
|
52
53
|
```
|
|
53
|
-
|
|
54
|
+
|
|
55
|
+
**Initialize once at the root, read anywhere in the tree.** Call `.useState()` with a `defaultValue` at a parent component to seed the state — then call `.useState()` without arguments in any descendant to consume it. No context wiring, no prop passing. Convenient in NextJs
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
// Root component — initializes the state
|
|
59
|
+
function Page() {
|
|
60
|
+
storage.demo.pageProps.useState({
|
|
61
|
+
defaultValue: {
|
|
62
|
+
a: 1,
|
|
63
|
+
b: 2,
|
|
64
|
+
c: ['one', 'two'],
|
|
65
|
+
},
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
return <DeepChild />
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Somewhere deep in the tree — reads the same state
|
|
72
|
+
function DeepChild() {
|
|
73
|
+
const [pageProps] = storage.demo.pageProps.useState()
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<div>
|
|
77
|
+
<p>a: {pageProps.a}</p>
|
|
78
|
+
<p>b: {pageProps.b}</p>
|
|
79
|
+
<p>c: {pageProps.c.join(', ')}</p>
|
|
80
|
+
</div>
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
The `defaultValue` at the root acts as the initializer — subsequent `.useState()` calls in children pick up the shared value automatically without re-specifying defaults.
|
|
86
|
+
|
|
54
87
|
**Dot-notation access with full TypeScript inference.** The state tree is navigated like a plain object — autocomplete guides you to the right node, and types flow from `defineState<T>` all the way to the hook return value without any manual annotations.
|
|
55
|
-
|
|
88
|
+
|
|
56
89
|
```ts
|
|
57
90
|
const [theme, setTheme] = storage.preference.theme.useState()
|
|
58
91
|
// ^? 'Dark' | 'White' | 'System'
|
|
59
|
-
|
|
92
|
+
|
|
60
93
|
const [birthday, setBirthday] = storage.personal.birthday.useState()
|
|
61
94
|
// ^? Date | null
|
|
62
95
|
```
|
|
63
|
-
|
|
96
|
+
|
|
64
97
|
If you rename or restructure a node in `setupStorage`, TypeScript immediately flags every broken reference across the codebase.
|
|
65
|
-
|
|
98
|
+
|
|
66
99
|
**Custom serialization per node.** Dates, Maps, class instances — define `serialize`/`deserialize` once and the hook handles the rest transparently.
|
|
67
|
-
|
|
100
|
+
|
|
68
101
|
```ts
|
|
69
102
|
defineState({
|
|
70
103
|
storage: localStorage,
|
|
71
104
|
deserialize: (raw) => new Date(JSON.parse(raw)),
|
|
72
105
|
})
|
|
73
106
|
```
|
|
74
|
-
|
|
107
|
+
|
|
75
108
|
**Minimal API surface.** Three exports: `defineState`, `setupStorage`, `StorageProvider`. No actions, reducers, selectors, or stores to configure.
|
|
76
109
|
|
|
77
110
|
## Installation
|
|
@@ -85,15 +118,17 @@ npm install @yakocloud/state-vocab react react-dom
|
|
|
85
118
|
## Quick Start
|
|
86
119
|
|
|
87
120
|
```tsx
|
|
88
|
-
import { setupStorage, defineState, StorageProvider } from 'state-vocab'
|
|
121
|
+
import { setupStorage, defineState, StorageProvider } from '@yakocloud/state-vocab'
|
|
122
|
+
|
|
123
|
+
type Theme = 'Dark' | 'White' | 'System'
|
|
89
124
|
|
|
90
125
|
const storage = setupStorage({
|
|
91
126
|
path: {
|
|
92
127
|
to: {
|
|
93
|
-
theme: defineState<
|
|
128
|
+
theme: defineState<Theme>({
|
|
94
129
|
storage: localStorage,
|
|
95
130
|
defaultValue: 'Dark',
|
|
96
|
-
})
|
|
131
|
+
}),
|
|
97
132
|
},
|
|
98
133
|
},
|
|
99
134
|
})
|
|
@@ -110,7 +145,7 @@ function Settings() {
|
|
|
110
145
|
const [theme, setTheme] = storage.path.to.theme.useState()
|
|
111
146
|
|
|
112
147
|
return (
|
|
113
|
-
<select value={theme} onChange={(e) => setTheme(e.target.value)}>
|
|
148
|
+
<select value={theme} onChange={(e) => setTheme(e.target.value as Theme)}>
|
|
114
149
|
<option value="Dark">Dark</option>
|
|
115
150
|
<option value="White">White</option>
|
|
116
151
|
<option value="System">System</option>
|
|
@@ -128,7 +163,8 @@ Defines a state node. Options:
|
|
|
128
163
|
| Option | Type | Description |
|
|
129
164
|
|---|---|---|
|
|
130
165
|
| `storage` | `Storage \| (() => Storage) \| undefined` | Where to persist the value. Omit for in-memory only. |
|
|
131
|
-
| `defaultValue` | `T` | Value used when storage has no entry. |
|
|
166
|
+
| `defaultValue` | `T \| (() => T)` | Value used when storage has no entry. Accepts a factory function. |
|
|
167
|
+
| `bidirectional` | `true \| undefined` | Sync state across browser tabs via the `storage` event. |
|
|
132
168
|
| `serialize` | `(v: T) => string` | Custom serializer. Default: `JSON.stringify`. |
|
|
133
169
|
| `deserialize` | `(v: string) => T` | Custom deserializer. Default: `JSON.parse`. |
|
|
134
170
|
|
|
@@ -142,20 +178,26 @@ const theme = defineState<'Dark' | 'White'>({
|
|
|
142
178
|
defaultValue: 'Dark',
|
|
143
179
|
})
|
|
144
180
|
|
|
145
|
-
// localStorage with custom
|
|
181
|
+
// localStorage with custom deserialization
|
|
146
182
|
const birthday = defineState({
|
|
147
183
|
storage: () => localStorage,
|
|
148
184
|
deserialize: (raw) => new Date(JSON.parse(raw)),
|
|
149
185
|
})
|
|
186
|
+
|
|
187
|
+
// bidirectional — syncs value when changed in another tab
|
|
188
|
+
const note = defineState({
|
|
189
|
+
storage: localStorage,
|
|
190
|
+
bidirectional: true,
|
|
191
|
+
})
|
|
150
192
|
```
|
|
151
193
|
|
|
152
|
-
### `setupStorage(tree, options)`
|
|
194
|
+
### `setupStorage(tree, options?)`
|
|
153
195
|
|
|
154
196
|
Wraps a nested object of `defineState()` nodes and injects dot-separated paths into each leaf. The returned object mirrors your tree structure.
|
|
155
197
|
|
|
156
|
-
|
|
|
157
|
-
|
|
158
|
-
| `ssr` | `boolean \| undefined` | SSR support | false
|
|
198
|
+
| Option | Type | Description | Default |
|
|
199
|
+
|---|---|---|---|
|
|
200
|
+
| `ssr` | `boolean \| undefined` | Defer storage reads until after mount (SSR support) | `false` |
|
|
159
201
|
|
|
160
202
|
```ts
|
|
161
203
|
const storage = setupStorage({
|
|
@@ -165,14 +207,13 @@ const storage = setupStorage({
|
|
|
165
207
|
},
|
|
166
208
|
})
|
|
167
209
|
|
|
168
|
-
// Access paths:
|
|
169
210
|
storage.user.name // → path: "user.name"
|
|
170
211
|
storage.user.age // → path: "user.age"
|
|
171
212
|
```
|
|
172
213
|
|
|
173
214
|
### `StorageProvider`
|
|
174
215
|
|
|
175
|
-
A React context provider that must wrap all components using
|
|
216
|
+
A React context provider that must wrap all components using `.useState()` from any state node. Place it once near the top of your tree.
|
|
176
217
|
|
|
177
218
|
```tsx
|
|
178
219
|
createRoot(document.getElementById('root')!).render(
|
|
@@ -182,44 +223,55 @@ createRoot(document.getElementById('root')!).render(
|
|
|
182
223
|
)
|
|
183
224
|
```
|
|
184
225
|
|
|
226
|
+
Accepts an optional `verbose` prop that logs the current state vocab to the browser console on every change — useful during development.
|
|
227
|
+
|
|
228
|
+
```tsx
|
|
229
|
+
<StorageProvider verbose>
|
|
230
|
+
<App />
|
|
231
|
+
</StorageProvider>
|
|
232
|
+
```
|
|
233
|
+
|
|
185
234
|
## `useState` Hook
|
|
186
235
|
|
|
187
236
|
Each state node exposes a `.useState()` method that works like React's built-in `useState` but adds persistence and callbacks.
|
|
188
237
|
|
|
189
238
|
```ts
|
|
190
|
-
const [value, setValue, resetValue] = storage.path.to.node.useState(
|
|
191
|
-
defaultValue?,
|
|
192
|
-
options?
|
|
193
|
-
)
|
|
239
|
+
const [value, setValue, resetValue] = storage.path.to.node.useState(options?)
|
|
194
240
|
```
|
|
195
241
|
|
|
196
|
-
###
|
|
242
|
+
### Options
|
|
197
243
|
|
|
198
|
-
**`defaultValue`** — overrides the `defineState`-level default for this usage. Accepts a value or
|
|
244
|
+
**`defaultValue`** — overrides the `defineState`-level default for this usage. Accepts a value or factory function:
|
|
199
245
|
|
|
200
246
|
```ts
|
|
201
|
-
const [alarm] = storage.alarm.useState(() => new Date())
|
|
247
|
+
const [alarm] = storage.alarm.useState({ defaultValue: () => new Date() })
|
|
202
248
|
```
|
|
203
249
|
|
|
204
|
-
**`
|
|
250
|
+
**`delayedSet`** — debounces the `onSet` callback by N milliseconds:
|
|
205
251
|
|
|
206
252
|
```ts
|
|
207
|
-
const [note, setNote] = storage.note.useState(
|
|
253
|
+
const [note, setNote] = storage.note.useState({
|
|
208
254
|
delayedSet: 1000,
|
|
209
255
|
onSet: (value) => saveToServer(value),
|
|
210
256
|
})
|
|
211
257
|
```
|
|
212
258
|
|
|
213
|
-
**`
|
|
259
|
+
**`onSet`** — called after every state change with `(nextValue, prevValue)`:
|
|
214
260
|
|
|
215
261
|
```ts
|
|
216
|
-
const [counter, setCounter] = storage.counter.useState(
|
|
262
|
+
const [counter, setCounter] = storage.counter.useState({
|
|
217
263
|
onSet(next, prev) {
|
|
218
264
|
console.log(`Changed from ${prev} to ${next}`)
|
|
219
265
|
},
|
|
220
266
|
})
|
|
221
267
|
```
|
|
222
268
|
|
|
269
|
+
**`bidirectional`** — enables cross-tab sync via the `storage` event. Can be set here or in `defineState`:
|
|
270
|
+
|
|
271
|
+
```ts
|
|
272
|
+
const [note, setNote] = storage.note.useState({ bidirectional: true })
|
|
273
|
+
```
|
|
274
|
+
|
|
223
275
|
### Return value
|
|
224
276
|
|
|
225
277
|
```ts
|
|
@@ -228,44 +280,49 @@ const [value, setValue, resetValue] = storage.node.useState()
|
|
|
228
280
|
|
|
229
281
|
- **`value`** — current state
|
|
230
282
|
- **`setValue(nextValue | updater)`** — set state; accepts a value or `(prev) => next` function
|
|
231
|
-
- **`resetValue()`** — restores the default value
|
|
283
|
+
- **`resetValue()`** — restores the default value (removes the storage entry if no default is defined)
|
|
232
284
|
|
|
233
285
|
## Custom Storage
|
|
234
286
|
|
|
235
|
-
Any object implementing the [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Storage) works as a backend:
|
|
287
|
+
Any object implementing the [Web Storage API](https://developer.mozilla.org/en-US/docs/Web/API/Storage) works as a backend. This makes it easy to add debouncing, encryption, or remote persistence:
|
|
236
288
|
|
|
237
289
|
```ts
|
|
290
|
+
const db: Record<string, string> = {}
|
|
291
|
+
|
|
238
292
|
const storage = setupStorage({
|
|
239
|
-
server:
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
293
|
+
server: {
|
|
294
|
+
data: defineState({
|
|
295
|
+
defaultValue: '',
|
|
296
|
+
storage: {
|
|
297
|
+
length: 0,
|
|
298
|
+
getItem: (key) => db[key] ?? null,
|
|
299
|
+
setItem: (key, value) => debouncedSave(key, value),
|
|
300
|
+
removeItem: (key) => { delete db[key] },
|
|
301
|
+
clear: () => {},
|
|
302
|
+
key: () => null,
|
|
303
|
+
},
|
|
304
|
+
}),
|
|
305
|
+
},
|
|
249
306
|
})
|
|
250
307
|
```
|
|
251
308
|
|
|
252
309
|
## Full Example
|
|
253
310
|
|
|
254
311
|
```tsx
|
|
255
|
-
import { setupStorage, defineState, StorageProvider } from 'state-vocab'
|
|
312
|
+
import { setupStorage, defineState, StorageProvider } from '@yakocloud/state-vocab'
|
|
256
313
|
|
|
257
314
|
type Theme = 'Dark' | 'White' | 'System'
|
|
258
315
|
|
|
259
316
|
const storage = setupStorage({
|
|
260
317
|
preference: {
|
|
261
318
|
theme: defineState<Theme>({ storage: localStorage, defaultValue: 'Dark' }),
|
|
262
|
-
nightMode: defineState({ storage: sessionStorage }),
|
|
319
|
+
nightMode: defineState({ storage: sessionStorage, defaultValue: false }),
|
|
263
320
|
},
|
|
264
321
|
stats: {
|
|
265
|
-
counter: defineState({ defaultValue: 0 }),
|
|
322
|
+
counter: defineState({ defaultValue: 0, storage: sessionStorage }),
|
|
266
323
|
},
|
|
267
324
|
personal: {
|
|
268
|
-
note: defineState({ storage: localStorage }),
|
|
325
|
+
note: defineState({ storage: localStorage, defaultValue: '' }),
|
|
269
326
|
birthday: defineState({
|
|
270
327
|
storage: localStorage,
|
|
271
328
|
deserialize: (raw) => {
|
|
@@ -273,20 +330,41 @@ const storage = setupStorage({
|
|
|
273
330
|
},
|
|
274
331
|
}),
|
|
275
332
|
},
|
|
333
|
+
demo: {
|
|
334
|
+
pageProps: defineState<{ title: string; count: number }>({
|
|
335
|
+
storage: localStorage,
|
|
336
|
+
}),
|
|
337
|
+
},
|
|
276
338
|
})
|
|
277
339
|
|
|
340
|
+
// Root — initializes shared state for the whole subtree
|
|
341
|
+
function Page() {
|
|
342
|
+
storage.demo.pageProps.useState({
|
|
343
|
+
defaultValue: { title: 'Hello', count: 42 },
|
|
344
|
+
})
|
|
345
|
+
|
|
346
|
+
return <Dashboard />
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Deep child — reads without re-specifying defaults
|
|
350
|
+
function PageHeader() {
|
|
351
|
+
const [pageProps] = storage.demo.pageProps.useState()
|
|
352
|
+
return <h1>{pageProps.title} ({pageProps.count})</h1>
|
|
353
|
+
}
|
|
354
|
+
|
|
278
355
|
function Dashboard() {
|
|
279
356
|
const [theme, setTheme] = storage.preference.theme.useState()
|
|
280
|
-
const [nightMode, setNightMode] = storage.preference.nightMode.useState(
|
|
281
|
-
const [counter, setCounter, resetCounter] = storage.stats.counter.useState(
|
|
282
|
-
const [note, setNote] = storage.personal.note.useState(
|
|
357
|
+
const [nightMode, setNightMode] = storage.preference.nightMode.useState()
|
|
358
|
+
const [counter, setCounter, resetCounter] = storage.stats.counter.useState()
|
|
359
|
+
const [note, setNote] = storage.personal.note.useState({
|
|
283
360
|
delayedSet: 500,
|
|
284
|
-
bidirectional: true,
|
|
285
361
|
onSet: (v) => console.log('Saving note:', v),
|
|
286
362
|
})
|
|
287
363
|
|
|
288
364
|
return (
|
|
289
365
|
<div>
|
|
366
|
+
<PageHeader />
|
|
367
|
+
|
|
290
368
|
<select value={theme ?? ''} onChange={(e) => setTheme(e.target.value as Theme)}>
|
|
291
369
|
<option value="Dark">Dark</option>
|
|
292
370
|
<option value="White">White</option>
|
|
@@ -317,7 +395,7 @@ function Dashboard() {
|
|
|
317
395
|
|
|
318
396
|
createRoot(document.getElementById('root')!).render(
|
|
319
397
|
<StorageProvider>
|
|
320
|
-
<
|
|
398
|
+
<Page />
|
|
321
399
|
</StorageProvider>
|
|
322
400
|
)
|
|
323
401
|
```
|
|
@@ -329,12 +407,16 @@ createRoot(document.getElementById('root')!).render(
|
|
|
329
407
|
| Option | Type | Default |
|
|
330
408
|
|---|---|---|
|
|
331
409
|
| `storage` | `Storage \| (() => Storage) \| undefined` | `undefined` (in-memory) |
|
|
332
|
-
| `defaultValue` | `T \| undefined` | `undefined` |
|
|
410
|
+
| `defaultValue` | `T \| (() => T) \| undefined` | `undefined` |
|
|
333
411
|
| `bidirectional` | `true \| undefined` | `undefined` |
|
|
334
412
|
| `serialize` | `(v: T) => string` | `JSON.stringify` |
|
|
335
413
|
| `deserialize` | `(v: string) => T` | `JSON.parse` |
|
|
336
414
|
|
|
337
|
-
### `setupStorage<T>(tree: T): T`
|
|
415
|
+
### `setupStorage<T>(tree: T, options?): T`
|
|
416
|
+
|
|
417
|
+
| Option | Type | Default |
|
|
418
|
+
|---|---|---|
|
|
419
|
+
| `ssr` | `boolean \| undefined` | `false` |
|
|
338
420
|
|
|
339
421
|
Returns a proxied copy of `tree` with paths injected into all leaf nodes.
|
|
340
422
|
|
|
@@ -342,13 +424,17 @@ Returns a proxied copy of `tree` with paths injected into all leaf nodes.
|
|
|
342
424
|
|
|
343
425
|
React context provider. Must be an ancestor of any component using `.useState()`.
|
|
344
426
|
|
|
345
|
-
|
|
427
|
+
| Prop | Type | Description |
|
|
428
|
+
|---|---|---|
|
|
429
|
+
| `verbose` | `boolean \| undefined` | Log state vocab to console on every change |
|
|
430
|
+
|
|
431
|
+
### `node.useState(options?)`
|
|
346
432
|
|
|
347
|
-
|
|
|
433
|
+
| Option | Type | Description |
|
|
348
434
|
|---|---|---|
|
|
349
|
-
| `defaultValue` | `
|
|
350
|
-
| `
|
|
351
|
-
| `
|
|
352
|
-
| `
|
|
435
|
+
| `defaultValue` | `T \| (() => T) \| undefined` | Local default, overrides `defineState` default |
|
|
436
|
+
| `delayedSet` | `number \| undefined` | Debounce delay for `onSet` in ms |
|
|
437
|
+
| `onSet` | `(next: T, prev: T) => void \| undefined` | Callback after state change |
|
|
438
|
+
| `bidirectional` | `true \| undefined` | Sync state across browser tabs |
|
|
353
439
|
|
|
354
440
|
Returns `[value, setValue, resetValue]`.
|
package/dist/state-vocab.cjs.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
2
|
-
`),r=[],
|
|
3
|
-
`),...
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("react"),re=Symbol("state-def"),$=Symbol("state-path"),W=Symbol("state-ssr");function ie(t,s,r){if(!s)return t;const a=s.split(".");let n=t;for(const c of a)if(n!==null&&typeof n=="object"&&c in n)n=n[c];else return r;return n===void 0?r:n}function fe(t,s,r){const a=s.replace(/\[(\d+)\]/g,".$1").split(".");let n=t;for(let c=0;c<a.length-1;c++){const m=a[c],v=a[c+1];(n[m]===void 0||n[m]===null)&&(n[m]=/^\d+$/.test(v)?[]:{}),n=n[m]}return n[a[a.length-1]]=r,t}function de(t,s=0){let r;return function(...a){r!==void 0&&clearTimeout(r),r=setTimeout(()=>{r=void 0,t.apply(this,a)},s)}}function me(t,s,r=[]){return p.useMemo(()=>de(t,s),r)}function be(t){const s=JSON.stringify(t,null,2).split(`
|
|
2
|
+
`),r=[],a=[];for(const n of s){const c=n.match(/^(\s*)"([^"]+)"(\s*:\s*)(.+)$/);if(c){const[,m,v,S,l]=c;r.push(`${m}%c"${v}"%c${S}%c${l}`),a.push("color: #9cdcfe; font-weight: bold","color: #cccccc","color: #ce9178")}else r.push(`%c${n}`),a.push("color: #cccccc")}console.log(r.join(`
|
|
3
|
+
`),...a,t)}var V={exports:{}},x={};var Z;function ve(){if(Z)return x;Z=1;var t=Symbol.for("react.transitional.element"),s=Symbol.for("react.fragment");function r(a,n,c){var m=null;if(c!==void 0&&(m=""+c),n.key!==void 0&&(m=""+n.key),"key"in n){c={};for(var v in n)v!=="key"&&(c[v]=n[v])}else c=n;return n=c.ref,{$$typeof:t,type:a,key:m,ref:n!==void 0?n:null,props:c}}return x.Fragment=s,x.jsx=r,x.jsxs=r,x}var O={};var Q;function Ee(){return Q||(Q=1,process.env.NODE_ENV!=="production"&&(function(){function t(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===ce?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case E:return"Fragment";case A:return"Profiler";case k:return"StrictMode";case J:return"Suspense";case w:return"SuspenseList";case se:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case g:return"Portal";case h:return e.displayName||"Context";case b:return(e._context.displayName||"Context")+".Consumer";case j:var o=e.render;return e=e.displayName,e||(e=o.displayName||o.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case ae:return o=e.displayName||null,o!==null?o:t(e.type)||"Memo";case I:o=e._payload,e=e._init;try{return t(e(o))}catch{}}return null}function s(e){return""+e}function r(e){try{s(e);var o=!1}catch{o=!0}if(o){o=console;var u=o.error,f=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return u.call(o,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",f),s(e)}}function a(e){if(e===E)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===I)return"<...>";try{var o=t(e);return o?"<"+o+">":"<...>"}catch{return"<...>"}}function n(){var e=M.A;return e===null?null:e.getOwner()}function c(){return Error("react-stack-top-frame")}function m(e){if(U.call(e,"key")){var o=Object.getOwnPropertyDescriptor(e,"key").get;if(o&&o.isReactWarning)return!1}return e.key!==void 0}function v(e,o){function u(){q||(q=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",o))}u.isReactWarning=!0,Object.defineProperty(e,"key",{get:u,configurable:!0})}function S(){var e=t(this.type);return G[e]||(G[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function l(e,o,u,f,N,D){var d=u.ref;return e={$$typeof:y,type:e,key:o,props:u,_owner:f},(d!==void 0?d:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:S}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:N}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:D}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function i(e,o,u,f,N,D){var d=o.children;if(d!==void 0)if(f)if(ue(d)){for(f=0;f<d.length;f++)_(d[f]);Object.freeze&&Object.freeze(d)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else _(d);if(U.call(o,"key")){d=t(e);var P=Object.keys(o).filter(function(le){return le!=="key"});f=0<P.length?"{key: someKey, "+P.join(": ..., ")+": ...}":"{key: someKey}",H[d+f]||(P=0<P.length?"{"+P.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
|
|
4
4
|
let props = %s;
|
|
5
5
|
<%s {...props} />
|
|
6
6
|
React keys must be passed directly to JSX without using spread:
|
|
7
7
|
let props = %s;
|
|
8
|
-
<%s key={someKey} {...props} />`,
|
|
8
|
+
<%s key={someKey} {...props} />`,f,d,P,d),H[d+f]=!0)}if(d=null,u!==void 0&&(r(u),d=""+u),m(o)&&(r(o.key),d=""+o.key),"key"in o){u={};for(var F in o)F!=="key"&&(u[F]=o[F])}else u=o;return d&&v(u,typeof e=="function"?e.displayName||e.name||"Unknown":e),l(e,d,u,n(),N,D)}function _(e){R(e)?e._store&&(e._store.validated=1):typeof e=="object"&&e!==null&&e.$$typeof===I&&(e._payload.status==="fulfilled"?R(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function R(e){return typeof e=="object"&&e!==null&&e.$$typeof===y}var T=p,y=Symbol.for("react.transitional.element"),g=Symbol.for("react.portal"),E=Symbol.for("react.fragment"),k=Symbol.for("react.strict_mode"),A=Symbol.for("react.profiler"),b=Symbol.for("react.consumer"),h=Symbol.for("react.context"),j=Symbol.for("react.forward_ref"),J=Symbol.for("react.suspense"),w=Symbol.for("react.suspense_list"),ae=Symbol.for("react.memo"),I=Symbol.for("react.lazy"),se=Symbol.for("react.activity"),ce=Symbol.for("react.client.reference"),M=T.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,U=Object.prototype.hasOwnProperty,ue=Array.isArray,Y=console.createTask?console.createTask:function(){return null};T={react_stack_bottom_frame:function(e){return e()}};var q,G={},X=T.react_stack_bottom_frame.bind(T,c)(),B=Y(a(c)),H={};O.Fragment=E,O.jsx=function(e,o,u){var f=1e4>M.recentlyCreatedOwnerStacks++;return i(e,o,u,!1,f?Error("react-stack-top-frame"):X,f?Y(a(e)):B)},O.jsxs=function(e,o,u){var f=1e4>M.recentlyCreatedOwnerStacks++;return i(e,o,u,!0,f?Error("react-stack-top-frame"):X,f?Y(a(e)):B)}})()),O}var K;function _e(){return K||(K=1,process.env.NODE_ENV==="production"?V.exports=ve():V.exports=Ee()),V.exports}var pe=_e();const ne=p.createContext({stateVocab:{},setStateVocab:()=>{}});function Se(){return p.useContext(ne)}const Re=t=>{const{children:s,verbose:r}=t,[a,n]=p.useState({});return r&&be(a),pe.jsx(ne.Provider,{value:{stateVocab:a,setStateVocab:n},children:s})},C=(t,s)=>r=>{const a={...r};return fe(a,t,s),a},Te=t=>typeof t=="function",ye=t=>typeof t=="function",z=t=>typeof t<"u",L=t=>ye(t)?t():t,ge=typeof window>"u";function he(t={}){return{[re]:!0,[W]:!1,[$]:"",useState(s){const r=ge?void 0:L(t.storage),a=t.serialize??JSON.stringify,n=t.deserialize??JSON.parse,c=L(t.defaultValue),m=t.bidirectional;s??={};const v=L(s.defaultValue),S=me(s.onSet??(()=>{}),s.delayedSet,[]),l=Se(),i=this[$],_=this[W],[R,T]=p.useState(!_);p.useEffect(()=>T(!0),[]);const y=p.useMemo(()=>{if(!R||!r)return;const b=r.getItem(i);return b===null?null:n(b)},[R]),g=p.useMemo(()=>ie(l.stateVocab,i,y??v??c),[l.stateVocab,y]),E=p.useRef(g);return p.useEffect(()=>{z(g)&&(l.setStateVocab(C(i,g)),r&&y===null&&r.setItem(i,a(g)))},[y]),p.useEffect(()=>{if(!s.bidirectional&&!m)return;const b=h=>{if(h.key!==i)return;const j=h.newValue,w=(j===null?null:n(j))??v??c;z(w)&&(l.setStateVocab(C(i,w)),S(w,E.current),E.current=w)};return window.addEventListener("storage",b),()=>window.removeEventListener("storage",b)},[s.bidirectional,m]),[g,b=>{const h=Te(b)?b(E.current):b;l.setStateVocab(C(i,h)),S(h,E.current),r&&r.setItem(i,a(h)),E.current=h},()=>{const b=v??c;if(!z(b)){r?.removeItem(i);return}l.setStateVocab(C(i,b)),S(b,E.current),E.current=b,r&&r.setItem(i,a(b))}]},toString(){return this[$]}}}const ee=new WeakMap,te=new WeakMap;function oe(t,s){s??={};const{path:r="",ssr:a}=s;let n=ee.get(t);n||(n=new Map,ee.set(t,n));const c=n.get(r);if(c)return c;const m=new Proxy(t,{get(v,S){const l=v[S],i=r?`${r}.${String(S)}`:String(S);if(l&&typeof l=="object"&&re in l){const _=l;let R=te.get(_);R||(R=new Map,te.set(_,R));const T=R.get(i);if(T)return T;const y=Reflect.ownKeys(_).filter(k=>typeof _[k]=="function"),g=Object.fromEntries(y.map(k=>[k,(...A)=>_[k].call({..._,[$]:i,[W]:a},...A)])),E={..._,...g};return R.set(i,E),E}return l&&typeof l=="object"?oe(l,{path:i,ssr:a}):l}});return n.set(r,m),m}function ke(t,s){return oe(t,s)}exports.StorageProvider=Re;exports.defineState=he;exports.setupStorage=ke;
|
package/dist/state-vocab.es.js
CHANGED
|
@@ -1,119 +1,119 @@
|
|
|
1
|
-
import
|
|
2
|
-
const
|
|
3
|
-
function
|
|
4
|
-
if (!
|
|
1
|
+
import de, { useMemo as W, createContext as me, useState as ne, useContext as be, useEffect as M, useRef as ve } from "react";
|
|
2
|
+
const oe = Symbol("state-def"), C = Symbol("state-path"), J = Symbol("state-ssr");
|
|
3
|
+
function Ee(t, s, r) {
|
|
4
|
+
if (!s)
|
|
5
5
|
return t;
|
|
6
|
-
const
|
|
6
|
+
const a = s.split(".");
|
|
7
7
|
let n = t;
|
|
8
|
-
for (const c of
|
|
8
|
+
for (const c of a)
|
|
9
9
|
if (n !== null && typeof n == "object" && c in n)
|
|
10
10
|
n = n[c];
|
|
11
11
|
else
|
|
12
12
|
return r;
|
|
13
13
|
return n === void 0 ? r : n;
|
|
14
14
|
}
|
|
15
|
-
function
|
|
16
|
-
const
|
|
15
|
+
function _e(t, s, r) {
|
|
16
|
+
const a = s.replace(/\[(\d+)\]/g, ".$1").split(".");
|
|
17
17
|
let n = t;
|
|
18
|
-
for (let c = 0; c <
|
|
19
|
-
const
|
|
20
|
-
(n[
|
|
18
|
+
for (let c = 0; c < a.length - 1; c++) {
|
|
19
|
+
const m = a[c], v = a[c + 1];
|
|
20
|
+
(n[m] === void 0 || n[m] === null) && (n[m] = /^\d+$/.test(v) ? [] : {}), n = n[m];
|
|
21
21
|
}
|
|
22
|
-
return n[
|
|
22
|
+
return n[a[a.length - 1]] = r, t;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function pe(t, s = 0) {
|
|
25
25
|
let r;
|
|
26
|
-
return function(...
|
|
26
|
+
return function(...a) {
|
|
27
27
|
r !== void 0 && clearTimeout(r), r = setTimeout(() => {
|
|
28
|
-
r = void 0, t.apply(this,
|
|
29
|
-
},
|
|
28
|
+
r = void 0, t.apply(this, a);
|
|
29
|
+
}, s);
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
-
function
|
|
33
|
-
return
|
|
34
|
-
() =>
|
|
32
|
+
function Se(t, s, r = []) {
|
|
33
|
+
return W(
|
|
34
|
+
() => pe(t, s),
|
|
35
35
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
36
|
r
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
|
-
function
|
|
40
|
-
const
|
|
41
|
-
`), r = [],
|
|
42
|
-
for (const n of
|
|
39
|
+
function Re(t) {
|
|
40
|
+
const s = JSON.stringify(t, null, 2).split(`
|
|
41
|
+
`), r = [], a = [];
|
|
42
|
+
for (const n of s) {
|
|
43
43
|
const c = n.match(/^(\s*)"([^"]+)"(\s*:\s*)(.+)$/);
|
|
44
44
|
if (c) {
|
|
45
|
-
const [,
|
|
46
|
-
r.push(`${
|
|
45
|
+
const [, m, v, p, l] = c;
|
|
46
|
+
r.push(`${m}%c"${v}"%c${p}%c${l}`), a.push(
|
|
47
47
|
"color: #9cdcfe; font-weight: bold",
|
|
48
48
|
"color: #cccccc",
|
|
49
49
|
"color: #ce9178"
|
|
50
50
|
);
|
|
51
51
|
} else
|
|
52
|
-
r.push(`%c${n}`),
|
|
52
|
+
r.push(`%c${n}`), a.push("color: #cccccc");
|
|
53
53
|
}
|
|
54
54
|
console.log(r.join(`
|
|
55
|
-
`), ...
|
|
55
|
+
`), ...a, t);
|
|
56
56
|
}
|
|
57
|
-
var
|
|
58
|
-
var
|
|
59
|
-
function
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
var t = Symbol.for("react.transitional.element"),
|
|
63
|
-
function r(
|
|
64
|
-
var
|
|
65
|
-
if (c !== void 0 && (
|
|
57
|
+
var N = { exports: {} }, P = {};
|
|
58
|
+
var Q;
|
|
59
|
+
function Te() {
|
|
60
|
+
if (Q) return P;
|
|
61
|
+
Q = 1;
|
|
62
|
+
var t = Symbol.for("react.transitional.element"), s = Symbol.for("react.fragment");
|
|
63
|
+
function r(a, n, c) {
|
|
64
|
+
var m = null;
|
|
65
|
+
if (c !== void 0 && (m = "" + c), n.key !== void 0 && (m = "" + n.key), "key" in n) {
|
|
66
66
|
c = {};
|
|
67
|
-
for (var
|
|
68
|
-
|
|
67
|
+
for (var v in n)
|
|
68
|
+
v !== "key" && (c[v] = n[v]);
|
|
69
69
|
} else c = n;
|
|
70
70
|
return n = c.ref, {
|
|
71
71
|
$$typeof: t,
|
|
72
|
-
type:
|
|
73
|
-
key:
|
|
72
|
+
type: a,
|
|
73
|
+
key: m,
|
|
74
74
|
ref: n !== void 0 ? n : null,
|
|
75
75
|
props: c
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
-
return P.Fragment =
|
|
78
|
+
return P.Fragment = s, P.jsx = r, P.jsxs = r, P;
|
|
79
79
|
}
|
|
80
80
|
var x = {};
|
|
81
|
-
var
|
|
82
|
-
function
|
|
83
|
-
return
|
|
81
|
+
var K;
|
|
82
|
+
function ye() {
|
|
83
|
+
return K || (K = 1, process.env.NODE_ENV !== "production" && (function() {
|
|
84
84
|
function t(e) {
|
|
85
85
|
if (e == null) return null;
|
|
86
86
|
if (typeof e == "function")
|
|
87
|
-
return e.$$typeof ===
|
|
87
|
+
return e.$$typeof === le ? null : e.displayName || e.name || null;
|
|
88
88
|
if (typeof e == "string") return e;
|
|
89
89
|
switch (e) {
|
|
90
|
-
case
|
|
90
|
+
case E:
|
|
91
91
|
return "Fragment";
|
|
92
|
-
case
|
|
92
|
+
case A:
|
|
93
93
|
return "Profiler";
|
|
94
94
|
case g:
|
|
95
95
|
return "StrictMode";
|
|
96
|
-
case
|
|
96
|
+
case U:
|
|
97
97
|
return "Suspense";
|
|
98
|
-
case
|
|
98
|
+
case k:
|
|
99
99
|
return "SuspenseList";
|
|
100
|
-
case
|
|
100
|
+
case ue:
|
|
101
101
|
return "Activity";
|
|
102
102
|
}
|
|
103
103
|
if (typeof e == "object")
|
|
104
104
|
switch (typeof e.tag == "number" && console.error(
|
|
105
105
|
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
106
106
|
), e.$$typeof) {
|
|
107
|
-
case
|
|
107
|
+
case y:
|
|
108
108
|
return "Portal";
|
|
109
|
-
case
|
|
109
|
+
case h:
|
|
110
110
|
return e.displayName || "Context";
|
|
111
|
-
case
|
|
111
|
+
case b:
|
|
112
112
|
return (e._context.displayName || "Context") + ".Consumer";
|
|
113
|
-
case
|
|
113
|
+
case O:
|
|
114
114
|
var o = e.render;
|
|
115
115
|
return e = e.displayName, e || (e = o.displayName || o.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e;
|
|
116
|
-
case
|
|
116
|
+
case ce:
|
|
117
117
|
return o = e.displayName || null, o !== null ? o : t(e.type) || "Memo";
|
|
118
118
|
case $:
|
|
119
119
|
o = e._payload, e = e._init;
|
|
@@ -124,28 +124,28 @@ function he() {
|
|
|
124
124
|
}
|
|
125
125
|
return null;
|
|
126
126
|
}
|
|
127
|
-
function
|
|
127
|
+
function s(e) {
|
|
128
128
|
return "" + e;
|
|
129
129
|
}
|
|
130
130
|
function r(e) {
|
|
131
131
|
try {
|
|
132
|
-
|
|
132
|
+
s(e);
|
|
133
133
|
var o = !1;
|
|
134
134
|
} catch {
|
|
135
135
|
o = !0;
|
|
136
136
|
}
|
|
137
137
|
if (o) {
|
|
138
138
|
o = console;
|
|
139
|
-
var
|
|
140
|
-
return
|
|
139
|
+
var u = o.error, f = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object";
|
|
140
|
+
return u.call(
|
|
141
141
|
o,
|
|
142
142
|
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
|
|
143
|
-
|
|
144
|
-
),
|
|
143
|
+
f
|
|
144
|
+
), s(e);
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
|
-
function
|
|
148
|
-
if (e ===
|
|
147
|
+
function a(e) {
|
|
148
|
+
if (e === E) return "<>";
|
|
149
149
|
if (typeof e == "object" && e !== null && e.$$typeof === $)
|
|
150
150
|
return "<...>";
|
|
151
151
|
try {
|
|
@@ -162,42 +162,42 @@ function he() {
|
|
|
162
162
|
function c() {
|
|
163
163
|
return Error("react-stack-top-frame");
|
|
164
164
|
}
|
|
165
|
-
function
|
|
166
|
-
if (
|
|
165
|
+
function m(e) {
|
|
166
|
+
if (q.call(e, "key")) {
|
|
167
167
|
var o = Object.getOwnPropertyDescriptor(e, "key").get;
|
|
168
168
|
if (o && o.isReactWarning) return !1;
|
|
169
169
|
}
|
|
170
170
|
return e.key !== void 0;
|
|
171
171
|
}
|
|
172
|
-
function
|
|
173
|
-
function
|
|
174
|
-
|
|
172
|
+
function v(e, o) {
|
|
173
|
+
function u() {
|
|
174
|
+
G || (G = !0, console.error(
|
|
175
175
|
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
|
|
176
176
|
o
|
|
177
177
|
));
|
|
178
178
|
}
|
|
179
|
-
|
|
180
|
-
get:
|
|
179
|
+
u.isReactWarning = !0, Object.defineProperty(e, "key", {
|
|
180
|
+
get: u,
|
|
181
181
|
configurable: !0
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
|
-
function
|
|
184
|
+
function p() {
|
|
185
185
|
var e = t(this.type);
|
|
186
|
-
return
|
|
186
|
+
return X[e] || (X[e] = !0, console.error(
|
|
187
187
|
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
|
|
188
188
|
)), e = this.props.ref, e !== void 0 ? e : null;
|
|
189
189
|
}
|
|
190
|
-
function
|
|
191
|
-
var
|
|
190
|
+
function l(e, o, u, f, j, D) {
|
|
191
|
+
var d = u.ref;
|
|
192
192
|
return e = {
|
|
193
|
-
$$typeof:
|
|
193
|
+
$$typeof: T,
|
|
194
194
|
type: e,
|
|
195
195
|
key: o,
|
|
196
|
-
props:
|
|
197
|
-
_owner:
|
|
198
|
-
}, (
|
|
196
|
+
props: u,
|
|
197
|
+
_owner: f
|
|
198
|
+
}, (d !== void 0 ? d : null) !== null ? Object.defineProperty(e, "ref", {
|
|
199
199
|
enumerable: !1,
|
|
200
|
-
get:
|
|
200
|
+
get: p
|
|
201
201
|
}) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", {
|
|
202
202
|
configurable: !1,
|
|
203
203
|
enumerable: !1,
|
|
@@ -212,7 +212,7 @@ function he() {
|
|
|
212
212
|
configurable: !1,
|
|
213
213
|
enumerable: !1,
|
|
214
214
|
writable: !0,
|
|
215
|
-
value:
|
|
215
|
+
value: j
|
|
216
216
|
}), Object.defineProperty(e, "_debugTask", {
|
|
217
217
|
configurable: !1,
|
|
218
218
|
enumerable: !1,
|
|
@@ -220,253 +220,248 @@ function he() {
|
|
|
220
220
|
value: D
|
|
221
221
|
}), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e;
|
|
222
222
|
}
|
|
223
|
-
function
|
|
224
|
-
var
|
|
225
|
-
if (
|
|
226
|
-
if (
|
|
227
|
-
if (
|
|
228
|
-
for (
|
|
229
|
-
|
|
230
|
-
Object.freeze && Object.freeze(
|
|
223
|
+
function i(e, o, u, f, j, D) {
|
|
224
|
+
var d = o.children;
|
|
225
|
+
if (d !== void 0)
|
|
226
|
+
if (f)
|
|
227
|
+
if (ie(d)) {
|
|
228
|
+
for (f = 0; f < d.length; f++)
|
|
229
|
+
_(d[f]);
|
|
230
|
+
Object.freeze && Object.freeze(d);
|
|
231
231
|
} else
|
|
232
232
|
console.error(
|
|
233
233
|
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
|
|
234
234
|
);
|
|
235
|
-
else
|
|
236
|
-
if (
|
|
237
|
-
|
|
238
|
-
var w = Object.keys(o).filter(function(
|
|
239
|
-
return
|
|
235
|
+
else _(d);
|
|
236
|
+
if (q.call(o, "key")) {
|
|
237
|
+
d = t(e);
|
|
238
|
+
var w = Object.keys(o).filter(function(fe) {
|
|
239
|
+
return fe !== "key";
|
|
240
240
|
});
|
|
241
|
-
|
|
241
|
+
f = 0 < w.length ? "{key: someKey, " + w.join(": ..., ") + ": ...}" : "{key: someKey}", Z[d + f] || (w = 0 < w.length ? "{" + w.join(": ..., ") + ": ...}" : "{}", console.error(
|
|
242
242
|
`A props object containing a "key" prop is being spread into JSX:
|
|
243
243
|
let props = %s;
|
|
244
244
|
<%s {...props} />
|
|
245
245
|
React keys must be passed directly to JSX without using spread:
|
|
246
246
|
let props = %s;
|
|
247
247
|
<%s key={someKey} {...props} />`,
|
|
248
|
-
i,
|
|
249
248
|
f,
|
|
249
|
+
d,
|
|
250
250
|
w,
|
|
251
|
-
|
|
252
|
-
),
|
|
251
|
+
d
|
|
252
|
+
), Z[d + f] = !0);
|
|
253
253
|
}
|
|
254
|
-
if (
|
|
255
|
-
|
|
254
|
+
if (d = null, u !== void 0 && (r(u), d = "" + u), m(o) && (r(o.key), d = "" + o.key), "key" in o) {
|
|
255
|
+
u = {};
|
|
256
256
|
for (var F in o)
|
|
257
|
-
F !== "key" && (
|
|
258
|
-
} else
|
|
259
|
-
return
|
|
260
|
-
|
|
257
|
+
F !== "key" && (u[F] = o[F]);
|
|
258
|
+
} else u = o;
|
|
259
|
+
return d && v(
|
|
260
|
+
u,
|
|
261
261
|
typeof e == "function" ? e.displayName || e.name || "Unknown" : e
|
|
262
|
-
),
|
|
262
|
+
), l(
|
|
263
263
|
e,
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
d,
|
|
265
|
+
u,
|
|
266
266
|
n(),
|
|
267
|
-
|
|
267
|
+
j,
|
|
268
268
|
D
|
|
269
269
|
);
|
|
270
270
|
}
|
|
271
|
-
function
|
|
271
|
+
function _(e) {
|
|
272
272
|
S(e) ? e._store && (e._store.validated = 1) : typeof e == "object" && e !== null && e.$$typeof === $ && (e._payload.status === "fulfilled" ? S(e._payload.value) && e._payload.value._store && (e._payload.value._store.validated = 1) : e._store && (e._store.validated = 1));
|
|
273
273
|
}
|
|
274
274
|
function S(e) {
|
|
275
|
-
return typeof e == "object" && e !== null && e.$$typeof ===
|
|
275
|
+
return typeof e == "object" && e !== null && e.$$typeof === T;
|
|
276
276
|
}
|
|
277
|
-
var
|
|
277
|
+
var R = de, T = Symbol.for("react.transitional.element"), y = Symbol.for("react.portal"), E = Symbol.for("react.fragment"), g = Symbol.for("react.strict_mode"), A = Symbol.for("react.profiler"), b = Symbol.for("react.consumer"), h = Symbol.for("react.context"), O = Symbol.for("react.forward_ref"), U = Symbol.for("react.suspense"), k = Symbol.for("react.suspense_list"), ce = Symbol.for("react.memo"), $ = Symbol.for("react.lazy"), ue = Symbol.for("react.activity"), le = Symbol.for("react.client.reference"), I = R.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, q = Object.prototype.hasOwnProperty, ie = Array.isArray, Y = console.createTask ? console.createTask : function() {
|
|
278
278
|
return null;
|
|
279
279
|
};
|
|
280
|
-
|
|
280
|
+
R = {
|
|
281
281
|
react_stack_bottom_frame: function(e) {
|
|
282
282
|
return e();
|
|
283
283
|
}
|
|
284
284
|
};
|
|
285
|
-
var
|
|
286
|
-
|
|
285
|
+
var G, X = {}, B = R.react_stack_bottom_frame.bind(
|
|
286
|
+
R,
|
|
287
287
|
c
|
|
288
|
-
)(),
|
|
289
|
-
x.Fragment =
|
|
290
|
-
var
|
|
291
|
-
return
|
|
288
|
+
)(), H = Y(a(c)), Z = {};
|
|
289
|
+
x.Fragment = E, x.jsx = function(e, o, u) {
|
|
290
|
+
var f = 1e4 > I.recentlyCreatedOwnerStacks++;
|
|
291
|
+
return i(
|
|
292
292
|
e,
|
|
293
293
|
o,
|
|
294
|
-
|
|
294
|
+
u,
|
|
295
295
|
!1,
|
|
296
|
-
|
|
297
|
-
|
|
296
|
+
f ? Error("react-stack-top-frame") : B,
|
|
297
|
+
f ? Y(a(e)) : H
|
|
298
298
|
);
|
|
299
|
-
}, x.jsxs = function(e, o,
|
|
300
|
-
var
|
|
301
|
-
return
|
|
299
|
+
}, x.jsxs = function(e, o, u) {
|
|
300
|
+
var f = 1e4 > I.recentlyCreatedOwnerStacks++;
|
|
301
|
+
return i(
|
|
302
302
|
e,
|
|
303
303
|
o,
|
|
304
|
-
|
|
304
|
+
u,
|
|
305
305
|
!0,
|
|
306
|
-
|
|
307
|
-
|
|
306
|
+
f ? Error("react-stack-top-frame") : B,
|
|
307
|
+
f ? Y(a(e)) : H
|
|
308
308
|
);
|
|
309
309
|
};
|
|
310
310
|
})()), x;
|
|
311
311
|
}
|
|
312
|
-
var
|
|
313
|
-
function
|
|
314
|
-
return
|
|
312
|
+
var ee;
|
|
313
|
+
function he() {
|
|
314
|
+
return ee || (ee = 1, process.env.NODE_ENV === "production" ? N.exports = Te() : N.exports = ye()), N.exports;
|
|
315
315
|
}
|
|
316
|
-
var
|
|
317
|
-
const
|
|
316
|
+
var ge = he();
|
|
317
|
+
const ae = me({
|
|
318
318
|
stateVocab: {},
|
|
319
319
|
setStateVocab: () => {
|
|
320
320
|
}
|
|
321
321
|
});
|
|
322
|
-
function
|
|
323
|
-
return
|
|
322
|
+
function ke() {
|
|
323
|
+
return be(ae);
|
|
324
324
|
}
|
|
325
|
-
const
|
|
326
|
-
const { children:
|
|
327
|
-
return r &&
|
|
328
|
-
},
|
|
329
|
-
const
|
|
330
|
-
return
|
|
331
|
-
},
|
|
332
|
-
|
|
333
|
-
return a === null ? null : r(a);
|
|
334
|
-
}, Pe = (t) => typeof t == "function", xe = (t) => typeof t == "function", z = (t) => typeof t < "u", V = (t) => xe(t) ? t() : t, Ae = typeof window > "u";
|
|
335
|
-
function Ve(t = {}) {
|
|
325
|
+
const Oe = (t) => {
|
|
326
|
+
const { children: s, verbose: r } = t, [a, n] = ne({});
|
|
327
|
+
return r && Re(a), /* @__PURE__ */ ge.jsx(ae.Provider, { value: { stateVocab: a, setStateVocab: n }, children: s });
|
|
328
|
+
}, V = (t, s) => (r) => {
|
|
329
|
+
const a = { ...r };
|
|
330
|
+
return _e(a, t, s), a;
|
|
331
|
+
}, we = (t) => typeof t == "function", Pe = (t) => typeof t == "function", z = (t) => typeof t < "u", L = (t) => Pe(t) ? t() : t, xe = typeof window > "u";
|
|
332
|
+
function je(t = {}) {
|
|
336
333
|
return {
|
|
337
|
-
[
|
|
334
|
+
[oe]: !0,
|
|
338
335
|
// marks this object as a leaf in the router tree
|
|
339
|
-
[
|
|
336
|
+
[J]: !1,
|
|
340
337
|
// placeholder; injected at runtime by injectPaths()
|
|
341
|
-
[
|
|
338
|
+
[C]: "",
|
|
342
339
|
// placeholder; injected at runtime by injectPaths()
|
|
343
|
-
useState(
|
|
344
|
-
const r =
|
|
345
|
-
|
|
346
|
-
const
|
|
347
|
-
|
|
340
|
+
useState(s) {
|
|
341
|
+
const r = xe ? void 0 : L(t.storage), a = t.serialize ?? JSON.stringify, n = t.deserialize ?? JSON.parse, c = L(t.defaultValue), m = t.bidirectional;
|
|
342
|
+
s ??= {};
|
|
343
|
+
const v = L(s.defaultValue), p = Se(
|
|
344
|
+
s.onSet ?? (() => {
|
|
348
345
|
}),
|
|
349
|
-
|
|
346
|
+
s.delayedSet,
|
|
350
347
|
[]
|
|
351
|
-
),
|
|
352
|
-
M(() =>
|
|
353
|
-
const
|
|
348
|
+
), l = ke(), i = this[C], _ = this[J], [S, R] = ne(!_);
|
|
349
|
+
M(() => R(!0), []);
|
|
350
|
+
const T = W(
|
|
354
351
|
() => {
|
|
355
|
-
if (!
|
|
352
|
+
if (!S || !r)
|
|
356
353
|
return;
|
|
357
|
-
const
|
|
358
|
-
return
|
|
354
|
+
const b = r.getItem(i);
|
|
355
|
+
return b === null ? null : n(b);
|
|
359
356
|
},
|
|
360
357
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
361
|
-
[
|
|
362
|
-
),
|
|
363
|
-
() =>
|
|
364
|
-
|
|
365
|
-
|
|
358
|
+
[S]
|
|
359
|
+
), y = W(
|
|
360
|
+
() => Ee(
|
|
361
|
+
l.stateVocab,
|
|
362
|
+
i,
|
|
366
363
|
// 3rd argument in order to avoid waiting for useEffect execution
|
|
367
|
-
|
|
364
|
+
T ?? v ?? c
|
|
368
365
|
),
|
|
369
366
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
370
367
|
[
|
|
371
|
-
|
|
372
|
-
|
|
368
|
+
l.stateVocab,
|
|
369
|
+
T
|
|
373
370
|
]
|
|
374
|
-
);
|
|
375
|
-
M(
|
|
371
|
+
), E = ve(y);
|
|
372
|
+
return M(
|
|
376
373
|
() => {
|
|
377
|
-
z(
|
|
374
|
+
z(y) && (l.setStateVocab(V(i, y)), r && T === null && r.setItem(i, a(y)));
|
|
378
375
|
},
|
|
379
376
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
380
|
-
[
|
|
377
|
+
[T]
|
|
381
378
|
), M(() => {
|
|
382
|
-
if (!
|
|
379
|
+
if (!s.bidirectional && !m)
|
|
383
380
|
return;
|
|
384
|
-
const
|
|
385
|
-
if (
|
|
381
|
+
const b = (h) => {
|
|
382
|
+
if (h.key !== i)
|
|
386
383
|
return;
|
|
387
|
-
const
|
|
388
|
-
z(k) && (
|
|
384
|
+
const O = h.newValue, k = (O === null ? null : n(O)) ?? v ?? c;
|
|
385
|
+
z(k) && (l.setStateVocab(V(i, k)), p(k, E.current), E.current = k);
|
|
389
386
|
};
|
|
390
|
-
return window.addEventListener("storage",
|
|
387
|
+
return window.addEventListener("storage", b), () => window.removeEventListener("storage", b);
|
|
391
388
|
}, [
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
])
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
const y = Pe(m) ? m(p.current) : m;
|
|
400
|
-
v.setStateVocab(j(u, y)), b(y, p.current), r && r.setItem(u, s(y)), p.current = y;
|
|
389
|
+
s.bidirectional,
|
|
390
|
+
m
|
|
391
|
+
]), [
|
|
392
|
+
y,
|
|
393
|
+
(b) => {
|
|
394
|
+
const h = we(b) ? b(E.current) : b;
|
|
395
|
+
l.setStateVocab(V(i, h)), p(h, E.current), r && r.setItem(i, a(h)), E.current = h;
|
|
401
396
|
},
|
|
402
397
|
() => {
|
|
403
|
-
const
|
|
404
|
-
if (!z(
|
|
405
|
-
r?.removeItem(
|
|
398
|
+
const b = v ?? c;
|
|
399
|
+
if (!z(b)) {
|
|
400
|
+
r?.removeItem(i);
|
|
406
401
|
return;
|
|
407
402
|
}
|
|
408
|
-
|
|
403
|
+
l.setStateVocab(V(i, b)), p(b, E.current), E.current = b, r && r.setItem(i, a(b));
|
|
409
404
|
}
|
|
410
405
|
];
|
|
411
406
|
},
|
|
412
407
|
/** Returns the fully qualified job name (dot-separated path). */
|
|
413
408
|
toString() {
|
|
414
|
-
return this[
|
|
409
|
+
return this[C];
|
|
415
410
|
}
|
|
416
411
|
};
|
|
417
412
|
}
|
|
418
|
-
const
|
|
419
|
-
function
|
|
420
|
-
|
|
413
|
+
const te = /* @__PURE__ */ new WeakMap(), re = /* @__PURE__ */ new WeakMap();
|
|
414
|
+
function se(t, s) {
|
|
415
|
+
s ??= {};
|
|
421
416
|
const {
|
|
422
417
|
path: r = "",
|
|
423
|
-
ssr:
|
|
424
|
-
} =
|
|
425
|
-
let n =
|
|
426
|
-
n || (n = /* @__PURE__ */ new Map(),
|
|
418
|
+
ssr: a
|
|
419
|
+
} = s;
|
|
420
|
+
let n = te.get(t);
|
|
421
|
+
n || (n = /* @__PURE__ */ new Map(), te.set(t, n));
|
|
427
422
|
const c = n.get(r);
|
|
428
423
|
if (c)
|
|
429
424
|
return c;
|
|
430
|
-
const
|
|
431
|
-
get(
|
|
432
|
-
const
|
|
433
|
-
if (
|
|
434
|
-
const
|
|
435
|
-
let S =
|
|
436
|
-
S || (S = /* @__PURE__ */ new Map(),
|
|
437
|
-
const
|
|
438
|
-
if (
|
|
439
|
-
return
|
|
440
|
-
const
|
|
441
|
-
(g) => typeof
|
|
442
|
-
),
|
|
443
|
-
|
|
425
|
+
const m = new Proxy(t, {
|
|
426
|
+
get(v, p) {
|
|
427
|
+
const l = v[p], i = r ? `${r}.${String(p)}` : String(p);
|
|
428
|
+
if (l && typeof l == "object" && oe in l) {
|
|
429
|
+
const _ = l;
|
|
430
|
+
let S = re.get(_);
|
|
431
|
+
S || (S = /* @__PURE__ */ new Map(), re.set(_, S));
|
|
432
|
+
const R = S.get(i);
|
|
433
|
+
if (R)
|
|
434
|
+
return R;
|
|
435
|
+
const T = Reflect.ownKeys(_).filter(
|
|
436
|
+
(g) => typeof _[g] == "function"
|
|
437
|
+
), y = Object.fromEntries(
|
|
438
|
+
T.map((g) => [
|
|
444
439
|
g,
|
|
445
|
-
(...
|
|
440
|
+
(...A) => _[g].call(
|
|
446
441
|
{
|
|
447
|
-
...
|
|
448
|
-
[
|
|
449
|
-
[
|
|
442
|
+
..._,
|
|
443
|
+
[C]: i,
|
|
444
|
+
[J]: a
|
|
450
445
|
},
|
|
451
|
-
...
|
|
446
|
+
...A
|
|
452
447
|
)
|
|
453
448
|
])
|
|
454
|
-
),
|
|
455
|
-
return S.set(
|
|
449
|
+
), E = { ..._, ...y };
|
|
450
|
+
return S.set(i, E), E;
|
|
456
451
|
}
|
|
457
|
-
return
|
|
458
|
-
path:
|
|
459
|
-
ssr:
|
|
460
|
-
}) :
|
|
452
|
+
return l && typeof l == "object" ? se(l, {
|
|
453
|
+
path: i,
|
|
454
|
+
ssr: a
|
|
455
|
+
}) : l;
|
|
461
456
|
}
|
|
462
457
|
});
|
|
463
|
-
return n.set(r,
|
|
458
|
+
return n.set(r, m), m;
|
|
464
459
|
}
|
|
465
|
-
function Ne(t,
|
|
466
|
-
return
|
|
460
|
+
function Ne(t, s) {
|
|
461
|
+
return se(t, s);
|
|
467
462
|
}
|
|
468
463
|
export {
|
|
469
|
-
|
|
470
|
-
|
|
464
|
+
Oe as StorageProvider,
|
|
465
|
+
je as defineState,
|
|
471
466
|
Ne as setupStorage
|
|
472
467
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types/state.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { STATE_DEFINITION, STATE_PATH, STATE_SSR } from "./constants";
|
|
2
2
|
import type { Deserialize, Serialize, ValueOrFactory, ValueOrTransformer } from "./state.types";
|
|
3
|
-
export declare function defineState<
|
|
3
|
+
export declare function defineState<D>(definitionOptions?: {
|
|
4
4
|
storage?: ValueOrFactory<Storage>;
|
|
5
|
-
defaultValue?:
|
|
5
|
+
defaultValue?: ValueOrFactory<D>;
|
|
6
6
|
bidirectional?: true;
|
|
7
|
-
serialize?: Serialize<
|
|
8
|
-
deserialize?: Deserialize<
|
|
7
|
+
serialize?: Serialize<D>;
|
|
8
|
+
deserialize?: Deserialize<D>;
|
|
9
9
|
}): {
|
|
10
10
|
[STATE_DEFINITION]: boolean;
|
|
11
11
|
[STATE_SSR]: boolean;
|
|
12
12
|
[STATE_PATH]: string;
|
|
13
|
-
useState
|
|
13
|
+
useState(this: {
|
|
14
14
|
[STATE_PATH]: string;
|
|
15
15
|
[STATE_SSR]: boolean;
|
|
16
16
|
}, options?: {
|
|
@@ -3,10 +3,6 @@ import type { ValueOrTransformer, Transformer, ValueOrFactory } from "./state.ty
|
|
|
3
3
|
export declare const embed: <D>(statePath: string, value: D) => (vocab: Vocab<D>) => {
|
|
4
4
|
[x: string]: D | null;
|
|
5
5
|
};
|
|
6
|
-
export declare const genStoredValue: <V>(options: {
|
|
7
|
-
serialized: string | null;
|
|
8
|
-
deserialize: (v: string) => V;
|
|
9
|
-
}) => V | null;
|
|
10
6
|
export declare const isTransformer: <V>(v: ValueOrTransformer<V>) => v is Transformer<V>;
|
|
11
7
|
export declare const isValueDefined: <V>(v: V | undefined) => v is V;
|
|
12
8
|
export declare const valueOrFactory: <V>(input: ValueOrFactory<V>) => V;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yakocloud/state-vocab",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"main": "dist/state-vocab.cjs.js",
|
|
5
5
|
"module": "dist/state-vocab.es.js",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -8,6 +8,22 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
"dist"
|
|
10
10
|
],
|
|
11
|
+
"keywords": [
|
|
12
|
+
"react",
|
|
13
|
+
"state",
|
|
14
|
+
"state-management",
|
|
15
|
+
"storage",
|
|
16
|
+
"localStorage",
|
|
17
|
+
"sessionStorage",
|
|
18
|
+
"persist",
|
|
19
|
+
"persistent-state",
|
|
20
|
+
"hooks",
|
|
21
|
+
"useState",
|
|
22
|
+
"typescript",
|
|
23
|
+
"no-boilerplate",
|
|
24
|
+
"sync",
|
|
25
|
+
"cross-tab"
|
|
26
|
+
],
|
|
11
27
|
"repository": {
|
|
12
28
|
"type": "git",
|
|
13
29
|
"url": "https://github.com/yakovenkoroman1993/state-vocab"
|