@graphrefly/graphrefly 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/README.md +7 -5
  2. package/dist/chunk-44HD4BTA.js +47 -0
  3. package/dist/chunk-44HD4BTA.js.map +1 -0
  4. package/dist/chunk-7TAQJHQV.js +103 -0
  5. package/dist/chunk-7TAQJHQV.js.map +1 -0
  6. package/dist/chunk-BLD3IFYF.js +6827 -0
  7. package/dist/chunk-BLD3IFYF.js.map +1 -0
  8. package/dist/{chunk-ZTCDY5NQ.js → chunk-EQUZ5NLD.js} +34 -45
  9. package/dist/chunk-EQUZ5NLD.js.map +1 -0
  10. package/dist/{chunk-VOQFK7YN.js → chunk-IR3KMOLX.js} +358 -128
  11. package/dist/chunk-IR3KMOLX.js.map +1 -0
  12. package/dist/{chunk-XWBVAO2R.js → chunk-MQBQOFDS.js} +20 -11
  13. package/dist/chunk-MQBQOFDS.js.map +1 -0
  14. package/dist/chunk-NXC35KC5.js +2417 -0
  15. package/dist/chunk-NXC35KC5.js.map +1 -0
  16. package/dist/chunk-QA3RP5NH.js +2234 -0
  17. package/dist/chunk-QA3RP5NH.js.map +1 -0
  18. package/dist/chunk-RHI3GHZW.js +115 -0
  19. package/dist/chunk-RHI3GHZW.js.map +1 -0
  20. package/dist/{chunk-7IGHIFTT.js → chunk-TH6COGOP.js} +15 -26
  21. package/dist/chunk-TH6COGOP.js.map +1 -0
  22. package/dist/compat/nestjs/index.cjs +3366 -2259
  23. package/dist/compat/nestjs/index.cjs.map +1 -1
  24. package/dist/compat/nestjs/index.d.cts +6 -4
  25. package/dist/compat/nestjs/index.d.ts +6 -4
  26. package/dist/compat/nestjs/index.js +8 -8
  27. package/dist/core/index.cjs +1611 -1218
  28. package/dist/core/index.cjs.map +1 -1
  29. package/dist/core/index.d.cts +3 -2
  30. package/dist/core/index.d.ts +3 -2
  31. package/dist/core/index.js +37 -34
  32. package/dist/extra/index.cjs +7387 -6089
  33. package/dist/extra/index.cjs.map +1 -1
  34. package/dist/extra/index.d.cts +4 -4
  35. package/dist/extra/index.d.ts +4 -4
  36. package/dist/extra/index.js +57 -30
  37. package/dist/graph/index.cjs +3107 -2216
  38. package/dist/graph/index.cjs.map +1 -1
  39. package/dist/graph/index.d.cts +5 -3
  40. package/dist/graph/index.d.ts +5 -3
  41. package/dist/graph/index.js +24 -11
  42. package/dist/graph-DFr0diXB.d.ts +1128 -0
  43. package/dist/graph-ab1yPwIB.d.cts +1128 -0
  44. package/dist/{index-8a605sg9.d.ts → index-BHm3Ba5q.d.ts} +2 -2
  45. package/dist/{index-DuN3bhtm.d.ts → index-BbYZma8G.d.ts} +1697 -586
  46. package/dist/{index-SFzE_KTa.d.cts → index-BvWfZCTt.d.cts} +1697 -586
  47. package/dist/index-C9z6rU9P.d.cts +388 -0
  48. package/dist/{index-BjtlNirP.d.cts → index-D36MAQ3f.d.ts} +4 -4
  49. package/dist/{index-VHA43cGP.d.cts → index-DLE1Sp-L.d.cts} +2 -2
  50. package/dist/{index-CgSiUouz.d.ts → index-DrJq9B1T.d.cts} +4 -4
  51. package/dist/index-DsGxLfwL.d.ts +315 -0
  52. package/dist/index-Dy04P4W3.d.cts +315 -0
  53. package/dist/index-HdJx_BjO.d.ts +388 -0
  54. package/dist/index.cjs +9781 -7878
  55. package/dist/index.cjs.map +1 -1
  56. package/dist/index.d.cts +214 -37
  57. package/dist/index.d.ts +214 -37
  58. package/dist/index.js +905 -638
  59. package/dist/index.js.map +1 -1
  60. package/dist/meta--fr9sxRM.d.cts +41 -0
  61. package/dist/meta-n3FoVWML.d.ts +41 -0
  62. package/dist/node-C5UD5MGq.d.cts +1146 -0
  63. package/dist/node-C5UD5MGq.d.ts +1146 -0
  64. package/dist/{observable-DcBwQY7t.d.ts → observable-CQRBtEbq.d.ts} +1 -1
  65. package/dist/{observable-C8Kx_O6k.d.cts → observable-DWydVy5b.d.cts} +1 -1
  66. package/dist/patterns/reactive-layout/index.cjs +3102 -2132
  67. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  68. package/dist/patterns/reactive-layout/index.d.cts +5 -3
  69. package/dist/patterns/reactive-layout/index.d.ts +5 -3
  70. package/dist/patterns/reactive-layout/index.js +5 -4
  71. package/dist/storage-Bew05Xy6.d.cts +182 -0
  72. package/dist/storage-C9fZfMfM.d.ts +182 -0
  73. package/package.json +1 -1
  74. package/dist/chunk-2UDLYZHT.js +0 -2117
  75. package/dist/chunk-2UDLYZHT.js.map +0 -1
  76. package/dist/chunk-4MQ2J6IG.js +0 -1631
  77. package/dist/chunk-4MQ2J6IG.js.map +0 -1
  78. package/dist/chunk-7IGHIFTT.js.map +0 -1
  79. package/dist/chunk-DOSLSFKL.js +0 -162
  80. package/dist/chunk-DOSLSFKL.js.map +0 -1
  81. package/dist/chunk-ECN37NVS.js +0 -6227
  82. package/dist/chunk-ECN37NVS.js.map +0 -1
  83. package/dist/chunk-G66H6ZRK.js +0 -111
  84. package/dist/chunk-G66H6ZRK.js.map +0 -1
  85. package/dist/chunk-VOQFK7YN.js.map +0 -1
  86. package/dist/chunk-WZ2Z2CRV.js +0 -32
  87. package/dist/chunk-WZ2Z2CRV.js.map +0 -1
  88. package/dist/chunk-XWBVAO2R.js.map +0 -1
  89. package/dist/chunk-ZTCDY5NQ.js.map +0 -1
  90. package/dist/graph-KsTe57nI.d.cts +0 -750
  91. package/dist/graph-mILUUqW8.d.ts +0 -750
  92. package/dist/index-B2SvPEbc.d.ts +0 -257
  93. package/dist/index-BHfg_Ez3.d.ts +0 -629
  94. package/dist/index-Bc_diYYJ.d.cts +0 -629
  95. package/dist/index-UudxGnzc.d.cts +0 -257
  96. package/dist/meta-BnG7XAaE.d.cts +0 -778
  97. package/dist/meta-BnG7XAaE.d.ts +0 -778
