@yakocloud/state-vocab 4.0.2 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +158 -8
- package/dist/client.cjs.js +1 -1
- package/dist/client.es.js +106 -94
- package/dist/provider-client-CAHe8VnM.js +1 -0
- package/dist/provider-client-D0BmMWcY.mjs +41 -0
- package/dist/server.cjs.js +1 -1
- package/dist/server.es.js +86 -52
- package/dist/types/client.d.ts +1 -0
- package/dist/types/context.client.d.ts +3 -1
- package/dist/types/context.server.d.ts +4 -2
- package/dist/types/provider.client.d.ts +3 -1
- package/dist/types/provider.d.ts +4 -1
- package/dist/types/provider.server.d.ts +1 -0
- package/dist/types/setup.client.d.ts +8 -2
- package/dist/types/setup.server.d.ts +4 -2
- package/dist/types/state.d.ts +1 -3
- package/package.json +1 -1
- package/dist/provider-client-B4XQ24JB.js +0 -1
- package/dist/provider-client-C2Aw0Lmi.mjs +0 -41
package/README.md
CHANGED
|
@@ -260,6 +260,81 @@ By default `ssr: true`:
|
|
|
260
260
|
|
|
261
261
|
This guarantees the server and client produce identical markup, and the value from storage is applied without a visible flash.
|
|
262
262
|
|
|
263
|
+
### Next.js Pages Router (SSR without RSC)
|
|
264
|
+
|
|
265
|
+
If you use Next.js with the **Pages Router** (or any SSR setup without React Server Components), you still need `ssr: true` to prevent hydration mismatches — but you don't have server components to wrap with `StateVocabProvider` from `serverify`.
|
|
266
|
+
|
|
267
|
+
In this case, wrap your app with `StateVocabClientProvider` from `@yakocloud/state-vocab/client`. It creates an isolated `VocabStore` per render, preventing state from leaking between concurrent SSR requests.
|
|
268
|
+
|
|
269
|
+
```tsx
|
|
270
|
+
// pages/_app.tsx
|
|
271
|
+
import type { AppProps } from 'next/app'
|
|
272
|
+
import { StateVocabClientProvider } from '@yakocloud/state-vocab/client'
|
|
273
|
+
|
|
274
|
+
export default function App({ Component, pageProps }: AppProps) {
|
|
275
|
+
return (
|
|
276
|
+
<StateVocabClientProvider>
|
|
277
|
+
<Component {...pageProps} />
|
|
278
|
+
</StateVocabClientProvider>
|
|
279
|
+
)
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Storage is still configured with `ssr: true` (the default):
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
// lib/storage.ts
|
|
287
|
+
import { setupStorage, defineState } from '@yakocloud/state-vocab'
|
|
288
|
+
import { clientify } from '@yakocloud/state-vocab/client'
|
|
289
|
+
|
|
290
|
+
const storage = setupStorage({
|
|
291
|
+
preference: {
|
|
292
|
+
theme: defineState<'Dark' | 'White' | 'System'>({
|
|
293
|
+
storage: localStorage,
|
|
294
|
+
defaultValue: 'Dark',
|
|
295
|
+
}),
|
|
296
|
+
},
|
|
297
|
+
// ssr: true is the default — storage reads are deferred until after hydration
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
export const clientStorage = clientify(storage)
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
Use `clientStorage` directly in any page or component — no additional wiring needed:
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
// pages/settings.tsx
|
|
307
|
+
import { clientStorage } from '@/lib/storage'
|
|
308
|
+
|
|
309
|
+
export default function Settings() {
|
|
310
|
+
const [theme, setTheme] = clientStorage.preference.theme.useState()
|
|
311
|
+
|
|
312
|
+
return (
|
|
313
|
+
<select value={theme} onChange={(e) => setTheme(e.target.value as 'Dark' | 'White' | 'System')}>
|
|
314
|
+
<option value="Dark">Dark</option>
|
|
315
|
+
<option value="White">White</option>
|
|
316
|
+
<option value="System">System</option>
|
|
317
|
+
</select>
|
|
318
|
+
)
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
`StateVocabClientProvider` also accepts an optional `value` prop to pre-seed the store with server-fetched data (e.g., from `getServerSideProps`):
|
|
323
|
+
|
|
324
|
+
```tsx
|
|
325
|
+
// pages/_app.tsx
|
|
326
|
+
import type { AppProps } from 'next/app'
|
|
327
|
+
import { StateVocabClientProvider } from '@yakocloud/state-vocab/client'
|
|
328
|
+
|
|
329
|
+
export default function App({ Component, pageProps }: AppProps) {
|
|
330
|
+
return (
|
|
331
|
+
<StateVocabClientProvider value={pageProps.initialVocab}>
|
|
332
|
+
<Component {...pageProps} />
|
|
333
|
+
</StateVocabClientProvider>
|
|
334
|
+
)
|
|
335
|
+
}
|
|
336
|
+
```
|
|
337
|
+
|
|
263
338
|
### React Server Components (RSC)
|
|
264
339
|
|
|
265
340
|
For Next.js apps using the App Router, state-vocab provides dedicated server and client entry points that let you read state in async server components and pass it down to client components via `StateVocabProvider`.
|
|
@@ -270,7 +345,7 @@ For Next.js apps using the App Router, state-vocab provides dedicated server and
|
|
|
270
345
|
|---|---|
|
|
271
346
|
| `@yakocloud/state-vocab` | Shared files — `defineState`, `setupStorage` |
|
|
272
347
|
| `@yakocloud/state-vocab/server` | Server Components — `serverify` |
|
|
273
|
-
| `@yakocloud/state-vocab/client` | Client Components — `clientify` |
|
|
348
|
+
| `@yakocloud/state-vocab/client` | Client Components — `clientify`, `StateVocabClientProvider` |
|
|
274
349
|
|
|
275
350
|
**1. Define the shared storage schema** (used on both server and client):
|
|
276
351
|
|
|
@@ -291,14 +366,28 @@ export const storage = setupStorage({
|
|
|
291
366
|
})
|
|
292
367
|
```
|
|
293
368
|
|
|
294
|
-
**2. Create server and client storage handles:**
|
|
369
|
+
**2. Create a client context, then create server and client storage handles:**
|
|
370
|
+
|
|
371
|
+
Each storage tree needs its own React context so that multiple independent providers can coexist on the same page without their state bleeding into each other.
|
|
372
|
+
|
|
373
|
+
```ts
|
|
374
|
+
// storage.context.client.ts ("use client")
|
|
375
|
+
"use client"
|
|
376
|
+
|
|
377
|
+
import { createContext } from 'react'
|
|
378
|
+
|
|
379
|
+
export const StorageClientContext = createContext({})
|
|
380
|
+
```
|
|
295
381
|
|
|
296
382
|
```ts
|
|
297
383
|
// storage.server.ts
|
|
298
384
|
import { storage } from '@/storage'
|
|
299
385
|
import { serverify } from '@yakocloud/state-vocab/server'
|
|
386
|
+
import { StorageClientContext } from '@/storage.context.client'
|
|
300
387
|
|
|
301
|
-
export const serverStorage = serverify(storage
|
|
388
|
+
export const serverStorage = serverify(storage, {
|
|
389
|
+
clientContext: StorageClientContext,
|
|
390
|
+
})
|
|
302
391
|
```
|
|
303
392
|
|
|
304
393
|
```ts
|
|
@@ -307,8 +396,11 @@ export const serverStorage = serverify(storage)
|
|
|
307
396
|
|
|
308
397
|
import { storage } from '@/storage'
|
|
309
398
|
import { clientify } from '@yakocloud/state-vocab/client'
|
|
399
|
+
import { StorageClientContext } from '@/storage.context.client'
|
|
310
400
|
|
|
311
|
-
export const clientStorage = clientify(storage
|
|
401
|
+
export const clientStorage = clientify(storage, {
|
|
402
|
+
clientContext: StorageClientContext,
|
|
403
|
+
})
|
|
312
404
|
```
|
|
313
405
|
|
|
314
406
|
**3. Seed initial state in the server component and read it in Server and Client children:**
|
|
@@ -362,6 +454,40 @@ export default function UserInfoClient() {
|
|
|
362
454
|
}
|
|
363
455
|
```
|
|
364
456
|
|
|
457
|
+
#### Multiple independent storage trees
|
|
458
|
+
|
|
459
|
+
Because each `serverify`/`clientify` pair is bound to its own context, you can have multiple independent providers active at the same time — for example, a layout-level store and a page-level store — without them interfering with each other:
|
|
460
|
+
|
|
461
|
+
```ts
|
|
462
|
+
// layout.context.client.ts ("use client")
|
|
463
|
+
export const LayoutClientContext = createContext({})
|
|
464
|
+
|
|
465
|
+
// page.context.client.ts ("use client")
|
|
466
|
+
export const PageClientContext = createContext({})
|
|
467
|
+
|
|
468
|
+
// layout.storage.server.ts
|
|
469
|
+
export const layoutServerStorage = serverify(layoutStorage, {
|
|
470
|
+
clientContext: LayoutClientContext
|
|
471
|
+
})
|
|
472
|
+
|
|
473
|
+
// layout.storage.client.ts ("use client")
|
|
474
|
+
export const layoutClientStorage = clientify(layoutStorage, {
|
|
475
|
+
clientContext: LayoutClientContext
|
|
476
|
+
})
|
|
477
|
+
|
|
478
|
+
// page.storage.server.ts
|
|
479
|
+
export const pageServerStorage = serverify(pageStorage, {
|
|
480
|
+
clientContext: PageClientContext
|
|
481
|
+
})
|
|
482
|
+
|
|
483
|
+
// page.storage.client.ts ("use client")
|
|
484
|
+
export const pageClientStorage = clientify(pageStorage, {
|
|
485
|
+
clientContext: PageClientContext
|
|
486
|
+
})
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Each `StateVocabProvider` wraps its own subtree; a component that calls `pageClientStorage.user.name.useState()` reads only from the nearest `pageServerStorage.StateVocabProvider`, not from the layout provider.
|
|
490
|
+
|
|
365
491
|
#### `serverify(storage)`
|
|
366
492
|
|
|
367
493
|
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.
|
|
@@ -607,15 +733,33 @@ const { StateVocabProvider } = serverStorage
|
|
|
607
733
|
</StateVocabProvider>
|
|
608
734
|
```
|
|
609
735
|
|
|
610
|
-
### `
|
|
736
|
+
### `StateVocabClientProvider`
|
|
737
|
+
|
|
738
|
+
A client-only provider for SSR setups **without** React Server Components (e.g. Next.js Pages Router). Import from `@yakocloud/state-vocab/client` and place it at your app root to ensure per-request store isolation. Accepts an optional `value` prop to pre-seed the store.
|
|
739
|
+
|
|
740
|
+
```tsx
|
|
741
|
+
import { StateVocabClientProvider } from '@yakocloud/state-vocab/client'
|
|
742
|
+
|
|
743
|
+
<StateVocabClientProvider value={initialVocab}>
|
|
744
|
+
<App />
|
|
745
|
+
</StateVocabClientProvider>
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
### `serverify<T>(storage: T, options)`
|
|
611
749
|
|
|
612
750
|
Converts a storage tree to its server-side counterpart. Available from `@yakocloud/state-vocab/server`.
|
|
613
751
|
|
|
752
|
+
| Option | Type | Description |
|
|
753
|
+
|---|---|---|
|
|
754
|
+
| `clientContext` | `Context<object>` | **Required.** A React context created with `createContext({})` in a `"use client"` file. Must match the `clientContext` passed to `clientify` for the same storage tree. |
|
|
755
|
+
|
|
614
756
|
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`.
|
|
615
757
|
|
|
616
758
|
```ts
|
|
617
759
|
import { serverify } from '@yakocloud/state-vocab/server'
|
|
618
|
-
|
|
760
|
+
import { MyClientContext } from '@/storage.context.client'
|
|
761
|
+
|
|
762
|
+
const serverStorage = serverify(storage, { clientContext: MyClientContext })
|
|
619
763
|
|
|
620
764
|
const { StateVocabProvider } = serverStorage // server-aware provider
|
|
621
765
|
|
|
@@ -625,15 +769,21 @@ serverStorage.person.address.seed({ city: 'NY' }) // → { person: { address:
|
|
|
625
769
|
serverStorage.seed({ user: { name: 'Alice' } }) // → { user: { name: 'Alice' } } (identity)
|
|
626
770
|
```
|
|
627
771
|
|
|
628
|
-
### `clientify<T>(storage: T)`
|
|
772
|
+
### `clientify<T>(storage: T, options?)`
|
|
629
773
|
|
|
630
774
|
Converts a storage tree to its client-side counterpart. Available from `@yakocloud/state-vocab/client`.
|
|
631
775
|
|
|
776
|
+
| Option | Type | Description |
|
|
777
|
+
|---|---|---|
|
|
778
|
+
| `clientContext` | `Context<object> \| undefined` | The React context created with `createContext({})` for this storage tree. Must match the `clientContext` passed to `serverify`. Required when using RSC; omit for SPA-only setups. |
|
|
779
|
+
|
|
632
780
|
Each leaf gains `.useState()` and `.useInitialState()`. The tree structure mirrors the original.
|
|
633
781
|
|
|
634
782
|
```ts
|
|
635
783
|
import { clientify } from '@yakocloud/state-vocab/client'
|
|
636
|
-
|
|
784
|
+
import { MyClientContext } from '@/storage.context.client'
|
|
785
|
+
|
|
786
|
+
const clientStorage = clientify(storage, { clientContext: MyClientContext })
|
|
637
787
|
|
|
638
788
|
// In a "use client" component:
|
|
639
789
|
const [name] = clientStorage.user.name.useState()
|
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 f=require("react"),v=require("./constants-CbsduCZ7.js"),a=require("./utils-0CTNJ4ZE.js"),V=require("./provider-client-CAHe8VnM.js");function D(t,n,s=[]){return f.useMemo(()=>a.debounce(t,n),s)}const y=t=>{const{vocabStore:n,storage:s,statePath:o,value:e,deserialize:l,serialize:c}=t,d=s.getItem(o);d===null?a.isValueDefined(e)&&s.setItem(o,c(e)):n.set(o,l(d))},R=typeof window>"u",m=R?f.useEffect:f.useLayoutEffect,A=new V.VocabStore,P="Make sure your component is wrapped in StateVocabProvider (RSC) or disable ssr option in setupStorage for SPA (RCC only)";function I(t){const n=R?void 0:a.valueOrFactory(t.storage),s=a.valueOrFactory(t.defaultValue),o=t.bidirectional,e=this[v.STATE_PATH],l=this[v.STATE_VERBOSE],c=this[v.STATE_VERBOSE_PATH],d=this[v.STATE_SSR];let i=V.useStateVocabClientContext({clientContext:t.clientContext,verbose:l});if(!(i instanceof V.VocabStore)){if(d)throw new Error(P);i=A}const S=t.serialize??JSON.stringify,u=t.deserialize??JSON.parse,E=D(t.onSet??(()=>{}),t.delayedSet,[]),g=f.useRef(void 0),z=f.useRef(!1);if(!z.current){z.current=!0;let r=i.get(e);a.isValueDefined(r)||(r=s,a.isValueDefined(r)&&i.set(e,r)),!d&&n&&y({vocabStore:i,storage:n,statePath:e,value:r,serialize:S,deserialize:u})}const C=f.useSyncExternalStore(i.subscribe.bind(i),i.getClientSnapshot.bind(i),i.getServerSnapshot.bind(i));if(l)if(c){const r=a.get(C,c);r&&a.logStyled(r)}else a.logStyled(C);const h=a.get(C,e,s);g.current=h,m(()=>{!d||!n||y({vocabStore:i,storage:n,statePath:e,value:h,serialize:S,deserialize:u})},[]);const w=f.useEffectEvent(r=>{if(r.key!==e)return;const b=r.newValue,T=(b===null?null:u(b))??s;a.isValueDefined(T)&&(i.set(e,T),E(T,g.current))});f.useEffect(()=>{if(o)return window.addEventListener("storage",w),()=>window.removeEventListener("storage",w)},[o]);const x=f.useCallback(r=>{const b=a.isTransformer(r)?r(g.current):r;i.set(e,b),E(b,g.current),n&&n.setItem(e,S(b))},[i,e,E,n,S]),_=f.useCallback(()=>{const r=s;if(!a.isValueDefined(r)){n?.removeItem(e);return}i.set(e,r),E(r,g.current),n&&n.setItem(e,S(r))},[s,i,e,E,n,S]);return[h,x,_]}function p(t){const n=R?void 0:a.valueOrFactory(t.storage),s=a.valueOrFactory(t.defaultValue),o=this[v.STATE_PATH],e=this[v.STATE_VERBOSE],l=this[v.STATE_SSR];let c=V.useStateVocabClientContext({clientContext:t.clientContext,verbose:e});if(!(c instanceof V.VocabStore)){if(l)throw new Error(P);c=A}const d=t.serialize??JSON.stringify,i=t.deserialize??JSON.parse,S=f.useRef(!1);let u;S.current||(S.current=!0,u=c.get(o),a.isValueDefined(u)||(u=s,a.isValueDefined(u)&&c.set(o,u)),!l&&n&&y({vocabStore:c,storage:n,statePath:o,value:u,serialize:d,deserialize:i})),m(()=>{!l||!n||y({vocabStore:c,storage:n,statePath:o,value:u,serialize:d,deserialize:i})},[])}function k(t){return typeof t=="object"&&t!==null&&"clientSlot"in t}function O(t,n={}){const s={};for(const o in t){const e=t[o];k(e)?(s[o]=e.clientSlot({useState(l){return I.apply(this,[{clientContext:n.clientContext,...l}])},useInitialState(l){p.apply(this,[{clientContext:n.clientContext,...l}])}}),delete s[o].serverSlot,delete s[o].clientSlot):e!==null&&typeof e=="object"?s[o]=O(e,n):s[o]=e}return s}exports.StateVocabClientProvider=V.StateVocabClientProvider;exports.clientify=O;
|
package/dist/client.es.js
CHANGED
|
@@ -1,127 +1,132 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useMemo as
|
|
3
|
-
import { S as
|
|
4
|
-
import { a as d, d as G, v as g, g as
|
|
5
|
-
import { V as
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { useMemo as j, useRef as y, useSyncExternalStore as B, useEffectEvent as D, useEffect as P, useCallback as p, useLayoutEffect as H } from "react";
|
|
3
|
+
import { S as A, a as I, b as O, c as F } from "./constants-BB1YAX6c.mjs";
|
|
4
|
+
import { a as d, d as G, v as g, g as T, l as x, i as q } from "./utils-xV3x3fTc.mjs";
|
|
5
|
+
import { V as C, u as _ } from "./provider-client-D0BmMWcY.mjs";
|
|
6
|
+
import { S as ne } from "./provider-client-D0BmMWcY.mjs";
|
|
7
|
+
function K(t, s, i = []) {
|
|
8
|
+
return j(
|
|
9
|
+
() => G(t, s),
|
|
9
10
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
10
|
-
|
|
11
|
+
i
|
|
11
12
|
);
|
|
12
13
|
}
|
|
13
14
|
const E = (t) => {
|
|
14
15
|
const {
|
|
15
|
-
vocabStore:
|
|
16
|
-
storage:
|
|
16
|
+
vocabStore: s,
|
|
17
|
+
storage: i,
|
|
17
18
|
statePath: o,
|
|
18
|
-
value:
|
|
19
|
-
deserialize:
|
|
20
|
-
serialize:
|
|
21
|
-
} = t,
|
|
22
|
-
|
|
23
|
-
},
|
|
19
|
+
value: e,
|
|
20
|
+
deserialize: a,
|
|
21
|
+
serialize: l
|
|
22
|
+
} = t, u = i.getItem(o);
|
|
23
|
+
u === null ? d(e) && i.setItem(o, l(e)) : s.set(o, a(u));
|
|
24
|
+
}, z = typeof window > "u", k = z ? P : H, J = new C(), L = "Make sure your component is wrapped in StateVocabProvider (RSC) or disable ssr option in setupStorage for SPA (RCC only)";
|
|
24
25
|
function Q(t) {
|
|
25
|
-
t
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
const s = z ? void 0 : g(t.storage), i = g(t.defaultValue), o = t.bidirectional, e = this[A], a = this[I], l = this[F], u = this[O];
|
|
27
|
+
let r = _({
|
|
28
|
+
clientContext: t.clientContext,
|
|
29
|
+
verbose: a
|
|
30
|
+
});
|
|
31
|
+
if (!(r instanceof C)) {
|
|
32
|
+
if (u)
|
|
33
|
+
throw new Error(L);
|
|
34
|
+
r = J;
|
|
32
35
|
}
|
|
33
|
-
const
|
|
36
|
+
const f = t.serialize ?? JSON.stringify, c = t.deserialize ?? JSON.parse, v = K(
|
|
34
37
|
t.onSet ?? (() => {
|
|
35
38
|
}),
|
|
36
39
|
t.delayedSet,
|
|
37
40
|
[]
|
|
38
|
-
), b =
|
|
39
|
-
if (!
|
|
40
|
-
|
|
41
|
-
let
|
|
42
|
-
d(
|
|
41
|
+
), b = y(void 0), w = y(!1);
|
|
42
|
+
if (!w.current) {
|
|
43
|
+
w.current = !0;
|
|
44
|
+
let n = r.get(e);
|
|
45
|
+
d(n) || (n = i, d(n) && r.set(e, n)), !u && s && E({
|
|
43
46
|
vocabStore: r,
|
|
44
|
-
storage:
|
|
45
|
-
statePath:
|
|
46
|
-
value:
|
|
47
|
-
serialize:
|
|
48
|
-
deserialize:
|
|
47
|
+
storage: s,
|
|
48
|
+
statePath: e,
|
|
49
|
+
value: n,
|
|
50
|
+
serialize: f,
|
|
51
|
+
deserialize: c
|
|
49
52
|
});
|
|
50
53
|
}
|
|
51
|
-
const h =
|
|
54
|
+
const h = B(
|
|
52
55
|
r.subscribe.bind(r),
|
|
53
56
|
r.getClientSnapshot.bind(r),
|
|
54
57
|
r.getServerSnapshot.bind(r)
|
|
55
58
|
);
|
|
56
|
-
if (
|
|
57
|
-
if (
|
|
58
|
-
const
|
|
59
|
-
|
|
59
|
+
if (a)
|
|
60
|
+
if (l) {
|
|
61
|
+
const n = T(h, l);
|
|
62
|
+
n && x(n);
|
|
60
63
|
} else
|
|
61
|
-
|
|
62
|
-
const m =
|
|
63
|
-
b.current = m,
|
|
64
|
-
!
|
|
64
|
+
x(h);
|
|
65
|
+
const m = T(h, e, i);
|
|
66
|
+
b.current = m, k(() => {
|
|
67
|
+
!u || !s || E({
|
|
65
68
|
vocabStore: r,
|
|
66
|
-
storage:
|
|
67
|
-
statePath:
|
|
69
|
+
storage: s,
|
|
70
|
+
statePath: e,
|
|
68
71
|
value: m,
|
|
69
|
-
serialize:
|
|
70
|
-
deserialize:
|
|
72
|
+
serialize: f,
|
|
73
|
+
deserialize: c
|
|
71
74
|
});
|
|
72
75
|
}, []);
|
|
73
|
-
const R =
|
|
74
|
-
if (
|
|
76
|
+
const R = D((n) => {
|
|
77
|
+
if (n.key !== e)
|
|
75
78
|
return;
|
|
76
|
-
const S =
|
|
77
|
-
d(
|
|
79
|
+
const S = n.newValue, V = (S === null ? null : c(S)) ?? i;
|
|
80
|
+
d(V) && (r.set(e, V), v(V, b.current));
|
|
78
81
|
});
|
|
79
|
-
|
|
82
|
+
P(() => {
|
|
80
83
|
if (o)
|
|
81
84
|
return window.addEventListener("storage", R), () => window.removeEventListener("storage", R);
|
|
82
85
|
}, [o]);
|
|
83
|
-
const
|
|
84
|
-
const S = q(
|
|
85
|
-
r.set(
|
|
86
|
-
}, [r,
|
|
87
|
-
const
|
|
88
|
-
if (!d(
|
|
89
|
-
|
|
86
|
+
const N = p((n) => {
|
|
87
|
+
const S = q(n) ? n(b.current) : n;
|
|
88
|
+
r.set(e, S), v(S, b.current), s && s.setItem(e, f(S));
|
|
89
|
+
}, [r, e, v, s, f]), M = p(() => {
|
|
90
|
+
const n = i;
|
|
91
|
+
if (!d(n)) {
|
|
92
|
+
s?.removeItem(e);
|
|
90
93
|
return;
|
|
91
94
|
}
|
|
92
|
-
r.set(
|
|
93
|
-
}, [
|
|
95
|
+
r.set(e, n), v(n, b.current), s && s.setItem(e, f(n));
|
|
96
|
+
}, [i, r, e, v, s, f]);
|
|
94
97
|
return [
|
|
95
98
|
m,
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
N,
|
|
100
|
+
M
|
|
98
101
|
];
|
|
99
102
|
}
|
|
100
103
|
function U(t) {
|
|
101
|
-
t
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
a
|
|
104
|
+
const s = z ? void 0 : g(t.storage), i = g(t.defaultValue), o = this[A], e = this[I], a = this[O];
|
|
105
|
+
let l = _({
|
|
106
|
+
clientContext: t.clientContext,
|
|
107
|
+
verbose: e
|
|
108
|
+
});
|
|
109
|
+
if (!(l instanceof C)) {
|
|
110
|
+
if (a)
|
|
111
|
+
throw new Error(L);
|
|
112
|
+
l = J;
|
|
108
113
|
}
|
|
109
|
-
const
|
|
110
|
-
let
|
|
111
|
-
|
|
112
|
-
vocabStore:
|
|
113
|
-
storage:
|
|
114
|
+
const u = t.serialize ?? JSON.stringify, r = t.deserialize ?? JSON.parse, f = y(!1);
|
|
115
|
+
let c;
|
|
116
|
+
f.current || (f.current = !0, c = l.get(o), d(c) || (c = i, d(c) && l.set(o, c)), !a && s && E({
|
|
117
|
+
vocabStore: l,
|
|
118
|
+
storage: s,
|
|
114
119
|
statePath: o,
|
|
115
|
-
value:
|
|
116
|
-
serialize:
|
|
120
|
+
value: c,
|
|
121
|
+
serialize: u,
|
|
117
122
|
deserialize: r
|
|
118
|
-
})),
|
|
119
|
-
!
|
|
120
|
-
vocabStore:
|
|
121
|
-
storage:
|
|
123
|
+
})), k(() => {
|
|
124
|
+
!a || !s || E({
|
|
125
|
+
vocabStore: l,
|
|
126
|
+
storage: s,
|
|
122
127
|
statePath: o,
|
|
123
|
-
value:
|
|
124
|
-
serialize:
|
|
128
|
+
value: c,
|
|
129
|
+
serialize: u,
|
|
125
130
|
deserialize: r
|
|
126
131
|
});
|
|
127
132
|
}, []);
|
|
@@ -129,21 +134,28 @@ function U(t) {
|
|
|
129
134
|
function W(t) {
|
|
130
135
|
return typeof t == "object" && t !== null && "clientSlot" in t;
|
|
131
136
|
}
|
|
132
|
-
function X(t) {
|
|
133
|
-
const
|
|
134
|
-
for (const
|
|
135
|
-
const
|
|
136
|
-
W(
|
|
137
|
-
useState(
|
|
138
|
-
return Q.apply(this,
|
|
137
|
+
function X(t, s = {}) {
|
|
138
|
+
const i = {};
|
|
139
|
+
for (const o in t) {
|
|
140
|
+
const e = t[o];
|
|
141
|
+
W(e) ? (i[o] = e.clientSlot({
|
|
142
|
+
useState(a) {
|
|
143
|
+
return Q.apply(this, [{
|
|
144
|
+
clientContext: s.clientContext,
|
|
145
|
+
...a
|
|
146
|
+
}]);
|
|
139
147
|
},
|
|
140
|
-
useInitialState(
|
|
141
|
-
U.apply(this,
|
|
148
|
+
useInitialState(a) {
|
|
149
|
+
U.apply(this, [{
|
|
150
|
+
clientContext: s.clientContext,
|
|
151
|
+
...a
|
|
152
|
+
}]);
|
|
142
153
|
}
|
|
143
|
-
}), delete
|
|
154
|
+
}), delete i[o].serverSlot, delete i[o].clientSlot) : e !== null && typeof e == "object" ? i[o] = X(e, s) : i[o] = e;
|
|
144
155
|
}
|
|
145
|
-
return
|
|
156
|
+
return i;
|
|
146
157
|
}
|
|
147
158
|
export {
|
|
159
|
+
ne as StateVocabClientProvider,
|
|
148
160
|
X as clientify
|
|
149
161
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";"use strict";const h=require("react/jsx-runtime"),c=require("react"),r=require("./utils-0CTNJ4ZE.js"),a=c.createContext({});function S(e){const t=c.useContext(e.clientContext??a);return e.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 r.get(this.#t,t)}set(t,n){const s=r.get(this.#t,t),i=r.isTransformer(n)?n(s):n,o={...this.#t};r.set(o,t,i),this.#t=o,this.#e.forEach(l=>l())}}function b(e){const{clientContext:t,value:n,children:s}=e,[i]=c.useState(()=>new u(n)),o=t??a;return h.jsx(o.Provider,{value:i,children:s})}exports.StateVocabClientProvider=b;exports.VocabStore=u;exports.useStateVocabClientContext=S;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as u } from "react/jsx-runtime";
|
|
3
|
+
import { createContext as l, useContext as h, useState as S } from "react";
|
|
4
|
+
import { g as i, i as C, s as b } from "./utils-xV3x3fTc.mjs";
|
|
5
|
+
const c = l({});
|
|
6
|
+
function m(e) {
|
|
7
|
+
const t = h(e.clientContext ?? c);
|
|
8
|
+
return e.verbose && console.log(`[Store uid]: ${t.uid}`), t;
|
|
9
|
+
}
|
|
10
|
+
class d {
|
|
11
|
+
#t;
|
|
12
|
+
#e;
|
|
13
|
+
constructor(t) {
|
|
14
|
+
this.uid = Math.random().toString(36).slice(2), this.#t = t ?? {}, this.#e = /* @__PURE__ */ new Set();
|
|
15
|
+
}
|
|
16
|
+
subscribe(t) {
|
|
17
|
+
return this.#e.add(t), () => this.#e.delete(t);
|
|
18
|
+
}
|
|
19
|
+
getClientSnapshot() {
|
|
20
|
+
return this.#t;
|
|
21
|
+
}
|
|
22
|
+
getServerSnapshot() {
|
|
23
|
+
return this.#t;
|
|
24
|
+
}
|
|
25
|
+
get(t) {
|
|
26
|
+
return i(this.#t, t);
|
|
27
|
+
}
|
|
28
|
+
set(t, o) {
|
|
29
|
+
const n = i(this.#t, t), s = C(o) ? o(n) : o, r = { ...this.#t };
|
|
30
|
+
b(r, t, s), this.#t = r, this.#e.forEach((a) => a());
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function v(e) {
|
|
34
|
+
const { clientContext: t, value: o, children: n } = e, [s] = S(() => new d(o));
|
|
35
|
+
return /* @__PURE__ */ u((t ?? c).Provider, { value: s, children: n });
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
v as S,
|
|
39
|
+
d as V,
|
|
40
|
+
m as u
|
|
41
|
+
};
|
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 s=require("react/jsx-runtime"),S=require("./constants-CbsduCZ7.js"),c=require("react"),d=require("./provider-client-CAHe8VnM.js"),y=require("./utils-0CTNJ4ZE.js"),i=e=>{if(c.useState)throw new Error(`${e} only intended for Server Components`)},a=c.cache(()=>new Map),x=({children:e})=>e,C=async e=>{i("StateVocabServerContext.Provider");const{serverContextKey:n,value:t,children:r}=e;return a().set(n,t),r},f=e=>(i("getStateVocab"),a().get(e)),b={Provider:c.useState?x:C},p=e=>{const{serverContextKey:n,value:t,children:r}=e;return s.jsx(b.Provider,{serverContextKey:n,value:t,children:r})};function P(e){const{children:n,serverContextKey:t,clientContext:r,value:o={}}=e;return s.jsx(p,{serverContextKey:t,value:o,children:s.jsx(d.StateVocabClientProvider,{clientContext:r,value:o,children:n})})}const h="Make sure your component is wrapped in StateVocabProvider";function w(e){const n=this[S.STATE_PATH],t=f(e.serverContextKey);if(!t)throw new Error(h);return y.get(t,n)}function g(e){return typeof e=="object"&&e!==null&&"serverSlot"in e}function l(e,n){const t={};for(const r in e){const o=e[r];if(g(o))t[r]=o.serverSlot({getState(){return w.apply(this,[{serverContextKey:n.serverContextKey}])}}),delete t[r].serverSlot,delete t[r].clientSlot;else if(o!==null&&typeof o=="object"){const u=v=>n.wrap({[r]:v});t[r]=l(o,{serverContextKey:n.serverContextKey,wrap:u})}else t[r]=o}return t.seed=r=>n.wrap(r),t}function K(e,n){const t=Symbol();return{...l(e,{serverContextKey:t,wrap:r=>r}),StateVocabProvider({children:r,value:o}){return s.jsx(P,{clientContext:n.clientContext,serverContextKey:t,value:o,children:r})}}}exports.serverify=K;
|
package/dist/server.es.js
CHANGED
|
@@ -1,70 +1,104 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { S as
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (f.useState)
|
|
1
|
+
import { jsx as c } from "react/jsx-runtime";
|
|
2
|
+
import { S as u } from "./constants-BB1YAX6c.mjs";
|
|
3
|
+
import s, { cache as d } from "react";
|
|
4
|
+
import { S as f } from "./provider-client-D0BmMWcY.mjs";
|
|
5
|
+
import { g as y } from "./utils-xV3x3fTc.mjs";
|
|
6
|
+
const a = (e) => {
|
|
7
|
+
if (s.useState)
|
|
9
8
|
throw new Error(`${e} only intended for Server Components`);
|
|
9
|
+
}, i = d(() => /* @__PURE__ */ new Map()), p = ({ children: e }) => e, C = async (e) => {
|
|
10
|
+
a("StateVocabServerContext.Provider");
|
|
11
|
+
const { serverContextKey: o, value: t, children: r } = e;
|
|
12
|
+
return i().set(o, t), r;
|
|
13
|
+
}, x = (e) => (a("getStateVocab"), i().get(e)), b = {
|
|
14
|
+
Provider: s.useState ? p : C
|
|
15
|
+
}, m = (e) => {
|
|
16
|
+
const { serverContextKey: o, value: t, children: r } = e;
|
|
17
|
+
return /* @__PURE__ */ c(
|
|
18
|
+
b.Provider,
|
|
19
|
+
{
|
|
20
|
+
serverContextKey: o,
|
|
21
|
+
value: t,
|
|
22
|
+
children: r
|
|
23
|
+
}
|
|
24
|
+
);
|
|
10
25
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
function h(e) {
|
|
27
|
+
const {
|
|
28
|
+
children: o,
|
|
29
|
+
serverContextKey: t,
|
|
30
|
+
clientContext: r,
|
|
31
|
+
value: n = {}
|
|
32
|
+
} = e;
|
|
33
|
+
return /* @__PURE__ */ c(
|
|
34
|
+
m,
|
|
35
|
+
{
|
|
36
|
+
serverContextKey: t,
|
|
37
|
+
value: n,
|
|
38
|
+
children: /* @__PURE__ */ c(
|
|
39
|
+
f,
|
|
40
|
+
{
|
|
41
|
+
clientContext: r,
|
|
42
|
+
value: n,
|
|
43
|
+
children: o
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
);
|
|
30
48
|
}
|
|
31
|
-
const
|
|
32
|
-
function w() {
|
|
33
|
-
const
|
|
49
|
+
const P = "Make sure your component is wrapped in StateVocabProvider";
|
|
50
|
+
function w(e) {
|
|
51
|
+
const o = this[u], t = x(e.serverContextKey);
|
|
34
52
|
if (!t)
|
|
35
|
-
throw new Error(
|
|
36
|
-
return
|
|
53
|
+
throw new Error(P);
|
|
54
|
+
return y(t, o);
|
|
37
55
|
}
|
|
38
|
-
function
|
|
56
|
+
function K(e) {
|
|
39
57
|
return typeof e == "object" && e !== null && "serverSlot" in e;
|
|
40
58
|
}
|
|
41
|
-
function
|
|
42
|
-
const
|
|
43
|
-
for (const
|
|
44
|
-
const n = e[
|
|
45
|
-
if (
|
|
46
|
-
r
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
59
|
+
function v(e, o) {
|
|
60
|
+
const t = {};
|
|
61
|
+
for (const r in e) {
|
|
62
|
+
const n = e[r];
|
|
63
|
+
if (K(n))
|
|
64
|
+
t[r] = n.serverSlot({
|
|
65
|
+
getState() {
|
|
66
|
+
return w.apply(this, [{
|
|
67
|
+
serverContextKey: o.serverContextKey
|
|
68
|
+
}]);
|
|
50
69
|
}
|
|
51
|
-
}), delete r
|
|
70
|
+
}), delete t[r].serverSlot, delete t[r].clientSlot;
|
|
52
71
|
else if (n !== null && typeof n == "object") {
|
|
53
|
-
const
|
|
54
|
-
r
|
|
72
|
+
const l = (S) => o.wrap({ [r]: S });
|
|
73
|
+
t[r] = v(n, {
|
|
74
|
+
serverContextKey: o.serverContextKey,
|
|
75
|
+
wrap: l
|
|
76
|
+
});
|
|
55
77
|
} else
|
|
56
|
-
r
|
|
78
|
+
t[r] = n;
|
|
57
79
|
}
|
|
58
|
-
return
|
|
80
|
+
return t.seed = (r) => o.wrap(r), t;
|
|
59
81
|
}
|
|
60
|
-
function
|
|
82
|
+
function k(e, o) {
|
|
83
|
+
const t = /* @__PURE__ */ Symbol();
|
|
61
84
|
return {
|
|
62
|
-
...
|
|
63
|
-
|
|
64
|
-
|
|
85
|
+
...v(e, {
|
|
86
|
+
serverContextKey: t,
|
|
87
|
+
wrap: (r) => r
|
|
88
|
+
}),
|
|
89
|
+
StateVocabProvider({ children: r, value: n }) {
|
|
90
|
+
return /* @__PURE__ */ c(
|
|
91
|
+
h,
|
|
92
|
+
{
|
|
93
|
+
clientContext: o.clientContext,
|
|
94
|
+
serverContextKey: t,
|
|
95
|
+
value: n,
|
|
96
|
+
children: r
|
|
97
|
+
}
|
|
98
|
+
);
|
|
65
99
|
}
|
|
66
100
|
};
|
|
67
101
|
}
|
|
68
102
|
export {
|
|
69
|
-
|
|
103
|
+
k as serverify
|
|
70
104
|
};
|
package/dist/types/client.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { type Context } from "react";
|
|
1
2
|
import VocabStore from "./store";
|
|
2
|
-
export declare const
|
|
3
|
+
export declare const DefaultStateVocabClientContext: Context<VocabStore>;
|
|
3
4
|
/**
|
|
4
5
|
* @see method from from https://zustand.docs.pmnd.rs/learn/guides/nextjs
|
|
5
6
|
*/
|
|
6
7
|
export declare function useStateVocabClientContext(options: {
|
|
8
|
+
clientContext: Context<VocabStore> | undefined;
|
|
7
9
|
verbose: boolean;
|
|
8
10
|
}): VocabStore;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
1
2
|
import type { PropsWithChildren, ReactNode } from "react";
|
|
2
3
|
import type { Vocab } from "./state.types";
|
|
3
|
-
export declare const getStateVocab: () => Vocab | undefined;
|
|
4
|
+
export declare const getStateVocab: (serverContextKey: symbol) => Vocab | undefined;
|
|
4
5
|
export declare const StateVocabServerContext: {
|
|
5
6
|
Provider: (({ children }: PropsWithChildren<{
|
|
6
7
|
value?: Vocab;
|
|
7
8
|
}>) => ReactNode) | ((props: PropsWithChildren<{
|
|
9
|
+
serverContextKey: symbol;
|
|
8
10
|
value: Vocab;
|
|
9
|
-
}>) => Promise<
|
|
11
|
+
}>) => Promise<React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | (string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined)>);
|
|
10
12
|
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { type PropsWithChildren } from "react";
|
|
1
|
+
import { type Context, type PropsWithChildren } from "react";
|
|
2
|
+
import VocabStore from "./store";
|
|
2
3
|
import type { Vocab } from "./state.types";
|
|
3
4
|
export declare function StateVocabClientProvider(props: PropsWithChildren<{
|
|
5
|
+
clientContext?: Context<VocabStore>;
|
|
4
6
|
value?: Vocab;
|
|
5
7
|
}>): import("react/jsx-runtime").JSX.Element;
|
package/dist/types/provider.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import type { PropsWithChildren } from "react";
|
|
1
|
+
import type { Context, PropsWithChildren } from "react";
|
|
2
2
|
import type { Vocab } from "./state.types";
|
|
3
|
+
import VocabStore from "./store";
|
|
3
4
|
export declare function StateVocabProvider(props: PropsWithChildren<{
|
|
4
5
|
value?: Vocab;
|
|
6
|
+
serverContextKey: symbol;
|
|
7
|
+
clientContext: Context<VocabStore>;
|
|
5
8
|
}>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
+
import { type Context } from "react";
|
|
1
2
|
import type { ValueOrTransformer, VocabThis } from "./state.types";
|
|
3
|
+
import VocabStore from "./store";
|
|
2
4
|
import type { UseInitialStateOptions, UseStateOptions } from "./setup.types";
|
|
3
|
-
declare function useState<V>(this: VocabThis, options
|
|
5
|
+
declare function useState<V>(this: VocabThis, options: UseStateOptions<V> & {
|
|
6
|
+
clientContext: Context<VocabStore> | undefined;
|
|
7
|
+
}): readonly [V, (nextValue: ValueOrTransformer<V>) => void, () => void];
|
|
4
8
|
type Placeholder<V> = {
|
|
5
9
|
useState(options?: UseStateOptions<V>): ReturnType<typeof useState<V>>;
|
|
6
10
|
useInitialState(options?: UseInitialStateOptions<V>): void;
|
|
@@ -11,5 +15,7 @@ type Slot<V> = {
|
|
|
11
15
|
type Clientified<R> = R extends Slot<infer TValue> ? Placeholder<TValue> : R extends object ? {
|
|
12
16
|
[K in keyof R]: Clientified<R[K]>;
|
|
13
17
|
} : R;
|
|
14
|
-
export declare function clientify<R extends object>(tree: R
|
|
18
|
+
export declare function clientify<R extends object>(tree: R, clientifyOptions?: {
|
|
19
|
+
clientContext?: Context<object>;
|
|
20
|
+
}): Clientified<R>;
|
|
15
21
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PropsWithChildren, ReactNode } from "react";
|
|
1
|
+
import type { Context, PropsWithChildren, ReactNode } from "react";
|
|
2
2
|
import type { Vocab } from "./state.types";
|
|
3
3
|
type Placeholder<V> = {
|
|
4
4
|
getState(): V;
|
|
@@ -22,5 +22,7 @@ type ServerifyResult<R extends object> = {
|
|
|
22
22
|
} & {
|
|
23
23
|
[K in keyof R]: Serverified<R[K]>;
|
|
24
24
|
};
|
|
25
|
-
export declare function serverify<R extends object>(tree: R
|
|
25
|
+
export declare function serverify<R extends object>(tree: R, serverifyOptions: {
|
|
26
|
+
clientContext: Context<object>;
|
|
27
|
+
}): ServerifyResult<R>;
|
|
26
28
|
export {};
|
package/dist/types/state.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
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,41 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as u } from "react/jsx-runtime";
|
|
3
|
-
import { createContext as h, useContext as l, useState as S } from "react";
|
|
4
|
-
import { g as n, i as d, s as b } from "./utils-xV3x3fTc.mjs";
|
|
5
|
-
const i = h({});
|
|
6
|
-
function V(s) {
|
|
7
|
-
const t = l(i);
|
|
8
|
-
return s.verbose && console.log(`[Store uid]: ${t.uid}`), t;
|
|
9
|
-
}
|
|
10
|
-
class f {
|
|
11
|
-
#t;
|
|
12
|
-
#e;
|
|
13
|
-
constructor(t) {
|
|
14
|
-
this.uid = Math.random().toString(36).slice(2), this.#t = t ?? {}, this.#e = /* @__PURE__ */ new Set();
|
|
15
|
-
}
|
|
16
|
-
subscribe(t) {
|
|
17
|
-
return this.#e.add(t), () => this.#e.delete(t);
|
|
18
|
-
}
|
|
19
|
-
getClientSnapshot() {
|
|
20
|
-
return this.#t;
|
|
21
|
-
}
|
|
22
|
-
getServerSnapshot() {
|
|
23
|
-
return this.#t;
|
|
24
|
-
}
|
|
25
|
-
get(t) {
|
|
26
|
-
return n(this.#t, t);
|
|
27
|
-
}
|
|
28
|
-
set(t, e) {
|
|
29
|
-
const o = n(this.#t, t), c = d(e) ? e(o) : e, r = { ...this.#t };
|
|
30
|
-
b(r, t, c), this.#t = r, this.#e.forEach((a) => a());
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function g(s) {
|
|
34
|
-
const { children: t, value: e } = s, [o] = S(() => new f(e));
|
|
35
|
-
return /* @__PURE__ */ u(i.Provider, { value: o, children: t });
|
|
36
|
-
}
|
|
37
|
-
export {
|
|
38
|
-
g as S,
|
|
39
|
-
f as V,
|
|
40
|
-
V as u
|
|
41
|
-
};
|