@yakocloud/state-vocab 4.2.0 → 4.3.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 CHANGED
@@ -117,7 +117,7 @@ npm install @yakocloud/state-vocab react react-dom
117
117
 
118
118
  ## Quick Start
119
119
 
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
120
+ Define your storage tree once (`setupStorage`/`defineState`), call `clientify` to attach React hooks. If you use React Server Components (RSC), wrap the relevant subtree with `StateVocabProvider` and call `serverify` to attach server-side `.getState()` 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.
@@ -366,28 +366,14 @@ export const storage = setupStorage({
366
366
  })
367
367
  ```
368
368
 
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
- ```
369
+ **2. Create server and client storage handles:**
381
370
 
382
371
  ```ts
383
372
  // storage.server.ts
384
373
  import { storage } from '@/storage'
385
374
  import { serverify } from '@yakocloud/state-vocab/server'
386
- import { StorageClientContext } from '@/storage.context.client'
387
375
 
388
- export const serverStorage = serverify(storage, {
389
- clientContext: StorageClientContext,
390
- })
376
+ export const serverStorage = serverify(storage)
391
377
  ```
392
378
 
393
379
  ```ts
@@ -396,11 +382,8 @@ export const serverStorage = serverify(storage, {
396
382
 
397
383
  import { storage } from '@/storage'
398
384
  import { clientify } from '@yakocloud/state-vocab/client'
399
- import { StorageClientContext } from '@/storage.context.client'
400
385
 
401
- export const clientStorage = clientify(storage, {
402
- clientContext: StorageClientContext,
403
- })
386
+ export const clientStorage = clientify(storage)
404
387
  ```
405
388
 
406
389
  **3. Seed initial state in the server component and read it in Server and Client children:**
@@ -412,10 +395,6 @@ import { serverStorage } from '@/storage.server'
412
395
  const { StateVocabProvider } = serverStorage
413
396
 