@@ -1,629 +0,0 @@
1
- import { b as NodeActions, N as Node, a as NodeOptions, l as Messages, a4 as NodeBase, q as NodeTransportOptions, A as Actor, C as CLEANUP_RESULT, c as COMPLETE, d as CleanupResult, D as DATA, e as DEFAULT_ACTOR, f as DIRTY, g as DescribeDetail, h as DescribeField, i as DescribeNodeOutput, E as ERROR, G as GuardAction, j as GuardDenied, k as GuardDeniedDetails, H as HashFn, I as INVALIDATE, M as Message, m as NodeDescribeKind, n as NodeGuard, o as NodeSink, p as NodeStatus, r as NodeVersionInfo, O as OnMessageHandler, P as PAUSE, s as PolicyAllow, t as PolicyDeny, u as PolicyRuleData, R as RESOLVED, v as RESUME, S as START, w as SubscribeHints, T as TEARDOWN, V as V0, x as V1, y as VersioningLevel, z as VersioningOptions, B as accessHintForGuard, F as advanceVersion, J as cleanupResult, K as createVersioning, L as defaultHash, Q as isKnownMessageType, U as isLocalOnly, W as isPhase2Message, X as isTerminalMessage, Y as isV1, Z as knownMessageTypes, _ as messageTier, $ as normalizeActor, a0 as policy, a1 as policyFromRules, a2 as propagatesToMeta, a3 as resolveDescribeFields } from './meta-BnG7XAaE.cjs';
2
-
3
- /**
4
- * `NodeImpl` — the canonical node primitive for static (compile-time known)
5
- * dependency graphs. Covers state, producer, derived, effect, operator, and
6
- * passthrough shapes from a single class.
7
- *
8
- * Lifecycle machinery (subscribe + START handshake + `_downInternal` pipeline)
9
- * lives in {@link NodeBase}. This file only adds:
10
- * - Dep-wave tracking via pre-set dirty masks (first run and subsequent waves
11
- * share the same code path — see `_connectUpstream` + `_handleDepMessages`)
12
- * - `_runFn` with identity-skip optimization on `_lastDepValues`
13
- * - Producer start/stop tied to sink count
14
- * - ROM/RAM cache semantics: compute nodes clear `_cached` on disconnect,
15
- * state sources preserve it (see `_onDeactivate`).
16
- *
17
- * See GRAPHREFLY-SPEC §§2.1–2.8 and COMPOSITION-GUIDE §§1, 9.
18
- */
19
-
20
- /**
21
- * Compute function passed to `node(deps, fn, opts?)`.
22
- *
23
- * @returns A value to emit, `undefined` to skip emission, or a cleanup
24
- * function invoked before the next run or on teardown.
25
- */
26
- type NodeFn<T = unknown> = (deps: readonly unknown[], actions: NodeActions) => T | undefined | (() => void);
27
- /**
28
- * Creates a reactive {@link Node} — the single GraphReFly primitive (§2).
29
- *
30
- * Typical shapes: `node([])` / `node([], opts)` for a manual source;
31
- * `node(producerFn, opts)` for a producer; `node(deps, computeFn, opts)` for
32
- * derived nodes and operators.
33
- *
34
- * @param depsOrFn - Dependency nodes, a {@link NodeFn} (producer), or {@link NodeOptions} alone.
35
- * @param fnOrOpts - With deps: compute function or options. Omitted for producer-only form.
36
- * @param optsArg - Options when both `deps` and `fn` are provided.
37
- * @returns `Node<T>` — lazy until subscribed.
38
- *
39
- * @remarks
40
- * **Protocol:** START handshake, DIRTY / DATA / RESOLVED ordering, completion,
41
- * and batch deferral follow `~/src/graphrefly/GRAPHREFLY-SPEC.md`.
42
- *
43
- * **`equals` and mutable values:** The default `Object.is` identity check is
44
- * correct for the common immutable-value case. If your node produces mutable
45
- * objects, provide a custom `equals` — otherwise `Object.is` always returns
46
- * `true` for the same reference and the node emits `RESOLVED` instead of `DATA`.
47
- *
48
- * **ROM/RAM (§2.2):** State nodes (no fn) preserve their cache across
49
- * disconnect — runtime writes survive. Compute nodes (derived, producer)
50
- * clear their cache on disconnect; reconnect re-runs fn.
51
- *
52
- * @example
53
- * ```ts
54
- * import { node, state } from "@graphrefly/graphrefly-ts";
55
- *
56
- * const a = state(1);
57
- * const b = node([a], ([x]) => (x as number) + 1);
58
- * ```
59
- *
60
- * @category core
61
- */
62
- declare function node<T = unknown>(depsOrFn?: readonly Node[] | NodeFn<T> | NodeOptions, fnOrOpts?: NodeFn<T> | NodeOptions, optsArg?: NodeOptions): Node<T>;
63
-
64
- /**
65
- * Returns whether the current call stack is inside a batch scope **or** while
66
- * deferred phase-2 work is draining.
67
- *
68
- * Matching Python's `is_batching()` semantics: nested emissions during drain
69
- * are deferred until the current drain pass completes, preventing ordering
70
- * bugs when callbacks trigger further DATA/RESOLVED.
71
- *
72
- * @returns `true` while inside `batch()` or while the drain loop is running.
73
- *
74
- * @example
75
- * ```ts
76
- * import { batch, isBatching } from "@graphrefly/graphrefly-ts";
77
- *
78
- * batch(() => {
79
- * console.log(isBatching()); // true
80
- * });
81
- * ```
82
- *
83
- * @category core
84
- */
85
- declare function isBatching(): boolean;
86
- /**
87
- * Runs `fn` inside a batch scope. Nested `batch()` calls share one deferral queue.
88
- * If `fn` throws (including from a nested `batch`), deferred DATA/RESOLVED for
89
- * that **outer** `batch` frame are discarded — phase-2 is not flushed after an
90
- * error. While the drain loop is running (`flushInProgress`), a nested `batch`
91
- * that throws must **not** clear the global queue (cross-language decision A4).
92
- *
93
- * During the drain loop, `isBatching()` remains true so nested `downWithBatch`
94
- * calls still defer phase-2 messages. The drain loop runs until the queue is
95
- * quiescent (no pending work remains). Per-emission try/catch ensures one
96
- * throwing callback does not orphan remaining emissions; the first error is
97
- * re-thrown after all emissions drain. Callbacks that ran before the throw may
98
- * have applied phase-2 — partial graph state is intentional (decision C1).
99
- *
100
- * @param fn — Synchronous work that may call `downWithBatch` / `node.down()`.
101
- * @returns `void` — all side-effects happen through `downWithBatch` and the
102
- * phase-2 drain that runs after `fn` returns.
103
- *
104
- * @example
105
- * ```ts
106
- * import { core } from "@graphrefly/graphrefly-ts";
107
- *
108
- * core.batch(() => {
109
- * core.downWithBatch(sink, [[core.DATA, 1]]);
110
- * });
111
- * ```
112
- *
113
- * @category core
114
- */
115
- declare function batch(fn: () => void): void;
116
- /**
117
- * Splits a message array into three groups by signal tier (see `messages.ts`):
118
- *
119
- * - **immediate** — tier 0–2, 5: START, DIRTY, INVALIDATE, PAUSE, RESUME, TEARDOWN, unknown
120
- * - **deferred** — tier 3: DATA, RESOLVED (phase-2, deferred inside `batch()`)
121
- * - **terminal** — tier 4: COMPLETE, ERROR (delivered after phase-2)
122
- *
123
- * Order within each group is preserved.
124
- *
125
- * @param messages — One `down()` payload.
126
- * @returns Three groups in canonical delivery order.
127
- *
128
- * @example
129
- * ```ts
130
- * import { DATA, DIRTY, COMPLETE, partitionForBatch } from "@graphrefly/graphrefly-ts";
131
- *
132
- * partitionForBatch([[DIRTY], [DATA, 1], [COMPLETE]]);
133
- * // { immediate: [[DIRTY]], deferred: [[DATA, 1]], terminal: [[COMPLETE]] }
134
- * ```
135
- *
136
- * @category core
137
- */
138
- declare function partitionForBatch(messages: Messages): {
139
- immediate: Messages;
140
- deferred: Messages;
141
- terminal: Messages;
142
- };
143
- /**
144
- * Delivers messages downstream through `sink`, applying batch semantics and
145
- * canonical tier-based ordering (see `messages.ts`):
146
- *
147
- * 1. **Immediate** (tier 0–2, 5): START, DIRTY, INVALIDATE, PAUSE, RESUME, TEARDOWN,
148
- * unknown — delivered synchronously.
149
- * 2. **Phase-2** (tier 3): DATA, RESOLVED — deferred while `isBatching()`.
150
- * 3. **Terminal** (tier 4): COMPLETE, ERROR — always delivered after phase-2.
151
- * When batching, terminal is queued after deferred phase-2 in the pending list.
152
- * When not batching, terminal is delivered after phase-2 synchronously.
153
- *
154
- * This ordering prevents the "COMPLETE-before-DATA" class of bugs: terminal
155
- * signals never make a node terminal before phase-2 values reach sinks,
156
- * regardless of how the source assembled the message array.
157
- *
158
- * @param sink — Sink callback. May be called up to three times per invocation
159
- * (immediate, deferred, terminal) when not batching.
160
- * @param messages — Full `[[Type, Data?], ...]` array for one downstream delivery.
161
- * @param phase — Starting delivery phase (`2` = data, `3` = terminal). Default `2`.
162
- * @param options - Optional configuration.
163
- * @option strategy | `"partition"` or `"sequential"` | `"partition"` | `"partition"` groups by tier; `"sequential"` preserves message order within each tier using `messageTier()` classification.
164
- * @returns `void` — delivery is performed through `sink` callbacks, synchronously
165
- * or deferred into the active batch queue.
166
- *
167
- * @example
168
- * ```ts
169
- * import { core } from "@graphrefly/graphrefly-ts";
170
- *
171
- * core.downWithBatch((msgs) => console.log(msgs), [[core.DIRTY], [core.DATA, 42]]);
172
- * ```
173
- *
174
- * @category core
175
- */
176
- /** Delivery strategy for {@link downWithBatch}. Mirrors Python `DownStrategy`. */
177
- type DownStrategy = "partition" | "sequential";
178
- declare function downWithBatch(sink: (messages: Messages) => void, messages: Messages, phase?: 2 | 3, options?: {
179
- strategy?: DownStrategy;
180
- }): void;
181
-
182
- /**
183
- * bridge — graph-visible message forwarding between two nodes.
184
- *
185
- * Replaces ad-hoc `subscribe()` bridges that bypass graph topology.
186
- * The returned node is an effect that intercepts messages from `from`
187
- * and forwards them to `to.down()`. Register it with `graph.add()` to
188
- * make the bridge visible in `describe()` and `snapshot()`.
189
- *
190
- * **Upstream path:** The bridge node has `from` as its dep, so anything
191
- * downstream of the bridge that calls `up()` naturally reaches `from`.
192
- * If `to` is used as a dep by other nodes and those nodes send `up()`,
193
- * the messages reach `to`'s deps (not `from`). For full upstream relay
194
- * across the bridge boundary, wire the bridge as a dep of `to`'s
195
- * consumers or use `graph.connect()`.
196
- *
197
- * **ABAC / guards:** `to.down()` is called without `NodeTransportOptions`,
198
- * so any ABAC guard on `to` receives `actor = undefined`. Upstream (`up()`)
199
- * messages propagate through the dep chain the same way — no actor is
200
- * injected on either path. Both paths are intentionally unguarded; if `to`
201
- * requires a specific actor, provide a guarded wrapper node and bridge to
202
- * that instead.
203
- *
204
- * **Default forwarding:** All standard message types are forwarded by
205
- * default, including TEARDOWN, PAUSE, RESUME, and INVALIDATE. Use the
206
- * `down` option to restrict which types are forwarded. Callers that need
207
- * to exclude TEARDOWN (e.g. inter-stage wiring in `funnel()`) pass an
208
- * explicit `down` array without TEARDOWN.
209
- *
210
- * @module
211
- */
212
-
213
- /** Options for {@link bridge}. */
214
- type BridgeOptions = {
215
- /** Node name (for graph registration / describe). */
216
- name?: string;
217
- /**
218
- * Standard message types to forward downstream. Default: all standard
219
- * types. Unknown (non-standard) types always forward per spec §1.3.6
220
- * regardless of this option.
221
- */
222
- down?: readonly symbol[];
223
- };
224
- /** All standard types forwarded by default. Export for callers that
225
- * need to customize (e.g. exclude TEARDOWN). */
226
- declare const DEFAULT_DOWN: readonly symbol[];
227
- /**
228
- * Create a graph-visible bridge node that forwards messages from `from` to `to`.
229
- *
230
- * The bridge is a real node (effect) — it shows up in `describe()`, participates
231
- * in two-phase push, and cleans up on TEARDOWN. Register it via `graph.add()`
232
- * to make it part of the graph topology.
233
- *
234
- * **Unknown message types** (custom domain signals not in the standard protocol
235
- * set) are always forwarded to `to`, regardless of the `down` option. This
236
- * satisfies spec §1.3.6 ("unknown types forward unchanged").
237
- *
238
- * **COMPLETE / ERROR**: when forwarded, the bridge also transitions to terminal
239
- * state so graph-wide completion detection works correctly.
240
- *
241
- * @param from - Source node to observe.
242
- * @param to - Target node to forward messages to via `to.down()`.
243
- * @param opts - Optional configuration.
244
- * @returns A bridge effect node. Add it to a graph with `graph.add(name, bridge(...))`.
245
- *
246
- * @example
247
- * ```ts
248
- * import { bridge, state } from "@graphrefly/graphrefly-ts";
249
- *
250
- * const a = state(0);
251
- * const b = state(0);
252
- * const br = bridge(a, b, { name: "__bridge_a_b" });
253
- * graph.add("__bridge_a_b", br);
254
- * // Now a's messages flow to b, visible in describe()
255
- * ```
256
- *
257
- * @category core
258
- */
259
- declare function bridge<T = unknown>(from: Node<T>, to: Node, opts?: BridgeOptions): Node<unknown>;
260
-
261
- /**
262
- * Centralised timestamp utilities.
263
- *
264
- * Convention: all graphrefly-ts timestamps use nanoseconds (`_ns` suffix).
265
- *
266
- * - {@link monotonicNs} — monotonic clock (ordering, durations, timeline events).
267
- * - {@link wallClockNs} — wall-clock (mutation attribution, cron emission).
268
- *
269
- * **Precision limits (JS platform):**
270
- *
271
- * - `monotonicNs`: effective ~microsecond precision. `performance.now()` returns
272
- * milliseconds with ~5µs resolution; the last 3 digits of the nanosecond value
273
- * are always zero. Python's `time.monotonic_ns()` gives true nanoseconds.
274
- *
275
- * - `wallClockNs`: ~256ns precision loss at current epoch. `Date.now() * 1e6`
276
- * produces values around 1.8×10¹⁸ which exceed IEEE 754's 2⁵³ safe integer
277
- * limit. Python's `time.time_ns()` (arbitrary-precision `int`) has no loss.
278
- * In practice this is irrelevant — JS is single-threaded, so sub-microsecond
279
- * timestamp collisions cannot occur.
280
- */
281
- /** Monotonic nanosecond timestamp via `performance.now()`. */
282
- declare function monotonicNs(): number;
283
- /** Wall-clock nanosecond timestamp via `Date.now()`. */
284
- declare function wallClockNs(): number;
285
-
286
- /**
287
- * `dynamicNode` — runtime dep tracking with diamond resolution (Phase 0.3b).
288
- *
289
- * Unlike `node()` where deps are fixed at construction, `dynamicNode`
290
- * discovers deps at runtime via a tracking `get()` proxy. After each
291
- * recompute, deps are diffed: new deps are connected, removed deps are
292
- * disconnected, and bitmasks are rebuilt.
293
- *
294
- * Shares subscribe / sink / lifecycle machinery with {@link NodeImpl} via
295
- * {@link NodeBase}. The only things that diverge from static nodes:
296
- * - deps are discovered inside `_runFn` via a tracking `get` proxy
297
- * - `_rewire` installs subscriptions lazily during `_runFn`
298
- * - during rewire, new dep messages are **buffered** (option C from the
299
- * Apr-2026 refactor); after rewire we scan the buffer for DATA values
300
- * that differ from what fn tracked, and re-run fn if any found
301
- * (bounded by `MAX_RERUN`)
302
- */
303
-
304
- /**
305
- * The tracking `get` function passed to `dynamicNode`'s compute function.
306
- * Each call to `get(dep)` reads the dep's current value and records it as a dependency.
307
- */
308
- type DynGet = <V>(dep: Node<V>) => V | undefined;
309
- /**
310
- * Compute function for `dynamicNode`. Receives a tracking `get` proxy.
311
- * Deps are discovered by which nodes are passed to `get()` during execution.
312
- */
313
- type DynamicNodeFn<T> = (get: DynGet) => T;
314
- /** Options for `dynamicNode`. */
315
- type DynamicNodeOptions = Pick<NodeOptions, "name" | "equals" | "meta" | "resubscribable" | "resetOnTeardown" | "guard" | "onMessage" | "onResubscribe" | "completeWhenDepsComplete" | "describeKind">;
316
- /**
317
- * Creates a node with runtime dep tracking. Deps are discovered each time the
318
- * compute function runs by tracking which nodes are passed to the `get()` proxy.
319
- *
320
- * After each recompute:
321
- * - New deps (not in previous set) are subscribed
322
- * - Removed deps (not in current set) are unsubscribed
323
- * - Kept deps retain their existing subscriptions
324
- *
325
- * The node participates in diamond resolution via the pre-set dirty mask
326
- * (shared with {@link NodeImpl}).
327
- *
328
- * **Lazy-dep composition:** when a tracked dep is itself a lazy compute node
329
- * whose first subscribe causes a fresh value to arrive, the rewire buffer
330
- * detects the discrepancy and re-runs fn once so it observes the real value.
331
- * Capped at {@link MAX_RERUN} iterations.
332
- *
333
- * @param fn - Compute function receiving a tracking `get` proxy.
334
- * @param opts - Optional configuration.
335
- * @returns `Node<T>` with dynamic dep tracking.
336
- *
337
- * @example
338
- * ```ts
339
- * import { dynamicNode, state } from "@graphrefly/graphrefly-ts";
340
- *
341
- * const cond = state(true);
342
- * const a = state(1);
343
- * const b = state(2);
344
- *
345
- * const d = dynamicNode((get) => {
346
- * const useA = get(cond);
347
- * return useA ? get(a) : get(b);
348
- * });
349
- * ```
350
- *
351
- * @category core
352
- */
353
- declare function dynamicNode<T = unknown>(fn: DynamicNodeFn<T>, opts?: DynamicNodeOptions): Node<T>;
354
- /** @internal — exported for {@link describeNode} `instanceof` check. */
355
- declare class DynamicNodeImpl<T = unknown> extends NodeBase<T> {
356
- private readonly _fn;
357
- private readonly _autoComplete;
358
- /** @internal Read by `describeNode`. */
359
- _deps: Node[];
360
- private _depUnsubs;
361
- private _depIndexMap;
362
- private _depDirtyBits;
363
- private _depSettledBits;
364
- private _depCompleteBits;
365
- private _running;
366
- private _rewiring;
367
- private _bufferedDepMessages;
368
- private _trackedValues;
369
- private _rerunCount;
370
- constructor(fn: DynamicNodeFn<T>, opts: DynamicNodeOptions);
371
- protected _createMetaNode(key: string, initialValue: unknown, opts: NodeOptions): Node;
372
- /** Versioning not supported on DynamicNodeImpl (override base). */
373
- get v(): undefined;
374
- up(messages: Messages, options?: NodeTransportOptions): void;
375
- protected _upInternal(messages: Messages): void;
376
- unsubscribe(): void;
377
- protected _onActivate(): void;
378
- protected _doDeactivate(): void;
379
- private _disconnect;
380
- private _runFn;
381
- private _rewire;
382
- private _handleDepMessages;
383
- /**
384
- * Update dep masks for a message without triggering `_runFn` — used
385
- * during post-rewire drain so the wave state is consistent with the
386
- * buffered activation cascade without recursing.
387
- */
388
- private _updateMasksForMessage;
389
- private _allDirtySettled;
390
- /**
391
- * True if any current dep value differs from what the last `_runFn`
392
- * saw via `get()`. Used to suppress redundant re-runs when deferred
393
- * handshake messages arrive after `_rewire` for a dep whose value
394
- * already matches `_trackedValues`.
395
- */
396
- private _depValuesDifferFromTracked;
397
- }
398
-
399
- /**
400
- * Creates a manual source with no upstream deps. Emit values with {@link Node.down}.
401
- *
402
- * Spec: `state(initial, opts?)` is `node([], { initial, ...opts })` (GRAPHREFLY-SPEC §2.7).
403
- *
404
- * @param initial - Initial cached value. Because `initial` is provided, `equals` is
405
- * called on the first {@link Node.down | down()} emission — if the value matches
406
- * `initial`, the node emits `RESOLVED` instead of `DATA` (spec §2.5).
407
- * @param opts - Optional {@link NodeOptions} (excluding `initial`).
408
- * @returns `Node<T>` - Stateful node you drive imperatively.
409
- *
410
- * @example
411
- * ```ts
412
- * import { DATA, state } from "@graphrefly/graphrefly-ts";
413
- *
414
- * const n = state(0);
415
- * n.down([[DATA, 1]]);
416
- * ```
417
- *
418
- * @category core
419
- */
420
- declare function state<T>(initial: T, opts?: Omit<NodeOptions, "initial">): Node<T>;
421
- /**
422
- * Creates a producer node with no deps; `fn` runs when the first subscriber connects.
423
- *
424
- * @param fn - Receives deps (empty) and {@link NodeActions}; use `emit` / `down` to push.
425
- * @param opts - Optional {@link NodeOptions}.
426
- * @returns `Node<T>` - Producer node.
427
- *
428
- * @example
429
- * ```ts
430
- * import { producer } from "@graphrefly/graphrefly-ts";
431
- *
432
- * const tick = producer((_d, a) => {
433
- * a.emit(1);
434
- * });
435
- * ```
436
- *
437
- * @category core
438
- */
439
- declare function producer<T = unknown>(fn: NodeFn<T>, opts?: NodeOptions): Node<T>;
440
- /**
441
- * Creates a derived node from dependencies and a compute function (same primitive as operators).
442
- *
443
- * @param deps - Upstream nodes.
444
- * @param fn - Compute function; return value is emitted, or use `actions` explicitly.
445
- * @param opts - Optional {@link NodeOptions}.
446
- * @returns `Node<T>` - Derived node.
447
- *
448
- * @example
449
- * ```ts
450
- * import { derived, state } from "@graphrefly/graphrefly-ts";
451
- *
452
- * const a = state(1);
453
- * const b = derived([a], ([x]) => (x as number) * 2);
454
- * ```
455
- *
456
- * @category core
457
- */
458
- declare function derived<T = unknown>(deps: readonly Node[], fn: NodeFn<T>, opts?: NodeOptions): Node<T>;
459
- /**
460
- * Runs a side-effect when deps settle; return value is not auto-emitted.
461
- *
462
- * @param deps - Nodes to watch.
463
- * @param fn - Side-effect body.
464
- * @returns `Node<unknown>` - Effect node.
465
- *
466
- * @example
467
- * ```ts
468
- * import { effect, state } from "@graphrefly/graphrefly-ts";
469
- *
470
- * const n = state(1);
471
- * effect([n], ([v]) => {
472
- * console.log(v);
473
- * });
474
- * ```
475
- *
476
- * @category core
477
- */
478
- declare function effect(deps: readonly Node[], fn: NodeFn<unknown>, opts?: NodeOptions): Node<unknown>;
479
- /** Unary transform used by {@link pipe} (typically returns a new node wrapping `n`). */
480
- type PipeOperator = (n: Node) => Node;
481
- /**
482
- * Composes unary operators left-to-right; returns the final node. Does not register a {@link Graph}.
483
- *
484
- * @param source - Starting node.
485
- * @param ops - Each operator maps `Node` to `Node` (curried operators from `extra` use a factory pattern — wrap or use direct calls).
486
- * @returns `Node` - Result of the last operator.
487
- *
488
- * @example
489
- * ```ts
490
- * import { filter, map, pipe, state } from "@graphrefly/graphrefly-ts";
491
- *
492
- * const src = state(1);
493
- * const out = pipe(
494
- * src,
495
- * (n) => map(n, (x) => x + 1),
496
- * (n) => filter(n, (x) => x > 0),
497
- * );
498
- * ```
499
- *
500
- * @category core
501
- */
502
- declare function pipe(source: Node, ...ops: PipeOperator[]): Node;
503
-
504
- /**
505
- * Creates a resettable deadline timer for internal timeout, retry, and rate-limiting use.
506
- *
507
- * @remarks **Centralised primitive:** wraps `setTimeout`/`clearTimeout` with a generation guard
508
- * so that stale callbacks never fire after `cancel()` or a new `start()`.
509
- *
510
- * @remarks **Spec §5.10 exception:** resilience operators (`timeout`, `retry`, `rateLimiter`)
511
- * need raw timers — `fromTimer` creates a new Node per reset, which is too heavy here.
512
- *
513
- * @example
514
- * ```ts
515
- * import { ResettableTimer } from "@graphrefly/graphrefly-ts";
516
- *
517
- * const timer = new ResettableTimer();
518
- * timer.start(1000, () => console.log("fired"));
519
- * timer.cancel(); // cancels before firing
520
- * timer.start(500, () => console.log("new deadline"));
521
- * console.log(timer.pending); // true
522
- * ```
523
- *
524
- * @category core
525
- */
526
- declare class ResettableTimer {
527
- private _timer;
528
- private _gen;
529
- /** Schedule callback after delayMs. Cancels any pending timer. */
530
- start(delayMs: number, callback: () => void): void;
531
- /** Cancel the pending timer (if any). */
532
- cancel(): void;
533
- /** Whether a timer is currently pending. */
534
- get pending(): boolean;
535
- }
536
-
537
- /**
538
- * Core layer: message protocol, node primitive, lifecycle (Phase 0).
539
- */
540
-
541
- declare const index_Actor: typeof Actor;
542
- type index_BridgeOptions = BridgeOptions;
543
- declare const index_CLEANUP_RESULT: typeof CLEANUP_RESULT;
544
- declare const index_COMPLETE: typeof COMPLETE;
545
- declare const index_CleanupResult: typeof CleanupResult;
546
- declare const index_DATA: typeof DATA;
547
- declare const index_DEFAULT_ACTOR: typeof DEFAULT_ACTOR;
548
- declare const index_DEFAULT_DOWN: typeof DEFAULT_DOWN;
549
- declare const index_DIRTY: typeof DIRTY;
550
- declare const index_DescribeDetail: typeof DescribeDetail;
551
- declare const index_DescribeField: typeof DescribeField;
552
- declare const index_DescribeNodeOutput: typeof DescribeNodeOutput;
553
- type index_DownStrategy = DownStrategy;
554
- type index_DynGet = DynGet;
555
- type index_DynamicNodeFn<T> = DynamicNodeFn<T>;
556
- type index_DynamicNodeImpl<T = unknown> = DynamicNodeImpl<T>;
557
- declare const index_DynamicNodeImpl: typeof DynamicNodeImpl;
558
- type index_DynamicNodeOptions = DynamicNodeOptions;
559
- declare const index_ERROR: typeof ERROR;
560
- declare const index_GuardAction: typeof GuardAction;
561
- declare const index_GuardDenied: typeof GuardDenied;
562
- declare const index_GuardDeniedDetails: typeof GuardDeniedDetails;
563
- declare const index_HashFn: typeof HashFn;
564
- declare const index_INVALIDATE: typeof INVALIDATE;
565
- declare const index_Message: typeof Message;
566
- declare const index_Messages: typeof Messages;
567
- declare const index_Node: typeof Node;
568
- declare const index_NodeActions: typeof NodeActions;
569
- declare const index_NodeDescribeKind: typeof NodeDescribeKind;
570
- type index_NodeFn<T = unknown> = NodeFn<T>;
571
- declare const index_NodeGuard: typeof NodeGuard;
572
- declare const index_NodeOptions: typeof NodeOptions;
573
- declare const index_NodeSink: typeof NodeSink;
574
- declare const index_NodeStatus: typeof NodeStatus;
575
- declare const index_NodeTransportOptions: typeof NodeTransportOptions;
576
- declare const index_NodeVersionInfo: typeof NodeVersionInfo;
577
- declare const index_OnMessageHandler: typeof OnMessageHandler;
578
- declare const index_PAUSE: typeof PAUSE;
579
- type index_PipeOperator = PipeOperator;
580
- declare const index_PolicyAllow: typeof PolicyAllow;
581
- declare const index_PolicyDeny: typeof PolicyDeny;
582
- declare const index_PolicyRuleData: typeof PolicyRuleData;
583
- declare const index_RESOLVED: typeof RESOLVED;
584
- declare const index_RESUME: typeof RESUME;
585
- type index_ResettableTimer = ResettableTimer;
586
- declare const index_ResettableTimer: typeof ResettableTimer;
587
- declare const index_START: typeof START;
588
- declare const index_SubscribeHints: typeof SubscribeHints;
589
- declare const index_TEARDOWN: typeof TEARDOWN;
590
- declare const index_V0: typeof V0;
591
- declare const index_V1: typeof V1;
592
- declare const index_VersioningLevel: typeof VersioningLevel;
593
- declare const index_VersioningOptions: typeof VersioningOptions;
594
- declare const index_accessHintForGuard: typeof accessHintForGuard;
595
- declare const index_advanceVersion: typeof advanceVersion;
596
- declare const index_batch: typeof batch;
597
- declare const index_bridge: typeof bridge;
598
- declare const index_cleanupResult: typeof cleanupResult;
599
- declare const index_createVersioning: typeof createVersioning;
600
- declare const index_defaultHash: typeof defaultHash;
601
- declare const index_derived: typeof derived;
602
- declare const index_downWithBatch: typeof downWithBatch;
603
- declare const index_dynamicNode: typeof dynamicNode;
604
- declare const index_effect: typeof effect;
605
- declare const index_isBatching: typeof isBatching;
606
- declare const index_isKnownMessageType: typeof isKnownMessageType;
607
- declare const index_isLocalOnly: typeof isLocalOnly;
608
- declare const index_isPhase2Message: typeof isPhase2Message;
609
- declare const index_isTerminalMessage: typeof isTerminalMessage;
610
- declare const index_isV1: typeof isV1;
611
- declare const index_knownMessageTypes: typeof knownMessageTypes;
612
- declare const index_messageTier: typeof messageTier;
613
- declare const index_monotonicNs: typeof monotonicNs;
614
- declare const index_node: typeof node;
615
- declare const index_normalizeActor: typeof normalizeActor;
616
- declare const index_partitionForBatch: typeof partitionForBatch;
617
- declare const index_pipe: typeof pipe;
618
- declare const index_policy: typeof policy;
619
- declare const index_policyFromRules: typeof policyFromRules;
620
- declare const index_producer: typeof producer;
621
- declare const index_propagatesToMeta: typeof propagatesToMeta;
622
- declare const index_resolveDescribeFields: typeof resolveDescribeFields;
623
- declare const index_state: typeof state;
624
- declare const index_wallClockNs: typeof wallClockNs;
625
- declare namespace index {
626
- export { index_Actor as Actor, type index_BridgeOptions as BridgeOptions, index_CLEANUP_RESULT as CLEANUP_RESULT, index_COMPLETE as COMPLETE, index_CleanupResult as CleanupResult, index_DATA as DATA, index_DEFAULT_ACTOR as DEFAULT_ACTOR, index_DEFAULT_DOWN as DEFAULT_DOWN, index_DIRTY as DIRTY, index_DescribeDetail as DescribeDetail, index_DescribeField as DescribeField, index_DescribeNodeOutput as DescribeNodeOutput, type index_DownStrategy as DownStrategy, type index_DynGet as DynGet, type index_DynamicNodeFn as DynamicNodeFn, index_DynamicNodeImpl as DynamicNodeImpl, type index_DynamicNodeOptions as DynamicNodeOptions, index_ERROR as ERROR, index_GuardAction as GuardAction, index_GuardDenied as GuardDenied, index_GuardDeniedDetails as GuardDeniedDetails, index_HashFn as HashFn, index_INVALIDATE as INVALIDATE, index_Message as Message, index_Messages as Messages, index_Node as Node, index_NodeActions as NodeActions, index_NodeDescribeKind as NodeDescribeKind, type index_NodeFn as NodeFn, index_NodeGuard as NodeGuard, index_NodeOptions as NodeOptions, index_NodeSink as NodeSink, index_NodeStatus as NodeStatus, index_NodeTransportOptions as NodeTransportOptions, index_NodeVersionInfo as NodeVersionInfo, index_OnMessageHandler as OnMessageHandler, index_PAUSE as PAUSE, type index_PipeOperator as PipeOperator, index_PolicyAllow as PolicyAllow, index_PolicyDeny as PolicyDeny, index_PolicyRuleData as PolicyRuleData, index_RESOLVED as RESOLVED, index_RESUME as RESUME, index_ResettableTimer as ResettableTimer, index_START as START, index_SubscribeHints as SubscribeHints, index_TEARDOWN as TEARDOWN, index_V0 as V0, index_V1 as V1, index_VersioningLevel as VersioningLevel, index_VersioningOptions as VersioningOptions, index_accessHintForGuard as accessHintForGuard, index_advanceVersion as advanceVersion, index_batch as batch, index_bridge as bridge, index_cleanupResult as cleanupResult, index_createVersioning as createVersioning, index_defaultHash as defaultHash, index_derived as derived, index_downWithBatch as downWithBatch, index_dynamicNode as dynamicNode, index_effect as effect, index_isBatching as isBatching, index_isKnownMessageType as isKnownMessageType, index_isLocalOnly as isLocalOnly, index_isPhase2Message as isPhase2Message, index_isTerminalMessage as isTerminalMessage, index_isV1 as isV1, index_knownMessageTypes as knownMessageTypes, index_messageTier as messageTier, index_monotonicNs as monotonicNs, index_node as node, index_normalizeActor as normalizeActor, index_partitionForBatch as partitionForBatch, index_pipe as pipe, index_policy as policy, index_policyFromRules as policyFromRules, index_producer as producer, index_propagatesToMeta as propagatesToMeta, index_resolveDescribeFields as resolveDescribeFields, index_state as state, index_wallClockNs as wallClockNs };
627
- }
628
-
629
- export { type BridgeOptions as B, DEFAULT_DOWN as D, type NodeFn as N, type PipeOperator as P, ResettableTimer as R, type DownStrategy as a, type DynGet as b, type DynamicNodeFn as c, DynamicNodeImpl as d, type DynamicNodeOptions as e, batch as f, bridge as g, derived as h, index as i, downWithBatch as j, dynamicNode as k, effect as l, isBatching as m, monotonicNs as n, node as o, partitionForBatch as p, pipe as q, producer as r, state as s, wallClockNs as w };