@graphrefly/ts 0.0.0 → 0.0.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 +135 -0
- package/dist/adapters/index.cjs +105 -66
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +11 -136
- package/dist/adapters/index.d.ts +11 -136
- package/dist/adapters/index.js +27 -225
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/observe-storage.d.cts +4 -4
- package/dist/adapters/observe-storage.d.ts +4 -4
- package/dist/adapters/observe-storage.js +1 -0
- package/dist/adapters/observe-storage.js.map +1 -1
- package/dist/adapters/react.cjs +166 -0
- package/dist/adapters/react.cjs.map +1 -0
- package/dist/adapters/react.d.cts +31 -0
- package/dist/adapters/react.d.ts +31 -0
- package/dist/adapters/react.js +51 -0
- package/dist/adapters/react.js.map +1 -0
- package/dist/adapters/solid.cjs +157 -0
- package/dist/adapters/solid.cjs.map +1 -0
- package/dist/adapters/solid.d.cts +26 -0
- package/dist/adapters/solid.d.ts +26 -0
- package/dist/adapters/solid.js +48 -0
- package/dist/adapters/solid.js.map +1 -0
- package/dist/adapters/svelte.cjs +148 -0
- package/dist/adapters/svelte.cjs.map +1 -0
- package/dist/adapters/svelte.d.cts +31 -0
- package/dist/adapters/svelte.d.ts +31 -0
- package/dist/adapters/svelte.js +46 -0
- package/dist/adapters/svelte.js.map +1 -0
- package/dist/adapters/vue.cjs +155 -0
- package/dist/adapters/vue.cjs.map +1 -0
- package/dist/adapters/vue.d.cts +26 -0
- package/dist/adapters/vue.d.ts +26 -0
- package/dist/adapters/vue.js +46 -0
- package/dist/adapters/vue.js.map +1 -0
- package/dist/agent-runtime-BesGDZcB.d.ts +555 -0
- package/dist/agent-runtime-DZTJ3C-p.d.cts +555 -0
- package/dist/agentic-memory-BmRCvh0d.d.ts +517 -0
- package/dist/agentic-memory-DfuVZ-lY.d.cts +517 -0
- package/dist/capability-admission-B0BzqAm5.d.cts +102 -0
- package/dist/capability-admission-g0mn9hpq.d.ts +102 -0
- package/dist/{chunk-JR4IKCR2.js → chunk-2747WN4Y.js} +5 -5
- package/dist/{chunk-2ILL7HQI.js → chunk-3JR3EDB2.js} +17 -17
- package/dist/{chunk-2ILL7HQI.js.map → chunk-3JR3EDB2.js.map} +1 -1
- package/dist/{chunk-GDL26N2T.js → chunk-3KN7NJDR.js} +2 -2
- package/dist/{chunk-DJC4CHLQ.js → chunk-43BKLFZU.js} +9 -9
- package/dist/chunk-6XAIOL3X.js +2407 -0
- package/dist/chunk-6XAIOL3X.js.map +1 -0
- package/dist/{chunk-SCRFRCGR.js → chunk-BSQGE5PS.js} +1 -1
- package/dist/{chunk-Y3ZLRGHC.js → chunk-CZNV3VXM.js} +16 -16
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/{chunk-JIMUDQN3.js → chunk-FBUU43PM.js} +2 -2
- package/dist/chunk-H75VXTGT.js +219 -0
- package/dist/chunk-H75VXTGT.js.map +1 -0
- package/dist/{chunk-RIIOUTGM.js → chunk-HKK2JD7Z.js} +12 -9
- package/dist/chunk-HKK2JD7Z.js.map +1 -0
- package/dist/{chunk-D6BG7U6A.js → chunk-IXZBUWSP.js} +3 -3
- package/dist/chunk-PC3BTTBE.js +3217 -0
- package/dist/chunk-PC3BTTBE.js.map +1 -0
- package/dist/chunk-QFY4AFY4.js +879 -0
- package/dist/chunk-QFY4AFY4.js.map +1 -0
- package/dist/{chunk-DK554R7P.js → chunk-S6HXABGL.js} +2 -1
- package/dist/chunk-S6HXABGL.js.map +1 -0
- package/dist/{chunk-PKVBHGBM.js → chunk-SS2A464I.js} +7 -7
- package/dist/chunk-UT3MHJCW.js +49 -0
- package/dist/chunk-UT3MHJCW.js.map +1 -0
- package/dist/{chunk-G4M3NHRJ.js → chunk-V7CIJE4B.js} +3 -3
- package/dist/{chunk-TEW47IVR.js → chunk-VPEFSDME.js} +2 -2
- package/dist/chunk-VTHLCFN4.js +368 -0
- package/dist/chunk-VTHLCFN4.js.map +1 -0
- package/dist/{chunk-SWTLEQL6.js → chunk-WQIA3GFB.js} +2 -2
- package/dist/chunk-WQIA3GFB.js.map +1 -0
- package/dist/{chunk-I3IHOHCJ.js → chunk-XKXWK2KP.js} +108 -64
- package/dist/chunk-XKXWK2KP.js.map +1 -0
- package/dist/{chunk-COHO25CZ.js → chunk-YDSIVHRR.js} +553 -7
- package/dist/chunk-YDSIVHRR.js.map +1 -0
- package/dist/chunk-YXMZ2N6J.js +1884 -0
- package/dist/chunk-YXMZ2N6J.js.map +1 -0
- package/dist/composition/index.cjs +102 -57
- package/dist/composition/index.cjs.map +1 -1
- package/dist/composition/index.d.cts +4 -4
- package/dist/composition/index.d.ts +4 -4
- package/dist/composition/index.js +6 -5
- package/dist/core/index.cjs +102 -57
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +5 -4
- package/dist/cqrs/index.cjs.map +1 -1
- package/dist/cqrs/index.d.cts +4 -4
- package/dist/cqrs/index.d.ts +4 -4
- package/dist/cqrs/index.js +3 -2
- package/dist/cqrs/index.js.map +1 -1
- package/dist/cqrs/messaging.cjs +312 -0
- package/dist/cqrs/messaging.cjs.map +1 -0
- package/dist/cqrs/messaging.d.cts +57 -0
- package/dist/cqrs/messaging.d.ts +57 -0
- package/dist/cqrs/messaging.js +274 -0
- package/dist/cqrs/messaging.js.map +1 -0
- package/dist/cqrs/work-queue.cjs +329 -0
- package/dist/cqrs/work-queue.cjs.map +1 -0
- package/dist/cqrs/work-queue.d.cts +90 -0
- package/dist/cqrs/work-queue.d.ts +90 -0
- package/dist/cqrs/work-queue.js +292 -0
- package/dist/cqrs/work-queue.js.map +1 -0
- package/dist/data/index.cjs +19 -0
- package/dist/data/index.cjs.map +1 -0
- package/dist/data/index.d.cts +36 -0
- package/dist/data/index.d.ts +36 -0
- package/dist/data/index.js +1 -0
- package/dist/data/index.js.map +1 -0
- package/dist/data-structures/index.cjs +105 -57
- package/dist/data-structures/index.cjs.map +1 -1
- package/dist/data-structures/index.d.cts +8 -8
- package/dist/data-structures/index.d.ts +8 -8
- package/dist/data-structures/index.js +7 -6
- package/dist/{describe-BZb7AS2y.d.ts → describe-BpyJuWkw.d.ts} +1 -1
- package/dist/{describe-Ciu8SUnN.d.cts → describe-DYMw_l1C.d.cts} +1 -1
- package/dist/executors/work-queue.cjs +342 -0
- package/dist/executors/work-queue.cjs.map +1 -0
- package/dist/executors/work-queue.d.cts +90 -0
- package/dist/executors/work-queue.d.ts +90 -0
- package/dist/executors/work-queue.js +306 -0
- package/dist/executors/work-queue.js.map +1 -0
- package/dist/graph/index.cjs +112 -58
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +9 -9
- package/dist/graph/index.d.ts +9 -9
- package/dist/graph/index.js +18 -17
- package/dist/{graph-DfdF9zy4.d.ts → graph-D-1-SQeC.d.ts} +3 -3
- package/dist/{graph-s23RbbFO.d.cts → graph-DCEWh4T2.d.cts} +3 -3
- package/dist/{index-CAEmLCYF.d.cts → index-72VZC0-E.d.cts} +2 -2
- package/dist/{index-SnzZu3x7.d.ts → index-Bmxeu0nK.d.ts} +2 -2
- package/dist/index.cjs +112 -58
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -10
- package/dist/index.d.ts +11 -10
- package/dist/index.js +118 -113
- package/dist/inspection/boundary.cjs +98 -0
- package/dist/inspection/boundary.cjs.map +1 -0
- package/dist/inspection/boundary.d.cts +61 -0
- package/dist/inspection/boundary.d.ts +61 -0
- package/dist/inspection/boundary.js +75 -0
- package/dist/inspection/boundary.js.map +1 -0
- package/dist/{messages-BZqrGGm1.d.ts → messages-CAzUPPJM.d.cts} +10 -5
- package/dist/{messages-BZqrGGm1.d.cts → messages-CAzUPPJM.d.ts} +10 -5
- package/dist/messaging/index.cjs +744 -613
- package/dist/messaging/index.cjs.map +1 -1
- package/dist/messaging/index.d.cts +216 -160
- package/dist/messaging/index.d.ts +216 -160
- package/dist/messaging/index.js +19 -749
- package/dist/messaging/index.js.map +1 -1
- package/dist/operators/index.cjs +102 -57
- package/dist/operators/index.cjs.map +1 -1
- package/dist/operators/index.d.cts +6 -6
- package/dist/operators/index.d.ts +6 -6
- package/dist/operators/index.js +8 -7
- package/dist/orchestration/index.cjs +3333 -59
- package/dist/orchestration/index.cjs.map +1 -1
- package/dist/orchestration/index.d.cts +7 -4
- package/dist/orchestration/index.d.ts +7 -4
- package/dist/orchestration/index.js +49 -8
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/messaging.cjs +314 -0
- package/dist/orchestration/messaging.cjs.map +1 -0
- package/dist/orchestration/messaging.d.cts +59 -0
- package/dist/orchestration/messaging.d.ts +59 -0
- package/dist/orchestration/messaging.js +276 -0
- package/dist/orchestration/messaging.js.map +1 -0
- package/dist/orchestration/work-queue.cjs +262 -0
- package/dist/orchestration/work-queue.cjs.map +1 -0
- package/dist/orchestration/work-queue.d.cts +85 -0
- package/dist/orchestration/work-queue.d.ts +85 -0
- package/dist/orchestration/work-queue.js +226 -0
- package/dist/orchestration/work-queue.js.map +1 -0
- package/dist/patterns/event-flow.cjs +447 -0
- package/dist/patterns/event-flow.cjs.map +1 -0
- package/dist/patterns/event-flow.d.cts +115 -0
- package/dist/patterns/event-flow.d.ts +115 -0
- package/dist/patterns/event-flow.js +14 -0
- package/dist/patterns/event-flow.js.map +1 -0
- package/dist/patterns/index.cjs +423 -18
- package/dist/patterns/index.cjs.map +1 -1
- package/dist/patterns/index.d.cts +8 -5
- package/dist/patterns/index.d.ts +8 -5
- package/dist/patterns/index.js +13 -4
- package/dist/{reactive-collection-Cb1II1Fi.d.ts → reactive-collection-BAmfrGjd.d.ts} +9 -9
- package/dist/{reactive-collection-BxBqtIOE.d.cts → reactive-collection-DNV0-gFi.d.cts} +9 -9
- package/dist/{reactive-collection-storage-D-KmjE0J.d.cts → reactive-collection-storage-BNEldDyi.d.cts} +5 -5
- package/dist/{reactive-collection-storage-BNiEc-Gd.d.ts → reactive-collection-storage-YZsAQsWK.d.ts} +5 -5
- package/dist/{reactive-map-D-g3dv8I.d.cts → reactive-map-DRD1LJ2H.d.cts} +6 -6
- package/dist/{reactive-map-BcB4KsQR.d.ts → reactive-map-EsDiCmJk.d.ts} +6 -6
- package/dist/render/index.d.cts +3 -3
- package/dist/render/index.d.ts +3 -3
- package/dist/render/index.js +1 -0
- package/dist/{semantic-memory-graph-BYoIlP35.d.cts → semantic-memory-graph-DKuNzuWw.d.cts} +2 -2
- package/dist/{semantic-memory-graph-CxyXLms3.d.ts → semantic-memory-graph-uwbwJdhe.d.ts} +2 -2
- package/dist/solutions/index.cjs +4478 -2
- package/dist/solutions/index.cjs.map +1 -1
- package/dist/solutions/index.d.cts +13 -519
- package/dist/solutions/index.d.ts +13 -519
- package/dist/solutions/index.js +90 -6
- package/dist/solutions/reactive-layout/browser/index.cjs +449 -0
- package/dist/solutions/reactive-layout/browser/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/browser/index.d.cts +44 -0
- package/dist/solutions/reactive-layout/browser/index.d.ts +44 -0
- package/dist/solutions/reactive-layout/browser/index.js +69 -0
- package/dist/solutions/reactive-layout/browser/index.js.map +1 -0
- package/dist/solutions/reactive-layout/index.cjs +4266 -0
- package/dist/solutions/reactive-layout/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/index.d.cts +581 -0
- package/dist/solutions/reactive-layout/index.d.ts +581 -0
- package/dist/solutions/reactive-layout/index.js +86 -0
- package/dist/solutions/reactive-layout/index.js.map +1 -0
- package/dist/solutions/reactive-layout/node-canvas/index.cjs +545 -0
- package/dist/solutions/reactive-layout/node-canvas/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/node-canvas/index.d.cts +54 -0
- package/dist/solutions/reactive-layout/node-canvas/index.d.ts +54 -0
- package/dist/solutions/reactive-layout/node-canvas/index.js +131 -0
- package/dist/solutions/reactive-layout/node-canvas/index.js.map +1 -0
- package/dist/solutions/reactive-layout/react-native/index.cjs +494 -0
- package/dist/solutions/reactive-layout/react-native/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/react-native/index.d.cts +51 -0
- package/dist/solutions/reactive-layout/react-native/index.d.ts +51 -0
- package/dist/solutions/reactive-layout/react-native/index.js +77 -0
- package/dist/solutions/reactive-layout/react-native/index.js.map +1 -0
- package/dist/solutions/reactive-layout/skia/index.cjs +547 -0
- package/dist/solutions/reactive-layout/skia/index.cjs.map +1 -0
- package/dist/solutions/reactive-layout/skia/index.d.cts +64 -0
- package/dist/solutions/reactive-layout/skia/index.d.ts +64 -0
- package/dist/solutions/reactive-layout/skia/index.js +70 -0
- package/dist/solutions/reactive-layout/skia/index.js.map +1 -0
- package/dist/solutions/work-item/actions.cjs +2164 -0
- package/dist/solutions/work-item/actions.cjs.map +1 -0
- package/dist/solutions/work-item/actions.d.cts +201 -0
- package/dist/solutions/work-item/actions.d.ts +201 -0
- package/dist/solutions/work-item/actions.js +1454 -0
- package/dist/solutions/work-item/actions.js.map +1 -0
- package/dist/solutions/work-item/scheduling.cjs +2454 -0
- package/dist/solutions/work-item/scheduling.cjs.map +1 -0
- package/dist/solutions/work-item/scheduling.d.cts +433 -0
- package/dist/solutions/work-item/scheduling.d.ts +433 -0
- package/dist/solutions/work-item/scheduling.js +32 -0
- package/dist/solutions/work-item/scheduling.js.map +1 -0
- package/dist/solutions/work-item/work-queue.cjs +306 -0
- package/dist/solutions/work-item/work-queue.cjs.map +1 -0
- package/dist/solutions/work-item/work-queue.d.cts +71 -0
- package/dist/solutions/work-item/work-queue.d.ts +71 -0
- package/dist/solutions/work-item/work-queue.js +270 -0
- package/dist/solutions/work-item/work-queue.js.map +1 -0
- package/dist/sources/browser.cjs +169 -57
- package/dist/sources/browser.cjs.map +1 -1
- package/dist/sources/browser.d.cts +33 -6
- package/dist/sources/browser.d.ts +33 -6
- package/dist/sources/browser.js +73 -6
- package/dist/sources/browser.js.map +1 -1
- package/dist/sources/index.cjs +102 -57
- package/dist/sources/index.cjs.map +1 -1
- package/dist/sources/index.d.cts +5 -5
- package/dist/sources/index.d.ts +5 -5
- package/dist/sources/index.js +6 -5
- package/dist/sources/node.cjs.map +1 -1
- package/dist/sources/node.d.cts +4 -4
- package/dist/sources/node.d.ts +4 -4
- package/dist/sources/node.js +2 -1
- package/dist/sources/node.js.map +1 -1
- package/dist/storage/browser.js +1 -0
- package/dist/storage/browser.js.map +1 -1
- package/dist/storage/index.d.cts +5 -5
- package/dist/storage/index.d.ts +5 -5
- package/dist/storage/index.js +5 -4
- package/dist/storage/node.js +1 -0
- package/dist/storage/node.js.map +1 -1
- package/dist/store-C-joM4gh.d.ts +123 -0
- package/dist/store-CNJwmT-h.d.cts +123 -0
- package/dist/testing/index.cjs +1 -0
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +3 -2
- package/dist/{types-h12mNYbq.d.ts → types-BsJvElYZ.d.ts} +31 -31
- package/dist/{types-bNMSWKqF.d.cts → types-CcPIn7sy.d.cts} +31 -31
- package/dist/work-item-runtime-C3M79vE9.d.ts +228 -0
- package/dist/work-item-runtime-qaVgsL0T.d.cts +228 -0
- package/dist/work-queue/index.cjs +1132 -0
- package/dist/work-queue/index.cjs.map +1 -0
- package/dist/work-queue/index.d.cts +369 -0
- package/dist/work-queue/index.d.ts +369 -0
- package/dist/work-queue/index.js +1078 -0
- package/dist/work-queue/index.js.map +1 -0
- package/package.json +266 -2
- package/dist/chunk-COHO25CZ.js.map +0 -1
- package/dist/chunk-DK554R7P.js.map +0 -1
- package/dist/chunk-I3IHOHCJ.js.map +0 -1
- package/dist/chunk-RIIOUTGM.js.map +0 -1
- package/dist/chunk-SWTLEQL6.js.map +0 -1
- /package/dist/{chunk-JR4IKCR2.js.map → chunk-2747WN4Y.js.map} +0 -0
- /package/dist/{chunk-GDL26N2T.js.map → chunk-3KN7NJDR.js.map} +0 -0
- /package/dist/{chunk-DJC4CHLQ.js.map → chunk-43BKLFZU.js.map} +0 -0
- /package/dist/{chunk-SCRFRCGR.js.map → chunk-BSQGE5PS.js.map} +0 -0
- /package/dist/{chunk-Y3ZLRGHC.js.map → chunk-CZNV3VXM.js.map} +0 -0
- /package/dist/{chunk-JIMUDQN3.js.map → chunk-FBUU43PM.js.map} +0 -0
- /package/dist/{chunk-D6BG7U6A.js.map → chunk-IXZBUWSP.js.map} +0 -0
- /package/dist/{chunk-PKVBHGBM.js.map → chunk-SS2A464I.js.map} +0 -0
- /package/dist/{chunk-G4M3NHRJ.js.map → chunk-V7CIJE4B.js.map} +0 -0
- /package/dist/{chunk-TEW47IVR.js.map → chunk-VPEFSDME.js.map} +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { O as ObserveEvent, d as Graph } from '../graph-
|
|
1
|
+
import { O as ObserveEvent, d as Graph } from '../graph-DCEWh4T2.cjs';
|
|
2
2
|
import { d as AppendLogStorageTier } from '../append-log-DisvEReb.cjs';
|
|
3
3
|
import { O as ObserveEventFrame } from '../observe-event-log-0SVsx7JG.cjs';
|
|
4
4
|
export { c as ObserveEventLogPage } from '../observe-event-log-0SVsx7JG.cjs';
|
|
5
5
|
import '../core/index.cjs';
|
|
6
|
-
import '../types-
|
|
7
|
-
import '../messages-
|
|
6
|
+
import '../types-CcPIn7sy.cjs';
|
|
7
|
+
import '../messages-CAzUPPJM.cjs';
|
|
8
8
|
import '../codec-BB7p8fJc.cjs';
|
|
9
|
-
import '../describe-
|
|
9
|
+
import '../describe-DYMw_l1C.cjs';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Graph-bound observe storage adapters.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { O as ObserveEvent, d as Graph } from '../graph-
|
|
1
|
+
import { O as ObserveEvent, d as Graph } from '../graph-D-1-SQeC.js';
|
|
2
2
|
import { d as AppendLogStorageTier } from '../append-log-DzKMmjxx.js';
|
|
3
3
|
import { O as ObserveEventFrame } from '../observe-event-log-Dnm76owp.js';
|
|
4
4
|
export { c as ObserveEventLogPage } from '../observe-event-log-Dnm76owp.js';
|
|
5
5
|
import '../core/index.js';
|
|
6
|
-
import '../types-
|
|
7
|
-
import '../messages-
|
|
6
|
+
import '../types-BsJvElYZ.js';
|
|
7
|
+
import '../messages-CAzUPPJM.js';
|
|
8
8
|
import '../codec-BB7p8fJc.js';
|
|
9
|
-
import '../describe-
|
|
9
|
+
import '../describe-BpyJuWkw.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Graph-bound observe storage adapters.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/adapters/observe-storage.ts"],"sourcesContent":["/**\n * Graph-bound observe storage adapters.\n *\n * Passive storage lives under ../storage. This subpath owns bridges that need\n * Graph.observe() and therefore sit above both graph and passive storage (D125).\n */\n\nimport type { Graph } from \"../graph/graph.js\";\nimport type { ObserveEvent } from \"../graph/inspect.js\";\nimport type { AppendLogStorageTier } from \"../storage/append-log.js\";\nimport {\n\ttype ObserveEventFrame,\n\ttype ObserveEventLogPage,\n\tobserveEventFrame,\n} from \"../storage/observe-event-log.js\";\n\n/** Adapter-owned sink for observed graph events (D57/D74/D125). */\nexport interface ObserveSink<T = ObserveEvent> {\n\t/** Persist or forward one mapped observe event. Thenables are serialized in observe order. */\n\twrite(event: T): void | PromiseLike<void>;\n\t/** Optional adapter flush barrier. Runs after all earlier writes. */\n\tflush?(): void | PromiseLike<void>;\n\t/** Optional adapter rollback hook. Runs after all earlier writes. */\n\trollback?(): void | PromiseLike<void>;\n\t/** Optional adapter cleanup hook. Runs once after queued work drains. */\n\tdispose?(): void | PromiseLike<void>;\n}\n\n/** Error routing context for attachObserveSink lifecycle hooks. */\nexport interface ObserveSinkErrorContext<T = ObserveEvent> {\n\tphase: \"map\" | \"write\" | \"flush\" | \"rollback\" | \"dispose\";\n\tevent?: ObserveEvent;\n\tvalue?: T;\n}\n\n/** Queue-drain completion callback for observe-sink control calls (D75). */\nexport type ObserveSinkDone = () => void;\n\n/** Options for attaching a sink to the read-only observe egress (D74/D125). */\nexport interface AttachObserveSinkOptions<T = ObserveEvent> {\n\t/** Optional exact-id or subtree path filter; forwarded to `graph.observe(path?)`. */\n\tpath?: string;\n\t/** Optional projection/filter. Return `undefined` to drop an observed event. */\n\tmap?: (event: ObserveEvent) => T | undefined;\n\t/** Optional error hook for mapper, write, and lifecycle failures. */\n\tonError?: (error: unknown, ctx: ObserveSinkErrorContext<T>) => void;\n}\n\n/** Done-only callback control handle for an attached observe sink (D75). */\nexport interface ObserveSinkHandle {\n\tflush(done?: ObserveSinkDone): void;\n\trollback(done?: ObserveSinkDone): void;\n\tdispose(done?: ObserveSinkDone): void;\n}\n\ntype QueueItem<T> =\n\t| { kind: \"write\"; event: ObserveEvent; value: T }\n\t| { kind: \"flush\"; done?: ObserveSinkDone }\n\t| { kind: \"rollback\"; done?: ObserveSinkDone }\n\t| { kind: \"dispose\" };\n\n/** Options for persisting Graph.observe() events into an append log. */\nexport interface AttachObserveEventLogOptions<T = ObserveEvent> {\n\tpath?: string;\n\tstream?: string;\n\tmap?: (event: ObserveEvent) => T | undefined;\n\tonError?: (error: unknown, ctx: ObserveSinkErrorContext<ObserveEventFrame<T>>) => void;\n}\n\n/** Done-callback lifecycle handle for an attached observe-event log. */\nexport interface ObserveEventLogHandle extends ObserveSinkHandle {\n\tflush(done?: ObserveSinkDone): void;\n\trollback(done?: ObserveSinkDone): void;\n\tdispose(done?: ObserveSinkDone): void;\n}\n\nexport type { ObserveEventFrame, ObserveEventLogPage };\n\n/**\n * Attach adapter-owned storage to `Graph.observe()` read-only egress (D57/D74/D125). Writes are\n * serialized in observe order; lifecycle barriers drain the queue without mutating graph topology.\n */\nexport function attachObserveSink<T = ObserveEvent>(\n\tgraph: Graph,\n\tsink: ObserveSink<T>,\n\topts: AttachObserveSinkOptions<T> = {},\n): ObserveSinkHandle {\n\tconst { map, onError, path } = opts;\n\tconst queue: QueueItem<T>[] = [];\n\tconst disposeDone: ObserveSinkDone[] = [];\n\tlet draining = false;\n\tlet disposeRequested = false;\n\tlet disposed = false;\n\n\tfunction report(error: unknown, ctx: ObserveSinkErrorContext<T>): void {\n\t\tif (!onError) return;\n\t\ttry {\n\t\t\tonError(error, ctx);\n\t\t} catch {\n\t\t\t// Error routing is best-effort; never let adapter logging wedge the queue.\n\t\t}\n\t}\n\n\tfunction callDone(done?: ObserveSinkDone): void {\n\t\ttry {\n\t\t\tdone?.();\n\t\t} catch {\n\t\t\t// Completion callbacks are advisory only; never wedge the queue on observer code.\n\t\t}\n\t}\n\n\tfunction run(item: QueueItem<T>): void | PromiseLike<void> {\n\t\tswitch (item.kind) {\n\t\t\tcase \"write\":\n\t\t\t\treturn sink.write(item.value);\n\t\t\tcase \"flush\":\n\t\t\t\treturn sink.flush?.();\n\t\t\tcase \"rollback\":\n\t\t\t\treturn sink.rollback?.();\n\t\t\tcase \"dispose\":\n\t\t\t\treturn sink.dispose?.();\n\t\t}\n\t}\n\n\tfunction finish(item: QueueItem<T>): void {\n\t\tif (item.kind === \"dispose\") {\n\t\t\tdisposed = true;\n\t\t\tfor (const done of disposeDone.splice(0)) callDone(done);\n\t\t} else if (item.kind !== \"write\") {\n\t\t\tcallDone(item.done);\n\t\t}\n\t\tdraining = false;\n\t\tdrain();\n\t}\n\n\tfunction fail(item: QueueItem<T>, error: unknown): void {\n\t\tif (item.kind === \"write\")\n\t\t\treport(error, { phase: \"write\", event: item.event, value: item.value });\n\t\telse report(error, { phase: item.kind });\n\t\tfinish(item);\n\t}\n\n\tfunction chainThenable(item: QueueItem<T>, value: unknown): boolean {\n\t\tif ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) return false;\n\n\t\tlet then: unknown;\n\t\ttry {\n\t\t\tthen = (value as { then?: unknown }).then;\n\t\t} catch (error) {\n\t\t\tfail(item, error);\n\t\t\treturn true;\n\t\t}\n\t\tif (typeof then !== \"function\") return false;\n\n\t\tlet settled = false;\n\t\tconst settle = (next: () => void) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tnext();\n\t\t};\n\t\ttry {\n\t\t\t(then as (onFulfilled: () => void, onRejected: (error: unknown) => void) => unknown).call(\n\t\t\t\tvalue,\n\t\t\t\t() => settle(() => finish(item)),\n\t\t\t\t(error) => settle(() => fail(item, error)),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tsettle(() => fail(item, error));\n\t\t}\n\t\treturn true;\n\t}\n\n\tfunction drain(): void {\n\t\tif (draining) return;\n\t\tconst item = queue.shift();\n\t\tif (!item) return;\n\t\tdraining = true;\n\t\tlet result: void | PromiseLike<void>;\n\t\ttry {\n\t\t\tresult = run(item);\n\t\t} catch (error) {\n\t\t\tfail(item, error);\n\t\t\treturn;\n\t\t}\n\t\tif (chainThenable(item, result)) return;\n\t\tfinish(item);\n\t}\n\n\tfunction enqueueBarrier(kind: \"flush\" | \"rollback\", done?: ObserveSinkDone): void {\n\t\tif (disposeRequested) {\n\t\t\tcallDone(done);\n\t\t\treturn;\n\t\t}\n\t\tqueue.push({ kind, done });\n\t\tdrain();\n\t}\n\n\tconst stop = graph.observe(path).subscribe((event) => {\n\t\tif (disposeRequested) return;\n\t\tlet value: T | undefined;\n\t\ttry {\n\t\t\tvalue = map ? map(event) : (event as unknown as T);\n\t\t} catch (error) {\n\t\t\treport(error, { phase: \"map\", event });\n\t\t\treturn;\n\t\t}\n\t\tif (value === undefined) return;\n\t\tqueue.push({ kind: \"write\", event, value });\n\t\tdrain();\n\t});\n\n\treturn {\n\t\tflush(done?: ObserveSinkDone): void {\n\t\t\tenqueueBarrier(\"flush\", done);\n\t\t},\n\t\trollback(done?: ObserveSinkDone): void {\n\t\t\tenqueueBarrier(\"rollback\", done);\n\t\t},\n\t\tdispose(done?: ObserveSinkDone): void {\n\t\t\tif (disposed) {\n\t\t\t\tcallDone(done);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (done) disposeDone.push(done);\n\t\t\tif (disposeRequested) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdisposeRequested = true;\n\t\t\tstop();\n\t\t\tqueue.push({ kind: \"dispose\" });\n\t\t\tdrain();\n\t\t},\n\t};\n}\n\n/**\n * Persist Graph.observe() events to an append log. This is a graph-bound\n * adapter over passive storage frames, not graph restore or projection.\n */\nexport function attachObserveEventLog<T = ObserveEvent>(\n\tgraph: Graph,\n\tlog: AppendLogStorageTier<ObserveEventFrame<T>>,\n\topts: AttachObserveEventLogOptions<T> = {},\n): ObserveEventLogHandle {\n\treturn attachObserveSink<ObserveEventFrame<T>>(\n\t\tgraph,\n\t\t{ write: (frame) => log.append(frame).then(() => undefined) },\n\t\t{\n\t\t\tpath: opts.path,\n\t\t\tmap: (event) => {\n\t\t\t\tconst value = opts.map ? opts.map(event) : (event as unknown as T);\n\t\t\t\treturn value === undefined ? undefined : observeEventFrame(event, value, opts);\n\t\t\t},\n\t\t\tonError: opts.onError,\n\t\t},\n\t);\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/observe-storage.ts"],"sourcesContent":["/**\n * Graph-bound observe storage adapters.\n *\n * Passive storage lives under ../storage. This subpath owns bridges that need\n * Graph.observe() and therefore sit above both graph and passive storage (D125).\n */\n\nimport type { Graph } from \"../graph/graph.js\";\nimport type { ObserveEvent } from \"../graph/inspect.js\";\nimport type { AppendLogStorageTier } from \"../storage/append-log.js\";\nimport {\n\ttype ObserveEventFrame,\n\ttype ObserveEventLogPage,\n\tobserveEventFrame,\n} from \"../storage/observe-event-log.js\";\n\n/** Adapter-owned sink for observed graph events (D57/D74/D125). */\nexport interface ObserveSink<T = ObserveEvent> {\n\t/** Persist or forward one mapped observe event. Thenables are serialized in observe order. */\n\twrite(event: T): void | PromiseLike<void>;\n\t/** Optional adapter flush barrier. Runs after all earlier writes. */\n\tflush?(): void | PromiseLike<void>;\n\t/** Optional adapter rollback hook. Runs after all earlier writes. */\n\trollback?(): void | PromiseLike<void>;\n\t/** Optional adapter cleanup hook. Runs once after queued work drains. */\n\tdispose?(): void | PromiseLike<void>;\n}\n\n/** Error routing context for attachObserveSink lifecycle hooks. */\nexport interface ObserveSinkErrorContext<T = ObserveEvent> {\n\tphase: \"map\" | \"write\" | \"flush\" | \"rollback\" | \"dispose\";\n\tevent?: ObserveEvent;\n\tvalue?: T;\n}\n\n/** Queue-drain completion callback for observe-sink control calls (D75). */\nexport type ObserveSinkDone = () => void;\n\n/** Options for attaching a sink to the read-only observe egress (D74/D125). */\nexport interface AttachObserveSinkOptions<T = ObserveEvent> {\n\t/** Optional exact-id or subtree path filter; forwarded to `graph.observe(path?)`. */\n\tpath?: string;\n\t/** Optional projection/filter. Return `undefined` to drop an observed event. */\n\tmap?: (event: ObserveEvent) => T | undefined;\n\t/** Optional error hook for mapper, write, and lifecycle failures. */\n\tonError?: (error: unknown, ctx: ObserveSinkErrorContext<T>) => void;\n}\n\n/** Done-only callback control handle for an attached observe sink (D75). */\nexport interface ObserveSinkHandle {\n\tflush(done?: ObserveSinkDone): void;\n\trollback(done?: ObserveSinkDone): void;\n\tdispose(done?: ObserveSinkDone): void;\n}\n\ntype QueueItem<T> =\n\t| { kind: \"write\"; event: ObserveEvent; value: T }\n\t| { kind: \"flush\"; done?: ObserveSinkDone }\n\t| { kind: \"rollback\"; done?: ObserveSinkDone }\n\t| { kind: \"dispose\" };\n\n/** Options for persisting Graph.observe() events into an append log. */\nexport interface AttachObserveEventLogOptions<T = ObserveEvent> {\n\tpath?: string;\n\tstream?: string;\n\tmap?: (event: ObserveEvent) => T | undefined;\n\tonError?: (error: unknown, ctx: ObserveSinkErrorContext<ObserveEventFrame<T>>) => void;\n}\n\n/** Done-callback lifecycle handle for an attached observe-event log. */\nexport interface ObserveEventLogHandle extends ObserveSinkHandle {\n\tflush(done?: ObserveSinkDone): void;\n\trollback(done?: ObserveSinkDone): void;\n\tdispose(done?: ObserveSinkDone): void;\n}\n\nexport type { ObserveEventFrame, ObserveEventLogPage };\n\n/**\n * Attach adapter-owned storage to `Graph.observe()` read-only egress (D57/D74/D125). Writes are\n * serialized in observe order; lifecycle barriers drain the queue without mutating graph topology.\n */\nexport function attachObserveSink<T = ObserveEvent>(\n\tgraph: Graph,\n\tsink: ObserveSink<T>,\n\topts: AttachObserveSinkOptions<T> = {},\n): ObserveSinkHandle {\n\tconst { map, onError, path } = opts;\n\tconst queue: QueueItem<T>[] = [];\n\tconst disposeDone: ObserveSinkDone[] = [];\n\tlet draining = false;\n\tlet disposeRequested = false;\n\tlet disposed = false;\n\n\tfunction report(error: unknown, ctx: ObserveSinkErrorContext<T>): void {\n\t\tif (!onError) return;\n\t\ttry {\n\t\t\tonError(error, ctx);\n\t\t} catch {\n\t\t\t// Error routing is best-effort; never let adapter logging wedge the queue.\n\t\t}\n\t}\n\n\tfunction callDone(done?: ObserveSinkDone): void {\n\t\ttry {\n\t\t\tdone?.();\n\t\t} catch {\n\t\t\t// Completion callbacks are advisory only; never wedge the queue on observer code.\n\t\t}\n\t}\n\n\tfunction run(item: QueueItem<T>): void | PromiseLike<void> {\n\t\tswitch (item.kind) {\n\t\t\tcase \"write\":\n\t\t\t\treturn sink.write(item.value);\n\t\t\tcase \"flush\":\n\t\t\t\treturn sink.flush?.();\n\t\t\tcase \"rollback\":\n\t\t\t\treturn sink.rollback?.();\n\t\t\tcase \"dispose\":\n\t\t\t\treturn sink.dispose?.();\n\t\t}\n\t}\n\n\tfunction finish(item: QueueItem<T>): void {\n\t\tif (item.kind === \"dispose\") {\n\t\t\tdisposed = true;\n\t\t\tfor (const done of disposeDone.splice(0)) callDone(done);\n\t\t} else if (item.kind !== \"write\") {\n\t\t\tcallDone(item.done);\n\t\t}\n\t\tdraining = false;\n\t\tdrain();\n\t}\n\n\tfunction fail(item: QueueItem<T>, error: unknown): void {\n\t\tif (item.kind === \"write\")\n\t\t\treport(error, { phase: \"write\", event: item.event, value: item.value });\n\t\telse report(error, { phase: item.kind });\n\t\tfinish(item);\n\t}\n\n\tfunction chainThenable(item: QueueItem<T>, value: unknown): boolean {\n\t\tif ((typeof value !== \"object\" && typeof value !== \"function\") || value === null) return false;\n\n\t\tlet then: unknown;\n\t\ttry {\n\t\t\tthen = (value as { then?: unknown }).then;\n\t\t} catch (error) {\n\t\t\tfail(item, error);\n\t\t\treturn true;\n\t\t}\n\t\tif (typeof then !== \"function\") return false;\n\n\t\tlet settled = false;\n\t\tconst settle = (next: () => void) => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\tnext();\n\t\t};\n\t\ttry {\n\t\t\t(then as (onFulfilled: () => void, onRejected: (error: unknown) => void) => unknown).call(\n\t\t\t\tvalue,\n\t\t\t\t() => settle(() => finish(item)),\n\t\t\t\t(error) => settle(() => fail(item, error)),\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tsettle(() => fail(item, error));\n\t\t}\n\t\treturn true;\n\t}\n\n\tfunction drain(): void {\n\t\tif (draining) return;\n\t\tconst item = queue.shift();\n\t\tif (!item) return;\n\t\tdraining = true;\n\t\tlet result: void | PromiseLike<void>;\n\t\ttry {\n\t\t\tresult = run(item);\n\t\t} catch (error) {\n\t\t\tfail(item, error);\n\t\t\treturn;\n\t\t}\n\t\tif (chainThenable(item, result)) return;\n\t\tfinish(item);\n\t}\n\n\tfunction enqueueBarrier(kind: \"flush\" | \"rollback\", done?: ObserveSinkDone): void {\n\t\tif (disposeRequested) {\n\t\t\tcallDone(done);\n\t\t\treturn;\n\t\t}\n\t\tqueue.push({ kind, done });\n\t\tdrain();\n\t}\n\n\tconst stop = graph.observe(path).subscribe((event) => {\n\t\tif (disposeRequested) return;\n\t\tlet value: T | undefined;\n\t\ttry {\n\t\t\tvalue = map ? map(event) : (event as unknown as T);\n\t\t} catch (error) {\n\t\t\treport(error, { phase: \"map\", event });\n\t\t\treturn;\n\t\t}\n\t\tif (value === undefined) return;\n\t\tqueue.push({ kind: \"write\", event, value });\n\t\tdrain();\n\t});\n\n\treturn {\n\t\tflush(done?: ObserveSinkDone): void {\n\t\t\tenqueueBarrier(\"flush\", done);\n\t\t},\n\t\trollback(done?: ObserveSinkDone): void {\n\t\t\tenqueueBarrier(\"rollback\", done);\n\t\t},\n\t\tdispose(done?: ObserveSinkDone): void {\n\t\t\tif (disposed) {\n\t\t\t\tcallDone(done);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (done) disposeDone.push(done);\n\t\t\tif (disposeRequested) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdisposeRequested = true;\n\t\t\tstop();\n\t\t\tqueue.push({ kind: \"dispose\" });\n\t\t\tdrain();\n\t\t},\n\t};\n}\n\n/**\n * Persist Graph.observe() events to an append log. This is a graph-bound\n * adapter over passive storage frames, not graph restore or projection.\n */\nexport function attachObserveEventLog<T = ObserveEvent>(\n\tgraph: Graph,\n\tlog: AppendLogStorageTier<ObserveEventFrame<T>>,\n\topts: AttachObserveEventLogOptions<T> = {},\n): ObserveEventLogHandle {\n\treturn attachObserveSink<ObserveEventFrame<T>>(\n\t\tgraph,\n\t\t{ write: (frame) => log.append(frame).then(() => undefined) },\n\t\t{\n\t\t\tpath: opts.path,\n\t\t\tmap: (event) => {\n\t\t\t\tconst value = opts.map ? opts.map(event) : (event as unknown as T);\n\t\t\t\treturn value === undefined ? undefined : observeEventFrame(event, value, opts);\n\t\t\t},\n\t\t\tonError: opts.onError,\n\t\t},\n\t);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/adapters/react.ts
|
|
21
|
+
var react_exports = {};
|
|
22
|
+
__export(react_exports, {
|
|
23
|
+
useNodeInput: () => useNodeInput,
|
|
24
|
+
useNodeRecord: () => useNodeRecord,
|
|
25
|
+
useNodeValue: () => useNodeValue
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(react_exports);
|
|
28
|
+
var import_react = require("react");
|
|
29
|
+
|
|
30
|
+
// src/adapters/store.ts
|
|
31
|
+
function nodeSnapshot(node) {
|
|
32
|
+
return node.cache;
|
|
33
|
+
}
|
|
34
|
+
function subscribeNodeValues(node, run, opts = {}) {
|
|
35
|
+
const read = opts.getSnapshot ?? (() => nodeSnapshot(node));
|
|
36
|
+
if (opts.immediate) run(read());
|
|
37
|
+
let subscribing = true;
|
|
38
|
+
const skipSynchronousHandshakeData = opts.changesOnly || opts.immediate;
|
|
39
|
+
const sink = (msg, delivery) => {
|
|
40
|
+
switch (msg[0]) {
|
|
41
|
+
case "DATA":
|
|
42
|
+
if (skipSynchronousHandshakeData && subscribing && delivery === void 0) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
run(msg[1]);
|
|
46
|
+
return;
|
|
47
|
+
case "ERROR":
|
|
48
|
+
opts.onError?.(msg[1]);
|
|
49
|
+
return;
|
|
50
|
+
case "COMPLETE":
|
|
51
|
+
opts.onComplete?.();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const unsubscribe = node.subscribe(sink);
|
|
56
|
+
subscribing = false;
|
|
57
|
+
return unsubscribe;
|
|
58
|
+
}
|
|
59
|
+
function externalStore(node, opts = {}) {
|
|
60
|
+
const read = opts.getSnapshot ?? (() => nodeSnapshot(node));
|
|
61
|
+
return {
|
|
62
|
+
getSnapshot: read,
|
|
63
|
+
getServerSnapshot: read,
|
|
64
|
+
subscribe: (onStoreChange) => subscribeNodeValues(node, () => onStoreChange(), {
|
|
65
|
+
changesOnly: true,
|
|
66
|
+
onError: opts.onError,
|
|
67
|
+
onComplete: opts.onComplete
|
|
68
|
+
})
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function recordReadableStore(keysNode, factory, opts = {}) {
|
|
72
|
+
const read = () => {
|
|
73
|
+
const keys = keysNode.cache ?? [];
|
|
74
|
+
const out = {};
|
|
75
|
+
for (const key of keys) {
|
|
76
|
+
const nodes = factory(key);
|
|
77
|
+
const values = {};
|
|
78
|
+
for (const field of Object.keys(nodes)) {
|
|
79
|
+
values[field] = nodes[field].cache;
|
|
80
|
+
}
|
|
81
|
+
out[key] = values;
|
|
82
|
+
}
|
|
83
|
+
return out;
|
|
84
|
+
};
|
|
85
|
+
return {
|
|
86
|
+
get: read,
|
|
87
|
+
subscribe(run) {
|
|
88
|
+
const entryUnsubs = [];
|
|
89
|
+
const cleanupEntries = () => {
|
|
90
|
+
for (const unsub of entryUnsubs.splice(0)) unsub();
|
|
91
|
+
};
|
|
92
|
+
const sync = () => {
|
|
93
|
+
cleanupEntries();
|
|
94
|
+
for (const key of keysNode.cache ?? []) {
|
|
95
|
+
const nodes = factory(key);
|
|
96
|
+
for (const field of Object.keys(nodes)) {
|
|
97
|
+
entryUnsubs.push(
|
|
98
|
+
subscribeNodeValues(nodes[field], () => run(read()), {
|
|
99
|
+
changesOnly: true,
|
|
100
|
+
onError: opts.onError,
|
|
101
|
+
onComplete: opts.onComplete
|
|
102
|
+
})
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
run(read());
|
|
107
|
+
};
|
|
108
|
+
const keysUnsub = subscribeNodeValues(keysNode, sync, {
|
|
109
|
+
changesOnly: true,
|
|
110
|
+
onError: opts.onError,
|
|
111
|
+
onComplete: opts.onComplete
|
|
112
|
+
});
|
|
113
|
+
sync();
|
|
114
|
+
return () => {
|
|
115
|
+
keysUnsub();
|
|
116
|
+
cleanupEntries();
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/adapters/react.ts
|
|
123
|
+
function assertDataValue(value) {
|
|
124
|
+
if (value === void 0) {
|
|
125
|
+
throw new TypeError("useNodeInput: undefined is SENTINEL/no DATA, not a writable DATA value");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function useNodeValue(node) {
|
|
129
|
+
const store = (0, import_react.useMemo)(() => externalStore(node), [node]);
|
|
130
|
+
return (0, import_react.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getServerSnapshot);
|
|
131
|
+
}
|
|
132
|
+
function useNodeInput(node) {
|
|
133
|
+
const value = useNodeValue(node);
|
|
134
|
+
const setValue = (0, import_react.useCallback)(
|
|
135
|
+
(next) => {
|
|
136
|
+
assertDataValue(next);
|
|
137
|
+
node.set(next);
|
|
138
|
+
},
|
|
139
|
+
[node]
|
|
140
|
+
);
|
|
141
|
+
return [value, setValue];
|
|
142
|
+
}
|
|
143
|
+
function useNodeRecord(keysNode, factory) {
|
|
144
|
+
const store = (0, import_react.useMemo)(() => {
|
|
145
|
+
const recordStore = recordReadableStore(keysNode, factory);
|
|
146
|
+
let current = recordStore.get() ?? {};
|
|
147
|
+
return {
|
|
148
|
+
getSnapshot: () => current,
|
|
149
|
+
subscribe(onStoreChange) {
|
|
150
|
+
return recordStore.subscribe((next) => {
|
|
151
|
+
current = next ?? {};
|
|
152
|
+
onStoreChange();
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}, [keysNode, factory]);
|
|
157
|
+
const getSnapshot = (0, import_react.useCallback)(() => store.getSnapshot(), [store]);
|
|
158
|
+
return (0, import_react.useSyncExternalStore)(store.subscribe, getSnapshot, getSnapshot);
|
|
159
|
+
}
|
|
160
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
161
|
+
0 && (module.exports = {
|
|
162
|
+
useNodeInput,
|
|
163
|
+
useNodeRecord,
|
|
164
|
+
useNodeValue
|
|
165
|
+
});
|
|
166
|
+
//# sourceMappingURL=react.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/react.ts","../../src/adapters/store.ts"],"sourcesContent":["/**\n * React node bindings for GraphReFly (D238).\n *\n * React is imported only from this focused subpath. The dependency-free\n * `@graphrefly/ts/adapters` barrel keeps the framework-neutral store contract.\n */\n\nimport { useCallback, useMemo, useSyncExternalStore } from \"react\";\nimport type { Node } from \"../node/node.js\";\nimport { externalStore, recordReadableStore, type WritableNode } from \"./store.js\";\n\nfunction assertDataValue(value: unknown): void {\n\tif (value === undefined) {\n\t\tthrow new TypeError(\"useNodeInput: undefined is SENTINEL/no DATA, not a writable DATA value\");\n\t}\n}\n\n/** Read a GraphReFly node through React's useSyncExternalStore contract. */\nexport function useNodeValue<T>(node: Node<T>): T | undefined {\n\tconst store = useMemo(() => externalStore(node), [node]);\n\treturn useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);\n}\n\n/**\n * Bind a writable GraphReFly node as `[value, setValue]`.\n *\n * The setter identity is stable for a stable node identity, and writes through\n * the node's reactive DATA boundary rather than a presentation-owned trigger.\n */\nexport function useNodeInput<T>(\n\tnode: WritableNode<T>,\n): readonly [T | undefined, (value: T) => void] {\n\tconst value = useNodeValue(node);\n\tconst setValue = useCallback(\n\t\t(next: T) => {\n\t\t\tassertDataValue(next);\n\t\t\tnode.set(next);\n\t\t},\n\t\t[node],\n\t);\n\treturn [value, setValue] as const;\n}\n\n/**\n * Read a keyed record of nodes.\n *\n * `factory` must have stable identity. Recreating it on every render forces the\n * record subscription graph to rebuild on every render.\n */\nexport function useNodeRecord<K extends string, R extends Record<string, unknown>>(\n\tkeysNode: Node<readonly K[]>,\n\tfactory: (key: K) => { [P in keyof R]: Node<R[P]> },\n): Record<K, R> {\n\tconst store = useMemo(() => {\n\t\tconst recordStore = recordReadableStore(keysNode, factory);\n\t\tlet current = recordStore.get() ?? ({} as Record<K, R>);\n\t\treturn {\n\t\t\tgetSnapshot: () => current,\n\t\t\tsubscribe(onStoreChange: () => void) {\n\t\t\t\treturn recordStore.subscribe((next) => {\n\t\t\t\t\tcurrent = next ?? ({} as Record<K, R>);\n\t\t\t\t\tonStoreChange();\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}, [keysNode, factory]);\n\tconst getSnapshot = useCallback(() => store.getSnapshot(), [store]);\n\treturn useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);\n}\n","/**\n * Framework-neutral store adapters.\n *\n * Focused framework bindings build on this tiny Node-facing layer without\n * importing framework packages into the dependency-free adapters barrel\n * (D125/D238).\n */\n\nimport type { DeliveryMeta, Sink } from \"../ctx/types.js\";\nimport type { Node } from \"../node/node.js\";\n\n/** A minimal readable store contract shared by Svelte/Nanostores-style adapters. */\nexport interface ReadableStore<T> {\n\tget(): T | undefined;\n\tsubscribe(run: (value: T | undefined) => void): () => void;\n}\n\n/** A minimal writable store contract over a clean-slate writable node. */\nexport interface WritableStore<T> extends ReadableStore<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\n/** React `useSyncExternalStore`-compatible shape, without importing React. */\nexport interface ExternalStore<T> {\n\tgetSnapshot(): T | undefined;\n\tgetServerSnapshot(): T | undefined;\n\tsubscribe(onStoreChange: () => void): () => void;\n}\n\n/** Object-of-nodes factory used by record subscription adapters. */\nexport type NodeRecordFactory<K extends string, R extends Record<string, unknown>> = (key: K) => {\n\t[P in keyof R]: Node<R[P]>;\n};\n\n/** Zustand-compatible store API over a caller-owned clean-slate state node. */\nexport interface ZustandStoreApi<T extends object> {\n\tgetState(): T;\n\tsetState(partial: T | Partial<T> | ((state: T) => T | Partial<T>), replace?: boolean): void;\n\tgetInitialState(): T;\n\tsubscribe(listener: (state: T, prevState: T) => void): () => void;\n\tdestroy(): void;\n}\n\n/** Jotai-style atom facade over a caller-owned node. */\nexport interface JotaiAtom<T> {\n\tget(): T | undefined;\n\tsubscribe(callback: (value: T | undefined) => void): () => void;\n\treadonly _node: Node<T>;\n}\n\n/** Writable Jotai-style atom facade over a caller-owned writable node. */\nexport interface WritableJotaiAtom<T> extends JotaiAtom<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\n/** Nanostores-style atom facade over a caller-owned node. */\nexport interface NanoAtom<T> {\n\tget(): T | undefined;\n\tsubscribe(callback: (value: T | undefined) => void): () => void;\n\tlisten(callback: (value: T | undefined) => void): () => void;\n\treadonly _node: Node<T>;\n}\n\n/** Writable Nanostores-style atom facade over a caller-owned writable node. */\nexport interface WritableNanoAtom<T> extends NanoAtom<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\n/** TC39-Signals-style facade over a caller-owned node. */\nexport interface SignalLike<T> {\n\tget(): T | undefined;\n\tsubscribe(callback: (value: T | undefined) => void): () => void;\n\treadonly _node: Node<T>;\n}\n\n/** Writable TC39-Signals-style facade over a caller-owned writable node. */\nexport interface WritableSignalLike<T> extends SignalLike<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\nexport interface SubscribeValuesOptions<T> {\n\t/** Emit the current cache snapshot immediately. `undefined` means SENTINEL/no DATA. */\n\timmediate?: boolean;\n\t/** Suppress synchronous push-on-subscribe/replay DATA. Useful for change-only store listeners. */\n\tchangesOnly?: boolean;\n\tonError?: (error: unknown) => void;\n\tonComplete?: () => void;\n\t/** Custom cache reader for wrappers that keep their own snapshot object. */\n\tgetSnapshot?: () => T | undefined;\n}\n\nexport interface WritableNode<T> extends Node<T> {\n\tset(value: T): void;\n}\n\nexport interface WritableStoreOptions<T> extends SubscribeValuesOptions<T> {\n\t/** Override writes for adapters that need a framework-owned reducer. */\n\twrite?: (node: WritableNode<T>, value: T) => void;\n}\n\n/** Read a node cache without activating it. */\nexport function nodeSnapshot<T>(node: Node<T>): T | undefined {\n\treturn node.cache as T | undefined;\n}\n\n/**\n * Subscribe to DATA values from a Node. Protocol internals stay below the adapter boundary:\n * DATA drives value listeners, ERROR/COMPLETE route to optional lifecycle callbacks.\n */\nexport function subscribeNodeValues<T>(\n\tnode: Node<T>,\n\trun: (value: T | undefined) => void,\n\topts: SubscribeValuesOptions<T> = {},\n): () => void {\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\tif (opts.immediate) run(read());\n\n\tlet subscribing = true;\n\tconst skipSynchronousHandshakeData = opts.changesOnly || opts.immediate;\n\tconst sink: Sink = (msg, delivery?: DeliveryMeta) => {\n\t\tswitch (msg[0]) {\n\t\t\tcase \"DATA\":\n\t\t\t\tif (skipSynchronousHandshakeData && subscribing && delivery === undefined) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trun(msg[1] as T);\n\t\t\t\treturn;\n\t\t\tcase \"ERROR\":\n\t\t\t\topts.onError?.(msg[1]);\n\t\t\t\treturn;\n\t\t\tcase \"COMPLETE\":\n\t\t\t\topts.onComplete?.();\n\t\t\t\treturn;\n\t\t}\n\t};\n\tconst unsubscribe = node.subscribe(sink);\n\tsubscribing = false;\n\treturn unsubscribe;\n}\n\n/** Build a Svelte/Nanostores-style readable store from a clean-slate Node. */\nexport function readableStore<T>(\n\tnode: Node<T>,\n\topts: SubscribeValuesOptions<T> = {},\n): ReadableStore<T> {\n\treturn {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (run) => subscribeNodeValues(node, run, { immediate: true, ...opts }),\n\t};\n}\n\nfunction hasWritableSet<T>(node: Node<T>): node is WritableNode<T> {\n\treturn typeof (node as { set?: unknown }).set === \"function\";\n}\n\nfunction defaultWrite<T>(node: WritableNode<T>, value: T): void {\n\tnode.set(value);\n}\n\n/** Build a writable store over a StateNode or compatible clean-slate writable Node. */\nexport function writableStore<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableStore<T>;\nexport function writableStore<T>(\n\tnode: Node<T>,\n\topts: WritableStoreOptions<T> & { write: (node: WritableNode<T>, value: T) => void },\n): WritableStore<T>;\nexport function writableStore<T>(\n\tnode: Node<T>,\n\topts: WritableStoreOptions<T> = {},\n): WritableStore<T> {\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\tconst write = opts.write ?? (hasWritableSet(node) ? defaultWrite : undefined);\n\tif (!write) {\n\t\tthrow new TypeError(\"writableStore: node must expose set(value) or opts.write\");\n\t}\n\tconst writable = node as WritableNode<T>;\n\treturn {\n\t\tget: read,\n\t\tsubscribe: (run) => subscribeNodeValues(node, run, { immediate: true, ...opts }),\n\t\tset: (value) => write(writable, value),\n\t\tupdate: (fn) => write(writable, fn(read())),\n\t};\n}\n\n/** Build the tiny shape React's `useSyncExternalStore` expects, without importing React. */\nexport function externalStore<T>(\n\tnode: Node<T>,\n\topts: Pick<SubscribeValuesOptions<T>, \"getSnapshot\" | \"onError\" | \"onComplete\"> = {},\n): ExternalStore<T> {\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\treturn {\n\t\tgetSnapshot: read,\n\t\tgetServerSnapshot: read,\n\t\tsubscribe: (onStoreChange) =>\n\t\t\tsubscribeNodeValues(node, () => onStoreChange(), {\n\t\t\t\tchangesOnly: true,\n\t\t\t\tonError: opts.onError,\n\t\t\t\tonComplete: opts.onComplete,\n\t\t\t}),\n\t};\n}\n\n/** Build a framework-neutral keyed record store for focused framework record bindings. */\nexport function recordReadableStore<K extends string, R extends Record<string, unknown>>(\n\tkeysNode: Node<readonly K[]>,\n\tfactory: NodeRecordFactory<K, R>,\n\topts: SubscribeValuesOptions<Record<K, R>> = {},\n): ReadableStore<Record<K, R>> {\n\tconst read = () => {\n\t\tconst keys = keysNode.cache ?? [];\n\t\tconst out = {} as Record<K, R>;\n\t\tfor (const key of keys) {\n\t\t\tconst nodes = factory(key);\n\t\t\tconst values = {} as R;\n\t\t\tfor (const field of Object.keys(nodes) as Array<keyof R>) {\n\t\t\t\tvalues[field] = nodes[field].cache as R[keyof R];\n\t\t\t}\n\t\t\tout[key] = values;\n\t\t}\n\t\treturn out;\n\t};\n\n\treturn {\n\t\tget: read,\n\t\tsubscribe(run) {\n\t\t\tconst entryUnsubs: Array<() => void> = [];\n\t\t\tconst cleanupEntries = () => {\n\t\t\t\tfor (const unsub of entryUnsubs.splice(0)) unsub();\n\t\t\t};\n\t\t\tconst sync = () => {\n\t\t\t\tcleanupEntries();\n\t\t\t\tfor (const key of keysNode.cache ?? []) {\n\t\t\t\t\tconst nodes = factory(key);\n\t\t\t\t\tfor (const field of Object.keys(nodes) as Array<keyof R>) {\n\t\t\t\t\t\tentryUnsubs.push(\n\t\t\t\t\t\t\tsubscribeNodeValues(nodes[field], () => run(read()), {\n\t\t\t\t\t\t\t\tchangesOnly: true,\n\t\t\t\t\t\t\t\tonError: opts.onError,\n\t\t\t\t\t\t\t\tonComplete: opts.onComplete,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trun(read());\n\t\t\t};\n\t\t\tconst keysUnsub = subscribeNodeValues(keysNode, sync, {\n\t\t\t\tchangesOnly: true,\n\t\t\t\tonError: opts.onError,\n\t\t\t\tonComplete: opts.onComplete,\n\t\t\t});\n\t\t\tsync();\n\t\t\treturn () => {\n\t\t\t\tkeysUnsub();\n\t\t\t\tcleanupEntries();\n\t\t\t};\n\t\t},\n\t};\n}\n\n/** Build a Zustand-compatible StoreApi over a caller-owned clean-slate state node. */\nexport function zustandStore<T extends object>(\n\tnode: WritableNode<T>,\n\tinitialState?: T,\n\topts?: WritableStoreOptions<T>,\n): ZustandStoreApi<T>;\nexport function zustandStore<T extends object>(\n\tnode: Node<T>,\n\tinitialState: T | undefined,\n\topts: WritableStoreOptions<T> & { write: (node: WritableNode<T>, value: T) => void },\n): ZustandStoreApi<T>;\nexport function zustandStore<T extends object>(\n\tnode: Node<T>,\n\tinitialState: T = nodeSnapshot(node) as T,\n\topts: WritableStoreOptions<T> = {},\n): ZustandStoreApi<T> {\n\tconst listeners = new Set<() => void>();\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\tconst write = opts.write ?? (hasWritableSet(node) ? defaultWrite : undefined);\n\tif (!write) {\n\t\tthrow new TypeError(\"zustandStore: node must expose set(value) or opts.write\");\n\t}\n\tconst writable = node as WritableNode<T>;\n\tconst api: ZustandStoreApi<T> = {\n\t\tgetState: () => read() as T,\n\t\tsetState(partial, replace) {\n\t\t\tconst prev = api.getState();\n\t\t\tconst next = typeof partial === \"function\" ? partial(prev) : partial;\n\t\t\twrite(writable, replace ? (next as T) : ({ ...prev, ...next } as T));\n\t\t},\n\t\tgetInitialState: () => initialState,\n\t\tsubscribe(listener) {\n\t\t\tlet prev = api.getState();\n\t\t\tconst unsub = subscribeNodeValues(\n\t\t\t\tnode,\n\t\t\t\t(value) => {\n\t\t\t\t\tconst next = value as T;\n\t\t\t\t\tlistener(next, prev);\n\t\t\t\t\tprev = next;\n\t\t\t\t},\n\t\t\t\t{ changesOnly: true, onError: opts.onError, onComplete: opts.onComplete },\n\t\t\t);\n\t\t\tlisteners.add(unsub);\n\t\t\treturn () => {\n\t\t\t\tif (!listeners.delete(unsub)) return;\n\t\t\t\tunsub();\n\t\t\t};\n\t\t},\n\t\tdestroy() {\n\t\t\tfor (const unsub of [...listeners]) {\n\t\t\t\tlisteners.delete(unsub);\n\t\t\t\tunsub();\n\t\t\t}\n\t\t},\n\t};\n\treturn api;\n}\n\n/** Build a Jotai-style atom facade over a caller-owned node. */\nexport function jotaiAtom<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableJotaiAtom<T>;\nexport function jotaiAtom<T>(node: Node<T>, opts?: SubscribeValuesOptions<T>): JotaiAtom<T>;\nexport function jotaiAtom<T>(\n\tnode: Node<T> | WritableNode<T>,\n\topts: SubscribeValuesOptions<T> | WritableStoreOptions<T> = {},\n): JotaiAtom<T> | WritableJotaiAtom<T> {\n\tconst base: JotaiAtom<T> = {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),\n\t\t_node: node,\n\t};\n\tif (hasWritableSet(node) || typeof (opts as WritableStoreOptions<T>).write === \"function\") {\n\t\tconst writable = writableStore(\n\t\t\tnode,\n\t\t\topts as WritableStoreOptions<T> & {\n\t\t\t\twrite: (node: WritableNode<T>, value: T) => void;\n\t\t\t},\n\t\t);\n\t\treturn { ...base, set: writable.set, update: writable.update };\n\t}\n\treturn base;\n}\n\n/** Build a Nanostores-style atom facade over a caller-owned node. */\nexport function nanoAtom<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableNanoAtom<T>;\nexport function nanoAtom<T>(node: Node<T>, opts?: SubscribeValuesOptions<T>): NanoAtom<T>;\nexport function nanoAtom<T>(\n\tnode: Node<T> | WritableNode<T>,\n\topts: SubscribeValuesOptions<T> | WritableStoreOptions<T> = {},\n): NanoAtom<T> | WritableNanoAtom<T> {\n\tconst base: NanoAtom<T> = {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (callback) => subscribeNodeValues(node, callback, { immediate: true, ...opts }),\n\t\tlisten: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),\n\t\t_node: node,\n\t};\n\tif (hasWritableSet(node) || typeof (opts as WritableStoreOptions<T>).write === \"function\") {\n\t\tconst writable = writableStore(\n\t\t\tnode,\n\t\t\topts as WritableStoreOptions<T> & {\n\t\t\t\twrite: (node: WritableNode<T>, value: T) => void;\n\t\t\t},\n\t\t);\n\t\treturn { ...base, set: writable.set, update: writable.update };\n\t}\n\treturn base;\n}\n\n/** Build a TC39-Signals-style facade over a caller-owned node. */\nexport function signalFromNode<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableSignalLike<T>;\nexport function signalFromNode<T>(node: Node<T>, opts?: SubscribeValuesOptions<T>): SignalLike<T>;\nexport function signalFromNode<T>(\n\tnode: Node<T> | WritableNode<T>,\n\topts: SubscribeValuesOptions<T> | WritableStoreOptions<T> = {},\n): SignalLike<T> | WritableSignalLike<T> {\n\tconst base: SignalLike<T> = {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),\n\t\t_node: node,\n\t};\n\tif (hasWritableSet(node) || typeof (opts as WritableStoreOptions<T>).write === \"function\") {\n\t\tconst writable = writableStore(\n\t\t\tnode,\n\t\t\topts as WritableStoreOptions<T> & {\n\t\t\t\twrite: (node: WritableNode<T>, value: T) => void;\n\t\t\t},\n\t\t);\n\t\treturn { ...base, set: writable.set, update: writable.update };\n\t}\n\treturn base;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { N as Node } from '../types-CcPIn7sy.cjs';
|
|
2
|
+
import { W as WritableNode } from '../store-CNJwmT-h.cjs';
|
|
3
|
+
import '../messages-CAzUPPJM.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* React node bindings for GraphReFly (D238).
|
|
7
|
+
*
|
|
8
|
+
* React is imported only from this focused subpath. The dependency-free
|
|
9
|
+
* `@graphrefly/ts/adapters` barrel keeps the framework-neutral store contract.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** Read a GraphReFly node through React's useSyncExternalStore contract. */
|
|
13
|
+
declare function useNodeValue<T>(node: Node<T>): T | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Bind a writable GraphReFly node as `[value, setValue]`.
|
|
16
|
+
*
|
|
17
|
+
* The setter identity is stable for a stable node identity, and writes through
|
|
18
|
+
* the node's reactive DATA boundary rather than a presentation-owned trigger.
|
|
19
|
+
*/
|
|
20
|
+
declare function useNodeInput<T>(node: WritableNode<T>): readonly [T | undefined, (value: T) => void];
|
|
21
|
+
/**
|
|
22
|
+
* Read a keyed record of nodes.
|
|
23
|
+
*
|
|
24
|
+
* `factory` must have stable identity. Recreating it on every render forces the
|
|
25
|
+
* record subscription graph to rebuild on every render.
|
|
26
|
+
*/
|
|
27
|
+
declare function useNodeRecord<K extends string, R extends Record<string, unknown>>(keysNode: Node<readonly K[]>, factory: (key: K) => {
|
|
28
|
+
[P in keyof R]: Node<R[P]>;
|
|
29
|
+
}): Record<K, R>;
|
|
30
|
+
|
|
31
|
+
export { useNodeInput, useNodeRecord, useNodeValue };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { N as Node } from '../types-BsJvElYZ.js';
|
|
2
|
+
import { W as WritableNode } from '../store-C-joM4gh.js';
|
|
3
|
+
import '../messages-CAzUPPJM.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* React node bindings for GraphReFly (D238).
|
|
7
|
+
*
|
|
8
|
+
* React is imported only from this focused subpath. The dependency-free
|
|
9
|
+
* `@graphrefly/ts/adapters` barrel keeps the framework-neutral store contract.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** Read a GraphReFly node through React's useSyncExternalStore contract. */
|
|
13
|
+
declare function useNodeValue<T>(node: Node<T>): T | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Bind a writable GraphReFly node as `[value, setValue]`.
|
|
16
|
+
*
|
|
17
|
+
* The setter identity is stable for a stable node identity, and writes through
|
|
18
|
+
* the node's reactive DATA boundary rather than a presentation-owned trigger.
|
|
19
|
+
*/
|
|
20
|
+
declare function useNodeInput<T>(node: WritableNode<T>): readonly [T | undefined, (value: T) => void];
|
|
21
|
+
/**
|
|
22
|
+
* Read a keyed record of nodes.
|
|
23
|
+
*
|
|
24
|
+
* `factory` must have stable identity. Recreating it on every render forces the
|
|
25
|
+
* record subscription graph to rebuild on every render.
|
|
26
|
+
*/
|
|
27
|
+
declare function useNodeRecord<K extends string, R extends Record<string, unknown>>(keysNode: Node<readonly K[]>, factory: (key: K) => {
|
|
28
|
+
[P in keyof R]: Node<R[P]>;
|
|
29
|
+
}): Record<K, R>;
|
|
30
|
+
|
|
31
|
+
export { useNodeInput, useNodeRecord, useNodeValue };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import {
|
|
2
|
+
externalStore,
|
|
3
|
+
recordReadableStore
|
|
4
|
+
} from "../chunk-H75VXTGT.js";
|
|
5
|
+
import "../chunk-DGUM43GV.js";
|
|
6
|
+
|
|
7
|
+
// src/adapters/react.ts
|
|
8
|
+
import { useCallback, useMemo, useSyncExternalStore } from "react";
|
|
9
|
+
function assertDataValue(value) {
|
|
10
|
+
if (value === void 0) {
|
|
11
|
+
throw new TypeError("useNodeInput: undefined is SENTINEL/no DATA, not a writable DATA value");
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function useNodeValue(node) {
|
|
15
|
+
const store = useMemo(() => externalStore(node), [node]);
|
|
16
|
+
return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);
|
|
17
|
+
}
|
|
18
|
+
function useNodeInput(node) {
|
|
19
|
+
const value = useNodeValue(node);
|
|
20
|
+
const setValue = useCallback(
|
|
21
|
+
(next) => {
|
|
22
|
+
assertDataValue(next);
|
|
23
|
+
node.set(next);
|
|
24
|
+
},
|
|
25
|
+
[node]
|
|
26
|
+
);
|
|
27
|
+
return [value, setValue];
|
|
28
|
+
}
|
|
29
|
+
function useNodeRecord(keysNode, factory) {
|
|
30
|
+
const store = useMemo(() => {
|
|
31
|
+
const recordStore = recordReadableStore(keysNode, factory);
|
|
32
|
+
let current = recordStore.get() ?? {};
|
|
33
|
+
return {
|
|
34
|
+
getSnapshot: () => current,
|
|
35
|
+
subscribe(onStoreChange) {
|
|
36
|
+
return recordStore.subscribe((next) => {
|
|
37
|
+
current = next ?? {};
|
|
38
|
+
onStoreChange();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
}, [keysNode, factory]);
|
|
43
|
+
const getSnapshot = useCallback(() => store.getSnapshot(), [store]);
|
|
44
|
+
return useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);
|
|
45
|
+
}
|
|
46
|
+
export {
|
|
47
|
+
useNodeInput,
|
|
48
|
+
useNodeRecord,
|
|
49
|
+
useNodeValue
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/react.ts"],"sourcesContent":["/**\n * React node bindings for GraphReFly (D238).\n *\n * React is imported only from this focused subpath. The dependency-free\n * `@graphrefly/ts/adapters` barrel keeps the framework-neutral store contract.\n */\n\nimport { useCallback, useMemo, useSyncExternalStore } from \"react\";\nimport type { Node } from \"../node/node.js\";\nimport { externalStore, recordReadableStore, type WritableNode } from \"./store.js\";\n\nfunction assertDataValue(value: unknown): void {\n\tif (value === undefined) {\n\t\tthrow new TypeError(\"useNodeInput: undefined is SENTINEL/no DATA, not a writable DATA value\");\n\t}\n}\n\n/** Read a GraphReFly node through React's useSyncExternalStore contract. */\nexport function useNodeValue<T>(node: Node<T>): T | undefined {\n\tconst store = useMemo(() => externalStore(node), [node]);\n\treturn useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);\n}\n\n/**\n * Bind a writable GraphReFly node as `[value, setValue]`.\n *\n * The setter identity is stable for a stable node identity, and writes through\n * the node's reactive DATA boundary rather than a presentation-owned trigger.\n */\nexport function useNodeInput<T>(\n\tnode: WritableNode<T>,\n): readonly [T | undefined, (value: T) => void] {\n\tconst value = useNodeValue(node);\n\tconst setValue = useCallback(\n\t\t(next: T) => {\n\t\t\tassertDataValue(next);\n\t\t\tnode.set(next);\n\t\t},\n\t\t[node],\n\t);\n\treturn [value, setValue] as const;\n}\n\n/**\n * Read a keyed record of nodes.\n *\n * `factory` must have stable identity. Recreating it on every render forces the\n * record subscription graph to rebuild on every render.\n */\nexport function useNodeRecord<K extends string, R extends Record<string, unknown>>(\n\tkeysNode: Node<readonly K[]>,\n\tfactory: (key: K) => { [P in keyof R]: Node<R[P]> },\n): Record<K, R> {\n\tconst store = useMemo(() => {\n\t\tconst recordStore = recordReadableStore(keysNode, factory);\n\t\tlet current = recordStore.get() ?? ({} as Record<K, R>);\n\t\treturn {\n\t\t\tgetSnapshot: () => current,\n\t\t\tsubscribe(onStoreChange: () => void) {\n\t\t\t\treturn recordStore.subscribe((next) => {\n\t\t\t\t\tcurrent = next ?? ({} as Record<K, R>);\n\t\t\t\t\tonStoreChange();\n\t\t\t\t});\n\t\t\t},\n\t\t};\n\t}, [keysNode, factory]);\n\tconst getSnapshot = useCallback(() => store.getSnapshot(), [store]);\n\treturn useSyncExternalStore(store.subscribe, getSnapshot, getSnapshot);\n}\n"],"mappings":";;;;;;;AAOA,SAAS,aAAa,SAAS,4BAA4B;AAI3D,SAAS,gBAAgB,OAAsB;AAC9C,MAAI,UAAU,QAAW;AACxB,UAAM,IAAI,UAAU,wEAAwE;AAAA,EAC7F;AACD;AAGO,SAAS,aAAgB,MAA8B;AAC7D,QAAM,QAAQ,QAAQ,MAAM,cAAc,IAAI,GAAG,CAAC,IAAI,CAAC;AACvD,SAAO,qBAAqB,MAAM,WAAW,MAAM,aAAa,MAAM,iBAAiB;AACxF;AAQO,SAAS,aACf,MAC+C;AAC/C,QAAM,QAAQ,aAAa,IAAI;AAC/B,QAAM,WAAW;AAAA,IAChB,CAAC,SAAY;AACZ,sBAAgB,IAAI;AACpB,WAAK,IAAI,IAAI;AAAA,IACd;AAAA,IACA,CAAC,IAAI;AAAA,EACN;AACA,SAAO,CAAC,OAAO,QAAQ;AACxB;AAQO,SAAS,cACf,UACA,SACe;AACf,QAAM,QAAQ,QAAQ,MAAM;AAC3B,UAAM,cAAc,oBAAoB,UAAU,OAAO;AACzD,QAAI,UAAU,YAAY,IAAI,KAAM,CAAC;AACrC,WAAO;AAAA,MACN,aAAa,MAAM;AAAA,MACnB,UAAU,eAA2B;AACpC,eAAO,YAAY,UAAU,CAAC,SAAS;AACtC,oBAAU,QAAS,CAAC;AACpB,wBAAc;AAAA,QACf,CAAC;AAAA,MACF;AAAA,IACD;AAAA,EACD,GAAG,CAAC,UAAU,OAAO,CAAC;AACtB,QAAM,cAAc,YAAY,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,CAAC;AAClE,SAAO,qBAAqB,MAAM,WAAW,aAAa,WAAW;AACtE;","names":[]}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/adapters/solid.ts
|
|
21
|
+
var solid_exports = {};
|
|
22
|
+
__export(solid_exports, {
|
|
23
|
+
createNodeInput: () => createNodeInput,
|
|
24
|
+
createNodeRecord: () => createNodeRecord,
|
|
25
|
+
createNodeValue: () => createNodeValue
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(solid_exports);
|
|
28
|
+
var import_solid_js = require("solid-js");
|
|
29
|
+
|
|
30
|
+
// src/adapters/store.ts
|
|
31
|
+
function nodeSnapshot(node) {
|
|
32
|
+
return node.cache;
|
|
33
|
+
}
|
|
34
|
+
function subscribeNodeValues(node, run, opts = {}) {
|
|
35
|
+
const read = opts.getSnapshot ?? (() => nodeSnapshot(node));
|
|
36
|
+
if (opts.immediate) run(read());
|
|
37
|
+
let subscribing = true;
|
|
38
|
+
const skipSynchronousHandshakeData = opts.changesOnly || opts.immediate;
|
|
39
|
+
const sink = (msg, delivery) => {
|
|
40
|
+
switch (msg[0]) {
|
|
41
|
+
case "DATA":
|
|
42
|
+
if (skipSynchronousHandshakeData && subscribing && delivery === void 0) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
run(msg[1]);
|
|
46
|
+
return;
|
|
47
|
+
case "ERROR":
|
|
48
|
+
opts.onError?.(msg[1]);
|
|
49
|
+
return;
|
|
50
|
+
case "COMPLETE":
|
|
51
|
+
opts.onComplete?.();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const unsubscribe = node.subscribe(sink);
|
|
56
|
+
subscribing = false;
|
|
57
|
+
return unsubscribe;
|
|
58
|
+
}
|
|
59
|
+
function readableStore(node, opts = {}) {
|
|
60
|
+
return {
|
|
61
|
+
get: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),
|
|
62
|
+
subscribe: (run) => subscribeNodeValues(node, run, { immediate: true, ...opts })
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function recordReadableStore(keysNode, factory, opts = {}) {
|
|
66
|
+
const read = () => {
|
|
67
|
+
const keys = keysNode.cache ?? [];
|
|
68
|
+
const out = {};
|
|
69
|
+
for (const key of keys) {
|
|
70
|
+
const nodes = factory(key);
|
|
71
|
+
const values = {};
|
|
72
|
+
for (const field of Object.keys(nodes)) {
|
|
73
|
+
values[field] = nodes[field].cache;
|
|
74
|
+
}
|
|
75
|
+
out[key] = values;
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
};
|
|
79
|
+
return {
|
|
80
|
+
get: read,
|
|
81
|
+
subscribe(run) {
|
|
82
|
+
const entryUnsubs = [];
|
|
83
|
+
const cleanupEntries = () => {
|
|
84
|
+
for (const unsub of entryUnsubs.splice(0)) unsub();
|
|
85
|
+
};
|
|
86
|
+
const sync = () => {
|
|
87
|
+
cleanupEntries();
|
|
88
|
+
for (const key of keysNode.cache ?? []) {
|
|
89
|
+
const nodes = factory(key);
|
|
90
|
+
for (const field of Object.keys(nodes)) {
|
|
91
|
+
entryUnsubs.push(
|
|
92
|
+
subscribeNodeValues(nodes[field], () => run(read()), {
|
|
93
|
+
changesOnly: true,
|
|
94
|
+
onError: opts.onError,
|
|
95
|
+
onComplete: opts.onComplete
|
|
96
|
+
})
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
run(read());
|
|
101
|
+
};
|
|
102
|
+
const keysUnsub = subscribeNodeValues(keysNode, sync, {
|
|
103
|
+
changesOnly: true,
|
|
104
|
+
onError: opts.onError,
|
|
105
|
+
onComplete: opts.onComplete
|
|
106
|
+
});
|
|
107
|
+
sync();
|
|
108
|
+
return () => {
|
|
109
|
+
keysUnsub();
|
|
110
|
+
cleanupEntries();
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/adapters/solid.ts
|
|
117
|
+
function assertDataValue(value) {
|
|
118
|
+
if (value === void 0) {
|
|
119
|
+
throw new TypeError(
|
|
120
|
+
"createNodeInput: undefined is SENTINEL/no DATA, not a writable DATA value"
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function bindReadable(store) {
|
|
125
|
+
const [value, setValue] = (0, import_solid_js.createSignal)(store.get());
|
|
126
|
+
const unsubscribe = store.subscribe((next) => {
|
|
127
|
+
setValue(() => next);
|
|
128
|
+
});
|
|
129
|
+
(0, import_solid_js.onCleanup)(unsubscribe);
|
|
130
|
+
return value;
|
|
131
|
+
}
|
|
132
|
+
function createNodeValue(node) {
|
|
133
|
+
return bindReadable(readableStore(node));
|
|
134
|
+
}
|
|
135
|
+
function createNodeInput(node) {
|
|
136
|
+
return [
|
|
137
|
+
createNodeValue(node),
|
|
138
|
+
(value) => {
|
|
139
|
+
assertDataValue(value);
|
|
140
|
+
node.set(value);
|
|
141
|
+
}
|
|
142
|
+
];
|
|
143
|
+
}
|
|
144
|
+
function createNodeRecord(keysNode, factory) {
|
|
145
|
+
const store = recordReadableStore(keysNode, factory);
|
|
146
|
+
return bindReadable({
|
|
147
|
+
get: () => store.get() ?? {},
|
|
148
|
+
subscribe: (run) => store.subscribe((value) => run(value ?? {}))
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
152
|
+
0 && (module.exports = {
|
|
153
|
+
createNodeInput,
|
|
154
|
+
createNodeRecord,
|
|
155
|
+
createNodeValue
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=solid.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/adapters/solid.ts","../../src/adapters/store.ts"],"sourcesContent":["/**\n * Solid node bindings for GraphReFly (D238).\n *\n * Solid is imported only from this focused subpath.\n */\n\nimport { type Accessor, createSignal, onCleanup } from \"solid-js\";\nimport type { Node } from \"../node/node.js\";\nimport { readableStore, recordReadableStore, type WritableNode } from \"./store.js\";\n\nfunction assertDataValue(value: unknown): void {\n\tif (value === undefined) {\n\t\tthrow new TypeError(\n\t\t\t\"createNodeInput: undefined is SENTINEL/no DATA, not a writable DATA value\",\n\t\t);\n\t}\n}\n\nfunction bindReadable<T>(store: { get(): T; subscribe(run: (value: T) => void): () => void }) {\n\tconst [value, setValue] = createSignal<T>(store.get());\n\tconst unsubscribe = store.subscribe((next) => {\n\t\tsetValue(() => next);\n\t});\n\tonCleanup(unsubscribe);\n\treturn value;\n}\n\n/** Read a GraphReFly node as a Solid accessor. */\nexport function createNodeValue<T>(node: Node<T>): Accessor<T | undefined> {\n\treturn bindReadable(readableStore(node));\n}\n\n/** Bind a writable GraphReFly node as `[valueAccessor, setValue]`. */\nexport function createNodeInput<T>(\n\tnode: WritableNode<T>,\n): readonly [Accessor<T | undefined>, (value: T) => void] {\n\treturn [\n\t\tcreateNodeValue(node),\n\t\t(value: T) => {\n\t\t\tassertDataValue(value);\n\t\t\tnode.set(value);\n\t\t},\n\t] as const;\n}\n\n/**\n * Read a keyed record of nodes as a Solid accessor.\n *\n * `factory` must have stable identity; callers should define it outside render\n * churn or memoize it in their component setup.\n */\nexport function createNodeRecord<K extends string, R extends Record<string, unknown>>(\n\tkeysNode: Node<readonly K[]>,\n\tfactory: (key: K) => { [P in keyof R]: Node<R[P]> },\n): Accessor<Record<K, R>> {\n\tconst store = recordReadableStore(keysNode, factory);\n\treturn bindReadable({\n\t\tget: () => store.get() ?? ({} as Record<K, R>),\n\t\tsubscribe: (run) => store.subscribe((value) => run(value ?? ({} as Record<K, R>))),\n\t});\n}\n","/**\n * Framework-neutral store adapters.\n *\n * Focused framework bindings build on this tiny Node-facing layer without\n * importing framework packages into the dependency-free adapters barrel\n * (D125/D238).\n */\n\nimport type { DeliveryMeta, Sink } from \"../ctx/types.js\";\nimport type { Node } from \"../node/node.js\";\n\n/** A minimal readable store contract shared by Svelte/Nanostores-style adapters. */\nexport interface ReadableStore<T> {\n\tget(): T | undefined;\n\tsubscribe(run: (value: T | undefined) => void): () => void;\n}\n\n/** A minimal writable store contract over a clean-slate writable node. */\nexport interface WritableStore<T> extends ReadableStore<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\n/** React `useSyncExternalStore`-compatible shape, without importing React. */\nexport interface ExternalStore<T> {\n\tgetSnapshot(): T | undefined;\n\tgetServerSnapshot(): T | undefined;\n\tsubscribe(onStoreChange: () => void): () => void;\n}\n\n/** Object-of-nodes factory used by record subscription adapters. */\nexport type NodeRecordFactory<K extends string, R extends Record<string, unknown>> = (key: K) => {\n\t[P in keyof R]: Node<R[P]>;\n};\n\n/** Zustand-compatible store API over a caller-owned clean-slate state node. */\nexport interface ZustandStoreApi<T extends object> {\n\tgetState(): T;\n\tsetState(partial: T | Partial<T> | ((state: T) => T | Partial<T>), replace?: boolean): void;\n\tgetInitialState(): T;\n\tsubscribe(listener: (state: T, prevState: T) => void): () => void;\n\tdestroy(): void;\n}\n\n/** Jotai-style atom facade over a caller-owned node. */\nexport interface JotaiAtom<T> {\n\tget(): T | undefined;\n\tsubscribe(callback: (value: T | undefined) => void): () => void;\n\treadonly _node: Node<T>;\n}\n\n/** Writable Jotai-style atom facade over a caller-owned writable node. */\nexport interface WritableJotaiAtom<T> extends JotaiAtom<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\n/** Nanostores-style atom facade over a caller-owned node. */\nexport interface NanoAtom<T> {\n\tget(): T | undefined;\n\tsubscribe(callback: (value: T | undefined) => void): () => void;\n\tlisten(callback: (value: T | undefined) => void): () => void;\n\treadonly _node: Node<T>;\n}\n\n/** Writable Nanostores-style atom facade over a caller-owned writable node. */\nexport interface WritableNanoAtom<T> extends NanoAtom<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\n/** TC39-Signals-style facade over a caller-owned node. */\nexport interface SignalLike<T> {\n\tget(): T | undefined;\n\tsubscribe(callback: (value: T | undefined) => void): () => void;\n\treadonly _node: Node<T>;\n}\n\n/** Writable TC39-Signals-style facade over a caller-owned writable node. */\nexport interface WritableSignalLike<T> extends SignalLike<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\nexport interface SubscribeValuesOptions<T> {\n\t/** Emit the current cache snapshot immediately. `undefined` means SENTINEL/no DATA. */\n\timmediate?: boolean;\n\t/** Suppress synchronous push-on-subscribe/replay DATA. Useful for change-only store listeners. */\n\tchangesOnly?: boolean;\n\tonError?: (error: unknown) => void;\n\tonComplete?: () => void;\n\t/** Custom cache reader for wrappers that keep their own snapshot object. */\n\tgetSnapshot?: () => T | undefined;\n}\n\nexport interface WritableNode<T> extends Node<T> {\n\tset(value: T): void;\n}\n\nexport interface WritableStoreOptions<T> extends SubscribeValuesOptions<T> {\n\t/** Override writes for adapters that need a framework-owned reducer. */\n\twrite?: (node: WritableNode<T>, value: T) => void;\n}\n\n/** Read a node cache without activating it. */\nexport function nodeSnapshot<T>(node: Node<T>): T | undefined {\n\treturn node.cache as T | undefined;\n}\n\n/**\n * Subscribe to DATA values from a Node. Protocol internals stay below the adapter boundary:\n * DATA drives value listeners, ERROR/COMPLETE route to optional lifecycle callbacks.\n */\nexport function subscribeNodeValues<T>(\n\tnode: Node<T>,\n\trun: (value: T | undefined) => void,\n\topts: SubscribeValuesOptions<T> = {},\n): () => void {\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\tif (opts.immediate) run(read());\n\n\tlet subscribing = true;\n\tconst skipSynchronousHandshakeData = opts.changesOnly || opts.immediate;\n\tconst sink: Sink = (msg, delivery?: DeliveryMeta) => {\n\t\tswitch (msg[0]) {\n\t\t\tcase \"DATA\":\n\t\t\t\tif (skipSynchronousHandshakeData && subscribing && delivery === undefined) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trun(msg[1] as T);\n\t\t\t\treturn;\n\t\t\tcase \"ERROR\":\n\t\t\t\topts.onError?.(msg[1]);\n\t\t\t\treturn;\n\t\t\tcase \"COMPLETE\":\n\t\t\t\topts.onComplete?.();\n\t\t\t\treturn;\n\t\t}\n\t};\n\tconst unsubscribe = node.subscribe(sink);\n\tsubscribing = false;\n\treturn unsubscribe;\n}\n\n/** Build a Svelte/Nanostores-style readable store from a clean-slate Node. */\nexport function readableStore<T>(\n\tnode: Node<T>,\n\topts: SubscribeValuesOptions<T> = {},\n): ReadableStore<T> {\n\treturn {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (run) => subscribeNodeValues(node, run, { immediate: true, ...opts }),\n\t};\n}\n\nfunction hasWritableSet<T>(node: Node<T>): node is WritableNode<T> {\n\treturn typeof (node as { set?: unknown }).set === \"function\";\n}\n\nfunction defaultWrite<T>(node: WritableNode<T>, value: T): void {\n\tnode.set(value);\n}\n\n/** Build a writable store over a StateNode or compatible clean-slate writable Node. */\nexport function writableStore<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableStore<T>;\nexport function writableStore<T>(\n\tnode: Node<T>,\n\topts: WritableStoreOptions<T> & { write: (node: WritableNode<T>, value: T) => void },\n): WritableStore<T>;\nexport function writableStore<T>(\n\tnode: Node<T>,\n\topts: WritableStoreOptions<T> = {},\n): WritableStore<T> {\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\tconst write = opts.write ?? (hasWritableSet(node) ? defaultWrite : undefined);\n\tif (!write) {\n\t\tthrow new TypeError(\"writableStore: node must expose set(value) or opts.write\");\n\t}\n\tconst writable = node as WritableNode<T>;\n\treturn {\n\t\tget: read,\n\t\tsubscribe: (run) => subscribeNodeValues(node, run, { immediate: true, ...opts }),\n\t\tset: (value) => write(writable, value),\n\t\tupdate: (fn) => write(writable, fn(read())),\n\t};\n}\n\n/** Build the tiny shape React's `useSyncExternalStore` expects, without importing React. */\nexport function externalStore<T>(\n\tnode: Node<T>,\n\topts: Pick<SubscribeValuesOptions<T>, \"getSnapshot\" | \"onError\" | \"onComplete\"> = {},\n): ExternalStore<T> {\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\treturn {\n\t\tgetSnapshot: read,\n\t\tgetServerSnapshot: read,\n\t\tsubscribe: (onStoreChange) =>\n\t\t\tsubscribeNodeValues(node, () => onStoreChange(), {\n\t\t\t\tchangesOnly: true,\n\t\t\t\tonError: opts.onError,\n\t\t\t\tonComplete: opts.onComplete,\n\t\t\t}),\n\t};\n}\n\n/** Build a framework-neutral keyed record store for focused framework record bindings. */\nexport function recordReadableStore<K extends string, R extends Record<string, unknown>>(\n\tkeysNode: Node<readonly K[]>,\n\tfactory: NodeRecordFactory<K, R>,\n\topts: SubscribeValuesOptions<Record<K, R>> = {},\n): ReadableStore<Record<K, R>> {\n\tconst read = () => {\n\t\tconst keys = keysNode.cache ?? [];\n\t\tconst out = {} as Record<K, R>;\n\t\tfor (const key of keys) {\n\t\t\tconst nodes = factory(key);\n\t\t\tconst values = {} as R;\n\t\t\tfor (const field of Object.keys(nodes) as Array<keyof R>) {\n\t\t\t\tvalues[field] = nodes[field].cache as R[keyof R];\n\t\t\t}\n\t\t\tout[key] = values;\n\t\t}\n\t\treturn out;\n\t};\n\n\treturn {\n\t\tget: read,\n\t\tsubscribe(run) {\n\t\t\tconst entryUnsubs: Array<() => void> = [];\n\t\t\tconst cleanupEntries = () => {\n\t\t\t\tfor (const unsub of entryUnsubs.splice(0)) unsub();\n\t\t\t};\n\t\t\tconst sync = () => {\n\t\t\t\tcleanupEntries();\n\t\t\t\tfor (const key of keysNode.cache ?? []) {\n\t\t\t\t\tconst nodes = factory(key);\n\t\t\t\t\tfor (const field of Object.keys(nodes) as Array<keyof R>) {\n\t\t\t\t\t\tentryUnsubs.push(\n\t\t\t\t\t\t\tsubscribeNodeValues(nodes[field], () => run(read()), {\n\t\t\t\t\t\t\t\tchangesOnly: true,\n\t\t\t\t\t\t\t\tonError: opts.onError,\n\t\t\t\t\t\t\t\tonComplete: opts.onComplete,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trun(read());\n\t\t\t};\n\t\t\tconst keysUnsub = subscribeNodeValues(keysNode, sync, {\n\t\t\t\tchangesOnly: true,\n\t\t\t\tonError: opts.onError,\n\t\t\t\tonComplete: opts.onComplete,\n\t\t\t});\n\t\t\tsync();\n\t\t\treturn () => {\n\t\t\t\tkeysUnsub();\n\t\t\t\tcleanupEntries();\n\t\t\t};\n\t\t},\n\t};\n}\n\n/** Build a Zustand-compatible StoreApi over a caller-owned clean-slate state node. */\nexport function zustandStore<T extends object>(\n\tnode: WritableNode<T>,\n\tinitialState?: T,\n\topts?: WritableStoreOptions<T>,\n): ZustandStoreApi<T>;\nexport function zustandStore<T extends object>(\n\tnode: Node<T>,\n\tinitialState: T | undefined,\n\topts: WritableStoreOptions<T> & { write: (node: WritableNode<T>, value: T) => void },\n): ZustandStoreApi<T>;\nexport function zustandStore<T extends object>(\n\tnode: Node<T>,\n\tinitialState: T = nodeSnapshot(node) as T,\n\topts: WritableStoreOptions<T> = {},\n): ZustandStoreApi<T> {\n\tconst listeners = new Set<() => void>();\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\tconst write = opts.write ?? (hasWritableSet(node) ? defaultWrite : undefined);\n\tif (!write) {\n\t\tthrow new TypeError(\"zustandStore: node must expose set(value) or opts.write\");\n\t}\n\tconst writable = node as WritableNode<T>;\n\tconst api: ZustandStoreApi<T> = {\n\t\tgetState: () => read() as T,\n\t\tsetState(partial, replace) {\n\t\t\tconst prev = api.getState();\n\t\t\tconst next = typeof partial === \"function\" ? partial(prev) : partial;\n\t\t\twrite(writable, replace ? (next as T) : ({ ...prev, ...next } as T));\n\t\t},\n\t\tgetInitialState: () => initialState,\n\t\tsubscribe(listener) {\n\t\t\tlet prev = api.getState();\n\t\t\tconst unsub = subscribeNodeValues(\n\t\t\t\tnode,\n\t\t\t\t(value) => {\n\t\t\t\t\tconst next = value as T;\n\t\t\t\t\tlistener(next, prev);\n\t\t\t\t\tprev = next;\n\t\t\t\t},\n\t\t\t\t{ changesOnly: true, onError: opts.onError, onComplete: opts.onComplete },\n\t\t\t);\n\t\t\tlisteners.add(unsub);\n\t\t\treturn () => {\n\t\t\t\tif (!listeners.delete(unsub)) return;\n\t\t\t\tunsub();\n\t\t\t};\n\t\t},\n\t\tdestroy() {\n\t\t\tfor (const unsub of [...listeners]) {\n\t\t\t\tlisteners.delete(unsub);\n\t\t\t\tunsub();\n\t\t\t}\n\t\t},\n\t};\n\treturn api;\n}\n\n/** Build a Jotai-style atom facade over a caller-owned node. */\nexport function jotaiAtom<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableJotaiAtom<T>;\nexport function jotaiAtom<T>(node: Node<T>, opts?: SubscribeValuesOptions<T>): JotaiAtom<T>;\nexport function jotaiAtom<T>(\n\tnode: Node<T> | WritableNode<T>,\n\topts: SubscribeValuesOptions<T> | WritableStoreOptions<T> = {},\n): JotaiAtom<T> | WritableJotaiAtom<T> {\n\tconst base: JotaiAtom<T> = {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),\n\t\t_node: node,\n\t};\n\tif (hasWritableSet(node) || typeof (opts as WritableStoreOptions<T>).write === \"function\") {\n\t\tconst writable = writableStore(\n\t\t\tnode,\n\t\t\topts as WritableStoreOptions<T> & {\n\t\t\t\twrite: (node: WritableNode<T>, value: T) => void;\n\t\t\t},\n\t\t);\n\t\treturn { ...base, set: writable.set, update: writable.update };\n\t}\n\treturn base;\n}\n\n/** Build a Nanostores-style atom facade over a caller-owned node. */\nexport function nanoAtom<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableNanoAtom<T>;\nexport function nanoAtom<T>(node: Node<T>, opts?: SubscribeValuesOptions<T>): NanoAtom<T>;\nexport function nanoAtom<T>(\n\tnode: Node<T> | WritableNode<T>,\n\topts: SubscribeValuesOptions<T> | WritableStoreOptions<T> = {},\n): NanoAtom<T> | WritableNanoAtom<T> {\n\tconst base: NanoAtom<T> = {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (callback) => subscribeNodeValues(node, callback, { immediate: true, ...opts }),\n\t\tlisten: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),\n\t\t_node: node,\n\t};\n\tif (hasWritableSet(node) || typeof (opts as WritableStoreOptions<T>).write === \"function\") {\n\t\tconst writable = writableStore(\n\t\t\tnode,\n\t\t\topts as WritableStoreOptions<T> & {\n\t\t\t\twrite: (node: WritableNode<T>, value: T) => void;\n\t\t\t},\n\t\t);\n\t\treturn { ...base, set: writable.set, update: writable.update };\n\t}\n\treturn base;\n}\n\n/** Build a TC39-Signals-style facade over a caller-owned node. */\nexport function signalFromNode<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableSignalLike<T>;\nexport function signalFromNode<T>(node: Node<T>, opts?: SubscribeValuesOptions<T>): SignalLike<T>;\nexport function signalFromNode<T>(\n\tnode: Node<T> | WritableNode<T>,\n\topts: SubscribeValuesOptions<T> | WritableStoreOptions<T> = {},\n): SignalLike<T> | WritableSignalLike<T> {\n\tconst base: SignalLike<T> = {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),\n\t\t_node: node,\n\t};\n\tif (hasWritableSet(node) || typeof (opts as WritableStoreOptions<T>).write === \"function\") {\n\t\tconst writable = writableStore(\n\t\t\tnode,\n\t\t\topts as WritableStoreOptions<T> & {\n\t\t\t\twrite: (node: WritableNode<T>, value: T) => void;\n\t\t\t},\n\t\t);\n\t\treturn { ...base, set: writable.set, update: writable.update };\n\t}\n\treturn base;\n}\n"],"mappings":"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","names":[]}
|