414
397
  export default async function Page() {
415
- // Call start() before rendering the provider — registers the store for this
416
- // request so child components can await getState() concurrently
417
- serverStorage.start()
418
-
419
398
  // Fetch data from DB / API
420
399
  const user = await db.getUser()
421
400
 
@@ -437,8 +416,8 @@ export default async function Page() {
437
416
  import { serverStorage } from '@/storage.server'
438
417
 
439
418
  export default async function UserInfo() {
440
- const name = await serverStorage.user.name.getState()
441
- const role = await serverStorage.user.role.getState()
419
+ const name = serverStorage.user.name.getState()
420
+ const role = serverStorage.user.role.getState()
442
421
 
443
422
  return <p>{name} — {role}</p>
444
423
  }
@@ -460,41 +439,67 @@ export default function UserInfoClient() {
460
439
 
461
440
  #### Multiple independent storage trees
462
441
 
463
- 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:
442
+ Because each `serverify`/`clientify` pair is bound to its own React 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. Pass a `clientContext` to link the server and client sides of each tree:
464
443
 
465
444
  ```ts
466
- // layout.context.client.ts ("use client")
467
- export const LayoutClientContext = createContext({})
468
-
469
- // page.context.client.ts ("use client")
470
- export const PageClientContext = createContext({})
471
-
472
445
  // layout.storage.server.ts
473
- export const layoutServerStorage = serverify(layoutStorage, {
474
- clientContext: LayoutClientContext
475
- })
446
+ import { createContext } from 'react'
447
+ export const LayoutClientContext = createContext({})
448
+ export const layoutServerStorage = serverify(layoutStorage, { clientContext: LayoutClientContext })
476
449
 
477
450
  // layout.storage.client.ts ("use client")
478
- export const layoutClientStorage = clientify(layoutStorage, {
479
- clientContext: LayoutClientContext
480
- })
451
+ "use client"
452
+ export const layoutClientStorage = clientify(layoutStorage, { clientContext: LayoutClientContext })
481
453
 
482
454
  // page.storage.server.ts
483
- export const pageServerStorage = serverify(pageStorage, {
484
- clientContext: PageClientContext
485
- })
455
+ import { createContext } from 'react'
456
+ export const PageClientContext = createContext({})
457
+ export const pageServerStorage = serverify(pageStorage, { clientContext: PageClientContext })
486
458
 
487
459
  // page.storage.client.ts ("use client")
488
- export const pageClientStorage = clientify(pageStorage, {
489
- clientContext: PageClientContext
490
- })
460
+ "use client"
461
+ export const pageClientStorage = clientify(pageStorage, { clientContext: PageClientContext })
491
462
  ```
492
463
 
493
464
  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.
494
465
 
466
+ #### Next.js App Router: layout and page are isolated contexts
467
+
468
+ In Next.js App Router, **layouts do not re-render during client-side navigation between pages**. Layout and page run as independent React render passes — the layout renders once on entry and stays mounted; the page renders fresh on every navigation.
469
+
470
+ Because `React.cache()` (which backs the per-request server store) is scoped to a single render pass, layout and page never share the same cache scope:
471
+
472
+ - A page server component **cannot** call `layoutServerStorage.someField.getState()` — the layout's `StateVocabProvider` ran in a separate pass, so its vocab is not in the page's cache scope.
473
+ - A layout server component **cannot** call `pageServerStorage.someField.getState()` for the same reason.
474
+ - **Each storage tree must be both seeded and consumed within the same route segment.**
475
+
476
+ ```tsx
477
+ // ✅ Correct — layout seeds and reads from its own storage
478
+ // app/(dashboard)/layout.tsx
479
+ const LayoutProvider = layoutServerStorage.StateVocabProvider
480
+ export default async function Layout({ children }) {
481
+ return (
482
+ <LayoutProvider value={{ session: { id: 123 } }}>
483
+ <LayoutHeader /> {/* ← can call layoutServerStorage.session.getState() */}
484
+ {children}
485
+ </LayoutProvider>
486
+ )
487
+ }
488
+
489
+ // ❌ Wrong — page cannot reach layout's storage
490
+ // app/(dashboard)/page.tsx
491
+ export default async function Page() {
492
+ const session = layoutServerStorage.session.getState() // throws — not in layout's render pass
493
+ }
494
+ ```
495
+
496
+ If a page needs data that the layout already fetches (e.g., the current user session), fetch it independently in the page, pass it via URL params, or use a separate mechanism — do not attempt to share it through other state-vocab server storage across route segments.
497
+
498
+ This constraint is **server-only**. On the client, there is no such limitation — client components can freely call `.useState()` from any storage (`layoutClientStorage`, `pageClientStorage`, or any other) regardless of which route segment they live in.
499
+
495
500
  #### `serverify(storage)`
496
501
 
497
- Converts a storage tree into its server-side counterpart. Each leaf gains an async `.getState()` method that resolves once the nearest `StateVocabProvider` renders and provides its value. Each namespace node (including the root) gains a `.seed()` method that returns the input wrapped under its full ancestor path. The result also exposes `StateVocabProvider` and `start()` — call `start()` at the top of the component that renders `StateVocabProvider` so concurrent server children can await the value without timing out.
502
+ Converts a storage tree into its server-side counterpart. Each leaf gains a synchronous `.getState()` method that reads the value injected by the nearest `StateVocabProvider`. Each namespace node (including the root) gains a `.seed()` method that returns the input wrapped under its full ancestor path. The result also exposes `StateVocabProvider`.
498
503
 
499
504
  **`.seed()` syntax:**
500
505
 
@@ -512,7 +517,7 @@ serverStorage.person.address.seed({ city: 'NY' })
512
517
  // → { person: { address: { city: 'NY' } } }
513
518
  ```
514
519
 
515
- **`node.getState()`** asynchronously reads the value for that leaf once the surrounding `StateVocabProvider` has rendered. Returns `Promise<V>` always `await` it. Throws (rejects) if called outside a provider scope or if `serverTimeout` expires.
520
+ **`node.getState()`** synchronously reads the value for that leaf. Must be called within a React render context (i.e., inside a component that is a descendant of `StateVocabProvider`). Throws if called outside a provider scope or outside a React render context.
516
521
 
517
522
  #### `clientify(storage)`
518
523
 
@@ -749,36 +754,31 @@ import { StateVocabClientProvider } from '@yakocloud/state-vocab/client'
749
754
  </StateVocabClientProvider>
750
755
  ```
751
756
 
752
- ### `serverify<T>(storage: T, options)`
757
+ ### `serverify<T>(storage: T, options?)`
753
758
 
754
759
  Converts a storage tree to its server-side counterpart. Available from `@yakocloud/state-vocab/server`.
755
760
 
756
761
  | Option | Type | Description |
757
762
  |---|---|---|
758
- | `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. |
759
- | `serverTimeout` | `number \| undefined` | Timeout in ms for each `getState()` call. Defaults to `1000`. If the `StateVocabProvider` has not rendered within this window, `getState()` rejects with a descriptive error. |
763
+ | `clientContext` | `Context<object> \| undefined` | A React context created with `createContext({})`. Pass the same context to `clientify` when multiple independent storage trees coexist on the same page. Omit for single-tree setups. |
760
764
 
761
765
  The result exposes:
762
766
 
763
- - **`start()`** — call once at the top of the component that renders `StateVocabProvider`, before any `await` expressions. It registers a pending promise in the per-request store (`React.cache()` scope), which lets concurrent server components `await getState()` without hanging. Must be called within a React render context.
764
- - **`StateVocabProvider`** — synchronous server component that accepts a `value` prop and resolves the pending promise registered by `start()`.
765
- - **`node.getState()`** — async; reads the value for that leaf once the nearest `StateVocabProvider` has rendered. Throws if called outside a provider scope or if the timeout expires.
767
+ - **`StateVocabProvider`** — server component that accepts a `value` prop and seeds the per-request store via `React.cache()`.
768
+ - **`node.getState()`** — synchronously reads the value for that leaf. Must be called within a React render context (descendant of `StateVocabProvider`). Throws if called outside a provider scope or outside a render context.
766
769
  - **`node.seed(input)`** — wraps `input` under the node's ancestor path, returning a plain object ready to pass as the `value` prop.
767
770
 
768
771
  ```ts
769
772
  import { serverify } from '@yakocloud/state-vocab/server'
770
- import { MyClientContext } from '@/storage.context.client'
771
773
 
772
- const serverStorage = serverify(storage, {
773
- clientContext: MyClientContext,
774
- serverTimeout: 2000, // optional, default 1000
775
- })
774
+ const serverStorage = serverify(storage)
775
+ // or, for multiple independent trees:
776
+ const serverStorage = serverify(storage, { clientContext: MyClientContext })
776
777
 
777
778
  const { StateVocabProvider } = serverStorage
778
779
 
779
780
  // In a Server Component:
780
- serverStorage.start() // register before rendering
781
- await serverStorage.user.name.getState() // reads "user.name" (async)
781
+ serverStorage.user.name.getState() // reads "user.name" (sync)
782
782
  serverStorage.user.seed({ name: 'Alice' }) // → { user: { name: 'Alice' } }
783
783
  serverStorage.person.address.seed({ city: 'NY' }) // → { person: { address: { city: 'NY' } } }
784
784
  serverStorage.seed({ user: { name: 'Alice' } }) // → { user: { name: 'Alice' } } (identity)
@@ -790,7 +790,7 @@ Converts a storage tree to its client-side counterpart. Available from `@yakoclo
790
790
 
791
791
  | Option | Type | Description |
792
792
  |---|---|---|
793
- | `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. |
793
+ | `clientContext` | `Context<object> \| undefined` | The React context used to isolate this storage tree. Must match the `clientContext` passed to `serverify` for the same tree. Omit for single-tree setups. |
794
794
 
795
795
  Each leaf gains `.useState()` and `.useInitialState()`. The tree structure mirrors the original.
796
796
 
@@ -1 +1 @@
1
- "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("react"),v=require("./constants-CbsduCZ7.js"),a=require("./utils-CuApuc3e.js"),V=require("./provider-client-DRdFy5dG.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;
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("react"),S=require("./constants-BTyJxzUH.js"),o=require("./utils-0CTNJ4ZE.js"),b=require("./provider-client-DA53zfcT.js");function L(t,n,s=[]){return f.useMemo(()=>o.debounce(t,n),s)}const C=t=>{const{vocabStore:n,storage:s,statePath:a,value:e,deserialize:l,serialize:c}=t,d=s.getItem(a);d===null?o.isValueDefined(e)&&s.setItem(a,c(e)):n.set(a,l(d))};function x(t){return typeof t=="object"&&t!==null&&S.STATE_CLIENT_SLOT in t}const R=typeof window>"u",A=R?f.useEffect:f.useLayoutEffect,O=new b.VocabStore,w="Make sure your component is wrapped in StateVocabProvider (RSC) or disable ssr option in setupStorage for SPA (RCC only)";function D(t){const n=R?void 0:o.valueOrFactory(t.storage),s=o.valueOrFactory(t.defaultValue),a=t.bidirectional,e=this[S.STATE_PATH],l=this[S.STATE_VERBOSE],c=this[S.STATE_VERBOSE_PATH],d=this[S.STATE_SSR];let i=b.useStateVocabClientContext({clientContext:t.clientContext,verbose:l});if(!(i instanceof b.VocabStore)){if(d)throw new Error(w);i=O}const E=t.serialize??JSON.stringify,u=t.deserialize??JSON.parse,v=L(t.onSet??(()=>{}),t.delayedSet,[]),V=f.useRef(void 0),_=f.useRef(!1);if(!_.current){_.current=!0;let r=i.get(e);o.isValueDefined(r)||(r=s,o.isValueDefined(r)&&i.set(e,r)),!d&&n&&C({vocabStore:i,storage:n,statePath:e,value:r,serialize:E,deserialize:u})}const g=f.useSyncExternalStore(i.subscribe.bind(i),i.getClientSnapshot.bind(i),i.getServerSnapshot.bind(i));if(l)if(c){const r=o.get(g,c);r&&o.logStyled(r)}else o.logStyled(g);const y=o.get(g,e,s);V.current=y,A(()=>{!d||!n||C({vocabStore:i,storage:n,statePath:e,value:y,serialize:E,deserialize:u})},[]);const z=f.useEffectEvent(r=>{if(r.key!==e)return;const T=r.newValue,h=(T===null?null:u(T))??s;o.isValueDefined(h)&&(i.set(e,h),v(h,V.current))});f.useEffect(()=>{if(a)return window.addEventListener("storage",z),()=>window.removeEventListener("storage",z)},[a]);const P=f.useCallback(r=>{const T=o.isTransformer(r)?r(V.current):r;i.set(e,T),v(T,V.current),n&&n.setItem(e,E(T))},[i,e,v,n,E]),I=f.useCallback(()=>{const r=s;if(!o.isValueDefined(r)){n?.removeItem(e);return}i.set(e,r),v(r,V.current),n&&n.setItem(e,E(r))},[s,i,e,v,n,E]);return[y,P,I]}function p(t){const n=R?void 0:o.valueOrFactory(t.storage),s=o.valueOrFactory(t.defaultValue),a=this[S.STATE_PATH],e=this[S.STATE_VERBOSE],l=this[S.STATE_SSR];let c=b.useStateVocabClientContext({clientContext:t.clientContext,verbose:e});if(!(c instanceof b.VocabStore)){if(l)throw new Error(w);c=O}const d=t.serialize??JSON.stringify,i=t.deserialize??JSON.parse,E=f.useRef(!1);let u;E.current||(E.current=!0,u=c.get(a),o.isValueDefined(u)||(u=s,o.isValueDefined(u)&&c.set(a,u)),!l&&n&&C({vocabStore:c,storage:n,statePath:a,value:u,serialize:d,deserialize:i})),A(()=>{!l||!n||C({vocabStore:c,storage:n,statePath:a,value:u,serialize:d,deserialize:i})},[])}function m(t,n={}){const s={};for(const a in t){const e=t[a];x(e)?(s[a]=e[S.STATE_CLIENT_SLOT]({useState(l){return D.apply(this,[{clientContext:n.clientContext,...l}])},useInitialState(l){p.apply(this,[{clientContext:n.clientContext,...l}])}}),delete s[S.STATE_CLIENT_SLOT],delete s[S.STATE_SERVER_SLOT]):e!==null&&typeof e=="object"?s[a]=m(e,n):s[a]=e}return s}exports.StateVocabClientProvider=b.StateVocabClientProvider;exports.clientify=m;
package/dist/client.es.js CHANGED
@@ -1,17 +1,17 @@
1
1
  "use client";
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-xNWifFE9.mjs";
5
- import { V as C, u as _ } from "./provider-client-BhPeK8Kz.mjs";
6
- import { S as ne } from "./provider-client-BhPeK8Kz.mjs";
7
- function K(t, s, i = []) {
8
- return j(
9
- () => G(t, s),
2
+ import { useMemo as B, useRef as C, useSyncExternalStore as D, useEffectEvent as H, useEffect as _, useCallback as p, useLayoutEffect as F } from "react";
3
+ import { S as T, a as G, b as I, c as P, d as O, e as q } from "./constants-Cf0m6moG.mjs";
4
+ import { a as d, d as K, v as E, g as x, l as A, i as Q } from "./utils-xV3x3fTc.mjs";
5
+ import { V as y, u as L } from "./provider-client-DLa3_Ms9.mjs";
6
+ import { S as oe } from "./provider-client-DLa3_Ms9.mjs";
7
+ function U(t, s, i = []) {
8
+ return B(
9
+ () => K(t, s),
10
10
  // eslint-disable-next-line react-hooks/exhaustive-deps
11
11
  i
12
12
  );
13
13
  }
14
- const E = (t) => {
14
+ const g = (t) => {
15
15
  const {
16
16
  vocabStore: s,
17
17
  storage: i,
@@ -21,28 +21,32 @@ const E = (t) => {
21
21
  serialize: l
22
22
  } = t, u = i.getItem(o);
23
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)";
25
- function Q(t) {
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 = _({
24
+ };
25
+ function W(t) {
26
+ return typeof t == "object" && t !== null && T in t;
27
+ }
28
+ const z = typeof window > "u", N = z ? _ : F, k = new y(), J = "Make sure your component is wrapped in StateVocabProvider (RSC) or disable ssr option in setupStorage for SPA (RCC only)";
29
+ function X(t) {
30
+ const s = z ? void 0 : E(t.storage), i = E(t.defaultValue), o = t.bidirectional, e = this[I], a = this[P], l = this[q], u = this[O];
31
+ let r = L({
28
32
  clientContext: t.clientContext,
29
33
  verbose: a
30
34
  });
31
- if (!(r instanceof C)) {
35
+ if (!(r instanceof y)) {
32
36
  if (u)
33
- throw new Error(L);
34
- r = J;
37
+ throw new Error(J);
38
+ r = k;
35
39
  }
36
- const f = t.serialize ?? JSON.stringify, c = t.deserialize ?? JSON.parse, v = K(
40
+ const f = t.serialize ?? JSON.stringify, c = t.deserialize ?? JSON.parse, v = U(
37
41
  t.onSet ?? (() => {
38
42
  }),
39
43
  t.delayedSet,
40
44
  []
41
- ), b = y(void 0), w = y(!1);
42
- if (!w.current) {
43
- w.current = !0;
45
+ ), b = C(void 0), R = C(!1);
46
+ if (!R.current) {
47
+ R.current = !0;
44
48
  let n = r.get(e);
45
- d(n) || (n = i, d(n) && r.set(e, n)), !u && s && E({
49
+ d(n) || (n = i, d(n) && r.set(e, n)), !u && s && g({
46
50
  vocabStore: r,
47
51
  storage: s,
48
52
  statePath: e,
@@ -51,42 +55,42 @@ function Q(t) {
51
55
  deserialize: c
52
56
  });
53
57
  }
54
- const h = B(
58
+ const V = D(
55
59
  r.subscribe.bind(r),
56
60
  r.getClientSnapshot.bind(r),
57
61
  r.getServerSnapshot.bind(r)
58
62
  );
59
63
  if (a)
60
64
  if (l) {
61
- const n = T(h, l);
62
- n && x(n);
65
+ const n = x(V, l);
66
+ n && A(n);
63
67
  } else
64
- x(h);
65
- const m = T(h, e, i);
66
- b.current = m, k(() => {
67
- !u || !s || E({
68
+ A(V);
69
+ const h = x(V, e, i);
70
+ b.current = h, N(() => {
71
+ !u || !s || g({
68
72
  vocabStore: r,
69
73
  storage: s,
70
74
  statePath: e,
71
- value: m,
75
+ value: h,
72
76
  serialize: f,
73
77
  deserialize: c
74
78
  });
75
79
  }, []);
76
- const R = D((n) => {
80
+ const w = H((n) => {
77
81
  if (n.key !== e)
78
82
  return;
79
- const S = n.newValue, V = (S === null ? null : c(S)) ?? i;
80
- d(V) && (r.set(e, V), v(V, b.current));
83
+ const S = n.newValue, m = (S === null ? null : c(S)) ?? i;
84
+ d(m) && (r.set(e, m), v(m, b.current));
81
85
  });
82
- P(() => {
86
+ _(() => {
83
87
  if (o)
84
- return window.addEventListener("storage", R), () => window.removeEventListener("storage", R);
88
+ return window.addEventListener("storage", w), () => window.removeEventListener("storage", w);
85
89
  }, [o]);
86
- const N = p((n) => {
87
- const S = q(n) ? n(b.current) : n;
90
+ const M = p((n) => {
91
+ const S = Q(n) ? n(b.current) : n;
88
92
  r.set(e, S), v(S, b.current), s && s.setItem(e, f(S));
89
- }, [r, e, v, s, f]), M = p(() => {
93
+ }, [r, e, v, s, f]), j = p(() => {
90
94
  const n = i;
91
95
  if (!d(n)) {
92
96
  s?.removeItem(e);
@@ -95,33 +99,33 @@ function Q(t) {
95
99
  r.set(e, n), v(n, b.current), s && s.setItem(e, f(n));
96
100
  }, [i, r, e, v, s, f]);
97
101
  return [
98
- m,
99
- N,
100
- M
102
+ h,
103
+ M,
104
+ j
101
105
  ];
102
106
  }
103
- function U(t) {
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 = _({
107
+ function Y(t) {
108
+ const s = z ? void 0 : E(t.storage), i = E(t.defaultValue), o = this[I], e = this[P], a = this[O];
109
+ let l = L({
106
110
  clientContext: t.clientContext,
107
111
  verbose: e
108
112
  });
109
- if (!(l instanceof C)) {
113
+ if (!(l instanceof y)) {
110
114
  if (a)
111
- throw new Error(L);
112
- l = J;
115
+ throw new Error(J);
116
+ l = k;
113
117
  }
114
- const u = t.serialize ?? JSON.stringify, r = t.deserialize ?? JSON.parse, f = y(!1);
118
+ const u = t.serialize ?? JSON.stringify, r = t.deserialize ?? JSON.parse, f = C(!1);
115
119
  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({
120
+ f.current || (f.current = !0, c = l.get(o), d(c) || (c = i, d(c) && l.set(o, c)), !a && s && g({
117
121
  vocabStore: l,
118
122
  storage: s,
119
123
  statePath: o,
120
124
  value: c,
121
125
  serialize: u,
122
126
  deserialize: r
123
- })), k(() => {
124
- !a || !s || E({
127
+ })), N(() => {
128
+ !a || !s || g({
125
129
  vocabStore: l,
126
130
  storage: s,
127
131
  statePath: o,
@@ -131,31 +135,28 @@ function U(t) {
131
135
  });
132
136
  }, []);
133
137
  }
134
- function W(t) {
135
- return typeof t == "object" && t !== null && "clientSlot" in t;
136
- }
137
- function X(t, s = {}) {
138
+ function Z(t, s = {}) {
138
139
  const i = {};
139
140
  for (const o in t) {
140
141
  const e = t[o];
141
- W(e) ? (i[o] = e.clientSlot({
142
+ W(e) ? (i[o] = e[T]({
142
143
  useState(a) {
143
- return Q.apply(this, [{
144
+ return X.apply(this, [{
144
145
  clientContext: s.clientContext,
145
146
  ...a
146
147
  }]);
147
148
  },
148
149
  useInitialState(a) {
149
- U.apply(this, [{
150
+ Y.apply(this, [{
150
151
  clientContext: s.clientContext,
151
152
  ...a
152
153
  }]);
153
154
  }
154
- }), delete i[o].serverSlot, delete i[o].clientSlot) : e !== null && typeof e == "object" ? i[o] = X(e, s) : i[o] = e;
155
+ }), delete i[T], delete i[G]) : e !== null && typeof e == "object" ? i[o] = Z(e, s) : i[o] = e;
155
156
  }
156
157
  return i;
157
158
  }
158
159
  export {
159
- ne as StateVocabClientProvider,
160
- X as clientify
160
+ oe as StateVocabClientProvider,
161
+ Z as clientify
161
162
  };
@@ -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"),_=Symbol("state-server-slot"),o=Symbol("state-client-slot");exports.STATE_CLIENT_SLOT=o;exports.STATE_DEFINITION=T;exports.STATE_PATH=S;exports.STATE_SERVER_SLOT=_;exports.STATE_SSR=s;exports.STATE_VERBOSE=E;exports.STATE_VERBOSE_PATH=t;
@@ -0,0 +1,10 @@
1
+ const s = /* @__PURE__ */ Symbol("state-def"), t = /* @__PURE__ */ Symbol("state-path"), S = /* @__PURE__ */ Symbol("state-verbose"), T = /* @__PURE__ */ Symbol("state-verbose-path"), o = /* @__PURE__ */ Symbol("state-ssr"), a = /* @__PURE__ */ Symbol("state-server-slot"), e = /* @__PURE__ */ Symbol("state-client-slot");
2
+ export {
3
+ e as S,
4
+ a,
5
+ t as b,
6
+ S as c,
7
+ o as d,
8
+ T as e,
9
+ s as f
10
+ };
package/dist/index.cjs.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./constants-CbsduCZ7.js"),h=require("./utils-CuApuc3e.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;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./constants-BTyJxzUH.js"),h=require("./utils-0CTNJ4ZE.js");function O(t={}){return{[a.STATE_DEFINITION]:!0,[a.STATE_PATH]:"",[a.STATE_VERBOSE]:!1,[a.STATE_VERBOSE_PATH]:"",[a.STATE_SSR]:!1,[a.STATE_SERVER_SLOT](r){return Object.assign(this,{getState(...e){return r.getState.apply(this,e)}})},[a.STATE_CLIENT_SLOT](r){return Object.assign(this,{useState(e){return e??={},r.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(...u){e.onSet&&e.onSet(...u)}}])},useInitialState(e){r.useInitialState.apply(this,[{defaultValue:e.defaultValue,storage:t.storage,serialize:t.serialize,deserialize:t.deserialize}])}})},toString(){return this[a.STATE_PATH]}}}function y(t,r){const{path:e="",verbose:u,verbosePath:A,ssr:_,cache:S}=r;let s=S.proxy.get(t);s||(s=new Map,S.proxy.set(t,s));const E=s.get(e);if(E)return E;const d=new Proxy(t,{get(b,f){const l=b[f],c=e?`${e}.${String(f)}`:String(f);if(l&&typeof l=="object"&&a.STATE_DEFINITION in l){const i=l;let n=S.leaf.get(i);n||(n=new Map,S.leaf.set(i,n));const o=n.get(c);if(o)return o;const P=Reflect.ownKeys(i).filter(T=>typeof i[T]=="function"),V=Object.fromEntries(P.map(T=>[T,(...I)=>i[T].call({...i,[a.STATE_PATH]:c,[a.STATE_VERBOSE]:u,[a.STATE_VERBOSE_PATH]:A,[a.STATE_SSR]:_},...I)])),g={...i,...V};return n.set(c,g),g}return l&&typeof l=="object"?y(l,{...r,path:c}):l}});return s.set(e,d),d}function R(t,r){return y(t,{...r,ssr:r?.ssr??!0,verbosePath:r?.verbosePath??"",cache:{proxy:new WeakMap,leaf:new WeakMap}})}exports.defineState=O;exports.setupStorage=R;
package/dist/index.es.js CHANGED
@@ -1,18 +1,18 @@
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-xNWifFE9.mjs";
3
- function M(t = {}) {
1
+ import { b as d, S as w, a as I, d as E, e as b, c as _, f as A } from "./constants-Cf0m6moG.mjs";
2
+ import { v as y } from "./utils-xV3x3fTc.mjs";
3
+ function L(t = {}) {
4
4
  return {
5
- [v]: !0,
5
+ [A]: !0,
6
6
  // marks this object as a leaf in the router tree
7
7
  [d]: "",
8
8
  // placeholder; injected at runtime by injectPaths()
9
- [P]: !1,
9
+ [_]: !1,
10
10
  // placeholder
11
- [E]: "",
11
+ [b]: "",
12
12
  // placeholder
13
- [T]: !1,
13
+ [E]: !1,
14
14
  // placeholder
15
- serverSlot(a) {
15
+ [I](a) {
16
16
  return Object.assign(this, {
17
17
  // Impl|RSC
18
18
  getState(...e) {
@@ -20,12 +20,12 @@ function M(t = {}) {
20
20
  }
21
21
  });
22
22
  },
23
- clientSlot(a) {
23
+ [w](a) {
24
24
  return Object.assign(this, {
25
25
  // Impl|RCC
26
26
  useState(e) {
27
27
  return e ??= {}, a.useState.apply(this, [{
28
- defaultValue: b(e.defaultValue) ?? b(t.defaultValue),
28
+ defaultValue: y(e.defaultValue) ?? y(t.defaultValue),
29
29
  bidirectional: e.bidirectional ?? t.bidirectional,
30
30
  storage: e.storage ?? t.storage,
31
31
  serialize: t.serialize ?? JSON.stringify,
@@ -53,58 +53,58 @@ function M(t = {}) {
53
53
  }
54
54
  };
55
55
  }
56
- function z(t, a) {
56
+ function P(t, a) {
57
57
  const {
58
58
  path: e = "",
59
59
  verbose: S,
60
- verbosePath: x,
61
- ssr: A,
60
+ verbosePath: z,
61
+ ssr: V,
62
62
  cache: n
63
63
  } = a;
64
- let s = n.proxy.get(t);
65
- s || (s = /* @__PURE__ */ new Map(), n.proxy.set(t, s));
66
- const o = s.get(e);
67
- if (o)
68
- return o;
69
- const h = new Proxy(t, {
70
- get(V, u) {
71
- const r = V[u], c = e ? `${e}.${String(u)}` : String(u);
72
- if (r && typeof r == "object" && v in r) {
73
- const l = r;
74
- let i = n.leaf.get(l);
75
- i || (i = /* @__PURE__ */ new Map(), n.leaf.set(l, i));
76
- const g = i.get(c);
77
- if (g)
78
- return g;
79
- const j = Reflect.ownKeys(l).filter(
80
- (f) => typeof l[f] == "function"
81
- ), m = Object.fromEntries(
82
- j.map((f) => [
64
+ let l = n.proxy.get(t);
65
+ l || (l = /* @__PURE__ */ new Map(), n.proxy.set(t, l));
66
+ const h = l.get(e);
67
+ if (h)
68
+ return h;
69
+ const o = new Proxy(t, {
70
+ get(v, u) {
71
+ const r = v[u], c = e ? `${e}.${String(u)}` : String(u);
72
+ if (r && typeof r == "object" && A in r) {
73
+ const s = r;
74
+ let i = n.leaf.get(s);
75
+ i || (i = /* @__PURE__ */ new Map(), n.leaf.set(s, i));
76
+ const T = i.get(c);
77
+ if (T)
78
+ return T;
79
+ const x = Reflect.ownKeys(s).filter(
80
+ (f) => typeof s[f] == "function"
81
+ ), j = Object.fromEntries(
82
+ x.map((f) => [
83
83
  f,
84
- (...w) => l[f].call(
84
+ (...m) => s[f].call(
85
85
  {
86
- ...l,
86
+ ...s,
87
87
  [d]: c,
88
- [P]: S,
89
- [E]: x,
90
- [T]: A
88
+ [_]: S,
89
+ [b]: z,
90
+ [E]: V
91
91
  },
92
- ...w
92
+ ...m
93
93
  )
94
94
  ])
95
- ), y = { ...l, ...m };
96
- return i.set(c, y), y;
95
+ ), g = { ...s, ...j };
96
+ return i.set(c, g), g;
97
97
  }
98
- return r && typeof r == "object" ? z(r, {
98
+ return r && typeof r == "object" ? P(r, {
99
99
  ...a,
100
100
  path: c
101
101
  }) : r;
102
102
  }
103
103
  });
104
- return s.set(e, h), h;
104
+ return l.set(e, o), o;
105
105
  }
106
- function N(t, a) {
107
- return z(t, {
106
+ function M(t, a) {
107
+ return P(t, {
108
108
  ...a,
109
109
  ssr: a?.ssr ?? !0,
110
110
  verbosePath: a?.verbosePath ?? "",
@@ -115,6 +115,6 @@ function N(t, a) {
115
115
  });
116
116
  }
117
117
  export {
118
- M as defineState,
119
- N as setupStorage
118
+ L as defineState,
119
+ M as setupStorage
120
120
  };
@@ -1 +1 @@
1
- "use client";"use strict";const h=require("react/jsx-runtime"),c=require("react"),r=require("./utils-CuApuc3e.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{uid;#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;
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{uid;#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;
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as u } from "react/jsx-runtime";
3
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-xNWifFE9.mjs";
4
+ import { g as i, i as C, s as b } from "./utils-xV3x3fTc.mjs";
5
5
  const c = l({});
6
6
  function m(e) {
7
7
  const t = h(e.clientContext ?? c);
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const y=require("react/jsx-runtime"),S=require("./constants-CbsduCZ7.js"),l=require("react"),m=require("./provider-client-DRdFy5dG.js"),a=require("./utils-CuApuc3e.js"),d=e=>{if(l.useState)throw new Error(`${e} only intended for Server Components`)},c=l.cache(()=>new Map),f=async e=>(d("getStateVocab"),await c().get(e)),u="Make sure your component is wrapped in StateVocabProvider";async function w(e){const t=this[S.STATE_PATH],r=await a.withTimeout(f(e.serverContextKey),e.timeout,`Failed access to "${t}". Reason: Operation timed out after ${e.timeout}ms. ${u}.`);if(!r)throw new Error(u);return a.get(r,t)}function b(e){return typeof e=="object"&&e!==null&&"serverSlot"in e}function v(e,t){const r={};for(const o in e){const n=e[o];if(b(n))r[o]=n.serverSlot({getState(){return w.apply(this,[{serverContextKey:t.serverContextKey,timeout:t.serverTimeout}])}}),delete r[o].serverSlot,delete r[o].clientSlot;else if(n!==null&&typeof n=="object"){const i=s=>t.wrap({[o]:s});r[o]=v(n,{serverContextKey:t.serverContextKey,serverTimeout:t.serverTimeout,wrap:i})}else r[o]=n}return r.seed=o=>t.wrap(o),r}function x(e,t){const r=Object.keys(e).slice(0,3).join("-"),o=Symbol(r),n=Promise.withResolvers();return{...v(e,{serverContextKey:o,serverTimeout:t.serverTimeout??1e3,wrap:i=>i}),start(){const{size:i}=c(),s=Symbol("test");if(c().set(s,n.promise),c().size===i)throw new Error("Start execution only within a React render context (per-request)");c().delete(s),c().set(o,n.promise)},StateVocabProvider({children:i,value:s}){return s??={},n.resolve(s),y.jsx(m.StateVocabClientProvider,{clientContext:t.clientContext,value:s,children:i})}}}exports.serverify=x;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const S=require("react/jsx-runtime"),i=require("./constants-BTyJxzUH.js"),l=require("react"),y=require("./provider-client-DA53zfcT.js"),T=require("./utils-0CTNJ4ZE.js"),s=l.cache(()=>new Map),d=e=>s().get(e),f=(e,t)=>s().set(e,t);function b(e=""){const t=Symbol("test"),{size:r}=s();if(s().set(t,{}),s().size===r)throw new Error([e,"Start execution only within a React render context (per-request)."].join(" "));s().delete(t)}function x(e){return typeof e=="object"&&e!==null&&i.STATE_SERVER_SLOT in e}function E(e){const t=this[i.STATE_PATH],r=`Failed access to "${t}".`;b(r);const n=d(e.serverContextKey);if(!n)throw new Error(`${r} Reason: no data. Make sure your component is wrapped in StateVocabProvider.`);return T.get(n,t)}function a(e,t){const r={};for(const n in e){const o=e[n];if(x(o))r[n]=o[i.STATE_SERVER_SLOT]({getState(){return E.apply(this,[{serverContextKey:t.serverContextKey}])}}),delete r[i.STATE_SERVER_SLOT],delete r[i.STATE_CLIENT_SLOT];else if(o!==null&&typeof o=="object"){const c=u=>t.wrap({[n]:u});r[n]=a(o,{serverContextKey:t.serverContextKey,wrap:c})}else r[n]=o}return r.seed=n=>t.wrap(n),r}function p(e,t){t??={};const r=Object.keys(e).slice(0,3).join("-"),n=Symbol(r);return{...a(e,{serverContextKey:n,wrap:o=>o}),StateVocabProvider({children:o,value:c}){return c??={},f(n,c),S.jsx(y.StateVocabClientProvider,{clientContext:t.clientContext,value:c,children:o})}}}exports.serverify=p;
package/dist/server.es.js CHANGED
@@ -1,76 +1,74 @@
1
- import { jsx as u } from "react/jsx-runtime";
2
- import { S as m } from "./constants-BB1YAX6c.mjs";
3
- import S, { cache as v } from "react";
4
- import { S as y } from "./provider-client-BhPeK8Kz.mjs";
5
- import { w as f, g as w } from "./utils-xNWifFE9.mjs";
6
- const p = (e) => {
7
- if (S.useState)
8
- throw new Error(`${e} only intended for Server Components`);
9
- }, c = v(() => /* @__PURE__ */ new Map()), d = async (e) => (p("getStateVocab"), await c().get(e)), a = "Make sure your component is wrapped in StateVocabProvider";
10
- async function x(e) {
11
- const t = this[m], r = await f(
12
- d(e.serverContextKey),
13
- e.timeout,
14
- `Failed access to "${t}". Reason: Operation timed out after ${e.timeout}ms. ${a}.`
15
- );
16
- if (!r)
17
- throw new Error(a);
18
- return w(r, t);
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import { a, b as f, S as u } from "./constants-Cf0m6moG.mjs";
3
+ import { cache as y } from "react";
4
+ import { S as p } from "./provider-client-DLa3_Ms9.mjs";
5
+ import { g as x } from "./utils-xV3x3fTc.mjs";
6
+ const s = y(() => /* @__PURE__ */ new Map()), b = (e) => s().get(e), d = (e, t) => s().set(e, t);
7
+ function m(e = "") {
8
+ const t = /* @__PURE__ */ Symbol("test"), { size: r } = s();
9
+ if (s().set(t, {}), s().size === r)
10
+ throw new Error([
11
+ e,
12
+ "Start execution only within a React render context (per-request)."
13
+ ].join(" "));
14
+ s().delete(t);
19
15
  }
20
- function b(e) {
21
- return typeof e == "object" && e !== null && "serverSlot" in e;
16
+ function w(e) {
17
+ return typeof e == "object" && e !== null && a in e;
22
18
  }
23
- function l(e, t) {
19
+ function C(e) {
20
+ const t = this[f], r = `Failed access to "${t}".`;
21
+ m(r);
22
+ const o = b(e.serverContextKey);
23
+ if (!o)
24
+ throw new Error(
25
+ `${r} Reason: no data. Make sure your component is wrapped in StateVocabProvider.`
26
+ );
27
+ return x(o, t);
28
+ }
29
+ function i(e, t) {
24
30
  const r = {};
25
31
  for (const o in e) {
26
32
  const n = e[o];
27
- if (b(n))
28
- r[o] = n.serverSlot({
33
+ if (w(n))
34
+ r[o] = n[a]({
29
35
  getState() {
30
- return x.apply(this, [{
31
- serverContextKey: t.serverContextKey,
32
- timeout: t.serverTimeout
36
+ return C.apply(this, [{
37
+ serverContextKey: t.serverContextKey
33
38
  }]);
34
39
  }
35
- }), delete r[o].serverSlot, delete r[o].clientSlot;
40
+ }), delete r[a], delete r[u];
36
41
  else if (n !== null && typeof n == "object") {
37
- const i = (s) => t.wrap({ [o]: s });
38
- r[o] = l(n, {
42
+ const c = (S) => t.wrap({ [o]: S });
43
+ r[o] = i(n, {
39
44
  serverContextKey: t.serverContextKey,
40
- serverTimeout: t.serverTimeout,
41
- wrap: i
45
+ wrap: c
42
46
  });
43
47
  } else
44
48
  r[o] = n;
45
49
  }
46
50
  return r.seed = (o) => t.wrap(o), r;
47
51
  }
48
- function E(e, t) {
49
- const r = Object.keys(e).slice(0, 3).join("-"), o = Symbol(r), n = Promise.withResolvers();
52
+ function K(e, t) {
53
+ t ??= {};
54
+ const r = Object.keys(e).slice(0, 3).join("-"), o = Symbol(r);
50
55
  return {
51
- ...l(e, {
56
+ ...i(e, {
52
57
  serverContextKey: o,
53
- serverTimeout: t.serverTimeout ?? 1e3,
54
- wrap: (i) => i
58
+ wrap: (n) => n
55
59
  }),
56
- start() {
57
- const { size: i } = c(), s = /* @__PURE__ */ Symbol("test");
58
- if (c().set(s, n.promise), c().size === i)
59
- throw new Error("Start execution only within a React render context (per-request)");
60
- c().delete(s), c().set(o, n.promise);
61
- },
62
- StateVocabProvider({ children: i, value: s }) {
63
- return s ??= {}, n.resolve(s), /* @__PURE__ */ u(
64
- y,
60
+ StateVocabProvider({ children: n, value: c }) {
61
+ return c ??= {}, d(o, c), /* @__PURE__ */ l(
62
+ p,
65
63
  {
66
64
  clientContext: t.clientContext,
67
- value: s,
68
- children: i
65
+ value: c,
66
+ children: n
69
67
  }
70
68
  );
71
69
  }
72
70
  };
73
71
  }
74
72
  export {
75
- E as serverify
73
+ K as serverify
76
74
  };
@@ -3,3 +3,5 @@ export declare const STATE_PATH: unique symbol;
3
3
  export declare const STATE_VERBOSE: unique symbol;
4
4
  export declare const STATE_VERBOSE_PATH: unique symbol;
5
5
  export declare const STATE_SSR: unique symbol;
6
+ export declare const STATE_SERVER_SLOT: unique symbol;
7
+ export declare const STATE_CLIENT_SLOT: unique symbol;
@@ -1,3 +1,4 @@
1
1
  import type { Vocab } from "./state.types";
2
- export declare const getRequestStore: () => Map<symbol, Promise<Vocab>>;
3
- export declare const getStateVocab: (serverContextKey: symbol) => Promise<Vocab | undefined>;
2
+ export declare const getRequestStore: () => Map<symbol, Vocab>;
3
+ export declare const getStateVocab: (serverContextKey: symbol) => Vocab | undefined;
4
+ export declare const setStateVocab: (serverContextKey: symbol, value: Vocab) => Map<symbol, Vocab>;
@@ -1,21 +1,5 @@
1
1
  import { type Context } from "react";
2
- import type { ValueOrTransformer, VocabThis } from "./state.types";
3
- import VocabStore from "./store";
4
- import type { UseInitialStateOptions, UseStateOptions } from "./setup.types";
5
- declare function useState<V>(this: VocabThis, options: UseStateOptions<V> & {
6
- clientContext: Context<VocabStore> | undefined;
7
- }): readonly [V, (nextValue: ValueOrTransformer<V>) => void, () => void];
8
- type Placeholder<V> = {
9
- useState(options?: UseStateOptions<V>): ReturnType<typeof useState<V>>;
10
- useInitialState(options?: UseInitialStateOptions<V>): void;
11
- };
12
- type Slot<V> = {
13
- clientSlot(input: Placeholder<V>): Placeholder<V>;
14
- };
15
- type Clientified<R> = R extends Slot<infer TValue> ? Placeholder<TValue> : R extends object ? {
16
- [K in keyof R]: Clientified<R[K]>;
17
- } : R;
2
+ import type { ClientifyResult } from "./setup.client.types";
18
3
  export declare function clientify<R extends object>(tree: R, clientifyOptions?: {
19
4
  clientContext?: Context<object>;
20
- }): Clientified<R>;
21
- export {};
5
+ }): ClientifyResult<R>;
@@ -0,0 +1,30 @@
1
+ import { STATE_CLIENT_SLOT } from "./constants";
2
+ import type { Deserialize, Serialize, ValueOrFactory, ValueOrTransformer } from "./state.types";
3
+ export type UseStateOptions<V> = {
4
+ defaultValue?: ValueOrFactory<V>;
5
+ delayedSet?: number;
6
+ bidirectional?: true;
7
+ onSet?(nextValue: NoInfer<V>, prevValue: NoInfer<V>): void;
8
+ storage?: unknown;
9
+ serialize?: Serialize<V>;
10
+ deserialize?: Deserialize<V>;
11
+ };
12
+ type UseStateResult<V> = readonly [V, (nextValue: ValueOrTransformer<V>) => void, () => void];
13
+ export type UseInitialStateOptions<V> = {
14
+ defaultValue?: ValueOrFactory<V>;
15
+ storage?: unknown;
16
+ serialize?: Serialize<V>;
17
+ deserialize?: Deserialize<V>;
18
+ };
19
+ type Placeholder<V> = {
20
+ useState(options?: UseStateOptions<V>): UseStateResult<V>;
21
+ useInitialState(options?: UseInitialStateOptions<V>): void;
22
+ };
23
+ export type ClientSlot<V> = {
24
+ [STATE_CLIENT_SLOT](input: Placeholder<V>): Placeholder<V>;
25
+ };
26
+ type Clientified<R> = R extends ClientSlot<infer V> ? Placeholder<V> : R extends object ? {
27
+ [K in keyof R]: Clientified<R[K]>;
28
+ } : R;
29
+ export type ClientifyResult<R> = Clientified<R>;
30
+ export {};
@@ -1,6 +1,7 @@
1
+ import type { ClientSlot } from "./setup.client.types";
2
+ import type { Deserialize, Serialize } from "./state.types";
1
3
  import { type DependencyList } from "react";
2
4
  import VocabStore from "./store";
3
- import type { Deserialize, Serialize } from "./state.types";
4
5
  export declare function useDebounce<T extends (...args: never[]) => unknown>(effect: T, wait: number | undefined, deps?: DependencyList): (...args: Parameters<T>) => void;
5
6
  export declare const sync: <V>(options: {
6
7
  vocabStore: VocabStore;
@@ -10,3 +11,4 @@ export declare const sync: <V>(options: {
10
11
  deserialize: Deserialize<V>;
11
12
  value: V | undefined;
12
13
  }) => void;
14
+ export declare function isClientSlot(value: unknown): value is ClientSlot<unknown>;
@@ -1,14 +1,2 @@
1
- import { STATE_DEFINITION } from "./constants";
2
- type Path<T, Prefix extends string = ""> = {
3
- [K in keyof T & string]: T[K] extends object ? T[K] extends {
4
- [STATE_DEFINITION]: unknown;
5
- } ? `${Prefix}${K}` : `${Prefix}${K}` | Path<T[K], `${Prefix}${K}.`> : `${Prefix}${K}`;
6
- }[keyof T & string];
7
- type InjectPathsOptions<T extends object> = {
8
- path: string;
9
- verbose: boolean;
10
- verbosePath: Path<T>;
11
- ssr: boolean;
12
- };
1
+ import type { InjectPathsOptions } from "./setup.types";
13
2
  export declare function setupStorage<T extends object>(tree: T, options?: Partial<Omit<InjectPathsOptions<T>, "path">>): T;
14
- export {};
@@ -1,36 +1,5 @@
1
- import type { Context, PropsWithChildren, ReactNode } from "react";
2
- import type { Vocab, VocabThis } from "./state.types";
3
- type Placeholder<V> = {
4
- getState(): Promise<V>;
5
- };
6
- type SlotValue<T> = T extends {
7
- serverSlot(input: {
8
- getState(this: VocabThis): infer V;
9
- }): unknown;
10
- } ? V : never;
11
- type ServerifiedValue<R> = {
12
- [K in keyof R]?: [
13
- SlotValue<R[K]>
14
- ] extends [never] ? R[K] extends object ? ServerifiedValue<R[K]> : R[K] : SlotValue<R[K]>;
15
- };
16
- type Serverified<R> = [
17
- SlotValue<R>
18
- ] extends [never] ? R extends object ? {
19
- seed(input: ServerifiedValue<R>): Vocab;
20
- } & {
21
- [K in keyof R]: Serverified<R[K]>;
22
- } : R : Placeholder<SlotValue<R>>;
23
- type ServerifyResult<R extends object> = {
24
- start(): void;
25
- seed(input: ServerifiedValue<R>): Vocab;
26
- StateVocabProvider(props: PropsWithChildren<{
27
- value?: ServerifiedValue<R>;
28
- }>): ReactNode;
29
- } & {
30
- [K in keyof R]: Serverified<R[K]>;
31
- };
32
- export declare function serverify<R extends object>(tree: R, serverifyOptions: {
33
- clientContext: Context<object>;
34
- serverTimeout?: number;
1
+ import type { Context } from "react";
2
+ import type { ServerifyResult } from "./setup.server.types";
3
+ export declare function serverify<R extends object>(tree: R, serverifyOptions?: {
4
+ clientContext?: Context<object>;
35
5
  }): ServerifyResult<R>;
36
- export {};
@@ -0,0 +1,26 @@
1
+ import type { PropsWithChildren, ReactNode } from "react";
2
+ import type { Vocab } from "./state.types";
3
+ import { STATE_SERVER_SLOT } from "./constants";
4
+ type Placeholder<V> = {
5
+ getState(): V;
6
+ };
7
+ export type ServerSlot<V> = {
8
+ [STATE_SERVER_SLOT](input: Placeholder<V>): Placeholder<V>;
9
+ };
10
+ type ServerifiedValue<R> = {
11
+ [K in keyof R]?: R[K] extends ServerSlot<infer V> ? V : R[K] extends object ? ServerifiedValue<R[K]> : R[K];
12
+ };
13
+ type Serverified<R> = R extends ServerSlot<infer V> ? Placeholder<V> : R extends object ? {
14
+ seed(input: ServerifiedValue<R>): Vocab;
15
+ } & {
16
+ [K in keyof R]: Serverified<R[K]>;
17
+ } : R;
18
+ export type ServerifyResult<R extends object> = {
19
+ seed(input: ServerifiedValue<R>): Vocab;
20
+ StateVocabProvider(props: PropsWithChildren<{
21
+ value?: ServerifiedValue<R>;
22
+ }>): ReactNode;
23
+ } & {
24
+ [K in keyof R]: Serverified<R[K]>;
25
+ };
26
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { ServerSlot } from "./setup.server.types";
2
+ export declare function healtcheck(prefix?: string): void;
3
+ export declare function isServerSlot(value: unknown): value is ServerSlot<unknown>;
@@ -1,16 +1,13 @@
1
- import type { Deserialize, Serialize, ValueOrFactory } from "./state.types";
2
- export type UseStateOptions<V> = {
3
- defaultValue?: ValueOrFactory<V>;
4
- delayedSet?: number;
5
- bidirectional?: true;
6
- onSet?(nextValue: NoInfer<V>, prevValue: NoInfer<V>): void;
7
- storage?: unknown;
8
- serialize?: Serialize<V>;
9
- deserialize?: Deserialize<V>;
10
- };
11
- export type UseInitialStateOptions<V> = {
12
- defaultValue?: ValueOrFactory<V>;
13
- storage?: unknown;
14
- serialize?: Serialize<V>;
15
- deserialize?: Deserialize<V>;
1
+ import { STATE_DEFINITION } from "./constants";
2
+ type Path<T, Prefix extends string = ""> = {
3
+ [K in keyof T & string]: T[K] extends object ? T[K] extends {
4
+ [STATE_DEFINITION]: unknown;
5
+ } ? `${Prefix}${K}` : `${Prefix}${K}` | Path<T[K], `${Prefix}${K}.`> : `${Prefix}${K}`;
6
+ }[keyof T & string];
7
+ export type InjectPathsOptions<T extends object> = {
8
+ path: string;
9
+ verbose: boolean;
10
+ verbosePath: Path<T>;
11
+ ssr: boolean;
16
12
  };
13
+ export {};
@@ -1,5 +1,5 @@
1
- import { STATE_DEFINITION, STATE_PATH, STATE_SSR, STATE_VERBOSE, STATE_VERBOSE_PATH } from "./constants";
2
1
  import type { Deserialize, Serialize, ValueOrFactory, ValueOrTransformer, VocabThis } from "./state.types";
2
+ import { STATE_CLIENT_SLOT, STATE_DEFINITION, STATE_PATH, STATE_SERVER_SLOT, STATE_SSR, STATE_VERBOSE, STATE_VERBOSE_PATH } from "./constants";
3
3
  export declare function defineState<V>(superOptions?: {
4
4
  defaultValue?: ValueOrFactory<V>;
5
5
  bidirectional?: true;
@@ -12,12 +12,12 @@ export declare function defineState<V>(superOptions?: {
12
12
  [STATE_VERBOSE]: boolean;
13
13
  [STATE_VERBOSE_PATH]: string;
14
14
  [STATE_SSR]: boolean;
15
- serverSlot(this: VocabThis, input: {
15
+ [STATE_SERVER_SLOT](this: VocabThis, input: {
16
16
  getState(this: VocabThis): V;
17
17
  }): VocabThis & {
18
18
  getState(this: VocabThis): V;
19
19
  };
20
- clientSlot(this: VocabThis, input: {
20
+ [STATE_CLIENT_SLOT](this: VocabThis, input: {
21
21
  useState(this: VocabThis, options?: {
22
22
  defaultValue?: ValueOrFactory<V>;
23
23
  delayedSet?: number;
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "@yakocloud/state-vocab",
3
- "version": "4.2.0",
3
+ "version": "4.3.1",
4
4
  "main": "dist/index.cjs.js",
5
5
  "module": "dist/index.es.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -1,8 +0,0 @@
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
- };
@@ -1 +0,0 @@
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;
@@ -1,3 +0,0 @@
1
- "use strict";function f(e,r,o){if(!r)return e;const n=r.split(".");let t=e;for(const c of n)if(t!==null&&typeof t=="object"&&c in t)t=t[c];else return o;return t===void 0?o:t}function y(e,r,o){const n=r.replace(/\[(\d+)\]/g,".$1").split(".");let t=e;for(let c=0;c<n.length-1;c++){const s=n[c],i=n[c+1];(t[s]===void 0||t[s]===null)&&(t[s]=/^\d+$/.test(i)?[]:{}),t=t[s]}return t[n[n.length-1]]=o,e}function a(e,r=0){let o;return function(...n){o!==void 0&&clearTimeout(o),o=setTimeout(()=>{o=void 0,e.apply(this,n)},r)}}function d(e){const r=JSON.stringify(e,null,2).split(`
2
- `),o=[],n=[];for(const t of r){const c=t.match(/^(\s*)"([^"]+)"(\s*:\s*)(.+)$/);if(c){const[,s,i,l,u]=c;o.push(`${s}%c"${i}"%c${l}%c${u}`),n.push("color: #9cdcfe; font-weight: bold","color: #cccccc","color: #ce9178")}else o.push(`%c${t}`),n.push("color: #cccccc")}console.log(o.join(`
3
- `),...n,e)}const m=e=>typeof e=="function",p=e=>typeof e=="function",h=e=>typeof e<"u",g=e=>p(e)?e():e;async function T(e,r,o){let n;try{return await Promise.race([e,new Promise((t,c)=>{n=setTimeout(()=>{c(new Error(o))},r)})])}finally{clearTimeout(n)}}exports.debounce=a;exports.get=f;exports.isTransformer=m;exports.isValueDefined=h;exports.logStyled=d;exports.set=y;exports.valueOrFactory=g;exports.withTimeout=T;
@@ -1,73 +0,0 @@
1
- function a(t, s, o) {
2
- if (!s)
3
- return t;
4
- const n = s.split(".");
5
- let e = t;
6
- for (const c of n)
7
- if (e !== null && typeof e == "object" && c in e)
8
- e = e[c];
9
- else
10
- return o;
11
- return e === void 0 ? o : e;
12
- }
13
- function y(t, s, o) {
14
- const n = s.replace(/\[(\d+)\]/g, ".$1").split(".");
15
- let e = t;
16
- for (let c = 0; c < n.length - 1; c++) {
17
- const r = n[c], i = n[c + 1];
18
- (e[r] === void 0 || e[r] === null) && (e[r] = /^\d+$/.test(i) ? [] : {}), e = e[r];
19
- }
20
- return e[n[n.length - 1]] = o, t;
21
- }
22
- function d(t, s = 0) {
23
- let o;
24
- return function(...n) {
25
- o !== void 0 && clearTimeout(o), o = setTimeout(() => {
26
- o = void 0, t.apply(this, n);
27
- }, s);
28
- };
29
- }
30
- function p(t) {
31
- const s = JSON.stringify(t, null, 2).split(`
32
- `), o = [], n = [];
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
- o.push(`${r}%c"${i}"%c${l}%c${u}`), n.push(
38
- "color: #9cdcfe; font-weight: bold",
39
- "color: #cccccc",
40
- "color: #ce9178"
41
- );
42
- } else
43
- o.push(`%c${e}`), n.push("color: #cccccc");
44
- }
45
- console.log(o.join(`
46
- `), ...n, t);
47
- }
48
- const m = (t) => typeof t == "function", f = (t) => typeof t == "function", h = (t) => typeof t < "u", g = (t) => f(t) ? t() : t;
49
- async function $(t, s, o) {
50
- let n;
51
- try {
52
- return await Promise.race([
53
- t,
54
- new Promise((e, c) => {
55
- n = setTimeout(() => {
56
- c(new Error(o));
57
- }, s);
58
- })
59
- ]);
60
- } finally {
61
- clearTimeout(n);
62
- }
63
- }
64
- export {
65
- h as a,
66
- d,
67
- a as g,
68
- m as i,
69
- p as l,
70
- y as s,
71
- g as v,
72
- $ as w
73
- };