@yakocloud/state-vocab 4.0.1 → 4.0.2
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 +49 -94
- package/dist/client.cjs.js +1 -1
- package/dist/client.es.js +118 -76
- package/dist/constants-BB1YAX6c.mjs +8 -0
- package/dist/constants-CbsduCZ7.js +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +15 -14
- package/dist/provider-client-B4XQ24JB.js +1 -0
- package/dist/{provider.client-CtAC9tPr.mjs → provider-client-C2Aw0Lmi.mjs} +2 -2
- package/dist/server.cjs.js +1 -1
- package/dist/server.es.js +32 -26
- package/dist/types/client.d.ts +0 -1
- package/dist/types/context.client.d.ts +2 -2
- package/dist/types/server.d.ts +0 -1
- package/dist/types/setup.client.utils.d.ts +12 -0
- package/dist/types/setup.server.d.ts +6 -2
- package/dist/utils-0CTNJ4ZE.js +3 -0
- package/dist/utils-xV3x3fTc.mjs +57 -0
- package/package.json +1 -1
- package/dist/provider.client--OPImdtY.js +0 -1
- package/dist/types/state.client.utils.d.ts +0 -2
- package/dist/utils-33NqsZoR.js +0 -3
- package/dist/utils-t8tYdd6B.mjs +0 -63
package/README.md
CHANGED
|
@@ -117,7 +117,7 @@ npm install @yakocloud/state-vocab react react-dom
|
|
|
117
117
|
|
|
118
118
|
## Quick Start
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
Define your storage tree once (`setupStorage`/`defineState`), call `clientify` to attach React hooks. If you use react server components (RSC) wrap your app with `StateVocabProvider` at the root and call `serverify` to attach RSC-methods. Use state anywhere in the tree
|
|
121
121
|
|
|
122
122
|
Library SSR-requirements:
|
|
123
123
|
- `Per-request store`: A Next.js server can handle multiple requests simultaneously. This means that the store should be created per request and should not be shared across requests.
|
|
@@ -125,11 +125,11 @@ Library SSR-requirements:
|
|
|
125
125
|
|
|
126
126
|
```tsx
|
|
127
127
|
import { setupStorage, defineState } from '@yakocloud/state-vocab'
|
|
128
|
-
import { clientify
|
|
128
|
+
import { clientify } from '@yakocloud/state-vocab/client'
|
|
129
129
|
|
|
130
130
|
type Theme = 'Dark' | 'White' | 'System'
|
|
131
131
|
|
|
132
|
-
const storage =
|
|
132
|
+
const storage = setupStorage({
|
|
133
133
|
path: {
|
|
134
134
|
to: {
|
|
135
135
|
theme: defineState<Theme>({
|
|
@@ -138,18 +138,14 @@ const storage = clientify(setupStorage({
|
|
|
138
138
|
}),
|
|
139
139
|
},
|
|
140
140
|
},
|
|
141
|
-
}
|
|
141
|
+
}, {
|
|
142
|
+
ssr: false // by default true
|
|
143
|
+
})
|
|
142
144
|
|
|
143
|
-
|
|
144
|
-
return (
|
|
145
|
-
<StateVocabProvider>
|
|
146
|
-
<Settings />
|
|
147
|
-
</StateVocabProvider>
|
|
148
|
-
)
|
|
149
|
-
}
|
|
145
|
+
const clientStorage = clientify(storage)
|
|
150
146
|
|
|
151
147
|
function Settings() {
|
|
152
|
-
const [theme, setTheme] =
|
|
148
|
+
const [theme, setTheme] = clientStorage.path.to.theme.useState()
|
|
153
149
|
|
|
154
150
|
return (
|
|
155
151
|
<select value={theme} onChange={(e) => setTheme(e.target.value as Theme)}>
|
|
@@ -161,37 +157,6 @@ function Settings() {
|
|
|
161
157
|
}
|
|
162
158
|
```
|
|
163
159
|
|
|
164
|
-
## Setup
|
|
165
|
-
|
|
166
|
-
### `StateVocabProvider`
|
|
167
|
-
|
|
168
|
-
All components that call `.useState()` must be descendants of `StateVocabProvider`. It creates an isolated `VocabStore` instance for its subtree — multiple providers can coexist in the same app without sharing state.
|
|
169
|
-
|
|
170
|
-
```tsx
|
|
171
|
-
import { StateVocabProvider } from '@yakocloud/state-vocab/client'
|
|
172
|
-
|
|
173
|
-
createRoot(document.getElementById('root')!).render(
|
|
174
|
-
<React.StrictMode>
|
|
175
|
-
<StateVocabProvider>
|
|
176
|
-
<App />
|
|
177
|
-
</StateVocabProvider>
|
|
178
|
-
</React.StrictMode>
|
|
179
|
-
)
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
You can mount multiple independent providers — each gets its own store:
|
|
183
|
-
|
|
184
|
-
```tsx
|
|
185
|
-
// Two isolated state trees — state does not bleed between them
|
|
186
|
-
<StateVocabProvider>
|
|
187
|
-
<WidgetA />
|
|
188
|
-
</StateVocabProvider>
|
|
189
|
-
|
|
190
|
-
<StateVocabProvider>
|
|
191
|
-
<WidgetB />
|
|
192
|
-
</StateVocabProvider>
|
|
193
|
-
```
|
|
194
|
-
|
|
195
160
|
## Core Concepts
|
|
196
161
|
|
|
197
162
|
### `defineState(options?)`
|
|
@@ -237,7 +202,7 @@ Wraps a nested object of `defineState()` nodes and injects dot-separated paths i
|
|
|
237
202
|
|---|---|---|---|
|
|
238
203
|
| `verbose` | `boolean \| undefined` | Log current state to the browser console on every change | `false` |
|
|
239
204
|
| `verbosePath` | `string \| undefined` | Narrow verbose logging to a specific subtree (dot-separated path). When set, only that subtree is logged instead of the entire state. TypeScript will autocomplete valid paths based on your tree. | `undefined` |
|
|
240
|
-
| `ssr` | `boolean \| undefined` | Defer storage reads until after hydration (Next.js / SSR) | `
|
|
205
|
+
| `ssr` | `boolean \| undefined` | Defer storage reads until after hydration (Next.js / SSR) | `true` |
|
|
241
206
|
|
|
242
207
|
```ts
|
|
243
208
|
const storage = setupStorage({
|
|
@@ -286,10 +251,10 @@ const storage = setupStorage({
|
|
|
286
251
|
preference: {
|
|
287
252
|
theme: defineState<Theme>({ storage: localStorage, defaultValue: 'Dark' }),
|
|
288
253
|
},
|
|
289
|
-
}
|
|
254
|
+
})
|
|
290
255
|
```
|
|
291
256
|
|
|
292
|
-
|
|
257
|
+
By default `ssr: true`:
|
|
293
258
|
- **Server & first client render** — always use `defaultValue`, storage is not read
|
|
294
259
|
- **After hydration** — `useLayoutEffect` fires synchronously before paint, reads storage and updates state
|
|
295
260
|
|
|
@@ -304,7 +269,7 @@ For Next.js apps using the App Router, state-vocab provides dedicated server and
|
|
|
304
269
|
| Import path | Use in |
|
|
305
270
|
|---|---|
|
|
306
271
|
| `@yakocloud/state-vocab` | Shared files — `defineState`, `setupStorage` |
|
|
307
|
-
| `@yakocloud/state-vocab/server` | Server Components — `serverify
|
|
272
|
+
| `@yakocloud/state-vocab/server` | Server Components — `serverify` |
|
|
308
273
|
| `@yakocloud/state-vocab/client` | Client Components — `clientify` |
|
|
309
274
|
|
|
310
275
|
**1. Define the shared storage schema** (used on both server and client):
|
|
@@ -323,7 +288,7 @@ export const storage = setupStorage({
|
|
|
323
288
|
city: defineState<string>(),
|
|
324
289
|
},
|
|
325
290
|
},
|
|
326
|
-
}
|
|
291
|
+
})
|
|
327
292
|
```
|
|
328
293
|
|
|
329
294
|
**2. Create server and client storage handles:**
|
|
@@ -351,7 +316,8 @@ export const clientStorage = clientify(storage)
|
|
|
351
316
|
```tsx
|
|
352
317
|
// app/page.tsx (Server Component)
|
|
353
318
|
import { serverStorage } from '@/storage.server'
|
|
354
|
-
|
|
319
|
+
|
|
320
|
+
const { StateVocabProvider } = serverStorage
|
|
355
321
|
|
|
356
322
|
export default async function Page() {
|
|
357
323
|
// Fetch data from DB / API
|
|
@@ -359,10 +325,10 @@ export default async function Page() {
|
|
|
359
325
|
|
|
360
326
|
return (
|
|
361
327
|
<StateVocabProvider
|
|
362
|
-
value={
|
|
328
|
+
value={{
|
|
363
329
|
user: { name: user.name, role: user.role },
|
|
364
330
|
person: { address: { city: user.city } },
|
|
365
|
-
}
|
|
331
|
+
}}
|
|
366
332
|
>
|
|
367
333
|
<UserInfo />
|
|
368
334
|
</StateVocabProvider>
|
|
@@ -398,35 +364,24 @@ export default function UserInfoClient() {
|
|
|
398
364
|
|
|
399
365
|
#### `serverify(storage)`
|
|
400
366
|
|
|
401
|
-
Converts a storage tree into its server-side counterpart. Each leaf gains a `.getState()` method that reads the value seeded into the nearest `StateVocabProvider`. Each namespace node (including the root) gains a `.
|
|
367
|
+
Converts a storage tree into its server-side counterpart. Each leaf gains a `.getState()` method that reads the value seeded into the nearest `StateVocabProvider`. Each namespace node (including the root) gains a `.seed()` method that returns the input wrapped under its full ancestor path. This method is optional for using. The result also exposes `StateVocabProvider` — a server-aware provider that accepts a plain object `value` prop to pre-seed the store.
|
|
402
368
|
|
|
403
|
-
**`.
|
|
369
|
+
**`.seed()` syntax:**
|
|
404
370
|
|
|
405
371
|
```ts
|
|
406
|
-
// Full tree at once — root .
|
|
407
|
-
serverStorage.
|
|
372
|
+
// Full tree at once — root .seed() returns input as-is
|
|
373
|
+
serverStorage.seed({ user: { name: 'Alice', role: 'Admin' } })
|
|
408
374
|
// → { user: { name: 'Alice', role: 'Admin' } }
|
|
409
375
|
|
|
410
376
|
// Single namespace — wraps input under its key
|
|
411
|
-
serverStorage.user.
|
|
377
|
+
serverStorage.user.seed({ name: 'Alice', role: 'Admin' })
|
|
412
378
|
// → { user: { name: 'Alice', role: 'Admin' } }
|
|
413
379
|
|
|
414
380
|
// Nested namespace — wraps up to the root
|
|
415
|
-
serverStorage.person.address.
|
|
381
|
+
serverStorage.person.address.seed({ city: 'NY' })
|
|
416
382
|
// → { person: { address: { city: 'NY' } } }
|
|
417
383
|
```
|
|
418
384
|
|
|
419
|
-
All three forms return a value ready to pass as `StateVocabProvider`'s `value` prop. They can be combined by spreading:
|
|
420
|
-
|
|
421
|
-
```tsx
|
|
422
|
-
<StateVocabProvider
|
|
423
|
-
value={{
|
|
424
|
-
...serverStorage.user.set({ name: 'Alice', role: 'Admin' }),
|
|
425
|
-
...serverStorage.person.address.set({ city: 'NY' }),
|
|
426
|
-
}}
|
|
427
|
-
>
|
|
428
|
-
```
|
|
429
|
-
|
|
430
385
|
**`node.getState()`** reads the value for that leaf from the surrounding `StateVocabProvider`. Throws if called outside one.
|
|
431
386
|
|
|
432
387
|
#### `clientify(storage)`
|
|
@@ -521,11 +476,11 @@ const storage = setupStorage({
|
|
|
521
476
|
import React from 'react'
|
|
522
477
|
import { createRoot } from 'react-dom/client'
|
|
523
478
|
import { setupStorage, defineState } from '@yakocloud/state-vocab'
|
|
524
|
-
import { clientify
|
|
479
|
+
import { clientify } from '@yakocloud/state-vocab/client'
|
|
525
480
|
|
|
526
481
|
type Theme = 'Dark' | 'White' | 'System'
|
|
527
482
|
|
|
528
|
-
const storage =
|
|
483
|
+
const storage = setupStorage({
|
|
529
484
|
preference: {
|
|
530
485
|
theme: defineState<Theme>({ storage: localStorage, defaultValue: 'Dark' }),
|
|
531
486
|
nightMode: defineState({ storage: sessionStorage, defaultValue: false }),
|
|
@@ -547,11 +502,15 @@ const storage = clientify(setupStorage({
|
|
|
547
502
|
storage: localStorage,
|
|
548
503
|
}),
|
|
549
504
|
},
|
|
550
|
-
}
|
|
505
|
+
}, {
|
|
506
|
+
ssr: false // by default true
|
|
507
|
+
})
|
|
508
|
+
|
|
509
|
+
const clientStorage = clientify(storage)
|
|
551
510
|
|
|
552
511
|
// Root — initializes shared state for the whole subtree
|
|
553
512
|
function Page() {
|
|
554
|
-
|
|
513
|
+
clientStorage.demo.pageProps.useState({
|
|
555
514
|
defaultValue: { title: 'Hello', count: 42 },
|
|
556
515
|
})
|
|
557
516
|
|
|
@@ -560,15 +519,15 @@ function Page() {
|
|
|
560
519
|
|
|
561
520
|
// Deep child — reads without re-specifying defaults
|
|
562
521
|
function PageHeader() {
|
|
563
|
-
const [pageProps] =
|
|
522
|
+
const [pageProps] = clientStorage.demo.pageProps.useState()
|
|
564
523
|
return <h1>{pageProps.title} ({pageProps.count})</h1>
|
|
565
524
|
}
|
|
566
525
|
|
|
567
526
|
function Dashboard() {
|
|
568
|
-
const [theme, setTheme] =
|
|
569
|
-
const [nightMode, setNightMode] =
|
|
570
|
-
const [counter, setCounter, resetCounter] =
|
|
571
|
-
const [note, setNote] =
|
|
527
|
+
const [theme, setTheme] = clientStorage.preference.theme.useState()
|
|
528
|
+
const [nightMode, setNightMode] = clientStorage.preference.nightMode.useState()
|
|
529
|
+
const [counter, setCounter, resetCounter] = clientStorage.stats.counter.useState()
|
|
530
|
+
const [note, setNote] = clientStorage.personal.note.useState({
|
|
572
531
|
delayedSet: 500,
|
|
573
532
|
onSet: (v) => console.log('Saving note:', v),
|
|
574
533
|
})
|
|
@@ -607,9 +566,7 @@ function Dashboard() {
|
|
|
607
566
|
|
|
608
567
|
createRoot(document.getElementById('root')!).render(
|
|
609
568
|
<React.StrictMode>
|
|
610
|
-
<
|
|
611
|
-
<Page />
|
|
612
|
-
</StateVocabProvider>
|
|
569
|
+
<Page />
|
|
613
570
|
</React.StrictMode>
|
|
614
571
|
)
|
|
615
572
|
```
|
|
@@ -632,24 +589,20 @@ createRoot(document.getElementById('root')!).render(
|
|
|
632
589
|
|---|---|---|
|
|
633
590
|
| `verbose` | `boolean \| undefined` | `false` |
|
|
634
591
|
| `verbosePath` | `Path<T> \| undefined` | `undefined` |
|
|
635
|
-
| `ssr` | `boolean \| undefined` | `
|
|
592
|
+
| `ssr` | `boolean \| undefined` | `true` |
|
|
636
593
|
|
|
637
594
|
Returns a proxied copy of `tree` with paths injected into all leaf nodes.
|
|
638
595
|
|
|
639
596
|
### `StateVocabProvider`
|
|
640
597
|
|
|
641
|
-
A React context provider that initializes a `VocabStore` for its subtree.
|
|
598
|
+
A React context provider that initializes a `VocabStore` for its subtree. Only required in RSC / Next.js App Router contexts (where `ssr: true`). For standard SPAs without SSR, no provider is needed — hooks use a module-level store automatically.
|
|
642
599
|
|
|
643
|
-
|
|
644
|
-
<StateVocabProvider>
|
|
645
|
-
<App />
|
|
646
|
-
</StateVocabProvider>
|
|
647
|
-
```
|
|
648
|
-
|
|
649
|
-
Accepts an optional `value` prop (imported from `@yakocloud/state-vocab/server` in RSC contexts) to pre-seed the store with server-fetched data:
|
|
600
|
+
In RSC contexts, `StateVocabProvider` is available on the `serverify()` result — it accepts an optional `value` prop to pre-seed the store with server-fetched data:
|
|
650
601
|
|
|
651
602
|
```tsx
|
|
652
|
-
|
|
603
|
+
const { StateVocabProvider } = serverStorage
|
|
604
|
+
|
|
605
|
+
<StateVocabProvider value={{ user: { name: 'Alice' } }}>
|
|
653
606
|
<App />
|
|
654
607
|
</StateVocabProvider>
|
|
655
608
|
```
|
|
@@ -658,16 +611,18 @@ Accepts an optional `value` prop (imported from `@yakocloud/state-vocab/server`
|
|
|
658
611
|
|
|
659
612
|
Converts a storage tree to its server-side counterpart. Available from `@yakocloud/state-vocab/server`.
|
|
660
613
|
|
|
661
|
-
Each leaf gains `.getState()` — reads the value from the nearest `StateVocabProvider`. Each namespace node gains `.
|
|
614
|
+
Each leaf gains `.getState()` — reads the value from the nearest `StateVocabProvider`. Each namespace node gains `.seed()`, which returns the input wrapped under its full ancestor path. The result also includes `StateVocabProvider` — use it instead of importing from `@yakocloud/state-vocab/server`.
|
|
662
615
|
|
|
663
616
|
```ts
|
|
664
617
|
import { serverify } from '@yakocloud/state-vocab/server'
|
|
665
618
|
const serverStorage = serverify(storage)
|
|
666
619
|
|
|
620
|
+
const { StateVocabProvider } = serverStorage // server-aware provider
|
|
621
|
+
|
|
667
622
|
serverStorage.user.name.getState() // reads "user.name" from context
|
|
668
|
-
serverStorage.user.
|
|
669
|
-
serverStorage.person.address.
|
|
670
|
-
serverStorage.
|
|
623
|
+
serverStorage.user.seed({ name: 'Alice' }) // → { user: { name: 'Alice' } }
|
|
624
|
+
serverStorage.person.address.seed({ city: 'NY' }) // → { person: { address: { city: 'NY' } } }
|
|
625
|
+
serverStorage.seed({ user: { name: 'Alice' } }) // → { user: { name: 'Alice' } } (identity)
|
|
671
626
|
```
|
|
672
627
|
|
|
673
628
|
### `clientify<T>(storage: T)`
|
package/dist/client.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("react"),v=require("./constants-CbsduCZ7.js"),a=require("./utils-0CTNJ4ZE.js"),y=require("./provider-client-B4XQ24JB.js");function D(t,e,n=[]){return u.useMemo(()=>a.debounce(t,e),n)}const g=t=>{const{vocabStore:e,storage:n,statePath:o,value:s,deserialize:S,serialize:l}=t,f=n.getItem(o);f===null?a.isValueDefined(s)&&n.setItem(o,l(s)):e.set(o,S(f))},z=typeof window>"u",m=z?u.useEffect:u.useLayoutEffect,A=new y.VocabStore,C="Make sure your component is wrapped in StateVocabProvider (RSC) or disable ssr option in setupStorage for SPA (RCC only)";function I(t){t??={};const e=z?void 0:a.valueOrFactory(t.storage),n=a.valueOrFactory(t.defaultValue),o=t.bidirectional,s=this[v.STATE_PATH],S=this[v.STATE_VERBOSE],l=this[v.STATE_VERBOSE_PATH],f=this[v.STATE_SSR];let i=y.useStateVocabClientContext({verbose:S});if(!(i instanceof y.VocabStore)){if(f)throw new Error(C);i=A}const d=t.serialize??JSON.stringify,c=t.deserialize??JSON.parse,V=D(t.onSet??(()=>{}),t.delayedSet,[]),E=u.useRef(void 0),w=u.useRef(!1);if(!w.current){w.current=!0;let r=i.get(s);a.isValueDefined(r)||(r=n,a.isValueDefined(r)&&i.set(s,r)),!f&&e&&g({vocabStore:i,storage:e,statePath:s,value:r,serialize:d,deserialize:c})}const h=u.useSyncExternalStore(i.subscribe.bind(i),i.getClientSnapshot.bind(i),i.getServerSnapshot.bind(i));if(S)if(l){const r=a.get(h,l);r&&a.logStyled(r)}else a.logStyled(h);const T=a.get(h,s,n);E.current=T,m(()=>{!f||!e||g({vocabStore:i,storage:e,statePath:s,value:T,serialize:d,deserialize:c})},[]);const O=u.useEffectEvent(r=>{if(r.key!==s)return;const b=r.newValue,R=(b===null?null:c(b))??n;a.isValueDefined(R)&&(i.set(s,R),V(R,E.current))});u.useEffect(()=>{if(o)return window.addEventListener("storage",O),()=>window.removeEventListener("storage",O)},[o]);const p=u.useCallback(r=>{const b=a.isTransformer(r)?r(E.current):r;i.set(s,b),V(b,E.current),e&&e.setItem(s,d(b))},[i,s,V,e,d]),_=u.useCallback(()=>{const r=n;if(!a.isValueDefined(r)){e?.removeItem(s);return}i.set(s,r),V(r,E.current),e&&e.setItem(s,d(r))},[n,i,s,V,e,d]);return[T,p,_]}function k(t){t??={};const e=z?void 0:a.valueOrFactory(t.storage),n=a.valueOrFactory(t.defaultValue),o=this[v.STATE_PATH],s=this[v.STATE_VERBOSE],S=this[v.STATE_SSR];let l=y.useStateVocabClientContext({verbose:s});if(!(l instanceof y.VocabStore)){if(S)throw new Error(C);l=A}const f=t.serialize??JSON.stringify,i=t.deserialize??JSON.parse,d=u.useRef(!1);let c;d.current||(d.current=!0,c=l.get(o),a.isValueDefined(c)||(c=n,a.isValueDefined(c)&&l.set(o,c)),!S&&e&&g({vocabStore:l,storage:e,statePath:o,value:c,serialize:f,deserialize:i})),m(()=>{!S||!e||g({vocabStore:l,storage:e,statePath:o,value:c,serialize:f,deserialize:i})},[])}function q(t){return typeof t=="object"&&t!==null&&"clientSlot"in t}function P(t){const e={};for(const n in t){const o=t[n];q(o)?(e[n]=o.clientSlot({useState(...s){return I.apply(this,s)},useInitialState(...s){k.apply(this,s)}}),delete e[n].serverSlot,delete e[n].clientSlot):o!==null&&typeof o=="object"?e[n]=P(o):e[n]=o}return e}exports.clientify=P;
|
package/dist/client.es.js
CHANGED
|
@@ -1,107 +1,149 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useMemo as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
function
|
|
7
|
-
return
|
|
8
|
-
() =>
|
|
2
|
+
import { useMemo as B, useRef as V, useSyncExternalStore as D, useEffectEvent as H, useEffect as I, useCallback as T, useLayoutEffect as x } from "react";
|
|
3
|
+
import { S as O, a as P, b as _, c as F } from "./constants-BB1YAX6c.mjs";
|
|
4
|
+
import { a as d, d as G, v as g, g as A, l as C, i as q } from "./utils-xV3x3fTc.mjs";
|
|
5
|
+
import { V as z, u as k } from "./provider-client-C2Aw0Lmi.mjs";
|
|
6
|
+
function K(t, e, n = []) {
|
|
7
|
+
return B(
|
|
8
|
+
() => G(t, e),
|
|
9
9
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
10
10
|
n
|
|
11
11
|
);
|
|
12
12
|
}
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
const E = (t) => {
|
|
14
|
+
const {
|
|
15
|
+
vocabStore: e,
|
|
16
|
+
storage: n,
|
|
17
|
+
statePath: o,
|
|
18
|
+
value: s,
|
|
19
|
+
deserialize: f,
|
|
20
|
+
serialize: a
|
|
21
|
+
} = t, c = n.getItem(o);
|
|
22
|
+
c === null ? d(s) && n.setItem(o, a(s)) : e.set(o, f(c));
|
|
23
|
+
}, w = typeof window > "u", J = w ? I : x, L = new z(), N = "Make sure your component is wrapped in StateVocabProvider (RSC) or disable ssr option in setupStorage for SPA (RCC only)";
|
|
24
|
+
function Q(t) {
|
|
25
|
+
t ??= {};
|
|
26
|
+
const e = w ? void 0 : g(t.storage), n = g(t.defaultValue), o = t.bidirectional, s = this[O], f = this[P], a = this[F], c = this[_];
|
|
27
|
+
let r = k({ verbose: f });
|
|
28
|
+
if (!(r instanceof z)) {
|
|
29
|
+
if (c)
|
|
30
|
+
throw new Error(N);
|
|
31
|
+
r = L;
|
|
32
|
+
}
|
|
33
|
+
const u = t.serialize ?? JSON.stringify, l = t.deserialize ?? JSON.parse, v = K(
|
|
34
|
+
t.onSet ?? (() => {
|
|
24
35
|
}),
|
|
25
|
-
|
|
36
|
+
t.delayedSet,
|
|
26
37
|
[]
|
|
27
|
-
),
|
|
28
|
-
if (!
|
|
29
|
-
|
|
30
|
-
let
|
|
31
|
-
d(
|
|
38
|
+
), b = V(void 0), p = V(!1);
|
|
39
|
+
if (!p.current) {
|
|
40
|
+
p.current = !0;
|
|
41
|
+
let i = r.get(s);
|
|
42
|
+
d(i) || (i = n, d(i) && r.set(s, i)), !c && e && E({
|
|
43
|
+
vocabStore: r,
|
|
44
|
+
storage: e,
|
|
45
|
+
statePath: s,
|
|
46
|
+
value: i,
|
|
47
|
+
serialize: u,
|
|
48
|
+
deserialize: l
|
|
49
|
+
});
|
|
32
50
|
}
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
51
|
+
const h = D(
|
|
52
|
+
r.subscribe.bind(r),
|
|
53
|
+
r.getClientSnapshot.bind(r),
|
|
54
|
+
r.getServerSnapshot.bind(r)
|
|
37
55
|
);
|
|
38
|
-
if (
|
|
39
|
-
if (
|
|
40
|
-
const
|
|
41
|
-
|
|
56
|
+
if (f)
|
|
57
|
+
if (a) {
|
|
58
|
+
const i = A(h, a);
|
|
59
|
+
i && C(i);
|
|
42
60
|
} else
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
!
|
|
61
|
+
C(h);
|
|
62
|
+
const m = A(h, s, n);
|
|
63
|
+
b.current = m, J(() => {
|
|
64
|
+
!c || !e || E({
|
|
65
|
+
vocabStore: r,
|
|
66
|
+
storage: e,
|
|
67
|
+
statePath: s,
|
|
68
|
+
value: m,
|
|
69
|
+
serialize: u,
|
|
70
|
+
deserialize: l
|
|
71
|
+
});
|
|
47
72
|
}, []);
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
73
|
+
const R = H((i) => {
|
|
74
|
+
if (i.key !== s)
|
|
50
75
|
return;
|
|
51
|
-
const
|
|
52
|
-
d(
|
|
76
|
+
const S = i.newValue, y = (S === null ? null : l(S)) ?? n;
|
|
77
|
+
d(y) && (r.set(s, y), v(y, b.current));
|
|
53
78
|
});
|
|
54
|
-
|
|
79
|
+
I(() => {
|
|
55
80
|
if (o)
|
|
56
|
-
return window.addEventListener("storage",
|
|
81
|
+
return window.addEventListener("storage", R), () => window.removeEventListener("storage", R);
|
|
57
82
|
}, [o]);
|
|
58
|
-
const
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
}, [
|
|
62
|
-
const
|
|
63
|
-
if (!d(
|
|
64
|
-
e?.removeItem(
|
|
83
|
+
const M = T((i) => {
|
|
84
|
+
const S = q(i) ? i(b.current) : i;
|
|
85
|
+
r.set(s, S), v(S, b.current), e && e.setItem(s, u(S));
|
|
86
|
+
}, [r, s, v, e, u]), j = T(() => {
|
|
87
|
+
const i = n;
|
|
88
|
+
if (!d(i)) {
|
|
89
|
+
e?.removeItem(s);
|
|
65
90
|
return;
|
|
66
91
|
}
|
|
67
|
-
|
|
68
|
-
}, [n,
|
|
92
|
+
r.set(s, i), v(i, b.current), e && e.setItem(s, u(i));
|
|
93
|
+
}, [n, r, s, v, e, u]);
|
|
69
94
|
return [
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
95
|
+
m,
|
|
96
|
+
M,
|
|
97
|
+
j
|
|
73
98
|
];
|
|
74
99
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
const e =
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
100
|
+
function U(t) {
|
|
101
|
+
t ??= {};
|
|
102
|
+
const e = w ? void 0 : g(t.storage), n = g(t.defaultValue), o = this[O], s = this[P], f = this[_];
|
|
103
|
+
let a = k({ verbose: s });
|
|
104
|
+
if (!(a instanceof z)) {
|
|
105
|
+
if (f)
|
|
106
|
+
throw new Error(N);
|
|
107
|
+
a = L;
|
|
108
|
+
}
|
|
109
|
+
const c = t.serialize ?? JSON.stringify, r = t.deserialize ?? JSON.parse, u = V(!1);
|
|
110
|
+
let l;
|
|
111
|
+
u.current || (u.current = !0, l = a.get(o), d(l) || (l = n, d(l) && a.set(o, l)), !f && e && E({
|
|
112
|
+
vocabStore: a,
|
|
113
|
+
storage: e,
|
|
114
|
+
statePath: o,
|
|
115
|
+
value: l,
|
|
116
|
+
serialize: c,
|
|
117
|
+
deserialize: r
|
|
118
|
+
})), J(() => {
|
|
119
|
+
!f || !e || E({
|
|
120
|
+
vocabStore: a,
|
|
121
|
+
storage: e,
|
|
122
|
+
statePath: o,
|
|
123
|
+
value: l,
|
|
124
|
+
serialize: c,
|
|
125
|
+
deserialize: r
|
|
126
|
+
});
|
|
84
127
|
}, []);
|
|
85
128
|
}
|
|
86
|
-
function
|
|
87
|
-
return typeof
|
|
129
|
+
function W(t) {
|
|
130
|
+
return typeof t == "object" && t !== null && "clientSlot" in t;
|
|
88
131
|
}
|
|
89
|
-
function
|
|
132
|
+
function X(t) {
|
|
90
133
|
const e = {};
|
|
91
|
-
for (const n in
|
|
92
|
-
const o =
|
|
93
|
-
|
|
94
|
-
useState(...
|
|
95
|
-
return
|
|
134
|
+
for (const n in t) {
|
|
135
|
+
const o = t[n];
|
|
136
|
+
W(o) ? (e[n] = o.clientSlot({
|
|
137
|
+
useState(...s) {
|
|
138
|
+
return Q.apply(this, s);
|
|
96
139
|
},
|
|
97
|
-
useInitialState(...
|
|
98
|
-
|
|
140
|
+
useInitialState(...s) {
|
|
141
|
+
U.apply(this, s);
|
|
99
142
|
}
|
|
100
|
-
}), delete e[n].serverSlot, delete e[n].clientSlot) : o !== null && typeof o == "object" ? e[n] =
|
|
143
|
+
}), delete e[n].serverSlot, delete e[n].clientSlot) : o !== null && typeof o == "object" ? e[n] = X(o) : e[n] = o;
|
|
101
144
|
}
|
|
102
145
|
return e;
|
|
103
146
|
}
|
|
104
147
|
export {
|
|
105
|
-
|
|
106
|
-
W as clientify
|
|
148
|
+
X as clientify
|
|
107
149
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const s = /* @__PURE__ */ Symbol("state-def"), t = /* @__PURE__ */ Symbol("state-path"), S = /* @__PURE__ */ Symbol("state-verbose"), a = /* @__PURE__ */ Symbol("state-verbose-path"), o = /* @__PURE__ */ Symbol("state-ssr");
|
|
2
|
+
export {
|
|
3
|
+
t as S,
|
|
4
|
+
S as a,
|
|
5
|
+
o as b,
|
|
6
|
+
a as c,
|
|
7
|
+
s as d
|
|
8
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const T=Symbol("state-def"),S=Symbol("state-path"),E=Symbol("state-verbose"),t=Symbol("state-verbose-path"),s=Symbol("state-ssr");exports.STATE_DEFINITION=T;exports.STATE_PATH=S;exports.STATE_SSR=s;exports.STATE_VERBOSE=E;exports.STATE_VERBOSE_PATH=t;
|
package/dist/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./constants-CbsduCZ7.js"),h=require("./utils-0CTNJ4ZE.js");function z(t={}){return{[r.STATE_DEFINITION]:!0,[r.STATE_PATH]:"",[r.STATE_VERBOSE]:!1,[r.STATE_VERBOSE_PATH]:"",[r.STATE_SSR]:!1,serverSlot(a){return Object.assign(this,{getState(...e){return a.getState.apply(this,e)}})},clientSlot(a){return Object.assign(this,{useState(e){return e??={},a.useState.apply(this,[{defaultValue:h.valueOrFactory(e.defaultValue)??h.valueOrFactory(t.defaultValue),bidirectional:e.bidirectional??t.bidirectional,storage:e.storage??t.storage,serialize:t.serialize??JSON.stringify,deserialize:t.deserialize??JSON.parse,delayedSet:e.delayedSet,onSet(...f){e.onSet&&e.onSet(...f)}}])},useInitialState(e){a.useInitialState.apply(this,[{defaultValue:e.defaultValue,storage:t.storage,serialize:t.serialize,deserialize:t.deserialize}])}})},toString(){return this[r.STATE_PATH]}}}function y(t,a){const{path:e="",verbose:f,verbosePath:A,ssr:b,cache:c}=a;let s=c.proxy.get(t);s||(s=new Map,c.proxy.set(t,s));const o=s.get(e);if(o)return o;const d=new Proxy(t,{get(P,T){const l=P[T],S=e?`${e}.${String(T)}`:String(T);if(l&&typeof l=="object"&&r.STATE_DEFINITION in l){const i=l;let n=c.leaf.get(i);n||(n=new Map,c.leaf.set(i,n));const g=n.get(S);if(g)return g;const _=Reflect.ownKeys(i).filter(u=>typeof i[u]=="function"),v=Object.fromEntries(_.map(u=>[u,(...V)=>i[u].call({...i,[r.STATE_PATH]:S,[r.STATE_VERBOSE]:f,[r.STATE_VERBOSE_PATH]:A,[r.STATE_SSR]:b},...V)])),E={...i,...v};return n.set(S,E),E}return l&&typeof l=="object"?y(l,{...a,path:S}):l}});return s.set(e,d),d}function I(t,a){return y(t,{...a,ssr:a?.ssr??!0,verbosePath:a?.verbosePath??"",cache:{proxy:new WeakMap,leaf:new WeakMap}})}exports.defineState=z;exports.setupStorage=I;
|
package/dist/index.es.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { S as d,
|
|
2
|
-
|
|
1
|
+
import { S as d, b as T, c as E, a as P, d as v } from "./constants-BB1YAX6c.mjs";
|
|
2
|
+
import { v as b } from "./utils-xV3x3fTc.mjs";
|
|
3
|
+
function M(t = {}) {
|
|
3
4
|
return {
|
|
4
5
|
[v]: !0,
|
|
5
6
|
// marks this object as a leaf in the router tree
|
|
@@ -62,10 +63,10 @@ function z(t, a) {
|
|
|
62
63
|
} = a;
|
|
63
64
|
let s = n.proxy.get(t);
|
|
64
65
|
s || (s = /* @__PURE__ */ new Map(), n.proxy.set(t, s));
|
|
65
|
-
const
|
|
66
|
-
if (
|
|
67
|
-
return
|
|
68
|
-
const
|
|
66
|
+
const o = s.get(e);
|
|
67
|
+
if (o)
|
|
68
|
+
return o;
|
|
69
|
+
const h = new Proxy(t, {
|
|
69
70
|
get(V, u) {
|
|
70
71
|
const r = V[u], c = e ? `${e}.${String(u)}` : String(u);
|
|
71
72
|
if (r && typeof r == "object" && v in r) {
|
|
@@ -77,10 +78,10 @@ function z(t, a) {
|
|
|
77
78
|
return g;
|
|
78
79
|
const j = Reflect.ownKeys(l).filter(
|
|
79
80
|
(f) => typeof l[f] == "function"
|
|
80
|
-
),
|
|
81
|
+
), m = Object.fromEntries(
|
|
81
82
|
j.map((f) => [
|
|
82
83
|
f,
|
|
83
|
-
(...
|
|
84
|
+
(...w) => l[f].call(
|
|
84
85
|
{
|
|
85
86
|
...l,
|
|
86
87
|
[d]: c,
|
|
@@ -88,10 +89,10 @@ function z(t, a) {
|
|
|
88
89
|
[E]: x,
|
|
89
90
|
[T]: A
|
|
90
91
|
},
|
|
91
|
-
...
|
|
92
|
+
...w
|
|
92
93
|
)
|
|
93
94
|
])
|
|
94
|
-
), y = { ...l, ...
|
|
95
|
+
), y = { ...l, ...m };
|
|
95
96
|
return i.set(c, y), y;
|
|
96
97
|
}
|
|
97
98
|
return r && typeof r == "object" ? z(r, {
|
|
@@ -100,9 +101,9 @@ function z(t, a) {
|
|
|
100
101
|
}) : r;
|
|
101
102
|
}
|
|
102
103
|
});
|
|
103
|
-
return s.set(e,
|
|
104
|
+
return s.set(e, h), h;
|
|
104
105
|
}
|
|
105
|
-
function
|
|
106
|
+
function N(t, a) {
|
|
106
107
|
return z(t, {
|
|
107
108
|
...a,
|
|
108
109
|
ssr: a?.ssr ?? !0,
|
|
@@ -114,6 +115,6 @@ function M(t, a) {
|
|
|
114
115
|
});
|
|
115
116
|
}
|
|
116
117
|
export {
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
M as defineState,
|
|
119
|
+
N as setupStorage
|
|
119
120
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";"use strict";const h=require("react/jsx-runtime"),r=require("react"),s=require("./utils-0CTNJ4ZE.js"),c=r.createContext({});function S(o){const t=r.useContext(c);return o.verbose&&console.log(`[Store uid]: ${t.uid}`),t}class u{#t;#e;constructor(t){this.uid=Math.random().toString(36).slice(2),this.#t=t??{},this.#e=new Set}subscribe(t){return this.#e.add(t),()=>this.#e.delete(t)}getClientSnapshot(){return this.#t}getServerSnapshot(){return this.#t}get(t){return s.get(this.#t,t)}set(t,e){const n=s.get(this.#t,t),a=s.isTransformer(e)?e(n):e,i={...this.#t};s.set(i,t,a),this.#t=i,this.#e.forEach(l=>l())}}function b(o){const{children:t,value:e}=o,[n]=r.useState(()=>new u(e));return h.jsx(c.Provider,{value:n,children:t})}exports.StateVocabClientProvider=b;exports.VocabStore=u;exports.useStateVocabClientContext=S;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as u } from "react/jsx-runtime";
|
|
3
3
|
import { createContext as h, useContext as l, useState as S } from "react";
|
|
4
|
-
import { g as n,
|
|
4
|
+
import { g as n, i as d, s as b } from "./utils-xV3x3fTc.mjs";
|
|
5
5
|
const i = h({});
|
|
6
|
-
function V(s
|
|
6
|
+
function V(s) {
|
|
7
7
|
const t = l(i);
|
|
8
8
|
return s.verbose && console.log(`[Store uid]: ${t.uid}`), t;
|
|
9
9
|
}
|
package/dist/server.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),S=require("./constants-CbsduCZ7.js"),d=require("react"),v=require("node:async_hooks"),f=require("./provider-client-B4XQ24JB.js"),b=require("./utils-0CTNJ4ZE.js");function y(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const r in e)if(r!=="default"){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}}return t.default=e,Object.freeze(t)}const p=y(v),a=e=>{if(d.useState)throw new Error(`${e} only intended for Server Components`)};let s=null;try{a("StateVocabServerContext"),s=new p.AsyncLocalStorage}catch{s=null}const g=({value:e})=>(s?.enterWith({value:e}),null),P=({children:e})=>e,j=async e=>{a("StateVocabServerContext.Provider");const{value:t,children:r}=e;return o.jsxs(o.Fragment,{children:[o.jsx(g,{value:t}),r]})},h=()=>(a("getStateVocab"),s?.getStore()?.value),x={Provider:s?j:P},V=({value:e,children:t})=>o.jsx(x.Provider,{value:e,children:t});function m(e){const{children:t,value:r={}}=e;return o.jsx(V,{value:r,children:o.jsx(f.StateVocabClientProvider,{value:r,children:t})})}const O="Make sure your component is wrapped in StateVocabProvider";function C(){const e=this[S.STATE_PATH],t=h();if(!t)throw new Error(O);return b.get(t,e)}function E(e){return typeof e=="object"&&e!==null&&"serverSlot"in e}function l(e,t){const r={};for(const n in e){const c=e[n];if(E(c))r[n]=c.serverSlot({getState(...i){return C.apply(this,i)}}),delete r[n].serverSlot,delete r[n].clientSlot;else if(c!==null&&typeof c=="object"){const i=u=>t({[n]:u});r[n]=l(c,i)}else r[n]=c}return r.seed=n=>t(n),r}function k(e){return{...l(e,t=>t),StateVocabProvider({children:t,value:r}){return o.jsx(m,{value:r,children:t})}}}exports.serverify=k;
|
package/dist/server.es.js
CHANGED
|
@@ -1,50 +1,52 @@
|
|
|
1
|
-
import { jsxs as u, Fragment as v, jsx as
|
|
1
|
+
import { jsxs as u, Fragment as v, jsx as c } from "react/jsx-runtime";
|
|
2
|
+
import { S as d } from "./constants-BB1YAX6c.mjs";
|
|
2
3
|
import f from "react";
|
|
3
|
-
import * as
|
|
4
|
-
import { S as
|
|
5
|
-
import {
|
|
4
|
+
import * as p from "node:async_hooks";
|
|
5
|
+
import { S as m } from "./provider-client-C2Aw0Lmi.mjs";
|
|
6
|
+
import { g as b } from "./utils-xV3x3fTc.mjs";
|
|
6
7
|
const i = (e) => {
|
|
7
8
|
if (f.useState)
|
|
8
9
|
throw new Error(`${e} only intended for Server Components`);
|
|
9
10
|
};
|
|
10
|
-
let
|
|
11
|
+
let s = null;
|
|
11
12
|
try {
|
|
12
|
-
i("StateVocabServerContext"),
|
|
13
|
+
i("StateVocabServerContext"), s = new p.AsyncLocalStorage();
|
|
13
14
|
} catch {
|
|
14
|
-
|
|
15
|
+
s = null;
|
|
15
16
|
}
|
|
16
|
-
const
|
|
17
|
+
const h = ({ value: e }) => (s?.enterWith({ value: e }), null), y = ({ children: e }) => e, P = async (e) => {
|
|
17
18
|
i("StateVocabServerContext.Provider");
|
|
18
19
|
const { value: t, children: r } = e;
|
|
19
20
|
return /* @__PURE__ */ u(v, { children: [
|
|
20
|
-
/* @__PURE__ */
|
|
21
|
+
/* @__PURE__ */ c(h, { value: t }),
|
|
21
22
|
r
|
|
22
23
|
] });
|
|
23
|
-
}, g = () => (i("getStateVocab"),
|
|
24
|
-
Provider:
|
|
25
|
-
},
|
|
26
|
-
function
|
|
24
|
+
}, g = () => (i("getStateVocab"), s?.getStore()?.value), V = {
|
|
25
|
+
Provider: s ? P : y
|
|
26
|
+
}, E = ({ value: e, children: t }) => /* @__PURE__ */ c(V.Provider, { value: e, children: t });
|
|
27
|
+
function x(e) {
|
|
27
28
|
const { children: t, value: r = {} } = e;
|
|
28
|
-
return /* @__PURE__ */
|
|
29
|
+
return /* @__PURE__ */ c(E, { value: r, children: /* @__PURE__ */ c(m, { value: r, children: t }) });
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
const C = "Make sure your component is wrapped in StateVocabProvider";
|
|
32
|
+
function w() {
|
|
33
|
+
const e = this[d], t = g();
|
|
32
34
|
if (!t)
|
|
33
|
-
throw new Error(
|
|
34
|
-
return
|
|
35
|
+
throw new Error(C);
|
|
36
|
+
return b(t, e);
|
|
35
37
|
}
|
|
36
|
-
function
|
|
38
|
+
function R(e) {
|
|
37
39
|
return typeof e == "object" && e !== null && "serverSlot" in e;
|
|
38
40
|
}
|
|
39
41
|
function l(e, t) {
|
|
40
42
|
const r = {};
|
|
41
43
|
for (const o in e) {
|
|
42
44
|
const n = e[o];
|
|
43
|
-
if (
|
|
45
|
+
if (R(n))
|
|
44
46
|
r[o] = n.serverSlot({
|
|
45
47
|
// Slot definition
|
|
46
48
|
getState(...a) {
|
|
47
|
-
return
|
|
49
|
+
return w.apply(this, a);
|
|
48
50
|
}
|
|
49
51
|
}), delete r[o].serverSlot, delete r[o].clientSlot;
|
|
50
52
|
else if (n !== null && typeof n == "object") {
|
|
@@ -53,12 +55,16 @@ function l(e, t) {
|
|
|
53
55
|
} else
|
|
54
56
|
r[o] = n;
|
|
55
57
|
}
|
|
56
|
-
return r.
|
|
58
|
+
return r.seed = (o) => t(o), r;
|
|
57
59
|
}
|
|
58
|
-
function
|
|
59
|
-
return
|
|
60
|
+
function M(e) {
|
|
61
|
+
return {
|
|
62
|
+
...l(e, (t) => t),
|
|
63
|
+
StateVocabProvider({ children: t, value: r }) {
|
|
64
|
+
return /* @__PURE__ */ c(x, { value: r, children: t });
|
|
65
|
+
}
|
|
66
|
+
};
|
|
60
67
|
}
|
|
61
68
|
export {
|
|
62
|
-
|
|
63
|
-
H as serverify
|
|
69
|
+
M as serverify
|
|
64
70
|
};
|
package/dist/types/client.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ export declare const StateVocabClientContext: import("react").Context<VocabStore
|
|
|
3
3
|
/**
|
|
4
4
|
* @see method from from https://zustand.docs.pmnd.rs/learn/guides/nextjs
|
|
5
5
|
*/
|
|
6
|
-
export declare function useStateVocabClientContext(options
|
|
7
|
-
verbose
|
|
6
|
+
export declare function useStateVocabClientContext(options: {
|
|
7
|
+
verbose: boolean;
|
|
8
8
|
}): VocabStore;
|
package/dist/types/server.d.ts
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type DependencyList } from "react";
|
|
2
|
+
import VocabStore from "./store";
|
|
3
|
+
import type { Deserialize, Serialize } from "./state.types";
|
|
4
|
+
export declare function useDebounce<T extends (...args: never[]) => unknown>(effect: T, wait: number | undefined, deps?: DependencyList): (...args: Parameters<T>) => void;
|
|
5
|
+
export declare const sync: <V>(options: {
|
|
6
|
+
vocabStore: VocabStore;
|
|
7
|
+
statePath: string;
|
|
8
|
+
storage: Storage;
|
|
9
|
+
serialize: Serialize<V>;
|
|
10
|
+
deserialize: Deserialize<V>;
|
|
11
|
+
value: V | undefined;
|
|
12
|
+
}) => void;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PropsWithChildren, ReactNode } from "react";
|
|
1
2
|
import type { Vocab } from "./state.types";
|
|
2
3
|
type Placeholder<V> = {
|
|
3
4
|
getState(): V;
|
|
@@ -9,12 +10,15 @@ type ServerifiedValue<R> = {
|
|
|
9
10
|
[K in keyof R]?: R[K] extends Slot<infer V> ? V : R[K] extends object ? ServerifiedValue<R[K]> : R[K];
|
|
10
11
|
};
|
|
11
12
|
type Serverified<R> = R extends Slot<infer TValue> ? Placeholder<TValue> : R extends object ? {
|
|
12
|
-
|
|
13
|
+
seed(input: ServerifiedValue<R>): Vocab;
|
|
13
14
|
} & {
|
|
14
15
|
[K in keyof R]: Serverified<R[K]>;
|
|
15
16
|
} : R;
|
|
16
17
|
type ServerifyResult<R extends object> = {
|
|
17
|
-
|
|
18
|
+
seed(input: ServerifiedValue<R>): Vocab;
|
|
19
|
+
StateVocabProvider(props: PropsWithChildren<{
|
|
20
|
+
value?: ServerifiedValue<R>;
|
|
21
|
+
}>): Promise<ReactNode>;
|
|
18
22
|
} & {
|
|
19
23
|
[K in keyof R]: Serverified<R[K]>;
|
|
20
24
|
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";function f(e,s,n){if(!s)return e;const o=s.split(".");let t=e;for(const c of o)if(t!==null&&typeof t=="object"&&c in t)t=t[c];else return n;return t===void 0?n:t}function y(e,s,n){const o=s.replace(/\[(\d+)\]/g,".$1").split(".");let t=e;for(let c=0;c<o.length-1;c++){const r=o[c],i=o[c+1];(t[r]===void 0||t[r]===null)&&(t[r]=/^\d+$/.test(i)?[]:{}),t=t[r]}return t[o[o.length-1]]=n,e}function d(e,s=0){let n;return function(...o){n!==void 0&&clearTimeout(n),n=setTimeout(()=>{n=void 0,e.apply(this,o)},s)}}function a(e){const s=JSON.stringify(e,null,2).split(`
|
|
2
|
+
`),n=[],o=[];for(const t of s){const c=t.match(/^(\s*)"([^"]+)"(\s*:\s*)(.+)$/);if(c){const[,r,i,l,u]=c;n.push(`${r}%c"${i}"%c${l}%c${u}`),o.push("color: #9cdcfe; font-weight: bold","color: #cccccc","color: #ce9178")}else n.push(`%c${t}`),o.push("color: #cccccc")}console.log(n.join(`
|
|
3
|
+
`),...o,e)}const p=e=>typeof e=="function",g=e=>typeof e=="function",h=e=>typeof e<"u",$=e=>g(e)?e():e;exports.debounce=d;exports.get=f;exports.isTransformer=p;exports.isValueDefined=h;exports.logStyled=a;exports.set=y;exports.valueOrFactory=$;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
function a(t, s, n) {
|
|
2
|
+
if (!s)
|
|
3
|
+
return t;
|
|
4
|
+
const o = s.split(".");
|
|
5
|
+
let e = t;
|
|
6
|
+
for (const c of o)
|
|
7
|
+
if (e !== null && typeof e == "object" && c in e)
|
|
8
|
+
e = e[c];
|
|
9
|
+
else
|
|
10
|
+
return n;
|
|
11
|
+
return e === void 0 ? n : e;
|
|
12
|
+
}
|
|
13
|
+
function y(t, s, n) {
|
|
14
|
+
const o = s.replace(/\[(\d+)\]/g, ".$1").split(".");
|
|
15
|
+
let e = t;
|
|
16
|
+
for (let c = 0; c < o.length - 1; c++) {
|
|
17
|
+
const r = o[c], i = o[c + 1];
|
|
18
|
+
(e[r] === void 0 || e[r] === null) && (e[r] = /^\d+$/.test(i) ? [] : {}), e = e[r];
|
|
19
|
+
}
|
|
20
|
+
return e[o[o.length - 1]] = n, t;
|
|
21
|
+
}
|
|
22
|
+
function d(t, s = 0) {
|
|
23
|
+
let n;
|
|
24
|
+
return function(...o) {
|
|
25
|
+
n !== void 0 && clearTimeout(n), n = setTimeout(() => {
|
|
26
|
+
n = void 0, t.apply(this, o);
|
|
27
|
+
}, s);
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function p(t) {
|
|
31
|
+
const s = JSON.stringify(t, null, 2).split(`
|
|
32
|
+
`), n = [], o = [];
|
|
33
|
+
for (const e of s) {
|
|
34
|
+
const c = e.match(/^(\s*)"([^"]+)"(\s*:\s*)(.+)$/);
|
|
35
|
+
if (c) {
|
|
36
|
+
const [, r, i, l, u] = c;
|
|
37
|
+
n.push(`${r}%c"${i}"%c${l}%c${u}`), o.push(
|
|
38
|
+
"color: #9cdcfe; font-weight: bold",
|
|
39
|
+
"color: #cccccc",
|
|
40
|
+
"color: #ce9178"
|
|
41
|
+
);
|
|
42
|
+
} else
|
|
43
|
+
n.push(`%c${e}`), o.push("color: #cccccc");
|
|
44
|
+
}
|
|
45
|
+
console.log(n.join(`
|
|
46
|
+
`), ...o, t);
|
|
47
|
+
}
|
|
48
|
+
const g = (t) => typeof t == "function", f = (t) => typeof t == "function", h = (t) => typeof t < "u", $ = (t) => f(t) ? t() : t;
|
|
49
|
+
export {
|
|
50
|
+
h as a,
|
|
51
|
+
d,
|
|
52
|
+
a as g,
|
|
53
|
+
g as i,
|
|
54
|
+
p as l,
|
|
55
|
+
y as s,
|
|
56
|
+
$ as v
|
|
57
|
+
};
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use client";"use strict";const h=require("react/jsx-runtime"),r=require("react"),s=require("./utils-33NqsZoR.js"),c=r.createContext({});function S(o={}){const t=r.useContext(c);return o.verbose&&console.log(`[Store uid]: ${t.uid}`),t}class u{#t;#e;constructor(t){this.uid=Math.random().toString(36).slice(2),this.#t=t??{},this.#e=new Set}subscribe(t){return this.#e.add(t),()=>this.#e.delete(t)}getClientSnapshot(){return this.#t}getServerSnapshot(){return this.#t}get(t){return s.get(this.#t,t)}set(t,e){const n=s.get(this.#t,t),a=s.isTransformer(e)?e(n):e,i={...this.#t};s.set(i,t,a),this.#t=i,this.#e.forEach(l=>l())}}function b(o){const{children:t,value:e}=o,[n]=r.useState(()=>new u(e));return h.jsx(c.Provider,{value:n,children:t})}exports.StateVocabClientProvider=b;exports.VocabStore=u;exports.useStateVocabClientContext=S;
|
package/dist/utils-33NqsZoR.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
"use strict";const T=Symbol("state-def"),f=Symbol("state-path"),S=Symbol("state-verbose"),y=Symbol("state-verbose-path"),a=Symbol("state-ssr");function E(t,s,o){if(!s)return t;const n=s.split(".");let e=t;for(const c of n)if(e!==null&&typeof e=="object"&&c in e)e=e[c];else return o;return e===void 0?o:e}function d(t,s,o){const n=s.replace(/\[(\d+)\]/g,".$1").split(".");let e=t;for(let c=0;c<n.length-1;c++){const r=n[c],l=n[c+1];(e[r]===void 0||e[r]===null)&&(e[r]=/^\d+$/.test(l)?[]:{}),e=e[r]}return e[n[n.length-1]]=o,t}function p(t,s=0){let o;return function(...n){o!==void 0&&clearTimeout(o),o=setTimeout(()=>{o=void 0,t.apply(this,n)},s)}}function A(t){const s=JSON.stringify(t,null,2).split(`
|
|
2
|
-
`),o=[],n=[];for(const e of s){const c=e.match(/^(\s*)"([^"]+)"(\s*:\s*)(.+)$/);if(c){const[,r,l,i,u]=c;o.push(`${r}%c"${l}"%c${i}%c${u}`),n.push("color: #9cdcfe; font-weight: bold","color: #cccccc","color: #ce9178")}else o.push(`%c${e}`),n.push("color: #cccccc")}console.log(o.join(`
|
|
3
|
-
`),...n,t)}const m=t=>typeof t=="function",_=t=>typeof t=="function",h=t=>typeof t<"u",g=t=>_(t)?t():t;exports.STATE_DEFINITION=T;exports.STATE_PATH=f;exports.STATE_SSR=a;exports.STATE_VERBOSE=S;exports.STATE_VERBOSE_PATH=y;exports.debounce=p;exports.get=E;exports.isTransformer=m;exports.isValueDefined=h;exports.logStyled=A;exports.set=d;exports.valueOrFactory=g;
|
package/dist/utils-t8tYdd6B.mjs
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
const u = /* @__PURE__ */ Symbol("state-def"), y = /* @__PURE__ */ Symbol("state-path"), S = /* @__PURE__ */ Symbol("state-verbose"), d = /* @__PURE__ */ Symbol("state-verbose-path"), T = /* @__PURE__ */ Symbol("state-ssr");
|
|
2
|
-
function p(t, c, s) {
|
|
3
|
-
if (!c)
|
|
4
|
-
return t;
|
|
5
|
-
const o = c.split(".");
|
|
6
|
-
let e = t;
|
|
7
|
-
for (const n of o)
|
|
8
|
-
if (e !== null && typeof e == "object" && n in e)
|
|
9
|
-
e = e[n];
|
|
10
|
-
else
|
|
11
|
-
return s;
|
|
12
|
-
return e === void 0 ? s : e;
|
|
13
|
-
}
|
|
14
|
-
function h(t, c, s) {
|
|
15
|
-
const o = c.replace(/\[(\d+)\]/g, ".$1").split(".");
|
|
16
|
-
let e = t;
|
|
17
|
-
for (let n = 0; n < o.length - 1; n++) {
|
|
18
|
-
const r = o[n], l = o[n + 1];
|
|
19
|
-
(e[r] === void 0 || e[r] === null) && (e[r] = /^\d+$/.test(l) ? [] : {}), e = e[r];
|
|
20
|
-
}
|
|
21
|
-
return e[o[o.length - 1]] = s, t;
|
|
22
|
-
}
|
|
23
|
-
function m(t, c = 0) {
|
|
24
|
-
let s;
|
|
25
|
-
return function(...o) {
|
|
26
|
-
s !== void 0 && clearTimeout(s), s = setTimeout(() => {
|
|
27
|
-
s = void 0, t.apply(this, o);
|
|
28
|
-
}, c);
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
function E(t) {
|
|
32
|
-
const c = JSON.stringify(t, null, 2).split(`
|
|
33
|
-
`), s = [], o = [];
|
|
34
|
-
for (const e of c) {
|
|
35
|
-
const n = e.match(/^(\s*)"([^"]+)"(\s*:\s*)(.+)$/);
|
|
36
|
-
if (n) {
|
|
37
|
-
const [, r, l, i, a] = n;
|
|
38
|
-
s.push(`${r}%c"${l}"%c${i}%c${a}`), o.push(
|
|
39
|
-
"color: #9cdcfe; font-weight: bold",
|
|
40
|
-
"color: #cccccc",
|
|
41
|
-
"color: #ce9178"
|
|
42
|
-
);
|
|
43
|
-
} else
|
|
44
|
-
s.push(`%c${e}`), o.push("color: #cccccc");
|
|
45
|
-
}
|
|
46
|
-
console.log(s.join(`
|
|
47
|
-
`), ...o, t);
|
|
48
|
-
}
|
|
49
|
-
const g = (t) => typeof t == "function", f = (t) => typeof t == "function", v = (t) => typeof t < "u", b = (t) => f(t) ? t() : t;
|
|
50
|
-
export {
|
|
51
|
-
y as S,
|
|
52
|
-
S as a,
|
|
53
|
-
T as b,
|
|
54
|
-
d as c,
|
|
55
|
-
m as d,
|
|
56
|
-
g as e,
|
|
57
|
-
u as f,
|
|
58
|
-
p as g,
|
|
59
|
-
v as i,
|
|
60
|
-
E as l,
|
|
61
|
-
h as s,
|
|
62
|
-
b as v
|
|
63
|
-
};
|