@graphrefly/graphrefly 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-RHI3GHZW.js → chunk-263BEJJO.js} +3 -3
- package/dist/{chunk-44HD4BTA.js → chunk-2GQLMQVJ.js} +3 -3
- package/dist/chunk-32N5A454.js +36 -0
- package/dist/chunk-32N5A454.js.map +1 -0
- package/dist/{chunk-IR3KMOLX.js → chunk-CWYPA63G.js} +3 -383
- package/dist/chunk-CWYPA63G.js.map +1 -0
- package/dist/{chunk-TH6COGOP.js → chunk-HVBX5KIW.js} +2 -2
- package/dist/chunk-JFONSPNF.js +391 -0
- package/dist/chunk-JFONSPNF.js.map +1 -0
- package/dist/{chunk-QA3RP5NH.js → chunk-NZMBRXQV.js} +101 -5
- package/dist/chunk-NZMBRXQV.js.map +1 -0
- package/dist/{chunk-MQBQOFDS.js → chunk-PNUZM7PC.js} +12 -31
- package/dist/chunk-PNUZM7PC.js.map +1 -0
- package/dist/{chunk-EQUZ5NLD.js → chunk-PX6PDUJ5.js} +11 -16
- package/dist/chunk-PX6PDUJ5.js.map +1 -0
- package/dist/{chunk-NXC35KC5.js → chunk-XRFJJ2IU.js} +3 -3
- package/dist/{chunk-BLD3IFYF.js → chunk-XTLYW4FR.js} +9 -7
- package/dist/{chunk-BLD3IFYF.js.map → chunk-XTLYW4FR.js.map} +1 -1
- package/dist/compat/nestjs/index.cjs +100 -4
- package/dist/compat/nestjs/index.cjs.map +1 -1
- package/dist/compat/nestjs/index.d.cts +6 -6
- package/dist/compat/nestjs/index.d.ts +6 -6
- package/dist/compat/nestjs/index.js +9 -7
- package/dist/core/index.cjs +100 -4
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +3 -3
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +3 -3
- package/dist/extra/index.cjs +100 -4
- package/dist/extra/index.cjs.map +1 -1
- package/dist/extra/index.d.cts +4 -4
- package/dist/extra/index.d.ts +4 -4
- package/dist/extra/index.js +9 -7
- package/dist/graph/index.cjs +100 -4
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +5 -5
- package/dist/graph/index.d.ts +5 -5
- package/dist/graph/index.js +4 -4
- package/dist/{graph-ab1yPwIB.d.cts → graph-BtdSRHUc.d.cts} +3 -3
- package/dist/{graph-DFr0diXB.d.ts → graph-CEO2FkLY.d.ts} +3 -3
- package/dist/{index-BvWfZCTt.d.cts → index-B0tfuXwV.d.cts} +3 -3
- package/dist/{index-Dy04P4W3.d.cts → index-BFGjXbiP.d.cts} +2 -2
- package/dist/{index-DrJq9B1T.d.cts → index-BPlWVAKY.d.cts} +3 -3
- package/dist/{index-C9z6rU9P.d.cts → index-BUj3ASVe.d.cts} +25 -7
- package/dist/{index-DLE1Sp-L.d.cts → index-C59uSJAH.d.cts} +2 -2
- package/dist/{index-DsGxLfwL.d.ts → index-CkElcUY6.d.ts} +2 -2
- package/dist/{index-HdJx_BjO.d.ts → index-DSPc5rkv.d.ts} +25 -7
- package/dist/{index-D36MAQ3f.d.ts → index-DgscL7v0.d.ts} +3 -3
- package/dist/{index-BbYZma8G.d.ts → index-RXN94sHK.d.ts} +3 -3
- package/dist/{index-BHm3Ba5q.d.ts → index-jEtF4N7L.d.ts} +2 -2
- package/dist/index.cjs +109 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -15
- package/dist/index.d.ts +15 -15
- package/dist/index.js +26 -22
- package/dist/index.js.map +1 -1
- package/dist/{meta-n3FoVWML.d.ts → meta-3QjzotRv.d.ts} +1 -1
- package/dist/{meta--fr9sxRM.d.cts → meta-B-Lbs4-O.d.cts} +1 -1
- package/dist/{node-C5UD5MGq.d.cts → node-C7PD3sn9.d.cts} +42 -0
- package/dist/{node-C5UD5MGq.d.ts → node-C7PD3sn9.d.ts} +42 -0
- package/dist/{observable-CQRBtEbq.d.ts → observable-EyO-moQY.d.ts} +1 -1
- package/dist/{observable-DWydVy5b.d.cts → observable-axpzv1K2.d.cts} +1 -1
- package/dist/patterns/reactive-layout/index.cjs +214 -117
- package/dist/patterns/reactive-layout/index.cjs.map +1 -1
- package/dist/patterns/reactive-layout/index.d.cts +5 -5
- package/dist/patterns/reactive-layout/index.d.ts +5 -5
- package/dist/patterns/reactive-layout/index.js +6 -4
- package/dist/{storage-C9fZfMfM.d.ts → storage-CHT5WE9m.d.ts} +1 -1
- package/dist/{storage-Bew05Xy6.d.cts → storage-DIgAr7M_.d.cts} +1 -1
- package/package.json +2 -1
- package/dist/chunk-EQUZ5NLD.js.map +0 -1
- package/dist/chunk-IR3KMOLX.js.map +0 -1
- package/dist/chunk-MQBQOFDS.js.map +0 -1
- package/dist/chunk-QA3RP5NH.js.map +0 -1
- /package/dist/{chunk-RHI3GHZW.js.map → chunk-263BEJJO.js.map} +0 -0
- /package/dist/{chunk-44HD4BTA.js.map → chunk-2GQLMQVJ.js.map} +0 -0
- /package/dist/{chunk-TH6COGOP.js.map → chunk-HVBX5KIW.js.map} +0 -0
- /package/dist/{chunk-NXC35KC5.js.map → chunk-XRFJJ2IU.js.map} +0 -0
package/dist/extra/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/extra/index.ts","../../src/core/batch.ts","../../src/core/clock.ts","../../src/core/messages.ts","../../src/graph/codec.ts","../../src/core/actor.ts","../../src/core/config.ts","../../src/core/guard.ts","../../src/core/versioning.ts","../../src/core/node.ts","../../src/core/sugar.ts","../../src/extra/backoff.ts","../../src/extra/external-register.ts","../../src/extra/sources.ts","../../src/extra/cron.ts","../../src/extra/operators.ts","../../src/extra/utils/ring-buffer.ts","../../src/extra/reactive-sink.ts","../../src/extra/timer.ts","../../src/extra/resilience.ts","../../src/extra/adapters.ts","../../src/extra/backpressure.ts","../../src/extra/cascading-cache.ts","../../src/extra/reactive-map.ts","../../src/extra/composite.ts","../../src/extra/observable.ts","../../src/extra/pubsub.ts","../../src/extra/reactive-index.ts","../../src/extra/reactive-list.ts","../../src/extra/reactive-log.ts","../../src/extra/storage.ts","../../src/extra/worker/protocol.ts","../../src/extra/worker/transport.ts","../../src/extra/worker/bridge.ts","../../src/extra/worker/self.ts"],"sourcesContent":["/**\n * Extra layer: operators, sources, sinks (Phase 2+).\n */\n\nexport * from \"./adapters.js\";\nexport * from \"./backoff.js\";\nexport * from \"./backpressure.js\";\nexport * from \"./cascading-cache.js\";\nexport * from \"./composite.js\";\nexport * from \"./cron.js\";\nexport * from \"./external-register.js\";\nexport * from \"./observable.js\";\nexport * from \"./operators.js\";\nexport * from \"./pubsub.js\";\nexport * from \"./reactive-index.js\";\nexport * from \"./reactive-list.js\";\nexport * from \"./reactive-log.js\";\nexport * from \"./reactive-map.js\";\nexport * from \"./reactive-sink.js\";\n// Re-export resilience explicitly to avoid `timeout` / `pipe` conflicts with operators.js\nexport {\n\ttype CircuitBreaker,\n\ttype CircuitBreakerOptions,\n\tCircuitOpenError,\n\ttype CircuitState,\n\tcircuitBreaker,\n\ttype FallbackInput,\n\tfallback,\n\ttype RateLimiterOptions,\n\tRateLimiterOverflowError,\n\ttype RateLimiterOverflowPolicy,\n\ttype RetryOptions,\n\ttype RetrySourceOptions,\n\trateLimiter,\n\tretry,\n\tretrySource,\n\ttype StatusValue,\n\tTimeoutError,\n\ttype TokenBucket,\n\ttimeout,\n\ttokenBucket,\n\ttype WithBreakerBundle,\n\ttype WithStatusBundle,\n\twithBreaker,\n\twithStatus,\n} from \"./resilience.js\";\nexport * from \"./sources.js\";\nexport * from \"./storage.js\";\nexport { ResettableTimer } from \"./timer.js\";\nexport * from \"./worker/index.js\";\n","/**\n * Batch deferral for tier-3+ messages.\n *\n * §1.3.7 — Inside a batch, tier 0–2 signals propagate immediately. Tier 3\n * (DATA/RESOLVED), tier 4 (COMPLETE/ERROR), and tier 5 (TEARDOWN) are queued\n * and drained in ascending phase order after the outermost `batch()` callback\n * returns.\n *\n * **Phase vocabulary:**\n * - Phase 1 = tiers 0–2 — immediate, never queued.\n * - Phase 2 = tier 3 — {@link drainPhase2}. Value settlements.\n * - Phase 3 = tier 4 — {@link drainPhase3}. Terminal signals.\n * - Phase 4 = tier 5 — {@link drainPhase4}. TEARDOWN (unified deferral).\n *\n * Drain rule: lowest non-empty phase first. Re-enqueues during drain bump the\n * loop back to the lowest non-empty phase, preserving \"earlier values settle\n * before later terminals/teardown\" across callback re-entry.\n *\n * **Pre-sorted input invariant.** `downWithBatch` assumes `messages` is\n * already sorted in ascending tier order (produced by `_frameBatch` in\n * `node.ts`). The walker exploits monotonicity for a single O(n) pass and\n * slices at phase boundaries without re-sorting.\n */\n\nimport type { Messages } from \"./messages.js\";\n\nconst MAX_DRAIN_ITERATIONS = 1000;\n\nlet batchDepth = 0;\nlet flushInProgress = false;\n\n/** Tier 3 (DATA/RESOLVED) deferral queue — drained first. */\nconst drainPhase2: Array<() => void> = [];\n/** Tier 4 (COMPLETE/ERROR) deferral queue — drained after phase 2. */\nconst drainPhase3: Array<() => void> = [];\n/** Tier 5 (TEARDOWN) deferral queue — drained last. */\nconst drainPhase4: Array<() => void> = [];\n\n/**\n * Returns whether the current call stack is inside a batch scope **or** while\n * a deferred drain is in progress. Nested `downWithBatch` calls during drain\n * still defer (they bump the drain loop).\n */\nexport function isBatching(): boolean {\n\treturn batchDepth > 0 || flushInProgress;\n}\n\n/**\n * Runs `fn` inside a batch scope. Nested `batch()` calls share one deferral\n * queue. If `fn` throws, deferred work for the outer frame is discarded\n * (unless a drain is already in progress — cross-language decision A4).\n */\nexport function batch(fn: () => void): void {\n\tbatchDepth += 1;\n\tlet threw = false;\n\ttry {\n\t\tfn();\n\t} catch (e) {\n\t\tthrew = true;\n\t\tthrow e;\n\t} finally {\n\t\tbatchDepth -= 1;\n\t\tif (batchDepth === 0) {\n\t\t\tif (threw) {\n\t\t\t\tif (!flushInProgress) {\n\t\t\t\t\tdrainPhase2.length = 0;\n\t\t\t\t\tdrainPhase3.length = 0;\n\t\t\t\t\tdrainPhase4.length = 0;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdrainPending();\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction drainPending(): void {\n\tconst ownsFlush = !flushInProgress;\n\tif (ownsFlush) flushInProgress = true;\n\n\tconst errors: unknown[] = [];\n\tlet iterations = 0;\n\ttry {\n\t\twhile (drainPhase2.length > 0 || drainPhase3.length > 0 || drainPhase4.length > 0) {\n\t\t\titerations += 1;\n\t\t\tif (iterations > MAX_DRAIN_ITERATIONS) {\n\t\t\t\tdrainPhase2.length = 0;\n\t\t\t\tdrainPhase3.length = 0;\n\t\t\t\tdrainPhase4.length = 0;\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`batch drain exceeded ${MAX_DRAIN_ITERATIONS} iterations — likely a reactive cycle`,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Always drain the lowest non-empty phase. Re-enqueues at any level\n\t\t\t// cause the next iteration to restart from phase 2 if needed.\n\t\t\tconst queue =\n\t\t\t\tdrainPhase2.length > 0 ? drainPhase2 : drainPhase3.length > 0 ? drainPhase3 : drainPhase4;\n\t\t\tconst ops = queue.splice(0);\n\t\t\tfor (const run of ops) {\n\t\t\t\ttry {\n\t\t\t\t\trun();\n\t\t\t\t} catch (e) {\n\t\t\t\t\terrors.push(e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tif (ownsFlush) flushInProgress = false;\n\t}\n\n\tif (errors.length === 1) throw errors[0];\n\tif (errors.length > 1) {\n\t\tthrow new AggregateError(errors, \"batch drain: multiple callbacks threw\");\n\t}\n}\n\n/**\n * Deliver pre-sorted messages through `sink` with tier-based deferral applied.\n *\n * `messages` MUST be in ascending tier order (produced by `_frameBatch` in\n * `node.ts`); the walker exploits that invariant to find phase cuts in one\n * pass without re-sorting.\n *\n * Behavior:\n * - Tier 0–2 — delivered synchronously.\n * - Tier 3 — deferred to {@link drainPhase2} when batching, else synchronous.\n * - Tier 4 — deferred to {@link drainPhase3} when batching, else synchronous.\n * - Tier 5 — deferred to {@link drainPhase4} when batching, else synchronous.\n *\n * Tier-classification uses the caller-supplied `tierOf` so that batch stays\n * decoupled from `GraphReFlyConfig`. NodeImpl passes `config.tierOf` (a\n * pre-bound closure built once in the config constructor) at the emit site;\n * alternate configs can pass their own lookup.\n */\nexport function downWithBatch(\n\tsink: (messages: Messages) => void,\n\tmessages: Messages,\n\ttierOf: (t: symbol) => number,\n): void {\n\tif (messages.length === 0) return;\n\n\t// Fast path: single message (hot in propagation).\n\tif (messages.length === 1) {\n\t\tconst tier = tierOf(messages[0][0]);\n\t\tif (tier < 3 || !isBatching()) {\n\t\t\tsink(messages);\n\t\t\treturn;\n\t\t}\n\t\tconst queue = tier >= 5 ? drainPhase4 : tier === 4 ? drainPhase3 : drainPhase2;\n\t\tqueue.push(() => sink(messages));\n\t\treturn;\n\t}\n\n\t// Multi-message: walk once over pre-sorted input, find phase cuts.\n\t// Monotone tier order means `phase2Start <= phase3Start <= phase4Start`.\n\tconst n = messages.length;\n\tlet phase2Start = n;\n\tlet phase3Start = n;\n\tlet phase4Start = n;\n\n\tlet i = 0;\n\twhile (i < n && tierOf(messages[i][0]) < 3) i++;\n\tphase2Start = i;\n\twhile (i < n && tierOf(messages[i][0]) === 3) i++;\n\tphase3Start = i;\n\twhile (i < n && tierOf(messages[i][0]) === 4) i++;\n\tphase4Start = i;\n\t// Anything from phase4Start..n has tier >= 5.\n\n\tconst batching = isBatching();\n\n\tif (phase2Start > 0) {\n\t\t// Immediate tier 0–2 region.\n\t\tconst immediate = messages.slice(0, phase2Start);\n\t\tsink(immediate);\n\t}\n\n\tif (phase3Start > phase2Start) {\n\t\tconst phase2 = messages.slice(phase2Start, phase3Start);\n\t\tif (batching) drainPhase2.push(() => sink(phase2));\n\t\telse sink(phase2);\n\t}\n\n\tif (phase4Start > phase3Start) {\n\t\tconst phase3 = messages.slice(phase3Start, phase4Start);\n\t\tif (batching) drainPhase3.push(() => sink(phase3));\n\t\telse sink(phase3);\n\t}\n\n\tif (n > phase4Start) {\n\t\tconst phase4 = messages.slice(phase4Start, n);\n\t\tif (batching) drainPhase4.push(() => sink(phase4));\n\t\telse sink(phase4);\n\t}\n}\n","/**\n * Centralised timestamp utilities.\n *\n * Convention: all graphrefly-ts timestamps use nanoseconds (`_ns` suffix).\n *\n * - {@link monotonicNs} — monotonic clock (ordering, durations, timeline events).\n * - {@link wallClockNs} — wall-clock (mutation attribution, cron emission).\n *\n * **Precision limits (JS platform):**\n *\n * - `monotonicNs`: effective ~microsecond precision. `performance.now()` returns\n * milliseconds with ~5µs resolution; the last 3 digits of the nanosecond value\n * are always zero. Python's `time.monotonic_ns()` gives true nanoseconds.\n *\n * - `wallClockNs`: ~256ns precision loss at current epoch. `Date.now() * 1e6`\n * produces values around 1.8×10¹⁸ which exceed IEEE 754's 2⁵³ safe integer\n * limit. Python's `time.time_ns()` (arbitrary-precision `int`) has no loss.\n * In practice this is irrelevant — JS is single-threaded, so sub-microsecond\n * timestamp collisions cannot occur.\n */\n\n/** Monotonic nanosecond timestamp via `performance.now()`. */\nexport function monotonicNs(): number {\n\treturn Math.trunc(performance.now() * 1_000_000);\n}\n\n/** Wall-clock nanosecond timestamp via `Date.now()`. */\nexport function wallClockNs(): number {\n\treturn Date.now() * 1_000_000;\n}\n","/**\n * GraphReFly message protocol — §1 `~/src/graphrefly/GRAPHREFLY-SPEC.md`.\n * Emissions are always `[[Type, Data?], ...]` (no single-tuple shorthand).\n *\n * This file is protocol-pure:\n * - Message type symbols (10 built-ins).\n * - `Message` / `Messages` tuple types.\n * - `MessageTypeRegistration` interface (shape of a registry entry).\n *\n * It does NOT own the registry, tier lookups, or any cross-cutting singleton\n * state — that lives in `GraphReFlyConfig` (see `config.ts`) so custom\n * protocols can build isolated instances. Import this module when you need\n * the symbol constants or the tuple types; import `config.ts` when you need\n * tier / wire-crossing / registry lookups.\n */\n\n/** Subscribe-time handshake. Delivered to each new sink at the top of `subscribe()`. Tier 0. */\nexport const START = Symbol.for(\"graphrefly/START\");\n/** Value delivery (`DATA`, value). Tier 3 — deferred inside `batch()`. */\nexport const DATA = Symbol.for(\"graphrefly/DATA\");\n/** Phase 1: value about to change. Tier 1 — immediate. */\nexport const DIRTY = Symbol.for(\"graphrefly/DIRTY\");\n/** Phase 2: dirty pass completed, value unchanged. Tier 3 — deferred inside `batch()`. */\nexport const RESOLVED = Symbol.for(\"graphrefly/RESOLVED\");\n/** Clear cached state; do not auto-emit. Tier 1 — immediate. */\nexport const INVALIDATE = Symbol.for(\"graphrefly/INVALIDATE\");\n/** Suspend activity. Tier 2 — immediate. */\nexport const PAUSE = Symbol.for(\"graphrefly/PAUSE\");\n/** Resume after pause. Tier 2 — immediate. */\nexport const RESUME = Symbol.for(\"graphrefly/RESUME\");\n/** Permanent cleanup. Tier 5 — deferred to batch phase 4. */\nexport const TEARDOWN = Symbol.for(\"graphrefly/TEARDOWN\");\n/** Clean termination. Tier 4 — deferred to batch phase 3. */\nexport const COMPLETE = Symbol.for(\"graphrefly/COMPLETE\");\n/** Error termination. Tier 4 — deferred to batch phase 3. */\nexport const ERROR = Symbol.for(\"graphrefly/ERROR\");\n\n/** One protocol tuple: `[Type, optional payload]`. */\nexport type Message = readonly [symbol, unknown?];\n\n/** A batch of tuples — the wire shape for `node.down()` / `node.up()`. */\nexport type Messages = readonly Message[];\n\n// ---------------------------------------------------------------------------\n// Interned singletons for payload-free tuples\n// ---------------------------------------------------------------------------\n//\n// Every emission path used to allocate fresh `[[DIRTY]]`, `[[RESOLVED]]`,\n// etc. — two arrays per emit in the hot path. Since none of these tuples\n// carry a payload, one frozen instance is indistinguishable from a\n// fresh one. We intern them at module load and reuse forever. Only\n// `[DATA, v]`, `[ERROR, e]`, `[PAUSE, lockId]`, `[RESUME, lockId]` still\n// allocate per-call because they carry payloads.\n//\n// Downstream code MUST treat these as immutable. `Object.freeze` makes\n// accidental mutation throw in strict mode. Do not `push`, splice, or\n// otherwise mutate a Messages array that came from one of these.\n\n/** Singleton `[DIRTY]` tuple — payload-free, interned. */\nexport const DIRTY_MSG: Message = Object.freeze([DIRTY]) as Message;\n/** Singleton `[RESOLVED]` tuple — payload-free, interned. */\nexport const RESOLVED_MSG: Message = Object.freeze([RESOLVED]) as Message;\n/** Singleton `[INVALIDATE]` tuple — payload-free, interned. */\nexport const INVALIDATE_MSG: Message = Object.freeze([INVALIDATE]) as Message;\n/** Singleton `[START]` tuple — payload-free, interned. */\nexport const START_MSG: Message = Object.freeze([START]) as Message;\n/** Singleton `[COMPLETE]` tuple — payload-free, interned. */\nexport const COMPLETE_MSG: Message = Object.freeze([COMPLETE]) as Message;\n/** Singleton `[TEARDOWN]` tuple — payload-free, interned. */\nexport const TEARDOWN_MSG: Message = Object.freeze([TEARDOWN]) as Message;\n\n/** Pre-wrapped `[[DIRTY]]` for `_emit([DIRTY_ONLY_BATCH])`-style callers. */\nexport const DIRTY_ONLY_BATCH: Messages = Object.freeze([DIRTY_MSG]) as Messages;\n/** Pre-wrapped `[[RESOLVED]]`. */\nexport const RESOLVED_ONLY_BATCH: Messages = Object.freeze([RESOLVED_MSG]) as Messages;\n/** Pre-wrapped `[[INVALIDATE]]`. */\nexport const INVALIDATE_ONLY_BATCH: Messages = Object.freeze([INVALIDATE_MSG]) as Messages;\n/** Pre-wrapped `[[COMPLETE]]`. */\nexport const COMPLETE_ONLY_BATCH: Messages = Object.freeze([COMPLETE_MSG]) as Messages;\n/** Pre-wrapped `[[TEARDOWN]]`. */\nexport const TEARDOWN_ONLY_BATCH: Messages = Object.freeze([TEARDOWN_MSG]) as Messages;\n\n// ---------------------------------------------------------------------------\n// Registry entry shape\n// ---------------------------------------------------------------------------\n\n/**\n * Per-type record stored in a {@link GraphReFlyConfig}'s registry.\n *\n * - `tier` — signal tier (0–5 built-in; custom tiers allowed but should fit\n * the phase model used by `batch.ts`).\n * - `wireCrossing` — when `true`, forwarded across SSE/WebSocket/worker\n * adapters. Defaults to `tier >= 3` if omitted in registration input.\n * - `metaPassthrough` — when `false`, this message type is filtered out of\n * `Graph.signal` deliveries to meta companion nodes (spec §2.3). Meta\n * companions still receive everything via their primary's own cascade.\n * Defaults to `true` (meta receives the message).\n */\nexport interface MessageTypeRegistration {\n\ttier: number;\n\twireCrossing: boolean;\n\tmetaPassthrough: boolean;\n}\n\n/**\n * Input accepted by {@link GraphReFlyConfig.registerMessageType}. Only `tier`\n * is required; `wireCrossing` defaults to `tier >= 3`; `metaPassthrough`\n * defaults to `true`.\n */\nexport interface MessageTypeRegistrationInput {\n\ttier: number;\n\twireCrossing?: boolean;\n\tmetaPassthrough?: boolean;\n}\n","/**\n * GraphCodec — pluggable serialization for graph snapshots (Phase 8.6).\n *\n * Design reference: `archive/docs/SESSION-serialization-memory-footprint.md`\n *\n * The codec interface decouples snapshot format from graph internals.\n * Default is JSON (current behavior). DAG-CBOR and compressed variants\n * ship as optional codecs. FlatBuffers/Arrow for advanced tiers.\n *\n * Tiered representation:\n * HOT — JS objects (live propagation, no codec involved)\n * WARM — DAG-CBOR in-memory buffer (lazy hydration, delta checkpoints)\n * COLD — Arrow/Parquet (bulk storage, ML pipelines, archival)\n * PEEK — FlatBuffers (zero-copy read from dormant graph)\n *\n * Wire-protocol envelope (v1):\n *\n * [envelope_v=1: u8][name_len: u8][name: utf8][codec_v: u16 BE][payload: rest]\n *\n * `graph.snapshot({format: \"bytes\", codec: name})` wraps the codec's\n * `encode` output in this envelope; `Graph.decode(bytes)` auto-dispatches\n * via the config's codec registry — no out-of-band content-type needed.\n */\n\nimport type { GraphReFlyConfig } from \"../core/config.js\";\nimport type { GraphCheckpointRecord, GraphPersistSnapshot } from \"./graph.js\";\n\n// ---------------------------------------------------------------------------\n// Core codec interface\n// ---------------------------------------------------------------------------\n\n/**\n * Encode/decode graph snapshots to/from binary.\n *\n * Implementations must be deterministic: `encode(x)` always produces the\n * same bytes for the same input. This is critical for CID computation (V1)\n * and snapshot hash-comparison.\n */\nexport interface GraphCodec {\n\t/** Human-readable name; used as the lookup key in the envelope and config registry. */\n\treadonly name: string;\n\n\t/**\n\t * Codec version. Bumps on breaking wire format changes; `decode` receives\n\t * this via the envelope so codecs can dispatch on historical layouts.\n\t * Must fit in a `u16` (0–65535).\n\t */\n\treadonly version: number;\n\n\t/** MIME-like content type identifier (e.g. `\"application/dag-cbor+zstd\"`). */\n\treadonly contentType: string;\n\n\t/** Encode a snapshot to binary. */\n\tencode(snapshot: GraphPersistSnapshot): Uint8Array;\n\n\t/**\n\t * Decode binary back to a snapshot.\n\t *\n\t * `codecVersion` is the version that produced `buffer` (read from the\n\t * envelope). Omit when the caller is sure of the version (tests, one-shot\n\t * round-trips). Codecs that support multiple historical layouts dispatch\n\t * on this value.\n\t *\n\t * For lazy codecs, this may return a proxy that decodes nodes on access\n\t * (see {@link LazyGraphCodec}).\n\t */\n\tdecode(buffer: Uint8Array, codecVersion?: number): GraphPersistSnapshot;\n}\n\n/**\n * Extended codec that supports lazy (on-demand) node decoding.\n *\n * `decodeLazy` returns a snapshot where `nodes` is a Proxy — individual\n * nodes are decoded only when accessed. This enables near-zero cold-start\n * for large graphs (decode envelope + topology, skip node values until read).\n */\nexport interface LazyGraphCodec extends GraphCodec {\n\t/** Decode envelope and topology; defer node value decoding to access time. */\n\tdecodeLazy(buffer: Uint8Array, codecVersion?: number): GraphPersistSnapshot;\n}\n\n// ---------------------------------------------------------------------------\n// Delta checkpoint types (requires V0 — Phase 6.0)\n// ---------------------------------------------------------------------------\n\n/**\n * WAL entry. Unified with {@link GraphCheckpointRecord} — every record\n * already carries `mode` / `seq` / `timestamp_ns` / `format_version`, so the\n * WAL is just an ordered list of records. `replayWAL` walks this list.\n */\nexport type WALEntry = GraphCheckpointRecord;\n\n// ---------------------------------------------------------------------------\n// Eviction policy (dormant subgraph management)\n// ---------------------------------------------------------------------------\n\n/**\n * Policy for evicting dormant subgraphs to reduce memory.\n *\n * When a subgraph hasn't propagated for `idleTimeoutMs`, it is serialized\n * using the graph's codec and JS objects are released. Re-hydrated on next\n * access (read, propagation, describe).\n */\nexport interface EvictionPolicy {\n\t/** Milliseconds of inactivity before eviction. */\n\tidleTimeoutMs: number;\n\t/** Codec to use for serializing evicted subgraphs (default: graph's codec). */\n\tcodec?: GraphCodec;\n}\n\n/** Metadata about an evicted subgraph, exposed via describe(). */\nexport interface EvictedSubgraphInfo {\n\t/** True if currently evicted (serialized, JS objects released). */\n\tevicted: true;\n\t/** Wall-clock ns of last propagation before eviction. */\n\tlastActiveNs: bigint;\n\t/** Size of serialized buffer in bytes. */\n\tserializedBytes: number;\n\t/** Codec used for serialization. */\n\tcodecName: string;\n}\n\n// ---------------------------------------------------------------------------\n// JSON codec (default — wraps current behavior)\n// ---------------------------------------------------------------------------\n\n/**\n * Default JSON codec. Wraps `JSON.stringify`/`JSON.parse` with deterministic\n * key ordering (matching current `snapshot()` behavior).\n */\nexport const JsonCodec: GraphCodec = {\n\tname: \"json\",\n\tversion: 1,\n\tcontentType: \"application/json\",\n\n\tencode(snapshot: GraphPersistSnapshot): Uint8Array {\n\t\t// Deterministic: snapshot() already sorts keys.\n\t\tconst json = JSON.stringify(snapshot);\n\t\treturn new TextEncoder().encode(json);\n\t},\n\n\tdecode(buffer: Uint8Array, _codecVersion?: number): GraphPersistSnapshot {\n\t\tconst json = new TextDecoder().decode(buffer);\n\t\treturn JSON.parse(json) as GraphPersistSnapshot;\n\t},\n};\n\n// ---------------------------------------------------------------------------\n// DAG-CBOR codec (factory — requires @ipld/dag-cbor DI)\n// ---------------------------------------------------------------------------\n\n/**\n * Create a DAG-CBOR codec.\n *\n * Requires `@ipld/dag-cbor` as a peer dependency. ~40-50% smaller than JSON,\n * deterministic encoding (required for V1 CID), CID links as native type.\n *\n * @example\n * ```ts\n * import * as dagCbor from \"@ipld/dag-cbor\";\n * const codec = createDagCborCodec(dagCbor);\n * config.registerCodec(codec);\n * const bytes = graph.snapshot({ format: \"bytes\", codec: \"dag-cbor\" });\n * ```\n */\nexport function createDagCborCodec(dagCbor: {\n\tencode: (value: unknown) => Uint8Array;\n\tdecode: (bytes: Uint8Array) => unknown;\n}): GraphCodec {\n\treturn {\n\t\tname: \"dag-cbor\",\n\t\tversion: 1,\n\t\tcontentType: \"application/dag-cbor\",\n\t\tencode: (snapshot) => dagCbor.encode(snapshot),\n\t\tdecode: (buffer, _codecVersion) => dagCbor.decode(buffer) as GraphPersistSnapshot,\n\t};\n}\n\n/**\n * Create a DAG-CBOR + zstd codec. ~80-90% smaller than JSON.\n *\n * Requires `@ipld/dag-cbor` and a zstd implementation (e.g. `fzstd` for\n * browser, `node:zlib` for Node.js).\n *\n * @example\n * ```ts\n * import * as dagCbor from \"@ipld/dag-cbor\";\n * import { compressSync, decompressSync } from \"fzstd\";\n * const codec = createDagCborZstdCodec(dagCbor, { compressSync, decompressSync });\n * config.registerCodec(codec);\n * ```\n */\nexport function createDagCborZstdCodec(\n\tdagCbor: {\n\t\tencode: (value: unknown) => Uint8Array;\n\t\tdecode: (bytes: Uint8Array) => unknown;\n\t},\n\tzstd: {\n\t\tcompressSync: (data: Uint8Array) => Uint8Array;\n\t\tdecompressSync: (data: Uint8Array) => Uint8Array;\n\t},\n): GraphCodec {\n\treturn {\n\t\tname: \"dag-cbor-zstd\",\n\t\tversion: 1,\n\t\tcontentType: \"application/dag-cbor+zstd\",\n\t\tencode: (snapshot) => zstd.compressSync(dagCbor.encode(snapshot)),\n\t\tdecode: (buffer, _codecVersion) =>\n\t\t\tdagCbor.decode(zstd.decompressSync(buffer)) as GraphPersistSnapshot,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Envelope (v1) — self-describing codec metadata prepended to payload bytes\n// ---------------------------------------------------------------------------\n\n/** Current envelope format version. Bump on breaking layout changes. */\nexport const ENVELOPE_VERSION = 1;\n\nconst ENVELOPE_MIN_LEN = 4; // env_v(1) + name_len(1) + codec_v(2) + name/payload(≥0)\n\n/**\n * Prepend the v1 envelope to `payload` identifying `codec`. The resulting\n * bytes are self-describing — any caller with access to the registering\n * {@link GraphReFlyConfig} can {@link decodeEnvelope} without knowing the\n * codec up front.\n *\n * Layout:\n * `[envelope_v=1: u8][name_len: u8][name: utf8][codec_v: u16 BE][payload: rest]`\n *\n * @throws If `codec.name` encodes to more than 255 UTF-8 bytes or\n * `codec.version` doesn't fit in a u16.\n */\nexport function encodeEnvelope(\n\tcodec: Pick<GraphCodec, \"name\" | \"version\">,\n\tpayload: Uint8Array,\n): Uint8Array {\n\tconst nameBytes = new TextEncoder().encode(codec.name);\n\tif (nameBytes.length === 0 || nameBytes.length > 255) {\n\t\tthrow new Error(\n\t\t\t`encodeEnvelope: codec name \"${codec.name}\" encodes to ${nameBytes.length} bytes (must be 1–255)`,\n\t\t);\n\t}\n\tconst cv = codec.version;\n\tif (!Number.isInteger(cv) || cv < 0 || cv > 0xffff) {\n\t\tthrow new Error(\n\t\t\t`encodeEnvelope: codec.version ${cv} out of u16 range (expected integer 0–65535)`,\n\t\t);\n\t}\n\t// Guard against RangeError-on-alloc for very large payloads — we need\n\t// `Number.isSafeInteger` math on `1 + 1 + nameBytes.length + 2 +\n\t// payload.length` and the resulting Uint8Array must fit within the\n\t// platform limit (2³² − 1 bytes on 64-bit JS engines).\n\tconst totalLen = 1 + 1 + nameBytes.length + 2 + payload.length;\n\tif (totalLen > 0xffffffff) {\n\t\tthrow new Error(\n\t\t\t`encodeEnvelope: total envelope size ${totalLen} exceeds 2^32-1 bytes (payload ${payload.length} bytes)`,\n\t\t);\n\t}\n\tconst out = new Uint8Array(totalLen);\n\tlet i = 0;\n\tout[i++] = ENVELOPE_VERSION;\n\tout[i++] = nameBytes.length;\n\tout.set(nameBytes, i);\n\ti += nameBytes.length;\n\tout[i++] = (cv >>> 8) & 0xff;\n\tout[i++] = cv & 0xff;\n\tout.set(payload, i);\n\treturn out;\n}\n\n/**\n * Inverse of {@link encodeEnvelope}. Reads the header, resolves the codec\n * via `config.lookupCodec(name)`, and returns the codec + its version + the\n * inner payload slice. The caller feeds `payload` to `codec.decode(payload,\n * codecVersion)` — or uses {@link Graph.decode} which does both steps.\n *\n * @throws If the envelope is truncated, the version is unsupported, or the\n * named codec isn't registered on `config`.\n */\nexport function decodeEnvelope(\n\tbytes: Uint8Array,\n\tconfig: GraphReFlyConfig,\n): { codec: GraphCodec; codecVersion: number; payload: Uint8Array } {\n\tif (bytes.length < ENVELOPE_MIN_LEN) {\n\t\tthrow new Error(`decodeEnvelope: bytes too short (${bytes.length} < ${ENVELOPE_MIN_LEN})`);\n\t}\n\tlet i = 0;\n\tconst envVersion = bytes[i++]!;\n\tif (envVersion !== ENVELOPE_VERSION) {\n\t\tthrow new Error(\n\t\t\t`decodeEnvelope: unsupported envelope version ${envVersion} (expected ${ENVELOPE_VERSION})`,\n\t\t);\n\t}\n\tconst nameLen = bytes[i++]!;\n\tif (nameLen === 0) {\n\t\tthrow new Error(\"decodeEnvelope: name_len must be >= 1\");\n\t}\n\tif (i + nameLen + 2 > bytes.length) {\n\t\tthrow new Error(\n\t\t\t`decodeEnvelope: envelope truncated (need ${i + nameLen + 2} bytes, have ${bytes.length})`,\n\t\t);\n\t}\n\tconst name = new TextDecoder().decode(bytes.subarray(i, i + nameLen));\n\ti += nameLen;\n\tconst codecVersion = ((bytes[i]! << 8) | bytes[i + 1]!) >>> 0;\n\ti += 2;\n\tconst payload = bytes.subarray(i);\n\tconst codec = config.lookupCodec<GraphCodec>(name);\n\tif (codec == null) {\n\t\tthrow new Error(\n\t\t\t`decodeEnvelope: codec \"${name}\" not registered (envelope codec_v=${codecVersion})`,\n\t\t);\n\t}\n\treturn { codec, codecVersion, payload };\n}\n\n/**\n * Register the built-in {@link JsonCodec} on a config. Called once on\n * `defaultConfig` at module load so `graph.snapshot({format: \"bytes\", codec:\n * \"json\"})` works out of the box. Test / isolated configs should call this\n * manually before the first node is created.\n */\nexport function registerBuiltinCodecs(config: GraphReFlyConfig): void {\n\tconfig.registerCodec(JsonCodec);\n}\n\n// ---------------------------------------------------------------------------\n// WAL helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Reconstruct a snapshot from a WAL (sequence of {@link GraphCheckpointRecord}s).\n *\n * - Must start with a `\"full\"` record carrying a baseline snapshot — that's\n * the anchor {@link Graph.attachStorage} always emits on the first flush\n * of any tier (and every `compactEvery`-th flush thereafter).\n * - Subsequent `\"full\"` entries (compaction points) **replace** the result\n * wholesale.\n * - `\"diff\"` entries roll forward by applying the structural diff —\n * added nodes (via `nodesAddedFull`), removed nodes, and changed fields\n * are reflected into the accumulated snapshot.\n *\n * Validates monotonic `seq` progression across entries.\n */\nexport function replayWAL(entries: readonly WALEntry[]): GraphPersistSnapshot {\n\tif (entries.length === 0) {\n\t\tthrow new Error(\"WAL is empty — need at least one full snapshot\");\n\t}\n\n\tconst first = entries[0]!;\n\tif (first.mode !== \"full\") {\n\t\tthrow new Error(\"WAL must start with a full record carrying a baseline snapshot\");\n\t}\n\n\tlet result: GraphPersistSnapshot = JSON.parse(JSON.stringify(first.snapshot));\n\tlet prevSeq: number = first.seq;\n\n\tfor (let i = 1; i < entries.length; i++) {\n\t\tconst entry = entries[i]!;\n\t\tif (entry.seq <= prevSeq) {\n\t\t\tthrow new Error(\n\t\t\t\t`WAL chain broken at index ${i}: seq=${entry.seq} must exceed prev seq=${prevSeq}`,\n\t\t\t);\n\t\t}\n\n\t\tif (entry.mode === \"full\") {\n\t\t\t// Replace baseline wholesale (Unit 23 D fix — Object.assign left\n\t\t\t// stale keys from pre-compact state visible).\n\t\t\tresult = JSON.parse(JSON.stringify(entry.snapshot));\n\t\t\tprevSeq = entry.seq;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// mode === \"diff\": apply structural diff to the accumulated snapshot.\n\t\tconst diff = entry.diff;\n\t\t// Apply removes first so a path reused across a remove+add in a single\n\t\t// diff lands on the `nodesAddedFull` slice rather than being wiped.\n\t\tfor (const path of diff.nodesRemoved) {\n\t\t\tdelete result.nodes[path];\n\t\t}\n\t\t// Reinstate added nodes from the full-slice payload carried by\n\t\t// GraphWALDiff. Deep-clone so later mutations don't alias the WAL\n\t\t// entry's source slice.\n\t\tconst addedFull = diff.nodesAddedFull;\n\t\tif (addedFull != null) {\n\t\t\tfor (const [path, slice] of Object.entries(addedFull)) {\n\t\t\t\tresult.nodes[path] = JSON.parse(JSON.stringify(slice));\n\t\t\t}\n\t\t}\n\t\tfor (const change of diff.nodesChanged) {\n\t\t\tconst existing = result.nodes[change.path];\n\t\t\tif (existing == null) continue;\n\t\t\t(existing as Record<string, unknown>)[change.field] = change.to;\n\t\t}\n\n\t\t// Edges are derived from node `_deps` at restore time (Unit 7) — no\n\t\t// separate edge-patch pass.\n\t\tprevSeq = entry.seq;\n\t}\n\n\treturn result;\n}\n","/**\n * Who is performing an operation (attribution + ABAC input).\n *\n * @see GRAPHREFLY-SPEC — roadmap Phase 1.5 (Actor & Guard).\n */\nexport type Actor = {\n\ttype: \"human\" | \"llm\" | \"wallet\" | \"system\" | string;\n\tid: string;\n} & Record<string, unknown>;\n\n/** Default actor when none is passed ({@link normalizeActor}). */\nexport const DEFAULT_ACTOR: Actor = { type: \"system\", id: \"\" };\n\n/**\n * Fills missing `type` / `id` on an actor and returns {@link DEFAULT_ACTOR} when input is undefined.\n *\n * @param actor - Optional partial actor from a transport hint.\n * @returns A normalized `Actor` safe to pass to guards and graph APIs.\n *\n * @example\n * ```ts\n * import { normalizeActor } from \"@graphrefly/graphrefly-ts\";\n *\n * normalizeActor({ type: \"human\", id: \"u1\" });\n * ```\n */\nexport function normalizeActor(actor?: Actor): Actor {\n\tif (actor == null) return DEFAULT_ACTOR;\n\tconst { type, id, ...rest } = actor;\n\treturn {\n\t\ttype: type ?? \"system\",\n\t\tid: id ?? \"\",\n\t\t...rest,\n\t} as Actor;\n}\n","/**\n * Singleton protocol config. Holds the message-type registry, the\n * `onMessage` / `onSubscribe` hooks, versioning defaults, and the freeze flag.\n *\n * Layering: this file is protocol-pure. It imports only from `messages.ts`\n * and declares opaque type shapes for handlers — the concrete default\n * implementations and the `defaultConfig` instance live in `node.ts` so that\n * handler bodies can touch `NodeImpl` internals without creating a cycle.\n *\n * Two access paths:\n * 1. **Default instance** (`defaultConfig` in `node.ts`) — use\n * `configure((cfg) => ...)` at app startup; every node implicitly binds to it.\n * 2. **Isolated instance** (`new GraphReFlyConfig(...)`) — pass via\n * `opts.config` for test isolation or custom protocol stacks.\n *\n * A config **freezes on first getter read** of any hook (`onMessage`,\n * `onSubscribe`). `NodeImpl`'s constructor intentionally touches one of these\n * on first use so configuration cannot drift once nodes exist.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tINVALIDATE,\n\ttype Message,\n\ttype Messages,\n\ttype MessageTypeRegistration,\n\ttype MessageTypeRegistrationInput,\n\tPAUSE,\n\tRESOLVED,\n\tRESUME,\n\tSTART,\n\tTEARDOWN,\n} from \"./messages.js\";\nimport type { HashFn, VersioningLevel } from \"./versioning.js\";\n\n// ---------------------------------------------------------------------------\n// Handler type shapes\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal node surface visible to default handlers. Concrete `NodeImpl`\n * implements this plus a large set of package-private fields; handlers that\n * need the richer surface cast to the concrete type in `node.ts`.\n */\nexport interface NodeCtx {\n\treadonly name?: string;\n\treadonly status: string;\n\treadonly cache: unknown;\n}\n\n/** Imperative actions available inside a node's compute function (§5). */\nexport interface NodeActions {\n\t/**\n\t * Sugar for `down([[DATA, value]])`. One call = one wave with a\n\t * single DATA payload. The emit pipeline auto-prefixes `[DIRTY]`,\n\t * runs equals substitution against the live cache, and dispatches\n\t * to sinks with phase deferral. Diamond-safe by construction.\n\t */\n\temit(value: unknown): void;\n\t/**\n\t * Send one or more messages downstream. Accepts either a single\n\t * {@link Message} tuple or a {@link Messages} array of tuples. One\n\t * call = one wave: the emit pipeline tier-sorts the input,\n\t * auto-prefixes `[DIRTY]` when a tier-3 payload is present and the\n\t * node isn't already dirty, runs equals substitution, then\n\t * dispatches. Multiple calls produce multiple waves.\n\t */\n\tdown(messageOrMessages: Message | Messages): void;\n\t/**\n\t * Send one or more messages upstream. Accepts the same shapes as\n\t * {@link down}. Tier 3 (DATA/RESOLVED) and tier 4 (COMPLETE/ERROR)\n\t * are downstream-only and will throw — up is for DIRTY, INVALIDATE,\n\t * PAUSE, RESUME, and TEARDOWN only. No cache advance, no equals,\n\t * no framing — a plain forward to every dep.\n\t */\n\tup(messageOrMessages: Message | Messages): void;\n}\n\n/**\n * Message-flow context passed to {@link OnMessageHandler}.\n *\n * - `\"down-in\"` — message arriving from a dep (identified by `depIndex`).\n * - `\"up-in\"` — message arriving from a sink.\n */\nexport type MessageContext = { direction: \"down-in\"; depIndex: number } | { direction: \"up-in\" };\n\n/**\n * Per-sink context passed to {@link OnSubscribeHandler}.\n */\nexport interface SubscribeContext {\n\t/** Post-subscribe sink count. `1` means first subscriber after 0. */\n\tsinkCount: number;\n\t/** True when this subscribe cleared a resubscribable terminal state. */\n\tafterTerminalReset: boolean;\n}\n\n/**\n * Singleton message interceptor. Called for every message in either direction\n * before the default per-tier dispatch runs. Return `\"consume\"` to suppress\n * default handling.\n */\nexport type OnMessageHandler = (\n\tnode: NodeCtx,\n\tmsg: Message,\n\tctx: MessageContext,\n\tactions: NodeActions,\n) => \"consume\" | undefined;\n\n/**\n * Singleton subscribe ceremony. Fires for every sink subscribe on every node.\n * Default implementation emits the START handshake (+ cached DATA when\n * present) to the new sink. Return a cleanup function to run on unsubscribe.\n */\nexport type OnSubscribeHandler = (\n\tnode: NodeCtx,\n\tsink: (messages: Messages) => void,\n\tctx: SubscribeContext,\n\tactions: NodeActions,\n) => (() => void) | undefined;\n\n/**\n * Event payload for {@link GlobalInspectorHook}. One event fires per outgoing\n * message batch from any node bound to the config.\n *\n * - `kind: \"emit\"` — fires after equals substitution (`finalMessages`) and\n * before sink dispatch. `messages` is the exact batch sinks see.\n */\nexport type GlobalInspectorEvent = {\n\tkind: \"emit\";\n\tnode: NodeCtx;\n\tmessages: Messages;\n};\n\n/**\n * Process-global observability hook for full-graph tracing\n * (Redux-DevTools-style action history). Fires from every node's `_emit`\n * waist whenever {@link GraphReFlyConfig.inspectorEnabled} is `true`.\n *\n * Distinct from per-node `_setInspectorHook` (which is the dep-message /\n * fn-run causal trace used by `Graph.observe(path, { causal, derived })`).\n * Use the global hook to record every emission across every node — useful for\n * time-travel debuggers, tracers, and replay tooling. Use the per-node hook\n * to attribute a single subscribed path's wave to its driving deps.\n *\n * Errors thrown from the hook are swallowed — instrumentation must not break\n * the data plane.\n */\nexport type GlobalInspectorHook = (event: GlobalInspectorEvent) => void;\n\n// ---------------------------------------------------------------------------\n// GraphReFlyConfig\n// ---------------------------------------------------------------------------\n\n/**\n * Singleton protocol config.\n *\n * A config freezes on first getter read of any hook. After freeze, any\n * attempt to mutate (register a message type, set a hook) throws.\n */\nexport class GraphReFlyConfig {\n\tprivate _messageTypes = new Map<symbol, MessageTypeRegistration>();\n\tprivate _codecs = new Map<string, { readonly name: string; readonly version: number }>();\n\tprivate _onMessage: OnMessageHandler;\n\tprivate _onSubscribe: OnSubscribeHandler;\n\tprivate _defaultVersioning: VersioningLevel | undefined;\n\tprivate _defaultHashFn: HashFn | undefined;\n\tprivate _inspectorEnabled: boolean = !(\n\t\ttypeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\"\n\t);\n\tprivate _globalInspector?: GlobalInspectorHook;\n\tprivate _frozen = false;\n\n\t/**\n\t * Pre-bound tier lookup — shared by every node bound to this config. Since\n\t * the registry is frozen on first hook access, this closure can be built\n\t * once in the constructor and handed directly to `downWithBatch` /\n\t * `_frameBatch` paths without per-node or per-emission `.bind(config)`\n\t * allocation.\n\t */\n\treadonly tierOf: (t: symbol) => number;\n\n\tconstructor(init: {\n\t\tonMessage: OnMessageHandler;\n\t\tonSubscribe: OnSubscribeHandler;\n\t\tdefaultVersioning?: VersioningLevel;\n\t\tdefaultHashFn?: HashFn;\n\t}) {\n\t\tthis._onMessage = init.onMessage;\n\t\tthis._onSubscribe = init.onSubscribe;\n\t\tthis._defaultVersioning = init.defaultVersioning;\n\t\tthis._defaultHashFn = init.defaultHashFn;\n\t\t// Captured once. Calls back into `this._messageTypes` — still returns\n\t\t// the current registration, but post-freeze the registry is immutable\n\t\t// so the closure is effectively constant.\n\t\tthis.tierOf = (t: symbol): number => {\n\t\t\tconst reg = this._messageTypes.get(t);\n\t\t\treturn reg != null ? reg.tier : 1;\n\t\t};\n\t}\n\n\t// --- Hook getters (freeze on read) ---\n\n\tget onMessage(): OnMessageHandler {\n\t\tthis._frozen = true;\n\t\treturn this._onMessage;\n\t}\n\n\tget onSubscribe(): OnSubscribeHandler {\n\t\tthis._frozen = true;\n\t\treturn this._onSubscribe;\n\t}\n\n\t// --- Hook setters (throw when frozen) ---\n\n\tset onMessage(v: OnMessageHandler) {\n\t\tthis._assertUnfrozen();\n\t\tthis._onMessage = v;\n\t}\n\n\tset onSubscribe(v: OnSubscribeHandler) {\n\t\tthis._assertUnfrozen();\n\t\tthis._onSubscribe = v;\n\t}\n\n\t/**\n\t * Default versioning level applied to every node bound to this config,\n\t * unless the node's own `opts.versioning` provides an explicit override.\n\t * Setting this is only allowed before the config freezes (i.e., before\n\t * the first node is created) so every node in the graph sees a\n\t * consistent starting level. Individual nodes can still opt into a\n\t * higher level via `opts.versioning`, or post-hoc via\n\t * `NodeImpl._applyVersioning(level)` when the node is quiescent.\n\t *\n\t * v0 is the minimum opt-in — unversioned nodes (`undefined`) skip\n\t * the version counter entirely. v1 adds content-addressed cid.\n\t * Future levels (v2, v3) are reserved for linked-history and\n\t * cryptographic attestation extensions.\n\t */\n\tget defaultVersioning(): VersioningLevel | undefined {\n\t\treturn this._defaultVersioning;\n\t}\n\tset defaultVersioning(v: VersioningLevel | undefined) {\n\t\tthis._assertUnfrozen();\n\t\tthis._defaultVersioning = v;\n\t}\n\n\t/**\n\t * Default content-hash function applied to every versioned node bound\n\t * to this config, unless the node's own `opts.versioningHash` provides\n\t * an explicit override. Use this when a graph needs a non-default hash\n\t * — e.g., swap the vendored sync SHA-256 for a faster non-crypto hash\n\t * (xxHash, FNV-1a) in hot-path workloads, or a stronger hash when\n\t * versioning v1 cids are used as audit anchors.\n\t *\n\t * Only settable before the config freezes. Individual nodes can still\n\t * override via `opts.versioningHash`.\n\t */\n\tget defaultHashFn(): HashFn | undefined {\n\t\treturn this._defaultHashFn;\n\t}\n\tset defaultHashFn(v: HashFn | undefined) {\n\t\tthis._assertUnfrozen();\n\t\tthis._defaultHashFn = v;\n\t}\n\n\t/**\n\t * When `false`, structured observation options (`causal`, `timeline`)\n\t * and `Graph.trace()` writes are no-ops. Raw `Graph.observe()` always\n\t * works. Default: `true` outside production (`NODE_ENV !== \"production\"`).\n\t *\n\t * Settable at any time — inspector gating is an operational concern, not\n\t * a protocol invariant, so it does NOT require freeze before node creation.\n\t */\n\tget inspectorEnabled(): boolean {\n\t\treturn this._inspectorEnabled;\n\t}\n\tset inspectorEnabled(v: boolean) {\n\t\tthis._inspectorEnabled = v;\n\t}\n\n\t/**\n\t * Process-global observability hook (Redux-DevTools-style full-graph\n\t * tracer). Fires once per outgoing batch from every node bound to this\n\t * config, gated by {@link inspectorEnabled}. See {@link GlobalInspectorHook}.\n\t *\n\t * Settable at any time — like {@link inspectorEnabled} this is operational,\n\t * not protocol-shaping, so it does NOT trigger config freeze.\n\t */\n\tget globalInspector(): GlobalInspectorHook | undefined {\n\t\treturn this._globalInspector;\n\t}\n\tset globalInspector(v: GlobalInspectorHook | undefined) {\n\t\tthis._globalInspector = v;\n\t}\n\n\t// --- Registry (writes require unfrozen; reads are free lookups) ---\n\n\t/**\n\t * Register a custom message type. Must be called before any node that\n\t * uses this config has been created — otherwise throws. Default\n\t * `wireCrossing` is `tier >= 3`.\n\t */\n\tregisterMessageType(t: symbol, input: MessageTypeRegistrationInput): this {\n\t\tthis._assertUnfrozen();\n\t\tthis._messageTypes.set(t, {\n\t\t\ttier: input.tier,\n\t\t\twireCrossing: input.wireCrossing ?? input.tier >= 3,\n\t\t\tmetaPassthrough: input.metaPassthrough ?? true,\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** Tier for `t`. Unknown types default to tier 1 (immediate, after START). */\n\tmessageTier(t: symbol): number {\n\t\tconst reg = this._messageTypes.get(t);\n\t\treturn reg != null ? reg.tier : 1;\n\t}\n\n\t/**\n\t * Whether `t` is registered as wire-crossing. Unknown types default to\n\t * `true` (spec §1.3.6 forward-compat — unknowns cross the wire).\n\t */\n\tisWireCrossing(t: symbol): boolean {\n\t\tconst reg = this._messageTypes.get(t);\n\t\treturn reg != null ? reg.wireCrossing : true;\n\t}\n\n\t/** Convenience inverse of {@link isWireCrossing}. */\n\tisLocalOnly(t: symbol): boolean {\n\t\treturn !this.isWireCrossing(t);\n\t}\n\n\t/**\n\t * Whether `t` is forwarded to meta companions by `Graph.signal`. Defaults\n\t * to `true` for unknowns (forward-compat — new types pass through meta by\n\t * default; opt-in filter via `registerMessageType({metaPassthrough: false})`).\n\t */\n\tisMetaPassthrough(t: symbol): boolean {\n\t\tconst reg = this._messageTypes.get(t);\n\t\treturn reg != null ? reg.metaPassthrough : true;\n\t}\n\n\t/** Whether `t` is a registered (built-in or custom) type. */\n\tisKnownMessageType(t: symbol): boolean {\n\t\treturn this._messageTypes.has(t);\n\t}\n\n\t// --- Codec registry (writes require unfrozen; reads are free lookups) ---\n\n\t/**\n\t * Register a graph codec by `codec.name`. Used by the envelope-based\n\t * `graph.snapshot({format: \"bytes\", codec: name})` path and\n\t * `Graph.decode(bytes)` auto-dispatch. Must be called before any node\n\t * bound to this config is created — otherwise throws.\n\t *\n\t * Re-registering the same name overwrites, so user codecs can shadow\n\t * built-in ones before freeze (e.g., to swap a zstd-wrapped dag-cbor in\n\t * for `\"dag-cbor\"`).\n\t */\n\tregisterCodec<T extends { readonly name: string; readonly version: number }>(codec: T): this {\n\t\tthis._assertUnfrozen();\n\t\tthis._codecs.set(codec.name, codec);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resolve a registered codec by name. Returns `undefined` for unknown\n\t * names. Typed callers cast to their concrete codec interface (e.g.,\n\t * `config.lookupCodec<GraphCodec>(\"json\")`) — this method stays\n\t * layer-pure (no import of graph-layer types into `core/`).\n\t */\n\tlookupCodec<T = { readonly name: string; readonly version: number }>(\n\t\tname: string,\n\t): T | undefined {\n\t\treturn this._codecs.get(name) as T | undefined;\n\t}\n\n\t/** @internal Used by tests and dev tooling — check freeze state without triggering it. */\n\t_isFrozen(): boolean {\n\t\treturn this._frozen;\n\t}\n\n\tprivate _assertUnfrozen(): void {\n\t\tif (this._frozen) {\n\t\t\tthrow new Error(\n\t\t\t\t\"GraphReFlyConfig is frozen: a node has already captured this config. \" +\n\t\t\t\t\t\"Register custom types and set hooks before creating any node.\",\n\t\t\t);\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Built-in registration\n// ---------------------------------------------------------------------------\n\n/**\n * Register the 10 built-in message types on a fresh config. Called by\n * `node.ts` when it constructs `defaultConfig` and by test code / advanced\n * users after `new GraphReFlyConfig(...)`.\n */\nexport function registerBuiltins(cfg: GraphReFlyConfig): void {\n\tcfg.registerMessageType(START, { tier: 0, wireCrossing: false });\n\tcfg.registerMessageType(DIRTY, { tier: 1, wireCrossing: false });\n\t// INVALIDATE, COMPLETE, ERROR, TEARDOWN do NOT pass through to meta\n\t// companions via Graph.signal (spec §2.3). Meta still sees them via the\n\t// primary's own down-cascade.\n\tcfg.registerMessageType(INVALIDATE, {\n\t\ttier: 1,\n\t\twireCrossing: false,\n\t\tmetaPassthrough: false,\n\t});\n\tcfg.registerMessageType(PAUSE, { tier: 2, wireCrossing: false });\n\tcfg.registerMessageType(RESUME, { tier: 2, wireCrossing: false });\n\tcfg.registerMessageType(DATA, { tier: 3, wireCrossing: true });\n\tcfg.registerMessageType(RESOLVED, { tier: 3, wireCrossing: true });\n\tcfg.registerMessageType(COMPLETE, {\n\t\ttier: 4,\n\t\twireCrossing: true,\n\t\tmetaPassthrough: false,\n\t});\n\tcfg.registerMessageType(ERROR, {\n\t\ttier: 4,\n\t\twireCrossing: true,\n\t\tmetaPassthrough: false,\n\t});\n\tcfg.registerMessageType(TEARDOWN, {\n\t\ttier: 5,\n\t\twireCrossing: true,\n\t\tmetaPassthrough: false,\n\t});\n}\n","import type { Actor } from \"./actor.js\";\n\n/**\n * Actions checked by {@link NodeGuard}. `write` covers both {@link Node.down} and\n * {@link Node.up} today; finer-grained strings may be added later (e.g. `\"write.data\"`).\n */\nexport type GuardAction = \"write\" | \"signal\" | \"observe\" | (string & {});\n\nexport type NodeGuard = (actor: Actor, action: GuardAction) => boolean;\n\nexport type GuardDeniedDetails = {\n\tactor: Actor;\n\taction: GuardAction;\n\t/** Registry or options name when known */\n\tnodeName?: string;\n};\n\n/**\n * Thrown when a {@link NodeGuard} denies an action for a given actor.\n *\n * Carries the rejected `actor`, `action`, and optional `nodeName` for diagnostic\n * messages and middleware error handling.\n *\n * @example\n * ```ts\n * import { GuardDenied, policy } from \"@graphrefly/graphrefly-ts\";\n *\n * const guard = policy((allow) => { allow(\"observe\"); });\n * try {\n * if (!guard({ type: \"llm\", id: \"agent-1\" }, \"write\")) {\n * throw new GuardDenied(\n * { actor: { type: \"llm\", id: \"agent-1\" }, action: \"write\", nodeName: \"userInput\" },\n * );\n * }\n * } catch (e) {\n * if (e instanceof GuardDenied) console.error(e.action, e.actor.type); // \"write\" \"llm\"\n * }\n * ```\n */\nexport class GuardDenied extends Error {\n\treadonly actor: Actor;\n\treadonly action: GuardAction;\n\treadonly nodeName?: string;\n\n\t/**\n\t * @param details - Actor, action, and optional node name for the denial.\n\t * @param message - Optional override for the default error message.\n\t */\n\tconstructor(details: GuardDeniedDetails, message?: string) {\n\t\tsuper(\n\t\t\tmessage ??\n\t\t\t\t`GuardDenied: action \"${String(details.action)}\" denied for actor type \"${String(details.actor.type)}\"`,\n\t\t);\n\t\tthis.name = \"GuardDenied\";\n\t\tthis.actor = details.actor;\n\t\tthis.action = details.action;\n\t\tthis.nodeName = details.nodeName;\n\t}\n\n\t/** Qualified registry path when known (roadmap diagnostics: same as {@link nodeName}). */\n\tget node(): string | undefined {\n\t\treturn this.nodeName;\n\t}\n}\n\ntype Where = (actor: Actor) => boolean;\n\ntype Rule = {\n\tkind: \"allow\" | \"deny\";\n\tactions: Set<GuardAction>;\n\twhere: Where;\n};\n\nfunction normalizeActions(action: GuardAction | readonly GuardAction[]): GuardAction[] {\n\tif (Array.isArray(action)) {\n\t\treturn [...action];\n\t}\n\treturn [action as GuardAction];\n}\n\nfunction matchesActions(set: Set<GuardAction>, action: GuardAction): boolean {\n\treturn set.has(action) || set.has(\"*\" as GuardAction);\n}\n\nexport type PolicyAllow = (\n\taction: GuardAction | readonly GuardAction[],\n\topts?: { where?: Where },\n) => void;\n\nexport type PolicyDeny = (\n\taction: GuardAction | readonly GuardAction[],\n\topts?: { where?: Where },\n) => void;\n\nexport type PolicyRuleData = {\n\teffect: \"allow\" | \"deny\";\n\taction: GuardAction | readonly GuardAction[];\n\tactorType?: string | readonly string[];\n\tactorId?: string | readonly string[];\n\tclaims?: Record<string, unknown>;\n};\n\n/**\n * Declarative guard builder. Precedence: any matching **deny** blocks even if an allow also matches.\n * If no rule matches, the guard returns `false` (deny-by-default). Aligned with graphrefly-py `policy()`.\n *\n * @param build - Callback that registers `allow(...)` / `deny(...)` rules in order.\n * @returns A `NodeGuard` for use as `node({ guard })`.\n *\n * @example\n * ```ts\n * const guard = policy((allow, deny) => {\n * allow(\"observe\");\n * deny(\"write\", { where: (a) => a.type === \"llm\" });\n * });\n * ```\n */\nexport function policy(build: (allow: PolicyAllow, deny: PolicyDeny) => void): NodeGuard {\n\tconst rules: Rule[] = [];\n\tconst allow: PolicyAllow = (action, opts) => {\n\t\trules.push({\n\t\t\tkind: \"allow\",\n\t\t\tactions: new Set(normalizeActions(action)),\n\t\t\twhere: opts?.where ?? (() => true),\n\t\t});\n\t};\n\tconst deny: PolicyDeny = (action, opts) => {\n\t\trules.push({\n\t\t\tkind: \"deny\",\n\t\t\tactions: new Set(normalizeActions(action)),\n\t\t\twhere: opts?.where ?? (() => true),\n\t\t});\n\t};\n\tbuild(allow, deny);\n\treturn (actor, action) => {\n\t\tlet denied = false;\n\t\tlet allowed = false;\n\t\tfor (const r of rules) {\n\t\t\tif (!matchesActions(r.actions, action)) continue;\n\t\t\tif (!r.where(actor)) continue;\n\t\t\tif (r.kind === \"deny\") {\n\t\t\t\tdenied = true;\n\t\t\t} else {\n\t\t\t\tallowed = true;\n\t\t\t}\n\t\t}\n\t\tif (denied) return false;\n\t\treturn allowed;\n\t};\n}\n\n/**\n * Rebuild a declarative guard from persisted policy data (snapshot-safe).\n *\n * Rules are deny-overrides, same semantics as {@link policy}.\n */\nexport function policyFromRules(rules: readonly PolicyRuleData[]): NodeGuard {\n\treturn policy((allow, deny) => {\n\t\tfor (const rule of rules) {\n\t\t\tconst actorTypes =\n\t\t\t\trule.actorType == null\n\t\t\t\t\t? null\n\t\t\t\t\t: new Set(Array.isArray(rule.actorType) ? rule.actorType : [rule.actorType]);\n\t\t\tconst actorIds =\n\t\t\t\trule.actorId == null\n\t\t\t\t\t? null\n\t\t\t\t\t: new Set(Array.isArray(rule.actorId) ? rule.actorId : [rule.actorId]);\n\t\t\tconst claimEntries = Object.entries(rule.claims ?? {});\n\t\t\tconst where: Where = (actor) => {\n\t\t\t\tif (actorTypes !== null && !actorTypes.has(String(actor.type))) return false;\n\t\t\t\tif (actorIds !== null && !actorIds.has(String(actor.id ?? \"\"))) return false;\n\t\t\t\tfor (const [key, value] of claimEntries) {\n\t\t\t\t\tif ((actor as Record<string, unknown>)[key] !== value) return false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t};\n\t\t\tif (rule.effect === \"deny\") {\n\t\t\t\tdeny(rule.action, { where });\n\t\t\t} else {\n\t\t\t\tallow(rule.action, { where });\n\t\t\t}\n\t\t}\n\t});\n}\n\nconst STANDARD_WRITE_TYPES = [\"human\", \"llm\", \"wallet\", \"system\"] as const;\n\n/**\n * Derives a best-effort `meta.access` hint string by probing `guard` with the\n * standard actor types `human`, `llm`, `wallet`, `system` for the `\"write\"` action\n * (roadmap 1.5). Aligned with graphrefly-py `access_hint_for_guard`.\n *\n * @param guard - Guard function to probe (typically from {@link policy}).\n * @returns `\"restricted\"` when no standard type is allowed; `\"both\"` when both\n * `human` and `llm` are allowed (plus optionally `system`); the single allowed\n * type name when only one passes; or a `\"+\"` joined list otherwise.\n *\n * @example\n * ```ts\n * import { policy, accessHintForGuard } from \"@graphrefly/graphrefly-ts\";\n *\n * const guardBoth = policy((allow) => { allow(\"write\"); });\n * accessHintForGuard(guardBoth); // \"both\"\n *\n * const guardHuman = policy((allow) => {\n * allow(\"write\", { where: (a) => a.type === \"human\" });\n * });\n * accessHintForGuard(guardHuman); // \"human\"\n * ```\n */\nexport function accessHintForGuard(guard: NodeGuard): string {\n\tconst allowed = STANDARD_WRITE_TYPES.filter((t) => guard({ type: t, id: \"\" }, \"write\"));\n\tif (allowed.length === 0) return \"restricted\";\n\tif (\n\t\tallowed.includes(\"human\") &&\n\t\tallowed.includes(\"llm\") &&\n\t\tallowed.every((t) => t === \"human\" || t === \"llm\" || t === \"system\")\n\t) {\n\t\treturn \"both\";\n\t}\n\tif (allowed.length === 1) return allowed[0];\n\treturn allowed.join(\"+\");\n}\n","/**\n * Node versioning — GRAPHREFLY-SPEC §7.\n *\n * Progressive, optional versioning for node identity and change tracking.\n *\n * - **V0**: `id` + `version` — identity & change detection (~16 bytes overhead)\n * - **V1**: + `cid` + `prev` — content addressing & linked history (~60 bytes overhead)\n *\n * **Lifecycle notes:**\n * - Version advances only on DATA (not RESOLVED, INVALIDATE, or TEARDOWN).\n * - `resetOnTeardown` clears the cached value but does NOT reset versioning state.\n * After teardown, `v.cid` still reflects the last DATA value, not the cleared cache.\n * The invariant `hash(node.cache) === v.cid` only holds in `settled`/`resolved` status.\n * - Resubscribable nodes preserve versioning across subscription lifetimes (monotonic counter).\n */\n\n// Runtime-agnostic — no `node:crypto` import. `randomUUID` comes from Web\n// Crypto (`globalThis.crypto.randomUUID()`), available in Node 14.17+,\n// browsers, Deno, Bun, and Cloudflare Workers. The default content hash is a\n// vendored sync SHA-256 (see `sha256Hex` below) so versioning stays callable\n// from any runtime — `crypto.subtle.digest` is async and can't back a\n// synchronous `defaultHash`.\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** V0: identity + monotonic version counter. */\nexport type V0 = {\n\treadonly id: string;\n\tversion: number;\n};\n\n/** V1: V0 + content-addressed identifier + previous cid link. */\nexport type V1 = V0 & {\n\tcid: string;\n\tprev: string | null;\n};\n\n/** Union of all versioning info shapes. */\nexport type NodeVersionInfo = V0 | V1;\n\n/** Supported versioning levels (extensible to 2, 3 later). */\nexport type VersioningLevel = 0 | 1;\n\n/** Function that hashes a value to a hex string (for V1 cid). */\nexport type HashFn = (value: unknown) => string;\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface VersioningOptions {\n\t/** Override auto-generated id. */\n\tid?: string;\n\t/** Custom hash function for V1 cid (default: SHA-256 truncated to 16 hex chars). */\n\thash?: HashFn;\n}\n\n// ---------------------------------------------------------------------------\n// Default hash\n// ---------------------------------------------------------------------------\n\n/**\n * Canonicalize a value for deterministic cross-language hashing.\n *\n * - Integer-valued floats normalize to integer strings (`1.0` → `1`).\n * - `NaN`, `Infinity`, `-Infinity` are rejected (no JSON equivalent).\n * - `undefined` normalizes to `null`.\n * - Object keys are sorted lexicographically.\n *\n * This ensures TS `JSON.stringify` and Python `json.dumps(sort_keys=True)`\n * produce identical output for the same logical value.\n */\nexport function canonicalizeForHash(value: unknown): unknown {\n\tif (value === undefined) return null;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) {\n\t\t\tthrow new TypeError(`Cannot hash non-finite number: ${value}`);\n\t\t}\n\t\tif (Number.isInteger(value) && !Number.isSafeInteger(value)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Cannot hash integer outside safe range (|n| > 2^53-1): ${value}. ` +\n\t\t\t\t\t\"Cross-language cid parity is not guaranteed for unsafe integers.\",\n\t\t\t);\n\t\t}\n\t\treturn value;\n\t}\n\tif (typeof value === \"string\" || typeof value === \"boolean\" || value === null) {\n\t\treturn value;\n\t}\n\tif (Array.isArray(value)) {\n\t\treturn value.map(canonicalizeForHash);\n\t}\n\tif (typeof value === \"object\" && value !== null) {\n\t\tconst sorted: Record<string, unknown> = {};\n\t\tfor (const k of Object.keys(value as Record<string, unknown>).sort()) {\n\t\t\tsorted[k] = canonicalizeForHash((value as Record<string, unknown>)[k]);\n\t\t}\n\t\treturn sorted;\n\t}\n\t// Fallback: coerce to null (bigint, symbol, function)\n\treturn null;\n}\n\n// SHA-256 round constants (FIPS 180-4).\nconst SHA256_K = /* @__PURE__ */ new Uint32Array([\n\t0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n\t0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n\t0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n\t0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n\t0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n\t0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n\t0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n\t0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\nconst UTF8_ENCODER = /* @__PURE__ */ new TextEncoder();\n\n/**\n * Sync SHA-256 of a UTF-8 string, returned as a lowercase hex digest. Matches\n * Node `crypto.createHash(\"sha256\").update(msg).digest(\"hex\")` byte-for-byte.\n *\n * Runtime-agnostic (no `node:crypto`, no `crypto.subtle`). Small enough to\n * inline rather than pulling a dependency; called only from `defaultHash`,\n * which runs once per DATA on versioned nodes, so per-call allocation is\n * acceptable. Callers that need a faster path override via\n * `NodeOptions.versioningHash`.\n */\nfunction sha256Hex(msg: string): string {\n\tconst bytes = UTF8_ENCODER.encode(msg);\n\tconst msgLen = bytes.length;\n\tconst bitLen = msgLen * 8;\n\t// Pad to multiple of 64: 0x80 byte + zeros + 8-byte big-endian bit length.\n\tconst totalLen = (msgLen + 9 + 63) & ~63;\n\tconst padded = new Uint8Array(totalLen);\n\tpadded.set(bytes);\n\tpadded[msgLen] = 0x80;\n\tconst dv = new DataView(padded.buffer);\n\t// Bit length as big-endian 64-bit int. JS numbers are 53-bit safe, so we\n\t// split into two 32-bit halves; messages up to 2^53 bits are supported.\n\tdv.setUint32(totalLen - 4, bitLen >>> 0, false);\n\tdv.setUint32(totalLen - 8, Math.floor(bitLen / 0x100000000) >>> 0, false);\n\n\t// Initial hash values (first 32 bits of fractional parts of sqrt of first 8 primes).\n\tlet h0 = 0x6a09e667;\n\tlet h1 = 0xbb67ae85;\n\tlet h2 = 0x3c6ef372;\n\tlet h3 = 0xa54ff53a;\n\tlet h4 = 0x510e527f;\n\tlet h5 = 0x9b05688c;\n\tlet h6 = 0x1f83d9ab;\n\tlet h7 = 0x5be0cd19;\n\n\tconst W = new Uint32Array(64);\n\tconst rotr = (x: number, n: number): number => (x >>> n) | (x << (32 - n));\n\n\tfor (let off = 0; off < totalLen; off += 64) {\n\t\tfor (let i = 0; i < 16; i++) W[i] = dv.getUint32(off + i * 4, false);\n\t\tfor (let i = 16; i < 64; i++) {\n\t\t\tconst w15 = W[i - 15];\n\t\t\tconst w2 = W[i - 2];\n\t\t\tconst s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ (w15 >>> 3);\n\t\t\tconst s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ (w2 >>> 10);\n\t\t\tW[i] = (W[i - 16] + s0 + W[i - 7] + s1) >>> 0;\n\t\t}\n\n\t\tlet a = h0;\n\t\tlet b = h1;\n\t\tlet c = h2;\n\t\tlet d = h3;\n\t\tlet e = h4;\n\t\tlet f = h5;\n\t\tlet g = h6;\n\t\tlet h = h7;\n\n\t\tfor (let i = 0; i < 64; i++) {\n\t\t\tconst S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);\n\t\t\tconst ch = (e & f) ^ (~e & g);\n\t\t\tconst t1 = (h + S1 + ch + SHA256_K[i] + W[i]) >>> 0;\n\t\t\tconst S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);\n\t\t\tconst mj = (a & b) ^ (a & c) ^ (b & c);\n\t\t\tconst t2 = (S0 + mj) >>> 0;\n\t\t\th = g;\n\t\t\tg = f;\n\t\t\tf = e;\n\t\t\te = (d + t1) >>> 0;\n\t\t\td = c;\n\t\t\tc = b;\n\t\t\tb = a;\n\t\t\ta = (t1 + t2) >>> 0;\n\t\t}\n\n\t\th0 = (h0 + a) >>> 0;\n\t\th1 = (h1 + b) >>> 0;\n\t\th2 = (h2 + c) >>> 0;\n\t\th3 = (h3 + d) >>> 0;\n\t\th4 = (h4 + e) >>> 0;\n\t\th5 = (h5 + f) >>> 0;\n\t\th6 = (h6 + g) >>> 0;\n\t\th7 = (h7 + h) >>> 0;\n\t}\n\n\tconst toHex = (x: number): string => x.toString(16).padStart(8, \"0\");\n\treturn (\n\t\ttoHex(h0) + toHex(h1) + toHex(h2) + toHex(h3) + toHex(h4) + toHex(h5) + toHex(h6) + toHex(h7)\n\t);\n}\n\n/**\n * Default content hash: SHA-256 of deterministic JSON, truncated to 16 hex\n * chars (~64-bit). Uses {@link canonicalizeForHash} for cross-language parity\n * with Python `default_hash`.\n */\nexport function defaultHash(value: unknown): string {\n\tconst canonical = canonicalizeForHash(value ?? null);\n\tconst json = JSON.stringify(canonical);\n\treturn sha256Hex(json).slice(0, 16);\n}\n\n/**\n * Cross-runtime UUID generator. Uses Web Crypto (`globalThis.crypto.randomUUID`)\n * when available. Falls back to a tiny `Math.random`-seeded RFC 4122 v4\n * generator for environments that omit `crypto.randomUUID` — identity only,\n * not cryptographic.\n */\nfunction randomUuid(): string {\n\tconst c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n\tif (c?.randomUUID) return c.randomUUID();\n\t// Fallback (extremely rare — only hits on very old runtimes that expose no\n\t// Web Crypto at all). Not cryptographically strong.\n\tconst r = () =>\n\t\tMath.floor(Math.random() * 0x100000000)\n\t\t\t.toString(16)\n\t\t\t.padStart(8, \"0\");\n\tconst hex = r() + r() + r() + r();\n\treturn (\n\t\t`${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-` +\n\t\t`${((parseInt(hex.slice(16, 17), 16) & 0x3) | 0x8).toString(16)}${hex.slice(17, 20)}-${hex.slice(20, 32)}`\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create initial versioning state for a node.\n *\n * @param level - 0 for V0, 1 for V1.\n * @param initialValue - The node's initial cached value (used for V1 cid).\n * @param opts - Optional overrides (id, hash).\n */\nexport function createVersioning(\n\tlevel: VersioningLevel,\n\tinitialValue: unknown,\n\topts?: VersioningOptions,\n): NodeVersionInfo {\n\tconst id = opts?.id ?? randomUuid();\n\tif (level === 0) {\n\t\treturn { id, version: 0 } satisfies V0;\n\t}\n\tconst hash = opts?.hash ?? defaultHash;\n\tconst cid = hash(initialValue);\n\treturn { id, version: 0, cid, prev: null } satisfies V1;\n}\n\n// ---------------------------------------------------------------------------\n// Advance\n// ---------------------------------------------------------------------------\n\n/**\n * Advance versioning state after a DATA emission (value changed).\n *\n * Mutates `info` in place for performance (called on every DATA).\n * Only call when the cached value has actually changed (not on RESOLVED).\n *\n * @param info - The node's current versioning state.\n * @param newValue - The new cached value.\n * @param hashFn - Hash function (only used for V1).\n */\nexport function advanceVersion(info: NodeVersionInfo, newValue: unknown, hashFn: HashFn): void {\n\tinfo.version += 1;\n\tif (\"cid\" in info) {\n\t\t(info as V1).prev = (info as V1).cid;\n\t\t(info as V1).cid = hashFn(newValue);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Guards\n// ---------------------------------------------------------------------------\n\n/** Type guard: is this V1 versioning info? */\nexport function isV1(info: NodeVersionInfo): info is V1 {\n\treturn \"cid\" in info;\n}\n","/**\n * `NodeImpl` — the single GraphReFly node primitive.\n *\n * Per-dep state lives in a `DepRecord[]` — one entry per declared dep —\n * consolidating subscription cleanup, latest-data tracking, dirty/settled\n * flags, and terminal state into a single structure per dep.\n *\n * This file also owns the default singleton handlers (`defaultOnMessage`,\n * `defaultOnSubscribe`), the `defaultConfig` instance, and the public\n * `configure(...)` entry point. They live here because their bodies touch\n * `NodeImpl` internals; `config.ts` stays NodeImpl-agnostic.\n *\n * See GRAPHREFLY-SPEC §2 and COMPOSITION-GUIDE §1/§9 for the behavior\n * contract. See SESSION-foundation-redesign.md §§1–10 for design history.\n */\n\nimport { registerBuiltinCodecs } from \"../graph/codec.js\";\nimport type { Actor } from \"./actor.js\";\nimport { normalizeActor } from \"./actor.js\";\nimport { downWithBatch } from \"./batch.js\";\nimport { wallClockNs } from \"./clock.js\";\nimport type {\n\tMessageContext,\n\tNodeActions,\n\tNodeCtx,\n\tOnMessageHandler,\n\tOnSubscribeHandler,\n\tSubscribeContext,\n} from \"./config.js\";\nimport { GraphReFlyConfig, registerBuiltins } from \"./config.js\";\nimport type { GuardAction, NodeGuard } from \"./guard.js\";\nimport { GuardDenied } from \"./guard.js\";\nimport {\n\tCOMPLETE,\n\tCOMPLETE_ONLY_BATCH,\n\tDATA,\n\tDIRTY,\n\tDIRTY_MSG,\n\tDIRTY_ONLY_BATCH,\n\tERROR,\n\tINVALIDATE,\n\tINVALIDATE_ONLY_BATCH,\n\ttype Message,\n\ttype Messages,\n\tPAUSE,\n\tRESOLVED,\n\tRESOLVED_MSG,\n\tRESOLVED_ONLY_BATCH,\n\tRESUME,\n\tSTART,\n\tSTART_MSG,\n\tTEARDOWN,\n\tTEARDOWN_ONLY_BATCH,\n} from \"./messages.js\";\nimport {\n\tadvanceVersion,\n\tcreateVersioning,\n\tdefaultHash,\n\ttype HashFn,\n\ttype NodeVersionInfo,\n\ttype VersioningLevel,\n} from \"./versioning.js\";\n\n// ---------------------------------------------------------------------------\n// Internal sentinel + type helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Placeholder unsubscribe used to mark a dep subscription as \"pending\" during\n * the synchronous window between `dep.unsub = noopUnsub` and the return of\n * `dep.node.subscribe(...)`. Ensures the liveness check `dep.unsub === null`\n * in the subscription callback correctly passes for synchronous push-on-\n * subscribe deliveries, while still blocking stale drainPhase2 closures that\n * fire after deactivation has set `dep.unsub = null`.\n */\nconst noopUnsub: () => void = () => {};\n\n/**\n * Maximum `_pendingRerun` depth before we give up and emit ERROR. Bounds\n * autoTrackNode / `_addDep` discovery loops — a well-formed discovery\n * converges in O(n) total rounds for n deps, so 100 is ample.\n */\nconst MAX_RERUN_DEPTH = 100;\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** Lifecycle status of a node (GRAPHREFLY-SPEC §2.2). */\nexport type NodeStatus =\n\t| \"sentinel\"\n\t| \"pending\"\n\t| \"dirty\"\n\t| \"settled\"\n\t| \"resolved\"\n\t| \"completed\"\n\t| \"errored\";\n\n/** Callback that receives downstream message batches. */\nexport type NodeSink = (messages: Messages) => void;\n\n/**\n * Observability hook events fired by a per-node inspector. Used by\n * `Graph.observe(path, { causal, derived })` to build causal traces.\n *\n * - `\"dep_message\"` — fires in `_onDepMessage` before default dispatch,\n * one event per message received from a dep. Includes `depIndex` and\n * the raw `Message` tuple.\n * - `\"run\"` — fires in `_execFn` just before the user fn runs. Includes\n * the per-dep `prevData` snapshot that will be passed to fn.\n */\nexport type NodeInspectorHookEvent =\n\t| { kind: \"dep_message\"; depIndex: number; message: Message }\n\t| {\n\t\t\tkind: \"run\";\n\t\t\tbatchData: readonly (readonly unknown[] | undefined)[];\n\t\t\tprevData: readonly unknown[];\n\t };\n\n/** Callback attached to a node for per-message/per-run inspection. */\nexport type NodeInspectorHook = (event: NodeInspectorHookEvent) => void;\n\n/** Describe `type` for `Graph.describe` (GRAPHREFLY-SPEC Appendix B). */\nexport type NodeDescribeKind = \"state\" | \"derived\" | \"producer\" | \"effect\";\n\n/** Actor/delivery context for {@link Node.down} and {@link Node.up}. */\nexport type NodeTransportOptions = {\n\tactor?: Actor;\n\t/** When `true`, skips guard checks. */\n\tinternal?: boolean;\n\t/** `signal` for `Graph.signal` deliveries; default `write`. */\n\tdelivery?: \"write\" | \"signal\";\n};\n\n/**\n * Cleanup return shape from a node {@link NodeFn}.\n * - `() => void` — fires before the next fn run AND on deactivation (default).\n * - `{ deactivation: () => void }` — fires only on deactivation (persistent\n * resources that should survive across fn re-runs).\n */\nexport type NodeFnCleanup = (() => void) | { deactivation: () => void };\n\n/**\n * Fn-time context exposing per-wave metadata and a per-node persistent\n * scratch pad.\n *\n * - `prevData[i]` — last DATA value from dep `i` as of the END of the\n * previous wave (i.e. the value that was stable before this wave started).\n * Use as the fallback when `data[i]` is `undefined` (not involved) or\n * `[]` (RESOLVED, no new values this wave).\n * `undefined` means dep `i` has never produced DATA (sentinel state).\n * `null` is a valid DATA value. `undefined` is not a valid DATA value —\n * the protocol reserves it as the \"never sent\" sentinel.\n * - `ctx.prevData[i] === undefined` → dep has never produced DATA\n * - `ctx.prevData[i] !== undefined` → last DATA value (may be `null`)\n * - `terminalDeps[i]` — runtime shape:\n * - `undefined` → dep `i` is still live.\n * - `true` → dep `i` sent COMPLETE.\n * - anything else → dep `i` sent ERROR, value is the error payload.\n * Type is `readonly unknown[]` because `true | unknown` collapses to\n * `unknown` anyway; the three states are documented contract, not type.\n * - `store` — mutable bag that persists across fn runs within one activation\n * cycle. Wiped on deactivation and on resubscribable terminal reset.\n */\nexport interface FnCtx {\n\treadonly prevData: readonly unknown[];\n\treadonly terminalDeps: readonly unknown[];\n\treadonly store: Record<string, unknown>;\n}\n\n/**\n * Compute function passed to `node(deps, fn, opts?)`.\n *\n * `data[i]` holds the batch of DATA values received from dep `i` during the\n * current wave. Shape contract:\n * - `undefined` — dep `i` was not involved in this wave (no DIRTY received).\n * - `[]` — dep `i` was involved (dirtied), but settled as RESOLVED (value\n * unchanged). Use `ctx.prevData[i]` to read its last known value from the\n * previous wave.\n * - `[v1, v2, ...]` — dep `i` sent one or more DATA values. `at(-1)` gives\n * the latest; iterate for multi-emission processing.\n *\n * Emission is explicit via `actions.emit(v)` (sugar: equals + framing) or\n * `actions.down(msgs)` (raw). Return a cleanup function (or\n * `{ deactivation }`) to register teardown — any non-cleanup return value\n * is ignored. The `| void` leg lets arrow-block bodies satisfy `NodeFn`\n * without an explicit `return undefined`.\n *\n * Sugar constructors (`derived`, `effect`, `dynamicNode`) unwrap `data[i]`\n * to a single scalar (`at(-1)` with `ctx.prevData[i]` fallback) so their\n * user-facing fn signatures stay unchanged. Use raw `node()` when you need\n * the full batch array.\n */\nexport type NodeFn = (\n\tdata: readonly (readonly unknown[] | undefined)[],\n\tactions: NodeActions,\n\tctx: FnCtx,\n\t// biome-ignore lint/suspicious/noConfusingVoidType: see JSDoc above.\n) => NodeFnCleanup | void;\n\n/** Options accepted by every node constructor. */\nexport interface NodeOptions<T = unknown> {\n\tname?: string;\n\tdescribeKind?: NodeDescribeKind;\n\tequals?: (a: T, b: T) => boolean;\n\t/**\n\t * Pre-populate the cache at construction. `null` is a valid initial value.\n\t * `undefined` is treated as absent (not a valid DATA payload).\n\t */\n\tinitial?: T | null;\n\tmeta?: Record<string, unknown>;\n\tresubscribable?: boolean;\n\tresetOnTeardown?: boolean;\n\t/** Auto-emit `[[COMPLETE]]` when all deps complete. Default `true`. */\n\tcompleteWhenDepsComplete?: boolean;\n\t/**\n\t * Auto-propagate `[[ERROR]]` when any dep errors. Default `true`.\n\t * Set `false` only for rescue/catchError operators that handle errors\n\t * explicitly via `ctx.terminalDeps`.\n\t */\n\terrorWhenDepsError?: boolean;\n\t/**\n\t * Tier-2 PAUSE/RESUME handling.\n\t * - `true` (default): wave completion suppressed while paused; fn fires\n\t * once on RESUME if gate is satisfied.\n\t * - `false`: node ignores PAUSE (sources like timers that must keep running).\n\t * - `\"resumeAll\"`: on RESUME, replay every buffered DATA (future).\n\t */\n\tpausable?: boolean | \"resumeAll\";\n\tguard?: NodeGuard;\n\tversioning?: VersioningLevel;\n\tversioningId?: string;\n\tversioningHash?: HashFn;\n\t/**\n\t * Override the config instance this node binds to. Defaults to\n\t * {@link defaultConfig}. Useful for test isolation and custom protocol\n\t * stacks. The first node that reads any hook on the config freezes it.\n\t */\n\tconfig?: GraphReFlyConfig;\n}\n\n/** A reactive node in the GraphReFly protocol. */\nexport interface Node<T = unknown> {\n\treadonly name?: string;\n\treadonly status: NodeStatus;\n\t/**\n\t * Current cached value. Returns `undefined` when the node is in\n\t * `\"sentinel\"` state (no DATA ever emitted). v5 reserves `undefined`\n\t * globally as the sentinel value — the valid DATA type is `T | null`.\n\t * Therefore `node.cache === undefined` is a valid \"never emitted\" guard.\n\t * `node.status` distinguishes the richer states (`\"sentinel\"`,\n\t * `\"settled\"`, `\"errored\"`, etc.) when you need more than has-value.\n\t */\n\treadonly cache: T | null | undefined;\n\treadonly meta: Record<string, Node>;\n\treadonly lastMutation: Readonly<{ actor: Actor; timestamp_ns: number }> | undefined;\n\treadonly v: Readonly<NodeVersionInfo> | undefined;\n\t/**\n\t * Send one or more messages downstream. Accepts either a single\n\t * {@link Message} tuple (e.g. `node.down([DATA, 42])`) or a\n\t * {@link Messages} array of tuples (e.g.\n\t * `node.down([[DIRTY], [DATA, 42]])`). One call = one wave: the\n\t * emit pipeline tier-sorts the input, auto-prefixes `[DIRTY]` when\n\t * any tier-3 payload is present and the node is not already dirty,\n\t * runs equals substitution against the live cache (§3.5.1), then\n\t * dispatches to sinks with phase deferral.\n\t */\n\tdown(messageOrMessages: Message | Messages, options?: NodeTransportOptions): void;\n\t/**\n\t * Sugar for `down([[DATA, value]])`. One wave with a single DATA\n\t * payload — the pipeline adds the synthetic DIRTY prefix and runs\n\t * equals substitution against the live cache.\n\t */\n\temit(value: T | undefined | null, options?: NodeTransportOptions): void;\n\t/**\n\t * Send one or more messages upstream. Accepts the same shapes as\n\t * {@link down}. Upstream messages are tier <3 + tier 5 only\n\t * (DIRTY, INVALIDATE, PAUSE, RESUME, TEARDOWN); tier-3/4 payloads\n\t * throw — DATA/RESOLVED/COMPLETE/ERROR are downstream-only in this\n\t * protocol. No equals substitution, no cache advance, no DIRTY\n\t * auto-prefix — the up direction just forwards to every dep.\n\t */\n\tup?(messageOrMessages: Message | Messages, options?: NodeTransportOptions): void;\n\tsubscribe(sink: NodeSink, actor?: Actor): () => void;\n\tallowsObserve(actor: Actor): boolean;\n\thasGuard(): boolean;\n}\n\n// ---------------------------------------------------------------------------\n// DepRecord — per-dep state (§8.2)\n// ---------------------------------------------------------------------------\n\n/**\n * Per-dep runtime state. One entry per upstream node.\n *\n * `terminal` is the single terminal-state slot, shaped to match\n * {@link FnCtx.terminalDeps}:\n * - `undefined` — dep is still live.\n * - `true` — dep sent COMPLETE.\n * - anything else — dep sent ERROR with that payload.\n *\n * Edge case: an ERROR carrying an `undefined` payload is indistinguishable\n * from \"live\". Pass meaningful error values (Error objects, domain tags).\n */\nexport interface DepRecord {\n\treadonly node: Node;\n\tunsub: (() => void) | null;\n\t/**\n\t * Last DATA value from this dep as of the end of the previous completed\n\t * wave. `undefined` until dep has produced at least one DATA (sentinel).\n\t * Committed by `_execFn` after snapshotting `ctx.prevData` and before\n\t * `_clearWaveFlags`. `undefined` is reserved as the \"never sent\" sentinel —\n\t * `undefined` is not a valid DATA payload.\n\t */\n\tprevData: unknown;\n\t/** True while awaiting DATA/RESOLVED for the current wave. */\n\tdirty: boolean;\n\t/**\n\t * True if this dep was dirtied in the current wave (set in `_depDirtied`,\n\t * cleared in `_clearWaveFlags`). Distinguishes \"RESOLVED\" (`involvedThisWave\n\t * && dataBatch.length === 0`) from \"not involved\" (`!involvedThisWave`) in\n\t * the `data[i]` batch snapshot passed to fn.\n\t */\n\tinvolvedThisWave: boolean;\n\t/**\n\t * DATA values accumulated from this dep during the current wave.\n\t * Populated by `_depSettledAsData`, cleared by `_clearWaveFlags`.\n\t * Snapshotted (copied) by `_execFn` before `_clearWaveFlags` runs so\n\t * that fn always sees the full wave batch.\n\t */\n\tdataBatch: unknown[];\n\t/** Terminal-state slot — see JSDoc on {@link DepRecord}. */\n\tterminal: unknown;\n}\n\nfunction createDepRecord(n: Node): DepRecord {\n\treturn {\n\t\tnode: n,\n\t\tunsub: null,\n\t\tprevData: undefined,\n\t\tdirty: false,\n\t\tinvolvedThisWave: false,\n\t\tdataBatch: [],\n\t\tterminal: undefined,\n\t};\n}\n\nfunction resetDepRecord(d: DepRecord): void {\n\td.prevData = undefined;\n\td.dirty = false;\n\td.involvedThisWave = false;\n\td.dataBatch.length = 0;\n\td.terminal = undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Normalization helper\n// ---------------------------------------------------------------------------\n\n/**\n * Accept either a single `Message` tuple or a `Messages` array and return\n * a `Messages` array. The discriminator is the type of the first element:\n * a `Message` has a symbol at index 0, while a `Messages` array has a\n * nested array at index 0. This lets `node.down(...)` and `actions.down(...)`\n * take either shape without a wrapper allocation on the common single-msg\n * path.\n */\nfunction normalizeMessages(input: Message | Messages): Messages {\n\tif (input.length === 0) return input as Messages;\n\treturn typeof (input as Message)[0] === \"symbol\" ? [input as Message] : (input as Messages);\n}\n\n// ---------------------------------------------------------------------------\n// Default handlers\n// ---------------------------------------------------------------------------\n\n/**\n * Default {@link OnMessageHandler}. For `\"down-in\"` messages (from a dep),\n * routes to `NodeImpl._onDepMessage`. For `\"up-in\"` messages (from a sink),\n * the up-path is wired directly via `Node.up()` and never passes through\n * onMessage — this hook is reserved for future P5 symmetry.\n */\nconst defaultOnMessage: OnMessageHandler = (\n\tnode: NodeCtx,\n\tmsg: Message,\n\tctx: MessageContext,\n\t_actions: NodeActions,\n): \"consume\" | undefined => {\n\tif (ctx.direction === \"down-in\") {\n\t\t(node as NodeImpl)._onDepMessage(ctx.depIndex, msg);\n\t}\n\t// up-in is currently unused; default is to do nothing.\n\treturn undefined;\n};\n\n/**\n * Default {@link OnSubscribeHandler}. Delivers the subscribe handshake —\n * `[[START]]` for a sentinel cache, or `[[START], [DATA, cached]]` when a\n * value exists. Terminal nodes skip entirely so absence of START tells the\n * sink the stream is over (spec §2.2). Delivered through `downWithBatch` so\n * `subscribe()` inside `batch()` still defers the paired DATA correctly.\n */\nconst defaultOnSubscribe: OnSubscribeHandler = (\n\tnode: NodeCtx,\n\tsink: NodeSink,\n\t_ctx: SubscribeContext,\n\t_actions: NodeActions,\n): (() => void) | undefined => {\n\tconst impl = node as NodeImpl;\n\tif (impl._status === \"completed\" || impl._status === \"errored\") return;\n\tconst cached = impl._cached;\n\tconst initial: Message[] =\n\t\tcached === undefined ? [START_MSG] : [START_MSG, [DATA, cached] as Message];\n\t// When the node is mid-wave (`\"dirty\"`), append a DIRTY so the late\n\t// joiner participates in the in-flight wave. Without this, the next\n\t// DATA/RESOLVED the sink receives lacks the preceding DIRTY required\n\t// by spec §1.3.1 — the emit-side DIRTY auto-prefix is suppressed when\n\t// `_status` is already `\"dirty\"`.\n\tif (impl._status === \"dirty\") initial.push(DIRTY_MSG);\n\tdownWithBatch(sink, initial, impl._config.tierOf);\n};\n\n// ---------------------------------------------------------------------------\n// defaultConfig + configure\n// ---------------------------------------------------------------------------\n\n/**\n * Default {@link GraphReFlyConfig} instance. Every `NodeImpl` constructed\n * without an explicit `opts.config` binds to this instance and freezes it\n * on first hook access.\n */\nexport const defaultConfig = new GraphReFlyConfig({\n\tonMessage: defaultOnMessage,\n\tonSubscribe: defaultOnSubscribe,\n});\nregisterBuiltins(defaultConfig);\nregisterBuiltinCodecs(defaultConfig);\n\n/**\n * Apply configuration to {@link defaultConfig}. Must be called before the\n * first node is created — otherwise throws. Custom message types, hook\n * overrides, etc. go through here at app startup.\n *\n * ```ts\n * configure((cfg) => {\n * cfg.registerMessageType(MY_TYPE, { tier: 3 });\n * cfg.onMessage = (node, msg, ctx, actions) => { ... };\n * });\n * ```\n */\nexport function configure(fn: (cfg: GraphReFlyConfig) => void): void {\n\tif (defaultConfig._isFrozen()) {\n\t\tthrow new Error(\n\t\t\t\"configure() called after a node was created — the default \" +\n\t\t\t\t\"GraphReFlyConfig is frozen. Call configure(...) at application \" +\n\t\t\t\t\"startup, before any node factories run.\",\n\t\t);\n\t}\n\tfn(defaultConfig);\n}\n\n// Re-export the class for advanced callers that want an isolated instance.\nexport { GraphReFlyConfig };\n\n// ---------------------------------------------------------------------------\n// NodeImpl\n// ---------------------------------------------------------------------------\n\n/**\n * Single-class node implementation. Covers state, producer, derived, effect,\n * and passthrough shapes. See `sugar.ts` for ergonomic factories and\n * `dynamicNode()` (sugar-level wrapper around plain `NodeImpl`).\n */\nexport class NodeImpl<T = unknown> implements Node<T> {\n\t// --- Identity ---\n\treadonly _optsName: string | undefined;\n\treadonly _describeKind: NodeDescribeKind | undefined;\n\treadonly meta: Record<string, Node>;\n\t/**\n\t * Cached `Object.keys(meta).length > 0` check. `meta` is frozen at\n\t * construction so this boolean never flips. Used by `_emit` to skip\n\t * the meta TEARDOWN fan-out block allocation on the common \"no meta\"\n\t * hot path.\n\t */\n\treadonly _hasMeta: boolean;\n\n\t// --- Config ---\n\treadonly _config: GraphReFlyConfig;\n\n\t// --- Topology ---\n\t/** Mutable for autoTrackNode / Graph.connect() post-construction dep addition. */\n\t_deps: DepRecord[];\n\t_sinks: NodeSink | Set<NodeSink> | null = null;\n\t_sinkCount = 0;\n\n\t// --- State ---\n\t_cached: T | undefined;\n\t_status: NodeStatus;\n\t_cleanup: NodeFnCleanup | undefined;\n\t_store: Record<string, unknown> = {};\n\t_waveHasNewData = false;\n\t_hasNewTerminal = false;\n\t_hasCalledFnOnce = false;\n\t_paused = false;\n\t_pendingWave = false;\n\t_isExecutingFn = false;\n\t_pendingRerun = false;\n\t_rerunDepth = 0;\n\n\t// --- Settlement counter (A3) ---\n\t/**\n\t * Count of deps currently in `dirty === true`. `_maybeRunFnOnSettlement`\n\t * treats `0` as \"wave settled\" — O(1) check for full dep settlement.\n\t */\n\t_dirtyDepCount = 0;\n\n\t// --- PAUSE/RESUME lock tracking (C0) ---\n\t/**\n\t * Set of active pause locks held against this node. Every `[PAUSE, lockId]`\n\t * adds its `lockId` to the set; every `[RESUME, lockId]` removes it.\n\t * `_paused` is a derived quantity: `_pauseLocks.size > 0`. Multi-pauser\n\t * correctness — one controller releasing its lock does NOT resume the\n\t * node while another controller still holds its lock.\n\t */\n\t_pauseLocks: Set<unknown> | null = null;\n\t/**\n\t * Buffered DATA messages held while paused. Only populated when\n\t * `_pausable === \"resumeAll\"` (bufferAll mode). On final lock release\n\t * the buffer is replayed through the node's outgoing pipeline in the\n\t * order received. Non-bufferAll pause mode drops DATA on the floor\n\t * (upstream is expected to honor PAUSE by suppressing production).\n\t */\n\t_pauseBuffer: Message[] | null = null;\n\n\t// --- Options (frozen at construction) ---\n\treadonly _fn: NodeFn | undefined;\n\treadonly _equals: (a: T, b: T) => boolean;\n\treadonly _resubscribable: boolean;\n\treadonly _resetOnTeardown: boolean;\n\treadonly _autoComplete: boolean;\n\treadonly _autoError: boolean;\n\treadonly _pausable: boolean | \"resumeAll\";\n\treadonly _guard: NodeGuard | undefined;\n\t_hashFn: HashFn;\n\t_versioning: NodeVersionInfo | undefined;\n\t/**\n\t * Explicit versioning level, tracked separately from `_versioning` so\n\t * monotonicity checks and future v2/v3 extensions don't rely on the\n\t * fragile `\"cid\" in _versioning` shape discriminator. `undefined` means\n\t * the node has no versioning attached; `0` / `1` / future levels name\n\t * the tier. Mutated in lockstep with `_versioning` by the constructor\n\t * and by `_applyVersioning`.\n\t */\n\t_versioningLevel: VersioningLevel | undefined;\n\n\t// --- ABAC ---\n\t_lastMutation: { actor: Actor; timestamp_ns: number } | undefined;\n\n\t/**\n\t * @internal Per-node inspector hooks for `Graph.observe(path,\n\t * { causal, derived })`. Fires in `_onDepMessage` and `_execFn`.\n\t * Attached via `_setInspectorHook` (returns a disposer). Multiple\n\t * observers can attach simultaneously — all registered hooks fire for\n\t * every event.\n\t */\n\t_inspectorHooks: Set<NodeInspectorHook> | undefined;\n\n\t// --- Actions (built once in the constructor) ---\n\treadonly _actions: NodeActions;\n\n\tconstructor(deps: readonly Node[], fn: NodeFn | undefined, opts: NodeOptions<T>) {\n\t\t// Bind to config FIRST so meta nodes inherit it. Touching a hook\n\t\t// getter below freezes the config on first node creation.\n\t\tthis._config = opts.config ?? defaultConfig;\n\t\tvoid this._config.onMessage;\n\n\t\tthis._optsName = opts.name;\n\t\tthis._describeKind = opts.describeKind;\n\t\tthis._equals = (opts.equals ?? (Object.is as (a: T, b: T) => boolean)) as (\n\t\t\ta: T,\n\t\t\tb: T,\n\t\t) => boolean;\n\t\tthis._resubscribable = opts.resubscribable ?? false;\n\t\tthis._resetOnTeardown = opts.resetOnTeardown ?? false;\n\t\tthis._autoComplete = opts.completeWhenDepsComplete ?? true;\n\t\tthis._autoError = opts.errorWhenDepsError ?? true;\n\t\tthis._pausable = opts.pausable ?? true;\n\t\tthis._guard = opts.guard;\n\t\tthis._fn = fn;\n\n\t\t// `undefined` is the sentinel (\"no cached value\") so `initial: undefined`\n\t\t// is treated as absent. `null` is a valid DATA value and sets the cache.\n\t\tthis._cached = opts.initial !== undefined ? (opts.initial as T) : undefined;\n\t\t// State-with-initial starts \"settled\"; everything else starts \"sentinel\".\n\t\tthis._status =\n\t\t\tdeps.length === 0 && fn == null && this._cached !== undefined ? \"settled\" : \"sentinel\";\n\n\t\t// Versioning\n\t\t// Hash resolution: per-node `opts.versioningHash` wins; then the\n\t\t// bound config's `defaultHashFn`; then the vendored sync SHA-256.\n\t\t// Hot-path workloads that want a faster hash (xxHash, FNV-1a) can\n\t\t// set it once at app init via `configure(cfg => { cfg.defaultHashFn = ... })`.\n\t\tthis._hashFn = opts.versioningHash ?? this._config.defaultHashFn ?? defaultHash;\n\t\t// Versioning level resolution: per-node `opts.versioning` wins; if\n\t\t// absent, fall back to the bound config's `defaultVersioning`. `null`\n\t\t// stays unversioned. Explicit levels (0, 1, …) attach the versioning\n\t\t// info at construction so the next DATA emit advances it.\n\t\tconst versioningLevel: VersioningLevel | undefined =\n\t\t\topts.versioning ?? this._config.defaultVersioning;\n\t\tthis._versioningLevel = versioningLevel;\n\t\tthis._versioning =\n\t\t\tversioningLevel != null\n\t\t\t\t? createVersioning(versioningLevel, this._cached === undefined ? undefined : this._cached, {\n\t\t\t\t\t\tid: opts.versioningId,\n\t\t\t\t\t\thash: this._hashFn,\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\n\t\t// Per-dep records: one DepRecord per declared dep.\n\t\tthis._deps = deps.map(createDepRecord);\n\n\t\t// Meta companions (simple state children; inherit config + guard).\n\t\tconst meta: Record<string, Node> = {};\n\t\tfor (const [k, v] of Object.entries(opts.meta ?? {})) {\n\t\t\tconst metaOpts: NodeOptions<unknown> = {\n\t\t\t\tinitial: v,\n\t\t\t\tname: `${opts.name ?? \"node\"}:meta:${k}`,\n\t\t\t\tdescribeKind: \"state\",\n\t\t\t\tconfig: this._config,\n\t\t\t};\n\t\t\tif (opts.guard != null) metaOpts.guard = opts.guard;\n\t\t\tmeta[k] = new NodeImpl<unknown>([], undefined, metaOpts);\n\t\t}\n\t\tObject.freeze(meta);\n\t\tthis.meta = meta;\n\t\tthis._hasMeta = Object.keys(meta).length > 0;\n\n\t\t// Actions: built once, closure over `this`. Every call goes through\n\t\t// `_emit` which owns the full dispatch invariant — tier sort,\n\t\t// synthetic DIRTY prefix, equals substitution, and phase dispatch.\n\t\t// One call = one wave. Multiple calls produce multiple waves.\n\t\t// No accumulation, no user-facing bundle builder.\n\t\tconst self = this;\n\t\tthis._actions = {\n\t\t\temit(value: unknown): void {\n\t\t\t\tself._emit([[DATA, value] as Message]);\n\t\t\t},\n\t\t\tdown(messageOrMessages: Message | Messages): void {\n\t\t\t\tself._emit(normalizeMessages(messageOrMessages));\n\t\t\t},\n\t\t\tup(messageOrMessages: Message | Messages): void {\n\t\t\t\tself._emitUp(normalizeMessages(messageOrMessages));\n\t\t\t},\n\t\t};\n\n\t\t// Bind commonly detached protocol methods.\n\t\tthis.down = this.down.bind(this);\n\t\tthis.up = this.up.bind(this);\n\t}\n\n\t// --- Derived state ---\n\n\tprivate get _isTerminal(): boolean {\n\t\treturn this._status === \"completed\" || this._status === \"errored\";\n\t}\n\n\t// --- Public getters ---\n\n\tget name(): string | undefined {\n\t\treturn this._optsName;\n\t}\n\n\tget status(): NodeStatus {\n\t\treturn this._status;\n\t}\n\n\tget cache(): T | undefined | null {\n\t\treturn this._cached === undefined ? undefined : (this._cached as T);\n\t}\n\n\tget lastMutation(): Readonly<{ actor: Actor; timestamp_ns: number }> | undefined {\n\t\treturn this._lastMutation;\n\t}\n\n\tget v(): Readonly<NodeVersionInfo> | undefined {\n\t\treturn this._versioning;\n\t}\n\n\thasGuard(): boolean {\n\t\treturn this._guard != null;\n\t}\n\n\t/**\n\t * @internal Retroactively attach (or upgrade) versioning state on this\n\t * node. Intended for `Graph.setVersioning(level)` bulk application and\n\t * for rare cases where a specific node needs to be bumped to a higher\n\t * level (e.g., `v0 → v1`) after construction.\n\t *\n\t * **Safety:** the mutation is rejected mid-wave. Specifically,\n\t * throws if the node is currently executing its fn (`_isExecutingFn`).\n\t * Callers at quiescent points — before the first sink subscribes, or\n\t * after all sinks unsubscribe, or between external `down()` / `emit()`\n\t * invocations — are safe. The re-entrance window that motivated §10.6.4\n\t * removal was the \"transition `_versioning` from `undefined` to a fresh\n\t * object mid-`_updateState`\" case; that path is now guarded.\n\t *\n\t * **Monotonicity:** levels can only go up. Downgrade (e.g., `v1 → v0`)\n\t * is a no-op — once a node carries higher-level metadata, dropping it\n\t * mid-graph would tear the linked-history invariant for v1 and above.\n\t *\n\t * **Linked-history boundary (D1, 2026-04-13):** upgrading v0 → v1\n\t * produces a **fresh history root**. The new v1 state has `cid =\n\t * hash(currentCachedValue)` and `prev = null`, not a synthetic `prev`\n\t * anchored to any previous v0 value. The v0 monotonic `version` counter\n\t * is preserved across the upgrade, but the linked-cid chain (spec §7)\n\t * starts fresh at the upgrade point. Downstream audit tools that walk\n\t * `v.cid.prev` backwards through time will see a `null` boundary at\n\t * the upgrade — **this is intentional**: v0 had no cid to link to, and\n\t * fabricating one would lie about the hash. Callers that require an\n\t * unbroken cid chain from birth must attach versioning at construction\n\t * via `opts.versioning` or `config.defaultVersioning`, not retroactively.\n\t *\n\t * @param level - New minimum versioning level.\n\t * @param opts - Optional id / hash overrides; applied only if the\n\t * node currently has no versioning state.\n\t */\n\t_applyVersioning(level: VersioningLevel, opts?: { id?: string; hash?: HashFn }): void {\n\t\tif (this._isExecutingFn) {\n\t\t\tthrow new Error(\n\t\t\t\t`Node \"${this.name}\": _applyVersioning cannot run mid-fn — ` +\n\t\t\t\t\t\"call it outside of `_execFn` (typically at graph setup time \" +\n\t\t\t\t\t\"before the first subscribe).\",\n\t\t\t);\n\t\t}\n\t\tconst currentLevel = this._versioningLevel;\n\t\tif (currentLevel != null && level <= currentLevel) {\n\t\t\t// Downgrade or no-op. Monotonic: higher levels only.\n\t\t\treturn;\n\t\t}\n\t\tconst hash = opts?.hash ?? this._hashFn;\n\t\tif (hash !== this._hashFn) this._hashFn = hash;\n\t\tconst initialValue = this._cached === undefined ? undefined : this._cached;\n\t\t// Preserve the existing id + version counter across upgrades so\n\t\t// downstream consumers watching `v.id` don't see an identity jump.\n\t\tconst current = this._versioning;\n\t\tconst preservedId = current?.id ?? opts?.id;\n\t\tconst preservedVersion = current?.version ?? 0;\n\t\tconst fresh = createVersioning(level, initialValue, {\n\t\t\tid: preservedId,\n\t\t\thash,\n\t\t});\n\t\tfresh.version = preservedVersion;\n\t\tthis._versioning = fresh;\n\t\tthis._versioningLevel = level;\n\t}\n\n\t/**\n\t * @internal Attach an inspector hook. Returns a disposer that removes\n\t * the hook. Used by `Graph.observe(path, { causal, derived })` to build\n\t * causal traces. Multiple hooks may be attached concurrently — all fire\n\t * for every event in registration order. Passing `undefined` is a no-op\n\t * and returns a no-op disposer.\n\t */\n\t_setInspectorHook(hook?: NodeInspectorHook): () => void {\n\t\tif (hook == null) return () => {};\n\t\tif (this._inspectorHooks == null) this._inspectorHooks = new Set();\n\t\tthis._inspectorHooks.add(hook);\n\t\treturn () => {\n\t\t\tthis._inspectorHooks?.delete(hook);\n\t\t\tif (this._inspectorHooks?.size === 0) this._inspectorHooks = undefined;\n\t\t};\n\t}\n\n\tallowsObserve(actor: Actor): boolean {\n\t\tif (this._guard == null) return true;\n\t\treturn this._guard(normalizeActor(actor), \"observe\");\n\t}\n\n\t// --- Guard helper ---\n\n\tprivate _checkGuard(options?: NodeTransportOptions): void {\n\t\tif (options?.internal || this._guard == null) return;\n\t\tconst actor = normalizeActor(options?.actor);\n\t\tconst action: GuardAction = options?.delivery === \"signal\" ? \"signal\" : \"write\";\n\t\tif (!this._guard(actor, action)) {\n\t\t\tthrow new GuardDenied({ actor, action, nodeName: this.name });\n\t\t}\n\t\tthis._lastMutation = { actor, timestamp_ns: wallClockNs() };\n\t}\n\n\t// --- Public transport ---\n\n\tdown(messageOrMessages: Message | Messages, options?: NodeTransportOptions): void {\n\t\tconst messages = normalizeMessages(messageOrMessages);\n\t\tif (messages.length === 0) return;\n\t\tthis._checkGuard(options);\n\t\tthis._emit(messages);\n\t}\n\n\temit(value: T | undefined | null, options?: NodeTransportOptions): void {\n\t\tthis._checkGuard(options);\n\t\tthis._emit([[DATA, value] as Message]);\n\t}\n\n\tup(messageOrMessages: Message | Messages, options?: NodeTransportOptions): void {\n\t\tif (this._deps.length === 0) return;\n\t\tconst messages = normalizeMessages(messageOrMessages);\n\t\tif (messages.length === 0) return;\n\t\tthis._checkGuard(options);\n\t\tconst forwardOpts: NodeTransportOptions = options ?? { internal: true };\n\t\t// Validate tier constraint before fanning out (B1.4 option a).\n\t\tthis._validateUpTiers(messages);\n\t\tfor (const d of this._deps) {\n\t\t\td.node.up?.(messages, forwardOpts);\n\t\t}\n\t}\n\n\t/**\n\t * @internal Internal up-path used by `actions.up(...)` from inside fn.\n\t * Same tier validation as public `up`, but bypasses the guard check\n\t * since the fn context is already inside an authorized operation.\n\t */\n\tprivate _emitUp(messages: Messages): void {\n\t\tif (this._deps.length === 0) return;\n\t\tif (messages.length === 0) return;\n\t\tthis._validateUpTiers(messages);\n\t\tfor (const d of this._deps) {\n\t\t\td.node.up?.(messages, { internal: true });\n\t\t}\n\t}\n\n\t/**\n\t * @internal Enforce spec §1.2 — up-direction messages are restricted to\n\t * tier 0–2 and tier 5 (START, DIRTY, INVALIDATE, PAUSE, RESUME,\n\t * TEARDOWN). Tier 3 (DATA/RESOLVED) and tier 4 (COMPLETE/ERROR) are\n\t * downstream-only. Emitting tier-3/4 via `up` would bypass equals\n\t * substitution and cache advance entirely and is a protocol bug.\n\t */\n\tprivate _validateUpTiers(messages: Messages): void {\n\t\tconst tierOf = this._config.tierOf;\n\t\tfor (const m of messages) {\n\t\t\tconst tier = tierOf(m[0]);\n\t\t\tif (tier === 3 || tier === 4) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Node \"${this.name}\": tier-${tier} messages cannot flow up — ` +\n\t\t\t\t\t\t\"DATA/RESOLVED/COMPLETE/ERROR are downstream-only. Use \" +\n\t\t\t\t\t\t\"`down(...)` for value delivery; `up(...)` is for control \" +\n\t\t\t\t\t\t\"signals (DIRTY, INVALIDATE, PAUSE, RESUME, TEARDOWN).\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tsubscribe(sink: NodeSink, actor?: Actor): () => void {\n\t\tif (actor != null && this._guard != null) {\n\t\t\tconst a = normalizeActor(actor);\n\t\t\tif (!this._guard(a, \"observe\")) {\n\t\t\t\tthrow new GuardDenied({ actor: a, action: \"observe\", nodeName: this.name });\n\t\t\t}\n\t\t}\n\n\t\t// Resubscribable terminal reset.\n\t\tconst wasTerminal = this._isTerminal;\n\t\tconst afterTerminalReset = wasTerminal && this._resubscribable;\n\t\tif (afterTerminalReset) {\n\t\t\tthis._cached = undefined;\n\t\t\tthis._status = \"sentinel\";\n\t\t\tthis._store = {};\n\t\t\tthis._hasCalledFnOnce = false;\n\t\t\tthis._waveHasNewData = false;\n\t\t\tthis._hasNewTerminal = false;\n\t\t\tthis._paused = false;\n\t\t\tthis._pendingWave = false;\n\t\t\tthis._pendingRerun = false;\n\t\t\tthis._isExecutingFn = false;\n\t\t\tthis._rerunDepth = 0;\n\t\t\tthis._dirtyDepCount = 0;\n\t\t\t// C0: clear pause state so a new subscriber after terminal-reset\n\t\t\t// starts from a clean pause lockset — otherwise a lockId from\n\t\t\t// the previous lifecycle would leave the node stuck paused and\n\t\t\t// swallow every emit.\n\t\t\tthis._pauseLocks = null;\n\t\t\tthis._pauseBuffer = null;\n\t\t\tfor (const d of this._deps) resetDepRecord(d);\n\t\t}\n\n\t\tthis._sinkCount += 1;\n\n\t\t// Subscribe ceremony via singleton.\n\t\t// Rollback on throw: undo the sinkCount bump — sink is not yet registered,\n\t\t// no _activate() has run, nothing else to clean up.\n\t\tlet subCleanup: (() => void) | undefined;\n\t\ttry {\n\t\t\tsubCleanup = this._config.onSubscribe(\n\t\t\t\tthis as unknown as NodeCtx,\n\t\t\t\tsink,\n\t\t\t\t{ sinkCount: this._sinkCount, afterTerminalReset },\n\t\t\t\tthis._actions,\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthis._sinkCount -= 1;\n\t\t\tthrow err;\n\t\t}\n\n\t\t// Register sink AFTER START delivery (spec §2.2).\n\t\tif (this._sinks == null) {\n\t\t\tthis._sinks = sink;\n\t\t} else if (typeof this._sinks === \"function\") {\n\t\t\tthis._sinks = new Set<NodeSink>([this._sinks, sink]);\n\t\t} else {\n\t\t\tthis._sinks.add(sink);\n\t\t}\n\n\t\t// First-subscriber activation.\n\t\t// Rollback on throw: undo sink registration, sinkCount bump, and subCleanup.\n\t\t// _activate() rolls back its own partial dep subscriptions before re-throwing.\n\t\tconst isTerminalNow = this._isTerminal;\n\t\tif (this._sinkCount === 1 && !isTerminalNow) {\n\t\t\ttry {\n\t\t\t\tthis._activate();\n\t\t\t} catch (err) {\n\t\t\t\tthis._sinkCount -= 1;\n\t\t\t\tthis._removeSink(sink);\n\t\t\t\t// Restore status: onSubscribe emitted START which set _status to\n\t\t\t\t// \"pending\". With zero sinks the node is back to its pre-subscribe\n\t\t\t\t// state; reset so node.status reflects no active subscription.\n\t\t\t\tif (this._sinkCount === 0) this._status = \"sentinel\";\n\t\t\t\tif (typeof subCleanup === \"function\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tsubCleanup();\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* best-effort: subCleanup errors are secondary */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\n\t\t// Reflect \"activated but no value yet\" as pending.\n\t\tif (this._status === \"sentinel\" && this._cached === undefined) {\n\t\t\tthis._status = \"pending\";\n\t\t}\n\n\t\tlet removed = false;\n\t\treturn (): void => {\n\t\t\tif (removed) return;\n\t\t\tremoved = true;\n\t\t\tthis._sinkCount -= 1;\n\t\t\tthis._removeSink(sink);\n\t\t\tif (typeof subCleanup === \"function\") subCleanup();\n\t\t\tif (this._sinks == null) this._deactivate();\n\t\t};\n\t}\n\n\tprivate _removeSink(sink: NodeSink): void {\n\t\tif (this._sinks === sink) {\n\t\t\tthis._sinks = null;\n\t\t} else if (this._sinks != null && typeof this._sinks !== \"function\") {\n\t\t\tthis._sinks.delete(sink);\n\t\t\tif (this._sinks.size === 1) {\n\t\t\t\tconst [only] = this._sinks;\n\t\t\t\tthis._sinks = only;\n\t\t\t} else if (this._sinks.size === 0) {\n\t\t\t\tthis._sinks = null;\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Lifecycle ---\n\n\t/**\n\t * @internal First-sink activation. For a producer (no deps + fn),\n\t * invokes fn once. For a compute node (has deps), subscribes to every\n\t * dep with the pre-set-dirty trick so the first-run gate waits for\n\t * every dep to settle at least once.\n\t */\n\t_activate(): void {\n\t\tif (this._deps.length === 0) {\n\t\t\tif (this._fn) this._execFn();\n\t\t\treturn;\n\t\t}\n\t\t// Pre-set every dep as sentinel BEFORE subscribing. If the first dep\n\t\t// delivers DATA synchronously during its subscribe callback, the\n\t\t// sentinel gate holds fn until all deps have contributed at least one\n\t\t// value. _dirtyDepCount starts at 0 — actual DIRTY messages from deps\n\t\t// drive it; pre-dirtying all deps would cause any dep that only delivers\n\t\t// [[START]] (no DATA) to appear permanently \"mid-wave\", which blocks\n\t\t// terminal propagation from other deps incorrectly.\n\t\tthis._dirtyDepCount = 0;\n\t\t// Capture the initial length BEFORE subscribing. `_addDep` can fire\n\t\t// synchronously during a dep's subscribe callback (e.g., via\n\t\t// `autoTrackNode` discovery in `_execFn`) and push new DepRecords.\n\t\t// Iterating `this._deps.length` live would mean this loop also\n\t\t// subscribes the new dep that `_addDep` already subscribed — a\n\t\t// double-subscribe bug. Snapshot the length instead; `_addDep`\n\t\t// owns the subscribe + counter bump for any dep it adds.\n\t\tconst initialLen = this._deps.length;\n\t\t// subscribedCount tracks how many deps were successfully subscribed.\n\t\t// On failure, only those deps need to be rolled back.\n\t\tlet subscribedCount = 0;\n\t\ttry {\n\t\t\tfor (let i = 0; i < initialLen; i++) {\n\t\t\t\tconst depIdx = i;\n\t\t\t\tconst dep = this._deps[i];\n\t\t\t\t// Pre-set to noopUnsub so the liveness check inside the callback\n\t\t\t\t// passes during synchronous push-on-subscribe (dep.unsub is non-null),\n\t\t\t\t// while still blocking stale drainPhase2 closures that fire after\n\t\t\t\t// _deactivate sets dep.unsub = null.\n\t\t\t\tdep.unsub = noopUnsub;\n\t\t\t\tdep.unsub = dep.node.subscribe((msgs) => {\n\t\t\t\t\t// Liveness check: dep.unsub === null means this subscription was\n\t\t\t\t\t// cancelled by _deactivate. Drop deliveries from stale drainPhase2\n\t\t\t\t\t// closures that outlived the subscription.\n\t\t\t\t\tif (dep.unsub === null) return;\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tthis._config.onMessage(\n\t\t\t\t\t\t\tthis as unknown as NodeCtx,\n\t\t\t\t\t\t\tm,\n\t\t\t\t\t\t\t{ direction: \"down-in\", depIndex: depIdx },\n\t\t\t\t\t\t\tthis._actions,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsubscribedCount++;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\t// Dep at index `subscribedCount` failed — its dep.unsub is still noopUnsub.\n\t\t\t// Mark it null so the liveness check treats any queued closures as stale.\n\t\t\tthis._deps[subscribedCount].unsub = null;\n\t\t\t// Unsubscribe all deps that DID subscribe successfully (0..subscribedCount-1).\n\t\t\tfor (let j = 0; j < subscribedCount; j++) {\n\t\t\t\tconst d = this._deps[j];\n\t\t\t\tif (d.unsub != null) {\n\t\t\t\t\tconst u = d.unsub;\n\t\t\t\t\td.unsub = null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tu();\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* best-effort: dep unsub errors are secondary */\n\t\t\t\t\t}\n\t\t\t\t\tresetDepRecord(d);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._dirtyDepCount = 0;\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * @internal Append a dep post-construction. Used by `autoTrackNode`\n\t * (runtime dep discovery) and `Graph.connect()` (post-construction\n\t * wiring). Subscribes immediately — if DATA arrives synchronously\n\t * during subscribe and fn is currently executing, the re-run is\n\t * deferred via `_pendingRerun` flag (see `_execFn` guard).\n\t *\n\t * **Dedup:** idempotent on duplicate `depNode` — if `depNode` is\n\t * already in `_deps`, returns the existing index without mutating\n\t * state. Callers can safely invoke `_addDep` without their own\n\t * \"already added\" check. `autoTrackNode` still keeps a `depIndexMap`\n\t * as a fast-path lookup for known deps (returning cached `data[idx]`\n\t * without calling `_addDep` at all); this internal dedup is the\n\t * backstop for any caller that doesn't track its own dep set.\n\t *\n\t * @returns The index of the new dep in `_deps`, or the existing index\n\t * if the dep was already present.\n\t */\n\t_addDep(depNode: Node): number {\n\t\t// Dedup: idempotent on repeated adds of the same dep. Matches\n\t\t// reference equality — the DepRecord is keyed by `node` identity,\n\t\t// so a caller with a fresh `depNode` that observes as equal but\n\t\t// is a distinct object is treated as a new dep.\n\t\tfor (let i = 0; i < this._deps.length; i++) {\n\t\t\tif (this._deps[i].node === depNode) return i;\n\t\t}\n\t\tconst depIdx = this._deps.length;\n\t\tconst record = createDepRecord(depNode);\n\t\tthis._deps.push(record);\n\n\t\t// If the node is inactive (no subscribers yet), defer subscribe to\n\t\t// _activate(). Subscribing here would create a duplicate subscription\n\t\t// because _activate() unconditionally subscribes to all _deps entries.\n\t\t// _activate() resets _dirtyDepCount to 0 before subscribing, so pre-\n\t\t// dirtying is wasted work and causes counter underflow on the first DATA.\n\t\tif (this._sinks == null) return depIdx;\n\n\t\trecord.dirty = true;\n\t\t// New dep starts dirty — bump the A3 counter to match the pre-set flag.\n\t\t// Skipping the helper here because the record isn't in the array yet when\n\t\t// the helper would early-return on `dep.dirty === true`.\n\t\tthis._dirtyDepCount++;\n\t\t// Topology change → downstream sees a new wave. Skip when already\n\t\t// dirty (we're inside an in-flight wave and have already emitted).\n\t\t// `_depDirtied` can't do this for us because `record.dirty` was\n\t\t// pre-set above, which short-circuits its DIRTY-emit path.\n\t\tif (this._status !== \"dirty\") this._emit(DIRTY_ONLY_BATCH);\n\t\trecord.unsub = noopUnsub;\n\t\ttry {\n\t\t\trecord.unsub = depNode.subscribe((msgs) => {\n\t\t\t\tif (record.unsub === null) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tthis._config.onMessage(\n\t\t\t\t\t\tthis as unknown as NodeCtx,\n\t\t\t\t\t\tm,\n\t\t\t\t\t\t{ direction: \"down-in\", depIndex: depIdx },\n\t\t\t\t\t\tthis._actions,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (err) {\n\t\t\t// Rollback: remove the dep record we just pushed and undo the dirty\n\t\t\t// counter. record.unsub stays null (already cleared below) so any\n\t\t\t// drainPhase2 closures queued by subscribe before it threw are\n\t\t\t// treated as stale and dropped by the liveness check.\n\t\t\trecord.unsub = null;\n\t\t\tthis._deps.pop();\n\t\t\tthis._dirtyDepCount--;\n\t\t\t// Propagate: _execFn's catch block will emit ERROR, which settles\n\t\t\t// downstream nodes that received the DIRTY we emitted above.\n\t\t\tthrow err;\n\t\t}\n\t\treturn depIdx;\n\t}\n\n\t/**\n\t * @internal Unsubscribes from deps, fires fn cleanup (both shapes),\n\t * clears wave/store state, and (for compute nodes) drops `_cached` per\n\t * the ROM/RAM rule. Idempotent: second call is a no-op.\n\t *\n\t * @param skipStatusUpdate — When `true`, the caller takes responsibility\n\t * for setting `_status` after deactivation (e.g. TEARDOWN always sets\n\t * `\"sentinel\"` unconditionally). When `false` (default), deactivation\n\t * applies the ROM rule: compute nodes → `\"sentinel\"`, state nodes\n\t * preserve their current status.\n\t */\n\t_deactivate(skipStatusUpdate = false): void {\n\t\t// Fn cleanup — both () => void and { deactivation } forms fire here.\n\t\t// Note on cleanup-throw ERRORs: when deactivation runs as part of\n\t\t// last-sink-unsubscribe, `_sinks` is already `null` by the time this\n\t\t// method is reached, so any ERROR emitted here lands on\n\t\t// `_deliverToSinks`'s null-guard and is dropped by design. Cleanup\n\t\t// errors during teardown are best-effort — callers that need to\n\t\t// observe them should install a host-level error channel via\n\t\t// `configure()`.\n\t\tconst cleanup = this._cleanup;\n\t\tthis._cleanup = undefined;\n\t\tif (typeof cleanup === \"function\") {\n\t\t\ttry {\n\t\t\t\tcleanup();\n\t\t\t} catch (err) {\n\t\t\t\tthis._emit([[ERROR, this._wrapFnError(\"cleanup threw\", err)]]);\n\t\t\t}\n\t\t} else if (\n\t\t\tcleanup != null &&\n\t\t\ttypeof (cleanup as { deactivation?: unknown }).deactivation === \"function\"\n\t\t) {\n\t\t\ttry {\n\t\t\t\t(cleanup as { deactivation: () => void }).deactivation();\n\t\t\t} catch (err) {\n\t\t\t\tthis._emit([[ERROR, this._wrapFnError(\"cleanup.deactivation threw\", err)]]);\n\t\t\t}\n\t\t}\n\n\t\t// Disconnect from deps.\n\t\tfor (const d of this._deps) {\n\t\t\tif (d.unsub != null) {\n\t\t\t\tconst u = d.unsub;\n\t\t\t\td.unsub = null;\n\t\t\t\ttry {\n\t\t\t\t\tu();\n\t\t\t\t} catch {\n\t\t\t\t\t/* best-effort teardown of upstream subscription */\n\t\t\t\t}\n\t\t\t}\n\t\t\tresetDepRecord(d);\n\t\t}\n\n\t\t// Clear wave + store state.\n\t\tthis._waveHasNewData = false;\n\t\tthis._hasNewTerminal = false;\n\t\tthis._hasCalledFnOnce = false;\n\t\tthis._paused = false;\n\t\tthis._pendingWave = false;\n\t\tthis._pendingRerun = false;\n\t\tthis._rerunDepth = 0;\n\t\tthis._store = {};\n\t\t// A3 counter reset with DepRecord bulk-reset.\n\t\tthis._dirtyDepCount = 0;\n\t\t// C0 pause state: TEARDOWN is a hard reset. Buffered tier-3/4\n\t\t// messages from a paused `resumeAll` node are DISCARDED rather than\n\t\t// drained, matching \"teardown wipes in-flight state\" semantics.\n\t\t// Clearing both structures also prevents a memory leak on\n\t\t// non-resubscribable teardown, and guarantees a resubscribable\n\t\t// re-activation starts from `_paused === false` with no stale\n\t\t// lockset carried over from the previous lifecycle.\n\t\tthis._pauseLocks = null;\n\t\tthis._pauseBuffer = null;\n\n\t\t// ROM/RAM: compute nodes clear cache; pure state nodes preserve it.\n\t\tif (this._fn != null) {\n\t\t\tthis._cached = undefined;\n\t\t}\n\n\t\tif (!skipStatusUpdate) {\n\t\t\t// Compute nodes → \"sentinel\" (cache cleared, no value).\n\t\t\t// - Non-terminal: always reset.\n\t\t\t// - Terminal + resubscribable: reset (resubscribable means\n\t\t\t// \"can be re-activated after terminal\" — the terminal state\n\t\t\t// doesn't persist across subscription cycles).\n\t\t\t// - Terminal + non-resubscribable: preserve (stream is over).\n\t\t\t// State nodes preserve status (ROM rule, value is intrinsic).\n\t\t\tif (this._fn != null || this._deps.length > 0) {\n\t\t\t\tif (!this._isTerminal || this._resubscribable) {\n\t\t\t\t\tthis._status = \"sentinel\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Dep message dispatch (§3.5 singleton default) ---\n\n\t/**\n\t * @internal Default per-tier dispatch for incoming dep messages. Called\n\t * by `defaultOnMessage`. Updates the DepRecord, triggers wave\n\t * completion, and forwards passthrough traffic.\n\t */\n\t_onDepMessage(depIndex: number, msg: Message): void {\n\t\tconst dep = this._deps[depIndex];\n\t\tconst t = msg[0];\n\n\t\t// Fire inspector hooks before default dispatch. Common case: no hooks\n\t\t// (undefined slot). Multiple observers can attach simultaneously.\n\t\tif (this._inspectorHooks != null) {\n\t\t\tconst ev: NodeInspectorHookEvent = { kind: \"dep_message\", depIndex, message: msg };\n\t\t\tfor (const hook of this._inspectorHooks) hook(ev);\n\t\t}\n\n\t\t// Tier 0 (START) — informational, no state change.\n\t\tif (t === START) return;\n\n\t\t// Tier 1\n\t\tif (t === DIRTY) {\n\t\t\tthis._depDirtied(dep);\n\t\t\treturn;\n\t\t}\n\t\tif (t === INVALIDATE) {\n\t\t\tthis._depInvalidated(dep);\n\t\t\tthis._emit(INVALIDATE_ONLY_BATCH);\n\t\t\treturn;\n\t\t}\n\n\t\t// Tier 2 — PAUSE / RESUME flow downstream (spec §1.2). Lock bookkeeping\n\t\t// happens inside `_emit` so both `_onDepMessage` (PAUSE received from\n\t\t// a dep) and external `node.down([[PAUSE, lockId]])` (source\n\t\t// directly issuing PAUSE) hit the same path. Here we just forward —\n\t\t// `_emit` will consume the lock, update `_paused`, and broadcast.\n\t\tif (t === PAUSE || t === RESUME) {\n\t\t\tthis._emit([msg]);\n\t\t\treturn;\n\t\t}\n\n\t\t// Tier 5\n\t\tif (t === TEARDOWN) {\n\t\t\tthis._emit(TEARDOWN_ONLY_BATCH);\n\t\t\treturn;\n\t\t}\n\n\t\t// Tier 3 / 4 — centralized transitions keep the settlement counters\n\t\t// (`_dirtyDepCount`, `_sentinelDepCount`) in sync with the flags on\n\t\t// every DepRecord. A3 optimization: the two counters let\n\t\t// `_maybeRunFnOnSettlement` check wave completion in O(1) instead\n\t\t// of two `every(...)` scans.\n\t\tif (t === DATA) {\n\t\t\tthis._depSettledAsData(dep, msg[1]);\n\t\t} else if (t === RESOLVED) {\n\t\t\tthis._depSettledAsResolved(dep);\n\t\t} else if (t === COMPLETE) {\n\t\t\tthis._depSettledAsTerminal(dep, true);\n\t\t} else if (t === ERROR) {\n\t\t\tthis._depSettledAsTerminal(dep, msg[1]);\n\t\t} else {\n\t\t\t// Unknown type: forward as-is (spec §1.3.6 forward-compat).\n\t\t\tthis._emit([msg]);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this._fn) {\n\t\t\t// Passthrough: forward DATA/RESOLVED 1:1 through the unified\n\t\t\t// emit pipeline. `_emit` owns tier sort + synthetic DIRTY\n\t\t\t// prefix + equals substitution uniformly — no manual framing.\n\t\t\tif (t === DATA || t === RESOLVED) {\n\t\t\t\tthis._emit([msg]);\n\t\t\t}\n\t\t\tif (t === COMPLETE || t === ERROR) {\n\t\t\t\tthis._maybeAutoTerminalAfterWave();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis._maybeRunFnOnSettlement();\n\t}\n\n\t// --- Centralized dep-state transitions (A3 settlement counters) ---\n\t//\n\t// Every mutation to `DepRecord.dirty` / `DepRecord.prevData` /\n\t// `DepRecord.terminal` must go through one of these helpers so the\n\t// `_dirtyDepCount` and `_sentinelDepCount` counters stay in sync with\n\t// the per-record flags. `_maybeRunFnOnSettlement` reads the counters\n\t// and never re-scans the `_deps` array.\n\n\t/**\n\t * Called when a dep transitions `dirty: false → true` (either from an\n\t * incoming DIRTY, or pre-set during `_activate` / `_addDep` /\n\t * `_depInvalidated`). No-op if the dep is already dirty. Fires the\n\t * downstream DIRTY emit if we're the first to dirty this wave.\n\t */\n\tprivate _depDirtied(dep: DepRecord): void {\n\t\tif (dep.dirty) return;\n\t\tdep.dirty = true;\n\t\tdep.involvedThisWave = true;\n\t\tthis._dirtyDepCount++;\n\t\t// First dep to dirty this wave → propagate DIRTY to our own sinks.\n\t\tif (this._status !== \"dirty\") {\n\t\t\tthis._emit(DIRTY_ONLY_BATCH);\n\t\t}\n\t}\n\n\t/**\n\t * Called when a dep delivers new DATA: clears dirty, stores the payload,\n\t * marks wave-has-data, and — if this is the dep's first DATA — clears\n\t * its sentinel slot so the first-run gate can open.\n\t */\n\tprivate _depSettledAsData(dep: DepRecord, value: unknown): void {\n\t\tif (dep.dirty) {\n\t\t\tdep.dirty = false;\n\t\t\tthis._dirtyDepCount--;\n\t\t}\n\t\tdep.involvedThisWave = true;\n\t\tdep.dataBatch.push(value);\n\t\tthis._waveHasNewData = true;\n\t}\n\n\t/**\n\t * Called when a dep emits RESOLVED (wave settled, value unchanged).\n\t * Clears dirty; does NOT touch `prevData` / `terminal` / sentinel\n\t * count — sentinel only exits on first DATA or terminal, not RESOLVED.\n\t */\n\tprivate _depSettledAsResolved(dep: DepRecord): void {\n\t\tif (dep.dirty) {\n\t\t\tdep.dirty = false;\n\t\t\tthis._dirtyDepCount--;\n\t\t}\n\t}\n\n\t/**\n\t * Called when a dep delivers COMPLETE (`terminal = true`) or ERROR\n\t * (`terminal = errorPayload`). Clears dirty, stores the terminal, and\n\t * — if the dep had never contributed a DATA yet — leaves sentinel\n\t * since the gate treats \"terminated without data\" as gate-open too.\n\t */\n\tprivate _depSettledAsTerminal(dep: DepRecord, terminal: unknown): void {\n\t\tif (dep.dirty) {\n\t\t\tdep.dirty = false;\n\t\t\tthis._dirtyDepCount--;\n\t\t}\n\t\tdep.terminal = terminal;\n\t\tdep.involvedThisWave = true;\n\t\tthis._hasNewTerminal = true;\n\t}\n\n\t/**\n\t * Called when a dep emits INVALIDATE: clears prevData, terminal, and\n\t * dataBatch. The dep is now back in the \"never delivered a real value\"\n\t * state — `prevData === undefined` so the sentinel check in fn will fire.\n\t */\n\tprivate _depInvalidated(dep: DepRecord): void {\n\t\tdep.prevData = undefined;\n\t\tdep.terminal = undefined;\n\t\tdep.dataBatch.length = 0;\n\t\tif (!dep.dirty) {\n\t\t\tdep.dirty = true;\n\t\t\tdep.involvedThisWave = true;\n\t\t\tthis._dirtyDepCount++;\n\t\t} else {\n\t\t\tdep.involvedThisWave = false; // cancel prior wave involvement\n\t\t}\n\t}\n\n\tprivate _maybeRunFnOnSettlement(): void {\n\t\tif (this._isTerminal && !this._resubscribable) return;\n\t\t// O(1) gate: `_dirtyDepCount === 0` means every dep has delivered its\n\t\t// settlement for this wave (DATA, RESOLVED, or terminal).\n\t\tif (this._dirtyDepCount > 0) return;\n\t\tif (this._paused) {\n\t\t\tthis._pendingWave = true;\n\t\t\treturn;\n\t\t}\n\t\t// Pre-fn skip: when no dep sent DATA this wave (all RESOLVED), skip\n\t\t// fn and emit RESOLVED directly. Transitive-skip optimization — leaf\n\t\t// fn is not re-run when a mid-chain node produces the same value.\n\t\tif (!this._waveHasNewData && !this._hasNewTerminal && this._hasCalledFnOnce) {\n\t\t\tthis._clearWaveFlags();\n\t\t\tthis._emit(RESOLVED_ONLY_BATCH);\n\t\t\tthis._maybeAutoTerminalAfterWave();\n\t\t\treturn;\n\t\t}\n\t\tif (this._fn) this._execFn();\n\t\tthis._maybeAutoTerminalAfterWave();\n\t}\n\n\tprivate _maybeAutoTerminalAfterWave(): void {\n\t\tif (this._deps.length === 0) return;\n\t\tif (this._isTerminal) return;\n\t\t// ERROR always propagates (unless rescue operator opts out via\n\t\t// errorWhenDepsError: false). Checked independently of _autoComplete\n\t\t// so operators with completeWhenDepsComplete: false still get\n\t\t// automatic error forwarding.\n\t\tconst erroredDep = this._deps.find((d) => d.terminal !== undefined && d.terminal !== true);\n\t\tif (erroredDep != null) {\n\t\t\tif (this._autoError) {\n\t\t\t\tthis._emit([[ERROR, erroredDep.terminal]]);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// COMPLETE only when autoComplete is true and ALL deps are terminal.\n\t\tif (this._autoComplete && this._deps.every((d) => d.terminal !== undefined)) {\n\t\t\tthis._emit(COMPLETE_ONLY_BATCH);\n\t\t}\n\t}\n\n\t// --- Fn execution ---\n\n\t/**\n\t * @internal Runs the node fn once. Default cleanup (function form) fires\n\t * before the new run; `{ deactivation }` cleanup survives.\n\t */\n\tprivate _execFn(): void {\n\t\tif (!this._fn) return;\n\t\tif (this._isTerminal && !this._resubscribable) return;\n\t\t// Re-entrance guard: if fn is currently executing (e.g. _addDep\n\t\t// triggered a synchronous DATA delivery → _maybeRunFnOnSettlement\n\t\t// → _execFn), defer the re-run until the current fn returns.\n\t\tif (this._isExecutingFn) {\n\t\t\tthis._pendingRerun = true;\n\t\t\treturn;\n\t\t}\n\n\t\t// Pre-run cleanup — only the function-form cleanup fires here.\n\t\tconst prevCleanup = this._cleanup;\n\t\tif (typeof prevCleanup === \"function\") {\n\t\t\tthis._cleanup = undefined;\n\t\t\ttry {\n\t\t\t\tprevCleanup();\n\t\t\t} catch (err) {\n\t\t\t\tthis._emit([[ERROR, this._wrapFnError(\"cleanup threw\", err)]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t// { deactivation } cleanup is preserved across runs.\n\n\t\t// Snapshot dep state BEFORE clearing wave flags so the snapshot\n\t\t// reflects \"this wave\" rather than \"next wave\".\n\t\t// dataBatch is copied here because _clearWaveFlags truncates the live\n\t\t// array in-place (length = 0) — the fn must see the full wave batch.\n\t\tconst batchData: (readonly unknown[] | undefined)[] = this._deps.map((d) =>\n\t\t\t!d.involvedThisWave ? undefined : d.dataBatch.length > 0 ? [...d.dataBatch] : [],\n\t\t);\n\t\t// Snapshot prevData BEFORE committing this wave's values — fn sees the\n\t\t// stable values from the end of the previous wave, not the current wave.\n\t\t// undefined = \"never sent DATA\". null is a valid DATA value.\n\t\tconst prevData: unknown[] = this._deps.map((d) => d.prevData);\n\t\t// Commit: advance each dep's prevData to this wave's last DATA so the\n\t\t// NEXT wave's fn snapshot sees the current wave as \"previous\".\n\t\t// Use the already-copied batchData rather than dep.dataBatch to avoid\n\t\t// any ordering dependency with _clearWaveFlags.\n\t\tfor (let i = 0; i < this._deps.length; i++) {\n\t\t\tconst batch = batchData[i];\n\t\t\tif (batch != null && batch.length > 0) {\n\t\t\t\tthis._deps[i].prevData = batch[batch.length - 1] as unknown;\n\t\t\t}\n\t\t}\n\t\tconst terminalDeps = this._deps.map((d) => d.terminal);\n\t\tconst ctx: FnCtx = { prevData, terminalDeps, store: this._store };\n\n\t\tthis._hasCalledFnOnce = true;\n\t\tthis._clearWaveFlags();\n\n\t\t// Fire inspector hooks before fn runs — for Graph.observe causal traces.\n\t\tif (this._inspectorHooks != null) {\n\t\t\tconst ev: NodeInspectorHookEvent = { kind: \"run\", batchData, prevData };\n\t\t\tfor (const hook of this._inspectorHooks) hook(ev);\n\t\t}\n\n\t\tthis._isExecutingFn = true;\n\t\ttry {\n\t\t\tconst result = this._fn(batchData, this._actions, ctx);\n\t\t\tif (typeof result === \"function\") {\n\t\t\t\tthis._cleanup = result;\n\t\t\t} else if (\n\t\t\t\tresult != null &&\n\t\t\t\ttypeof result === \"object\" &&\n\t\t\t\ttypeof (result as { deactivation?: unknown }).deactivation === \"function\"\n\t\t\t) {\n\t\t\t\tthis._cleanup = result as { deactivation: () => void };\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthis._emit([[ERROR, this._wrapFnError(\"fn threw\", err)]]);\n\t\t} finally {\n\t\t\tthis._isExecutingFn = false;\n\t\t\t// Run any pending rerun BEFORE clearing wave flags so the\n\t\t\t// rerun's settlement check sees \"this wave had new data\" and\n\t\t\t// skips the pre-fn-skip optimization. Without this ordering,\n\t\t\t// autoTrackNode discovery's second pass gets swallowed by\n\t\t\t// the pre-fn-skip path.\n\t\t\tif (this._pendingRerun) {\n\t\t\t\tthis._pendingRerun = false;\n\t\t\t\tthis._rerunDepth += 1;\n\t\t\t\tif (this._rerunDepth > MAX_RERUN_DEPTH) {\n\t\t\t\t\tthis._rerunDepth = 0;\n\t\t\t\t\tthis._emit([\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tERROR,\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`Node \"${this.name}\": _pendingRerun depth exceeded ${MAX_RERUN_DEPTH} — likely a reactive cycle`,\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} else {\n\t\t\t\t\tthis._maybeRunFnOnSettlement();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Chain converged — reset the depth counter for the next wave.\n\t\t\t\tthis._rerunDepth = 0;\n\t\t\t}\n\t\t\t// Clear flags after rerun so any involvedThisWave/dataBatch set by\n\t\t\t// fn's _addDep subscribe handshakes doesn't leak into the next\n\t\t\t// wave's snapshot. The inner _execFn (if any) already did\n\t\t\t// its own pre-snapshot clear; this is for the case where\n\t\t\t// fn added deps but no rerun fired.\n\t\t\tthis._clearWaveFlags();\n\t\t}\n\t}\n\n\tprivate _clearWaveFlags(): void {\n\t\tthis._waveHasNewData = false;\n\t\tthis._hasNewTerminal = false;\n\t\tfor (const d of this._deps) {\n\t\t\td.involvedThisWave = false;\n\t\t\td.dataBatch.length = 0;\n\t\t}\n\t}\n\n\tprivate _wrapFnError(label: string, err: unknown): Error {\n\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\treturn new Error(`Node \"${this.name}\": ${label}: ${msg}`, { cause: err });\n\t}\n\n\t// --- Framing (tier sort + synthetic DIRTY prefix) ---\n\n\t/**\n\t * @internal Stable tier sort + synthetic DIRTY prefix for an outgoing\n\t * batch. Fast path: already-monotone single-tier batches (the common\n\t * case from interned singletons like `DIRTY_ONLY_BATCH`) return the\n\t * input unchanged. General path: decorate-sort-undecorate into a new\n\t * array, then prepend `[DIRTY]` after any tier-0 START entries when\n\t * a tier-3 payload is present and the node isn't already dirty.\n\t *\n\t * Single source of truth for the spec §1.3.1 framing invariant. Every\n\t * outgoing path hits `_frameBatch` exactly once via `_emit`.\n\t */\n\tprivate _frameBatch(messages: Messages): Messages {\n\t\tconst tierOf = this._config.tierOf;\n\t\t// Fast path: single message.\n\t\tif (messages.length === 1) {\n\t\t\tconst t = tierOf(messages[0][0]);\n\t\t\tif (t === 3 && this._status !== \"dirty\") {\n\t\t\t\treturn [DIRTY_MSG, messages[0]];\n\t\t\t}\n\t\t\treturn messages;\n\t\t}\n\t\t// Check monotonicity and tier-3 presence in a single pass.\n\t\tlet monotone = true;\n\t\tlet hasTier3 = false;\n\t\tlet hasDirty = false;\n\t\tlet prevTier = -1;\n\t\tfor (const m of messages) {\n\t\t\tconst tier = tierOf(m[0]);\n\t\t\tif (tier < prevTier) monotone = false;\n\t\t\tif (tier === 3) hasTier3 = true;\n\t\t\tif (m[0] === DIRTY) hasDirty = true;\n\t\t\tprevTier = tier;\n\t\t}\n\t\tlet sorted: Messages = messages;\n\t\tif (!monotone) {\n\t\t\t// Stable sort via index-keyed decoration.\n\t\t\tconst indexed = messages.map((m, i) => ({ m, i, tier: tierOf(m[0]) }));\n\t\t\tindexed.sort((a, b) => a.tier - b.tier || a.i - b.i);\n\t\t\tsorted = indexed.map((x) => x.m);\n\t\t}\n\t\tif (hasTier3 && !hasDirty && this._status !== \"dirty\") {\n\t\t\t// Insert DIRTY after any tier-0 START entries to preserve\n\t\t\t// monotonicity.\n\t\t\tlet insertAt = 0;\n\t\t\twhile (insertAt < sorted.length && tierOf(sorted[insertAt][0]) === 0) insertAt++;\n\t\t\tif (insertAt === 0) return [DIRTY_MSG, ...sorted];\n\t\t\treturn [...sorted.slice(0, insertAt), DIRTY_MSG, ...sorted.slice(insertAt)];\n\t\t}\n\t\treturn sorted;\n\t}\n\n\t// --- Emit pipeline ---\n\n\t/**\n\t * @internal The unified dispatch waist — one call = one wave.\n\t *\n\t * Pipeline stages, in order:\n\t *\n\t * 1. Early-return on empty batch.\n\t * 2. Terminal filter — post-COMPLETE/ERROR only TEARDOWN/INVALIDATE\n\t * still propagate so graph teardown and cache-clear still work.\n\t * 3. Tier sort (stable) — the batch can be in any order when it\n\t * arrives; the walker downstream (`downWithBatch`) assumes\n\t * ascending tier monotone, and so does `_updateState`'s tier-3\n\t * slice walk. This is the single source of truth for ordering.\n\t * 4. Synthetic DIRTY prefix — if a tier-3 payload is present, no\n\t * DIRTY is already in the batch, and the node isn't already in\n\t * `\"dirty\"` status, prepend `[DIRTY]` after any tier-0 START\n\t * entries. Guarantees spec §1.3.1 (DIRTY precedes DATA within\n\t * the same batch) uniformly across every entry point.\n\t * 5. PAUSE/RESUME lock bookkeeping (C0) — update `_pauseLocks`,\n\t * derive `_paused`, filter unknown-lockId RESUME, replay\n\t * bufferAll buffer on final lock release.\n\t * 6. Meta TEARDOWN fan-out — notify meta children before\n\t * `_updateState`'s TEARDOWN branch calls `_deactivate`. Hoisted\n\t * out of the walk to keep `_updateState` re-entrance-free.\n\t * 7. `_updateState` — walk the batch in tier order, advancing\n\t * `_cached` / `_status` / `_versioning` and running equals\n\t * substitution on tier-3 DATA (§3.5.1). Returns\n\t * `{finalMessages, equalsError?}`.\n\t * 8. `downWithBatch` dispatch (or bufferAll capture if paused with\n\t * `pausable: \"resumeAll\"`).\n\t * 9. Recursive ERROR emission if equals threw mid-walk.\n\t *\n\t * `node.down` / `node.emit` / `actions.down` / `actions.emit` all\n\t * converge here — the unified `_emit` waist (spec §1.3.1).\n\t */\n\t_emit(messages: Messages): void {\n\t\tif (messages.length === 0) return;\n\n\t\t// Terminal filter: after COMPLETE/ERROR (non-resubscribable), only\n\t\t// TEARDOWN / INVALIDATE still propagate so graph teardown and cache-\n\t\t// clear still work.\n\t\tlet deliverable = messages;\n\t\tconst terminal = this._isTerminal;\n\t\tif (terminal && !this._resubscribable) {\n\t\t\tconst pass = messages.filter((m) => m[0] === TEARDOWN || m[0] === INVALIDATE);\n\t\t\tif (pass.length === 0) return;\n\t\t\tdeliverable = pass;\n\t\t}\n\n\t\t// Tier sort + synthetic DIRTY prefix (stages 3 + 4 of the emit\n\t\t// pipeline). `_frameBatch` is a no-op for pre-sorted single-msg\n\t\t// batches (the common case from the tuple-interning A2 call sites);\n\t\t// otherwise it produces a stable tier-sorted copy with `[DIRTY]`\n\t\t// auto-prepended after any tier-0 messages when a tier-3 payload\n\t\t// is present and the node isn't already dirty.\n\t\tdeliverable = this._frameBatch(deliverable);\n\n\t\t// C0 — PAUSE/RESUME lock tracking. Every tier-2 tuple MUST carry a\n\t\t// `lockId` payload. Each PAUSE / RESUME updates `_pauseLocks` and\n\t\t// derives `_paused` from set size — multi-pauser correctness\n\t\t// guarantees a node only resumes when every lock it holds is\n\t\t// released. All tier-2 messages are forwarded unconditionally so\n\t\t// downstream nodes on the propagation path keep their own lock\n\t\t// sets consistent (subscribers that joined the graph before any\n\t\t// PAUSE see the full lock history). `pausable: false` sources\n\t\t// forward PAUSE/RESUME but do not track locks — appropriate for\n\t\t// reactive timers that must keep ticking. Unknown-lockId RESUME\n\t\t// is swallowed to keep `dispose()` idempotent.\n\t\tlet filtered: Message[] | null = null;\n\t\tfor (let i = 0; i < deliverable.length; i++) {\n\t\t\tconst m = deliverable[i];\n\t\t\tconst t = m[0];\n\t\t\tif (t !== PAUSE && t !== RESUME) {\n\t\t\t\tif (filtered != null) filtered.push(m);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (m.length < 2) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Node \"${this.name}\": [[${t === PAUSE ? \"PAUSE\" : \"RESUME\"}]] must ` +\n\t\t\t\t\t\t\"carry a lockId payload — bare PAUSE/RESUME is a protocol \" +\n\t\t\t\t\t\t\"violation (C0 rule). Use `[[PAUSE, lockId]]` / \" +\n\t\t\t\t\t\t\"`[[RESUME, lockId]]`.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tlet forward = true;\n\t\t\tif (this._pausable !== false) {\n\t\t\t\tconst lockId = m[1];\n\t\t\t\tif (t === PAUSE) {\n\t\t\t\t\tif (this._pauseLocks == null) this._pauseLocks = new Set();\n\t\t\t\t\tthis._pauseLocks.add(lockId);\n\t\t\t\t\tthis._paused = true;\n\t\t\t\t\tif (this._pausable === \"resumeAll\" && this._pauseBuffer == null) {\n\t\t\t\t\t\tthis._pauseBuffer = [];\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// RESUME\n\t\t\t\t\tif (this._pauseLocks == null || !this._pauseLocks.has(lockId)) {\n\t\t\t\t\t\t// Unknown lockId — swallow to keep dispose idempotent.\n\t\t\t\t\t\tforward = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._pauseLocks.delete(lockId);\n\t\t\t\t\t\tif (this._pauseLocks.size === 0) {\n\t\t\t\t\t\t\tthis._paused = false;\n\t\t\t\t\t\t\t// Replay bufferAll buffer through the outgoing\n\t\t\t\t\t\t\t// pipeline BEFORE forwarding RESUME — subscribers\n\t\t\t\t\t\t\t// observe the deferred DATAs as part of the\n\t\t\t\t\t\t\t// pre-RESUME wake-up.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// D2 (2026-04-13) semantic note: the recursive\n\t\t\t\t\t\t\t// `_emit(drain)` goes through the full pipeline\n\t\t\t\t\t\t\t// including `_updateState`'s equals substitution.\n\t\t\t\t\t\t\t// A buffered `[DATA, v]` whose value matches the\n\t\t\t\t\t\t\t// *pre-pause* cache will collapse to RESOLVED on\n\t\t\t\t\t\t\t// replay — producer \"pulses\" that write the same\n\t\t\t\t\t\t\t// value while paused are absorbed. This matches\n\t\t\t\t\t\t\t// diamond-safety intent: `.cache` stays coherent\n\t\t\t\t\t\t\t// with \"the last DATA actually delivered to\n\t\t\t\t\t\t\t// sinks\". Producers that need pulse semantics\n\t\t\t\t\t\t\t// (every write observable regardless of value)\n\t\t\t\t\t\t\t// should set `equals: () => false` on the node.\n\t\t\t\t\t\t\tif (this._pauseBuffer != null && this._pauseBuffer.length > 0) {\n\t\t\t\t\t\t\t\tconst drain = this._pauseBuffer;\n\t\t\t\t\t\t\t\tthis._pauseBuffer = [];\n\t\t\t\t\t\t\t\tthis._emit(drain);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Kick the held wave forward if one was pending.\n\t\t\t\t\t\t\tif (this._pendingWave) {\n\t\t\t\t\t\t\t\tthis._pendingWave = false;\n\t\t\t\t\t\t\t\tthis._maybeRunFnOnSettlement();\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}\n\t\t\tif (!forward) {\n\t\t\t\tif (filtered == null) filtered = deliverable.slice(0, i) as Message[];\n\t\t\t} else if (filtered != null) {\n\t\t\t\tfiltered.push(m);\n\t\t\t}\n\t\t}\n\t\tif (filtered != null) {\n\t\t\tif (filtered.length === 0) return;\n\t\t\tdeliverable = filtered;\n\t\t}\n\n\t\t// Meta TEARDOWN fan-out happens BEFORE `_updateState` so the walk\n\t\t// stays re-entrance-free: a meta node's own dispatch must not\n\t\t// re-enter the parent's outgoing pipeline while `this._cached` /\n\t\t// `this._status` are mid-commit. This preserves the spec ordering\n\t\t// \"meta propagates before deactivation\" — `_updateState`'s TEARDOWN\n\t\t// branch still runs `_deactivate` AFTER the meta children\n\t\t// have already been notified here.\n\t\tif (this._hasMeta && deliverable.some((m) => m[0] === TEARDOWN)) {\n\t\t\tfor (const k of Object.keys(this.meta)) {\n\t\t\t\ttry {\n\t\t\t\t\t(this.meta[k] as NodeImpl)._emit(TEARDOWN_ONLY_BATCH);\n\t\t\t\t} catch {\n\t\t\t\t\t/* best-effort */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// State update + equals substitution (§3.5.1 invariant). Returns the\n\t\t// possibly-rewritten batch and an optional equals-throw error. When\n\t\t// equals throws mid-walk we still deliver the successfully-walked\n\t\t// prefix to sinks before emitting ERROR, preserving cache/wire\n\t\t// coherence (user P2 option (i)).\n\t\tconst { finalMessages, equalsError } = this._updateState(deliverable);\n\n\t\t// Global inspector fan-out (Redux-DevTools-style tracer). Fires once\n\t\t// per outgoing batch, gated by `inspectorEnabled` so production paths\n\t\t// pay one boolean check. Hook errors are swallowed — instrumentation\n\t\t// must not break the data plane.\n\t\tif (finalMessages.length > 0 && this._config.inspectorEnabled) {\n\t\t\tconst inspector = this._config.globalInspector;\n\t\t\tif (inspector != null) {\n\t\t\t\ttry {\n\t\t\t\t\tinspector({ kind: \"emit\", node: this, messages: finalMessages });\n\t\t\t\t} catch {\n\t\t\t\t\t/* best-effort */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (finalMessages.length > 0) {\n\t\t\t// BufferAll: while paused with `pausable: \"resumeAll\"`, buffer\n\t\t\t// tier-3/4 payloads in order. Tier 0–2 and tier 5 continue to\n\t\t\t// dispatch synchronously — START/DIRTY/RESUME/PAUSE/TEARDOWN\n\t\t\t// must stay live so subscribers, downstream pausers, and graph\n\t\t\t// teardown all observe them. Cache/status advance has already\n\t\t\t// happened via `_updateState`, so the replay later just pushes\n\t\t\t// the deferred messages back through `downWithBatch`.\n\t\t\tif (this._paused && this._pausable === \"resumeAll\" && this._pauseBuffer != null) {\n\t\t\t\tconst tierOf = this._config.tierOf;\n\t\t\t\tconst immediate: Message[] = [];\n\t\t\t\tfor (const m of finalMessages) {\n\t\t\t\t\tconst tier = tierOf(m[0]);\n\t\t\t\t\tif (tier < 3 || tier === 5) {\n\t\t\t\t\t\timmediate.push(m);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._pauseBuffer.push(m);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (immediate.length > 0) {\n\t\t\t\t\tdownWithBatch(this._deliverToSinks, immediate, tierOf);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdownWithBatch(this._deliverToSinks, finalMessages, this._config.tierOf);\n\t\t\t}\n\t\t}\n\n\t\tif (equalsError != null) {\n\t\t\tthis._emit([[ERROR, equalsError]]);\n\t\t}\n\t}\n\n\t/**\n\t * @internal Walk an outgoing (already-framed) batch, updating own\n\t * cache / status / versioning and running equals substitution on\n\t * every tier-3 DATA (§3.5.1). Framing — tier sort and synthetic\n\t * DIRTY prefix — has already happened upstream in `_frameBatch`.\n\t * This walk trusts the input is in monotone tier order and that the\n\t * spec §1.3.1 DIRTY/RESOLVED precedence invariant is already\n\t * satisfied by the frame.\n\t *\n\t * Equals substitution: every DATA payload is compared against the\n\t * live `_cached`; when equal, the tuple is rewritten to `[RESOLVED]`\n\t * in a per-call copy and cache is not re-advanced. `.cache` remains\n\t * coherent with \"the last DATA payload this node actually sent\n\t * downstream\".\n\t *\n\t * Returns `{ finalMessages, equalsError? }`:\n\t * - `finalMessages` — the array to deliver to sinks (may be\n\t * `messages` unchanged, a rewritten copy with DATA→RESOLVED\n\t * substitutions, or a truncated prefix when equals throws mid-walk).\n\t * - `equalsError` — present only when the configured `equals` function\n\t * threw on some DATA message. `_emit` delivers the prefix first,\n\t * then emits a fresh ERROR batch via a recursive `_emit` call so\n\t * subscribers observe `[...walked_prefix, ERROR]` in order.\n\t */\n\tprivate _updateState(messages: Messages): {\n\t\tfinalMessages: Messages;\n\t\tequalsError?: Error;\n\t} {\n\t\tconst tierOf = this._config.tierOf;\n\t\tlet rewritten: Message[] | undefined;\n\t\tlet equalsError: Error | undefined;\n\t\tlet abortedAt = -1;\n\t\t// Count tier-3 messages (DATA + RESOLVED) in the batch. Equals\n\t\t// substitution is only worthwhile for a single tier-3 message —\n\t\t// an unchanged value can be rewritten to RESOLVED, enabling the\n\t\t// downstream pre-fn skip. With multiple tier-3 messages the\n\t\t// downstream fn must run regardless, so equals on each is wasted.\n\t\tlet dataCount = 0;\n\t\tfor (const m of messages) {\n\t\t\tif (tierOf(m[0]) === 3) dataCount++;\n\t\t}\n\t\tconst checkEquals = dataCount <= 1;\n\t\t// Version advances once per batch wave, not per DATA in the batch.\n\t\t// _cached only retains the last DATA value, so intermediate version\n\t\t// entries would reference values that can never be retrieved from cache.\n\t\t// Pre-scan for the last DATA index so we know when to fire advanceVersion.\n\t\tlet lastDataIdx = -1;\n\t\tif (this._versioning != null && dataCount > 1) {\n\t\t\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\t\t\tif (messages[i][0] === DATA) {\n\t\t\t\t\tlastDataIdx = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let i = 0; i < messages.length; i++) {\n\t\t\tconst m = messages[i];\n\t\t\tconst t = m[0];\n\t\t\tif (t === DATA) {\n\t\t\t\tif (m.length >= 2) {\n\t\t\t\t\tlet unchanged = false;\n\t\t\t\t\tif (checkEquals && this._cached !== undefined) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tunchanged = this._equals(this._cached as T, m[1] as T);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t// Abort walk on equals throw: deliver successfully-walked\n\t\t\t\t\t\t\t// prefix, then caller emits ERROR. Excludes the throwing\n\t\t\t\t\t\t\t// message from the prefix.\n\t\t\t\t\t\t\tequalsError = this._wrapFnError(\"equals threw\", err);\n\t\t\t\t\t\t\tabortedAt = i;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (unchanged) {\n\t\t\t\t\t\tif (rewritten == null) rewritten = messages.slice(0, i) as Message[];\n\t\t\t\t\t\trewritten.push(RESOLVED_MSG);\n\t\t\t\t\t\tthis._status = \"resolved\";\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthis._cached = m[1] as T;\n\t\t\t\t\tif (this._versioning != null) {\n\t\t\t\t\t\t// dataCount <= 1: lastDataIdx is -1; advance unconditionally\n\t\t\t\t\t\t// (single DATA, correct as before).\n\t\t\t\t\t\t// dataCount > 1: only advance on the last DATA in the batch.\n\t\t\t\t\t\tif (lastDataIdx < 0 || i === lastDataIdx) {\n\t\t\t\t\t\t\tadvanceVersion(this._versioning, m[1], this._hashFn);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis._status = \"settled\";\n\t\t\t\tif (rewritten != null) rewritten.push(m);\n\t\t\t} else {\n\t\t\t\tif (rewritten != null) rewritten.push(m);\n\t\t\t\tif (t === DIRTY) {\n\t\t\t\t\tthis._status = \"dirty\";\n\t\t\t\t} else if (t === RESOLVED) {\n\t\t\t\t\tthis._status = \"resolved\";\n\t\t\t\t} else if (t === COMPLETE) {\n\t\t\t\t\tthis._status = \"completed\";\n\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\tthis._status = \"errored\";\n\t\t\t\t} else if (t === INVALIDATE) {\n\t\t\t\t\tthis._cached = undefined;\n\t\t\t\t\tthis._status = \"dirty\";\n\t\t\t\t\t// Function-form cleanup fires on invalidate (treats as \"re-run\").\n\t\t\t\t\tconst c = this._cleanup;\n\t\t\t\t\tif (typeof c === \"function\") {\n\t\t\t\t\t\tthis._cleanup = undefined;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tc();\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* best-effort */\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\tif (this._resetOnTeardown) this._cached = undefined;\n\t\t\t\t\t// Meta TEARDOWN fan-out was already performed by `_emit`\n\t\t\t\t\t// before this walk. Deactivate now that meta children\n\t\t\t\t\t// have been notified.\n\t\t\t\t\tthis._deactivate(/* skipStatusUpdate */ true);\n\t\t\t\t\t// TEARDOWN is a hard reset — unconditionally \"sentinel\",\n\t\t\t\t\t// even if the node was previously completed/errored.\n\t\t\t\t\tthis._status = \"sentinel\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst base: Messages =\n\t\t\tabortedAt >= 0\n\t\t\t\t? ((rewritten ?? (messages.slice(0, abortedAt) as Messages)) as Messages)\n\t\t\t\t: (rewritten ?? messages);\n\t\treturn equalsError != null ? { finalMessages: base, equalsError } : { finalMessages: base };\n\t}\n\n\tprivate _deliverToSinks = (messages: Messages): void => {\n\t\tif (this._sinks == null) return;\n\t\tif (typeof this._sinks === \"function\") {\n\t\t\tthis._sinks(messages);\n\t\t\treturn;\n\t\t}\n\t\t// Snapshot: a sink callback may unsubscribe itself or others\n\t\t// mid-iteration. Iterating the live Set would skip not-yet-visited\n\t\t// sinks that were removed.\n\t\tconst snapshot = [...this._sinks];\n\t\tfor (const sink of snapshot) sink(messages);\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nconst isNodeArray = (value: unknown): value is readonly Node[] => Array.isArray(value);\nconst isNodeOptionsObject = (value: unknown): value is NodeOptions<unknown> =>\n\ttypeof value === \"object\" && value != null && !Array.isArray(value);\n\n/**\n * Creates a reactive {@link Node} — the single GraphReFly primitive (§2).\n *\n * Typical shapes:\n * - `node([])` / `node({ initial: v })` — a manual source (state node).\n * - `node(producerFn, opts)` — a producer that runs on first-subscribe.\n * - `node(deps, computeFn, opts)` — a derived / effect node.\n *\n * For value-returning computations, prefer the sugar factories in `sugar.ts`\n * (`state`, `derived`, `effect`, `producer`, `dynamicNode`), which wrap user\n * fns with `actions.emit(userFn(data))`. Calling `node()` directly gives you\n * the raw `NodeFn` contract: explicit emission via `actions`, cleanup return.\n */\nexport function node<T = unknown>(\n\tdepsOrFn?: readonly Node[] | NodeFn | NodeOptions<T>,\n\tfnOrOpts?: NodeFn | NodeOptions<T>,\n\toptsArg?: NodeOptions<T>,\n): Node<T> {\n\tconst deps: readonly Node[] = isNodeArray(depsOrFn) ? depsOrFn : [];\n\tconst fn: NodeFn | undefined =\n\t\ttypeof depsOrFn === \"function\"\n\t\t\t? depsOrFn\n\t\t\t: typeof fnOrOpts === \"function\"\n\t\t\t\t? fnOrOpts\n\t\t\t\t: undefined;\n\tlet opts: NodeOptions<T> = {};\n\tif (isNodeArray(depsOrFn)) {\n\t\topts = ((isNodeOptionsObject(fnOrOpts) ? fnOrOpts : optsArg) ?? {}) as NodeOptions<T>;\n\t} else if (isNodeOptionsObject(depsOrFn)) {\n\t\topts = depsOrFn as NodeOptions<T>;\n\t} else {\n\t\topts = ((isNodeOptionsObject(fnOrOpts) ? fnOrOpts : optsArg) ?? {}) as NodeOptions<T>;\n\t}\n\treturn new NodeImpl<T>(deps, fn, opts);\n}\n","/**\n * Sugar constructors over the raw `node()` primitive.\n *\n * Each factory wraps a user-friendly function into the canonical\n * `NodeFn = (data, actions, ctx) => cleanup | void` shape, then calls\n * `node(...)`. This is the only place `actions.emit(...)` is invoked\n * on behalf of the user — if you need finer control (multi-emission,\n * raw `actions.down` / `actions.up`, cleanup return), use the raw\n * `node()` factory from `./node.js` directly.\n *\n * See SESSION-foundation-redesign.md §8.5 + §10.6 for the rewrite.\n */\n\nimport type { NodeActions } from \"./config.js\";\nimport { RESOLVED } from \"./messages.js\";\nimport {\n\ttype FnCtx,\n\ttype Node,\n\ttype NodeFn,\n\ttype NodeFnCleanup,\n\tNodeImpl,\n\ttype NodeOptions,\n\tnode,\n} from \"./node.js\";\n\n// ---------------------------------------------------------------------------\n// Shared sentinel guard\n// ---------------------------------------------------------------------------\n\n/**\n * Returns `true` when fn should be suppressed (RESOLVED emitted instead).\n *\n * Fires when `allowPartial` is `false` and any dep has never delivered DATA:\n * `data[i]` absent this wave AND `ctx.prevData[i] === undefined`.\n *\n * `undefined` is the protocol-reserved \"never sent DATA\" sentinel. `null` is\n * a valid DATA value and will NOT trigger the guard.\n */\nfunction sentinelGuard(\n\tbatchData: readonly (readonly unknown[] | undefined)[],\n\tctx: FnCtx,\n\tallowPartial: boolean,\n): boolean {\n\tif (allowPartial) return false;\n\treturn batchData.some(\n\t\t(batch, i) => !(batch != null && batch.length > 0) && ctx.prevData[i] === undefined,\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// state — manual source with an optional initial value\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a manual source node. Drive it with `state.emit(v)` (framed,\n * diamond-safe) or `state.down([[DATA, v]])` (raw compat path).\n *\n * @param initial - Starting cached value. Pass `undefined` or `null`\n * explicitly to cache that value; omit to leave the node in `\"sentinel\"`.\n * @param opts - Optional {@link NodeOptions} (excluding `initial`).\n */\nexport function state<T>(initial: T, opts?: Omit<NodeOptions<T>, \"initial\">): Node<T> {\n\treturn node<T>([], { ...opts, initial });\n}\n\n// ---------------------------------------------------------------------------\n// producer — no-deps source with a compute body\n// ---------------------------------------------------------------------------\n\n/**\n * User-level producer compute: runs once on first-subscriber activation.\n * Receives `actions` for imperative emission and `ctx` for FnCtx (typically\n * only `store` is useful on a producer — no deps means `prevData` and\n * `terminalDeps` are empty).\n */\nexport type ProducerFn = (\n\tactions: NodeActions,\n\tctx: FnCtx,\n\t// biome-ignore lint/suspicious/noConfusingVoidType: matches NodeFn — see its JSDoc.\n) => NodeFnCleanup | void;\n\n/**\n * Creates a producer node with no deps; `fn` runs once when the first\n * subscriber connects. Return a cleanup function (`() => void`) or\n * `{ deactivation: () => void }` to register teardown.\n *\n * @example\n * ```ts\n * const ticker = producer((actions) => {\n * const id = setInterval(() => actions.emit(Date.now()), 1000);\n * return () => clearInterval(id);\n * });\n * ```\n */\nexport function producer<T = unknown>(fn: ProducerFn, opts?: NodeOptions<T>): Node<T> {\n\tconst wrapped: NodeFn = (_data, actions, ctx) => fn(actions, ctx) ?? undefined;\n\treturn node<T>(wrapped, { describeKind: \"producer\", ...opts });\n}\n\n// ---------------------------------------------------------------------------\n// derived — dep-driven pure compute\n// ---------------------------------------------------------------------------\n\n/**\n * User-level derived compute: receives the latest DATA from each dep and\n * returns the new value. The sugar wraps it with `actions.emit(fn(...))`\n * so the return value flows through the framed emit pipeline.\n *\n * For derived nodes that need to inspect `ctx.prevData` / `ctx.terminalDeps`\n * / `ctx.store`, accept the optional second parameter.\n */\nexport type DerivedFn<T> = (data: readonly unknown[], ctx: FnCtx) => T | undefined | null;\n\n/**\n * Creates a derived node that computes **one output per wave** from the latest\n * value of each dependency — **snapshot / combine semantics**.\n *\n * `fn` receives one scalar per dep (the last DATA value seen this wave, or the\n * prior-wave value as fallback). It is called once per settled wave and emits\n * a single value via `actions.emit`. The equals check then suppresses the\n * emission as `RESOLVED` if the output has not changed.\n *\n * **Not for streaming one-to-one transforms.** If each DATA value in a batch\n * must produce a corresponding output (e.g. transforming every item emitted by\n * `fromIter` individually), use {@link map} or raw `node()` with full batch\n * iteration instead. `derived` only sees the *last* value per dep when a batch\n * carries multiple DATAs.\n *\n * @example\n * ```ts\n * const a = state(1);\n * const b = derived([a], ([x]) => (x as number) * 2);\n * ```\n */\nexport function derived<T = unknown>(\n\tdeps: readonly Node[],\n\tfn: DerivedFn<T>,\n\topts?: NodeOptions<T> & { partial?: boolean },\n): Node<T> {\n\tconst allowPartial = opts?.partial ?? false;\n\tconst wrapped: NodeFn = (batchData, actions, ctx) => {\n\t\t// Sentinel guard: if any dep has never sent DATA, emit RESOLVED.\n\t\t// Uses ctx.prevData[i] === undefined (the \"never sent\" sentinel).\n\t\t// null is valid DATA and won't trigger this. Skipped when partial:true.\n\t\tif (sentinelGuard(batchData, ctx, allowPartial)) {\n\t\t\tactions.down([[RESOLVED]]);\n\t\t\treturn undefined;\n\t\t}\n\t\t// Unwrap batch-per-dep to single latest scalar per dep.\n\t\t// Batch non-null+non-empty → take last value from this wave;\n\t\t// otherwise fall back to ctx.prevData[i] (last value from prior wave).\n\t\t// undefined means \"never sent DATA\" — sentinelGuard already blocks this\n\t\t// fn when partial:false and any dep is unset, so partial:true callers\n\t\t// receive undefined for uninitiated deps (same as JS convention).\n\t\tconst data = batchData.map((batch, i) =>\n\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t);\n\t\tactions.emit(fn(data, ctx));\n\t\treturn undefined;\n\t};\n\treturn node<T>(deps, wrapped, { describeKind: \"derived\", ...opts });\n}\n\n// ---------------------------------------------------------------------------\n// effect — dep-driven side effect, no auto-emit\n// ---------------------------------------------------------------------------\n\n/**\n * User-level effect compute: fires when deps settle. Return value is NOT\n * auto-emitted — use `actions.emit(v)` / `actions.down(msgs)` explicitly if\n * the effect also wants to produce downstream messages. Return a cleanup\n * function or `{ deactivation }` to register teardown.\n */\nexport type EffectFn = (\n\tdata: readonly unknown[],\n\tactions: NodeActions,\n\tctx: FnCtx,\n\t// biome-ignore lint/suspicious/noConfusingVoidType: matches NodeFn — see its JSDoc.\n) => NodeFnCleanup | void;\n\n/**\n * Runs a side-effect when deps settle. Return value is not auto-emitted.\n *\n * @example\n * ```ts\n * effect([source], ([v]) => {\n * console.log(v);\n * });\n * ```\n */\nexport function effect(\n\tdeps: readonly Node[],\n\tfn: EffectFn,\n\topts?: NodeOptions<unknown> & { partial?: boolean },\n): Node<unknown> {\n\tconst allowPartial = opts?.partial ?? false;\n\tconst wrapped: NodeFn = (batchData, actions, ctx) => {\n\t\t// Sentinel guard: hold effect until all deps have initialised.\n\t\t// Matches pre-wave2 framework gate behaviour. Use partial:true to allow\n\t\t// the effect to fire before all deps have delivered their first value.\n\t\tif (sentinelGuard(batchData, ctx, allowPartial)) {\n\t\t\tactions.down([[RESOLVED]]);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst data = batchData.map((batch, i) =>\n\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t);\n\t\treturn fn(data, actions, ctx) ?? undefined;\n\t};\n\treturn node(deps, wrapped, { describeKind: \"effect\", ...opts });\n}\n\n// ---------------------------------------------------------------------------\n// dynamicNode — track-proxy wrapper over `derived`\n// ---------------------------------------------------------------------------\n\n/**\n * Proxy handed to a {@link DynamicFn}. `track(dep)` returns the dep's\n * latest DATA payload, as delivered through the protocol. Reading from\n * `track` does NOT bypass the message protocol — it reads the internal\n * `DepRecord.prevData` (the stable end-of-previous-wave value) that\n * `_onDepMessage` already populated. If a dep has not yet sent DATA,\n * `track` returns `undefined`.\n */\nexport type TrackFn = (dep: Node) => unknown;\n\n/** User-level dynamicNode compute. */\nexport type DynamicFn<T> = (track: TrackFn, ctx: FnCtx) => T | undefined | null;\n\n/**\n * Sugar over `derived(...)` that exposes dep values via a `track(dep)`\n * proxy instead of positional `data[i]`. All declared `allDeps` participate\n * in wave tracking, so the first fn run waits for every dep to settle.\n * Unused deps that update just re-run fn; `equals` absorbs unchanged\n * outputs as RESOLVED.\n *\n * P3-compliant: `track(dep)` reads from the framework-managed\n * `DepRecord.prevData` populated by the protocol, never from\n * `dep.cache`.\n *\n * @example\n * ```ts\n * const a = state(1);\n * const b = state(10);\n * const sum = dynamicNode([a, b], (track) => (track(a) as number) + (track(b) as number));\n * ```\n */\nexport function dynamicNode<T = unknown>(\n\tallDeps: readonly Node[],\n\tfn: DynamicFn<T>,\n\topts?: NodeOptions<T> & { partial?: boolean },\n): Node<T> {\n\tconst depIndex = new Map<Node, number>();\n\tallDeps.forEach((d, i) => {\n\t\tdepIndex.set(d, i);\n\t});\n\treturn derived<T>(\n\t\tallDeps,\n\t\t// data[i] is already sugar-unwrapped to a scalar by derived()'s wrapper.\n\t\t(data, ctx) => {\n\t\t\tconst track: TrackFn = (dep) => {\n\t\t\t\tconst i = depIndex.get(dep);\n\t\t\t\tif (i == null) {\n\t\t\t\t\tthrow new Error(`dynamicNode: untracked dep \"${dep.name ?? \"<unnamed>\"}\"`);\n\t\t\t\t}\n\t\t\t\treturn data[i];\n\t\t\t};\n\t\t\treturn fn(track, ctx);\n\t\t},\n\t\topts,\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// pipe — left-to-right operator composition\n// ---------------------------------------------------------------------------\n// autoTrackNode — runtime dep discovery (Jotai/signals compat)\n// ---------------------------------------------------------------------------\n\n/**\n * Like {@link dynamicNode} but deps are discovered at runtime via `track()`\n * calls — no upfront `allDeps` array needed. Designed for pull-based compat\n * layers (Jotai atoms, TC39 Signals) where deps are unknown until fn runs.\n *\n * **Two-phase discovery:**\n * 1. fn runs. Each `track(dep)` for an unknown dep: subscribes immediately\n * via `_addDep`, returns `dep.cache` as a stub (P3 boundary exception).\n * Result is discarded (discovery run).\n * 2. New deps settle (DATA from subscribe handshake). Wave machinery\n * re-triggers fn. `track(dep)` now returns protocol-delivered `data[i]`.\n * If MORE unknown deps appear, repeat step 1.\n * 3. Converges when no new deps found → real run → `actions.emit(result)`.\n *\n * P3 violation is limited to discovery runs. Once all deps are known,\n * subsequent waves use protocol-delivered values exclusively.\n *\n * Re-entrance safety: `_addDep` subscribes immediately. If the dep delivers\n * DATA synchronously during fn execution, `_execFn`'s re-entrance guard\n * defers the re-run to after the current fn returns.\n *\n * @param opts - Optional {@link AutoTrackOptions}. Pass `{ partial: true }` to\n * allow fn to run before all known deps have delivered their first value\n * (useful for optional/secondary deps).\n *\n * @example\n * ```ts\n * const a = state(1), b = state(2);\n * const sum = autoTrackNode((track) => track(a) + track(b));\n * // deps [a, b] discovered automatically on first run\n * ```\n */\n/**\n * Options for {@link autoTrackNode}.\n */\nexport interface AutoTrackOptions<T> extends NodeOptions<T> {\n\t/**\n\t * When `true`, fn may run before all known deps have delivered their first\n\t * DATA. Unknown deps return `undefined` via `track()`, which the fn must\n\t * handle explicitly. Useful when some deps are \"nice-to-have\" — e.g. a\n\t * primary computation should continue while a secondary dep is still\n\t * initialising.\n\t *\n\t * When `false` (default), fn is held until every known dep has delivered at\n\t * least one DATA value — a RESOLVED is emitted for the wave instead.\n\t * This matches `derived()` semantics and is the correct default for\n\t * pull-based compat layers (Signals, Jotai) where all deps must be\n\t * initialised before the computation is meaningful.\n\t *\n\t * @default false\n\t */\n\tpartial?: boolean;\n}\n\nexport function autoTrackNode<T = unknown>(\n\tfn: (track: TrackFn, ctx: FnCtx) => T | undefined | null,\n\topts?: AutoTrackOptions<T>,\n): Node<T> {\n\tlet implRef: NodeImpl<T>;\n\tconst depIndexMap = new Map<Node, number>();\n\tconst allowPartial = opts?.partial ?? false;\n\n\tconst wrappedFn: NodeFn = (batchData, actions, ctx) => {\n\t\tlet foundNew = false;\n\t\tconst track: TrackFn = (dep) => {\n\t\t\tconst idx = depIndexMap.get(dep);\n\t\t\tif (idx !== undefined) {\n\t\t\t\t// Known dep — return latest protocol-delivered value.\n\t\t\t\t// batch non-null+non-empty → latest from this wave;\n\t\t\t\t// otherwise fall back to ctx.prevData (last known value).\n\t\t\t\tif (idx < batchData.length) {\n\t\t\t\t\tconst batch = batchData[idx];\n\t\t\t\t\tif (batch != null && batch.length > 0) return batch.at(-1);\n\t\t\t\t\treturn ctx.prevData[idx];\n\t\t\t\t}\n\t\t\t\treturn dep.cache;\n\t\t\t}\n\t\t\t// Unknown dep — discovery phase.\n\t\t\tfoundNew = true;\n\t\t\tconst newIdx = implRef._addDep(dep);\n\t\t\tdepIndexMap.set(dep, newIdx);\n\t\t\treturn dep.cache; // P3 boundary exception (discovery stub)\n\t\t};\n\n\t\t// Sentinel guard (skipped when partial:true): if any known dep has never\n\t\t// delivered DATA (no DATA this wave AND ctx.prevData[idx] === undefined), emit RESOLVED\n\t\t// and defer. Mirrors derived()'s guard for the same sequential-handshake\n\t\t// scenario: when a node re-activates outside a batch and dep A delivers\n\t\t// synchronously before dep B is even subscribed, this holds fn until all\n\t\t// known deps have initialised rather than running with B=undefined.\n\t\t// Uses ctx.prevData[idx] === undefined — the protocol sentinel for\n\t\t// \"dep never sent DATA\". null is valid DATA and won't trigger this.\n\t\t// Only active when depIndexMap is non-empty (initial discovery runs are\n\t\t// unaffected) and when partial:false (default).\n\t\tif (!allowPartial && depIndexMap.size > 0) {\n\t\t\tfor (const [, idx] of depIndexMap) {\n\t\t\t\tif (idx < batchData.length) {\n\t\t\t\t\tconst batch = batchData[idx];\n\t\t\t\t\tif (!(batch != null && batch.length > 0) && ctx.prevData[idx] === undefined) {\n\t\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = fn(track, ctx);\n\t\t\tif (!foundNew) {\n\t\t\t\t// Real run — all deps known, protocol-delivered values.\n\t\t\t\tactions.emit(result);\n\t\t\t\t// Clear any stale discovery error from a prior run.\n\t\t\t\tif (ctx.store.__autoTrackLastDiscoveryError != null) {\n\t\t\t\t\tdelete ctx.store.__autoTrackLastDiscoveryError;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Discovery run — result discarded. New deps are subscribed via\n\t\t\t// _addDep. Their DATA delivery triggers _maybeRunFnOnSettlement\n\t\t\t// via the _pendingRerun mechanism, which will re-call fn.\n\t\t} catch (err) {\n\t\t\tif (!foundNew) throw err;\n\t\t\t// Discovery run threw — most likely a stale `.cache` read (P3\n\t\t\t// boundary exception), which the protocol-delivered retry will\n\t\t\t// not hit. Preserve the error on `ctx.store` for inspection; if\n\t\t\t// the retry succeeds, the flag is cleared above. If fn has a\n\t\t\t// real bug unrelated to cache, the non-discovery retry will\n\t\t\t// re-throw it out of `_execFn`.\n\t\t\tctx.store.__autoTrackLastDiscoveryError = err;\n\t\t}\n\t\treturn undefined;\n\t};\n\n\timplRef = new NodeImpl<T>([], wrappedFn, {\n\t\tdescribeKind: \"derived\",\n\t\t...opts,\n\t});\n\treturn implRef;\n}\n\n// ---------------------------------------------------------------------------\n// pipe — left-to-right operator composition\n// ---------------------------------------------------------------------------\n\n/** Unary operator used by {@link pipe}. */\nexport type PipeOperator = (n: Node) => Node;\n\n/**\n * Composes unary operators left-to-right; returns the final node.\n *\n * @example\n * ```ts\n * const out = pipe(\n * source,\n * (n) => map(n, (x) => x + 1),\n * (n) => filter(n, (x) => x > 0),\n * );\n * ```\n */\nexport function pipe(source: Node, ...ops: PipeOperator[]): Node {\n\tlet current = source;\n\tfor (const op of ops) current = op(current);\n\treturn current;\n}\n","/**\n * Backoff strategies for {@link retry} (roadmap §3.1). Delays are in **nanoseconds**.\n *\n * Convention: all graphrefly-ts timestamps and durations use nanoseconds (`_ns` suffix).\n * 1 second = 1_000_000_000 ns, 1 ms = 1_000_000 ns.\n */\n\nexport const NS_PER_MS = 1_000_000;\nexport const NS_PER_SEC = 1_000_000_000;\n\nexport type JitterMode = \"none\" | \"full\" | \"equal\";\n\nexport type BackoffPreset =\n\t| \"constant\"\n\t| \"linear\"\n\t| \"exponential\"\n\t| \"fibonacci\"\n\t| \"decorrelatedJitter\";\n\n/** `(attempt, error?, previousDelayNs?) => delayNs | null` — `null` means zero delay. */\nexport type BackoffStrategy = (\n\tattempt: number,\n\terror?: unknown,\n\tprevDelayNs?: number | null,\n) => number | null;\n\nfunction clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nfunction applyJitter(delay: number, jitter: JitterMode): number {\n\tif (jitter === \"none\") return delay;\n\tif (jitter === \"full\") return Math.random() * delay;\n\treturn delay / 2 + Math.random() * (delay / 2);\n}\n\nfunction randomBetween(min: number, max: number): number {\n\treturn min + Math.random() * (max - min);\n}\n\n/**\n * Builds a strategy that always returns the same delay in nanoseconds.\n *\n * @param delayNs - Non-negative delay in nanoseconds; values below zero are clamped to zero.\n * @returns `BackoffStrategy` for use with {@link retry} or custom timers.\n *\n * @example\n * ```ts\n * import { constant, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, { count: 3, backoff: constant(0.25 * NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function constant(delayNs: number): BackoffStrategy {\n\tconst safe = clampNonNegative(delayNs);\n\treturn () => safe;\n}\n\n/**\n * Builds linear backoff: `baseNs + stepNs * attempt` (`stepNs` defaults to `baseNs`).\n *\n * @param baseNs - Base delay in nanoseconds (clamped non-negative).\n * @param stepNs - Added per retry attempt in nanoseconds (clamped non-negative).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { linear, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * // Attempt 0 → 1 s, attempt 1 → 2 s, attempt 2 → 3 s …\n * const out = retry(source, { count: 4, backoff: linear(NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function linear(baseNs: number, stepNs?: number): BackoffStrategy {\n\tconst safeBase = clampNonNegative(baseNs);\n\tconst safeStep = stepNs === undefined ? safeBase : clampNonNegative(stepNs);\n\treturn (attempt: number) => safeBase + safeStep * Math.max(0, attempt);\n}\n\nexport type ExponentialBackoffOptions = {\n\tbaseNs?: number;\n\tfactor?: number;\n\tmaxDelayNs?: number;\n\tjitter?: JitterMode;\n};\n\n/**\n * Builds exponential backoff in nanoseconds, capped by `maxDelayNs`, with optional jitter.\n *\n * @param options - Base, factor, cap, and jitter mode.\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @remarks\n * **Jitter:** `\"full\"` spreads delay across `[0, delay]`; `\"equal\"` uses `[delay/2, delay]`.\n *\n * @example\n * ```ts\n * import { exponential, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * // 100 ms → 200 ms → 400 ms … capped at 30 s, with full jitter\n * const out = retry(source, {\n * count: 5,\n * backoff: exponential({ baseNs: 100 * NS_PER_SEC / 1000, jitter: \"full\" }),\n * });\n * ```\n *\n * @category extra\n */\nexport function exponential(options?: ExponentialBackoffOptions): BackoffStrategy {\n\tconst baseNs = clampNonNegative(options?.baseNs ?? 100 * NS_PER_MS);\n\tconst factor = options?.factor !== undefined && options.factor < 1 ? 1 : (options?.factor ?? 2);\n\tconst maxDelayNs = clampNonNegative(options?.maxDelayNs ?? 30 * NS_PER_SEC);\n\tconst jitter = options?.jitter ?? \"none\";\n\n\treturn (attempt: number) => {\n\t\tlet delay: number;\n\t\tif (baseNs === 0) {\n\t\t\tdelay = 0;\n\t\t} else if (factor === 1) {\n\t\t\tdelay = baseNs;\n\t\t} else {\n\t\t\tconst capRatio = maxDelayNs / baseNs;\n\t\t\tlet growth = 1;\n\t\t\tfor (let i = 0; i < Math.max(0, attempt); i++) {\n\t\t\t\tif (growth >= capRatio) {\n\t\t\t\t\tgrowth = capRatio;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tgrowth *= factor;\n\t\t\t}\n\t\t\tdelay = baseNs * growth;\n\t\t\tif (delay > maxDelayNs) delay = maxDelayNs;\n\t\t}\n\t\treturn applyJitter(delay, jitter);\n\t};\n}\n\n/**\n * Builds Fibonacci-scaled delays: `1, 2, 3, 5, … × baseNs`, capped at `maxDelayNs`.\n *\n * @param baseNs - Multiplier applied to the Fibonacci unit (default `100ms` in nanoseconds).\n * @param maxDelayNs - Upper bound in nanoseconds (default `30s`).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { fibonacci, retry, NS_PER_MS } from \"@graphrefly/graphrefly-ts\";\n *\n * // Delays: 100 ms, 200 ms, 300 ms, 500 ms, 800 ms … (× 100 ms base)\n * const out = retry(source, { count: 5, backoff: fibonacci(100 * NS_PER_MS) });\n * ```\n *\n * @category extra\n */\nexport function fibonacci(baseNs = 100 * NS_PER_MS, maxDelayNs = 30 * NS_PER_SEC): BackoffStrategy {\n\tconst safeBase = clampNonNegative(baseNs);\n\tconst safeMax = clampNonNegative(maxDelayNs);\n\n\tfunction fibUnit(attempt: number): number {\n\t\tif (attempt <= 0) return 1;\n\t\tlet prev = 1;\n\t\tlet cur = 2;\n\t\tfor (let i = 1; i < attempt; i++) {\n\t\t\tconst next = prev + cur;\n\t\t\tprev = cur;\n\t\t\tcur = next;\n\t\t}\n\t\treturn cur;\n\t}\n\n\treturn (attempt: number) => {\n\t\tconst raw = fibUnit(attempt) * safeBase;\n\t\treturn raw <= safeMax ? raw : safeMax;\n\t};\n}\n\n/**\n * Decorrelated jitter (AWS-recommended): `random(baseNs, min(maxNs, lastDelay * 3))`.\n *\n * Stateless — uses `prevDelayNs` (passed by the consumer) instead of closure state.\n * Safe to share across concurrent retry sequences.\n *\n * @param baseNs - Floor of the random range (default `100ms` in nanoseconds).\n * @param maxNs - Ceiling cap (default `30s` in nanoseconds).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { decorrelatedJitter, retry, NS_PER_MS, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, {\n * count: 6,\n * backoff: decorrelatedJitter(100 * NS_PER_MS, 10 * NS_PER_SEC),\n * });\n * ```\n *\n * @category extra\n */\nexport function decorrelatedJitter(\n\tbaseNs = 100 * NS_PER_MS,\n\tmaxNs = 30 * NS_PER_SEC,\n): BackoffStrategy {\n\treturn (_attempt, _error, prevDelayNs) => {\n\t\tconst last = prevDelayNs ?? baseNs;\n\t\tconst ceiling = Math.min(maxNs, last * 3);\n\t\treturn randomBetween(baseNs, ceiling);\n\t};\n}\n\n/**\n * Decorator that caps any strategy at `maxAttempts`. Returns `null` (stop retrying) after the cap.\n *\n * @param strategy - Inner strategy to wrap.\n * @param maxAttempts - Maximum number of attempts (inclusive).\n * @returns Wrapped `BackoffStrategy`.\n *\n * @example\n * ```ts\n * import { withMaxAttempts, exponential } from \"@graphrefly/graphrefly-ts\";\n *\n * const capped = withMaxAttempts(exponential(), 3);\n * capped(3); // null — no more retries beyond attempt 3\n * ```\n *\n * @category extra\n */\nexport function withMaxAttempts(strategy: BackoffStrategy, maxAttempts: number): BackoffStrategy {\n\treturn (attempt, error, prevDelayNs) => {\n\t\tif (attempt >= maxAttempts) return null;\n\t\treturn strategy(attempt, error, prevDelayNs);\n\t};\n}\n\n/**\n * Maps a preset name to a concrete {@link BackoffStrategy} with library-default parameters.\n *\n * @param name - One of `constant`, `linear`, `exponential`, `fibonacci`, or `decorrelatedJitter`.\n * @returns Configured strategy with default parameters.\n * @throws Error when `name` is not a known preset.\n *\n * @example\n * ```ts\n * import { resolveBackoffPreset, retry } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, { count: 3, backoff: resolveBackoffPreset(\"exponential\") });\n * // Equivalent to retry(source, { count: 3, backoff: exponential() })\n * ```\n *\n * @category extra\n */\nexport function resolveBackoffPreset(name: BackoffPreset): BackoffStrategy {\n\tif (name === \"constant\") return constant(1 * NS_PER_SEC);\n\tif (name === \"linear\") return linear(1 * NS_PER_SEC);\n\tif (name === \"exponential\") return exponential();\n\tif (name === \"fibonacci\") return fibonacci();\n\tif (name === \"decorrelatedJitter\") return decorrelatedJitter();\n\tthrow new Error(\n\t\t`Unknown backoff preset: \"${String(name)}\". Use one of: constant, linear, exponential, fibonacci, decorrelatedJitter`,\n\t);\n}\n","/**\n * External-register helpers — the common `register({emit, error, complete})`\n * contract shared by webhook, MCP, syslog, StatsD, OTel and other callback-\n * based integrations. Absorbs the `active` flag that every such adapter needs\n * to guard against emits after teardown (§5.10 boundary pattern).\n *\n * Two shapes:\n *\n * - {@link externalProducer} — single channel. Lazy activation: the register\n * fn runs when the node gains its first subscriber; its returned cleanup\n * runs on deactivation.\n *\n * - {@link externalBundle} — multiple named channels. Eager activation: the\n * register fn runs at bundle construction time so externally-owned servers\n * (HTTP endpoints, UDP sockets) start accepting traffic immediately. A\n * shared refcount fires the returned cleanup once every channel has fully\n * torn down.\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { COMPLETE, DATA, ERROR } from \"../core/messages.js\";\nimport type { Node, NodeOptions } from \"../core/node.js\";\nimport { producer } from \"../core/sugar.js\";\n\ntype ExtraOpts = Omit<NodeOptions<unknown>, \"describeKind\">;\n\nfunction sourceOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\n\n/**\n * Standard emit-triad passed to a single-channel external registrar.\n *\n * Post-teardown calls on any of these are automatically no-ops — the\n * registrar does not need its own guard flag.\n *\n * @category extra\n */\nexport type EmitTriad<T> = {\n\t/** Emit a value as `DATA`. */\n\temit: (value: T) => void;\n\t/** Terminate with `ERROR`. Subsequent `emit` / `error` / `complete` are ignored. */\n\terror: (err: unknown) => void;\n\t/** Terminate with `COMPLETE`. Subsequent `emit` / `error` / `complete` are ignored. */\n\tcomplete: () => void;\n};\n\n/**\n * Multi-channel emit bundle. Each declared channel name maps to an emit fn;\n * `error` and `complete` terminate every channel atomically.\n *\n * @category extra\n */\nexport type BundleTriad<TChannels extends Record<string, unknown>> = {\n\t[K in keyof TChannels]: (value: TChannels[K]) => void;\n} & {\n\t/** Terminate every channel with `ERROR`. */\n\terror: (err: unknown) => void;\n\t/** Terminate every channel with `COMPLETE`. */\n\tcomplete: () => void;\n};\n\n/**\n * Generic external registrator contract. The caller installs handlers into a\n * third-party library / framework / server and optionally returns a cleanup\n * callback. Returning `undefined` / `void` is equivalent to a no-op cleanup.\n *\n * @category extra\n */\nexport type ExternalRegister<H> = (handlers: H) => (() => void) | undefined;\n\n/**\n * Wraps a callback-style external integration as a reactive source.\n *\n * The registrar installs the supplied `emit` / `error` / `complete` handlers\n * into the external SDK; post-teardown calls are silently dropped. Synchronous\n * exceptions thrown by the registrar surface as terminal `ERROR`.\n *\n * @param register - Installs handlers. Optionally returns a cleanup fn.\n * @param opts - Node options (name, equals, resubscribable, ...).\n *\n * @example\n * ```ts\n * import { externalProducer } from \"@graphrefly/graphrefly-ts\";\n *\n * const hook$ = externalProducer<Payload>(({ emit, error }) => {\n * const id = transport.onMessage((raw) => {\n * try { emit(parse(raw)); } catch (e) { error(e); }\n * });\n * return () => transport.off(id);\n * });\n * ```\n *\n * @category extra\n */\nexport function externalProducer<T = unknown>(\n\tregister: ExternalRegister<EmitTriad<T>>,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet active = true;\n\t\tconst triad: EmitTriad<T> = {\n\t\t\temit(value) {\n\t\t\t\tif (!active) return;\n\t\t\t\ta.emit(value);\n\t\t\t},\n\t\t\terror(err) {\n\t\t\t\tif (!active) return;\n\t\t\t\tactive = false;\n\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t},\n\t\t\tcomplete() {\n\t\t\t\tif (!active) return;\n\t\t\t\tactive = false;\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t},\n\t\t};\n\t\tlet cleanup: (() => void) | undefined;\n\t\ttry {\n\t\t\tconst ret = register(triad);\n\t\t\tcleanup = typeof ret === \"function\" ? ret : undefined;\n\t\t} catch (err) {\n\t\t\ttriad.error(err);\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t}\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\ttry {\n\t\t\t\tcleanup?.();\n\t\t\t} catch {\n\t\t\t\t/* registrar cleanup failure is not a reactive signal */\n\t\t\t}\n\t\t};\n\t}, sourceOpts(opts));\n}\n\n/**\n * Options for {@link externalBundle}.\n *\n * @category extra\n */\nexport type ExternalBundleOptions<TChannels extends Record<string, unknown>> = {\n\t/** Base name prefix for channel nodes; each node is named `${name}::${channel}`. */\n\tname?: string;\n\t/** Per-channel node options (equals, resubscribable, ...). */\n\tchannelOpts?: { [K in keyof TChannels]?: ExtraOpts };\n};\n\n/**\n * Multi-channel variant — one `Node<T>` per named channel, sharing a single\n * registrar. Activation is eager: the registrar runs at construction time so\n * externally-owned servers (HTTP, UDP, queue consumers) can start accepting\n * traffic immediately. The returned cleanup fires once every channel has been\n * subscribed and then fully deactivated (refcount-on-teardown).\n *\n * Any call to `error` or `complete` propagates to every channel atomically.\n *\n * @param register - Installs handlers for each channel plus shared error/complete.\n * @param channels - Ordered channel names; determines the returned object shape.\n * @param opts - Optional name prefix and per-channel node options.\n *\n * @example\n * ```ts\n * import { externalBundle } from \"@graphrefly/graphrefly-ts\";\n *\n * type OTelChannels = { traces: Span; metrics: Metric; logs: LogRec };\n * const otel = externalBundle<OTelChannels>(\n * ({ traces, metrics, logs, error }) => {\n * app.post(\"/v1/traces\", (req, res) => { traces(req.body); res.sendStatus(200); });\n * app.post(\"/v1/metrics\", (req, res) => { metrics(req.body); res.sendStatus(200); });\n * app.post(\"/v1/logs\", (req, res) => { logs(req.body); res.sendStatus(200); });\n * server.on(\"error\", error);\n * return () => server.close();\n * },\n * [\"traces\", \"metrics\", \"logs\"],\n * );\n * otel.traces.subscribe(...);\n * ```\n *\n * @category extra\n */\nexport function externalBundle<TChannels extends Record<string, unknown>>(\n\tregister: ExternalRegister<BundleTriad<TChannels>>,\n\tchannels: readonly (keyof TChannels & string)[],\n\topts?: ExternalBundleOptions<TChannels>,\n): { [K in keyof TChannels]: Node<TChannels[K]> } & { dispose(): void } {\n\tlet active = true;\n\tlet cleanup: (() => void) | undefined;\n\tlet activatedCount = 0;\n\tlet teardownCount = 0;\n\n\tconst nodes = {} as { [K in keyof TChannels]: Node<TChannels[K]> };\n\tconst channelNodes: Array<Node<unknown>> = [];\n\n\tconst finishCleanup = () => {\n\t\tconst fn = cleanup;\n\t\tcleanup = undefined;\n\t\ttry {\n\t\t\tfn?.();\n\t\t} catch {\n\t\t\t/* registrar cleanup failure is not a reactive signal */\n\t\t}\n\t};\n\n\tfor (const ch of channels) {\n\t\tconst name = opts?.name ? `${opts.name}::${ch}` : ch;\n\t\tconst chOpts = opts?.channelOpts?.[ch];\n\t\tconst n = producer<TChannels[typeof ch]>(\n\t\t\t(_a) => {\n\t\t\t\tactivatedCount++;\n\t\t\t\treturn () => {\n\t\t\t\t\tteardownCount++;\n\t\t\t\t\t// Cleanup fires once every channel has activated at least once\n\t\t\t\t\t// and then deactivated. Channels that never subscribe do not\n\t\t\t\t\t// gate cleanup — use the explicit `.dispose()` method for\n\t\t\t\t\t// unconditional teardown.\n\t\t\t\t\tif (\n\t\t\t\t\t\tactivatedCount > 0 &&\n\t\t\t\t\t\tteardownCount >= activatedCount &&\n\t\t\t\t\t\tteardownCount >= channels.length\n\t\t\t\t\t) {\n\t\t\t\t\t\tfinishCleanup();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\t\t\tsourceOpts({ ...chOpts, name }),\n\t\t);\n\t\tnodes[ch as keyof TChannels] = n as Node<TChannels[typeof ch]>;\n\t\tchannelNodes.push(n as Node<unknown>);\n\t}\n\n\tconst bundle = {} as BundleTriad<TChannels>;\n\tfor (const ch of channels) {\n\t\t(bundle as Record<string, unknown>)[ch] = (value: unknown) => {\n\t\t\tif (!active) return;\n\t\t\t(nodes[ch as keyof TChannels] as Node<unknown>).down([[DATA, value]]);\n\t\t};\n\t}\n\tbundle.error = (err: unknown) => {\n\t\tif (!active) return;\n\t\tactive = false;\n\t\tbatch(() => {\n\t\t\tfor (const n of channelNodes) n.down([[ERROR, err]]);\n\t\t});\n\t\tfinishCleanup();\n\t};\n\tbundle.complete = () => {\n\t\tif (!active) return;\n\t\tactive = false;\n\t\tbatch(() => {\n\t\t\tfor (const n of channelNodes) n.down([[COMPLETE]]);\n\t\t});\n\t\tfinishCleanup();\n\t};\n\n\t// Eager activation — register fires at construction time so externally-\n\t// owned servers can start accepting traffic immediately. Synchronous throws\n\t// propagate to the caller (no subscribers exist yet, so there is no\n\t// reactive ERROR path to deliver to). This matches the existing `fromOTel`\n\t// contract.\n\tconst ret = register(bundle);\n\tcleanup = typeof ret === \"function\" ? ret : undefined;\n\n\tconst dispose = () => {\n\t\tif (!active) return;\n\t\tactive = false;\n\t\t// Fire COMPLETE on every channel so downstream sees a clean terminal.\n\t\tbatch(() => {\n\t\t\tfor (const n of channelNodes) {\n\t\t\t\ttry {\n\t\t\t\t\tn.down([[COMPLETE]]);\n\t\t\t\t} catch {\n\t\t\t\t\t/* terminal filter / re-entrance — swallow */\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tfinishCleanup();\n\t};\n\n\treturn Object.assign(nodes, { dispose });\n}\n","/**\n * Core reactive sources, sinks, and utilities (roadmap §2.3).\n *\n * Each API returns a {@link Node} built with {@link node}, {@link producer},\n * {@link derived}, or {@link effect} — no second protocol.\n *\n * Protocol/system/ingest adapters (fromHTTP, fromWebSocket, fromKafka, etc.)\n * live in {@link ./adapters.ts}.\n */\n\nimport { existsSync, watch } from \"node:fs\";\nimport { resolve as resolvePath } from \"node:path\";\nimport { wallClockNs } from \"../core/clock.js\";\nimport { COMPLETE, DATA, DIRTY, ERROR, type Message, RESOLVED } from \"../core/messages.js\";\nimport { type Node, type NodeOptions, type NodeSink, node } from \"../core/node.js\";\nimport { producer, state } from \"../core/sugar.js\";\nimport { type CronSchedule, matchesCron, parseCron } from \"./cron.js\";\n\ntype ExtraOpts = Omit<NodeOptions<unknown>, \"describeKind\">;\n\nfunction sourceOpts<T = unknown>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\n\n/** Options for {@link fromTimer} / {@link fromPromise} / {@link fromAsyncIter}. */\nexport type AsyncSourceOpts = ExtraOpts & { signal?: AbortSignal };\n\n/**\n * Values accepted by {@link fromAny}.\n *\n * @category extra\n */\nexport type NodeInput<T> = Node<T> | PromiseLike<T> | AsyncIterable<T> | Iterable<T> | T;\n\n/** Options for {@link fromCron}. */\nexport type FromCronOptions = ExtraOpts & {\n\t/** Polling interval in ms. Default `60_000`. */\n\ttickMs?: number;\n\t/** Output format: `\"timestamp_ns\"` (default) emits wall-clock nanoseconds; `\"date\"` emits a `Date` object. */\n\toutput?: \"timestamp_ns\" | \"date\";\n};\n\n/** DOM-style event target (browser or `node:events`). */\nexport type EventTargetLike = {\n\taddEventListener(\n\t\ttype: string,\n\t\tlistener: (ev: unknown) => void,\n\t\toptions?: boolean | { capture?: boolean; passive?: boolean; once?: boolean },\n\t): void;\n\tremoveEventListener(\n\t\ttype: string,\n\t\tlistener: (ev: unknown) => void,\n\t\toptions?: boolean | { capture?: boolean; passive?: boolean; once?: boolean },\n\t): void;\n};\n\nexport type FSEventType = \"change\" | \"rename\" | \"create\" | \"delete\";\nexport type FSEvent = {\n\ttype: FSEventType;\n\tpath: string;\n\troot: string;\n\trelative_path: string;\n\tsrc_path?: string;\n\tdest_path?: string;\n\ttimestamp_ns: number;\n};\n\nexport type FromFSWatchOptions = ExtraOpts & {\n\trecursive?: boolean;\n\tdebounce?: number;\n\tinclude?: string[];\n\texclude?: string[];\n};\n\n/** @internal Shared with adapters.ts for glob matching in fromFSWatch / fromGitHook. */\nexport function escapeRegexChar(ch: string): string {\n\treturn /[\\\\^$+?.()|[\\]{}]/.test(ch) ? `\\\\${ch}` : ch;\n}\n\n/** @internal */\nexport function globToRegExp(glob: string): RegExp {\n\tlet out = \"^\";\n\tfor (let i = 0; i < glob.length; i += 1) {\n\t\tconst ch = glob[i];\n\t\tif (ch === \"*\") {\n\t\t\tconst next = glob[i + 1];\n\t\t\tif (next === \"*\") {\n\t\t\t\tout += \".*\";\n\t\t\t\ti += 1;\n\t\t\t} else {\n\t\t\t\tout += \"[^/]*\";\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tout += escapeRegexChar(ch);\n\t}\n\tout += \"$\";\n\treturn new RegExp(out);\n}\n\n/** @internal */\nexport function matchesAnyPattern(path: string, patterns: RegExp[]): boolean {\n\tfor (const pattern of patterns) {\n\t\tif (pattern.test(path)) return true;\n\t}\n\treturn false;\n}\n\nfunction wrapSubscribeHook<T>(inner: Node<T>, before: (sink: NodeSink) => void): Node<T> {\n\t// node() passthrough instead of derived([inner], ([v]) => v) — derived uses\n\t// .at(-1) and would drop intermediate values from multi-DATA batches (D1 gap).\n\tconst wrapper = node<T>(\n\t\t[inner as Node],\n\t\t(data, a) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) a.emit(v as T);\n\t\t},\n\t\t{ describeKind: \"derived\", initial: inner.cache as T },\n\t);\n\tconst origSubscribe = wrapper.subscribe.bind(wrapper);\n\t(wrapper as { subscribe: typeof wrapper.subscribe }).subscribe = (sink, actor) => {\n\t\tbefore(sink);\n\t\treturn origSubscribe(sink, actor);\n\t};\n\treturn wrapper;\n}\n\n/**\n * Builds a timer-driven source: one-shot (first tick then `COMPLETE`) or periodic (`0`, `1`, `2`, …).\n *\n * @param ms - Milliseconds before the first emission.\n * @param opts - Producer options plus optional `period` for repeating ticks and optional `signal` (`AbortSignal`) to cancel with `ERROR`.\n * @returns `Node<number>` — tick counter from `0`; teardown clears timers.\n *\n * @example\n * ```ts\n * import { fromTimer } from \"@graphrefly/graphrefly-ts\";\n *\n * fromTimer(250, { period: 1_000 });\n * ```\n *\n * @category extra\n */\nexport function fromTimer(ms: number, opts?: AsyncSourceOpts & { period?: number }): Node<number> {\n\tconst { signal, period, ...rest } = opts ?? {};\n\treturn producer<number>((a) => {\n\t\tlet done = false;\n\t\tlet count = 0;\n\t\tlet t: ReturnType<typeof setTimeout> | undefined;\n\t\tlet iv: ReturnType<typeof setInterval> | undefined;\n\t\tconst cleanup = () => {\n\t\t\tdone = true;\n\t\t\tif (t !== undefined) clearTimeout(t);\n\t\t\tif (iv !== undefined) clearInterval(iv);\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\t\tconst finish = () => {\n\t\t\tif (done) return;\n\t\t\tif (period != null) {\n\t\t\t\ta.emit(count++);\n\t\t\t\tiv = setInterval(() => {\n\t\t\t\t\tif (done) return;\n\t\t\t\t\ta.emit(count++);\n\t\t\t\t}, period);\n\t\t\t} else {\n\t\t\t\t// One-shot: mark done, emit, complete synchronously.\n\t\t\t\t// a.emit() delivers DATA to downstream synchronously before\n\t\t\t\t// COMPLETE arrives — no queueMicrotask needed.\n\t\t\t\tdone = true;\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\ta.emit(count++);\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t}\n\t\t};\n\t\tconst onAbort = () => {\n\t\t\tif (done) return;\n\t\t\tcleanup();\n\t\t\ta.down([[ERROR, signal!.reason]]);\n\t\t};\n\t\tif (signal?.aborted) {\n\t\t\tonAbort();\n\t\t\treturn;\n\t\t}\n\t\tt = setTimeout(finish, ms);\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\treturn cleanup;\n\t}, sourceOpts(rest));\n}\n\n/**\n * Polls on an interval; when the current minute matches a 5-field cron expression, emits once (see {@link parseCron}).\n *\n * @param expr - Cron string (`min hour dom month dow`).\n * @param opts - Producer options plus `tickMs` (default `60_000`) and `output` (`timestamp_ns` default, or `date` for `Date` values).\n * @returns `Node<number>` (nanosecond timestamp) or `Node<Date>` when `output: \"date\"`.\n *\n * @example\n * ```ts\n * import { fromCron } from \"@graphrefly/graphrefly-ts\";\n *\n * fromCron(\"0 9 * * 1\");\n * ```\n *\n * @category extra\n */\nexport function fromCron(expr: string, opts?: FromCronOptions & { output: \"date\" }): Node<Date>;\nexport function fromCron(expr: string, opts?: FromCronOptions): Node<number>;\nexport function fromCron(expr: string, opts?: FromCronOptions): Node<number | Date> {\n\tconst schedule: CronSchedule = parseCron(expr);\n\tconst { tickMs: tickOpt, output, ...rest } = opts ?? {};\n\tconst tickMs = tickOpt ?? 60_000;\n\tconst emitDate = output === \"date\";\n\treturn producer<number | Date>(\n\t\t(a) => {\n\t\t\tlet lastFiredKey = -1;\n\t\t\tconst check = () => {\n\t\t\t\tconst now = new Date();\n\t\t\t\tconst key =\n\t\t\t\t\tnow.getFullYear() * 100_000_000 +\n\t\t\t\t\t(now.getMonth() + 1) * 1_000_000 +\n\t\t\t\t\tnow.getDate() * 10_000 +\n\t\t\t\t\tnow.getHours() * 100 +\n\t\t\t\t\tnow.getMinutes();\n\t\t\t\tif (key !== lastFiredKey && matchesCron(schedule, now)) {\n\t\t\t\t\tlastFiredKey = key;\n\t\t\t\t\ta.emit(emitDate ? now : wallClockNs());\n\t\t\t\t}\n\t\t\t};\n\t\t\tcheck();\n\t\t\tconst id = setInterval(check, tickMs);\n\t\t\treturn () => clearInterval(id);\n\t\t},\n\t\t{ ...sourceOpts(rest), name: rest.name ?? `cron:${expr}` },\n\t);\n}\n\n/**\n * Wraps a DOM-style `addEventListener` target; each event becomes a `DATA` emission.\n *\n * @param target - Object with `addEventListener` / `removeEventListener`.\n * @param type - Event name (e.g. `\"click\"`).\n * @param opts - Producer options plus listener options (`capture`, `passive`, `once`).\n * @returns `Node<T>` — event payloads; teardown removes the listener.\n *\n * @example\n * ```ts\n * import { fromEvent } from \"@graphrefly/graphrefly-ts\";\n *\n * fromEvent(document.body, \"click\");\n * ```\n *\n * @category extra\n */\nexport function fromEvent<T = unknown>(\n\ttarget: EventTargetLike,\n\ttype: string,\n\topts?: ExtraOpts & { capture?: boolean; passive?: boolean; once?: boolean },\n): Node<T> {\n\tconst { capture, passive, once, ...rest } = opts ?? {};\n\treturn producer<T>((a) => {\n\t\tconst handler = (e: unknown) => {\n\t\t\ta.emit(e as T);\n\t\t};\n\t\tconst options = { capture, passive, once };\n\t\ttarget.addEventListener(type, handler, options);\n\t\treturn () => target.removeEventListener(type, handler, options);\n\t}, sourceOpts(rest));\n}\n\n/**\n * Watches filesystem paths and emits debounced change events.\n *\n * Uses `fs.watch` only (no polling fallback). Teardown closes all watchers.\n *\n * @category extra\n */\nexport function fromFSWatch(paths: string | string[], opts?: FromFSWatchOptions): Node<FSEvent> {\n\tconst list = Array.isArray(paths) ? paths : [paths];\n\tif (list.length === 0) {\n\t\tthrow new RangeError(\"fromFSWatch expects at least one path\");\n\t}\n\tconst { recursive = true, debounce = 100, include, exclude, ...rest } = opts ?? {};\n\tconst includePatterns = include?.map(globToRegExp) ?? [];\n\tconst excludePatterns = (exclude ?? [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\"]).map(\n\t\tglobToRegExp,\n\t);\n\treturn producer<FSEvent>((a) => {\n\t\tconst pending = new Map<string, FSEvent>();\n\t\tconst watchers: ReturnType<typeof watch>[] = [];\n\t\tlet stopped = false;\n\t\tlet terminalEmitted = false;\n\t\tlet generation = 0;\n\t\tconst closeWatchers = () => {\n\t\t\tfor (const watcher of watchers.splice(0)) watcher.close();\n\t\t};\n\t\tconst emitError = (err: unknown) => {\n\t\t\tif (terminalEmitted) return;\n\t\t\tterminalEmitted = true;\n\t\t\tstopped = true;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t\tpending.clear();\n\t\t\tcloseWatchers();\n\t\t\ta.down([[ERROR, err]]);\n\t\t};\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tconst flush = (token: number) => {\n\t\t\ttimer = undefined;\n\t\t\tif (stopped || terminalEmitted) return;\n\t\t\tif (pending.size === 0) return;\n\t\t\tconst batchMessages: Message[] = [];\n\t\t\tfor (const evt of pending.values()) batchMessages.push([DATA, evt]);\n\t\t\tpending.clear();\n\t\t\tif (stopped || terminalEmitted || token !== generation) return;\n\t\t\ta.down(batchMessages);\n\t\t};\n\t\ttry {\n\t\t\tfor (const basePath of list) {\n\t\t\t\tconst watcher = watch(\n\t\t\t\t\tbasePath,\n\t\t\t\t\t{ recursive },\n\t\t\t\t\t(eventType: \"rename\" | \"change\", fileName: string | Buffer | null) => {\n\t\t\t\t\t\tif (stopped || terminalEmitted) return;\n\t\t\t\t\t\tif (fileName == null) return;\n\t\t\t\t\t\tconst rel = String(fileName).replaceAll(\"\\\\\", \"/\");\n\t\t\t\t\t\tconst abs = resolvePath(basePath, String(fileName));\n\t\t\t\t\t\tconst normalized = abs.replaceAll(\"\\\\\", \"/\");\n\t\t\t\t\t\tconst root = resolvePath(basePath).replaceAll(\"\\\\\", \"/\");\n\t\t\t\t\t\tconst relForMatch = rel.startsWith(\"./\") ? rel.slice(2) : rel;\n\t\t\t\t\t\tconst included =\n\t\t\t\t\t\t\tincludePatterns.length === 0 ||\n\t\t\t\t\t\t\tmatchesAnyPattern(normalized, includePatterns) ||\n\t\t\t\t\t\t\tmatchesAnyPattern(relForMatch, includePatterns);\n\t\t\t\t\t\tif (!included) return;\n\t\t\t\t\t\tconst excluded =\n\t\t\t\t\t\t\tmatchesAnyPattern(normalized, excludePatterns) ||\n\t\t\t\t\t\t\tmatchesAnyPattern(relForMatch, excludePatterns);\n\t\t\t\t\t\tif (excluded) return;\n\t\t\t\t\t\tlet kind: FSEventType = \"change\";\n\t\t\t\t\t\tif (eventType === \"rename\") {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tkind = existsSync(normalized) ? \"create\" : \"delete\";\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tkind = \"rename\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpending.set(normalized, {\n\t\t\t\t\t\t\ttype: kind,\n\t\t\t\t\t\t\tpath: normalized,\n\t\t\t\t\t\t\troot,\n\t\t\t\t\t\t\trelative_path: relForMatch,\n\t\t\t\t\t\t\ttimestamp_ns: wallClockNs(),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\t\t\t\tconst token = generation;\n\t\t\t\t\t\ttimer = setTimeout(() => flush(token), debounce);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\twatcher.on(\"error\", (err) => emitError(err));\n\t\t\t\twatchers.push(watcher);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\temitError(err);\n\t\t}\n\t\treturn () => {\n\t\t\tstopped = true;\n\t\t\tgeneration += 1;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t\tcloseWatchers();\n\t\t\tpending.clear();\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/**\n * Drains a synchronous iterable; each item is `DATA`, then `COMPLETE`, or `ERROR` if iteration throws.\n *\n * @param iterable - Values to emit in order.\n * @param opts - Optional producer options.\n * @returns `Node<T>` — one emission per element.\n *\n * @example\n * ```ts\n * import { fromIter } from \"@graphrefly/graphrefly-ts\";\n *\n * fromIter([1, 2, 3]);\n * ```\n *\n * @category extra\n */\nexport function fromIter<T>(iterable: Iterable<T>, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet cancelled = false;\n\t\ttry {\n\t\t\tfor (const x of iterable) {\n\t\t\t\tif (cancelled) return;\n\t\t\t\ta.emit(x);\n\t\t\t}\n\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t} catch (e) {\n\t\t\tif (!cancelled) a.down([[ERROR, e]]);\n\t\t}\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, sourceOpts(opts));\n}\n\nfunction isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\n/**\n * Lifts a Promise (or thenable) to a single-value stream: one `DATA` then `COMPLETE`, or `ERROR` on rejection.\n *\n * @param p - Promise to await.\n * @param opts - Producer options plus optional `signal` for abort → `ERROR` with reason.\n * @returns `Node<T>` — settles once.\n *\n * @example\n * ```ts\n * import { fromPromise } from \"@graphrefly/graphrefly-ts\";\n *\n * fromPromise(Promise.resolve(42));\n * ```\n *\n * @category extra\n */\nexport function fromPromise<T>(p: Promise<T> | PromiseLike<T>, opts?: AsyncSourceOpts): Node<T> {\n\tconst { signal, ...rest } = opts ?? {};\n\treturn producer<T>((a) => {\n\t\tlet settled = false;\n\t\tconst onAbort = () => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\ta.down([[ERROR, signal!.reason]]);\n\t\t};\n\t\tif (signal?.aborted) {\n\t\t\tonAbort();\n\t\t\treturn;\n\t\t}\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tvoid Promise.resolve(p).then(\n\t\t\t(v) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\ta.emit(v as T);\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t},\n\t\t\t(e) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\ta.down([[ERROR, e]]);\n\t\t\t},\n\t\t);\n\t\treturn () => {\n\t\t\tsettled = true;\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/**\n * Reads an async iterable; each `next()` value becomes `DATA`; `COMPLETE` when done; `ERROR` on failure.\n *\n * @param iterable - Async source (`for await` shape).\n * @param opts - Producer options plus optional `signal` to abort the pump.\n * @returns `Node<T>` — async pull stream.\n *\n * @example\n * ```ts\n * import { fromAsyncIter } from \"@graphrefly/graphrefly-ts\";\n *\n * async function* gen() {\n * yield 1;\n * }\n * fromAsyncIter(gen());\n * ```\n *\n * @category extra\n */\nexport function fromAsyncIter<T>(iterable: AsyncIterable<T>, opts?: AsyncSourceOpts): Node<T> {\n\tconst { signal: outerSignal, ...rest } = opts ?? {};\n\treturn producer<T>((a) => {\n\t\tconst ac = new AbortController();\n\t\tconst onOuterAbort = () => ac.abort(outerSignal?.reason);\n\t\tif (outerSignal?.aborted) {\n\t\t\tac.abort(outerSignal.reason);\n\t\t} else {\n\t\t\touterSignal?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\t\t}\n\t\tconst signal = outerSignal ?? ac.signal;\n\t\tlet cancelled = false;\n\t\tconst it = iterable[Symbol.asyncIterator]();\n\t\t// Each pump() call chains directly into the next via Promise.then —\n\t\t// no queueMicrotask needed; Promise resolution already yields to the\n\t\t// microtask queue. COMPLETE is delivered synchronously after the last\n\t\t// value, same as fromIter semantics.\n\t\tconst pump = (): void => {\n\t\t\tif (cancelled || signal.aborted) return;\n\t\t\tvoid Promise.resolve(it.next()).then(\n\t\t\t\t(step) => {\n\t\t\t\t\tif (cancelled || signal.aborted) return;\n\t\t\t\t\tif (step.done) {\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\ta.emit(step.value as T);\n\t\t\t\t\tpump();\n\t\t\t\t},\n\t\t\t\t(e) => {\n\t\t\t\t\tif (!cancelled && !signal.aborted) a.down([[ERROR, e]]);\n\t\t\t\t},\n\t\t\t);\n\t\t};\n\t\tpump();\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t\touterSignal?.removeEventListener(\"abort\", onOuterAbort);\n\t\t\tac.abort();\n\t\t\tvoid Promise.resolve(it.return?.()).catch(() => undefined);\n\t\t};\n\t}, sourceOpts(rest));\n}\n\nfunction isNode(x: unknown): x is Node {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\t\"cache\" in x &&\n\t\ttypeof (x as Node).subscribe === \"function\"\n\t);\n}\n\n/**\n * Coerces a value to a `Node` by shape: existing `Node` passthrough, thenable → {@link fromPromise},\n * async iterable → {@link fromAsyncIter}, sync iterable → {@link fromIter}, else scalar → {@link of}.\n *\n * @param input - Any value to wrap.\n * @param opts - Passed through when a Promise/async path is chosen.\n * @returns `Node` of the inferred element type.\n *\n * @example\n * ```ts\n * import { fromAny, state } from \"@graphrefly/graphrefly-ts\";\n *\n * fromAny(state(1));\n * fromAny(Promise.resolve(2));\n * ```\n *\n * @category extra\n */\nexport function fromAny<T>(input: NodeInput<T>, opts?: AsyncSourceOpts): Node<T> {\n\tif (isNode(input)) {\n\t\treturn input as Node<T>;\n\t}\n\tif (isThenable(input)) {\n\t\treturn fromPromise(input as PromiseLike<T>, opts);\n\t}\n\tif (input !== null && input !== undefined) {\n\t\tconst candidate = input as { [Symbol.asyncIterator]?: unknown; [Symbol.iterator]?: unknown };\n\t\tif (typeof candidate[Symbol.asyncIterator] === \"function\") {\n\t\t\treturn fromAsyncIter(input as AsyncIterable<T>, opts);\n\t\t}\n\t\tif (typeof candidate[Symbol.iterator] === \"function\") {\n\t\t\treturn fromIter(input as Iterable<T>, opts);\n\t\t}\n\t}\n\t// scalar fallback\n\treturn of(input as T);\n}\n\n/**\n * Emits each argument as `DATA` in order, then `COMPLETE` (implemented via {@link fromIter}).\n *\n * @param values - Values to emit.\n * @returns `Node<T>` — finite sequence.\n *\n * @example\n * ```ts\n * import { of } from \"@graphrefly/graphrefly-ts\";\n *\n * of(1, 2, 3);\n * ```\n *\n * @category extra\n */\nexport function of<T>(...values: T[]): Node<T> {\n\treturn fromIter(values, undefined);\n}\n\n/**\n * Completes immediately with no `DATA` (cold `EMPTY` analogue).\n *\n * @param opts - Optional producer options.\n * @returns `Node<T>` — terminal `COMPLETE` only.\n *\n * @example\n * ```ts\n * import { empty } from \"@graphrefly/graphrefly-ts\";\n *\n * empty();\n * ```\n *\n * @category extra\n */\nexport function empty<T = never>(opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\ta.down([[COMPLETE]]);\n\t\treturn undefined;\n\t}, sourceOpts(opts));\n}\n\n/**\n * Never emits and never completes until teardown (cold `NEVER` analogue).\n *\n * @param opts - Optional producer options.\n * @returns `Node<T>` — silent until unsubscribed.\n *\n * @example\n * ```ts\n * import { never } from \"@graphrefly/graphrefly-ts\";\n *\n * never();\n * ```\n *\n * @category extra\n */\nexport function never<T = never>(opts?: ExtraOpts): Node<T> {\n\treturn producer<T>(() => undefined, sourceOpts(opts));\n}\n\n/**\n * Emits `ERROR` as soon as the producer starts (cold error source).\n *\n * @param err - Error payload forwarded as `ERROR` data.\n * @param opts - Optional producer options.\n * @returns `Node<never>` — terminates with `ERROR`.\n *\n * @example\n * ```ts\n * import { throwError } from \"@graphrefly/graphrefly-ts\";\n *\n * throwError(new Error(\"fail\"));\n * ```\n *\n * @category extra\n */\nexport function throwError(err: unknown, opts?: ExtraOpts): Node<never> {\n\treturn producer<never>((a) => {\n\t\ta.down([[ERROR, err]]);\n\t\treturn undefined;\n\t}, sourceOpts(opts));\n}\n\n/**\n * Subscribes immediately and runs `fn` for each upstream `DATA`; returns unsubscribe.\n *\n * @param source - Upstream node.\n * @param fn - Side effect per value.\n * @param opts - Effect node options.\n * @returns Unsubscribe function (idempotent).\n *\n * @example\n * ```ts\n * import { forEach, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const u = forEach(state(1), (v) => console.log(v));\n * u();\n * ```\n *\n * @category extra\n */\nexport function forEach<T>(source: Node<T>, fn: (value: T) => void, opts?: ExtraOpts): () => void {\n\tconst inner = node(\n\t\t[source as Node],\n\t\t(data, _actions) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\tfor (const v of batch0) fn(v as T);\n\t\t\t}\n\t\t},\n\t\t{ describeKind: \"effect\", ...opts } as NodeOptions,\n\t);\n\treturn inner.subscribe(() => {});\n}\n\n/**\n * Buffers every `DATA`; on upstream `COMPLETE` emits one `DATA` with the full array then `COMPLETE`.\n *\n * @param source - Upstream node.\n * @param opts - Optional node options (derived describe kind).\n * @returns `Node<T[]>` — single array emission before completion.\n *\n * @example\n * ```ts\n * import { of, toArray } from \"@graphrefly/graphrefly-ts\";\n *\n * toArray(of(1, 2, 3));\n * ```\n *\n * @category extra\n */\nexport function toArray<T>(source: Node<T>, opts?: ExtraOpts): Node<T[]> {\n\treturn node<T[]>(\n\t\t[source as Node],\n\t\t(data, actions, ctx) => {\n\t\t\tif (!ctx.store.buf) ctx.store.buf = [];\n\t\t\tconst buf = ctx.store.buf as T[];\n\t\t\t// Accumulate DATA first — must happen before the COMPLETE check so\n\t\t\t// that a same-wave DATA+COMPLETE batch (e.g. fromTimer one-shot,\n\t\t\t// fromIter last item) is included in the emitted array.\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\tfor (const v of batch0) buf.push(v as T);\n\t\t\t}\n\t\t\t// COMPLETE: emit accumulated array then complete.\n\t\t\t// ERROR: autoError propagates; do NOT emit the partial buffer.\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tactions.emit([...buf]);\n\t\t\t\tactions.down([[COMPLETE]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// RESOLVED wave: propagate RESOLVED. Covers first-wave case; after first\n\t\t\t// call the pre-fn skip handles this automatically.\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tdescribeKind: \"derived\",\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\t...opts,\n\t\t} as NodeOptions<T[]>,\n\t);\n}\n\n/**\n * Multicasts upstream: one subscription to `source` while this wrapper has subscribers (via {@link producer}).\n *\n * @param source - Upstream node to share.\n * @param opts - Producer options; `initial` seeds from `source.cache` when set by factory.\n * @returns `Node<T>` — hot ref-counted bridge.\n *\n * @example\n * ```ts\n * import { share, state } from \"@graphrefly/graphrefly-ts\";\n *\n * share(state(0));\n * ```\n *\n * @category extra\n */\nexport function share<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>(\n\t\t(a) =>\n\t\t\tsource.subscribe((msgs) => {\n\t\t\t\ta.down(msgs);\n\t\t\t}),\n\t\t{ ...sourceOpts<T>(opts), initial: source.cache },\n\t);\n}\n\n/**\n * Like {@link share} with a bounded replay buffer: new subscribers receive the last `bufferSize`\n * `DATA` payloads (as separate batches) before live updates.\n *\n * @param source - Upstream node.\n * @param bufferSize - Maximum past values to replay (≥ 1).\n * @param opts - Producer options.\n * @returns `Node<T>` — multicast with replay on subscribe.\n *\n * @example\n * ```ts\n * import { replay, state } from \"@graphrefly/graphrefly-ts\";\n *\n * replay(state(0), 3);\n * ```\n *\n * @category extra\n */\nexport function replay<T>(source: Node<T>, bufferSize: number, opts?: ExtraOpts): Node<T> {\n\tif (bufferSize < 1) throw new RangeError(\"replay expects bufferSize >= 1\");\n\tconst buf: T[] = [];\n\tconst inner = producer<T>(\n\t\t(a) =>\n\t\t\tsource.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tbuf.push(m[1] as T);\n\t\t\t\t\t\tif (buf.length > bufferSize) buf.shift();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ta.down(msgs);\n\t\t\t}),\n\t\t{ ...sourceOpts<T>(opts), initial: source.cache },\n\t);\n\treturn wrapSubscribeHook(inner, (sink) => {\n\t\tfor (const v of buf) {\n\t\t\tsink([[DATA, v]]);\n\t\t}\n\t});\n}\n\n/**\n * {@link replay} with `bufferSize === 1` — replays the latest `DATA` to new subscribers.\n *\n * @param source - Upstream node.\n * @param opts - Producer options.\n * @returns `Node<T>` — share + last-value replay.\n *\n * @example\n * ```ts\n * import { cached, state } from \"@graphrefly/graphrefly-ts\";\n *\n * cached(state(0));\n * ```\n *\n * @category extra\n */\nexport function cached<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn replay(source, 1, opts);\n}\n\n/**\n * Converts the first `DATA` on `source` into a Promise; rejects on `ERROR` or `COMPLETE` without data.\n *\n * **Important:** This subscribes and waits for a **future** emission. Data that\n * has already flowed is gone and will not be seen. Call this *before* the upstream\n * emits, or use `source.cache` / `source.status` for already-cached state.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * @param source - Node to read once.\n * @returns Promise of the first value.\n *\n * @example\n * ```ts\n * import { firstValueFrom, of } from \"@graphrefly/graphrefly-ts\";\n *\n * await firstValueFrom(of(42));\n * ```\n *\n * @category extra\n */\nexport function firstValueFrom<T>(source: Node<T>): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tlet shouldUnsub = false;\n\t\tlet unsub: (() => void) | undefined;\n\t\tunsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (settled) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\tresolve(m[1] as T);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(m[1]);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(new Error(\"completed without DATA\"));\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tif (shouldUnsub) {\n\t\t\tunsub?.();\n\t\t\tunsub = undefined;\n\t\t}\n\t});\n}\n\n/**\n * Wait for the first DATA value from `source` that satisfies `predicate`.\n *\n * Subscribes directly and resolves on the first DATA value where\n * `predicate` returns true. Reactive, no polling. Use in tests and\n * bridging code where you need a single matching value as a Promise.\n *\n * **Important:** This only captures **future** emissions — data that has\n * already flowed through the node is gone. Call this *before* the upstream\n * emits. For already-cached values, use `source.cache` / `source.status`.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * ```ts\n * const val = await firstWhere(strategy.node, snap => snap.size > 0);\n * ```\n *\n * @category extra\n */\nexport function firstWhere<T>(source: Node<T>, predicate: (value: T) => boolean): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tlet shouldUnsub = false;\n\t\tlet unsub: (() => void) | undefined;\n\t\tunsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (settled) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tconst v = m[1] as T;\n\t\t\t\t\tif (predicate(v)) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tresolve(v);\n\t\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\t\tunsub();\n\t\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(m[1]);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(new Error(\"completed without matching value\"));\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tif (shouldUnsub) {\n\t\t\tunsub?.();\n\t\t\tunsub = undefined;\n\t\t}\n\t});\n}\n\n// ——————————————————————————————————————————————————————————————\n// RxJS-compatible aliases\n// ——————————————————————————————————————————————————————————————\n\n/**\n * RxJS-named alias for {@link replay} — multicast with a replay buffer of size `bufferSize`.\n *\n * @param source - Upstream node.\n * @param bufferSize - Replay depth (≥ 1).\n * @param opts - Producer options.\n * @returns Same behavior as `replay`.\n *\n * @example\n * ```ts\n * import { shareReplay, state } from \"@graphrefly/graphrefly-ts\";\n *\n * shareReplay(state(0), 5);\n * ```\n *\n * @category extra\n */\nexport const shareReplay = replay;\n\n// ---------------------------------------------------------------------------\n// keepalive\n// ---------------------------------------------------------------------------\n\n/**\n * Activate a compute node's upstream wiring without a real sink.\n *\n * Derived/effect nodes are lazy — they don't compute until at least one\n * subscriber exists (COMPOSITION-GUIDE §5). `keepalive` subscribes with an\n * empty sink so the node stays wired for `.cache` and upstream propagation.\n *\n * Returns the unsubscribe handle. Common usage:\n * `graph.addDisposer(keepalive(node))`.\n *\n * @category extra\n */\nexport function keepalive(n: Node<unknown>): () => void {\n\treturn n.subscribe(() => {});\n}\n\n// ---------------------------------------------------------------------------\n// reactiveCounter\n// ---------------------------------------------------------------------------\n\n/** Bundle returned by {@link reactiveCounter}. */\nexport type ReactiveCounterBundle = {\n\t/** Reactive node holding the current count. */\n\treadonly node: Node<number>;\n\t/** Increment by 1. Returns `false` if cap would be exceeded. */\n\tincrement(): boolean;\n\t/** Current count (synchronous read). */\n\tget(): number;\n\t/** Whether the counter has reached its cap. */\n\tatCap(): boolean;\n};\n\n/**\n * Reactive counter with a cap — the building block for circuit breakers.\n *\n * Wraps a `state(0)` node with `increment()` that respects a maximum.\n * The `node` is subscribable and composable like any reactive node. When\n * the cap is reached, `increment()` returns `false`.\n *\n * ```ts\n * const retries = reactiveCounter(10);\n * retries.increment(); // true — count is now 1\n * retries.node.subscribe(...); // reactive updates\n * retries.atCap(); // false\n * ```\n *\n * @param cap - Maximum value (inclusive). 0 = no increments allowed.\n * @category extra\n */\nexport function reactiveCounter(cap: number): ReactiveCounterBundle {\n\tconst counter = state(0);\n\treturn {\n\t\tnode: counter,\n\t\tincrement() {\n\t\t\tconst current = counter.cache ?? 0;\n\t\t\tif (current >= cap) return false;\n\t\t\tcounter.down([[DIRTY], [DATA, current + 1]]);\n\t\t\treturn true;\n\t\t},\n\t\tget() {\n\t\t\treturn counter.cache ?? 0;\n\t\t},\n\t\tatCap() {\n\t\t\treturn (counter.cache ?? 0) >= cap;\n\t\t},\n\t};\n}\n","/**\n * Minimal 5-field cron parser and matcher (minute hour day-of-month month day-of-week).\n * Ported from callbag-recharge `extra/cron.ts` for `fromCron` (roadmap §2.3).\n */\nexport interface CronSchedule {\n\tminutes: Set<number>;\n\thours: Set<number>;\n\tdaysOfMonth: Set<number>;\n\tmonths: Set<number>;\n\tdaysOfWeek: Set<number>;\n}\n\nfunction parseField(field: string, min: number, max: number): Set<number> {\n\tconst result = new Set<number>();\n\tfor (const part of field.split(\",\")) {\n\t\tconst [range, stepStr] = part.split(\"/\");\n\t\tconst step = stepStr ? Number.parseInt(stepStr, 10) : 1;\n\t\tif (Number.isNaN(step) || step < 1) throw new Error(`Invalid cron step: ${part}`);\n\t\tlet start: number;\n\t\tlet end: number;\n\t\tif (range === \"*\") {\n\t\t\tstart = min;\n\t\t\tend = max;\n\t\t} else if (range.includes(\"-\")) {\n\t\t\tconst [a, b] = range.split(\"-\");\n\t\t\tstart = Number.parseInt(a, 10);\n\t\t\tend = Number.parseInt(b, 10);\n\t\t} else {\n\t\t\tstart = Number.parseInt(range, 10);\n\t\t\tend = start;\n\t\t}\n\t\tif (Number.isNaN(start) || Number.isNaN(end)) throw new Error(`Invalid cron field: ${field}`);\n\t\tif (start < min || end > max)\n\t\t\tthrow new Error(`Cron field out of range: ${field} (${min}-${max})`);\n\t\tif (start > end) throw new Error(`Invalid cron range: ${start}-${end} in ${field}`);\n\t\tfor (let i = start; i <= end; i += step) result.add(i);\n\t}\n\treturn result;\n}\n\n/**\n * Parses a standard 5-field cron expression into a {@link CronSchedule}.\n *\n * Supports `*`, ranges (`1-5`), steps (`*\\/5`, `0-30/10`), and comma-separated\n * lists. Fields are: minute (0–59), hour (0–23), day-of-month (1–31),\n * month (1–12), day-of-week (0–6, Sunday = 0).\n *\n * @param expr - Five-field whitespace-separated cron string (e.g. `\"0 9 * * 1-5\"`).\n * @returns Parsed {@link CronSchedule} with one `Set<number>` per field.\n * @throws Error when the expression does not have exactly 5 fields, contains\n * out-of-range values, or uses an invalid step.\n *\n * @example\n * ```ts\n * import { parseCron } from \"@graphrefly/graphrefly-ts\";\n *\n * const sched = parseCron(\"0 9 * * 1-5\"); // weekdays at 09:00\n * sched.hours; // Set { 9 }\n * sched.daysOfWeek; // Set { 1, 2, 3, 4, 5 }\n * ```\n */\nexport function parseCron(expr: string): CronSchedule {\n\tconst parts = expr.trim().split(/\\s+/);\n\tif (parts.length !== 5) throw new Error(`Invalid cron: expected 5 fields, got ${parts.length}`);\n\treturn {\n\t\tminutes: parseField(parts[0], 0, 59),\n\t\thours: parseField(parts[1], 0, 23),\n\t\tdaysOfMonth: parseField(parts[2], 1, 31),\n\t\tmonths: parseField(parts[3], 1, 12),\n\t\tdaysOfWeek: parseField(parts[4], 0, 6),\n\t};\n}\n\n/**\n * Returns `true` if `date` satisfies every field of `schedule`.\n *\n * @param schedule - Parsed schedule from {@link parseCron}.\n * @param date - Moment to test (local time via `getMinutes`, `getHours`, etc.).\n * @returns `true` when all five cron fields match the given date.\n *\n * @example\n * ```ts\n * import { parseCron, matchesCron } from \"@graphrefly/graphrefly-ts\";\n *\n * const sched = parseCron(\"30 8 * * 1\"); // Mondays at 08:30\n * const monday = new Date(\"2026-03-30T08:30:00\"); // a Monday\n * matchesCron(sched, monday); // true\n * ```\n */\nexport function matchesCron(schedule: CronSchedule, date: Date): boolean {\n\treturn (\n\t\tschedule.minutes.has(date.getMinutes()) &&\n\t\tschedule.hours.has(date.getHours()) &&\n\t\tschedule.daysOfMonth.has(date.getDate()) &&\n\t\tschedule.months.has(date.getMonth() + 1) &&\n\t\tschedule.daysOfWeek.has(date.getDay())\n\t);\n}\n","/**\n * Tier 1 sync operators (roadmap §2.1) and Tier 2 async/dynamic operators (roadmap §2.2) —\n * each returns a {@link Node} built with {@link node} (or {@link producer} for cold sources).\n *\n * v5 foundation redesign: all operators use `actions.emit()` for value emission,\n * `ctx.store` for persistent state, `ctx.terminalDeps` for terminal handling,\n * and `data[i]` batch shape for DATA vs RESOLVED discrimination. `onMessage`\n * and `onResubscribe` are removed.\n */\n\nimport { monotonicNs } from \"../core/clock.js\";\nimport type { NodeActions } from \"../core/config.js\";\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Message,\n\ttype Messages,\n\tRESOLVED,\n\tSTART,\n} from \"../core/messages.js\";\nimport { type Node, type NodeOptions, node } from \"../core/node.js\";\nimport { derived, producer } from \"../core/sugar.js\";\nimport { NS_PER_MS } from \"./backoff.js\";\nimport { fromAny, type NodeInput } from \"./sources.js\";\n\ntype ExtraOpts = Omit<NodeOptions<unknown>, \"describeKind\">;\n\nfunction operatorOpts<T = unknown>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"derived\", ...opts } as NodeOptions<T>;\n}\n\n/**\n * Maps each settled value from `source` through `project`.\n *\n * @param source - Upstream node.\n * @param project - Transform for each value.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Derived node emitting mapped values.\n *\n * @example\n * ```ts\n * import { map, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = map(state(2), (x) => x * 3);\n * ```\n *\n * @category extra\n */\nexport function map<T, R>(source: Node<T>, project: (value: T) => R, opts?: ExtraOpts): Node<R> {\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) {\n\t\t\t\ta.emit(project(v as T));\n\t\t\t}\n\t\t},\n\t\toperatorOpts<R>(opts),\n\t);\n}\n\n/**\n * Forwards values that satisfy `predicate`; otherwise emits `RESOLVED` with no `DATA` (two-phase semantics).\n *\n * @param source - Upstream node.\n * @param predicate - Inclusion test.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Filtered node.\n *\n * @example\n * ```ts\n * import { filter, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = filter(state(1), (x) => x > 0);\n * ```\n *\n * @category extra\n */\nexport function filter<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet emitted = false;\n\t\t\tfor (const v of batch0) {\n\t\t\t\tif (predicate(v as T)) {\n\t\t\t\t\ta.emit(v as T);\n\t\t\t\t\temitted = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!emitted) a.down([[RESOLVED]]);\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n/**\n * Folds each upstream value into an accumulator; emits the new accumulator every time.\n *\n * Unlike RxJS, `seed` is always required — there is no seedless mode where the first\n * value silently becomes the accumulator.\n *\n * @param source - Upstream node.\n * @param reducer - `(acc, value) => nextAcc`.\n * @param seed - Initial accumulator (required).\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Scan node.\n *\n * @example\n * ```ts\n * import { scan, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = scan(state(1), (a, x) => a + x, 0);\n * ```\n *\n * @category extra\n */\nexport function scan<T, R>(\n\tsource: Node<T>,\n\treducer: (acc: R, value: T) => R,\n\tseed: R,\n\topts?: ExtraOpts,\n): Node<R> {\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (!(\"acc\" in ctx.store)) ctx.store.acc = seed;\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) {\n\t\t\t\tctx.store.acc = reducer(ctx.store.acc as R, v as T);\n\t\t\t\ta.emit(ctx.store.acc as R);\n\t\t\t}\n\t\t},\n\t\t{ ...operatorOpts(opts), initial: seed, resetOnTeardown: true },\n\t);\n}\n\n/**\n * Reduces to one value emitted when `source` completes; if no `DATA` arrived, emits `seed`.\n *\n * Unlike RxJS, `seed` is always required. If the source completes without emitting\n * DATA, the seed value is emitted (RxJS would throw without a seed).\n *\n * @param source - Upstream node.\n * @param reducer - `(acc, value) => nextAcc`.\n * @param seed - Empty-completion default and initial accumulator (required).\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Node that emits once on completion.\n *\n * @example\n * ```ts\n * import { reduce, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = reduce(state(1), (a, x) => a + x, 0);\n * ```\n *\n * @category extra\n */\nexport function reduce<T, R>(\n\tsource: Node<T>,\n\treducer: (acc: R, value: T) => R,\n\tseed: R,\n\topts?: ExtraOpts,\n): Node<R> {\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (!(\"acc\" in ctx.store)) ctx.store.acc = seed;\n\t\t\t// COMPLETE: emit accumulated value then COMPLETE.\n\t\t\t// ERROR: autoError propagates automatically; nothing to emit.\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\ta.emit(ctx.store.acc as R);\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\t// RESOLVED wave (empty batch): propagate RESOLVED. After fn has run once\n\t\t\t// the pre-fn skip handles this; this guard covers the first-wave case.\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// DATA: accumulate silently — emit nothing until COMPLETE.\n\t\t\tfor (const v of batch0) {\n\t\t\t\tctx.store.acc = reducer(ctx.store.acc as R, v as T);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t},\n\t);\n}\n\n/**\n * Emits at most `count` **`DATA`** values, then **`COMPLETE`**. `RESOLVED` does not advance the counter.\n *\n * @param source - Upstream node.\n * @param count - Maximum `DATA` emissions (≤0 completes immediately).\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Limited stream.\n *\n * @example\n * ```ts\n * import { take, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = take(state(0), 3);\n * ```\n *\n * @category extra\n */\nexport function take<T>(source: Node<T>, count: number, opts?: ExtraOpts): Node<T> {\n\tif (count <= 0) {\n\t\treturn node<T>(\n\t\t\t[source as Node],\n\t\t\t(_d, a, ctx) => {\n\t\t\t\tif (ctx.store.completed) return;\n\t\t\t\tctx.store.completed = true;\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t},\n\t\t\t{\n\t\t\t\t...operatorOpts(opts),\n\t\t\t\tcompleteWhenDepsComplete: false,\n\t\t\t},\n\t\t);\n\t}\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (!(\"taken\" in ctx.store)) ctx.store.taken = 0;\n\t\t\tif (ctx.store.done) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Upstream COMPLETE before count reached → forward COMPLETE.\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tctx.store.done = true;\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// DATA wave: iterate full batch, stop at count\n\t\t\tfor (const v of batch0) {\n\t\t\t\t(ctx.store.taken as number)++;\n\t\t\t\ta.emit(v as T);\n\t\t\t\tif ((ctx.store.taken as number) >= count) {\n\t\t\t\t\tctx.store.done = true;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t},\n\t);\n}\n\n/**\n * Skips the first `count` **`DATA`** emissions. `RESOLVED` does not advance the counter.\n *\n * @param source - Upstream node.\n * @param count - Number of `DATA` values to drop.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Skipped stream.\n *\n * @example\n * ```ts\n * import { skip, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = skip(state(0), 2);\n * ```\n *\n * @category extra\n */\nexport function skip<T>(source: Node<T>, count: number, opts?: ExtraOpts): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (!(\"skipped\" in ctx.store)) ctx.store.skipped = 0;\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\t// RESOLVED wave — pass through\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet emitted = false;\n\t\t\tfor (const v of batch0) {\n\t\t\t\t(ctx.store.skipped as number)++;\n\t\t\t\tif ((ctx.store.skipped as number) <= count) {\n\t\t\t\t\t// Still in skip window\n\t\t\t\t} else {\n\t\t\t\t\ta.emit(v as T);\n\t\t\t\t\temitted = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!emitted) a.down([[RESOLVED]]);\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n/**\n * Emits while `predicate` holds; on first false, sends **`COMPLETE`**.\n *\n * @param source - Upstream node.\n * @param predicate - Continuation test.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Truncated stream.\n *\n * @example\n * ```ts\n * import { takeWhile, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = takeWhile(state(1), (x) => x < 10);\n * ```\n *\n * @category extra\n */\nexport function takeWhile<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (ctx.store.done) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) {\n\t\t\t\tif (!predicate(v as T)) {\n\t\t\t\t\tctx.store.done = true;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ta.emit(v as T);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t},\n\t);\n}\n\n/**\n * Forwards `source` until `notifier` matches `predicate` (default: notifier **`DATA`**), then **`COMPLETE`**.\n *\n * @param source - Main upstream.\n * @param notifier - Triggers completion when `predicate(msg)` is true.\n * @param opts - Optional {@link NodeOptions}, plus `predicate` for custom notifier matching.\n * @returns `Node<T>` - Truncated stream.\n *\n * @example\n * ```ts\n * import { producer, takeUntil, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = state(1);\n * const stop = producer((_d, a) => a.emit(undefined));\n * const n = takeUntil(src, stop);\n * ```\n *\n * @category extra\n */\nexport function takeUntil<T>(\n\tsource: Node<T>,\n\tnotifier: Node,\n\topts?: ExtraOpts & { predicate?: (msg: Message) => boolean },\n): Node<T> {\n\tconst pred = opts?.predicate ?? ((m: Message) => m[0] === DATA);\n\tconst { predicate: _, ...restOpts } = opts ?? {};\n\t// Use producer pattern — subscribe to both manually for message-level control.\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tlet stopped = false;\n\t\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\t\tif (stopped) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tif (m[0] === DATA) a.emit(m[1] as T);\n\t\t\t\t\telse if (m[0] === COMPLETE || m[0] === ERROR) {\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tconst notUnsub = notifier.subscribe((msgs) => {\n\t\t\t\tif (stopped) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tif (pred(m)) {\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tsrcUnsub();\n\t\t\t\tnotUnsub();\n\t\t\t};\n\t\t},\n\t\toperatorOpts(restOpts as ExtraOpts),\n\t);\n}\n\n/**\n * Emits the first **`DATA`** then **`COMPLETE`** (same as `take(source, 1)`).\n *\n * @param source - Upstream node.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Single-value stream.\n *\n * @example\n * ```ts\n * import { first, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = first(state(42));\n * ```\n *\n * @category extra\n */\nexport function first<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn take(source, 1, opts);\n}\n\n/**\n * Buffers values and emits the last **`DATA`** on **`COMPLETE`**; optional `defaultValue` if none arrived.\n *\n * @param source - Upstream node.\n * @param options - Optional {@link NodeOptions} and `defaultValue` when empty.\n * @returns `Node<T>` - Last-or-default node.\n *\n * @example\n * ```ts\n * import { last, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = last(state(1), { defaultValue: 0 });\n * ```\n *\n * @category extra\n */\nexport function last<T>(source: Node<T>, options?: ExtraOpts & { defaultValue?: T }): Node<T> {\n\tconst { defaultValue, ...rest } = options ?? {};\n\tconst useDefault = options != null && Object.hasOwn(options, \"defaultValue\");\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\t// COMPLETE (terminal === true): emit latest or default, then COMPLETE.\n\t\t\t// ERROR: autoError propagates automatically.\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tif (ctx.store.has) {\n\t\t\t\t\ta.emit(ctx.store.latest as T);\n\t\t\t\t} else if (useDefault) {\n\t\t\t\t\ta.emit(defaultValue as T);\n\t\t\t\t}\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\t// RESOLVED wave: propagate RESOLVED. Covers first-wave case; after first\n\t\t\t// call the pre-fn skip handles this automatically.\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// DATA: accumulate latest — emit nothing until COMPLETE.\n\t\t\tctx.store.latest = batch0.at(-1) as T;\n\t\t\tctx.store.has = true;\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(rest),\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t},\n\t);\n}\n\n/**\n * Emits the first value matching `predicate`, then **`COMPLETE`**.\n *\n * @param source - Upstream node.\n * @param predicate - Match test.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - First-match stream.\n *\n * @example\n * ```ts\n * import { find, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = find(state(1), (x) => x > 0);\n * ```\n *\n * @category extra\n */\nexport function find<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn take(filter(source, predicate, opts), 1, opts);\n}\n\n/**\n * Emits the `index`th **`DATA`** (zero-based), then **`COMPLETE`**.\n *\n * @param source - Upstream node.\n * @param index - Zero-based emission index.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Single indexed value.\n *\n * @example\n * ```ts\n * import { elementAt, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = elementAt(state(0), 2);\n * ```\n *\n * @category extra\n */\nexport function elementAt<T>(source: Node<T>, index: number, opts?: ExtraOpts): Node<T> {\n\treturn take(skip(source, index, opts), 1, opts);\n}\n\n/**\n * Observer shape for {@link tap} — side effects for data, error, and/or complete.\n */\nexport type TapObserver<T> = {\n\tdata?: (value: T) => void;\n\terror?: (err: unknown) => void;\n\tcomplete?: () => void;\n};\n\n/**\n * Invokes side effects; values pass through unchanged.\n *\n * Accepts either a function (called on each DATA) or an observer object\n * `{ data?, error?, complete? }` for lifecycle-aware side effects.\n *\n * @param source - Upstream node.\n * @param fnOrObserver - Side effect function or observer object.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Passthrough node.\n *\n * @example\n * ```ts\n * import { tap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * // Function form (DATA only)\n * tap(state(1), (x) => console.log(x));\n *\n * // Observer form (DATA + ERROR + COMPLETE)\n * tap(state(1), { data: console.log, error: console.error, complete: () => console.log(\"done\") });\n * ```\n *\n * @category extra\n */\nexport function tap<T>(\n\tsource: Node<T>,\n\tfnOrObserver: ((value: T) => void) | TapObserver<T>,\n\topts?: ExtraOpts,\n): Node<T> {\n\tif (typeof fnOrObserver === \"function\") {\n\t\treturn node<T>(\n\t\t\t[source as Node],\n\t\t\t(data, a) => {\n\t\t\t\tconst batch0 = data[0];\n\t\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const v of batch0) {\n\t\t\t\t\tfnOrObserver(v as T);\n\t\t\t\t\ta.emit(v as T);\n\t\t\t\t}\n\t\t\t},\n\t\t\toperatorOpts(opts),\n\t\t);\n\t}\n\tconst obs = fnOrObserver;\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\t// Check for terminal events\n\t\t\tif (ctx.terminalDeps[0] !== undefined) {\n\t\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\t\tobs.complete?.();\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else {\n\t\t\t\t\tobs.error?.(ctx.terminalDeps[0]);\n\t\t\t\t\ta.down([[ERROR, ctx.terminalDeps[0]]]);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) {\n\t\t\t\tobs.data?.(v as T);\n\t\t\t\ta.emit(v as T);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t},\n\t);\n}\n\n/**\n * Suppresses adjacent duplicates using `equals` (default `Object.is`).\n *\n * @param source - Upstream node.\n * @param equals - Optional equality for consecutive values.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Deduped stream.\n *\n * @example\n * ```ts\n * import { distinctUntilChanged, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = distinctUntilChanged(state(1));\n * ```\n *\n * @category extra\n */\nexport function distinctUntilChanged<T>(\n\tsource: Node<T>,\n\tequals: (a: T, b: T) => boolean = Object.is,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet emitted = false;\n\t\t\tfor (const val of batch0 as T[]) {\n\t\t\t\tif (ctx.store.hasPrev && equals(ctx.store.prev as T, val)) {\n\t\t\t\t\t// Suppressed — same as previous\n\t\t\t\t} else {\n\t\t\t\t\tctx.store.prev = val;\n\t\t\t\t\tctx.store.hasPrev = true;\n\t\t\t\t\ta.emit(val);\n\t\t\t\t\temitted = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!emitted) a.down([[RESOLVED]]);\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n/**\n * Emits `[previous, current]` pairs starting after the second value (first pair uses `RESOLVED` only).\n *\n * @param source - Upstream node.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<readonly [T, T]>` - Pair stream.\n *\n * @example\n * ```ts\n * import { pairwise, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = pairwise(state(0));\n * ```\n *\n * @category extra\n */\nexport function pairwise<T>(source: Node<T>, opts?: ExtraOpts): Node<readonly [T, T]> {\n\treturn node<readonly [T, T]>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet emitted = false;\n\t\t\tfor (const x of batch0 as T[]) {\n\t\t\t\tif (!ctx.store.hasPrev) {\n\t\t\t\t\tctx.store.prev = x;\n\t\t\t\t\tctx.store.hasPrev = true;\n\t\t\t\t\t// First value — no pair yet\n\t\t\t\t} else {\n\t\t\t\t\tconst pair = [ctx.store.prev as T, x] as const;\n\t\t\t\t\tctx.store.prev = x;\n\t\t\t\t\ta.emit(pair);\n\t\t\t\t\temitted = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!emitted) a.down([[RESOLVED]]);\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n/**\n * Combines the latest value from each dependency whenever any dep settles (combineLatest).\n *\n * @param sources - Nodes to combine (variadic).\n * @returns `Node<T>` - Tuple of latest values.\n *\n * @example\n * ```ts\n * import { combine, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = combine(state(1), state(\"a\"));\n * ```\n *\n * @remarks\n * Unlike RxJS `combineLatest`, this is named `combine`. Use the {@link combineLatest} alias\n * if you prefer the RxJS name. Seed is always required for `scan`/`reduce` (no seedless mode).\n *\n * @category extra\n */\nexport function combine<const T extends readonly unknown[]>(\n\t...sources: { [K in keyof T]: Node<T[K]> }\n): Node<T> {\n\tconst deps = [...sources] as unknown as Node[];\n\treturn derived(deps, (vals) => vals as unknown as T, {\n\t\t...operatorOpts<T>(),\n\t\tequals: (a, b) => {\n\t\t\tif (a.length !== b.length) return false;\n\t\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\t\tif (!Object.is(a[i], b[i])) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t});\n}\n\n/**\n * When `primary` settles, emits `[primary, latestSecondary]`. `secondary` alone updates cache only.\n *\n * @param primary - Main stream.\n * @param secondary - Latest value is paired on each primary emission.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<readonly [A, B]>` - Paired stream.\n *\n * @example\n * ```ts\n * import { state, withLatestFrom } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = withLatestFrom(state(1), state(\"x\"));\n * ```\n *\n * @category extra\n */\nexport function withLatestFrom<A, B>(\n\tprimary: Node<A>,\n\tsecondary: Node<B>,\n\topts?: ExtraOpts,\n): Node<readonly [A, B]> {\n\t// Known semantic (documented): on initial activation when BOTH deps are\n\t// `state()` nodes with cached values, the paired emission is dropped.\n\t// `_activate` (src/core/node.ts:1002) subscribes deps sequentially in\n\t// declaration order; primary's push-on-subscribe fires before secondary\n\t// has subscribed, so the first-run gate (§2.7) forces RESOLVED. Secondary\n\t// then fires in a separate wave with primary silent, and the fn's\n\t// \"emit only when primary fired this wave\" rule takes the else branch.\n\t// Use the factory-time seed pattern for initial-value pairing (see\n\t// stratify, budgetGate, distill for examples; COMPOSITION-GUIDE §21).\n\t// A naïve `[secondary, primary]` flip breaks topology-sensitive diamond\n\t// callers like `harness/loop.ts` — the fix needs a deeper design pass.\n\treturn node<readonly [A, B]>(\n\t\t[primary as Node, secondary as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tconst batch1 = data[1];\n\t\t\t// Current secondary value: this wave's last DATA if secondary fired,\n\t\t\t// otherwise last known value from ctx.prevData (previous wave).\n\t\t\tconst secondaryVal = (\n\t\t\t\tbatch1 != null && batch1.length > 0 ? batch1.at(-1) : ctx.prevData[1]\n\t\t\t) as B | undefined;\n\n\t\t\t// Only emit when primary (dep 0) sent DATA this wave.\n\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\t// secondary has never produced DATA — undefined is the protocol\n\t\t\t\t// sentinel for \"never sent DATA\"; null is a valid DATA value.\n\t\t\t\tif (!(batch1 != null && batch1.length > 0) && ctx.prevData[1] === undefined) {\n\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const v of batch0 as A[]) {\n\t\t\t\t\ta.emit([v, secondaryVal]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Secondary update only (or both RESOLVED) — no downstream DATA.\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t}\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n/**\n * Merges **`DATA`** from any source with correct two-phase dirty tracking. **`COMPLETE`** after **all** sources complete (spec §1.3.5).\n *\n * @param sources - Nodes to merge (variadic; empty completes immediately).\n * @returns `Node<T>` - Merged stream.\n *\n * @remarks\n * **Ordering:** DIRTY/RESOLVED rules follow multi-source semantics in `~/src/graphrefly/GRAPHREFLY-SPEC.md`.\n *\n * @example\n * ```ts\n * import { merge, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = merge(state(1), state(2));\n * ```\n *\n * @category extra\n */\nexport function merge<T>(...sources: readonly Node<T>[]): Node<T> {\n\tif (sources.length === 0) {\n\t\treturn producer<T>((a) => {\n\t\t\ta.down([[COMPLETE]]);\n\t\t}, operatorOpts());\n\t}\n\t// producer pattern: node() cannot be used here because the sentinel gate\n\t// would block the fn until ALL sources have sent their first DATA, which\n\t// defeats the purpose of merge (forward whichever source fires first).\n\treturn producer<T>((a) => {\n\t\tconst n = sources.length;\n\t\tlet completed = 0;\n\t\tconst unsubs: (() => void)[] = [];\n\t\tfor (const src of sources) {\n\t\t\tconst u = src.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t\tcompleted += 1;\n\t\t\t\t\t\tif (completed >= n) {\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t}\n\t\t\t\t\t// DIRTY, RESOLVED, START silently absorbed\n\t\t\t\t}\n\t\t\t});\n\t\t\tunsubs.push(u);\n\t\t}\n\t\treturn () => {\n\t\t\tfor (const u of unsubs) u();\n\t\t};\n\t}, operatorOpts());\n}\n\n/**\n * Zips one **`DATA`** from each source per cycle into a tuple. Only **`DATA`** enqueues (spec §1.3.3).\n *\n * @param sources - Nodes to zip (variadic).\n * @returns `Node<T>` - Zipped tuples.\n *\n * @example\n * ```ts\n * import { state, zip } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = zip(state(1), state(2));\n * ```\n *\n * @category extra\n */\nexport function zip<const T extends readonly unknown[]>(\n\t...sources: { [K in keyof T]: Node<T[K]> }\n): Node<T> {\n\tconst n = sources.length;\n\tif (n === 0) {\n\t\treturn producer<T>((a) => {\n\t\t\ta.emit([] as unknown as T);\n\t\t\ta.down([[COMPLETE]]);\n\t\t}, operatorOpts());\n\t}\n\t// Producer pattern: manage queues internally.\n\treturn producer<T>((a) => {\n\t\tconst queues: unknown[][] = Array.from({ length: n }, () => []);\n\t\tlet active = n;\n\n\t\tfunction tryEmit(): void {\n\t\t\twhile (queues.every((q) => q.length > 0)) {\n\t\t\t\tconst tuple = queues.map((q) => q.shift()!) as unknown as T;\n\t\t\t\ta.emit(tuple);\n\t\t\t}\n\t\t}\n\n\t\tconst unsubs: (() => void)[] = [];\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst idx = i;\n\t\t\tconst u = (sources[i] as Node).subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tqueues[idx].push(m[1]);\n\t\t\t\t\t\ttryEmit();\n\t\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t\tactive -= 1;\n\t\t\t\t\t\tif (active === 0 || queues[idx].length === 0) {\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tunsubs.push(u);\n\t\t}\n\t\treturn () => {\n\t\t\tfor (const u of unsubs) u();\n\t\t};\n\t}, operatorOpts());\n}\n\n/**\n * Plays all of `firstSrc`, then all of `secondSrc`. **`DATA`** from `secondSrc` during phase one is buffered until handoff.\n *\n * @param firstSrc - First segment.\n * @param secondSrc - Second segment.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Concatenated stream.\n *\n * @example\n * ```ts\n * import { concat, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = concat(state(1), state(2));\n * ```\n *\n * @category extra\n */\nexport function concat<T>(firstSrc: Node<T>, secondSrc: Node<T>, opts?: ExtraOpts): Node<T> {\n\t// producer pattern: node() cannot be used here because the sentinel gate\n\t// would block the fn until ALL sources have sent their first DATA, which\n\t// defeats the purpose of concat (start forwarding firstSrc immediately,\n\t// regardless of secondSrc state).\n\treturn producer<T>((a) => {\n\t\tlet phase: 0 | 1 = 0;\n\t\tconst pending: unknown[] = [];\n\t\tlet firstUnsub: (() => void) | undefined;\n\t\tlet secondUnsub: (() => void) | undefined;\n\n\t\tsecondUnsub = secondSrc.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (phase === 0) {\n\t\t\t\t\tif (m[0] === DATA) pending.push(m[1]);\n\t\t\t\t\telse if (m[0] === ERROR) a.down([m]);\n\t\t\t\t} else {\n\t\t\t\t\t// phase 1 — forward everything from second\n\t\t\t\t\tif (m[0] === DATA) a.emit(m[1] as T);\n\t\t\t\t\telse if (m[0] === COMPLETE || m[0] === ERROR) a.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tfirstUnsub = firstSrc.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (phase === 0) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t\tphase = 1;\n\t\t\t\t\t\t// Flush buffered second-source DATA\n\t\t\t\t\t\tfor (const v of pending) {\n\t\t\t\t\t\t\ta.emit(v as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpending.length = 0;\n\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// phase 1: ignore further first-source messages\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tfirstUnsub?.();\n\t\t\tsecondUnsub?.();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * First source to emit **`DATA`** wins; later traffic follows only the winner (Rx-style `race`).\n *\n * @param sources - Contestants (variadic; empty completes immediately; one node is identity).\n * @returns `Node<T>` - Winning stream.\n *\n * @example\n * ```ts\n * import { race, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = race(state(1), state(2));\n * ```\n *\n * @category extra\n */\nexport function race<T>(...sources: readonly Node<T>[]): Node<T> {\n\tif (sources.length === 0) {\n\t\treturn producer<T>((a) => {\n\t\t\ta.down([[COMPLETE]]);\n\t\t}, operatorOpts());\n\t}\n\tif (sources.length === 1) {\n\t\t// Identity passthrough — full batch iteration, not derived's .at(-1).\n\t\treturn node<T>(\n\t\t\t[sources[0] as Node],\n\t\t\t(data, a) => {\n\t\t\t\tconst batch0 = data[0];\n\t\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const v of batch0) a.emit(v as T);\n\t\t\t},\n\t\t\toperatorOpts<T>(),\n\t\t);\n\t}\n\t// Producer pattern: first DATA wins.\n\treturn producer<T>((a) => {\n\t\tlet winner: number | null = null;\n\t\tconst unsubs: (() => void)[] = [];\n\t\tfor (let i = 0; i < sources.length; i++) {\n\t\t\tconst idx = i;\n\t\t\tconst u = (sources[i] as Node).subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (winner !== null && idx !== winner) return;\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tif (winner === null) winner = idx;\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (m[0] === COMPLETE || m[0] === ERROR) {\n\t\t\t\t\t\tif (winner === null || idx === winner) {\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tunsubs.push(u);\n\t\t}\n\t\treturn () => {\n\t\t\tfor (const u of unsubs) u();\n\t\t};\n\t}, operatorOpts());\n}\n\n// --- Tier 2: async / dynamic (roadmap §2.2), all on `node` / `producer` ---\n\nfunction forwardInner<R>(inner: Node<R>, a: NodeActions, onInnerComplete: () => void): () => void {\n\tlet unsub: (() => void) | undefined;\n\tlet finished = false;\n\tconst finish = (): void => {\n\t\tif (finished) return;\n\t\tfinished = true;\n\t\tonInnerComplete();\n\t};\n\tunsub = inner.subscribe((msgs) => {\n\t\tlet sawComplete = false;\n\t\tlet sawError = false;\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === START) continue;\n\t\t\tif (m[0] === DATA) {\n\t\t\t\ta.emit(m[1] as R);\n\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\tsawComplete = true;\n\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\tsawError = true;\n\t\t\t\ta.down([m]);\n\t\t\t} else if (m[0] === DIRTY || m[0] === RESOLVED) {\n\t\t\t\t// Reactive wave signals forwarded to outer output.\n\t\t\t\ta.down([m]);\n\t\t\t}\n\t\t\t// INVALIDATE, PAUSE, RESUME, TEARDOWN from inner are intentionally\n\t\t\t// dropped. Inner lifecycle and flow-control signals are internal to\n\t\t\t// the *Map operator. INVALIDATE is dropped because the inner will\n\t\t\t// follow up with DIRTY+DATA when it recomputes — forwarding\n\t\t\t// INVALIDATE to the outer output's sinks is redundant and wrong for\n\t\t\t// mergeMap (one inner's cache state must not invalidate the whole\n\t\t\t// merged output). PAUSE/RESUME/TEARDOWN: RxJS/callbag precedent —\n\t\t\t// no backpressure forwarding in merge-style operators.\n\t\t}\n\t\tif (sawError) {\n\t\t\tunsub?.();\n\t\t\tunsub = undefined;\n\t\t\tfinish();\n\t\t} else if (sawComplete) {\n\t\t\tfinish();\n\t\t}\n\t});\n\t// P4 START handshake guarantees: subscribe delivers [[START], [DATA, cache]]\n\t// synchronously for settled nodes. Any relevant state is already handled by\n\t// the callback above — no post-subscribe .status/.cache reads needed.\n\treturn () => {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t};\n}\n\n/**\n * Maps each settled value to an inner node; unsubscribes the previous inner (Rx-style `switchMap`).\n *\n * @param source - Upstream node.\n * @param project - Maps each outer value to an inner source shape (`Node`, scalar, `PromiseLike`, `Iterable`, or `AsyncIterable`) coerced via {@link fromAny}.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Emissions from the active inner subscription.\n * @example\n * ```ts\n * import { switchMap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = state(0);\n * switchMap(src, (n) => state((n as number) * 2));\n * ```\n *\n * @category extra\n */\nexport function switchMap<T, R>(\n\tsource: Node<T>,\n\tproject: (value: T) => NodeInput<R>,\n\topts?: ExtraOpts,\n): Node<R> {\n\tlet innerUnsub: (() => void) | undefined;\n\tlet sourceDone = false;\n\n\tfunction clearInner(): void {\n\t\tinnerUnsub?.();\n\t\tinnerUnsub = undefined;\n\t}\n\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\t// Source ERROR: cleanup inner, autoError forwards\n\t\t\tif (ctx.terminalDeps[0] != null && ctx.terminalDeps[0] !== true) {\n\t\t\t\tclearInner();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Source COMPLETE\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tsourceDone = true;\n\t\t\t\tif (!innerUnsub) a.down([[COMPLETE]]);\n\t\t\t\t// inner active: onInnerComplete will fire COMPLETE later\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\n\t\t\t// Switch: only the latest value matters; skip to the last in the\n\t\t\t// batch to avoid creating and immediately discarding N-1 inners.\n\t\t\t// clearInner() runs once to cancel any prior-wave inner.\n\t\t\tclearInner();\n\t\t\tinnerUnsub = forwardInner(fromAny(project(batch0[batch0.length - 1] as T)), a, () => {\n\t\t\t\tclearInner();\n\t\t\t\tif (sourceDone) a.down([[COMPLETE]]);\n\t\t\t});\n\n\t\t\t// Deactivation-only cleanup: must NOT fire before fn reruns\n\t\t\t// because the terminal wave needs to see innerUnsub intact.\n\t\t\treturn {\n\t\t\t\tdeactivation: () => {\n\t\t\t\t\tclearInner();\n\t\t\t\t\tsourceDone = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...operatorOpts(opts), completeWhenDepsComplete: false },\n\t);\n}\n\n/**\n * Like {@link switchMap}, but ignores outer `DATA` while an inner subscription is active (`exhaustMap`).\n *\n * @param source - Upstream node.\n * @param project - Maps each outer value to an inner source shape (`Node`, scalar, `PromiseLike`, `Iterable`, or `AsyncIterable`) coerced via {@link fromAny}.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Emissions from the active inner while it runs.\n * @example\n * ```ts\n * import { exhaustMap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * exhaustMap(state(0), () => state(1));\n * ```\n *\n * @category extra\n */\nexport function exhaustMap<T, R>(\n\tsource: Node<T>,\n\tproject: (value: T) => NodeInput<R>,\n\topts?: ExtraOpts,\n): Node<R> {\n\tlet innerUnsub: (() => void) | undefined;\n\tlet sourceDone = false;\n\n\tfunction clearInner(): void {\n\t\tinnerUnsub?.();\n\t\tinnerUnsub = undefined;\n\t}\n\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (ctx.terminalDeps[0] != null && ctx.terminalDeps[0] !== true) {\n\t\t\t\tclearInner();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tsourceDone = true;\n\t\t\t\tif (!innerUnsub) a.down([[COMPLETE]]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\n\t\t\tif (innerUnsub === undefined) {\n\t\t\t\t// First value in batch wins (FIFO exhaustMap gate)\n\t\t\t\tinnerUnsub = forwardInner(fromAny(project(batch0[0] as T)), a, () => {\n\t\t\t\t\tclearInner();\n\t\t\t\t\tif (sourceDone) a.down([[COMPLETE]]);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// Inner active — drop, settle the dep-wave\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tdeactivation: () => {\n\t\t\t\t\tclearInner();\n\t\t\t\t\tsourceDone = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...operatorOpts(opts), completeWhenDepsComplete: false },\n\t);\n}\n\n/**\n * Enqueues each outer value and subscribes to inners one at a time (`concatMap`).\n *\n * @param source - Upstream node.\n * @param project - Maps each outer value to an inner source shape (`Node`, scalar, `PromiseLike`, `Iterable`, or `AsyncIterable`) coerced via {@link fromAny}.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Sequential concatenation of inner streams.\n * @example\n * ```ts\n * import { concatMap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * concatMap(state(0), (n) => state((n as number) + 1));\n * ```\n *\n * @category extra\n */\nexport function concatMap<T, R>(\n\tsource: Node<T>,\n\tproject: (value: T) => NodeInput<R>,\n\topts?: ExtraOpts & { maxBuffer?: number },\n): Node<R> {\n\tconst { maxBuffer: maxBuf, ...concatNodeOpts } = opts ?? {};\n\tconst queue: T[] = [];\n\tlet innerUnsub: (() => void) | undefined;\n\tlet sourceDone = false;\n\tlet actions: NodeActions | undefined;\n\n\tfunction clearInner(): void {\n\t\tinnerUnsub?.();\n\t\tinnerUnsub = undefined;\n\t}\n\n\tfunction tryPump(): void {\n\t\tif (!actions || innerUnsub !== undefined) return;\n\t\tif (queue.length === 0) {\n\t\t\tif (sourceDone) actions.down([[COMPLETE]]);\n\t\t\treturn;\n\t\t}\n\t\tconst v = queue.shift()!;\n\t\tinnerUnsub = forwardInner(fromAny(project(v)), actions, () => {\n\t\t\tclearInner();\n\t\t\ttryPump();\n\t\t});\n\t}\n\n\tfunction enqueue(v: T): void {\n\t\tif (maxBuf && maxBuf > 0 && queue.length >= maxBuf) queue.shift();\n\t\tqueue.push(v);\n\t\ttryPump();\n\t}\n\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tactions = a;\n\n\t\t\tif (ctx.terminalDeps[0] != null && ctx.terminalDeps[0] !== true) {\n\t\t\t\tclearInner();\n\t\t\t\tqueue.length = 0;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tsourceDone = true;\n\t\t\t\ttryPump();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\n\t\t\tfor (const v of batch0 as T[]) {\n\t\t\t\tenqueue(v as T);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tdeactivation: () => {\n\t\t\t\t\tclearInner();\n\t\t\t\t\tqueue.length = 0;\n\t\t\t\t\tsourceDone = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...operatorOpts(concatNodeOpts), completeWhenDepsComplete: false },\n\t);\n}\n\n/** Options for {@link mergeMap}. */\nexport type MergeMapOptions = ExtraOpts & {\n\t/** Maximum number of concurrent inner subscriptions. Default: `Infinity` (unbounded). */\n\tconcurrent?: number;\n};\n\n/**\n * Subscribes to inner nodes in parallel (up to `concurrent`) and merges outputs (`mergeMap` / `flatMap`).\n *\n * @param source - Upstream node.\n * @param project - Maps each outer value to an inner source shape (`Node`, scalar, `PromiseLike`, `Iterable`, or `AsyncIterable`) coerced via {@link fromAny}.\n * @param opts - Optional options including `concurrent` limit.\n * @returns `Node<R>` - Merged output of all active inners; completes when the outer and every inner complete.\n *\n * @remarks\n * **ERROR handling:** An `ERROR` from the outer source cancels all active inner\n * subscriptions and propagates the error downstream. An `ERROR` from an inner\n * subscription propagates downstream immediately but does **not** cancel sibling\n * inner subscriptions — other active inners continue until they complete or the\n * outer errors/completes. This is intentional: for parallel work, isolating\n * failures per-inner is more useful than Rx-style \"first error cancels all.\"\n *\n * @example\n * ```ts\n * import { mergeMap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * // Unbounded (default)\n * mergeMap(state(0), (n) => state((n as number) + 1));\n *\n * // Limited concurrency\n * mergeMap(state(0), (n) => state((n as number) + 1), { concurrent: 3 });\n * ```\n *\n * @category extra\n */\nexport function mergeMap<T, R>(\n\tsource: Node<T>,\n\tproject: (value: T) => NodeInput<R>,\n\topts?: MergeMapOptions,\n): Node<R> {\n\tconst { concurrent: concurrentOpt, ...mergeNodeOpts } = opts ?? {};\n\tconst maxConcurrent =\n\t\tconcurrentOpt != null && concurrentOpt > 0 ? concurrentOpt : Number.POSITIVE_INFINITY;\n\n\tlet active = 0;\n\tlet sourceDone = false;\n\tconst innerStops = new Set<() => void>();\n\tconst buffer: T[] = [];\n\tlet actions: NodeActions | undefined;\n\n\tfunction tryComplete(): void {\n\t\tif (sourceDone && active === 0 && buffer.length === 0 && actions) {\n\t\t\tactions.down([[COMPLETE]]);\n\t\t}\n\t}\n\n\tfunction spawn(v: T): void {\n\t\tif (!actions) return;\n\t\tactive++;\n\t\t// Use `let` (not `const`) so the closure can reference `stop` safely even\n\t\t// if onInnerComplete fires synchronously (e.g. already-completed inner node).\n\t\tlet stop: (() => void) | undefined;\n\t\tstop = forwardInner(fromAny(project(v)), actions, () => {\n\t\t\tif (stop) innerStops.delete(stop);\n\t\t\tactive--;\n\t\t\tdrainBuffer();\n\t\t\ttryComplete();\n\t\t});\n\t\tinnerStops.add(stop);\n\t}\n\n\tfunction drainBuffer(): void {\n\t\twhile (buffer.length > 0 && active < maxConcurrent) {\n\t\t\tspawn(buffer.shift()!);\n\t\t}\n\t}\n\n\tfunction enqueue(v: T): void {\n\t\tif (active < maxConcurrent) spawn(v);\n\t\telse buffer.push(v);\n\t}\n\n\tfunction clearAll(): void {\n\t\tfor (const u of innerStops) u();\n\t\tinnerStops.clear();\n\t\tactive = 0;\n\t\tbuffer.length = 0;\n\t}\n\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tactions = a;\n\n\t\t\tif (ctx.terminalDeps[0] != null && ctx.terminalDeps[0] !== true) {\n\t\t\t\tclearAll();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tsourceDone = true;\n\t\t\t\ttryComplete();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\n\t\t\tfor (const v of batch0 as T[]) {\n\t\t\t\tenqueue(v as T);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tdeactivation: () => {\n\t\t\t\t\tclearAll();\n\t\t\t\t\tsourceDone = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...operatorOpts(mergeNodeOpts), completeWhenDepsComplete: false },\n\t);\n}\n\n/**\n * RxJS-named alias for {@link mergeMap} — projects each `DATA` to an inner node and merges outputs.\n *\n * @param source - Upstream node.\n * @param project - Returns an inner `Node<R>` per value.\n * @param opts - Optional concurrency cap and node options (excluding `describeKind`).\n * @returns Merged projection; behavior matches `mergeMap`.\n *\n * @example\n * ```ts\n * import { flatMap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * flatMap(state(0), (n) => state(n));\n * ```\n *\n * @category extra\n */\nexport const flatMap = mergeMap;\n\n/**\n * Delays phase-2 emissions by `ms` (timers). `DIRTY` still forwards immediately.\n *\n * @param source - Upstream node.\n * @param ms - Delay in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Same values, shifted in time.\n * @example\n * ```ts\n * import { delay, state } from \"@graphrefly/graphrefly-ts\";\n *\n * delay(state(1), 100);\n * ```\n *\n * @category extra\n */\nexport function delay<T>(source: Node<T>, ms: number, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\tconst timers = new Set<ReturnType<typeof setTimeout>>();\n\t\tfunction clearAll(): void {\n\t\t\tfor (const id of timers) clearTimeout(id);\n\t\t\ttimers.clear();\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tconst id = setTimeout(() => {\n\t\t\t\t\t\ttimers.delete(id);\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t}, ms);\n\t\t\t\t\ttimers.add(id);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t// Wait for all pending timers, then complete\n\t\t\t\t\tconst id = setTimeout(() => {\n\t\t\t\t\t\ttimers.delete(id);\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t}, ms);\n\t\t\t\t\ttimers.add(id);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tclearAll();\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t\t// DIRTY from source is NOT forwarded — delay transforms the\n\t\t\t\t// timeline. a.emit(v) in the timer callback handles full\n\t\t\t\t// DIRTY+DATA framing atomically at the delayed time.\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearAll();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Emits the latest value only after `ms` quiet time since the last trigger (`debounce`).\n *\n * @param source - Upstream node.\n * @param ms - Quiet window in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Debounced stream.\n * @example\n * ```ts\n * import { debounce, state } from \"@graphrefly/graphrefly-ts\";\n *\n * debounce(state(0), 50);\n * ```\n *\n * @category extra\n */\nexport function debounce<T>(source: Node<T>, ms: number, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet pending: T | undefined;\n\n\t\tfunction clearTimer(): void {\n\t\t\tif (timer !== undefined) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\ttimer = undefined;\n\t\t\t}\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tclearTimer();\n\t\t\t\t\tpending = m[1] as T;\n\t\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\t\ttimer = undefined;\n\t\t\t\t\t\ta.emit(pending as T);\n\t\t\t\t\t}, ms);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tif (timer !== undefined) {\n\t\t\t\t\t\tclearTimer();\n\t\t\t\t\t\ta.emit(pending as T);\n\t\t\t\t\t}\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tclearTimer();\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearTimer();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\nexport type ThrottleOptions = { leading?: boolean; trailing?: boolean };\n\n/**\n * Rate-limits emissions to at most once per `ms` window (`throttleTime`).\n *\n * @param source - Upstream node.\n * @param ms - Minimum spacing in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`) plus `leading` / `trailing`.\n * @returns `Node<T>` - Throttled stream.\n * @example\n * ```ts\n * import { throttle, state } from \"@graphrefly/graphrefly-ts\";\n *\n * throttle(state(0), 1_000, { trailing: false });\n * ```\n *\n * @category extra\n */\nexport function throttle<T>(\n\tsource: Node<T>,\n\tms: number,\n\topts?: ExtraOpts & ThrottleOptions,\n): Node<T> {\n\tconst { leading: leadingOpt, trailing: trailingOpt, ...throttleNodeOpts } = opts ?? {};\n\tconst leading = leadingOpt !== false;\n\tconst trailing = trailingOpt === true;\n\tconst windowNs = ms * NS_PER_MS;\n\n\treturn producer<T>((a) => {\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet lastEmitNs = -Infinity;\n\t\tlet pending: T | undefined;\n\t\tlet hasPending = false;\n\n\t\tfunction clearTimer(): void {\n\t\t\tif (timer !== undefined) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\ttimer = undefined;\n\t\t\t}\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tconst v = m[1] as T;\n\t\t\t\t\tconst nowNs = monotonicNs();\n\t\t\t\t\tif (leading && nowNs - lastEmitNs >= windowNs) {\n\t\t\t\t\t\tlastEmitNs = nowNs;\n\t\t\t\t\t\ta.emit(v);\n\t\t\t\t\t\tclearTimer();\n\t\t\t\t\t\tif (trailing) {\n\t\t\t\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\t\t\t\ttimer = undefined;\n\t\t\t\t\t\t\t\tif (hasPending) {\n\t\t\t\t\t\t\t\t\tlastEmitNs = monotonicNs();\n\t\t\t\t\t\t\t\t\ta.emit(pending as T);\n\t\t\t\t\t\t\t\t\thasPending = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}, ms);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (trailing) {\n\t\t\t\t\t\tpending = v;\n\t\t\t\t\t\thasPending = true;\n\t\t\t\t\t\tif (timer === undefined) {\n\t\t\t\t\t\t\tconst elapsedMs = (nowNs - lastEmitNs) / NS_PER_MS;\n\t\t\t\t\t\t\ttimer = setTimeout(\n\t\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\t\ttimer = undefined;\n\t\t\t\t\t\t\t\t\tif (hasPending) {\n\t\t\t\t\t\t\t\t\t\tlastEmitNs = monotonicNs();\n\t\t\t\t\t\t\t\t\t\ta.emit(pending as T);\n\t\t\t\t\t\t\t\t\t\thasPending = false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tMath.max(0, ms - elapsedMs),\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} else if (m[0] === COMPLETE || m[0] === ERROR) {\n\t\t\t\t\tclearTimer();\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearTimer();\n\t\t};\n\t}, operatorOpts(throttleNodeOpts));\n}\n\n/**\n * Emits the most recent source value whenever `notifier` emits `DATA` (`sample`).\n *\n * Source `COMPLETE` stops sampling (clears held value); notifier `COMPLETE` terminates the\n * operator. `ERROR` from either dep terminates immediately. At most one terminal message is\n * emitted downstream (latch). Supports `resubscribable` — `ctx.store` resets automatically.\n *\n * @param source - Node whose latest value is sampled.\n * @param notifier - When this node emits `DATA`, a sample is taken.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Sampled snapshots of `source`.\n * @example\n * ```ts\n * import { sample, state } from \"@graphrefly/graphrefly-ts\";\n *\n * sample(state(1), state(0));\n * ```\n *\n * @category extra\n */\nexport function sample<T>(source: Node<T>, notifier: Node<unknown>, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet lastSourceValue: { v: T } | undefined;\n\t\tlet terminated = false;\n\t\tlet sourceCompleted = false;\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tif (terminated) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (terminated) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tlastSourceValue = { v: m[1] as T };\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tterminated = true;\n\t\t\t\t\ta.down([m]);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tsourceCompleted = true;\n\t\t\t\t\tlastSourceValue = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst notUnsub = notifier.subscribe((msgs) => {\n\t\t\tif (terminated) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (terminated) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tif (lastSourceValue !== undefined && !sourceCompleted) {\n\t\t\t\t\t\ta.emit(lastSourceValue.v);\n\t\t\t\t\t}\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tterminated = true;\n\t\t\t\t\ta.down([m]);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tterminated = true;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tnotUnsub();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * After each source `DATA`, waits `ms` then emits the latest value if another `DATA` has not arrived (`auditTime` / trailing window).\n *\n * @param source - Upstream node.\n * @param ms - Window in milliseconds after each `DATA`.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Trailing-edge sampled stream.\n * @example\n * ```ts\n * import { audit, state } from \"@graphrefly/graphrefly-ts\";\n *\n * audit(state(0), 100);\n * ```\n *\n * @category extra\n */\nexport function audit<T>(source: Node<T>, ms: number, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet latest: T | undefined;\n\t\tlet has = false;\n\n\t\tfunction clearTimer(): void {\n\t\t\tif (timer !== undefined) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\ttimer = undefined;\n\t\t\t}\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tlatest = m[1] as T;\n\t\t\t\t\thas = true;\n\t\t\t\t\tclearTimer();\n\t\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\t\ttimer = undefined;\n\t\t\t\t\t\tif (has) {\n\t\t\t\t\t\t\thas = false;\n\t\t\t\t\t\t\ta.emit(latest as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, ms);\n\t\t\t\t} else if (m[0] === COMPLETE || m[0] === ERROR) {\n\t\t\t\t\tclearTimer();\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearTimer();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Errors if no `DATA` arrives within `ms` after subscribe or after the previous `DATA`.\n *\n * @param source - Upstream node.\n * @param ms - Idle budget in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`) and `with` for a custom error payload.\n * @returns `Node<T>` - Pass-through with idle watchdog.\n * @example\n * ```ts\n * import { timeout, state } from \"@graphrefly/graphrefly-ts\";\n *\n * timeout(state(0), 5_000);\n * ```\n *\n * @category extra\n */\nexport function timeout<T>(\n\tsource: Node<T>,\n\tms: number,\n\topts?: ExtraOpts & { with?: unknown },\n): Node<T> {\n\tconst { with: withPayload, ...timeoutNodeOpts } = opts ?? {};\n\tconst err = withPayload ?? new Error(\"timeout\");\n\n\treturn producer<T>((a) => {\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\n\t\tfunction arm(): void {\n\t\t\tclearTimeout(timer);\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\ttimer = undefined;\n\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t}, ms);\n\t\t}\n\n\t\t// Arm immediately on subscribe\n\t\tarm();\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tarm();\n\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t} else if (m[0] === COMPLETE || m[0] === ERROR) {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearTimeout(timer);\n\t\t};\n\t}, operatorOpts(timeoutNodeOpts));\n}\n\n/**\n * Buffers source `DATA` values; flushes an array when `notifier` settles (`buffer`).\n *\n * @param source - Upstream node.\n * @param notifier - Flush trigger on each settlement.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T[]>` - Emits buffered arrays (may be empty-handled via `RESOLVED` when nothing buffered).\n * @example\n * ```ts\n * import { buffer, state } from \"@graphrefly/graphrefly-ts\";\n *\n * buffer(state(0), state(0));\n * ```\n *\n * @category extra\n */\nexport function buffer<T>(source: Node<T>, notifier: Node<unknown>, opts?: ExtraOpts): Node<T[]> {\n\treturn producer<T[]>((a) => {\n\t\tconst buf: T[] = [];\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tbuf.push(m[1] as T);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tif (buf.length > 0) a.emit([...buf]);\n\t\t\t\t\tbuf.length = 0;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst notUnsub = notifier.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tif (buf.length > 0) {\n\t\t\t\t\t\ta.emit([...buf]);\n\t\t\t\t\t\tbuf.length = 0;\n\t\t\t\t\t}\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t// Notifier complete — forward\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tnotUnsub();\n\t\t\tbuf.length = 0;\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Batches consecutive `DATA` values into arrays of length `count` (`bufferCount` / `windowCount`).\n *\n * @param source - Upstream node.\n * @param count - Buffer size before emit; must be > 0.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T[]>` - Emits fixed-size arrays; remainder flushes on `COMPLETE`.\n * @example\n * ```ts\n * import { bufferCount, state } from \"@graphrefly/graphrefly-ts\";\n *\n * bufferCount(state(0), 3);\n * ```\n *\n * @category extra\n */\nexport function bufferCount<T>(source: Node<T>, count: number, opts?: ExtraOpts): Node<T[]> {\n\tif (count <= 0) throw new RangeError(\"bufferCount expects count > 0\");\n\treturn producer<T[]>((a) => {\n\t\tconst buf: T[] = [];\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tbuf.push(m[1] as T);\n\t\t\t\t\tif (buf.length >= count) {\n\t\t\t\t\t\ta.emit(buf.splice(0, buf.length));\n\t\t\t\t\t}\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tif (buf.length > 0) a.emit([...buf]);\n\t\t\t\t\tbuf.length = 0;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tbuf.length = 0;\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Splits source `DATA` into sub-nodes of `count` values each. Each sub-node completes after `count` items or when source completes.\n *\n * @param source - Upstream node.\n * @param count - Items per window.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<Node<T>>` - Each emission is a sub-node carrying that window's values.\n *\n * @example\n * ```ts\n * import { windowCount, state } from \"@graphrefly/graphrefly-ts\";\n *\n * windowCount(state(0), 3);\n * ```\n *\n * @category extra\n */\nexport function windowCount<T>(source: Node<T>, count: number, opts?: ExtraOpts): Node<Node<T>> {\n\tif (count <= 0) throw new RangeError(\"windowCount expects count > 0\");\n\n\treturn producer<Node<T>>((a) => {\n\t\tlet winDown: ((msgs: Messages) => void) | undefined;\n\t\tlet n = 0;\n\n\t\tfunction openWindow(): void {\n\t\t\tconst s = producer<T>((actions) => {\n\t\t\t\twinDown = actions.down.bind(actions);\n\t\t\t\treturn () => {\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t};\n\t\t\t}, operatorOpts());\n\t\t\tn = 0;\n\t\t\ta.emit(s);\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tif (!winDown) openWindow();\n\t\t\t\t\twinDown?.([[DATA, m[1]]]);\n\t\t\t\t\tn += 1;\n\t\t\t\t\tif (n >= count) {\n\t\t\t\t\t\twinDown?.([[COMPLETE]]);\n\t\t\t\t\t\twinDown = undefined;\n\t\t\t\t\t}\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\twinDown?.([[COMPLETE]]);\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\twinDown?.([m]);\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\twinDown?.([[COMPLETE]]);\n\t\t\twinDown = undefined;\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Flushes buffered `DATA` values every `ms` (`bufferTime` / `windowTime`).\n *\n * @param source - Upstream node.\n * @param ms - Flush interval in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T[]>` - Time-windowed batches.\n * @example\n * ```ts\n * import { bufferTime, state } from \"@graphrefly/graphrefly-ts\";\n *\n * bufferTime(state(0), 250);\n * ```\n *\n * @category extra\n */\nexport function bufferTime<T>(source: Node<T>, ms: number, opts?: ExtraOpts): Node<T[]> {\n\treturn producer<T[]>((a) => {\n\t\tconst buf: T[] = [];\n\n\t\tconst iv = setInterval(() => {\n\t\t\tif (buf.length > 0) {\n\t\t\t\ta.emit([...buf]);\n\t\t\t\tbuf.length = 0;\n\t\t\t}\n\t\t}, ms);\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tbuf.push(m[1] as T);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tclearInterval(iv);\n\t\t\t\t\tif (buf.length > 0) a.emit([...buf]);\n\t\t\t\t\tbuf.length = 0;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tclearInterval(iv);\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t\t// DIRTY from source is NOT forwarded — bufferTime\n\t\t\t\t// transforms the timeline. a.emit(buf) handles full\n\t\t\t\t// DIRTY+DATA framing when the interval fires.\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearInterval(iv);\n\t\t\tbuf.length = 0;\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Splits source `DATA` into time-windowed sub-nodes; each window lasts `ms`.\n *\n * @param source - Upstream node.\n * @param ms - Window duration in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<Node<T>>` - Each emission is a sub-node carrying that window's values.\n *\n * @example\n * ```ts\n * import { windowTime, state } from \"@graphrefly/graphrefly-ts\";\n *\n * windowTime(state(0), 500);\n * ```\n *\n * @category extra\n */\nexport function windowTime<T>(source: Node<T>, ms: number, opts?: ExtraOpts): Node<Node<T>> {\n\treturn producer<Node<T>>((a) => {\n\t\tlet winDown: ((msgs: Messages) => void) | undefined;\n\n\t\tfunction closeWindow(): void {\n\t\t\twinDown?.([[COMPLETE]]);\n\t\t\twinDown = undefined;\n\t\t}\n\n\t\tfunction openWindow(): void {\n\t\t\tconst s = producer<T>((actions) => {\n\t\t\t\twinDown = actions.down.bind(actions);\n\t\t\t\treturn () => {\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t};\n\t\t\t}, operatorOpts());\n\t\t\ta.emit(s);\n\t\t}\n\n\t\topenWindow();\n\t\tconst iv = setInterval(() => {\n\t\t\tcloseWindow();\n\t\t\topenWindow();\n\t\t}, ms);\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\twinDown?.([[DATA, m[1]]]);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tclearInterval(iv);\n\t\t\t\t\tcloseWindow();\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tclearInterval(iv);\n\t\t\t\t\twinDown?.([m]);\n\t\t\t\t\tcloseWindow();\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearInterval(iv);\n\t\t\tcloseWindow();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Splits source `DATA` into sub-nodes, opening a new window each time `notifier` emits `DATA`.\n *\n * @param source - Upstream node.\n * @param notifier - Each `DATA` from `notifier` closes the current window and opens a new one.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<Node<T>>` - Each emission is a sub-node carrying that window's values.\n *\n * @example\n * ```ts\n * import { state, window } from \"@graphrefly/graphrefly-ts\";\n *\n * window(state(0), state(0));\n * ```\n *\n * @category extra\n */\nexport function window<T>(\n\tsource: Node<T>,\n\tnotifier: Node<unknown>,\n\topts?: ExtraOpts,\n): Node<Node<T>> {\n\treturn producer<Node<T>>((a) => {\n\t\tlet winDown: ((msgs: Messages) => void) | undefined;\n\n\t\tfunction closeWindow(): void {\n\t\t\twinDown?.([[COMPLETE]]);\n\t\t\twinDown = undefined;\n\t\t}\n\n\t\tfunction openWindow(): void {\n\t\t\tconst s = producer<T>((actions) => {\n\t\t\t\twinDown = actions.down.bind(actions);\n\t\t\t\treturn () => {\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t};\n\t\t\t}, operatorOpts());\n\t\t\ta.emit(s);\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tif (!winDown) openWindow();\n\t\t\t\t\twinDown?.([[DATA, m[1]]]);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tcloseWindow();\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\twinDown?.([m]);\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst notUnsub = notifier.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tcloseWindow();\n\t\t\t\t\topenWindow();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tnotUnsub();\n\t\t\tcloseWindow();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Increments on each tick (`interval`); uses `setInterval` via {@link producer}.\n *\n * @param periodMs - Time between ticks.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<number>` - Emits `0`, `1`, `2`, … while subscribed.\n * @example\n * ```ts\n * import { interval } from \"@graphrefly/graphrefly-ts\";\n *\n * interval(1_000);\n * ```\n *\n * @category extra\n */\nexport function interval(periodMs: number, opts?: ExtraOpts): Node<number> {\n\treturn producer<number>((a, ctx) => {\n\t\tif (!(\"n\" in ctx.store)) ctx.store.n = 0;\n\t\tconst id = setInterval(() => {\n\t\t\ta.emit(ctx.store.n as number);\n\t\t\tctx.store.n = (ctx.store.n as number) + 1;\n\t\t}, periodMs);\n\t\treturn () => clearInterval(id);\n\t}, operatorOpts(opts));\n}\n\n/**\n * Subscribes to `source` repeatedly (`count` times, sequentially). Best with a fresh or `resubscribable` source.\n *\n * @param source - Upstream node to replay.\n * @param count - Number of subscription rounds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Forwards each round then completes after the last inner `COMPLETE`.\n * @example\n * ```ts\n * import { repeat, state } from \"@graphrefly/graphrefly-ts\";\n *\n * repeat(state(1, { resubscribable: true }), 2);\n * ```\n *\n * @category extra\n */\nexport function repeat<T>(source: Node<T>, count: number, opts?: ExtraOpts): Node<T> {\n\tif (count <= 0) throw new RangeError(\"repeat expects count > 0\");\n\treturn producer<T>((a) => {\n\t\tlet remaining = count;\n\t\tlet innerU: (() => void) | undefined;\n\n\t\tconst start = (): void => {\n\t\t\tinnerU?.();\n\t\t\tinnerU = source.subscribe((msgs) => {\n\t\t\t\tlet completed = false;\n\t\t\t\tconst fwd: Message[] = [];\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === COMPLETE) completed = true;\n\t\t\t\t\telse fwd.push(m);\n\t\t\t\t}\n\t\t\t\tif (fwd.length > 0) a.down(fwd as unknown as Messages);\n\t\t\t\tif (completed) {\n\t\t\t\t\tinnerU?.();\n\t\t\t\t\tinnerU = undefined;\n\t\t\t\t\tremaining -= 1;\n\t\t\t\t\tif (remaining > 0) start();\n\t\t\t\t\telse a.down([[COMPLETE]]);\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\tstart();\n\t\treturn () => {\n\t\t\tinnerU?.();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Identity passthrough — `pausable()` has been promoted to default node behavior in v5 (§4).\n *\n * @deprecated Default node behavior now handles PAUSE/RESUME. This operator is a no-op\n * identity passthrough kept only for migration compatibility.\n *\n * @param source - Upstream node.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Pass-through (identity).\n * @example\n * ```ts\n * import { pausable, state } from \"@graphrefly/graphrefly-ts\";\n *\n * // No longer needed — default nodes handle PAUSE/RESUME.\n * const s = state(0);\n * pausable(s); // identity passthrough\n * ```\n *\n * @category extra\n */\nexport function pausable<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) a.emit(v as T);\n\t\t},\n\t\toperatorOpts<T>(opts),\n\t);\n}\n\n/**\n * Replaces an upstream `ERROR` with a recovered value (`catchError`-style).\n *\n * @param source - Upstream node.\n * @param recover - Maps the error payload to a replacement value; if it throws, `ERROR` is forwarded.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Recovered stream.\n * @example\n * ```ts\n * import { rescue, state } from \"@graphrefly/graphrefly-ts\";\n *\n * rescue(state(0), () => 0);\n * ```\n *\n * @category extra\n */\nexport function rescue<T>(\n\tsource: Node<T>,\n\trecover: (err: unknown) => T,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn producer<T>((a) => {\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ta.emit(recover(m[1]));\n\t\t\t\t\t} catch (recoverErr) {\n\t\t\t\t\t\ta.down([[ERROR, recoverErr]]);\n\t\t\t\t\t}\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Forwards upstream `DATA` only while `control.get()` is truthy; when closed, emits `RESOLVED`\n * instead of repeating the last value (value-level valve). For protocol pause/resume, use default\n * node PAUSE/RESUME behavior.\n *\n * @param source - Upstream value node.\n * @param control - Boolean node; when falsy, output stays \"closed\" for that tick.\n * @param opts - Optional node options (excluding `describeKind`).\n * @returns `Node<T>` gated by `control`.\n *\n * @example\n * ```ts\n * import { valve, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const data = state(1);\n * const open = state(true);\n * valve(data, open);\n * ```\n *\n * @category extra\n */\nexport function valve<T>(source: Node<T>, control: Node<boolean>, opts?: ExtraOpts): Node<T> {\n\treturn node<T>(\n\t\t[source as Node, control as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch1 = data[1];\n\t\t\t// undefined = control never sent DATA (gate closed); falsy = explicitly closed.\n\t\t\tconst controlValue = batch1 != null && batch1.length > 0 ? batch1.at(-1) : ctx.prevData[1];\n\t\t\tif (!controlValue) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\t// Source data this wave: forward it.\n\t\t\t\tfor (const v of batch0) a.emit(v as T);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Control just opened this wave but source didn't fire this wave.\n\t\t\t// Re-emit the last known source value so downstream sees the current\n\t\t\t// value when the gate opens (only when source has a prior value).\n\t\t\tif (batch1 != null && batch1.length > 0 && ctx.prevData[0] !== undefined) {\n\t\t\t\ta.emit(ctx.prevData[0] as T);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ta.down([[RESOLVED]]);\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// RxJS-compatible aliases — improve AI code-generation accuracy\n// ——————————————————————————————————————————————————————————————\n\n/**\n * RxJS-named alias for {@link combine} — emits when any dep updates with latest tuple of values.\n *\n * @param sources - Upstream nodes as separate arguments (same calling shape as `combine`).\n * @returns Combined node; signature matches `combine`.\n *\n * @example\n * ```ts\n * import { combineLatest, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = combineLatest(state(1), state(\"a\"));\n * ```\n *\n * @category extra\n */\nexport const combineLatest = combine;\n\n/**\n * RxJS-named alias for {@link debounce} — drops rapid `DATA` until `ms` of quiet.\n *\n * @param source - Upstream node.\n * @param ms - Quiet period in milliseconds.\n * @param opts - Optional node options (excluding `describeKind`).\n * @returns Debounced node; behavior matches `debounce`.\n *\n * @example\n * ```ts\n * import { debounceTime, state } from \"@graphrefly/graphrefly-ts\";\n *\n * debounceTime(state(0), 100);\n * ```\n *\n * @category extra\n */\nexport const debounceTime = debounce;\n\n/**\n * RxJS-named alias for {@link throttle} — emits on leading/trailing edges within `ms`.\n *\n * @param source - Upstream node.\n * @param ms - Minimum spacing in milliseconds.\n * @param opts - Optional throttle shape (`leading` / `trailing`) and node options.\n * @returns Throttled node; behavior matches `throttle`.\n *\n * @example\n * ```ts\n * import { throttleTime, state } from \"@graphrefly/graphrefly-ts\";\n *\n * throttleTime(state(0), 100);\n * ```\n *\n * @category extra\n */\nexport const throttleTime = throttle;\n\n/**\n * RxJS-named alias for {@link rescue} — replaces upstream `ERROR` with a recovered value.\n *\n * @param source - Upstream node.\n * @param recover - Maps error payload to replacement value.\n * @param opts - Optional node options (excluding `describeKind`).\n * @returns Recovered stream; behavior matches `rescue`.\n *\n * @example\n * ```ts\n * import { catchError, state } from \"@graphrefly/graphrefly-ts\";\n *\n * catchError(state(0), () => 0);\n * ```\n *\n * @category extra\n */\nexport const catchError = rescue;\n","/**\n * Fixed-capacity ring buffer — O(1) push and drop-oldest eviction.\n *\n * Used by `Graph._traceRing` (reasoning trace), `reactiveLog` (append-only\n * log backend), and `reactiveSink` (drop-oldest backpressure buffer). One\n * implementation, three use sites.\n *\n * @module\n * @internal\n */\n\n/**\n * Fixed-capacity ring buffer. Once `capacity` entries are stored, subsequent\n * `push` calls evict the oldest entry (drop-oldest / FIFO eviction).\n *\n * Operations:\n * - `push(item)` — O(1).\n * - `shift()` — O(1) remove oldest (returns `undefined` when empty).\n * - `at(i)` — O(1) index lookup, with Python-style negative indexing.\n * - `toArray()` — O(n) materialize in insertion order.\n * - `clear()` — O(1) reset to empty.\n *\n * Not thread-safe; JS semantics assumed (single-threaded within a sync call).\n */\nexport class RingBuffer<T> {\n\tprivate buf: (T | undefined)[];\n\tprivate head = 0;\n\tprivate _size = 0;\n\n\tconstructor(private capacity: number) {\n\t\tif (!Number.isInteger(capacity) || capacity <= 0) {\n\t\t\tthrow new Error(`RingBuffer capacity must be a positive integer (got ${capacity})`);\n\t\t}\n\t\tthis.buf = new Array(capacity);\n\t}\n\n\t/** Current number of stored entries. */\n\tget size(): number {\n\t\treturn this._size;\n\t}\n\n\t/** Configured maximum before drop-oldest eviction fires. */\n\tget maxSize(): number {\n\t\treturn this.capacity;\n\t}\n\n\t/**\n\t * Append an item. If size equals capacity, drops the oldest entry and\n\t * advances the head pointer.\n\t */\n\tpush(item: T): void {\n\t\tconst idx = (this.head + this._size) % this.capacity;\n\t\tthis.buf[idx] = item;\n\t\tif (this._size < this.capacity) this._size++;\n\t\telse this.head = (this.head + 1) % this.capacity;\n\t}\n\n\t/** Remove and return the oldest entry; `undefined` when empty. */\n\tshift(): T | undefined {\n\t\tif (this._size === 0) return undefined;\n\t\tconst item = this.buf[this.head];\n\t\tthis.buf[this.head] = undefined;\n\t\tthis.head = (this.head + 1) % this.capacity;\n\t\tthis._size--;\n\t\treturn item;\n\t}\n\n\t/**\n\t * O(1) index lookup. Negative indices count from the tail (Python-style).\n\t * Returns `undefined` for out-of-range.\n\t */\n\tat(i: number): T | undefined {\n\t\tif (this._size === 0) return undefined;\n\t\tconst n = i < 0 ? this._size + i : i;\n\t\tif (n < 0 || n >= this._size) return undefined;\n\t\treturn this.buf[(this.head + n) % this.capacity];\n\t}\n\n\t/**\n\t * Materialize the contents in insertion order (oldest → newest).\n\t * Returns a new array each call.\n\t */\n\ttoArray(): T[] {\n\t\tconst result: T[] = new Array(this._size);\n\t\tfor (let i = 0; i < this._size; i++) {\n\t\t\tresult[i] = this.buf[(this.head + i) % this.capacity]!;\n\t\t}\n\t\treturn result;\n\t}\n\n\t/** Reset to empty. Storage slots are released so held refs can GC. */\n\tclear(): void {\n\t\tfor (let i = 0; i < this._size; i++) {\n\t\t\tthis.buf[(this.head + i) % this.capacity] = undefined;\n\t\t}\n\t\tthis.head = 0;\n\t\tthis._size = 0;\n\t}\n}\n","/**\n * {@link reactiveSink} — canonical sink factory for Wave 5 adapters.\n *\n * Every `to*` adapter in {@link ./adapters.ts} can be expressed as a thin\n * config wrapper around this one factory. It centralizes:\n *\n * - **Transport boundary** — the sole place in the sink layer where a raw\n * Promise / `.then` / `.catch` sits (§5.10 boundary documented here).\n * - **Retry** — delegates to {@link BackoffStrategy} from `backoff.ts`.\n * - **Buffering** — `batchSize` / `flushIntervalMs` with tier-3 flush-on-\n * terminal per spec §5.11. Buffered mode activates when `sendBatch` is\n * supplied or a batching knob is set.\n * - **Backpressure** — bounded internal queue with `drop-oldest` /\n * `drop-newest` / `error` strategies. The `\"wait\"` strategy is deferred\n * to external composition (`source | valve(...) | reactiveSink(...)`).\n * - **Companions** — `sent` / `failed` / `inFlight` / `errors` (+ `buffered`\n * / `paused` when buffering or backpressure is active). These surface\n * every transport outcome as reactive nodes so downstream operators can\n * build retry fallbacks, dead-letter queues, or SLO gauges without\n * touching callback soup.\n */\n\nimport { COMPLETE, DATA, ERROR, type Message, TEARDOWN } from \"../core/messages.js\";\nimport { defaultConfig, type Node } from \"../core/node.js\";\nimport { state } from \"../core/sugar.js\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tresolveBackoffPreset,\n} from \"./backoff.js\";\nimport { RingBuffer } from \"./utils/ring-buffer.js\";\n\n/**\n * Dual-mode buffer for the sink's backpressure queue.\n * - Bounded (finite `maxBuf`): wraps {@link RingBuffer} so drop-oldest is O(1)\n * instead of O(n) via `Array.prototype.shift`.\n * - Unbounded (`Infinity`): plain array — no drops, no need for ring semantics.\n * `drain()` always returns the current contents and resets to empty.\n */\nclass BackpressureBuffer<T> {\n\tprivate ring: RingBuffer<T> | null;\n\tprivate arr: T[] | null;\n\tconstructor(cap: number) {\n\t\tif (cap === Number.POSITIVE_INFINITY || cap <= 0) {\n\t\t\tthis.arr = [];\n\t\t\tthis.ring = null;\n\t\t} else {\n\t\t\tthis.ring = new RingBuffer<T>(cap);\n\t\t\tthis.arr = null;\n\t\t}\n\t}\n\tget length(): number {\n\t\treturn this.ring != null ? this.ring.size : this.arr!.length;\n\t}\n\tpush(item: T): void {\n\t\tif (this.ring != null) this.ring.push(item);\n\t\telse this.arr!.push(item);\n\t}\n\t/** Drop-oldest — O(1) in bounded mode. Returns undefined when empty. */\n\tshift(): T | undefined {\n\t\tif (this.ring != null) return this.ring.shift();\n\t\treturn this.arr!.shift();\n\t}\n\t/** Full drain — returns contents, resets to empty. */\n\tdrain(): T[] {\n\t\tif (this.ring != null) {\n\t\t\tconst out = this.ring.toArray();\n\t\t\tthis.ring.clear();\n\t\t\treturn out;\n\t\t}\n\t\tconst out = this.arr!;\n\t\tthis.arr = [];\n\t\treturn out;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Structured transport-failure record. Every sink routes both recoverable\n * (pre-retry) and terminal (post-exhaustion) failures through this shape.\n *\n * @category extra\n */\nexport type SinkTransportError = {\n\t/**\n\t * Failure stage. Known values: `\"serialize\"`, `\"send\"`, `\"close\"`,\n\t * `\"routing_key\"`, `\"ack\"`, `\"retry_exhausted\"`. Open to extension for\n\t * protocol-specific stages.\n\t */\n\tstage: string;\n\t/** The error. */\n\terror: Error;\n\t/** Unwrapped DATA value (present for per-record failures). */\n\tvalue: unknown;\n\t/** Full message tuple (present for non-DATA stages like `\"close\"`). */\n\tmessage?: Message;\n\t/** Attempt number when `retry` is active — `1` = initial send. */\n\tattempt?: number;\n};\n\n/**\n * Terminal failure record delivered on the `failed` companion after retries\n * are exhausted (or `shouldRetry` returned `false`).\n *\n * @category extra\n */\nexport type SinkFailure<T> = {\n\tvalue: T;\n\terror: Error;\n\t/** Total attempts made, including the initial send. */\n\tattempts: number;\n};\n\n/**\n * Handle returned by every Wave 5 sink.\n *\n * @category extra\n */\nexport type ReactiveSinkHandle<T> = {\n\t/** Unsubscribe from source, cancel timers, fire `TEARDOWN` on companions. */\n\tdispose(): void;\n\t/** Drain buffer + await in-flight sends (buffered mode only). */\n\tflush?(): Promise<void>;\n\t/** DATA values that successfully reached the transport. */\n\tsent: Node<T>;\n\t/** Values that permanently failed (after any retries). */\n\tfailed: Node<SinkFailure<T> | null>;\n\t/** Number of pending transport operations. */\n\tinFlight: Node<number>;\n\t/** Every transient transport error (pre-retry). Latest-only. */\n\terrors: Node<SinkTransportError | null>;\n\t/** Items currently buffered (buffered mode / backpressure only). */\n\tbuffered?: Node<number>;\n\t/** `true` when a backpressure strategy has dropped / rejected items. */\n\tpaused?: Node<boolean>;\n};\n\n/**\n * Retry configuration for {@link reactiveSink}.\n *\n * @category extra\n */\nexport type ReactiveSinkRetryOptions = {\n\t/** Total attempts including the initial send. Default: `1` (no retry). */\n\tmaxAttempts?: number;\n\t/** Backoff strategy (ns) or preset name. Default: `\"exponential\"` when `maxAttempts > 1`. */\n\tbackoff?: BackoffStrategy | BackoffPreset;\n\t/** Predicate — return `false` to short-circuit retry for a given error. */\n\tshouldRetry?: (err: Error, attempt: number) => boolean;\n};\n\n/**\n * Backpressure configuration for {@link reactiveSink}. When omitted, the\n * sink has no internal buffer cap beyond the natural `batchSize` /\n * `flushIntervalMs` limits.\n *\n * @category extra\n */\nexport type ReactiveSinkBackpressureOptions = {\n\t/** Hard cap on buffered items; further items trigger `strategy`. Default: `Infinity`. */\n\tmaxBuffer?: number;\n\t/** Policy when the buffer is full. Default: `\"drop-oldest\"`. */\n\tstrategy?: \"drop-oldest\" | \"drop-newest\" | \"error\";\n};\n\n/**\n * Base options shared by every sink built on {@link reactiveSink}.\n *\n * @category extra\n */\nexport type ReactiveSinkOptions<T> = {\n\t/** Optional name used for companion node naming. */\n\tname?: string;\n\t/** Invoked synchronously for every transient transport error. */\n\tonTransportError?: (err: SinkTransportError) => void;\n\t/** Retry configuration. */\n\tretry?: ReactiveSinkRetryOptions;\n\t/** Backpressure configuration. */\n\tbackpressure?: ReactiveSinkBackpressureOptions;\n\t/** Batch size before auto-flush (buffered mode). */\n\tbatchSize?: number;\n\t/** Flush interval in ms; `0` = write-through (buffered mode). */\n\tflushIntervalMs?: number;\n\t/** Optional transform applied before `send` / `sendBatch`. */\n\tserialize?: (value: T) => unknown;\n\t/**\n\t * Reactive stop signal — when this node emits any DATA or terminal, the\n\t * sink tears down. Gives callers a reactive alternative to the imperative\n\t * `handle.dispose()` call so teardown can be wired through the graph.\n\t */\n\tstopOn?: Node<unknown>;\n\t/**\n\t * Optional hook invoked for each upstream non-DATA message (COMPLETE /\n\t * ERROR / etc.) observed by the sink. Used by adapters like\n\t * {@link toWebSocket} to close the underlying resource when the source\n\t * terminates, without the caller having to subscribe twice.\n\t */\n\tonUpstreamMessage?: (msg: Message) => void;\n\t/**\n\t * Invoked once during `dispose()` after the sink's own cleanup (unsub,\n\t * final drain, TEARDOWN on companions). Adapters wrap external resources\n\t * (socket listeners, file handles) by passing their cleanup here —\n\t * avoids hand-rolling a wrapper around `handle.dispose`.\n\t */\n\tonDispose?: () => void;\n\t/**\n\t * Ignored — reserved for future parity with `source.pipe(...)` style.\n\t *\n\t * @internal\n\t */\n\t_reserved?: never;\n};\n\n/**\n * Full config accepted by {@link reactiveSink}. One of `send` / `sendBatch`\n * is required.\n *\n * @category extra\n */\nexport type ReactiveSinkConfig<T, Ctx = unknown> = ReactiveSinkOptions<T> & {\n\t/** Per-record transport call. */\n\tsend?: (value: T, ctx: Ctx) => Promise<void> | void;\n\t/** Batched transport call. When supplied, buffering activates automatically. */\n\tsendBatch?: (batch: T[], ctx: Ctx) => Promise<void> | void;\n\t/** Context object threaded into every `send` / `sendBatch` call. */\n\tctx?: Ctx;\n};\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction coerceError(err: unknown): Error {\n\treturn err instanceof Error ? err : new Error(String(err));\n}\n\nfunction resolveBackoff(\n\tbackoff: BackoffStrategy | BackoffPreset | undefined,\n): BackoffStrategy | null {\n\tif (backoff === undefined) return null;\n\tif (typeof backoff === \"string\") return resolveBackoffPreset(backoff);\n\treturn backoff;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Build a reactive sink with retry / buffering / backpressure / observability\n * companions. Every Wave 5 `to*` adapter is a thin config wrapper around\n * this factory.\n *\n * **Modes:**\n * - `send` only, no batching knobs → **per-record write-through**\n * - `send` + `batchSize` or `flushIntervalMs` → **per-record buffered**\n * (buffer drains via repeated `send` calls — one-by-one in order)\n * - `sendBatch` → **batched** (whole chunks handed to the transport)\n *\n * @category extra\n */\nexport function reactiveSink<T, Ctx = unknown>(\n\tsource: Node<T>,\n\tconfig: ReactiveSinkConfig<T, Ctx>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tname,\n\t\tonTransportError,\n\t\tretry,\n\t\tbackpressure,\n\t\tbatchSize = Number.POSITIVE_INFINITY,\n\t\tflushIntervalMs = 0,\n\t\tserialize,\n\t\tstopOn,\n\t\tonUpstreamMessage,\n\t\tonDispose,\n\t\tsend,\n\t\tsendBatch,\n\t\tctx: ctxValue,\n\t} = config;\n\n\tif (!send && !sendBatch) {\n\t\tthrow new Error(\"reactiveSink: `send` or `sendBatch` must be provided\");\n\t}\n\n\tconst ctx = ctxValue as Ctx;\n\tconst maxAttempts = Math.max(1, retry?.maxAttempts ?? 1);\n\tconst backoffStrategy = resolveBackoff(\n\t\tretry?.backoff ?? (maxAttempts > 1 ? \"exponential\" : undefined),\n\t);\n\tconst shouldRetry = retry?.shouldRetry ?? (() => true);\n\n\tconst useBuffering =\n\t\tsendBatch !== undefined || batchSize < Number.POSITIVE_INFINITY || flushIntervalMs > 0;\n\n\tconst nameFor = (suffix: string) => (name ? `${name}::${suffix}` : undefined);\n\n\tconst sent = state<T | undefined>(undefined, {\n\t\tequals: () => false,\n\t\tname: nameFor(\"sent\"),\n\t}) as unknown as Node<T>;\n\tconst failed = state<SinkFailure<T> | null>(null, { name: nameFor(\"failed\") });\n\tconst inFlightCountNode = state(0, { name: nameFor(\"inFlight\") });\n\tconst errorsNode = state<SinkTransportError | null>(null, { name: nameFor(\"errors\") });\n\tconst bufferedNode = useBuffering ? state(0, { name: nameFor(\"buffered\") }) : undefined;\n\tconst pausedNode = backpressure ? state(false, { name: nameFor(\"paused\") }) : undefined;\n\n\tlet inFlightCount = 0;\n\tconst bumpInFlight = (delta: number) => {\n\t\tinFlightCount += delta;\n\t\tinFlightCountNode.down([[DATA, inFlightCount]]);\n\t};\n\n\tconst reportError = (err: SinkTransportError) => {\n\t\ttry {\n\t\t\tonTransportError?.(err);\n\t\t} catch {\n\t\t\t/* user hook must not escape */\n\t\t}\n\t\ttry {\n\t\t\terrorsNode.down([[DATA, err]]);\n\t\t} catch {\n\t\t\t/* re-entrant drain — swallow */\n\t\t}\n\t};\n\n\tconst inFlightPromises = new Set<Promise<void>>();\n\n\tconst trackPromise = (p: Promise<void>) => {\n\t\tinFlightPromises.add(p);\n\t\tconst done = () => inFlightPromises.delete(p);\n\t\tp.then(done, done);\n\t};\n\n\t// Retry scheduling shared by per-record + batched paths.\n\tconst scheduleRetry = (runAgain: () => Promise<void>, attempt: number, error: Error) => {\n\t\tconst raw = backoffStrategy ? backoffStrategy(attempt - 1, error, null) : 0;\n\t\tconst delayNs =\n\t\t\traw === null || raw === undefined ? 0 : typeof raw === \"number\" && raw > 0 ? raw : 0;\n\t\t// Clamp to >=1ms — sub-ms delays via integer division collapse to 0 and\n\t\t// create synchronous retry loops that starve the event loop.\n\t\tconst delayMs = Math.max(1, Math.ceil(delayNs / NS_PER_MS));\n\t\treturn new Promise<void>((resolve) => {\n\t\t\t// §5.10: retry delay at the transport boundary.\n\t\t\tsetTimeout(() => resolve(runAgain()), delayMs);\n\t\t});\n\t};\n\n\tconst isThenable = (v: unknown): v is Promise<void> =>\n\t\tv != null && typeof v === \"object\" && typeof (v as { then?: unknown }).then === \"function\";\n\n\t// -------------------------------------------------------------------\n\t// Per-record send path — handles retry for a single value.\n\t//\n\t// Sync throws in `serialize` → reported synchronously as stage:\"serialize\".\n\t// Sync throws in `send` → reported synchronously as stage:\"send\".\n\t// Async rejections from send → reported as stage:\"send\" on the next tick.\n\t// -------------------------------------------------------------------\n\tconst performSend = (value: T): Promise<void> => {\n\t\tlet payload: unknown;\n\t\ttry {\n\t\t\tpayload = serialize ? serialize(value) : value;\n\t\t} catch (rawErr) {\n\t\t\tconst error = coerceError(rawErr);\n\t\t\treportError({ stage: \"serialize\", error, value });\n\t\t\tfailed.down([[DATA, { value, error, attempts: 0 } satisfies SinkFailure<T>]]);\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tlet attempt = 0;\n\n\t\tconst onError = (rawErr: unknown): Promise<void> | undefined => {\n\t\t\tbumpInFlight(-1);\n\t\t\tconst error = coerceError(rawErr);\n\t\t\treportError({ stage: \"send\", error, value, attempt });\n\t\t\tconst more = attempt < maxAttempts && shouldRetry(error, attempt);\n\t\t\tif (!more) {\n\t\t\t\tfailed.down([[DATA, { value, error, attempts: attempt } satisfies SinkFailure<T>]]);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn scheduleRetry(run, attempt, error);\n\t\t};\n\n\t\tconst onSuccess = () => {\n\t\t\tbumpInFlight(-1);\n\t\t\tsent.down([[DATA, value]]);\n\t\t};\n\n\t\tfunction run(): Promise<void> {\n\t\t\tattempt += 1;\n\t\t\tbumpInFlight(+1);\n\t\t\tlet result: Promise<void> | void;\n\t\t\ttry {\n\t\t\t\tresult = (send as (v: unknown, c: Ctx) => Promise<void> | void)(payload, ctx);\n\t\t\t} catch (rawErr) {\n\t\t\t\treturn onError(rawErr) ?? Promise.resolve();\n\t\t\t}\n\t\t\tif (isThenable(result)) {\n\t\t\t\treturn result.then(onSuccess, (rawErr) => onError(rawErr));\n\t\t\t}\n\t\t\tonSuccess();\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\treturn run();\n\t};\n\n\t// -------------------------------------------------------------------\n\t// Buffer management (buffered mode).\n\t//\n\t// Buffer entries keep the original value (for failure reporting) alongside\n\t// the post-serialize payload (for the transport call). Serializing at push\n\t// time guarantees sync `stage: \"serialize\"` error reporting — the old\n\t// hand-rolled sinks relied on this ordering.\n\t// -------------------------------------------------------------------\n\ttype BufferEntry = { value: T; payload: unknown };\n\tconst maxBuf = backpressure?.maxBuffer ?? Number.POSITIVE_INFINITY;\n\tconst buffer = new BackpressureBuffer<BufferEntry>(maxBuf);\n\tlet flushTimer: ReturnType<typeof setTimeout> | undefined;\n\tlet disposed = false;\n\n\tconst updateBuffered = () => {\n\t\tbufferedNode?.down([[DATA, buffer.length]]);\n\t};\n\n\tconst markPaused = (paused: boolean) => {\n\t\tif (!pausedNode) return;\n\t\tpausedNode.down([[DATA, paused]]);\n\t};\n\n\tconst bpStrategy = backpressure?.strategy ?? \"drop-oldest\";\n\n\tconst pushWithBackpressure = (value: T, payload: unknown): boolean => {\n\t\tconst entry: BufferEntry = { value, payload };\n\t\tif (buffer.length < maxBuf) {\n\t\t\tbuffer.push(entry);\n\t\t\tupdateBuffered();\n\t\t\treturn true;\n\t\t}\n\t\t// At cap — apply strategy.\n\t\tif (bpStrategy === \"drop-oldest\") {\n\t\t\tconst dropped = buffer.shift() as BufferEntry;\n\t\t\tbuffer.push(entry);\n\t\t\tupdateBuffered();\n\t\t\tmarkPaused(true);\n\t\t\tfailed.down([\n\t\t\t\t[\n\t\t\t\t\tDATA,\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: dropped.value,\n\t\t\t\t\t\terror: new Error(\"backpressure: buffer overflow — dropped oldest\"),\n\t\t\t\t\t\tattempts: 0,\n\t\t\t\t\t} satisfies SinkFailure<T>,\n\t\t\t\t],\n\t\t\t]);\n\t\t\treturn true;\n\t\t}\n\t\tif (bpStrategy === \"drop-newest\") {\n\t\t\tmarkPaused(true);\n\t\t\tfailed.down([\n\t\t\t\t[\n\t\t\t\t\tDATA,\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\terror: new Error(\"backpressure: buffer overflow — dropped newest\"),\n\t\t\t\t\t\tattempts: 0,\n\t\t\t\t\t} satisfies SinkFailure<T>,\n\t\t\t\t],\n\t\t\t]);\n\t\t\treturn false;\n\t\t}\n\t\t// \"error\"\n\t\tconst err = new Error(\"backpressure: buffer overflow\");\n\t\treportError({ stage: \"send\", error: err, value });\n\t\tfailed.down([[DATA, { value, error: err, attempts: 0 } satisfies SinkFailure<T>]]);\n\t\tmarkPaused(true);\n\t\treturn false;\n\t};\n\n\t// Buffered flush: chunk is already serialized at push time. Retry the whole\n\t// chunk on sendBatch failure (or per-record send failure).\n\tconst performBufferedBatchFlush = (chunk: BufferEntry[]): Promise<void> => {\n\t\tlet attempt = 0;\n\t\tconst payloads = chunk.map((e) => e.payload);\n\n\t\tconst onError = (rawErr: unknown): Promise<void> | undefined => {\n\t\t\tbumpInFlight(-1);\n\t\t\tconst error = coerceError(rawErr);\n\t\t\treportError({ stage: \"send\", error, value: chunk.map((e) => e.value), attempt });\n\t\t\tconst more = attempt < maxAttempts && shouldRetry(error, attempt);\n\t\t\tif (!more) {\n\t\t\t\tfor (const { value: v } of chunk) {\n\t\t\t\t\tfailed.down([[DATA, { value: v, error, attempts: attempt } satisfies SinkFailure<T>]]);\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn scheduleRetry(run, attempt, error);\n\t\t};\n\n\t\tconst onSuccess = () => {\n\t\t\tbumpInFlight(-1);\n\t\t\tfor (const { value: v } of chunk) sent.down([[DATA, v]]);\n\t\t};\n\n\t\tfunction run(): Promise<void> {\n\t\t\tattempt += 1;\n\t\t\tbumpInFlight(+1);\n\t\t\tlet result: Promise<void> | void;\n\t\t\ttry {\n\t\t\t\tresult = (sendBatch as (b: unknown[], c: Ctx) => Promise<void> | void)(payloads, ctx);\n\t\t\t} catch (rawErr) {\n\t\t\t\treturn onError(rawErr) ?? Promise.resolve();\n\t\t\t}\n\t\t\tif (isThenable(result)) {\n\t\t\t\treturn result.then(onSuccess, (rawErr) => onError(rawErr));\n\t\t\t}\n\t\t\tonSuccess();\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\treturn run();\n\t};\n\n\tconst performBufferedPerRecordFlush = async (chunk: BufferEntry[]): Promise<void> => {\n\t\tfor (const entry of chunk) {\n\t\t\t// Intentionally do NOT check `disposed` here — a dispose() mid-\n\t\t\t// drain must let the already-captured chunk finish; otherwise\n\t\t\t// buffered items would be dropped silently. `teardownRequested`\n\t\t\t// prevents NEW work from starting (no new subscribe batches past\n\t\t\t// this point), which is the right guard.\n\t\t\tawait performPreSerializedSend(entry.value, entry.payload);\n\t\t}\n\t};\n\n\t// Per-record send that skips re-serialization (buffer already serialized).\n\tconst performPreSerializedSend = (value: T, payload: unknown): Promise<void> => {\n\t\tlet attempt = 0;\n\t\tconst onError = (rawErr: unknown): Promise<void> | undefined => {\n\t\t\tbumpInFlight(-1);\n\t\t\tconst error = coerceError(rawErr);\n\t\t\treportError({ stage: \"send\", error, value, attempt });\n\t\t\tconst more = attempt < maxAttempts && shouldRetry(error, attempt);\n\t\t\tif (!more) {\n\t\t\t\tfailed.down([[DATA, { value, error, attempts: attempt } satisfies SinkFailure<T>]]);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn scheduleRetry(run, attempt, error);\n\t\t};\n\t\tconst onSuccess = () => {\n\t\t\tbumpInFlight(-1);\n\t\t\tsent.down([[DATA, value]]);\n\t\t};\n\t\tfunction run(): Promise<void> {\n\t\t\tattempt += 1;\n\t\t\tbumpInFlight(+1);\n\t\t\tlet result: Promise<void> | void;\n\t\t\ttry {\n\t\t\t\tresult = (send as (v: unknown, c: Ctx) => Promise<void> | void)(payload, ctx);\n\t\t\t} catch (rawErr) {\n\t\t\t\treturn onError(rawErr) ?? Promise.resolve();\n\t\t\t}\n\t\t\tif (isThenable(result)) {\n\t\t\t\treturn result.then(onSuccess, (rawErr) => onError(rawErr));\n\t\t\t}\n\t\t\tonSuccess();\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\treturn run();\n\t};\n\n\tconst doFlush = (): Promise<void> => {\n\t\tif (disposed || buffer.length === 0) return Promise.resolve();\n\t\tconst chunk = buffer.drain();\n\t\tupdateBuffered();\n\t\tmarkPaused(false);\n\t\tif (sendBatch !== undefined) {\n\t\t\tconst p = performBufferedBatchFlush(chunk);\n\t\t\ttrackPromise(p);\n\t\t\treturn p;\n\t\t}\n\t\tconst p = performBufferedPerRecordFlush(chunk);\n\t\ttrackPromise(p);\n\t\treturn p;\n\t};\n\n\tconst scheduleFlush = () => {\n\t\tif (flushTimer !== undefined || disposed) return;\n\t\tif (flushIntervalMs <= 0) return;\n\t\tflushTimer = setTimeout(() => {\n\t\t\t/* §5.10: flush deadline timer — not reactive scheduling */\n\t\t\tflushTimer = undefined;\n\t\t\tvoid doFlush();\n\t\t}, flushIntervalMs);\n\t};\n\n\t// -------------------------------------------------------------------\n\t// Upstream subscription.\n\t// -------------------------------------------------------------------\n\tconst unsub = source.subscribe((msgs) => {\n\t\tfor (const msg of msgs) {\n\t\t\tconst type = msg[0];\n\t\t\tif (type !== DATA) {\n\t\t\t\ttry {\n\t\t\t\t\tonUpstreamMessage?.(msg);\n\t\t\t\t} catch {\n\t\t\t\t\t/* user hook must not escape */\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (type === DATA) {\n\t\t\t\tconst value = msg[1] as T;\n\t\t\t\tif (useBuffering) {\n\t\t\t\t\t// Serialize sync at push time so `stage: \"serialize\"` errors\n\t\t\t\t\t// surface on the same tick as the upstream DATA emission.\n\t\t\t\t\tlet payload: unknown;\n\t\t\t\t\tif (serialize) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tpayload = serialize(value);\n\t\t\t\t\t\t} catch (rawErr) {\n\t\t\t\t\t\t\tconst error = coerceError(rawErr);\n\t\t\t\t\t\t\treportError({ stage: \"serialize\", error, value });\n\t\t\t\t\t\t\tfailed.down([[DATA, { value, error, attempts: 0 } satisfies SinkFailure<T>]]);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpayload = value;\n\t\t\t\t\t}\n\t\t\t\t\tconst admitted = pushWithBackpressure(value, payload);\n\t\t\t\t\tif (!admitted) continue;\n\t\t\t\t\tif (buffer.length >= batchSize) void doFlush();\n\t\t\t\t\telse scheduleFlush();\n\t\t\t\t} else {\n\t\t\t\t\tconst p = performSend(value);\n\t\t\t\t\ttrackPromise(p);\n\t\t\t\t}\n\t\t\t} else if (defaultConfig.messageTier(type) >= 3) {\n\t\t\t\t// Spec §5.11 — flush on tier-3+ terminal / teardown. INVALIDATE\n\t\t\t\t// (tier 4) hits an empty buffer and is a no-op.\n\t\t\t\tif (useBuffering) {\n\t\t\t\t\tif (flushTimer !== undefined) {\n\t\t\t\t\t\tclearTimeout(flushTimer);\n\t\t\t\t\t\tflushTimer = undefined;\n\t\t\t\t\t}\n\t\t\t\t\tvoid doFlush();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\t// -------------------------------------------------------------------\n\t// Reactive stop signal — a *fresh* emission on `stopOn` tears the sink\n\t// down. The first batch delivered through subscribe contains the cached\n\t// push-on-subscribe DATA (§2.2) and must be skipped; any emission\n\t// arriving in a later batch is a real stop request.\n\t// -------------------------------------------------------------------\n\tlet stopUnsub: (() => void) | undefined;\n\tif (stopOn) {\n\t\tlet firstBatchSeen = false;\n\t\tstopUnsub = stopOn.subscribe((msgs) => {\n\t\t\tif (!firstBatchSeen) {\n\t\t\t\tfirstBatchSeen = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (msgs.length > 0 && !teardownRequested) dispose();\n\t\t});\n\t}\n\n\t// -------------------------------------------------------------------\n\t// Dispose.\n\t//\n\t// Two flags:\n\t// - `teardownRequested`: set synchronously when `dispose()` is entered.\n\t// Gates further subscribe / buffer work and short-circuits stopOn\n\t// re-entry.\n\t// - `disposed`: set only after the final drain + unsub + TEARDOWN fan-\n\t// out have landed. In-flight per-record drain loops read this to\n\t// decide \"am I mid-cleanup vs fully-torn-down?\" They only stop on\n\t// `disposed`, so a dispose mid-drain doesn't truncate the current\n\t// buffer — it just prevents further work from being scheduled.\n\t// -------------------------------------------------------------------\n\tlet teardownRequested = false;\n\tconst dispose = () => {\n\t\tif (teardownRequested) return;\n\t\tteardownRequested = true;\n\t\tif (flushTimer !== undefined) {\n\t\t\tclearTimeout(flushTimer);\n\t\t\tflushTimer = undefined;\n\t\t}\n\t\t// Final drain of buffered items. Fire-and-forget — the per-record\n\t\t// drain loop reads `disposed` (still false) to keep draining the\n\t\t// already-captured chunk.\n\t\tif (useBuffering) void doFlush();\n\t\tdisposed = true;\n\t\tstopUnsub?.();\n\t\tunsub();\n\t\t// Fire TEARDOWN on companions so downstream subscribers observe\n\t\t// the sink's lifecycle end.\n\t\tconst tearDown = (n: Node<unknown>) => {\n\t\t\ttry {\n\t\t\t\tn.down([[TEARDOWN]]);\n\t\t\t} catch {\n\t\t\t\t/* drain re-entrance — swallow */\n\t\t\t}\n\t\t};\n\t\ttearDown(errorsNode as Node<unknown>);\n\t\ttearDown(failed as Node<unknown>);\n\t\ttearDown(sent as Node<unknown>);\n\t\ttearDown(inFlightCountNode as Node<unknown>);\n\t\tif (bufferedNode) tearDown(bufferedNode as Node<unknown>);\n\t\tif (pausedNode) tearDown(pausedNode as Node<unknown>);\n\t\t// Run adapter-supplied cleanup AFTER our own teardown completes so\n\t\t// external resources (socket listeners, file handles) tear down with\n\t\t// the sink as an atomic boundary.\n\t\ttry {\n\t\t\tonDispose?.();\n\t\t} catch {\n\t\t\t/* adapter cleanup failure must not escape */\n\t\t}\n\t};\n\n\tconst handle: ReactiveSinkHandle<T> = {\n\t\tdispose,\n\t\tsent,\n\t\tfailed,\n\t\tinFlight: inFlightCountNode,\n\t\terrors: errorsNode,\n\t};\n\tif (useBuffering) {\n\t\thandle.buffered = bufferedNode;\n\t\thandle.flush = async () => {\n\t\t\tif (disposed) return;\n\t\t\tawait doFlush();\n\t\t\tawait Promise.all(inFlightPromises);\n\t\t};\n\t}\n\tif (pausedNode) handle.paused = pausedNode;\n\n\t// Silence \"unused\" warnings for COMPLETE / ERROR — they're handled as\n\t// part of the messageTier(type) >= 3 branch above.\n\tvoid COMPLETE;\n\tvoid ERROR;\n\n\treturn handle;\n}\n","/**\n * Creates a resettable deadline timer for internal timeout, retry, and rate-limiting use.\n *\n * @remarks **Centralised primitive:** wraps `setTimeout`/`clearTimeout` with a generation guard\n * so that stale callbacks never fire after `cancel()` or a new `start()`.\n *\n * @remarks **Spec §5.10 exception:** resilience operators (`timeout`, `retry`, `rateLimiter`)\n * need raw timers — `fromTimer` creates a new Node per reset, which is too heavy here.\n * Lives in `src/extra/` (not `src/core/`) because it is a documented escape hatch from\n * the protocol-pure core layer.\n *\n * @example\n * ```ts\n * import { ResettableTimer } from \"@graphrefly/graphrefly-ts\";\n *\n * const timer = new ResettableTimer();\n * timer.start(1000, () => console.log(\"fired\"));\n * timer.cancel(); // cancels before firing\n * timer.start(500, () => console.log(\"new deadline\"));\n * console.log(timer.pending); // true\n * ```\n *\n * @category extra\n */\nexport class ResettableTimer {\n\tprivate _timer: ReturnType<typeof setTimeout> | undefined;\n\tprivate _gen = 0;\n\n\t/** Schedule callback after delayMs. Cancels any pending timer. */\n\tstart(delayMs: number, callback: () => void): void {\n\t\tthis.cancel();\n\t\tthis._gen += 1;\n\t\tconst gen = this._gen;\n\t\tthis._timer = setTimeout(() => {\n\t\t\tthis._timer = undefined;\n\t\t\tif (gen !== this._gen) return;\n\t\t\tcallback();\n\t\t}, delayMs);\n\t}\n\n\t/** Cancel the pending timer (if any). */\n\tcancel(): void {\n\t\tif (this._timer !== undefined) {\n\t\t\tclearTimeout(this._timer);\n\t\t\tthis._timer = undefined;\n\t\t}\n\t}\n\n\t/** Whether a timer is currently pending. */\n\tget pending(): boolean {\n\t\treturn this._timer !== undefined;\n\t}\n}\n","/**\n * Resilience utilities — roadmap §3.1 + §3.1c (retry, breaker, rate limit, status,\n * fallback, cache, timeout).\n */\nimport { batch } from \"../core/batch.js\";\nimport { monotonicNs } from \"../core/clock.js\";\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Message,\n\tRESOLVED,\n\tTEARDOWN,\n} from \"../core/messages.js\";\nimport { type Node, type NodeOptions, node } from \"../core/node.js\";\nimport { producer } from \"../core/sugar.js\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tNS_PER_SEC,\n\tresolveBackoffPreset,\n} from \"./backoff.js\";\nimport { fromAny } from \"./sources.js\";\nimport { ResettableTimer } from \"./timer.js\";\n\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nfunction operatorOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"derived\", ...opts } as NodeOptions<T>;\n}\n\nfunction clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nfunction msgVal(m: Message): unknown {\n\treturn m[1];\n}\n\nfunction coerceDelayNs(raw: number): number {\n\tif (typeof raw !== \"number\" || !Number.isFinite(raw)) {\n\t\tthrow new TypeError(\"backoff strategy must return a finite number\");\n\t}\n\treturn raw < 0 ? 0 : raw;\n}\n\nexport type RetryOptions = {\n\t/** Max retry attempts after each terminal `ERROR` (not counting the first failure). */\n\tcount?: number;\n\t/** Delay between attempts; strategies use **nanoseconds**. */\n\tbackoff?: BackoffStrategy | BackoffPreset;\n};\n\n/**\n * Resubscribes to the upstream node after each terminal `ERROR`, after an optional delay.\n *\n * @param source - Upstream node (should use `resubscribable: true`).\n * @param opts - `count` caps attempts; `backoff` supplies delay in **nanoseconds** (or a preset name).\n * @returns Node that retries on error.\n *\n * @remarks\n * **Resubscribable sources:** The upstream should use `resubscribable: true` if it must emit again after `ERROR`.\n * **Protocol:** Forwards unknown message tuples unchanged; handles `DIRTY`, `DATA`, `RESOLVED`, `COMPLETE`, `ERROR`.\n *\n * @example\n * ```ts\n * import { ERROR, NS_PER_SEC, pipe, producer, retry, constant } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = producer(\n * (a) => {\n * a.down([[ERROR, new Error(\"x\")]]);\n * },\n * { resubscribable: true },\n * );\n * const out = retry(src, { count: 2, backoff: constant(0.25 * NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function retry<T>(source: Node<T>, opts?: RetryOptions): Node<T> {\n\tconst count = opts?.count;\n\tconst backoffOpt = opts?.backoff;\n\tconst maxRetries = count !== undefined ? count : backoffOpt === undefined ? 0 : 0x7fffffff;\n\tif (maxRetries < 0) throw new RangeError(\"retry count must be >= 0\");\n\n\tconst strategy: BackoffStrategy | null =\n\t\tbackoffOpt === undefined\n\t\t\t? null\n\t\t\t: typeof backoffOpt === \"string\"\n\t\t\t\t? resolveBackoffPreset(backoffOpt)\n\t\t\t\t: backoffOpt;\n\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tlet attempt = 0;\n\t\t\tlet stopped = false;\n\t\t\tlet prevDelay: number | null = null;\n\t\t\tlet unsub: (() => void) | undefined;\n\t\t\tconst timer = new ResettableTimer();\n\n\t\t\tfunction disconnectUpstream(): void {\n\t\t\t\tunsub?.();\n\t\t\t\tunsub = undefined;\n\t\t\t}\n\n\t\t\tfunction scheduleRetryOrFinish(err: unknown): void {\n\t\t\t\tif (stopped) return;\n\t\t\t\tif (attempt >= maxRetries) {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst raw = strategy === null ? 0 : strategy(attempt, err, prevDelay);\n\t\t\t\t// null from strategy = \"stop retrying\" (e.g. withMaxAttempts cap reached)\n\t\t\t\tif (raw === null || raw === undefined) {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// A misbehaving strategy (returns NaN / non-finite) MUST NOT\n\t\t\t\t// escape into the upstream drain — treat it as \"stop retrying\"\n\t\t\t\t// and emit the original error.\n\t\t\t\tlet delayNs: number;\n\t\t\t\ttry {\n\t\t\t\t\tdelayNs = coerceDelayNs(raw);\n\t\t\t\t} catch {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tprevDelay = delayNs;\n\t\t\t\tattempt += 1;\n\t\t\t\tdisconnectUpstream();\n\t\t\t\tconst delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;\n\t\t\t\t// §5.10: setTimeout (not fromTimer) — retry delay needs clearTimeout/setTimeout;\n\t\t\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\t\t\ttimer.start(delayMs, () => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tconnect();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction connect(): void {\n\t\t\t\ttimer.cancel();\n\t\t\t\tdisconnectUpstream();\n\t\t\t\tunsub = source.subscribe((msgs) => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tconst t = m[0];\n\t\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\t\tattempt = 0;\n\t\t\t\t\t\t\tprevDelay = null;\n\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\tscheduleRetryOrFinish(msgVal(m));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else a.down([m]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconnect();\n\n\t\t\treturn () => {\n\t\t\t\tstopped = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tdisconnectUpstream();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t},\n\t);\n}\n\n/**\n * Options for {@link retrySource}. Superset of {@link RetryOptions} with an\n * optional `initial` forwarded to the outer node cache.\n *\n * @category extra\n */\nexport type RetrySourceOptions<T> = RetryOptions & {\n\t/** Initial cache value for the outer node (forwarded to `NodeOptions.initial`). */\n\tinitial?: T;\n};\n\n/**\n * Fresh-instance variant of {@link retry}: invokes the `factory` to build a\n * new `Node<T>` on every connect / reconnect. Unlike {@link retry}, which\n * re-subscribes to the same node (requiring `resubscribable: true`), this\n * creates a new source per attempt — ideal for producers that capture\n * per-attempt resources (sockets, clients, file handles) that become unusable\n * after an error.\n *\n * Synchronous exceptions thrown by `factory` are treated as terminal ERROR\n * and run through the same retry pipeline as inner-node ERROR.\n *\n * @param factory - Called to build a fresh source per attempt.\n * @param opts - `count` caps attempts; `backoff` supplies delay (ns) or preset.\n * @returns Node that retries by rebuilding the source.\n *\n * @example\n * ```ts\n * import { NS_PER_SEC, exponential, retrySource, fromWebSocket } from \"@graphrefly/graphrefly-ts\";\n *\n * // Each reconnect opens a fresh WebSocket:\n * const connected$ = retrySource(\n * () => fromWebSocket(new WebSocket(\"wss://example/stream\")),\n * { count: 10, backoff: exponential({ baseNs: 1 * NS_PER_SEC }) },\n * );\n * ```\n *\n * @category extra\n */\nexport function retrySource<T>(factory: () => Node<T>, opts?: RetrySourceOptions<T>): Node<T> {\n\tconst count = opts?.count;\n\tconst backoffOpt = opts?.backoff;\n\tconst maxRetries = count !== undefined ? count : backoffOpt === undefined ? 0 : 0x7fffffff;\n\tif (maxRetries < 0) throw new RangeError(\"retry count must be >= 0\");\n\n\tconst strategy: BackoffStrategy | null =\n\t\tbackoffOpt === undefined\n\t\t\t? null\n\t\t\t: typeof backoffOpt === \"string\"\n\t\t\t\t? resolveBackoffPreset(backoffOpt)\n\t\t\t\t: backoffOpt;\n\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tlet attempt = 0;\n\t\t\tlet stopped = false;\n\t\t\tlet prevDelay: number | null = null;\n\t\t\tlet unsub: (() => void) | undefined;\n\t\t\tconst timer = new ResettableTimer();\n\n\t\t\tfunction disconnectUpstream(): void {\n\t\t\t\tunsub?.();\n\t\t\t\tunsub = undefined;\n\t\t\t}\n\n\t\t\tfunction scheduleRetryOrFinish(err: unknown): void {\n\t\t\t\tif (stopped) return;\n\t\t\t\tif (attempt >= maxRetries) {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst raw = strategy === null ? 0 : strategy(attempt, err, prevDelay);\n\t\t\t\tif (raw === null || raw === undefined) {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// A misbehaving strategy (returns NaN / non-finite / negative)\n\t\t\t\t// MUST NOT escape into the upstream drain. Treat it like\n\t\t\t\t// `strategy === null` (stop retrying) and emit the original\n\t\t\t\t// error — the strategy bug is a separate concern the user\n\t\t\t\t// can inspect via the emitted error's stack.\n\t\t\t\tlet delayNs: number;\n\t\t\t\ttry {\n\t\t\t\t\tdelayNs = coerceDelayNs(raw);\n\t\t\t\t} catch {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tprevDelay = delayNs;\n\t\t\t\tattempt += 1;\n\t\t\t\tdisconnectUpstream();\n\t\t\t\tconst delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;\n\t\t\t\t// §5.10: setTimeout (not fromTimer) — retry delay needs clearTimeout/setTimeout;\n\t\t\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\t\t\ttimer.start(delayMs, () => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tconnect();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction connect(): void {\n\t\t\t\ttimer.cancel();\n\t\t\t\tdisconnectUpstream();\n\t\t\t\tlet src: Node<T>;\n\t\t\t\ttry {\n\t\t\t\t\tsrc = factory();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tscheduleRetryOrFinish(err);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tunsub = src.subscribe((msgs) => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tconst t = m[0];\n\t\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\t\tattempt = 0;\n\t\t\t\t\t\t\tprevDelay = null;\n\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\tscheduleRetryOrFinish(msgVal(m));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else a.down([m]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconnect();\n\n\t\t\treturn () => {\n\t\t\t\tstopped = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tdisconnectUpstream();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: opts?.initial,\n\t\t},\n\t);\n}\n\nexport type CircuitState = \"closed\" | \"open\" | \"half-open\";\n\n/**\n * Thrown when {@link withBreaker} is configured with `onOpen: \"error\"` and the breaker rejects work.\n *\n * @category extra\n */\nexport class CircuitOpenError extends Error {\n\toverride name = \"CircuitOpenError\";\n\tconstructor() {\n\t\tsuper(\"Circuit breaker is open\");\n\t}\n}\n\nexport interface CircuitBreakerOptions {\n\t/** Number of consecutive failures before opening. Default: 5. */\n\tfailureThreshold?: number;\n\t/** Base cooldown in nanoseconds before transitioning to half-open. Default: 30s. */\n\tcooldownNs?: number;\n\t/** Backoff strategy for cooldown escalation across consecutive open cycles. Overrides `cooldownNs` when provided. */\n\tcooldown?: BackoffStrategy;\n\t/** Max trial requests allowed in half-open state. Default: 1. */\n\thalfOpenMax?: number;\n\t/** Clock function returning nanoseconds (for testability). Default: `monotonicNs`. */\n\tnow?: () => number;\n}\n\nexport interface CircuitBreaker {\n\t/** Whether a request should be allowed through. Triggers open→half-open transition when cooldown expires. */\n\tcanExecute(): boolean;\n\t/** Record a successful execution. Resets to closed. */\n\trecordSuccess(): void;\n\t/** Record a failed execution. May transition to open. */\n\trecordFailure(error?: unknown): void;\n\t/** Current circuit state (read-only, does not trigger transitions). */\n\treadonly state: CircuitState;\n\t/** Number of consecutive failures in the current closed period. */\n\treadonly failureCount: number;\n\t/** Manually reset to closed state, clearing all counters. */\n\treset(): void;\n}\n\n/**\n * Factory for a synchronous circuit breaker with `closed`, `open`, and `half-open` states.\n *\n * Supports escalating cooldown via an optional {@link BackoffStrategy} — each consecutive\n * open→half-open→open cycle increments the backoff attempt.\n *\n * @param options - Threshold, cooldown, half-open limit, and optional clock override.\n * @returns {@link CircuitBreaker} instance.\n *\n * @remarks\n * **Timing:** Uses `monotonicNs()` by default (nanoseconds). Override `now` for tests.\n *\n * @example\n * ```ts\n * import { circuitBreaker, exponential, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const b = circuitBreaker({\n * failureThreshold: 3,\n * cooldown: exponential({ baseNs: 1 * NS_PER_SEC }),\n * });\n * ```\n *\n * @category extra\n */\nexport function circuitBreaker(options?: CircuitBreakerOptions): CircuitBreaker {\n\tconst threshold = Math.max(1, options?.failureThreshold ?? 5);\n\tconst baseCooldownNs = clampNonNegative(options?.cooldownNs ?? 30 * NS_PER_SEC);\n\tconst cooldownStrategy = options?.cooldown ?? null;\n\tconst halfOpenMax = Math.max(1, options?.halfOpenMax ?? 1);\n\tconst now = options?.now ?? monotonicNs;\n\n\tlet _state: CircuitState = \"closed\";\n\tlet _failureCount = 0;\n\tlet _openCycle = 0;\n\tlet _lastOpenedAt = 0;\n\tlet _lastCooldownNs = baseCooldownNs;\n\tlet _halfOpenAttempts = 0;\n\n\tfunction getCooldownNs(): number {\n\t\tif (!cooldownStrategy) return baseCooldownNs;\n\t\tconst delayNs = cooldownStrategy(_openCycle);\n\t\treturn delayNs !== null ? delayNs : baseCooldownNs;\n\t}\n\n\tfunction transitionToOpen(): void {\n\t\t_state = \"open\";\n\t\t_lastCooldownNs = getCooldownNs();\n\t\t_lastOpenedAt = now();\n\t\t_halfOpenAttempts = 0;\n\t}\n\n\tconst breaker: CircuitBreaker = {\n\t\tcanExecute(): boolean {\n\t\t\tif (_state === \"closed\") return true;\n\n\t\t\tif (_state === \"open\") {\n\t\t\t\tconst elapsed = now() - _lastOpenedAt;\n\t\t\t\tif (elapsed >= _lastCooldownNs) {\n\t\t\t\t\t_state = \"half-open\";\n\t\t\t\t\t_halfOpenAttempts = 1;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (_halfOpenAttempts < halfOpenMax) {\n\t\t\t\t_halfOpenAttempts++;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\n\t\trecordSuccess(): void {\n\t\t\tif (_state === \"half-open\") {\n\t\t\t\t_state = \"closed\";\n\t\t\t\t_failureCount = 0;\n\t\t\t\t_openCycle = 0;\n\t\t\t} else if (_state === \"closed\") {\n\t\t\t\t_failureCount = 0;\n\t\t\t}\n\t\t},\n\n\t\trecordFailure(_error?: unknown): void {\n\t\t\tif (_state === \"half-open\") {\n\t\t\t\t_openCycle++;\n\t\t\t\ttransitionToOpen();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (_state === \"closed\") {\n\t\t\t\t_failureCount++;\n\t\t\t\tif (_failureCount >= threshold) {\n\t\t\t\t\ttransitionToOpen();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tget state(): CircuitState {\n\t\t\treturn _state;\n\t\t},\n\n\t\tget failureCount(): number {\n\t\t\treturn _failureCount;\n\t\t},\n\n\t\treset(): void {\n\t\t\t_state = \"closed\";\n\t\t\t_failureCount = 0;\n\t\t\t_openCycle = 0;\n\t\t\t_halfOpenAttempts = 0;\n\t\t},\n\t};\n\n\treturn breaker;\n}\n\nexport type WithBreakerBundle<T> = {\n\tnode: Node<T>;\n\tbreakerState: Node<CircuitState>;\n};\n\n/**\n * Returns a unary wrapper that gates upstream `DATA` through a {@link CircuitBreaker}.\n *\n * @param breaker - Shared breaker instance (typically one per resource).\n * @param options - `onOpen: \"skip\"` emits `RESOLVED` when open; `\"error\"` emits {@link CircuitOpenError}.\n * @returns Function mapping `Node<T>` to `{ node, breakerState }` companion nodes.\n *\n * @remarks\n * **Success path:** `COMPLETE` calls {@link CircuitBreaker.recordSuccess}. **Failure path:** upstream `ERROR` calls {@link CircuitBreaker.recordFailure} and is forwarded.\n *\n * @example\n * ```ts\n * import { state, withBreaker, circuitBreaker } from \"@graphrefly/graphrefly-ts\";\n *\n * const b = circuitBreaker({ failureThreshold: 2 });\n * const s = state(1);\n * const { node, breakerState } = withBreaker(b)(s);\n * ```\n *\n * @category extra\n */\nexport function withBreaker<T>(\n\tbreaker: CircuitBreaker,\n\toptions?: { onOpen?: \"skip\" | \"error\" },\n): (source: Node<T>) => WithBreakerBundle<T> {\n\tconst onOpen = options?.onOpen ?? \"skip\";\n\n\treturn (source: Node<T>): WithBreakerBundle<T> => {\n\t\tconst wrapped = node<T>(\n\t\t\t[],\n\t\t\t(_deps, a) => {\n\t\t\t\tfunction syncState(): void {\n\t\t\t\t\twrapped.meta.breakerState.down([[DATA, breaker.state]]);\n\t\t\t\t}\n\n\t\t\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tconst t = m[0];\n\t\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\t\tif (breaker.canExecute()) {\n\t\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\t\tif (onOpen === \"error\") a.down([[ERROR, new CircuitOpenError()]]);\n\t\t\t\t\t\t\t\telse a.down([[RESOLVED]]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\t\tbreaker.recordSuccess();\n\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\tbreaker.recordFailure(msgVal(m));\n\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t} else a.down([m]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsyncState();\n\t\t\t\treturn unsub;\n\t\t\t},\n\t\t\t{\n\t\t\t\t...operatorOpts(),\n\t\t\t\tmeta: { breakerState: breaker.state },\n\t\t\t\tcompleteWhenDepsComplete: false,\n\t\t\t\tinitial: source.cache,\n\t\t\t},\n\t\t);\n\n\t\treturn { node: wrapped, breakerState: wrapped.meta.breakerState as Node<CircuitState> };\n\t};\n}\n\nexport interface TokenBucket {\n\t/** Number of tokens currently available (after refill). */\n\tavailable(): number;\n\t/** Try to consume `cost` tokens. Returns `true` if successful. */\n\ttryConsume(cost?: number): boolean;\n}\n\n/**\n * Token-bucket meter (capacity + refill rate per second). Use with {@link rateLimiter} or custom gates.\n *\n * @param capacity - Maximum tokens (must be positive).\n * @param refillPerSecond - Tokens added per elapsed second (non-negative).\n * @returns {@link TokenBucket} instance.\n *\n * @example\n * ```ts\n * import { tokenBucket } from \"@graphrefly/graphrefly-ts\";\n *\n * const bucket = tokenBucket(10, 2); // capacity 10, refill 2 tokens/sec\n * bucket.tryConsume(3); // true — 7 tokens remaining\n * bucket.available(); // ~7 (plus any elapsed refill)\n * ```\n *\n * @category extra\n */\nexport function tokenBucket(capacity: number, refillPerSecond: number): TokenBucket {\n\tif (capacity <= 0) throw new RangeError(\"capacity must be > 0\");\n\tif (refillPerSecond < 0) throw new RangeError(\"refillPerSecond must be >= 0\");\n\n\tlet tokens = capacity;\n\tlet updatedAt = monotonicNs();\n\n\tfunction refill(now: number): void {\n\t\tif (refillPerSecond > 0) {\n\t\t\tconst elapsedNs = now - updatedAt;\n\t\t\ttokens = Math.min(capacity, tokens + (elapsedNs / NS_PER_SEC) * refillPerSecond);\n\t\t}\n\t\tupdatedAt = now;\n\t}\n\n\treturn {\n\t\tavailable(): number {\n\t\t\trefill(monotonicNs());\n\t\t\treturn tokens;\n\t\t},\n\t\ttryConsume(cost = 1): boolean {\n\t\t\tif (cost <= 0) return true;\n\t\t\tconst now = monotonicNs();\n\t\t\trefill(now);\n\t\t\tif (tokens >= cost) {\n\t\t\t\ttokens -= cost;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t};\n}\n\nexport type RateLimiterOverflowPolicy = \"drop-oldest\" | \"drop-newest\" | \"error\";\n\nexport type RateLimiterOptions = {\n\t/** Maximum `DATA` emissions per window (must be > 0). */\n\tmaxEvents: number;\n\t/** Window length in nanoseconds (must be > 0). */\n\twindowNs: number;\n\t/** Cap on items queued while waiting for token refill (must be >= 1). Unbounded if omitted. */\n\tmaxBuffer?: number;\n\t/** Overflow policy when `maxBuffer` is exceeded. Default: `\"drop-newest\"`. */\n\tonOverflow?: RateLimiterOverflowPolicy;\n};\n\n/**\n * Thrown by {@link rateLimiter} when `onOverflow: \"error\"` and the pending buffer is full.\n *\n * @category extra\n */\nexport class RateLimiterOverflowError extends Error {\n\toverride name = \"RateLimiterOverflowError\";\n\tconstructor(maxBuffer: number) {\n\t\tsuper(`rateLimiter buffer overflow (maxBuffer=${maxBuffer})`);\n\t}\n}\n\n/**\n * Token-bucket rate limiter: at most `maxEvents` `DATA` values per `windowNs`.\n *\n * Uses {@link tokenBucket} internally (capacity = `maxEvents`, refill = `maxEvents / windowSeconds`).\n * Excess items are queued FIFO until a token is available. The queue may be bounded via\n * `maxBuffer` with a configurable overflow policy.\n *\n * @param source - Upstream node.\n * @param opts - Rate + optional bounded-buffer configuration.\n * @returns Node that emits DATA at most `maxEvents` per `windowNs`.\n *\n * @remarks\n * **Terminal:** `COMPLETE` / `ERROR` cancel the refill timer, drop the pending queue, and propagate.\n *\n * @example\n * ```ts\n * import { rateLimiter, state, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = state(0);\n * // Allow at most 5 DATA values per second; queue up to 100 excess items, drop newest beyond.\n * const limited = rateLimiter(src, { maxEvents: 5, windowNs: NS_PER_SEC, maxBuffer: 100 });\n * ```\n *\n * @category extra\n */\nexport function rateLimiter<T>(source: Node<T>, opts: RateLimiterOptions): Node<T> {\n\tconst { maxEvents, windowNs } = opts;\n\tif (maxEvents <= 0) throw new RangeError(\"maxEvents must be > 0\");\n\tif (windowNs <= 0) throw new RangeError(\"windowNs must be > 0\");\n\tconst maxBuffer = opts.maxBuffer;\n\tif (maxBuffer !== undefined && maxBuffer < 1) throw new RangeError(\"maxBuffer must be >= 1\");\n\tconst onOverflow: RateLimiterOverflowPolicy = opts.onOverflow ?? \"drop-newest\";\n\tconst refillPerSec = (maxEvents * NS_PER_SEC) / windowNs;\n\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tconst bucket = tokenBucket(maxEvents, refillPerSec);\n\t\t\tconst pending: T[] = [];\n\t\t\tconst timer = new ResettableTimer();\n\t\t\tlet terminated = false;\n\n\t\t\tconst tokenTimeNs = NS_PER_SEC / refillPerSec;\n\n\t\t\tfunction tryEmit(): void {\n\t\t\t\twhile (pending.length > 0) {\n\t\t\t\t\tif (bucket.tryConsume(1)) {\n\t\t\t\t\t\ta.emit(pending.shift() as T);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Wait one full token-refill interval. Avoids calling bucket.available()\n\t\t\t\t\t\t// which would advance the internal refill clock and steal fractional credit.\n\t\t\t\t\t\t// §5.10: setTimeout (not fromTimer) — refill-delay scheduling needs clearTimeout/setTimeout;\n\t\t\t\t\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\t\t\t\t\ttimer.start(Math.max(1, tokenTimeNs / NS_PER_MS), tryEmit);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (terminated) return;\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\tif (maxBuffer !== undefined && pending.length >= maxBuffer) {\n\t\t\t\t\t\t\tif (onOverflow === \"drop-newest\") {\n\t\t\t\t\t\t\t\t// silently drop the incoming item\n\t\t\t\t\t\t\t} else if (onOverflow === \"drop-oldest\") {\n\t\t\t\t\t\t\t\tpending.shift();\n\t\t\t\t\t\t\t\tpending.push(m[1] as T);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\t\tpending.length = 0;\n\t\t\t\t\t\t\t\ta.down([[ERROR, new RateLimiterOverflowError(maxBuffer)]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpending.push(m[1] as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttryEmit();\n\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tpending.length = 0;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tpending.length = 0;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tpending.length = 0;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tterminated = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tunsub();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t},\n\t);\n}\n\nexport type StatusValue = \"pending\" | \"active\" | \"completed\" | \"errored\";\n\nexport type WithStatusBundle<T> = {\n\tnode: Node<T>;\n\tstatus: Node<StatusValue>;\n\terror: Node<unknown | null>;\n};\n\n/**\n * Wraps `src` with `status` and `error` {@link state} companions for UI or meta snapshots.\n *\n * @param src - Upstream node to mirror.\n * @param options - `initialStatus` defaults to `\"pending\"`.\n * @returns `{ node, status, error }` where `error` holds the last `ERROR` payload.\n *\n * @remarks\n * **Recovery:** After `errored`, the next `DATA` clears `error` and sets `active` inside {@link batch} (matches graphrefly-py).\n *\n * @example\n * ```ts\n * import { withStatus, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = state<number>(0);\n * const { node, status, error } = withStatus(src);\n *\n * status.subscribe((msgs) => console.log(\"status:\", msgs));\n * src.down([[DATA, 42]]); // status → \"active\"\n * ```\n *\n * @category extra\n */\nexport function withStatus<T>(\n\tsrc: Node<T>,\n\toptions?: { initialStatus?: StatusValue },\n): WithStatusBundle<T> {\n\tconst initialStatus = options?.initialStatus ?? \"pending\";\n\n\tconst out = node<T>(\n\t\t[],\n\t\t(_deps, a) => {\n\t\t\tlet currentStatus: StatusValue = initialStatus;\n\t\t\tout.meta.status.down([[DATA, initialStatus]]);\n\t\t\tout.meta.error.down([[DATA, null]]);\n\n\t\t\tconst unsub = src.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\tif (currentStatus === \"errored\") {\n\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\tout.meta.error.down([[DATA, null]]);\n\t\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"active\"]]);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"active\"]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentStatus = \"active\";\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\tout.meta.status.down([[DATA, \"completed\"]]);\n\t\t\t\t\t\tcurrentStatus = \"completed\";\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tconst err = msgVal(m);\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tout.meta.error.down([[DATA, err]]);\n\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"errored\"]]);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcurrentStatus = \"errored\";\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn unsub;\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tmeta: { status: initialStatus, error: null },\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\tresubscribable: true,\n\t\t\tinitial: src.cache,\n\t\t},\n\t);\n\n\treturn {\n\t\tnode: out,\n\t\tstatus: out.meta.status as Node<StatusValue>,\n\t\terror: out.meta.error as Node<unknown | null>,\n\t};\n}\n\n// ——————————————————————————————————————————————————————————————\n// §3.1c — Caching, fallback & composition sugar\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Thrown by {@link timeout} when no `DATA` arrives within the deadline.\n *\n * @category extra\n */\nexport class TimeoutError extends Error {\n\toverride name = \"TimeoutError\";\n\tconstructor(ns: number) {\n\t\tsuper(`Timed out after ${ns / NS_PER_MS}ms`);\n\t}\n}\n\nfunction isNode(x: unknown): x is Node {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\t\"cache\" in x &&\n\t\ttypeof (x as Node).subscribe === \"function\"\n\t);\n}\n\nfunction isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nfunction isAsyncIterable(x: unknown): x is AsyncIterable<unknown> {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\ttypeof (x as AsyncIterable<unknown>)[Symbol.asyncIterator] === \"function\"\n\t);\n}\n\n/** Inputs accepted by {@link fallback}. */\nexport type FallbackInput<T> = T | Node<T> | PromiseLike<T> | AsyncIterable<T>;\n\n/**\n * On upstream terminal `ERROR`, switch to a fallback source instead of propagating the error.\n *\n * Accepts any of:\n * - **scalar value** — emits `[[DATA, fb], [COMPLETE]]`\n * - **`Node<T>`** — subscribes and forwards all messages (push-on-subscribe delivers current cache)\n * - **`Promise<T>` / thenable** — resolves into a one-shot `DATA` then `COMPLETE` (via {@link fromAny})\n * - **`AsyncIterable<T>`** — streams each yielded value as `DATA`, then `COMPLETE` (via {@link fromAny})\n *\n * Non-`Node` inputs are routed through {@link fromAny} so the fallback participates in the\n * reactive protocol uniformly. Bare strings, arrays, and other synchronous scalars are treated\n * as single values (NOT split into characters / elements) to avoid the `fromAny`-on-string\n * iteration gotcha.\n *\n * Composes naturally with {@link retry}:\n * `pipe(source, retry({count:3}), fallback(\"default\"))`.\n *\n * @param source - Upstream node.\n * @param fb - Fallback value, node, promise, or async iterable.\n * @returns Node that replaces errors with the fallback.\n *\n * @example\n * ```ts\n * import { fallback, throwError } from \"@graphrefly/graphrefly-ts\";\n *\n * const safe = fallback(throwError(new Error(\"boom\")), \"default\");\n * safe.cache; // \"default\" after subscribe\n * ```\n *\n * @category extra\n */\nexport function fallback<T>(source: Node<T>, fb: FallbackInput<T>): Node<T> {\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tlet fallbackUnsub: (() => void) | undefined;\n\t\t\tlet sourceUnsub: (() => void) | undefined;\n\n\t\t\tfunction switchToFallback(): void {\n\t\t\t\tsourceUnsub?.();\n\t\t\t\tsourceUnsub = undefined;\n\t\t\t\tif (isNode(fb) || isThenable(fb) || isAsyncIterable(fb)) {\n\t\t\t\t\tconst fbNode = fromAny(fb as Node<T> | PromiseLike<T> | AsyncIterable<T>);\n\t\t\t\t\tfallbackUnsub = fbNode.subscribe((fMsgs) => {\n\t\t\t\t\t\ta.down(fMsgs);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\ta.emit(fb as T);\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsourceUnsub = source.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) a.emit(m[1] as T);\n\t\t\t\t\telse if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) a.down([[COMPLETE]]);\n\t\t\t\t\telse if (t === ERROR) {\n\t\t\t\t\t\tswitchToFallback();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\tfallbackUnsub?.();\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tsourceUnsub?.();\n\t\t\t\tfallbackUnsub?.();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t},\n\t);\n}\n\n/**\n * Emits `ERROR` with {@link TimeoutError} if no `DATA` arrives within the deadline.\n *\n * The timer starts on subscription and resets on each `DATA`. `DIRTY` does NOT reset\n * the timer. Terminal messages (`COMPLETE`/`ERROR`) cancel the timer.\n *\n * @param source - Upstream node.\n * @param timeoutNs - Deadline in nanoseconds.\n * @returns Node that errors on timeout.\n *\n * @example\n * ```ts\n * import { timeout, never, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const t = timeout(never(), 5 * NS_PER_SEC);\n * // After 5 seconds with no DATA: [[ERROR, TimeoutError]]\n * ```\n *\n * @category extra\n */\nexport function timeout<T>(source: Node<T>, timeoutNs: number): Node<T> {\n\tif (timeoutNs <= 0) throw new RangeError(\"timeoutNs must be > 0\");\n\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tlet stopped = false;\n\t\t\tconst timer = new ResettableTimer();\n\n\t\t\tfunction startTimer(): void {\n\t\t\t\tconst delayMs = timeoutNs / NS_PER_MS;\n\t\t\t\t// §5.10: setTimeout (not fromTimer) — resettable deadline needs clearTimeout/setTimeout; fromTimer creates a new Node per reset, adding lifecycle overhead on every DATA.\n\t\t\t\ttimer.start(delayMs, () => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tunsub();\n\t\t\t\t\ta.down([[ERROR, new TimeoutError(timeoutNs)]]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\tstartTimer();\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tstartTimer();\n\n\t\t\treturn () => {\n\t\t\t\tstopped = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tunsub();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t},\n\t);\n}\n","/**\n * Protocol, system, and ingest adapters (roadmap §5.2, §5.2c).\n *\n * Each adapter wraps an external protocol or system as a reactive {@link Node}\n * built on {@link producer} / {@link node} — no second protocol.\n *\n * **Moved from sources.ts:** fromHTTP, fromWebSocket/toWebSocket, fromWebhook,\n * toSSE, fromMCP, fromGitHook.\n *\n * **New (5.2c):** fromOTel, fromSyslog, fromStatsD, fromPrometheus,\n * fromKafka/toKafka, fromRedisStream/toRedisStream, fromCSV, fromNDJSON,\n * fromClickHouseWatch, fromPulsar/toPulsar, fromNATS/toNATS,\n * fromRabbitMQ/toRabbitMQ.\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { wallClockNs } from \"../core/clock.js\";\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Message,\n\tRESOLVED,\n\tTEARDOWN,\n} from \"../core/messages.js\";\nimport { defaultConfig, type Node, type NodeOptions, node } from \"../core/node.js\";\nimport { producer, state } from \"../core/sugar.js\";\nimport { NS_PER_MS, NS_PER_SEC } from \"./backoff.js\";\nimport {\n\ttype BundleTriad,\n\ttype EmitTriad,\n\ttype ExternalRegister,\n\texternalBundle,\n\texternalProducer,\n} from \"./external-register.js\";\nimport { switchMap } from \"./operators.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkFailure } from \"./reactive-sink.js\";\nimport { retrySource, type WithStatusBundle, withStatus } from \"./resilience.js\";\nimport type { AsyncSourceOpts } from \"./sources.js\";\nimport { fromTimer, globToRegExp, matchesAnyPattern } from \"./sources.js\";\n\nexport type { SinkTransportError } from \"./reactive-sink.js\";\n\nimport type { SinkTransportError } from \"./reactive-sink.js\";\n\n/** Handle returned by per-record and buffered sinks. */\nexport type SinkHandle = {\n\t/** Stop the sink (unsubscribe from source). */\n\tdispose: () => void;\n\t/** Reactive node that emits the latest transport error (or `null`). */\n\terrors: Node<SinkTransportError | null>;\n\t/** Manually drain the internal buffer (buffered sinks only). */\n\tflush?: () => Promise<void>;\n};\n\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nfunction sourceOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\n\n// ——————————————————————————————————————————————————————————————\n// WebSocket adapter (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/** WebSocket-like transport accepted by {@link fromWebSocket} / {@link toWebSocket}. */\nexport type WebSocketLike = {\n\tsend(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;\n\tclose(code?: number, reason?: string): void;\n\taddEventListener(type: \"message\" | \"error\" | \"close\", listener: (ev: unknown) => void): void;\n\tremoveEventListener(type: \"message\" | \"error\" | \"close\", listener: (ev: unknown) => void): void;\n};\n\nexport type WebSocketMessageEventLike = { data: unknown };\nexport type WebSocketRegister<T> = (\n\temit: (payload: T) => void,\n\terror: (err: unknown) => void,\n\tcomplete: () => void,\n) => () => void;\n\n/**\n * Wraps a WebSocket as a GraphReFly producer source.\n *\n * Incoming socket messages are emitted as `DATA`; socket `error` emits `ERROR`; socket `close`\n * emits `COMPLETE`. Teardown detaches listeners and optionally closes the socket.\n *\n * @category extra\n */\nexport function fromWebSocket<T = unknown>(\n\tsocket: WebSocketLike,\n\topts?: ExtraOpts & {\n\t\tparse?: (payload: unknown, event: unknown) => T;\n\t\tcloseOnTeardown?: boolean;\n\t},\n): Node<T>;\nexport function fromWebSocket<T = unknown>(\n\tregister: WebSocketRegister<T>,\n\topts?: ExtraOpts & {\n\t\tparse?: (payload: unknown, event: unknown) => T;\n\t\tcloseOnTeardown?: boolean;\n\t},\n): Node<T>;\nexport function fromWebSocket<T = unknown>(\n\tsocketOrRegister: WebSocketLike | WebSocketRegister<T>,\n\topts?: ExtraOpts & {\n\t\tparse?: (payload: unknown, event: unknown) => T;\n\t\tcloseOnTeardown?: boolean;\n\t},\n): Node<T> {\n\tconst { parse, closeOnTeardown = false, ...rest } = opts ?? {};\n\treturn producer<T>((a) => {\n\t\tlet active = true;\n\t\tlet cleanup: (() => void) | undefined;\n\t\tconst runCleanup = () => {\n\t\t\tconst fn = cleanup;\n\t\t\tcleanup = undefined;\n\t\t\tfn?.();\n\t\t};\n\t\tconst terminate = (message: Message) => {\n\t\t\tif (!active) return;\n\t\t\tactive = false;\n\t\t\ta.down([message]);\n\t\t\trunCleanup();\n\t\t};\n\t\tconst emit = (raw: unknown, event: unknown = raw) => {\n\t\t\tif (!active) return;\n\t\t\ttry {\n\t\t\t\tconst payload =\n\t\t\t\t\traw !== null && typeof raw === \"object\" && \"data\" in (raw as Record<string, unknown>)\n\t\t\t\t\t\t? (raw as WebSocketMessageEventLike).data\n\t\t\t\t\t\t: raw;\n\t\t\t\tconst parsed = parse ? parse(payload, event) : (payload as T);\n\t\t\t\ta.emit(parsed);\n\t\t\t} catch (err) {\n\t\t\t\tterminate([ERROR, err]);\n\t\t\t}\n\t\t};\n\t\tconst error = (err: unknown) => {\n\t\t\tterminate([ERROR, err]);\n\t\t};\n\t\tconst complete = () => {\n\t\t\tterminate([COMPLETE]);\n\t\t};\n\t\tif (typeof socketOrRegister === \"function\") {\n\t\t\ttry {\n\t\t\t\tcleanup = socketOrRegister(emit, error, complete);\n\t\t\t\tif (typeof cleanup !== \"function\") {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"fromWebSocket register contract violation: register must return cleanup callable\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tterminate([ERROR, err]);\n\t\t\t}\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t\trunCleanup();\n\t\t\t};\n\t\t}\n\n\t\tconst ws = socketOrRegister;\n\t\tconst onMessage = (event: unknown) => emit(event, event);\n\t\tconst onError = (event: unknown) => error(event);\n\t\tconst onClose = () => complete();\n\t\tws.addEventListener(\"message\", onMessage);\n\t\tws.addEventListener(\"error\", onError);\n\t\tws.addEventListener(\"close\", onClose);\n\t\tcleanup = () => {\n\t\t\tws.removeEventListener(\"message\", onMessage);\n\t\t\tws.removeEventListener(\"error\", onError);\n\t\t\tws.removeEventListener(\"close\", onClose);\n\t\t\tif (closeOnTeardown) ws.close();\n\t\t};\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\trunCleanup();\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n// ——————————————————————————————————————————————————————————————\n// Webhook adapter (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/** Registration callback for {@link fromWebhook}. Alias of {@link ExternalRegister} over {@link EmitTriad}. */\nexport type WebhookRegister<T> = ExternalRegister<EmitTriad<T>>;\n\n/**\n * Bridges HTTP webhook callbacks into a GraphReFly source.\n *\n * The `register` callback wires your runtime/framework callback to GraphReFly and may return a\n * cleanup function. This keeps the adapter runtime-agnostic while following the same producer\n * pattern as {@link fromEvent}.\n *\n * @param register - Registers webhook handlers (`emit`, `error`, `complete`) and optionally returns cleanup.\n * @param opts - Optional producer options.\n * @returns `Node<T>` — webhook payloads as `DATA`; teardown runs returned cleanup.\n *\n * @example\n * ```ts\n * import express from \"express\";\n * import { fromWebhook } from \"@graphrefly/graphrefly-ts\";\n *\n * type HookPayload = { event: string; data: unknown };\n * const app = express();\n * app.use(express.json());\n *\n * const hook$ = fromWebhook<HookPayload>(({ emit, error }) => {\n * const handler = (req: express.Request, res: express.Response) => {\n * try {\n * emit(req.body as HookPayload);\n * res.status(200).send(\"ok\");\n * } catch (e) {\n * error(e);\n * res.status(500).send(\"error\");\n * }\n * };\n * app.post(\"/webhook\", handler);\n * return () => {\n * // Express has no direct route-removal API in common use.\n * };\n * });\n * ```\n *\n * @example Fastify\n * ```ts\n * import Fastify from \"fastify\";\n * import { fromWebhook } from \"@graphrefly/graphrefly-ts\";\n *\n * const fastify = Fastify();\n * const hook$ = fromWebhook<any>(({ emit, error }) => {\n * const handler = async (req: any, reply: any) => {\n * try {\n * emit(req.body);\n * reply.code(200).send({ ok: true });\n * } catch (e) {\n * error(e);\n * reply.code(500).send({ ok: false });\n * }\n * };\n * fastify.post(\"/webhook\", handler);\n * return () => {};\n * });\n * ```\n *\n * @category extra\n */\nexport function fromWebhook<T = unknown>(register: WebhookRegister<T>, opts?: ExtraOpts): Node<T> {\n\treturn externalProducer<T>(register, opts);\n}\n\n// ——————————————————————————————————————————————————————————————\n// HTTP adapter (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Options for {@link fromHTTP}.\n *\n * @category extra\n */\nexport interface FromHTTPOptions extends AsyncSourceOpts {\n\t/** HTTP method. Default: `\"GET\"`. */\n\tmethod?: string;\n\t/** Request headers. */\n\theaders?: Record<string, string>;\n\t/** Request body (for POST/PUT/PATCH). */\n\tbody?: any;\n\t/** Transform the Response before emitting. Default: `response.json()`. */\n\ttransform?: (response: Response) => any | Promise<any>;\n\t/** Request timeout in **nanoseconds**. Default: `30s` (30 * NS_PER_SEC). */\n\ttimeoutNs?: number;\n\t/**\n\t * When `true`, emit `COMPLETE` after the first successful fetch. Useful for\n\t * one-shot semantics where downstream wants to know \"no more values ever.\"\n\t * Default: `false` — the node stays live and replays cached DATA to late\n\t * subscribers via push-on-subscribe (spec §2.2).\n\t */\n\tcompleteAfterFetch?: boolean;\n\t/**\n\t * When `true`, trigger a fresh fetch on each new subscriber instead of\n\t * sharing one cached result. Default: `false` — one shared fetch whose\n\t * result is cached and replayed to every subscriber.\n\t */\n\trefetchOnSubscribe?: boolean;\n}\n\n/**\n * Result of {@link fromHTTP}: main source plus status, error, and fetch count companions.\n *\n * @category extra\n */\nexport type HTTPBundle<T> = WithStatusBundle<T> & {\n\t/** Number of successful fetches. */\n\tfetchCount: Node<number>;\n\t/** Nanosecond wall-clock timestamp of the last successful fetch. */\n\tlastUpdated: Node<number>;\n\t/**\n\t * `true` after at least one successful fetch; stays `true` across\n\t * resubscribes. Orthogonal to {@link withStatus}'s `active`/`completed`\n\t * lifecycle — use this as the \"fetch done\" signal under the default\n\t * (cached, stays-live) behavior where `withStatus` never transitions to\n\t * `\"completed\"` unless `completeAfterFetch: true` is set.\n\t */\n\tfetched: Node<boolean>;\n};\n\n/**\n * Creates a one-shot fetch-based HTTP source with lifecycle tracking.\n *\n * @category extra\n */\nexport function fromHTTP<T = any>(url: string, opts?: FromHTTPOptions): HTTPBundle<T> {\n\tconst {\n\t\tmethod = \"GET\",\n\t\theaders,\n\t\tbody: bodyOpt,\n\t\ttransform = (r: Response) => r.json(),\n\t\ttimeoutNs = 30 * NS_PER_SEC,\n\t\tsignal: externalSignal,\n\t\tcompleteAfterFetch = false,\n\t\trefetchOnSubscribe = false,\n\t\t...rest\n\t} = opts ?? {};\n\n\tconst fetchCount = state(0, { name: `${rest.name ?? \"http\"}/fetchCount` });\n\tconst lastUpdated = state(0, { name: `${rest.name ?? \"http\"}/lastUpdated` });\n\tconst fetched = state(false, { name: `${rest.name ?? \"http\"}/fetched` });\n\t// Closure-owned counter: `fetchCount` is a write-only observable of this\n\t// local count. Avoids the `fetchCount.cache + 1` read-modify-write pattern\n\t// (P3 audit #6) — the node stays in sync because every write flows through\n\t// here.\n\tlet fetchCountLocal = 0;\n\n\tconst body =\n\t\tbodyOpt !== undefined\n\t\t\t? typeof bodyOpt === \"string\"\n\t\t\t\t? bodyOpt\n\t\t\t\t: JSON.stringify(bodyOpt)\n\t\t\t: undefined;\n\n\t// Fetch body + lifecycle — shared between the default \"one shared fetch\"\n\t// path and the refetch-on-subscribe resubscribable producer path.\n\tconst runFetch = (a: {\n\t\temit: (v: T) => void;\n\t\tdown: (msgs: [symbol, ...unknown[]][]) => void;\n\t}): (() => void) => {\n\t\tconst abort = new AbortController();\n\t\tlet active = true;\n\n\t\tif (externalSignal?.aborted) {\n\t\t\t// Abort already fired before activation — short-circuit with ERROR\n\t\t\t// and flip `active` so the idempotent cleanup below is coherent.\n\t\t\tactive = false;\n\t\t\ta.down([[ERROR, externalSignal.reason ?? new Error(\"Aborted\")]]);\n\t\t\treturn () => {};\n\t\t}\n\t\texternalSignal?.addEventListener(\"abort\", () => abort.abort(externalSignal.reason), {\n\t\t\tonce: true,\n\t\t});\n\n\t\tconst timeoutId = setTimeout(\n\t\t\t() => abort.abort(new Error(\"Request timeout\")),\n\t\t\tMath.ceil(timeoutNs / NS_PER_MS),\n\t\t);\n\n\t\tfetch(url, { method, headers, body, signal: abort.signal })\n\t\t\t.then(async (res) => {\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\tif (!active) return;\n\t\t\t\tif (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\t\t\tconst data = await transform(res);\n\t\t\t\tif (!active) return;\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfetchCountLocal += 1;\n\t\t\t\t\tfetchCount.down([[DATA, fetchCountLocal]]);\n\t\t\t\t\tlastUpdated.down([[DATA, wallClockNs()]]);\n\t\t\t\t\tfetched.down([[DATA, true]]);\n\t\t\t\t\ta.emit(data as T);\n\t\t\t\t});\n\t\t\t\tif (completeAfterFetch) a.down([[COMPLETE]]);\n\t\t\t})\n\t\t\t.catch((err) => {\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\tif (!active) return;\n\t\t\t\tif (err && (err as Error).name === \"AbortError\") return;\n\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\tabort.abort();\n\t\t};\n\t};\n\n\tconst sourceNode = producer<T>(\n\t\t(a) =>\n\t\t\trunFetch({\n\t\t\t\temit: (v) => a.emit(v),\n\t\t\t\tdown: (msgs) => a.down(msgs as unknown as [symbol, unknown?][]),\n\t\t\t}),\n\t\t{\n\t\t\t...sourceOpts(rest),\n\t\t\t// `resubscribable: true` when refetchOnSubscribe — each new activation\n\t\t\t// (subscribe after full deactivation) re-runs the producer fn → fresh\n\t\t\t// fetch. Default (cache-once) stays non-resubscribable: producer runs\n\t\t\t// once on first activation, cached DATA replays to late subscribers.\n\t\t\tresubscribable: refetchOnSubscribe,\n\t\t},\n\t);\n\n\tconst tracked = withStatus(sourceNode);\n\n\treturn {\n\t\t...tracked,\n\t\tfetchCount,\n\t\tlastUpdated,\n\t\tfetched,\n\t};\n}\n\n// ——————————————————————————————————————————————————————————————\n// toHTTP sink\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link toHTTP}. */\nexport type ToHTTPOptions<T> = ExtraOpts & {\n\t/** HTTP method. Default: `\"POST\"`. */\n\tmethod?: string;\n\t/** Request headers applied to every call. Caller sets Content-Type. */\n\theaders?: Record<string, string>;\n\t/** Serialize a value to a request body. Default: `JSON.stringify`. */\n\tserialize?: (value: T) => string | Uint8Array;\n\t/** Optional request timeout in nanoseconds. */\n\ttimeoutNs?: number;\n\t/**\n\t * Format used when `batchSize` / `flushIntervalMs` is set:\n\t * - `\"json-array\"` — body is `JSON.stringify(batch)`\n\t * - `\"ndjson\"` — body is newline-delimited JSON.\n\t * Default: `\"json-array\"`.\n\t */\n\tbatchFormat?: \"json-array\" | \"ndjson\";\n\t/** Batch size before auto-flush (buffered mode). */\n\tbatchSize?: number;\n\t/** Flush interval in ms (buffered mode). */\n\tflushIntervalMs?: number;\n\t/** Retry configuration — same shape as {@link ReactiveSinkRetryOptions}. */\n\tretry?: Parameters<typeof reactiveSink<T>>[1][\"retry\"];\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * HTTP sink — forwards upstream `DATA` values as HTTP requests.\n *\n * Per-record mode (default, no batching knobs): one request per DATA.\n * Buffered mode (`batchSize` / `flushIntervalMs`): one request per chunk,\n * body is JSON-array or NDJSON depending on `batchFormat`.\n *\n * @param source - Upstream node.\n * @param url - Request URL.\n * @param opts - Serialization, batching, retry options.\n * @returns {@link ReactiveSinkHandle}.\n *\n * @category extra\n */\nexport function toHTTP<T>(\n\tsource: Node<T>,\n\turl: string,\n\topts?: ToHTTPOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tmethod = \"POST\",\n\t\theaders = { \"Content-Type\": \"application/json\" },\n\t\tserialize = (v: T) => JSON.stringify(v),\n\t\ttimeoutNs,\n\t\tbatchFormat = \"json-array\",\n\t\tbatchSize,\n\t\tflushIntervalMs,\n\t\tretry,\n\t\tonTransportError,\n\t} = opts ?? {};\n\n\tconst sendOne = async (body: string | Uint8Array): Promise<void> => {\n\t\tconst controller = timeoutNs !== undefined ? new AbortController() : undefined;\n\t\tlet timeoutId: ReturnType<typeof setTimeout> | undefined;\n\t\tif (controller && timeoutNs !== undefined) {\n\t\t\ttimeoutId = setTimeout(\n\t\t\t\t() => controller.abort(new Error(\"Request timeout\")),\n\t\t\t\tMath.ceil(timeoutNs / NS_PER_MS),\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tconst res = await fetch(url, {\n\t\t\t\tmethod,\n\t\t\t\theaders,\n\t\t\t\tbody: body as BodyInit | null | undefined,\n\t\t\t\tsignal: controller?.signal,\n\t\t\t});\n\t\t\t// Drain the response body in every branch — un-drained bodies on\n\t\t\t// non-ok responses hold the connection open in Node's fetch pool\n\t\t\t// until GC, which starves the pool during retry storms.\n\t\t\tconst drain = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait res.arrayBuffer?.();\n\t\t\t\t} catch {\n\t\t\t\t\t/* body already consumed / socket dead — nothing to drain */\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (!res.ok) {\n\t\t\t\tawait drain();\n\t\t\t\tthrow new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\t\t}\n\t\t\tawait drain();\n\t\t} finally {\n\t\t\tif (timeoutId !== undefined) clearTimeout(timeoutId);\n\t\t}\n\t};\n\n\tconst buffered = batchSize !== undefined || flushIntervalMs !== undefined;\n\tif (buffered) {\n\t\t// Buffered mode: batchFormat decides the body shape; per-item `serialize`\n\t\t// is only applied for ndjson (line-oriented). json-array format sends the\n\t\t// raw batch through `JSON.stringify` as a single array.\n\t\treturn reactiveSink<T>(source, {\n\t\t\tonTransportError,\n\t\t\tretry,\n\t\t\tbatchSize,\n\t\t\tflushIntervalMs,\n\t\t\tsendBatch: async (chunk) => {\n\t\t\t\tlet body: string | Uint8Array;\n\t\t\t\tif (batchFormat === \"ndjson\") {\n\t\t\t\t\tbody = (chunk as T[])\n\t\t\t\t\t\t.map((v) => {\n\t\t\t\t\t\t\tconst s = serialize(v);\n\t\t\t\t\t\t\treturn typeof s === \"string\" ? s : new TextDecoder().decode(s);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(\"\\n\");\n\t\t\t\t} else {\n\t\t\t\t\tbody = JSON.stringify(chunk);\n\t\t\t\t}\n\t\t\t\tawait sendOne(body);\n\t\t\t},\n\t\t});\n\t}\n\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tretry,\n\t\tserialize,\n\t\tsend: async (payload) => {\n\t\t\tawait sendOne(payload as string | Uint8Array);\n\t\t},\n\t});\n}\n\n// ——————————————————————————————————————————————————————————————\n// SSE sink\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link toSSE}. */\nexport type ToSSEOptions = {\n\t/** Custom payload serializer for non-string payloads. Default: `JSON.stringify` fallback to `String(value)`. */\n\tserialize?: (value: unknown) => string;\n\t/** Event name for DATA tuples. Default: `\"data\"`. */\n\tdataEvent?: string;\n\t/** Event name for ERROR tuples. Default: `\"error\"`. */\n\terrorEvent?: string;\n\t/** Event name for COMPLETE tuples. Default: `\"complete\"`. */\n\tcompleteEvent?: string;\n\t/** Emit `event: resolved` when RESOLVED arrives. Default: `false`. */\n\tincludeResolved?: boolean;\n\t/** Emit `event: dirty` when DIRTY arrives. Default: `false`. */\n\tincludeDirty?: boolean;\n\t/** Add SSE comment keepalive frames (`: keepalive`) on an interval. Disabled when unset. */\n\tkeepAliveMs?: number;\n\t/** Optional abort signal to terminate the stream early. */\n\tsignal?: AbortSignal;\n\t/** Maps custom message types to SSE event names. */\n\teventNameResolver?: (type: symbol) => string;\n};\n\nfunction messageTypeLabel(t: symbol): string {\n\treturn Symbol.keyFor(t) ?? t.description ?? \"message\";\n}\n\nfunction serializeSseData(value: unknown, serialize: (value: unknown) => string): string {\n\tif (typeof value === \"string\") return value;\n\treturn serialize(value);\n}\n\nfunction sseFrame(event: string, data?: string): string {\n\tlet out = `event: ${event}\\n`;\n\tif (data !== undefined) {\n\t\tconst lines = data.split(/\\r?\\n/);\n\t\tfor (const line of lines) {\n\t\t\tout += `data: ${line}\\n`;\n\t\t}\n\t}\n\treturn `${out}\\n`;\n}\n\n/**\n * Creates a standard Server-Sent Events stream from node messages.\n *\n * @category extra\n */\nexport function toSSE<T>(source: Node<T>, opts?: ToSSEOptions): ReadableStream<Uint8Array> {\n\tconst {\n\t\tserialize = (value: unknown) => {\n\t\t\tif (value instanceof Error) return value.message;\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(value);\n\t\t\t} catch {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t},\n\t\tdataEvent = \"data\",\n\t\terrorEvent = \"error\",\n\t\tcompleteEvent = \"complete\",\n\t\tincludeResolved = false,\n\t\tincludeDirty = false,\n\t\tkeepAliveMs,\n\t\tsignal,\n\t\teventNameResolver = messageTypeLabel,\n\t} = opts ?? {};\n\tconst encoder = new TextEncoder();\n\tlet stop: (() => void) | undefined;\n\n\treturn new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\n\t\t\tlet closed = false;\n\t\t\tlet keepAlive: ReturnType<typeof setInterval> | undefined;\n\t\t\tlet unsub: () => void = () => {};\n\t\t\tconst close = () => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tif (keepAlive !== undefined) clearInterval(keepAlive);\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tunsub();\n\t\t\t\tcontroller.close();\n\t\t\t};\n\t\t\tstop = close;\n\t\t\tconst write = (event: string, data?: string) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tcontroller.enqueue(encoder.encode(sseFrame(event, data)));\n\t\t\t};\n\t\t\tconst onAbort = () => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclose();\n\t\t\t};\n\t\t\tunsub = source.subscribe((msgs) => {\n\t\t\t\tfor (const msg of msgs) {\n\t\t\t\t\tconst t = msg[0];\n\t\t\t\t\t// Skip graph-local signals (tier < 3: START, DIRTY, INVALIDATE,\n\t\t\t\t\t// PAUSE, RESUME). DIRTY is opt-in for observability.\n\t\t\t\t\tif (defaultConfig.isLocalOnly(t)) {\n\t\t\t\t\t\tif (t === DIRTY && includeDirty) {\n\t\t\t\t\t\t\t/* fall through to write */\n\t\t\t\t\t\t} else continue;\n\t\t\t\t\t}\n\t\t\t\t\tif (t === DATA) {\n\t\t\t\t\t\twrite(dataEvent, serializeSseData(msg[1], serialize));\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (t === ERROR) {\n\t\t\t\t\t\twrite(errorEvent, serializeSseData(msg[1], serialize));\n\t\t\t\t\t\tclose();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (t === COMPLETE) {\n\t\t\t\t\t\twrite(completeEvent);\n\t\t\t\t\t\tclose();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// RESOLVED (tier 3) is opt-in for observability.\n\t\t\t\t\tif (!includeResolved && t === RESOLVED) continue;\n\t\t\t\t\twrite(\n\t\t\t\t\t\teventNameResolver(t),\n\t\t\t\t\t\tmsg.length > 1 ? serializeSseData(msg[1], serialize) : undefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t\tif (keepAliveMs !== undefined && keepAliveMs > 0) {\n\t\t\t\tkeepAlive = setInterval(() => {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tcontroller.enqueue(encoder.encode(\": keepalive\\n\\n\"));\n\t\t\t\t}, keepAliveMs);\n\t\t\t}\n\t\t\tif (signal?.aborted) onAbort();\n\t\t\telse signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t},\n\t\tcancel() {\n\t\t\tstop?.();\n\t\t},\n\t});\n}\n\n/**\n * Composable variant of {@link toSSE} — emits encoded SSE frames as\n * `Uint8Array` through a reactive `Node`. Use this when you want to pipe SSE\n * bytes through the reactive graph (persist to file, tee to multiple streams,\n * etc.). Wrap with {@link toReadableStream} to expose a `ReadableStream` for\n * `new Response(...)` use cases.\n *\n * @category extra\n */\nexport function toSSEBytes<T>(source: Node<T>, opts?: ToSSEOptions): Node<Uint8Array> {\n\tconst {\n\t\tserialize = (value: unknown) => {\n\t\t\tif (value instanceof Error) return value.message;\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(value);\n\t\t\t} catch {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t},\n\t\tdataEvent = \"data\",\n\t\terrorEvent = \"error\",\n\t\tcompleteEvent = \"complete\",\n\t\tincludeResolved = false,\n\t\tincludeDirty = false,\n\t\tkeepAliveMs,\n\t\tsignal,\n\t\teventNameResolver = messageTypeLabel,\n\t} = opts ?? {};\n\tconst encoder = new TextEncoder();\n\treturn producer<Uint8Array>((a) => {\n\t\tlet active = true;\n\t\tlet keepAlive: ReturnType<typeof setInterval> | undefined;\n\t\tconst emitFrame = (event: string, data?: string) => {\n\t\t\tif (!active) return;\n\t\t\ta.emit(encoder.encode(sseFrame(event, data)));\n\t\t};\n\t\tconst onAbort = () => {\n\t\t\tif (!active) return;\n\t\t\tactive = false;\n\t\t\ta.down([[COMPLETE]]);\n\t\t};\n\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\tif (!active) return;\n\t\t\tfor (const msg of msgs) {\n\t\t\t\tconst t = msg[0];\n\t\t\t\tif (defaultConfig.isLocalOnly(t)) {\n\t\t\t\t\tif (t === DIRTY && includeDirty) {\n\t\t\t\t\t\t/* fall through */\n\t\t\t\t\t} else continue;\n\t\t\t\t}\n\t\t\t\tif (t === DATA) {\n\t\t\t\t\temitFrame(dataEvent, serializeSseData(msg[1], serialize));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (t === ERROR) {\n\t\t\t\t\temitFrame(errorEvent, serializeSseData(msg[1], serialize));\n\t\t\t\t\tactive = false;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (t === COMPLETE) {\n\t\t\t\t\temitFrame(completeEvent);\n\t\t\t\t\tactive = false;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!includeResolved && t === RESOLVED) continue;\n\t\t\t\temitFrame(\n\t\t\t\t\teventNameResolver(t),\n\t\t\t\t\tmsg.length > 1 ? serializeSseData(msg[1], serialize) : undefined,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t\tif (keepAliveMs !== undefined && keepAliveMs > 0) {\n\t\t\tkeepAlive = setInterval(() => {\n\t\t\t\tif (!active) return;\n\t\t\t\ta.emit(encoder.encode(\": keepalive\\n\\n\"));\n\t\t\t}, keepAliveMs);\n\t\t}\n\t\tif (signal?.aborted) onAbort();\n\t\telse signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\tif (keepAlive !== undefined) clearInterval(keepAlive);\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tunsub();\n\t\t};\n\t});\n}\n\n/**\n * Converts a `Node<Uint8Array>` into a WHATWG `ReadableStream<Uint8Array>`.\n * Useful for composing with `new Response(...)` / `fetch` bodies.\n *\n * @category extra\n */\nexport function toReadableStream(bytes: Node<Uint8Array>): ReadableStream<Uint8Array> {\n\tlet unsub: (() => void) | undefined;\n\tlet closed = false;\n\treturn new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\n\t\t\tunsub = bytes.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tif (t === DATA) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tcontroller.enqueue(m[1] as Uint8Array);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* controller closed mid-batch — upstream unsub will follow */\n\t\t\t\t\t\t\tclosed = true;\n\t\t\t\t\t\t\tunsub?.();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tclosed = true;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tcontroller.error(m[1]);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* controller already closed */\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === COMPLETE) {\n\t\t\t\t\t\tclosed = true;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* controller already closed */\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\tcancel() {\n\t\t\tclosed = true;\n\t\t\tunsub?.();\n\t\t},\n\t});\n}\n\n// ——————————————————————————————————————————————————————————————\n// fromSSE source\n// ——————————————————————————————————————————————————————————————\n\n/** Parsed Server-Sent Event. */\nexport type SSEEvent<T = string> = {\n\tevent: string;\n\tdata: T;\n\tid?: string;\n\tretry?: number;\n};\n\n/** Options for {@link fromSSE}. */\nexport type FromSSEOptions<T = string> = ExtraOpts & {\n\t/** Parse the raw `data:` payload. Default: identity (string). */\n\tparse?: (raw: string) => T;\n};\n\n/**\n * Parses a Server-Sent Events stream into structured `{event, data, id}` records.\n *\n * @param source - SSE byte source (`ReadableStream`, `Response`, or `AsyncIterable<Uint8Array>`).\n * @param opts - Parse function and node options.\n * @returns `Node<SSEEvent<T>>` — one `DATA` per SSE event; `COMPLETE` on stream end.\n *\n * @category extra\n */\nexport function fromSSE<T = string>(\n\tsource: ReadableStream<Uint8Array> | Response | AsyncIterable<Uint8Array>,\n\topts?: FromSSEOptions<T>,\n): Node<SSEEvent<T>> {\n\tconst { parse = (raw: string) => raw as unknown as T, ...rest } = opts ?? {};\n\treturn producer<SSEEvent<T>>((a) => {\n\t\tlet active = true;\n\t\tconst decoder = new TextDecoder();\n\t\tlet buffer = \"\";\n\t\tlet currentEvent = \"message\";\n\t\tlet currentData: string[] = [];\n\t\tlet currentId: string | undefined;\n\t\tlet currentRetry: number | undefined;\n\n\t\tconst flushEvent = () => {\n\t\t\tif (currentData.length === 0 && currentEvent === \"message\" && currentId === undefined) {\n\t\t\t\tcurrentData = [];\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst raw = currentData.join(\"\\n\");\n\t\t\ta.emit({\n\t\t\t\tevent: currentEvent,\n\t\t\t\tdata: parse(raw),\n\t\t\t\tid: currentId,\n\t\t\t\tretry: currentRetry,\n\t\t\t});\n\t\t\tcurrentEvent = \"message\";\n\t\t\tcurrentData = [];\n\t\t\tcurrentId = undefined;\n\t\t\tcurrentRetry = undefined;\n\t\t};\n\n\t\tconst processLine = (line: string) => {\n\t\t\tif (line === \"\") {\n\t\t\t\tflushEvent();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (line.startsWith(\":\")) return; // comment\n\t\t\tconst colon = line.indexOf(\":\");\n\t\t\tconst field = colon < 0 ? line : line.slice(0, colon);\n\t\t\tlet value = colon < 0 ? \"\" : line.slice(colon + 1);\n\t\t\tif (value.startsWith(\" \")) value = value.slice(1);\n\t\t\tswitch (field) {\n\t\t\t\tcase \"event\":\n\t\t\t\t\tcurrentEvent = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"data\":\n\t\t\t\t\tcurrentData.push(value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"id\":\n\t\t\t\t\tif (!value.includes(\"\\0\")) currentId = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"retry\": {\n\t\t\t\t\tconst n = Number(value);\n\t\t\t\t\tif (Number.isFinite(n)) currentRetry = n;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tconst processChunk = (chunk: Uint8Array, done: boolean) => {\n\t\t\tif (!active) return;\n\t\t\tbuffer += decoder.decode(chunk, { stream: !done });\n\t\t\tconst parts = buffer.split(/\\r?\\n/);\n\t\t\tbuffer = parts.pop() ?? \"\";\n\t\t\tfor (const line of parts) processLine(line);\n\t\t};\n\n\t\t// Captured so teardown can `cancel()` the reader / iterator promptly\n\t\t// instead of waiting for `reader.read()` to resolve on its own.\n\t\tlet reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n\t\tlet iter: AsyncIterator<Uint8Array> | undefined;\n\n\t\tconst run = async () => {\n\t\t\ttry {\n\t\t\t\tconst resp = source as Response;\n\t\t\t\tconst stream =\n\t\t\t\t\tsource instanceof ReadableStream\n\t\t\t\t\t\t? source\n\t\t\t\t\t\t: resp && typeof resp === \"object\" && resp.body instanceof ReadableStream\n\t\t\t\t\t\t\t? resp.body\n\t\t\t\t\t\t\t: null;\n\t\t\t\tif (stream) {\n\t\t\t\t\treader = stream.getReader();\n\t\t\t\t\twhile (active) {\n\t\t\t\t\t\tconst { value, done } = await reader.read();\n\t\t\t\t\t\tif (done) break;\n\t\t\t\t\t\tprocessChunk(value, false);\n\t\t\t\t\t}\n\t\t\t\t\tprocessChunk(new Uint8Array(), true);\n\t\t\t\t} else {\n\t\t\t\t\tconst asyncIter = source as AsyncIterable<Uint8Array>;\n\t\t\t\t\titer = asyncIter[Symbol.asyncIterator]();\n\t\t\t\t\twhile (active) {\n\t\t\t\t\t\tconst step = await iter.next();\n\t\t\t\t\t\tif (step.done) break;\n\t\t\t\t\t\tprocessChunk(step.value, false);\n\t\t\t\t\t}\n\t\t\t\t\tprocessChunk(new Uint8Array(), true);\n\t\t\t\t}\n\t\t\t\tif (buffer.trim()) {\n\t\t\t\t\tfor (const line of buffer.split(/\\r?\\n/)) processLine(line);\n\t\t\t\t\tflushEvent();\n\t\t\t\t}\n\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\t\tvoid run();\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\t// Cancel reader / iterator so the pending `read()` / `next()`\n\t\t\t// resolves immediately — otherwise teardown would wait for the\n\t\t\t// next chunk (could be indefinitely on a quiet stream).\n\t\t\tif (reader) {\n\t\t\t\tvoid reader.cancel().catch(() => {\n\t\t\t\t\t/* cancel on already-closed reader is a no-op */\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (iter && typeof iter.return === \"function\") {\n\t\t\t\tvoid Promise.resolve(iter.return()).catch(() => undefined);\n\t\t\t}\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n// ——————————————————————————————————————————————————————————————\n// fromHTTPStream source\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link fromHTTPStream}. */\nexport type FromHTTPStreamOptions = ExtraOpts & {\n\tmethod?: string;\n\theaders?: Record<string, string>;\n\tbody?: unknown;\n\tsignal?: AbortSignal;\n};\n\n/**\n * Streaming HTTP source — emits each chunk from the response body as a\n * `Uint8Array` `DATA`. `COMPLETE` when the stream ends; `ERROR` on non-ok\n * response or fetch failure.\n *\n * Useful for ingesting server-push APIs (LLM streaming, SSE endpoints — pair\n * with {@link fromSSE}, NDJSON endpoints — pair with {@link fromNDJSON}).\n *\n * @category extra\n */\nexport function fromHTTPStream(url: string, opts?: FromHTTPStreamOptions): Node<Uint8Array> {\n\tconst { method = \"GET\", headers, body: bodyOpt, signal: externalSignal, ...rest } = opts ?? {};\n\treturn producer<Uint8Array>((a) => {\n\t\tlet active = true;\n\t\tconst abort = new AbortController();\n\t\tif (externalSignal?.aborted) {\n\t\t\ta.down([[ERROR, externalSignal.reason ?? new Error(\"Aborted\")]]);\n\t\t\treturn () => {};\n\t\t}\n\t\texternalSignal?.addEventListener(\"abort\", () => abort.abort(externalSignal.reason), {\n\t\t\tonce: true,\n\t\t});\n\t\tconst body =\n\t\t\tbodyOpt !== undefined\n\t\t\t\t? typeof bodyOpt === \"string\"\n\t\t\t\t\t? bodyOpt\n\t\t\t\t\t: JSON.stringify(bodyOpt)\n\t\t\t\t: undefined;\n\n\t\tconst run = async () => {\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(url, { method, headers, body, signal: abort.signal });\n\t\t\t\tif (!active) return;\n\t\t\t\tif (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\t\t\tif (!res.body) throw new Error(\"HTTP response has no body\");\n\t\t\t\tconst reader = res.body.getReader();\n\t\t\t\twhile (active) {\n\t\t\t\t\tconst { value, done } = await reader.read();\n\t\t\t\t\tif (done) break;\n\t\t\t\t\tif (value) a.emit(value);\n\t\t\t\t}\n\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\tif (!active) return;\n\t\t\t\tif (err && (err as Error).name === \"AbortError\") return;\n\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\t\tvoid run();\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\tabort.abort();\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n// ——————————————————————————————————————————————————————————————\n// fromHTTPPoll source\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link fromHTTPPoll}. */\nexport type FromHTTPPollOptions = FromHTTPOptions & {\n\t/** Poll interval in milliseconds. Default: `5000`. */\n\tintervalMs?: number;\n};\n\n/**\n * Repeatedly-fetching HTTP source — a reactive composition of\n * {@link fromTimer} + {@link switchMap} + {@link fromHTTP} that fetches on an\n * interval and emits the latest response. Previous in-flight fetches are\n * cancelled when a new tick arrives (switch semantics).\n *\n * @example\n * ```ts\n * import { fromHTTPPoll } from \"@graphrefly/graphrefly-ts\";\n * const health$ = fromHTTPPoll<{ ok: boolean }>(\"https://example.com/health\", { intervalMs: 10_000 });\n * ```\n *\n * @category extra\n */\nexport function fromHTTPPoll<T = unknown>(url: string, opts?: FromHTTPPollOptions): Node<T> {\n\tconst { intervalMs = 5000, ...httpOpts } = opts ?? {};\n\treturn switchMap(\n\t\tfromTimer(intervalMs, { period: intervalMs }),\n\t\t() => fromHTTP<T>(url, { ...httpOpts, completeAfterFetch: true }).node,\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// WebSocket sink (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link toWebSocket}. */\nexport type ToWebSocketOptions<T> = {\n\t/** Serialize DATA payloads before `socket.send(...)`. */\n\tserialize?: (value: T) => string | ArrayBufferLike | Blob | ArrayBufferView;\n\t/** Close socket when upstream emits COMPLETE. Default: `true`. */\n\tcloseOnComplete?: boolean;\n\t/** Close socket when upstream emits ERROR. Default: `true`. */\n\tcloseOnError?: boolean;\n\t/** Optional close code used when close is triggered by terminal tuples. */\n\tcloseCode?: number;\n\t/** Optional close reason used when close is triggered by terminal tuples. */\n\tcloseReason?: string;\n\t/** Structured callback — uses the unified {@link SinkTransportError} shape. */\n\tonTransportError?: (event: SinkTransportError) => void;\n\t/** Retry configuration — passed through to {@link reactiveSink}. */\n\tretry?: ReactiveSinkHandle<T> extends infer _\n\t\t? Parameters<typeof reactiveSink<T>>[1][\"retry\"]\n\t\t: never;\n\t/** Backpressure configuration — passed through to {@link reactiveSink}. */\n\tbackpressure?: Parameters<typeof reactiveSink<T>>[1][\"backpressure\"];\n\t/** Reactive stop signal — when it emits any DATA / terminal, the sink tears down. */\n\tstopOn?: Node<unknown>;\n};\n\n/**\n * Forwards upstream `DATA` payloads to a WebSocket via `send`.\n *\n * Returns a {@link ReactiveSinkHandle} — every transport outcome (including\n * socket `close` events) surfaces on the `errors` / `failed` / `sent` /\n * `inFlight` companions.\n *\n * @category extra\n */\nexport function toWebSocket<T>(\n\tsource: Node<T>,\n\tsocket: WebSocketLike,\n\topts?: ToWebSocketOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tserialize = (value: T) => {\n\t\t\tif (\n\t\t\t\ttypeof value === \"string\" ||\n\t\t\t\tvalue instanceof Blob ||\n\t\t\t\tvalue instanceof ArrayBuffer ||\n\t\t\t\tArrayBuffer.isView(value)\n\t\t\t) {\n\t\t\t\treturn value as string | ArrayBufferLike | Blob | ArrayBufferView;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(value);\n\t\t\t} catch {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t},\n\t\tcloseOnComplete = true,\n\t\tcloseOnError = true,\n\t\tcloseCode,\n\t\tcloseReason,\n\t\tonTransportError,\n\t\tretry,\n\t\tbackpressure,\n\t\tstopOn,\n\t} = opts ?? {};\n\n\tlet socketClosed = false;\n\tconst closeSocket = (trigger?: Message) => {\n\t\tif (socketClosed) return;\n\t\tsocketClosed = true;\n\t\ttry {\n\t\t\tsocket.close(closeCode, closeReason);\n\t\t} catch (err) {\n\t\t\tconst error = err instanceof Error ? err : new Error(String(err));\n\t\t\ttry {\n\t\t\t\tonTransportError?.({ stage: \"close\", error, value: undefined, message: trigger });\n\t\t\t} catch {\n\t\t\t\t/* user hook must not escape */\n\t\t\t}\n\t\t}\n\t};\n\n\t// External close listener — installed before sink construction so we can\n\t// pass its cleanup via reactiveSink's `onDispose` hook. That hook fires on\n\t// any teardown path (user `.dispose()`, `stopOn` signal, upstream\n\t// terminal) — guaranteeing the listener is removed even when the reactive\n\t// sink's internal dispose fires without going through a wrapper.\n\tlet externalCloseHandler: ((ev: unknown) => void) | null = null;\n\tconst removeExternalCloseHandler = () => {\n\t\tif (externalCloseHandler) {\n\t\t\ttry {\n\t\t\t\tsocket.removeEventListener(\"close\", externalCloseHandler);\n\t\t\t} catch {\n\t\t\t\t/* removeEventListener may throw on some environments when socket is dead */\n\t\t\t}\n\t\t\texternalCloseHandler = null;\n\t\t}\n\t};\n\n\tconst handle = reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tserialize: (value) => {\n\t\t\tconst s = serialize(value);\n\t\t\tif (s === undefined) {\n\t\t\t\tthrow new Error(\"serialize returned undefined\");\n\t\t\t}\n\t\t\treturn s;\n\t\t},\n\t\tretry,\n\t\tbackpressure,\n\t\tstopOn,\n\t\tonDispose: removeExternalCloseHandler,\n\t\tsend: (payload) => {\n\t\t\tsocket.send(payload as string | ArrayBufferLike | Blob | ArrayBufferView);\n\t\t},\n\t\tonUpstreamMessage: (msg) => {\n\t\t\tif (msg[0] === COMPLETE && closeOnComplete) closeSocket(msg);\n\t\t\telse if (msg[0] === ERROR && closeOnError) closeSocket(msg);\n\t\t},\n\t});\n\n\t// Listen for external socket `close` events to tear the sink down.\n\texternalCloseHandler = () => {\n\t\tsocketClosed = true;\n\t\thandle.dispose();\n\t};\n\tsocket.addEventListener(\"close\", externalCloseHandler);\n\treturn handle;\n}\n\n// ——————————————————————————————————————————————————————————————\n// fromWebSocketReconnect — reconnecting WebSocket source via retrySource\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link fromWebSocketReconnect}. */\nexport type FromWebSocketReconnectOptions<T> = ExtraOpts & {\n\t/** Optional parser applied to incoming messages. */\n\tparse?: (payload: unknown, event: unknown) => T;\n\t/** Max reconnect attempts. Default: `Infinity` (implied when `backoff` is set). */\n\tmaxRetries?: number;\n\t/** Backoff strategy (ns) or preset name. Default: `\"exponential\"`. */\n\tbackoff?: Parameters<typeof retrySource>[1] extends infer O\n\t\t? O extends { backoff?: infer B }\n\t\t\t? B\n\t\t\t: never\n\t\t: never;\n\t/** Close the socket on teardown. Default: `true`. */\n\tcloseOnTeardown?: boolean;\n};\n\n/**\n * Reconnecting WebSocket source — each connection attempt calls `factory` to\n * obtain a fresh {@link WebSocketLike}; on `close` (treated as terminal\n * `COMPLETE`), {@link retrySource} rebuilds the inner source and reconnects.\n *\n * For transient errors, {@link retrySource} retries with the configured\n * backoff. On `maxRetries` exhaustion, terminal `ERROR` propagates.\n *\n * @param factory - Invoked per reconnect to create a fresh WebSocket.\n * @param opts - Parse, retry, and close options.\n *\n * @example\n * ```ts\n * import { fromWebSocketReconnect } from \"@graphrefly/graphrefly-ts\";\n * const ws$ = fromWebSocketReconnect(\n * () => new WebSocket(\"wss://example/stream\"),\n * { backoff: \"exponential\", maxRetries: 10 },\n * );\n * ```\n *\n * @category extra\n */\nexport function fromWebSocketReconnect<T = unknown>(\n\tfactory: () => WebSocketLike,\n\topts?: FromWebSocketReconnectOptions<T>,\n): Node<T> {\n\tconst {\n\t\tparse,\n\t\tmaxRetries,\n\t\tbackoff = \"exponential\",\n\t\tcloseOnTeardown = true,\n\t\t...rest\n\t} = opts ?? {};\n\treturn retrySource<T>(\n\t\t() =>\n\t\t\tfromWebSocket<T>(factory(), {\n\t\t\t\tparse,\n\t\t\t\tcloseOnTeardown,\n\t\t\t\t...rest,\n\t\t\t}),\n\t\t{ count: maxRetries, backoff },\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// MCP adapter (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Duck-typed MCP (Model Context Protocol) client — only the notification\n * registration surface is required so callers are not coupled to a specific SDK.\n */\nexport type MCPClientLike = {\n\tsetNotificationHandler(method: string, handler: (notification: unknown) => void): void;\n};\n\n/** Options for {@link fromMCP}. */\nexport type FromMCPOptions = ExtraOpts & {\n\t/** MCP notification method to subscribe to. Default `\"notifications/message\"`. */\n\tmethod?: string;\n\tonDisconnect?: (cb: (err?: unknown) => void) => void;\n};\n\n/**\n * Wraps an MCP client's server-push notifications as a reactive source.\n *\n * @category extra\n */\nexport function fromMCP<T = unknown>(client: MCPClientLike, opts?: FromMCPOptions): Node<T> {\n\tconst { method = \"notifications/message\", onDisconnect, ...rest } = opts ?? {};\n\treturn externalProducer<T>(({ emit, error }) => {\n\t\tclient.setNotificationHandler(method, (notification) => emit(notification as T));\n\t\tonDisconnect?.((err?: unknown) => error(err ?? new Error(\"MCP client disconnected\")));\n\t\t// MCP SDKs do not expose handler deregistration — replace with a no-op\n\t\t// on teardown. Caller owns the client lifecycle for full cleanup.\n\t\treturn () => client.setNotificationHandler(method, () => {});\n\t}, rest);\n}\n\n// ——————————————————————————————————————————————————————————————\n// Git adapter (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/** Git hook type for {@link fromGitHook}. */\nexport type GitHookType = \"post-commit\" | \"post-merge\" | \"post-checkout\" | \"post-rewrite\";\n\n/** Structured git event emitted by {@link fromGitHook}. */\nexport type GitEvent = {\n\thook: GitHookType;\n\tcommit: string;\n\tfiles: string[];\n\tmessage: string;\n\tauthor: string;\n\ttimestamp_ns: number;\n};\n\n/** Options for {@link fromGitHook}. */\nexport type FromGitHookOptions = ExtraOpts & {\n\tpollMs?: number;\n\tinclude?: string[];\n\texclude?: string[];\n\t/**\n\t * Maximum consecutive poll errors before terminating the source. Prevents\n\t * error storms when the repository is unavailable (e.g. deleted, corrupt,\n\t * permissions lost). Default: `1` (terminate on first error — preserves pre-switchMap back-compat). Raise it (or set `Infinity`) to keep retrying\n\t * indefinitely (legacy behavior).\n\t */\n\tmaxConsecutiveErrors?: number;\n};\n\n// globToRegExp, matchesAnyPattern imported from ./sources.js\n\n/**\n * Git change detection as a reactive source.\n *\n * @category extra\n */\nexport function fromGitHook(repoPath: string, opts?: FromGitHookOptions): Node<GitEvent> {\n\tconst { pollMs = 5000, include, exclude, maxConsecutiveErrors = 1 } = opts ?? {};\n\tconst includePatterns = include?.map(globToRegExp) ?? [];\n\tconst excludePatterns = exclude?.map(globToRegExp) ?? [];\n\tconst { execFileSync } = require(\"node:child_process\") as typeof import(\"node:child_process\");\n\n\tconst gitQuery = (args: string[]): string =>\n\t\texecFileSync(\"git\", args, { cwd: repoPath, encoding: \"utf-8\" }).trim();\n\n\t// Shared across ticks: the previous HEAD we committed to. Undefined on the\n\t// very first poll (we record the initial HEAD without emitting).\n\tlet lastSeen: string | undefined;\n\t// Circuit breaker: consecutive error count. Resets on any successful poll.\n\tlet consecutiveErrors = 0;\n\n\t// `fromTimer | switchMap(sync-git-diff)` — ticks drive the poll, switchMap\n\t// cancels any in-flight inner on next tick. First tick at t=0 records the\n\t// baseline HEAD silently; subsequent ticks emit `GitEvent` on HEAD change.\n\treturn switchMap(fromTimer(0, { period: pollMs }), () =>\n\t\tproducer<GitEvent>((a) => {\n\t\t\ttry {\n\t\t\t\tconst head = gitQuery([\"rev-parse\", \"HEAD\"]);\n\t\t\t\tif (!head) {\n\t\t\t\t\tconsecutiveErrors = 0;\n\t\t\t\t\treturn () => {};\n\t\t\t\t}\n\t\t\t\tif (lastSeen === undefined) {\n\t\t\t\t\t// First poll: record baseline; stay idle until next tick\n\t\t\t\t\t// disposes this inner.\n\t\t\t\t\tlastSeen = head;\n\t\t\t\t\tconsecutiveErrors = 0;\n\t\t\t\t\treturn () => {};\n\t\t\t\t}\n\t\t\t\tif (head === lastSeen) {\n\t\t\t\t\tconsecutiveErrors = 0;\n\t\t\t\t\treturn () => {};\n\t\t\t\t}\n\t\t\t\tlet files = gitQuery([\"diff\", \"--name-only\", `${lastSeen}..${head}`])\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.filter(Boolean);\n\t\t\t\tif (includePatterns.length > 0) {\n\t\t\t\t\tfiles = files.filter((f) => matchesAnyPattern(f, includePatterns));\n\t\t\t\t}\n\t\t\t\tif (excludePatterns.length > 0) {\n\t\t\t\t\tfiles = files.filter((f) => !matchesAnyPattern(f, excludePatterns));\n\t\t\t\t}\n\t\t\t\tconst message = gitQuery([\"log\", \"-1\", \"--format=%s\", head]);\n\t\t\t\tconst author = gitQuery([\"log\", \"-1\", \"--format=%an\", head]);\n\t\t\t\ta.emit({\n\t\t\t\t\thook: \"post-commit\" as GitHookType,\n\t\t\t\t\tcommit: head,\n\t\t\t\t\tfiles,\n\t\t\t\t\tmessage,\n\t\t\t\t\tauthor,\n\t\t\t\t\ttimestamp_ns: wallClockNs(),\n\t\t\t\t});\n\t\t\t\tlastSeen = head;\n\t\t\t\tconsecutiveErrors = 0;\n\t\t\t} catch (err) {\n\t\t\t\tconsecutiveErrors += 1;\n\t\t\t\tif (consecutiveErrors >= maxConsecutiveErrors) {\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t\t// else: transient error — next tick will retry; don't spam ERROR.\n\t\t\t}\n\t\t\treturn () => {};\n\t\t}),\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// 5.2c — Ingest adapters (universal source layer)\n// ——————————————————————————————————————————————————————————————\n\n// ——— Shared helpers ———\n\n/** Standard handler triple for adapters that accept injected registrations. Alias of {@link EmitTriad}. */\nexport type AdapterHandlers<T> = EmitTriad<T>;\n\n/**\n * Message envelope emitted by queue consumers when `autoAck: false`. The\n * caller is responsible for calling `ack()` after successful processing or\n * `nack()` to re-queue / dead-letter. Pairs cleanly with reactive pipelines:\n *\n * ```ts\n * const messages$ = fromPulsar(consumer, { autoAck: false });\n * effect([messages$], ([m]) => {\n * try {\n * process(m.value);\n * m.ack();\n * } catch (err) {\n * m.nack({ requeue: true });\n * }\n * });\n * ```\n *\n * Ack/nack are imperative callbacks (§5.10 boundary) because the underlying\n * SDKs expose them as such. Reactive-all-the-way ack flows can be built by\n * piping `msg.ack` calls into a `reactiveSink` if desired.\n *\n * **Caller contract — must settle every emitted message.** The envelope holds\n * a closure reference to the raw SDK message; unsettled envelopes keep the\n * broker's in-flight window full and leak memory proportional to consumer\n * throughput. Patterns that drop messages (filter, take-first, switchMap\n * discard) must explicitly `nack({ requeue: true })` the discarded ones, or\n * wrap the source to force-settle on teardown.\n *\n * **Ack/nack transport failures.** Both methods route exceptions through\n * the source's `onAckError` option (when provided) — SDK rejections from\n * `acknowledge()`/`negativeAcknowledge()` don't escape as unhandled\n * rejections. Default (no `onAckError`): swallow. The broker handles\n * redelivery on its own timeline.\n *\n * @category extra\n */\nexport type AckableMessage<T> = {\n\t/** The wrapped message body. */\n\tvalue: T;\n\t/** Acknowledge successful processing. Safe to call more than once — idempotent. */\n\tack(): void;\n\t/**\n\t * Negative-acknowledge — signals the broker the message was not processed\n\t * successfully. `requeue: true` asks the broker to redeliver; `requeue: false`\n\t * may route to a dead-letter queue (SDK-specific). Omit `requeue` to\n\t * defer to the SDK's own default.\n\t */\n\tnack(opts?: { requeue?: boolean }): void;\n};\n\n// ——— OpenTelemetry (OTLP/HTTP) ———\n\n/** Structured OTel span. */\nexport type OTelSpan = {\n\ttraceId: string;\n\tspanId: string;\n\toperationName: string;\n\tserviceName: string;\n\tstartTimeNs: number;\n\tendTimeNs: number;\n\tstatus: \"OK\" | \"ERROR\" | \"UNSET\";\n\tattributes: Record<string, unknown>;\n\tevents: Array<{ name: string; timestampNs: number; attributes?: Record<string, unknown> }>;\n};\n\n/** Structured OTel metric data point. */\nexport type OTelMetric = {\n\tname: string;\n\tdescription?: string;\n\tunit?: string;\n\ttype: \"gauge\" | \"sum\" | \"histogram\" | \"summary\";\n\tvalue: number;\n\tattributes: Record<string, unknown>;\n\ttimestampNs: number;\n};\n\n/** Structured OTel log record. */\nexport type OTelLog = {\n\ttimestampNs: number;\n\tseverityNumber?: number;\n\tseverityText?: string;\n\tbody: unknown;\n\tattributes: Record<string, unknown>;\n\ttraceId?: string;\n\tspanId?: string;\n};\n\n/** Registration callback for the OTLP/HTTP receiver. */\nexport type OTelRegister = (handlers: {\n\tonTraces: (spans: OTelSpan[]) => void;\n\tonMetrics: (metrics: OTelMetric[]) => void;\n\tonLogs: (logs: OTelLog[]) => void;\n\tonError: (err: unknown) => void;\n}) => (() => void) | undefined;\n\n/** Options for {@link fromOTel}. */\nexport type FromOTelOptions = ExtraOpts & {};\n\n/** Bundle returned by {@link fromOTel}. */\nexport type OTelBundle = {\n\ttraces: Node<OTelSpan>;\n\tmetrics: Node<OTelMetric>;\n\tlogs: Node<OTelLog>;\n\t/** Unconditional teardown — calls the registrar's cleanup and fires COMPLETE on every channel. */\n\tdispose(): void;\n};\n\n/**\n * OTLP/HTTP receiver — accepts traces, metrics, and logs as separate reactive nodes.\n *\n * The caller owns the HTTP server. `fromOTel` receives a `register` callback that\n * wires OTLP POST endpoints to the three signal handlers. Each signal type gets\n * its own `Node` so downstream can subscribe selectively.\n *\n * @param register - Wires OTLP HTTP routes to `onTraces`, `onMetrics`, `onLogs` handlers.\n * @param opts - Optional producer options.\n * @returns {@link OTelBundle} — `{ traces, metrics, logs }` nodes.\n *\n * @example\n * ```ts\n * import express from \"express\";\n * import { fromOTel } from \"@graphrefly/graphrefly-ts\";\n *\n * const app = express();\n * app.use(express.json());\n *\n * const otel = fromOTel(({ onTraces, onMetrics, onLogs }) => {\n * app.post(\"/v1/traces\", (req, res) => { onTraces(req.body.resourceSpans ?? []); res.sendStatus(200); });\n * app.post(\"/v1/metrics\", (req, res) => { onMetrics(req.body.resourceMetrics ?? []); res.sendStatus(200); });\n * app.post(\"/v1/logs\", (req, res) => { onLogs(req.body.resourceLogs ?? []); res.sendStatus(200); });\n * return () => {};\n * });\n * ```\n *\n * @category extra\n */\nexport function fromOTel(register: OTelRegister, opts?: FromOTelOptions): OTelBundle {\n\ttype OTelChannels = { traces: OTelSpan; metrics: OTelMetric; logs: OTelLog };\n\tconst nodes = externalBundle<OTelChannels>(\n\t\t({ traces, metrics, logs, error }: BundleTriad<OTelChannels>) => {\n\t\t\treturn (\n\t\t\t\tregister({\n\t\t\t\t\tonTraces: (spans) => {\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tfor (const s of spans) traces(s);\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tonMetrics: (ms) => {\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tfor (const m of ms) metrics(m);\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tonLogs: (ls) => {\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tfor (const l of ls) logs(l);\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tonError: error,\n\t\t\t\t}) ?? undefined\n\t\t\t);\n\t\t},\n\t\t[\"traces\", \"metrics\", \"logs\"],\n\t\topts?.name ? { name: opts.name } : undefined,\n\t);\n\treturn nodes;\n}\n\n// ——— Syslog (RFC 5424) ———\n\n/** Parsed syslog message (RFC 5424). */\nexport type SyslogMessage = {\n\tfacility: number;\n\tseverity: number;\n\ttimestamp: string;\n\thostname: string;\n\tappName: string;\n\tprocId: string;\n\tmsgId: string;\n\tmessage: string;\n\ttimestampNs: number;\n};\n\n/** Registration callback for syslog receiver. Alias of {@link ExternalRegister} over {@link EmitTriad}. */\nexport type SyslogRegister = ExternalRegister<EmitTriad<SyslogMessage>>;\n\n/** Options for {@link fromSyslog}. */\nexport type FromSyslogOptions = ExtraOpts & {};\n\n/**\n * RFC 5424 syslog receiver as a reactive source.\n *\n * The caller owns the UDP/TCP socket. `fromSyslog` receives a `register` callback\n * that wires socket data events to the `emit` handler with parsed syslog messages.\n *\n * @param register - Wires socket to emit/error/complete handlers.\n * @param opts - Optional producer options.\n * @returns `Node<SyslogMessage>` — one `DATA` per syslog message.\n *\n * @example\n * ```ts\n * import dgram from \"node:dgram\";\n * import { fromSyslog, parseSyslog } from \"@graphrefly/graphrefly-ts\";\n *\n * const server = dgram.createSocket(\"udp4\");\n * const syslog$ = fromSyslog(({ emit, error }) => {\n * server.on(\"message\", (buf) => {\n * try { emit(parseSyslog(buf.toString())); }\n * catch (e) { error(e); }\n * });\n * server.bind(514);\n * return () => server.close();\n * });\n * ```\n *\n * @category extra\n */\nexport function fromSyslog(\n\tregister: SyslogRegister,\n\topts?: FromSyslogOptions,\n): Node<SyslogMessage> {\n\treturn externalProducer<SyslogMessage>(register, opts);\n}\n\n/**\n * Parses a raw RFC 5424 syslog line into a structured {@link SyslogMessage}.\n *\n * Format: `<PRI>VERSION TIMESTAMP HOSTNAME APP-NAME PROCID MSGID MSG`\n *\n * @category extra\n */\nexport function parseSyslog(raw: string): SyslogMessage {\n\tconst match = raw.match(/^<(\\d{1,3})>\\d?\\s*(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s*(.*)/s);\n\tif (!match) {\n\t\tconst nowNs = wallClockNs();\n\t\treturn {\n\t\t\tfacility: 1,\n\t\t\tseverity: 6,\n\t\t\ttimestamp: new Date(Math.floor(nowNs / 1_000_000)).toISOString(),\n\t\t\thostname: \"-\",\n\t\t\tappName: \"-\",\n\t\t\tprocId: \"-\",\n\t\t\tmsgId: \"-\",\n\t\t\tmessage: raw.trim(),\n\t\t\ttimestampNs: nowNs,\n\t\t};\n\t}\n\tconst pri = Number(match[1]);\n\treturn {\n\t\tfacility: pri >> 3,\n\t\tseverity: pri & 7,\n\t\ttimestamp: match[2],\n\t\thostname: match[3],\n\t\tappName: match[4],\n\t\tprocId: match[5],\n\t\tmsgId: match[6],\n\t\tmessage: (match[7] ?? \"\").trim(),\n\t\ttimestampNs: wallClockNs(),\n\t};\n}\n\n// ——— StatsD / DogStatsD ———\n\n/** Parsed StatsD metric. */\nexport type StatsDMetric = {\n\tname: string;\n\tvalue: number;\n\ttype: \"counter\" | \"gauge\" | \"timer\" | \"histogram\" | \"set\" | \"distribution\";\n\tsampleRate?: number;\n\ttags: Record<string, string>;\n\ttimestampNs: number;\n};\n\n/** Registration callback for StatsD receiver. Alias of {@link ExternalRegister} over {@link EmitTriad}. */\nexport type StatsDRegister = ExternalRegister<EmitTriad<StatsDMetric>>;\n\n/** Options for {@link fromStatsD}. */\nexport type FromStatsDOptions = ExtraOpts & {};\n\n/**\n * StatsD/DogStatsD UDP receiver as a reactive source.\n *\n * The caller owns the UDP socket. `fromStatsD` receives a `register` callback\n * that wires datagrams to the `emit` handler with parsed metrics.\n *\n * @param register - Wires socket to emit/error/complete handlers.\n * @param opts - Optional producer options.\n * @returns `Node<StatsDMetric>` — one `DATA` per metric line.\n *\n * @example\n * ```ts\n * import dgram from \"node:dgram\";\n * import { fromStatsD, parseStatsD } from \"@graphrefly/graphrefly-ts\";\n *\n * const server = dgram.createSocket(\"udp4\");\n * const stats$ = fromStatsD(({ emit, error }) => {\n * server.on(\"message\", (buf) => {\n * for (const line of buf.toString().split(\"\\\\n\")) {\n * if (line.trim()) {\n * try { emit(parseStatsD(line)); }\n * catch (e) { error(e); }\n * }\n * }\n * });\n * server.bind(8125);\n * return () => server.close();\n * });\n * ```\n *\n * @category extra\n */\nexport function fromStatsD(register: StatsDRegister, opts?: FromStatsDOptions): Node<StatsDMetric> {\n\treturn externalProducer<StatsDMetric>(register, opts);\n}\n\nconst STATSD_TYPES: Record<string, StatsDMetric[\"type\"]> = {\n\tc: \"counter\",\n\tg: \"gauge\",\n\tms: \"timer\",\n\th: \"histogram\",\n\ts: \"set\",\n\td: \"distribution\",\n};\n\n/**\n * Parses a raw StatsD/DogStatsD line into a structured {@link StatsDMetric}.\n *\n * Format: `metric.name:value|type|@sampleRate|#tag1:val1,tag2:val2`\n *\n * @category extra\n */\nexport function parseStatsD(line: string): StatsDMetric {\n\tconst parts = line.split(\"|\");\n\tconst [name, valueStr] = (parts[0] ?? \"\").split(\":\");\n\tif (!name || valueStr === undefined) {\n\t\tthrow new Error(`Invalid StatsD line: ${line}`);\n\t}\n\tconst typeCode = parts[1]?.trim() ?? \"c\";\n\tconst type = STATSD_TYPES[typeCode] ?? \"counter\";\n\t// Set type uses string identifiers (e.g. unique user IDs), not numeric values.\n\tconst value = type === \"set\" ? 0 : Number(valueStr);\n\n\tlet sampleRate: number | undefined;\n\tconst tags: Record<string, string> = {};\n\n\tfor (let i = 2; i < parts.length; i++) {\n\t\tconst part = parts[i].trim();\n\t\tif (part.startsWith(\"@\")) {\n\t\t\tsampleRate = Number(part.slice(1));\n\t\t} else if (part.startsWith(\"#\")) {\n\t\t\tfor (const tag of part.slice(1).split(\",\")) {\n\t\t\t\tconst [k, v] = tag.split(\":\");\n\t\t\t\tif (k) tags[k] = v ?? \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { name: name.trim(), value, type, sampleRate, tags, timestampNs: wallClockNs() };\n}\n\n// ——— Prometheus scrape ———\n\n/** Parsed Prometheus metric. */\nexport type PrometheusMetric = {\n\tname: string;\n\tlabels: Record<string, string>;\n\tvalue: number;\n\ttimestampMs?: number;\n\ttype?: \"counter\" | \"gauge\" | \"histogram\" | \"summary\" | \"untyped\";\n\thelp?: string;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromPrometheus}. */\nexport type FromPrometheusOptions = AsyncSourceOpts & {\n\t/** Scrape interval in nanoseconds. Default `15 * NS_PER_SEC` (15s). */\n\tintervalNs?: number;\n\t/** Request headers for the scrape. */\n\theaders?: Record<string, string>;\n\t/** Request timeout in nanoseconds. Default `10 * NS_PER_SEC` (10s). */\n\ttimeoutNs?: number;\n\t/**\n\t * Maximum consecutive scrape errors before terminating the source. Prevents\n\t * error storms when the endpoint is down. Default: `1` (terminate on first error — preserves pre-switchMap back-compat). Raise it (or set `Infinity`)\n\t * to keep retrying indefinitely.\n\t */\n\tmaxConsecutiveErrors?: number;\n};\n\n/**\n * Scrapes a Prometheus `/metrics` endpoint on a reactive timer interval.\n *\n * Each scrape parses the exposition format and emits one `DATA` per metric line.\n * Uses `fromTimer` semantics internally (reactive timer source, not polling).\n *\n * @param endpoint - URL of the Prometheus metrics endpoint.\n * @param opts - Scrape interval, headers, timeout.\n * @returns `Node<PrometheusMetric>` — one `DATA` per metric per scrape.\n *\n * @example\n * ```ts\n * import { fromPrometheus } from \"@graphrefly/graphrefly-ts\";\n *\n * const prom$ = fromPrometheus(\"http://localhost:9090/metrics\", { intervalNs: 30 * NS_PER_SEC });\n * ```\n *\n * @category extra\n */\nexport function fromPrometheus(\n\tendpoint: string,\n\topts?: FromPrometheusOptions,\n): Node<PrometheusMetric> {\n\tconst {\n\t\tintervalNs = 15 * NS_PER_SEC,\n\t\theaders,\n\t\ttimeoutNs = 10 * NS_PER_SEC,\n\t\tsignal: externalSignal,\n\t\tmaxConsecutiveErrors = 1,\n\t} = opts ?? {};\n\tconst intervalMs = Math.ceil(intervalNs / NS_PER_MS);\n\t// Circuit breaker shared across switchMap inners — resets on any successful\n\t// scrape, trips when consecutive errors hit the cap.\n\tlet consecutiveErrors = 0;\n\n\t// Timer drives scrapes: first tick at t=0, then every intervalMs. Each tick\n\t// switches to a fresh inner producer that does one scrape and completes —\n\t// switchMap cancels any in-flight scrape when the next tick arrives.\n\treturn switchMap(fromTimer(0, { period: intervalMs, signal: externalSignal }), () =>\n\t\tproducer<PrometheusMetric>((a) => {\n\t\t\tlet active = true;\n\t\t\tconst abort = new AbortController();\n\t\t\tconst timeoutId = setTimeout(\n\t\t\t\t() => abort.abort(new Error(\"Scrape timeout\")),\n\t\t\t\tMath.ceil(timeoutNs / NS_PER_MS),\n\t\t\t);\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst res = await fetch(endpoint, {\n\t\t\t\t\t\theaders: { Accept: \"text/plain\", ...headers },\n\t\t\t\t\t\tsignal: abort.signal,\n\t\t\t\t\t});\n\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tif (!res.ok) throw new Error(`Prometheus scrape ${res.status}: ${res.statusText}`);\n\t\t\t\t\tconst text = await res.text();\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tconst metrics = parsePrometheusText(text);\n\t\t\t\t\tfor (const m of metrics) a.emit(m);\n\t\t\t\t\tconsecutiveErrors = 0;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tif (err instanceof Error && err.name === \"AbortError\") return;\n\t\t\t\t\tconsecutiveErrors += 1;\n\t\t\t\t\tif (consecutiveErrors >= maxConsecutiveErrors) {\n\t\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\t}\n\t\t\t\t\t// else: swallow transient error; next tick retries.\n\t\t\t\t}\n\t\t\t};\n\t\t\tvoid run();\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\tabort.abort();\n\t\t\t};\n\t\t}),\n\t);\n}\n\n/**\n * Parses Prometheus exposition format text into structured metrics.\n *\n * @category extra\n */\nexport function parsePrometheusText(text: string): PrometheusMetric[] {\n\tconst results: PrometheusMetric[] = [];\n\tconst types = new Map<string, string>();\n\tconst helps = new Map<string, string>();\n\n\tfor (const rawLine of text.split(\"\\n\")) {\n\t\tconst line = rawLine.trim();\n\t\tif (!line) continue;\n\n\t\tif (line.startsWith(\"# TYPE \")) {\n\t\t\tconst rest = line.slice(7);\n\t\t\tconst spaceIdx = rest.indexOf(\" \");\n\t\t\tif (spaceIdx > 0) {\n\t\t\t\ttypes.set(rest.slice(0, spaceIdx), rest.slice(spaceIdx + 1).trim());\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\"# HELP \")) {\n\t\t\tconst rest = line.slice(7);\n\t\t\tconst spaceIdx = rest.indexOf(\" \");\n\t\t\tif (spaceIdx > 0) {\n\t\t\t\thelps.set(rest.slice(0, spaceIdx), rest.slice(spaceIdx + 1).trim());\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\"#\")) continue;\n\n\t\t// metric_name{label=\"value\"} 123 timestamp?\n\t\tlet name: string;\n\t\tlet labels: Record<string, string> = {};\n\t\tlet valueStr: string;\n\t\tlet tsStr: string | undefined;\n\n\t\tconst braceIdx = line.indexOf(\"{\");\n\t\tif (braceIdx >= 0) {\n\t\t\tname = line.slice(0, braceIdx);\n\t\t\tconst closeBrace = line.indexOf(\"}\", braceIdx);\n\t\t\tif (closeBrace < 0) continue;\n\t\t\tconst labelStr = line.slice(braceIdx + 1, closeBrace);\n\t\t\tlabels = parsePrometheusLabels(labelStr);\n\t\t\tconst after = line\n\t\t\t\t.slice(closeBrace + 1)\n\t\t\t\t.trim()\n\t\t\t\t.split(/\\s+/);\n\t\t\tvalueStr = after[0] ?? \"\";\n\t\t\ttsStr = after[1];\n\t\t} else {\n\t\t\tconst parts = line.split(/\\s+/);\n\t\t\tname = parts[0] ?? \"\";\n\t\t\tvalueStr = parts[1] ?? \"\";\n\t\t\ttsStr = parts[2];\n\t\t}\n\n\t\tif (!name || !valueStr) continue;\n\n\t\tconst baseName = name.replace(/(_total|_count|_sum|_bucket|_created|_info)$/, \"\");\n\t\tresults.push({\n\t\t\tname,\n\t\t\tlabels,\n\t\t\tvalue: Number(valueStr),\n\t\t\ttimestampMs: tsStr ? Number(tsStr) : undefined,\n\t\t\ttype: (types.get(baseName) ?? types.get(name)) as PrometheusMetric[\"type\"],\n\t\t\thelp: helps.get(baseName) ?? helps.get(name),\n\t\t\ttimestampNs: wallClockNs(),\n\t\t});\n\t}\n\n\treturn results;\n}\n\nfunction parsePrometheusLabels(str: string): Record<string, string> {\n\tconst labels: Record<string, string> = {};\n\tconst re = /(\\w+)=\"((?:[^\"\\\\]|\\\\.)*)\"/g;\n\tlet m: RegExpExecArray | null = re.exec(str);\n\twhile (m !== null) {\n\t\tlabels[m[1]] = m[2].replace(/\\\\(.)/g, \"$1\");\n\t\tm = re.exec(str);\n\t}\n\treturn labels;\n}\n\n// ——— Kafka ———\n\n/** Duck-typed Kafka consumer (compatible with kafkajs, confluent-kafka, Pulsar KoP). */\nexport type KafkaConsumerLike = {\n\tsubscribe(opts: { topic: string; fromBeginning?: boolean }): Promise<void>;\n\trun(opts: {\n\t\teachMessage: (payload: {\n\t\t\ttopic: string;\n\t\t\tpartition: number;\n\t\t\tmessage: {\n\t\t\t\tkey: Buffer | null;\n\t\t\t\tvalue: Buffer | null;\n\t\t\t\theaders?: Record<string, Buffer | string | undefined>;\n\t\t\t\toffset: string;\n\t\t\t\ttimestamp: string;\n\t\t\t};\n\t\t}) => Promise<void>;\n\t}): Promise<void>;\n\tdisconnect(): Promise<void>;\n};\n\n/** Duck-typed Kafka producer. */\nexport type KafkaProducerLike = {\n\tsend(record: {\n\t\ttopic: string;\n\t\tmessages: Array<{\n\t\t\tkey?: string | Buffer | null;\n\t\t\tvalue: string | Buffer | null;\n\t\t\theaders?: Record<string, string | Buffer>;\n\t\t}>;\n\t}): Promise<void>;\n\tdisconnect(): Promise<void>;\n};\n\n/** Structured Kafka message. */\nexport type KafkaMessage<T = unknown> = {\n\ttopic: string;\n\tpartition: number;\n\tkey: string | null;\n\tvalue: T;\n\theaders: Record<string, string>;\n\toffset: string;\n\ttimestamp: string;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromKafka}. */\nexport type FromKafkaOptions = ExtraOpts & {\n\t/** Start from beginning of topic. Default: `false`. */\n\tfromBeginning?: boolean;\n\t/** Deserialize message value. Default: `JSON.parse(buffer.toString())`. */\n\tdeserialize?: (value: Buffer | null) => unknown;\n};\n\n/**\n * Kafka consumer as a reactive source.\n *\n * Wraps a KafkaJS-compatible consumer. Each message becomes a `DATA` emission.\n * Compatible with Pulsar via KoP (Kafka-on-Pulsar).\n *\n * @param consumer - KafkaJS-compatible consumer instance (caller owns connect/disconnect lifecycle).\n * @param topic - Topic to consume from.\n * @param opts - Deserialization and source options.\n * @returns `Node<KafkaMessage<T>>` — one `DATA` per Kafka message.\n *\n * @example\n * ```ts\n * import { Kafka } from \"kafkajs\";\n * import { fromKafka } from \"@graphrefly/graphrefly-ts\";\n *\n * const kafka = new Kafka({ brokers: [\"localhost:9092\"] });\n * const consumer = kafka.consumer({ groupId: \"my-group\" });\n * await consumer.connect();\n *\n * const events$ = fromKafka(consumer, \"events\", { deserialize: (buf) => JSON.parse(buf!.toString()) });\n * ```\n *\n * @category extra\n */\nexport function fromKafka<T = unknown>(\n\tconsumer: KafkaConsumerLike,\n\ttopic: string,\n\topts?: FromKafkaOptions,\n): Node<KafkaMessage<T>> {\n\tconst {\n\t\tfromBeginning = false,\n\t\tdeserialize = (buf: Buffer | null) => {\n\t\t\tif (buf === null) return null;\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(buf.toString());\n\t\t\t} catch {\n\t\t\t\treturn buf.toString();\n\t\t\t}\n\t\t},\n\t\t...rest\n\t} = opts ?? {};\n\n\treturn producer<KafkaMessage<T>>((a) => {\n\t\tlet active = true;\n\n\t\tconst start = async () => {\n\t\t\ttry {\n\t\t\t\tawait consumer.subscribe({ topic, fromBeginning });\n\t\t\t\tawait consumer.run({\n\t\t\t\t\teachMessage: async ({ topic: t, partition, message: msg }) => {\n\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\tconst headers: Record<string, string> = {};\n\t\t\t\t\t\tif (msg.headers) {\n\t\t\t\t\t\t\tfor (const [k, v] of Object.entries(msg.headers)) {\n\t\t\t\t\t\t\t\tif (v !== undefined) headers[k] = typeof v === \"string\" ? v : v.toString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\ta.emit({\n\t\t\t\t\t\t\ttopic: t,\n\t\t\t\t\t\t\tpartition,\n\t\t\t\t\t\t\tkey: msg.key?.toString() ?? null,\n\t\t\t\t\t\t\tvalue: deserialize(msg.value) as T,\n\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\toffset: msg.offset,\n\t\t\t\t\t\t\ttimestamp: msg.timestamp,\n\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\n\t\tvoid start();\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/** Options for {@link toKafka}. */\nexport type ToKafkaOptions<T> = ExtraOpts & {\n\t/** Serialize value for Kafka. Default: `JSON.stringify`. */\n\tserialize?: (value: T) => string | Buffer;\n\t/** Extract message key from value. Default: `null` (no key). */\n\tkeyExtractor?: (value: T) => string | null;\n\t/** Called on serialization or send failures. */\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * Kafka producer sink — forwards upstream `DATA` to a Kafka topic.\n *\n * @param source - Upstream node to forward.\n * @param kafkaProducer - KafkaJS-compatible producer instance.\n * @param topic - Target topic.\n * @param opts - Serialization and key extraction options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toKafka<T>(\n\tsource: Node<T>,\n\tkafkaProducer: KafkaProducerLike,\n\ttopic: string,\n\topts?: ToKafkaOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst { serialize = (v: T) => JSON.stringify(v), keyExtractor, onTransportError } = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tsend: async (value) => {\n\t\t\tconst key = keyExtractor?.(value) ?? null;\n\t\t\tconst serialized = serialize(value);\n\t\t\tawait kafkaProducer.send({\n\t\t\t\ttopic,\n\t\t\t\tmessages: [{ key, value: Buffer.from(serialized as string) }],\n\t\t\t});\n\t\t},\n\t});\n}\n\n// ——— Redis Streams ———\n\n/** Duck-typed Redis client (compatible with ioredis, redis). */\nexport type RedisClientLike = {\n\txadd(key: string, id: string, ...fieldsAndValues: string[]): Promise<string>;\n\txread(\n\t\t...args: Array<string | number>\n\t): Promise<Array<[string, Array<[string, string[]]>]> | null>;\n\tdisconnect(): void;\n};\n\n/** Structured Redis Stream entry. */\nexport type RedisStreamEntry<T = unknown> = {\n\tid: string;\n\tkey: string;\n\tdata: T;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromRedisStream}. */\nexport type FromRedisStreamOptions = ExtraOpts & {\n\t/** Block timeout in ms for XREAD. Default: `5000`. */\n\tblockMs?: number;\n\t/** Start ID. Default: `\"$\"` (new entries only). */\n\tstartId?: string;\n\t/** Parse raw Redis hash fields to structured data. Default: parses `data` field as JSON. */\n\tparse?: (fields: string[]) => unknown;\n};\n\n/**\n * Redis Streams consumer as a reactive source.\n *\n * Uses XREAD with BLOCK to reactively consume stream entries.\n *\n * @param client - ioredis/redis-compatible client (caller owns connection).\n * @param key - Redis stream key.\n * @param opts - Block timeout, start ID, and parsing options.\n * @returns `Node<RedisStreamEntry<T>>` — one `DATA` per stream entry.\n *\n * @remarks\n * **COMPLETE:** This source never emits `COMPLETE` under normal operation — it\n * is a long-lived stream consumer that runs until teardown or error, same as\n * Kafka consumers. If you need a bounded read, wrap with `take()` or\n * `takeUntil()`.\n *\n * **Client lifecycle:** The caller owns the Redis client connection. The adapter\n * does not call `disconnect()` on teardown — the caller is responsible for\n * closing the connection (same contract as `fromKafka`).\n *\n * @category extra\n */\nexport function fromRedisStream<T = unknown>(\n\tclient: RedisClientLike,\n\tkey: string,\n\topts?: FromRedisStreamOptions,\n): Node<RedisStreamEntry<T>> {\n\tconst {\n\t\tblockMs = 5000,\n\t\tstartId = \"$\",\n\t\tparse = (fields: string[]) => {\n\t\t\t// Redis returns flat [field, value, field, value, ...] arrays.\n\t\t\tfor (let i = 0; i < fields.length; i += 2) {\n\t\t\t\tif (fields[i] === \"data\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn JSON.parse(fields[i + 1]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn fields[i + 1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Return as object if no \"data\" field.\n\t\t\tconst obj: Record<string, string> = {};\n\t\t\tfor (let i = 0; i < fields.length; i += 2) {\n\t\t\t\tobj[fields[i]] = fields[i + 1];\n\t\t\t}\n\t\t\treturn obj;\n\t\t},\n\t\t...rest\n\t} = opts ?? {};\n\n\treturn producer<RedisStreamEntry<T>>((a) => {\n\t\tlet active = true;\n\t\tlet lastId = startId;\n\n\t\tconst poll = async () => {\n\t\t\twhile (active) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await client.xread(\"BLOCK\", blockMs, \"STREAMS\", key, lastId);\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\tfor (const [_streamKey, entries] of result) {\n\t\t\t\t\t\t\tfor (const [id, fields] of entries) {\n\t\t\t\t\t\t\t\tlastId = id;\n\t\t\t\t\t\t\t\ta.emit({\n\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\t\tdata: parse(fields) as T,\n\t\t\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t\t\t\t});\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} catch (err) {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tvoid poll();\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/** Options for {@link toRedisStream}. */\nexport type ToRedisStreamOptions<T> = ExtraOpts & {\n\t/** Serialize value to Redis hash fields. Default: `[\"data\", JSON.stringify(value)]`. */\n\tserialize?: (value: T) => string[];\n\t/** Max stream length (MAXLEN ~). Default: no trimming. */\n\tmaxLen?: number;\n\t/** Called on serialization or send failures. */\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * Redis Streams producer sink — forwards upstream `DATA` to a Redis stream.\n *\n * @param source - Upstream node to forward.\n * @param client - ioredis/redis-compatible client.\n * @param key - Redis stream key.\n * @param opts - Serialization options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toRedisStream<T>(\n\tsource: Node<T>,\n\tclient: RedisClientLike,\n\tkey: string,\n\topts?: ToRedisStreamOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tserialize = (v: T) => [\"data\", JSON.stringify(v)],\n\t\tmaxLen,\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tsend: async (value) => {\n\t\t\tconst fields = serialize(value);\n\t\t\tawait (maxLen !== undefined\n\t\t\t\t? client.xadd(key, \"MAXLEN\", \"~\", String(maxLen), \"*\", ...fields)\n\t\t\t\t: client.xadd(key, \"*\", ...fields));\n\t\t},\n\t});\n}\n\n// ——— CSV ingest ———\n\n/** Parsed CSV row. */\nexport type CSVRow = Record<string, string>;\n\n/** Options for {@link fromCSV}. */\nexport type FromCSVOptions = ExtraOpts & {\n\t/** Column delimiter. Default: `\",\"`. */\n\tdelimiter?: string;\n\t/** Whether the first row is a header. Default: `true`. */\n\thasHeader?: boolean;\n\t/** Explicit column names (overrides header row). */\n\tcolumns?: string[];\n\t/** Custom line parser (e.g. wrapping a library like `csv-parse`). Overrides built-in parser + delimiter. */\n\tparseLine?: (line: string) => string[];\n};\n\n/**\n * CSV file/stream ingest for batch replay.\n *\n * Reads a CSV from a `ReadableStream<string>` or an `AsyncIterable<string>` of lines,\n * emitting one `DATA` per row. `COMPLETE` after all rows are emitted.\n *\n * @param source - Async iterable of CSV text chunks (lines or multi-line chunks).\n * @param opts - Delimiter, header, and column options.\n * @returns `Node<CSVRow>` — one `DATA` per parsed row.\n *\n * @example\n * ```ts\n * import { createReadStream } from \"node:fs\";\n * import { fromCSV } from \"@graphrefly/graphrefly-ts\";\n *\n * const csv$ = fromCSV(createReadStream(\"data.csv\", \"utf-8\"));\n * ```\n *\n * @category extra\n */\nexport function fromCSV(source: AsyncIterable<string>, opts?: FromCSVOptions): Node<CSVRow> {\n\tconst {\n\t\tdelimiter = \",\",\n\t\thasHeader = true,\n\t\tcolumns: explicitColumns,\n\t\tparseLine,\n\t\t...rest\n\t} = opts ?? {};\n\tconst parse = parseLine ?? ((line: string) => parseCSVLine(line, delimiter));\n\n\treturn producer<CSVRow>((a) => {\n\t\tlet cancelled = false;\n\n\t\tconst run = async () => {\n\t\t\ttry {\n\t\t\t\tlet headers: string[] | undefined = explicitColumns;\n\t\t\t\tlet buffer = \"\";\n\n\t\t\t\tfor await (const chunk of source) {\n\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\tbuffer += chunk;\n\n\t\t\t\t\tconst lines = buffer.split(/\\r?\\n/);\n\t\t\t\t\t// Keep last partial line in buffer.\n\t\t\t\t\tbuffer = lines.pop() ?? \"\";\n\n\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\tif (!line.trim()) continue;\n\n\t\t\t\t\t\tconst values = parse(line);\n\n\t\t\t\t\t\tif (!headers && hasHeader) {\n\t\t\t\t\t\t\theaders = values;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!headers) {\n\t\t\t\t\t\t\theaders = values.map((_, i) => `col${i}`);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst row: CSVRow = {};\n\t\t\t\t\t\tfor (let i = 0; i < headers.length; i++) {\n\t\t\t\t\t\t\trow[headers[i]] = values[i] ?? \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\ta.emit(row);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Process remaining buffer.\n\t\t\t\tif (!cancelled && buffer.trim()) {\n\t\t\t\t\tconst values = parse(buffer);\n\t\t\t\t\tif (headers) {\n\t\t\t\t\t\tconst row: CSVRow = {};\n\t\t\t\t\t\tfor (let i = 0; i < headers.length; i++) {\n\t\t\t\t\t\t\trow[headers[i]] = values[i] ?? \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\ta.emit(row);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\tif (!cancelled) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\n\t\tvoid run();\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/**\n * Stateful CSV parser operator — takes a `Node<string>` emitting raw text\n * chunks (from any source: {@link fromAsyncIter}, {@link fromHTTPStream},\n * WebSocket, file watcher, etc.) and emits one `DATA` per parsed row.\n *\n * Buffers incomplete lines across chunks. Mirrors {@link fromCSV}'s parsing\n * logic without committing to an async-iterable-only input.\n *\n * @example\n * ```ts\n * import { fromHTTPStream, csvRows } from \"@graphrefly/graphrefly-ts\";\n * const bytes$ = fromHTTPStream(\"https://example.com/data.csv\");\n * const text$ = decodeText(bytes$); // caller-provided byte→string decoder\n * const rows$ = csvRows(text$, { columns: [\"name\", \"age\"] });\n * ```\n *\n * @category extra\n */\nexport function csvRows(source: Node<string>, opts?: FromCSVOptions): Node<CSVRow> {\n\tconst {\n\t\tdelimiter = \",\",\n\t\thasHeader = true,\n\t\tcolumns: explicitColumns,\n\t\tparseLine,\n\t\t...rest\n\t} = opts ?? {};\n\tconst parse = parseLine ?? ((line: string) => parseCSVLine(line, delimiter));\n\treturn node<CSVRow>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\t\t\t// Parser state lives in `ctx.store` so it resets automatically on\n\t\t\t// deactivation / resubscribable terminal reset (COMPOSITION-GUIDE §20).\n\t\t\t// That lets the operator sit under retry / resubscribe patterns without\n\t\t\t// leaking a stale half-parsed line from a previous run.\n\t\t\tconst s = ctx.store as { buffer: string; headers: string[] | undefined };\n\t\t\tif (typeof s.buffer !== \"string\") s.buffer = \"\";\n\t\t\tif (s.headers === undefined && explicitColumns) s.headers = explicitColumns.slice();\n\t\t\tfor (const chunkRaw of batch0) {\n\t\t\t\ts.buffer = s.buffer + (chunkRaw as string);\n\t\t\t\tconst lines: string[] = s.buffer.split(/\\r?\\n/);\n\t\t\t\ts.buffer = lines.pop() ?? \"\";\n\t\t\t\tfor (const line of lines) {\n\t\t\t\t\tif (!line.trim()) continue;\n\t\t\t\t\tconst values = parse(line);\n\t\t\t\t\tif (!s.headers && hasHeader) {\n\t\t\t\t\t\ts.headers = values;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!s.headers) s.headers = values.map((_, i) => `col${i}`);\n\t\t\t\t\tconst row: CSVRow = {};\n\t\t\t\t\tfor (let i = 0; i < s.headers.length; i++) row[s.headers[i]] = values[i] ?? \"\";\n\t\t\t\t\ta.emit(row);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ describeKind: \"derived\", ...rest } as NodeOptions<CSVRow>,\n\t);\n}\n\n/**\n * Stateful NDJSON parser operator — takes a `Node<string>` of raw text chunks\n * and emits one `DATA` per parsed JSON object. Buffers partial lines across\n * chunks.\n *\n * @category extra\n */\nexport function ndjsonRows<T = unknown>(source: Node<string>, opts?: ExtraOpts): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\t\t\t// Parser buffer in `ctx.store` resets on deactivation / resubscribable\n\t\t\t// reset (COMPOSITION-GUIDE §20) so resubscribing the operator starts\n\t\t\t// clean rather than bleeding a half-line from a previous run.\n\t\t\tconst s = ctx.store as { buffer: string };\n\t\t\tif (typeof s.buffer !== \"string\") s.buffer = \"\";\n\t\t\tfor (const chunkRaw of batch0) {\n\t\t\t\ts.buffer = s.buffer + (chunkRaw as string);\n\t\t\t\tconst lines: string[] = s.buffer.split(/\\r?\\n/);\n\t\t\t\ts.buffer = lines.pop() ?? \"\";\n\t\t\t\tfor (const line of lines) {\n\t\t\t\t\tif (!line.trim()) continue;\n\t\t\t\t\ttry {\n\t\t\t\t\t\ta.emit(JSON.parse(line) as T);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ describeKind: \"derived\", ...(opts ?? {}) } as NodeOptions<T>,\n\t);\n}\n\nfunction parseCSVLine(line: string, delimiter: string): string[] {\n\tconst values: string[] = [];\n\tlet current = \"\";\n\tlet inQuotes = false;\n\n\tfor (let i = 0; i < line.length; i++) {\n\t\tconst ch = line[i];\n\t\tif (inQuotes) {\n\t\t\tif (ch === '\"') {\n\t\t\t\tif (line[i + 1] === '\"') {\n\t\t\t\t\tcurrent += '\"';\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tinQuotes = false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcurrent += ch;\n\t\t\t}\n\t\t} else if (ch === '\"') {\n\t\t\tinQuotes = true;\n\t\t} else if (ch === delimiter) {\n\t\t\tvalues.push(current);\n\t\t\tcurrent = \"\";\n\t\t} else {\n\t\t\tcurrent += ch;\n\t\t}\n\t}\n\tvalues.push(current);\n\treturn values;\n}\n\n// ——— NDJSON ingest ———\n\n/** Options for {@link fromNDJSON}. */\nexport type FromNDJSONOptions = ExtraOpts & {};\n\n/**\n * Newline-delimited JSON stream ingest for batch replay.\n *\n * Reads an async iterable of text chunks, splits by newline, parses each line\n * as JSON, and emits one `DATA` per parsed object. `COMPLETE` after stream ends.\n *\n * @param source - Async iterable of NDJSON text chunks.\n * @param opts - Optional producer options.\n * @returns `Node<T>` — one `DATA` per JSON line.\n *\n * @example\n * ```ts\n * import { createReadStream } from \"node:fs\";\n * import { fromNDJSON } from \"@graphrefly/graphrefly-ts\";\n *\n * const logs$ = fromNDJSON(createReadStream(\"logs.ndjson\", \"utf-8\"));\n * ```\n *\n * @category extra\n */\nexport function fromNDJSON<T = unknown>(\n\tsource: AsyncIterable<string>,\n\topts?: FromNDJSONOptions,\n): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet cancelled = false;\n\n\t\tconst run = async () => {\n\t\t\ttry {\n\t\t\t\tlet buffer = \"\";\n\n\t\t\t\tfor await (const chunk of source) {\n\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\tbuffer += chunk;\n\n\t\t\t\t\tconst lines = buffer.split(/\\r?\\n/);\n\t\t\t\t\tbuffer = lines.pop() ?? \"\";\n\n\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\tconst trimmed = line.trim();\n\t\t\t\t\t\tif (!trimmed) continue;\n\t\t\t\t\t\ta.emit(JSON.parse(trimmed) as T);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Process remaining buffer.\n\t\t\t\tif (!cancelled && buffer.trim()) {\n\t\t\t\t\ta.emit(JSON.parse(buffer.trim()) as T);\n\t\t\t\t}\n\n\t\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\tif (!cancelled) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\n\t\tvoid run();\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, sourceOpts(opts));\n}\n\n// ——— ClickHouse live materialized view ———\n\n/** Structured ClickHouse query result row. */\nexport type ClickHouseRow = Record<string, unknown>;\n\n/** Duck-typed ClickHouse client. */\nexport type ClickHouseClientLike = {\n\tquery(opts: { query: string; format?: string }): Promise<{\n\t\tjson<T = unknown>(): Promise<T[]>;\n\t}>;\n};\n\n/** Options for {@link fromClickHouseWatch}. */\nexport type FromClickHouseWatchOptions = AsyncSourceOpts & {\n\t/** Polling interval in nanoseconds. Default: `5 * NS_PER_SEC` (5s). */\n\tintervalNs?: number;\n\t/** JSON format to request. Default: `\"JSONEachRow\"`. */\n\tformat?: string;\n\t/**\n\t * Maximum consecutive query errors before terminating the source. Prevents\n\t * error storms when the database is unavailable. Default: `5`. Set to\n\t * `Infinity` to keep retrying indefinitely.\n\t */\n\tmaxConsecutiveErrors?: number;\n};\n\n/**\n * ClickHouse live materialized view as a reactive source.\n *\n * Polls a ClickHouse query on a reactive timer interval and emits new/changed rows.\n * Uses a timer-driven approach (not busy-wait polling).\n *\n * @param client - ClickHouse client instance (caller owns connection).\n * @param query - SQL query to execute on each interval.\n * @param opts - Polling interval and format options.\n * @returns `Node<ClickHouseRow>` — one `DATA` per result row per scrape.\n *\n * @example\n * ```ts\n * import { createClient } from \"@clickhouse/client\";\n * import { fromClickHouseWatch } from \"@graphrefly/graphrefly-ts\";\n *\n * const client = createClient({ url: \"http://localhost:8123\" });\n * const rows$ = fromClickHouseWatch(client, \"SELECT * FROM errors_mv ORDER BY timestamp DESC LIMIT 100\");\n * ```\n *\n * @category extra\n */\nexport function fromClickHouseWatch(\n\tclient: ClickHouseClientLike,\n\tquery: string,\n\topts?: FromClickHouseWatchOptions,\n): Node<ClickHouseRow> {\n\tconst {\n\t\tintervalNs = 5 * NS_PER_SEC,\n\t\tformat = \"JSONEachRow\",\n\t\tsignal: externalSignal,\n\t\tmaxConsecutiveErrors = 1,\n\t} = opts ?? {};\n\tconst intervalMs = Math.ceil(intervalNs / NS_PER_MS);\n\t// Circuit breaker shared across switchMap inners.\n\tlet consecutiveErrors = 0;\n\n\t// `fromTimer | switchMap(producer(one-query))` — timer ticks drive a single\n\t// query each; switchMap cancels any in-flight inner when the next tick\n\t// arrives. First tick at t=0, then every intervalMs.\n\treturn switchMap(fromTimer(0, { period: intervalMs, signal: externalSignal }), () =>\n\t\tproducer<ClickHouseRow>((a) => {\n\t\t\tlet active = true;\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await client.query({ query, format });\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tconst rows = await result.json<ClickHouseRow>();\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tfor (const row of rows) a.emit(row);\n\t\t\t\t\tconsecutiveErrors = 0;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tconsecutiveErrors += 1;\n\t\t\t\t\tif (consecutiveErrors >= maxConsecutiveErrors) {\n\t\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\t}\n\t\t\t\t\t// else: swallow transient error; next tick retries.\n\t\t\t\t}\n\t\t\t};\n\t\t\tvoid run();\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t}),\n\t);\n}\n\n// ——— Apache Pulsar (native client) ———\n\n/** Duck-typed Pulsar consumer (compatible with pulsar-client). */\nexport type PulsarConsumerLike = {\n\treceive(): Promise<{\n\t\tgetData(): Buffer;\n\t\tgetMessageId(): { toString(): string };\n\t\tgetPartitionKey(): string;\n\t\tgetProperties(): Record<string, string>;\n\t\tgetPublishTimestamp(): number;\n\t\tgetEventTimestamp(): number;\n\t\tgetTopicName(): string;\n\t}>;\n\tacknowledge(msg: unknown): Promise<void>;\n\tclose(): Promise<void>;\n};\n\n/** Duck-typed Pulsar producer. */\nexport type PulsarProducerLike = {\n\tsend(msg: {\n\t\tdata: Buffer;\n\t\tpartitionKey?: string;\n\t\tproperties?: Record<string, string>;\n\t}): Promise<void>;\n\tclose(): Promise<void>;\n};\n\n/** Structured Pulsar message. */\nexport type PulsarMessage<T = unknown> = {\n\ttopic: string;\n\tmessageId: string;\n\tkey: string;\n\tvalue: T;\n\tproperties: Record<string, string>;\n\tpublishTime: number;\n\teventTime: number;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromPulsar}. */\nexport type FromPulsarOptions = ExtraOpts & {\n\t/** Deserialize message data. Default: `JSON.parse(buffer.toString())`. */\n\tdeserialize?: (data: Buffer) => unknown;\n\t/** Acknowledge messages automatically. Default: `true`. */\n\tautoAck?: boolean;\n\t/**\n\t * Routes ack/nack transport failures to the caller. Covers:\n\t * - `autoAck: true` — post-emit `acknowledge()` promise rejections.\n\t * - `autoAck: false` — envelope `ack()` / `nack()` promise rejections.\n\t * Default: swallow (SDK handles redelivery on its own).\n\t */\n\tonAckError?: (err: Error) => void;\n};\n\n/**\n * Apache Pulsar consumer as a reactive source (native client).\n *\n * Wraps a `pulsar-client`-compatible consumer. Each message becomes a `DATA` emission.\n * For Kafka-on-Pulsar (KoP), use {@link fromKafka} instead.\n *\n * @param consumer - Pulsar consumer instance (caller owns create/close lifecycle).\n * @param opts - Deserialization and source options.\n * @returns `Node<PulsarMessage<T>>` — one `DATA` per Pulsar message.\n *\n * @remarks\n * Teardown sets an internal flag but cannot interrupt a pending `consumer.receive()`.\n * The loop exits on the next message or when the consumer is closed externally.\n * Callers should call `consumer.close()` after unsubscribing for prompt cleanup.\n *\n * @example\n * ```ts\n * import Pulsar from \"pulsar-client\";\n * import { fromPulsar } from \"@graphrefly/graphrefly-ts\";\n *\n * const client = new Pulsar.Client({ serviceUrl: \"pulsar://localhost:6650\" });\n * const consumer = await client.subscribe({ topic: \"events\", subscription: \"my-sub\" });\n * const events$ = fromPulsar(consumer);\n * ```\n *\n * @category extra\n */\nexport function fromPulsar<T = unknown>(\n\tconsumer: PulsarConsumerLike,\n\topts?: FromPulsarOptions & { autoAck?: true },\n): Node<PulsarMessage<T>>;\nexport function fromPulsar<T = unknown>(\n\tconsumer: PulsarConsumerLike,\n\topts: FromPulsarOptions & { autoAck: false },\n): Node<AckableMessage<PulsarMessage<T>>>;\nexport function fromPulsar<T = unknown>(\n\tconsumer: PulsarConsumerLike,\n\topts?: FromPulsarOptions,\n): Node<PulsarMessage<T> | AckableMessage<PulsarMessage<T>>> {\n\tconst {\n\t\tautoAck = true,\n\t\tdeserialize = (buf: Buffer) => {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(buf.toString());\n\t\t\t} catch {\n\t\t\t\treturn buf.toString();\n\t\t\t}\n\t\t},\n\t\tonAckError,\n\t\t...rest\n\t} = opts ?? {};\n\n\tconst reportAckError = (err: unknown) => {\n\t\tif (!onAckError) return;\n\t\ttry {\n\t\t\tonAckError(err instanceof Error ? err : new Error(String(err)));\n\t\t} catch {\n\t\t\t/* user hook must not escape */\n\t\t}\n\t};\n\n\treturn producer<PulsarMessage<T> | AckableMessage<PulsarMessage<T>>>((a) => {\n\t\tlet active = true;\n\n\t\tconst loop = async () => {\n\t\t\twhile (active) {\n\t\t\t\ttry {\n\t\t\t\t\tconst rawMsg = await consumer.receive();\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tconst structured: PulsarMessage<T> = {\n\t\t\t\t\t\ttopic: rawMsg.getTopicName(),\n\t\t\t\t\t\tmessageId: rawMsg.getMessageId().toString(),\n\t\t\t\t\t\tkey: rawMsg.getPartitionKey(),\n\t\t\t\t\t\tvalue: deserialize(rawMsg.getData()) as T,\n\t\t\t\t\t\tproperties: rawMsg.getProperties(),\n\t\t\t\t\t\tpublishTime: rawMsg.getPublishTimestamp(),\n\t\t\t\t\t\teventTime: rawMsg.getEventTimestamp(),\n\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t};\n\t\t\t\t\tif (autoAck) {\n\t\t\t\t\t\ta.emit(structured);\n\t\t\t\t\t\tvoid consumer.acknowledge(rawMsg).catch(reportAckError);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Manual ack — wrap in AckableMessage. Pulsar's SDK has no\n\t\t\t\t\t\t// per-message nack(requeue=false) — a plain `nack` re-delivers\n\t\t\t\t\t\t// after the subscription's negativeAckRedeliveryDelay. `requeue`\n\t\t\t\t\t\t// is honored as \"always redeliver\" (SDK default).\n\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\tconst envelope: AckableMessage<PulsarMessage<T>> = {\n\t\t\t\t\t\t\tvalue: structured,\n\t\t\t\t\t\t\tack() {\n\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\tvoid consumer.acknowledge(rawMsg).catch(reportAckError);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnack(_opts) {\n\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\tconst anyConsumer = consumer as unknown as {\n\t\t\t\t\t\t\t\t\tnegativeAcknowledge?: (m: unknown) => Promise<void> | void;\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst result = anyConsumer.negativeAcknowledge?.(rawMsg);\n\t\t\t\t\t\t\t\t\t// nack may return Promise (some SDKs) — route rejection.\n\t\t\t\t\t\t\t\t\tif (result && typeof (result as Promise<void>).then === \"function\") {\n\t\t\t\t\t\t\t\t\t\tvoid (result as Promise<void>).catch(reportAckError);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t\ta.emit(envelope);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tvoid loop();\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/** Options for {@link toPulsar}. */\nexport type ToPulsarOptions<T> = ExtraOpts & {\n\t/** Serialize value for Pulsar. Default: `JSON.stringify` → Buffer. */\n\tserialize?: (value: T) => Buffer;\n\t/** Extract partition key from value. Default: none. */\n\tkeyExtractor?: (value: T) => string | undefined;\n\t/** Extract properties from value. */\n\tpropertiesExtractor?: (value: T) => Record<string, string> | undefined;\n\t/** Called on serialization or send failures. */\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * Pulsar producer sink — forwards upstream `DATA` to a Pulsar topic.\n *\n * @param source - Upstream node to forward.\n * @param pulsarProducer - Pulsar producer instance (caller owns lifecycle).\n * @param opts - Serialization options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toPulsar<T>(\n\tsource: Node<T>,\n\tpulsarProducer: PulsarProducerLike,\n\topts?: ToPulsarOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tserialize = (v: T) => Buffer.from(JSON.stringify(v)),\n\t\tkeyExtractor,\n\t\tpropertiesExtractor,\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tsend: async (value) => {\n\t\t\tawait pulsarProducer.send({\n\t\t\t\tdata: serialize(value),\n\t\t\t\tpartitionKey: keyExtractor?.(value),\n\t\t\t\tproperties: propertiesExtractor?.(value),\n\t\t\t});\n\t\t},\n\t});\n}\n\n// ——— NATS ———\n\n/** Duck-typed NATS subscription (compatible with nats.js). */\nexport type NATSSubscriptionLike = AsyncIterable<{\n\tsubject: string;\n\tdata: Uint8Array;\n\theaders?: { get(key: string): string; keys(): string[] };\n\treply?: string;\n\tsid: number;\n}>;\n\n/** Duck-typed NATS client (compatible with nats.js). */\nexport type NATSClientLike = {\n\tsubscribe(subject: string, opts?: { queue?: string }): NATSSubscriptionLike;\n\tpublish(subject: string, data?: Uint8Array, opts?: { headers?: unknown; reply?: string }): void;\n\tdrain(): Promise<void>;\n};\n\n/** Structured NATS message. */\nexport type NATSMessage<T = unknown> = {\n\tsubject: string;\n\tdata: T;\n\theaders: Record<string, string>;\n\treply: string | undefined;\n\tsid: number;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromNATS}. */\nexport type FromNATSOptions = ExtraOpts & {\n\t/** Queue group name for load balancing. */\n\tqueue?: string;\n\t/** Deserialize message data. Default: `JSON.parse(textDecoder.decode(data))`. */\n\tdeserialize?: (data: Uint8Array) => unknown;\n};\n\n/**\n * NATS consumer as a reactive source.\n *\n * Wraps a `nats.js`-compatible client subscription. Each message becomes a `DATA` emission.\n *\n * @param client - NATS client instance (caller owns connect/drain lifecycle).\n * @param subject - Subject to subscribe to (supports wildcards).\n * @param opts - Queue group, deserialization, and source options.\n * @returns `Node<NATSMessage<T>>` — one `DATA` per NATS message.\n *\n * @remarks\n * Teardown sets an internal flag but cannot break the async iterator. The loop\n * exits on the next message or when the subscription is drained/unsubscribed\n * externally. Call `client.drain()` after unsubscribing for prompt cleanup.\n *\n * @example\n * ```ts\n * import { connect } from \"nats\";\n * import { fromNATS } from \"@graphrefly/graphrefly-ts\";\n *\n * const nc = await connect({ servers: \"localhost:4222\" });\n * const events$ = fromNATS(nc, \"events.>\");\n * ```\n *\n * @category extra\n */\nexport function fromNATS<T = unknown>(\n\tclient: NATSClientLike,\n\tsubject: string,\n\topts?: FromNATSOptions,\n): Node<NATSMessage<T>> {\n\tconst decoder = new TextDecoder();\n\tconst {\n\t\tqueue,\n\t\tdeserialize = (data: Uint8Array) => {\n\t\t\tconst text = decoder.decode(data);\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(text);\n\t\t\t} catch {\n\t\t\t\treturn text;\n\t\t\t}\n\t\t},\n\t\t...rest\n\t} = opts ?? {};\n\n\treturn producer<NATSMessage<T>>((a) => {\n\t\tlet active = true;\n\t\tconst sub = client.subscribe(subject, queue ? { queue } : undefined);\n\n\t\tconst loop = async () => {\n\t\t\ttry {\n\t\t\t\tfor await (const msg of sub) {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tconst headers: Record<string, string> = {};\n\t\t\t\t\tif (msg.headers) {\n\t\t\t\t\t\tfor (const k of msg.headers.keys()) {\n\t\t\t\t\t\t\theaders[k] = msg.headers.get(k);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ta.emit({\n\t\t\t\t\t\tsubject: msg.subject,\n\t\t\t\t\t\tdata: deserialize(msg.data) as T,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\treply: msg.reply,\n\t\t\t\t\t\tsid: msg.sid,\n\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// Subscription closed (drain or unsubscribe) — complete.\n\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\n\t\tvoid loop();\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/** Options for {@link toNATS}. */\nexport type ToNATSOptions<T> = ExtraOpts & {\n\t/** Serialize value for NATS. Default: `JSON.stringify` → Uint8Array. */\n\tserialize?: (value: T) => Uint8Array;\n\t/** Called on serialization failures. */\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * NATS publisher sink — forwards upstream `DATA` to a NATS subject.\n *\n * @param source - Upstream node to forward.\n * @param client - NATS client instance.\n * @param subject - Target subject.\n * @param opts - Serialization options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toNATS<T>(\n\tsource: Node<T>,\n\tclient: NATSClientLike,\n\tsubject: string,\n\topts?: ToNATSOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst encoder = new TextEncoder();\n\tconst { serialize = (v: T) => encoder.encode(JSON.stringify(v)), onTransportError } = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tsend: (value) => {\n\t\t\t// NATS publish is synchronous; wrap in a resolved Promise for the\n\t\t\t// reactiveSink transport boundary.\n\t\t\tclient.publish(subject, serialize(value));\n\t\t},\n\t});\n}\n\n// ——— RabbitMQ ———\n\n/** Duck-typed RabbitMQ channel (compatible with amqplib). */\nexport type RabbitMQChannelLike = {\n\tconsume(\n\t\tqueue: string,\n\t\tonMessage: (\n\t\t\tmsg: {\n\t\t\t\tcontent: Buffer;\n\t\t\t\tfields: {\n\t\t\t\t\troutingKey: string;\n\t\t\t\t\texchange: string;\n\t\t\t\t\tdeliveryTag: number;\n\t\t\t\t\tredelivered: boolean;\n\t\t\t\t};\n\t\t\t\tproperties: Record<string, unknown>;\n\t\t\t} | null,\n\t\t) => void,\n\t\topts?: { noAck?: boolean },\n\t): Promise<{ consumerTag: string }>;\n\tcancel(consumerTag: string): Promise<void>;\n\tack(msg: unknown): void;\n\tpublish(\n\t\texchange: string,\n\t\troutingKey: string,\n\t\tcontent: Buffer,\n\t\topts?: Record<string, unknown>,\n\t): boolean;\n\tsendToQueue(queue: string, content: Buffer, opts?: Record<string, unknown>): boolean;\n};\n\n/** Structured RabbitMQ message. */\nexport type RabbitMQMessage<T = unknown> = {\n\tqueue: string;\n\troutingKey: string;\n\texchange: string;\n\tcontent: T;\n\tproperties: Record<string, unknown>;\n\tdeliveryTag: number;\n\tredelivered: boolean;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromRabbitMQ}. */\nexport type FromRabbitMQOptions = ExtraOpts & {\n\t/** Deserialize message content. Default: `JSON.parse(buffer.toString())`. */\n\tdeserialize?: (content: Buffer) => unknown;\n\t/** Auto-acknowledge messages. Default: `true`. */\n\tautoAck?: boolean;\n\t/**\n\t * Routes envelope ack/nack transport failures (including \"SDK exposes no\n\t * `nack` method\") to the caller. Default: swallow.\n\t */\n\tonAckError?: (err: Error) => void;\n};\n\n/**\n * RabbitMQ consumer as a reactive source.\n *\n * Wraps an `amqplib`-compatible channel. Each message becomes a `DATA` emission.\n *\n * @param channel - AMQP channel instance (caller owns connection/channel lifecycle).\n * @param queue - Queue to consume from.\n * @param opts - Deserialization and acknowledgment options.\n * @returns `Node<RabbitMQMessage<T>>` — one `DATA` per RabbitMQ message.\n *\n * @remarks\n * When `autoAck` is `false`, the adapter opens the channel with `noAck: false`\n * (broker requires acks) but does not call `channel.ack()`. The caller must ack\n * messages externally using the `deliveryTag` from the emitted {@link RabbitMQMessage}:\n * ```ts\n * channel.ack({ fields: { deliveryTag: msg.deliveryTag } } as any);\n * ```\n *\n * @example\n * ```ts\n * import amqplib from \"amqplib\";\n * import { fromRabbitMQ } from \"@graphrefly/graphrefly-ts\";\n *\n * const conn = await amqplib.connect(\"amqp://localhost\");\n * const ch = await conn.createChannel();\n * await ch.assertQueue(\"events\");\n * const events$ = fromRabbitMQ(ch, \"events\");\n * ```\n *\n * @category extra\n */\nexport function fromRabbitMQ<T = unknown>(\n\tchannel: RabbitMQChannelLike,\n\tqueue: string,\n\topts?: FromRabbitMQOptions & { autoAck?: true },\n): Node<RabbitMQMessage<T>>;\nexport function fromRabbitMQ<T = unknown>(\n\tchannel: RabbitMQChannelLike,\n\tqueue: string,\n\topts: FromRabbitMQOptions & { autoAck: false },\n): Node<AckableMessage<RabbitMQMessage<T>>>;\nexport function fromRabbitMQ<T = unknown>(\n\tchannel: RabbitMQChannelLike,\n\tqueue: string,\n\topts?: FromRabbitMQOptions,\n): Node<RabbitMQMessage<T> | AckableMessage<RabbitMQMessage<T>>> {\n\tconst {\n\t\tautoAck = true,\n\t\tdeserialize = (buf: Buffer) => {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(buf.toString());\n\t\t\t} catch {\n\t\t\t\treturn buf.toString();\n\t\t\t}\n\t\t},\n\t\tonAckError,\n\t\t...rest\n\t} = opts ?? {};\n\n\tconst reportAckError = (err: unknown) => {\n\t\tif (!onAckError) return;\n\t\ttry {\n\t\t\tonAckError(err instanceof Error ? err : new Error(String(err)));\n\t\t} catch {\n\t\t\t/* user hook must not escape */\n\t\t}\n\t};\n\n\treturn producer<RabbitMQMessage<T> | AckableMessage<RabbitMQMessage<T>>>((a) => {\n\t\tlet active = true;\n\t\tlet consumerTag: string | undefined;\n\n\t\tconst start = async () => {\n\t\t\ttry {\n\t\t\t\tconst result = await channel.consume(\n\t\t\t\t\tqueue,\n\t\t\t\t\t(rawMsg) => {\n\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\tif (rawMsg === null) {\n\t\t\t\t\t\t\t// Broker cancelled the consumer (queue deleted, etc.).\n\t\t\t\t\t\t\tif (active) a.down([[ERROR, new Error(\"Consumer cancelled by broker\")]]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst structured: RabbitMQMessage<T> = {\n\t\t\t\t\t\t\tqueue,\n\t\t\t\t\t\t\troutingKey: rawMsg.fields.routingKey,\n\t\t\t\t\t\t\texchange: rawMsg.fields.exchange,\n\t\t\t\t\t\t\tcontent: deserialize(rawMsg.content) as T,\n\t\t\t\t\t\t\tproperties: rawMsg.properties,\n\t\t\t\t\t\t\tdeliveryTag: rawMsg.fields.deliveryTag,\n\t\t\t\t\t\t\tredelivered: rawMsg.fields.redelivered,\n\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (autoAck) {\n\t\t\t\t\t\t\ta.emit(structured);\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tchannel.ack(rawMsg);\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\tconst channelWithNack = channel as unknown as {\n\t\t\t\t\t\t\t\tnack?: (msg: unknown, allUpTo?: boolean, requeue?: boolean) => void;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tconst envelope: AckableMessage<RabbitMQMessage<T>> = {\n\t\t\t\t\t\t\t\tvalue: structured,\n\t\t\t\t\t\t\t\tack() {\n\t\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tchannel.ack(rawMsg);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnack(nackOpts) {\n\t\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\t// `requeue` passes through to SDK — `undefined` lets the\n\t\t\t\t\t\t\t\t\t// SDK apply its own default (amqplib: true). Explicit\n\t\t\t\t\t\t\t\t\t// `false` routes to DLX if configured.\n\t\t\t\t\t\t\t\t\tconst requeue = nackOpts?.requeue;\n\t\t\t\t\t\t\t\t\tif (!channelWithNack.nack) {\n\t\t\t\t\t\t\t\t\t\treportAckError(\n\t\t\t\t\t\t\t\t\t\t\tnew Error(\"RabbitMQ channel does not expose `nack`; cannot negative-ack\"),\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tchannelWithNack.nack(rawMsg, false, requeue);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\ta.emit(envelope);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{ noAck: false },\n\t\t\t\t);\n\t\t\t\tconsumerTag = result.consumerTag;\n\t\t\t} catch (err) {\n\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\n\t\tvoid start();\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\tif (consumerTag !== undefined) {\n\t\t\t\tvoid channel.cancel(consumerTag);\n\t\t\t}\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/** Options for {@link toRabbitMQ}. */\nexport type ToRabbitMQOptions<T> = ExtraOpts & {\n\t/** Serialize value for RabbitMQ. Default: `Buffer.from(JSON.stringify(value))`. */\n\tserialize?: (value: T) => Buffer;\n\t/** Extract routing key from value. Default: `\"\"`. */\n\troutingKeyExtractor?: (value: T) => string;\n\t/** Called on serialization or send failures. */\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * RabbitMQ producer sink — forwards upstream `DATA` to a RabbitMQ exchange/queue.\n *\n * @param source - Upstream node to forward.\n * @param channel - AMQP channel instance.\n * @param exchange - Target exchange (use `\"\"` for default exchange + queue routing).\n * @param opts - Serialization and routing options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toRabbitMQ<T>(\n\tsource: Node<T>,\n\tchannel: RabbitMQChannelLike,\n\texchange: string,\n\topts?: ToRabbitMQOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tserialize = (v: T) => Buffer.from(JSON.stringify(v)),\n\t\troutingKeyExtractor = () => \"\",\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tsend: (value) => {\n\t\t\tconst routingKey = routingKeyExtractor(value);\n\t\t\tconst content = serialize(value);\n\t\t\tchannel.publish(exchange, routingKey, content);\n\t\t},\n\t});\n}\n\n// ——————————————————————————————————————————————————————————————\n// Phase 5.2d — Storage & sink adapters\n// ——————————————————————————————————————————————————————————————\n\n/** Handle returned by buffered sinks. `flush()` drains remaining buffer. */\nexport type BufferedSinkHandle = SinkHandle & {\n\t/** Manually drain the internal buffer. */\n\tflush: () => Promise<void>;\n};\n\n// ——— toFile ———\n\n/** Duck-typed writable file handle (compatible with `fs.createWriteStream`). */\nexport type FileWriterLike = {\n\twrite(data: string | Uint8Array): boolean | undefined;\n\tend(): void;\n};\n\n/** Options for {@link toFile}. */\nexport type ToFileOptions<T> = ExtraOpts & {\n\t/** Serialize a value to a string line. Default: `JSON.stringify(v) + \"\\n\"`. */\n\tserialize?: (value: T) => string;\n\t/** `\"append\"` (default) or `\"overwrite\"` — controls initial file behavior hint. */\n\tmode?: \"append\" | \"overwrite\";\n\t/** Flush interval in ms. `0` = write-through (no buffering). Default: `0`. */\n\tflushIntervalMs?: number;\n\t/** Buffer size (item count) before auto-flush. Default: `Infinity` (timer only). */\n\tbatchSize?: number;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * File sink — writes upstream `DATA` values to a file-like writable.\n *\n * When `flushIntervalMs > 0` or `batchSize` is set, values are buffered and\n * flushed in batches. Otherwise, each value is written immediately.\n *\n * @param source - Upstream node.\n * @param writer - Writable file handle (e.g. `fs.createWriteStream(path, { flags: \"a\" })`).\n * @param opts - Serialization, buffering, and mode options.\n * @returns `BufferedSinkHandle` with `dispose()` and `flush()`.\n *\n * @category extra\n */\nexport function toFile<T>(\n\tsource: Node<T>,\n\twriter: FileWriterLike,\n\topts?: ToFileOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tserialize = (v: T) => `${JSON.stringify(v)}\\n`,\n\t\tflushIntervalMs = 0,\n\t\tbatchSize = Number.POSITIVE_INFINITY,\n\t\tonTransportError,\n\t\tmode: _mode,\n\t} = opts ?? {};\n\n\tconst buffered = flushIntervalMs > 0 || batchSize < Number.POSITIVE_INFINITY;\n\t// Pass `serialize` via reactiveSink's config so sync throws are classified as\n\t// `stage:\"serialize\"` rather than `stage:\"send\"`. Inside send/sendBatch the\n\t// payload is already a string (serialize output).\n\tconst handle: ReactiveSinkHandle<T> = buffered\n\t\t? reactiveSink<T>(source, {\n\t\t\t\tonTransportError,\n\t\t\t\tbatchSize,\n\t\t\t\tflushIntervalMs,\n\t\t\t\tserialize,\n\t\t\t\tsendBatch: (chunk) => {\n\t\t\t\t\twriter.write((chunk as unknown as string[]).join(\"\"));\n\t\t\t\t},\n\t\t\t})\n\t\t: reactiveSink<T>(source, {\n\t\t\t\tonTransportError,\n\t\t\t\tserialize,\n\t\t\t\tsend: (line) => {\n\t\t\t\t\twriter.write(line as unknown as string);\n\t\t\t\t},\n\t\t\t});\n\n\tconst originalDispose = handle.dispose;\n\thandle.dispose = () => {\n\t\toriginalDispose();\n\t\ttry {\n\t\t\twriter.end();\n\t\t} catch {\n\t\t\t/* writer may already be closed */\n\t\t}\n\t};\n\treturn handle;\n}\n\n// ——— toCSV ———\n\n/** Options for {@link toCSV}. */\nexport type ToCSVOptions<T> = ExtraOpts & {\n\t/** Column names. Required — determines header row and field order. */\n\tcolumns: string[];\n\t/** Column delimiter. Default: `\",\"`. */\n\tdelimiter?: string;\n\t/** Whether to write a header row on first flush. Default: `true`. */\n\twriteHeader?: boolean;\n\t/** Extract a cell value from the row object. Default: `String(row[col] ?? \"\")`. */\n\tcellExtractor?: (row: T, column: string) => string;\n\t/** Flush interval in ms. Default: `0` (write-through). */\n\tflushIntervalMs?: number;\n\t/** Buffer size before auto-flush. Default: `Infinity`. */\n\tbatchSize?: number;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\nfunction escapeCSVField(value: string, delimiter: string): string {\n\tif (value.includes(delimiter) || value.includes('\"') || value.includes(\"\\n\")) {\n\t\treturn `\"${value.replace(/\"/g, '\"\"')}\"`;\n\t}\n\treturn value;\n}\n\n/**\n * CSV file sink — writes upstream `DATA` as CSV rows.\n *\n * @param source - Upstream node.\n * @param writer - Writable file handle.\n * @param opts - Column definition, delimiter, and buffering options.\n * @returns `BufferedSinkHandle`.\n *\n * @category extra\n */\nexport function toCSV<T>(\n\tsource: Node<T>,\n\twriter: FileWriterLike,\n\topts: ToCSVOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tcolumns,\n\t\tdelimiter = \",\",\n\t\twriteHeader = true,\n\t\tcellExtractor = (row: T, col: string) => String((row as Record<string, unknown>)[col] ?? \"\"),\n\t\tflushIntervalMs = 0,\n\t\tbatchSize = Number.POSITIVE_INFINITY,\n\t\tonTransportError,\n\t\t...rest\n\t} = opts;\n\n\tlet headerWritten = false;\n\n\tconst serializeRow = (row: T): string => {\n\t\tif (!headerWritten && writeHeader) {\n\t\t\theaderWritten = true;\n\t\t\tconst header = columns.map((c) => escapeCSVField(c, delimiter)).join(delimiter);\n\t\t\tconst data = columns\n\t\t\t\t.map((c) => escapeCSVField(cellExtractor(row, c), delimiter))\n\t\t\t\t.join(delimiter);\n\t\t\treturn `${header}\\n${data}\\n`;\n\t\t}\n\t\treturn `${columns.map((c) => escapeCSVField(cellExtractor(row, c), delimiter)).join(delimiter)}\\n`;\n\t};\n\n\treturn toFile<T>(source, writer, {\n\t\tserialize: serializeRow,\n\t\tflushIntervalMs,\n\t\tbatchSize,\n\t\tonTransportError,\n\t\t...rest,\n\t});\n}\n\n// ——— toClickHouse ———\n\n/** Duck-typed ClickHouse client for batch inserts. */\nexport type ClickHouseInsertClientLike = {\n\tinsert(params: { table: string; values: unknown[]; format?: string }): Promise<void>;\n};\n\n/** Options for {@link toClickHouse}. */\nexport type ToClickHouseOptions<T> = ExtraOpts & {\n\t/** Batch size before auto-flush. Default: `1000`. */\n\tbatchSize?: number;\n\t/** Flush interval in ms. Default: `5000`. */\n\tflushIntervalMs?: number;\n\t/** Insert format. Default: `\"JSONEachRow\"`. */\n\tformat?: string;\n\t/** Transform value before insert. Default: identity. */\n\ttransform?: (value: T) => unknown;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * ClickHouse buffered batch insert sink.\n *\n * Accumulates upstream `DATA` values and inserts in batches.\n *\n * @param source - Upstream node.\n * @param client - ClickHouse client with `insert()`.\n * @param table - Target table name.\n * @param opts - Batch size, flush interval, and transform options.\n * @returns `BufferedSinkHandle`.\n *\n * @category extra\n */\nexport function toClickHouse<T>(\n\tsource: Node<T>,\n\tclient: ClickHouseInsertClientLike,\n\ttable: string,\n\topts?: ToClickHouseOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tbatchSize = 1000,\n\t\tflushIntervalMs = 5000,\n\t\tformat = \"JSONEachRow\",\n\t\ttransform = (v: T) => v,\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tbatchSize,\n\t\tflushIntervalMs,\n\t\tserialize: transform,\n\t\tsendBatch: async (batch) => {\n\t\t\tawait client.insert({ table, values: batch, format });\n\t\t},\n\t});\n}\n\n// ——— toS3 ———\n\n/** Duck-typed S3 client (compatible with AWS SDK v3 `S3Client.send(PutObjectCommand(...))`). */\nexport type S3ClientLike = {\n\tputObject(params: {\n\t\tBucket: string;\n\t\tKey: string;\n\t\tBody: string | Uint8Array;\n\t\tContentType?: string;\n\t}): Promise<unknown>;\n};\n\n/** Options for {@link toS3}. */\nexport type ToS3Options<T> = ExtraOpts & {\n\t/** Output format. Default: `\"ndjson\"`. */\n\tformat?: \"ndjson\" | \"json\";\n\t/** Generate the S3 key for each batch. Receives `(seq, wallClockNs)`. Default: ISO timestamp + sequence. */\n\tkeyGenerator?: (seq: number, timestampNs: number) => string;\n\t/** Batch size before auto-flush. Default: `1000`. */\n\tbatchSize?: number;\n\t/** Flush interval in ms. Default: `10000`. */\n\tflushIntervalMs?: number;\n\t/** Transform value before serialization. Default: identity. */\n\ttransform?: (value: T) => unknown;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * S3 object storage sink — buffers values and uploads as NDJSON or JSON objects.\n *\n * @param source - Upstream node.\n * @param client - S3-compatible client with `putObject()`.\n * @param bucket - S3 bucket name.\n * @param opts - Format, key generation, batching options.\n * @returns `BufferedSinkHandle`.\n *\n * @category extra\n */\nexport function toS3<T>(\n\tsource: Node<T>,\n\tclient: S3ClientLike,\n\tbucket: string,\n\topts?: ToS3Options<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tformat = \"ndjson\",\n\t\tkeyGenerator = (seq: number, timestampNs: number) => {\n\t\t\tconst ms = Math.floor(timestampNs / 1_000_000);\n\t\t\tconst ts = new Date(ms).toISOString().replace(/[:.]/g, \"-\");\n\t\t\treturn `data/${ts}-${seq}.${format === \"ndjson\" ? \"ndjson\" : \"json\"}`;\n\t\t},\n\t\tbatchSize = 1000,\n\t\tflushIntervalMs = 10000,\n\t\ttransform = (v: T) => v,\n\t\tonTransportError,\n\t} = opts ?? {};\n\n\tconst contentType = format === \"ndjson\" ? \"application/x-ndjson\" : \"application/json\";\n\tlet seq = 0;\n\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tbatchSize,\n\t\tflushIntervalMs,\n\t\tserialize: transform,\n\t\tsendBatch: async (batch) => {\n\t\t\tseq += 1;\n\t\t\tconst body =\n\t\t\t\tformat === \"ndjson\"\n\t\t\t\t\t? `${batch.map((v) => JSON.stringify(v)).join(\"\\n\")}\\n`\n\t\t\t\t\t: JSON.stringify(batch);\n\t\t\tconst key = keyGenerator(seq, wallClockNs());\n\t\t\tawait client.putObject({ Bucket: bucket, Key: key, Body: body, ContentType: contentType });\n\t\t},\n\t});\n}\n\n// ——— toPostgres ———\n\n/** Duck-typed Postgres client (compatible with `pg.Client` / `pg.Pool`). */\nexport type PostgresClientLike = {\n\tquery(sql: string, params?: unknown[]): Promise<unknown>;\n};\n\n/** Options for {@link toPostgres}. */\nexport type ToPostgresOptions<T> = ExtraOpts & {\n\t/** Build the SQL + params for an insert. Default: JSON insert into `table`. */\n\ttoSQL?: (value: T, table: string) => { sql: string; params: unknown[] };\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * PostgreSQL sink — inserts each upstream `DATA` value as a row.\n *\n * @param source - Upstream node.\n * @param client - Postgres client with `query()`.\n * @param table - Target table name.\n * @param opts - SQL builder and error options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toPostgres<T>(\n\tsource: Node<T>,\n\tclient: PostgresClientLike,\n\ttable: string,\n\topts?: ToPostgresOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\ttoSQL = (v: T, t: string) => ({\n\t\t\tsql: `INSERT INTO \"${t.replace(/\"/g, '\"\"')}\" (data) VALUES ($1)`,\n\t\t\tparams: [JSON.stringify(v)],\n\t\t}),\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tserialize: (value) => toSQL(value, table),\n\t\tsend: async (q) => {\n\t\t\tconst query = q as unknown as { sql: string; params: unknown[] };\n\t\t\tawait client.query(query.sql, query.params);\n\t\t},\n\t});\n}\n\n// ——— toMongo ———\n\n/** Duck-typed MongoDB collection (compatible with `mongodb` driver). */\nexport type MongoCollectionLike = {\n\tinsertOne(doc: unknown): Promise<unknown>;\n};\n\n/** Options for {@link toMongo}. */\nexport type ToMongoOptions<T> = ExtraOpts & {\n\t/** Transform value to a MongoDB document. Default: identity. */\n\ttoDocument?: (value: T) => unknown;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * MongoDB sink — inserts each upstream `DATA` value as a document.\n *\n * @param source - Upstream node.\n * @param collection - MongoDB collection with `insertOne()`.\n * @param opts - Document transform and error options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toMongo<T>(\n\tsource: Node<T>,\n\tcollection: MongoCollectionLike,\n\topts?: ToMongoOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst { toDocument = (v: T) => v, onTransportError } = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tserialize: toDocument,\n\t\tsend: async (doc) => {\n\t\t\tawait collection.insertOne(doc);\n\t\t},\n\t});\n}\n\n// ——— toLoki ———\n\n/** Loki log stream entry. */\nexport type LokiStream = {\n\tstream: Record<string, string>;\n\tvalues: [string, string][];\n};\n\n/** Duck-typed Loki push client (HTTP push API). */\nexport type LokiClientLike = {\n\tpush(streams: { streams: LokiStream[] }): Promise<unknown>;\n};\n\n/** Options for {@link toLoki}. */\nexport type ToLokiOptions<T> = ExtraOpts & {\n\t/** Static labels applied to every log entry. */\n\tlabels?: Record<string, string>;\n\t/** Extract the log line from a value. Default: `JSON.stringify(v)`. */\n\ttoLine?: (value: T) => string;\n\t/** Extract additional labels from a value. Default: none. */\n\ttoLabels?: (value: T) => Record<string, string>;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * Grafana Loki sink — pushes upstream `DATA` values as log entries.\n *\n * @param source - Upstream node.\n * @param client - Loki-compatible client with `push()`.\n * @param opts - Label, serialization, and error options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toLoki<T>(\n\tsource: Node<T>,\n\tclient: LokiClientLike,\n\topts?: ToLokiOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tlabels = {},\n\t\ttoLine = (v: T) => JSON.stringify(v),\n\t\ttoLabels,\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tserialize: (value) => ({\n\t\t\tline: toLine(value),\n\t\t\tlabels: toLabels ? { ...labels, ...toLabels(value) } : labels,\n\t\t}),\n\t\tsend: async (payload) => {\n\t\t\tconst { line, labels: streamLabels } = payload as {\n\t\t\t\tline: string;\n\t\t\t\tlabels: Record<string, string>;\n\t\t\t};\n\t\t\tconst ts = `${wallClockNs()}`;\n\t\t\tawait client.push({ streams: [{ stream: streamLabels, values: [[ts, line]] }] });\n\t\t},\n\t});\n}\n\n// ——— toTempo ———\n\n/** Duck-typed Tempo span push client (OTLP/HTTP shape). */\nexport type TempoClientLike = {\n\tpush(payload: { resourceSpans: unknown[] }): Promise<unknown>;\n};\n\n/** Options for {@link toTempo}. */\nexport type ToTempoOptions<T> = ExtraOpts & {\n\t/** Transform a value into OTLP resourceSpans entries. */\n\ttoResourceSpans?: (value: T) => unknown[];\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * Grafana Tempo sink — pushes upstream `DATA` values as trace spans.\n *\n * @param source - Upstream node.\n * @param client - Tempo-compatible client with `push()`.\n * @param opts - Span transform and error options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toTempo<T>(\n\tsource: Node<T>,\n\tclient: TempoClientLike,\n\topts?: ToTempoOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst { toResourceSpans = (v: T) => [v], onTransportError } = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tserialize: toResourceSpans,\n\t\tsend: async (spans) => {\n\t\t\tawait client.push({ resourceSpans: spans as unknown[] });\n\t\t},\n\t});\n}\n\n// ——— checkpointToS3 ———\n\n/** Options for {@link checkpointToS3}. */\nexport type CheckpointToS3Options = {\n\t/** S3 key prefix. Default: `\"checkpoints/\"`. */\n\tprefix?: string;\n\t/** Debounce ms on the S3 tier. Default: `500`. */\n\tdebounceMs?: number;\n\t/** Full snapshot compaction interval. Default: `10`. */\n\tcompactEvery?: number;\n\tonError?: (error: unknown) => void;\n};\n\ntype StorageTierLike = {\n\tload(key: string): unknown | Promise<unknown>;\n\tsave(key: string, data: unknown): void | Promise<void>;\n\tclear?(key: string): void | Promise<void>;\n\tdebounceMs?: number;\n\tcompactEvery?: number;\n};\n\ntype AttachStorageGraphLike = {\n\tattachStorage: (tiers: readonly StorageTierLike[], opts?: unknown) => { dispose(): void };\n\tname: string;\n};\n\n/**\n * Wires `graph.attachStorage()` with an S3-backed tier.\n *\n * @param graph - Graph instance to checkpoint.\n * @param client - S3-compatible client with `putObject()`.\n * @param bucket - S3 bucket name.\n * @param opts - Key prefix, debounce, and compaction options.\n * @returns Dispose handle.\n *\n * @category extra\n */\nexport function checkpointToS3(\n\tgraph: AttachStorageGraphLike,\n\tclient: S3ClientLike,\n\tbucket: string,\n\topts?: CheckpointToS3Options,\n): { dispose(): void } {\n\tconst { prefix = \"checkpoints/\", debounceMs = 500, compactEvery = 10, onError } = opts ?? {};\n\tconst tier: StorageTierLike = {\n\t\tdebounceMs,\n\t\tcompactEvery,\n\t\tsave(_key, data) {\n\t\t\tconst ms = Math.floor(wallClockNs() / 1_000_000);\n\t\t\tconst s3Key = `${prefix}${graph.name}/checkpoint-${ms}.json`;\n\t\t\tlet body: string;\n\t\t\ttry {\n\t\t\t\tbody = JSON.stringify(data);\n\t\t\t} catch (err) {\n\t\t\t\tonError?.(err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvoid client\n\t\t\t\t.putObject({\n\t\t\t\t\tBucket: bucket,\n\t\t\t\t\tKey: s3Key,\n\t\t\t\t\tBody: body,\n\t\t\t\t\tContentType: \"application/json\",\n\t\t\t\t})\n\t\t\t\t.catch((err) => onError?.(err));\n\t\t},\n\t\tload() {\n\t\t\t// S3 tier is write-only here — one object per checkpoint timestamp,\n\t\t\t// no canonical \"latest\" key for load.\n\t\t\treturn null;\n\t\t},\n\t};\n\treturn graph.attachStorage([tier], { onError: (err: unknown) => onError?.(err) });\n}\n\n// ——— checkpointToRedis ———\n\n/** Duck-typed Redis client for checkpoint storage. */\nexport type RedisCheckpointClientLike = {\n\tset(key: string, value: string): Promise<unknown>;\n\tget(key: string): Promise<string | null>;\n};\n\n/** Options for {@link checkpointToRedis}. */\nexport type CheckpointToRedisOptions = {\n\t/** Key prefix. Default: `\"graphrefly:checkpoint:\"`. */\n\tprefix?: string;\n\t/** Debounce ms on the Redis tier. Default: `500`. */\n\tdebounceMs?: number;\n\t/** Full snapshot compaction interval. Default: `10`. */\n\tcompactEvery?: number;\n\tonError?: (error: unknown) => void;\n};\n\n/**\n * Wires `graph.attachStorage()` with a Redis-backed tier.\n *\n * @param graph - Graph instance to checkpoint.\n * @param client - Redis client with `set()`/`get()`.\n * @param opts - Key prefix, debounce, and compaction options.\n * @returns Dispose handle.\n *\n * @category extra\n */\nexport function checkpointToRedis(\n\tgraph: AttachStorageGraphLike,\n\tclient: RedisCheckpointClientLike,\n\topts?: CheckpointToRedisOptions,\n): { dispose(): void } {\n\tconst {\n\t\tprefix = \"graphrefly:checkpoint:\",\n\t\tdebounceMs = 500,\n\t\tcompactEvery = 10,\n\t\tonError,\n\t} = opts ?? {};\n\tconst redisKey = `${prefix}${graph.name}`;\n\tconst tier: StorageTierLike = {\n\t\tdebounceMs,\n\t\tcompactEvery,\n\t\tsave(_key, data) {\n\t\t\tlet body: string;\n\t\t\ttry {\n\t\t\t\tbody = JSON.stringify(data);\n\t\t\t} catch (err) {\n\t\t\t\tonError?.(err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvoid client.set(redisKey, body).catch((err) => onError?.(err));\n\t\t},\n\t\tasync load() {\n\t\t\tconst raw = await client.get(redisKey);\n\t\t\tif (raw == null) return null;\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(raw) as unknown;\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t};\n\treturn graph.attachStorage([tier], { onError: (err: unknown) => onError?.(err) });\n}\n\n// ——————————————————————————————————————————————————————————————\n// SQLite adapters (roadmap §5.2b)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Duck-typed synchronous SQLite database.\n *\n * Compatible with `better-sqlite3` (`.prepare().all()` / `.prepare().run()`)\n * and Node.js `node:sqlite` `DatabaseSync`. The user wraps their driver behind\n * this uniform contract — method name `query` matches the project-wide\n * convention (`PostgresClientLike.query`, `ClickHouseClientLike.query`).\n */\nexport type SqliteDbLike = {\n\tquery(sql: string, params?: unknown[]): unknown[];\n};\n\n/** Options for {@link fromSqlite}. */\nexport type FromSqliteOptions<T> = ExtraOpts & {\n\t/** Map a raw row object to the desired type. Default: identity cast. */\n\tmapRow?: (row: unknown) => T;\n\t/** Bind parameters for the query. */\n\tparams?: unknown[];\n};\n\n/**\n * One-shot SQLite query as a reactive source.\n *\n * Executes `query` synchronously via `db.query()`, emits **one `DATA` containing\n * the full result array**, then `COMPLETE`. Downstream flattens with\n * `mergeAll` / a custom operator if per-row semantics are required — the\n * array shape is the simpler default and matches how every SQL driver returns\n * results natively. Use {@link fromSqliteCursor} for streaming row-by-row.\n *\n * @param db - SQLite database (caller owns connection).\n * @param query - SQL string to execute.\n * @param opts - Row mapper, params, and node options.\n * @returns `Node<T[]>` — one `DATA` with the full row array, then `COMPLETE`.\n *\n * @example\n * ```ts\n * import Database from \"better-sqlite3\";\n * import { fromSqlite } from \"@graphrefly/graphrefly-ts\";\n *\n * const raw = new Database(\"app.db\");\n * const db = { query: (sql, params) => raw.prepare(sql).all(...(params ?? [])) };\n * const rows$ = fromSqlite(db, \"SELECT * FROM users WHERE active = ?\", { params: [1] });\n * ```\n *\n * @category extra\n */\nexport function fromSqlite<T = unknown>(\n\tdb: SqliteDbLike,\n\tquery: string,\n\topts?: FromSqliteOptions<T>,\n): Node<T[]> {\n\tconst { mapRow = (r: unknown) => r as T, params, ...rest } = opts ?? {};\n\n\treturn producer<T[]>(\n\t\t(a) => {\n\t\t\ttry {\n\t\t\t\tconst rows = db.query(query, params);\n\t\t\t\tconst mapped = rows.map(mapRow);\n\t\t\t\ta.emit(mapped);\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\ta.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t\t{ describeKind: \"producer\", completeWhenDepsComplete: false, ...rest } as NodeOptions<T[]>,\n\t);\n}\n\n/**\n * Duck-typed iterable-capable SQLite database — `iterate(sql, params)` returns\n * a synchronous iterator over rows, avoiding the \"all-rows-in-memory\" cost of\n * `db.query`. Compatible with `better-sqlite3`'s `.prepare().iterate()`.\n *\n * @category extra\n */\nexport type SqliteIterableDbLike = {\n\titerate(sql: string, params?: unknown[]): Iterable<unknown>;\n};\n\n/**\n * Cursor-streaming SQLite query — emits one `DATA` per row from a synchronous\n * row iterator, then `COMPLETE`. Use when result sets are too large to\n * materialize fully into an array.\n *\n * @category extra\n */\nexport function fromSqliteCursor<T = unknown>(\n\tdb: SqliteIterableDbLike,\n\tquery: string,\n\topts?: FromSqliteOptions<T>,\n): Node<T> {\n\tconst { mapRow = (r: unknown) => r as T, params, ...rest } = opts ?? {};\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\ttry {\n\t\t\t\tconst it = db.iterate(query, params);\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfor (const row of it) a.emit(mapRow(row));\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\ta.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t\t{ describeKind: \"producer\", completeWhenDepsComplete: false, ...rest } as NodeOptions<T>,\n\t);\n}\n\n/** Options for {@link toSqlite}. */\nexport type ToSqliteOptions<T> = ExtraOpts & {\n\t/** Build SQL + params for an insert. Default: JSON insert into `(data)` column. */\n\ttoSQL?: (value: T, table: string) => { sql: string; params: unknown[] };\n\tonTransportError?: (err: SinkTransportError) => void;\n\t/**\n\t * When `true`, buffer DATA values and execute all inserts inside a single\n\t * `BEGIN`/`COMMIT` transaction when the batch drains. This avoids per-row\n\t * fsync overhead and dramatically reduces event-loop blocking for\n\t * high-throughput sources. The first insert error stops the batch and\n\t * triggers a `ROLLBACK`; the error is reported via `onTransportError`.\n\t */\n\tbatchInsert?: boolean;\n\t/** Auto-flush when buffer reaches this size. Default: `1000`. Only applies when `batchInsert` is `true`. */\n\tmaxBatchSize?: number;\n\t/** Periodic flush interval in ms. `0` = no timer (flush on terminal messages only). Default: `0`. Only applies when `batchInsert` is `true`. */\n\tflushIntervalMs?: number;\n};\n\n/**\n * SQLite sink — inserts each upstream `DATA` value as a row.\n *\n * Follows the same pattern as {@link toPostgres} / {@link toMongo}. Since SQLite\n * is synchronous, errors propagate immediately (no `void promise.catch`).\n *\n * @param source - Upstream node.\n * @param db - SQLite database (caller owns connection).\n * @param table - Target table name.\n * @param opts - SQL builder and error options.\n * @returns Unsubscribe function.\n *\n * @example\n * ```ts\n * import Database from \"better-sqlite3\";\n * import { toSqlite, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const raw = new Database(\"app.db\");\n * const db = { query: (sql, params) => (raw.prepare(sql).run(...(params ?? [])), []) };\n * const source = state({ name: \"Alice\", score: 42 });\n * const unsub = toSqlite(source, db, \"events\");\n * ```\n *\n * @category extra\n */\nexport function toSqlite<T>(\n\tsource: Node<T>,\n\tdb: SqliteDbLike,\n\ttable: string,\n\topts?: ToSqliteOptions<T>,\n): ReactiveSinkHandle<T> {\n\tif (table.includes(\"\\0\") || table.length === 0) {\n\t\tthrow new Error(`toSqlite: invalid table name: ${JSON.stringify(table)}`);\n\t}\n\tconst {\n\t\ttoSQL = (v: T, t: string) => ({\n\t\t\tsql: `INSERT INTO \"${t.replace(/\"/g, '\"\"')}\" (data) VALUES (?)`,\n\t\t\tparams: [JSON.stringify(v)],\n\t\t}),\n\t\tonTransportError,\n\t\tbatchInsert = false,\n\t\tmaxBatchSize = 1000,\n\t\tflushIntervalMs = 0,\n\t} = opts ?? {};\n\n\tconst serialize = (value: T) => toSQL(value, table);\n\ttype Query = { sql: string; params: unknown[] };\n\n\tif (!batchInsert) {\n\t\treturn reactiveSink<T>(source, {\n\t\t\tonTransportError,\n\t\t\tserialize,\n\t\t\tsend: (q) => {\n\t\t\t\tconst query = q as Query;\n\t\t\t\tdb.query(query.sql, query.params);\n\t\t\t},\n\t\t});\n\t}\n\n\t// Batched mode — transactional: BEGIN → inserts → COMMIT (or ROLLBACK on\n\t// first insert error). Must preserve pending queries when BEGIN itself\n\t// fails (e.g. \"database is locked\") so a subsequent `flush()` can retry\n\t// with the same data intact. The generic `reactiveSink` clears its buffer\n\t// before invoking `sendBatch`, so we keep a bespoke transactional loop on\n\t// top of the reactiveSink skeleton: custom `flush()` + local pending\n\t// queue with re-queue semantics on BEGIN failure.\n\tconst errorsNode = state<SinkTransportError | null>(null);\n\tconst sentNode = state<T | undefined>(undefined, { equals: () => false }) as unknown as Node<T>;\n\tconst failedNode = state<SinkFailure<T> | null>(null);\n\tconst inFlightNode = state(0);\n\tconst bufferedNode = state(0);\n\n\tconst reportError = (err: SinkTransportError) => {\n\t\ttry {\n\t\t\tonTransportError?.(err);\n\t\t} catch {\n\t\t\t/* user hook must not escape */\n\t\t}\n\t\ttry {\n\t\t\terrorsNode.down([[DATA, err]]);\n\t\t} catch {\n\t\t\t/* drain re-entrance */\n\t\t}\n\t};\n\n\ttype PendingEntry = { value: T; query: Query };\n\tlet pending: PendingEntry[] = [];\n\tlet flushing = false;\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet disposed = false;\n\n\tconst updateBuffered = () => bufferedNode.down([[DATA, pending.length]]);\n\n\t// Guarded emit helpers — drop post-TEARDOWN writes silently (spec §1.3.4\n\t// terminal filter already blocks them downstream; this skips the\n\t// allocation). Prevents \"emit after TEARDOWN\" observable in subscribers\n\t// that race with in-flight flushes.\n\tconst safeEmitSent = (v: T) => {\n\t\tif (disposed) return;\n\t\tsentNode.down([[DATA, v]]);\n\t};\n\tconst safeEmitFailed = (f: SinkFailure<T>) => {\n\t\tif (disposed) return;\n\t\tfailedNode.down([[DATA, f]]);\n\t};\n\tconst safeSetInFlight = (n: number) => {\n\t\tif (disposed) return;\n\t\tinFlightNode.down([[DATA, n]]);\n\t};\n\tconst safeReportError = (err: SinkTransportError) => {\n\t\tif (disposed) return;\n\t\treportError(err);\n\t};\n\n\tconst flushTransaction = () => {\n\t\tif (pending.length === 0 || flushing) return;\n\t\tflushing = true;\n\t\tsafeSetInFlight(1);\n\t\ttry {\n\t\t\tdb.query(\"BEGIN\", []);\n\t\t} catch (err) {\n\t\t\t// BEGIN failed — keep `pending` intact so a later flush can retry.\n\t\t\tflushing = false;\n\t\t\tsafeSetInFlight(0);\n\t\t\tsafeReportError({\n\t\t\t\tstage: \"send\",\n\t\t\t\terror: err instanceof Error ? err : new Error(String(err)),\n\t\t\t\tvalue: undefined,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst chunk = pending;\n\t\tpending = [];\n\t\tupdateBuffered();\n\n\t\tlet firstError: Error | undefined;\n\t\tlet committedCount = 0;\n\t\tfor (const entry of chunk) {\n\t\t\ttry {\n\t\t\t\tdb.query(entry.query.sql, entry.query.params);\n\t\t\t\tcommittedCount += 1;\n\t\t\t} catch (err) {\n\t\t\t\tfirstError = err instanceof Error ? err : new Error(String(err));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (firstError) {\n\t\t\ttry {\n\t\t\t\tdb.query(\"ROLLBACK\", []);\n\t\t\t} catch {\n\t\t\t\t/* ROLLBACK failure — firstError already captured */\n\t\t\t}\n\t\t\tsafeReportError({ stage: \"send\", error: firstError, value: undefined });\n\t\t\tfor (const entry of chunk) {\n\t\t\t\tsafeEmitFailed({ value: entry.value, error: firstError, attempts: 1 });\n\t\t\t}\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tdb.query(\"COMMIT\", []);\n\t\t\t\tfor (const entry of chunk) safeEmitSent(entry.value);\n\t\t\t} catch (err) {\n\t\t\t\tconst error = err instanceof Error ? err : new Error(String(err));\n\t\t\t\tsafeReportError({ stage: \"send\", error, value: undefined });\n\t\t\t\tfor (let i = 0; i < committedCount; i++) {\n\t\t\t\t\tsafeEmitFailed({ value: chunk[i].value, error, attempts: 1 });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tflushing = false;\n\t\tsafeSetInFlight(0);\n\t};\n\n\tconst scheduleFlush = () => {\n\t\tif (flushIntervalMs > 0 && timer === undefined && !disposed) {\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\t/* I/O flush timer — not reactive scheduling (§5.10) */\n\t\t\t\ttimer = undefined;\n\t\t\t\tflushTransaction();\n\t\t\t}, flushIntervalMs);\n\t\t}\n\t};\n\n\tconst unsub = source.subscribe((msgs) => {\n\t\tfor (const msg of msgs) {\n\t\t\tconst t = msg[0];\n\t\t\tif (t === DATA) {\n\t\t\t\tconst value = msg[1] as T;\n\t\t\t\tlet query: Query;\n\t\t\t\ttry {\n\t\t\t\t\tquery = serialize(value);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst error = err instanceof Error ? err : new Error(String(err));\n\t\t\t\t\treportError({ stage: \"serialize\", error, value });\n\t\t\t\t\tfailedNode.down([[DATA, { value, error, attempts: 0 } satisfies SinkFailure<T>]]);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpending.push({ value, query });\n\t\t\t\tupdateBuffered();\n\t\t\t\tif (pending.length >= maxBatchSize) flushTransaction();\n\t\t\t\telse scheduleFlush();\n\t\t\t} else if (defaultConfig.messageTier(t) >= 3) {\n\t\t\t\tflushTransaction();\n\t\t\t}\n\t\t}\n\t});\n\n\tconst dispose = () => {\n\t\tif (disposed) return;\n\t\tif (timer !== undefined) {\n\t\t\tclearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t}\n\t\tflushTransaction();\n\t\tdisposed = true;\n\t\tunsub();\n\t\tfor (const n of [errorsNode, sentNode, failedNode, inFlightNode, bufferedNode]) {\n\t\t\ttry {\n\t\t\t\t(n as Node<unknown>).down([[TEARDOWN]]);\n\t\t\t} catch {\n\t\t\t\t/* drain re-entrance */\n\t\t\t}\n\t\t}\n\t};\n\n\treturn {\n\t\tdispose,\n\t\tsent: sentNode,\n\t\tfailed: failedNode,\n\t\tinFlight: inFlightNode,\n\t\terrors: errorsNode,\n\t\tbuffered: bufferedNode,\n\t\tflush: async () => {\n\t\t\tif (!disposed) flushTransaction();\n\t\t},\n\t};\n}\n\n// ——————————————————————————————————————————————————————————————\n// Prisma adapter (5.2b)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Duck-typed Prisma model delegate.\n *\n * Compatible with any Prisma model's `findMany` method (e.g. `prisma.user`).\n * The consumer passes the model delegate directly — no dependency on `@prisma/client`.\n */\nexport type PrismaModelLike<T = unknown> = {\n\tfindMany(args?: unknown): Promise<T[]>;\n};\n\n/** Options for {@link fromPrisma}. */\nexport type FromPrismaOptions<T, U = T> = ExtraOpts & {\n\t/** Prisma `findMany` args (where, orderBy, select, include, take, skip, etc.). */\n\targs?: unknown;\n\t/** Map each row to the desired shape. Default: identity cast. */\n\tmapRow?: (row: T) => U;\n};\n\n/**\n * One-shot Prisma query as a reactive source.\n *\n * Calls `model.findMany(args)`, emits one `DATA` per result row, then `COMPLETE`.\n * Compose with `switchMap` + `fromTimer` for periodic re-query.\n *\n * @param model - Prisma model delegate (e.g. `prisma.user`).\n * @param opts - `findMany` args, row mapper, and node options.\n * @returns `Node<U>` — one `DATA` per row, then `COMPLETE`.\n *\n * @example\n * ```ts\n * import { PrismaClient } from \"@prisma/client\";\n * import { fromPrisma } from \"@graphrefly/graphrefly-ts\";\n *\n * const prisma = new PrismaClient();\n * const activeUsers = fromPrisma(prisma.user, {\n * args: { where: { active: true } },\n * });\n * ```\n *\n * @category extra\n */\nexport function fromPrisma<T = unknown, U = T>(\n\tmodel: PrismaModelLike<T>,\n\topts?: FromPrismaOptions<T, U>,\n): Node<U[]> {\n\tconst { args, mapRow = (r: T) => r as unknown as U, ...rest } = opts ?? {};\n\n\treturn producer<U[]>(\n\t\t(a) => {\n\t\t\tlet active = true;\n\n\t\t\tvoid model\n\t\t\t\t.findMany(args)\n\t\t\t\t.then((rows) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ta.emit(rows.map(mapRow));\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\ta.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* node already torn down — swallow */\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t},\n\t\t{ ...rest, describeKind: \"producer\", completeWhenDepsComplete: false } as NodeOptions<U[]>,\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// Drizzle adapter (5.2b)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Duck-typed Drizzle query builder result.\n *\n * Drizzle query builders (e.g. `db.select().from(users)`) expose `.execute()`\n * which returns `Promise<T[]>`. This interface captures that contract without\n * depending on `drizzle-orm`.\n */\nexport type DrizzleQueryLike<T = unknown> = {\n\texecute(): Promise<T[]>;\n};\n\n/** Options for {@link fromDrizzle}. */\nexport type FromDrizzleOptions<T, U = T> = ExtraOpts & {\n\t/** Map each row to the desired shape. Default: identity cast. */\n\tmapRow?: (row: T) => U;\n};\n\n/**\n * One-shot Drizzle query as a reactive source.\n *\n * Calls `query.execute()`, emits one `DATA` per result row, then `COMPLETE`.\n * Compose with `switchMap` + `fromTimer` for periodic re-query.\n *\n * @param query - Drizzle query builder (e.g. `db.select().from(users).where(...)`).\n * @param opts - Row mapper and node options.\n * @returns `Node<U>` — one `DATA` per row, then `COMPLETE`.\n *\n * @example\n * ```ts\n * import { drizzle } from \"drizzle-orm/node-postgres\";\n * import { fromDrizzle } from \"@graphrefly/graphrefly-ts\";\n *\n * const db = drizzle(pool);\n * const rows$ = fromDrizzle(db.select().from(users).where(eq(users.active, true)));\n * ```\n *\n * @category extra\n */\nexport function fromDrizzle<T = unknown, U = T>(\n\tquery: DrizzleQueryLike<T>,\n\topts?: FromDrizzleOptions<T, U>,\n): Node<U[]> {\n\tconst { mapRow = (r: T) => r as unknown as U, ...rest } = opts ?? {};\n\n\treturn producer<U[]>(\n\t\t(a) => {\n\t\t\tlet active = true;\n\n\t\t\tvoid query\n\t\t\t\t.execute()\n\t\t\t\t.then((rows) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ta.emit(rows.map(mapRow));\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\ta.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* node already torn down — swallow */\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t},\n\t\t{ ...rest, describeKind: \"producer\", completeWhenDepsComplete: false } as NodeOptions<U[]>,\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// Kysely adapter (5.2b)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Duck-typed Kysely query builder result.\n *\n * Kysely query builders expose `.execute()` which returns `Promise<T[]>`.\n * This interface captures that contract without depending on `kysely`.\n */\nexport type KyselyQueryLike<T = unknown> = {\n\texecute(): Promise<T[]>;\n};\n\n/** Options for {@link fromKysely}. */\nexport type FromKyselyOptions<T, U = T> = ExtraOpts & {\n\t/** Map each row to the desired shape. Default: identity cast. */\n\tmapRow?: (row: T) => U;\n};\n\n/**\n * One-shot Kysely query as a reactive source.\n *\n * Calls `query.execute()`, emits one `DATA` per result row, then `COMPLETE`.\n * Compose with `switchMap` + `fromTimer` for periodic re-query.\n *\n * @param query - Kysely query builder (e.g. `db.selectFrom(\"users\").selectAll()`).\n * @param opts - Row mapper and node options.\n * @returns `Node<U>` — one `DATA` per row, then `COMPLETE`.\n *\n * @example\n * ```ts\n * import { Kysely, PostgresDialect } from \"kysely\";\n * import { fromKysely } from \"@graphrefly/graphrefly-ts\";\n *\n * const db = new Kysely<DB>({ dialect: new PostgresDialect({ pool }) });\n * const rows$ = fromKysely(db.selectFrom(\"users\").selectAll().where(\"active\", \"=\", true));\n * ```\n *\n * @category extra\n */\nexport function fromKysely<T = unknown, U = T>(\n\tquery: KyselyQueryLike<T>,\n\topts?: FromKyselyOptions<T, U>,\n): Node<U[]> {\n\tconst { mapRow = (r: T) => r as unknown as U, ...rest } = opts ?? {};\n\n\treturn producer<U[]>(\n\t\t(a) => {\n\t\t\tlet active = true;\n\n\t\t\tvoid query\n\t\t\t\t.execute()\n\t\t\t\t.then((rows) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ta.emit(rows.map(mapRow));\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\ta.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* node already torn down — swallow */\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t},\n\t\t{ ...rest, describeKind: \"producer\", completeWhenDepsComplete: false } as NodeOptions<U[]>,\n\t);\n}\n","/**\n * Watermark-based backpressure controller — reactive PAUSE/RESUME flow control.\n *\n * Purely synchronous, event-driven. No timers, no polling, no Promises.\n * Each controller instance uses a unique lockId so multiple controllers\n * on the same upstream node do not collide.\n *\n * @module\n */\n\nimport { type Messages, PAUSE, RESUME } from \"../core/messages.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type WatermarkOptions = {\n\t/** Pending count at which PAUSE is sent upstream. */\n\thighWaterMark: number;\n\t/** Pending count at which RESUME is sent upstream (after being paused). */\n\tlowWaterMark: number;\n};\n\nexport type WatermarkController = {\n\t/** Call when a DATA message is buffered/enqueued. Returns `true` if PAUSE was just sent. */\n\tonEnqueue(): boolean;\n\t/** Call when a buffered item is consumed. Returns `true` if RESUME was just sent. */\n\tonDequeue(): boolean;\n\t/** Current un-consumed item count. */\n\treadonly pending: number;\n\t/** Whether upstream is currently paused by this controller. */\n\treadonly paused: boolean;\n\t/** Dispose: if paused, sends RESUME to unblock upstream. */\n\tdispose(): void;\n};\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nlet nextLockId = 0;\n\n/**\n * Creates a watermark-based backpressure controller.\n *\n * @param sendUp - Callback that delivers messages upstream (typically `handle.up`).\n * @param opts - High/low watermark thresholds (item counts).\n * @returns A {@link WatermarkController}.\n *\n * @example\n * ```ts\n * const handle = graph.observe(\"fast-source\");\n * const wm = createWatermarkController(\n * (msgs) => handle.up(msgs),\n * { highWaterMark: 64, lowWaterMark: 16 },\n * );\n *\n * // In sink callback:\n * handle.subscribe((msgs) => {\n * for (const msg of msgs) {\n * if (msg[0] === DATA) {\n * buffer.push(msg[1]);\n * wm.onEnqueue();\n * }\n * }\n * });\n *\n * // When consumer drains:\n * const item = buffer.shift();\n * wm.onDequeue();\n * ```\n *\n * @category extra\n */\nexport function createWatermarkController(\n\tsendUp: (messages: Messages) => void,\n\topts: WatermarkOptions,\n): WatermarkController {\n\tif (opts.highWaterMark < 1) throw new RangeError(\"highWaterMark must be >= 1\");\n\tif (opts.lowWaterMark < 0) throw new RangeError(\"lowWaterMark must be >= 0\");\n\tif (opts.lowWaterMark >= opts.highWaterMark)\n\t\tthrow new RangeError(\"lowWaterMark must be < highWaterMark\");\n\tconst lockId = Symbol(`bp-${++nextLockId}`);\n\tlet pending = 0;\n\tlet paused = false;\n\n\treturn {\n\t\tonEnqueue(): boolean {\n\t\t\tpending += 1;\n\t\t\tif (!paused && pending >= opts.highWaterMark) {\n\t\t\t\tpaused = true;\n\t\t\t\tsendUp([[PAUSE, lockId]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tonDequeue(): boolean {\n\t\t\tif (pending > 0) pending -= 1;\n\t\t\tif (paused && pending <= opts.lowWaterMark) {\n\t\t\t\tpaused = false;\n\t\t\t\tsendUp([[RESUME, lockId]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tget pending() {\n\t\t\treturn pending;\n\t\t},\n\t\tget paused() {\n\t\t\treturn paused;\n\t\t},\n\t\tdispose() {\n\t\t\tif (paused) {\n\t\t\t\tpaused = false;\n\t\t\t\tsendUp([[RESUME, lockId]]);\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * N-tier cascading cache — roadmap §3.1c.\n *\n * Each cached entry is a `state()` node. On miss, tiers are tried in order\n * (tier 0 = hottest). Hits auto-promote to faster tiers. Supports eviction\n * policy and write-through.\n *\n * Consumes {@link StorageTier} directly (the same primitive used by\n * {@link Graph.attachStorage}) — no separate `CacheTier` interface. Async\n * tiers participate via `Promise<unknown>` returns from `load`; sync tiers\n * stay zero-microtask (the cascade inspects the return type and branches).\n */\nimport { DATA, TEARDOWN } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { state } from \"../core/sugar.js\";\nimport type { StorageTier } from \"./storage.js\";\n\n// ——————————————————————————————————————————————————————————————\n// Eviction policy\n// ——————————————————————————————————————————————————————————————\n\n/** Pluggable eviction policy for {@link cascadingCache}. */\nexport interface CacheEvictionPolicy<K> {\n\tinsert(key: K): void;\n\ttouch(key: K): void;\n\tdelete(key: K): void;\n\tevict(count: number): K[];\n\tsize(): number;\n}\n\n/**\n * LRU eviction policy backed by a doubly-linked list + Map.\n *\n * @returns An {@link CacheEvictionPolicy} that evicts least-recently-used entries.\n *\n * @category extra\n */\nexport function lru<K>(): CacheEvictionPolicy<K> {\n\ttype LNode = { key: K; prev: LNode | null; next: LNode | null };\n\tconst map = new Map<K, LNode>();\n\tlet head: LNode | null = null;\n\tlet tail: LNode | null = null;\n\n\tfunction unlink(n: LNode): void {\n\t\tif (n.prev) n.prev.next = n.next;\n\t\telse head = n.next;\n\t\tif (n.next) n.next.prev = n.prev;\n\t\telse tail = n.prev;\n\t\tn.prev = null;\n\t\tn.next = null;\n\t}\n\n\tfunction pushFront(n: LNode): void {\n\t\tn.next = head;\n\t\tn.prev = null;\n\t\tif (head) head.prev = n;\n\t\thead = n;\n\t\tif (tail === null) tail = n;\n\t}\n\n\treturn {\n\t\tinsert(key: K): void {\n\t\t\tif (map.has(key)) {\n\t\t\t\tthis.touch(key);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst n: LNode = { key, prev: null, next: null };\n\t\t\tmap.set(key, n);\n\t\t\tpushFront(n);\n\t\t},\n\t\ttouch(key: K): void {\n\t\t\tconst n = map.get(key);\n\t\t\tif (!n) return;\n\t\t\tunlink(n);\n\t\t\tpushFront(n);\n\t\t},\n\t\tdelete(key: K): void {\n\t\t\tconst n = map.get(key);\n\t\t\tif (!n) return;\n\t\t\tunlink(n);\n\t\t\tmap.delete(key);\n\t\t},\n\t\tevict(count: number): K[] {\n\t\t\tconst victims: K[] = [];\n\t\t\tfor (let i = 0; i < count && tail !== null; i++) {\n\t\t\t\tconst n = tail;\n\t\t\t\tvictims.push(n.key);\n\t\t\t\tunlink(n);\n\t\t\t\tmap.delete(n.key);\n\t\t\t}\n\t\t\treturn victims;\n\t\t},\n\t\tsize(): number {\n\t\t\treturn map.size;\n\t\t},\n\t};\n}\n\n// ——————————————————————————————————————————————————————————————\n// CascadingCache\n// ——————————————————————————————————————————————————————————————\n\nexport interface CascadingCacheOptions {\n\t/** Max entries before eviction. 0 = unlimited (default). */\n\tmaxSize?: number;\n\t/** Eviction policy. Default: LRU. Only used when maxSize > 0. */\n\teviction?: CacheEvictionPolicy<string>;\n\t/** Write-through: save() writes to all tiers, not just tier 0. Default: false. */\n\twriteThrough?: boolean;\n}\n\nexport interface CascadingCache<V> {\n\t/** Get or create a singleton state node for this key. Cascades tiers on miss. */\n\tload(key: string): Node<V | undefined>;\n\t/** Write value to tier(s) and update cache node in-place. */\n\tsave(key: string, value: V): void;\n\t/** Re-cascade tiers into the existing cache node (subscribers see the update). */\n\tinvalidate(key: string): void;\n\t/** Remove from all tiers, teardown the node, and delete cache entry. */\n\tdelete(key: string): void;\n\t/** Check if key exists in cache map. */\n\thas(key: string): boolean;\n\t/** Number of cached entries. */\n\treadonly size: number;\n}\n\nfunction isPromiseLike(v: unknown): v is Promise<unknown> {\n\treturn v != null && typeof (v as Promise<unknown>).then === \"function\";\n}\n\nfunction fireAndForget(result: void | Promise<void>): void {\n\tif (isPromiseLike(result)) {\n\t\t(result as Promise<void>).catch(() => {\n\t\t\t/* ignore — users opt into onError via attachStorage, not cache */\n\t\t});\n\t}\n}\n\n/**\n * Creates a singleton reactive cache with N-tier cascading lookup.\n *\n * Each cached entry is a `state()` node. On cache miss, tiers are tried in order\n * (index 0 = hottest/fastest). When a lower tier hits, the value is auto-promoted\n * to all faster tiers. Concurrent loads for the same key share the same state\n * instance — natural dedup.\n *\n * **Sync vs async tiers:** if `tier.load` returns a plain value, the cache node\n * cache is populated synchronously (`c.load(\"k\").cache` is readable immediately).\n * If it returns a `Promise`, the node emits `DATA` when the promise resolves.\n *\n * **Miss sentinel:** `undefined` and `null` are both treated as misses — the\n * cascade continues to the next tier.\n *\n * @param tiers - Ordered lookup tiers, hottest first.\n * @param opts - Optional configuration (maxSize, eviction policy, writeThrough).\n * @returns A reactive cache where each entry is a `Node<V | undefined>`.\n *\n * @example\n * ```ts\n * import { cascadingCache, memoryStorage, fileStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * const cache = cascadingCache<User>([memoryStorage(), fileStorage(\"./cache\")]);\n * const user = cache.load(\"user:42\"); // Node<User | undefined>\n * user.subscribe(msgs => console.log(msgs));\n * ```\n *\n * @category extra\n */\nexport function cascadingCache<V = unknown>(\n\ttiers: readonly StorageTier[],\n\topts?: CascadingCacheOptions,\n): CascadingCache<V> {\n\tconst entries = new Map<string, Node<V | undefined>>();\n\tconst maxSize = opts?.maxSize ?? 0;\n\tconst policy = maxSize > 0 ? (opts?.eviction ?? lru<string>()) : null;\n\tconst writeThrough = opts?.writeThrough ?? false;\n\n\tfunction promote(key: string, value: V, hitTierIndex: number): void {\n\t\tfor (let i = 0; i < hitTierIndex; i++) {\n\t\t\ttry {\n\t\t\t\tfireAndForget(tiers[i]!.save(key, value));\n\t\t\t} catch {\n\t\t\t\t/* ignore promote failures — cache still serves this request */\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Cascade from `startTier` onward. Sync tiers resolve inline; async tiers\n\t * yield control via Promise chaining and recurse on miss. Both paths end\n\t * by emitting `[[DATA, value]]` on `nd` and promoting to faster tiers.\n\t */\n\tfunction cascade(key: string, nd: Node<V | undefined>, startTier = 0): void {\n\t\tfor (let tierIndex = startTier; tierIndex < tiers.length; tierIndex++) {\n\t\t\tlet result: unknown;\n\t\t\ttry {\n\t\t\t\tresult = tiers[tierIndex]!.load(key);\n\t\t\t} catch {\n\t\t\t\tcontinue; // sync throw — next tier\n\t\t\t}\n\t\t\tif (isPromiseLike(result)) {\n\t\t\t\tconst captured = tierIndex;\n\t\t\t\t(result as Promise<unknown>).then(\n\t\t\t\t\t(val) => {\n\t\t\t\t\t\tif (val !== undefined && val !== null) {\n\t\t\t\t\t\t\tnd.down([[DATA, val]]);\n\t\t\t\t\t\t\tpromote(key, val as V, captured);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcascade(key, nd, captured + 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t() => {\n\t\t\t\t\t\tcascade(key, nd, captured + 1);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn; // async branch continues the cascade\n\t\t\t}\n\t\t\tif (result !== undefined && result !== null) {\n\t\t\t\tnd.down([[DATA, result]]);\n\t\t\t\tpromote(key, result as V, tierIndex);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t// all tiers missed — value stays undefined\n\t}\n\n\tfunction evictIfNeeded(): void {\n\t\tif (!policy || maxSize <= 0) return;\n\t\twhile (policy.size() >= maxSize) {\n\t\t\tconst victims = policy.evict(1);\n\t\t\tif (victims.length === 0) break;\n\t\t\tfor (const key of victims) {\n\t\t\t\tconst nd = entries.get(key);\n\t\t\t\tif (nd) {\n\t\t\t\t\tconst value = nd.cache;\n\t\t\t\t\tif (nd.status !== \"sentinel\" && tiers.length > 0) {\n\t\t\t\t\t\t// Demote to last tier, clear faster tiers.\n\t\t\t\t\t\tconst lastIndex = tiers.length - 1;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tfireAndForget(tiers[lastIndex]!.save(key, value as V));\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* ignore */\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (let j = 0; j < lastIndex; j++) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst clearFn = tiers[j]!.clear;\n\t\t\t\t\t\t\t\tif (clearFn) fireAndForget(clearFn.call(tiers[j], key));\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t/* ignore */\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\tnd.down([[TEARDOWN]]);\n\t\t\t\t}\n\t\t\t\tentries.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tload(key: string): Node<V | undefined> {\n\t\t\tconst existing = entries.get(key);\n\t\t\tif (existing) {\n\t\t\t\tpolicy?.touch(key);\n\t\t\t\treturn existing;\n\t\t\t}\n\t\t\tif (policy && maxSize > 0 && policy.size() >= maxSize) {\n\t\t\t\tevictIfNeeded();\n\t\t\t}\n\t\t\tconst nd = state<V | undefined>(undefined);\n\t\t\tentries.set(key, nd);\n\t\t\tpolicy?.insert(key);\n\t\t\tcascade(key, nd);\n\t\t\treturn nd;\n\t\t},\n\n\t\tsave(key: string, value: V): void {\n\t\t\tif (writeThrough) {\n\t\t\t\tfor (const tier of tiers) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfireAndForget(tier.save(key, value));\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* ignore */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (tiers[0]) {\n\t\t\t\ttry {\n\t\t\t\t\tfireAndForget(tiers[0].save(key, value));\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore */\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst existing = entries.get(key);\n\t\t\tif (existing) {\n\t\t\t\texisting.down([[DATA, value]]);\n\t\t\t\tpolicy?.touch(key);\n\t\t\t} else {\n\t\t\t\tif (policy && maxSize > 0 && policy.size() >= maxSize) {\n\t\t\t\t\tevictIfNeeded();\n\t\t\t\t}\n\t\t\t\tconst nd = state<V | undefined>(value);\n\t\t\t\tentries.set(key, nd);\n\t\t\t\tpolicy?.insert(key);\n\t\t\t}\n\t\t},\n\n\t\tinvalidate(key: string): void {\n\t\t\tconst existing = entries.get(key);\n\t\t\tif (existing) cascade(key, existing);\n\t\t},\n\n\t\tdelete(key: string): void {\n\t\t\tpolicy?.delete(key);\n\t\t\tconst nd = entries.get(key);\n\t\t\tif (nd) nd.down([[TEARDOWN]]);\n\t\t\tentries.delete(key);\n\t\t\tfor (const tier of tiers) {\n\t\t\t\ttry {\n\t\t\t\t\tconst clearFn = tier.clear;\n\t\t\t\t\tif (clearFn) fireAndForget(clearFn.call(tier, key));\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore */\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\thas(key: string): boolean {\n\t\t\treturn entries.has(key);\n\t\t},\n\n\t\tget size(): number {\n\t\t\treturn entries.size;\n\t\t},\n\t};\n}\n","/**\n * Reactive key–value map (roadmap §3.2) — emits `ReadonlyMap` snapshots directly.\n *\n * Internal version counter drives efficient equality without leaking `Versioned`\n * into the public API (spec §5.12).\n *\n * **Wave 4 refactor (2026-04-15):** Introduces the `MapBackend<K, V>` pluggable-backend\n * interface. The default `NativeMapBackend` owns LRU ordering, TTL expiry, and a\n * monotonic `version` counter. Reads that discover expired entries prune them and\n * emit (fixes the former `size`-getter stale-snapshot gap).\n */\nimport { batch } from \"../core/batch.js\";\nimport { monotonicNs } from \"../core/clock.js\";\nimport { DATA, DIRTY } from \"../core/messages.js\";\nimport type { Node, NodeOptions } from \"../core/node.js\";\nimport { state } from \"../core/sugar.js\";\nimport type { VersioningLevel } from \"../core/versioning.js\";\n\nexport type ReactiveMapOptions<K, V> = {\n\t/** Optional registry name for `describe()` / debugging. */\n\tname?: string;\n\t/**\n\t * LRU cap. When set, evicts least-recently-used keys after inserts that exceed this size.\n\t * Forwarded to the default `NativeMapBackend`. Ignored if a custom `backend` is provided.\n\t */\n\tmaxSize?: number;\n\t/**\n\t * Default TTL in seconds. Used when `set`/`setMany` omits per-call `ttl`.\n\t * Forwarded to the default `NativeMapBackend`. Ignored if a custom `backend` is provided.\n\t */\n\tdefaultTtl?: number;\n\t/**\n\t * Storage backend. Defaults to `NativeMapBackend`. Users can plug in persistent\n\t * (HAMT / Immutable.js) or shared-state backends via the {@link MapBackend} interface.\n\t */\n\tbackend?: MapBackend<K, V>;\n\t/**\n\t * Optional versioning level for the underlying `entries` state node. Set at\n\t * construction time; cannot be changed later. Pass `0` for V0 identity +\n\t * monotonic version counter, or `1` for V1 + content-addressed cid.\n\t */\n\tversioning?: VersioningLevel;\n} & Omit<NodeOptions, \"initial\" | \"describeKind\" | \"equals\" | \"versioning\">;\n\nexport type ReactiveMapBundle<K, V> = {\n\t/** Emits `ReadonlyMap<K, V>` on each structural change (two-phase). */\n\tentries: Node<ReadonlyMap<K, V>>;\n\t/**\n\t * Checks existence. O(1) for live keys. If the key is expired, prunes it AND\n\t * emits a snapshot so the reactive surface stays consistent with the return\n\t * value. Reads on expired keys are therefore **observable side effects**.\n\t *\n\t * **LRU touch (F4):** When `maxSize` is configured, a live-key `has` also\n\t * marks the entry as most-recently-used — which rearranges internal insertion\n\t * order without bumping `version` or emitting. If you care about iteration\n\t * order in a downstream subscriber, rely on the `entries` snapshot (a fresh\n\t * `ReadonlyMap` per mutation) rather than iterating the backend directly.\n\t */\n\thas: (key: K) => boolean;\n\t/**\n\t * Gets value. O(1) for live keys. If the key is expired, prunes it AND emits\n\t * a snapshot. Reads on expired keys are therefore **observable side effects**.\n\t *\n\t * **LRU touch (F4):** When `maxSize` is configured, a live-key `get` also\n\t * marks the entry as most-recently-used (no version bump, no emission). See\n\t * `has` for the full note on iteration order.\n\t */\n\tget: (key: K) => V | undefined;\n\t/**\n\t * Sets value with optional TTL (seconds). Throws on `ttl <= 0`. Applies LRU eviction\n\t * if `maxSize` is set. Always emits.\n\t */\n\tset: (key: K, value: V, opts?: { ttl?: number }) => void;\n\t/**\n\t * Bulk set — emits one snapshot for the whole batch. Applies `opts.ttl` (falls back\n\t * to `defaultTtl`) to every entry. No-op if `entries` is empty.\n\t *\n\t * **Iterable consumption:** Consumes `entries` once (single-pass). Pass an array\n\t * or `Set` for multi-shot consumers. If the iterator throws mid-iteration,\n\t * entries already applied remain committed and a snapshot IS emitted (via the\n\t * wrapper's finally-block).\n\t */\n\tsetMany: (entries: Iterable<readonly [K, V]>, opts?: { ttl?: number }) => void;\n\tdelete: (key: K) => void;\n\t/**\n\t * Bulk delete — emits one snapshot. No-op if no keys were present.\n\t *\n\t * **Iterable consumption:** Consumes `keys` once (single-pass).\n\t */\n\tdeleteMany: (keys: Iterable<K>) => void;\n\tclear: () => void;\n\t/**\n\t * Current entry count — O(1), **pure read** (no emission). May include\n\t * expired entries on TTL maps until a mutation or explicit\n\t * `pruneExpired()` / `has(key)` / `get(key)` prunes them. Call\n\t * `pruneExpired()` first if you need a live count.\n\t */\n\treadonly size: number;\n\t/** Explicitly prunes all expired entries. Emits if any were removed. */\n\tpruneExpired: () => void;\n\t/**\n\t * Releases any internal keepalive subscriptions so the bundle can be\n\t * GC'd. `reactiveMap` currently holds none (the `entries` node lives only\n\t * as long as external subscribers keep it alive), so `dispose()` is a\n\t * no-op today — exposed for API parity with `reactiveIndex.dispose` /\n\t * `reactiveList.dispose` / `reactiveLog.dispose`. Idempotent. D6(a).\n\t */\n\tdispose: () => void;\n};\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link reactiveMap}. Implementations own the mutable state,\n * including optional TTL and LRU semantics, and expose a monotonic `version` counter\n * that increments on every change to visible state.\n *\n * The reactive layer reads `version` before and after each backend call; when it\n * advances, a snapshot is emitted. Reads (`has`, `get`) may internally prune the\n * target key if expired and advance `version` — in which case the layer emits so\n * subscribers see state consistent with the read's return value.\n *\n * @remarks Post-1.0 op-log changesets will extend this interface with a\n * `changesSince(version: number): Iterable<Change>` method. Current consumers\n * should treat all methods here as stable.\n *\n * @category extra\n */\nexport interface MapBackend<K, V> {\n\t/** Monotonic mutation counter; increments on every visible state change. */\n\treadonly version: number;\n\t/** Raw entry count (may include expired entries until a read / prune removes them). */\n\treadonly size: number;\n\t/** Checks existence. May prune target key if expired; advances `version` if pruned. */\n\thas(key: K): boolean;\n\t/** Gets value. May prune target key if expired; advances `version` if pruned. */\n\tget(key: K): V | undefined;\n\t/**\n\t * Sets a value with optional TTL (seconds). Throws `RangeError` if `ttl <= 0`.\n\t * Applies LRU eviction if `maxSize` is configured. Advances `version`.\n\t *\n\t * **Atomicity contract:** Either fully succeeds or throws before any state\n\t * change; `version` advances only on success.\n\t */\n\tset(key: K, value: V, ttl?: number): void;\n\t/**\n\t * Atomic bulk set. Pre-validates TTL once, then applies all entries. Advances\n\t * `version` at most once (even for N entries). No-op if iterable is empty.\n\t *\n\t * **Consumes `entries` once** — pass an array if you want repeatability.\n\t *\n\t * **Atomicity contract:** TTL validation throws before any mutation. If the\n\t * iterable itself throws mid-iteration, entries committed before the throw\n\t * remain persisted AND `version` is bumped once (surfaced via finally) so\n\t * the reactive wrapper emits a snapshot reflecting the partial state. \"At\n\t * most once\" invariant is preserved.\n\t */\n\tsetMany(entries: Iterable<readonly [K, V]>, ttl?: number): void;\n\t/** Removes a key. Returns `true` if the key existed. Advances `version` only if true. */\n\tdelete(key: K): boolean;\n\t/**\n\t * Atomic bulk delete. Returns count removed. Advances `version` at most once\n\t * (even for N keys). No-op if no keys were present. Consumes `keys` once.\n\t */\n\tdeleteMany(keys: Iterable<K>): number;\n\t/** Removes all entries. Returns count removed. Advances `version` only if non-zero. */\n\tclear(): number;\n\t/** Removes all expired entries. Returns count removed. Advances `version` only if non-zero. */\n\tpruneExpired(): number;\n\t/** Fresh snapshot of non-expired entries (does NOT mutate state). */\n\ttoMap(): ReadonlyMap<K, V>;\n}\n\nexport type NativeMapBackendOptions = {\n\tmaxSize?: number;\n\t/** Default TTL in seconds. */\n\tdefaultTtl?: number;\n};\n\ntype MapEntry<V> = { value: V; expiresAt?: number };\n\n/**\n * Default `Map<K, {value, expiresAt}>` backend with optional per-key TTL and LRU cap.\n *\n * **Complexity:**\n * - `has`, `get`, `delete`, `size`: O(1)\n * - `set`: O(1) amortized (LRU touch + eviction)\n * - `pruneExpired`, `toMap`: O(n)\n *\n * LRU order uses native `Map` insertion order. `get` / `has` on a live key \"touches\"\n * it by delete-then-reinsert (moving it to the end). This touch does NOT advance\n * `version` — it's an internal optimization; the externally visible snapshot\n * preserves iteration order as of the last mutation. **Note:** because touch\n * reorders the internal `_store` without emitting, an in-process consumer iterating\n * `_store` directly (custom subclasses) could observe changing order; external\n * subscribers only see `toMap()` snapshots which are defensively copied and stable.\n *\n * @category extra\n */\nexport class NativeMapBackend<K, V> implements MapBackend<K, V> {\n\tprivate _version = 0;\n\tprivate readonly _store = new Map<K, MapEntry<V>>();\n\tprivate readonly _maxSize?: number;\n\tprivate readonly _defaultTtl?: number;\n\n\tconstructor(options: NativeMapBackendOptions = {}) {\n\t\tconst { maxSize, defaultTtl } = options;\n\t\tif (maxSize !== undefined && maxSize < 1) {\n\t\t\tthrow new RangeError(\"maxSize must be >= 1\");\n\t\t}\n\t\tif (defaultTtl !== undefined && defaultTtl <= 0) {\n\t\t\tthrow new RangeError(\"defaultTtl must be positive\");\n\t\t}\n\t\tthis._maxSize = maxSize;\n\t\tthis._defaultTtl = defaultTtl;\n\t}\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget size(): number {\n\t\treturn this._store.size;\n\t}\n\n\thas(key: K): boolean {\n\t\tconst e = this._store.get(key);\n\t\tif (e === undefined) return false;\n\t\tif (this._isExpired(e)) {\n\t\t\tthis._store.delete(key);\n\t\t\tthis._version += 1;\n\t\t\treturn false;\n\t\t}\n\t\tthis._touchLru(key, e);\n\t\treturn true;\n\t}\n\n\tget(key: K): V | undefined {\n\t\tconst e = this._store.get(key);\n\t\tif (e === undefined) return undefined;\n\t\tif (this._isExpired(e)) {\n\t\t\tthis._store.delete(key);\n\t\t\tthis._version += 1;\n\t\t\treturn undefined;\n\t\t}\n\t\tthis._touchLru(key, e);\n\t\treturn e.value;\n\t}\n\n\tset(key: K, value: V, ttl?: number): void {\n\t\tconst expiresAt = this._resolveExpiresAt(ttl);\n\t\t// Delete-then-insert to place key at LRU end.\n\t\tif (this._store.has(key)) this._store.delete(key);\n\t\tthis._store.set(key, { value, expiresAt });\n\t\tthis._evictLruWhileOver();\n\t\tthis._version += 1;\n\t}\n\n\tsetMany(entries: Iterable<readonly [K, V]>, ttl?: number): void {\n\t\t// Pre-validate TTL once (throws before any mutation).\n\t\tconst expiresAt = this._resolveExpiresAt(ttl);\n\t\tlet count = 0;\n\t\ttry {\n\t\t\tfor (const [key, value] of entries) {\n\t\t\t\tif (this._store.has(key)) this._store.delete(key);\n\t\t\t\tthis._store.set(key, { value, expiresAt });\n\t\t\t\tcount += 1;\n\t\t\t}\n\t\t} finally {\n\t\t\t// D3: if the iterable threw mid-iteration, entries committed before\n\t\t\t// the throw must still advance `version` so subscribers see the\n\t\t\t// partial state consistently. \"At most once\" is preserved.\n\t\t\tif (count > 0) {\n\t\t\t\tthis._evictLruWhileOver();\n\t\t\t\tthis._version += 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tdelete(key: K): boolean {\n\t\tconst had = this._store.delete(key);\n\t\tif (had) this._version += 1;\n\t\treturn had;\n\t}\n\n\tdeleteMany(keys: Iterable<K>): number {\n\t\tlet removed = 0;\n\t\ttry {\n\t\t\tfor (const k of keys) {\n\t\t\t\tif (this._store.delete(k)) removed += 1;\n\t\t\t}\n\t\t} finally {\n\t\t\tif (removed > 0) this._version += 1;\n\t\t}\n\t\treturn removed;\n\t}\n\n\tclear(): number {\n\t\tconst n = this._store.size;\n\t\tif (n === 0) return 0;\n\t\tthis._store.clear();\n\t\tthis._version += 1;\n\t\treturn n;\n\t}\n\n\tpruneExpired(): number {\n\t\tconst now = monotonicNs();\n\t\tlet removed = 0;\n\t\tfor (const [k, e] of this._store) {\n\t\t\tif (this._isExpired(e, now)) {\n\t\t\t\tthis._store.delete(k);\n\t\t\t\tremoved += 1;\n\t\t\t}\n\t\t}\n\t\tif (removed > 0) this._version += 1;\n\t\treturn removed;\n\t}\n\n\ttoMap(): ReadonlyMap<K, V> {\n\t\tconst now = monotonicNs();\n\t\tconst out = new Map<K, V>();\n\t\tfor (const [k, e] of this._store) {\n\t\t\tif (!this._isExpired(e, now)) out.set(k, e.value);\n\t\t}\n\t\treturn out;\n\t}\n\n\tprivate _resolveExpiresAt(ttl?: number): number | undefined {\n\t\tconst effectiveTtl = ttl ?? this._defaultTtl;\n\t\tif (effectiveTtl === undefined) return undefined;\n\t\tif (!Number.isFinite(effectiveTtl) || effectiveTtl <= 0) {\n\t\t\tthrow new RangeError(\n\t\t\t\t`MapBackend: ttl must be a positive finite number (got ${effectiveTtl})`,\n\t\t\t);\n\t\t}\n\t\treturn monotonicNs() + effectiveTtl * 1_000_000_000;\n\t}\n\n\tprivate _isExpired(e: MapEntry<V>, now?: number): boolean {\n\t\tif (e.expiresAt === undefined) return false;\n\t\treturn (now ?? monotonicNs()) >= e.expiresAt;\n\t}\n\n\tprivate _touchLru(key: K, entry: MapEntry<V>): void {\n\t\t// Move to LRU end. Does NOT advance `version` — internal optimization.\n\t\tthis._store.delete(key);\n\t\tthis._store.set(key, entry);\n\t}\n\n\tprivate _evictLruWhileOver(): void {\n\t\tif (this._maxSize === undefined) return;\n\t\twhile (this._store.size > this._maxSize) {\n\t\t\tconst first = this._store.keys().next().value as K | undefined;\n\t\t\tif (first === undefined) break;\n\t\t\tthis._store.delete(first);\n\t\t}\n\t}\n}\n\n// ── Reactive wrapper ──────────────────────────────────────────────────────\n\n/**\n * Creates a reactive `Map` with optional per-key TTL and optional LRU max size.\n *\n * @param options - `name`, `maxSize`, `defaultTtl` (seconds), or custom `backend`.\n * @returns `ReactiveMapBundle` — imperative methods (`has`/`get`/`set`/`setMany`/`delete`/\n * `deleteMany`/`clear`/`pruneExpired`), reactive `entries` node, and O(1)-ish `size`.\n *\n * @remarks\n * **TTL:** Expiry is checked on `get`, `has`, `size`, `pruneExpired`, and before each\n * snapshot emission (expired keys are pruned first). Reads that discover expired keys\n * emit a snapshot so subscribers see state consistent with the read's return value.\n * There is no background timer; monotonic-clock expiry is immune to wall-clock changes.\n *\n * **LRU:** Uses native `Map` insertion order — `get` / `has` refreshes position via\n * delete-then-reinsert; under `maxSize` pressure the first key in iteration order is\n * evicted. LRU touching does NOT trigger emission (internal optimization).\n *\n * **Backend:** The default {@link NativeMapBackend} owns LRU/TTL. For persistent /\n * HAMT / shared-state semantics plug in a custom {@link MapBackend}. `maxSize` and\n * `defaultTtl` on the options object are only applied to the default backend — if\n * you supply `backend`, configure those on your backend directly.\n *\n * @example\n * ```ts\n * import { reactiveMap } from \"@graphrefly/graphrefly-ts\";\n *\n * const m = reactiveMap<string, number>({ name: \"cache\", maxSize: 100, defaultTtl: 60 });\n * m.set(\"x\", 1);\n * m.setMany([[\"y\", 2], [\"z\", 3]]);\n * m.entries.subscribe((msgs) => { console.log(msgs); });\n * ```\n *\n * @category extra\n */\nexport function reactiveMap<K, V>(options: ReactiveMapOptions<K, V> = {}): ReactiveMapBundle<K, V> {\n\tconst { name, maxSize, defaultTtl, versioning, backend: userBackend } = options;\n\tconst backend: MapBackend<K, V> =\n\t\tuserBackend ?? new NativeMapBackend<K, V>({ maxSize, defaultTtl });\n\n\tconst n = state<ReadonlyMap<K, V>>(backend.toMap(), {\n\t\tname,\n\t\tdescribeKind: \"state\",\n\t\tequals: (a, b) => a === b,\n\t\t...(versioning != null ? { versioning } : {}),\n\t});\n\n\tfunction pushSnapshot(): void {\n\t\tconst map = backend.toMap();\n\t\tbatch(() => {\n\t\t\tn.down([[DIRTY]]);\n\t\t\tn.down([[DATA, map]]);\n\t\t});\n\t}\n\n\t/**\n\t * Defense-in-depth emission guard: compares `version` before/after `op` and\n\t * emits a snapshot if advanced. Uses `try/finally` so partial-mutation state\n\t * from a custom non-atomic backend is still surfaced to subscribers if the\n\t * op throws mid-way (native backends are atomic by contract and won't trip\n\t * this path).\n\t */\n\tfunction wrapMutation<T>(op: () => T): T {\n\t\tconst prev = backend.version;\n\t\ttry {\n\t\t\treturn op();\n\t\t} finally {\n\t\t\tif (backend.version !== prev) pushSnapshot();\n\t\t}\n\t}\n\n\treturn {\n\t\tentries: n,\n\n\t\thas(key: K): boolean {\n\t\t\treturn wrapMutation(() => backend.has(key));\n\t\t},\n\n\t\tget(key: K): V | undefined {\n\t\t\treturn wrapMutation(() => backend.get(key));\n\t\t},\n\n\t\tset(key: K, value: V, opts?: { ttl?: number }): void {\n\t\t\twrapMutation(() => backend.set(key, value, opts?.ttl));\n\t\t},\n\n\t\tsetMany(entries: Iterable<readonly [K, V]>, opts?: { ttl?: number }): void {\n\t\t\twrapMutation(() => backend.setMany(entries, opts?.ttl));\n\t\t},\n\n\t\tdelete(key: K): void {\n\t\t\twrapMutation(() => backend.delete(key));\n\t\t},\n\n\t\tdeleteMany(keys: Iterable<K>): void {\n\t\t\twrapMutation(() => backend.deleteMany(keys));\n\t\t},\n\n\t\tclear(): void {\n\t\t\twrapMutation(() => backend.clear());\n\t\t},\n\n\t\tpruneExpired(): void {\n\t\t\twrapMutation(() => backend.pruneExpired());\n\t\t},\n\n\t\t/**\n\t\t * Current raw entry count — O(1), **pure read**. May include\n\t\t * not-yet-pruned expired entries on TTL maps until the next mutation\n\t\t * or an explicit `pruneExpired()` / `has` / `get` triggers a prune.\n\t\t *\n\t\t * Previously this getter ran `pruneExpired()` inline and emitted a\n\t\t * snapshot as a side effect — that violated spec §5.8 \"no\n\t\t * side-effectful reads\" and created a re-entrancy hazard when a\n\t\t * subscriber to `entries` read `.size` from its own callback. D2(a).\n\t\t *\n\t\t * For a live count that excludes expired entries, call\n\t\t * `bundle.pruneExpired()` first.\n\t\t */\n\t\tget size(): number {\n\t\t\treturn backend.size;\n\t\t},\n\n\t\tdispose(): void {\n\t\t\t// D6(a): no internal keepalives yet — no-op for API parity with\n\t\t\t// reactive-index / reactive-list / reactive-log. If a future\n\t\t\t// refactor adds a keepalive (e.g. on `entries`), wire its\n\t\t\t// disposer here.\n\t\t},\n\t};\n}\n","/**\n * Composite data patterns (roadmap §3.2b).\n *\n * These helpers compose existing primitives (`node`, `switchMap`, `reactiveMap`,\n * `dynamicNode`, `fromAny`) without introducing new protocol semantics.\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { DATA } from \"../core/messages.js\";\nimport type { Node, NodeOptions } from \"../core/node.js\";\nimport { derived, state } from \"../core/sugar.js\";\nimport { merge, switchMap } from \"./operators.js\";\nimport { type ReactiveMapBundle, type ReactiveMapOptions, reactiveMap } from \"./reactive-map.js\";\nimport { forEach, fromAny, type NodeInput } from \"./sources.js\";\n\nfunction isNodeLike<T>(value: unknown): value is Node<T> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"cache\" in (value as Node<T>) &&\n\t\ttypeof (value as Node<T>).subscribe === \"function\"\n\t);\n}\n\n/**\n * Verification payload shape is intentionally user-defined.\n */\nexport type VerifyValue = unknown;\n\nexport type VerifiableOptions<TVerify = VerifyValue> = Omit<\n\tNodeOptions,\n\t\"describeKind\" | \"initial\"\n> & {\n\t/** Reactive re-verification trigger. */\n\ttrigger?: NodeInput<unknown>;\n\t/** Re-run verification whenever `source` settles. */\n\tautoVerify?: boolean;\n\t/** Initial verification companion value. */\n\tinitialVerified?: TVerify | null;\n};\n\nexport type VerifiableBundle<T, TVerify = VerifyValue> = {\n\t/** Coerced source node. */\n\tnode: Node<T>;\n\t/** Latest verification result (`null` before first verification). */\n\tverified: Node<TVerify | null>;\n\t/** Effective trigger node used for verification, if any. */\n\ttrigger: Node<unknown> | null;\n};\n\n/**\n * Composes a value node with a reactive verification companion.\n *\n * Uses `switchMap` so newer triggers cancel stale in-flight verification work.\n */\nexport function verifiable<T, TVerify = VerifyValue>(\n\tsource: NodeInput<T>,\n\tverifyFn: (value: T) => NodeInput<TVerify>,\n\topts?: VerifiableOptions<TVerify>,\n): VerifiableBundle<T, TVerify> {\n\tconst sourceNode = fromAny(source);\n\tconst hasSourceVersioning = sourceNode.v != null;\n\tconst verified = state<TVerify | null>(opts?.initialVerified ?? null, {\n\t\t...(hasSourceVersioning ? { meta: { sourceVersion: null } } : {}),\n\t});\n\tconst hasTrigger = opts?.trigger !== undefined && opts.trigger !== null;\n\n\tlet triggerNode: Node<unknown> | null = null;\n\tif (hasTrigger && opts?.autoVerify) {\n\t\ttriggerNode = merge(fromAny(opts.trigger) as Node<unknown>, sourceNode as Node<unknown>);\n\t} else if (hasTrigger) {\n\t\ttriggerNode = fromAny(opts.trigger);\n\t} else if (opts?.autoVerify) {\n\t\ttriggerNode = sourceNode as Node<unknown>;\n\t}\n\n\tif (triggerNode !== null) {\n\t\t// Closes P3 audit #2. Two patterns used depending on trigger shape:\n\t\t// - autoVerify-only (triggerNode === sourceNode): the projected\n\t\t// switchMap value IS the source DATA, pass it directly.\n\t\t// - explicit trigger: capture the source value into a closure\n\t\t// (`latestSource`) seeded from `sourceNode.cache` at wiring time\n\t\t// (§3.6 boundary read) and kept current via a subscribe handler.\n\t\t// The switchMap fn reads the closure, never `sourceNode.cache`\n\t\t// from a reactive context.\n\t\tlet verifyStream: Node<TVerify>;\n\t\tif (triggerNode === (sourceNode as Node<unknown>)) {\n\t\t\tverifyStream = switchMap(sourceNode, (src) => verifyFn(src as T));\n\t\t} else {\n\t\t\tlet latestSource: T | undefined = sourceNode.cache as T | undefined;\n\t\t\tsourceNode.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) latestSource = m[1] as T;\n\t\t\t\t}\n\t\t\t});\n\t\t\tverifyStream = switchMap(triggerNode, () => verifyFn(latestSource as T));\n\t\t}\n\t\tforEach(verifyStream, (value) => {\n\t\t\tbatch(() => {\n\t\t\t\tverified.down([[DATA, value]]);\n\t\t\t\t// V0 backfill: stamp which source version was verified (§6.0b).\n\t\t\t\tif (hasSourceVersioning) {\n\t\t\t\t\tconst sv = sourceNode.v;\n\t\t\t\t\tif (sv != null) {\n\t\t\t\t\t\tverified.meta.sourceVersion.down([[DATA, { id: sv.id, version: sv.version }]]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\treturn { node: sourceNode, verified, trigger: triggerNode };\n}\n\nexport type Extraction<TMem> = {\n\tupsert: Array<{ key: string; value: TMem }>;\n\tremove?: string[];\n};\n\nexport type DistillOptions<TMem> = {\n\tscore: (mem: TMem, context: unknown) => number;\n\tcost: (mem: TMem) => number;\n\tbudget?: number;\n\tevict?: (key: string, mem: TMem) => boolean | Node<boolean>;\n\tconsolidate?: (entries: ReadonlyMap<string, TMem>) => NodeInput<Extraction<TMem>>;\n\tconsolidateTrigger?: NodeInput<unknown>;\n\tcontext?: NodeInput<unknown>;\n\tmapOptions?: ReactiveMapOptions<string, TMem>;\n};\n\nexport type DistillBundle<TMem> = {\n\tstore: ReactiveMapBundle<string, TMem>;\n\tcompact: Node<Array<{ key: string; value: TMem; score: number }>>;\n\tsize: Node<number>;\n};\n\nfunction keepalive(node: Node): void {\n\tnode.subscribe(() => undefined);\n}\n\nfunction mapFromSnapshot<TMem>(snapshot: unknown): ReadonlyMap<string, TMem> {\n\tif (snapshot instanceof Map) return snapshot as ReadonlyMap<string, TMem>;\n\treturn new Map<string, TMem>();\n}\n\nfunction applyExtraction<TMem>(\n\tstore: ReactiveMapBundle<string, TMem>,\n\textraction: Extraction<TMem>,\n): void {\n\tif (!Array.isArray(extraction.upsert)) {\n\t\tthrow new TypeError(\"distill extraction requires upsert: Array<{ key, value }>\");\n\t}\n\tbatch(() => {\n\t\tfor (const { key, value } of extraction.upsert) {\n\t\t\tstore.set(key, value);\n\t\t}\n\t\tfor (const key of extraction.remove ?? []) {\n\t\t\tstore.delete(key);\n\t\t}\n\t});\n}\n\n/**\n * Budget-constrained reactive memory composition.\n */\nexport function distill<TRaw, TMem>(\n\tsource: NodeInput<TRaw>,\n\textractFn: (raw: TRaw, existing: ReadonlyMap<string, TMem>) => NodeInput<Extraction<TMem>>,\n\topts: DistillOptions<TMem>,\n): DistillBundle<TMem> {\n\tconst sourceNode = fromAny(source);\n\tconst store = reactiveMap<string, TMem>(opts.mapOptions ?? {});\n\tconst budget = opts.budget ?? 2000;\n\tconst hasContext = opts.context !== undefined && opts.context !== null;\n\tconst contextNode = hasContext ? fromAny(opts.context) : state<unknown>(null);\n\n\t// Closes P3 audit #7. `latestStore` is seeded at wiring time (§3.6\n\t// boundary read) and kept current via a subscribe handler. `extractFn`\n\t// and `consolidate` read the closure, never `store.entries.cache` from\n\t// inside a reactive callback. `withLatestFrom` would swallow the initial\n\t// source emission because primary's push-on-subscribe fires before\n\t// secondary subscribes — same reason stratify/budgetGate use this pattern.\n\tlet latestStore: ReadonlyMap<string, TMem> = mapFromSnapshot<TMem>(store.entries.cache);\n\tstore.entries.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA) latestStore = mapFromSnapshot<TMem>(m[1]);\n\t\t}\n\t});\n\n\tconst extractionStream = switchMap(sourceNode, (raw) => extractFn(raw as TRaw, latestStore));\n\tforEach(extractionStream, (extraction) => {\n\t\tapplyExtraction(store, extraction);\n\t});\n\n\tif (opts.evict) {\n\t\t// Track active verdict-node subscriptions so we can react to Node<boolean> changes.\n\t\tconst verdictUnsubs = new Map<string, () => void>();\n\n\t\tconst evictionKeys = derived([store.entries], ([snapshot]) => {\n\t\t\tconst out: string[] = [];\n\t\t\tconst entries = mapFromSnapshot<TMem>(snapshot);\n\t\t\t// Clean up verdict subscriptions for removed keys.\n\t\t\tfor (const key of verdictUnsubs.keys()) {\n\t\t\t\tif (!entries.has(key)) {\n\t\t\t\t\tverdictUnsubs.get(key)!();\n\t\t\t\t\tverdictUnsubs.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [key, mem] of entries) {\n\t\t\t\tconst verdict = opts.evict!(key, mem);\n\t\t\t\tif (isNodeLike<boolean>(verdict)) {\n\t\t\t\t\t// Subscribe if not already — push-on-subscribe fires with\n\t\t\t\t\t// the verdict's current value on first subscribe, so an\n\t\t\t\t\t// already-true verdict deletes via the callback without\n\t\t\t\t\t// needing a `verdict.cache` read (closes P3 audit #3).\n\t\t\t\t\t// Future transitions to `true` flow through the same path.\n\t\t\t\t\tif (!verdictUnsubs.has(key)) {\n\t\t\t\t\t\tconst unsub = forEach(verdict, (val) => {\n\t\t\t\t\t\t\tif (val === true && store.has(key)) {\n\t\t\t\t\t\t\t\tstore.delete(key);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\tverdictUnsubs.set(key, unsub);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (typeof verdict === \"boolean\") {\n\t\t\t\t\tif (verdict) out.push(key);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new TypeError(\"distill evict() must return boolean or Node<boolean>\");\n\t\t\t}\n\t\t\treturn out;\n\t\t});\n\t\tforEach(evictionKeys, (keys) => {\n\t\t\tfor (const key of keys) store.delete(key);\n\t\t});\n\t}\n\n\tconst hasConsolidateTrigger =\n\t\topts.consolidateTrigger !== undefined && opts.consolidateTrigger !== null;\n\tif (opts.consolidate && hasConsolidateTrigger) {\n\t\tconst consolidateTriggerNode = fromAny(opts.consolidateTrigger);\n\t\tconst consolidationStream = switchMap(consolidateTriggerNode, () =>\n\t\t\topts.consolidate!(latestStore),\n\t\t);\n\t\tforEach(consolidationStream, (extraction) => {\n\t\t\tapplyExtraction(store, extraction);\n\t\t});\n\t}\n\n\tconst compact = derived([store.entries, contextNode], ([snapshot, context]) => {\n\t\tconst entries = [...mapFromSnapshot<TMem>(snapshot).entries()].map(([key, value]) => ({\n\t\t\tkey,\n\t\t\tvalue,\n\t\t\tscore: opts.score(value, context),\n\t\t\tcost: opts.cost(value),\n\t\t}));\n\t\tentries.sort((a, b) => b.score - a.score);\n\n\t\tconst packed: Array<{ key: string; value: TMem; score: number }> = [];\n\t\tlet remaining = budget;\n\t\tfor (const item of entries) {\n\t\t\tif (item.cost <= remaining) {\n\t\t\t\tpacked.push({ key: item.key, value: item.value, score: item.score });\n\t\t\t\tremaining -= item.cost;\n\t\t\t}\n\t\t}\n\t\treturn packed;\n\t});\n\n\tconst size = derived([store.entries], ([snapshot]) => mapFromSnapshot<TMem>(snapshot).size);\n\tkeepalive(compact);\n\tkeepalive(size);\n\n\treturn { store, compact, size };\n}\n","// ---------------------------------------------------------------------------\n// RxJS bridge — reactive interop between GraphReFly nodes and RxJS Observables.\n// ---------------------------------------------------------------------------\n// Usage:\n// import { toObservable } from '@graphrefly/graphrefly-ts/extra';\n// const values$ = toObservable(myNode); // Observable<T>\n// const msgs$ = toObservable(myNode, { raw: true }); // Observable<Messages>\n// ---------------------------------------------------------------------------\n\nimport { Observable } from \"rxjs\";\nimport { COMPLETE, DATA, ERROR, type Messages } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\n\n/** Options for {@link toObservable}. */\nexport type ToObservableOptions = {\n\t/**\n\t * When `true`, emit raw `Messages` batches instead of extracted `DATA` values.\n\t * Terminal batches are still emitted as the final `next()` before the\n\t * Observable signal (error/complete).\n\t */\n\traw?: boolean;\n};\n\n/**\n * Bridge a `Node<T>` to an RxJS `Observable`.\n *\n * Default mode emits the node's value on each `DATA` message. Maps `ERROR` to\n * `subscriber.error()` and `COMPLETE` to `subscriber.complete()`.\n * Protocol-internal signals (DIRTY, RESOLVED, PAUSE, etc.) are skipped.\n *\n * With `{ raw: true }`, emits full `[[Type, Data?], ...]` message batches.\n * The Observable terminates on ERROR or COMPLETE (the terminal batch is still\n * emitted as the final `next()` before the Observable signal).\n *\n * For graph-level observation, use `toObservable(graph.resolve(path))` or\n * subscribe to `graph.observe()` directly.\n *\n * Unsubscribing the Observable unsubscribes the node.\n */\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions & { raw?: false },\n): Observable<T>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions: ToObservableOptions & { raw: true },\n): Observable<Messages>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions,\n): Observable<T | Messages> {\n\tif (options?.raw) {\n\t\treturn new Observable<Messages>((subscriber) => {\n\t\t\tconst unsub = node.subscribe((msgs) => {\n\t\t\t\tif (subscriber.closed) return;\n\t\t\t\tsubscriber.next(msgs);\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\t\tsubscriber.error(m[1]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\t\tsubscriber.complete();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn unsub;\n\t\t});\n\t}\n\n\treturn new Observable<T>((subscriber) => {\n\t\tconst unsub = node.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (subscriber.closed) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tsubscriber.next(m[1] as T);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tsubscriber.error(m[1]);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tsubscriber.complete();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn unsub;\n\t});\n}\n","/**\n * Lazy per-topic state hub (roadmap §3.2) — lightweight last-value broadcasts.\n *\n * Each topic is a sentinel `node<unknown>()` with push-on-subscribe replay of\n * the most recent published value (no push until the first `publish`). For\n * Pulsar-inspired retained message logs,\n * cursor-based subscriptions, and job-queue semantics, use `messagingHub()` in\n * `patterns/messaging.ts` — built on `TopicGraph` / `SubscriptionGraph` with\n * retention policies, absolute cursor tracking, and per-subscriber state.\n *\n * **Wave 4 refactor (2026-04-15):** Introduces `PubSubBackend` (thin registry\n * with version counter). Converts class-based hub to closure factory for\n * consistency with other `extra/` factories. New bundle APIs: `has(name)`,\n * `size`, `topicNames()`, `publishMany(entries)`. `removeTopic` → `TEARDOWN`\n * semantics preserved.\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { TEARDOWN } from \"../core/messages.js\";\nimport { type Node, node } from \"../core/node.js\";\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link pubsub} — registry only.\n *\n * Tracks the set of topic names plus a monotonic `version` counter that\n * advances on topic create/remove. Does NOT own per-topic message storage —\n * per-topic cached last values live in the topic nodes themselves (sentinel\n * until the first publish).\n *\n * For distributed / persistent per-topic storage, use `messagingHub()` in\n * `patterns/messaging.ts`, which composes `TopicGraph` under a lazy registry.\n *\n * @category extra\n */\nexport interface PubSubBackend {\n\t/** Monotonic counter; advances on topic create/remove. */\n\treadonly version: number;\n\treadonly topicCount: number;\n\thasTopic(name: string): boolean;\n\ttopicNames(): IterableIterator<string>;\n\t/** Records topic creation. Returns `true` if newly added (advances `version`). */\n\tcreateTopic(name: string): boolean;\n\t/** Records topic removal. Returns `true` if it existed (advances `version`). */\n\tremoveTopic(name: string): boolean;\n}\n\n/**\n * Default in-memory registry backend.\n *\n * @category extra\n */\nexport class NativePubSubBackend implements PubSubBackend {\n\tprivate _version = 0;\n\tprivate readonly _topics = new Set<string>();\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget topicCount(): number {\n\t\treturn this._topics.size;\n\t}\n\n\thasTopic(name: string): boolean {\n\t\treturn this._topics.has(name);\n\t}\n\n\ttopicNames(): IterableIterator<string> {\n\t\treturn this._topics.values();\n\t}\n\n\tcreateTopic(name: string): boolean {\n\t\tif (this._topics.has(name)) return false;\n\t\tthis._topics.add(name);\n\t\tthis._version += 1;\n\t\treturn true;\n\t}\n\n\tremoveTopic(name: string): boolean {\n\t\tconst had = this._topics.delete(name);\n\t\tif (had) this._version += 1;\n\t\treturn had;\n\t}\n}\n\n// ── Hub ───────────────────────────────────────────────────────────────────\n\nexport type PubSubHubOptions = {\n\t/**\n\t * Storage backend. Defaults to `NativePubSubBackend`. Pluggable for audit /\n\t * monitoring / mirror-to-external-broker use cases.\n\t */\n\tbackend?: PubSubBackend;\n};\n\n/**\n * Lazy per-topic state hub. Topics are single-value sentinel nodes\n * with push-on-subscribe replay of the most recent publish.\n *\n * @category extra\n */\nexport interface PubSubHub {\n\t/**\n\t * Returns the topic node, creating it on first use.\n\t *\n\t * @param name - Topic key.\n\t * @returns `Node` whose value is the last published payload. Starts in\n\t * sentinel state — no push-on-subscribe until the first publish.\n\t */\n\ttopic(name: string): Node<unknown>;\n\t/** Publishes a value to the topic (lazily creating the topic if missing). */\n\tpublish(name: string, value: unknown): void;\n\t/**\n\t * Bulk publish — single outer batch for all entries. No-op if empty.\n\t *\n\t * **Iterable consumption (F6):** `entries` is consumed once (single-pass).\n\t * Pass an array or `Set` for multi-shot callers. Iteration happens INSIDE\n\t * the batch frame — if the iterator throws mid-way, the batch is discarded\n\t * and NO publishes are visible to subscribers (all-or-nothing within one\n\t * call).\n\t */\n\tpublishMany(entries: Iterable<[string, unknown]>): void;\n\t/** Removes a topic; sends `TEARDOWN` to its node. Returns `true` if it existed. */\n\tremoveTopic(name: string): boolean;\n\t/** Checks topic existence without creating. O(1). */\n\thas(name: string): boolean;\n\t/** Number of topics currently registered. O(1). */\n\treadonly size: number;\n\t/** Iterator over topic names. */\n\ttopicNames(): IterableIterator<string>;\n}\n\n/**\n * Creates a lazy per-topic state hub.\n *\n * @param options - Optional pluggable `backend` (defaults to `NativePubSubBackend`).\n * @returns Hub with lazy `topic()` / `publish()` / `publishMany()` / `removeTopic()` /\n * `has()` / `size` / `topicNames()`.\n *\n * @remarks\n * **Scope:** Each topic is a sentinel node — retains only the last published\n * value (no push-on-subscribe before the first publish). For Pulsar-inspired\n * retention + cursor reading, use\n * `messagingHub()` in `patterns/messaging.ts`.\n *\n * **`removeTopic`:** Sends `TEARDOWN` to the topic node; all subscribers receive\n * the TEARDOWN message. Subsequent `publish(name, value)` silently recreates the\n * topic with a fresh node — existing subscribers to the old node do NOT reconnect.\n *\n * @example\n * ```ts\n * import { pubsub } from \"@graphrefly/graphrefly-ts\";\n *\n * const hub = pubsub();\n * const t = hub.topic(\"events\");\n * t.subscribe((msgs) => console.log(msgs));\n * hub.publish(\"events\", { ok: true });\n * hub.publishMany([[\"events\", 1], [\"status\", \"ready\"]]);\n * ```\n *\n * @category extra\n */\nexport function pubsub(options: PubSubHubOptions = {}): PubSubHub {\n\tconst { backend: userBackend } = options;\n\tconst backend: PubSubBackend = userBackend ?? new NativePubSubBackend();\n\tconst nodes = new Map<string, Node<unknown>>();\n\n\tfunction ensureTopic(name: string): Node<unknown> {\n\t\tlet n = nodes.get(name);\n\t\tif (n === undefined) {\n\t\t\tn = node<unknown>({ describeKind: \"state\" });\n\t\t\tnodes.set(name, n);\n\t\t\tbackend.createTopic(name);\n\t\t}\n\t\treturn n;\n\t}\n\n\treturn {\n\t\ttopic(name: string): Node<unknown> {\n\t\t\treturn ensureTopic(name);\n\t\t},\n\n\t\tpublish(name: string, value: unknown): void {\n\t\t\t// P7: use emit() so the pipeline auto-prefixes DIRTY, runs equals\n\t\t\t// substitution (if user configured one on a custom topic node),\n\t\t\t// and produces the proper two-phase wave.\n\t\t\tensureTopic(name).emit(value);\n\t\t},\n\n\t\tpublishMany(entries: Iterable<[string, unknown]>): void {\n\t\t\t// P1: iterate INSIDE the batch so a mid-iteration throw is\n\t\t\t// contained by the batch frame (no partial-publish leak) and\n\t\t\t// memory stays bounded — no intermediate array from `[...entries]`.\n\t\t\tbatch(() => {\n\t\t\t\tfor (const [name, value] of entries) {\n\t\t\t\t\tensureTopic(name).emit(value);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tremoveTopic(name: string): boolean {\n\t\t\tconst n = nodes.get(name);\n\t\t\tif (n === undefined) return false;\n\t\t\t// Delete from map + backend BEFORE sending TEARDOWN (P2). A\n\t\t\t// synchronous TEARDOWN handler that calls `hub.publish(name, v)`\n\t\t\t// would otherwise race: `ensureTopic` finds no entry, creates a\n\t\t\t// fresh node, backend records the re-creation — then the cleanup\n\t\t\t// below would delete the NEW node, leaking a subscriber on it.\n\t\t\tnodes.delete(name);\n\t\t\tbackend.removeTopic(name);\n\t\t\tn.down([[TEARDOWN]]);\n\t\t\treturn true;\n\t\t},\n\n\t\thas(name: string): boolean {\n\t\t\treturn backend.hasTopic(name);\n\t\t},\n\n\t\tget size(): number {\n\t\t\treturn backend.topicCount;\n\t\t},\n\n\t\ttopicNames(): IterableIterator<string> {\n\t\t\treturn backend.topicNames();\n\t\t},\n\t};\n}\n","/**\n * Dual-key sorted index (roadmap §3.2) — unique primary key, rows ordered by `(secondary, primary)`.\n *\n * Emits `readonly IndexRow[]` snapshots directly — no `Versioned` wrapper (spec §5.12).\n *\n * **Wave 4 pilot (2026-04-15):** Introduces the `IndexBackend<K, V>` pluggable-backend interface.\n * The default `NativeIndexBackend` maintains a parallel `Map<K, IndexRow>` for O(1) `has`/`get`\n * and eliminates the O(n) filter pass during `upsert`/`delete`. A monotonic `version` counter\n * on the backend tracks mutations — foundation for post-1.0 op-log changesets.\n */\nimport { batch } from \"../core/batch.js\";\nimport { DATA, DIRTY } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { derived, state } from \"../core/sugar.js\";\nimport type { VersioningLevel } from \"../core/versioning.js\";\n\nexport type IndexRow<K, V = unknown> = {\n\treadonly primary: K;\n\treadonly secondary: unknown;\n\treadonly value: V;\n};\n\nexport type ReactiveIndexOptions<K, V = unknown> = {\n\t/** Optional registry name for `describe()` / debugging. */\n\tname?: string;\n\t/**\n\t * Storage backend. Defaults to `NativeIndexBackend` (flat array + parallel `Map<K,IndexRow>`).\n\t * Users can plug in persistent / B-tree backends via the {@link IndexBackend} interface.\n\t */\n\tbackend?: IndexBackend<K, V>;\n\t/**\n\t * Optional versioning level for the underlying `ordered` state node. Set at\n\t * construction time; cannot be changed later. Pass `0` for V0 identity +\n\t * monotonic version counter, or `1` for V1 + content-addressed cid.\n\t * (The `byPrimary` derived node inherits through the dep graph.)\n\t */\n\tversioning?: VersioningLevel;\n\t/**\n\t * Default row-equality used to short-circuit idempotent upserts. When\n\t * provided, every `upsert` / `upsertMany` that finds an existing primary\n\t * compares the stored and candidate rows via `equals(existing, next)` —\n\t * on `true` the call is a no-op (no version bump, no emission). Per-call\n\t * `UpsertOptions.equals` overrides this default. Analogous to\n\t * `NodeOptions.equals` on the core `node()` primitive.\n\t */\n\tequals?: (existing: IndexRow<K, V>, next: IndexRow<K, V>) => boolean;\n};\n\nexport type ReactiveIndexBundle<K, V = unknown> = {\n\t/** Rows sorted by `(secondary, primary)`. */\n\treadonly ordered: Node<readonly IndexRow<K, V>[]>;\n\t/** Map from primary key to stored value. */\n\treadonly byPrimary: Node<ReadonlyMap<K, V>>;\n\t/** O(1) primary-key existence check. */\n\thas: (primary: K) => boolean;\n\t/** O(1) value lookup by primary key. */\n\tget: (primary: K) => V | undefined;\n\t/** Number of rows currently in the index (O(1)). */\n\treadonly size: number;\n\t/**\n\t * Upserts a row. When `opts.equals(existing, next)` returns `true` for an\n\t * existing primary key, the upsert is a no-op (no version bump, no emission).\n\t * Useful for idempotent writes.\n\t *\n\t * @returns `true` if a new row was inserted (primary key was absent),\n\t * `false` if the primary key was already present (updated in place OR\n\t * skipped idempotently via `opts.equals`). D5(a).\n\t */\n\tupsert: (primary: K, secondary: unknown, value: V, opts?: UpsertOptions<K, V>) => boolean;\n\t/**\n\t * Bulk upsert — emits one snapshot for the whole batch. `opts.equals` applied\n\t * per-row. No-op if empty or all rows skipped.\n\t *\n\t * **Iterable consumption:** Consumes `rows` once (single-pass).\n\t */\n\tupsertMany: (\n\t\trows: Iterable<{ primary: K; secondary: unknown; value: V }>,\n\t\topts?: UpsertOptions<K, V>,\n\t) => void;\n\tdelete: (primary: K) => void;\n\t/**\n\t * Bulk delete — emits one snapshot for the whole batch. No-op if nothing was removed.\n\t *\n\t * **Iterable consumption:** Consumes `primaries` once (single-pass).\n\t */\n\tdeleteMany: (primaries: Iterable<K>) => void;\n\tclear: () => void;\n\t/**\n\t * Releases internal keepalive subscriptions (on `byPrimary`) so the bundle\n\t * can be GC'd. Safe to call more than once (subsequent calls are no-ops).\n\t * Subsequent mutations after `dispose()` still execute on the backend but\n\t * `byPrimary` may stop updating if no external subscriber is attached.\n\t * D6(a).\n\t */\n\tdispose: () => void;\n};\n\n// ── Ordering ──────────────────────────────────────────────────────────────\n\n/** Lexicographic ordering for index keys (mirrors Python tuple compare for typical primitives). */\nfunction cmpOrd(a: unknown, b: unknown): number {\n\tif (a === b) return 0;\n\tconst ta = typeof a;\n\tconst tb = typeof b;\n\tif (ta === tb && (ta === \"number\" || ta === \"string\" || ta === \"boolean\" || ta === \"bigint\")) {\n\t\tconst ax = a as number | string | boolean | bigint;\n\t\tconst bx = b as number | string | boolean | bigint;\n\t\tif (ax < bx) return -1;\n\t\tif (ax > bx) return 1;\n\t\treturn 0;\n\t}\n\treturn String(a).localeCompare(String(b));\n}\n\nfunction compareKeys<K>(a: [unknown, K], b: [unknown, K]): number {\n\tconst c = cmpOrd(a[0], b[0]);\n\tif (c !== 0) return c;\n\treturn cmpOrd(a[1], b[1]);\n}\n\nfunction rowKey<K, V>(row: IndexRow<K, V>): [unknown, K] {\n\treturn [row.secondary, row.primary];\n}\n\nfunction bisectLeft<K, V>(rows: readonly IndexRow<K, V>[], row: IndexRow<K, V>): number {\n\tconst k = rowKey(row);\n\tlet lo = 0;\n\tlet hi = rows.length;\n\twhile (lo < hi) {\n\t\tconst mid = (lo + hi) >> 1;\n\t\tif (compareKeys(k, rowKey(rows[mid]!)) > 0) lo = mid + 1;\n\t\telse hi = mid;\n\t}\n\treturn lo;\n}\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link reactiveIndex}. Implementations own the mutable state and\n * expose a monotonic `version` counter that increments on every structural change.\n *\n * The reactive layer reads `version` to decide when to emit; it does not inspect\n * internal representation. Users can plug in B-tree / skip-list / persistent backends\n * without touching the reactive emission logic.\n *\n * @remarks Post-1.0 op-log changesets will extend this interface with a\n * `changesSince(version: number): Iterable<Change>` method. Current consumers\n * should treat all methods here as stable.\n *\n * @category extra\n */\n/**\n * Optional per-call options for {@link IndexBackend.upsert} and bulk upsert.\n *\n * @category extra\n */\nexport type UpsertOptions<K, V> = {\n\t/**\n\t * Skip the upsert if an existing row is considered equal to the proposed row.\n\t * Default: no skip — every upsert advances `version`. Provide for idempotent\n\t * keys (e.g., `(a, b) => a.secondary === b.secondary && a.value === b.value`).\n\t */\n\tequals?: (existing: IndexRow<K, V>, next: IndexRow<K, V>) => boolean;\n};\n\nexport interface IndexBackend<K, V = unknown> {\n\t/** Monotonic mutation counter; increments on every upsert/delete/clear that changes state. */\n\treadonly version: number;\n\t/** Number of rows currently stored. */\n\treadonly size: number;\n\t/** O(1) primary-key existence check. */\n\thas(primary: K): boolean;\n\t/** Value lookup by primary key. */\n\tget(primary: K): V | undefined;\n\t/**\n\t * Insert or replace a row. Returns `true` if a row was inserted (primary\n\t * didn't exist), `false` otherwise (updated OR skipped via `opts.equals`).\n\t *\n\t * **Atomicity contract:** Either fully succeeds or throws before any state\n\t * change; `version` advances only on state change.\n\t */\n\tupsert(primary: K, secondary: unknown, value: V, opts?: UpsertOptions<K, V>): boolean;\n\t/**\n\t * Atomic bulk upsert. Returns the number of rows that caused a state change\n\t * (inserts + non-skipped updates). Advances `version` at most once.\n\t * No-op if iterable is empty or all rows skipped by `opts.equals`.\n\t *\n\t * **Consumes `rows` once** — pass an array for multi-shot consumers.\n\t */\n\tupsertMany(\n\t\trows: Iterable<{ primary: K; secondary: unknown; value: V }>,\n\t\topts?: UpsertOptions<K, V>,\n\t): number;\n\t/** Remove a row by primary key. Returns `true` if the row existed. Advances `version` only if true. */\n\tdelete(primary: K): boolean;\n\t/**\n\t * Atomic bulk delete. Returns count removed. Advances `version` at most once.\n\t * No-op if no keys were present. Consumes `primaries` once.\n\t */\n\tdeleteMany(primaries: Iterable<K>): number;\n\t/** Remove all rows. Returns the number removed. Advances `version` only if non-zero. */\n\tclear(): number;\n\t/** Rows in sorted `(secondary, primary)` order — fresh snapshot suitable for emission. */\n\ttoArray(): readonly IndexRow<K, V>[];\n\t/** Primary-key → value map — fresh snapshot. */\n\ttoPrimaryMap(): ReadonlyMap<K, V>;\n}\n\n/**\n * Default flat-array backend. Maintains `buf: IndexRow[]` sorted by `(secondary, primary)`\n * and a parallel `Map<K, IndexRow>` for O(1) primary-key lookup.\n *\n * **Complexity:**\n * - `has`, `get`: O(1)\n * - `upsert`: up to 2× O(log n) bisect (locate old + locate new) + up to 2× O(n) splice (remove-old + insert-new) = O(n)\n * - `upsertMany(k rows)`: O(k log n) bisect + O(k·n) splice worst case; single version bump\n * - `delete`: O(log n) bisect + O(n) splice = O(n)\n * - `deleteMany(k keys)`: O(k log n) + O(k·n) splice worst case; single version bump\n * - `clear`: O(1)\n * - `toArray`, `toPrimaryMap`: O(n)\n *\n * @category extra\n */\nexport class NativeIndexBackend<K, V = unknown> implements IndexBackend<K, V> {\n\tprivate _version = 0;\n\tprivate readonly _buf: IndexRow<K, V>[] = [];\n\tprivate readonly _byPrimary = new Map<K, IndexRow<K, V>>();\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget size(): number {\n\t\treturn this._buf.length;\n\t}\n\n\thas(primary: K): boolean {\n\t\treturn this._byPrimary.has(primary);\n\t}\n\n\tget(primary: K): V | undefined {\n\t\treturn this._byPrimary.get(primary)?.value;\n\t}\n\n\tupsert(primary: K, secondary: unknown, value: V, opts?: UpsertOptions<K, V>): boolean {\n\t\tconst existing = this._byPrimary.get(primary);\n\t\tconst row: IndexRow<K, V> = { primary, secondary, value };\n\t\tif (existing !== undefined && opts?.equals?.(existing, row)) {\n\t\t\t// Idempotent — no state change, no version advance.\n\t\t\treturn false;\n\t\t}\n\t\tif (existing !== undefined) {\n\t\t\t// Remove from current sorted position via bisect on the stored row.\n\t\t\tconst oldPos = bisectLeft(this._buf, existing);\n\t\t\tthis._buf.splice(oldPos, 1);\n\t\t}\n\t\tconst newPos = bisectLeft(this._buf, row);\n\t\tthis._buf.splice(newPos, 0, row);\n\t\tthis._byPrimary.set(primary, row);\n\t\tthis._version += 1;\n\t\treturn existing === undefined;\n\t}\n\n\tupsertMany(\n\t\trows: Iterable<{ primary: K; secondary: unknown; value: V }>,\n\t\topts?: UpsertOptions<K, V>,\n\t): number {\n\t\tlet changed = 0;\n\t\ttry {\n\t\t\tfor (const r of rows) {\n\t\t\t\tconst existing = this._byPrimary.get(r.primary);\n\t\t\t\tconst row: IndexRow<K, V> = {\n\t\t\t\t\tprimary: r.primary,\n\t\t\t\t\tsecondary: r.secondary,\n\t\t\t\t\tvalue: r.value,\n\t\t\t\t};\n\t\t\t\tif (existing !== undefined && opts?.equals?.(existing, row)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (existing !== undefined) {\n\t\t\t\t\tconst oldPos = bisectLeft(this._buf, existing);\n\t\t\t\t\tthis._buf.splice(oldPos, 1);\n\t\t\t\t}\n\t\t\t\tconst newPos = bisectLeft(this._buf, row);\n\t\t\t\tthis._buf.splice(newPos, 0, row);\n\t\t\t\tthis._byPrimary.set(r.primary, row);\n\t\t\t\tchanged += 1;\n\t\t\t}\n\t\t} finally {\n\t\t\t// D3: surface partial commits on iterator throw; \"at most once\" preserved.\n\t\t\tif (changed > 0) this._version += 1;\n\t\t}\n\t\treturn changed;\n\t}\n\n\tdelete(primary: K): boolean {\n\t\tconst existing = this._byPrimary.get(primary);\n\t\tif (existing === undefined) return false;\n\t\tconst pos = bisectLeft(this._buf, existing);\n\t\tthis._buf.splice(pos, 1);\n\t\tthis._byPrimary.delete(primary);\n\t\tthis._version += 1;\n\t\treturn true;\n\t}\n\n\tdeleteMany(primaries: Iterable<K>): number {\n\t\tlet removed = 0;\n\t\ttry {\n\t\t\tfor (const primary of primaries) {\n\t\t\t\tconst existing = this._byPrimary.get(primary);\n\t\t\t\tif (existing === undefined) continue;\n\t\t\t\tconst pos = bisectLeft(this._buf, existing);\n\t\t\t\tthis._buf.splice(pos, 1);\n\t\t\t\tthis._byPrimary.delete(primary);\n\t\t\t\tremoved += 1;\n\t\t\t}\n\t\t} finally {\n\t\t\tif (removed > 0) this._version += 1;\n\t\t}\n\t\treturn removed;\n\t}\n\n\tclear(): number {\n\t\tconst n = this._buf.length;\n\t\tif (n === 0) return 0;\n\t\tthis._buf.length = 0;\n\t\tthis._byPrimary.clear();\n\t\tthis._version += 1;\n\t\treturn n;\n\t}\n\n\ttoArray(): readonly IndexRow<K, V>[] {\n\t\treturn [...this._buf];\n\t}\n\n\ttoPrimaryMap(): ReadonlyMap<K, V> {\n\t\tconst m = new Map<K, V>();\n\t\tfor (const r of this._buf) m.set(r.primary, r.value);\n\t\treturn m;\n\t}\n}\n\n// ── Reactive wrapper ──────────────────────────────────────────────────────\n\nfunction keepaliveDerived(n: Node<unknown>): () => void {\n\treturn n.subscribe(() => {});\n}\n\n/**\n * Creates a reactive index: unique primary key per row, rows sorted by `(secondary, primary)` for ordered scans.\n *\n * @param options - Optional `name` for `describe()` / debugging, and optional `backend` (see {@link IndexBackend}).\n * @returns Bundle with `ordered` (sorted rows), `byPrimary` (map), O(1) `has` / `get` / `size`,\n * imperative `upsert` / `upsertMany` / `delete` / `deleteMany` / `clear`.\n *\n * @remarks\n * **Ordering:** `secondary` and `primary` are compared via a small total order: same primitive `typeof` uses\n * numeric/string/boolean/bigint comparison; mixed or object keys fall back to `String(a).localeCompare(String(b))`\n * (not identical to Python's rich comparison for exotic types).\n *\n * **Backend:** The default {@link NativeIndexBackend} offers O(1) primary-key lookups and O(n) upserts.\n * For scale beyond a few thousand rows, supply a user-pluggable persistent/B-tree backend via the\n * `backend` option — reactive emission semantics are unchanged.\n *\n * @example\n * ```ts\n * import { reactiveIndex } from \"@graphrefly/graphrefly-ts\";\n *\n * const idx = reactiveIndex<string, string>();\n * idx.upsert(\"id1\", 10, \"row-a\");\n * idx.upsert(\"id2\", 5, \"row-b\");\n * ```\n *\n * @category extra\n */\nexport function reactiveIndex<K, V = unknown>(\n\toptions: ReactiveIndexOptions<K, V> = {},\n): ReactiveIndexBundle<K, V> {\n\tconst { name, versioning, equals: defaultEquals, backend: userBackend } = options;\n\tconst backend: IndexBackend<K, V> = userBackend ?? new NativeIndexBackend<K, V>();\n\n\t// F1 override: merge factory-level `equals` into per-call UpsertOptions\n\t// so callers who set it once at construction get idempotent-key semantics\n\t// on every upsert without repeating the predicate.\n\tfunction withDefaultEquals(opts?: UpsertOptions<K, V>): UpsertOptions<K, V> | undefined {\n\t\tif (opts?.equals !== undefined) return opts;\n\t\tif (defaultEquals === undefined) return opts;\n\t\treturn { ...opts, equals: defaultEquals };\n\t}\n\n\tconst ordered = state<readonly IndexRow<K, V>[]>([], {\n\t\tname,\n\t\tdescribeKind: \"state\",\n\t\tequals: (a, b) => a === b,\n\t\t...(versioning != null ? { versioning } : {}),\n\t});\n\n\tconst byPrimary = derived(\n\t\t[ordered],\n\t\t([s]) => {\n\t\t\tconst rows = s as readonly IndexRow<K, V>[];\n\t\t\tconst m = new Map<K, V>();\n\t\t\tfor (const r of rows) m.set(r.primary, r.value);\n\t\t\treturn m;\n\t\t},\n\t\t{ initial: backend.toPrimaryMap(), describeKind: \"derived\" },\n\t);\n\tconst disposeByPrimaryKeepalive = keepaliveDerived(byPrimary);\n\tlet disposed = false;\n\n\tfunction pushSnapshot(): void {\n\t\tconst snapshot = backend.toArray();\n\t\tbatch(() => {\n\t\t\tordered.down([[DIRTY]]);\n\t\t\tordered.down([[DATA, snapshot]]);\n\t\t});\n\t}\n\n\t/**\n\t * Defense-in-depth emission guard: compares `version` before/after `op` and\n\t * emits a snapshot if advanced. `try/finally` surfaces partial-mutation\n\t * state from non-atomic custom backends even on thrown ops; native backends\n\t * are atomic by contract and won't reach the finally with a changed version.\n\t */\n\tfunction wrapMutation<R>(op: () => R): R {\n\t\tconst prev = backend.version;\n\t\ttry {\n\t\t\treturn op();\n\t\t} finally {\n\t\t\tif (backend.version !== prev) pushSnapshot();\n\t\t}\n\t}\n\n\treturn {\n\t\tordered,\n\t\tbyPrimary,\n\n\t\thas(primary: K): boolean {\n\t\t\treturn backend.has(primary);\n\t\t},\n\n\t\tget(primary: K): V | undefined {\n\t\t\treturn backend.get(primary);\n\t\t},\n\n\t\tget size(): number {\n\t\t\treturn backend.size;\n\t\t},\n\n\t\tupsert(primary: K, secondary: unknown, value: V, opts?: UpsertOptions<K, V>): boolean {\n\t\t\treturn wrapMutation(() => backend.upsert(primary, secondary, value, withDefaultEquals(opts)));\n\t\t},\n\n\t\tupsertMany(\n\t\t\trows: Iterable<{ primary: K; secondary: unknown; value: V }>,\n\t\t\topts?: UpsertOptions<K, V>,\n\t\t): void {\n\t\t\t// Extra: materialize the iterable at the public wrapper so a\n\t\t\t// caller who passes (e.g.) `index.ordered.cache` as input can't\n\t\t\t// have the splice-during-iteration semantics observed by the\n\t\t\t// backend. The backend mutates `_buf` on each upsert; if `rows`\n\t\t\t// aliased `_buf` (directly or via a wrapping iterator), iteration\n\t\t\t// would observe mid-mutation state. Arrays are iterator-snapshot\n\t\t\t// safe.\n\t\t\tconst list = [...rows];\n\t\t\tif (list.length === 0) return;\n\t\t\twrapMutation(() => backend.upsertMany(list, withDefaultEquals(opts)));\n\t\t},\n\n\t\tdelete(primary: K): void {\n\t\t\twrapMutation(() => backend.delete(primary));\n\t\t},\n\n\t\tdeleteMany(primaries: Iterable<K>): void {\n\t\t\t// Extra: materialize before mutating — same reasoning as upsertMany.\n\t\t\tconst list = [...primaries];\n\t\t\tif (list.length === 0) return;\n\t\t\twrapMutation(() => backend.deleteMany(list));\n\t\t},\n\n\t\tclear(): void {\n\t\t\twrapMutation(() => backend.clear());\n\t\t},\n\n\t\tdispose(): void {\n\t\t\tif (disposed) return;\n\t\t\tdisposed = true;\n\t\t\tdisposeByPrimaryKeepalive();\n\t\t},\n\t};\n}\n","/**\n * Reactive positional list (roadmap §3.2) — emits `readonly T[]` snapshots directly.\n *\n * Internal version counter drives efficient equality without leaking `Versioned`\n * into the public API (spec §5.12).\n *\n * **Wave 4 refactor (2026-04-15):** Introduces the `ListBackend<T>` pluggable-backend\n * interface. The default `NativeListBackend` uses a mutable array with a monotonic\n * `version` counter. No `maxSize` cap — bounded append-heavy workloads should use\n * `reactiveLog` (head-trim under cap is unambiguous for append-only; insert-anywhere\n * with a cap is not).\n */\nimport { batch } from \"../core/batch.js\";\nimport { DATA, DIRTY } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { state } from \"../core/sugar.js\";\nimport type { VersioningLevel } from \"../core/versioning.js\";\n\nexport type ReactiveListOptions<T> = {\n\tname?: string;\n\t/**\n\t * Storage backend. Defaults to `NativeListBackend` (flat mutable array).\n\t * Users can plug in persistent / RRB-tree backends via the {@link ListBackend} interface.\n\t */\n\tbackend?: ListBackend<T>;\n\t/**\n\t * Optional versioning level for the underlying `items` state node. Set at\n\t * construction time; cannot be changed later. Pass `0` for V0 identity +\n\t * monotonic version counter, or `1` for V1 + content-addressed cid.\n\t */\n\tversioning?: VersioningLevel;\n};\n\nexport type ReactiveListBundle<T> = {\n\t/** Emits `readonly T[]` on each structural change (two-phase). */\n\treadonly items: Node<readonly T[]>;\n\t/** Current entry count (O(1)). */\n\treadonly size: number;\n\t/** Positional access (O(1)); supports negative indices (Python-style). Returns `undefined` on out-of-range. */\n\tat: (index: number) => T | undefined;\n\tappend: (value: T) => void;\n\t/** Push all values, emit one snapshot. No-op if `values` is empty. */\n\tappendMany: (values: readonly T[]) => void;\n\t/** Insert a value at `index`. Throws `RangeError` on out-of-range. */\n\tinsert: (index: number, value: T) => void;\n\t/** Insert all values at `index` as one bulk op; emits one snapshot. No-op if `values` is empty. */\n\tinsertMany: (index: number, values: readonly T[]) => void;\n\t/** Remove and return the value at `index` (default: last). Negative indices Python-style. Throws on empty / out-of-range. */\n\tpop: (index?: number) => T;\n\tclear: () => void;\n\t/**\n\t * Releases any internal keepalive subscriptions so the bundle can be\n\t * GC'd. `reactiveList` currently holds none (no internal derived nodes),\n\t * so `dispose()` is a no-op today — exposed for API parity with\n\t * `reactiveIndex.dispose` / `reactiveMap.dispose` / `reactiveLog.dispose`.\n\t * Idempotent. D6(a).\n\t */\n\tdispose: () => void;\n};\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link reactiveList}. Implementations own the mutable state\n * and expose a monotonic `version` counter that increments on every structural change.\n *\n * The reactive layer reads `version` before and after each backend call; when it\n * advances, a snapshot is emitted.\n *\n * @remarks Post-1.0 op-log changesets will extend this interface with a\n * `changesSince(version: number): Iterable<Change>` method. Current consumers\n * should treat all methods here as stable.\n *\n * @category extra\n */\nexport interface ListBackend<T> {\n\t/** Monotonic mutation counter; increments on every structural change. */\n\treadonly version: number;\n\t/** Number of items currently stored. */\n\treadonly size: number;\n\t/** Positional access; `undefined` on out-of-range. */\n\tat(index: number): T | undefined;\n\t/** Append a single value. Advances `version`. */\n\tappend(value: T): void;\n\t/** Append a batch. Advances `version` once. No-op if empty. */\n\tappendMany(values: readonly T[]): void;\n\t/** Insert at index; throws `RangeError` on out-of-range `0 <= index <= size`. Advances `version`. */\n\tinsert(index: number, value: T): void;\n\t/** Bulk insert at index; throws on out-of-range. Advances `version` once. No-op if `values` empty. */\n\tinsertMany(index: number, values: readonly T[]): void;\n\t/** Remove and return value at index; throws on empty / out-of-range. Advances `version`. */\n\tpop(index: number): T;\n\t/** Clear all entries. Returns count removed. Advances `version` only if non-zero. */\n\tclear(): number;\n\t/** Full snapshot as a fresh array. */\n\ttoArray(): readonly T[];\n}\n\n/**\n * Default mutable-array backend.\n *\n * **Complexity:**\n * - `at`, `size`: O(1)\n * - `append`: O(1) amortized\n * - `appendMany(values)`, `insertMany(index, values)`: O(n + k) where k = values.length\n * - `insert`, `pop` (middle): O(n) due to splice\n * - `pop` (last): O(1)\n * - `clear`: O(1)\n * - `toArray`: O(n)\n *\n * @category extra\n */\nexport class NativeListBackend<T> implements ListBackend<T> {\n\tprivate _version = 0;\n\tprivate readonly _buf: T[];\n\n\tconstructor(initial?: readonly T[]) {\n\t\tthis._buf = initial ? [...initial] : [];\n\t}\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget size(): number {\n\t\treturn this._buf.length;\n\t}\n\n\tat(index: number): T | undefined {\n\t\tif (!Number.isInteger(index)) return undefined;\n\t\tconst i = index >= 0 ? index : this._buf.length + index;\n\t\tif (i < 0 || i >= this._buf.length) return undefined;\n\t\treturn this._buf[i];\n\t}\n\n\tappend(value: T): void {\n\t\tthis._buf.push(value);\n\t\tthis._version += 1;\n\t}\n\n\tappendMany(values: readonly T[]): void {\n\t\tif (values.length === 0) return;\n\t\t// Extra: avoid `this._buf.push(...values)` — spread-push has an\n\t\t// engine-dependent stack-argument limit (typically ~100k–500k), so\n\t\t// very large bulk inserts can throw \"Maximum call stack size exceeded\".\n\t\t// Indexed write is O(n) and has no spread limit.\n\t\tconst oldLen = this._buf.length;\n\t\tthis._buf.length = oldLen + values.length;\n\t\tfor (let i = 0; i < values.length; i++) {\n\t\t\tthis._buf[oldLen + i] = values[i] as T;\n\t\t}\n\t\tthis._version += 1;\n\t}\n\n\tinsert(index: number, value: T): void {\n\t\tif (!Number.isInteger(index) || index < 0 || index > this._buf.length) {\n\t\t\tthrow new RangeError(`insert: index ${index} out of range [0, ${this._buf.length}]`);\n\t\t}\n\t\tthis._buf.splice(index, 0, value);\n\t\tthis._version += 1;\n\t}\n\n\tinsertMany(index: number, values: readonly T[]): void {\n\t\tif (!Number.isInteger(index) || index < 0 || index > this._buf.length) {\n\t\t\tthrow new RangeError(`insertMany: index ${index} out of range [0, ${this._buf.length}]`);\n\t\t}\n\t\tif (values.length === 0) return;\n\t\tthis._buf.splice(index, 0, ...values);\n\t\tthis._version += 1;\n\t}\n\n\tpop(index: number): T {\n\t\tif (this._buf.length === 0) {\n\t\t\tthrow new RangeError(\"pop from empty list\");\n\t\t}\n\t\tif (!Number.isInteger(index)) {\n\t\t\tthrow new RangeError(`pop: index ${index} must be an integer`);\n\t\t}\n\t\tconst i = index >= 0 ? index : this._buf.length + index;\n\t\tif (i < 0 || i >= this._buf.length) {\n\t\t\tthrow new RangeError(`pop: index ${index} out of range`);\n\t\t}\n\t\tconst [v] = this._buf.splice(i, 1);\n\t\tthis._version += 1;\n\t\treturn v as T;\n\t}\n\n\tclear(): number {\n\t\tconst n = this._buf.length;\n\t\tif (n === 0) return 0;\n\t\tthis._buf.length = 0;\n\t\tthis._version += 1;\n\t\treturn n;\n\t}\n\n\ttoArray(): readonly T[] {\n\t\treturn [...this._buf];\n\t}\n}\n\n// ── Reactive wrapper ──────────────────────────────────────────────────────\n\n/**\n * Creates a reactive list with immutable array snapshots.\n *\n * @param initial - Optional initial items (copied).\n * @param options - Optional `name` for `describe()` / debugging, or pluggable `backend`.\n * @returns Bundle with `items` (state node), `size` / `at`, `append` / `appendMany` / `insert` /\n * `insertMany` / `pop` / `clear`.\n *\n * @remarks\n * **No `maxSize`:** insert/pop-anywhere semantics make eviction-under-cap ambiguous.\n * For bounded append-heavy workloads use `reactiveLog` (head-trim is well-defined for\n * append-only).\n *\n * **Backend:** Default {@link NativeListBackend}. For persistent / RRB-tree semantics\n * supply a custom {@link ListBackend}. If you provide a `backend`, `initial` is ignored\n * — seed the backend directly.\n *\n * @example\n * ```ts\n * import { reactiveList } from \"@graphrefly/graphrefly-ts\";\n *\n * const list = reactiveList<string>([\"a\"], { name: \"queue\" });\n * list.append(\"b\");\n * list.insertMany(1, [\"x\", \"y\"]);\n * ```\n *\n * @category extra\n */\nexport function reactiveList<T>(\n\tinitial?: readonly T[],\n\toptions: ReactiveListOptions<T> = {},\n): ReactiveListBundle<T> {\n\tconst { name, versioning, backend: userBackend } = options;\n\tconst backend: ListBackend<T> = userBackend ?? new NativeListBackend<T>(initial);\n\n\tconst items = state<readonly T[]>(backend.toArray(), {\n\t\tname,\n\t\tdescribeKind: \"state\",\n\t\tequals: (a, b) => a === b,\n\t\t...(versioning != null ? { versioning } : {}),\n\t});\n\n\tfunction pushSnapshot(): void {\n\t\tconst snapshot = backend.toArray();\n\t\tbatch(() => {\n\t\t\titems.down([[DIRTY]]);\n\t\t\titems.down([[DATA, snapshot]]);\n\t\t});\n\t}\n\n\t/**\n\t * D4(a): try/finally defense-in-depth — if a custom backend op throws\n\t * mid-mutation, surface the partial state via pushSnapshot so subscribers\n\t * don't see a stale cache. Native ops are atomic by contract; this only\n\t * matters for user-supplied backends. Mirrors the pattern in reactive-map,\n\t * reactive-index, and reactive-log.\n\t */\n\tfunction wrapMutation<R>(op: () => R): R {\n\t\tconst prev = backend.version;\n\t\ttry {\n\t\t\treturn op();\n\t\t} finally {\n\t\t\tif (backend.version !== prev) pushSnapshot();\n\t\t}\n\t}\n\n\treturn {\n\t\titems,\n\n\t\tget size(): number {\n\t\t\treturn backend.size;\n\t\t},\n\n\t\tat(index: number): T | undefined {\n\t\t\treturn backend.at(index);\n\t\t},\n\n\t\tappend(value: T): void {\n\t\t\twrapMutation(() => backend.append(value));\n\t\t},\n\n\t\tappendMany(values: readonly T[]): void {\n\t\t\twrapMutation(() => backend.appendMany(values));\n\t\t},\n\n\t\tinsert(index: number, value: T): void {\n\t\t\twrapMutation(() => backend.insert(index, value));\n\t\t},\n\n\t\tinsertMany(index: number, values: readonly T[]): void {\n\t\t\twrapMutation(() => backend.insertMany(index, values));\n\t\t},\n\n\t\tpop(index = -1): T {\n\t\t\treturn wrapMutation(() => backend.pop(index));\n\t\t},\n\n\t\tclear(): void {\n\t\t\twrapMutation(() => backend.clear());\n\t\t},\n\n\t\tdispose(): void {\n\t\t\t// D6(a): no internal keepalives — no-op for API parity. If a future\n\t\t\t// refactor adds a keepalive, wire its disposer here.\n\t\t},\n\t};\n}\n","/**\n * Reactive append-only log (roadmap §3.2) — emits `readonly T[]` snapshots directly.\n *\n * Internal version counter drives efficient equality without leaking `Versioned`\n * into the public API (spec §5.12).\n *\n * **Wave 4 refactor (2026-04-15):** Introduces the `LogBackend<T>` pluggable-backend\n * interface. The default `NativeLogBackend` uses a ring buffer when `maxSize` is set\n * (O(1) append + trim) and a flat array otherwise. `tail(n)` and `slice(start, stop)`\n * are memoized — repeat calls with identical arguments return the same derived node,\n * bounding the keepalive-subscription footprint. The standalone `logSlice` factory\n * has been removed; use `log.slice(start, stop)` instead.\n */\nimport { batch } from \"../core/batch.js\";\nimport { DATA, DIRTY } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { derived, state } from \"../core/sugar.js\";\nimport type { VersioningLevel } from \"../core/versioning.js\";\n\nexport type ReactiveLogOptions<T> = {\n\tname?: string;\n\tmaxSize?: number;\n\t/**\n\t * Optional versioning level for the underlying `entries` state node. Set\n\t * at construction time; cannot be changed later. Pass `0` for V0 identity\n\t * + monotonic version counter, or `1` for V1 + content-addressed cid.\n\t */\n\tversioning?: VersioningLevel;\n\t/**\n\t * Storage backend. Defaults to `NativeLogBackend` (ring buffer if `maxSize` is set,\n\t * flat array otherwise). Users can plug in persistent / RRB-tree backends via\n\t * the {@link LogBackend} interface.\n\t */\n\tbackend?: LogBackend<T>;\n};\n\nexport type ReactiveLogBundle<T> = {\n\t/** Emits `readonly T[]` on each append/clear/trim (two-phase). */\n\treadonly entries: Node<readonly T[]>;\n\t/** Current entry count (O(1)). */\n\treadonly size: number;\n\t/** Positional access (O(1)); returns `undefined` on out-of-range. Supports negative indices (Python-style). */\n\tat: (index: number) => T | undefined;\n\tappend: (value: T) => void;\n\t/**\n\t * Push all values, emit one snapshot. No-op if `values` is empty.\n\t * **Iterable consumption:** `values` is a `readonly T[]` — safe to pass arrays.\n\t */\n\tappendMany: (values: readonly T[]) => void;\n\tclear: () => void;\n\t/** Remove the first `n` entries (clamped to `size`). Throws on non-integer or negative `n`. */\n\ttrimHead: (n: number) => void;\n\t/**\n\t * Last `n` entries (or fewer) as a derived reactive view. Memoized with\n\t * an LRU cache (default cap 64) — repeat calls with the same `n` return\n\t * the same node. Throws on non-integer or negative `n`.\n\t *\n\t * **LRU eviction contract (D3(b)):** when a 65th distinct `n` is passed,\n\t * the least-recently-used cached view is evicted and its keepalive is\n\t * disposed. External holders of the evicted node will NOT receive further\n\t * updates — re-call `tail(n)` for a fresh node, or dispose proactively\n\t * via {@link disposeTail} / {@link disposeAllViews}. To avoid surprise:\n\t * resolve `tail(n)` at the point of use rather than caching the returned\n\t * node across many distinct `n`s.\n\t */\n\ttail: (n: number) => Node<readonly T[]>;\n\t/**\n\t * Reactive view of `entries.slice(start, stop)` — non-negative integer\n\t * `start`, non-negative integer `stop` (exclusive) or `undefined` (to end).\n\t * Memoized with an LRU cache (default cap 64) — repeat calls with the\n\t * same `(start, stop)` return the same node.\n\t *\n\t * Throws on non-integer `start`, negative `start`, non-integer `stop`, or\n\t * negative `stop` (P4 — the backend cannot cheaply honor JS-style\n\t * negative `stop` without scanning length; disallowed for a consistent\n\t * contract between backend, derived recomputation, and cached initial).\n\t *\n\t * **LRU eviction contract (D3(b)):** same as {@link tail} — past 64\n\t * distinct `(start, stop)` pairs, the oldest cached view is evicted and\n\t * its keepalive disposed. External holders stop receiving updates.\n\t */\n\tslice: (start: number, stop?: number) => Node<readonly T[]>;\n\t/**\n\t * Releases the cached `tail(n)` view if present (disposes its keepalive\n\t * subscription). Subsequent `tail(n)` calls create a fresh node. No-op if\n\t * `n` was not cached. Returns `true` if a view was disposed.\n\t */\n\tdisposeTail: (n: number) => boolean;\n\t/**\n\t * Releases the cached `slice(start, stop?)` view if present. No-op if not cached.\n\t */\n\tdisposeSlice: (start: number, stop?: number) => boolean;\n\t/** Releases all cached tail/slice views and their keepalive subscriptions. */\n\tdisposeAllViews: () => void;\n\t/**\n\t * Releases all internal keepalive subscriptions so the bundle can be\n\t * GC'd — currently equivalent to {@link disposeAllViews}, but exposed as\n\t * a uniform API across all reactive data structures for lifecycle\n\t * symmetry (mirrors `reactiveMap.dispose` / `reactiveList.dispose` /\n\t * `reactiveIndex.dispose`). Idempotent. D6(a).\n\t */\n\tdispose: () => void;\n};\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link reactiveLog}. Implementations own the mutable state and\n * expose a monotonic `version` counter that increments on every structural change.\n *\n * The reactive layer reads `version` to decide when to emit; it does not inspect\n * internal representation. Users can plug in persistent / ring-buffer / skip-list\n * backends without touching the reactive emission logic.\n *\n * @remarks Post-1.0 op-log changesets will extend this interface with a\n * `changesSince(version: number): Iterable<Change>` method. Current consumers\n * should treat all methods here as stable.\n *\n * @category extra\n */\nexport interface LogBackend<T> {\n\t/** Monotonic mutation counter; increments on every append/trim/clear that changes state. */\n\treadonly version: number;\n\t/** Number of entries currently stored. */\n\treadonly size: number;\n\t/** O(1) positional access; returns `undefined` on out-of-range. */\n\tat(index: number): T | undefined;\n\t/** Append a value. Applies `maxSize` head-drop if configured. Advances `version`. */\n\tappend(value: T): void;\n\t/** Append a batch; advances `version` once. No-op if `values.length === 0`. */\n\tappendMany(values: readonly T[]): void;\n\t/** Remove all entries. Returns count removed. Advances `version` only if non-zero. */\n\tclear(): number;\n\t/** Remove the first `n` entries (clamped). Returns count removed. Throws on negative `n`. */\n\ttrimHead(n: number): number;\n\t/** Fresh snapshot array for `[start, stop)`. Throws on negative `start`. */\n\tslice(start: number, stop?: number): readonly T[];\n\t/** Last `n` entries as a fresh array. Throws on negative `n`. */\n\ttail(n: number): readonly T[];\n\t/** Full snapshot as a fresh array. */\n\ttoArray(): readonly T[];\n}\n\n/**\n * Default append-only log backend.\n *\n * - When `maxSize` is set: uses a **ring buffer** with `_head` index and circular\n * modular arithmetic. Append and trim become O(1); snapshot is O(size) unrolling.\n * - When `maxSize` is unset: uses a flat array with standard push/splice.\n *\n * `appendMany` pre-trims oversize input: if `values.length > maxSize`, only the\n * tail of `values` is pushed (the rest would be immediately evicted).\n *\n * @category extra\n */\nexport class NativeLogBackend<T> implements LogBackend<T> {\n\tprivate _version = 0;\n\tprivate readonly _maxSize?: number;\n\tprivate readonly _buf: T[];\n\tprivate _head = 0;\n\tprivate _size = 0;\n\n\tconstructor(initial?: readonly T[], maxSize?: number) {\n\t\tif (maxSize !== undefined && maxSize < 1) {\n\t\t\tthrow new RangeError(\"maxSize must be >= 1\");\n\t\t}\n\t\tthis._maxSize = maxSize;\n\t\tif (maxSize !== undefined) {\n\t\t\t// Ring buffer mode — pre-allocate fixed size\n\t\t\tthis._buf = new Array(maxSize);\n\t\t\tif (initial && initial.length > 0) {\n\t\t\t\tconst take = Math.min(initial.length, maxSize);\n\t\t\t\tconst start = initial.length - take;\n\t\t\t\tfor (let i = 0; i < take; i++) {\n\t\t\t\t\tthis._buf[i] = initial[start + i]!;\n\t\t\t\t}\n\t\t\t\tthis._size = take;\n\t\t\t}\n\t\t} else {\n\t\t\t// Unbounded mode — dynamic array\n\t\t\tthis._buf = initial ? [...initial] : [];\n\t\t\tthis._size = this._buf.length;\n\t\t}\n\t}\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget size(): number {\n\t\treturn this._size;\n\t}\n\n\tat(index: number): T | undefined {\n\t\tif (!Number.isInteger(index)) return undefined;\n\t\t// P5: Python-style negative index — `-1` returns the last entry.\n\t\tconst i = index >= 0 ? index : this._size + index;\n\t\tif (i < 0 || i >= this._size) return undefined;\n\t\tif (this._maxSize !== undefined) {\n\t\t\treturn this._buf[(this._head + i) % this._maxSize];\n\t\t}\n\t\treturn this._buf[i];\n\t}\n\n\tappend(value: T): void {\n\t\tthis._rawAppend(value);\n\t\tthis._version += 1;\n\t}\n\n\tappendMany(values: readonly T[]): void {\n\t\tif (values.length === 0) return;\n\t\t// Pre-trim oversize input in ring mode — skip values that would be\n\t\t// immediately evicted. Iterate with a start index instead of\n\t\t// allocating an intermediate slice. F2.\n\t\tconst start =\n\t\t\tthis._maxSize !== undefined && values.length > this._maxSize\n\t\t\t\t? values.length - this._maxSize\n\t\t\t\t: 0;\n\t\tfor (let i = start; i < values.length; i++) {\n\t\t\tthis._rawAppend(values[i] as T);\n\t\t}\n\t\tthis._version += 1;\n\t}\n\n\tclear(): number {\n\t\tif (this._size === 0) return 0;\n\t\tconst n = this._size;\n\t\tif (this._maxSize === undefined) {\n\t\t\tthis._buf.length = 0;\n\t\t} else {\n\t\t\t// Ring buffer: only null the currently-live window so the GC can\n\t\t\t// reclaim ref-typed `T`. Iterating the full capacity would be O(cap)\n\t\t\t// even when only a few slots are in use (P6). Non-live slots are\n\t\t\t// already `undefined` (pre-allocation state) or whatever a prior\n\t\t\t// trim/clear left — they hold no live refs.\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tthis._buf[(this._head + i) % this._maxSize] = undefined as unknown as T;\n\t\t\t}\n\t\t}\n\t\tthis._head = 0;\n\t\tthis._size = 0;\n\t\tthis._version += 1;\n\t\treturn n;\n\t}\n\n\ttrimHead(n: number): number {\n\t\tif (!Number.isInteger(n) || n < 0) {\n\t\t\tthrow new RangeError(`trimHead: n must be a non-negative integer (got ${n})`);\n\t\t}\n\t\tif (n === 0 || this._size === 0) return 0;\n\t\tconst removed = Math.min(n, this._size);\n\t\tif (this._maxSize === undefined) {\n\t\t\tthis._buf.splice(0, removed);\n\t\t} else {\n\t\t\t// Null trimmed slots so the GC can reclaim ref-typed T (P4 extension).\n\t\t\tfor (let i = 0; i < removed; i++) {\n\t\t\t\tthis._buf[(this._head + i) % this._maxSize] = undefined as unknown as T;\n\t\t\t}\n\t\t\tthis._head = (this._head + removed) % this._maxSize;\n\t\t}\n\t\tthis._size -= removed;\n\t\tthis._version += 1;\n\t\treturn removed;\n\t}\n\n\tslice(start: number, stop?: number): readonly T[] {\n\t\tif (!Number.isInteger(start) || start < 0) {\n\t\t\tthrow new RangeError(`slice: start must be a non-negative integer (got ${start})`);\n\t\t}\n\t\t// P4: reject negative `stop` explicitly so the bundle / backend / derived\n\t\t// contract stays consistent. Previously stop was silently clamped to 0,\n\t\t// producing `[]` in the backend but a different value under JS semantics\n\t\t// in the derived recomputation — a latent bug for negative inputs.\n\t\tif (stop !== undefined && (!Number.isInteger(stop) || stop < 0)) {\n\t\t\tthrow new RangeError(`slice: stop must be a non-negative integer or undefined (got ${stop})`);\n\t\t}\n\t\tconst end = stop === undefined ? this._size : Math.min(Math.max(stop, 0), this._size);\n\t\tconst s = Math.min(start, this._size);\n\t\tif (s >= end) return [];\n\t\tconst len = end - s;\n\t\tif (this._maxSize === undefined) {\n\t\t\treturn this._buf.slice(s, end);\n\t\t}\n\t\tconst out: T[] = new Array(len);\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tout[i] = this._buf[(this._head + s + i) % this._maxSize]!;\n\t\t}\n\t\treturn out;\n\t}\n\n\ttail(n: number): readonly T[] {\n\t\tif (!Number.isInteger(n) || n < 0) {\n\t\t\tthrow new RangeError(`tail: n must be a non-negative integer (got ${n})`);\n\t\t}\n\t\tif (n === 0 || this._size === 0) return [];\n\t\tconst take = Math.min(n, this._size);\n\t\treturn this.slice(this._size - take, this._size);\n\t}\n\n\ttoArray(): readonly T[] {\n\t\tif (this._maxSize === undefined) {\n\t\t\treturn [...this._buf];\n\t\t}\n\t\tconst out: T[] = new Array(this._size);\n\t\tfor (let i = 0; i < this._size; i++) {\n\t\t\tout[i] = this._buf[(this._head + i) % this._maxSize]!;\n\t\t}\n\t\treturn out;\n\t}\n\n\t/** Internal append without version bump — used by `appendMany`. */\n\tprivate _rawAppend(value: T): void {\n\t\tif (this._maxSize === undefined) {\n\t\t\tthis._buf.push(value);\n\t\t\tthis._size = this._buf.length;\n\t\t\treturn;\n\t\t}\n\t\tif (this._size < this._maxSize) {\n\t\t\tthis._buf[(this._head + this._size) % this._maxSize] = value;\n\t\t\tthis._size += 1;\n\t\t} else {\n\t\t\t// Overwrite slot at head, advance head.\n\t\t\tthis._buf[this._head] = value;\n\t\t\tthis._head = (this._head + 1) % this._maxSize;\n\t\t}\n\t}\n}\n\n// ── Reactive wrapper ──────────────────────────────────────────────────────\n\n/** Installs a keepalive subscription; returns the disposer so callers can release it. */\nfunction keepaliveDerived(n: Node<unknown>): () => void {\n\treturn n.subscribe(() => {});\n}\n\n/** Default cap on the LRU view cache for `tail(n)` / `slice(start, stop?)`. D2(c). */\nconst DEFAULT_VIEW_CACHE_MAX = 64;\n\n/**\n * Creates an append-only reactive log with immutable array snapshots.\n *\n * @param initial - Optional seed entries (copied; pre-trimmed to `maxSize` if set).\n * @param options - `name`, `maxSize`, and optional pluggable `backend`.\n * @returns Bundle with `entries` (state node), `append`/`appendMany`/`clear`/`trimHead`,\n * `size` / `at`, and memoized derived views `tail(n)` / `slice(start, stop?)`.\n *\n * @remarks\n * **Backend:** The default {@link NativeLogBackend} uses a ring buffer when `maxSize`\n * is set (O(1) append + trim) and a flat array otherwise. For persistent/structural-\n * sharing semantics plug in a custom {@link LogBackend}.\n *\n * **`initial` + custom `backend` (F5):** When you supply `options.backend`, the\n * `initial` argument is IGNORED — seed the backend yourself before passing it in.\n * The `initial` seed only applies to the default `NativeLogBackend`.\n *\n * **Memoized views:** {@link ReactiveLogBundle.tail} and {@link ReactiveLogBundle.slice}\n * cache derived nodes per-argument. Repeat calls with the same `n` / `(start, stop)`\n * return the same node, bounding keepalive-subscription count to one per unique argument.\n *\n * @example\n * ```ts\n * import { reactiveLog } from \"@graphrefly/graphrefly-ts\";\n *\n * const lg = reactiveLog<number>([1, 2], { name: \"audit\", maxSize: 100 });\n * lg.append(3);\n * lg.entries.subscribe((msgs) => console.log(msgs));\n * const last5 = lg.tail(5); // derived node\n * const window = lg.slice(10, 20); // derived node\n * ```\n *\n * @category extra\n */\nexport function reactiveLog<T>(\n\tinitial?: readonly T[],\n\toptions: ReactiveLogOptions<T> = {},\n): ReactiveLogBundle<T> {\n\tconst { name, maxSize, versioning, backend: userBackend } = options;\n\tconst backend: LogBackend<T> = userBackend ?? new NativeLogBackend<T>(initial, maxSize);\n\n\tconst entries = state<readonly T[]>(backend.toArray(), {\n\t\tname,\n\t\tdescribeKind: \"state\",\n\t\tequals: (a, b) => a === b,\n\t\t...(versioning != null ? { versioning } : {}),\n\t});\n\n\tfunction pushSnapshot(): void {\n\t\tconst snapshot = backend.toArray();\n\t\tbatch(() => {\n\t\t\tentries.down([[DIRTY]]);\n\t\t\tentries.down([[DATA, snapshot]]);\n\t\t});\n\t}\n\n\t// Memoization caches for derived views (D2(c)). Each cache is an LRU keyed by\n\t// the unique view argument, bounded by `DEFAULT_VIEW_CACHE_MAX`. On cache miss\n\t// past the cap, the least-recently-used entry is evicted and its keepalive\n\t// disposer is called so the underlying derived node can be GC'd. Callers can\n\t// also release views proactively via `disposeTail` / `disposeSlice` /\n\t// `disposeAllViews`. Iteration order of `Map` is insertion order, so moving\n\t// an entry to the end on hit is the LRU \"touch\".\n\ttype ViewEntry = { node: Node<readonly T[]>; dispose: () => void };\n\tconst tailCache = new Map<number, ViewEntry>();\n\tconst sliceCache = new Map<string, ViewEntry>();\n\n\tfunction sliceKey(start: number, stop?: number): string {\n\t\treturn `${start}:${stop === undefined ? \"END\" : stop}`;\n\t}\n\n\tfunction evictOldestIfFull<K>(cache: Map<K, ViewEntry>): void {\n\t\tif (cache.size < DEFAULT_VIEW_CACHE_MAX) return;\n\t\tconst first = cache.keys().next();\n\t\tif (first.done) return;\n\t\tconst oldest = cache.get(first.value);\n\t\tif (oldest !== undefined) oldest.dispose();\n\t\tcache.delete(first.value);\n\t}\n\n\t/**\n\t * D4(a): try/finally defense-in-depth — if a custom backend op throws\n\t * mid-mutation, surface the partial state via pushSnapshot so subscribers\n\t * don't see a stale cache. Matches the pattern in reactive-map and\n\t * reactive-index. Native ops are atomic by contract; this only matters\n\t * for user-supplied backends.\n\t */\n\tfunction wrapMutation<R>(op: () => R): R {\n\t\tconst prev = backend.version;\n\t\ttry {\n\t\t\treturn op();\n\t\t} finally {\n\t\t\tif (backend.version !== prev) pushSnapshot();\n\t\t}\n\t}\n\n\treturn {\n\t\tentries,\n\n\t\tget size(): number {\n\t\t\treturn backend.size;\n\t\t},\n\n\t\tat(index: number): T | undefined {\n\t\t\treturn backend.at(index);\n\t\t},\n\n\t\tappend(value: T): void {\n\t\t\twrapMutation(() => backend.append(value));\n\t\t},\n\n\t\tappendMany(values: readonly T[]): void {\n\t\t\tif (values.length === 0) return;\n\t\t\twrapMutation(() => backend.appendMany(values));\n\t\t},\n\n\t\tclear(): void {\n\t\t\twrapMutation(() => backend.clear());\n\t\t\t// NOTE: cached tail/slice derived views are intentionally NOT\n\t\t\t// disposed here. Disposing would kill the keepalive on any node\n\t\t\t// a caller already holds externally, silently stopping their\n\t\t\t// updates. The derived nodes recompute from the new empty\n\t\t\t// snapshot when `entries` emits post-clear, so `.cache` on an\n\t\t\t// outstanding view settles to `[]` without any manual\n\t\t\t// reset. (Initial snapshots, if inspected before the next wave,\n\t\t\t// may be stale — callers who care can `disposeTail` / `slice`\n\t\t\t// explicitly.)\n\t\t},\n\n\t\ttrimHead(n: number): void {\n\t\t\twrapMutation(() => backend.trimHead(n));\n\t\t},\n\n\t\ttail(n: number): Node<readonly T[]> {\n\t\t\tif (!Number.isInteger(n) || n < 0) {\n\t\t\t\tthrow new RangeError(`tail: n must be a non-negative integer (got ${n})`);\n\t\t\t}\n\t\t\tconst hit = tailCache.get(n);\n\t\t\tif (hit !== undefined) {\n\t\t\t\t// LRU touch: move to end of insertion order.\n\t\t\t\ttailCache.delete(n);\n\t\t\t\ttailCache.set(n, hit);\n\t\t\t\treturn hit.node;\n\t\t\t}\n\t\t\tevictOldestIfFull(tailCache);\n\t\t\tconst node_ = derived(\n\t\t\t\t[entries],\n\t\t\t\t([s]) => {\n\t\t\t\t\tconst list = s as readonly T[];\n\t\t\t\t\tif (n === 0 || list.length === 0) return [];\n\t\t\t\t\treturn list.slice(Math.max(0, list.length - n));\n\t\t\t\t},\n\t\t\t\t{ initial: backend.tail(n), describeKind: \"derived\" },\n\t\t\t);\n\t\t\tconst dispose = keepaliveDerived(node_);\n\t\t\ttailCache.set(n, { node: node_, dispose });\n\t\t\treturn node_;\n\t\t},\n\n\t\tslice(start: number, stop?: number): Node<readonly T[]> {\n\t\t\tif (!Number.isInteger(start) || start < 0) {\n\t\t\t\tthrow new RangeError(`slice: start must be a non-negative integer (got ${start})`);\n\t\t\t}\n\t\t\t// P4: reject negative stop explicitly to keep bundle / backend / derived\n\t\t\t// consistent (JS `Array.prototype.slice` supports negative stop, but the\n\t\t\t// backend can't cheaply honor it without scanning length, so we disallow).\n\t\t\tif (stop !== undefined && (!Number.isInteger(stop) || stop < 0)) {\n\t\t\t\tthrow new RangeError(\n\t\t\t\t\t`slice: stop must be a non-negative integer or undefined (got ${stop})`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst key = sliceKey(start, stop);\n\t\t\tconst hit = sliceCache.get(key);\n\t\t\tif (hit !== undefined) {\n\t\t\t\tsliceCache.delete(key);\n\t\t\t\tsliceCache.set(key, hit);\n\t\t\t\treturn hit.node;\n\t\t\t}\n\t\t\tevictOldestIfFull(sliceCache);\n\t\t\tconst node_ = derived(\n\t\t\t\t[entries],\n\t\t\t\t([s]) => {\n\t\t\t\t\tconst list = s as readonly T[];\n\t\t\t\t\treturn stop === undefined ? list.slice(start) : list.slice(start, stop);\n\t\t\t\t},\n\t\t\t\t{ initial: backend.slice(start, stop), describeKind: \"derived\" },\n\t\t\t);\n\t\t\tconst dispose = keepaliveDerived(node_);\n\t\t\tsliceCache.set(key, { node: node_, dispose });\n\t\t\treturn node_;\n\t\t},\n\n\t\tdisposeTail(n: number): boolean {\n\t\t\tconst hit = tailCache.get(n);\n\t\t\tif (hit === undefined) return false;\n\t\t\thit.dispose();\n\t\t\ttailCache.delete(n);\n\t\t\treturn true;\n\t\t},\n\n\t\tdisposeSlice(start: number, stop?: number): boolean {\n\t\t\tconst key = sliceKey(start, stop);\n\t\t\tconst hit = sliceCache.get(key);\n\t\t\tif (hit === undefined) return false;\n\t\t\thit.dispose();\n\t\t\tsliceCache.delete(key);\n\t\t\treturn true;\n\t\t},\n\n\t\tdisposeAllViews(): void {\n\t\t\tfor (const entry of tailCache.values()) entry.dispose();\n\t\t\ttailCache.clear();\n\t\t\tfor (const entry of sliceCache.values()) entry.dispose();\n\t\t\tsliceCache.clear();\n\t\t},\n\n\t\tdispose(): void {\n\t\t\t// D6(a): currently identical to disposeAllViews. Exposed as a\n\t\t\t// uniform lifecycle API across all 4 reactive data structures.\n\t\t\tfor (const entry of tailCache.values()) entry.dispose();\n\t\t\ttailCache.clear();\n\t\t\tfor (const entry of sliceCache.values()) entry.dispose();\n\t\t\tsliceCache.clear();\n\t\t},\n\t};\n}\n","/**\n * Storage tier primitive — unified persistence surface (roadmap §3.1).\n *\n * A {@link StorageTier} is the single abstraction used by:\n * - {@link Graph.attachStorage} — snapshot cascade with per-tier cadence\n * - {@link Graph.fromStorage} — hot-boot from the first tier that hits\n * - {@link cascadingCache} — keyed lookup cache with auto-promotion\n *\n * Factory functions cover the common backends: {@link memoryStorage},\n * {@link dictStorage}, {@link fileStorage}, {@link sqliteStorage} (sync), and\n * {@link indexedDbStorage} (async). {@link fromIDBRequest} /\n * {@link fromIDBTransaction} wrap raw IndexedDB primitives as reactive sources\n * — they belong here as the browser-runtime neighbors of `indexedDbStorage`.\n */\n/// <reference lib=\"dom\" />\n\nimport { randomBytes } from \"node:crypto\";\nimport { mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { DatabaseSync } from \"node:sqlite\";\nimport { COMPLETE, DATA, ERROR } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { producer } from \"../core/sugar.js\";\n\n/**\n * Single persistence primitive — supports sync and async backends alike via\n * `void | Promise<void>` returns. `debounceMs` / `compactEvery` / `filter`\n * are per-tier cadence controls honored by {@link Graph.attachStorage};\n * {@link cascadingCache} ignores them (it has its own eviction policy).\n */\nexport interface StorageTier {\n\t/** Read a value. Returns `null` (or resolves to `null`) on miss. */\n\tload(key: string): unknown | Promise<unknown>;\n\t/** Write a record. Sync tiers return `void`; async tiers return `Promise<void>`. */\n\tsave(key: string, data: unknown): void | Promise<void>;\n\t/** Delete a value. Optional — tiers without `clear` are append/overwrite-only. */\n\tclear?(key: string): void | Promise<void>;\n\t/**\n\t * Debounce saves on this tier (ms). Hot tier: `0` (sync-through).\n\t * Warm: `1000`. Cold: `60000`. Each tier holds its own last-save baseline,\n\t * so cold flushes aren't penalized by hot flushes.\n\t */\n\tdebounceMs?: number;\n\t/**\n\t * Every Nth record is a full snapshot; others are diffs against this\n\t * tier's own baseline. Default `10`. Set `1` for always-full;\n\t * `Number.POSITIVE_INFINITY` is unsafe — WAL replay needs periodic anchors.\n\t */\n\tcompactEvery?: number;\n\t/** Pre-save filter — return `false` to skip this record on this tier. */\n\tfilter?: (key: string, record: unknown) => boolean;\n}\n\n/** Handle returned by {@link Graph.attachStorage} — dispose to stop observing. */\nexport interface StorageHandle {\n\tdispose(): void;\n}\n\nfunction sortJsonValue(value: unknown): unknown {\n\tif (value === null || typeof value !== \"object\") return value;\n\tif (Array.isArray(value)) return value.map(sortJsonValue);\n\tconst obj = value as Record<string, unknown>;\n\tconst keys = Object.keys(obj).sort();\n\tconst out: Record<string, unknown> = {};\n\tfor (const k of keys) out[k] = sortJsonValue(obj[k]);\n\treturn out;\n}\n\nfunction stableJsonString(data: unknown): string {\n\t// No trailing newline — tiers that want POSIX newline convention (e.g.\n\t// fileStorage) append their own; in-database tiers (sqliteStorage) keep\n\t// the payload byte-identical for cross-tier hash/CID comparison.\n\treturn JSON.stringify(sortJsonValue(data), undefined, 0);\n}\n\n/**\n * In-memory storage tier (process-local; useful for tests and hot tier).\n *\n * @returns Sync {@link StorageTier} with JSON-cloned isolation.\n *\n * @example\n * ```ts\n * import { memoryStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * const hot = memoryStorage();\n * graph.attachStorage([hot]);\n * ```\n *\n * @category extra\n */\nexport function memoryStorage(): StorageTier {\n\tconst data = new Map<string, unknown>();\n\treturn {\n\t\tsave(key, record) {\n\t\t\tdata.set(key, JSON.parse(JSON.stringify(record)));\n\t\t},\n\t\tload(key) {\n\t\t\tconst v = data.get(key);\n\t\t\treturn v === undefined ? null : JSON.parse(JSON.stringify(v));\n\t\t},\n\t\tclear(key) {\n\t\t\tdata.delete(key);\n\t\t},\n\t};\n}\n\n/**\n * Dict-backed storage tier — stores JSON-cloned values under caller keys in\n * a caller-owned plain object. Useful for embedding in a parent state shape.\n *\n * @param storage - Caller-owned object used as the backing store.\n * @returns Sync {@link StorageTier}.\n *\n * @example\n * ```ts\n * import { dictStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * const state: Record<string, unknown> = {};\n * graph.attachStorage([dictStorage(state)]);\n * ```\n *\n * @category extra\n */\nexport function dictStorage(storage: Record<string, unknown>): StorageTier {\n\treturn {\n\t\tsave(key, record) {\n\t\t\tstorage[key] = JSON.parse(JSON.stringify(record));\n\t\t},\n\t\tload(key) {\n\t\t\tconst raw = storage[key];\n\t\t\treturn raw === undefined ? null : JSON.parse(JSON.stringify(raw));\n\t\t},\n\t\tclear(key) {\n\t\t\tdelete storage[key];\n\t\t},\n\t};\n}\n\n/**\n * Atomic JSON file storage tier (one file per key in a directory, temp + rename).\n *\n * Keys are sanitized to filesystem-safe names (`[^a-zA-Z0-9_-]` → `%<hex>`).\n * `load` returns `null` for missing files, empty files, or invalid JSON.\n *\n * @param dir - Directory where per-key JSON files are written.\n * @returns Sync {@link StorageTier}.\n *\n * @example\n * ```ts\n * import { fileStorage, memoryStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * graph.attachStorage([memoryStorage(), fileStorage(\"./checkpoints\")]);\n * ```\n *\n * @category extra\n */\nexport function fileStorage(dir: string): StorageTier {\n\tconst pathFor = (key: string): string => {\n\t\tconst safe = key.replace(\n\t\t\t/[^a-zA-Z0-9_-]/g,\n\t\t\t(c) => `%${c.charCodeAt(0).toString(16).padStart(2, \"0\")}`,\n\t\t);\n\t\treturn join(dir, `${safe}.json`);\n\t};\n\treturn {\n\t\tsave(key, record) {\n\t\t\tmkdirSync(dir, { recursive: true });\n\t\t\tconst filePath = pathFor(key);\n\t\t\t// POSIX newline for file-on-disk convention; does not affect payload hash.\n\t\t\tconst payload = `${stableJsonString(record)}\\n`;\n\t\t\tconst base = basename(filePath);\n\t\t\tconst d = dirname(filePath);\n\t\t\tconst tmp = join(d, `.${base}.${randomBytes(8).toString(\"hex\")}.tmp`);\n\t\t\ttry {\n\t\t\t\twriteFileSync(tmp, payload, \"utf8\");\n\t\t\t\trenameSync(tmp, filePath);\n\t\t\t} catch (e) {\n\t\t\t\ttry {\n\t\t\t\t\tunlinkSync(tmp);\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore */\n\t\t\t\t}\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t},\n\t\tload(key) {\n\t\t\ttry {\n\t\t\t\tconst text = readFileSync(pathFor(key), \"utf8\").trim();\n\t\t\t\tif (!text) return null;\n\t\t\t\treturn JSON.parse(text) as unknown;\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\tclear(key) {\n\t\t\ttry {\n\t\t\t\tunlinkSync(pathFor(key));\n\t\t\t} catch (e) {\n\t\t\t\tif ((e as NodeJS.ErrnoException).code !== \"ENOENT\") throw e;\n\t\t\t}\n\t\t},\n\t};\n}\n\n/**\n * SQLite storage tier using Node.js `node:sqlite` ({@link DatabaseSync}).\n *\n * Returns a {@link StorageTier} extended with `close()` — the caller owns the\n * connection and should close it when discarding the tier.\n *\n * **Runtime:** Requires Node 22.5+ with `node:sqlite` enabled.\n *\n * @param path - SQLite database file path.\n * @returns Sync {@link StorageTier} with an idempotent `close()` method.\n *\n * @example\n * ```ts\n * import { sqliteStorage, memoryStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * const cold = sqliteStorage(\"./graphs.sqlite\");\n * graph.attachStorage([memoryStorage(), cold]);\n * // ... later, on shutdown:\n * cold.close();\n * ```\n *\n * @category extra\n */\nexport function sqliteStorage(path: string): StorageTier & { close(): void } {\n\tconst db = new DatabaseSync(path);\n\tdb.exec(`CREATE TABLE IF NOT EXISTS graphrefly_checkpoint (k TEXT PRIMARY KEY, v TEXT NOT NULL)`);\n\treturn {\n\t\tsave(key, record) {\n\t\t\tconst payload = stableJsonString(record);\n\t\t\tdb.prepare(`INSERT OR REPLACE INTO graphrefly_checkpoint (k, v) VALUES (?, ?)`).run(\n\t\t\t\tkey,\n\t\t\t\tpayload,\n\t\t\t);\n\t\t},\n\t\tload(key) {\n\t\t\tconst row = db.prepare(`SELECT v FROM graphrefly_checkpoint WHERE k = ?`).get(key) as\n\t\t\t\t| { v: string }\n\t\t\t\t| undefined;\n\t\t\tif (row === undefined || typeof row.v !== \"string\" || row.v.trim() === \"\") return null;\n\t\t\treturn JSON.parse(row.v) as unknown;\n\t\t},\n\t\tclear(key) {\n\t\t\tdb.prepare(`DELETE FROM graphrefly_checkpoint WHERE k = ?`).run(key);\n\t\t},\n\t\tclose() {\n\t\t\ttry {\n\t\t\t\tdb.close();\n\t\t\t} catch {\n\t\t\t\t/* already closed */\n\t\t\t}\n\t\t},\n\t};\n}\n\n// ——————————————————————————————————————————————————————————————\n// IndexedDB — async storage tier + raw reactive sources\n// ——————————————————————————————————————————————————————————————\n\nexport type IndexedDbStorageSpec = {\n\tdbName: string;\n\tstoreName: string;\n\t/** Object-store key under which snapshots are written. @default `\"graphrefly_checkpoint\"`. */\n\tkey?: string;\n\tversion?: number;\n};\n\n/**\n * Wraps an `IDBRequest` as a one-shot reactive source.\n *\n * @param req - Request whose callbacks are converted to protocol messages.\n * @returns `Node<T>` that emits `DATA` once on success then `COMPLETE`;\n * emits `ERROR` on failure.\n *\n * @category extra\n */\nexport function fromIDBRequest<T>(req: IDBRequest<T>): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet done = false;\n\t\tconst clear = () => {\n\t\t\treq.onsuccess = null;\n\t\t\treq.onerror = null;\n\t\t};\n\t\treq.onsuccess = () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t\ta.down([[DATA, req.result], [COMPLETE]]);\n\t\t};\n\t\treq.onerror = () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t\ta.down([[ERROR, req.error ?? new Error(\"IndexedDB request failed\")]]);\n\t\t};\n\t\treturn () => {\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t};\n\t});\n}\n\n/**\n * Wraps an `IDBTransaction` terminal lifecycle as a one-shot reactive source.\n *\n * @param tx - Transaction to observe.\n * @returns `Node<void>` that emits `DATA` (`undefined`) then `COMPLETE` on\n * success; emits `ERROR` on `error`/`abort`.\n *\n * @category extra\n */\nexport function fromIDBTransaction(tx: IDBTransaction): Node<void> {\n\treturn producer<void>((a) => {\n\t\tlet done = false;\n\t\tconst clear = () => {\n\t\t\ttx.oncomplete = null;\n\t\t\ttx.onerror = null;\n\t\t\ttx.onabort = null;\n\t\t};\n\t\ttx.oncomplete = () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t\ta.down([[DATA, undefined], [COMPLETE]]);\n\t\t};\n\t\ttx.onerror = () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t\ta.down([[ERROR, tx.error ?? new Error(\"IndexedDB transaction failed\")]]);\n\t\t};\n\t\ttx.onabort = () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t\ta.down([[ERROR, tx.error ?? new Error(\"IndexedDB transaction aborted\")]]);\n\t\t};\n\t\treturn () => {\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t};\n\t});\n}\n\nfunction openIdb(dbName: string, storeName: string, version: number): Promise<IDBDatabase> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (typeof indexedDB === \"undefined\") {\n\t\t\treject(new TypeError(\"indexedDB is not available in this environment\"));\n\t\t\treturn;\n\t\t}\n\t\tconst req = indexedDB.open(dbName, version);\n\t\treq.onupgradeneeded = () => {\n\t\t\tconst db = req.result;\n\t\t\tif (!db.objectStoreNames.contains(storeName)) {\n\t\t\t\tdb.createObjectStore(storeName);\n\t\t\t}\n\t\t};\n\t\treq.onsuccess = () => resolve(req.result);\n\t\treq.onerror = () => reject(req.error ?? new Error(\"IndexedDB open failed\"));\n\t});\n}\n\nfunction idbOp<T>(\n\tdbName: string,\n\tstoreName: string,\n\tversion: number,\n\tmode: IDBTransactionMode,\n\top: (store: IDBObjectStore) => IDBRequest<T>,\n): Promise<T> {\n\treturn openIdb(dbName, storeName, version).then(\n\t\t(db) =>\n\t\t\tnew Promise<T>((resolve, reject) => {\n\t\t\t\tconst tx = db.transaction(storeName, mode);\n\t\t\t\tconst store = tx.objectStore(storeName);\n\t\t\t\tconst req = op(store);\n\t\t\t\tlet reqResult: T | undefined;\n\t\t\t\tlet reqDone = false;\n\t\t\t\tlet txDone = false;\n\t\t\t\tconst finish = () => {\n\t\t\t\t\tif (!reqDone || !txDone) return;\n\t\t\t\t\tdb.close();\n\t\t\t\t\tresolve(reqResult as T);\n\t\t\t\t};\n\t\t\t\treq.onsuccess = () => {\n\t\t\t\t\treqResult = req.result;\n\t\t\t\t\treqDone = true;\n\t\t\t\t\tfinish();\n\t\t\t\t};\n\t\t\t\treq.onerror = () => {\n\t\t\t\t\tdb.close();\n\t\t\t\t\treject(req.error ?? new Error(\"IndexedDB request failed\"));\n\t\t\t\t};\n\t\t\t\ttx.oncomplete = () => {\n\t\t\t\t\ttxDone = true;\n\t\t\t\t\tif (!reqDone) {\n\t\t\t\t\t\t// Transaction completed without a request success callback —\n\t\t\t\t\t\t// spec guarantees this shouldn't happen for successful tx,\n\t\t\t\t\t\t// but defensively reject so the caller's promise doesn't\n\t\t\t\t\t\t// hang silently.\n\t\t\t\t\t\tdb.close();\n\t\t\t\t\t\treject(new Error(\"IndexedDB transaction completed without request result\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tfinish();\n\t\t\t\t};\n\t\t\t\ttx.onerror = () => {\n\t\t\t\t\tdb.close();\n\t\t\t\t\treject(tx.error ?? new Error(\"IndexedDB transaction failed\"));\n\t\t\t\t};\n\t\t\t\ttx.onabort = () => {\n\t\t\t\t\tdb.close();\n\t\t\t\t\treject(tx.error ?? new Error(\"IndexedDB transaction aborted\"));\n\t\t\t\t};\n\t\t\t}),\n\t);\n}\n\n/**\n * IndexedDB-backed async storage tier (browser runtime).\n *\n * All three methods return `Promise`s — pairs naturally with a warm/cold\n * cadence where async writes are debounced per tier via\n * {@link Graph.attachStorage}. Writes use `readwrite` transactions; reads use\n * `readonly`. Missing records resolve to `null`.\n *\n * @param spec - Database name, store name, optional `key` (default\n * `\"graphrefly_checkpoint\"`) and schema `version` (default `1`).\n * @returns Async {@link StorageTier}.\n *\n * @example\n * ```ts\n * import { indexedDbStorage, memoryStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * graph.attachStorage([\n * memoryStorage(),\n * indexedDbStorage({ dbName: \"myApp\", storeName: \"checkpoints\" }),\n * ]);\n * ```\n *\n * @category extra\n */\nexport function indexedDbStorage(spec: IndexedDbStorageSpec): StorageTier {\n\tconst { dbName, storeName } = spec;\n\tconst version = spec.version ?? 1;\n\tconst recordKey = spec.key ?? \"graphrefly_checkpoint\";\n\treturn {\n\t\tasync save(_key, record) {\n\t\t\tawait idbOp(dbName, storeName, version, \"readwrite\", (store) =>\n\t\t\t\tstore.put(record as unknown as IDBValidKey, recordKey),\n\t\t\t);\n\t\t},\n\t\tasync load(_key) {\n\t\t\tconst raw = await idbOp(dbName, storeName, version, \"readonly\", (store) =>\n\t\t\t\tstore.get(recordKey),\n\t\t\t);\n\t\t\tif (raw === undefined || raw === null) return null;\n\t\t\tif (typeof raw !== \"object\" || Array.isArray(raw)) return null;\n\t\t\treturn raw;\n\t\t},\n\t\tasync clear(_key) {\n\t\t\tawait idbOp(dbName, storeName, version, \"readwrite\", (store) => store.delete(recordKey));\n\t\t},\n\t};\n}\n","/**\n * Wire protocol for worker bridge communication.\n *\n * Graph-local signals ({@link isLocalOnly}) stay local to each side's\n * reactive graph. DATA values cross via coalescing; RESOLVED/COMPLETE/TEARDOWN\n * as signals; ERROR as serialized payloads.\n *\n * Lifecycle signals serialize as string names since Symbols can't survive\n * structured clone. Unknown {@link Symbol.for} symbols are round-tripped\n * via their registered key.\n */\n\nimport { COMPLETE, ERROR, INVALIDATE, PAUSE, RESUME, TEARDOWN } from \"../../core/messages.js\";\n\n// ---------------------------------------------------------------------------\n// Wire message types\n// ---------------------------------------------------------------------------\n\n/** Value update — one node changed. */\nexport interface ValueMessage {\n\tt: \"v\";\n\t/** Node name. */\n\ts: string;\n\t/** Serialized value. */\n\td: unknown;\n}\n\n/** Lifecycle signal — serialized symbol name. */\nexport interface SignalMessage {\n\tt: \"s\";\n\t/** Node name, or `\"*\"` for bridge-wide. */\n\ts: string;\n\t/** Signal name string (e.g. \"TEARDOWN\"). */\n\tsig: string;\n\t/** Optional payload for custom symbols (spec §1.3.6 forward unchanged). */\n\td?: unknown;\n}\n\n/** Ready — worker declares its exported nodes with initial values. */\nexport interface ReadyMessage {\n\tt: \"r\";\n\tstores: Record<string, unknown>;\n}\n\n/** Init — main sends initial values of its exposed nodes. */\nexport interface InitMessage {\n\tt: \"i\";\n\tstores: Record<string, unknown>;\n}\n\n/** Batch value update — multiple nodes changed in one reactive cycle. */\nexport interface BatchMessage {\n\tt: \"b\";\n\tu: Record<string, unknown>;\n\t/** V0 versions per node for delta sync — peer skips if version <= lastSeen (§6.0b). */\n\tv?: Record<string, number>;\n}\n\n/** Error payload — serialized since Error objects don't survive structured clone. */\nexport interface ErrorMessage {\n\tt: \"e\";\n\t/** Node name. */\n\ts: string;\n\t/** Serialized error. */\n\terr: { message: string; name: string; stack?: string };\n}\n\nexport type BridgeMessage =\n\t| ValueMessage\n\t| SignalMessage\n\t| ReadyMessage\n\t| InitMessage\n\t| BatchMessage\n\t| ErrorMessage;\n\n// ---------------------------------------------------------------------------\n// Signal serialization — Symbol <-> string for structured clone\n// ---------------------------------------------------------------------------\n\nconst signalToNameMap = new Map<symbol, string>([\n\t[INVALIDATE, \"INVALIDATE\"],\n\t[PAUSE, \"PAUSE\"],\n\t[RESUME, \"RESUME\"],\n\t[TEARDOWN, \"TEARDOWN\"],\n\t[COMPLETE, \"COMPLETE\"],\n\t[ERROR, \"ERROR\"],\n]);\n\nconst nameToSignalMap = new Map<string, symbol>([\n\t[\"INVALIDATE\", INVALIDATE],\n\t[\"PAUSE\", PAUSE],\n\t[\"RESUME\", RESUME],\n\t[\"TEARDOWN\", TEARDOWN],\n\t[\"COMPLETE\", COMPLETE],\n\t[\"ERROR\", ERROR],\n]);\n\n/**\n * Serialize a message type symbol to a string for structured clone transfer.\n *\n * Known GraphReFly symbols map to their canonical names. Unknown symbols\n * registered via {@link Symbol.for} use their registered key. Unregistered\n * symbols return `\"UNKNOWN\"`.\n */\nexport function signalToName(s: symbol): string {\n\tconst known = signalToNameMap.get(s);\n\tif (known) return known;\n\tconst key = Symbol.keyFor(s);\n\treturn key ?? \"UNKNOWN\";\n}\n\n/**\n * Deserialize a string back to a message type symbol.\n *\n * Known GraphReFly names map to their canonical symbols. Other non-empty\n * strings are reconstructed via {@link Symbol.for} (round-trip safe for\n * custom message types). Returns `undefined` for `\"UNKNOWN\"`.\n */\nexport function nameToSignal(name: string): symbol | undefined {\n\tconst known = nameToSignalMap.get(name);\n\tif (known) return known;\n\tif (name && name !== \"UNKNOWN\") return Symbol.for(name);\n\treturn undefined;\n}\n\n/** Serialize an error for structured clone transfer. */\nexport function serializeError(err: unknown): { message: string; name: string; stack?: string } {\n\tif (err instanceof Error) {\n\t\treturn { message: err.message, name: err.name, stack: err.stack };\n\t}\n\treturn { message: String(err), name: \"Error\" };\n}\n\n/** Deserialize an error payload back to an Error object. */\nexport function deserializeError(payload: {\n\tmessage: string;\n\tname: string;\n\tstack?: string;\n}): Error {\n\tconst err = new Error(payload.message);\n\terr.name = payload.name;\n\tif (payload.stack) err.stack = payload.stack;\n\treturn err;\n}\n","/**\n * WorkerTransport — normalized message channel for all worker types.\n *\n * Abstracts Worker, SharedWorker, ServiceWorker, BroadcastChannel, and\n * MessagePort behind a uniform post/listen/terminate interface.\n */\n\n/** Normalized bidirectional message channel. */\nexport interface WorkerTransport {\n\t/** Send data to the other side. Optional transferables for zero-copy. */\n\tpost(data: unknown, transfer?: Transferable[]): void;\n\t/** Listen for incoming messages. Returns unsubscribe function. */\n\tlisten(handler: (data: unknown) => void): () => void;\n\t/** Terminate the connection (if supported by the underlying transport). */\n\tterminate?(): void;\n}\n\n/**\n * Auto-detect transport type and create a normalized WorkerTransport.\n *\n * Supports:\n * - `Worker` — direct postMessage/onmessage\n * - `SharedWorker` — port-based postMessage/onmessage\n * - `ServiceWorker` — postMessage via controller, listen via navigator.serviceWorker\n * - `BroadcastChannel` — postMessage/onmessage (no Transferable support)\n * - `MessagePort` — direct postMessage/onmessage (worker-side SharedWorker port)\n */\nexport function createTransport(target: unknown): WorkerTransport {\n\t// MessagePort (SharedWorker port from inside the worker, or raw MessagePort)\n\tif (typeof MessagePort !== \"undefined\" && target instanceof MessagePort) {\n\t\treturn {\n\t\t\tpost(data, transfer) {\n\t\t\t\ttarget.postMessage(data, transfer ?? []);\n\t\t\t},\n\t\t\tlisten(handler) {\n\t\t\t\tconst h = (e: MessageEvent) => handler(e.data);\n\t\t\t\ttarget.addEventListener(\"message\", h);\n\t\t\t\ttarget.start();\n\t\t\t\treturn () => target.removeEventListener(\"message\", h);\n\t\t\t},\n\t\t\tterminate() {\n\t\t\t\ttarget.close();\n\t\t\t},\n\t\t};\n\t}\n\n\t// SharedWorker — use its port\n\tif (typeof SharedWorker !== \"undefined\" && target instanceof SharedWorker) {\n\t\treturn createTransport(target.port);\n\t}\n\n\t// Web Worker\n\tif (typeof Worker !== \"undefined\" && target instanceof Worker) {\n\t\treturn {\n\t\t\tpost(data, transfer) {\n\t\t\t\ttarget.postMessage(data, transfer ?? []);\n\t\t\t},\n\t\t\tlisten(handler) {\n\t\t\t\tconst h = (e: MessageEvent) => handler(e.data);\n\t\t\t\ttarget.addEventListener(\"message\", h);\n\t\t\t\treturn () => target.removeEventListener(\"message\", h);\n\t\t\t},\n\t\t\tterminate() {\n\t\t\t\ttarget.terminate();\n\t\t\t},\n\t\t};\n\t}\n\n\t// BroadcastChannel — no Transferable support\n\tif (typeof BroadcastChannel !== \"undefined\" && target instanceof BroadcastChannel) {\n\t\treturn {\n\t\t\tpost(data, transfer?) {\n\t\t\t\tif (transfer && transfer.length > 0) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\"[graphrefly] WorkerTransport: BroadcastChannel does not support Transferable objects. The transfer argument is ignored and objects will be cloned instead.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\ttarget.postMessage(data);\n\t\t\t},\n\t\t\tlisten(handler) {\n\t\t\t\tconst h = (e: MessageEvent) => handler(e.data);\n\t\t\t\ttarget.addEventListener(\"message\", h);\n\t\t\t\treturn () => target.removeEventListener(\"message\", h);\n\t\t\t},\n\t\t\tterminate() {\n\t\t\t\ttarget.close();\n\t\t\t},\n\t\t};\n\t}\n\n\t// ServiceWorker\n\tif (typeof ServiceWorker !== \"undefined\" && target instanceof ServiceWorker) {\n\t\treturn {\n\t\t\tpost(data, transfer) {\n\t\t\t\ttarget.postMessage(data, transfer ?? []);\n\t\t\t},\n\t\t\tlisten(handler) {\n\t\t\t\tconst h = (e: MessageEvent) => {\n\t\t\t\t\tif (e.source === target) handler(e.data);\n\t\t\t\t};\n\t\t\t\tnavigator.serviceWorker.addEventListener(\"message\", h);\n\t\t\t\treturn () => navigator.serviceWorker.removeEventListener(\"message\", h);\n\t\t\t},\n\t\t};\n\t}\n\n\tthrow new Error(\n\t\t\"createTransport: unsupported target type. Expected Worker, SharedWorker, ServiceWorker, BroadcastChannel, or MessagePort.\",\n\t);\n}\n","/**\n * workerBridge — main-thread reactive node bridge to a worker.\n *\n * Creates proxy nodes for imported worker nodes, subscribes to exposed\n * nodes and sends values across the wire. Uses derived() + effect() for\n * natural batch coalescing via two-phase push + bitmask resolution.\n *\n * Wire filtering: graph-local signals ({@link isLocalOnly}) stay local;\n * DATA values go through the coalescing path; RESOLVED, COMPLETE, ERROR,\n * TEARDOWN, and unknown {@link Symbol.for} types go through the signal\n * subscription.\n *\n * Handshake:\n * 1. Main creates bridge, starts listening\n * 2. Worker sends { t: 'r', stores: { name: initialValue, ... } }\n * 3. Main creates proxy nodes, marks meta.status \"connected\"\n * 4. Main sends { t: 'i', stores: { name: currentValue, ... } }\n * 5. Bidirectional value flow begins\n */\n\nimport { batch } from \"../../core/batch.js\";\nimport { DATA, ERROR, type Messages, TEARDOWN } from \"../../core/messages.js\";\nimport { defaultConfig, type Node, type NodeSink, node } from \"../../core/node.js\";\nimport { effect, state } from \"../../core/sugar.js\";\nimport { filter, first, map, merge } from \"../operators.js\";\nimport { fromTimer } from \"../sources.js\";\nimport type { BatchMessage, BridgeMessage } from \"./protocol.js\";\nimport { deserializeError, nameToSignal, serializeError, signalToName } from \"./protocol.js\";\nimport type { WorkerTransport } from \"./transport.js\";\nimport { createTransport } from \"./transport.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface WorkerBridgeOptions<\n\tTExpose extends Record<string, Node<any>>,\n\tTImport extends readonly string[],\n> {\n\t/** Nodes to send to the worker. */\n\texpose?: TExpose;\n\t/** Node names the worker will provide. */\n\timport?: TImport;\n\t/** Per-node transferable extractors for zero-copy ArrayBuffer passing. */\n\ttransfer?: Partial<Record<keyof TExpose, (value: any) => Transferable[]>>;\n\t/** Debug name. */\n\tname?: string;\n\t/**\n\t * Handshake timeout in milliseconds. If the worker doesn't send READY\n\t * within this window, `meta.status` transitions to `\"closed\"` and\n\t * `meta.error` is set. Default: no timeout.\n\t */\n\ttimeoutMs?: number;\n}\n\n/** Proxy nodes created from imported worker node names. */\ntype ImportedNodes<T extends readonly string[]> = {\n\treadonly [K in T[number]]: Node<any>;\n};\n\nexport type WorkerBridge<\n\t_TExpose extends Record<string, Node<any>>,\n\tTImport extends readonly string[],\n> = ImportedNodes<TImport> & {\n\t/** Connection status meta node. */\n\tmeta: {\n\t\tstatus: Node<\"connecting\" | \"connected\" | \"closed\">;\n\t\terror: Node<Error | null>;\n\t};\n\t/** Destroy the bridge: sends TEARDOWN, disconnects, terminates worker. */\n\tdestroy(): void;\n};\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nfunction isTransport(t: unknown): t is WorkerTransport {\n\treturn (\n\t\ttypeof t === \"object\" &&\n\t\tt !== null &&\n\t\ttypeof (t as any).post === \"function\" &&\n\t\ttypeof (t as any).listen === \"function\"\n\t);\n}\n\nexport function workerBridge<\n\tTExpose extends Record<string, Node<any>>,\n\tTImport extends readonly string[],\n>(\n\ttarget: unknown | WorkerTransport,\n\topts: WorkerBridgeOptions<TExpose, TImport>,\n): WorkerBridge<TExpose, TImport> {\n\tconst transport = isTransport(target) ? target : createTransport(target);\n\tconst bridgeName = opts.name ?? \"workerBridge\";\n\tconst exposeEntries = Object.entries(opts.expose ?? {});\n\tconst importNames = (opts.import ?? []) as readonly string[];\n\tconst transferFns = opts.transfer ?? {};\n\n\t// -- Meta: connection status -----------------------------------------------\n\tconst statusNode = state<\"connecting\" | \"connected\" | \"closed\">(\"connecting\", {\n\t\tname: `${bridgeName}::meta::status`,\n\t});\n\tconst errorNode = state<Error | null>(null, {\n\t\tname: `${bridgeName}::meta::error`,\n\t});\n\n\t// -- Proxy nodes for imports (worker -> main) ------------------------------\n\tconst proxyNodes = new Map<string, Node<any>>();\n\tconst lastSeenImportVersions = new Map<string, number>();\n\tfor (const name of importNames) {\n\t\tconst proxy = state(undefined, { name: `${bridgeName}::${name}` });\n\t\tproxyNodes.set(name, proxy);\n\t}\n\n\t// -- Send coalescing via raw `node` + `effect` -----------------------------\n\t//\n\t// Aggregator uses raw `node([deps], (data, a) => ...)` so it can inspect\n\t// the full **wave-form** `data[i]`: a per-dep batch of DATA values emitted\n\t// this wave (or `undefined` if the dep was silent). Deps whose `equals`\n\t// absorb a repeat emission send `RESOLVED` instead of `DATA`, so silent\n\t// slots correctly mean \"no change\" and are omitted from the wire message.\n\t//\n\t// Net effect: no `.cache` reads inside fn, no `equals: () => false`, no\n\t// closure `lastSent` Map — Option B shape under v5 semantics.\n\tlet effectUnsub: (() => void) | undefined;\n\n\tif (exposeEntries.length > 0) {\n\t\tconst exposedNodes = exposeEntries.map(([, n]) => n) as Node[];\n\n\t\tconst aggregated = node<Record<string, unknown>>(\n\t\t\texposedNodes,\n\t\t\t(data, a) => {\n\t\t\t\tconst updates: Record<string, unknown> = {};\n\t\t\t\tfor (let i = 0; i < exposeEntries.length; i++) {\n\t\t\t\t\tconst [name] = exposeEntries[i];\n\t\t\t\t\tconst batch0 = data[i];\n\t\t\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\t\t\tupdates[name] = batch0.at(-1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Object.keys(updates).length === 0) return;\n\t\t\t\ta.emit(updates);\n\t\t\t},\n\t\t\t// Each `updates` object is a fresh allocation, so default reference\n\t\t\t// equality correctly propagates every aggregation wave — no\n\t\t\t// `equals: () => false` override needed.\n\t\t\t{ name: `${bridgeName}::aggregated` },\n\t\t);\n\n\t\tconst effectNode = effect([aggregated], (data) => {\n\t\t\tconst updates = data[0] as Record<string, unknown> | undefined;\n\t\t\tif (updates == null || Object.keys(updates).length === 0) return;\n\n\t\t\tconst transferList: Transferable[] = [];\n\t\t\tfor (const name of Object.keys(updates)) {\n\t\t\t\tconst fn = (transferFns as any)[name];\n\t\t\t\tif (fn) transferList.push(...fn(updates[name]));\n\t\t\t}\n\n\t\t\t// V0 delta sync: include version counters when available (§6.0b).\n\t\t\tlet versions: Record<string, number> | undefined;\n\t\t\tfor (const [name, n] of exposeEntries) {\n\t\t\t\tif (name in updates && n.v != null) {\n\t\t\t\t\tif (versions == null) versions = {};\n\t\t\t\t\tversions[name] = n.v.version;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst msg: BatchMessage = { t: \"b\", u: updates, ...(versions ? { v: versions } : {}) };\n\t\t\ttry {\n\t\t\t\ttransport.post(msg, transferList.length > 0 ? transferList : undefined);\n\t\t\t} catch (err) {\n\t\t\t\terrorNode.down([[DATA, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t}\n\t\t});\n\t\t// Effect nodes are lazy — subscribe to activate the chain\n\t\teffectUnsub = effectNode.subscribe(() => {});\n\t}\n\n\t// -- Receive handler -------------------------------------------------------\n\tlet destroyed = false;\n\n\tconst unlisten = transport.listen((data) => {\n\t\tif (destroyed) return;\n\t\tconst msg = data as BridgeMessage;\n\n\t\tswitch (msg.t) {\n\t\t\t// Worker ready — set proxy nodes with initial values.\n\t\t\t// The handshake deadline auto-cancels via the reactive race\n\t\t\t// (`statusNode → \"connected\"` wins) — no explicit clearTimeout.\n\t\t\tcase \"r\": {\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfor (const [name, value] of Object.entries(msg.stores)) {\n\t\t\t\t\t\tconst proxy = proxyNodes.get(name);\n\t\t\t\t\t\tif (proxy) proxy.down([[DATA, value]]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tstatusNode.down([[DATA, \"connected\"]]);\n\n\t\t\t\t// Send initial values of exposed nodes.\n\t\t\t\t// `.cache` here is a documented transport-boundary read: at the\n\t\t\t\t// worker's \"ready\" moment we need a point-in-time snapshot of\n\t\t\t\t// every exposed node, not a reactive wave. (§5.10 boundary.)\n\t\t\t\tconst initValues: Record<string, unknown> = {};\n\t\t\t\tfor (const [name, n] of exposeEntries) {\n\t\t\t\t\tinitValues[name] = n.cache;\n\t\t\t\t}\n\t\t\t\ttransport.post({ t: \"i\", stores: initValues } satisfies BridgeMessage);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Single value update from worker\n\t\t\tcase \"v\": {\n\t\t\t\tconst proxy = proxyNodes.get(msg.s);\n\t\t\t\tif (proxy) proxy.down([[DATA, msg.d]]);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Batch value update from worker\n\t\t\tcase \"b\": {\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfor (const [name, value] of Object.entries(msg.u)) {\n\t\t\t\t\t\tconst incomingVersion = msg.v?.[name];\n\t\t\t\t\t\tif (incomingVersion != null) {\n\t\t\t\t\t\t\tconst lastSeen = lastSeenImportVersions.get(name);\n\t\t\t\t\t\t\tif (lastSeen != null && incomingVersion <= lastSeen) continue;\n\t\t\t\t\t\t\tlastSeenImportVersions.set(name, incomingVersion);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst proxy = proxyNodes.get(name);\n\t\t\t\t\t\tif (proxy) proxy.down([[DATA, value]]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Error from worker node\n\t\t\tcase \"e\": {\n\t\t\t\tconst proxy = proxyNodes.get(msg.s);\n\t\t\t\tif (proxy) proxy.down([[ERROR, deserializeError(msg.err)]]);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Lifecycle signal from worker\n\t\t\tcase \"s\": {\n\t\t\t\tconst sig = nameToSignal(msg.sig);\n\t\t\t\tif (!sig) break;\n\n\t\t\t\tconst targets: Node<any>[] =\n\t\t\t\t\tmsg.s === \"*\"\n\t\t\t\t\t\t? [...proxyNodes.values()]\n\t\t\t\t\t\t: proxyNodes.has(msg.s)\n\t\t\t\t\t\t\t? [proxyNodes.get(msg.s)!]\n\t\t\t\t\t\t\t: [];\n\n\t\t\t\tfor (const proxy of targets) {\n\t\t\t\t\tproxy.down((msg.d === undefined ? [[sig]] : [[sig, msg.d]]) as Messages);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t});\n\n\t// -- Subscribe to exposed nodes: forward tier >= 3 messages -----------------\n\tconst exposeUnsubs: Array<() => void> = [];\n\tfor (const [name, n] of exposeEntries) {\n\t\tconst unsub = n.subscribe(((msgs: Messages) => {\n\t\t\tif (destroyed) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tconst type = m[0] as symbol;\n\t\t\t\t// DATA goes through the coalescing path — skip here\n\t\t\t\tif (type === DATA) continue;\n\t\t\t\t// Block graph-local signals (START, DIRTY, INVALIDATE, PAUSE, RESUME).\n\t\t\t\t// Unknown types forward (spec §1.3.6).\n\t\t\t\tif (defaultConfig.isLocalOnly(type)) continue;\n\t\t\t\t// ERROR: serialize payload\n\t\t\t\tif (type === ERROR) {\n\t\t\t\t\ttransport.post({\n\t\t\t\t\t\tt: \"e\",\n\t\t\t\t\t\ts: name,\n\t\t\t\t\t\terr: serializeError(m[1]),\n\t\t\t\t\t} satisfies BridgeMessage);\n\t\t\t\t} else {\n\t\t\t\t\t// RESOLVED, COMPLETE, TEARDOWN, and unknown Symbol.for types\n\t\t\t\t\ttransport.post({\n\t\t\t\t\t\tt: \"s\",\n\t\t\t\t\t\ts: name,\n\t\t\t\t\t\tsig: signalToName(type),\n\t\t\t\t\t\td: m.length > 1 ? m[1] : undefined,\n\t\t\t\t\t} satisfies BridgeMessage);\n\t\t\t\t}\n\t\t\t}\n\t\t}) as NodeSink);\n\t\texposeUnsubs.push(unsub);\n\t}\n\n\t// -- Handshake timeout — reactive race between status→\"connected\" and a\n\t// one-shot `fromTimer` deadline. Whichever fires first wins via `first()`,\n\t// which completes and auto-unsubs upstream (cancelling the deadline if\n\t// ready arrived first, or vice-versa).\n\tlet handshakeUnsub: (() => void) | undefined;\n\tif (opts.timeoutMs != null && opts.timeoutMs > 0) {\n\t\tconst deadline$ = fromTimer(opts.timeoutMs);\n\t\tconst ready$ = filter(statusNode, (s) => s === \"connected\");\n\t\tconst race$ = first(\n\t\t\tmerge(\n\t\t\t\tmap(deadline$, () => \"timeout\" as const),\n\t\t\t\tmap(ready$, () => \"ready\" as const),\n\t\t\t),\n\t\t);\n\t\thandshakeUnsub = race$.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA && m[1] === \"timeout\") {\n\t\t\t\t\terrorNode.down([[DATA, new Error(\"Worker bridge handshake timeout\")]]);\n\t\t\t\t\tdestroy();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t// -- Build result object ---------------------------------------------------\n\tfunction destroy() {\n\t\tif (destroyed) return;\n\t\tdestroyed = true;\n\n\t\thandshakeUnsub?.();\n\n\t\t// Send bridge-level TEARDOWN to worker\n\t\ttransport.post({\n\t\t\tt: \"s\",\n\t\t\ts: \"*\",\n\t\t\tsig: signalToName(TEARDOWN),\n\t\t} satisfies BridgeMessage);\n\n\t\t// Cleanup: unsub effect first (stops sending), then unsub expose\n\t\t// listeners, then unlisten on transport\n\t\tif (effectUnsub) effectUnsub();\n\t\tfor (const unsub of exposeUnsubs) unsub();\n\t\texposeUnsubs.length = 0;\n\t\tunlisten();\n\n\t\tstatusNode.down([[DATA, \"closed\"]]);\n\n\t\tlastSeenImportVersions.clear();\n\t\tproxyNodes.clear();\n\t}\n\n\tconst result: any = {\n\t\tmeta: { status: statusNode, error: errorNode },\n\t\tdestroy,\n\t};\n\n\t// Attach proxy nodes as properties\n\tfor (const [name, proxy] of proxyNodes) {\n\t\tresult[name] = proxy;\n\t}\n\n\treturn result as WorkerBridge<TExpose, TImport>;\n}\n","/**\n * workerSelf — worker-side reactive node bridge.\n *\n * Mirror of workerBridge() for the worker side. Creates proxy nodes for\n * imports from main thread, exposes local nodes via the same wire protocol.\n * Uses derived() + effect() for batch coalescing.\n *\n * Wire filtering: graph-local signals ({@link isLocalOnly}) stay local;\n * DATA values go through the coalescing path; RESOLVED, COMPLETE, ERROR,\n * TEARDOWN, and unknown {@link Symbol.for} types go through the signal\n * subscription.\n *\n * Handshake (worker perspective):\n * 1. workerSelf() called — creates proxy nodes for imports\n * 2. Runs expose factory with proxy nodes -> gets nodes to expose\n * 3. Sends { t: 'r', stores: { name: initialValue, ... } } to main\n * 4. Receives { t: 'i', stores: { name: value, ... } } from main\n * 5. Updates proxy nodes -> triggers local effects\n */\n\nimport { batch } from \"../../core/batch.js\";\nimport { DATA, ERROR, type Messages, TEARDOWN } from \"../../core/messages.js\";\nimport { defaultConfig, type Node, type NodeSink, node } from \"../../core/node.js\";\nimport { effect, state } from \"../../core/sugar.js\";\nimport type { BatchMessage, BridgeMessage } from \"./protocol.js\";\nimport { deserializeError, nameToSignal, serializeError, signalToName } from \"./protocol.js\";\nimport type { WorkerTransport } from \"./transport.js\";\nimport { createTransport } from \"./transport.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface WorkerSelfOptions<TImport extends readonly string[]> {\n\t/** Node names that the main thread will provide. */\n\timport?: TImport;\n\t/** Factory that receives imported proxy nodes and returns nodes to expose. */\n\texpose: (imported: WorkerImported<TImport>) => Record<string, Node<any>>;\n\t/** Per-node transferable extractors for zero-copy ArrayBuffer passing. */\n\ttransfer?: Record<string, (value: any) => Transferable[]>;\n}\n\n/** Proxy nodes available inside the worker from main-thread exposed nodes. */\ntype WorkerImported<T extends readonly string[]> = {\n\treadonly [K in T[number]]: Node<any>;\n};\n\nexport interface WorkerSelfHandle {\n\t/** Dispose all subscriptions and stop the bridge. */\n\tdestroy(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nfunction isTransport(t: unknown): t is WorkerTransport {\n\treturn (\n\t\ttypeof t === \"object\" &&\n\t\tt !== null &&\n\t\ttypeof (t as any).post === \"function\" &&\n\t\ttypeof (t as any).listen === \"function\"\n\t);\n}\n\nexport function workerSelf<TImport extends readonly string[]>(\n\ttarget: unknown | WorkerTransport,\n\topts: WorkerSelfOptions<TImport>,\n): WorkerSelfHandle {\n\tconst transport = isTransport(target) ? target : createTransport(target);\n\tconst importNames = (opts.import ?? []) as readonly string[];\n\tconst transferFns = opts.transfer ?? {};\n\n\t// -- Proxy nodes for imports (main -> worker) ------------------------------\n\tconst proxyNodes = new Map<string, Node<any>>();\n\tconst lastSeenImportVersions = new Map<string, number>();\n\tconst importedObj: any = {};\n\tfor (const name of importNames) {\n\t\tconst s = state(undefined, { name: `worker::${name}` });\n\t\tproxyNodes.set(name, s);\n\t\timportedObj[name] = s;\n\t}\n\n\t// -- Run expose factory ----------------------------------------------------\n\tconst exposedNodes = opts.expose(importedObj as WorkerImported<TImport>);\n\tconst exposeEntries = Object.entries(exposedNodes);\n\n\t// -- Send coalescing via raw `node` + `effect` ----------------------------\n\t// See bridge.ts for the Option B rationale — raw `node([deps], fn)` with\n\t// wave-form `data[]` replaces the prior `lastSent` diff + `.cache` reads.\n\tlet effectUnsub: (() => void) | undefined;\n\tlet destroyed = false;\n\n\tif (exposeEntries.length > 0) {\n\t\tconst nodes = exposeEntries.map(([, n]) => n) as Node[];\n\n\t\tconst aggregated = node<Record<string, unknown>>(\n\t\t\tnodes,\n\t\t\t(data, a) => {\n\t\t\t\tconst updates: Record<string, unknown> = {};\n\t\t\t\tfor (let i = 0; i < exposeEntries.length; i++) {\n\t\t\t\t\tconst [name] = exposeEntries[i];\n\t\t\t\t\tconst batch0 = data[i];\n\t\t\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\t\t\tupdates[name] = batch0.at(-1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Object.keys(updates).length === 0) return;\n\t\t\t\ta.emit(updates);\n\t\t\t},\n\t\t\t// Fresh `updates` object per wave → default reference equality is\n\t\t\t// correct; no `equals: () => false` override needed.\n\t\t\t{ name: \"workerSelf::aggregated\" },\n\t\t);\n\n\t\tconst effectNode = effect([aggregated], (data) => {\n\t\t\tif (destroyed) return;\n\t\t\tconst updates = data[0] as Record<string, unknown> | undefined;\n\t\t\tif (updates == null || Object.keys(updates).length === 0) return;\n\n\t\t\tconst transferList: Transferable[] = [];\n\t\t\tfor (const name of Object.keys(updates)) {\n\t\t\t\tconst fn = (transferFns as any)[name];\n\t\t\t\tif (fn) transferList.push(...fn(updates[name]));\n\t\t\t}\n\n\t\t\t// V0 delta sync: include version counters when available (§6.0b).\n\t\t\tlet versions: Record<string, number> | undefined;\n\t\t\tfor (const [name, n] of exposeEntries) {\n\t\t\t\tif (name in updates && n.v != null) {\n\t\t\t\t\tif (versions == null) versions = {};\n\t\t\t\t\tversions[name] = n.v.version;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst msg: BatchMessage = { t: \"b\", u: updates, ...(versions ? { v: versions } : {}) };\n\t\t\ttry {\n\t\t\t\ttransport.post(msg, transferList.length > 0 ? transferList : undefined);\n\t\t\t} catch (_err) {\n\t\t\t\t// Transport failure — bridge is likely destroyed; swallow\n\t\t\t}\n\t\t});\n\t\t// Effect nodes are lazy — subscribe to activate the chain\n\t\teffectUnsub = effectNode.subscribe(() => {});\n\t}\n\n\t// -- Subscribe to exposed nodes: forward tier >= 3 messages -----------------\n\tconst exposeUnsubs: Array<() => void> = [];\n\tfor (const [name, n] of exposeEntries) {\n\t\tconst unsub = n.subscribe(((msgs: Messages) => {\n\t\t\tif (destroyed) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tconst type = m[0] as symbol;\n\t\t\t\t// DATA goes through the coalescing path — skip here\n\t\t\t\tif (type === DATA) continue;\n\t\t\t\t// Block graph-local signals (START, DIRTY, INVALIDATE, PAUSE, RESUME).\n\t\t\t\t// Unknown types forward (spec §1.3.6).\n\t\t\t\tif (defaultConfig.isLocalOnly(type)) continue;\n\t\t\t\t// ERROR: serialize payload\n\t\t\t\tif (type === ERROR) {\n\t\t\t\t\ttransport.post({\n\t\t\t\t\t\tt: \"e\",\n\t\t\t\t\t\ts: name,\n\t\t\t\t\t\terr: serializeError(m[1]),\n\t\t\t\t\t} satisfies BridgeMessage);\n\t\t\t\t} else {\n\t\t\t\t\t// RESOLVED, COMPLETE, TEARDOWN, and unknown Symbol.for types\n\t\t\t\t\ttransport.post({\n\t\t\t\t\t\tt: \"s\",\n\t\t\t\t\t\ts: name,\n\t\t\t\t\t\tsig: signalToName(type),\n\t\t\t\t\t\td: m.length > 1 ? m[1] : undefined,\n\t\t\t\t\t} satisfies BridgeMessage);\n\t\t\t\t}\n\t\t\t}\n\t\t}) as NodeSink);\n\t\texposeUnsubs.push(unsub);\n\t}\n\n\t// -- Receive handler -------------------------------------------------------\n\tconst unlisten = transport.listen((data) => {\n\t\tif (destroyed) return;\n\t\tconst msg = data as BridgeMessage;\n\n\t\tswitch (msg.t) {\n\t\t\t// Init from main — set proxy node values\n\t\t\tcase \"i\": {\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfor (const [name, value] of Object.entries(msg.stores)) {\n\t\t\t\t\t\tconst proxy = proxyNodes.get(name);\n\t\t\t\t\t\tif (proxy) proxy.down([[DATA, value]]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Single value update from main\n\t\t\tcase \"v\": {\n\t\t\t\tconst proxy = proxyNodes.get(msg.s);\n\t\t\t\tif (proxy) proxy.down([[DATA, msg.d]]);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Batch value update from main\n\t\t\tcase \"b\": {\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfor (const [name, value] of Object.entries(msg.u)) {\n\t\t\t\t\t\tconst incomingVersion = msg.v?.[name];\n\t\t\t\t\t\tif (incomingVersion != null) {\n\t\t\t\t\t\t\tconst lastSeen = lastSeenImportVersions.get(name);\n\t\t\t\t\t\t\tif (lastSeen != null && incomingVersion <= lastSeen) continue;\n\t\t\t\t\t\t\tlastSeenImportVersions.set(name, incomingVersion);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst proxy = proxyNodes.get(name);\n\t\t\t\t\t\tif (proxy) proxy.down([[DATA, value]]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Error from main node\n\t\t\tcase \"e\": {\n\t\t\t\tconst proxy = proxyNodes.get(msg.s);\n\t\t\t\tif (proxy) proxy.down([[ERROR, deserializeError(msg.err)]]);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Lifecycle signal from main\n\t\t\tcase \"s\": {\n\t\t\t\tconst sig = nameToSignal(msg.sig);\n\t\t\t\tif (!sig) break;\n\n\t\t\t\tif (sig === TEARDOWN && msg.s === \"*\") {\n\t\t\t\t\tdestroy();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst targets: Node<any>[] =\n\t\t\t\t\tmsg.s === \"*\"\n\t\t\t\t\t\t? [...proxyNodes.values()]\n\t\t\t\t\t\t: proxyNodes.has(msg.s)\n\t\t\t\t\t\t\t? [proxyNodes.get(msg.s)!]\n\t\t\t\t\t\t\t: [];\n\n\t\t\t\tfor (const proxy of targets) {\n\t\t\t\t\tproxy.down((msg.d === undefined ? [[sig]] : [[sig, msg.d]]) as Messages);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t});\n\n\t// -- Send ready message ----------------------------------------------------\n\t// `.cache` is a documented transport-boundary snapshot read here — not a\n\t// reactive access (§5.10 boundary).\n\tconst readyValues: Record<string, unknown> = {};\n\tfor (const [name, n] of exposeEntries) {\n\t\treadyValues[name] = n.cache;\n\t}\n\ttransport.post({ t: \"r\", stores: readyValues } satisfies BridgeMessage);\n\n\t// -- Destroy ---------------------------------------------------------------\n\tfunction destroy() {\n\t\tif (destroyed) return;\n\t\tdestroyed = true;\n\n\t\t// Cleanup: unsub effect first (stops sending), then expose listeners,\n\t\t// then unlisten on transport\n\t\tif (effectUnsub) effectUnsub();\n\t\tfor (const unsub of exposeUnsubs) unsub();\n\t\texposeUnsubs.length = 0;\n\t\tunlisten();\n\t\ttransport.terminate?.();\n\n\t\tlastSeenImportVersions.clear();\n\t\tproxyNodes.clear();\n\t}\n\n\treturn { destroy };\n}\n"],"mappings":"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","names":["buffer","node","cached","batch","batch","delay","last","sourceOpts","debounce","resolvePath","buffer","out","retry","isThenable","buffer","p","operatorOpts","clampNonNegative","isNode","isThenable","sourceOpts","retry","buffer","batch","seq","map","first","map","keepalive","node","node","take","keepaliveDerived","first","import_node_fs","import_node_path","isTransport"]}
|
|
1
|
+
{"version":3,"sources":["../../src/extra/index.ts","../../src/core/batch.ts","../../src/core/clock.ts","../../src/core/messages.ts","../../src/graph/codec.ts","../../src/core/actor.ts","../../src/core/config.ts","../../src/core/guard.ts","../../src/core/versioning.ts","../../src/core/node.ts","../../src/core/sugar.ts","../../src/extra/backoff.ts","../../src/extra/external-register.ts","../../src/extra/sources.ts","../../src/extra/cron.ts","../../src/extra/operators.ts","../../src/extra/utils/ring-buffer.ts","../../src/extra/reactive-sink.ts","../../src/extra/timer.ts","../../src/extra/resilience.ts","../../src/extra/adapters.ts","../../src/extra/backpressure.ts","../../src/extra/cascading-cache.ts","../../src/extra/reactive-map.ts","../../src/extra/composite.ts","../../src/extra/observable.ts","../../src/extra/pubsub.ts","../../src/extra/reactive-index.ts","../../src/extra/reactive-list.ts","../../src/extra/reactive-log.ts","../../src/extra/storage.ts","../../src/extra/worker/protocol.ts","../../src/extra/worker/transport.ts","../../src/extra/worker/bridge.ts","../../src/extra/worker/self.ts"],"sourcesContent":["/**\n * Extra layer: operators, sources, sinks (Phase 2+).\n */\n\nexport * from \"./adapters.js\";\nexport * from \"./backoff.js\";\nexport * from \"./backpressure.js\";\nexport * from \"./cascading-cache.js\";\nexport * from \"./composite.js\";\nexport * from \"./cron.js\";\nexport * from \"./external-register.js\";\nexport * from \"./observable.js\";\nexport * from \"./operators.js\";\nexport * from \"./pubsub.js\";\nexport * from \"./reactive-index.js\";\nexport * from \"./reactive-list.js\";\nexport * from \"./reactive-log.js\";\nexport * from \"./reactive-map.js\";\nexport * from \"./reactive-sink.js\";\n// Re-export resilience explicitly to avoid `timeout` / `pipe` conflicts with operators.js\nexport {\n\ttype CircuitBreaker,\n\ttype CircuitBreakerOptions,\n\tCircuitOpenError,\n\ttype CircuitState,\n\tcircuitBreaker,\n\ttype FallbackInput,\n\tfallback,\n\ttype RateLimiterOptions,\n\tRateLimiterOverflowError,\n\ttype RateLimiterOverflowPolicy,\n\ttype RetryOptions,\n\ttype RetrySourceOptions,\n\trateLimiter,\n\tretry,\n\tretrySource,\n\ttype StatusValue,\n\tTimeoutError,\n\ttype TokenBucket,\n\ttimeout,\n\ttokenBucket,\n\ttype WithBreakerBundle,\n\ttype WithStatusBundle,\n\twithBreaker,\n\twithStatus,\n} from \"./resilience.js\";\nexport * from \"./sources.js\";\nexport * from \"./storage.js\";\nexport { ResettableTimer } from \"./timer.js\";\nexport * from \"./worker/index.js\";\n","/**\n * Batch deferral for tier-3+ messages, plus per-node emit coalescing inside\n * explicit `batch()` scopes.\n *\n * §1.3.7 — Inside a batch, tier 0–2 signals propagate immediately. Tier 3\n * (DATA/RESOLVED), tier 4 (COMPLETE/ERROR), and tier 5 (TEARDOWN) are queued\n * and drained in ascending phase order after the outermost `batch()` callback\n * returns.\n *\n * **Per-node emit coalescing (Bug 2 fix, 2026-04-17).** Inside an explicit\n * `batch()` scope, consecutive emissions from the same node accumulate in\n * `NodeImpl._batchPendingMessages` instead of each producing a separate\n * downstream wave. At batch end, each node flushes its accumulated messages\n * as ONE multi-message `downWithBatch` call — K `.emit()`s to the same\n * source collapse to K DIRTYs in one tier-1 sink call + K DATAs in one\n * tier-3 sink call. Downstream nodes' fns run once per wave with the full\n * `batchData` (dep's `dataBatch` accumulates all K values, fn sees\n * `[[v1, v2, ..., vK]]`). Resolves the K+1 fan-in over-fire.\n *\n * Outside batch — and during drain (where `flushInProgress` is true but\n * `batchDepth` is 0) — coalescing does NOT apply: each emit goes through\n * its own `downWithBatch` call and produces its own wave.\n *\n * **Phase vocabulary:**\n * - Phase 1 = tiers 0–2 — immediate, never queued.\n * - Phase 2 = tier 3 — {@link drainPhase2}. Value settlements.\n * - Phase 3 = tier 4 — {@link drainPhase3}. Terminal signals.\n * - Phase 4 = tier 5 — {@link drainPhase4}. TEARDOWN (unified deferral).\n *\n * Drain rule: fire any pending flush hooks first, then the lowest non-empty\n * phase. Re-enqueues during drain (and hooks registered by reentrant batches\n * inside subscriber callbacks) bump the loop back to the top so newly-added\n * hooks and closures get processed.\n *\n * **Pre-sorted input invariant.** `downWithBatch` assumes `messages` is\n * already sorted in ascending tier order (produced by `_frameBatch` in\n * `node.ts`). The walker exploits monotonicity for a single O(n) pass and\n * slices at phase boundaries without re-sorting. Flushed multi-emit batches\n * re-run `_frameBatch` to restore monotonicity (the per-emit framings\n * accumulate in interleaved order: `[DIRTY, DATA, DIRTY, DATA, ...]`).\n */\n\nimport type { Messages } from \"./messages.js\";\n\nconst MAX_DRAIN_ITERATIONS = 1000;\n\nlet batchDepth = 0;\nlet flushInProgress = false;\n\n/** Tier 3 (DATA/RESOLVED) deferral queue — drained first. */\nconst drainPhase2: Array<() => void> = [];\n/** Tier 4 (COMPLETE/ERROR) deferral queue — drained after phase 2. */\nconst drainPhase3: Array<() => void> = [];\n/** Tier 5 (TEARDOWN) deferral queue — drained last. */\nconst drainPhase4: Array<() => void> = [];\n\n/**\n * Per-batch flush hooks. Each hook is registered by a node the first time\n * it accumulates an emission inside an explicit `batch()` scope (Bug 2 —\n * per-node emit coalescing). Hooks fire at the head of `drainPending`,\n * before the standard tier-3/4/5 drain queues — they call `downWithBatch`\n * with the node's accumulated multi-message batch, which enqueues the\n * tier-3+ portion into `drainPhase2/3/4` for the standard loop.\n *\n * On a `batch()` throw, hooks still fire so each node clears its pending\n * state (they're idempotent — the side-effects are wiped because the\n * drainPhase queues that they enqueue into are cleared in the same finally\n * block).\n */\nconst flushHooks: Array<() => void> = [];\n\n/**\n * Returns whether the current call stack is inside a batch scope **or** while\n * a deferred drain is in progress. Nested `downWithBatch` calls during drain\n * still defer (they bump the drain loop).\n */\nexport function isBatching(): boolean {\n\treturn batchDepth > 0 || flushInProgress;\n}\n\n/**\n * Returns whether the current call stack is inside an **explicit** `batch()`\n * scope. Excludes `flushInProgress` — i.e. emissions that happen during a\n * drain (e.g. inside a fn callback) are NOT explicitly batched and should\n * not trigger per-node coalescing (Bug 2).\n */\nexport function isExplicitlyBatching(): boolean {\n\treturn batchDepth > 0;\n}\n\n/**\n * Register a hook to fire at the head of the next `drainPending`. Used by\n * `NodeImpl._emit` to flush its per-batch accumulator (Bug 2). If called\n * outside an explicit batch the hook fires immediately, since there's no\n * drain coming.\n */\nexport function registerBatchFlushHook(hook: () => void): void {\n\tif (batchDepth > 0) {\n\t\tflushHooks.push(hook);\n\t} else {\n\t\thook();\n\t}\n}\n\n/**\n * Runs `fn` inside a batch scope. Nested `batch()` calls share one deferral\n * queue. If `fn` throws, deferred work for the outer frame is discarded\n * (unless a drain is already in progress — cross-language decision A4).\n */\nexport function batch(fn: () => void): void {\n\tbatchDepth += 1;\n\tlet threw = false;\n\ttry {\n\t\tfn();\n\t} catch (e) {\n\t\tthrew = true;\n\t\tthrow e;\n\t} finally {\n\t\tbatchDepth -= 1;\n\t\tif (batchDepth === 0) {\n\t\t\tif (threw) {\n\t\t\t\tif (!flushInProgress) {\n\t\t\t\t\t// Fire any per-node flush hooks so nodes clear their\n\t\t\t\t\t// pending state. The downWithBatch calls those hooks\n\t\t\t\t\t// make enqueue into drainPhase queues — those queues\n\t\t\t\t\t// are cleared right after, so the side-effects are\n\t\t\t\t\t// wiped. Net result: clean node state, no delivery.\n\t\t\t\t\tconst hooks = flushHooks.splice(0);\n\t\t\t\t\tfor (const h of hooks) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\th();\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* best-effort */\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdrainPhase2.length = 0;\n\t\t\t\t\tdrainPhase3.length = 0;\n\t\t\t\t\tdrainPhase4.length = 0;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdrainPending();\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction drainPending(): void {\n\tconst ownsFlush = !flushInProgress;\n\tif (ownsFlush) flushInProgress = true;\n\n\tconst errors: unknown[] = [];\n\n\tlet iterations = 0;\n\ttry {\n\t\t// Loop while EITHER tier-3+ deferred work OR pending flush hooks exist.\n\t\t// Hooks can be re-registered mid-drain by reentrant `batch()` calls\n\t\t// inside subscriber callbacks; checking `flushHooks` each iteration\n\t\t// (not just before the loop) ensures those late hooks fire too.\n\t\twhile (\n\t\t\tdrainPhase2.length > 0 ||\n\t\t\tdrainPhase3.length > 0 ||\n\t\t\tdrainPhase4.length > 0 ||\n\t\t\t(ownsFlush && flushHooks.length > 0)\n\t\t) {\n\t\t\t// Fire any pending flush hooks FIRST so their downWithBatch calls\n\t\t\t// enqueue tier-3+ work into drainPhase before we process it.\n\t\t\tif (ownsFlush && flushHooks.length > 0) {\n\t\t\t\tconst hooks = flushHooks.splice(0);\n\t\t\t\tfor (const h of hooks) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\th();\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\terrors.push(e);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue; // restart loop — hooks may have enqueued tier-3+ work or more hooks\n\t\t\t}\n\t\t\titerations += 1;\n\t\t\tif (iterations > MAX_DRAIN_ITERATIONS) {\n\t\t\t\tdrainPhase2.length = 0;\n\t\t\t\tdrainPhase3.length = 0;\n\t\t\t\tdrainPhase4.length = 0;\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`batch drain exceeded ${MAX_DRAIN_ITERATIONS} iterations — likely a reactive cycle`,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Always drain the lowest non-empty phase. Re-enqueues at any level\n\t\t\t// cause the next iteration to restart from phase 2 if needed.\n\t\t\tconst queue =\n\t\t\t\tdrainPhase2.length > 0 ? drainPhase2 : drainPhase3.length > 0 ? drainPhase3 : drainPhase4;\n\t\t\tconst ops = queue.splice(0);\n\t\t\tfor (const run of ops) {\n\t\t\t\ttry {\n\t\t\t\t\trun();\n\t\t\t\t} catch (e) {\n\t\t\t\t\terrors.push(e);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tif (ownsFlush) flushInProgress = false;\n\t}\n\n\tif (errors.length === 1) throw errors[0];\n\tif (errors.length > 1) {\n\t\tthrow new AggregateError(errors, \"batch drain: multiple callbacks threw\");\n\t}\n}\n\n/**\n * Deliver pre-sorted messages through `sink` with tier-based deferral applied.\n *\n * `messages` MUST be in ascending tier order (produced by `_frameBatch` in\n * `node.ts`); the walker exploits that invariant to find phase cuts in one\n * pass without re-sorting.\n *\n * Behavior:\n * - Tier 0–2 — delivered synchronously.\n * - Tier 3 — deferred to {@link drainPhase2} when batching, else synchronous.\n * - Tier 4 — deferred to {@link drainPhase3} when batching, else synchronous.\n * - Tier 5 — deferred to {@link drainPhase4} when batching, else synchronous.\n *\n * Tier-classification uses the caller-supplied `tierOf` so that batch stays\n * decoupled from `GraphReFlyConfig`. NodeImpl passes `config.tierOf` (a\n * pre-bound closure built once in the config constructor) at the emit site;\n * alternate configs can pass their own lookup.\n */\nexport function downWithBatch(\n\tsink: (messages: Messages) => void,\n\tmessages: Messages,\n\ttierOf: (t: symbol) => number,\n): void {\n\tif (messages.length === 0) return;\n\n\t// Fast path: single message (hot in propagation).\n\tif (messages.length === 1) {\n\t\tconst tier = tierOf(messages[0][0]);\n\t\tif (tier < 3 || !isBatching()) {\n\t\t\tsink(messages);\n\t\t\treturn;\n\t\t}\n\t\tconst queue = tier >= 5 ? drainPhase4 : tier === 4 ? drainPhase3 : drainPhase2;\n\t\tqueue.push(() => sink(messages));\n\t\treturn;\n\t}\n\n\t// Multi-message: walk once over pre-sorted input, find phase cuts.\n\t// Monotone tier order means `phase2Start <= phase3Start <= phase4Start`.\n\tconst n = messages.length;\n\tlet phase2Start = n;\n\tlet phase3Start = n;\n\tlet phase4Start = n;\n\n\tlet i = 0;\n\twhile (i < n && tierOf(messages[i][0]) < 3) i++;\n\tphase2Start = i;\n\twhile (i < n && tierOf(messages[i][0]) === 3) i++;\n\tphase3Start = i;\n\twhile (i < n && tierOf(messages[i][0]) === 4) i++;\n\tphase4Start = i;\n\t// Anything from phase4Start..n has tier >= 5.\n\n\tconst batching = isBatching();\n\n\tif (phase2Start > 0) {\n\t\t// Immediate tier 0–2 region.\n\t\tconst immediate = messages.slice(0, phase2Start);\n\t\tsink(immediate);\n\t}\n\n\tif (phase3Start > phase2Start) {\n\t\tconst phase2 = messages.slice(phase2Start, phase3Start);\n\t\tif (batching) drainPhase2.push(() => sink(phase2));\n\t\telse sink(phase2);\n\t}\n\n\tif (phase4Start > phase3Start) {\n\t\tconst phase3 = messages.slice(phase3Start, phase4Start);\n\t\tif (batching) drainPhase3.push(() => sink(phase3));\n\t\telse sink(phase3);\n\t}\n\n\tif (n > phase4Start) {\n\t\tconst phase4 = messages.slice(phase4Start, n);\n\t\tif (batching) drainPhase4.push(() => sink(phase4));\n\t\telse sink(phase4);\n\t}\n}\n","/**\n * Centralised timestamp utilities.\n *\n * Convention: all graphrefly-ts timestamps use nanoseconds (`_ns` suffix).\n *\n * - {@link monotonicNs} — monotonic clock (ordering, durations, timeline events).\n * - {@link wallClockNs} — wall-clock (mutation attribution, cron emission).\n *\n * **Precision limits (JS platform):**\n *\n * - `monotonicNs`: effective ~microsecond precision. `performance.now()` returns\n * milliseconds with ~5µs resolution; the last 3 digits of the nanosecond value\n * are always zero. Python's `time.monotonic_ns()` gives true nanoseconds.\n *\n * - `wallClockNs`: ~256ns precision loss at current epoch. `Date.now() * 1e6`\n * produces values around 1.8×10¹⁸ which exceed IEEE 754's 2⁵³ safe integer\n * limit. Python's `time.time_ns()` (arbitrary-precision `int`) has no loss.\n * In practice this is irrelevant — JS is single-threaded, so sub-microsecond\n * timestamp collisions cannot occur.\n */\n\n/** Monotonic nanosecond timestamp via `performance.now()`. */\nexport function monotonicNs(): number {\n\treturn Math.trunc(performance.now() * 1_000_000);\n}\n\n/** Wall-clock nanosecond timestamp via `Date.now()`. */\nexport function wallClockNs(): number {\n\treturn Date.now() * 1_000_000;\n}\n","/**\n * GraphReFly message protocol — §1 `~/src/graphrefly/GRAPHREFLY-SPEC.md`.\n * Emissions are always `[[Type, Data?], ...]` (no single-tuple shorthand).\n *\n * This file is protocol-pure:\n * - Message type symbols (10 built-ins).\n * - `Message` / `Messages` tuple types.\n * - `MessageTypeRegistration` interface (shape of a registry entry).\n *\n * It does NOT own the registry, tier lookups, or any cross-cutting singleton\n * state — that lives in `GraphReFlyConfig` (see `config.ts`) so custom\n * protocols can build isolated instances. Import this module when you need\n * the symbol constants or the tuple types; import `config.ts` when you need\n * tier / wire-crossing / registry lookups.\n */\n\n/** Subscribe-time handshake. Delivered to each new sink at the top of `subscribe()`. Tier 0. */\nexport const START = Symbol.for(\"graphrefly/START\");\n/** Value delivery (`DATA`, value). Tier 3 — deferred inside `batch()`. */\nexport const DATA = Symbol.for(\"graphrefly/DATA\");\n/** Phase 1: value about to change. Tier 1 — immediate. */\nexport const DIRTY = Symbol.for(\"graphrefly/DIRTY\");\n/** Phase 2: dirty pass completed, value unchanged. Tier 3 — deferred inside `batch()`. */\nexport const RESOLVED = Symbol.for(\"graphrefly/RESOLVED\");\n/** Clear cached state; do not auto-emit. Tier 1 — immediate. */\nexport const INVALIDATE = Symbol.for(\"graphrefly/INVALIDATE\");\n/** Suspend activity. Tier 2 — immediate. */\nexport const PAUSE = Symbol.for(\"graphrefly/PAUSE\");\n/** Resume after pause. Tier 2 — immediate. */\nexport const RESUME = Symbol.for(\"graphrefly/RESUME\");\n/** Permanent cleanup. Tier 5 — deferred to batch phase 4. */\nexport const TEARDOWN = Symbol.for(\"graphrefly/TEARDOWN\");\n/** Clean termination. Tier 4 — deferred to batch phase 3. */\nexport const COMPLETE = Symbol.for(\"graphrefly/COMPLETE\");\n/** Error termination. Tier 4 — deferred to batch phase 3. */\nexport const ERROR = Symbol.for(\"graphrefly/ERROR\");\n\n/** One protocol tuple: `[Type, optional payload]`. */\nexport type Message = readonly [symbol, unknown?];\n\n/** A batch of tuples — the wire shape for `node.down()` / `node.up()`. */\nexport type Messages = readonly Message[];\n\n// ---------------------------------------------------------------------------\n// Interned singletons for payload-free tuples\n// ---------------------------------------------------------------------------\n//\n// Every emission path used to allocate fresh `[[DIRTY]]`, `[[RESOLVED]]`,\n// etc. — two arrays per emit in the hot path. Since none of these tuples\n// carry a payload, one frozen instance is indistinguishable from a\n// fresh one. We intern them at module load and reuse forever. Only\n// `[DATA, v]`, `[ERROR, e]`, `[PAUSE, lockId]`, `[RESUME, lockId]` still\n// allocate per-call because they carry payloads.\n//\n// Downstream code MUST treat these as immutable. `Object.freeze` makes\n// accidental mutation throw in strict mode. Do not `push`, splice, or\n// otherwise mutate a Messages array that came from one of these.\n\n/** Singleton `[DIRTY]` tuple — payload-free, interned. */\nexport const DIRTY_MSG: Message = Object.freeze([DIRTY]) as Message;\n/** Singleton `[RESOLVED]` tuple — payload-free, interned. */\nexport const RESOLVED_MSG: Message = Object.freeze([RESOLVED]) as Message;\n/** Singleton `[INVALIDATE]` tuple — payload-free, interned. */\nexport const INVALIDATE_MSG: Message = Object.freeze([INVALIDATE]) as Message;\n/** Singleton `[START]` tuple — payload-free, interned. */\nexport const START_MSG: Message = Object.freeze([START]) as Message;\n/** Singleton `[COMPLETE]` tuple — payload-free, interned. */\nexport const COMPLETE_MSG: Message = Object.freeze([COMPLETE]) as Message;\n/** Singleton `[TEARDOWN]` tuple — payload-free, interned. */\nexport const TEARDOWN_MSG: Message = Object.freeze([TEARDOWN]) as Message;\n\n/** Pre-wrapped `[[DIRTY]]` for `_emit([DIRTY_ONLY_BATCH])`-style callers. */\nexport const DIRTY_ONLY_BATCH: Messages = Object.freeze([DIRTY_MSG]) as Messages;\n/** Pre-wrapped `[[RESOLVED]]`. */\nexport const RESOLVED_ONLY_BATCH: Messages = Object.freeze([RESOLVED_MSG]) as Messages;\n/** Pre-wrapped `[[INVALIDATE]]`. */\nexport const INVALIDATE_ONLY_BATCH: Messages = Object.freeze([INVALIDATE_MSG]) as Messages;\n/** Pre-wrapped `[[COMPLETE]]`. */\nexport const COMPLETE_ONLY_BATCH: Messages = Object.freeze([COMPLETE_MSG]) as Messages;\n/** Pre-wrapped `[[TEARDOWN]]`. */\nexport const TEARDOWN_ONLY_BATCH: Messages = Object.freeze([TEARDOWN_MSG]) as Messages;\n\n// ---------------------------------------------------------------------------\n// Registry entry shape\n// ---------------------------------------------------------------------------\n\n/**\n * Per-type record stored in a {@link GraphReFlyConfig}'s registry.\n *\n * - `tier` — signal tier (0–5 built-in; custom tiers allowed but should fit\n * the phase model used by `batch.ts`).\n * - `wireCrossing` — when `true`, forwarded across SSE/WebSocket/worker\n * adapters. Defaults to `tier >= 3` if omitted in registration input.\n * - `metaPassthrough` — when `false`, this message type is filtered out of\n * `Graph.signal` deliveries to meta companion nodes (spec §2.3). Meta\n * companions still receive everything via their primary's own cascade.\n * Defaults to `true` (meta receives the message).\n */\nexport interface MessageTypeRegistration {\n\ttier: number;\n\twireCrossing: boolean;\n\tmetaPassthrough: boolean;\n}\n\n/**\n * Input accepted by {@link GraphReFlyConfig.registerMessageType}. Only `tier`\n * is required; `wireCrossing` defaults to `tier >= 3`; `metaPassthrough`\n * defaults to `true`.\n */\nexport interface MessageTypeRegistrationInput {\n\ttier: number;\n\twireCrossing?: boolean;\n\tmetaPassthrough?: boolean;\n}\n","/**\n * GraphCodec — pluggable serialization for graph snapshots (Phase 8.6).\n *\n * Design reference: `archive/docs/SESSION-serialization-memory-footprint.md`\n *\n * The codec interface decouples snapshot format from graph internals.\n * Default is JSON (current behavior). DAG-CBOR and compressed variants\n * ship as optional codecs. FlatBuffers/Arrow for advanced tiers.\n *\n * Tiered representation:\n * HOT — JS objects (live propagation, no codec involved)\n * WARM — DAG-CBOR in-memory buffer (lazy hydration, delta checkpoints)\n * COLD — Arrow/Parquet (bulk storage, ML pipelines, archival)\n * PEEK — FlatBuffers (zero-copy read from dormant graph)\n *\n * Wire-protocol envelope (v1):\n *\n * [envelope_v=1: u8][name_len: u8][name: utf8][codec_v: u16 BE][payload: rest]\n *\n * `graph.snapshot({format: \"bytes\", codec: name})` wraps the codec's\n * `encode` output in this envelope; `Graph.decode(bytes)` auto-dispatches\n * via the config's codec registry — no out-of-band content-type needed.\n */\n\nimport type { GraphReFlyConfig } from \"../core/config.js\";\nimport type { GraphCheckpointRecord, GraphPersistSnapshot } from \"./graph.js\";\n\n// ---------------------------------------------------------------------------\n// Core codec interface\n// ---------------------------------------------------------------------------\n\n/**\n * Encode/decode graph snapshots to/from binary.\n *\n * Implementations must be deterministic: `encode(x)` always produces the\n * same bytes for the same input. This is critical for CID computation (V1)\n * and snapshot hash-comparison.\n */\nexport interface GraphCodec {\n\t/** Human-readable name; used as the lookup key in the envelope and config registry. */\n\treadonly name: string;\n\n\t/**\n\t * Codec version. Bumps on breaking wire format changes; `decode` receives\n\t * this via the envelope so codecs can dispatch on historical layouts.\n\t * Must fit in a `u16` (0–65535).\n\t */\n\treadonly version: number;\n\n\t/** MIME-like content type identifier (e.g. `\"application/dag-cbor+zstd\"`). */\n\treadonly contentType: string;\n\n\t/** Encode a snapshot to binary. */\n\tencode(snapshot: GraphPersistSnapshot): Uint8Array;\n\n\t/**\n\t * Decode binary back to a snapshot.\n\t *\n\t * `codecVersion` is the version that produced `buffer` (read from the\n\t * envelope). Omit when the caller is sure of the version (tests, one-shot\n\t * round-trips). Codecs that support multiple historical layouts dispatch\n\t * on this value.\n\t *\n\t * For lazy codecs, this may return a proxy that decodes nodes on access\n\t * (see {@link LazyGraphCodec}).\n\t */\n\tdecode(buffer: Uint8Array, codecVersion?: number): GraphPersistSnapshot;\n}\n\n/**\n * Extended codec that supports lazy (on-demand) node decoding.\n *\n * `decodeLazy` returns a snapshot where `nodes` is a Proxy — individual\n * nodes are decoded only when accessed. This enables near-zero cold-start\n * for large graphs (decode envelope + topology, skip node values until read).\n */\nexport interface LazyGraphCodec extends GraphCodec {\n\t/** Decode envelope and topology; defer node value decoding to access time. */\n\tdecodeLazy(buffer: Uint8Array, codecVersion?: number): GraphPersistSnapshot;\n}\n\n// ---------------------------------------------------------------------------\n// Delta checkpoint types (requires V0 — Phase 6.0)\n// ---------------------------------------------------------------------------\n\n/**\n * WAL entry. Unified with {@link GraphCheckpointRecord} — every record\n * already carries `mode` / `seq` / `timestamp_ns` / `format_version`, so the\n * WAL is just an ordered list of records. `replayWAL` walks this list.\n */\nexport type WALEntry = GraphCheckpointRecord;\n\n// ---------------------------------------------------------------------------\n// Eviction policy (dormant subgraph management)\n// ---------------------------------------------------------------------------\n\n/**\n * Policy for evicting dormant subgraphs to reduce memory.\n *\n * When a subgraph hasn't propagated for `idleTimeoutMs`, it is serialized\n * using the graph's codec and JS objects are released. Re-hydrated on next\n * access (read, propagation, describe).\n */\nexport interface EvictionPolicy {\n\t/** Milliseconds of inactivity before eviction. */\n\tidleTimeoutMs: number;\n\t/** Codec to use for serializing evicted subgraphs (default: graph's codec). */\n\tcodec?: GraphCodec;\n}\n\n/** Metadata about an evicted subgraph, exposed via describe(). */\nexport interface EvictedSubgraphInfo {\n\t/** True if currently evicted (serialized, JS objects released). */\n\tevicted: true;\n\t/** Wall-clock ns of last propagation before eviction. */\n\tlastActiveNs: bigint;\n\t/** Size of serialized buffer in bytes. */\n\tserializedBytes: number;\n\t/** Codec used for serialization. */\n\tcodecName: string;\n}\n\n// ---------------------------------------------------------------------------\n// JSON codec (default — wraps current behavior)\n// ---------------------------------------------------------------------------\n\n/**\n * Default JSON codec. Wraps `JSON.stringify`/`JSON.parse` with deterministic\n * key ordering (matching current `snapshot()` behavior).\n */\nexport const JsonCodec: GraphCodec = {\n\tname: \"json\",\n\tversion: 1,\n\tcontentType: \"application/json\",\n\n\tencode(snapshot: GraphPersistSnapshot): Uint8Array {\n\t\t// Deterministic: snapshot() already sorts keys.\n\t\tconst json = JSON.stringify(snapshot);\n\t\treturn new TextEncoder().encode(json);\n\t},\n\n\tdecode(buffer: Uint8Array, _codecVersion?: number): GraphPersistSnapshot {\n\t\tconst json = new TextDecoder().decode(buffer);\n\t\treturn JSON.parse(json) as GraphPersistSnapshot;\n\t},\n};\n\n// ---------------------------------------------------------------------------\n// DAG-CBOR codec (factory — requires @ipld/dag-cbor DI)\n// ---------------------------------------------------------------------------\n\n/**\n * Create a DAG-CBOR codec.\n *\n * Requires `@ipld/dag-cbor` as a peer dependency. ~40-50% smaller than JSON,\n * deterministic encoding (required for V1 CID), CID links as native type.\n *\n * @example\n * ```ts\n * import * as dagCbor from \"@ipld/dag-cbor\";\n * const codec = createDagCborCodec(dagCbor);\n * config.registerCodec(codec);\n * const bytes = graph.snapshot({ format: \"bytes\", codec: \"dag-cbor\" });\n * ```\n */\nexport function createDagCborCodec(dagCbor: {\n\tencode: (value: unknown) => Uint8Array;\n\tdecode: (bytes: Uint8Array) => unknown;\n}): GraphCodec {\n\treturn {\n\t\tname: \"dag-cbor\",\n\t\tversion: 1,\n\t\tcontentType: \"application/dag-cbor\",\n\t\tencode: (snapshot) => dagCbor.encode(snapshot),\n\t\tdecode: (buffer, _codecVersion) => dagCbor.decode(buffer) as GraphPersistSnapshot,\n\t};\n}\n\n/**\n * Create a DAG-CBOR + zstd codec. ~80-90% smaller than JSON.\n *\n * Requires `@ipld/dag-cbor` and a zstd implementation (e.g. `fzstd` for\n * browser, `node:zlib` for Node.js).\n *\n * @example\n * ```ts\n * import * as dagCbor from \"@ipld/dag-cbor\";\n * import { compressSync, decompressSync } from \"fzstd\";\n * const codec = createDagCborZstdCodec(dagCbor, { compressSync, decompressSync });\n * config.registerCodec(codec);\n * ```\n */\nexport function createDagCborZstdCodec(\n\tdagCbor: {\n\t\tencode: (value: unknown) => Uint8Array;\n\t\tdecode: (bytes: Uint8Array) => unknown;\n\t},\n\tzstd: {\n\t\tcompressSync: (data: Uint8Array) => Uint8Array;\n\t\tdecompressSync: (data: Uint8Array) => Uint8Array;\n\t},\n): GraphCodec {\n\treturn {\n\t\tname: \"dag-cbor-zstd\",\n\t\tversion: 1,\n\t\tcontentType: \"application/dag-cbor+zstd\",\n\t\tencode: (snapshot) => zstd.compressSync(dagCbor.encode(snapshot)),\n\t\tdecode: (buffer, _codecVersion) =>\n\t\t\tdagCbor.decode(zstd.decompressSync(buffer)) as GraphPersistSnapshot,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Envelope (v1) — self-describing codec metadata prepended to payload bytes\n// ---------------------------------------------------------------------------\n\n/** Current envelope format version. Bump on breaking layout changes. */\nexport const ENVELOPE_VERSION = 1;\n\nconst ENVELOPE_MIN_LEN = 4; // env_v(1) + name_len(1) + codec_v(2) + name/payload(≥0)\n\n/**\n * Prepend the v1 envelope to `payload` identifying `codec`. The resulting\n * bytes are self-describing — any caller with access to the registering\n * {@link GraphReFlyConfig} can {@link decodeEnvelope} without knowing the\n * codec up front.\n *\n * Layout:\n * `[envelope_v=1: u8][name_len: u8][name: utf8][codec_v: u16 BE][payload: rest]`\n *\n * @throws If `codec.name` encodes to more than 255 UTF-8 bytes or\n * `codec.version` doesn't fit in a u16.\n */\nexport function encodeEnvelope(\n\tcodec: Pick<GraphCodec, \"name\" | \"version\">,\n\tpayload: Uint8Array,\n): Uint8Array {\n\tconst nameBytes = new TextEncoder().encode(codec.name);\n\tif (nameBytes.length === 0 || nameBytes.length > 255) {\n\t\tthrow new Error(\n\t\t\t`encodeEnvelope: codec name \"${codec.name}\" encodes to ${nameBytes.length} bytes (must be 1–255)`,\n\t\t);\n\t}\n\tconst cv = codec.version;\n\tif (!Number.isInteger(cv) || cv < 0 || cv > 0xffff) {\n\t\tthrow new Error(\n\t\t\t`encodeEnvelope: codec.version ${cv} out of u16 range (expected integer 0–65535)`,\n\t\t);\n\t}\n\t// Guard against RangeError-on-alloc for very large payloads — we need\n\t// `Number.isSafeInteger` math on `1 + 1 + nameBytes.length + 2 +\n\t// payload.length` and the resulting Uint8Array must fit within the\n\t// platform limit (2³² − 1 bytes on 64-bit JS engines).\n\tconst totalLen = 1 + 1 + nameBytes.length + 2 + payload.length;\n\tif (totalLen > 0xffffffff) {\n\t\tthrow new Error(\n\t\t\t`encodeEnvelope: total envelope size ${totalLen} exceeds 2^32-1 bytes (payload ${payload.length} bytes)`,\n\t\t);\n\t}\n\tconst out = new Uint8Array(totalLen);\n\tlet i = 0;\n\tout[i++] = ENVELOPE_VERSION;\n\tout[i++] = nameBytes.length;\n\tout.set(nameBytes, i);\n\ti += nameBytes.length;\n\tout[i++] = (cv >>> 8) & 0xff;\n\tout[i++] = cv & 0xff;\n\tout.set(payload, i);\n\treturn out;\n}\n\n/**\n * Inverse of {@link encodeEnvelope}. Reads the header, resolves the codec\n * via `config.lookupCodec(name)`, and returns the codec + its version + the\n * inner payload slice. The caller feeds `payload` to `codec.decode(payload,\n * codecVersion)` — or uses {@link Graph.decode} which does both steps.\n *\n * @throws If the envelope is truncated, the version is unsupported, or the\n * named codec isn't registered on `config`.\n */\nexport function decodeEnvelope(\n\tbytes: Uint8Array,\n\tconfig: GraphReFlyConfig,\n): { codec: GraphCodec; codecVersion: number; payload: Uint8Array } {\n\tif (bytes.length < ENVELOPE_MIN_LEN) {\n\t\tthrow new Error(`decodeEnvelope: bytes too short (${bytes.length} < ${ENVELOPE_MIN_LEN})`);\n\t}\n\tlet i = 0;\n\tconst envVersion = bytes[i++]!;\n\tif (envVersion !== ENVELOPE_VERSION) {\n\t\tthrow new Error(\n\t\t\t`decodeEnvelope: unsupported envelope version ${envVersion} (expected ${ENVELOPE_VERSION})`,\n\t\t);\n\t}\n\tconst nameLen = bytes[i++]!;\n\tif (nameLen === 0) {\n\t\tthrow new Error(\"decodeEnvelope: name_len must be >= 1\");\n\t}\n\tif (i + nameLen + 2 > bytes.length) {\n\t\tthrow new Error(\n\t\t\t`decodeEnvelope: envelope truncated (need ${i + nameLen + 2} bytes, have ${bytes.length})`,\n\t\t);\n\t}\n\tconst name = new TextDecoder().decode(bytes.subarray(i, i + nameLen));\n\ti += nameLen;\n\tconst codecVersion = ((bytes[i]! << 8) | bytes[i + 1]!) >>> 0;\n\ti += 2;\n\tconst payload = bytes.subarray(i);\n\tconst codec = config.lookupCodec<GraphCodec>(name);\n\tif (codec == null) {\n\t\tthrow new Error(\n\t\t\t`decodeEnvelope: codec \"${name}\" not registered (envelope codec_v=${codecVersion})`,\n\t\t);\n\t}\n\treturn { codec, codecVersion, payload };\n}\n\n/**\n * Register the built-in {@link JsonCodec} on a config. Called once on\n * `defaultConfig` at module load so `graph.snapshot({format: \"bytes\", codec:\n * \"json\"})` works out of the box. Test / isolated configs should call this\n * manually before the first node is created.\n */\nexport function registerBuiltinCodecs(config: GraphReFlyConfig): void {\n\tconfig.registerCodec(JsonCodec);\n}\n\n// ---------------------------------------------------------------------------\n// WAL helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Reconstruct a snapshot from a WAL (sequence of {@link GraphCheckpointRecord}s).\n *\n * - Must start with a `\"full\"` record carrying a baseline snapshot — that's\n * the anchor {@link Graph.attachStorage} always emits on the first flush\n * of any tier (and every `compactEvery`-th flush thereafter).\n * - Subsequent `\"full\"` entries (compaction points) **replace** the result\n * wholesale.\n * - `\"diff\"` entries roll forward by applying the structural diff —\n * added nodes (via `nodesAddedFull`), removed nodes, and changed fields\n * are reflected into the accumulated snapshot.\n *\n * Validates monotonic `seq` progression across entries.\n */\nexport function replayWAL(entries: readonly WALEntry[]): GraphPersistSnapshot {\n\tif (entries.length === 0) {\n\t\tthrow new Error(\"WAL is empty — need at least one full snapshot\");\n\t}\n\n\tconst first = entries[0]!;\n\tif (first.mode !== \"full\") {\n\t\tthrow new Error(\"WAL must start with a full record carrying a baseline snapshot\");\n\t}\n\n\tlet result: GraphPersistSnapshot = JSON.parse(JSON.stringify(first.snapshot));\n\tlet prevSeq: number = first.seq;\n\n\tfor (let i = 1; i < entries.length; i++) {\n\t\tconst entry = entries[i]!;\n\t\tif (entry.seq <= prevSeq) {\n\t\t\tthrow new Error(\n\t\t\t\t`WAL chain broken at index ${i}: seq=${entry.seq} must exceed prev seq=${prevSeq}`,\n\t\t\t);\n\t\t}\n\n\t\tif (entry.mode === \"full\") {\n\t\t\t// Replace baseline wholesale (Unit 23 D fix — Object.assign left\n\t\t\t// stale keys from pre-compact state visible).\n\t\t\tresult = JSON.parse(JSON.stringify(entry.snapshot));\n\t\t\tprevSeq = entry.seq;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// mode === \"diff\": apply structural diff to the accumulated snapshot.\n\t\tconst diff = entry.diff;\n\t\t// Apply removes first so a path reused across a remove+add in a single\n\t\t// diff lands on the `nodesAddedFull` slice rather than being wiped.\n\t\tfor (const path of diff.nodesRemoved) {\n\t\t\tdelete result.nodes[path];\n\t\t}\n\t\t// Reinstate added nodes from the full-slice payload carried by\n\t\t// GraphWALDiff. Deep-clone so later mutations don't alias the WAL\n\t\t// entry's source slice.\n\t\tconst addedFull = diff.nodesAddedFull;\n\t\tif (addedFull != null) {\n\t\t\tfor (const [path, slice] of Object.entries(addedFull)) {\n\t\t\t\tresult.nodes[path] = JSON.parse(JSON.stringify(slice));\n\t\t\t}\n\t\t}\n\t\tfor (const change of diff.nodesChanged) {\n\t\t\tconst existing = result.nodes[change.path];\n\t\t\tif (existing == null) continue;\n\t\t\t(existing as Record<string, unknown>)[change.field] = change.to;\n\t\t}\n\n\t\t// Edges are derived from node `_deps` at restore time (Unit 7) — no\n\t\t// separate edge-patch pass.\n\t\tprevSeq = entry.seq;\n\t}\n\n\treturn result;\n}\n","/**\n * Who is performing an operation (attribution + ABAC input).\n *\n * @see GRAPHREFLY-SPEC — roadmap Phase 1.5 (Actor & Guard).\n */\nexport type Actor = {\n\ttype: \"human\" | \"llm\" | \"wallet\" | \"system\" | string;\n\tid: string;\n} & Record<string, unknown>;\n\n/** Default actor when none is passed ({@link normalizeActor}). */\nexport const DEFAULT_ACTOR: Actor = { type: \"system\", id: \"\" };\n\n/**\n * Fills missing `type` / `id` on an actor and returns {@link DEFAULT_ACTOR} when input is undefined.\n *\n * @param actor - Optional partial actor from a transport hint.\n * @returns A normalized `Actor` safe to pass to guards and graph APIs.\n *\n * @example\n * ```ts\n * import { normalizeActor } from \"@graphrefly/graphrefly-ts\";\n *\n * normalizeActor({ type: \"human\", id: \"u1\" });\n * ```\n */\nexport function normalizeActor(actor?: Actor): Actor {\n\tif (actor == null) return DEFAULT_ACTOR;\n\tconst { type, id, ...rest } = actor;\n\treturn {\n\t\ttype: type ?? \"system\",\n\t\tid: id ?? \"\",\n\t\t...rest,\n\t} as Actor;\n}\n","/**\n * Singleton protocol config. Holds the message-type registry, the\n * `onMessage` / `onSubscribe` hooks, versioning defaults, and the freeze flag.\n *\n * Layering: this file is protocol-pure. It imports only from `messages.ts`\n * and declares opaque type shapes for handlers — the concrete default\n * implementations and the `defaultConfig` instance live in `node.ts` so that\n * handler bodies can touch `NodeImpl` internals without creating a cycle.\n *\n * Two access paths:\n * 1. **Default instance** (`defaultConfig` in `node.ts`) — use\n * `configure((cfg) => ...)` at app startup; every node implicitly binds to it.\n * 2. **Isolated instance** (`new GraphReFlyConfig(...)`) — pass via\n * `opts.config` for test isolation or custom protocol stacks.\n *\n * A config **freezes on first getter read** of any hook (`onMessage`,\n * `onSubscribe`). `NodeImpl`'s constructor intentionally touches one of these\n * on first use so configuration cannot drift once nodes exist.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tINVALIDATE,\n\ttype Message,\n\ttype Messages,\n\ttype MessageTypeRegistration,\n\ttype MessageTypeRegistrationInput,\n\tPAUSE,\n\tRESOLVED,\n\tRESUME,\n\tSTART,\n\tTEARDOWN,\n} from \"./messages.js\";\nimport type { HashFn, VersioningLevel } from \"./versioning.js\";\n\n// ---------------------------------------------------------------------------\n// Handler type shapes\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal node surface visible to default handlers. Concrete `NodeImpl`\n * implements this plus a large set of package-private fields; handlers that\n * need the richer surface cast to the concrete type in `node.ts`.\n */\nexport interface NodeCtx {\n\treadonly name?: string;\n\treadonly status: string;\n\treadonly cache: unknown;\n}\n\n/** Imperative actions available inside a node's compute function (§5). */\nexport interface NodeActions {\n\t/**\n\t * Sugar for `down([[DATA, value]])`. One call = one wave with a\n\t * single DATA payload. The emit pipeline auto-prefixes `[DIRTY]`,\n\t * runs equals substitution against the live cache, and dispatches\n\t * to sinks with phase deferral. Diamond-safe by construction.\n\t */\n\temit(value: unknown): void;\n\t/**\n\t * Send one or more messages downstream. Accepts either a single\n\t * {@link Message} tuple or a {@link Messages} array of tuples. One\n\t * call = one wave: the emit pipeline tier-sorts the input,\n\t * auto-prefixes `[DIRTY]` when a tier-3 payload is present and the\n\t * node isn't already dirty, runs equals substitution, then\n\t * dispatches. Multiple calls produce multiple waves.\n\t */\n\tdown(messageOrMessages: Message | Messages): void;\n\t/**\n\t * Send one or more messages upstream. Accepts the same shapes as\n\t * {@link down}. Tier 3 (DATA/RESOLVED) and tier 4 (COMPLETE/ERROR)\n\t * are downstream-only and will throw — up is for DIRTY, INVALIDATE,\n\t * PAUSE, RESUME, and TEARDOWN only. No cache advance, no equals,\n\t * no framing — a plain forward to every dep.\n\t */\n\tup(messageOrMessages: Message | Messages): void;\n}\n\n/**\n * Message-flow context passed to {@link OnMessageHandler}.\n *\n * - `\"down-in\"` — message arriving from a dep (identified by `depIndex`).\n * - `\"up-in\"` — message arriving from a sink.\n */\nexport type MessageContext = { direction: \"down-in\"; depIndex: number } | { direction: \"up-in\" };\n\n/**\n * Per-sink context passed to {@link OnSubscribeHandler}.\n */\nexport interface SubscribeContext {\n\t/** Post-subscribe sink count. `1` means first subscriber after 0. */\n\tsinkCount: number;\n\t/** True when this subscribe cleared a resubscribable terminal state. */\n\tafterTerminalReset: boolean;\n}\n\n/**\n * Singleton message interceptor. Called for every message in either direction\n * before the default per-tier dispatch runs. Return `\"consume\"` to suppress\n * default handling.\n */\nexport type OnMessageHandler = (\n\tnode: NodeCtx,\n\tmsg: Message,\n\tctx: MessageContext,\n\tactions: NodeActions,\n) => \"consume\" | undefined;\n\n/**\n * Singleton subscribe ceremony. Fires for every sink subscribe on every node.\n * Default implementation emits the START handshake (+ cached DATA when\n * present) to the new sink. Return a cleanup function to run on unsubscribe.\n */\nexport type OnSubscribeHandler = (\n\tnode: NodeCtx,\n\tsink: (messages: Messages) => void,\n\tctx: SubscribeContext,\n\tactions: NodeActions,\n) => (() => void) | undefined;\n\n/**\n * Event payload for {@link GlobalInspectorHook}. One event fires per outgoing\n * message batch from any node bound to the config.\n *\n * - `kind: \"emit\"` — fires after equals substitution (`finalMessages`) and\n * before sink dispatch. `messages` is the exact batch sinks see.\n */\nexport type GlobalInspectorEvent = {\n\tkind: \"emit\";\n\tnode: NodeCtx;\n\tmessages: Messages;\n};\n\n/**\n * Process-global observability hook for full-graph tracing\n * (Redux-DevTools-style action history). Fires from every node's `_emit`\n * waist whenever {@link GraphReFlyConfig.inspectorEnabled} is `true`.\n *\n * Distinct from per-node `_setInspectorHook` (which is the dep-message /\n * fn-run causal trace used by `Graph.observe(path, { causal, derived })`).\n * Use the global hook to record every emission across every node — useful for\n * time-travel debuggers, tracers, and replay tooling. Use the per-node hook\n * to attribute a single subscribed path's wave to its driving deps.\n *\n * Errors thrown from the hook are swallowed — instrumentation must not break\n * the data plane.\n */\nexport type GlobalInspectorHook = (event: GlobalInspectorEvent) => void;\n\n// ---------------------------------------------------------------------------\n// GraphReFlyConfig\n// ---------------------------------------------------------------------------\n\n/**\n * Singleton protocol config.\n *\n * A config freezes on first getter read of any hook. After freeze, any\n * attempt to mutate (register a message type, set a hook) throws.\n */\nexport class GraphReFlyConfig {\n\tprivate _messageTypes = new Map<symbol, MessageTypeRegistration>();\n\tprivate _codecs = new Map<string, { readonly name: string; readonly version: number }>();\n\tprivate _onMessage: OnMessageHandler;\n\tprivate _onSubscribe: OnSubscribeHandler;\n\tprivate _defaultVersioning: VersioningLevel | undefined;\n\tprivate _defaultHashFn: HashFn | undefined;\n\tprivate _inspectorEnabled: boolean = !(\n\t\ttypeof process !== \"undefined\" && process.env?.NODE_ENV === \"production\"\n\t);\n\tprivate _globalInspector?: GlobalInspectorHook;\n\tprivate _frozen = false;\n\n\t/**\n\t * Pre-bound tier lookup — shared by every node bound to this config. Since\n\t * the registry is frozen on first hook access, this closure can be built\n\t * once in the constructor and handed directly to `downWithBatch` /\n\t * `_frameBatch` paths without per-node or per-emission `.bind(config)`\n\t * allocation.\n\t */\n\treadonly tierOf: (t: symbol) => number;\n\n\tconstructor(init: {\n\t\tonMessage: OnMessageHandler;\n\t\tonSubscribe: OnSubscribeHandler;\n\t\tdefaultVersioning?: VersioningLevel;\n\t\tdefaultHashFn?: HashFn;\n\t}) {\n\t\tthis._onMessage = init.onMessage;\n\t\tthis._onSubscribe = init.onSubscribe;\n\t\tthis._defaultVersioning = init.defaultVersioning;\n\t\tthis._defaultHashFn = init.defaultHashFn;\n\t\t// Captured once. Calls back into `this._messageTypes` — still returns\n\t\t// the current registration, but post-freeze the registry is immutable\n\t\t// so the closure is effectively constant.\n\t\tthis.tierOf = (t: symbol): number => {\n\t\t\tconst reg = this._messageTypes.get(t);\n\t\t\treturn reg != null ? reg.tier : 1;\n\t\t};\n\t}\n\n\t// --- Hook getters (freeze on read) ---\n\n\tget onMessage(): OnMessageHandler {\n\t\tthis._frozen = true;\n\t\treturn this._onMessage;\n\t}\n\n\tget onSubscribe(): OnSubscribeHandler {\n\t\tthis._frozen = true;\n\t\treturn this._onSubscribe;\n\t}\n\n\t// --- Hook setters (throw when frozen) ---\n\n\tset onMessage(v: OnMessageHandler) {\n\t\tthis._assertUnfrozen();\n\t\tthis._onMessage = v;\n\t}\n\n\tset onSubscribe(v: OnSubscribeHandler) {\n\t\tthis._assertUnfrozen();\n\t\tthis._onSubscribe = v;\n\t}\n\n\t/**\n\t * Default versioning level applied to every node bound to this config,\n\t * unless the node's own `opts.versioning` provides an explicit override.\n\t * Setting this is only allowed before the config freezes (i.e., before\n\t * the first node is created) so every node in the graph sees a\n\t * consistent starting level. Individual nodes can still opt into a\n\t * higher level via `opts.versioning`, or post-hoc via\n\t * `NodeImpl._applyVersioning(level)` when the node is quiescent.\n\t *\n\t * v0 is the minimum opt-in — unversioned nodes (`undefined`) skip\n\t * the version counter entirely. v1 adds content-addressed cid.\n\t * Future levels (v2, v3) are reserved for linked-history and\n\t * cryptographic attestation extensions.\n\t */\n\tget defaultVersioning(): VersioningLevel | undefined {\n\t\treturn this._defaultVersioning;\n\t}\n\tset defaultVersioning(v: VersioningLevel | undefined) {\n\t\tthis._assertUnfrozen();\n\t\tthis._defaultVersioning = v;\n\t}\n\n\t/**\n\t * Default content-hash function applied to every versioned node bound\n\t * to this config, unless the node's own `opts.versioningHash` provides\n\t * an explicit override. Use this when a graph needs a non-default hash\n\t * — e.g., swap the vendored sync SHA-256 for a faster non-crypto hash\n\t * (xxHash, FNV-1a) in hot-path workloads, or a stronger hash when\n\t * versioning v1 cids are used as audit anchors.\n\t *\n\t * Only settable before the config freezes. Individual nodes can still\n\t * override via `opts.versioningHash`.\n\t */\n\tget defaultHashFn(): HashFn | undefined {\n\t\treturn this._defaultHashFn;\n\t}\n\tset defaultHashFn(v: HashFn | undefined) {\n\t\tthis._assertUnfrozen();\n\t\tthis._defaultHashFn = v;\n\t}\n\n\t/**\n\t * When `false`, structured observation options (`causal`, `timeline`)\n\t * and `Graph.trace()` writes are no-ops. Raw `Graph.observe()` always\n\t * works. Default: `true` outside production (`NODE_ENV !== \"production\"`).\n\t *\n\t * Settable at any time — inspector gating is an operational concern, not\n\t * a protocol invariant, so it does NOT require freeze before node creation.\n\t */\n\tget inspectorEnabled(): boolean {\n\t\treturn this._inspectorEnabled;\n\t}\n\tset inspectorEnabled(v: boolean) {\n\t\tthis._inspectorEnabled = v;\n\t}\n\n\t/**\n\t * Process-global observability hook (Redux-DevTools-style full-graph\n\t * tracer). Fires once per outgoing batch from every node bound to this\n\t * config, gated by {@link inspectorEnabled}. See {@link GlobalInspectorHook}.\n\t *\n\t * Settable at any time — like {@link inspectorEnabled} this is operational,\n\t * not protocol-shaping, so it does NOT trigger config freeze.\n\t */\n\tget globalInspector(): GlobalInspectorHook | undefined {\n\t\treturn this._globalInspector;\n\t}\n\tset globalInspector(v: GlobalInspectorHook | undefined) {\n\t\tthis._globalInspector = v;\n\t}\n\n\t// --- Registry (writes require unfrozen; reads are free lookups) ---\n\n\t/**\n\t * Register a custom message type. Must be called before any node that\n\t * uses this config has been created — otherwise throws. Default\n\t * `wireCrossing` is `tier >= 3`.\n\t */\n\tregisterMessageType(t: symbol, input: MessageTypeRegistrationInput): this {\n\t\tthis._assertUnfrozen();\n\t\tthis._messageTypes.set(t, {\n\t\t\ttier: input.tier,\n\t\t\twireCrossing: input.wireCrossing ?? input.tier >= 3,\n\t\t\tmetaPassthrough: input.metaPassthrough ?? true,\n\t\t});\n\t\treturn this;\n\t}\n\n\t/** Tier for `t`. Unknown types default to tier 1 (immediate, after START). */\n\tmessageTier(t: symbol): number {\n\t\tconst reg = this._messageTypes.get(t);\n\t\treturn reg != null ? reg.tier : 1;\n\t}\n\n\t/**\n\t * Whether `t` is registered as wire-crossing. Unknown types default to\n\t * `true` (spec §1.3.6 forward-compat — unknowns cross the wire).\n\t */\n\tisWireCrossing(t: symbol): boolean {\n\t\tconst reg = this._messageTypes.get(t);\n\t\treturn reg != null ? reg.wireCrossing : true;\n\t}\n\n\t/** Convenience inverse of {@link isWireCrossing}. */\n\tisLocalOnly(t: symbol): boolean {\n\t\treturn !this.isWireCrossing(t);\n\t}\n\n\t/**\n\t * Whether `t` is forwarded to meta companions by `Graph.signal`. Defaults\n\t * to `true` for unknowns (forward-compat — new types pass through meta by\n\t * default; opt-in filter via `registerMessageType({metaPassthrough: false})`).\n\t */\n\tisMetaPassthrough(t: symbol): boolean {\n\t\tconst reg = this._messageTypes.get(t);\n\t\treturn reg != null ? reg.metaPassthrough : true;\n\t}\n\n\t/** Whether `t` is a registered (built-in or custom) type. */\n\tisKnownMessageType(t: symbol): boolean {\n\t\treturn this._messageTypes.has(t);\n\t}\n\n\t// --- Codec registry (writes require unfrozen; reads are free lookups) ---\n\n\t/**\n\t * Register a graph codec by `codec.name`. Used by the envelope-based\n\t * `graph.snapshot({format: \"bytes\", codec: name})` path and\n\t * `Graph.decode(bytes)` auto-dispatch. Must be called before any node\n\t * bound to this config is created — otherwise throws.\n\t *\n\t * Re-registering the same name overwrites, so user codecs can shadow\n\t * built-in ones before freeze (e.g., to swap a zstd-wrapped dag-cbor in\n\t * for `\"dag-cbor\"`).\n\t */\n\tregisterCodec<T extends { readonly name: string; readonly version: number }>(codec: T): this {\n\t\tthis._assertUnfrozen();\n\t\tthis._codecs.set(codec.name, codec);\n\t\treturn this;\n\t}\n\n\t/**\n\t * Resolve a registered codec by name. Returns `undefined` for unknown\n\t * names. Typed callers cast to their concrete codec interface (e.g.,\n\t * `config.lookupCodec<GraphCodec>(\"json\")`) — this method stays\n\t * layer-pure (no import of graph-layer types into `core/`).\n\t */\n\tlookupCodec<T = { readonly name: string; readonly version: number }>(\n\t\tname: string,\n\t): T | undefined {\n\t\treturn this._codecs.get(name) as T | undefined;\n\t}\n\n\t/** @internal Used by tests and dev tooling — check freeze state without triggering it. */\n\t_isFrozen(): boolean {\n\t\treturn this._frozen;\n\t}\n\n\tprivate _assertUnfrozen(): void {\n\t\tif (this._frozen) {\n\t\t\tthrow new Error(\n\t\t\t\t\"GraphReFlyConfig is frozen: a node has already captured this config. \" +\n\t\t\t\t\t\"Register custom types and set hooks before creating any node.\",\n\t\t\t);\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Built-in registration\n// ---------------------------------------------------------------------------\n\n/**\n * Register the 10 built-in message types on a fresh config. Called by\n * `node.ts` when it constructs `defaultConfig` and by test code / advanced\n * users after `new GraphReFlyConfig(...)`.\n */\nexport function registerBuiltins(cfg: GraphReFlyConfig): void {\n\tcfg.registerMessageType(START, { tier: 0, wireCrossing: false });\n\tcfg.registerMessageType(DIRTY, { tier: 1, wireCrossing: false });\n\t// INVALIDATE, COMPLETE, ERROR, TEARDOWN do NOT pass through to meta\n\t// companions via Graph.signal (spec §2.3). Meta still sees them via the\n\t// primary's own down-cascade.\n\tcfg.registerMessageType(INVALIDATE, {\n\t\ttier: 1,\n\t\twireCrossing: false,\n\t\tmetaPassthrough: false,\n\t});\n\tcfg.registerMessageType(PAUSE, { tier: 2, wireCrossing: false });\n\tcfg.registerMessageType(RESUME, { tier: 2, wireCrossing: false });\n\tcfg.registerMessageType(DATA, { tier: 3, wireCrossing: true });\n\tcfg.registerMessageType(RESOLVED, { tier: 3, wireCrossing: true });\n\tcfg.registerMessageType(COMPLETE, {\n\t\ttier: 4,\n\t\twireCrossing: true,\n\t\tmetaPassthrough: false,\n\t});\n\tcfg.registerMessageType(ERROR, {\n\t\ttier: 4,\n\t\twireCrossing: true,\n\t\tmetaPassthrough: false,\n\t});\n\tcfg.registerMessageType(TEARDOWN, {\n\t\ttier: 5,\n\t\twireCrossing: true,\n\t\tmetaPassthrough: false,\n\t});\n}\n","import type { Actor } from \"./actor.js\";\n\n/**\n * Actions checked by {@link NodeGuard}. `write` covers both {@link Node.down} and\n * {@link Node.up} today; finer-grained strings may be added later (e.g. `\"write.data\"`).\n */\nexport type GuardAction = \"write\" | \"signal\" | \"observe\" | (string & {});\n\nexport type NodeGuard = (actor: Actor, action: GuardAction) => boolean;\n\nexport type GuardDeniedDetails = {\n\tactor: Actor;\n\taction: GuardAction;\n\t/** Registry or options name when known */\n\tnodeName?: string;\n};\n\n/**\n * Thrown when a {@link NodeGuard} denies an action for a given actor.\n *\n * Carries the rejected `actor`, `action`, and optional `nodeName` for diagnostic\n * messages and middleware error handling.\n *\n * @example\n * ```ts\n * import { GuardDenied, policy } from \"@graphrefly/graphrefly-ts\";\n *\n * const guard = policy((allow) => { allow(\"observe\"); });\n * try {\n * if (!guard({ type: \"llm\", id: \"agent-1\" }, \"write\")) {\n * throw new GuardDenied(\n * { actor: { type: \"llm\", id: \"agent-1\" }, action: \"write\", nodeName: \"userInput\" },\n * );\n * }\n * } catch (e) {\n * if (e instanceof GuardDenied) console.error(e.action, e.actor.type); // \"write\" \"llm\"\n * }\n * ```\n */\nexport class GuardDenied extends Error {\n\treadonly actor: Actor;\n\treadonly action: GuardAction;\n\treadonly nodeName?: string;\n\n\t/**\n\t * @param details - Actor, action, and optional node name for the denial.\n\t * @param message - Optional override for the default error message.\n\t */\n\tconstructor(details: GuardDeniedDetails, message?: string) {\n\t\tsuper(\n\t\t\tmessage ??\n\t\t\t\t`GuardDenied: action \"${String(details.action)}\" denied for actor type \"${String(details.actor.type)}\"`,\n\t\t);\n\t\tthis.name = \"GuardDenied\";\n\t\tthis.actor = details.actor;\n\t\tthis.action = details.action;\n\t\tthis.nodeName = details.nodeName;\n\t}\n\n\t/** Qualified registry path when known (roadmap diagnostics: same as {@link nodeName}). */\n\tget node(): string | undefined {\n\t\treturn this.nodeName;\n\t}\n}\n\ntype Where = (actor: Actor) => boolean;\n\ntype Rule = {\n\tkind: \"allow\" | \"deny\";\n\tactions: Set<GuardAction>;\n\twhere: Where;\n};\n\nfunction normalizeActions(action: GuardAction | readonly GuardAction[]): GuardAction[] {\n\tif (Array.isArray(action)) {\n\t\treturn [...action];\n\t}\n\treturn [action as GuardAction];\n}\n\nfunction matchesActions(set: Set<GuardAction>, action: GuardAction): boolean {\n\treturn set.has(action) || set.has(\"*\" as GuardAction);\n}\n\nexport type PolicyAllow = (\n\taction: GuardAction | readonly GuardAction[],\n\topts?: { where?: Where },\n) => void;\n\nexport type PolicyDeny = (\n\taction: GuardAction | readonly GuardAction[],\n\topts?: { where?: Where },\n) => void;\n\nexport type PolicyRuleData = {\n\teffect: \"allow\" | \"deny\";\n\taction: GuardAction | readonly GuardAction[];\n\tactorType?: string | readonly string[];\n\tactorId?: string | readonly string[];\n\tclaims?: Record<string, unknown>;\n};\n\n/**\n * Declarative guard builder. Precedence: any matching **deny** blocks even if an allow also matches.\n * If no rule matches, the guard returns `false` (deny-by-default). Aligned with graphrefly-py `policy()`.\n *\n * @param build - Callback that registers `allow(...)` / `deny(...)` rules in order.\n * @returns A `NodeGuard` for use as `node({ guard })`.\n *\n * @example\n * ```ts\n * const guard = policy((allow, deny) => {\n * allow(\"observe\");\n * deny(\"write\", { where: (a) => a.type === \"llm\" });\n * });\n * ```\n */\nexport function policy(build: (allow: PolicyAllow, deny: PolicyDeny) => void): NodeGuard {\n\tconst rules: Rule[] = [];\n\tconst allow: PolicyAllow = (action, opts) => {\n\t\trules.push({\n\t\t\tkind: \"allow\",\n\t\t\tactions: new Set(normalizeActions(action)),\n\t\t\twhere: opts?.where ?? (() => true),\n\t\t});\n\t};\n\tconst deny: PolicyDeny = (action, opts) => {\n\t\trules.push({\n\t\t\tkind: \"deny\",\n\t\t\tactions: new Set(normalizeActions(action)),\n\t\t\twhere: opts?.where ?? (() => true),\n\t\t});\n\t};\n\tbuild(allow, deny);\n\treturn (actor, action) => {\n\t\tlet denied = false;\n\t\tlet allowed = false;\n\t\tfor (const r of rules) {\n\t\t\tif (!matchesActions(r.actions, action)) continue;\n\t\t\tif (!r.where(actor)) continue;\n\t\t\tif (r.kind === \"deny\") {\n\t\t\t\tdenied = true;\n\t\t\t} else {\n\t\t\t\tallowed = true;\n\t\t\t}\n\t\t}\n\t\tif (denied) return false;\n\t\treturn allowed;\n\t};\n}\n\n/**\n * Rebuild a declarative guard from persisted policy data (snapshot-safe).\n *\n * Rules are deny-overrides, same semantics as {@link policy}.\n */\nexport function policyFromRules(rules: readonly PolicyRuleData[]): NodeGuard {\n\treturn policy((allow, deny) => {\n\t\tfor (const rule of rules) {\n\t\t\tconst actorTypes =\n\t\t\t\trule.actorType == null\n\t\t\t\t\t? null\n\t\t\t\t\t: new Set(Array.isArray(rule.actorType) ? rule.actorType : [rule.actorType]);\n\t\t\tconst actorIds =\n\t\t\t\trule.actorId == null\n\t\t\t\t\t? null\n\t\t\t\t\t: new Set(Array.isArray(rule.actorId) ? rule.actorId : [rule.actorId]);\n\t\t\tconst claimEntries = Object.entries(rule.claims ?? {});\n\t\t\tconst where: Where = (actor) => {\n\t\t\t\tif (actorTypes !== null && !actorTypes.has(String(actor.type))) return false;\n\t\t\t\tif (actorIds !== null && !actorIds.has(String(actor.id ?? \"\"))) return false;\n\t\t\t\tfor (const [key, value] of claimEntries) {\n\t\t\t\t\tif ((actor as Record<string, unknown>)[key] !== value) return false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t};\n\t\t\tif (rule.effect === \"deny\") {\n\t\t\t\tdeny(rule.action, { where });\n\t\t\t} else {\n\t\t\t\tallow(rule.action, { where });\n\t\t\t}\n\t\t}\n\t});\n}\n\nconst STANDARD_WRITE_TYPES = [\"human\", \"llm\", \"wallet\", \"system\"] as const;\n\n/**\n * Derives a best-effort `meta.access` hint string by probing `guard` with the\n * standard actor types `human`, `llm`, `wallet`, `system` for the `\"write\"` action\n * (roadmap 1.5). Aligned with graphrefly-py `access_hint_for_guard`.\n *\n * @param guard - Guard function to probe (typically from {@link policy}).\n * @returns `\"restricted\"` when no standard type is allowed; `\"both\"` when both\n * `human` and `llm` are allowed (plus optionally `system`); the single allowed\n * type name when only one passes; or a `\"+\"` joined list otherwise.\n *\n * @example\n * ```ts\n * import { policy, accessHintForGuard } from \"@graphrefly/graphrefly-ts\";\n *\n * const guardBoth = policy((allow) => { allow(\"write\"); });\n * accessHintForGuard(guardBoth); // \"both\"\n *\n * const guardHuman = policy((allow) => {\n * allow(\"write\", { where: (a) => a.type === \"human\" });\n * });\n * accessHintForGuard(guardHuman); // \"human\"\n * ```\n */\nexport function accessHintForGuard(guard: NodeGuard): string {\n\tconst allowed = STANDARD_WRITE_TYPES.filter((t) => guard({ type: t, id: \"\" }, \"write\"));\n\tif (allowed.length === 0) return \"restricted\";\n\tif (\n\t\tallowed.includes(\"human\") &&\n\t\tallowed.includes(\"llm\") &&\n\t\tallowed.every((t) => t === \"human\" || t === \"llm\" || t === \"system\")\n\t) {\n\t\treturn \"both\";\n\t}\n\tif (allowed.length === 1) return allowed[0];\n\treturn allowed.join(\"+\");\n}\n","/**\n * Node versioning — GRAPHREFLY-SPEC §7.\n *\n * Progressive, optional versioning for node identity and change tracking.\n *\n * - **V0**: `id` + `version` — identity & change detection (~16 bytes overhead)\n * - **V1**: + `cid` + `prev` — content addressing & linked history (~60 bytes overhead)\n *\n * **Lifecycle notes:**\n * - Version advances only on DATA (not RESOLVED, INVALIDATE, or TEARDOWN).\n * - `resetOnTeardown` clears the cached value but does NOT reset versioning state.\n * After teardown, `v.cid` still reflects the last DATA value, not the cleared cache.\n * The invariant `hash(node.cache) === v.cid` only holds in `settled`/`resolved` status.\n * - Resubscribable nodes preserve versioning across subscription lifetimes (monotonic counter).\n */\n\n// Runtime-agnostic — no `node:crypto` import. `randomUUID` comes from Web\n// Crypto (`globalThis.crypto.randomUUID()`), available in Node 14.17+,\n// browsers, Deno, Bun, and Cloudflare Workers. The default content hash is a\n// vendored sync SHA-256 (see `sha256Hex` below) so versioning stays callable\n// from any runtime — `crypto.subtle.digest` is async and can't back a\n// synchronous `defaultHash`.\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** V0: identity + monotonic version counter. */\nexport type V0 = {\n\treadonly id: string;\n\tversion: number;\n};\n\n/** V1: V0 + content-addressed identifier + previous cid link. */\nexport type V1 = V0 & {\n\tcid: string;\n\tprev: string | null;\n};\n\n/** Union of all versioning info shapes. */\nexport type NodeVersionInfo = V0 | V1;\n\n/** Supported versioning levels (extensible to 2, 3 later). */\nexport type VersioningLevel = 0 | 1;\n\n/** Function that hashes a value to a hex string (for V1 cid). */\nexport type HashFn = (value: unknown) => string;\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface VersioningOptions {\n\t/** Override auto-generated id. */\n\tid?: string;\n\t/** Custom hash function for V1 cid (default: SHA-256 truncated to 16 hex chars). */\n\thash?: HashFn;\n}\n\n// ---------------------------------------------------------------------------\n// Default hash\n// ---------------------------------------------------------------------------\n\n/**\n * Canonicalize a value for deterministic cross-language hashing.\n *\n * - Integer-valued floats normalize to integer strings (`1.0` → `1`).\n * - `NaN`, `Infinity`, `-Infinity` are rejected (no JSON equivalent).\n * - `undefined` normalizes to `null`.\n * - Object keys are sorted lexicographically.\n *\n * This ensures TS `JSON.stringify` and Python `json.dumps(sort_keys=True)`\n * produce identical output for the same logical value.\n */\nexport function canonicalizeForHash(value: unknown): unknown {\n\tif (value === undefined) return null;\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) {\n\t\t\tthrow new TypeError(`Cannot hash non-finite number: ${value}`);\n\t\t}\n\t\tif (Number.isInteger(value) && !Number.isSafeInteger(value)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`Cannot hash integer outside safe range (|n| > 2^53-1): ${value}. ` +\n\t\t\t\t\t\"Cross-language cid parity is not guaranteed for unsafe integers.\",\n\t\t\t);\n\t\t}\n\t\treturn value;\n\t}\n\tif (typeof value === \"string\" || typeof value === \"boolean\" || value === null) {\n\t\treturn value;\n\t}\n\tif (Array.isArray(value)) {\n\t\treturn value.map(canonicalizeForHash);\n\t}\n\tif (typeof value === \"object\" && value !== null) {\n\t\tconst sorted: Record<string, unknown> = {};\n\t\tfor (const k of Object.keys(value as Record<string, unknown>).sort()) {\n\t\t\tsorted[k] = canonicalizeForHash((value as Record<string, unknown>)[k]);\n\t\t}\n\t\treturn sorted;\n\t}\n\t// Fallback: coerce to null (bigint, symbol, function)\n\treturn null;\n}\n\n// SHA-256 round constants (FIPS 180-4).\nconst SHA256_K = /* @__PURE__ */ new Uint32Array([\n\t0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,\n\t0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,\n\t0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,\n\t0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,\n\t0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,\n\t0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,\n\t0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,\n\t0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,\n]);\n\nconst UTF8_ENCODER = /* @__PURE__ */ new TextEncoder();\n\n/**\n * Sync SHA-256 of a UTF-8 string, returned as a lowercase hex digest. Matches\n * Node `crypto.createHash(\"sha256\").update(msg).digest(\"hex\")` byte-for-byte.\n *\n * Runtime-agnostic (no `node:crypto`, no `crypto.subtle`). Small enough to\n * inline rather than pulling a dependency; called only from `defaultHash`,\n * which runs once per DATA on versioned nodes, so per-call allocation is\n * acceptable. Callers that need a faster path override via\n * `NodeOptions.versioningHash`.\n */\nfunction sha256Hex(msg: string): string {\n\tconst bytes = UTF8_ENCODER.encode(msg);\n\tconst msgLen = bytes.length;\n\tconst bitLen = msgLen * 8;\n\t// Pad to multiple of 64: 0x80 byte + zeros + 8-byte big-endian bit length.\n\tconst totalLen = (msgLen + 9 + 63) & ~63;\n\tconst padded = new Uint8Array(totalLen);\n\tpadded.set(bytes);\n\tpadded[msgLen] = 0x80;\n\tconst dv = new DataView(padded.buffer);\n\t// Bit length as big-endian 64-bit int. JS numbers are 53-bit safe, so we\n\t// split into two 32-bit halves; messages up to 2^53 bits are supported.\n\tdv.setUint32(totalLen - 4, bitLen >>> 0, false);\n\tdv.setUint32(totalLen - 8, Math.floor(bitLen / 0x100000000) >>> 0, false);\n\n\t// Initial hash values (first 32 bits of fractional parts of sqrt of first 8 primes).\n\tlet h0 = 0x6a09e667;\n\tlet h1 = 0xbb67ae85;\n\tlet h2 = 0x3c6ef372;\n\tlet h3 = 0xa54ff53a;\n\tlet h4 = 0x510e527f;\n\tlet h5 = 0x9b05688c;\n\tlet h6 = 0x1f83d9ab;\n\tlet h7 = 0x5be0cd19;\n\n\tconst W = new Uint32Array(64);\n\tconst rotr = (x: number, n: number): number => (x >>> n) | (x << (32 - n));\n\n\tfor (let off = 0; off < totalLen; off += 64) {\n\t\tfor (let i = 0; i < 16; i++) W[i] = dv.getUint32(off + i * 4, false);\n\t\tfor (let i = 16; i < 64; i++) {\n\t\t\tconst w15 = W[i - 15];\n\t\t\tconst w2 = W[i - 2];\n\t\t\tconst s0 = rotr(w15, 7) ^ rotr(w15, 18) ^ (w15 >>> 3);\n\t\t\tconst s1 = rotr(w2, 17) ^ rotr(w2, 19) ^ (w2 >>> 10);\n\t\t\tW[i] = (W[i - 16] + s0 + W[i - 7] + s1) >>> 0;\n\t\t}\n\n\t\tlet a = h0;\n\t\tlet b = h1;\n\t\tlet c = h2;\n\t\tlet d = h3;\n\t\tlet e = h4;\n\t\tlet f = h5;\n\t\tlet g = h6;\n\t\tlet h = h7;\n\n\t\tfor (let i = 0; i < 64; i++) {\n\t\t\tconst S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);\n\t\t\tconst ch = (e & f) ^ (~e & g);\n\t\t\tconst t1 = (h + S1 + ch + SHA256_K[i] + W[i]) >>> 0;\n\t\t\tconst S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);\n\t\t\tconst mj = (a & b) ^ (a & c) ^ (b & c);\n\t\t\tconst t2 = (S0 + mj) >>> 0;\n\t\t\th = g;\n\t\t\tg = f;\n\t\t\tf = e;\n\t\t\te = (d + t1) >>> 0;\n\t\t\td = c;\n\t\t\tc = b;\n\t\t\tb = a;\n\t\t\ta = (t1 + t2) >>> 0;\n\t\t}\n\n\t\th0 = (h0 + a) >>> 0;\n\t\th1 = (h1 + b) >>> 0;\n\t\th2 = (h2 + c) >>> 0;\n\t\th3 = (h3 + d) >>> 0;\n\t\th4 = (h4 + e) >>> 0;\n\t\th5 = (h5 + f) >>> 0;\n\t\th6 = (h6 + g) >>> 0;\n\t\th7 = (h7 + h) >>> 0;\n\t}\n\n\tconst toHex = (x: number): string => x.toString(16).padStart(8, \"0\");\n\treturn (\n\t\ttoHex(h0) + toHex(h1) + toHex(h2) + toHex(h3) + toHex(h4) + toHex(h5) + toHex(h6) + toHex(h7)\n\t);\n}\n\n/**\n * Default content hash: SHA-256 of deterministic JSON, truncated to 16 hex\n * chars (~64-bit). Uses {@link canonicalizeForHash} for cross-language parity\n * with Python `default_hash`.\n */\nexport function defaultHash(value: unknown): string {\n\tconst canonical = canonicalizeForHash(value ?? null);\n\tconst json = JSON.stringify(canonical);\n\treturn sha256Hex(json).slice(0, 16);\n}\n\n/**\n * Cross-runtime UUID generator. Uses Web Crypto (`globalThis.crypto.randomUUID`)\n * when available. Falls back to a tiny `Math.random`-seeded RFC 4122 v4\n * generator for environments that omit `crypto.randomUUID` — identity only,\n * not cryptographic.\n */\nfunction randomUuid(): string {\n\tconst c = (globalThis as { crypto?: { randomUUID?: () => string } }).crypto;\n\tif (c?.randomUUID) return c.randomUUID();\n\t// Fallback (extremely rare — only hits on very old runtimes that expose no\n\t// Web Crypto at all). Not cryptographically strong.\n\tconst r = () =>\n\t\tMath.floor(Math.random() * 0x100000000)\n\t\t\t.toString(16)\n\t\t\t.padStart(8, \"0\");\n\tconst hex = r() + r() + r() + r();\n\treturn (\n\t\t`${hex.slice(0, 8)}-${hex.slice(8, 12)}-4${hex.slice(13, 16)}-` +\n\t\t`${((parseInt(hex.slice(16, 17), 16) & 0x3) | 0x8).toString(16)}${hex.slice(17, 20)}-${hex.slice(20, 32)}`\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create initial versioning state for a node.\n *\n * @param level - 0 for V0, 1 for V1.\n * @param initialValue - The node's initial cached value (used for V1 cid).\n * @param opts - Optional overrides (id, hash).\n */\nexport function createVersioning(\n\tlevel: VersioningLevel,\n\tinitialValue: unknown,\n\topts?: VersioningOptions,\n): NodeVersionInfo {\n\tconst id = opts?.id ?? randomUuid();\n\tif (level === 0) {\n\t\treturn { id, version: 0 } satisfies V0;\n\t}\n\tconst hash = opts?.hash ?? defaultHash;\n\tconst cid = hash(initialValue);\n\treturn { id, version: 0, cid, prev: null } satisfies V1;\n}\n\n// ---------------------------------------------------------------------------\n// Advance\n// ---------------------------------------------------------------------------\n\n/**\n * Advance versioning state after a DATA emission (value changed).\n *\n * Mutates `info` in place for performance (called on every DATA).\n * Only call when the cached value has actually changed (not on RESOLVED).\n *\n * @param info - The node's current versioning state.\n * @param newValue - The new cached value.\n * @param hashFn - Hash function (only used for V1).\n */\nexport function advanceVersion(info: NodeVersionInfo, newValue: unknown, hashFn: HashFn): void {\n\tinfo.version += 1;\n\tif (\"cid\" in info) {\n\t\t(info as V1).prev = (info as V1).cid;\n\t\t(info as V1).cid = hashFn(newValue);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Guards\n// ---------------------------------------------------------------------------\n\n/** Type guard: is this V1 versioning info? */\nexport function isV1(info: NodeVersionInfo): info is V1 {\n\treturn \"cid\" in info;\n}\n","/**\n * `NodeImpl` — the single GraphReFly node primitive.\n *\n * Per-dep state lives in a `DepRecord[]` — one entry per declared dep —\n * consolidating subscription cleanup, latest-data tracking, dirty/settled\n * flags, and terminal state into a single structure per dep.\n *\n * This file also owns the default singleton handlers (`defaultOnMessage`,\n * `defaultOnSubscribe`), the `defaultConfig` instance, and the public\n * `configure(...)` entry point. They live here because their bodies touch\n * `NodeImpl` internals; `config.ts` stays NodeImpl-agnostic.\n *\n * See GRAPHREFLY-SPEC §2 and COMPOSITION-GUIDE §1/§9 for the behavior\n * contract. See SESSION-foundation-redesign.md §§1–10 for design history.\n */\n\nimport { registerBuiltinCodecs } from \"../graph/codec.js\";\nimport type { Actor } from \"./actor.js\";\nimport { normalizeActor } from \"./actor.js\";\nimport { downWithBatch, isExplicitlyBatching, registerBatchFlushHook } from \"./batch.js\";\nimport { wallClockNs } from \"./clock.js\";\nimport type {\n\tMessageContext,\n\tNodeActions,\n\tNodeCtx,\n\tOnMessageHandler,\n\tOnSubscribeHandler,\n\tSubscribeContext,\n} from \"./config.js\";\nimport { GraphReFlyConfig, registerBuiltins } from \"./config.js\";\nimport type { GuardAction, NodeGuard } from \"./guard.js\";\nimport { GuardDenied } from \"./guard.js\";\nimport {\n\tCOMPLETE,\n\tCOMPLETE_ONLY_BATCH,\n\tDATA,\n\tDIRTY,\n\tDIRTY_MSG,\n\tDIRTY_ONLY_BATCH,\n\tERROR,\n\tINVALIDATE,\n\tINVALIDATE_ONLY_BATCH,\n\ttype Message,\n\ttype Messages,\n\tPAUSE,\n\tRESOLVED,\n\tRESOLVED_MSG,\n\tRESOLVED_ONLY_BATCH,\n\tRESUME,\n\tSTART,\n\tSTART_MSG,\n\tTEARDOWN,\n\tTEARDOWN_ONLY_BATCH,\n} from \"./messages.js\";\nimport {\n\tadvanceVersion,\n\tcreateVersioning,\n\tdefaultHash,\n\ttype HashFn,\n\ttype NodeVersionInfo,\n\ttype VersioningLevel,\n} from \"./versioning.js\";\n\n// ---------------------------------------------------------------------------\n// Internal sentinel + type helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Placeholder unsubscribe used to mark a dep subscription as \"pending\" during\n * the synchronous window between `dep.unsub = noopUnsub` and the return of\n * `dep.node.subscribe(...)`. Ensures the liveness check `dep.unsub === null`\n * in the subscription callback correctly passes for synchronous push-on-\n * subscribe deliveries, while still blocking stale drainPhase2 closures that\n * fire after deactivation has set `dep.unsub = null`.\n */\nconst noopUnsub: () => void = () => {};\n\n/**\n * Maximum `_pendingRerun` depth before we give up and emit ERROR. Bounds\n * autoTrackNode / `_addDep` discovery loops — a well-formed discovery\n * converges in O(n) total rounds for n deps, so 100 is ample.\n */\nconst MAX_RERUN_DEPTH = 100;\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** Lifecycle status of a node (GRAPHREFLY-SPEC §2.2). */\nexport type NodeStatus =\n\t| \"sentinel\"\n\t| \"pending\"\n\t| \"dirty\"\n\t| \"settled\"\n\t| \"resolved\"\n\t| \"completed\"\n\t| \"errored\";\n\n/** Callback that receives downstream message batches. */\nexport type NodeSink = (messages: Messages) => void;\n\n/**\n * Observability hook events fired by a per-node inspector. Used by\n * `Graph.observe(path, { causal, derived })` to build causal traces.\n *\n * - `\"dep_message\"` — fires in `_onDepMessage` before default dispatch,\n * one event per message received from a dep. Includes `depIndex` and\n * the raw `Message` tuple.\n * - `\"run\"` — fires in `_execFn` just before the user fn runs. Includes\n * the per-dep `prevData` snapshot that will be passed to fn.\n */\nexport type NodeInspectorHookEvent =\n\t| { kind: \"dep_message\"; depIndex: number; message: Message }\n\t| {\n\t\t\tkind: \"run\";\n\t\t\tbatchData: readonly (readonly unknown[] | undefined)[];\n\t\t\tprevData: readonly unknown[];\n\t };\n\n/** Callback attached to a node for per-message/per-run inspection. */\nexport type NodeInspectorHook = (event: NodeInspectorHookEvent) => void;\n\n/** Describe `type` for `Graph.describe` (GRAPHREFLY-SPEC Appendix B). */\nexport type NodeDescribeKind = \"state\" | \"derived\" | \"producer\" | \"effect\";\n\n/** Actor/delivery context for {@link Node.down} and {@link Node.up}. */\nexport type NodeTransportOptions = {\n\tactor?: Actor;\n\t/** When `true`, skips guard checks. */\n\tinternal?: boolean;\n\t/** `signal` for `Graph.signal` deliveries; default `write`. */\n\tdelivery?: \"write\" | \"signal\";\n};\n\n/**\n * Cleanup return shape from a node {@link NodeFn}.\n * - `() => void` — fires before the next fn run AND on deactivation (default).\n * - `{ deactivation: () => void }` — fires only on deactivation (persistent\n * resources that should survive across fn re-runs).\n */\nexport type NodeFnCleanup = (() => void) | { deactivation: () => void };\n\n/**\n * Fn-time context exposing per-wave metadata and a per-node persistent\n * scratch pad.\n *\n * - `prevData[i]` — last DATA value from dep `i` as of the END of the\n * previous wave (i.e. the value that was stable before this wave started).\n * Use as the fallback when `data[i]` is `undefined` (not involved) or\n * `[]` (RESOLVED, no new values this wave).\n * `undefined` means dep `i` has never produced DATA (sentinel state).\n * `null` is a valid DATA value. `undefined` is not a valid DATA value —\n * the protocol reserves it as the \"never sent\" sentinel.\n * - `ctx.prevData[i] === undefined` → dep has never produced DATA\n * - `ctx.prevData[i] !== undefined` → last DATA value (may be `null`)\n * - `terminalDeps[i]` — runtime shape:\n * - `undefined` → dep `i` is still live.\n * - `true` → dep `i` sent COMPLETE.\n * - anything else → dep `i` sent ERROR, value is the error payload.\n * Type is `readonly unknown[]` because `true | unknown` collapses to\n * `unknown` anyway; the three states are documented contract, not type.\n * - `store` — mutable bag that persists across fn runs within one activation\n * cycle. Wiped on deactivation and on resubscribable terminal reset.\n */\nexport interface FnCtx {\n\treadonly prevData: readonly unknown[];\n\treadonly terminalDeps: readonly unknown[];\n\treadonly store: Record<string, unknown>;\n}\n\n/**\n * Compute function passed to `node(deps, fn, opts?)`.\n *\n * `data[i]` holds the batch of DATA values received from dep `i` during the\n * current wave. Shape contract:\n * - `undefined` — dep `i` was not involved in this wave (no DIRTY received).\n * - `[]` — dep `i` was involved (dirtied), but settled as RESOLVED (value\n * unchanged). Use `ctx.prevData[i]` to read its last known value from the\n * previous wave.\n * - `[v1, v2, ...]` — dep `i` sent one or more DATA values. `at(-1)` gives\n * the latest; iterate for multi-emission processing.\n *\n * Emission is explicit via `actions.emit(v)` (sugar: equals + framing) or\n * `actions.down(msgs)` (raw). Return a cleanup function (or\n * `{ deactivation }`) to register teardown — any non-cleanup return value\n * is ignored. The `| void` leg lets arrow-block bodies satisfy `NodeFn`\n * without an explicit `return undefined`.\n *\n * Sugar constructors (`derived`, `effect`, `dynamicNode`) unwrap `data[i]`\n * to a single scalar (`at(-1)` with `ctx.prevData[i]` fallback) so their\n * user-facing fn signatures stay unchanged. Use raw `node()` when you need\n * the full batch array.\n */\nexport type NodeFn = (\n\tdata: readonly (readonly unknown[] | undefined)[],\n\tactions: NodeActions,\n\tctx: FnCtx,\n\t// biome-ignore lint/suspicious/noConfusingVoidType: see JSDoc above.\n) => NodeFnCleanup | void;\n\n/** Options accepted by every node constructor. */\nexport interface NodeOptions<T = unknown> {\n\tname?: string;\n\tdescribeKind?: NodeDescribeKind;\n\tequals?: (a: T, b: T) => boolean;\n\t/**\n\t * Pre-populate the cache at construction. `null` is a valid initial value.\n\t * `undefined` is treated as absent (not a valid DATA payload).\n\t */\n\tinitial?: T | null;\n\tmeta?: Record<string, unknown>;\n\tresubscribable?: boolean;\n\tresetOnTeardown?: boolean;\n\t/** Auto-emit `[[COMPLETE]]` when all deps complete. Default `true`. */\n\tcompleteWhenDepsComplete?: boolean;\n\t/**\n\t * Auto-propagate `[[ERROR]]` when any dep errors. Default `true`.\n\t * Set `false` only for rescue/catchError operators that handle errors\n\t * explicitly via `ctx.terminalDeps`.\n\t */\n\terrorWhenDepsError?: boolean;\n\t/**\n\t * Tier-2 PAUSE/RESUME handling.\n\t * - `true` (default): wave completion suppressed while paused; fn fires\n\t * once on RESUME if gate is satisfied.\n\t * - `false`: node ignores PAUSE (sources like timers that must keep running).\n\t * - `\"resumeAll\"`: on RESUME, replay every buffered DATA (future).\n\t */\n\tpausable?: boolean | \"resumeAll\";\n\tguard?: NodeGuard;\n\tversioning?: VersioningLevel;\n\tversioningId?: string;\n\tversioningHash?: HashFn;\n\t/**\n\t * Override the config instance this node binds to. Defaults to\n\t * {@link defaultConfig}. Useful for test isolation and custom protocol\n\t * stacks. The first node that reads any hook on the config freezes it.\n\t */\n\tconfig?: GraphReFlyConfig;\n}\n\n/** A reactive node in the GraphReFly protocol. */\nexport interface Node<T = unknown> {\n\treadonly name?: string;\n\treadonly status: NodeStatus;\n\t/**\n\t * Current cached value. Returns `undefined` when the node is in\n\t * `\"sentinel\"` state (no DATA ever emitted). v5 reserves `undefined`\n\t * globally as the sentinel value — the valid DATA type is `T | null`.\n\t * Therefore `node.cache === undefined` is a valid \"never emitted\" guard.\n\t * `node.status` distinguishes the richer states (`\"sentinel\"`,\n\t * `\"settled\"`, `\"errored\"`, etc.) when you need more than has-value.\n\t */\n\treadonly cache: T | null | undefined;\n\treadonly meta: Record<string, Node>;\n\treadonly lastMutation: Readonly<{ actor: Actor; timestamp_ns: number }> | undefined;\n\treadonly v: Readonly<NodeVersionInfo> | undefined;\n\t/**\n\t * Send one or more messages downstream. Accepts either a single\n\t * {@link Message} tuple (e.g. `node.down([DATA, 42])`) or a\n\t * {@link Messages} array of tuples (e.g.\n\t * `node.down([[DIRTY], [DATA, 42]])`). One call = one wave: the\n\t * emit pipeline tier-sorts the input, auto-prefixes `[DIRTY]` when\n\t * any tier-3 payload is present and the node is not already dirty,\n\t * runs equals substitution against the live cache (§3.5.1), then\n\t * dispatches to sinks with phase deferral.\n\t */\n\tdown(messageOrMessages: Message | Messages, options?: NodeTransportOptions): void;\n\t/**\n\t * Sugar for `down([[DATA, value]])`. One wave with a single DATA\n\t * payload — the pipeline adds the synthetic DIRTY prefix and runs\n\t * equals substitution against the live cache.\n\t */\n\temit(value: T | undefined | null, options?: NodeTransportOptions): void;\n\t/**\n\t * Send one or more messages upstream. Accepts the same shapes as\n\t * {@link down}. Upstream messages are tier <3 + tier 5 only\n\t * (DIRTY, INVALIDATE, PAUSE, RESUME, TEARDOWN); tier-3/4 payloads\n\t * throw — DATA/RESOLVED/COMPLETE/ERROR are downstream-only in this\n\t * protocol. No equals substitution, no cache advance, no DIRTY\n\t * auto-prefix — the up direction just forwards to every dep.\n\t */\n\tup?(messageOrMessages: Message | Messages, options?: NodeTransportOptions): void;\n\tsubscribe(sink: NodeSink, actor?: Actor): () => void;\n\tallowsObserve(actor: Actor): boolean;\n\thasGuard(): boolean;\n}\n\n// ---------------------------------------------------------------------------\n// DepRecord — per-dep state (§8.2)\n// ---------------------------------------------------------------------------\n\n/**\n * Per-dep runtime state. One entry per upstream node.\n *\n * `terminal` is the single terminal-state slot, shaped to match\n * {@link FnCtx.terminalDeps}:\n * - `undefined` — dep is still live.\n * - `true` — dep sent COMPLETE.\n * - anything else — dep sent ERROR with that payload.\n *\n * Edge case: an ERROR carrying an `undefined` payload is indistinguishable\n * from \"live\". Pass meaningful error values (Error objects, domain tags).\n */\nexport interface DepRecord {\n\treadonly node: Node;\n\tunsub: (() => void) | null;\n\t/**\n\t * Last DATA value from this dep as of the end of the previous completed\n\t * wave. `undefined` until dep has produced at least one DATA (sentinel).\n\t * Committed by `_execFn` after snapshotting `ctx.prevData` and before\n\t * `_clearWaveFlags`. `undefined` is reserved as the \"never sent\" sentinel —\n\t * `undefined` is not a valid DATA payload.\n\t */\n\tprevData: unknown;\n\t/** True while awaiting DATA/RESOLVED for the current wave. */\n\tdirty: boolean;\n\t/**\n\t * True if this dep was dirtied in the current wave (set in `_depDirtied`,\n\t * cleared in `_clearWaveFlags`). Distinguishes \"RESOLVED\" (`involvedThisWave\n\t * && dataBatch.length === 0`) from \"not involved\" (`!involvedThisWave`) in\n\t * the `data[i]` batch snapshot passed to fn.\n\t */\n\tinvolvedThisWave: boolean;\n\t/**\n\t * DATA values accumulated from this dep during the current wave.\n\t * Populated by `_depSettledAsData`, cleared by `_clearWaveFlags`.\n\t * Snapshotted (copied) by `_execFn` before `_clearWaveFlags` runs so\n\t * that fn always sees the full wave batch.\n\t */\n\tdataBatch: unknown[];\n\t/** Terminal-state slot — see JSDoc on {@link DepRecord}. */\n\tterminal: unknown;\n}\n\nfunction createDepRecord(n: Node): DepRecord {\n\treturn {\n\t\tnode: n,\n\t\tunsub: null,\n\t\tprevData: undefined,\n\t\tdirty: false,\n\t\tinvolvedThisWave: false,\n\t\tdataBatch: [],\n\t\tterminal: undefined,\n\t};\n}\n\nfunction resetDepRecord(d: DepRecord): void {\n\td.prevData = undefined;\n\td.dirty = false;\n\td.involvedThisWave = false;\n\td.dataBatch.length = 0;\n\td.terminal = undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Normalization helper\n// ---------------------------------------------------------------------------\n\n/**\n * Accept either a single `Message` tuple or a `Messages` array and return\n * a `Messages` array. The discriminator is the type of the first element:\n * a `Message` has a symbol at index 0, while a `Messages` array has a\n * nested array at index 0. This lets `node.down(...)` and `actions.down(...)`\n * take either shape without a wrapper allocation on the common single-msg\n * path.\n */\nfunction normalizeMessages(input: Message | Messages): Messages {\n\tif (input.length === 0) return input as Messages;\n\treturn typeof (input as Message)[0] === \"symbol\" ? [input as Message] : (input as Messages);\n}\n\n// ---------------------------------------------------------------------------\n// Default handlers\n// ---------------------------------------------------------------------------\n\n/**\n * Default {@link OnMessageHandler}. For `\"down-in\"` messages (from a dep),\n * routes to `NodeImpl._onDepMessage`. For `\"up-in\"` messages (from a sink),\n * the up-path is wired directly via `Node.up()` and never passes through\n * onMessage — this hook is reserved for future P5 symmetry.\n */\nconst defaultOnMessage: OnMessageHandler = (\n\tnode: NodeCtx,\n\tmsg: Message,\n\tctx: MessageContext,\n\t_actions: NodeActions,\n): \"consume\" | undefined => {\n\tif (ctx.direction === \"down-in\") {\n\t\t(node as NodeImpl)._onDepMessage(ctx.depIndex, msg);\n\t}\n\t// up-in is currently unused; default is to do nothing.\n\treturn undefined;\n};\n\n/**\n * Default {@link OnSubscribeHandler}. Delivers the subscribe handshake —\n * `[[START]]` for a sentinel cache, or `[[START], [DATA, cached]]` when a\n * value exists. Terminal nodes skip entirely so absence of START tells the\n * sink the stream is over (spec §2.2). Delivered through `downWithBatch` so\n * `subscribe()` inside `batch()` still defers the paired DATA correctly.\n */\nconst defaultOnSubscribe: OnSubscribeHandler = (\n\tnode: NodeCtx,\n\tsink: NodeSink,\n\t_ctx: SubscribeContext,\n\t_actions: NodeActions,\n): (() => void) | undefined => {\n\tconst impl = node as NodeImpl;\n\tif (impl._status === \"completed\" || impl._status === \"errored\") return;\n\tconst cached = impl._cached;\n\tconst initial: Message[] =\n\t\tcached === undefined ? [START_MSG] : [START_MSG, [DATA, cached] as Message];\n\t// When the node is mid-wave (`\"dirty\"`), append a DIRTY so the late\n\t// joiner participates in the in-flight wave. Without this, the next\n\t// DATA/RESOLVED the sink receives lacks the preceding DIRTY required\n\t// by spec §1.3.1 — the emit-side DIRTY auto-prefix is suppressed when\n\t// `_status` is already `\"dirty\"`.\n\tif (impl._status === \"dirty\") initial.push(DIRTY_MSG);\n\tdownWithBatch(sink, initial, impl._config.tierOf);\n};\n\n// ---------------------------------------------------------------------------\n// defaultConfig + configure\n// ---------------------------------------------------------------------------\n\n/**\n * Default {@link GraphReFlyConfig} instance. Every `NodeImpl` constructed\n * without an explicit `opts.config` binds to this instance and freezes it\n * on first hook access.\n */\nexport const defaultConfig = new GraphReFlyConfig({\n\tonMessage: defaultOnMessage,\n\tonSubscribe: defaultOnSubscribe,\n});\nregisterBuiltins(defaultConfig);\nregisterBuiltinCodecs(defaultConfig);\n\n/**\n * Apply configuration to {@link defaultConfig}. Must be called before the\n * first node is created — otherwise throws. Custom message types, hook\n * overrides, etc. go through here at app startup.\n *\n * ```ts\n * configure((cfg) => {\n * cfg.registerMessageType(MY_TYPE, { tier: 3 });\n * cfg.onMessage = (node, msg, ctx, actions) => { ... };\n * });\n * ```\n */\nexport function configure(fn: (cfg: GraphReFlyConfig) => void): void {\n\tif (defaultConfig._isFrozen()) {\n\t\tthrow new Error(\n\t\t\t\"configure() called after a node was created — the default \" +\n\t\t\t\t\"GraphReFlyConfig is frozen. Call configure(...) at application \" +\n\t\t\t\t\"startup, before any node factories run.\",\n\t\t);\n\t}\n\tfn(defaultConfig);\n}\n\n// Re-export the class for advanced callers that want an isolated instance.\nexport { GraphReFlyConfig };\n\n// ---------------------------------------------------------------------------\n// NodeImpl\n// ---------------------------------------------------------------------------\n\n/**\n * Single-class node implementation. Covers state, producer, derived, effect,\n * and passthrough shapes. See `sugar.ts` for ergonomic factories and\n * `dynamicNode()` (sugar-level wrapper around plain `NodeImpl`).\n */\nexport class NodeImpl<T = unknown> implements Node<T> {\n\t// --- Identity ---\n\treadonly _optsName: string | undefined;\n\treadonly _describeKind: NodeDescribeKind | undefined;\n\treadonly meta: Record<string, Node>;\n\t/**\n\t * Cached `Object.keys(meta).length > 0` check. `meta` is frozen at\n\t * construction so this boolean never flips. Used by `_emit` to skip\n\t * the meta TEARDOWN fan-out block allocation on the common \"no meta\"\n\t * hot path.\n\t */\n\treadonly _hasMeta: boolean;\n\n\t// --- Config ---\n\treadonly _config: GraphReFlyConfig;\n\n\t// --- Topology ---\n\t/** Mutable for autoTrackNode / Graph.connect() post-construction dep addition. */\n\t_deps: DepRecord[];\n\t_sinks: NodeSink | Set<NodeSink> | null = null;\n\t_sinkCount = 0;\n\n\t// --- State ---\n\t_cached: T | undefined;\n\t_status: NodeStatus;\n\t_cleanup: NodeFnCleanup | undefined;\n\t_store: Record<string, unknown> = {};\n\t_waveHasNewData = false;\n\t_hasNewTerminal = false;\n\t_hasCalledFnOnce = false;\n\t_paused = false;\n\t_pendingWave = false;\n\t_isExecutingFn = false;\n\t_pendingRerun = false;\n\t_rerunDepth = 0;\n\n\t// --- Settlement counter (A3) ---\n\t/**\n\t * Count of deps currently in `dirty === true`. `_maybeRunFnOnSettlement`\n\t * treats `0` as \"wave settled\" — O(1) check for full dep settlement.\n\t */\n\t_dirtyDepCount = 0;\n\n\t// --- Per-batch emit accumulator (Bug 2: K+1 fan-in fix) ---\n\t/**\n\t * Inside an explicit `batch(() => ...)` scope, every `_emit` accumulates\n\t * its already-framed messages here instead of dispatching synchronously.\n\t * At batch end, `_flushBatchPending` runs (registered via\n\t * `registerBatchFlushHook`) and delivers the whole accumulated batch as\n\t * one `downWithBatch` call — collapsing what would otherwise be K\n\t * separate sink invocations into one. This is the fix for the diamond\n\t * fan-in K+1 over-fire.\n\t *\n\t * `null` outside batch (or after flush). Only ever appended to within\n\t * a single explicit batch lifetime; reset to `null` on flush. State\n\t * updates (cache, version, status) still happen per-emit via\n\t * `_updateState` — only the downstream delivery is coalesced.\n\t */\n\t_batchPendingMessages: Message[] | null = null;\n\n\t// --- PAUSE/RESUME lock tracking (C0) ---\n\t/**\n\t * Set of active pause locks held against this node. Every `[PAUSE, lockId]`\n\t * adds its `lockId` to the set; every `[RESUME, lockId]` removes it.\n\t * `_paused` is a derived quantity: `_pauseLocks.size > 0`. Multi-pauser\n\t * correctness — one controller releasing its lock does NOT resume the\n\t * node while another controller still holds its lock.\n\t */\n\t_pauseLocks: Set<unknown> | null = null;\n\t/**\n\t * Buffered DATA messages held while paused. Only populated when\n\t * `_pausable === \"resumeAll\"` (bufferAll mode). On final lock release\n\t * the buffer is replayed through the node's outgoing pipeline in the\n\t * order received. Non-bufferAll pause mode drops DATA on the floor\n\t * (upstream is expected to honor PAUSE by suppressing production).\n\t */\n\t_pauseBuffer: Message[] | null = null;\n\n\t// --- Options (frozen at construction) ---\n\treadonly _fn: NodeFn | undefined;\n\treadonly _equals: (a: T, b: T) => boolean;\n\treadonly _resubscribable: boolean;\n\treadonly _resetOnTeardown: boolean;\n\treadonly _autoComplete: boolean;\n\treadonly _autoError: boolean;\n\treadonly _pausable: boolean | \"resumeAll\";\n\treadonly _guard: NodeGuard | undefined;\n\t_hashFn: HashFn;\n\t_versioning: NodeVersionInfo | undefined;\n\t/**\n\t * Explicit versioning level, tracked separately from `_versioning` so\n\t * monotonicity checks and future v2/v3 extensions don't rely on the\n\t * fragile `\"cid\" in _versioning` shape discriminator. `undefined` means\n\t * the node has no versioning attached; `0` / `1` / future levels name\n\t * the tier. Mutated in lockstep with `_versioning` by the constructor\n\t * and by `_applyVersioning`.\n\t */\n\t_versioningLevel: VersioningLevel | undefined;\n\n\t// --- ABAC ---\n\t_lastMutation: { actor: Actor; timestamp_ns: number } | undefined;\n\n\t/**\n\t * @internal Per-node inspector hooks for `Graph.observe(path,\n\t * { causal, derived })`. Fires in `_onDepMessage` and `_execFn`.\n\t * Attached via `_setInspectorHook` (returns a disposer). Multiple\n\t * observers can attach simultaneously — all registered hooks fire for\n\t * every event.\n\t */\n\t_inspectorHooks: Set<NodeInspectorHook> | undefined;\n\n\t// --- Actions (built once in the constructor) ---\n\treadonly _actions: NodeActions;\n\n\tconstructor(deps: readonly Node[], fn: NodeFn | undefined, opts: NodeOptions<T>) {\n\t\t// Bind to config FIRST so meta nodes inherit it. Touching a hook\n\t\t// getter below freezes the config on first node creation.\n\t\tthis._config = opts.config ?? defaultConfig;\n\t\tvoid this._config.onMessage;\n\n\t\tthis._optsName = opts.name;\n\t\tthis._describeKind = opts.describeKind;\n\t\tthis._equals = (opts.equals ?? (Object.is as (a: T, b: T) => boolean)) as (\n\t\t\ta: T,\n\t\t\tb: T,\n\t\t) => boolean;\n\t\tthis._resubscribable = opts.resubscribable ?? false;\n\t\tthis._resetOnTeardown = opts.resetOnTeardown ?? false;\n\t\tthis._autoComplete = opts.completeWhenDepsComplete ?? true;\n\t\tthis._autoError = opts.errorWhenDepsError ?? true;\n\t\tthis._pausable = opts.pausable ?? true;\n\t\tthis._guard = opts.guard;\n\t\tthis._fn = fn;\n\n\t\t// `undefined` is the sentinel (\"no cached value\") so `initial: undefined`\n\t\t// is treated as absent. `null` is a valid DATA value and sets the cache.\n\t\tthis._cached = opts.initial !== undefined ? (opts.initial as T) : undefined;\n\t\t// State-with-initial starts \"settled\"; everything else starts \"sentinel\".\n\t\tthis._status =\n\t\t\tdeps.length === 0 && fn == null && this._cached !== undefined ? \"settled\" : \"sentinel\";\n\n\t\t// Versioning\n\t\t// Hash resolution: per-node `opts.versioningHash` wins; then the\n\t\t// bound config's `defaultHashFn`; then the vendored sync SHA-256.\n\t\t// Hot-path workloads that want a faster hash (xxHash, FNV-1a) can\n\t\t// set it once at app init via `configure(cfg => { cfg.defaultHashFn = ... })`.\n\t\tthis._hashFn = opts.versioningHash ?? this._config.defaultHashFn ?? defaultHash;\n\t\t// Versioning level resolution: per-node `opts.versioning` wins; if\n\t\t// absent, fall back to the bound config's `defaultVersioning`. `null`\n\t\t// stays unversioned. Explicit levels (0, 1, …) attach the versioning\n\t\t// info at construction so the next DATA emit advances it.\n\t\tconst versioningLevel: VersioningLevel | undefined =\n\t\t\topts.versioning ?? this._config.defaultVersioning;\n\t\tthis._versioningLevel = versioningLevel;\n\t\tthis._versioning =\n\t\t\tversioningLevel != null\n\t\t\t\t? createVersioning(versioningLevel, this._cached === undefined ? undefined : this._cached, {\n\t\t\t\t\t\tid: opts.versioningId,\n\t\t\t\t\t\thash: this._hashFn,\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\n\t\t// Per-dep records: one DepRecord per declared dep.\n\t\tthis._deps = deps.map(createDepRecord);\n\n\t\t// Meta companions (simple state children; inherit config + guard).\n\t\tconst meta: Record<string, Node> = {};\n\t\tfor (const [k, v] of Object.entries(opts.meta ?? {})) {\n\t\t\tconst metaOpts: NodeOptions<unknown> = {\n\t\t\t\tinitial: v,\n\t\t\t\tname: `${opts.name ?? \"node\"}:meta:${k}`,\n\t\t\t\tdescribeKind: \"state\",\n\t\t\t\tconfig: this._config,\n\t\t\t};\n\t\t\tif (opts.guard != null) metaOpts.guard = opts.guard;\n\t\t\tmeta[k] = new NodeImpl<unknown>([], undefined, metaOpts);\n\t\t}\n\t\tObject.freeze(meta);\n\t\tthis.meta = meta;\n\t\tthis._hasMeta = Object.keys(meta).length > 0;\n\n\t\t// Actions: built once, closure over `this`. Every call goes through\n\t\t// `_emit` which owns the full dispatch invariant — tier sort,\n\t\t// synthetic DIRTY prefix, equals substitution, and phase dispatch.\n\t\t// One call = one wave. Multiple calls produce multiple waves.\n\t\t// No accumulation, no user-facing bundle builder.\n\t\tconst self = this;\n\t\tthis._actions = {\n\t\t\temit(value: unknown): void {\n\t\t\t\tself._emit([[DATA, value] as Message]);\n\t\t\t},\n\t\t\tdown(messageOrMessages: Message | Messages): void {\n\t\t\t\tself._emit(normalizeMessages(messageOrMessages));\n\t\t\t},\n\t\t\tup(messageOrMessages: Message | Messages): void {\n\t\t\t\tself._emitUp(normalizeMessages(messageOrMessages));\n\t\t\t},\n\t\t};\n\n\t\t// Bind commonly detached protocol methods.\n\t\tthis.down = this.down.bind(this);\n\t\tthis.up = this.up.bind(this);\n\t}\n\n\t// --- Derived state ---\n\n\tprivate get _isTerminal(): boolean {\n\t\treturn this._status === \"completed\" || this._status === \"errored\";\n\t}\n\n\t// --- Public getters ---\n\n\tget name(): string | undefined {\n\t\treturn this._optsName;\n\t}\n\n\tget status(): NodeStatus {\n\t\treturn this._status;\n\t}\n\n\tget cache(): T | undefined | null {\n\t\treturn this._cached === undefined ? undefined : (this._cached as T);\n\t}\n\n\tget lastMutation(): Readonly<{ actor: Actor; timestamp_ns: number }> | undefined {\n\t\treturn this._lastMutation;\n\t}\n\n\tget v(): Readonly<NodeVersionInfo> | undefined {\n\t\treturn this._versioning;\n\t}\n\n\thasGuard(): boolean {\n\t\treturn this._guard != null;\n\t}\n\n\t/**\n\t * @internal Retroactively attach (or upgrade) versioning state on this\n\t * node. Intended for `Graph.setVersioning(level)` bulk application and\n\t * for rare cases where a specific node needs to be bumped to a higher\n\t * level (e.g., `v0 → v1`) after construction.\n\t *\n\t * **Safety:** the mutation is rejected mid-wave. Specifically,\n\t * throws if the node is currently executing its fn (`_isExecutingFn`).\n\t * Callers at quiescent points — before the first sink subscribes, or\n\t * after all sinks unsubscribe, or between external `down()` / `emit()`\n\t * invocations — are safe. The re-entrance window that motivated §10.6.4\n\t * removal was the \"transition `_versioning` from `undefined` to a fresh\n\t * object mid-`_updateState`\" case; that path is now guarded.\n\t *\n\t * **Monotonicity:** levels can only go up. Downgrade (e.g., `v1 → v0`)\n\t * is a no-op — once a node carries higher-level metadata, dropping it\n\t * mid-graph would tear the linked-history invariant for v1 and above.\n\t *\n\t * **Linked-history boundary (D1, 2026-04-13):** upgrading v0 → v1\n\t * produces a **fresh history root**. The new v1 state has `cid =\n\t * hash(currentCachedValue)` and `prev = null`, not a synthetic `prev`\n\t * anchored to any previous v0 value. The v0 monotonic `version` counter\n\t * is preserved across the upgrade, but the linked-cid chain (spec §7)\n\t * starts fresh at the upgrade point. Downstream audit tools that walk\n\t * `v.cid.prev` backwards through time will see a `null` boundary at\n\t * the upgrade — **this is intentional**: v0 had no cid to link to, and\n\t * fabricating one would lie about the hash. Callers that require an\n\t * unbroken cid chain from birth must attach versioning at construction\n\t * via `opts.versioning` or `config.defaultVersioning`, not retroactively.\n\t *\n\t * @param level - New minimum versioning level.\n\t * @param opts - Optional id / hash overrides; applied only if the\n\t * node currently has no versioning state.\n\t */\n\t_applyVersioning(level: VersioningLevel, opts?: { id?: string; hash?: HashFn }): void {\n\t\tif (this._isExecutingFn) {\n\t\t\tthrow new Error(\n\t\t\t\t`Node \"${this.name}\": _applyVersioning cannot run mid-fn — ` +\n\t\t\t\t\t\"call it outside of `_execFn` (typically at graph setup time \" +\n\t\t\t\t\t\"before the first subscribe).\",\n\t\t\t);\n\t\t}\n\t\tconst currentLevel = this._versioningLevel;\n\t\tif (currentLevel != null && level <= currentLevel) {\n\t\t\t// Downgrade or no-op. Monotonic: higher levels only.\n\t\t\treturn;\n\t\t}\n\t\tconst hash = opts?.hash ?? this._hashFn;\n\t\tif (hash !== this._hashFn) this._hashFn = hash;\n\t\tconst initialValue = this._cached === undefined ? undefined : this._cached;\n\t\t// Preserve the existing id + version counter across upgrades so\n\t\t// downstream consumers watching `v.id` don't see an identity jump.\n\t\tconst current = this._versioning;\n\t\tconst preservedId = current?.id ?? opts?.id;\n\t\tconst preservedVersion = current?.version ?? 0;\n\t\tconst fresh = createVersioning(level, initialValue, {\n\t\t\tid: preservedId,\n\t\t\thash,\n\t\t});\n\t\tfresh.version = preservedVersion;\n\t\tthis._versioning = fresh;\n\t\tthis._versioningLevel = level;\n\t}\n\n\t/**\n\t * @internal Attach an inspector hook. Returns a disposer that removes\n\t * the hook. Used by `Graph.observe(path, { causal, derived })` to build\n\t * causal traces. Multiple hooks may be attached concurrently — all fire\n\t * for every event in registration order. Passing `undefined` is a no-op\n\t * and returns a no-op disposer.\n\t */\n\t_setInspectorHook(hook?: NodeInspectorHook): () => void {\n\t\tif (hook == null) return () => {};\n\t\tif (this._inspectorHooks == null) this._inspectorHooks = new Set();\n\t\tthis._inspectorHooks.add(hook);\n\t\treturn () => {\n\t\t\tthis._inspectorHooks?.delete(hook);\n\t\t\tif (this._inspectorHooks?.size === 0) this._inspectorHooks = undefined;\n\t\t};\n\t}\n\n\tallowsObserve(actor: Actor): boolean {\n\t\tif (this._guard == null) return true;\n\t\treturn this._guard(normalizeActor(actor), \"observe\");\n\t}\n\n\t// --- Guard helper ---\n\n\tprivate _checkGuard(options?: NodeTransportOptions): void {\n\t\tif (options?.internal || this._guard == null) return;\n\t\tconst actor = normalizeActor(options?.actor);\n\t\tconst action: GuardAction = options?.delivery === \"signal\" ? \"signal\" : \"write\";\n\t\tif (!this._guard(actor, action)) {\n\t\t\tthrow new GuardDenied({ actor, action, nodeName: this.name });\n\t\t}\n\t\tthis._lastMutation = { actor, timestamp_ns: wallClockNs() };\n\t}\n\n\t// --- Public transport ---\n\n\tdown(messageOrMessages: Message | Messages, options?: NodeTransportOptions): void {\n\t\tconst messages = normalizeMessages(messageOrMessages);\n\t\tif (messages.length === 0) return;\n\t\tthis._checkGuard(options);\n\t\tthis._emit(messages);\n\t}\n\n\temit(value: T | undefined | null, options?: NodeTransportOptions): void {\n\t\tthis._checkGuard(options);\n\t\tthis._emit([[DATA, value] as Message]);\n\t}\n\n\tup(messageOrMessages: Message | Messages, options?: NodeTransportOptions): void {\n\t\tif (this._deps.length === 0) return;\n\t\tconst messages = normalizeMessages(messageOrMessages);\n\t\tif (messages.length === 0) return;\n\t\tthis._checkGuard(options);\n\t\tconst forwardOpts: NodeTransportOptions = options ?? { internal: true };\n\t\t// Validate tier constraint before fanning out (B1.4 option a).\n\t\tthis._validateUpTiers(messages);\n\t\tfor (const d of this._deps) {\n\t\t\td.node.up?.(messages, forwardOpts);\n\t\t}\n\t}\n\n\t/**\n\t * @internal Internal up-path used by `actions.up(...)` from inside fn.\n\t * Same tier validation as public `up`, but bypasses the guard check\n\t * since the fn context is already inside an authorized operation.\n\t */\n\tprivate _emitUp(messages: Messages): void {\n\t\tif (this._deps.length === 0) return;\n\t\tif (messages.length === 0) return;\n\t\tthis._validateUpTiers(messages);\n\t\tfor (const d of this._deps) {\n\t\t\td.node.up?.(messages, { internal: true });\n\t\t}\n\t}\n\n\t/**\n\t * @internal Enforce spec §1.2 — up-direction messages are restricted to\n\t * tier 0–2 and tier 5 (START, DIRTY, INVALIDATE, PAUSE, RESUME,\n\t * TEARDOWN). Tier 3 (DATA/RESOLVED) and tier 4 (COMPLETE/ERROR) are\n\t * downstream-only. Emitting tier-3/4 via `up` would bypass equals\n\t * substitution and cache advance entirely and is a protocol bug.\n\t */\n\tprivate _validateUpTiers(messages: Messages): void {\n\t\tconst tierOf = this._config.tierOf;\n\t\tfor (const m of messages) {\n\t\t\tconst tier = tierOf(m[0]);\n\t\t\tif (tier === 3 || tier === 4) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Node \"${this.name}\": tier-${tier} messages cannot flow up — ` +\n\t\t\t\t\t\t\"DATA/RESOLVED/COMPLETE/ERROR are downstream-only. Use \" +\n\t\t\t\t\t\t\"`down(...)` for value delivery; `up(...)` is for control \" +\n\t\t\t\t\t\t\"signals (DIRTY, INVALIDATE, PAUSE, RESUME, TEARDOWN).\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tsubscribe(sink: NodeSink, actor?: Actor): () => void {\n\t\tif (actor != null && this._guard != null) {\n\t\t\tconst a = normalizeActor(actor);\n\t\t\tif (!this._guard(a, \"observe\")) {\n\t\t\t\tthrow new GuardDenied({ actor: a, action: \"observe\", nodeName: this.name });\n\t\t\t}\n\t\t}\n\n\t\t// Resubscribable terminal reset.\n\t\tconst wasTerminal = this._isTerminal;\n\t\tconst afterTerminalReset = wasTerminal && this._resubscribable;\n\t\tif (afterTerminalReset) {\n\t\t\tthis._cached = undefined;\n\t\t\tthis._status = \"sentinel\";\n\t\t\tthis._store = {};\n\t\t\tthis._hasCalledFnOnce = false;\n\t\t\tthis._waveHasNewData = false;\n\t\t\tthis._hasNewTerminal = false;\n\t\t\tthis._paused = false;\n\t\t\tthis._pendingWave = false;\n\t\t\tthis._pendingRerun = false;\n\t\t\tthis._isExecutingFn = false;\n\t\t\tthis._rerunDepth = 0;\n\t\t\tthis._dirtyDepCount = 0;\n\t\t\t// C0: clear pause state so a new subscriber after terminal-reset\n\t\t\t// starts from a clean pause lockset — otherwise a lockId from\n\t\t\t// the previous lifecycle would leave the node stuck paused and\n\t\t\t// swallow every emit.\n\t\t\tthis._pauseLocks = null;\n\t\t\tthis._pauseBuffer = null;\n\t\t\tfor (const d of this._deps) resetDepRecord(d);\n\t\t}\n\n\t\tthis._sinkCount += 1;\n\n\t\t// Subscribe ceremony via singleton.\n\t\t// Rollback on throw: undo the sinkCount bump — sink is not yet registered,\n\t\t// no _activate() has run, nothing else to clean up.\n\t\tlet subCleanup: (() => void) | undefined;\n\t\ttry {\n\t\t\tsubCleanup = this._config.onSubscribe(\n\t\t\t\tthis as unknown as NodeCtx,\n\t\t\t\tsink,\n\t\t\t\t{ sinkCount: this._sinkCount, afterTerminalReset },\n\t\t\t\tthis._actions,\n\t\t\t);\n\t\t} catch (err) {\n\t\t\tthis._sinkCount -= 1;\n\t\t\tthrow err;\n\t\t}\n\n\t\t// Register sink AFTER START delivery (spec §2.2).\n\t\tif (this._sinks == null) {\n\t\t\tthis._sinks = sink;\n\t\t} else if (typeof this._sinks === \"function\") {\n\t\t\tthis._sinks = new Set<NodeSink>([this._sinks, sink]);\n\t\t} else {\n\t\t\tthis._sinks.add(sink);\n\t\t}\n\n\t\t// First-subscriber activation.\n\t\t// Rollback on throw: undo sink registration, sinkCount bump, and subCleanup.\n\t\t// _activate() rolls back its own partial dep subscriptions before re-throwing.\n\t\tconst isTerminalNow = this._isTerminal;\n\t\tif (this._sinkCount === 1 && !isTerminalNow) {\n\t\t\ttry {\n\t\t\t\tthis._activate();\n\t\t\t} catch (err) {\n\t\t\t\tthis._sinkCount -= 1;\n\t\t\t\tthis._removeSink(sink);\n\t\t\t\t// Restore status: onSubscribe emitted START which set _status to\n\t\t\t\t// \"pending\". With zero sinks the node is back to its pre-subscribe\n\t\t\t\t// state; reset so node.status reflects no active subscription.\n\t\t\t\tif (this._sinkCount === 0) this._status = \"sentinel\";\n\t\t\t\tif (typeof subCleanup === \"function\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tsubCleanup();\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* best-effort: subCleanup errors are secondary */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\n\t\t// Reflect \"activated but no value yet\" as pending.\n\t\tif (this._status === \"sentinel\" && this._cached === undefined) {\n\t\t\tthis._status = \"pending\";\n\t\t}\n\n\t\tlet removed = false;\n\t\treturn (): void => {\n\t\t\tif (removed) return;\n\t\t\tremoved = true;\n\t\t\tthis._sinkCount -= 1;\n\t\t\tthis._removeSink(sink);\n\t\t\tif (typeof subCleanup === \"function\") subCleanup();\n\t\t\tif (this._sinks == null) this._deactivate();\n\t\t};\n\t}\n\n\tprivate _removeSink(sink: NodeSink): void {\n\t\tif (this._sinks === sink) {\n\t\t\tthis._sinks = null;\n\t\t} else if (this._sinks != null && typeof this._sinks !== \"function\") {\n\t\t\tthis._sinks.delete(sink);\n\t\t\tif (this._sinks.size === 1) {\n\t\t\t\tconst [only] = this._sinks;\n\t\t\t\tthis._sinks = only;\n\t\t\t} else if (this._sinks.size === 0) {\n\t\t\t\tthis._sinks = null;\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Lifecycle ---\n\n\t/**\n\t * @internal First-sink activation. For a producer (no deps + fn),\n\t * invokes fn once. For a compute node (has deps), subscribes to every\n\t * dep with the pre-set-dirty trick so the first-run gate waits for\n\t * every dep to settle at least once.\n\t */\n\t_activate(): void {\n\t\tif (this._deps.length === 0) {\n\t\t\tif (this._fn) this._execFn();\n\t\t\treturn;\n\t\t}\n\t\t// Pre-set every dep as sentinel BEFORE subscribing. If the first dep\n\t\t// delivers DATA synchronously during its subscribe callback, the\n\t\t// sentinel gate holds fn until all deps have contributed at least one\n\t\t// value. _dirtyDepCount starts at 0 — actual DIRTY messages from deps\n\t\t// drive it; pre-dirtying all deps would cause any dep that only delivers\n\t\t// [[START]] (no DATA) to appear permanently \"mid-wave\", which blocks\n\t\t// terminal propagation from other deps incorrectly.\n\t\tthis._dirtyDepCount = 0;\n\t\t// Capture the initial length BEFORE subscribing. `_addDep` can fire\n\t\t// synchronously during a dep's subscribe callback (e.g., via\n\t\t// `autoTrackNode` discovery in `_execFn`) and push new DepRecords.\n\t\t// Iterating `this._deps.length` live would mean this loop also\n\t\t// subscribes the new dep that `_addDep` already subscribed — a\n\t\t// double-subscribe bug. Snapshot the length instead; `_addDep`\n\t\t// owns the subscribe + counter bump for any dep it adds.\n\t\tconst initialLen = this._deps.length;\n\t\t// subscribedCount tracks how many deps were successfully subscribed.\n\t\t// On failure, only those deps need to be rolled back.\n\t\tlet subscribedCount = 0;\n\t\ttry {\n\t\t\tfor (let i = 0; i < initialLen; i++) {\n\t\t\t\tconst depIdx = i;\n\t\t\t\tconst dep = this._deps[i];\n\t\t\t\t// Pre-set to noopUnsub so the liveness check inside the callback\n\t\t\t\t// passes during synchronous push-on-subscribe (dep.unsub is non-null),\n\t\t\t\t// while still blocking stale drainPhase2 closures that fire after\n\t\t\t\t// _deactivate sets dep.unsub = null.\n\t\t\t\tdep.unsub = noopUnsub;\n\t\t\t\tdep.unsub = dep.node.subscribe((msgs) => {\n\t\t\t\t\t// Liveness check: dep.unsub === null means this subscription was\n\t\t\t\t\t// cancelled by _deactivate. Drop deliveries from stale drainPhase2\n\t\t\t\t\t// closures that outlived the subscription.\n\t\t\t\t\tif (dep.unsub === null) return;\n\t\t\t\t\t// Track whether any tier-3+ settlement-class message arrived\n\t\t\t\t\t// (DATA/RESOLVED at tier 3, COMPLETE/ERROR at tier 4). We only\n\t\t\t\t\t// fire `_maybeRunFnOnSettlement` once per sink call when at\n\t\t\t\t\t// least one settlement was processed — preserves the old\n\t\t\t\t\t// `_onDepMessage` semantic (which only triggered the check\n\t\t\t\t\t// after settlement-class messages) while letting multi-DATA\n\t\t\t\t\t// batches fire `fn` exactly once with the full wave (Bug 1\n\t\t\t\t\t// fix). Tier classification goes through the central\n\t\t\t\t\t// `config.tierOf` utility per spec §5.11 — never hardcode\n\t\t\t\t\t// message-type checks here.\n\t\t\t\t\tconst tierOf = this._config.tierOf;\n\t\t\t\t\tlet sawSettlement = false;\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (tierOf(m[0]) >= 3) sawSettlement = true;\n\t\t\t\t\t\tthis._config.onMessage(\n\t\t\t\t\t\t\tthis as unknown as NodeCtx,\n\t\t\t\t\t\t\tm,\n\t\t\t\t\t\t\t{ direction: \"down-in\", depIndex: depIdx },\n\t\t\t\t\t\t\tthis._actions,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tif (sawSettlement) this._maybeRunFnOnSettlement();\n\t\t\t\t});\n\t\t\t\tsubscribedCount++;\n\t\t\t}\n\t\t} catch (err) {\n\t\t\t// Dep at index `subscribedCount` failed — its dep.unsub is still noopUnsub.\n\t\t\t// Mark it null so the liveness check treats any queued closures as stale.\n\t\t\tthis._deps[subscribedCount].unsub = null;\n\t\t\t// Unsubscribe all deps that DID subscribe successfully (0..subscribedCount-1).\n\t\t\tfor (let j = 0; j < subscribedCount; j++) {\n\t\t\t\tconst d = this._deps[j];\n\t\t\t\tif (d.unsub != null) {\n\t\t\t\t\tconst u = d.unsub;\n\t\t\t\t\td.unsub = null;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tu();\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* best-effort: dep unsub errors are secondary */\n\t\t\t\t\t}\n\t\t\t\t\tresetDepRecord(d);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._dirtyDepCount = 0;\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\t/**\n\t * @internal Append a dep post-construction. Used by `autoTrackNode`\n\t * (runtime dep discovery) and `Graph.connect()` (post-construction\n\t * wiring). Subscribes immediately — if DATA arrives synchronously\n\t * during subscribe and fn is currently executing, the re-run is\n\t * deferred via `_pendingRerun` flag (see `_execFn` guard).\n\t *\n\t * **Dedup:** idempotent on duplicate `depNode` — if `depNode` is\n\t * already in `_deps`, returns the existing index without mutating\n\t * state. Callers can safely invoke `_addDep` without their own\n\t * \"already added\" check. `autoTrackNode` still keeps a `depIndexMap`\n\t * as a fast-path lookup for known deps (returning cached `data[idx]`\n\t * without calling `_addDep` at all); this internal dedup is the\n\t * backstop for any caller that doesn't track its own dep set.\n\t *\n\t * @returns The index of the new dep in `_deps`, or the existing index\n\t * if the dep was already present.\n\t */\n\t_addDep(depNode: Node): number {\n\t\t// Dedup: idempotent on repeated adds of the same dep. Matches\n\t\t// reference equality — the DepRecord is keyed by `node` identity,\n\t\t// so a caller with a fresh `depNode` that observes as equal but\n\t\t// is a distinct object is treated as a new dep.\n\t\tfor (let i = 0; i < this._deps.length; i++) {\n\t\t\tif (this._deps[i].node === depNode) return i;\n\t\t}\n\t\tconst depIdx = this._deps.length;\n\t\tconst record = createDepRecord(depNode);\n\t\tthis._deps.push(record);\n\n\t\t// If the node is inactive (no subscribers yet), defer subscribe to\n\t\t// _activate(). Subscribing here would create a duplicate subscription\n\t\t// because _activate() unconditionally subscribes to all _deps entries.\n\t\t// _activate() resets _dirtyDepCount to 0 before subscribing, so pre-\n\t\t// dirtying is wasted work and causes counter underflow on the first DATA.\n\t\tif (this._sinks == null) return depIdx;\n\n\t\trecord.dirty = true;\n\t\t// New dep starts dirty — bump the A3 counter to match the pre-set flag.\n\t\t// Skipping the helper here because the record isn't in the array yet when\n\t\t// the helper would early-return on `dep.dirty === true`.\n\t\tthis._dirtyDepCount++;\n\t\t// Topology change → downstream sees a new wave. Skip when already\n\t\t// dirty (we're inside an in-flight wave and have already emitted).\n\t\t// `_depDirtied` can't do this for us because `record.dirty` was\n\t\t// pre-set above, which short-circuits its DIRTY-emit path.\n\t\tif (this._status !== \"dirty\") this._emit(DIRTY_ONLY_BATCH);\n\t\trecord.unsub = noopUnsub;\n\t\ttry {\n\t\t\trecord.unsub = depNode.subscribe((msgs) => {\n\t\t\t\tif (record.unsub === null) return;\n\t\t\t\t// Tier-3+ classification via central `tierOf` per spec §5.11\n\t\t\t\t// (Bug 1 fix — see _activate for details).\n\t\t\t\tconst tierOf = this._config.tierOf;\n\t\t\t\tlet sawSettlement = false;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (tierOf(m[0]) >= 3) sawSettlement = true;\n\t\t\t\t\tthis._config.onMessage(\n\t\t\t\t\t\tthis as unknown as NodeCtx,\n\t\t\t\t\t\tm,\n\t\t\t\t\t\t{ direction: \"down-in\", depIndex: depIdx },\n\t\t\t\t\t\tthis._actions,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (sawSettlement) this._maybeRunFnOnSettlement();\n\t\t\t});\n\t\t} catch (err) {\n\t\t\t// Rollback: remove the dep record we just pushed and undo the dirty\n\t\t\t// counter. record.unsub stays null (already cleared below) so any\n\t\t\t// drainPhase2 closures queued by subscribe before it threw are\n\t\t\t// treated as stale and dropped by the liveness check.\n\t\t\trecord.unsub = null;\n\t\t\tthis._deps.pop();\n\t\t\tthis._dirtyDepCount--;\n\t\t\t// Propagate: _execFn's catch block will emit ERROR, which settles\n\t\t\t// downstream nodes that received the DIRTY we emitted above.\n\t\t\tthrow err;\n\t\t}\n\t\treturn depIdx;\n\t}\n\n\t/**\n\t * @internal Unsubscribes from deps, fires fn cleanup (both shapes),\n\t * clears wave/store state, and (for compute nodes) drops `_cached` per\n\t * the ROM/RAM rule. Idempotent: second call is a no-op.\n\t *\n\t * @param skipStatusUpdate — When `true`, the caller takes responsibility\n\t * for setting `_status` after deactivation (e.g. TEARDOWN always sets\n\t * `\"sentinel\"` unconditionally). When `false` (default), deactivation\n\t * applies the ROM rule: compute nodes → `\"sentinel\"`, state nodes\n\t * preserve their current status.\n\t */\n\t_deactivate(skipStatusUpdate = false): void {\n\t\t// Fn cleanup — both () => void and { deactivation } forms fire here.\n\t\t// Note on cleanup-throw ERRORs: when deactivation runs as part of\n\t\t// last-sink-unsubscribe, `_sinks` is already `null` by the time this\n\t\t// method is reached, so any ERROR emitted here lands on\n\t\t// `_deliverToSinks`'s null-guard and is dropped by design. Cleanup\n\t\t// errors during teardown are best-effort — callers that need to\n\t\t// observe them should install a host-level error channel via\n\t\t// `configure()`.\n\t\tconst cleanup = this._cleanup;\n\t\tthis._cleanup = undefined;\n\t\tif (typeof cleanup === \"function\") {\n\t\t\ttry {\n\t\t\t\tcleanup();\n\t\t\t} catch (err) {\n\t\t\t\tthis._emit([[ERROR, this._wrapFnError(\"cleanup threw\", err)]]);\n\t\t\t}\n\t\t} else if (\n\t\t\tcleanup != null &&\n\t\t\ttypeof (cleanup as { deactivation?: unknown }).deactivation === \"function\"\n\t\t) {\n\t\t\ttry {\n\t\t\t\t(cleanup as { deactivation: () => void }).deactivation();\n\t\t\t} catch (err) {\n\t\t\t\tthis._emit([[ERROR, this._wrapFnError(\"cleanup.deactivation threw\", err)]]);\n\t\t\t}\n\t\t}\n\n\t\t// Disconnect from deps.\n\t\tfor (const d of this._deps) {\n\t\t\tif (d.unsub != null) {\n\t\t\t\tconst u = d.unsub;\n\t\t\t\td.unsub = null;\n\t\t\t\ttry {\n\t\t\t\t\tu();\n\t\t\t\t} catch {\n\t\t\t\t\t/* best-effort teardown of upstream subscription */\n\t\t\t\t}\n\t\t\t}\n\t\t\tresetDepRecord(d);\n\t\t}\n\n\t\t// Clear wave + store state.\n\t\tthis._waveHasNewData = false;\n\t\tthis._hasNewTerminal = false;\n\t\tthis._hasCalledFnOnce = false;\n\t\tthis._paused = false;\n\t\tthis._pendingWave = false;\n\t\tthis._pendingRerun = false;\n\t\tthis._rerunDepth = 0;\n\t\tthis._store = {};\n\t\t// A3 counter reset with DepRecord bulk-reset.\n\t\tthis._dirtyDepCount = 0;\n\t\t// C0 pause state: TEARDOWN is a hard reset. Buffered tier-3/4\n\t\t// messages from a paused `resumeAll` node are DISCARDED rather than\n\t\t// drained, matching \"teardown wipes in-flight state\" semantics.\n\t\t// Clearing both structures also prevents a memory leak on\n\t\t// non-resubscribable teardown, and guarantees a resubscribable\n\t\t// re-activation starts from `_paused === false` with no stale\n\t\t// lockset carried over from the previous lifecycle.\n\t\tthis._pauseLocks = null;\n\t\tthis._pauseBuffer = null;\n\n\t\t// ROM/RAM: compute nodes clear cache; pure state nodes preserve it.\n\t\tif (this._fn != null) {\n\t\t\tthis._cached = undefined;\n\t\t}\n\n\t\tif (!skipStatusUpdate) {\n\t\t\t// Compute nodes → \"sentinel\" (cache cleared, no value).\n\t\t\t// - Non-terminal: always reset.\n\t\t\t// - Terminal + resubscribable: reset (resubscribable means\n\t\t\t// \"can be re-activated after terminal\" — the terminal state\n\t\t\t// doesn't persist across subscription cycles).\n\t\t\t// - Terminal + non-resubscribable: preserve (stream is over).\n\t\t\t// State nodes preserve status (ROM rule, value is intrinsic).\n\t\t\tif (this._fn != null || this._deps.length > 0) {\n\t\t\t\tif (!this._isTerminal || this._resubscribable) {\n\t\t\t\t\tthis._status = \"sentinel\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// --- Dep message dispatch (§3.5 singleton default) ---\n\n\t/**\n\t * @internal Default per-tier dispatch for incoming dep messages. Called\n\t * by `defaultOnMessage`. Updates the DepRecord, triggers wave\n\t * completion, and forwards passthrough traffic.\n\t */\n\t_onDepMessage(depIndex: number, msg: Message): void {\n\t\tconst dep = this._deps[depIndex];\n\t\tconst t = msg[0];\n\n\t\t// Fire inspector hooks before default dispatch. Common case: no hooks\n\t\t// (undefined slot). Multiple observers can attach simultaneously.\n\t\tif (this._inspectorHooks != null) {\n\t\t\tconst ev: NodeInspectorHookEvent = { kind: \"dep_message\", depIndex, message: msg };\n\t\t\tfor (const hook of this._inspectorHooks) hook(ev);\n\t\t}\n\n\t\t// Tier 0 (START) — informational, no state change.\n\t\tif (t === START) return;\n\n\t\t// Tier 1\n\t\tif (t === DIRTY) {\n\t\t\tthis._depDirtied(dep);\n\t\t\treturn;\n\t\t}\n\t\tif (t === INVALIDATE) {\n\t\t\tthis._depInvalidated(dep);\n\t\t\tthis._emit(INVALIDATE_ONLY_BATCH);\n\t\t\treturn;\n\t\t}\n\n\t\t// Tier 2 — PAUSE / RESUME flow downstream (spec §1.2). Lock bookkeeping\n\t\t// happens inside `_emit` so both `_onDepMessage` (PAUSE received from\n\t\t// a dep) and external `node.down([[PAUSE, lockId]])` (source\n\t\t// directly issuing PAUSE) hit the same path. Here we just forward —\n\t\t// `_emit` will consume the lock, update `_paused`, and broadcast.\n\t\tif (t === PAUSE || t === RESUME) {\n\t\t\tthis._emit([msg]);\n\t\t\treturn;\n\t\t}\n\n\t\t// Tier 5\n\t\tif (t === TEARDOWN) {\n\t\t\tthis._emit(TEARDOWN_ONLY_BATCH);\n\t\t\treturn;\n\t\t}\n\n\t\t// Tier 3 / 4 — centralized transitions keep the settlement counters\n\t\t// (`_dirtyDepCount`, `_sentinelDepCount`) in sync with the flags on\n\t\t// every DepRecord. A3 optimization: the two counters let\n\t\t// `_maybeRunFnOnSettlement` check wave completion in O(1) instead\n\t\t// of two `every(...)` scans.\n\t\tif (t === DATA) {\n\t\t\tthis._depSettledAsData(dep, msg[1]);\n\t\t} else if (t === RESOLVED) {\n\t\t\tthis._depSettledAsResolved(dep);\n\t\t} else if (t === COMPLETE) {\n\t\t\tthis._depSettledAsTerminal(dep, true);\n\t\t} else if (t === ERROR) {\n\t\t\tthis._depSettledAsTerminal(dep, msg[1]);\n\t\t} else {\n\t\t\t// Unknown type: forward as-is (spec §1.3.6 forward-compat).\n\t\t\tthis._emit([msg]);\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this._fn) {\n\t\t\t// Passthrough: forward DATA/RESOLVED 1:1 through the unified\n\t\t\t// emit pipeline. `_emit` owns tier sort + synthetic DIRTY\n\t\t\t// prefix + equals substitution uniformly — no manual framing.\n\t\t\tif (t === DATA || t === RESOLVED) {\n\t\t\t\tthis._emit([msg]);\n\t\t\t}\n\t\t\tif (t === COMPLETE || t === ERROR) {\n\t\t\t\tthis._maybeAutoTerminalAfterWave();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\t// NOTE: `_maybeRunFnOnSettlement()` is intentionally NOT called here.\n\t\t// It is invoked once at the end of the dep-subscribe callback's\n\t\t// message-iteration loop so that a multi-message sink call —\n\t\t// e.g. `dep.down([[DATA, a], [DATA, b]])` — fires `fn` exactly\n\t\t// once with the full wave batch (`batchData = [[a, b]]`), per the\n\t\t// `_execFn` contract at line 1462: \"fn must see the full wave batch\".\n\t}\n\n\t// --- Centralized dep-state transitions (A3 settlement counters) ---\n\t//\n\t// Every mutation to `DepRecord.dirty` / `DepRecord.prevData` /\n\t// `DepRecord.terminal` must go through one of these helpers so the\n\t// `_dirtyDepCount` and `_sentinelDepCount` counters stay in sync with\n\t// the per-record flags. `_maybeRunFnOnSettlement` reads the counters\n\t// and never re-scans the `_deps` array.\n\n\t/**\n\t * Called when a dep transitions `dirty: false → true` (either from an\n\t * incoming DIRTY, or pre-set during `_activate` / `_addDep` /\n\t * `_depInvalidated`). No-op if the dep is already dirty. Fires the\n\t * downstream DIRTY emit if we're the first to dirty this wave.\n\t */\n\tprivate _depDirtied(dep: DepRecord): void {\n\t\tif (dep.dirty) return;\n\t\tdep.dirty = true;\n\t\tdep.involvedThisWave = true;\n\t\tthis._dirtyDepCount++;\n\t\t// First dep to dirty this wave → propagate DIRTY to our own sinks.\n\t\tif (this._status !== \"dirty\") {\n\t\t\tthis._emit(DIRTY_ONLY_BATCH);\n\t\t}\n\t}\n\n\t/**\n\t * Called when a dep delivers new DATA: clears dirty, stores the payload,\n\t * marks wave-has-data, and — if this is the dep's first DATA — clears\n\t * its sentinel slot so the first-run gate can open.\n\t */\n\tprivate _depSettledAsData(dep: DepRecord, value: unknown): void {\n\t\tif (dep.dirty) {\n\t\t\tdep.dirty = false;\n\t\t\tthis._dirtyDepCount--;\n\t\t}\n\t\tdep.involvedThisWave = true;\n\t\tdep.dataBatch.push(value);\n\t\tthis._waveHasNewData = true;\n\t}\n\n\t/**\n\t * Called when a dep emits RESOLVED (wave settled, value unchanged).\n\t * Clears dirty; does NOT touch `prevData` / `terminal` / sentinel\n\t * count — sentinel only exits on first DATA or terminal, not RESOLVED.\n\t */\n\tprivate _depSettledAsResolved(dep: DepRecord): void {\n\t\tif (dep.dirty) {\n\t\t\tdep.dirty = false;\n\t\t\tthis._dirtyDepCount--;\n\t\t}\n\t}\n\n\t/**\n\t * Called when a dep delivers COMPLETE (`terminal = true`) or ERROR\n\t * (`terminal = errorPayload`). Clears dirty, stores the terminal, and\n\t * — if the dep had never contributed a DATA yet — leaves sentinel\n\t * since the gate treats \"terminated without data\" as gate-open too.\n\t */\n\tprivate _depSettledAsTerminal(dep: DepRecord, terminal: unknown): void {\n\t\tif (dep.dirty) {\n\t\t\tdep.dirty = false;\n\t\t\tthis._dirtyDepCount--;\n\t\t}\n\t\tdep.terminal = terminal;\n\t\tdep.involvedThisWave = true;\n\t\tthis._hasNewTerminal = true;\n\t}\n\n\t/**\n\t * Called when a dep emits INVALIDATE: clears prevData, terminal, and\n\t * dataBatch. The dep is now back in the \"never delivered a real value\"\n\t * state — `prevData === undefined` so the sentinel check in fn will fire.\n\t */\n\tprivate _depInvalidated(dep: DepRecord): void {\n\t\tdep.prevData = undefined;\n\t\tdep.terminal = undefined;\n\t\tdep.dataBatch.length = 0;\n\t\tif (!dep.dirty) {\n\t\t\tdep.dirty = true;\n\t\t\tdep.involvedThisWave = true;\n\t\t\tthis._dirtyDepCount++;\n\t\t} else {\n\t\t\tdep.involvedThisWave = false; // cancel prior wave involvement\n\t\t}\n\t}\n\n\tprivate _maybeRunFnOnSettlement(): void {\n\t\tif (this._isTerminal && !this._resubscribable) return;\n\t\t// O(1) gate: `_dirtyDepCount === 0` means every dep has delivered its\n\t\t// settlement for this wave (DATA, RESOLVED, or terminal).\n\t\tif (this._dirtyDepCount > 0) return;\n\t\tif (this._paused) {\n\t\t\tthis._pendingWave = true;\n\t\t\treturn;\n\t\t}\n\t\t// Pre-fn skip: when no dep sent DATA this wave (all RESOLVED), skip\n\t\t// fn and emit RESOLVED directly. Transitive-skip optimization — leaf\n\t\t// fn is not re-run when a mid-chain node produces the same value.\n\t\tif (!this._waveHasNewData && !this._hasNewTerminal && this._hasCalledFnOnce) {\n\t\t\tthis._clearWaveFlags();\n\t\t\tthis._emit(RESOLVED_ONLY_BATCH);\n\t\t\tthis._maybeAutoTerminalAfterWave();\n\t\t\treturn;\n\t\t}\n\t\tif (this._fn) this._execFn();\n\t\tthis._maybeAutoTerminalAfterWave();\n\t}\n\n\tprivate _maybeAutoTerminalAfterWave(): void {\n\t\tif (this._deps.length === 0) return;\n\t\tif (this._isTerminal) return;\n\t\t// ERROR always propagates (unless rescue operator opts out via\n\t\t// errorWhenDepsError: false). Checked independently of _autoComplete\n\t\t// so operators with completeWhenDepsComplete: false still get\n\t\t// automatic error forwarding.\n\t\tconst erroredDep = this._deps.find((d) => d.terminal !== undefined && d.terminal !== true);\n\t\tif (erroredDep != null) {\n\t\t\tif (this._autoError) {\n\t\t\t\tthis._emit([[ERROR, erroredDep.terminal]]);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// COMPLETE only when autoComplete is true and ALL deps are terminal.\n\t\tif (this._autoComplete && this._deps.every((d) => d.terminal !== undefined)) {\n\t\t\tthis._emit(COMPLETE_ONLY_BATCH);\n\t\t}\n\t}\n\n\t// --- Fn execution ---\n\n\t/**\n\t * @internal Runs the node fn once. Default cleanup (function form) fires\n\t * before the new run; `{ deactivation }` cleanup survives.\n\t */\n\tprivate _execFn(): void {\n\t\tif (!this._fn) return;\n\t\tif (this._isTerminal && !this._resubscribable) return;\n\t\t// Re-entrance guard: if fn is currently executing (e.g. _addDep\n\t\t// triggered a synchronous DATA delivery → _maybeRunFnOnSettlement\n\t\t// → _execFn), defer the re-run until the current fn returns.\n\t\tif (this._isExecutingFn) {\n\t\t\tthis._pendingRerun = true;\n\t\t\treturn;\n\t\t}\n\n\t\t// Pre-run cleanup — only the function-form cleanup fires here.\n\t\tconst prevCleanup = this._cleanup;\n\t\tif (typeof prevCleanup === \"function\") {\n\t\t\tthis._cleanup = undefined;\n\t\t\ttry {\n\t\t\t\tprevCleanup();\n\t\t\t} catch (err) {\n\t\t\t\tthis._emit([[ERROR, this._wrapFnError(\"cleanup threw\", err)]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t// { deactivation } cleanup is preserved across runs.\n\n\t\t// Snapshot dep state BEFORE clearing wave flags so the snapshot\n\t\t// reflects \"this wave\" rather than \"next wave\".\n\t\t// dataBatch is copied here because _clearWaveFlags truncates the live\n\t\t// array in-place (length = 0) — the fn must see the full wave batch.\n\t\tconst batchData: (readonly unknown[] | undefined)[] = this._deps.map((d) =>\n\t\t\t!d.involvedThisWave ? undefined : d.dataBatch.length > 0 ? [...d.dataBatch] : [],\n\t\t);\n\t\t// Snapshot prevData BEFORE committing this wave's values — fn sees the\n\t\t// stable values from the end of the previous wave, not the current wave.\n\t\t// undefined = \"never sent DATA\". null is a valid DATA value.\n\t\tconst prevData: unknown[] = this._deps.map((d) => d.prevData);\n\t\t// Commit: advance each dep's prevData to this wave's last DATA so the\n\t\t// NEXT wave's fn snapshot sees the current wave as \"previous\".\n\t\t// Use the already-copied batchData rather than dep.dataBatch to avoid\n\t\t// any ordering dependency with _clearWaveFlags.\n\t\tfor (let i = 0; i < this._deps.length; i++) {\n\t\t\tconst batch = batchData[i];\n\t\t\tif (batch != null && batch.length > 0) {\n\t\t\t\tthis._deps[i].prevData = batch[batch.length - 1] as unknown;\n\t\t\t}\n\t\t}\n\t\tconst terminalDeps = this._deps.map((d) => d.terminal);\n\t\tconst ctx: FnCtx = { prevData, terminalDeps, store: this._store };\n\n\t\tthis._hasCalledFnOnce = true;\n\t\tthis._clearWaveFlags();\n\n\t\t// Fire inspector hooks before fn runs — for Graph.observe causal traces.\n\t\tif (this._inspectorHooks != null) {\n\t\t\tconst ev: NodeInspectorHookEvent = { kind: \"run\", batchData, prevData };\n\t\t\tfor (const hook of this._inspectorHooks) hook(ev);\n\t\t}\n\n\t\tthis._isExecutingFn = true;\n\t\ttry {\n\t\t\tconst result = this._fn(batchData, this._actions, ctx);\n\t\t\tif (typeof result === \"function\") {\n\t\t\t\tthis._cleanup = result;\n\t\t\t} else if (\n\t\t\t\tresult != null &&\n\t\t\t\ttypeof result === \"object\" &&\n\t\t\t\ttypeof (result as { deactivation?: unknown }).deactivation === \"function\"\n\t\t\t) {\n\t\t\t\tthis._cleanup = result as { deactivation: () => void };\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tthis._emit([[ERROR, this._wrapFnError(\"fn threw\", err)]]);\n\t\t} finally {\n\t\t\tthis._isExecutingFn = false;\n\t\t\t// Run any pending rerun BEFORE clearing wave flags so the\n\t\t\t// rerun's settlement check sees \"this wave had new data\" and\n\t\t\t// skips the pre-fn-skip optimization. Without this ordering,\n\t\t\t// autoTrackNode discovery's second pass gets swallowed by\n\t\t\t// the pre-fn-skip path.\n\t\t\tif (this._pendingRerun) {\n\t\t\t\tthis._pendingRerun = false;\n\t\t\t\tthis._rerunDepth += 1;\n\t\t\t\tif (this._rerunDepth > MAX_RERUN_DEPTH) {\n\t\t\t\t\tthis._rerunDepth = 0;\n\t\t\t\t\tthis._emit([\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tERROR,\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`Node \"${this.name}\": _pendingRerun depth exceeded ${MAX_RERUN_DEPTH} — likely a reactive cycle`,\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} else {\n\t\t\t\t\tthis._maybeRunFnOnSettlement();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Chain converged — reset the depth counter for the next wave.\n\t\t\t\tthis._rerunDepth = 0;\n\t\t\t}\n\t\t\t// Clear flags after rerun so any involvedThisWave/dataBatch set by\n\t\t\t// fn's _addDep subscribe handshakes doesn't leak into the next\n\t\t\t// wave's snapshot. The inner _execFn (if any) already did\n\t\t\t// its own pre-snapshot clear; this is for the case where\n\t\t\t// fn added deps but no rerun fired.\n\t\t\tthis._clearWaveFlags();\n\t\t}\n\t}\n\n\tprivate _clearWaveFlags(): void {\n\t\tthis._waveHasNewData = false;\n\t\tthis._hasNewTerminal = false;\n\t\tfor (const d of this._deps) {\n\t\t\td.involvedThisWave = false;\n\t\t\td.dataBatch.length = 0;\n\t\t}\n\t}\n\n\tprivate _wrapFnError(label: string, err: unknown): Error {\n\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\treturn new Error(`Node \"${this.name}\": ${label}: ${msg}`, { cause: err });\n\t}\n\n\t// --- Framing (tier sort + synthetic DIRTY prefix) ---\n\n\t/**\n\t * @internal Stable tier sort + synthetic DIRTY prefix for an outgoing\n\t * batch. Fast path: already-monotone single-tier batches (the common\n\t * case from interned singletons like `DIRTY_ONLY_BATCH`) return the\n\t * input unchanged. General path: decorate-sort-undecorate into a new\n\t * array, then prepend `[DIRTY]` after any tier-0 START entries when\n\t * a tier-3 payload is present and the node isn't already dirty.\n\t *\n\t * Single source of truth for the spec §1.3.1 framing invariant. Every\n\t * outgoing path hits `_frameBatch` exactly once via `_emit`.\n\t */\n\tprivate _frameBatch(messages: Messages): Messages {\n\t\tconst tierOf = this._config.tierOf;\n\t\t// Fast path: single message.\n\t\tif (messages.length === 1) {\n\t\t\tconst t = tierOf(messages[0][0]);\n\t\t\tif (t === 3 && this._status !== \"dirty\") {\n\t\t\t\treturn [DIRTY_MSG, messages[0]];\n\t\t\t}\n\t\t\treturn messages;\n\t\t}\n\t\t// Check monotonicity and tier-3 presence in a single pass.\n\t\tlet monotone = true;\n\t\tlet hasTier3 = false;\n\t\tlet hasDirty = false;\n\t\tlet prevTier = -1;\n\t\tfor (const m of messages) {\n\t\t\tconst tier = tierOf(m[0]);\n\t\t\tif (tier < prevTier) monotone = false;\n\t\t\tif (tier === 3) hasTier3 = true;\n\t\t\tif (m[0] === DIRTY) hasDirty = true;\n\t\t\tprevTier = tier;\n\t\t}\n\t\tlet sorted: Messages = messages;\n\t\tif (!monotone) {\n\t\t\t// Stable sort via index-keyed decoration.\n\t\t\tconst indexed = messages.map((m, i) => ({ m, i, tier: tierOf(m[0]) }));\n\t\t\tindexed.sort((a, b) => a.tier - b.tier || a.i - b.i);\n\t\t\tsorted = indexed.map((x) => x.m);\n\t\t}\n\t\tif (hasTier3 && !hasDirty && this._status !== \"dirty\") {\n\t\t\t// Insert DIRTY after any tier-0 START entries to preserve\n\t\t\t// monotonicity.\n\t\t\tlet insertAt = 0;\n\t\t\twhile (insertAt < sorted.length && tierOf(sorted[insertAt][0]) === 0) insertAt++;\n\t\t\tif (insertAt === 0) return [DIRTY_MSG, ...sorted];\n\t\t\treturn [...sorted.slice(0, insertAt), DIRTY_MSG, ...sorted.slice(insertAt)];\n\t\t}\n\t\treturn sorted;\n\t}\n\n\t// --- Emit pipeline ---\n\n\t/**\n\t * @internal The unified dispatch waist — one call = one wave.\n\t *\n\t * Pipeline stages, in order:\n\t *\n\t * 1. Early-return on empty batch.\n\t * 2. Terminal filter — post-COMPLETE/ERROR only TEARDOWN/INVALIDATE\n\t * still propagate so graph teardown and cache-clear still work.\n\t * 3. Tier sort (stable) — the batch can be in any order when it\n\t * arrives; the walker downstream (`downWithBatch`) assumes\n\t * ascending tier monotone, and so does `_updateState`'s tier-3\n\t * slice walk. This is the single source of truth for ordering.\n\t * 4. Synthetic DIRTY prefix — if a tier-3 payload is present, no\n\t * DIRTY is already in the batch, and the node isn't already in\n\t * `\"dirty\"` status, prepend `[DIRTY]` after any tier-0 START\n\t * entries. Guarantees spec §1.3.1 (DIRTY precedes DATA within\n\t * the same batch) uniformly across every entry point.\n\t * 5. PAUSE/RESUME lock bookkeeping (C0) — update `_pauseLocks`,\n\t * derive `_paused`, filter unknown-lockId RESUME, replay\n\t * bufferAll buffer on final lock release.\n\t * 6. Meta TEARDOWN fan-out — notify meta children before\n\t * `_updateState`'s TEARDOWN branch calls `_deactivate`. Hoisted\n\t * out of the walk to keep `_updateState` re-entrance-free.\n\t * 7. `_updateState` — walk the batch in tier order, advancing\n\t * `_cached` / `_status` / `_versioning` and running equals\n\t * substitution on tier-3 DATA (§3.5.1). Returns\n\t * `{finalMessages, equalsError?}`.\n\t * 8. `downWithBatch` dispatch (or bufferAll capture if paused with\n\t * `pausable: \"resumeAll\"`).\n\t * 9. Recursive ERROR emission if equals threw mid-walk.\n\t *\n\t * `node.down` / `node.emit` / `actions.down` / `actions.emit` all\n\t * converge here — the unified `_emit` waist (spec §1.3.1).\n\t */\n\t_emit(messages: Messages): void {\n\t\tif (messages.length === 0) return;\n\n\t\t// Terminal filter: after COMPLETE/ERROR (non-resubscribable), only\n\t\t// TEARDOWN / INVALIDATE still propagate so graph teardown and cache-\n\t\t// clear still work.\n\t\tlet deliverable = messages;\n\t\tconst terminal = this._isTerminal;\n\t\tif (terminal && !this._resubscribable) {\n\t\t\tconst pass = messages.filter((m) => m[0] === TEARDOWN || m[0] === INVALIDATE);\n\t\t\tif (pass.length === 0) return;\n\t\t\tdeliverable = pass;\n\t\t}\n\n\t\t// Tier sort + synthetic DIRTY prefix (stages 3 + 4 of the emit\n\t\t// pipeline). `_frameBatch` is a no-op for pre-sorted single-msg\n\t\t// batches (the common case from the tuple-interning A2 call sites);\n\t\t// otherwise it produces a stable tier-sorted copy with `[DIRTY]`\n\t\t// auto-prepended after any tier-0 messages when a tier-3 payload\n\t\t// is present and the node isn't already dirty.\n\t\tdeliverable = this._frameBatch(deliverable);\n\n\t\t// C0 — PAUSE/RESUME lock tracking. Every tier-2 tuple MUST carry a\n\t\t// `lockId` payload. Each PAUSE / RESUME updates `_pauseLocks` and\n\t\t// derives `_paused` from set size — multi-pauser correctness\n\t\t// guarantees a node only resumes when every lock it holds is\n\t\t// released. All tier-2 messages are forwarded unconditionally so\n\t\t// downstream nodes on the propagation path keep their own lock\n\t\t// sets consistent (subscribers that joined the graph before any\n\t\t// PAUSE see the full lock history). `pausable: false` sources\n\t\t// forward PAUSE/RESUME but do not track locks — appropriate for\n\t\t// reactive timers that must keep ticking. Unknown-lockId RESUME\n\t\t// is swallowed to keep `dispose()` idempotent.\n\t\tlet filtered: Message[] | null = null;\n\t\tfor (let i = 0; i < deliverable.length; i++) {\n\t\t\tconst m = deliverable[i];\n\t\t\tconst t = m[0];\n\t\t\tif (t !== PAUSE && t !== RESUME) {\n\t\t\t\tif (filtered != null) filtered.push(m);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (m.length < 2) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Node \"${this.name}\": [[${t === PAUSE ? \"PAUSE\" : \"RESUME\"}]] must ` +\n\t\t\t\t\t\t\"carry a lockId payload — bare PAUSE/RESUME is a protocol \" +\n\t\t\t\t\t\t\"violation (C0 rule). Use `[[PAUSE, lockId]]` / \" +\n\t\t\t\t\t\t\"`[[RESUME, lockId]]`.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tlet forward = true;\n\t\t\tif (this._pausable !== false) {\n\t\t\t\tconst lockId = m[1];\n\t\t\t\tif (t === PAUSE) {\n\t\t\t\t\tif (this._pauseLocks == null) this._pauseLocks = new Set();\n\t\t\t\t\tthis._pauseLocks.add(lockId);\n\t\t\t\t\tthis._paused = true;\n\t\t\t\t\tif (this._pausable === \"resumeAll\" && this._pauseBuffer == null) {\n\t\t\t\t\t\tthis._pauseBuffer = [];\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// RESUME\n\t\t\t\t\tif (this._pauseLocks == null || !this._pauseLocks.has(lockId)) {\n\t\t\t\t\t\t// Unknown lockId — swallow to keep dispose idempotent.\n\t\t\t\t\t\tforward = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._pauseLocks.delete(lockId);\n\t\t\t\t\t\tif (this._pauseLocks.size === 0) {\n\t\t\t\t\t\t\tthis._paused = false;\n\t\t\t\t\t\t\t// Replay bufferAll buffer through the outgoing\n\t\t\t\t\t\t\t// pipeline BEFORE forwarding RESUME — subscribers\n\t\t\t\t\t\t\t// observe the deferred DATAs as part of the\n\t\t\t\t\t\t\t// pre-RESUME wake-up.\n\t\t\t\t\t\t\t//\n\t\t\t\t\t\t\t// D2 (2026-04-13) semantic note: the recursive\n\t\t\t\t\t\t\t// `_emit(drain)` goes through the full pipeline\n\t\t\t\t\t\t\t// including `_updateState`'s equals substitution.\n\t\t\t\t\t\t\t// A buffered `[DATA, v]` whose value matches the\n\t\t\t\t\t\t\t// *pre-pause* cache will collapse to RESOLVED on\n\t\t\t\t\t\t\t// replay — producer \"pulses\" that write the same\n\t\t\t\t\t\t\t// value while paused are absorbed. This matches\n\t\t\t\t\t\t\t// diamond-safety intent: `.cache` stays coherent\n\t\t\t\t\t\t\t// with \"the last DATA actually delivered to\n\t\t\t\t\t\t\t// sinks\". Producers that need pulse semantics\n\t\t\t\t\t\t\t// (every write observable regardless of value)\n\t\t\t\t\t\t\t// should set `equals: () => false` on the node.\n\t\t\t\t\t\t\tif (this._pauseBuffer != null && this._pauseBuffer.length > 0) {\n\t\t\t\t\t\t\t\tconst drain = this._pauseBuffer;\n\t\t\t\t\t\t\t\tthis._pauseBuffer = [];\n\t\t\t\t\t\t\t\tthis._emit(drain);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Kick the held wave forward if one was pending.\n\t\t\t\t\t\t\tif (this._pendingWave) {\n\t\t\t\t\t\t\t\tthis._pendingWave = false;\n\t\t\t\t\t\t\t\tthis._maybeRunFnOnSettlement();\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}\n\t\t\tif (!forward) {\n\t\t\t\tif (filtered == null) filtered = deliverable.slice(0, i) as Message[];\n\t\t\t} else if (filtered != null) {\n\t\t\t\tfiltered.push(m);\n\t\t\t}\n\t\t}\n\t\tif (filtered != null) {\n\t\t\tif (filtered.length === 0) return;\n\t\t\tdeliverable = filtered;\n\t\t}\n\n\t\t// Meta TEARDOWN fan-out happens BEFORE `_updateState` so the walk\n\t\t// stays re-entrance-free: a meta node's own dispatch must not\n\t\t// re-enter the parent's outgoing pipeline while `this._cached` /\n\t\t// `this._status` are mid-commit. This preserves the spec ordering\n\t\t// \"meta propagates before deactivation\" — `_updateState`'s TEARDOWN\n\t\t// branch still runs `_deactivate` AFTER the meta children\n\t\t// have already been notified here.\n\t\tif (this._hasMeta && deliverable.some((m) => m[0] === TEARDOWN)) {\n\t\t\tfor (const k of Object.keys(this.meta)) {\n\t\t\t\ttry {\n\t\t\t\t\t(this.meta[k] as NodeImpl)._emit(TEARDOWN_ONLY_BATCH);\n\t\t\t\t} catch {\n\t\t\t\t\t/* best-effort */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// State update + equals substitution (§3.5.1 invariant). Returns the\n\t\t// possibly-rewritten batch and an optional equals-throw error. When\n\t\t// equals throws mid-walk we still deliver the successfully-walked\n\t\t// prefix to sinks before emitting ERROR, preserving cache/wire\n\t\t// coherence (user P2 option (i)).\n\t\tconst { finalMessages, equalsError } = this._updateState(deliverable);\n\n\t\t// Global inspector fan-out (Redux-DevTools-style tracer). Fires once\n\t\t// per outgoing batch, gated by `inspectorEnabled` so production paths\n\t\t// pay one boolean check. Hook errors are swallowed — instrumentation\n\t\t// must not break the data plane.\n\t\tif (finalMessages.length > 0 && this._config.inspectorEnabled) {\n\t\t\tconst inspector = this._config.globalInspector;\n\t\t\tif (inspector != null) {\n\t\t\t\ttry {\n\t\t\t\t\tinspector({ kind: \"emit\", node: this, messages: finalMessages });\n\t\t\t\t} catch {\n\t\t\t\t\t/* best-effort */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (finalMessages.length > 0) {\n\t\t\t// BufferAll: while paused with `pausable: \"resumeAll\"`, buffer\n\t\t\t// tier-3/4 payloads in order. Tier 0–2 and tier 5 continue to\n\t\t\t// dispatch synchronously — START/DIRTY/RESUME/PAUSE/TEARDOWN\n\t\t\t// must stay live so subscribers, downstream pausers, and graph\n\t\t\t// teardown all observe them. Cache/status advance has already\n\t\t\t// happened via `_updateState`, so the replay later just pushes\n\t\t\t// the deferred messages back through `downWithBatch`.\n\t\t\tif (this._paused && this._pausable === \"resumeAll\" && this._pauseBuffer != null) {\n\t\t\t\tconst tierOf = this._config.tierOf;\n\t\t\t\tconst immediate: Message[] = [];\n\t\t\t\tfor (const m of finalMessages) {\n\t\t\t\t\tconst tier = tierOf(m[0]);\n\t\t\t\t\tif (tier < 3 || tier === 5) {\n\t\t\t\t\t\timmediate.push(m);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._pauseBuffer.push(m);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (immediate.length > 0) {\n\t\t\t\t\tthis._dispatchOrAccumulate(immediate);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis._dispatchOrAccumulate(finalMessages);\n\t\t\t}\n\t\t}\n\n\t\tif (equalsError != null) {\n\t\t\tthis._emit([[ERROR, equalsError]]);\n\t\t}\n\t}\n\n\t/**\n\t * @internal Walk an outgoing (already-framed) batch, updating own\n\t * cache / status / versioning and running equals substitution on\n\t * every tier-3 DATA (§3.5.1). Framing — tier sort and synthetic\n\t * DIRTY prefix — has already happened upstream in `_frameBatch`.\n\t * This walk trusts the input is in monotone tier order and that the\n\t * spec §1.3.1 DIRTY/RESOLVED precedence invariant is already\n\t * satisfied by the frame.\n\t *\n\t * Equals substitution: every DATA payload is compared against the\n\t * live `_cached`; when equal, the tuple is rewritten to `[RESOLVED]`\n\t * in a per-call copy and cache is not re-advanced. `.cache` remains\n\t * coherent with \"the last DATA payload this node actually sent\n\t * downstream\".\n\t *\n\t * Returns `{ finalMessages, equalsError? }`:\n\t * - `finalMessages` — the array to deliver to sinks (may be\n\t * `messages` unchanged, a rewritten copy with DATA→RESOLVED\n\t * substitutions, or a truncated prefix when equals throws mid-walk).\n\t * - `equalsError` — present only when the configured `equals` function\n\t * threw on some DATA message. `_emit` delivers the prefix first,\n\t * then emits a fresh ERROR batch via a recursive `_emit` call so\n\t * subscribers observe `[...walked_prefix, ERROR]` in order.\n\t */\n\tprivate _updateState(messages: Messages): {\n\t\tfinalMessages: Messages;\n\t\tequalsError?: Error;\n\t} {\n\t\tconst tierOf = this._config.tierOf;\n\t\tlet rewritten: Message[] | undefined;\n\t\tlet equalsError: Error | undefined;\n\t\tlet abortedAt = -1;\n\t\t// Count tier-3 messages (DATA + RESOLVED) in the batch. Equals\n\t\t// substitution is only worthwhile for a single tier-3 message —\n\t\t// an unchanged value can be rewritten to RESOLVED, enabling the\n\t\t// downstream pre-fn skip. With multiple tier-3 messages the\n\t\t// downstream fn must run regardless, so equals on each is wasted.\n\t\tlet dataCount = 0;\n\t\tfor (const m of messages) {\n\t\t\tif (tierOf(m[0]) === 3) dataCount++;\n\t\t}\n\t\tconst checkEquals = dataCount <= 1;\n\t\t// Version advances once per batch wave, not per DATA in the batch.\n\t\t// _cached only retains the last DATA value, so intermediate version\n\t\t// entries would reference values that can never be retrieved from cache.\n\t\t// Pre-scan for the last DATA index so we know when to fire advanceVersion.\n\t\tlet lastDataIdx = -1;\n\t\tif (this._versioning != null && dataCount > 1) {\n\t\t\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\t\t\tif (messages[i][0] === DATA) {\n\t\t\t\t\tlastDataIdx = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (let i = 0; i < messages.length; i++) {\n\t\t\tconst m = messages[i];\n\t\t\tconst t = m[0];\n\t\t\tif (t === DATA) {\n\t\t\t\tif (m.length >= 2) {\n\t\t\t\t\tlet unchanged = false;\n\t\t\t\t\tif (checkEquals && this._cached !== undefined) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tunchanged = this._equals(this._cached as T, m[1] as T);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t// Abort walk on equals throw: deliver successfully-walked\n\t\t\t\t\t\t\t// prefix, then caller emits ERROR. Excludes the throwing\n\t\t\t\t\t\t\t// message from the prefix.\n\t\t\t\t\t\t\tequalsError = this._wrapFnError(\"equals threw\", err);\n\t\t\t\t\t\t\tabortedAt = i;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (unchanged) {\n\t\t\t\t\t\tif (rewritten == null) rewritten = messages.slice(0, i) as Message[];\n\t\t\t\t\t\trewritten.push(RESOLVED_MSG);\n\t\t\t\t\t\tthis._status = \"resolved\";\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthis._cached = m[1] as T;\n\t\t\t\t\tif (this._versioning != null) {\n\t\t\t\t\t\t// dataCount <= 1: lastDataIdx is -1; advance unconditionally\n\t\t\t\t\t\t// (single DATA, correct as before).\n\t\t\t\t\t\t// dataCount > 1: only advance on the last DATA in the batch.\n\t\t\t\t\t\tif (lastDataIdx < 0 || i === lastDataIdx) {\n\t\t\t\t\t\t\tadvanceVersion(this._versioning, m[1], this._hashFn);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthis._status = \"settled\";\n\t\t\t\tif (rewritten != null) rewritten.push(m);\n\t\t\t} else {\n\t\t\t\tif (rewritten != null) rewritten.push(m);\n\t\t\t\tif (t === DIRTY) {\n\t\t\t\t\tthis._status = \"dirty\";\n\t\t\t\t} else if (t === RESOLVED) {\n\t\t\t\t\tthis._status = \"resolved\";\n\t\t\t\t} else if (t === COMPLETE) {\n\t\t\t\t\tthis._status = \"completed\";\n\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\tthis._status = \"errored\";\n\t\t\t\t} else if (t === INVALIDATE) {\n\t\t\t\t\tthis._cached = undefined;\n\t\t\t\t\tthis._status = \"dirty\";\n\t\t\t\t\t// Function-form cleanup fires on invalidate (treats as \"re-run\").\n\t\t\t\t\tconst c = this._cleanup;\n\t\t\t\t\tif (typeof c === \"function\") {\n\t\t\t\t\t\tthis._cleanup = undefined;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tc();\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* best-effort */\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\tif (this._resetOnTeardown) this._cached = undefined;\n\t\t\t\t\t// Meta TEARDOWN fan-out was already performed by `_emit`\n\t\t\t\t\t// before this walk. Deactivate now that meta children\n\t\t\t\t\t// have been notified.\n\t\t\t\t\tthis._deactivate(/* skipStatusUpdate */ true);\n\t\t\t\t\t// TEARDOWN is a hard reset — unconditionally \"sentinel\",\n\t\t\t\t\t// even if the node was previously completed/errored.\n\t\t\t\t\tthis._status = \"sentinel\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst base: Messages =\n\t\t\tabortedAt >= 0\n\t\t\t\t? ((rewritten ?? (messages.slice(0, abortedAt) as Messages)) as Messages)\n\t\t\t\t: (rewritten ?? messages);\n\t\treturn equalsError != null ? { finalMessages: base, equalsError } : { finalMessages: base };\n\t}\n\n\tprivate _deliverToSinks = (messages: Messages): void => {\n\t\tif (this._sinks == null) return;\n\t\tif (typeof this._sinks === \"function\") {\n\t\t\tthis._sinks(messages);\n\t\t\treturn;\n\t\t}\n\t\t// Snapshot: a sink callback may unsubscribe itself or others\n\t\t// mid-iteration. Iterating the live Set would skip not-yet-visited\n\t\t// sinks that were removed.\n\t\tconst snapshot = [...this._sinks];\n\t\tfor (const sink of snapshot) sink(messages);\n\t};\n\n\t/**\n\t * @internal Dispatch entry point that respects the per-batch emit\n\t * accumulator (Bug 2). Inside an explicit `batch()` scope, append to\n\t * `_batchPendingMessages` and register a flush hook on first append.\n\t * Outside batch — or during a drain (where `flushInProgress` is true\n\t * but `batchDepth` is 0) — dispatch synchronously through `downWithBatch`.\n\t *\n\t * Per-emit state updates (`_frameBatch`, `_updateState`) have already\n\t * happened by the time we reach here; only the **downstream delivery**\n\t * is coalesced. Cache, version, and status are visible mid-batch on\n\t * the emitting node itself.\n\t */\n\tprivate _dispatchOrAccumulate(messages: Messages): void {\n\t\tif (isExplicitlyBatching()) {\n\t\t\tif (this._batchPendingMessages === null) {\n\t\t\t\tthis._batchPendingMessages = [];\n\t\t\t\tregisterBatchFlushHook(() => this._flushBatchPending());\n\t\t\t}\n\t\t\tfor (const m of messages) this._batchPendingMessages.push(m);\n\t\t\treturn;\n\t\t}\n\t\tdownWithBatch(this._deliverToSinks, messages, this._config.tierOf);\n\t}\n\n\t/**\n\t * @internal Flushes the accumulated batch through `downWithBatch` and\n\t * clears the pending state. Idempotent — safe to call when pending is\n\t * already null or empty (e.g. on a `batch()` throw, where the hook\n\t * fires for cleanup but the drainPhase queues are wiped after).\n\t *\n\t * Critical: the accumulated batch is interleaved per-emit framings like\n\t * `[DIRTY, DATA(1), DIRTY, DATA(2)]` — non-monotone tier order. We must\n\t * re-frame to sort by tier before handing to `downWithBatch`, which\n\t * assumes pre-sorted input. `_frameBatch` also handles the synthetic\n\t * DIRTY prepend rule (no-op here — `hasDirty` is true since each\n\t * accumulated emit already carries its own DIRTY prefix).\n\t */\n\tprivate _flushBatchPending(): void {\n\t\tconst pending = this._batchPendingMessages;\n\t\tif (pending === null) return;\n\t\tthis._batchPendingMessages = null;\n\t\tif (pending.length === 0) return;\n\t\tconst framed = this._frameBatch(pending);\n\t\tdownWithBatch(this._deliverToSinks, framed, this._config.tierOf);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nconst isNodeArray = (value: unknown): value is readonly Node[] => Array.isArray(value);\nconst isNodeOptionsObject = (value: unknown): value is NodeOptions<unknown> =>\n\ttypeof value === \"object\" && value != null && !Array.isArray(value);\n\n/**\n * Creates a reactive {@link Node} — the single GraphReFly primitive (§2).\n *\n * Typical shapes:\n * - `node([])` / `node({ initial: v })` — a manual source (state node).\n * - `node(producerFn, opts)` — a producer that runs on first-subscribe.\n * - `node(deps, computeFn, opts)` — a derived / effect node.\n *\n * For value-returning computations, prefer the sugar factories in `sugar.ts`\n * (`state`, `derived`, `effect`, `producer`, `dynamicNode`), which wrap user\n * fns with `actions.emit(userFn(data))`. Calling `node()` directly gives you\n * the raw `NodeFn` contract: explicit emission via `actions`, cleanup return.\n */\nexport function node<T = unknown>(\n\tdepsOrFn?: readonly Node[] | NodeFn | NodeOptions<T>,\n\tfnOrOpts?: NodeFn | NodeOptions<T>,\n\toptsArg?: NodeOptions<T>,\n): Node<T> {\n\tconst deps: readonly Node[] = isNodeArray(depsOrFn) ? depsOrFn : [];\n\tconst fn: NodeFn | undefined =\n\t\ttypeof depsOrFn === \"function\"\n\t\t\t? depsOrFn\n\t\t\t: typeof fnOrOpts === \"function\"\n\t\t\t\t? fnOrOpts\n\t\t\t\t: undefined;\n\tlet opts: NodeOptions<T> = {};\n\tif (isNodeArray(depsOrFn)) {\n\t\topts = ((isNodeOptionsObject(fnOrOpts) ? fnOrOpts : optsArg) ?? {}) as NodeOptions<T>;\n\t} else if (isNodeOptionsObject(depsOrFn)) {\n\t\topts = depsOrFn as NodeOptions<T>;\n\t} else {\n\t\topts = ((isNodeOptionsObject(fnOrOpts) ? fnOrOpts : optsArg) ?? {}) as NodeOptions<T>;\n\t}\n\treturn new NodeImpl<T>(deps, fn, opts);\n}\n","/**\n * Sugar constructors over the raw `node()` primitive.\n *\n * Each factory wraps a user-friendly function into the canonical\n * `NodeFn = (data, actions, ctx) => cleanup | void` shape, then calls\n * `node(...)`. This is the only place `actions.emit(...)` is invoked\n * on behalf of the user — if you need finer control (multi-emission,\n * raw `actions.down` / `actions.up`, cleanup return), use the raw\n * `node()` factory from `./node.js` directly.\n *\n * See SESSION-foundation-redesign.md §8.5 + §10.6 for the rewrite.\n */\n\nimport type { NodeActions } from \"./config.js\";\nimport { RESOLVED } from \"./messages.js\";\nimport {\n\ttype FnCtx,\n\ttype Node,\n\ttype NodeFn,\n\ttype NodeFnCleanup,\n\tNodeImpl,\n\ttype NodeOptions,\n\tnode,\n} from \"./node.js\";\n\n// ---------------------------------------------------------------------------\n// Shared sentinel guard\n// ---------------------------------------------------------------------------\n\n/**\n * Returns `true` when fn should be suppressed (RESOLVED emitted instead).\n *\n * Fires when `allowPartial` is `false` and any dep has never delivered DATA:\n * `data[i]` absent this wave AND `ctx.prevData[i] === undefined`.\n *\n * `undefined` is the protocol-reserved \"never sent DATA\" sentinel. `null` is\n * a valid DATA value and will NOT trigger the guard.\n */\nfunction sentinelGuard(\n\tbatchData: readonly (readonly unknown[] | undefined)[],\n\tctx: FnCtx,\n\tallowPartial: boolean,\n): boolean {\n\tif (allowPartial) return false;\n\treturn batchData.some(\n\t\t(batch, i) => !(batch != null && batch.length > 0) && ctx.prevData[i] === undefined,\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// state — manual source with an optional initial value\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a manual source node. Drive it with `state.emit(v)` (framed,\n * diamond-safe) or `state.down([[DATA, v]])` (raw compat path).\n *\n * @param initial - Starting cached value. Pass `undefined` or `null`\n * explicitly to cache that value; omit to leave the node in `\"sentinel\"`.\n * @param opts - Optional {@link NodeOptions} (excluding `initial`).\n */\nexport function state<T>(initial: T, opts?: Omit<NodeOptions<T>, \"initial\">): Node<T> {\n\treturn node<T>([], { ...opts, initial });\n}\n\n// ---------------------------------------------------------------------------\n// producer — no-deps source with a compute body\n// ---------------------------------------------------------------------------\n\n/**\n * User-level producer compute: runs once on first-subscriber activation.\n * Receives `actions` for imperative emission and `ctx` for FnCtx (typically\n * only `store` is useful on a producer — no deps means `prevData` and\n * `terminalDeps` are empty).\n */\nexport type ProducerFn = (\n\tactions: NodeActions,\n\tctx: FnCtx,\n\t// biome-ignore lint/suspicious/noConfusingVoidType: matches NodeFn — see its JSDoc.\n) => NodeFnCleanup | void;\n\n/**\n * Creates a producer node with no deps; `fn` runs once when the first\n * subscriber connects. Return a cleanup function (`() => void`) or\n * `{ deactivation: () => void }` to register teardown.\n *\n * @example\n * ```ts\n * const ticker = producer((actions) => {\n * const id = setInterval(() => actions.emit(Date.now()), 1000);\n * return () => clearInterval(id);\n * });\n * ```\n */\nexport function producer<T = unknown>(fn: ProducerFn, opts?: NodeOptions<T>): Node<T> {\n\tconst wrapped: NodeFn = (_data, actions, ctx) => fn(actions, ctx) ?? undefined;\n\treturn node<T>(wrapped, { describeKind: \"producer\", ...opts });\n}\n\n// ---------------------------------------------------------------------------\n// derived — dep-driven pure compute\n// ---------------------------------------------------------------------------\n\n/**\n * User-level derived compute: receives the latest DATA from each dep and\n * returns the new value. The sugar wraps it with `actions.emit(fn(...))`\n * so the return value flows through the framed emit pipeline.\n *\n * For derived nodes that need to inspect `ctx.prevData` / `ctx.terminalDeps`\n * / `ctx.store`, accept the optional second parameter.\n */\nexport type DerivedFn<T> = (data: readonly unknown[], ctx: FnCtx) => T | undefined | null;\n\n/**\n * Creates a derived node that computes **one output per wave** from the latest\n * value of each dependency — **snapshot / combine semantics**.\n *\n * `fn` receives one scalar per dep (the last DATA value seen this wave, or the\n * prior-wave value as fallback). It is called once per settled wave and emits\n * a single value via `actions.emit`. The equals check then suppresses the\n * emission as `RESOLVED` if the output has not changed.\n *\n * **Not for streaming one-to-one transforms.** If each DATA value in a batch\n * must produce a corresponding output (e.g. transforming every item emitted by\n * `fromIter` individually), use {@link map} or raw `node()` with full batch\n * iteration instead. `derived` only sees the *last* value per dep when a batch\n * carries multiple DATAs.\n *\n * @example\n * ```ts\n * const a = state(1);\n * const b = derived([a], ([x]) => (x as number) * 2);\n * ```\n */\nexport function derived<T = unknown>(\n\tdeps: readonly Node[],\n\tfn: DerivedFn<T>,\n\topts?: NodeOptions<T> & { partial?: boolean },\n): Node<T> {\n\tconst allowPartial = opts?.partial ?? false;\n\tconst wrapped: NodeFn = (batchData, actions, ctx) => {\n\t\t// Sentinel guard: if any dep has never sent DATA, emit RESOLVED.\n\t\t// Uses ctx.prevData[i] === undefined (the \"never sent\" sentinel).\n\t\t// null is valid DATA and won't trigger this. Skipped when partial:true.\n\t\tif (sentinelGuard(batchData, ctx, allowPartial)) {\n\t\t\tactions.down([[RESOLVED]]);\n\t\t\treturn undefined;\n\t\t}\n\t\t// Unwrap batch-per-dep to single latest scalar per dep.\n\t\t// Batch non-null+non-empty → take last value from this wave;\n\t\t// otherwise fall back to ctx.prevData[i] (last value from prior wave).\n\t\t// undefined means \"never sent DATA\" — sentinelGuard already blocks this\n\t\t// fn when partial:false and any dep is unset, so partial:true callers\n\t\t// receive undefined for uninitiated deps (same as JS convention).\n\t\tconst data = batchData.map((batch, i) =>\n\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t);\n\t\tactions.emit(fn(data, ctx));\n\t\treturn undefined;\n\t};\n\treturn node<T>(deps, wrapped, { describeKind: \"derived\", ...opts });\n}\n\n// ---------------------------------------------------------------------------\n// effect — dep-driven side effect, no auto-emit\n// ---------------------------------------------------------------------------\n\n/**\n * User-level effect compute: fires when deps settle. Return value is NOT\n * auto-emitted — use `actions.emit(v)` / `actions.down(msgs)` explicitly if\n * the effect also wants to produce downstream messages. Return a cleanup\n * function or `{ deactivation }` to register teardown.\n */\nexport type EffectFn = (\n\tdata: readonly unknown[],\n\tactions: NodeActions,\n\tctx: FnCtx,\n\t// biome-ignore lint/suspicious/noConfusingVoidType: matches NodeFn — see its JSDoc.\n) => NodeFnCleanup | void;\n\n/**\n * Runs a side-effect when deps settle. Return value is not auto-emitted.\n *\n * @example\n * ```ts\n * effect([source], ([v]) => {\n * console.log(v);\n * });\n * ```\n */\nexport function effect(\n\tdeps: readonly Node[],\n\tfn: EffectFn,\n\topts?: NodeOptions<unknown> & { partial?: boolean },\n): Node<unknown> {\n\tconst allowPartial = opts?.partial ?? false;\n\tconst wrapped: NodeFn = (batchData, actions, ctx) => {\n\t\t// Sentinel guard: hold effect until all deps have initialised.\n\t\t// Matches pre-wave2 framework gate behaviour. Use partial:true to allow\n\t\t// the effect to fire before all deps have delivered their first value.\n\t\tif (sentinelGuard(batchData, ctx, allowPartial)) {\n\t\t\tactions.down([[RESOLVED]]);\n\t\t\treturn undefined;\n\t\t}\n\t\tconst data = batchData.map((batch, i) =>\n\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t);\n\t\treturn fn(data, actions, ctx) ?? undefined;\n\t};\n\treturn node(deps, wrapped, { describeKind: \"effect\", ...opts });\n}\n\n// ---------------------------------------------------------------------------\n// dynamicNode — track-proxy wrapper over `derived`\n// ---------------------------------------------------------------------------\n\n/**\n * Proxy handed to a {@link DynamicFn}. `track(dep)` returns the dep's\n * latest DATA payload, as delivered through the protocol. Reading from\n * `track` does NOT bypass the message protocol — it reads the internal\n * `DepRecord.prevData` (the stable end-of-previous-wave value) that\n * `_onDepMessage` already populated. If a dep has not yet sent DATA,\n * `track` returns `undefined`.\n */\nexport type TrackFn = (dep: Node) => unknown;\n\n/** User-level dynamicNode compute. */\nexport type DynamicFn<T> = (track: TrackFn, ctx: FnCtx) => T | undefined | null;\n\n/**\n * Sugar over `derived(...)` that exposes dep values via a `track(dep)`\n * proxy instead of positional `data[i]`. All declared `allDeps` participate\n * in wave tracking, so the first fn run waits for every dep to settle.\n * Unused deps that update just re-run fn; `equals` absorbs unchanged\n * outputs as RESOLVED.\n *\n * P3-compliant: `track(dep)` reads from the framework-managed\n * `DepRecord.prevData` populated by the protocol, never from\n * `dep.cache`.\n *\n * @example\n * ```ts\n * const a = state(1);\n * const b = state(10);\n * const sum = dynamicNode([a, b], (track) => (track(a) as number) + (track(b) as number));\n * ```\n */\nexport function dynamicNode<T = unknown>(\n\tallDeps: readonly Node[],\n\tfn: DynamicFn<T>,\n\topts?: NodeOptions<T> & { partial?: boolean },\n): Node<T> {\n\tconst depIndex = new Map<Node, number>();\n\tallDeps.forEach((d, i) => {\n\t\tdepIndex.set(d, i);\n\t});\n\treturn derived<T>(\n\t\tallDeps,\n\t\t// data[i] is already sugar-unwrapped to a scalar by derived()'s wrapper.\n\t\t(data, ctx) => {\n\t\t\tconst track: TrackFn = (dep) => {\n\t\t\t\tconst i = depIndex.get(dep);\n\t\t\t\tif (i == null) {\n\t\t\t\t\tthrow new Error(`dynamicNode: untracked dep \"${dep.name ?? \"<unnamed>\"}\"`);\n\t\t\t\t}\n\t\t\t\treturn data[i];\n\t\t\t};\n\t\t\treturn fn(track, ctx);\n\t\t},\n\t\topts,\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// pipe — left-to-right operator composition\n// ---------------------------------------------------------------------------\n// autoTrackNode — runtime dep discovery (Jotai/signals compat)\n// ---------------------------------------------------------------------------\n\n/**\n * Like {@link dynamicNode} but deps are discovered at runtime via `track()`\n * calls — no upfront `allDeps` array needed. Designed for pull-based compat\n * layers (Jotai atoms, TC39 Signals) where deps are unknown until fn runs.\n *\n * **Two-phase discovery:**\n * 1. fn runs. Each `track(dep)` for an unknown dep: subscribes immediately\n * via `_addDep`, returns `dep.cache` as a stub (P3 boundary exception).\n * Result is discarded (discovery run).\n * 2. New deps settle (DATA from subscribe handshake). Wave machinery\n * re-triggers fn. `track(dep)` now returns protocol-delivered `data[i]`.\n * If MORE unknown deps appear, repeat step 1.\n * 3. Converges when no new deps found → real run → `actions.emit(result)`.\n *\n * P3 violation is limited to discovery runs. Once all deps are known,\n * subsequent waves use protocol-delivered values exclusively.\n *\n * Re-entrance safety: `_addDep` subscribes immediately. If the dep delivers\n * DATA synchronously during fn execution, `_execFn`'s re-entrance guard\n * defers the re-run to after the current fn returns.\n *\n * @param opts - Optional {@link AutoTrackOptions}. Pass `{ partial: true }` to\n * allow fn to run before all known deps have delivered their first value\n * (useful for optional/secondary deps).\n *\n * @example\n * ```ts\n * const a = state(1), b = state(2);\n * const sum = autoTrackNode((track) => track(a) + track(b));\n * // deps [a, b] discovered automatically on first run\n * ```\n */\n/**\n * Options for {@link autoTrackNode}.\n */\nexport interface AutoTrackOptions<T> extends NodeOptions<T> {\n\t/**\n\t * When `true`, fn may run before all known deps have delivered their first\n\t * DATA. Unknown deps return `undefined` via `track()`, which the fn must\n\t * handle explicitly. Useful when some deps are \"nice-to-have\" — e.g. a\n\t * primary computation should continue while a secondary dep is still\n\t * initialising.\n\t *\n\t * When `false` (default), fn is held until every known dep has delivered at\n\t * least one DATA value — a RESOLVED is emitted for the wave instead.\n\t * This matches `derived()` semantics and is the correct default for\n\t * pull-based compat layers (Signals, Jotai) where all deps must be\n\t * initialised before the computation is meaningful.\n\t *\n\t * @default false\n\t */\n\tpartial?: boolean;\n}\n\nexport function autoTrackNode<T = unknown>(\n\tfn: (track: TrackFn, ctx: FnCtx) => T | undefined | null,\n\topts?: AutoTrackOptions<T>,\n): Node<T> {\n\tlet implRef: NodeImpl<T>;\n\tconst depIndexMap = new Map<Node, number>();\n\tconst allowPartial = opts?.partial ?? false;\n\n\tconst wrappedFn: NodeFn = (batchData, actions, ctx) => {\n\t\tlet foundNew = false;\n\t\tconst track: TrackFn = (dep) => {\n\t\t\tconst idx = depIndexMap.get(dep);\n\t\t\tif (idx !== undefined) {\n\t\t\t\t// Known dep — return latest protocol-delivered value.\n\t\t\t\t// batch non-null+non-empty → latest from this wave;\n\t\t\t\t// otherwise fall back to ctx.prevData (last known value).\n\t\t\t\tif (idx < batchData.length) {\n\t\t\t\t\tconst batch = batchData[idx];\n\t\t\t\t\tif (batch != null && batch.length > 0) return batch.at(-1);\n\t\t\t\t\treturn ctx.prevData[idx];\n\t\t\t\t}\n\t\t\t\treturn dep.cache;\n\t\t\t}\n\t\t\t// Unknown dep — discovery phase.\n\t\t\tfoundNew = true;\n\t\t\tconst newIdx = implRef._addDep(dep);\n\t\t\tdepIndexMap.set(dep, newIdx);\n\t\t\treturn dep.cache; // P3 boundary exception (discovery stub)\n\t\t};\n\n\t\t// Sentinel guard (skipped when partial:true): if any known dep has never\n\t\t// delivered DATA (no DATA this wave AND ctx.prevData[idx] === undefined), emit RESOLVED\n\t\t// and defer. Mirrors derived()'s guard for the same sequential-handshake\n\t\t// scenario: when a node re-activates outside a batch and dep A delivers\n\t\t// synchronously before dep B is even subscribed, this holds fn until all\n\t\t// known deps have initialised rather than running with B=undefined.\n\t\t// Uses ctx.prevData[idx] === undefined — the protocol sentinel for\n\t\t// \"dep never sent DATA\". null is valid DATA and won't trigger this.\n\t\t// Only active when depIndexMap is non-empty (initial discovery runs are\n\t\t// unaffected) and when partial:false (default).\n\t\tif (!allowPartial && depIndexMap.size > 0) {\n\t\t\tfor (const [, idx] of depIndexMap) {\n\t\t\t\tif (idx < batchData.length) {\n\t\t\t\t\tconst batch = batchData[idx];\n\t\t\t\t\tif (!(batch != null && batch.length > 0) && ctx.prevData[idx] === undefined) {\n\t\t\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = fn(track, ctx);\n\t\t\tif (!foundNew) {\n\t\t\t\t// Real run — all deps known, protocol-delivered values.\n\t\t\t\tactions.emit(result);\n\t\t\t\t// Clear any stale discovery error from a prior run.\n\t\t\t\tif (ctx.store.__autoTrackLastDiscoveryError != null) {\n\t\t\t\t\tdelete ctx.store.__autoTrackLastDiscoveryError;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Discovery run — result discarded. New deps are subscribed via\n\t\t\t// _addDep. Their DATA delivery triggers _maybeRunFnOnSettlement\n\t\t\t// via the _pendingRerun mechanism, which will re-call fn.\n\t\t} catch (err) {\n\t\t\tif (!foundNew) throw err;\n\t\t\t// Discovery run threw — most likely a stale `.cache` read (P3\n\t\t\t// boundary exception), which the protocol-delivered retry will\n\t\t\t// not hit. Preserve the error on `ctx.store` for inspection; if\n\t\t\t// the retry succeeds, the flag is cleared above. If fn has a\n\t\t\t// real bug unrelated to cache, the non-discovery retry will\n\t\t\t// re-throw it out of `_execFn`.\n\t\t\tctx.store.__autoTrackLastDiscoveryError = err;\n\t\t}\n\t\treturn undefined;\n\t};\n\n\timplRef = new NodeImpl<T>([], wrappedFn, {\n\t\tdescribeKind: \"derived\",\n\t\t...opts,\n\t});\n\treturn implRef;\n}\n\n// ---------------------------------------------------------------------------\n// pipe — left-to-right operator composition\n// ---------------------------------------------------------------------------\n\n/** Unary operator used by {@link pipe}. */\nexport type PipeOperator = (n: Node) => Node;\n\n/**\n * Composes unary operators left-to-right; returns the final node.\n *\n * @example\n * ```ts\n * const out = pipe(\n * source,\n * (n) => map(n, (x) => x + 1),\n * (n) => filter(n, (x) => x > 0),\n * );\n * ```\n */\nexport function pipe(source: Node, ...ops: PipeOperator[]): Node {\n\tlet current = source;\n\tfor (const op of ops) current = op(current);\n\treturn current;\n}\n","/**\n * Backoff strategies for {@link retry} (roadmap §3.1). Delays are in **nanoseconds**.\n *\n * Convention: all graphrefly-ts timestamps and durations use nanoseconds (`_ns` suffix).\n * 1 second = 1_000_000_000 ns, 1 ms = 1_000_000 ns.\n */\n\nexport const NS_PER_MS = 1_000_000;\nexport const NS_PER_SEC = 1_000_000_000;\n\nexport type JitterMode = \"none\" | \"full\" | \"equal\";\n\nexport type BackoffPreset =\n\t| \"constant\"\n\t| \"linear\"\n\t| \"exponential\"\n\t| \"fibonacci\"\n\t| \"decorrelatedJitter\";\n\n/** `(attempt, error?, previousDelayNs?) => delayNs | null` — `null` means zero delay. */\nexport type BackoffStrategy = (\n\tattempt: number,\n\terror?: unknown,\n\tprevDelayNs?: number | null,\n) => number | null;\n\nfunction clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nfunction applyJitter(delay: number, jitter: JitterMode): number {\n\tif (jitter === \"none\") return delay;\n\tif (jitter === \"full\") return Math.random() * delay;\n\treturn delay / 2 + Math.random() * (delay / 2);\n}\n\nfunction randomBetween(min: number, max: number): number {\n\treturn min + Math.random() * (max - min);\n}\n\n/**\n * Builds a strategy that always returns the same delay in nanoseconds.\n *\n * @param delayNs - Non-negative delay in nanoseconds; values below zero are clamped to zero.\n * @returns `BackoffStrategy` for use with {@link retry} or custom timers.\n *\n * @example\n * ```ts\n * import { constant, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, { count: 3, backoff: constant(0.25 * NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function constant(delayNs: number): BackoffStrategy {\n\tconst safe = clampNonNegative(delayNs);\n\treturn () => safe;\n}\n\n/**\n * Builds linear backoff: `baseNs + stepNs * attempt` (`stepNs` defaults to `baseNs`).\n *\n * @param baseNs - Base delay in nanoseconds (clamped non-negative).\n * @param stepNs - Added per retry attempt in nanoseconds (clamped non-negative).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { linear, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * // Attempt 0 → 1 s, attempt 1 → 2 s, attempt 2 → 3 s …\n * const out = retry(source, { count: 4, backoff: linear(NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function linear(baseNs: number, stepNs?: number): BackoffStrategy {\n\tconst safeBase = clampNonNegative(baseNs);\n\tconst safeStep = stepNs === undefined ? safeBase : clampNonNegative(stepNs);\n\treturn (attempt: number) => safeBase + safeStep * Math.max(0, attempt);\n}\n\nexport type ExponentialBackoffOptions = {\n\tbaseNs?: number;\n\tfactor?: number;\n\tmaxDelayNs?: number;\n\tjitter?: JitterMode;\n};\n\n/**\n * Builds exponential backoff in nanoseconds, capped by `maxDelayNs`, with optional jitter.\n *\n * @param options - Base, factor, cap, and jitter mode.\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @remarks\n * **Jitter:** `\"full\"` spreads delay across `[0, delay]`; `\"equal\"` uses `[delay/2, delay]`.\n *\n * @example\n * ```ts\n * import { exponential, retry, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * // 100 ms → 200 ms → 400 ms … capped at 30 s, with full jitter\n * const out = retry(source, {\n * count: 5,\n * backoff: exponential({ baseNs: 100 * NS_PER_SEC / 1000, jitter: \"full\" }),\n * });\n * ```\n *\n * @category extra\n */\nexport function exponential(options?: ExponentialBackoffOptions): BackoffStrategy {\n\tconst baseNs = clampNonNegative(options?.baseNs ?? 100 * NS_PER_MS);\n\tconst factor = options?.factor !== undefined && options.factor < 1 ? 1 : (options?.factor ?? 2);\n\tconst maxDelayNs = clampNonNegative(options?.maxDelayNs ?? 30 * NS_PER_SEC);\n\tconst jitter = options?.jitter ?? \"none\";\n\n\treturn (attempt: number) => {\n\t\tlet delay: number;\n\t\tif (baseNs === 0) {\n\t\t\tdelay = 0;\n\t\t} else if (factor === 1) {\n\t\t\tdelay = baseNs;\n\t\t} else {\n\t\t\tconst capRatio = maxDelayNs / baseNs;\n\t\t\tlet growth = 1;\n\t\t\tfor (let i = 0; i < Math.max(0, attempt); i++) {\n\t\t\t\tif (growth >= capRatio) {\n\t\t\t\t\tgrowth = capRatio;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tgrowth *= factor;\n\t\t\t}\n\t\t\tdelay = baseNs * growth;\n\t\t\tif (delay > maxDelayNs) delay = maxDelayNs;\n\t\t}\n\t\treturn applyJitter(delay, jitter);\n\t};\n}\n\n/**\n * Builds Fibonacci-scaled delays: `1, 2, 3, 5, … × baseNs`, capped at `maxDelayNs`.\n *\n * @param baseNs - Multiplier applied to the Fibonacci unit (default `100ms` in nanoseconds).\n * @param maxDelayNs - Upper bound in nanoseconds (default `30s`).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { fibonacci, retry, NS_PER_MS } from \"@graphrefly/graphrefly-ts\";\n *\n * // Delays: 100 ms, 200 ms, 300 ms, 500 ms, 800 ms … (× 100 ms base)\n * const out = retry(source, { count: 5, backoff: fibonacci(100 * NS_PER_MS) });\n * ```\n *\n * @category extra\n */\nexport function fibonacci(baseNs = 100 * NS_PER_MS, maxDelayNs = 30 * NS_PER_SEC): BackoffStrategy {\n\tconst safeBase = clampNonNegative(baseNs);\n\tconst safeMax = clampNonNegative(maxDelayNs);\n\n\tfunction fibUnit(attempt: number): number {\n\t\tif (attempt <= 0) return 1;\n\t\tlet prev = 1;\n\t\tlet cur = 2;\n\t\tfor (let i = 1; i < attempt; i++) {\n\t\t\tconst next = prev + cur;\n\t\t\tprev = cur;\n\t\t\tcur = next;\n\t\t}\n\t\treturn cur;\n\t}\n\n\treturn (attempt: number) => {\n\t\tconst raw = fibUnit(attempt) * safeBase;\n\t\treturn raw <= safeMax ? raw : safeMax;\n\t};\n}\n\n/**\n * Decorrelated jitter (AWS-recommended): `random(baseNs, min(maxNs, lastDelay * 3))`.\n *\n * Stateless — uses `prevDelayNs` (passed by the consumer) instead of closure state.\n * Safe to share across concurrent retry sequences.\n *\n * @param baseNs - Floor of the random range (default `100ms` in nanoseconds).\n * @param maxNs - Ceiling cap (default `30s` in nanoseconds).\n * @returns `BackoffStrategy` for {@link retry}.\n *\n * @example\n * ```ts\n * import { decorrelatedJitter, retry, NS_PER_MS, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, {\n * count: 6,\n * backoff: decorrelatedJitter(100 * NS_PER_MS, 10 * NS_PER_SEC),\n * });\n * ```\n *\n * @category extra\n */\nexport function decorrelatedJitter(\n\tbaseNs = 100 * NS_PER_MS,\n\tmaxNs = 30 * NS_PER_SEC,\n): BackoffStrategy {\n\treturn (_attempt, _error, prevDelayNs) => {\n\t\tconst last = prevDelayNs ?? baseNs;\n\t\tconst ceiling = Math.min(maxNs, last * 3);\n\t\treturn randomBetween(baseNs, ceiling);\n\t};\n}\n\n/**\n * Decorator that caps any strategy at `maxAttempts`. Returns `null` (stop retrying) after the cap.\n *\n * @param strategy - Inner strategy to wrap.\n * @param maxAttempts - Maximum number of attempts (inclusive).\n * @returns Wrapped `BackoffStrategy`.\n *\n * @example\n * ```ts\n * import { withMaxAttempts, exponential } from \"@graphrefly/graphrefly-ts\";\n *\n * const capped = withMaxAttempts(exponential(), 3);\n * capped(3); // null — no more retries beyond attempt 3\n * ```\n *\n * @category extra\n */\nexport function withMaxAttempts(strategy: BackoffStrategy, maxAttempts: number): BackoffStrategy {\n\treturn (attempt, error, prevDelayNs) => {\n\t\tif (attempt >= maxAttempts) return null;\n\t\treturn strategy(attempt, error, prevDelayNs);\n\t};\n}\n\n/**\n * Maps a preset name to a concrete {@link BackoffStrategy} with library-default parameters.\n *\n * @param name - One of `constant`, `linear`, `exponential`, `fibonacci`, or `decorrelatedJitter`.\n * @returns Configured strategy with default parameters.\n * @throws Error when `name` is not a known preset.\n *\n * @example\n * ```ts\n * import { resolveBackoffPreset, retry } from \"@graphrefly/graphrefly-ts\";\n *\n * const out = retry(source, { count: 3, backoff: resolveBackoffPreset(\"exponential\") });\n * // Equivalent to retry(source, { count: 3, backoff: exponential() })\n * ```\n *\n * @category extra\n */\nexport function resolveBackoffPreset(name: BackoffPreset): BackoffStrategy {\n\tif (name === \"constant\") return constant(1 * NS_PER_SEC);\n\tif (name === \"linear\") return linear(1 * NS_PER_SEC);\n\tif (name === \"exponential\") return exponential();\n\tif (name === \"fibonacci\") return fibonacci();\n\tif (name === \"decorrelatedJitter\") return decorrelatedJitter();\n\tthrow new Error(\n\t\t`Unknown backoff preset: \"${String(name)}\". Use one of: constant, linear, exponential, fibonacci, decorrelatedJitter`,\n\t);\n}\n","/**\n * External-register helpers — the common `register({emit, error, complete})`\n * contract shared by webhook, MCP, syslog, StatsD, OTel and other callback-\n * based integrations. Absorbs the `active` flag that every such adapter needs\n * to guard against emits after teardown (§5.10 boundary pattern).\n *\n * Two shapes:\n *\n * - {@link externalProducer} — single channel. Lazy activation: the register\n * fn runs when the node gains its first subscriber; its returned cleanup\n * runs on deactivation.\n *\n * - {@link externalBundle} — multiple named channels. Eager activation: the\n * register fn runs at bundle construction time so externally-owned servers\n * (HTTP endpoints, UDP sockets) start accepting traffic immediately. A\n * shared refcount fires the returned cleanup once every channel has fully\n * torn down.\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { COMPLETE, DATA, ERROR } from \"../core/messages.js\";\nimport type { Node, NodeOptions } from \"../core/node.js\";\nimport { producer } from \"../core/sugar.js\";\n\ntype ExtraOpts = Omit<NodeOptions<unknown>, \"describeKind\">;\n\nfunction sourceOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\n\n/**\n * Standard emit-triad passed to a single-channel external registrar.\n *\n * Post-teardown calls on any of these are automatically no-ops — the\n * registrar does not need its own guard flag.\n *\n * @category extra\n */\nexport type EmitTriad<T> = {\n\t/** Emit a value as `DATA`. */\n\temit: (value: T) => void;\n\t/** Terminate with `ERROR`. Subsequent `emit` / `error` / `complete` are ignored. */\n\terror: (err: unknown) => void;\n\t/** Terminate with `COMPLETE`. Subsequent `emit` / `error` / `complete` are ignored. */\n\tcomplete: () => void;\n};\n\n/**\n * Multi-channel emit bundle. Each declared channel name maps to an emit fn;\n * `error` and `complete` terminate every channel atomically.\n *\n * @category extra\n */\nexport type BundleTriad<TChannels extends Record<string, unknown>> = {\n\t[K in keyof TChannels]: (value: TChannels[K]) => void;\n} & {\n\t/** Terminate every channel with `ERROR`. */\n\terror: (err: unknown) => void;\n\t/** Terminate every channel with `COMPLETE`. */\n\tcomplete: () => void;\n};\n\n/**\n * Generic external registrator contract. The caller installs handlers into a\n * third-party library / framework / server and optionally returns a cleanup\n * callback. Returning `undefined` / `void` is equivalent to a no-op cleanup.\n *\n * @category extra\n */\nexport type ExternalRegister<H> = (handlers: H) => (() => void) | undefined;\n\n/**\n * Wraps a callback-style external integration as a reactive source.\n *\n * The registrar installs the supplied `emit` / `error` / `complete` handlers\n * into the external SDK; post-teardown calls are silently dropped. Synchronous\n * exceptions thrown by the registrar surface as terminal `ERROR`.\n *\n * @param register - Installs handlers. Optionally returns a cleanup fn.\n * @param opts - Node options (name, equals, resubscribable, ...).\n *\n * @example\n * ```ts\n * import { externalProducer } from \"@graphrefly/graphrefly-ts\";\n *\n * const hook$ = externalProducer<Payload>(({ emit, error }) => {\n * const id = transport.onMessage((raw) => {\n * try { emit(parse(raw)); } catch (e) { error(e); }\n * });\n * return () => transport.off(id);\n * });\n * ```\n *\n * @category extra\n */\nexport function externalProducer<T = unknown>(\n\tregister: ExternalRegister<EmitTriad<T>>,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet active = true;\n\t\tconst triad: EmitTriad<T> = {\n\t\t\temit(value) {\n\t\t\t\tif (!active) return;\n\t\t\t\ta.emit(value);\n\t\t\t},\n\t\t\terror(err) {\n\t\t\t\tif (!active) return;\n\t\t\t\tactive = false;\n\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t},\n\t\t\tcomplete() {\n\t\t\t\tif (!active) return;\n\t\t\t\tactive = false;\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t},\n\t\t};\n\t\tlet cleanup: (() => void) | undefined;\n\t\ttry {\n\t\t\tconst ret = register(triad);\n\t\t\tcleanup = typeof ret === \"function\" ? ret : undefined;\n\t\t} catch (err) {\n\t\t\ttriad.error(err);\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t}\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\ttry {\n\t\t\t\tcleanup?.();\n\t\t\t} catch {\n\t\t\t\t/* registrar cleanup failure is not a reactive signal */\n\t\t\t}\n\t\t};\n\t}, sourceOpts(opts));\n}\n\n/**\n * Options for {@link externalBundle}.\n *\n * @category extra\n */\nexport type ExternalBundleOptions<TChannels extends Record<string, unknown>> = {\n\t/** Base name prefix for channel nodes; each node is named `${name}::${channel}`. */\n\tname?: string;\n\t/** Per-channel node options (equals, resubscribable, ...). */\n\tchannelOpts?: { [K in keyof TChannels]?: ExtraOpts };\n};\n\n/**\n * Multi-channel variant — one `Node<T>` per named channel, sharing a single\n * registrar. Activation is eager: the registrar runs at construction time so\n * externally-owned servers (HTTP, UDP, queue consumers) can start accepting\n * traffic immediately. The returned cleanup fires once every channel has been\n * subscribed and then fully deactivated (refcount-on-teardown).\n *\n * Any call to `error` or `complete` propagates to every channel atomically.\n *\n * @param register - Installs handlers for each channel plus shared error/complete.\n * @param channels - Ordered channel names; determines the returned object shape.\n * @param opts - Optional name prefix and per-channel node options.\n *\n * @example\n * ```ts\n * import { externalBundle } from \"@graphrefly/graphrefly-ts\";\n *\n * type OTelChannels = { traces: Span; metrics: Metric; logs: LogRec };\n * const otel = externalBundle<OTelChannels>(\n * ({ traces, metrics, logs, error }) => {\n * app.post(\"/v1/traces\", (req, res) => { traces(req.body); res.sendStatus(200); });\n * app.post(\"/v1/metrics\", (req, res) => { metrics(req.body); res.sendStatus(200); });\n * app.post(\"/v1/logs\", (req, res) => { logs(req.body); res.sendStatus(200); });\n * server.on(\"error\", error);\n * return () => server.close();\n * },\n * [\"traces\", \"metrics\", \"logs\"],\n * );\n * otel.traces.subscribe(...);\n * ```\n *\n * @category extra\n */\nexport function externalBundle<TChannels extends Record<string, unknown>>(\n\tregister: ExternalRegister<BundleTriad<TChannels>>,\n\tchannels: readonly (keyof TChannels & string)[],\n\topts?: ExternalBundleOptions<TChannels>,\n): { [K in keyof TChannels]: Node<TChannels[K]> } & { dispose(): void } {\n\tlet active = true;\n\tlet cleanup: (() => void) | undefined;\n\tlet activatedCount = 0;\n\tlet teardownCount = 0;\n\n\tconst nodes = {} as { [K in keyof TChannels]: Node<TChannels[K]> };\n\tconst channelNodes: Array<Node<unknown>> = [];\n\n\tconst finishCleanup = () => {\n\t\tconst fn = cleanup;\n\t\tcleanup = undefined;\n\t\ttry {\n\t\t\tfn?.();\n\t\t} catch {\n\t\t\t/* registrar cleanup failure is not a reactive signal */\n\t\t}\n\t};\n\n\tfor (const ch of channels) {\n\t\tconst name = opts?.name ? `${opts.name}::${ch}` : ch;\n\t\tconst chOpts = opts?.channelOpts?.[ch];\n\t\tconst n = producer<TChannels[typeof ch]>(\n\t\t\t(_a) => {\n\t\t\t\tactivatedCount++;\n\t\t\t\treturn () => {\n\t\t\t\t\tteardownCount++;\n\t\t\t\t\t// Cleanup fires once every channel has activated at least once\n\t\t\t\t\t// and then deactivated. Channels that never subscribe do not\n\t\t\t\t\t// gate cleanup — use the explicit `.dispose()` method for\n\t\t\t\t\t// unconditional teardown.\n\t\t\t\t\tif (\n\t\t\t\t\t\tactivatedCount > 0 &&\n\t\t\t\t\t\tteardownCount >= activatedCount &&\n\t\t\t\t\t\tteardownCount >= channels.length\n\t\t\t\t\t) {\n\t\t\t\t\t\tfinishCleanup();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\t\t\tsourceOpts({ ...chOpts, name }),\n\t\t);\n\t\tnodes[ch as keyof TChannels] = n as Node<TChannels[typeof ch]>;\n\t\tchannelNodes.push(n as Node<unknown>);\n\t}\n\n\tconst bundle = {} as BundleTriad<TChannels>;\n\tfor (const ch of channels) {\n\t\t(bundle as Record<string, unknown>)[ch] = (value: unknown) => {\n\t\t\tif (!active) return;\n\t\t\t(nodes[ch as keyof TChannels] as Node<unknown>).down([[DATA, value]]);\n\t\t};\n\t}\n\tbundle.error = (err: unknown) => {\n\t\tif (!active) return;\n\t\tactive = false;\n\t\tbatch(() => {\n\t\t\tfor (const n of channelNodes) n.down([[ERROR, err]]);\n\t\t});\n\t\tfinishCleanup();\n\t};\n\tbundle.complete = () => {\n\t\tif (!active) return;\n\t\tactive = false;\n\t\tbatch(() => {\n\t\t\tfor (const n of channelNodes) n.down([[COMPLETE]]);\n\t\t});\n\t\tfinishCleanup();\n\t};\n\n\t// Eager activation — register fires at construction time so externally-\n\t// owned servers can start accepting traffic immediately. Synchronous throws\n\t// propagate to the caller (no subscribers exist yet, so there is no\n\t// reactive ERROR path to deliver to). This matches the existing `fromOTel`\n\t// contract.\n\tconst ret = register(bundle);\n\tcleanup = typeof ret === \"function\" ? ret : undefined;\n\n\tconst dispose = () => {\n\t\tif (!active) return;\n\t\tactive = false;\n\t\t// Fire COMPLETE on every channel so downstream sees a clean terminal.\n\t\tbatch(() => {\n\t\t\tfor (const n of channelNodes) {\n\t\t\t\ttry {\n\t\t\t\t\tn.down([[COMPLETE]]);\n\t\t\t\t} catch {\n\t\t\t\t\t/* terminal filter / re-entrance — swallow */\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tfinishCleanup();\n\t};\n\n\treturn Object.assign(nodes, { dispose });\n}\n","/**\n * Core reactive sources, sinks, and utilities (roadmap §2.3).\n *\n * Each API returns a {@link Node} built with {@link node}, {@link producer},\n * {@link derived}, or {@link effect} — no second protocol.\n *\n * Protocol/system/ingest adapters (fromHTTP, fromWebSocket, fromKafka, etc.)\n * live in {@link ./adapters.ts}.\n */\n\nimport { existsSync, watch } from \"node:fs\";\nimport { resolve as resolvePath } from \"node:path\";\nimport { wallClockNs } from \"../core/clock.js\";\nimport { COMPLETE, DATA, DIRTY, ERROR, type Message, RESOLVED } from \"../core/messages.js\";\nimport { type Node, type NodeOptions, type NodeSink, node } from \"../core/node.js\";\nimport { producer, state } from \"../core/sugar.js\";\nimport { type CronSchedule, matchesCron, parseCron } from \"./cron.js\";\n\ntype ExtraOpts = Omit<NodeOptions<unknown>, \"describeKind\">;\n\nfunction sourceOpts<T = unknown>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\n\n/** Options for {@link fromTimer} / {@link fromPromise} / {@link fromAsyncIter}. */\nexport type AsyncSourceOpts = ExtraOpts & { signal?: AbortSignal };\n\n/**\n * Values accepted by {@link fromAny}.\n *\n * @category extra\n */\nexport type NodeInput<T> = Node<T> | PromiseLike<T> | AsyncIterable<T> | Iterable<T> | T;\n\n/** Options for {@link fromCron}. */\nexport type FromCronOptions = ExtraOpts & {\n\t/** Polling interval in ms. Default `60_000`. */\n\ttickMs?: number;\n\t/** Output format: `\"timestamp_ns\"` (default) emits wall-clock nanoseconds; `\"date\"` emits a `Date` object. */\n\toutput?: \"timestamp_ns\" | \"date\";\n};\n\n/** DOM-style event target (browser or `node:events`). */\nexport type EventTargetLike = {\n\taddEventListener(\n\t\ttype: string,\n\t\tlistener: (ev: unknown) => void,\n\t\toptions?: boolean | { capture?: boolean; passive?: boolean; once?: boolean },\n\t): void;\n\tremoveEventListener(\n\t\ttype: string,\n\t\tlistener: (ev: unknown) => void,\n\t\toptions?: boolean | { capture?: boolean; passive?: boolean; once?: boolean },\n\t): void;\n};\n\nexport type FSEventType = \"change\" | \"rename\" | \"create\" | \"delete\";\nexport type FSEvent = {\n\ttype: FSEventType;\n\tpath: string;\n\troot: string;\n\trelative_path: string;\n\tsrc_path?: string;\n\tdest_path?: string;\n\ttimestamp_ns: number;\n};\n\nexport type FromFSWatchOptions = ExtraOpts & {\n\trecursive?: boolean;\n\tdebounce?: number;\n\tinclude?: string[];\n\texclude?: string[];\n};\n\n/** @internal Shared with adapters.ts for glob matching in fromFSWatch / fromGitHook. */\nexport function escapeRegexChar(ch: string): string {\n\treturn /[\\\\^$+?.()|[\\]{}]/.test(ch) ? `\\\\${ch}` : ch;\n}\n\n/** @internal */\nexport function globToRegExp(glob: string): RegExp {\n\tlet out = \"^\";\n\tfor (let i = 0; i < glob.length; i += 1) {\n\t\tconst ch = glob[i];\n\t\tif (ch === \"*\") {\n\t\t\tconst next = glob[i + 1];\n\t\t\tif (next === \"*\") {\n\t\t\t\tout += \".*\";\n\t\t\t\ti += 1;\n\t\t\t} else {\n\t\t\t\tout += \"[^/]*\";\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tout += escapeRegexChar(ch);\n\t}\n\tout += \"$\";\n\treturn new RegExp(out);\n}\n\n/** @internal */\nexport function matchesAnyPattern(path: string, patterns: RegExp[]): boolean {\n\tfor (const pattern of patterns) {\n\t\tif (pattern.test(path)) return true;\n\t}\n\treturn false;\n}\n\nfunction wrapSubscribeHook<T>(inner: Node<T>, before: (sink: NodeSink) => void): Node<T> {\n\t// node() passthrough instead of derived([inner], ([v]) => v) — derived uses\n\t// .at(-1) and would drop intermediate values from multi-DATA batches (D1 gap).\n\tconst wrapper = node<T>(\n\t\t[inner as Node],\n\t\t(data, a) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) a.emit(v as T);\n\t\t},\n\t\t{ describeKind: \"derived\", initial: inner.cache as T },\n\t);\n\tconst origSubscribe = wrapper.subscribe.bind(wrapper);\n\t(wrapper as { subscribe: typeof wrapper.subscribe }).subscribe = (sink, actor) => {\n\t\tbefore(sink);\n\t\treturn origSubscribe(sink, actor);\n\t};\n\treturn wrapper;\n}\n\n/**\n * Builds a timer-driven source: one-shot (first tick then `COMPLETE`) or periodic (`0`, `1`, `2`, …).\n *\n * @param ms - Milliseconds before the first emission.\n * @param opts - Producer options plus optional `period` for repeating ticks and optional `signal` (`AbortSignal`) to cancel with `ERROR`.\n * @returns `Node<number>` — tick counter from `0`; teardown clears timers.\n *\n * @example\n * ```ts\n * import { fromTimer } from \"@graphrefly/graphrefly-ts\";\n *\n * fromTimer(250, { period: 1_000 });\n * ```\n *\n * @category extra\n */\nexport function fromTimer(ms: number, opts?: AsyncSourceOpts & { period?: number }): Node<number> {\n\tconst { signal, period, ...rest } = opts ?? {};\n\treturn producer<number>((a) => {\n\t\tlet done = false;\n\t\tlet count = 0;\n\t\tlet t: ReturnType<typeof setTimeout> | undefined;\n\t\tlet iv: ReturnType<typeof setInterval> | undefined;\n\t\tconst cleanup = () => {\n\t\t\tdone = true;\n\t\t\tif (t !== undefined) clearTimeout(t);\n\t\t\tif (iv !== undefined) clearInterval(iv);\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\t\tconst finish = () => {\n\t\t\tif (done) return;\n\t\t\tif (period != null) {\n\t\t\t\ta.emit(count++);\n\t\t\t\tiv = setInterval(() => {\n\t\t\t\t\tif (done) return;\n\t\t\t\t\ta.emit(count++);\n\t\t\t\t}, period);\n\t\t\t} else {\n\t\t\t\t// One-shot: mark done, emit, complete synchronously.\n\t\t\t\t// a.emit() delivers DATA to downstream synchronously before\n\t\t\t\t// COMPLETE arrives — no queueMicrotask needed.\n\t\t\t\tdone = true;\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\ta.emit(count++);\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t}\n\t\t};\n\t\tconst onAbort = () => {\n\t\t\tif (done) return;\n\t\t\tcleanup();\n\t\t\ta.down([[ERROR, signal!.reason]]);\n\t\t};\n\t\tif (signal?.aborted) {\n\t\t\tonAbort();\n\t\t\treturn;\n\t\t}\n\t\tt = setTimeout(finish, ms);\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\treturn cleanup;\n\t}, sourceOpts(rest));\n}\n\n/**\n * Polls on an interval; when the current minute matches a 5-field cron expression, emits once (see {@link parseCron}).\n *\n * @param expr - Cron string (`min hour dom month dow`).\n * @param opts - Producer options plus `tickMs` (default `60_000`) and `output` (`timestamp_ns` default, or `date` for `Date` values).\n * @returns `Node<number>` (nanosecond timestamp) or `Node<Date>` when `output: \"date\"`.\n *\n * @example\n * ```ts\n * import { fromCron } from \"@graphrefly/graphrefly-ts\";\n *\n * fromCron(\"0 9 * * 1\");\n * ```\n *\n * @category extra\n */\nexport function fromCron(expr: string, opts?: FromCronOptions & { output: \"date\" }): Node<Date>;\nexport function fromCron(expr: string, opts?: FromCronOptions): Node<number>;\nexport function fromCron(expr: string, opts?: FromCronOptions): Node<number | Date> {\n\tconst schedule: CronSchedule = parseCron(expr);\n\tconst { tickMs: tickOpt, output, ...rest } = opts ?? {};\n\tconst tickMs = tickOpt ?? 60_000;\n\tconst emitDate = output === \"date\";\n\treturn producer<number | Date>(\n\t\t(a) => {\n\t\t\tlet lastFiredKey = -1;\n\t\t\tconst check = () => {\n\t\t\t\tconst now = new Date();\n\t\t\t\tconst key =\n\t\t\t\t\tnow.getFullYear() * 100_000_000 +\n\t\t\t\t\t(now.getMonth() + 1) * 1_000_000 +\n\t\t\t\t\tnow.getDate() * 10_000 +\n\t\t\t\t\tnow.getHours() * 100 +\n\t\t\t\t\tnow.getMinutes();\n\t\t\t\tif (key !== lastFiredKey && matchesCron(schedule, now)) {\n\t\t\t\t\tlastFiredKey = key;\n\t\t\t\t\ta.emit(emitDate ? now : wallClockNs());\n\t\t\t\t}\n\t\t\t};\n\t\t\tcheck();\n\t\t\tconst id = setInterval(check, tickMs);\n\t\t\treturn () => clearInterval(id);\n\t\t},\n\t\t{ ...sourceOpts(rest), name: rest.name ?? `cron:${expr}` },\n\t);\n}\n\n/**\n * Wraps a DOM-style `addEventListener` target; each event becomes a `DATA` emission.\n *\n * @param target - Object with `addEventListener` / `removeEventListener`.\n * @param type - Event name (e.g. `\"click\"`).\n * @param opts - Producer options plus listener options (`capture`, `passive`, `once`).\n * @returns `Node<T>` — event payloads; teardown removes the listener.\n *\n * @example\n * ```ts\n * import { fromEvent } from \"@graphrefly/graphrefly-ts\";\n *\n * fromEvent(document.body, \"click\");\n * ```\n *\n * @category extra\n */\nexport function fromEvent<T = unknown>(\n\ttarget: EventTargetLike,\n\ttype: string,\n\topts?: ExtraOpts & { capture?: boolean; passive?: boolean; once?: boolean },\n): Node<T> {\n\tconst { capture, passive, once, ...rest } = opts ?? {};\n\treturn producer<T>((a) => {\n\t\tconst handler = (e: unknown) => {\n\t\t\ta.emit(e as T);\n\t\t};\n\t\tconst options = { capture, passive, once };\n\t\ttarget.addEventListener(type, handler, options);\n\t\treturn () => target.removeEventListener(type, handler, options);\n\t}, sourceOpts(rest));\n}\n\n/**\n * Watches filesystem paths and emits debounced change events.\n *\n * Uses `fs.watch` only (no polling fallback). Teardown closes all watchers.\n *\n * @category extra\n */\nexport function fromFSWatch(paths: string | string[], opts?: FromFSWatchOptions): Node<FSEvent> {\n\tconst list = Array.isArray(paths) ? paths : [paths];\n\tif (list.length === 0) {\n\t\tthrow new RangeError(\"fromFSWatch expects at least one path\");\n\t}\n\tconst { recursive = true, debounce = 100, include, exclude, ...rest } = opts ?? {};\n\tconst includePatterns = include?.map(globToRegExp) ?? [];\n\tconst excludePatterns = (exclude ?? [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\"]).map(\n\t\tglobToRegExp,\n\t);\n\treturn producer<FSEvent>((a) => {\n\t\tconst pending = new Map<string, FSEvent>();\n\t\tconst watchers: ReturnType<typeof watch>[] = [];\n\t\tlet stopped = false;\n\t\tlet terminalEmitted = false;\n\t\tlet generation = 0;\n\t\tconst closeWatchers = () => {\n\t\t\tfor (const watcher of watchers.splice(0)) watcher.close();\n\t\t};\n\t\tconst emitError = (err: unknown) => {\n\t\t\tif (terminalEmitted) return;\n\t\t\tterminalEmitted = true;\n\t\t\tstopped = true;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t\tpending.clear();\n\t\t\tcloseWatchers();\n\t\t\ta.down([[ERROR, err]]);\n\t\t};\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tconst flush = (token: number) => {\n\t\t\ttimer = undefined;\n\t\t\tif (stopped || terminalEmitted) return;\n\t\t\tif (pending.size === 0) return;\n\t\t\tconst batchMessages: Message[] = [];\n\t\t\tfor (const evt of pending.values()) batchMessages.push([DATA, evt]);\n\t\t\tpending.clear();\n\t\t\tif (stopped || terminalEmitted || token !== generation) return;\n\t\t\ta.down(batchMessages);\n\t\t};\n\t\ttry {\n\t\t\tfor (const basePath of list) {\n\t\t\t\tconst watcher = watch(\n\t\t\t\t\tbasePath,\n\t\t\t\t\t{ recursive },\n\t\t\t\t\t(eventType: \"rename\" | \"change\", fileName: string | Buffer | null) => {\n\t\t\t\t\t\tif (stopped || terminalEmitted) return;\n\t\t\t\t\t\tif (fileName == null) return;\n\t\t\t\t\t\tconst rel = String(fileName).replaceAll(\"\\\\\", \"/\");\n\t\t\t\t\t\tconst abs = resolvePath(basePath, String(fileName));\n\t\t\t\t\t\tconst normalized = abs.replaceAll(\"\\\\\", \"/\");\n\t\t\t\t\t\tconst root = resolvePath(basePath).replaceAll(\"\\\\\", \"/\");\n\t\t\t\t\t\tconst relForMatch = rel.startsWith(\"./\") ? rel.slice(2) : rel;\n\t\t\t\t\t\tconst included =\n\t\t\t\t\t\t\tincludePatterns.length === 0 ||\n\t\t\t\t\t\t\tmatchesAnyPattern(normalized, includePatterns) ||\n\t\t\t\t\t\t\tmatchesAnyPattern(relForMatch, includePatterns);\n\t\t\t\t\t\tif (!included) return;\n\t\t\t\t\t\tconst excluded =\n\t\t\t\t\t\t\tmatchesAnyPattern(normalized, excludePatterns) ||\n\t\t\t\t\t\t\tmatchesAnyPattern(relForMatch, excludePatterns);\n\t\t\t\t\t\tif (excluded) return;\n\t\t\t\t\t\tlet kind: FSEventType = \"change\";\n\t\t\t\t\t\tif (eventType === \"rename\") {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tkind = existsSync(normalized) ? \"create\" : \"delete\";\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tkind = \"rename\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpending.set(normalized, {\n\t\t\t\t\t\t\ttype: kind,\n\t\t\t\t\t\t\tpath: normalized,\n\t\t\t\t\t\t\troot,\n\t\t\t\t\t\t\trelative_path: relForMatch,\n\t\t\t\t\t\t\ttimestamp_ns: wallClockNs(),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\t\t\t\tconst token = generation;\n\t\t\t\t\t\ttimer = setTimeout(() => flush(token), debounce);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\twatcher.on(\"error\", (err) => emitError(err));\n\t\t\t\twatchers.push(watcher);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\temitError(err);\n\t\t}\n\t\treturn () => {\n\t\t\tstopped = true;\n\t\t\tgeneration += 1;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t\tcloseWatchers();\n\t\t\tpending.clear();\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/**\n * Drains a synchronous iterable; each item is `DATA`, then `COMPLETE`, or `ERROR` if iteration throws.\n *\n * @param iterable - Values to emit in order.\n * @param opts - Optional producer options.\n * @returns `Node<T>` — one emission per element.\n *\n * @example\n * ```ts\n * import { fromIter } from \"@graphrefly/graphrefly-ts\";\n *\n * fromIter([1, 2, 3]);\n * ```\n *\n * @category extra\n */\nexport function fromIter<T>(iterable: Iterable<T>, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet cancelled = false;\n\t\ttry {\n\t\t\tfor (const x of iterable) {\n\t\t\t\tif (cancelled) return;\n\t\t\t\ta.emit(x);\n\t\t\t}\n\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t} catch (e) {\n\t\t\tif (!cancelled) a.down([[ERROR, e]]);\n\t\t}\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, sourceOpts(opts));\n}\n\nfunction isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\n/**\n * Lifts a Promise (or thenable) to a single-value stream: one `DATA` then `COMPLETE`, or `ERROR` on rejection.\n *\n * @param p - Promise to await.\n * @param opts - Producer options plus optional `signal` for abort → `ERROR` with reason.\n * @returns `Node<T>` — settles once.\n *\n * @example\n * ```ts\n * import { fromPromise } from \"@graphrefly/graphrefly-ts\";\n *\n * fromPromise(Promise.resolve(42));\n * ```\n *\n * @category extra\n */\nexport function fromPromise<T>(p: Promise<T> | PromiseLike<T>, opts?: AsyncSourceOpts): Node<T> {\n\tconst { signal, ...rest } = opts ?? {};\n\treturn producer<T>((a) => {\n\t\tlet settled = false;\n\t\tconst onAbort = () => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\ta.down([[ERROR, signal!.reason]]);\n\t\t};\n\t\tif (signal?.aborted) {\n\t\t\tonAbort();\n\t\t\treturn;\n\t\t}\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tvoid Promise.resolve(p).then(\n\t\t\t(v) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\ta.emit(v as T);\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t},\n\t\t\t(e) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\ta.down([[ERROR, e]]);\n\t\t\t},\n\t\t);\n\t\treturn () => {\n\t\t\tsettled = true;\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/**\n * Reads an async iterable; each `next()` value becomes `DATA`; `COMPLETE` when done; `ERROR` on failure.\n *\n * @param iterable - Async source (`for await` shape).\n * @param opts - Producer options plus optional `signal` to abort the pump.\n * @returns `Node<T>` — async pull stream.\n *\n * @example\n * ```ts\n * import { fromAsyncIter } from \"@graphrefly/graphrefly-ts\";\n *\n * async function* gen() {\n * yield 1;\n * }\n * fromAsyncIter(gen());\n * ```\n *\n * @category extra\n */\nexport function fromAsyncIter<T>(iterable: AsyncIterable<T>, opts?: AsyncSourceOpts): Node<T> {\n\tconst { signal: outerSignal, ...rest } = opts ?? {};\n\treturn producer<T>((a) => {\n\t\tconst ac = new AbortController();\n\t\tconst onOuterAbort = () => ac.abort(outerSignal?.reason);\n\t\tif (outerSignal?.aborted) {\n\t\t\tac.abort(outerSignal.reason);\n\t\t} else {\n\t\t\touterSignal?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\t\t}\n\t\tconst signal = outerSignal ?? ac.signal;\n\t\tlet cancelled = false;\n\t\tconst it = iterable[Symbol.asyncIterator]();\n\t\t// Each pump() call chains directly into the next via Promise.then —\n\t\t// no queueMicrotask needed; Promise resolution already yields to the\n\t\t// microtask queue. COMPLETE is delivered synchronously after the last\n\t\t// value, same as fromIter semantics.\n\t\tconst pump = (): void => {\n\t\t\tif (cancelled || signal.aborted) return;\n\t\t\tvoid Promise.resolve(it.next()).then(\n\t\t\t\t(step) => {\n\t\t\t\t\tif (cancelled || signal.aborted) return;\n\t\t\t\t\tif (step.done) {\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\ta.emit(step.value as T);\n\t\t\t\t\tpump();\n\t\t\t\t},\n\t\t\t\t(e) => {\n\t\t\t\t\tif (!cancelled && !signal.aborted) a.down([[ERROR, e]]);\n\t\t\t\t},\n\t\t\t);\n\t\t};\n\t\tpump();\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t\touterSignal?.removeEventListener(\"abort\", onOuterAbort);\n\t\t\tac.abort();\n\t\t\tvoid Promise.resolve(it.return?.()).catch(() => undefined);\n\t\t};\n\t}, sourceOpts(rest));\n}\n\nfunction isNode(x: unknown): x is Node {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\t\"cache\" in x &&\n\t\ttypeof (x as Node).subscribe === \"function\"\n\t);\n}\n\n/**\n * Coerces a value to a `Node` by shape: existing `Node` passthrough, thenable → {@link fromPromise},\n * async iterable → {@link fromAsyncIter}, sync iterable → {@link fromIter}, else scalar → {@link of}.\n *\n * @param input - Any value to wrap.\n * @param opts - Passed through when a Promise/async path is chosen.\n * @returns `Node` of the inferred element type.\n *\n * @example\n * ```ts\n * import { fromAny, state } from \"@graphrefly/graphrefly-ts\";\n *\n * fromAny(state(1));\n * fromAny(Promise.resolve(2));\n * ```\n *\n * @category extra\n */\nexport function fromAny<T>(input: NodeInput<T>, opts?: AsyncSourceOpts): Node<T> {\n\tif (isNode(input)) {\n\t\treturn input as Node<T>;\n\t}\n\tif (isThenable(input)) {\n\t\treturn fromPromise(input as PromiseLike<T>, opts);\n\t}\n\tif (input !== null && input !== undefined) {\n\t\tconst candidate = input as { [Symbol.asyncIterator]?: unknown; [Symbol.iterator]?: unknown };\n\t\tif (typeof candidate[Symbol.asyncIterator] === \"function\") {\n\t\t\treturn fromAsyncIter(input as AsyncIterable<T>, opts);\n\t\t}\n\t\tif (typeof candidate[Symbol.iterator] === \"function\") {\n\t\t\treturn fromIter(input as Iterable<T>, opts);\n\t\t}\n\t}\n\t// scalar fallback\n\treturn of(input as T);\n}\n\n/**\n * Emits each argument as `DATA` in order, then `COMPLETE` (implemented via {@link fromIter}).\n *\n * @param values - Values to emit.\n * @returns `Node<T>` — finite sequence.\n *\n * @example\n * ```ts\n * import { of } from \"@graphrefly/graphrefly-ts\";\n *\n * of(1, 2, 3);\n * ```\n *\n * @category extra\n */\nexport function of<T>(...values: T[]): Node<T> {\n\treturn fromIter(values, undefined);\n}\n\n/**\n * Completes immediately with no `DATA` (cold `EMPTY` analogue).\n *\n * @param opts - Optional producer options.\n * @returns `Node<T>` — terminal `COMPLETE` only.\n *\n * @example\n * ```ts\n * import { empty } from \"@graphrefly/graphrefly-ts\";\n *\n * empty();\n * ```\n *\n * @category extra\n */\nexport function empty<T = never>(opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\ta.down([[COMPLETE]]);\n\t\treturn undefined;\n\t}, sourceOpts(opts));\n}\n\n/**\n * Never emits and never completes until teardown (cold `NEVER` analogue).\n *\n * @param opts - Optional producer options.\n * @returns `Node<T>` — silent until unsubscribed.\n *\n * @example\n * ```ts\n * import { never } from \"@graphrefly/graphrefly-ts\";\n *\n * never();\n * ```\n *\n * @category extra\n */\nexport function never<T = never>(opts?: ExtraOpts): Node<T> {\n\treturn producer<T>(() => undefined, sourceOpts(opts));\n}\n\n/**\n * Emits `ERROR` as soon as the producer starts (cold error source).\n *\n * @param err - Error payload forwarded as `ERROR` data.\n * @param opts - Optional producer options.\n * @returns `Node<never>` — terminates with `ERROR`.\n *\n * @example\n * ```ts\n * import { throwError } from \"@graphrefly/graphrefly-ts\";\n *\n * throwError(new Error(\"fail\"));\n * ```\n *\n * @category extra\n */\nexport function throwError(err: unknown, opts?: ExtraOpts): Node<never> {\n\treturn producer<never>((a) => {\n\t\ta.down([[ERROR, err]]);\n\t\treturn undefined;\n\t}, sourceOpts(opts));\n}\n\n/**\n * Subscribes immediately and runs `fn` for each upstream `DATA`; returns unsubscribe.\n *\n * @param source - Upstream node.\n * @param fn - Side effect per value.\n * @param opts - Effect node options.\n * @returns Unsubscribe function (idempotent).\n *\n * @example\n * ```ts\n * import { forEach, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const u = forEach(state(1), (v) => console.log(v));\n * u();\n * ```\n *\n * @category extra\n */\nexport function forEach<T>(source: Node<T>, fn: (value: T) => void, opts?: ExtraOpts): () => void {\n\tconst inner = node(\n\t\t[source as Node],\n\t\t(data, _actions) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\tfor (const v of batch0) fn(v as T);\n\t\t\t}\n\t\t},\n\t\t{ describeKind: \"effect\", ...opts } as NodeOptions,\n\t);\n\treturn inner.subscribe(() => {});\n}\n\n/**\n * Buffers every `DATA`; on upstream `COMPLETE` emits one `DATA` with the full array then `COMPLETE`.\n *\n * @param source - Upstream node.\n * @param opts - Optional node options (derived describe kind).\n * @returns `Node<T[]>` — single array emission before completion.\n *\n * @example\n * ```ts\n * import { of, toArray } from \"@graphrefly/graphrefly-ts\";\n *\n * toArray(of(1, 2, 3));\n * ```\n *\n * @category extra\n */\nexport function toArray<T>(source: Node<T>, opts?: ExtraOpts): Node<T[]> {\n\treturn node<T[]>(\n\t\t[source as Node],\n\t\t(data, actions, ctx) => {\n\t\t\tif (!ctx.store.buf) ctx.store.buf = [];\n\t\t\tconst buf = ctx.store.buf as T[];\n\t\t\t// Accumulate DATA first — must happen before the COMPLETE check so\n\t\t\t// that a same-wave DATA+COMPLETE batch (e.g. fromTimer one-shot,\n\t\t\t// fromIter last item) is included in the emitted array.\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\tfor (const v of batch0) buf.push(v as T);\n\t\t\t}\n\t\t\t// COMPLETE: emit accumulated array then complete.\n\t\t\t// ERROR: autoError propagates; do NOT emit the partial buffer.\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tactions.emit([...buf]);\n\t\t\t\tactions.down([[COMPLETE]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// RESOLVED wave: propagate RESOLVED. Covers first-wave case; after first\n\t\t\t// call the pre-fn skip handles this automatically.\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\tactions.down([[RESOLVED]]);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tdescribeKind: \"derived\",\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\t...opts,\n\t\t} as NodeOptions<T[]>,\n\t);\n}\n\n/**\n * Multicasts upstream: one subscription to `source` while this wrapper has subscribers (via {@link producer}).\n *\n * @param source - Upstream node to share.\n * @param opts - Producer options; `initial` seeds from `source.cache` when set by factory.\n * @returns `Node<T>` — hot ref-counted bridge.\n *\n * @example\n * ```ts\n * import { share, state } from \"@graphrefly/graphrefly-ts\";\n *\n * share(state(0));\n * ```\n *\n * @category extra\n */\nexport function share<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>(\n\t\t(a) =>\n\t\t\tsource.subscribe((msgs) => {\n\t\t\t\ta.down(msgs);\n\t\t\t}),\n\t\t{ ...sourceOpts<T>(opts), initial: source.cache },\n\t);\n}\n\n/**\n * Like {@link share} with a bounded replay buffer: new subscribers receive the last `bufferSize`\n * `DATA` payloads (as separate batches) before live updates.\n *\n * @param source - Upstream node.\n * @param bufferSize - Maximum past values to replay (≥ 1).\n * @param opts - Producer options.\n * @returns `Node<T>` — multicast with replay on subscribe.\n *\n * @example\n * ```ts\n * import { replay, state } from \"@graphrefly/graphrefly-ts\";\n *\n * replay(state(0), 3);\n * ```\n *\n * @category extra\n */\nexport function replay<T>(source: Node<T>, bufferSize: number, opts?: ExtraOpts): Node<T> {\n\tif (bufferSize < 1) throw new RangeError(\"replay expects bufferSize >= 1\");\n\tconst buf: T[] = [];\n\tconst inner = producer<T>(\n\t\t(a) =>\n\t\t\tsource.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tbuf.push(m[1] as T);\n\t\t\t\t\t\tif (buf.length > bufferSize) buf.shift();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ta.down(msgs);\n\t\t\t}),\n\t\t{ ...sourceOpts<T>(opts), initial: source.cache },\n\t);\n\treturn wrapSubscribeHook(inner, (sink) => {\n\t\tfor (const v of buf) {\n\t\t\tsink([[DATA, v]]);\n\t\t}\n\t});\n}\n\n/**\n * {@link replay} with `bufferSize === 1` — replays the latest `DATA` to new subscribers.\n *\n * @param source - Upstream node.\n * @param opts - Producer options.\n * @returns `Node<T>` — share + last-value replay.\n *\n * @example\n * ```ts\n * import { cached, state } from \"@graphrefly/graphrefly-ts\";\n *\n * cached(state(0));\n * ```\n *\n * @category extra\n */\nexport function cached<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn replay(source, 1, opts);\n}\n\n/**\n * Converts the first `DATA` on `source` into a Promise; rejects on `ERROR` or `COMPLETE` without data.\n *\n * **Important:** This subscribes and waits for a **future** emission. Data that\n * has already flowed is gone and will not be seen. Call this *before* the upstream\n * emits, or use `source.cache` / `source.status` for already-cached state.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * @param source - Node to read once.\n * @returns Promise of the first value.\n *\n * @example\n * ```ts\n * import { firstValueFrom, of } from \"@graphrefly/graphrefly-ts\";\n *\n * await firstValueFrom(of(42));\n * ```\n *\n * @category extra\n */\nexport function firstValueFrom<T>(source: Node<T>): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tlet shouldUnsub = false;\n\t\tlet unsub: (() => void) | undefined;\n\t\tunsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (settled) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\tresolve(m[1] as T);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(m[1]);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(new Error(\"completed without DATA\"));\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tif (shouldUnsub) {\n\t\t\tunsub?.();\n\t\t\tunsub = undefined;\n\t\t}\n\t});\n}\n\n/**\n * Wait for the first DATA value from `source` that satisfies `predicate`.\n *\n * Subscribes directly and resolves on the first DATA value where\n * `predicate` returns true. Reactive, no polling. Use in tests and\n * bridging code where you need a single matching value as a Promise.\n *\n * **Important:** This only captures **future** emissions — data that has\n * already flowed through the node is gone. Call this *before* the upstream\n * emits. For already-cached values, use `source.cache` / `source.status`.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * ```ts\n * const val = await firstWhere(strategy.node, snap => snap.size > 0);\n * ```\n *\n * @category extra\n */\nexport function firstWhere<T>(source: Node<T>, predicate: (value: T) => boolean): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tlet shouldUnsub = false;\n\t\tlet unsub: (() => void) | undefined;\n\t\tunsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (settled) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tconst v = m[1] as T;\n\t\t\t\t\tif (predicate(v)) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tresolve(v);\n\t\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\t\tunsub();\n\t\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(m[1]);\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(new Error(\"completed without matching value\"));\n\t\t\t\t\tif (unsub) {\n\t\t\t\t\t\tunsub();\n\t\t\t\t\t\tunsub = undefined;\n\t\t\t\t\t} else shouldUnsub = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tif (shouldUnsub) {\n\t\t\tunsub?.();\n\t\t\tunsub = undefined;\n\t\t}\n\t});\n}\n\n// ——————————————————————————————————————————————————————————————\n// RxJS-compatible aliases\n// ——————————————————————————————————————————————————————————————\n\n/**\n * RxJS-named alias for {@link replay} — multicast with a replay buffer of size `bufferSize`.\n *\n * @param source - Upstream node.\n * @param bufferSize - Replay depth (≥ 1).\n * @param opts - Producer options.\n * @returns Same behavior as `replay`.\n *\n * @example\n * ```ts\n * import { shareReplay, state } from \"@graphrefly/graphrefly-ts\";\n *\n * shareReplay(state(0), 5);\n * ```\n *\n * @category extra\n */\nexport const shareReplay = replay;\n\n// ---------------------------------------------------------------------------\n// keepalive\n// ---------------------------------------------------------------------------\n\n/**\n * Activate a compute node's upstream wiring without a real sink.\n *\n * Derived/effect nodes are lazy — they don't compute until at least one\n * subscriber exists (COMPOSITION-GUIDE §5). `keepalive` subscribes with an\n * empty sink so the node stays wired for `.cache` and upstream propagation.\n *\n * Returns the unsubscribe handle. Common usage:\n * `graph.addDisposer(keepalive(node))`.\n *\n * @category extra\n */\nexport function keepalive(n: Node<unknown>): () => void {\n\treturn n.subscribe(() => {});\n}\n\n// ---------------------------------------------------------------------------\n// reactiveCounter\n// ---------------------------------------------------------------------------\n\n/** Bundle returned by {@link reactiveCounter}. */\nexport type ReactiveCounterBundle = {\n\t/** Reactive node holding the current count. */\n\treadonly node: Node<number>;\n\t/** Increment by 1. Returns `false` if cap would be exceeded. */\n\tincrement(): boolean;\n\t/** Current count (synchronous read). */\n\tget(): number;\n\t/** Whether the counter has reached its cap. */\n\tatCap(): boolean;\n};\n\n/**\n * Reactive counter with a cap — the building block for circuit breakers.\n *\n * Wraps a `state(0)` node with `increment()` that respects a maximum.\n * The `node` is subscribable and composable like any reactive node. When\n * the cap is reached, `increment()` returns `false`.\n *\n * ```ts\n * const retries = reactiveCounter(10);\n * retries.increment(); // true — count is now 1\n * retries.node.subscribe(...); // reactive updates\n * retries.atCap(); // false\n * ```\n *\n * @param cap - Maximum value (inclusive). 0 = no increments allowed.\n * @category extra\n */\nexport function reactiveCounter(cap: number): ReactiveCounterBundle {\n\tconst counter = state(0);\n\treturn {\n\t\tnode: counter,\n\t\tincrement() {\n\t\t\tconst current = counter.cache ?? 0;\n\t\t\tif (current >= cap) return false;\n\t\t\tcounter.down([[DIRTY], [DATA, current + 1]]);\n\t\t\treturn true;\n\t\t},\n\t\tget() {\n\t\t\treturn counter.cache ?? 0;\n\t\t},\n\t\tatCap() {\n\t\t\treturn (counter.cache ?? 0) >= cap;\n\t\t},\n\t};\n}\n","/**\n * Minimal 5-field cron parser and matcher (minute hour day-of-month month day-of-week).\n * Ported from callbag-recharge `extra/cron.ts` for `fromCron` (roadmap §2.3).\n */\nexport interface CronSchedule {\n\tminutes: Set<number>;\n\thours: Set<number>;\n\tdaysOfMonth: Set<number>;\n\tmonths: Set<number>;\n\tdaysOfWeek: Set<number>;\n}\n\nfunction parseField(field: string, min: number, max: number): Set<number> {\n\tconst result = new Set<number>();\n\tfor (const part of field.split(\",\")) {\n\t\tconst [range, stepStr] = part.split(\"/\");\n\t\tconst step = stepStr ? Number.parseInt(stepStr, 10) : 1;\n\t\tif (Number.isNaN(step) || step < 1) throw new Error(`Invalid cron step: ${part}`);\n\t\tlet start: number;\n\t\tlet end: number;\n\t\tif (range === \"*\") {\n\t\t\tstart = min;\n\t\t\tend = max;\n\t\t} else if (range.includes(\"-\")) {\n\t\t\tconst [a, b] = range.split(\"-\");\n\t\t\tstart = Number.parseInt(a, 10);\n\t\t\tend = Number.parseInt(b, 10);\n\t\t} else {\n\t\t\tstart = Number.parseInt(range, 10);\n\t\t\tend = start;\n\t\t}\n\t\tif (Number.isNaN(start) || Number.isNaN(end)) throw new Error(`Invalid cron field: ${field}`);\n\t\tif (start < min || end > max)\n\t\t\tthrow new Error(`Cron field out of range: ${field} (${min}-${max})`);\n\t\tif (start > end) throw new Error(`Invalid cron range: ${start}-${end} in ${field}`);\n\t\tfor (let i = start; i <= end; i += step) result.add(i);\n\t}\n\treturn result;\n}\n\n/**\n * Parses a standard 5-field cron expression into a {@link CronSchedule}.\n *\n * Supports `*`, ranges (`1-5`), steps (`*\\/5`, `0-30/10`), and comma-separated\n * lists. Fields are: minute (0–59), hour (0–23), day-of-month (1–31),\n * month (1–12), day-of-week (0–6, Sunday = 0).\n *\n * @param expr - Five-field whitespace-separated cron string (e.g. `\"0 9 * * 1-5\"`).\n * @returns Parsed {@link CronSchedule} with one `Set<number>` per field.\n * @throws Error when the expression does not have exactly 5 fields, contains\n * out-of-range values, or uses an invalid step.\n *\n * @example\n * ```ts\n * import { parseCron } from \"@graphrefly/graphrefly-ts\";\n *\n * const sched = parseCron(\"0 9 * * 1-5\"); // weekdays at 09:00\n * sched.hours; // Set { 9 }\n * sched.daysOfWeek; // Set { 1, 2, 3, 4, 5 }\n * ```\n */\nexport function parseCron(expr: string): CronSchedule {\n\tconst parts = expr.trim().split(/\\s+/);\n\tif (parts.length !== 5) throw new Error(`Invalid cron: expected 5 fields, got ${parts.length}`);\n\treturn {\n\t\tminutes: parseField(parts[0], 0, 59),\n\t\thours: parseField(parts[1], 0, 23),\n\t\tdaysOfMonth: parseField(parts[2], 1, 31),\n\t\tmonths: parseField(parts[3], 1, 12),\n\t\tdaysOfWeek: parseField(parts[4], 0, 6),\n\t};\n}\n\n/**\n * Returns `true` if `date` satisfies every field of `schedule`.\n *\n * @param schedule - Parsed schedule from {@link parseCron}.\n * @param date - Moment to test (local time via `getMinutes`, `getHours`, etc.).\n * @returns `true` when all five cron fields match the given date.\n *\n * @example\n * ```ts\n * import { parseCron, matchesCron } from \"@graphrefly/graphrefly-ts\";\n *\n * const sched = parseCron(\"30 8 * * 1\"); // Mondays at 08:30\n * const monday = new Date(\"2026-03-30T08:30:00\"); // a Monday\n * matchesCron(sched, monday); // true\n * ```\n */\nexport function matchesCron(schedule: CronSchedule, date: Date): boolean {\n\treturn (\n\t\tschedule.minutes.has(date.getMinutes()) &&\n\t\tschedule.hours.has(date.getHours()) &&\n\t\tschedule.daysOfMonth.has(date.getDate()) &&\n\t\tschedule.months.has(date.getMonth() + 1) &&\n\t\tschedule.daysOfWeek.has(date.getDay())\n\t);\n}\n","/**\n * Tier 1 sync operators (roadmap §2.1) and Tier 2 async/dynamic operators (roadmap §2.2) —\n * each returns a {@link Node} built with {@link node} (or {@link producer} for cold sources).\n *\n * v5 foundation redesign: all operators use `actions.emit()` for value emission,\n * `ctx.store` for persistent state, `ctx.terminalDeps` for terminal handling,\n * and `data[i]` batch shape for DATA vs RESOLVED discrimination. `onMessage`\n * and `onResubscribe` are removed.\n */\n\nimport { monotonicNs } from \"../core/clock.js\";\nimport type { NodeActions } from \"../core/config.js\";\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Message,\n\ttype Messages,\n\tRESOLVED,\n\tSTART,\n} from \"../core/messages.js\";\nimport { type Node, type NodeOptions, node } from \"../core/node.js\";\nimport { derived, producer } from \"../core/sugar.js\";\nimport { NS_PER_MS } from \"./backoff.js\";\nimport { fromAny, type NodeInput } from \"./sources.js\";\n\ntype ExtraOpts = Omit<NodeOptions<unknown>, \"describeKind\">;\n\nfunction operatorOpts<T = unknown>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"derived\", ...opts } as NodeOptions<T>;\n}\n\n/**\n * Maps each settled value from `source` through `project`.\n *\n * @param source - Upstream node.\n * @param project - Transform for each value.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Derived node emitting mapped values.\n *\n * @example\n * ```ts\n * import { map, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = map(state(2), (x) => x * 3);\n * ```\n *\n * @category extra\n */\nexport function map<T, R>(source: Node<T>, project: (value: T) => R, opts?: ExtraOpts): Node<R> {\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) {\n\t\t\t\ta.emit(project(v as T));\n\t\t\t}\n\t\t},\n\t\toperatorOpts<R>(opts),\n\t);\n}\n\n/**\n * Forwards values that satisfy `predicate`; otherwise emits `RESOLVED` with no `DATA` (two-phase semantics).\n *\n * @param source - Upstream node.\n * @param predicate - Inclusion test.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Filtered node.\n *\n * @example\n * ```ts\n * import { filter, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = filter(state(1), (x) => x > 0);\n * ```\n *\n * @category extra\n */\nexport function filter<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet emitted = false;\n\t\t\tfor (const v of batch0) {\n\t\t\t\tif (predicate(v as T)) {\n\t\t\t\t\ta.emit(v as T);\n\t\t\t\t\temitted = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!emitted) a.down([[RESOLVED]]);\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n/**\n * Folds each upstream value into an accumulator; emits the new accumulator every time.\n *\n * Unlike RxJS, `seed` is always required — there is no seedless mode where the first\n * value silently becomes the accumulator.\n *\n * @param source - Upstream node.\n * @param reducer - `(acc, value) => nextAcc`.\n * @param seed - Initial accumulator (required).\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Scan node.\n *\n * @example\n * ```ts\n * import { scan, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = scan(state(1), (a, x) => a + x, 0);\n * ```\n *\n * @category extra\n */\nexport function scan<T, R>(\n\tsource: Node<T>,\n\treducer: (acc: R, value: T) => R,\n\tseed: R,\n\topts?: ExtraOpts,\n): Node<R> {\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (!(\"acc\" in ctx.store)) ctx.store.acc = seed;\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) {\n\t\t\t\tctx.store.acc = reducer(ctx.store.acc as R, v as T);\n\t\t\t\ta.emit(ctx.store.acc as R);\n\t\t\t}\n\t\t},\n\t\t{ ...operatorOpts(opts), initial: seed, resetOnTeardown: true },\n\t);\n}\n\n/**\n * Reduces to one value emitted when `source` completes; if no `DATA` arrived, emits `seed`.\n *\n * Unlike RxJS, `seed` is always required. If the source completes without emitting\n * DATA, the seed value is emitted (RxJS would throw without a seed).\n *\n * @param source - Upstream node.\n * @param reducer - `(acc, value) => nextAcc`.\n * @param seed - Empty-completion default and initial accumulator (required).\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Node that emits once on completion.\n *\n * @example\n * ```ts\n * import { reduce, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = reduce(state(1), (a, x) => a + x, 0);\n * ```\n *\n * @category extra\n */\nexport function reduce<T, R>(\n\tsource: Node<T>,\n\treducer: (acc: R, value: T) => R,\n\tseed: R,\n\topts?: ExtraOpts,\n): Node<R> {\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (!(\"acc\" in ctx.store)) ctx.store.acc = seed;\n\t\t\t// COMPLETE: emit accumulated value then COMPLETE.\n\t\t\t// ERROR: autoError propagates automatically; nothing to emit.\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\ta.emit(ctx.store.acc as R);\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\t// RESOLVED wave (empty batch): propagate RESOLVED. After fn has run once\n\t\t\t// the pre-fn skip handles this; this guard covers the first-wave case.\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// DATA: accumulate silently — emit nothing until COMPLETE.\n\t\t\tfor (const v of batch0) {\n\t\t\t\tctx.store.acc = reducer(ctx.store.acc as R, v as T);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t},\n\t);\n}\n\n/**\n * Emits at most `count` **`DATA`** values, then **`COMPLETE`**. `RESOLVED` does not advance the counter.\n *\n * @param source - Upstream node.\n * @param count - Maximum `DATA` emissions (≤0 completes immediately).\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Limited stream.\n *\n * @example\n * ```ts\n * import { take, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = take(state(0), 3);\n * ```\n *\n * @category extra\n */\nexport function take<T>(source: Node<T>, count: number, opts?: ExtraOpts): Node<T> {\n\tif (count <= 0) {\n\t\treturn node<T>(\n\t\t\t[source as Node],\n\t\t\t(_d, a, ctx) => {\n\t\t\t\tif (ctx.store.completed) return;\n\t\t\t\tctx.store.completed = true;\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t},\n\t\t\t{\n\t\t\t\t...operatorOpts(opts),\n\t\t\t\tcompleteWhenDepsComplete: false,\n\t\t\t},\n\t\t);\n\t}\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (!(\"taken\" in ctx.store)) ctx.store.taken = 0;\n\t\t\tif (ctx.store.done) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Upstream COMPLETE before count reached → forward COMPLETE.\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tctx.store.done = true;\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// DATA wave: iterate full batch, stop at count\n\t\t\tfor (const v of batch0) {\n\t\t\t\t(ctx.store.taken as number)++;\n\t\t\t\ta.emit(v as T);\n\t\t\t\tif ((ctx.store.taken as number) >= count) {\n\t\t\t\t\tctx.store.done = true;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t},\n\t);\n}\n\n/**\n * Skips the first `count` **`DATA`** emissions. `RESOLVED` does not advance the counter.\n *\n * @param source - Upstream node.\n * @param count - Number of `DATA` values to drop.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Skipped stream.\n *\n * @example\n * ```ts\n * import { skip, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = skip(state(0), 2);\n * ```\n *\n * @category extra\n */\nexport function skip<T>(source: Node<T>, count: number, opts?: ExtraOpts): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (!(\"skipped\" in ctx.store)) ctx.store.skipped = 0;\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\t// RESOLVED wave — pass through\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet emitted = false;\n\t\t\tfor (const v of batch0) {\n\t\t\t\t(ctx.store.skipped as number)++;\n\t\t\t\tif ((ctx.store.skipped as number) <= count) {\n\t\t\t\t\t// Still in skip window\n\t\t\t\t} else {\n\t\t\t\t\ta.emit(v as T);\n\t\t\t\t\temitted = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!emitted) a.down([[RESOLVED]]);\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n/**\n * Emits while `predicate` holds; on first false, sends **`COMPLETE`**.\n *\n * @param source - Upstream node.\n * @param predicate - Continuation test.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Truncated stream.\n *\n * @example\n * ```ts\n * import { takeWhile, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = takeWhile(state(1), (x) => x < 10);\n * ```\n *\n * @category extra\n */\nexport function takeWhile<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (ctx.store.done) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) {\n\t\t\t\tif (!predicate(v as T)) {\n\t\t\t\t\tctx.store.done = true;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ta.emit(v as T);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t},\n\t);\n}\n\n/**\n * Forwards `source` until `notifier` matches `predicate` (default: notifier **`DATA`**), then **`COMPLETE`**.\n *\n * @param source - Main upstream.\n * @param notifier - Triggers completion when `predicate(msg)` is true.\n * @param opts - Optional {@link NodeOptions}, plus `predicate` for custom notifier matching.\n * @returns `Node<T>` - Truncated stream.\n *\n * @example\n * ```ts\n * import { producer, takeUntil, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = state(1);\n * const stop = producer((_d, a) => a.emit(undefined));\n * const n = takeUntil(src, stop);\n * ```\n *\n * @category extra\n */\nexport function takeUntil<T>(\n\tsource: Node<T>,\n\tnotifier: Node,\n\topts?: ExtraOpts & { predicate?: (msg: Message) => boolean },\n): Node<T> {\n\tconst pred = opts?.predicate ?? ((m: Message) => m[0] === DATA);\n\tconst { predicate: _, ...restOpts } = opts ?? {};\n\t// Use producer pattern — subscribe to both manually for message-level control.\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tlet stopped = false;\n\t\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\t\tif (stopped) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tif (m[0] === DATA) a.emit(m[1] as T);\n\t\t\t\t\telse if (m[0] === COMPLETE || m[0] === ERROR) {\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tconst notUnsub = notifier.subscribe((msgs) => {\n\t\t\t\tif (stopped) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tif (pred(m)) {\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn () => {\n\t\t\t\tsrcUnsub();\n\t\t\t\tnotUnsub();\n\t\t\t};\n\t\t},\n\t\toperatorOpts(restOpts as ExtraOpts),\n\t);\n}\n\n/**\n * Emits the first **`DATA`** then **`COMPLETE`** (same as `take(source, 1)`).\n *\n * @param source - Upstream node.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Single-value stream.\n *\n * @example\n * ```ts\n * import { first, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = first(state(42));\n * ```\n *\n * @category extra\n */\nexport function first<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn take(source, 1, opts);\n}\n\n/**\n * Buffers values and emits the last **`DATA`** on **`COMPLETE`**; optional `defaultValue` if none arrived.\n *\n * @param source - Upstream node.\n * @param options - Optional {@link NodeOptions} and `defaultValue` when empty.\n * @returns `Node<T>` - Last-or-default node.\n *\n * @example\n * ```ts\n * import { last, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = last(state(1), { defaultValue: 0 });\n * ```\n *\n * @category extra\n */\nexport function last<T>(source: Node<T>, options?: ExtraOpts & { defaultValue?: T }): Node<T> {\n\tconst { defaultValue, ...rest } = options ?? {};\n\tconst useDefault = options != null && Object.hasOwn(options, \"defaultValue\");\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\t// COMPLETE (terminal === true): emit latest or default, then COMPLETE.\n\t\t\t// ERROR: autoError propagates automatically.\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tif (ctx.store.has) {\n\t\t\t\t\ta.emit(ctx.store.latest as T);\n\t\t\t\t} else if (useDefault) {\n\t\t\t\t\ta.emit(defaultValue as T);\n\t\t\t\t}\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\t// RESOLVED wave: propagate RESOLVED. Covers first-wave case; after first\n\t\t\t// call the pre-fn skip handles this automatically.\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// DATA: accumulate latest — emit nothing until COMPLETE.\n\t\t\tctx.store.latest = batch0.at(-1) as T;\n\t\t\tctx.store.has = true;\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(rest),\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t},\n\t);\n}\n\n/**\n * Emits the first value matching `predicate`, then **`COMPLETE`**.\n *\n * @param source - Upstream node.\n * @param predicate - Match test.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - First-match stream.\n *\n * @example\n * ```ts\n * import { find, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = find(state(1), (x) => x > 0);\n * ```\n *\n * @category extra\n */\nexport function find<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn take(filter(source, predicate, opts), 1, opts);\n}\n\n/**\n * Emits the `index`th **`DATA`** (zero-based), then **`COMPLETE`**.\n *\n * @param source - Upstream node.\n * @param index - Zero-based emission index.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Single indexed value.\n *\n * @example\n * ```ts\n * import { elementAt, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = elementAt(state(0), 2);\n * ```\n *\n * @category extra\n */\nexport function elementAt<T>(source: Node<T>, index: number, opts?: ExtraOpts): Node<T> {\n\treturn take(skip(source, index, opts), 1, opts);\n}\n\n/**\n * Observer shape for {@link tap} — side effects for data, error, and/or complete.\n */\nexport type TapObserver<T> = {\n\tdata?: (value: T) => void;\n\terror?: (err: unknown) => void;\n\tcomplete?: () => void;\n};\n\n/**\n * Invokes side effects; values pass through unchanged.\n *\n * Accepts either a function (called on each DATA) or an observer object\n * `{ data?, error?, complete? }` for lifecycle-aware side effects.\n *\n * @param source - Upstream node.\n * @param fnOrObserver - Side effect function or observer object.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Passthrough node.\n *\n * @example\n * ```ts\n * import { tap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * // Function form (DATA only)\n * tap(state(1), (x) => console.log(x));\n *\n * // Observer form (DATA + ERROR + COMPLETE)\n * tap(state(1), { data: console.log, error: console.error, complete: () => console.log(\"done\") });\n * ```\n *\n * @category extra\n */\nexport function tap<T>(\n\tsource: Node<T>,\n\tfnOrObserver: ((value: T) => void) | TapObserver<T>,\n\topts?: ExtraOpts,\n): Node<T> {\n\tif (typeof fnOrObserver === \"function\") {\n\t\treturn node<T>(\n\t\t\t[source as Node],\n\t\t\t(data, a) => {\n\t\t\t\tconst batch0 = data[0];\n\t\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const v of batch0) {\n\t\t\t\t\tfnOrObserver(v as T);\n\t\t\t\t\ta.emit(v as T);\n\t\t\t\t}\n\t\t\t},\n\t\t\toperatorOpts(opts),\n\t\t);\n\t}\n\tconst obs = fnOrObserver;\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\t// Check for terminal events\n\t\t\tif (ctx.terminalDeps[0] !== undefined) {\n\t\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\t\tobs.complete?.();\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else {\n\t\t\t\t\tobs.error?.(ctx.terminalDeps[0]);\n\t\t\t\t\ta.down([[ERROR, ctx.terminalDeps[0]]]);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) {\n\t\t\t\tobs.data?.(v as T);\n\t\t\t\ta.emit(v as T);\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t},\n\t);\n}\n\n/**\n * Suppresses adjacent duplicates using `equals` (default `Object.is`).\n *\n * @param source - Upstream node.\n * @param equals - Optional equality for consecutive values.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Deduped stream.\n *\n * @example\n * ```ts\n * import { distinctUntilChanged, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = distinctUntilChanged(state(1));\n * ```\n *\n * @category extra\n */\nexport function distinctUntilChanged<T>(\n\tsource: Node<T>,\n\tequals: (a: T, b: T) => boolean = Object.is,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet emitted = false;\n\t\t\tfor (const val of batch0 as T[]) {\n\t\t\t\tif (ctx.store.hasPrev && equals(ctx.store.prev as T, val)) {\n\t\t\t\t\t// Suppressed — same as previous\n\t\t\t\t} else {\n\t\t\t\t\tctx.store.prev = val;\n\t\t\t\t\tctx.store.hasPrev = true;\n\t\t\t\t\ta.emit(val);\n\t\t\t\t\temitted = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!emitted) a.down([[RESOLVED]]);\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n/**\n * Emits `[previous, current]` pairs starting after the second value (first pair uses `RESOLVED` only).\n *\n * @param source - Upstream node.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<readonly [T, T]>` - Pair stream.\n *\n * @example\n * ```ts\n * import { pairwise, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = pairwise(state(0));\n * ```\n *\n * @category extra\n */\nexport function pairwise<T>(source: Node<T>, opts?: ExtraOpts): Node<readonly [T, T]> {\n\treturn node<readonly [T, T]>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet emitted = false;\n\t\t\tfor (const x of batch0 as T[]) {\n\t\t\t\tif (!ctx.store.hasPrev) {\n\t\t\t\t\tctx.store.prev = x;\n\t\t\t\t\tctx.store.hasPrev = true;\n\t\t\t\t\t// First value — no pair yet\n\t\t\t\t} else {\n\t\t\t\t\tconst pair = [ctx.store.prev as T, x] as const;\n\t\t\t\t\tctx.store.prev = x;\n\t\t\t\t\ta.emit(pair);\n\t\t\t\t\temitted = true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!emitted) a.down([[RESOLVED]]);\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n/**\n * Combines the latest value from each dependency whenever any dep settles (combineLatest).\n *\n * @param sources - Nodes to combine (variadic).\n * @returns `Node<T>` - Tuple of latest values.\n *\n * @example\n * ```ts\n * import { combine, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = combine(state(1), state(\"a\"));\n * ```\n *\n * @remarks\n * Unlike RxJS `combineLatest`, this is named `combine`. Use the {@link combineLatest} alias\n * if you prefer the RxJS name. Seed is always required for `scan`/`reduce` (no seedless mode).\n *\n * @category extra\n */\nexport function combine<const T extends readonly unknown[]>(\n\t...sources: { [K in keyof T]: Node<T[K]> }\n): Node<T> {\n\tconst deps = [...sources] as unknown as Node[];\n\treturn derived(deps, (vals) => vals as unknown as T, {\n\t\t...operatorOpts<T>(),\n\t\tequals: (a, b) => {\n\t\t\tif (a.length !== b.length) return false;\n\t\t\tfor (let i = 0; i < a.length; i++) {\n\t\t\t\tif (!Object.is(a[i], b[i])) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\t});\n}\n\n/**\n * When `primary` settles, emits `[primary, latestSecondary]`. `secondary` alone updates cache only.\n *\n * @param primary - Main stream.\n * @param secondary - Latest value is paired on each primary emission.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<readonly [A, B]>` - Paired stream.\n *\n * @example\n * ```ts\n * import { state, withLatestFrom } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = withLatestFrom(state(1), state(\"x\"));\n * ```\n *\n * @category extra\n */\nexport function withLatestFrom<A, B>(\n\tprimary: Node<A>,\n\tsecondary: Node<B>,\n\topts?: ExtraOpts,\n): Node<readonly [A, B]> {\n\t// Known semantic (documented): on initial activation when BOTH deps are\n\t// `state()` nodes with cached values, the paired emission is dropped.\n\t// `_activate` (src/core/node.ts:1002) subscribes deps sequentially in\n\t// declaration order; primary's push-on-subscribe fires before secondary\n\t// has subscribed, so the first-run gate (§2.7) forces RESOLVED. Secondary\n\t// then fires in a separate wave with primary silent, and the fn's\n\t// \"emit only when primary fired this wave\" rule takes the else branch.\n\t// Use the factory-time seed pattern for initial-value pairing (see\n\t// stratify, budgetGate, distill for examples; COMPOSITION-GUIDE §21).\n\t// A naïve `[secondary, primary]` flip breaks topology-sensitive diamond\n\t// callers like `harness/loop.ts` — the fix needs a deeper design pass.\n\treturn node<readonly [A, B]>(\n\t\t[primary as Node, secondary as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tconst batch1 = data[1];\n\t\t\t// Current secondary value: this wave's last DATA if secondary fired,\n\t\t\t// otherwise last known value from ctx.prevData (previous wave).\n\t\t\tconst secondaryVal = (\n\t\t\t\tbatch1 != null && batch1.length > 0 ? batch1.at(-1) : ctx.prevData[1]\n\t\t\t) as B | undefined;\n\n\t\t\t// Only emit when primary (dep 0) sent DATA this wave.\n\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\t// secondary has never produced DATA — undefined is the protocol\n\t\t\t\t// sentinel for \"never sent DATA\"; null is a valid DATA value.\n\t\t\t\tif (!(batch1 != null && batch1.length > 0) && ctx.prevData[1] === undefined) {\n\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const v of batch0 as A[]) {\n\t\t\t\t\ta.emit([v, secondaryVal]);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Secondary update only (or both RESOLVED) — no downstream DATA.\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t}\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n/**\n * Merges **`DATA`** from any source with correct two-phase dirty tracking. **`COMPLETE`** after **all** sources complete (spec §1.3.5).\n *\n * @param sources - Nodes to merge (variadic; empty completes immediately).\n * @returns `Node<T>` - Merged stream.\n *\n * @remarks\n * **Ordering:** DIRTY/RESOLVED rules follow multi-source semantics in `~/src/graphrefly/GRAPHREFLY-SPEC.md`.\n *\n * @example\n * ```ts\n * import { merge, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = merge(state(1), state(2));\n * ```\n *\n * @category extra\n */\nexport function merge<T>(...sources: readonly Node<T>[]): Node<T> {\n\tif (sources.length === 0) {\n\t\treturn producer<T>((a) => {\n\t\t\ta.down([[COMPLETE]]);\n\t\t}, operatorOpts());\n\t}\n\t// producer pattern: node() cannot be used here because the sentinel gate\n\t// would block the fn until ALL sources have sent their first DATA, which\n\t// defeats the purpose of merge (forward whichever source fires first).\n\treturn producer<T>((a) => {\n\t\tconst n = sources.length;\n\t\tlet completed = 0;\n\t\tconst unsubs: (() => void)[] = [];\n\t\tfor (const src of sources) {\n\t\t\tconst u = src.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t\tcompleted += 1;\n\t\t\t\t\t\tif (completed >= n) {\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t}\n\t\t\t\t\t// DIRTY, RESOLVED, START silently absorbed\n\t\t\t\t}\n\t\t\t});\n\t\t\tunsubs.push(u);\n\t\t}\n\t\treturn () => {\n\t\t\tfor (const u of unsubs) u();\n\t\t};\n\t}, operatorOpts());\n}\n\n/**\n * Zips one **`DATA`** from each source per cycle into a tuple. Only **`DATA`** enqueues (spec §1.3.3).\n *\n * @param sources - Nodes to zip (variadic).\n * @returns `Node<T>` - Zipped tuples.\n *\n * @example\n * ```ts\n * import { state, zip } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = zip(state(1), state(2));\n * ```\n *\n * @category extra\n */\nexport function zip<const T extends readonly unknown[]>(\n\t...sources: { [K in keyof T]: Node<T[K]> }\n): Node<T> {\n\tconst n = sources.length;\n\tif (n === 0) {\n\t\treturn producer<T>((a) => {\n\t\t\ta.emit([] as unknown as T);\n\t\t\ta.down([[COMPLETE]]);\n\t\t}, operatorOpts());\n\t}\n\t// Producer pattern: manage queues internally.\n\treturn producer<T>((a) => {\n\t\tconst queues: unknown[][] = Array.from({ length: n }, () => []);\n\t\tlet active = n;\n\n\t\tfunction tryEmit(): void {\n\t\t\twhile (queues.every((q) => q.length > 0)) {\n\t\t\t\tconst tuple = queues.map((q) => q.shift()!) as unknown as T;\n\t\t\t\ta.emit(tuple);\n\t\t\t}\n\t\t}\n\n\t\tconst unsubs: (() => void)[] = [];\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst idx = i;\n\t\t\tconst u = (sources[i] as Node).subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tqueues[idx].push(m[1]);\n\t\t\t\t\t\ttryEmit();\n\t\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t\tactive -= 1;\n\t\t\t\t\t\tif (active === 0 || queues[idx].length === 0) {\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tunsubs.push(u);\n\t\t}\n\t\treturn () => {\n\t\t\tfor (const u of unsubs) u();\n\t\t};\n\t}, operatorOpts());\n}\n\n/**\n * Plays all of `firstSrc`, then all of `secondSrc`. **`DATA`** from `secondSrc` during phase one is buffered until handoff.\n *\n * @param firstSrc - First segment.\n * @param secondSrc - Second segment.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Concatenated stream.\n *\n * @example\n * ```ts\n * import { concat, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = concat(state(1), state(2));\n * ```\n *\n * @category extra\n */\nexport function concat<T>(firstSrc: Node<T>, secondSrc: Node<T>, opts?: ExtraOpts): Node<T> {\n\t// producer pattern: node() cannot be used here because the sentinel gate\n\t// would block the fn until ALL sources have sent their first DATA, which\n\t// defeats the purpose of concat (start forwarding firstSrc immediately,\n\t// regardless of secondSrc state).\n\treturn producer<T>((a) => {\n\t\tlet phase: 0 | 1 = 0;\n\t\tconst pending: unknown[] = [];\n\t\tlet firstUnsub: (() => void) | undefined;\n\t\tlet secondUnsub: (() => void) | undefined;\n\n\t\tsecondUnsub = secondSrc.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (phase === 0) {\n\t\t\t\t\tif (m[0] === DATA) pending.push(m[1]);\n\t\t\t\t\telse if (m[0] === ERROR) a.down([m]);\n\t\t\t\t} else {\n\t\t\t\t\t// phase 1 — forward everything from second\n\t\t\t\t\tif (m[0] === DATA) a.emit(m[1] as T);\n\t\t\t\t\telse if (m[0] === COMPLETE || m[0] === ERROR) a.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tfirstUnsub = firstSrc.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (phase === 0) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t\tphase = 1;\n\t\t\t\t\t\t// Flush buffered second-source DATA\n\t\t\t\t\t\tfor (const v of pending) {\n\t\t\t\t\t\t\ta.emit(v as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpending.length = 0;\n\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// phase 1: ignore further first-source messages\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tfirstUnsub?.();\n\t\t\tsecondUnsub?.();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * First source to emit **`DATA`** wins; later traffic follows only the winner (Rx-style `race`).\n *\n * @param sources - Contestants (variadic; empty completes immediately; one node is identity).\n * @returns `Node<T>` - Winning stream.\n *\n * @example\n * ```ts\n * import { race, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = race(state(1), state(2));\n * ```\n *\n * @category extra\n */\nexport function race<T>(...sources: readonly Node<T>[]): Node<T> {\n\tif (sources.length === 0) {\n\t\treturn producer<T>((a) => {\n\t\t\ta.down([[COMPLETE]]);\n\t\t}, operatorOpts());\n\t}\n\tif (sources.length === 1) {\n\t\t// Identity passthrough — full batch iteration, not derived's .at(-1).\n\t\treturn node<T>(\n\t\t\t[sources[0] as Node],\n\t\t\t(data, a) => {\n\t\t\t\tconst batch0 = data[0];\n\t\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const v of batch0) a.emit(v as T);\n\t\t\t},\n\t\t\toperatorOpts<T>(),\n\t\t);\n\t}\n\t// Producer pattern: first DATA wins.\n\treturn producer<T>((a) => {\n\t\tlet winner: number | null = null;\n\t\tconst unsubs: (() => void)[] = [];\n\t\tfor (let i = 0; i < sources.length; i++) {\n\t\t\tconst idx = i;\n\t\t\tconst u = (sources[i] as Node).subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (winner !== null && idx !== winner) return;\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tif (winner === null) winner = idx;\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (m[0] === COMPLETE || m[0] === ERROR) {\n\t\t\t\t\t\tif (winner === null || idx === winner) {\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tunsubs.push(u);\n\t\t}\n\t\treturn () => {\n\t\t\tfor (const u of unsubs) u();\n\t\t};\n\t}, operatorOpts());\n}\n\n// --- Tier 2: async / dynamic (roadmap §2.2), all on `node` / `producer` ---\n\nfunction forwardInner<R>(inner: Node<R>, a: NodeActions, onInnerComplete: () => void): () => void {\n\tlet unsub: (() => void) | undefined;\n\tlet finished = false;\n\tconst finish = (): void => {\n\t\tif (finished) return;\n\t\tfinished = true;\n\t\tonInnerComplete();\n\t};\n\tunsub = inner.subscribe((msgs) => {\n\t\tlet sawComplete = false;\n\t\tlet sawError = false;\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === START) continue;\n\t\t\tif (m[0] === DATA) {\n\t\t\t\ta.emit(m[1] as R);\n\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\tsawComplete = true;\n\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\tsawError = true;\n\t\t\t\ta.down([m]);\n\t\t\t} else if (m[0] === DIRTY || m[0] === RESOLVED) {\n\t\t\t\t// Reactive wave signals forwarded to outer output.\n\t\t\t\ta.down([m]);\n\t\t\t}\n\t\t\t// INVALIDATE, PAUSE, RESUME, TEARDOWN from inner are intentionally\n\t\t\t// dropped. Inner lifecycle and flow-control signals are internal to\n\t\t\t// the *Map operator. INVALIDATE is dropped because the inner will\n\t\t\t// follow up with DIRTY+DATA when it recomputes — forwarding\n\t\t\t// INVALIDATE to the outer output's sinks is redundant and wrong for\n\t\t\t// mergeMap (one inner's cache state must not invalidate the whole\n\t\t\t// merged output). PAUSE/RESUME/TEARDOWN: RxJS/callbag precedent —\n\t\t\t// no backpressure forwarding in merge-style operators.\n\t\t}\n\t\tif (sawError) {\n\t\t\tunsub?.();\n\t\t\tunsub = undefined;\n\t\t\tfinish();\n\t\t} else if (sawComplete) {\n\t\t\tfinish();\n\t\t}\n\t});\n\t// P4 START handshake guarantees: subscribe delivers [[START], [DATA, cache]]\n\t// synchronously for settled nodes. Any relevant state is already handled by\n\t// the callback above — no post-subscribe .status/.cache reads needed.\n\treturn () => {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t};\n}\n\n/**\n * Maps each settled value to an inner node; unsubscribes the previous inner (Rx-style `switchMap`).\n *\n * @param source - Upstream node.\n * @param project - Maps each outer value to an inner source shape (`Node`, scalar, `PromiseLike`, `Iterable`, or `AsyncIterable`) coerced via {@link fromAny}.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Emissions from the active inner subscription.\n * @example\n * ```ts\n * import { switchMap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = state(0);\n * switchMap(src, (n) => state((n as number) * 2));\n * ```\n *\n * @category extra\n */\nexport function switchMap<T, R>(\n\tsource: Node<T>,\n\tproject: (value: T) => NodeInput<R>,\n\topts?: ExtraOpts,\n): Node<R> {\n\tlet innerUnsub: (() => void) | undefined;\n\tlet sourceDone = false;\n\n\tfunction clearInner(): void {\n\t\tinnerUnsub?.();\n\t\tinnerUnsub = undefined;\n\t}\n\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\t// Source ERROR: cleanup inner, autoError forwards\n\t\t\tif (ctx.terminalDeps[0] != null && ctx.terminalDeps[0] !== true) {\n\t\t\t\tclearInner();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Source COMPLETE\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tsourceDone = true;\n\t\t\t\tif (!innerUnsub) a.down([[COMPLETE]]);\n\t\t\t\t// inner active: onInnerComplete will fire COMPLETE later\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\n\t\t\t// Switch: only the latest value matters; skip to the last in the\n\t\t\t// batch to avoid creating and immediately discarding N-1 inners.\n\t\t\t// clearInner() runs once to cancel any prior-wave inner.\n\t\t\tclearInner();\n\t\t\tinnerUnsub = forwardInner(fromAny(project(batch0[batch0.length - 1] as T)), a, () => {\n\t\t\t\tclearInner();\n\t\t\t\tif (sourceDone) a.down([[COMPLETE]]);\n\t\t\t});\n\n\t\t\t// Deactivation-only cleanup: must NOT fire before fn reruns\n\t\t\t// because the terminal wave needs to see innerUnsub intact.\n\t\t\treturn {\n\t\t\t\tdeactivation: () => {\n\t\t\t\t\tclearInner();\n\t\t\t\t\tsourceDone = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...operatorOpts(opts), completeWhenDepsComplete: false },\n\t);\n}\n\n/**\n * Like {@link switchMap}, but ignores outer `DATA` while an inner subscription is active (`exhaustMap`).\n *\n * @param source - Upstream node.\n * @param project - Maps each outer value to an inner source shape (`Node`, scalar, `PromiseLike`, `Iterable`, or `AsyncIterable`) coerced via {@link fromAny}.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Emissions from the active inner while it runs.\n * @example\n * ```ts\n * import { exhaustMap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * exhaustMap(state(0), () => state(1));\n * ```\n *\n * @category extra\n */\nexport function exhaustMap<T, R>(\n\tsource: Node<T>,\n\tproject: (value: T) => NodeInput<R>,\n\topts?: ExtraOpts,\n): Node<R> {\n\tlet innerUnsub: (() => void) | undefined;\n\tlet sourceDone = false;\n\n\tfunction clearInner(): void {\n\t\tinnerUnsub?.();\n\t\tinnerUnsub = undefined;\n\t}\n\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (ctx.terminalDeps[0] != null && ctx.terminalDeps[0] !== true) {\n\t\t\t\tclearInner();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tsourceDone = true;\n\t\t\t\tif (!innerUnsub) a.down([[COMPLETE]]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\n\t\t\tif (innerUnsub === undefined) {\n\t\t\t\t// First value in batch wins (FIFO exhaustMap gate)\n\t\t\t\tinnerUnsub = forwardInner(fromAny(project(batch0[0] as T)), a, () => {\n\t\t\t\t\tclearInner();\n\t\t\t\t\tif (sourceDone) a.down([[COMPLETE]]);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// Inner active — drop, settle the dep-wave\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tdeactivation: () => {\n\t\t\t\t\tclearInner();\n\t\t\t\t\tsourceDone = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...operatorOpts(opts), completeWhenDepsComplete: false },\n\t);\n}\n\n/**\n * Enqueues each outer value and subscribes to inners one at a time (`concatMap`).\n *\n * @param source - Upstream node.\n * @param project - Maps each outer value to an inner source shape (`Node`, scalar, `PromiseLike`, `Iterable`, or `AsyncIterable`) coerced via {@link fromAny}.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<R>` - Sequential concatenation of inner streams.\n * @example\n * ```ts\n * import { concatMap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * concatMap(state(0), (n) => state((n as number) + 1));\n * ```\n *\n * @category extra\n */\nexport function concatMap<T, R>(\n\tsource: Node<T>,\n\tproject: (value: T) => NodeInput<R>,\n\topts?: ExtraOpts & { maxBuffer?: number },\n): Node<R> {\n\tconst { maxBuffer: maxBuf, ...concatNodeOpts } = opts ?? {};\n\tconst queue: T[] = [];\n\tlet innerUnsub: (() => void) | undefined;\n\tlet sourceDone = false;\n\tlet actions: NodeActions | undefined;\n\n\tfunction clearInner(): void {\n\t\tinnerUnsub?.();\n\t\tinnerUnsub = undefined;\n\t}\n\n\tfunction tryPump(): void {\n\t\tif (!actions || innerUnsub !== undefined) return;\n\t\tif (queue.length === 0) {\n\t\t\tif (sourceDone) actions.down([[COMPLETE]]);\n\t\t\treturn;\n\t\t}\n\t\tconst v = queue.shift()!;\n\t\tinnerUnsub = forwardInner(fromAny(project(v)), actions, () => {\n\t\t\tclearInner();\n\t\t\ttryPump();\n\t\t});\n\t}\n\n\tfunction enqueue(v: T): void {\n\t\tif (maxBuf && maxBuf > 0 && queue.length >= maxBuf) queue.shift();\n\t\tqueue.push(v);\n\t\ttryPump();\n\t}\n\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tactions = a;\n\n\t\t\tif (ctx.terminalDeps[0] != null && ctx.terminalDeps[0] !== true) {\n\t\t\t\tclearInner();\n\t\t\t\tqueue.length = 0;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tsourceDone = true;\n\t\t\t\ttryPump();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\n\t\t\tfor (const v of batch0 as T[]) {\n\t\t\t\tenqueue(v as T);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tdeactivation: () => {\n\t\t\t\t\tclearInner();\n\t\t\t\t\tqueue.length = 0;\n\t\t\t\t\tsourceDone = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...operatorOpts(concatNodeOpts), completeWhenDepsComplete: false },\n\t);\n}\n\n/** Options for {@link mergeMap}. */\nexport type MergeMapOptions = ExtraOpts & {\n\t/** Maximum number of concurrent inner subscriptions. Default: `Infinity` (unbounded). */\n\tconcurrent?: number;\n};\n\n/**\n * Subscribes to inner nodes in parallel (up to `concurrent`) and merges outputs (`mergeMap` / `flatMap`).\n *\n * @param source - Upstream node.\n * @param project - Maps each outer value to an inner source shape (`Node`, scalar, `PromiseLike`, `Iterable`, or `AsyncIterable`) coerced via {@link fromAny}.\n * @param opts - Optional options including `concurrent` limit.\n * @returns `Node<R>` - Merged output of all active inners; completes when the outer and every inner complete.\n *\n * @remarks\n * **ERROR handling:** An `ERROR` from the outer source cancels all active inner\n * subscriptions and propagates the error downstream. An `ERROR` from an inner\n * subscription propagates downstream immediately but does **not** cancel sibling\n * inner subscriptions — other active inners continue until they complete or the\n * outer errors/completes. This is intentional: for parallel work, isolating\n * failures per-inner is more useful than Rx-style \"first error cancels all.\"\n *\n * @example\n * ```ts\n * import { mergeMap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * // Unbounded (default)\n * mergeMap(state(0), (n) => state((n as number) + 1));\n *\n * // Limited concurrency\n * mergeMap(state(0), (n) => state((n as number) + 1), { concurrent: 3 });\n * ```\n *\n * @category extra\n */\nexport function mergeMap<T, R>(\n\tsource: Node<T>,\n\tproject: (value: T) => NodeInput<R>,\n\topts?: MergeMapOptions,\n): Node<R> {\n\tconst { concurrent: concurrentOpt, ...mergeNodeOpts } = opts ?? {};\n\tconst maxConcurrent =\n\t\tconcurrentOpt != null && concurrentOpt > 0 ? concurrentOpt : Number.POSITIVE_INFINITY;\n\n\tlet active = 0;\n\tlet sourceDone = false;\n\tconst innerStops = new Set<() => void>();\n\tconst buffer: T[] = [];\n\tlet actions: NodeActions | undefined;\n\n\tfunction tryComplete(): void {\n\t\tif (sourceDone && active === 0 && buffer.length === 0 && actions) {\n\t\t\tactions.down([[COMPLETE]]);\n\t\t}\n\t}\n\n\tfunction spawn(v: T): void {\n\t\tif (!actions) return;\n\t\tactive++;\n\t\t// Use `let` (not `const`) so the closure can reference `stop` safely even\n\t\t// if onInnerComplete fires synchronously (e.g. already-completed inner node).\n\t\tlet stop: (() => void) | undefined;\n\t\tstop = forwardInner(fromAny(project(v)), actions, () => {\n\t\t\tif (stop) innerStops.delete(stop);\n\t\t\tactive--;\n\t\t\tdrainBuffer();\n\t\t\ttryComplete();\n\t\t});\n\t\tinnerStops.add(stop);\n\t}\n\n\tfunction drainBuffer(): void {\n\t\twhile (buffer.length > 0 && active < maxConcurrent) {\n\t\t\tspawn(buffer.shift()!);\n\t\t}\n\t}\n\n\tfunction enqueue(v: T): void {\n\t\tif (active < maxConcurrent) spawn(v);\n\t\telse buffer.push(v);\n\t}\n\n\tfunction clearAll(): void {\n\t\tfor (const u of innerStops) u();\n\t\tinnerStops.clear();\n\t\tactive = 0;\n\t\tbuffer.length = 0;\n\t}\n\n\treturn node<R>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tactions = a;\n\n\t\t\tif (ctx.terminalDeps[0] != null && ctx.terminalDeps[0] !== true) {\n\t\t\t\tclearAll();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (ctx.terminalDeps[0] === true) {\n\t\t\t\tsourceDone = true;\n\t\t\t\ttryComplete();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\n\t\t\tfor (const v of batch0 as T[]) {\n\t\t\t\tenqueue(v as T);\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tdeactivation: () => {\n\t\t\t\t\tclearAll();\n\t\t\t\t\tsourceDone = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...operatorOpts(mergeNodeOpts), completeWhenDepsComplete: false },\n\t);\n}\n\n/**\n * RxJS-named alias for {@link mergeMap} — projects each `DATA` to an inner node and merges outputs.\n *\n * @param source - Upstream node.\n * @param project - Returns an inner `Node<R>` per value.\n * @param opts - Optional concurrency cap and node options (excluding `describeKind`).\n * @returns Merged projection; behavior matches `mergeMap`.\n *\n * @example\n * ```ts\n * import { flatMap, state } from \"@graphrefly/graphrefly-ts\";\n *\n * flatMap(state(0), (n) => state(n));\n * ```\n *\n * @category extra\n */\nexport const flatMap = mergeMap;\n\n/**\n * Delays phase-2 emissions by `ms` (timers). `DIRTY` still forwards immediately.\n *\n * @param source - Upstream node.\n * @param ms - Delay in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Same values, shifted in time.\n * @example\n * ```ts\n * import { delay, state } from \"@graphrefly/graphrefly-ts\";\n *\n * delay(state(1), 100);\n * ```\n *\n * @category extra\n */\nexport function delay<T>(source: Node<T>, ms: number, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\tconst timers = new Set<ReturnType<typeof setTimeout>>();\n\t\tfunction clearAll(): void {\n\t\t\tfor (const id of timers) clearTimeout(id);\n\t\t\ttimers.clear();\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tconst id = setTimeout(() => {\n\t\t\t\t\t\ttimers.delete(id);\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t}, ms);\n\t\t\t\t\ttimers.add(id);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t// Wait for all pending timers, then complete\n\t\t\t\t\tconst id = setTimeout(() => {\n\t\t\t\t\t\ttimers.delete(id);\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t}, ms);\n\t\t\t\t\ttimers.add(id);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tclearAll();\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t\t// DIRTY from source is NOT forwarded — delay transforms the\n\t\t\t\t// timeline. a.emit(v) in the timer callback handles full\n\t\t\t\t// DIRTY+DATA framing atomically at the delayed time.\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearAll();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Emits the latest value only after `ms` quiet time since the last trigger (`debounce`).\n *\n * @param source - Upstream node.\n * @param ms - Quiet window in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Debounced stream.\n * @example\n * ```ts\n * import { debounce, state } from \"@graphrefly/graphrefly-ts\";\n *\n * debounce(state(0), 50);\n * ```\n *\n * @category extra\n */\nexport function debounce<T>(source: Node<T>, ms: number, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet pending: T | undefined;\n\n\t\tfunction clearTimer(): void {\n\t\t\tif (timer !== undefined) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\ttimer = undefined;\n\t\t\t}\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tclearTimer();\n\t\t\t\t\tpending = m[1] as T;\n\t\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\t\ttimer = undefined;\n\t\t\t\t\t\ta.emit(pending as T);\n\t\t\t\t\t}, ms);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tif (timer !== undefined) {\n\t\t\t\t\t\tclearTimer();\n\t\t\t\t\t\ta.emit(pending as T);\n\t\t\t\t\t}\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tclearTimer();\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearTimer();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\nexport type ThrottleOptions = { leading?: boolean; trailing?: boolean };\n\n/**\n * Rate-limits emissions to at most once per `ms` window (`throttleTime`).\n *\n * @param source - Upstream node.\n * @param ms - Minimum spacing in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`) plus `leading` / `trailing`.\n * @returns `Node<T>` - Throttled stream.\n * @example\n * ```ts\n * import { throttle, state } from \"@graphrefly/graphrefly-ts\";\n *\n * throttle(state(0), 1_000, { trailing: false });\n * ```\n *\n * @category extra\n */\nexport function throttle<T>(\n\tsource: Node<T>,\n\tms: number,\n\topts?: ExtraOpts & ThrottleOptions,\n): Node<T> {\n\tconst { leading: leadingOpt, trailing: trailingOpt, ...throttleNodeOpts } = opts ?? {};\n\tconst leading = leadingOpt !== false;\n\tconst trailing = trailingOpt === true;\n\tconst windowNs = ms * NS_PER_MS;\n\n\treturn producer<T>((a) => {\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet lastEmitNs = -Infinity;\n\t\tlet pending: T | undefined;\n\t\tlet hasPending = false;\n\n\t\tfunction clearTimer(): void {\n\t\t\tif (timer !== undefined) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\ttimer = undefined;\n\t\t\t}\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tconst v = m[1] as T;\n\t\t\t\t\tconst nowNs = monotonicNs();\n\t\t\t\t\tif (leading && nowNs - lastEmitNs >= windowNs) {\n\t\t\t\t\t\tlastEmitNs = nowNs;\n\t\t\t\t\t\ta.emit(v);\n\t\t\t\t\t\tclearTimer();\n\t\t\t\t\t\tif (trailing) {\n\t\t\t\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\t\t\t\ttimer = undefined;\n\t\t\t\t\t\t\t\tif (hasPending) {\n\t\t\t\t\t\t\t\t\tlastEmitNs = monotonicNs();\n\t\t\t\t\t\t\t\t\ta.emit(pending as T);\n\t\t\t\t\t\t\t\t\thasPending = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}, ms);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (trailing) {\n\t\t\t\t\t\tpending = v;\n\t\t\t\t\t\thasPending = true;\n\t\t\t\t\t\tif (timer === undefined) {\n\t\t\t\t\t\t\tconst elapsedMs = (nowNs - lastEmitNs) / NS_PER_MS;\n\t\t\t\t\t\t\ttimer = setTimeout(\n\t\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\t\ttimer = undefined;\n\t\t\t\t\t\t\t\t\tif (hasPending) {\n\t\t\t\t\t\t\t\t\t\tlastEmitNs = monotonicNs();\n\t\t\t\t\t\t\t\t\t\ta.emit(pending as T);\n\t\t\t\t\t\t\t\t\t\thasPending = false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tMath.max(0, ms - elapsedMs),\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} else if (m[0] === COMPLETE || m[0] === ERROR) {\n\t\t\t\t\tclearTimer();\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearTimer();\n\t\t};\n\t}, operatorOpts(throttleNodeOpts));\n}\n\n/**\n * Emits the most recent source value whenever `notifier` emits `DATA` (`sample`).\n *\n * Source `COMPLETE` stops sampling (clears held value); notifier `COMPLETE` terminates the\n * operator. `ERROR` from either dep terminates immediately. At most one terminal message is\n * emitted downstream (latch). Supports `resubscribable` — `ctx.store` resets automatically.\n *\n * @param source - Node whose latest value is sampled.\n * @param notifier - When this node emits `DATA`, a sample is taken.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Sampled snapshots of `source`.\n * @example\n * ```ts\n * import { sample, state } from \"@graphrefly/graphrefly-ts\";\n *\n * sample(state(1), state(0));\n * ```\n *\n * @category extra\n */\nexport function sample<T>(source: Node<T>, notifier: Node<unknown>, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet lastSourceValue: { v: T } | undefined;\n\t\tlet terminated = false;\n\t\tlet sourceCompleted = false;\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tif (terminated) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (terminated) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tlastSourceValue = { v: m[1] as T };\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tterminated = true;\n\t\t\t\t\ta.down([m]);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tsourceCompleted = true;\n\t\t\t\t\tlastSourceValue = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst notUnsub = notifier.subscribe((msgs) => {\n\t\t\tif (terminated) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (terminated) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tif (lastSourceValue !== undefined && !sourceCompleted) {\n\t\t\t\t\t\ta.emit(lastSourceValue.v);\n\t\t\t\t\t}\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tterminated = true;\n\t\t\t\t\ta.down([m]);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tterminated = true;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tnotUnsub();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * After each source `DATA`, waits `ms` then emits the latest value if another `DATA` has not arrived (`auditTime` / trailing window).\n *\n * @param source - Upstream node.\n * @param ms - Window in milliseconds after each `DATA`.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Trailing-edge sampled stream.\n * @example\n * ```ts\n * import { audit, state } from \"@graphrefly/graphrefly-ts\";\n *\n * audit(state(0), 100);\n * ```\n *\n * @category extra\n */\nexport function audit<T>(source: Node<T>, ms: number, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet latest: T | undefined;\n\t\tlet has = false;\n\n\t\tfunction clearTimer(): void {\n\t\t\tif (timer !== undefined) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\ttimer = undefined;\n\t\t\t}\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tlatest = m[1] as T;\n\t\t\t\t\thas = true;\n\t\t\t\t\tclearTimer();\n\t\t\t\t\ttimer = setTimeout(() => {\n\t\t\t\t\t\ttimer = undefined;\n\t\t\t\t\t\tif (has) {\n\t\t\t\t\t\t\thas = false;\n\t\t\t\t\t\t\ta.emit(latest as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, ms);\n\t\t\t\t} else if (m[0] === COMPLETE || m[0] === ERROR) {\n\t\t\t\t\tclearTimer();\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearTimer();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Errors if no `DATA` arrives within `ms` after subscribe or after the previous `DATA`.\n *\n * @param source - Upstream node.\n * @param ms - Idle budget in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`) and `with` for a custom error payload.\n * @returns `Node<T>` - Pass-through with idle watchdog.\n * @example\n * ```ts\n * import { timeout, state } from \"@graphrefly/graphrefly-ts\";\n *\n * timeout(state(0), 5_000);\n * ```\n *\n * @category extra\n */\nexport function timeout<T>(\n\tsource: Node<T>,\n\tms: number,\n\topts?: ExtraOpts & { with?: unknown },\n): Node<T> {\n\tconst { with: withPayload, ...timeoutNodeOpts } = opts ?? {};\n\tconst err = withPayload ?? new Error(\"timeout\");\n\n\treturn producer<T>((a) => {\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\n\t\tfunction arm(): void {\n\t\t\tclearTimeout(timer);\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\ttimer = undefined;\n\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t}, ms);\n\t\t}\n\n\t\t// Arm immediately on subscribe\n\t\tarm();\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tarm();\n\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t} else if (m[0] === COMPLETE || m[0] === ERROR) {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearTimeout(timer);\n\t\t};\n\t}, operatorOpts(timeoutNodeOpts));\n}\n\n/**\n * Buffers source `DATA` values; flushes an array when `notifier` settles (`buffer`).\n *\n * @param source - Upstream node.\n * @param notifier - Flush trigger on each settlement.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T[]>` - Emits buffered arrays (may be empty-handled via `RESOLVED` when nothing buffered).\n * @example\n * ```ts\n * import { buffer, state } from \"@graphrefly/graphrefly-ts\";\n *\n * buffer(state(0), state(0));\n * ```\n *\n * @category extra\n */\nexport function buffer<T>(source: Node<T>, notifier: Node<unknown>, opts?: ExtraOpts): Node<T[]> {\n\treturn producer<T[]>((a) => {\n\t\tconst buf: T[] = [];\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tbuf.push(m[1] as T);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tif (buf.length > 0) a.emit([...buf]);\n\t\t\t\t\tbuf.length = 0;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst notUnsub = notifier.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tif (buf.length > 0) {\n\t\t\t\t\t\ta.emit([...buf]);\n\t\t\t\t\t\tbuf.length = 0;\n\t\t\t\t\t}\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t// Notifier complete — forward\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tnotUnsub();\n\t\t\tbuf.length = 0;\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Batches consecutive `DATA` values into arrays of length `count` (`bufferCount` / `windowCount`).\n *\n * @param source - Upstream node.\n * @param count - Buffer size before emit; must be > 0.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T[]>` - Emits fixed-size arrays; remainder flushes on `COMPLETE`.\n * @example\n * ```ts\n * import { bufferCount, state } from \"@graphrefly/graphrefly-ts\";\n *\n * bufferCount(state(0), 3);\n * ```\n *\n * @category extra\n */\nexport function bufferCount<T>(source: Node<T>, count: number, opts?: ExtraOpts): Node<T[]> {\n\tif (count <= 0) throw new RangeError(\"bufferCount expects count > 0\");\n\treturn producer<T[]>((a) => {\n\t\tconst buf: T[] = [];\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tbuf.push(m[1] as T);\n\t\t\t\t\tif (buf.length >= count) {\n\t\t\t\t\t\ta.emit(buf.splice(0, buf.length));\n\t\t\t\t\t}\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tif (buf.length > 0) a.emit([...buf]);\n\t\t\t\t\tbuf.length = 0;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tbuf.length = 0;\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Splits source `DATA` into sub-nodes of `count` values each. Each sub-node completes after `count` items or when source completes.\n *\n * @param source - Upstream node.\n * @param count - Items per window.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<Node<T>>` - Each emission is a sub-node carrying that window's values.\n *\n * @example\n * ```ts\n * import { windowCount, state } from \"@graphrefly/graphrefly-ts\";\n *\n * windowCount(state(0), 3);\n * ```\n *\n * @category extra\n */\nexport function windowCount<T>(source: Node<T>, count: number, opts?: ExtraOpts): Node<Node<T>> {\n\tif (count <= 0) throw new RangeError(\"windowCount expects count > 0\");\n\n\treturn producer<Node<T>>((a) => {\n\t\tlet winDown: ((msgs: Messages) => void) | undefined;\n\t\tlet n = 0;\n\n\t\tfunction openWindow(): void {\n\t\t\tconst s = producer<T>((actions) => {\n\t\t\t\twinDown = actions.down.bind(actions);\n\t\t\t\treturn () => {\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t};\n\t\t\t}, operatorOpts());\n\t\t\tn = 0;\n\t\t\ta.emit(s);\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tif (!winDown) openWindow();\n\t\t\t\t\twinDown?.([[DATA, m[1]]]);\n\t\t\t\t\tn += 1;\n\t\t\t\t\tif (n >= count) {\n\t\t\t\t\t\twinDown?.([[COMPLETE]]);\n\t\t\t\t\t\twinDown = undefined;\n\t\t\t\t\t}\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\twinDown?.([[COMPLETE]]);\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\twinDown?.([m]);\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\twinDown?.([[COMPLETE]]);\n\t\t\twinDown = undefined;\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Flushes buffered `DATA` values every `ms` (`bufferTime` / `windowTime`).\n *\n * @param source - Upstream node.\n * @param ms - Flush interval in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T[]>` - Time-windowed batches.\n * @example\n * ```ts\n * import { bufferTime, state } from \"@graphrefly/graphrefly-ts\";\n *\n * bufferTime(state(0), 250);\n * ```\n *\n * @category extra\n */\nexport function bufferTime<T>(source: Node<T>, ms: number, opts?: ExtraOpts): Node<T[]> {\n\treturn producer<T[]>((a) => {\n\t\tconst buf: T[] = [];\n\n\t\tconst iv = setInterval(() => {\n\t\t\tif (buf.length > 0) {\n\t\t\t\ta.emit([...buf]);\n\t\t\t\tbuf.length = 0;\n\t\t\t}\n\t\t}, ms);\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tbuf.push(m[1] as T);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tclearInterval(iv);\n\t\t\t\t\tif (buf.length > 0) a.emit([...buf]);\n\t\t\t\t\tbuf.length = 0;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tclearInterval(iv);\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t\t// DIRTY from source is NOT forwarded — bufferTime\n\t\t\t\t// transforms the timeline. a.emit(buf) handles full\n\t\t\t\t// DIRTY+DATA framing when the interval fires.\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearInterval(iv);\n\t\t\tbuf.length = 0;\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Splits source `DATA` into time-windowed sub-nodes; each window lasts `ms`.\n *\n * @param source - Upstream node.\n * @param ms - Window duration in milliseconds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<Node<T>>` - Each emission is a sub-node carrying that window's values.\n *\n * @example\n * ```ts\n * import { windowTime, state } from \"@graphrefly/graphrefly-ts\";\n *\n * windowTime(state(0), 500);\n * ```\n *\n * @category extra\n */\nexport function windowTime<T>(source: Node<T>, ms: number, opts?: ExtraOpts): Node<Node<T>> {\n\treturn producer<Node<T>>((a) => {\n\t\tlet winDown: ((msgs: Messages) => void) | undefined;\n\n\t\tfunction closeWindow(): void {\n\t\t\twinDown?.([[COMPLETE]]);\n\t\t\twinDown = undefined;\n\t\t}\n\n\t\tfunction openWindow(): void {\n\t\t\tconst s = producer<T>((actions) => {\n\t\t\t\twinDown = actions.down.bind(actions);\n\t\t\t\treturn () => {\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t};\n\t\t\t}, operatorOpts());\n\t\t\ta.emit(s);\n\t\t}\n\n\t\topenWindow();\n\t\tconst iv = setInterval(() => {\n\t\t\tcloseWindow();\n\t\t\topenWindow();\n\t\t}, ms);\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\twinDown?.([[DATA, m[1]]]);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tclearInterval(iv);\n\t\t\t\t\tcloseWindow();\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tclearInterval(iv);\n\t\t\t\t\twinDown?.([m]);\n\t\t\t\t\tcloseWindow();\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tclearInterval(iv);\n\t\t\tcloseWindow();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Splits source `DATA` into sub-nodes, opening a new window each time `notifier` emits `DATA`.\n *\n * @param source - Upstream node.\n * @param notifier - Each `DATA` from `notifier` closes the current window and opens a new one.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<Node<T>>` - Each emission is a sub-node carrying that window's values.\n *\n * @example\n * ```ts\n * import { state, window } from \"@graphrefly/graphrefly-ts\";\n *\n * window(state(0), state(0));\n * ```\n *\n * @category extra\n */\nexport function window<T>(\n\tsource: Node<T>,\n\tnotifier: Node<unknown>,\n\topts?: ExtraOpts,\n): Node<Node<T>> {\n\treturn producer<Node<T>>((a) => {\n\t\tlet winDown: ((msgs: Messages) => void) | undefined;\n\n\t\tfunction closeWindow(): void {\n\t\t\twinDown?.([[COMPLETE]]);\n\t\t\twinDown = undefined;\n\t\t}\n\n\t\tfunction openWindow(): void {\n\t\t\tconst s = producer<T>((actions) => {\n\t\t\t\twinDown = actions.down.bind(actions);\n\t\t\t\treturn () => {\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t};\n\t\t\t}, operatorOpts());\n\t\t\ta.emit(s);\n\t\t}\n\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tif (!winDown) openWindow();\n\t\t\t\t\twinDown?.([[DATA, m[1]]]);\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tcloseWindow();\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\twinDown?.([m]);\n\t\t\t\t\twinDown = undefined;\n\t\t\t\t\ta.down([m]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tconst notUnsub = notifier.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tcloseWindow();\n\t\t\t\t\topenWindow();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t\tnotUnsub();\n\t\t\tcloseWindow();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Increments on each tick (`interval`); uses `setInterval` via {@link producer}.\n *\n * @param periodMs - Time between ticks.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<number>` - Emits `0`, `1`, `2`, … while subscribed.\n * @example\n * ```ts\n * import { interval } from \"@graphrefly/graphrefly-ts\";\n *\n * interval(1_000);\n * ```\n *\n * @category extra\n */\nexport function interval(periodMs: number, opts?: ExtraOpts): Node<number> {\n\treturn producer<number>((a, ctx) => {\n\t\tif (!(\"n\" in ctx.store)) ctx.store.n = 0;\n\t\tconst id = setInterval(() => {\n\t\t\ta.emit(ctx.store.n as number);\n\t\t\tctx.store.n = (ctx.store.n as number) + 1;\n\t\t}, periodMs);\n\t\treturn () => clearInterval(id);\n\t}, operatorOpts(opts));\n}\n\n/**\n * Subscribes to `source` repeatedly (`count` times, sequentially). Best with a fresh or `resubscribable` source.\n *\n * @param source - Upstream node to replay.\n * @param count - Number of subscription rounds.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Forwards each round then completes after the last inner `COMPLETE`.\n * @example\n * ```ts\n * import { repeat, state } from \"@graphrefly/graphrefly-ts\";\n *\n * repeat(state(1, { resubscribable: true }), 2);\n * ```\n *\n * @category extra\n */\nexport function repeat<T>(source: Node<T>, count: number, opts?: ExtraOpts): Node<T> {\n\tif (count <= 0) throw new RangeError(\"repeat expects count > 0\");\n\treturn producer<T>((a) => {\n\t\tlet remaining = count;\n\t\tlet innerU: (() => void) | undefined;\n\n\t\tconst start = (): void => {\n\t\t\tinnerU?.();\n\t\t\tinnerU = source.subscribe((msgs) => {\n\t\t\t\tlet completed = false;\n\t\t\t\tconst fwd: Message[] = [];\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === COMPLETE) completed = true;\n\t\t\t\t\telse fwd.push(m);\n\t\t\t\t}\n\t\t\t\tif (fwd.length > 0) a.down(fwd as unknown as Messages);\n\t\t\t\tif (completed) {\n\t\t\t\t\tinnerU?.();\n\t\t\t\t\tinnerU = undefined;\n\t\t\t\t\tremaining -= 1;\n\t\t\t\t\tif (remaining > 0) start();\n\t\t\t\t\telse a.down([[COMPLETE]]);\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\n\t\tstart();\n\t\treturn () => {\n\t\t\tinnerU?.();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Identity passthrough — `pausable()` has been promoted to default node behavior in v5 (§4).\n *\n * @deprecated Default node behavior now handles PAUSE/RESUME. This operator is a no-op\n * identity passthrough kept only for migration compatibility.\n *\n * @param source - Upstream node.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Pass-through (identity).\n * @example\n * ```ts\n * import { pausable, state } from \"@graphrefly/graphrefly-ts\";\n *\n * // No longer needed — default nodes handle PAUSE/RESUME.\n * const s = state(0);\n * pausable(s); // identity passthrough\n * ```\n *\n * @category extra\n */\nexport function pausable<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfor (const v of batch0) a.emit(v as T);\n\t\t},\n\t\toperatorOpts<T>(opts),\n\t);\n}\n\n/**\n * Replaces an upstream `ERROR` with a recovered value (`catchError`-style).\n *\n * @param source - Upstream node.\n * @param recover - Maps the error payload to a replacement value; if it throws, `ERROR` is forwarded.\n * @param opts - Optional {@link NodeOptions} (excluding `describeKind`).\n * @returns `Node<T>` - Recovered stream.\n * @example\n * ```ts\n * import { rescue, state } from \"@graphrefly/graphrefly-ts\";\n *\n * rescue(state(0), () => 0);\n * ```\n *\n * @category extra\n */\nexport function rescue<T>(\n\tsource: Node<T>,\n\trecover: (err: unknown) => T,\n\topts?: ExtraOpts,\n): Node<T> {\n\treturn producer<T>((a) => {\n\t\tconst srcUnsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ta.emit(recover(m[1]));\n\t\t\t\t\t} catch (recoverErr) {\n\t\t\t\t\t\ta.down([[ERROR, recoverErr]]);\n\t\t\t\t\t}\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn () => {\n\t\t\tsrcUnsub();\n\t\t};\n\t}, operatorOpts(opts));\n}\n\n/**\n * Forwards upstream `DATA` only while `control.get()` is truthy; when closed, emits `RESOLVED`\n * instead of repeating the last value (value-level valve). For protocol pause/resume, use default\n * node PAUSE/RESUME behavior.\n *\n * @param source - Upstream value node.\n * @param control - Boolean node; when falsy, output stays \"closed\" for that tick.\n * @param opts - Optional node options (excluding `describeKind`).\n * @returns `Node<T>` gated by `control`.\n *\n * @example\n * ```ts\n * import { valve, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const data = state(1);\n * const open = state(true);\n * valve(data, open);\n * ```\n *\n * @category extra\n */\nexport function valve<T>(source: Node<T>, control: Node<boolean>, opts?: ExtraOpts): Node<T> {\n\treturn node<T>(\n\t\t[source as Node, control as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch1 = data[1];\n\t\t\t// undefined = control never sent DATA (gate closed); falsy = explicitly closed.\n\t\t\tconst controlValue = batch1 != null && batch1.length > 0 ? batch1.at(-1) : ctx.prevData[1];\n\t\t\tif (!controlValue) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\t// Source data this wave: forward it.\n\t\t\t\tfor (const v of batch0) a.emit(v as T);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Control just opened this wave but source didn't fire this wave.\n\t\t\t// Re-emit the last known source value so downstream sees the current\n\t\t\t// value when the gate opens (only when source has a prior value).\n\t\t\tif (batch1 != null && batch1.length > 0 && ctx.prevData[0] !== undefined) {\n\t\t\t\ta.emit(ctx.prevData[0] as T);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ta.down([[RESOLVED]]);\n\t\t},\n\t\toperatorOpts(opts),\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// RxJS-compatible aliases — improve AI code-generation accuracy\n// ——————————————————————————————————————————————————————————————\n\n/**\n * RxJS-named alias for {@link combine} — emits when any dep updates with latest tuple of values.\n *\n * @param sources - Upstream nodes as separate arguments (same calling shape as `combine`).\n * @returns Combined node; signature matches `combine`.\n *\n * @example\n * ```ts\n * import { combineLatest, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const n = combineLatest(state(1), state(\"a\"));\n * ```\n *\n * @category extra\n */\nexport const combineLatest = combine;\n\n/**\n * RxJS-named alias for {@link debounce} — drops rapid `DATA` until `ms` of quiet.\n *\n * @param source - Upstream node.\n * @param ms - Quiet period in milliseconds.\n * @param opts - Optional node options (excluding `describeKind`).\n * @returns Debounced node; behavior matches `debounce`.\n *\n * @example\n * ```ts\n * import { debounceTime, state } from \"@graphrefly/graphrefly-ts\";\n *\n * debounceTime(state(0), 100);\n * ```\n *\n * @category extra\n */\nexport const debounceTime = debounce;\n\n/**\n * RxJS-named alias for {@link throttle} — emits on leading/trailing edges within `ms`.\n *\n * @param source - Upstream node.\n * @param ms - Minimum spacing in milliseconds.\n * @param opts - Optional throttle shape (`leading` / `trailing`) and node options.\n * @returns Throttled node; behavior matches `throttle`.\n *\n * @example\n * ```ts\n * import { throttleTime, state } from \"@graphrefly/graphrefly-ts\";\n *\n * throttleTime(state(0), 100);\n * ```\n *\n * @category extra\n */\nexport const throttleTime = throttle;\n\n/**\n * RxJS-named alias for {@link rescue} — replaces upstream `ERROR` with a recovered value.\n *\n * @param source - Upstream node.\n * @param recover - Maps error payload to replacement value.\n * @param opts - Optional node options (excluding `describeKind`).\n * @returns Recovered stream; behavior matches `rescue`.\n *\n * @example\n * ```ts\n * import { catchError, state } from \"@graphrefly/graphrefly-ts\";\n *\n * catchError(state(0), () => 0);\n * ```\n *\n * @category extra\n */\nexport const catchError = rescue;\n","/**\n * Fixed-capacity ring buffer — O(1) push and drop-oldest eviction.\n *\n * Used by `Graph._traceRing` (reasoning trace), `reactiveLog` (append-only\n * log backend), and `reactiveSink` (drop-oldest backpressure buffer). One\n * implementation, three use sites.\n *\n * @module\n * @internal\n */\n\n/**\n * Fixed-capacity ring buffer. Once `capacity` entries are stored, subsequent\n * `push` calls evict the oldest entry (drop-oldest / FIFO eviction).\n *\n * Operations:\n * - `push(item)` — O(1).\n * - `shift()` — O(1) remove oldest (returns `undefined` when empty).\n * - `at(i)` — O(1) index lookup, with Python-style negative indexing.\n * - `toArray()` — O(n) materialize in insertion order.\n * - `clear()` — O(1) reset to empty.\n *\n * Not thread-safe; JS semantics assumed (single-threaded within a sync call).\n */\nexport class RingBuffer<T> {\n\tprivate buf: (T | undefined)[];\n\tprivate head = 0;\n\tprivate _size = 0;\n\n\tconstructor(private capacity: number) {\n\t\tif (!Number.isInteger(capacity) || capacity <= 0) {\n\t\t\tthrow new Error(`RingBuffer capacity must be a positive integer (got ${capacity})`);\n\t\t}\n\t\tthis.buf = new Array(capacity);\n\t}\n\n\t/** Current number of stored entries. */\n\tget size(): number {\n\t\treturn this._size;\n\t}\n\n\t/** Configured maximum before drop-oldest eviction fires. */\n\tget maxSize(): number {\n\t\treturn this.capacity;\n\t}\n\n\t/**\n\t * Append an item. If size equals capacity, drops the oldest entry and\n\t * advances the head pointer.\n\t */\n\tpush(item: T): void {\n\t\tconst idx = (this.head + this._size) % this.capacity;\n\t\tthis.buf[idx] = item;\n\t\tif (this._size < this.capacity) this._size++;\n\t\telse this.head = (this.head + 1) % this.capacity;\n\t}\n\n\t/** Remove and return the oldest entry; `undefined` when empty. */\n\tshift(): T | undefined {\n\t\tif (this._size === 0) return undefined;\n\t\tconst item = this.buf[this.head];\n\t\tthis.buf[this.head] = undefined;\n\t\tthis.head = (this.head + 1) % this.capacity;\n\t\tthis._size--;\n\t\treturn item;\n\t}\n\n\t/**\n\t * O(1) index lookup. Negative indices count from the tail (Python-style).\n\t * Returns `undefined` for out-of-range.\n\t */\n\tat(i: number): T | undefined {\n\t\tif (this._size === 0) return undefined;\n\t\tconst n = i < 0 ? this._size + i : i;\n\t\tif (n < 0 || n >= this._size) return undefined;\n\t\treturn this.buf[(this.head + n) % this.capacity];\n\t}\n\n\t/**\n\t * Materialize the contents in insertion order (oldest → newest).\n\t * Returns a new array each call.\n\t */\n\ttoArray(): T[] {\n\t\tconst result: T[] = new Array(this._size);\n\t\tfor (let i = 0; i < this._size; i++) {\n\t\t\tresult[i] = this.buf[(this.head + i) % this.capacity]!;\n\t\t}\n\t\treturn result;\n\t}\n\n\t/** Reset to empty. Storage slots are released so held refs can GC. */\n\tclear(): void {\n\t\tfor (let i = 0; i < this._size; i++) {\n\t\t\tthis.buf[(this.head + i) % this.capacity] = undefined;\n\t\t}\n\t\tthis.head = 0;\n\t\tthis._size = 0;\n\t}\n}\n","/**\n * {@link reactiveSink} — canonical sink factory for Wave 5 adapters.\n *\n * Every `to*` adapter in {@link ./adapters.ts} can be expressed as a thin\n * config wrapper around this one factory. It centralizes:\n *\n * - **Transport boundary** — the sole place in the sink layer where a raw\n * Promise / `.then` / `.catch` sits (§5.10 boundary documented here).\n * - **Retry** — delegates to {@link BackoffStrategy} from `backoff.ts`.\n * - **Buffering** — `batchSize` / `flushIntervalMs` with tier-3 flush-on-\n * terminal per spec §5.11. Buffered mode activates when `sendBatch` is\n * supplied or a batching knob is set.\n * - **Backpressure** — bounded internal queue with `drop-oldest` /\n * `drop-newest` / `error` strategies. The `\"wait\"` strategy is deferred\n * to external composition (`source | valve(...) | reactiveSink(...)`).\n * - **Companions** — `sent` / `failed` / `inFlight` / `errors` (+ `buffered`\n * / `paused` when buffering or backpressure is active). These surface\n * every transport outcome as reactive nodes so downstream operators can\n * build retry fallbacks, dead-letter queues, or SLO gauges without\n * touching callback soup.\n */\n\nimport { COMPLETE, DATA, ERROR, type Message, TEARDOWN } from \"../core/messages.js\";\nimport { defaultConfig, type Node } from \"../core/node.js\";\nimport { state } from \"../core/sugar.js\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tresolveBackoffPreset,\n} from \"./backoff.js\";\nimport { RingBuffer } from \"./utils/ring-buffer.js\";\n\n/**\n * Dual-mode buffer for the sink's backpressure queue.\n * - Bounded (finite `maxBuf`): wraps {@link RingBuffer} so drop-oldest is O(1)\n * instead of O(n) via `Array.prototype.shift`.\n * - Unbounded (`Infinity`): plain array — no drops, no need for ring semantics.\n * `drain()` always returns the current contents and resets to empty.\n */\nclass BackpressureBuffer<T> {\n\tprivate ring: RingBuffer<T> | null;\n\tprivate arr: T[] | null;\n\tconstructor(cap: number) {\n\t\tif (cap === Number.POSITIVE_INFINITY || cap <= 0) {\n\t\t\tthis.arr = [];\n\t\t\tthis.ring = null;\n\t\t} else {\n\t\t\tthis.ring = new RingBuffer<T>(cap);\n\t\t\tthis.arr = null;\n\t\t}\n\t}\n\tget length(): number {\n\t\treturn this.ring != null ? this.ring.size : this.arr!.length;\n\t}\n\tpush(item: T): void {\n\t\tif (this.ring != null) this.ring.push(item);\n\t\telse this.arr!.push(item);\n\t}\n\t/** Drop-oldest — O(1) in bounded mode. Returns undefined when empty. */\n\tshift(): T | undefined {\n\t\tif (this.ring != null) return this.ring.shift();\n\t\treturn this.arr!.shift();\n\t}\n\t/** Full drain — returns contents, resets to empty. */\n\tdrain(): T[] {\n\t\tif (this.ring != null) {\n\t\t\tconst out = this.ring.toArray();\n\t\t\tthis.ring.clear();\n\t\t\treturn out;\n\t\t}\n\t\tconst out = this.arr!;\n\t\tthis.arr = [];\n\t\treturn out;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/**\n * Structured transport-failure record. Every sink routes both recoverable\n * (pre-retry) and terminal (post-exhaustion) failures through this shape.\n *\n * @category extra\n */\nexport type SinkTransportError = {\n\t/**\n\t * Failure stage. Known values: `\"serialize\"`, `\"send\"`, `\"close\"`,\n\t * `\"routing_key\"`, `\"ack\"`, `\"retry_exhausted\"`. Open to extension for\n\t * protocol-specific stages.\n\t */\n\tstage: string;\n\t/** The error. */\n\terror: Error;\n\t/** Unwrapped DATA value (present for per-record failures). */\n\tvalue: unknown;\n\t/** Full message tuple (present for non-DATA stages like `\"close\"`). */\n\tmessage?: Message;\n\t/** Attempt number when `retry` is active — `1` = initial send. */\n\tattempt?: number;\n};\n\n/**\n * Terminal failure record delivered on the `failed` companion after retries\n * are exhausted (or `shouldRetry` returned `false`).\n *\n * @category extra\n */\nexport type SinkFailure<T> = {\n\tvalue: T;\n\terror: Error;\n\t/** Total attempts made, including the initial send. */\n\tattempts: number;\n};\n\n/**\n * Handle returned by every Wave 5 sink.\n *\n * @category extra\n */\nexport type ReactiveSinkHandle<T> = {\n\t/** Unsubscribe from source, cancel timers, fire `TEARDOWN` on companions. */\n\tdispose(): void;\n\t/** Drain buffer + await in-flight sends (buffered mode only). */\n\tflush?(): Promise<void>;\n\t/** DATA values that successfully reached the transport. */\n\tsent: Node<T>;\n\t/** Values that permanently failed (after any retries). */\n\tfailed: Node<SinkFailure<T> | null>;\n\t/** Number of pending transport operations. */\n\tinFlight: Node<number>;\n\t/** Every transient transport error (pre-retry). Latest-only. */\n\terrors: Node<SinkTransportError | null>;\n\t/** Items currently buffered (buffered mode / backpressure only). */\n\tbuffered?: Node<number>;\n\t/** `true` when a backpressure strategy has dropped / rejected items. */\n\tpaused?: Node<boolean>;\n};\n\n/**\n * Retry configuration for {@link reactiveSink}.\n *\n * @category extra\n */\nexport type ReactiveSinkRetryOptions = {\n\t/** Total attempts including the initial send. Default: `1` (no retry). */\n\tmaxAttempts?: number;\n\t/** Backoff strategy (ns) or preset name. Default: `\"exponential\"` when `maxAttempts > 1`. */\n\tbackoff?: BackoffStrategy | BackoffPreset;\n\t/** Predicate — return `false` to short-circuit retry for a given error. */\n\tshouldRetry?: (err: Error, attempt: number) => boolean;\n};\n\n/**\n * Backpressure configuration for {@link reactiveSink}. When omitted, the\n * sink has no internal buffer cap beyond the natural `batchSize` /\n * `flushIntervalMs` limits.\n *\n * @category extra\n */\nexport type ReactiveSinkBackpressureOptions = {\n\t/** Hard cap on buffered items; further items trigger `strategy`. Default: `Infinity`. */\n\tmaxBuffer?: number;\n\t/** Policy when the buffer is full. Default: `\"drop-oldest\"`. */\n\tstrategy?: \"drop-oldest\" | \"drop-newest\" | \"error\";\n};\n\n/**\n * Base options shared by every sink built on {@link reactiveSink}.\n *\n * @category extra\n */\nexport type ReactiveSinkOptions<T> = {\n\t/** Optional name used for companion node naming. */\n\tname?: string;\n\t/** Invoked synchronously for every transient transport error. */\n\tonTransportError?: (err: SinkTransportError) => void;\n\t/** Retry configuration. */\n\tretry?: ReactiveSinkRetryOptions;\n\t/** Backpressure configuration. */\n\tbackpressure?: ReactiveSinkBackpressureOptions;\n\t/** Batch size before auto-flush (buffered mode). */\n\tbatchSize?: number;\n\t/** Flush interval in ms; `0` = write-through (buffered mode). */\n\tflushIntervalMs?: number;\n\t/** Optional transform applied before `send` / `sendBatch`. */\n\tserialize?: (value: T) => unknown;\n\t/**\n\t * Reactive stop signal — when this node emits any DATA or terminal, the\n\t * sink tears down. Gives callers a reactive alternative to the imperative\n\t * `handle.dispose()` call so teardown can be wired through the graph.\n\t */\n\tstopOn?: Node<unknown>;\n\t/**\n\t * Optional hook invoked for each upstream non-DATA message (COMPLETE /\n\t * ERROR / etc.) observed by the sink. Used by adapters like\n\t * {@link toWebSocket} to close the underlying resource when the source\n\t * terminates, without the caller having to subscribe twice.\n\t */\n\tonUpstreamMessage?: (msg: Message) => void;\n\t/**\n\t * Invoked once during `dispose()` after the sink's own cleanup (unsub,\n\t * final drain, TEARDOWN on companions). Adapters wrap external resources\n\t * (socket listeners, file handles) by passing their cleanup here —\n\t * avoids hand-rolling a wrapper around `handle.dispose`.\n\t */\n\tonDispose?: () => void;\n\t/**\n\t * Ignored — reserved for future parity with `source.pipe(...)` style.\n\t *\n\t * @internal\n\t */\n\t_reserved?: never;\n};\n\n/**\n * Full config accepted by {@link reactiveSink}. One of `send` / `sendBatch`\n * is required.\n *\n * @category extra\n */\nexport type ReactiveSinkConfig<T, Ctx = unknown> = ReactiveSinkOptions<T> & {\n\t/** Per-record transport call. */\n\tsend?: (value: T, ctx: Ctx) => Promise<void> | void;\n\t/** Batched transport call. When supplied, buffering activates automatically. */\n\tsendBatch?: (batch: T[], ctx: Ctx) => Promise<void> | void;\n\t/** Context object threaded into every `send` / `sendBatch` call. */\n\tctx?: Ctx;\n};\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction coerceError(err: unknown): Error {\n\treturn err instanceof Error ? err : new Error(String(err));\n}\n\nfunction resolveBackoff(\n\tbackoff: BackoffStrategy | BackoffPreset | undefined,\n): BackoffStrategy | null {\n\tif (backoff === undefined) return null;\n\tif (typeof backoff === \"string\") return resolveBackoffPreset(backoff);\n\treturn backoff;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Build a reactive sink with retry / buffering / backpressure / observability\n * companions. Every Wave 5 `to*` adapter is a thin config wrapper around\n * this factory.\n *\n * **Modes:**\n * - `send` only, no batching knobs → **per-record write-through**\n * - `send` + `batchSize` or `flushIntervalMs` → **per-record buffered**\n * (buffer drains via repeated `send` calls — one-by-one in order)\n * - `sendBatch` → **batched** (whole chunks handed to the transport)\n *\n * @category extra\n */\nexport function reactiveSink<T, Ctx = unknown>(\n\tsource: Node<T>,\n\tconfig: ReactiveSinkConfig<T, Ctx>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tname,\n\t\tonTransportError,\n\t\tretry,\n\t\tbackpressure,\n\t\tbatchSize = Number.POSITIVE_INFINITY,\n\t\tflushIntervalMs = 0,\n\t\tserialize,\n\t\tstopOn,\n\t\tonUpstreamMessage,\n\t\tonDispose,\n\t\tsend,\n\t\tsendBatch,\n\t\tctx: ctxValue,\n\t} = config;\n\n\tif (!send && !sendBatch) {\n\t\tthrow new Error(\"reactiveSink: `send` or `sendBatch` must be provided\");\n\t}\n\n\tconst ctx = ctxValue as Ctx;\n\tconst maxAttempts = Math.max(1, retry?.maxAttempts ?? 1);\n\tconst backoffStrategy = resolveBackoff(\n\t\tretry?.backoff ?? (maxAttempts > 1 ? \"exponential\" : undefined),\n\t);\n\tconst shouldRetry = retry?.shouldRetry ?? (() => true);\n\n\tconst useBuffering =\n\t\tsendBatch !== undefined || batchSize < Number.POSITIVE_INFINITY || flushIntervalMs > 0;\n\n\tconst nameFor = (suffix: string) => (name ? `${name}::${suffix}` : undefined);\n\n\tconst sent = state<T | undefined>(undefined, {\n\t\tequals: () => false,\n\t\tname: nameFor(\"sent\"),\n\t}) as unknown as Node<T>;\n\tconst failed = state<SinkFailure<T> | null>(null, { name: nameFor(\"failed\") });\n\tconst inFlightCountNode = state(0, { name: nameFor(\"inFlight\") });\n\tconst errorsNode = state<SinkTransportError | null>(null, { name: nameFor(\"errors\") });\n\tconst bufferedNode = useBuffering ? state(0, { name: nameFor(\"buffered\") }) : undefined;\n\tconst pausedNode = backpressure ? state(false, { name: nameFor(\"paused\") }) : undefined;\n\n\tlet inFlightCount = 0;\n\tconst bumpInFlight = (delta: number) => {\n\t\tinFlightCount += delta;\n\t\tinFlightCountNode.down([[DATA, inFlightCount]]);\n\t};\n\n\tconst reportError = (err: SinkTransportError) => {\n\t\ttry {\n\t\t\tonTransportError?.(err);\n\t\t} catch {\n\t\t\t/* user hook must not escape */\n\t\t}\n\t\ttry {\n\t\t\terrorsNode.down([[DATA, err]]);\n\t\t} catch {\n\t\t\t/* re-entrant drain — swallow */\n\t\t}\n\t};\n\n\tconst inFlightPromises = new Set<Promise<void>>();\n\n\tconst trackPromise = (p: Promise<void>) => {\n\t\tinFlightPromises.add(p);\n\t\tconst done = () => inFlightPromises.delete(p);\n\t\tp.then(done, done);\n\t};\n\n\t// Retry scheduling shared by per-record + batched paths.\n\tconst scheduleRetry = (runAgain: () => Promise<void>, attempt: number, error: Error) => {\n\t\tconst raw = backoffStrategy ? backoffStrategy(attempt - 1, error, null) : 0;\n\t\tconst delayNs =\n\t\t\traw === null || raw === undefined ? 0 : typeof raw === \"number\" && raw > 0 ? raw : 0;\n\t\t// Clamp to >=1ms — sub-ms delays via integer division collapse to 0 and\n\t\t// create synchronous retry loops that starve the event loop.\n\t\tconst delayMs = Math.max(1, Math.ceil(delayNs / NS_PER_MS));\n\t\treturn new Promise<void>((resolve) => {\n\t\t\t// §5.10: retry delay at the transport boundary.\n\t\t\tsetTimeout(() => resolve(runAgain()), delayMs);\n\t\t});\n\t};\n\n\tconst isThenable = (v: unknown): v is Promise<void> =>\n\t\tv != null && typeof v === \"object\" && typeof (v as { then?: unknown }).then === \"function\";\n\n\t// -------------------------------------------------------------------\n\t// Per-record send path — handles retry for a single value.\n\t//\n\t// Sync throws in `serialize` → reported synchronously as stage:\"serialize\".\n\t// Sync throws in `send` → reported synchronously as stage:\"send\".\n\t// Async rejections from send → reported as stage:\"send\" on the next tick.\n\t// -------------------------------------------------------------------\n\tconst performSend = (value: T): Promise<void> => {\n\t\tlet payload: unknown;\n\t\ttry {\n\t\t\tpayload = serialize ? serialize(value) : value;\n\t\t} catch (rawErr) {\n\t\t\tconst error = coerceError(rawErr);\n\t\t\treportError({ stage: \"serialize\", error, value });\n\t\t\tfailed.down([[DATA, { value, error, attempts: 0 } satisfies SinkFailure<T>]]);\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tlet attempt = 0;\n\n\t\tconst onError = (rawErr: unknown): Promise<void> | undefined => {\n\t\t\tbumpInFlight(-1);\n\t\t\tconst error = coerceError(rawErr);\n\t\t\treportError({ stage: \"send\", error, value, attempt });\n\t\t\tconst more = attempt < maxAttempts && shouldRetry(error, attempt);\n\t\t\tif (!more) {\n\t\t\t\tfailed.down([[DATA, { value, error, attempts: attempt } satisfies SinkFailure<T>]]);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn scheduleRetry(run, attempt, error);\n\t\t};\n\n\t\tconst onSuccess = () => {\n\t\t\tbumpInFlight(-1);\n\t\t\tsent.down([[DATA, value]]);\n\t\t};\n\n\t\tfunction run(): Promise<void> {\n\t\t\tattempt += 1;\n\t\t\tbumpInFlight(+1);\n\t\t\tlet result: Promise<void> | void;\n\t\t\ttry {\n\t\t\t\tresult = (send as (v: unknown, c: Ctx) => Promise<void> | void)(payload, ctx);\n\t\t\t} catch (rawErr) {\n\t\t\t\treturn onError(rawErr) ?? Promise.resolve();\n\t\t\t}\n\t\t\tif (isThenable(result)) {\n\t\t\t\treturn result.then(onSuccess, (rawErr) => onError(rawErr));\n\t\t\t}\n\t\t\tonSuccess();\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\treturn run();\n\t};\n\n\t// -------------------------------------------------------------------\n\t// Buffer management (buffered mode).\n\t//\n\t// Buffer entries keep the original value (for failure reporting) alongside\n\t// the post-serialize payload (for the transport call). Serializing at push\n\t// time guarantees sync `stage: \"serialize\"` error reporting — the old\n\t// hand-rolled sinks relied on this ordering.\n\t// -------------------------------------------------------------------\n\ttype BufferEntry = { value: T; payload: unknown };\n\tconst maxBuf = backpressure?.maxBuffer ?? Number.POSITIVE_INFINITY;\n\tconst buffer = new BackpressureBuffer<BufferEntry>(maxBuf);\n\tlet flushTimer: ReturnType<typeof setTimeout> | undefined;\n\tlet disposed = false;\n\n\tconst updateBuffered = () => {\n\t\tbufferedNode?.down([[DATA, buffer.length]]);\n\t};\n\n\tconst markPaused = (paused: boolean) => {\n\t\tif (!pausedNode) return;\n\t\tpausedNode.down([[DATA, paused]]);\n\t};\n\n\tconst bpStrategy = backpressure?.strategy ?? \"drop-oldest\";\n\n\tconst pushWithBackpressure = (value: T, payload: unknown): boolean => {\n\t\tconst entry: BufferEntry = { value, payload };\n\t\tif (buffer.length < maxBuf) {\n\t\t\tbuffer.push(entry);\n\t\t\tupdateBuffered();\n\t\t\treturn true;\n\t\t}\n\t\t// At cap — apply strategy.\n\t\tif (bpStrategy === \"drop-oldest\") {\n\t\t\tconst dropped = buffer.shift() as BufferEntry;\n\t\t\tbuffer.push(entry);\n\t\t\tupdateBuffered();\n\t\t\tmarkPaused(true);\n\t\t\tfailed.down([\n\t\t\t\t[\n\t\t\t\t\tDATA,\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue: dropped.value,\n\t\t\t\t\t\terror: new Error(\"backpressure: buffer overflow — dropped oldest\"),\n\t\t\t\t\t\tattempts: 0,\n\t\t\t\t\t} satisfies SinkFailure<T>,\n\t\t\t\t],\n\t\t\t]);\n\t\t\treturn true;\n\t\t}\n\t\tif (bpStrategy === \"drop-newest\") {\n\t\t\tmarkPaused(true);\n\t\t\tfailed.down([\n\t\t\t\t[\n\t\t\t\t\tDATA,\n\t\t\t\t\t{\n\t\t\t\t\t\tvalue,\n\t\t\t\t\t\terror: new Error(\"backpressure: buffer overflow — dropped newest\"),\n\t\t\t\t\t\tattempts: 0,\n\t\t\t\t\t} satisfies SinkFailure<T>,\n\t\t\t\t],\n\t\t\t]);\n\t\t\treturn false;\n\t\t}\n\t\t// \"error\"\n\t\tconst err = new Error(\"backpressure: buffer overflow\");\n\t\treportError({ stage: \"send\", error: err, value });\n\t\tfailed.down([[DATA, { value, error: err, attempts: 0 } satisfies SinkFailure<T>]]);\n\t\tmarkPaused(true);\n\t\treturn false;\n\t};\n\n\t// Buffered flush: chunk is already serialized at push time. Retry the whole\n\t// chunk on sendBatch failure (or per-record send failure).\n\tconst performBufferedBatchFlush = (chunk: BufferEntry[]): Promise<void> => {\n\t\tlet attempt = 0;\n\t\tconst payloads = chunk.map((e) => e.payload);\n\n\t\tconst onError = (rawErr: unknown): Promise<void> | undefined => {\n\t\t\tbumpInFlight(-1);\n\t\t\tconst error = coerceError(rawErr);\n\t\t\treportError({ stage: \"send\", error, value: chunk.map((e) => e.value), attempt });\n\t\t\tconst more = attempt < maxAttempts && shouldRetry(error, attempt);\n\t\t\tif (!more) {\n\t\t\t\tfor (const { value: v } of chunk) {\n\t\t\t\t\tfailed.down([[DATA, { value: v, error, attempts: attempt } satisfies SinkFailure<T>]]);\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn scheduleRetry(run, attempt, error);\n\t\t};\n\n\t\tconst onSuccess = () => {\n\t\t\tbumpInFlight(-1);\n\t\t\tfor (const { value: v } of chunk) sent.down([[DATA, v]]);\n\t\t};\n\n\t\tfunction run(): Promise<void> {\n\t\t\tattempt += 1;\n\t\t\tbumpInFlight(+1);\n\t\t\tlet result: Promise<void> | void;\n\t\t\ttry {\n\t\t\t\tresult = (sendBatch as (b: unknown[], c: Ctx) => Promise<void> | void)(payloads, ctx);\n\t\t\t} catch (rawErr) {\n\t\t\t\treturn onError(rawErr) ?? Promise.resolve();\n\t\t\t}\n\t\t\tif (isThenable(result)) {\n\t\t\t\treturn result.then(onSuccess, (rawErr) => onError(rawErr));\n\t\t\t}\n\t\t\tonSuccess();\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\treturn run();\n\t};\n\n\tconst performBufferedPerRecordFlush = async (chunk: BufferEntry[]): Promise<void> => {\n\t\tfor (const entry of chunk) {\n\t\t\t// Intentionally do NOT check `disposed` here — a dispose() mid-\n\t\t\t// drain must let the already-captured chunk finish; otherwise\n\t\t\t// buffered items would be dropped silently. `teardownRequested`\n\t\t\t// prevents NEW work from starting (no new subscribe batches past\n\t\t\t// this point), which is the right guard.\n\t\t\tawait performPreSerializedSend(entry.value, entry.payload);\n\t\t}\n\t};\n\n\t// Per-record send that skips re-serialization (buffer already serialized).\n\tconst performPreSerializedSend = (value: T, payload: unknown): Promise<void> => {\n\t\tlet attempt = 0;\n\t\tconst onError = (rawErr: unknown): Promise<void> | undefined => {\n\t\t\tbumpInFlight(-1);\n\t\t\tconst error = coerceError(rawErr);\n\t\t\treportError({ stage: \"send\", error, value, attempt });\n\t\t\tconst more = attempt < maxAttempts && shouldRetry(error, attempt);\n\t\t\tif (!more) {\n\t\t\t\tfailed.down([[DATA, { value, error, attempts: attempt } satisfies SinkFailure<T>]]);\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn scheduleRetry(run, attempt, error);\n\t\t};\n\t\tconst onSuccess = () => {\n\t\t\tbumpInFlight(-1);\n\t\t\tsent.down([[DATA, value]]);\n\t\t};\n\t\tfunction run(): Promise<void> {\n\t\t\tattempt += 1;\n\t\t\tbumpInFlight(+1);\n\t\t\tlet result: Promise<void> | void;\n\t\t\ttry {\n\t\t\t\tresult = (send as (v: unknown, c: Ctx) => Promise<void> | void)(payload, ctx);\n\t\t\t} catch (rawErr) {\n\t\t\t\treturn onError(rawErr) ?? Promise.resolve();\n\t\t\t}\n\t\t\tif (isThenable(result)) {\n\t\t\t\treturn result.then(onSuccess, (rawErr) => onError(rawErr));\n\t\t\t}\n\t\t\tonSuccess();\n\t\t\treturn Promise.resolve();\n\t\t}\n\t\treturn run();\n\t};\n\n\tconst doFlush = (): Promise<void> => {\n\t\tif (disposed || buffer.length === 0) return Promise.resolve();\n\t\tconst chunk = buffer.drain();\n\t\tupdateBuffered();\n\t\tmarkPaused(false);\n\t\tif (sendBatch !== undefined) {\n\t\t\tconst p = performBufferedBatchFlush(chunk);\n\t\t\ttrackPromise(p);\n\t\t\treturn p;\n\t\t}\n\t\tconst p = performBufferedPerRecordFlush(chunk);\n\t\ttrackPromise(p);\n\t\treturn p;\n\t};\n\n\tconst scheduleFlush = () => {\n\t\tif (flushTimer !== undefined || disposed) return;\n\t\tif (flushIntervalMs <= 0) return;\n\t\tflushTimer = setTimeout(() => {\n\t\t\t/* §5.10: flush deadline timer — not reactive scheduling */\n\t\t\tflushTimer = undefined;\n\t\t\tvoid doFlush();\n\t\t}, flushIntervalMs);\n\t};\n\n\t// -------------------------------------------------------------------\n\t// Upstream subscription.\n\t// -------------------------------------------------------------------\n\tconst unsub = source.subscribe((msgs) => {\n\t\tfor (const msg of msgs) {\n\t\t\tconst type = msg[0];\n\t\t\tif (type !== DATA) {\n\t\t\t\ttry {\n\t\t\t\t\tonUpstreamMessage?.(msg);\n\t\t\t\t} catch {\n\t\t\t\t\t/* user hook must not escape */\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (type === DATA) {\n\t\t\t\tconst value = msg[1] as T;\n\t\t\t\tif (useBuffering) {\n\t\t\t\t\t// Serialize sync at push time so `stage: \"serialize\"` errors\n\t\t\t\t\t// surface on the same tick as the upstream DATA emission.\n\t\t\t\t\tlet payload: unknown;\n\t\t\t\t\tif (serialize) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tpayload = serialize(value);\n\t\t\t\t\t\t} catch (rawErr) {\n\t\t\t\t\t\t\tconst error = coerceError(rawErr);\n\t\t\t\t\t\t\treportError({ stage: \"serialize\", error, value });\n\t\t\t\t\t\t\tfailed.down([[DATA, { value, error, attempts: 0 } satisfies SinkFailure<T>]]);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpayload = value;\n\t\t\t\t\t}\n\t\t\t\t\tconst admitted = pushWithBackpressure(value, payload);\n\t\t\t\t\tif (!admitted) continue;\n\t\t\t\t\tif (buffer.length >= batchSize) void doFlush();\n\t\t\t\t\telse scheduleFlush();\n\t\t\t\t} else {\n\t\t\t\t\tconst p = performSend(value);\n\t\t\t\t\ttrackPromise(p);\n\t\t\t\t}\n\t\t\t} else if (defaultConfig.messageTier(type) >= 3) {\n\t\t\t\t// Spec §5.11 — flush on tier-3+ terminal / teardown. INVALIDATE\n\t\t\t\t// (tier 4) hits an empty buffer and is a no-op.\n\t\t\t\tif (useBuffering) {\n\t\t\t\t\tif (flushTimer !== undefined) {\n\t\t\t\t\t\tclearTimeout(flushTimer);\n\t\t\t\t\t\tflushTimer = undefined;\n\t\t\t\t\t}\n\t\t\t\t\tvoid doFlush();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\t// -------------------------------------------------------------------\n\t// Reactive stop signal — a *fresh* emission on `stopOn` tears the sink\n\t// down. The first batch delivered through subscribe contains the cached\n\t// push-on-subscribe DATA (§2.2) and must be skipped; any emission\n\t// arriving in a later batch is a real stop request.\n\t// -------------------------------------------------------------------\n\tlet stopUnsub: (() => void) | undefined;\n\tif (stopOn) {\n\t\tlet firstBatchSeen = false;\n\t\tstopUnsub = stopOn.subscribe((msgs) => {\n\t\t\tif (!firstBatchSeen) {\n\t\t\t\tfirstBatchSeen = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (msgs.length > 0 && !teardownRequested) dispose();\n\t\t});\n\t}\n\n\t// -------------------------------------------------------------------\n\t// Dispose.\n\t//\n\t// Two flags:\n\t// - `teardownRequested`: set synchronously when `dispose()` is entered.\n\t// Gates further subscribe / buffer work and short-circuits stopOn\n\t// re-entry.\n\t// - `disposed`: set only after the final drain + unsub + TEARDOWN fan-\n\t// out have landed. In-flight per-record drain loops read this to\n\t// decide \"am I mid-cleanup vs fully-torn-down?\" They only stop on\n\t// `disposed`, so a dispose mid-drain doesn't truncate the current\n\t// buffer — it just prevents further work from being scheduled.\n\t// -------------------------------------------------------------------\n\tlet teardownRequested = false;\n\tconst dispose = () => {\n\t\tif (teardownRequested) return;\n\t\tteardownRequested = true;\n\t\tif (flushTimer !== undefined) {\n\t\t\tclearTimeout(flushTimer);\n\t\t\tflushTimer = undefined;\n\t\t}\n\t\t// Final drain of buffered items. Fire-and-forget — the per-record\n\t\t// drain loop reads `disposed` (still false) to keep draining the\n\t\t// already-captured chunk.\n\t\tif (useBuffering) void doFlush();\n\t\tdisposed = true;\n\t\tstopUnsub?.();\n\t\tunsub();\n\t\t// Fire TEARDOWN on companions so downstream subscribers observe\n\t\t// the sink's lifecycle end.\n\t\tconst tearDown = (n: Node<unknown>) => {\n\t\t\ttry {\n\t\t\t\tn.down([[TEARDOWN]]);\n\t\t\t} catch {\n\t\t\t\t/* drain re-entrance — swallow */\n\t\t\t}\n\t\t};\n\t\ttearDown(errorsNode as Node<unknown>);\n\t\ttearDown(failed as Node<unknown>);\n\t\ttearDown(sent as Node<unknown>);\n\t\ttearDown(inFlightCountNode as Node<unknown>);\n\t\tif (bufferedNode) tearDown(bufferedNode as Node<unknown>);\n\t\tif (pausedNode) tearDown(pausedNode as Node<unknown>);\n\t\t// Run adapter-supplied cleanup AFTER our own teardown completes so\n\t\t// external resources (socket listeners, file handles) tear down with\n\t\t// the sink as an atomic boundary.\n\t\ttry {\n\t\t\tonDispose?.();\n\t\t} catch {\n\t\t\t/* adapter cleanup failure must not escape */\n\t\t}\n\t};\n\n\tconst handle: ReactiveSinkHandle<T> = {\n\t\tdispose,\n\t\tsent,\n\t\tfailed,\n\t\tinFlight: inFlightCountNode,\n\t\terrors: errorsNode,\n\t};\n\tif (useBuffering) {\n\t\thandle.buffered = bufferedNode;\n\t\thandle.flush = async () => {\n\t\t\tif (disposed) return;\n\t\t\tawait doFlush();\n\t\t\tawait Promise.all(inFlightPromises);\n\t\t};\n\t}\n\tif (pausedNode) handle.paused = pausedNode;\n\n\t// Silence \"unused\" warnings for COMPLETE / ERROR — they're handled as\n\t// part of the messageTier(type) >= 3 branch above.\n\tvoid COMPLETE;\n\tvoid ERROR;\n\n\treturn handle;\n}\n","/**\n * Creates a resettable deadline timer for internal timeout, retry, and rate-limiting use.\n *\n * @remarks **Centralised primitive:** wraps `setTimeout`/`clearTimeout` with a generation guard\n * so that stale callbacks never fire after `cancel()` or a new `start()`.\n *\n * @remarks **Spec §5.10 exception:** resilience operators (`timeout`, `retry`, `rateLimiter`)\n * need raw timers — `fromTimer` creates a new Node per reset, which is too heavy here.\n * Lives in `src/extra/` (not `src/core/`) because it is a documented escape hatch from\n * the protocol-pure core layer.\n *\n * @example\n * ```ts\n * import { ResettableTimer } from \"@graphrefly/graphrefly-ts\";\n *\n * const timer = new ResettableTimer();\n * timer.start(1000, () => console.log(\"fired\"));\n * timer.cancel(); // cancels before firing\n * timer.start(500, () => console.log(\"new deadline\"));\n * console.log(timer.pending); // true\n * ```\n *\n * @category extra\n */\nexport class ResettableTimer {\n\tprivate _timer: ReturnType<typeof setTimeout> | undefined;\n\tprivate _gen = 0;\n\n\t/** Schedule callback after delayMs. Cancels any pending timer. */\n\tstart(delayMs: number, callback: () => void): void {\n\t\tthis.cancel();\n\t\tthis._gen += 1;\n\t\tconst gen = this._gen;\n\t\tthis._timer = setTimeout(() => {\n\t\t\tthis._timer = undefined;\n\t\t\tif (gen !== this._gen) return;\n\t\t\tcallback();\n\t\t}, delayMs);\n\t}\n\n\t/** Cancel the pending timer (if any). */\n\tcancel(): void {\n\t\tif (this._timer !== undefined) {\n\t\t\tclearTimeout(this._timer);\n\t\t\tthis._timer = undefined;\n\t\t}\n\t}\n\n\t/** Whether a timer is currently pending. */\n\tget pending(): boolean {\n\t\treturn this._timer !== undefined;\n\t}\n}\n","/**\n * Resilience utilities — roadmap §3.1 + §3.1c (retry, breaker, rate limit, status,\n * fallback, cache, timeout).\n */\nimport { batch } from \"../core/batch.js\";\nimport { monotonicNs } from \"../core/clock.js\";\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Message,\n\tRESOLVED,\n\tTEARDOWN,\n} from \"../core/messages.js\";\nimport { type Node, type NodeOptions, node } from \"../core/node.js\";\nimport { producer } from \"../core/sugar.js\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tNS_PER_SEC,\n\tresolveBackoffPreset,\n} from \"./backoff.js\";\nimport { fromAny } from \"./sources.js\";\nimport { ResettableTimer } from \"./timer.js\";\n\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nfunction operatorOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"derived\", ...opts } as NodeOptions<T>;\n}\n\nfunction clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nfunction msgVal(m: Message): unknown {\n\treturn m[1];\n}\n\nfunction coerceDelayNs(raw: number): number {\n\tif (typeof raw !== \"number\" || !Number.isFinite(raw)) {\n\t\tthrow new TypeError(\"backoff strategy must return a finite number\");\n\t}\n\treturn raw < 0 ? 0 : raw;\n}\n\nexport type RetryOptions = {\n\t/** Max retry attempts after each terminal `ERROR` (not counting the first failure). */\n\tcount?: number;\n\t/** Delay between attempts; strategies use **nanoseconds**. */\n\tbackoff?: BackoffStrategy | BackoffPreset;\n};\n\n/**\n * Resubscribes to the upstream node after each terminal `ERROR`, after an optional delay.\n *\n * @param source - Upstream node (should use `resubscribable: true`).\n * @param opts - `count` caps attempts; `backoff` supplies delay in **nanoseconds** (or a preset name).\n * @returns Node that retries on error.\n *\n * @remarks\n * **Resubscribable sources:** The upstream should use `resubscribable: true` if it must emit again after `ERROR`.\n * **Protocol:** Forwards unknown message tuples unchanged; handles `DIRTY`, `DATA`, `RESOLVED`, `COMPLETE`, `ERROR`.\n *\n * @example\n * ```ts\n * import { ERROR, NS_PER_SEC, pipe, producer, retry, constant } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = producer(\n * (a) => {\n * a.down([[ERROR, new Error(\"x\")]]);\n * },\n * { resubscribable: true },\n * );\n * const out = retry(src, { count: 2, backoff: constant(0.25 * NS_PER_SEC) });\n * ```\n *\n * @category extra\n */\nexport function retry<T>(source: Node<T>, opts?: RetryOptions): Node<T> {\n\tconst count = opts?.count;\n\tconst backoffOpt = opts?.backoff;\n\tconst maxRetries = count !== undefined ? count : backoffOpt === undefined ? 0 : 0x7fffffff;\n\tif (maxRetries < 0) throw new RangeError(\"retry count must be >= 0\");\n\n\tconst strategy: BackoffStrategy | null =\n\t\tbackoffOpt === undefined\n\t\t\t? null\n\t\t\t: typeof backoffOpt === \"string\"\n\t\t\t\t? resolveBackoffPreset(backoffOpt)\n\t\t\t\t: backoffOpt;\n\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tlet attempt = 0;\n\t\t\tlet stopped = false;\n\t\t\tlet prevDelay: number | null = null;\n\t\t\tlet unsub: (() => void) | undefined;\n\t\t\tconst timer = new ResettableTimer();\n\n\t\t\tfunction disconnectUpstream(): void {\n\t\t\t\tunsub?.();\n\t\t\t\tunsub = undefined;\n\t\t\t}\n\n\t\t\tfunction scheduleRetryOrFinish(err: unknown): void {\n\t\t\t\tif (stopped) return;\n\t\t\t\tif (attempt >= maxRetries) {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst raw = strategy === null ? 0 : strategy(attempt, err, prevDelay);\n\t\t\t\t// null from strategy = \"stop retrying\" (e.g. withMaxAttempts cap reached)\n\t\t\t\tif (raw === null || raw === undefined) {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// A misbehaving strategy (returns NaN / non-finite) MUST NOT\n\t\t\t\t// escape into the upstream drain — treat it as \"stop retrying\"\n\t\t\t\t// and emit the original error.\n\t\t\t\tlet delayNs: number;\n\t\t\t\ttry {\n\t\t\t\t\tdelayNs = coerceDelayNs(raw);\n\t\t\t\t} catch {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tprevDelay = delayNs;\n\t\t\t\tattempt += 1;\n\t\t\t\tdisconnectUpstream();\n\t\t\t\tconst delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;\n\t\t\t\t// §5.10: setTimeout (not fromTimer) — retry delay needs clearTimeout/setTimeout;\n\t\t\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\t\t\ttimer.start(delayMs, () => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tconnect();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction connect(): void {\n\t\t\t\ttimer.cancel();\n\t\t\t\tdisconnectUpstream();\n\t\t\t\tunsub = source.subscribe((msgs) => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tconst t = m[0];\n\t\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\t\tattempt = 0;\n\t\t\t\t\t\t\tprevDelay = null;\n\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\tscheduleRetryOrFinish(msgVal(m));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else a.down([m]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconnect();\n\n\t\t\treturn () => {\n\t\t\t\tstopped = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tdisconnectUpstream();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t},\n\t);\n}\n\n/**\n * Options for {@link retrySource}. Superset of {@link RetryOptions} with an\n * optional `initial` forwarded to the outer node cache.\n *\n * @category extra\n */\nexport type RetrySourceOptions<T> = RetryOptions & {\n\t/** Initial cache value for the outer node (forwarded to `NodeOptions.initial`). */\n\tinitial?: T;\n};\n\n/**\n * Fresh-instance variant of {@link retry}: invokes the `factory` to build a\n * new `Node<T>` on every connect / reconnect. Unlike {@link retry}, which\n * re-subscribes to the same node (requiring `resubscribable: true`), this\n * creates a new source per attempt — ideal for producers that capture\n * per-attempt resources (sockets, clients, file handles) that become unusable\n * after an error.\n *\n * Synchronous exceptions thrown by `factory` are treated as terminal ERROR\n * and run through the same retry pipeline as inner-node ERROR.\n *\n * @param factory - Called to build a fresh source per attempt.\n * @param opts - `count` caps attempts; `backoff` supplies delay (ns) or preset.\n * @returns Node that retries by rebuilding the source.\n *\n * @example\n * ```ts\n * import { NS_PER_SEC, exponential, retrySource, fromWebSocket } from \"@graphrefly/graphrefly-ts\";\n *\n * // Each reconnect opens a fresh WebSocket:\n * const connected$ = retrySource(\n * () => fromWebSocket(new WebSocket(\"wss://example/stream\")),\n * { count: 10, backoff: exponential({ baseNs: 1 * NS_PER_SEC }) },\n * );\n * ```\n *\n * @category extra\n */\nexport function retrySource<T>(factory: () => Node<T>, opts?: RetrySourceOptions<T>): Node<T> {\n\tconst count = opts?.count;\n\tconst backoffOpt = opts?.backoff;\n\tconst maxRetries = count !== undefined ? count : backoffOpt === undefined ? 0 : 0x7fffffff;\n\tif (maxRetries < 0) throw new RangeError(\"retry count must be >= 0\");\n\n\tconst strategy: BackoffStrategy | null =\n\t\tbackoffOpt === undefined\n\t\t\t? null\n\t\t\t: typeof backoffOpt === \"string\"\n\t\t\t\t? resolveBackoffPreset(backoffOpt)\n\t\t\t\t: backoffOpt;\n\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tlet attempt = 0;\n\t\t\tlet stopped = false;\n\t\t\tlet prevDelay: number | null = null;\n\t\t\tlet unsub: (() => void) | undefined;\n\t\t\tconst timer = new ResettableTimer();\n\n\t\t\tfunction disconnectUpstream(): void {\n\t\t\t\tunsub?.();\n\t\t\t\tunsub = undefined;\n\t\t\t}\n\n\t\t\tfunction scheduleRetryOrFinish(err: unknown): void {\n\t\t\t\tif (stopped) return;\n\t\t\t\tif (attempt >= maxRetries) {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst raw = strategy === null ? 0 : strategy(attempt, err, prevDelay);\n\t\t\t\tif (raw === null || raw === undefined) {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// A misbehaving strategy (returns NaN / non-finite / negative)\n\t\t\t\t// MUST NOT escape into the upstream drain. Treat it like\n\t\t\t\t// `strategy === null` (stop retrying) and emit the original\n\t\t\t\t// error — the strategy bug is a separate concern the user\n\t\t\t\t// can inspect via the emitted error's stack.\n\t\t\t\tlet delayNs: number;\n\t\t\t\ttry {\n\t\t\t\t\tdelayNs = coerceDelayNs(raw);\n\t\t\t\t} catch {\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tprevDelay = delayNs;\n\t\t\t\tattempt += 1;\n\t\t\t\tdisconnectUpstream();\n\t\t\t\tconst delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;\n\t\t\t\t// §5.10: setTimeout (not fromTimer) — retry delay needs clearTimeout/setTimeout;\n\t\t\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\t\t\ttimer.start(delayMs, () => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tconnect();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction connect(): void {\n\t\t\t\ttimer.cancel();\n\t\t\t\tdisconnectUpstream();\n\t\t\t\tlet src: Node<T>;\n\t\t\t\ttry {\n\t\t\t\t\tsrc = factory();\n\t\t\t\t} catch (err) {\n\t\t\t\t\tscheduleRetryOrFinish(err);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tunsub = src.subscribe((msgs) => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tconst t = m[0];\n\t\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\t\tattempt = 0;\n\t\t\t\t\t\t\tprevDelay = null;\n\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\tscheduleRetryOrFinish(msgVal(m));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else a.down([m]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconnect();\n\n\t\t\treturn () => {\n\t\t\t\tstopped = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tdisconnectUpstream();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: opts?.initial,\n\t\t},\n\t);\n}\n\nexport type CircuitState = \"closed\" | \"open\" | \"half-open\";\n\n/**\n * Thrown when {@link withBreaker} is configured with `onOpen: \"error\"` and the breaker rejects work.\n *\n * @category extra\n */\nexport class CircuitOpenError extends Error {\n\toverride name = \"CircuitOpenError\";\n\tconstructor() {\n\t\tsuper(\"Circuit breaker is open\");\n\t}\n}\n\nexport interface CircuitBreakerOptions {\n\t/** Number of consecutive failures before opening. Default: 5. */\n\tfailureThreshold?: number;\n\t/** Base cooldown in nanoseconds before transitioning to half-open. Default: 30s. */\n\tcooldownNs?: number;\n\t/** Backoff strategy for cooldown escalation across consecutive open cycles. Overrides `cooldownNs` when provided. */\n\tcooldown?: BackoffStrategy;\n\t/** Max trial requests allowed in half-open state. Default: 1. */\n\thalfOpenMax?: number;\n\t/** Clock function returning nanoseconds (for testability). Default: `monotonicNs`. */\n\tnow?: () => number;\n}\n\nexport interface CircuitBreaker {\n\t/** Whether a request should be allowed through. Triggers open→half-open transition when cooldown expires. */\n\tcanExecute(): boolean;\n\t/** Record a successful execution. Resets to closed. */\n\trecordSuccess(): void;\n\t/** Record a failed execution. May transition to open. */\n\trecordFailure(error?: unknown): void;\n\t/** Current circuit state (read-only, does not trigger transitions). */\n\treadonly state: CircuitState;\n\t/** Number of consecutive failures in the current closed period. */\n\treadonly failureCount: number;\n\t/** Manually reset to closed state, clearing all counters. */\n\treset(): void;\n}\n\n/**\n * Factory for a synchronous circuit breaker with `closed`, `open`, and `half-open` states.\n *\n * Supports escalating cooldown via an optional {@link BackoffStrategy} — each consecutive\n * open→half-open→open cycle increments the backoff attempt.\n *\n * @param options - Threshold, cooldown, half-open limit, and optional clock override.\n * @returns {@link CircuitBreaker} instance.\n *\n * @remarks\n * **Timing:** Uses `monotonicNs()` by default (nanoseconds). Override `now` for tests.\n *\n * @example\n * ```ts\n * import { circuitBreaker, exponential, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const b = circuitBreaker({\n * failureThreshold: 3,\n * cooldown: exponential({ baseNs: 1 * NS_PER_SEC }),\n * });\n * ```\n *\n * @category extra\n */\nexport function circuitBreaker(options?: CircuitBreakerOptions): CircuitBreaker {\n\tconst threshold = Math.max(1, options?.failureThreshold ?? 5);\n\tconst baseCooldownNs = clampNonNegative(options?.cooldownNs ?? 30 * NS_PER_SEC);\n\tconst cooldownStrategy = options?.cooldown ?? null;\n\tconst halfOpenMax = Math.max(1, options?.halfOpenMax ?? 1);\n\tconst now = options?.now ?? monotonicNs;\n\n\tlet _state: CircuitState = \"closed\";\n\tlet _failureCount = 0;\n\tlet _openCycle = 0;\n\tlet _lastOpenedAt = 0;\n\tlet _lastCooldownNs = baseCooldownNs;\n\tlet _halfOpenAttempts = 0;\n\n\tfunction getCooldownNs(): number {\n\t\tif (!cooldownStrategy) return baseCooldownNs;\n\t\tconst delayNs = cooldownStrategy(_openCycle);\n\t\treturn delayNs !== null ? delayNs : baseCooldownNs;\n\t}\n\n\tfunction transitionToOpen(): void {\n\t\t_state = \"open\";\n\t\t_lastCooldownNs = getCooldownNs();\n\t\t_lastOpenedAt = now();\n\t\t_halfOpenAttempts = 0;\n\t}\n\n\tconst breaker: CircuitBreaker = {\n\t\tcanExecute(): boolean {\n\t\t\tif (_state === \"closed\") return true;\n\n\t\t\tif (_state === \"open\") {\n\t\t\t\tconst elapsed = now() - _lastOpenedAt;\n\t\t\t\tif (elapsed >= _lastCooldownNs) {\n\t\t\t\t\t_state = \"half-open\";\n\t\t\t\t\t_halfOpenAttempts = 1;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (_halfOpenAttempts < halfOpenMax) {\n\t\t\t\t_halfOpenAttempts++;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\n\t\trecordSuccess(): void {\n\t\t\tif (_state === \"half-open\") {\n\t\t\t\t_state = \"closed\";\n\t\t\t\t_failureCount = 0;\n\t\t\t\t_openCycle = 0;\n\t\t\t} else if (_state === \"closed\") {\n\t\t\t\t_failureCount = 0;\n\t\t\t}\n\t\t},\n\n\t\trecordFailure(_error?: unknown): void {\n\t\t\tif (_state === \"half-open\") {\n\t\t\t\t_openCycle++;\n\t\t\t\ttransitionToOpen();\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (_state === \"closed\") {\n\t\t\t\t_failureCount++;\n\t\t\t\tif (_failureCount >= threshold) {\n\t\t\t\t\ttransitionToOpen();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tget state(): CircuitState {\n\t\t\treturn _state;\n\t\t},\n\n\t\tget failureCount(): number {\n\t\t\treturn _failureCount;\n\t\t},\n\n\t\treset(): void {\n\t\t\t_state = \"closed\";\n\t\t\t_failureCount = 0;\n\t\t\t_openCycle = 0;\n\t\t\t_halfOpenAttempts = 0;\n\t\t},\n\t};\n\n\treturn breaker;\n}\n\nexport type WithBreakerBundle<T> = {\n\tnode: Node<T>;\n\tbreakerState: Node<CircuitState>;\n};\n\n/**\n * Returns a unary wrapper that gates upstream `DATA` through a {@link CircuitBreaker}.\n *\n * @param breaker - Shared breaker instance (typically one per resource).\n * @param options - `onOpen: \"skip\"` emits `RESOLVED` when open; `\"error\"` emits {@link CircuitOpenError}.\n * @returns Function mapping `Node<T>` to `{ node, breakerState }` companion nodes.\n *\n * @remarks\n * **Success path:** `COMPLETE` calls {@link CircuitBreaker.recordSuccess}. **Failure path:** upstream `ERROR` calls {@link CircuitBreaker.recordFailure} and is forwarded.\n *\n * @example\n * ```ts\n * import { state, withBreaker, circuitBreaker } from \"@graphrefly/graphrefly-ts\";\n *\n * const b = circuitBreaker({ failureThreshold: 2 });\n * const s = state(1);\n * const { node, breakerState } = withBreaker(b)(s);\n * ```\n *\n * @category extra\n */\nexport function withBreaker<T>(\n\tbreaker: CircuitBreaker,\n\toptions?: { onOpen?: \"skip\" | \"error\" },\n): (source: Node<T>) => WithBreakerBundle<T> {\n\tconst onOpen = options?.onOpen ?? \"skip\";\n\n\treturn (source: Node<T>): WithBreakerBundle<T> => {\n\t\tconst wrapped = node<T>(\n\t\t\t[],\n\t\t\t(_deps, a) => {\n\t\t\t\tfunction syncState(): void {\n\t\t\t\t\twrapped.meta.breakerState.down([[DATA, breaker.state]]);\n\t\t\t\t}\n\n\t\t\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tconst t = m[0];\n\t\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\t\tif (breaker.canExecute()) {\n\t\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\t\tif (onOpen === \"error\") a.down([[ERROR, new CircuitOpenError()]]);\n\t\t\t\t\t\t\t\telse a.down([[RESOLVED]]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\t\tbreaker.recordSuccess();\n\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\tbreaker.recordFailure(msgVal(m));\n\t\t\t\t\t\t\tsyncState();\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t} else a.down([m]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tsyncState();\n\t\t\t\treturn unsub;\n\t\t\t},\n\t\t\t{\n\t\t\t\t...operatorOpts(),\n\t\t\t\tmeta: { breakerState: breaker.state },\n\t\t\t\tcompleteWhenDepsComplete: false,\n\t\t\t\tinitial: source.cache,\n\t\t\t},\n\t\t);\n\n\t\treturn { node: wrapped, breakerState: wrapped.meta.breakerState as Node<CircuitState> };\n\t};\n}\n\nexport interface TokenBucket {\n\t/** Number of tokens currently available (after refill). */\n\tavailable(): number;\n\t/** Try to consume `cost` tokens. Returns `true` if successful. */\n\ttryConsume(cost?: number): boolean;\n}\n\n/**\n * Token-bucket meter (capacity + refill rate per second). Use with {@link rateLimiter} or custom gates.\n *\n * @param capacity - Maximum tokens (must be positive).\n * @param refillPerSecond - Tokens added per elapsed second (non-negative).\n * @returns {@link TokenBucket} instance.\n *\n * @example\n * ```ts\n * import { tokenBucket } from \"@graphrefly/graphrefly-ts\";\n *\n * const bucket = tokenBucket(10, 2); // capacity 10, refill 2 tokens/sec\n * bucket.tryConsume(3); // true — 7 tokens remaining\n * bucket.available(); // ~7 (plus any elapsed refill)\n * ```\n *\n * @category extra\n */\nexport function tokenBucket(capacity: number, refillPerSecond: number): TokenBucket {\n\tif (capacity <= 0) throw new RangeError(\"capacity must be > 0\");\n\tif (refillPerSecond < 0) throw new RangeError(\"refillPerSecond must be >= 0\");\n\n\tlet tokens = capacity;\n\tlet updatedAt = monotonicNs();\n\n\tfunction refill(now: number): void {\n\t\tif (refillPerSecond > 0) {\n\t\t\tconst elapsedNs = now - updatedAt;\n\t\t\ttokens = Math.min(capacity, tokens + (elapsedNs / NS_PER_SEC) * refillPerSecond);\n\t\t}\n\t\tupdatedAt = now;\n\t}\n\n\treturn {\n\t\tavailable(): number {\n\t\t\trefill(monotonicNs());\n\t\t\treturn tokens;\n\t\t},\n\t\ttryConsume(cost = 1): boolean {\n\t\t\tif (cost <= 0) return true;\n\t\t\tconst now = monotonicNs();\n\t\t\trefill(now);\n\t\t\tif (tokens >= cost) {\n\t\t\t\ttokens -= cost;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t};\n}\n\nexport type RateLimiterOverflowPolicy = \"drop-oldest\" | \"drop-newest\" | \"error\";\n\nexport type RateLimiterOptions = {\n\t/** Maximum `DATA` emissions per window (must be > 0). */\n\tmaxEvents: number;\n\t/** Window length in nanoseconds (must be > 0). */\n\twindowNs: number;\n\t/** Cap on items queued while waiting for token refill (must be >= 1). Unbounded if omitted. */\n\tmaxBuffer?: number;\n\t/** Overflow policy when `maxBuffer` is exceeded. Default: `\"drop-newest\"`. */\n\tonOverflow?: RateLimiterOverflowPolicy;\n};\n\n/**\n * Thrown by {@link rateLimiter} when `onOverflow: \"error\"` and the pending buffer is full.\n *\n * @category extra\n */\nexport class RateLimiterOverflowError extends Error {\n\toverride name = \"RateLimiterOverflowError\";\n\tconstructor(maxBuffer: number) {\n\t\tsuper(`rateLimiter buffer overflow (maxBuffer=${maxBuffer})`);\n\t}\n}\n\n/**\n * Token-bucket rate limiter: at most `maxEvents` `DATA` values per `windowNs`.\n *\n * Uses {@link tokenBucket} internally (capacity = `maxEvents`, refill = `maxEvents / windowSeconds`).\n * Excess items are queued FIFO until a token is available. The queue may be bounded via\n * `maxBuffer` with a configurable overflow policy.\n *\n * @param source - Upstream node.\n * @param opts - Rate + optional bounded-buffer configuration.\n * @returns Node that emits DATA at most `maxEvents` per `windowNs`.\n *\n * @remarks\n * **Terminal:** `COMPLETE` / `ERROR` cancel the refill timer, drop the pending queue, and propagate.\n *\n * @example\n * ```ts\n * import { rateLimiter, state, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = state(0);\n * // Allow at most 5 DATA values per second; queue up to 100 excess items, drop newest beyond.\n * const limited = rateLimiter(src, { maxEvents: 5, windowNs: NS_PER_SEC, maxBuffer: 100 });\n * ```\n *\n * @category extra\n */\nexport function rateLimiter<T>(source: Node<T>, opts: RateLimiterOptions): Node<T> {\n\tconst { maxEvents, windowNs } = opts;\n\tif (maxEvents <= 0) throw new RangeError(\"maxEvents must be > 0\");\n\tif (windowNs <= 0) throw new RangeError(\"windowNs must be > 0\");\n\tconst maxBuffer = opts.maxBuffer;\n\tif (maxBuffer !== undefined && maxBuffer < 1) throw new RangeError(\"maxBuffer must be >= 1\");\n\tconst onOverflow: RateLimiterOverflowPolicy = opts.onOverflow ?? \"drop-newest\";\n\tconst refillPerSec = (maxEvents * NS_PER_SEC) / windowNs;\n\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tconst bucket = tokenBucket(maxEvents, refillPerSec);\n\t\t\tconst pending: T[] = [];\n\t\t\tconst timer = new ResettableTimer();\n\t\t\tlet terminated = false;\n\n\t\t\tconst tokenTimeNs = NS_PER_SEC / refillPerSec;\n\n\t\t\tfunction tryEmit(): void {\n\t\t\t\twhile (pending.length > 0) {\n\t\t\t\t\tif (bucket.tryConsume(1)) {\n\t\t\t\t\t\ta.emit(pending.shift() as T);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Wait one full token-refill interval. Avoids calling bucket.available()\n\t\t\t\t\t\t// which would advance the internal refill clock and steal fractional credit.\n\t\t\t\t\t\t// §5.10: setTimeout (not fromTimer) — refill-delay scheduling needs clearTimeout/setTimeout;\n\t\t\t\t\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\t\t\t\t\ttimer.start(Math.max(1, tokenTimeNs / NS_PER_MS), tryEmit);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (terminated) return;\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\tif (maxBuffer !== undefined && pending.length >= maxBuffer) {\n\t\t\t\t\t\t\tif (onOverflow === \"drop-newest\") {\n\t\t\t\t\t\t\t\t// silently drop the incoming item\n\t\t\t\t\t\t\t} else if (onOverflow === \"drop-oldest\") {\n\t\t\t\t\t\t\t\tpending.shift();\n\t\t\t\t\t\t\t\tpending.push(m[1] as T);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\t\tpending.length = 0;\n\t\t\t\t\t\t\t\ta.down([[ERROR, new RateLimiterOverflowError(maxBuffer)]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpending.push(m[1] as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttryEmit();\n\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tpending.length = 0;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tpending.length = 0;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tpending.length = 0;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tterminated = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tunsub();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t},\n\t);\n}\n\nexport type StatusValue = \"pending\" | \"active\" | \"completed\" | \"errored\";\n\nexport type WithStatusBundle<T> = {\n\tnode: Node<T>;\n\tstatus: Node<StatusValue>;\n\terror: Node<unknown | null>;\n};\n\n/**\n * Wraps `src` with `status` and `error` {@link state} companions for UI or meta snapshots.\n *\n * @param src - Upstream node to mirror.\n * @param options - `initialStatus` defaults to `\"pending\"`.\n * @returns `{ node, status, error }` where `error` holds the last `ERROR` payload.\n *\n * @remarks\n * **Recovery:** After `errored`, the next `DATA` clears `error` and sets `active` inside {@link batch} (matches graphrefly-py).\n *\n * @example\n * ```ts\n * import { withStatus, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = state<number>(0);\n * const { node, status, error } = withStatus(src);\n *\n * status.subscribe((msgs) => console.log(\"status:\", msgs));\n * src.down([[DATA, 42]]); // status → \"active\"\n * ```\n *\n * @category extra\n */\nexport function withStatus<T>(\n\tsrc: Node<T>,\n\toptions?: { initialStatus?: StatusValue },\n): WithStatusBundle<T> {\n\tconst initialStatus = options?.initialStatus ?? \"pending\";\n\n\tconst out = node<T>(\n\t\t[],\n\t\t(_deps, a) => {\n\t\t\tlet currentStatus: StatusValue = initialStatus;\n\t\t\tout.meta.status.down([[DATA, initialStatus]]);\n\t\t\tout.meta.error.down([[DATA, null]]);\n\n\t\t\tconst unsub = src.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\tif (currentStatus === \"errored\") {\n\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\tout.meta.error.down([[DATA, null]]);\n\t\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"active\"]]);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"active\"]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentStatus = \"active\";\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\tout.meta.status.down([[DATA, \"completed\"]]);\n\t\t\t\t\t\tcurrentStatus = \"completed\";\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tconst err = msgVal(m);\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tout.meta.error.down([[DATA, err]]);\n\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"errored\"]]);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcurrentStatus = \"errored\";\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn unsub;\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tmeta: { status: initialStatus, error: null },\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\tresubscribable: true,\n\t\t\tinitial: src.cache,\n\t\t},\n\t);\n\n\treturn {\n\t\tnode: out,\n\t\tstatus: out.meta.status as Node<StatusValue>,\n\t\terror: out.meta.error as Node<unknown | null>,\n\t};\n}\n\n// ——————————————————————————————————————————————————————————————\n// §3.1c — Caching, fallback & composition sugar\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Thrown by {@link timeout} when no `DATA` arrives within the deadline.\n *\n * @category extra\n */\nexport class TimeoutError extends Error {\n\toverride name = \"TimeoutError\";\n\tconstructor(ns: number) {\n\t\tsuper(`Timed out after ${ns / NS_PER_MS}ms`);\n\t}\n}\n\nfunction isNode(x: unknown): x is Node {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\t\"cache\" in x &&\n\t\ttypeof (x as Node).subscribe === \"function\"\n\t);\n}\n\nfunction isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nfunction isAsyncIterable(x: unknown): x is AsyncIterable<unknown> {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\ttypeof (x as AsyncIterable<unknown>)[Symbol.asyncIterator] === \"function\"\n\t);\n}\n\n/** Inputs accepted by {@link fallback}. */\nexport type FallbackInput<T> = T | Node<T> | PromiseLike<T> | AsyncIterable<T>;\n\n/**\n * On upstream terminal `ERROR`, switch to a fallback source instead of propagating the error.\n *\n * Accepts any of:\n * - **scalar value** — emits `[[DATA, fb], [COMPLETE]]`\n * - **`Node<T>`** — subscribes and forwards all messages (push-on-subscribe delivers current cache)\n * - **`Promise<T>` / thenable** — resolves into a one-shot `DATA` then `COMPLETE` (via {@link fromAny})\n * - **`AsyncIterable<T>`** — streams each yielded value as `DATA`, then `COMPLETE` (via {@link fromAny})\n *\n * Non-`Node` inputs are routed through {@link fromAny} so the fallback participates in the\n * reactive protocol uniformly. Bare strings, arrays, and other synchronous scalars are treated\n * as single values (NOT split into characters / elements) to avoid the `fromAny`-on-string\n * iteration gotcha.\n *\n * Composes naturally with {@link retry}:\n * `pipe(source, retry({count:3}), fallback(\"default\"))`.\n *\n * @param source - Upstream node.\n * @param fb - Fallback value, node, promise, or async iterable.\n * @returns Node that replaces errors with the fallback.\n *\n * @example\n * ```ts\n * import { fallback, throwError } from \"@graphrefly/graphrefly-ts\";\n *\n * const safe = fallback(throwError(new Error(\"boom\")), \"default\");\n * safe.cache; // \"default\" after subscribe\n * ```\n *\n * @category extra\n */\nexport function fallback<T>(source: Node<T>, fb: FallbackInput<T>): Node<T> {\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tlet fallbackUnsub: (() => void) | undefined;\n\t\t\tlet sourceUnsub: (() => void) | undefined;\n\n\t\t\tfunction switchToFallback(): void {\n\t\t\t\tsourceUnsub?.();\n\t\t\t\tsourceUnsub = undefined;\n\t\t\t\tif (isNode(fb) || isThenable(fb) || isAsyncIterable(fb)) {\n\t\t\t\t\tconst fbNode = fromAny(fb as Node<T> | PromiseLike<T> | AsyncIterable<T>);\n\t\t\t\t\tfallbackUnsub = fbNode.subscribe((fMsgs) => {\n\t\t\t\t\t\ta.down(fMsgs);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\ta.emit(fb as T);\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tsourceUnsub = source.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) a.emit(m[1] as T);\n\t\t\t\t\telse if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) a.down([[COMPLETE]]);\n\t\t\t\t\telse if (t === ERROR) {\n\t\t\t\t\t\tswitchToFallback();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\tfallbackUnsub?.();\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tsourceUnsub?.();\n\t\t\t\tfallbackUnsub?.();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t},\n\t);\n}\n\n/**\n * Emits `ERROR` with {@link TimeoutError} if no `DATA` arrives within the deadline.\n *\n * The timer starts on subscription and resets on each `DATA`. `DIRTY` does NOT reset\n * the timer. Terminal messages (`COMPLETE`/`ERROR`) cancel the timer.\n *\n * @param source - Upstream node.\n * @param timeoutNs - Deadline in nanoseconds.\n * @returns Node that errors on timeout.\n *\n * @example\n * ```ts\n * import { timeout, never, NS_PER_SEC } from \"@graphrefly/graphrefly-ts\";\n *\n * const t = timeout(never(), 5 * NS_PER_SEC);\n * // After 5 seconds with no DATA: [[ERROR, TimeoutError]]\n * ```\n *\n * @category extra\n */\nexport function timeout<T>(source: Node<T>, timeoutNs: number): Node<T> {\n\tif (timeoutNs <= 0) throw new RangeError(\"timeoutNs must be > 0\");\n\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\tlet stopped = false;\n\t\t\tconst timer = new ResettableTimer();\n\n\t\t\tfunction startTimer(): void {\n\t\t\t\tconst delayMs = timeoutNs / NS_PER_MS;\n\t\t\t\t// §5.10: setTimeout (not fromTimer) — resettable deadline needs clearTimeout/setTimeout; fromTimer creates a new Node per reset, adding lifecycle overhead on every DATA.\n\t\t\t\ttimer.start(delayMs, () => {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tunsub();\n\t\t\t\t\ta.down([[ERROR, new TimeoutError(timeoutNs)]]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (stopped) return;\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\t\telse if (t === DATA) {\n\t\t\t\t\t\tstartTimer();\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else a.down([m]);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tstartTimer();\n\n\t\t\treturn () => {\n\t\t\t\tstopped = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tunsub();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t},\n\t);\n}\n","/**\n * Protocol, system, and ingest adapters (roadmap §5.2, §5.2c).\n *\n * Each adapter wraps an external protocol or system as a reactive {@link Node}\n * built on {@link producer} / {@link node} — no second protocol.\n *\n * **Moved from sources.ts:** fromHTTP, fromWebSocket/toWebSocket, fromWebhook,\n * toSSE, fromMCP, fromGitHook.\n *\n * **New (5.2c):** fromOTel, fromSyslog, fromStatsD, fromPrometheus,\n * fromKafka/toKafka, fromRedisStream/toRedisStream, fromCSV, fromNDJSON,\n * fromClickHouseWatch, fromPulsar/toPulsar, fromNATS/toNATS,\n * fromRabbitMQ/toRabbitMQ.\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { wallClockNs } from \"../core/clock.js\";\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Message,\n\tRESOLVED,\n\tTEARDOWN,\n} from \"../core/messages.js\";\nimport { defaultConfig, type Node, type NodeOptions, node } from \"../core/node.js\";\nimport { producer, state } from \"../core/sugar.js\";\nimport { NS_PER_MS, NS_PER_SEC } from \"./backoff.js\";\nimport {\n\ttype BundleTriad,\n\ttype EmitTriad,\n\ttype ExternalRegister,\n\texternalBundle,\n\texternalProducer,\n} from \"./external-register.js\";\nimport { switchMap } from \"./operators.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkFailure } from \"./reactive-sink.js\";\nimport { retrySource, type WithStatusBundle, withStatus } from \"./resilience.js\";\nimport type { AsyncSourceOpts } from \"./sources.js\";\nimport { fromTimer, globToRegExp, matchesAnyPattern } from \"./sources.js\";\n\nexport type { SinkTransportError } from \"./reactive-sink.js\";\n\nimport type { SinkTransportError } from \"./reactive-sink.js\";\n\n/** Handle returned by per-record and buffered sinks. */\nexport type SinkHandle = {\n\t/** Stop the sink (unsubscribe from source). */\n\tdispose: () => void;\n\t/** Reactive node that emits the latest transport error (or `null`). */\n\terrors: Node<SinkTransportError | null>;\n\t/** Manually drain the internal buffer (buffered sinks only). */\n\tflush?: () => Promise<void>;\n};\n\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nfunction sourceOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\n\n// ——————————————————————————————————————————————————————————————\n// WebSocket adapter (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/** WebSocket-like transport accepted by {@link fromWebSocket} / {@link toWebSocket}. */\nexport type WebSocketLike = {\n\tsend(data: string | ArrayBufferLike | Blob | ArrayBufferView): void;\n\tclose(code?: number, reason?: string): void;\n\taddEventListener(type: \"message\" | \"error\" | \"close\", listener: (ev: unknown) => void): void;\n\tremoveEventListener(type: \"message\" | \"error\" | \"close\", listener: (ev: unknown) => void): void;\n};\n\nexport type WebSocketMessageEventLike = { data: unknown };\nexport type WebSocketRegister<T> = (\n\temit: (payload: T) => void,\n\terror: (err: unknown) => void,\n\tcomplete: () => void,\n) => () => void;\n\n/**\n * Wraps a WebSocket as a GraphReFly producer source.\n *\n * Incoming socket messages are emitted as `DATA`; socket `error` emits `ERROR`; socket `close`\n * emits `COMPLETE`. Teardown detaches listeners and optionally closes the socket.\n *\n * @category extra\n */\nexport function fromWebSocket<T = unknown>(\n\tsocket: WebSocketLike,\n\topts?: ExtraOpts & {\n\t\tparse?: (payload: unknown, event: unknown) => T;\n\t\tcloseOnTeardown?: boolean;\n\t},\n): Node<T>;\nexport function fromWebSocket<T = unknown>(\n\tregister: WebSocketRegister<T>,\n\topts?: ExtraOpts & {\n\t\tparse?: (payload: unknown, event: unknown) => T;\n\t\tcloseOnTeardown?: boolean;\n\t},\n): Node<T>;\nexport function fromWebSocket<T = unknown>(\n\tsocketOrRegister: WebSocketLike | WebSocketRegister<T>,\n\topts?: ExtraOpts & {\n\t\tparse?: (payload: unknown, event: unknown) => T;\n\t\tcloseOnTeardown?: boolean;\n\t},\n): Node<T> {\n\tconst { parse, closeOnTeardown = false, ...rest } = opts ?? {};\n\treturn producer<T>((a) => {\n\t\tlet active = true;\n\t\tlet cleanup: (() => void) | undefined;\n\t\tconst runCleanup = () => {\n\t\t\tconst fn = cleanup;\n\t\t\tcleanup = undefined;\n\t\t\tfn?.();\n\t\t};\n\t\tconst terminate = (message: Message) => {\n\t\t\tif (!active) return;\n\t\t\tactive = false;\n\t\t\ta.down([message]);\n\t\t\trunCleanup();\n\t\t};\n\t\tconst emit = (raw: unknown, event: unknown = raw) => {\n\t\t\tif (!active) return;\n\t\t\ttry {\n\t\t\t\tconst payload =\n\t\t\t\t\traw !== null && typeof raw === \"object\" && \"data\" in (raw as Record<string, unknown>)\n\t\t\t\t\t\t? (raw as WebSocketMessageEventLike).data\n\t\t\t\t\t\t: raw;\n\t\t\t\tconst parsed = parse ? parse(payload, event) : (payload as T);\n\t\t\t\ta.emit(parsed);\n\t\t\t} catch (err) {\n\t\t\t\tterminate([ERROR, err]);\n\t\t\t}\n\t\t};\n\t\tconst error = (err: unknown) => {\n\t\t\tterminate([ERROR, err]);\n\t\t};\n\t\tconst complete = () => {\n\t\t\tterminate([COMPLETE]);\n\t\t};\n\t\tif (typeof socketOrRegister === \"function\") {\n\t\t\ttry {\n\t\t\t\tcleanup = socketOrRegister(emit, error, complete);\n\t\t\t\tif (typeof cleanup !== \"function\") {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\"fromWebSocket register contract violation: register must return cleanup callable\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\tterminate([ERROR, err]);\n\t\t\t}\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t\trunCleanup();\n\t\t\t};\n\t\t}\n\n\t\tconst ws = socketOrRegister;\n\t\tconst onMessage = (event: unknown) => emit(event, event);\n\t\tconst onError = (event: unknown) => error(event);\n\t\tconst onClose = () => complete();\n\t\tws.addEventListener(\"message\", onMessage);\n\t\tws.addEventListener(\"error\", onError);\n\t\tws.addEventListener(\"close\", onClose);\n\t\tcleanup = () => {\n\t\t\tws.removeEventListener(\"message\", onMessage);\n\t\t\tws.removeEventListener(\"error\", onError);\n\t\t\tws.removeEventListener(\"close\", onClose);\n\t\t\tif (closeOnTeardown) ws.close();\n\t\t};\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\trunCleanup();\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n// ——————————————————————————————————————————————————————————————\n// Webhook adapter (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/** Registration callback for {@link fromWebhook}. Alias of {@link ExternalRegister} over {@link EmitTriad}. */\nexport type WebhookRegister<T> = ExternalRegister<EmitTriad<T>>;\n\n/**\n * Bridges HTTP webhook callbacks into a GraphReFly source.\n *\n * The `register` callback wires your runtime/framework callback to GraphReFly and may return a\n * cleanup function. This keeps the adapter runtime-agnostic while following the same producer\n * pattern as {@link fromEvent}.\n *\n * @param register - Registers webhook handlers (`emit`, `error`, `complete`) and optionally returns cleanup.\n * @param opts - Optional producer options.\n * @returns `Node<T>` — webhook payloads as `DATA`; teardown runs returned cleanup.\n *\n * @example\n * ```ts\n * import express from \"express\";\n * import { fromWebhook } from \"@graphrefly/graphrefly-ts\";\n *\n * type HookPayload = { event: string; data: unknown };\n * const app = express();\n * app.use(express.json());\n *\n * const hook$ = fromWebhook<HookPayload>(({ emit, error }) => {\n * const handler = (req: express.Request, res: express.Response) => {\n * try {\n * emit(req.body as HookPayload);\n * res.status(200).send(\"ok\");\n * } catch (e) {\n * error(e);\n * res.status(500).send(\"error\");\n * }\n * };\n * app.post(\"/webhook\", handler);\n * return () => {\n * // Express has no direct route-removal API in common use.\n * };\n * });\n * ```\n *\n * @example Fastify\n * ```ts\n * import Fastify from \"fastify\";\n * import { fromWebhook } from \"@graphrefly/graphrefly-ts\";\n *\n * const fastify = Fastify();\n * const hook$ = fromWebhook<any>(({ emit, error }) => {\n * const handler = async (req: any, reply: any) => {\n * try {\n * emit(req.body);\n * reply.code(200).send({ ok: true });\n * } catch (e) {\n * error(e);\n * reply.code(500).send({ ok: false });\n * }\n * };\n * fastify.post(\"/webhook\", handler);\n * return () => {};\n * });\n * ```\n *\n * @category extra\n */\nexport function fromWebhook<T = unknown>(register: WebhookRegister<T>, opts?: ExtraOpts): Node<T> {\n\treturn externalProducer<T>(register, opts);\n}\n\n// ——————————————————————————————————————————————————————————————\n// HTTP adapter (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Options for {@link fromHTTP}.\n *\n * @category extra\n */\nexport interface FromHTTPOptions extends AsyncSourceOpts {\n\t/** HTTP method. Default: `\"GET\"`. */\n\tmethod?: string;\n\t/** Request headers. */\n\theaders?: Record<string, string>;\n\t/** Request body (for POST/PUT/PATCH). */\n\tbody?: any;\n\t/** Transform the Response before emitting. Default: `response.json()`. */\n\ttransform?: (response: Response) => any | Promise<any>;\n\t/** Request timeout in **nanoseconds**. Default: `30s` (30 * NS_PER_SEC). */\n\ttimeoutNs?: number;\n\t/**\n\t * When `true`, emit `COMPLETE` after the first successful fetch. Useful for\n\t * one-shot semantics where downstream wants to know \"no more values ever.\"\n\t * Default: `false` — the node stays live and replays cached DATA to late\n\t * subscribers via push-on-subscribe (spec §2.2).\n\t */\n\tcompleteAfterFetch?: boolean;\n\t/**\n\t * When `true`, trigger a fresh fetch on each new subscriber instead of\n\t * sharing one cached result. Default: `false` — one shared fetch whose\n\t * result is cached and replayed to every subscriber.\n\t */\n\trefetchOnSubscribe?: boolean;\n}\n\n/**\n * Result of {@link fromHTTP}: main source plus status, error, and fetch count companions.\n *\n * @category extra\n */\nexport type HTTPBundle<T> = WithStatusBundle<T> & {\n\t/** Number of successful fetches. */\n\tfetchCount: Node<number>;\n\t/** Nanosecond wall-clock timestamp of the last successful fetch. */\n\tlastUpdated: Node<number>;\n\t/**\n\t * `true` after at least one successful fetch; stays `true` across\n\t * resubscribes. Orthogonal to {@link withStatus}'s `active`/`completed`\n\t * lifecycle — use this as the \"fetch done\" signal under the default\n\t * (cached, stays-live) behavior where `withStatus` never transitions to\n\t * `\"completed\"` unless `completeAfterFetch: true` is set.\n\t */\n\tfetched: Node<boolean>;\n};\n\n/**\n * Creates a one-shot fetch-based HTTP source with lifecycle tracking.\n *\n * @category extra\n */\nexport function fromHTTP<T = any>(url: string, opts?: FromHTTPOptions): HTTPBundle<T> {\n\tconst {\n\t\tmethod = \"GET\",\n\t\theaders,\n\t\tbody: bodyOpt,\n\t\ttransform = (r: Response) => r.json(),\n\t\ttimeoutNs = 30 * NS_PER_SEC,\n\t\tsignal: externalSignal,\n\t\tcompleteAfterFetch = false,\n\t\trefetchOnSubscribe = false,\n\t\t...rest\n\t} = opts ?? {};\n\n\tconst fetchCount = state(0, { name: `${rest.name ?? \"http\"}/fetchCount` });\n\tconst lastUpdated = state(0, { name: `${rest.name ?? \"http\"}/lastUpdated` });\n\tconst fetched = state(false, { name: `${rest.name ?? \"http\"}/fetched` });\n\t// Closure-owned counter: `fetchCount` is a write-only observable of this\n\t// local count. Avoids the `fetchCount.cache + 1` read-modify-write pattern\n\t// (P3 audit #6) — the node stays in sync because every write flows through\n\t// here.\n\tlet fetchCountLocal = 0;\n\n\tconst body =\n\t\tbodyOpt !== undefined\n\t\t\t? typeof bodyOpt === \"string\"\n\t\t\t\t? bodyOpt\n\t\t\t\t: JSON.stringify(bodyOpt)\n\t\t\t: undefined;\n\n\t// Fetch body + lifecycle — shared between the default \"one shared fetch\"\n\t// path and the refetch-on-subscribe resubscribable producer path.\n\tconst runFetch = (a: {\n\t\temit: (v: T) => void;\n\t\tdown: (msgs: [symbol, ...unknown[]][]) => void;\n\t}): (() => void) => {\n\t\tconst abort = new AbortController();\n\t\tlet active = true;\n\n\t\tif (externalSignal?.aborted) {\n\t\t\t// Abort already fired before activation — short-circuit with ERROR\n\t\t\t// and flip `active` so the idempotent cleanup below is coherent.\n\t\t\tactive = false;\n\t\t\ta.down([[ERROR, externalSignal.reason ?? new Error(\"Aborted\")]]);\n\t\t\treturn () => {};\n\t\t}\n\t\texternalSignal?.addEventListener(\"abort\", () => abort.abort(externalSignal.reason), {\n\t\t\tonce: true,\n\t\t});\n\n\t\tconst timeoutId = setTimeout(\n\t\t\t() => abort.abort(new Error(\"Request timeout\")),\n\t\t\tMath.ceil(timeoutNs / NS_PER_MS),\n\t\t);\n\n\t\tfetch(url, { method, headers, body, signal: abort.signal })\n\t\t\t.then(async (res) => {\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\tif (!active) return;\n\t\t\t\tif (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\t\t\tconst data = await transform(res);\n\t\t\t\tif (!active) return;\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfetchCountLocal += 1;\n\t\t\t\t\tfetchCount.down([[DATA, fetchCountLocal]]);\n\t\t\t\t\tlastUpdated.down([[DATA, wallClockNs()]]);\n\t\t\t\t\tfetched.down([[DATA, true]]);\n\t\t\t\t\ta.emit(data as T);\n\t\t\t\t});\n\t\t\t\tif (completeAfterFetch) a.down([[COMPLETE]]);\n\t\t\t})\n\t\t\t.catch((err) => {\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\tif (!active) return;\n\t\t\t\tif (err && (err as Error).name === \"AbortError\") return;\n\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t});\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\tabort.abort();\n\t\t};\n\t};\n\n\tconst sourceNode = producer<T>(\n\t\t(a) =>\n\t\t\trunFetch({\n\t\t\t\temit: (v) => a.emit(v),\n\t\t\t\tdown: (msgs) => a.down(msgs as unknown as [symbol, unknown?][]),\n\t\t\t}),\n\t\t{\n\t\t\t...sourceOpts(rest),\n\t\t\t// `resubscribable: true` when refetchOnSubscribe — each new activation\n\t\t\t// (subscribe after full deactivation) re-runs the producer fn → fresh\n\t\t\t// fetch. Default (cache-once) stays non-resubscribable: producer runs\n\t\t\t// once on first activation, cached DATA replays to late subscribers.\n\t\t\tresubscribable: refetchOnSubscribe,\n\t\t},\n\t);\n\n\tconst tracked = withStatus(sourceNode);\n\n\treturn {\n\t\t...tracked,\n\t\tfetchCount,\n\t\tlastUpdated,\n\t\tfetched,\n\t};\n}\n\n// ——————————————————————————————————————————————————————————————\n// toHTTP sink\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link toHTTP}. */\nexport type ToHTTPOptions<T> = ExtraOpts & {\n\t/** HTTP method. Default: `\"POST\"`. */\n\tmethod?: string;\n\t/** Request headers applied to every call. Caller sets Content-Type. */\n\theaders?: Record<string, string>;\n\t/** Serialize a value to a request body. Default: `JSON.stringify`. */\n\tserialize?: (value: T) => string | Uint8Array;\n\t/** Optional request timeout in nanoseconds. */\n\ttimeoutNs?: number;\n\t/**\n\t * Format used when `batchSize` / `flushIntervalMs` is set:\n\t * - `\"json-array\"` — body is `JSON.stringify(batch)`\n\t * - `\"ndjson\"` — body is newline-delimited JSON.\n\t * Default: `\"json-array\"`.\n\t */\n\tbatchFormat?: \"json-array\" | \"ndjson\";\n\t/** Batch size before auto-flush (buffered mode). */\n\tbatchSize?: number;\n\t/** Flush interval in ms (buffered mode). */\n\tflushIntervalMs?: number;\n\t/** Retry configuration — same shape as {@link ReactiveSinkRetryOptions}. */\n\tretry?: Parameters<typeof reactiveSink<T>>[1][\"retry\"];\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * HTTP sink — forwards upstream `DATA` values as HTTP requests.\n *\n * Per-record mode (default, no batching knobs): one request per DATA.\n * Buffered mode (`batchSize` / `flushIntervalMs`): one request per chunk,\n * body is JSON-array or NDJSON depending on `batchFormat`.\n *\n * @param source - Upstream node.\n * @param url - Request URL.\n * @param opts - Serialization, batching, retry options.\n * @returns {@link ReactiveSinkHandle}.\n *\n * @category extra\n */\nexport function toHTTP<T>(\n\tsource: Node<T>,\n\turl: string,\n\topts?: ToHTTPOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tmethod = \"POST\",\n\t\theaders = { \"Content-Type\": \"application/json\" },\n\t\tserialize = (v: T) => JSON.stringify(v),\n\t\ttimeoutNs,\n\t\tbatchFormat = \"json-array\",\n\t\tbatchSize,\n\t\tflushIntervalMs,\n\t\tretry,\n\t\tonTransportError,\n\t} = opts ?? {};\n\n\tconst sendOne = async (body: string | Uint8Array): Promise<void> => {\n\t\tconst controller = timeoutNs !== undefined ? new AbortController() : undefined;\n\t\tlet timeoutId: ReturnType<typeof setTimeout> | undefined;\n\t\tif (controller && timeoutNs !== undefined) {\n\t\t\ttimeoutId = setTimeout(\n\t\t\t\t() => controller.abort(new Error(\"Request timeout\")),\n\t\t\t\tMath.ceil(timeoutNs / NS_PER_MS),\n\t\t\t);\n\t\t}\n\t\ttry {\n\t\t\tconst res = await fetch(url, {\n\t\t\t\tmethod,\n\t\t\t\theaders,\n\t\t\t\tbody: body as BodyInit | null | undefined,\n\t\t\t\tsignal: controller?.signal,\n\t\t\t});\n\t\t\t// Drain the response body in every branch — un-drained bodies on\n\t\t\t// non-ok responses hold the connection open in Node's fetch pool\n\t\t\t// until GC, which starves the pool during retry storms.\n\t\t\tconst drain = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait res.arrayBuffer?.();\n\t\t\t\t} catch {\n\t\t\t\t\t/* body already consumed / socket dead — nothing to drain */\n\t\t\t\t}\n\t\t\t};\n\t\t\tif (!res.ok) {\n\t\t\t\tawait drain();\n\t\t\t\tthrow new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\t\t}\n\t\t\tawait drain();\n\t\t} finally {\n\t\t\tif (timeoutId !== undefined) clearTimeout(timeoutId);\n\t\t}\n\t};\n\n\tconst buffered = batchSize !== undefined || flushIntervalMs !== undefined;\n\tif (buffered) {\n\t\t// Buffered mode: batchFormat decides the body shape; per-item `serialize`\n\t\t// is only applied for ndjson (line-oriented). json-array format sends the\n\t\t// raw batch through `JSON.stringify` as a single array.\n\t\treturn reactiveSink<T>(source, {\n\t\t\tonTransportError,\n\t\t\tretry,\n\t\t\tbatchSize,\n\t\t\tflushIntervalMs,\n\t\t\tsendBatch: async (chunk) => {\n\t\t\t\tlet body: string | Uint8Array;\n\t\t\t\tif (batchFormat === \"ndjson\") {\n\t\t\t\t\tbody = (chunk as T[])\n\t\t\t\t\t\t.map((v) => {\n\t\t\t\t\t\t\tconst s = serialize(v);\n\t\t\t\t\t\t\treturn typeof s === \"string\" ? s : new TextDecoder().decode(s);\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.join(\"\\n\");\n\t\t\t\t} else {\n\t\t\t\t\tbody = JSON.stringify(chunk);\n\t\t\t\t}\n\t\t\t\tawait sendOne(body);\n\t\t\t},\n\t\t});\n\t}\n\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tretry,\n\t\tserialize,\n\t\tsend: async (payload) => {\n\t\t\tawait sendOne(payload as string | Uint8Array);\n\t\t},\n\t});\n}\n\n// ——————————————————————————————————————————————————————————————\n// SSE sink\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link toSSE}. */\nexport type ToSSEOptions = {\n\t/** Custom payload serializer for non-string payloads. Default: `JSON.stringify` fallback to `String(value)`. */\n\tserialize?: (value: unknown) => string;\n\t/** Event name for DATA tuples. Default: `\"data\"`. */\n\tdataEvent?: string;\n\t/** Event name for ERROR tuples. Default: `\"error\"`. */\n\terrorEvent?: string;\n\t/** Event name for COMPLETE tuples. Default: `\"complete\"`. */\n\tcompleteEvent?: string;\n\t/** Emit `event: resolved` when RESOLVED arrives. Default: `false`. */\n\tincludeResolved?: boolean;\n\t/** Emit `event: dirty` when DIRTY arrives. Default: `false`. */\n\tincludeDirty?: boolean;\n\t/** Add SSE comment keepalive frames (`: keepalive`) on an interval. Disabled when unset. */\n\tkeepAliveMs?: number;\n\t/** Optional abort signal to terminate the stream early. */\n\tsignal?: AbortSignal;\n\t/** Maps custom message types to SSE event names. */\n\teventNameResolver?: (type: symbol) => string;\n};\n\nfunction messageTypeLabel(t: symbol): string {\n\treturn Symbol.keyFor(t) ?? t.description ?? \"message\";\n}\n\nfunction serializeSseData(value: unknown, serialize: (value: unknown) => string): string {\n\tif (typeof value === \"string\") return value;\n\treturn serialize(value);\n}\n\nfunction sseFrame(event: string, data?: string): string {\n\tlet out = `event: ${event}\\n`;\n\tif (data !== undefined) {\n\t\tconst lines = data.split(/\\r?\\n/);\n\t\tfor (const line of lines) {\n\t\t\tout += `data: ${line}\\n`;\n\t\t}\n\t}\n\treturn `${out}\\n`;\n}\n\n/**\n * Creates a standard Server-Sent Events stream from node messages.\n *\n * @category extra\n */\nexport function toSSE<T>(source: Node<T>, opts?: ToSSEOptions): ReadableStream<Uint8Array> {\n\tconst {\n\t\tserialize = (value: unknown) => {\n\t\t\tif (value instanceof Error) return value.message;\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(value);\n\t\t\t} catch {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t},\n\t\tdataEvent = \"data\",\n\t\terrorEvent = \"error\",\n\t\tcompleteEvent = \"complete\",\n\t\tincludeResolved = false,\n\t\tincludeDirty = false,\n\t\tkeepAliveMs,\n\t\tsignal,\n\t\teventNameResolver = messageTypeLabel,\n\t} = opts ?? {};\n\tconst encoder = new TextEncoder();\n\tlet stop: (() => void) | undefined;\n\n\treturn new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\n\t\t\tlet closed = false;\n\t\t\tlet keepAlive: ReturnType<typeof setInterval> | undefined;\n\t\t\tlet unsub: () => void = () => {};\n\t\t\tconst close = () => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tif (keepAlive !== undefined) clearInterval(keepAlive);\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tunsub();\n\t\t\t\tcontroller.close();\n\t\t\t};\n\t\t\tstop = close;\n\t\t\tconst write = (event: string, data?: string) => {\n\t\t\t\tif (closed) return;\n\t\t\t\tcontroller.enqueue(encoder.encode(sseFrame(event, data)));\n\t\t\t};\n\t\t\tconst onAbort = () => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclose();\n\t\t\t};\n\t\t\tunsub = source.subscribe((msgs) => {\n\t\t\t\tfor (const msg of msgs) {\n\t\t\t\t\tconst t = msg[0];\n\t\t\t\t\t// Skip graph-local signals (tier < 3: START, DIRTY, INVALIDATE,\n\t\t\t\t\t// PAUSE, RESUME). DIRTY is opt-in for observability.\n\t\t\t\t\tif (defaultConfig.isLocalOnly(t)) {\n\t\t\t\t\t\tif (t === DIRTY && includeDirty) {\n\t\t\t\t\t\t\t/* fall through to write */\n\t\t\t\t\t\t} else continue;\n\t\t\t\t\t}\n\t\t\t\t\tif (t === DATA) {\n\t\t\t\t\t\twrite(dataEvent, serializeSseData(msg[1], serialize));\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (t === ERROR) {\n\t\t\t\t\t\twrite(errorEvent, serializeSseData(msg[1], serialize));\n\t\t\t\t\t\tclose();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (t === COMPLETE) {\n\t\t\t\t\t\twrite(completeEvent);\n\t\t\t\t\t\tclose();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// RESOLVED (tier 3) is opt-in for observability.\n\t\t\t\t\tif (!includeResolved && t === RESOLVED) continue;\n\t\t\t\t\twrite(\n\t\t\t\t\t\teventNameResolver(t),\n\t\t\t\t\t\tmsg.length > 1 ? serializeSseData(msg[1], serialize) : undefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t\tif (keepAliveMs !== undefined && keepAliveMs > 0) {\n\t\t\t\tkeepAlive = setInterval(() => {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tcontroller.enqueue(encoder.encode(\": keepalive\\n\\n\"));\n\t\t\t\t}, keepAliveMs);\n\t\t\t}\n\t\t\tif (signal?.aborted) onAbort();\n\t\t\telse signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t},\n\t\tcancel() {\n\t\t\tstop?.();\n\t\t},\n\t});\n}\n\n/**\n * Composable variant of {@link toSSE} — emits encoded SSE frames as\n * `Uint8Array` through a reactive `Node`. Use this when you want to pipe SSE\n * bytes through the reactive graph (persist to file, tee to multiple streams,\n * etc.). Wrap with {@link toReadableStream} to expose a `ReadableStream` for\n * `new Response(...)` use cases.\n *\n * @category extra\n */\nexport function toSSEBytes<T>(source: Node<T>, opts?: ToSSEOptions): Node<Uint8Array> {\n\tconst {\n\t\tserialize = (value: unknown) => {\n\t\t\tif (value instanceof Error) return value.message;\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(value);\n\t\t\t} catch {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t},\n\t\tdataEvent = \"data\",\n\t\terrorEvent = \"error\",\n\t\tcompleteEvent = \"complete\",\n\t\tincludeResolved = false,\n\t\tincludeDirty = false,\n\t\tkeepAliveMs,\n\t\tsignal,\n\t\teventNameResolver = messageTypeLabel,\n\t} = opts ?? {};\n\tconst encoder = new TextEncoder();\n\treturn producer<Uint8Array>((a) => {\n\t\tlet active = true;\n\t\tlet keepAlive: ReturnType<typeof setInterval> | undefined;\n\t\tconst emitFrame = (event: string, data?: string) => {\n\t\t\tif (!active) return;\n\t\t\ta.emit(encoder.encode(sseFrame(event, data)));\n\t\t};\n\t\tconst onAbort = () => {\n\t\t\tif (!active) return;\n\t\t\tactive = false;\n\t\t\ta.down([[COMPLETE]]);\n\t\t};\n\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\tif (!active) return;\n\t\t\tfor (const msg of msgs) {\n\t\t\t\tconst t = msg[0];\n\t\t\t\tif (defaultConfig.isLocalOnly(t)) {\n\t\t\t\t\tif (t === DIRTY && includeDirty) {\n\t\t\t\t\t\t/* fall through */\n\t\t\t\t\t} else continue;\n\t\t\t\t}\n\t\t\t\tif (t === DATA) {\n\t\t\t\t\temitFrame(dataEvent, serializeSseData(msg[1], serialize));\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (t === ERROR) {\n\t\t\t\t\temitFrame(errorEvent, serializeSseData(msg[1], serialize));\n\t\t\t\t\tactive = false;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (t === COMPLETE) {\n\t\t\t\t\temitFrame(completeEvent);\n\t\t\t\t\tactive = false;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!includeResolved && t === RESOLVED) continue;\n\t\t\t\temitFrame(\n\t\t\t\t\teventNameResolver(t),\n\t\t\t\t\tmsg.length > 1 ? serializeSseData(msg[1], serialize) : undefined,\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t\tif (keepAliveMs !== undefined && keepAliveMs > 0) {\n\t\t\tkeepAlive = setInterval(() => {\n\t\t\t\tif (!active) return;\n\t\t\t\ta.emit(encoder.encode(\": keepalive\\n\\n\"));\n\t\t\t}, keepAliveMs);\n\t\t}\n\t\tif (signal?.aborted) onAbort();\n\t\telse signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\tif (keepAlive !== undefined) clearInterval(keepAlive);\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tunsub();\n\t\t};\n\t});\n}\n\n/**\n * Converts a `Node<Uint8Array>` into a WHATWG `ReadableStream<Uint8Array>`.\n * Useful for composing with `new Response(...)` / `fetch` bodies.\n *\n * @category extra\n */\nexport function toReadableStream(bytes: Node<Uint8Array>): ReadableStream<Uint8Array> {\n\tlet unsub: (() => void) | undefined;\n\tlet closed = false;\n\treturn new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\n\t\t\tunsub = bytes.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tconst t = m[0];\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tif (t === DATA) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tcontroller.enqueue(m[1] as Uint8Array);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* controller closed mid-batch — upstream unsub will follow */\n\t\t\t\t\t\t\tclosed = true;\n\t\t\t\t\t\t\tunsub?.();\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tclosed = true;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tcontroller.error(m[1]);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* controller already closed */\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === COMPLETE) {\n\t\t\t\t\t\tclosed = true;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tcontroller.close();\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* controller already closed */\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\tcancel() {\n\t\t\tclosed = true;\n\t\t\tunsub?.();\n\t\t},\n\t});\n}\n\n// ——————————————————————————————————————————————————————————————\n// fromSSE source\n// ——————————————————————————————————————————————————————————————\n\n/** Parsed Server-Sent Event. */\nexport type SSEEvent<T = string> = {\n\tevent: string;\n\tdata: T;\n\tid?: string;\n\tretry?: number;\n};\n\n/** Options for {@link fromSSE}. */\nexport type FromSSEOptions<T = string> = ExtraOpts & {\n\t/** Parse the raw `data:` payload. Default: identity (string). */\n\tparse?: (raw: string) => T;\n};\n\n/**\n * Parses a Server-Sent Events stream into structured `{event, data, id}` records.\n *\n * @param source - SSE byte source (`ReadableStream`, `Response`, or `AsyncIterable<Uint8Array>`).\n * @param opts - Parse function and node options.\n * @returns `Node<SSEEvent<T>>` — one `DATA` per SSE event; `COMPLETE` on stream end.\n *\n * @category extra\n */\nexport function fromSSE<T = string>(\n\tsource: ReadableStream<Uint8Array> | Response | AsyncIterable<Uint8Array>,\n\topts?: FromSSEOptions<T>,\n): Node<SSEEvent<T>> {\n\tconst { parse = (raw: string) => raw as unknown as T, ...rest } = opts ?? {};\n\treturn producer<SSEEvent<T>>((a) => {\n\t\tlet active = true;\n\t\tconst decoder = new TextDecoder();\n\t\tlet buffer = \"\";\n\t\tlet currentEvent = \"message\";\n\t\tlet currentData: string[] = [];\n\t\tlet currentId: string | undefined;\n\t\tlet currentRetry: number | undefined;\n\n\t\tconst flushEvent = () => {\n\t\t\tif (currentData.length === 0 && currentEvent === \"message\" && currentId === undefined) {\n\t\t\t\tcurrentData = [];\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst raw = currentData.join(\"\\n\");\n\t\t\ta.emit({\n\t\t\t\tevent: currentEvent,\n\t\t\t\tdata: parse(raw),\n\t\t\t\tid: currentId,\n\t\t\t\tretry: currentRetry,\n\t\t\t});\n\t\t\tcurrentEvent = \"message\";\n\t\t\tcurrentData = [];\n\t\t\tcurrentId = undefined;\n\t\t\tcurrentRetry = undefined;\n\t\t};\n\n\t\tconst processLine = (line: string) => {\n\t\t\tif (line === \"\") {\n\t\t\t\tflushEvent();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (line.startsWith(\":\")) return; // comment\n\t\t\tconst colon = line.indexOf(\":\");\n\t\t\tconst field = colon < 0 ? line : line.slice(0, colon);\n\t\t\tlet value = colon < 0 ? \"\" : line.slice(colon + 1);\n\t\t\tif (value.startsWith(\" \")) value = value.slice(1);\n\t\t\tswitch (field) {\n\t\t\t\tcase \"event\":\n\t\t\t\t\tcurrentEvent = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"data\":\n\t\t\t\t\tcurrentData.push(value);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"id\":\n\t\t\t\t\tif (!value.includes(\"\\0\")) currentId = value;\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"retry\": {\n\t\t\t\t\tconst n = Number(value);\n\t\t\t\t\tif (Number.isFinite(n)) currentRetry = n;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tconst processChunk = (chunk: Uint8Array, done: boolean) => {\n\t\t\tif (!active) return;\n\t\t\tbuffer += decoder.decode(chunk, { stream: !done });\n\t\t\tconst parts = buffer.split(/\\r?\\n/);\n\t\t\tbuffer = parts.pop() ?? \"\";\n\t\t\tfor (const line of parts) processLine(line);\n\t\t};\n\n\t\t// Captured so teardown can `cancel()` the reader / iterator promptly\n\t\t// instead of waiting for `reader.read()` to resolve on its own.\n\t\tlet reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n\t\tlet iter: AsyncIterator<Uint8Array> | undefined;\n\n\t\tconst run = async () => {\n\t\t\ttry {\n\t\t\t\tconst resp = source as Response;\n\t\t\t\tconst stream =\n\t\t\t\t\tsource instanceof ReadableStream\n\t\t\t\t\t\t? source\n\t\t\t\t\t\t: resp && typeof resp === \"object\" && resp.body instanceof ReadableStream\n\t\t\t\t\t\t\t? resp.body\n\t\t\t\t\t\t\t: null;\n\t\t\t\tif (stream) {\n\t\t\t\t\treader = stream.getReader();\n\t\t\t\t\twhile (active) {\n\t\t\t\t\t\tconst { value, done } = await reader.read();\n\t\t\t\t\t\tif (done) break;\n\t\t\t\t\t\tprocessChunk(value, false);\n\t\t\t\t\t}\n\t\t\t\t\tprocessChunk(new Uint8Array(), true);\n\t\t\t\t} else {\n\t\t\t\t\tconst asyncIter = source as AsyncIterable<Uint8Array>;\n\t\t\t\t\titer = asyncIter[Symbol.asyncIterator]();\n\t\t\t\t\twhile (active) {\n\t\t\t\t\t\tconst step = await iter.next();\n\t\t\t\t\t\tif (step.done) break;\n\t\t\t\t\t\tprocessChunk(step.value, false);\n\t\t\t\t\t}\n\t\t\t\t\tprocessChunk(new Uint8Array(), true);\n\t\t\t\t}\n\t\t\t\tif (buffer.trim()) {\n\t\t\t\t\tfor (const line of buffer.split(/\\r?\\n/)) processLine(line);\n\t\t\t\t\tflushEvent();\n\t\t\t\t}\n\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\t\tvoid run();\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\t// Cancel reader / iterator so the pending `read()` / `next()`\n\t\t\t// resolves immediately — otherwise teardown would wait for the\n\t\t\t// next chunk (could be indefinitely on a quiet stream).\n\t\t\tif (reader) {\n\t\t\t\tvoid reader.cancel().catch(() => {\n\t\t\t\t\t/* cancel on already-closed reader is a no-op */\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (iter && typeof iter.return === \"function\") {\n\t\t\t\tvoid Promise.resolve(iter.return()).catch(() => undefined);\n\t\t\t}\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n// ——————————————————————————————————————————————————————————————\n// fromHTTPStream source\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link fromHTTPStream}. */\nexport type FromHTTPStreamOptions = ExtraOpts & {\n\tmethod?: string;\n\theaders?: Record<string, string>;\n\tbody?: unknown;\n\tsignal?: AbortSignal;\n};\n\n/**\n * Streaming HTTP source — emits each chunk from the response body as a\n * `Uint8Array` `DATA`. `COMPLETE` when the stream ends; `ERROR` on non-ok\n * response or fetch failure.\n *\n * Useful for ingesting server-push APIs (LLM streaming, SSE endpoints — pair\n * with {@link fromSSE}, NDJSON endpoints — pair with {@link fromNDJSON}).\n *\n * @category extra\n */\nexport function fromHTTPStream(url: string, opts?: FromHTTPStreamOptions): Node<Uint8Array> {\n\tconst { method = \"GET\", headers, body: bodyOpt, signal: externalSignal, ...rest } = opts ?? {};\n\treturn producer<Uint8Array>((a) => {\n\t\tlet active = true;\n\t\tconst abort = new AbortController();\n\t\tif (externalSignal?.aborted) {\n\t\t\ta.down([[ERROR, externalSignal.reason ?? new Error(\"Aborted\")]]);\n\t\t\treturn () => {};\n\t\t}\n\t\texternalSignal?.addEventListener(\"abort\", () => abort.abort(externalSignal.reason), {\n\t\t\tonce: true,\n\t\t});\n\t\tconst body =\n\t\t\tbodyOpt !== undefined\n\t\t\t\t? typeof bodyOpt === \"string\"\n\t\t\t\t\t? bodyOpt\n\t\t\t\t\t: JSON.stringify(bodyOpt)\n\t\t\t\t: undefined;\n\n\t\tconst run = async () => {\n\t\t\ttry {\n\t\t\t\tconst res = await fetch(url, { method, headers, body, signal: abort.signal });\n\t\t\t\tif (!active) return;\n\t\t\t\tif (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\t\t\tif (!res.body) throw new Error(\"HTTP response has no body\");\n\t\t\t\tconst reader = res.body.getReader();\n\t\t\t\twhile (active) {\n\t\t\t\t\tconst { value, done } = await reader.read();\n\t\t\t\t\tif (done) break;\n\t\t\t\t\tif (value) a.emit(value);\n\t\t\t\t}\n\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\tif (!active) return;\n\t\t\t\tif (err && (err as Error).name === \"AbortError\") return;\n\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\t\tvoid run();\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\tabort.abort();\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n// ——————————————————————————————————————————————————————————————\n// fromHTTPPoll source\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link fromHTTPPoll}. */\nexport type FromHTTPPollOptions = FromHTTPOptions & {\n\t/** Poll interval in milliseconds. Default: `5000`. */\n\tintervalMs?: number;\n};\n\n/**\n * Repeatedly-fetching HTTP source — a reactive composition of\n * {@link fromTimer} + {@link switchMap} + {@link fromHTTP} that fetches on an\n * interval and emits the latest response. Previous in-flight fetches are\n * cancelled when a new tick arrives (switch semantics).\n *\n * @example\n * ```ts\n * import { fromHTTPPoll } from \"@graphrefly/graphrefly-ts\";\n * const health$ = fromHTTPPoll<{ ok: boolean }>(\"https://example.com/health\", { intervalMs: 10_000 });\n * ```\n *\n * @category extra\n */\nexport function fromHTTPPoll<T = unknown>(url: string, opts?: FromHTTPPollOptions): Node<T> {\n\tconst { intervalMs = 5000, ...httpOpts } = opts ?? {};\n\treturn switchMap(\n\t\tfromTimer(intervalMs, { period: intervalMs }),\n\t\t() => fromHTTP<T>(url, { ...httpOpts, completeAfterFetch: true }).node,\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// WebSocket sink (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link toWebSocket}. */\nexport type ToWebSocketOptions<T> = {\n\t/** Serialize DATA payloads before `socket.send(...)`. */\n\tserialize?: (value: T) => string | ArrayBufferLike | Blob | ArrayBufferView;\n\t/** Close socket when upstream emits COMPLETE. Default: `true`. */\n\tcloseOnComplete?: boolean;\n\t/** Close socket when upstream emits ERROR. Default: `true`. */\n\tcloseOnError?: boolean;\n\t/** Optional close code used when close is triggered by terminal tuples. */\n\tcloseCode?: number;\n\t/** Optional close reason used when close is triggered by terminal tuples. */\n\tcloseReason?: string;\n\t/** Structured callback — uses the unified {@link SinkTransportError} shape. */\n\tonTransportError?: (event: SinkTransportError) => void;\n\t/** Retry configuration — passed through to {@link reactiveSink}. */\n\tretry?: ReactiveSinkHandle<T> extends infer _\n\t\t? Parameters<typeof reactiveSink<T>>[1][\"retry\"]\n\t\t: never;\n\t/** Backpressure configuration — passed through to {@link reactiveSink}. */\n\tbackpressure?: Parameters<typeof reactiveSink<T>>[1][\"backpressure\"];\n\t/** Reactive stop signal — when it emits any DATA / terminal, the sink tears down. */\n\tstopOn?: Node<unknown>;\n};\n\n/**\n * Forwards upstream `DATA` payloads to a WebSocket via `send`.\n *\n * Returns a {@link ReactiveSinkHandle} — every transport outcome (including\n * socket `close` events) surfaces on the `errors` / `failed` / `sent` /\n * `inFlight` companions.\n *\n * @category extra\n */\nexport function toWebSocket<T>(\n\tsource: Node<T>,\n\tsocket: WebSocketLike,\n\topts?: ToWebSocketOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tserialize = (value: T) => {\n\t\t\tif (\n\t\t\t\ttypeof value === \"string\" ||\n\t\t\t\tvalue instanceof Blob ||\n\t\t\t\tvalue instanceof ArrayBuffer ||\n\t\t\t\tArrayBuffer.isView(value)\n\t\t\t) {\n\t\t\t\treturn value as string | ArrayBufferLike | Blob | ArrayBufferView;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(value);\n\t\t\t} catch {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t},\n\t\tcloseOnComplete = true,\n\t\tcloseOnError = true,\n\t\tcloseCode,\n\t\tcloseReason,\n\t\tonTransportError,\n\t\tretry,\n\t\tbackpressure,\n\t\tstopOn,\n\t} = opts ?? {};\n\n\tlet socketClosed = false;\n\tconst closeSocket = (trigger?: Message) => {\n\t\tif (socketClosed) return;\n\t\tsocketClosed = true;\n\t\ttry {\n\t\t\tsocket.close(closeCode, closeReason);\n\t\t} catch (err) {\n\t\t\tconst error = err instanceof Error ? err : new Error(String(err));\n\t\t\ttry {\n\t\t\t\tonTransportError?.({ stage: \"close\", error, value: undefined, message: trigger });\n\t\t\t} catch {\n\t\t\t\t/* user hook must not escape */\n\t\t\t}\n\t\t}\n\t};\n\n\t// External close listener — installed before sink construction so we can\n\t// pass its cleanup via reactiveSink's `onDispose` hook. That hook fires on\n\t// any teardown path (user `.dispose()`, `stopOn` signal, upstream\n\t// terminal) — guaranteeing the listener is removed even when the reactive\n\t// sink's internal dispose fires without going through a wrapper.\n\tlet externalCloseHandler: ((ev: unknown) => void) | null = null;\n\tconst removeExternalCloseHandler = () => {\n\t\tif (externalCloseHandler) {\n\t\t\ttry {\n\t\t\t\tsocket.removeEventListener(\"close\", externalCloseHandler);\n\t\t\t} catch {\n\t\t\t\t/* removeEventListener may throw on some environments when socket is dead */\n\t\t\t}\n\t\t\texternalCloseHandler = null;\n\t\t}\n\t};\n\n\tconst handle = reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tserialize: (value) => {\n\t\t\tconst s = serialize(value);\n\t\t\tif (s === undefined) {\n\t\t\t\tthrow new Error(\"serialize returned undefined\");\n\t\t\t}\n\t\t\treturn s;\n\t\t},\n\t\tretry,\n\t\tbackpressure,\n\t\tstopOn,\n\t\tonDispose: removeExternalCloseHandler,\n\t\tsend: (payload) => {\n\t\t\tsocket.send(payload as string | ArrayBufferLike | Blob | ArrayBufferView);\n\t\t},\n\t\tonUpstreamMessage: (msg) => {\n\t\t\tif (msg[0] === COMPLETE && closeOnComplete) closeSocket(msg);\n\t\t\telse if (msg[0] === ERROR && closeOnError) closeSocket(msg);\n\t\t},\n\t});\n\n\t// Listen for external socket `close` events to tear the sink down.\n\texternalCloseHandler = () => {\n\t\tsocketClosed = true;\n\t\thandle.dispose();\n\t};\n\tsocket.addEventListener(\"close\", externalCloseHandler);\n\treturn handle;\n}\n\n// ——————————————————————————————————————————————————————————————\n// fromWebSocketReconnect — reconnecting WebSocket source via retrySource\n// ——————————————————————————————————————————————————————————————\n\n/** Options for {@link fromWebSocketReconnect}. */\nexport type FromWebSocketReconnectOptions<T> = ExtraOpts & {\n\t/** Optional parser applied to incoming messages. */\n\tparse?: (payload: unknown, event: unknown) => T;\n\t/** Max reconnect attempts. Default: `Infinity` (implied when `backoff` is set). */\n\tmaxRetries?: number;\n\t/** Backoff strategy (ns) or preset name. Default: `\"exponential\"`. */\n\tbackoff?: Parameters<typeof retrySource>[1] extends infer O\n\t\t? O extends { backoff?: infer B }\n\t\t\t? B\n\t\t\t: never\n\t\t: never;\n\t/** Close the socket on teardown. Default: `true`. */\n\tcloseOnTeardown?: boolean;\n};\n\n/**\n * Reconnecting WebSocket source — each connection attempt calls `factory` to\n * obtain a fresh {@link WebSocketLike}; on `close` (treated as terminal\n * `COMPLETE`), {@link retrySource} rebuilds the inner source and reconnects.\n *\n * For transient errors, {@link retrySource} retries with the configured\n * backoff. On `maxRetries` exhaustion, terminal `ERROR` propagates.\n *\n * @param factory - Invoked per reconnect to create a fresh WebSocket.\n * @param opts - Parse, retry, and close options.\n *\n * @example\n * ```ts\n * import { fromWebSocketReconnect } from \"@graphrefly/graphrefly-ts\";\n * const ws$ = fromWebSocketReconnect(\n * () => new WebSocket(\"wss://example/stream\"),\n * { backoff: \"exponential\", maxRetries: 10 },\n * );\n * ```\n *\n * @category extra\n */\nexport function fromWebSocketReconnect<T = unknown>(\n\tfactory: () => WebSocketLike,\n\topts?: FromWebSocketReconnectOptions<T>,\n): Node<T> {\n\tconst {\n\t\tparse,\n\t\tmaxRetries,\n\t\tbackoff = \"exponential\",\n\t\tcloseOnTeardown = true,\n\t\t...rest\n\t} = opts ?? {};\n\treturn retrySource<T>(\n\t\t() =>\n\t\t\tfromWebSocket<T>(factory(), {\n\t\t\t\tparse,\n\t\t\t\tcloseOnTeardown,\n\t\t\t\t...rest,\n\t\t\t}),\n\t\t{ count: maxRetries, backoff },\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// MCP adapter (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Duck-typed MCP (Model Context Protocol) client — only the notification\n * registration surface is required so callers are not coupled to a specific SDK.\n */\nexport type MCPClientLike = {\n\tsetNotificationHandler(method: string, handler: (notification: unknown) => void): void;\n};\n\n/** Options for {@link fromMCP}. */\nexport type FromMCPOptions = ExtraOpts & {\n\t/** MCP notification method to subscribe to. Default `\"notifications/message\"`. */\n\tmethod?: string;\n\tonDisconnect?: (cb: (err?: unknown) => void) => void;\n};\n\n/**\n * Wraps an MCP client's server-push notifications as a reactive source.\n *\n * @category extra\n */\nexport function fromMCP<T = unknown>(client: MCPClientLike, opts?: FromMCPOptions): Node<T> {\n\tconst { method = \"notifications/message\", onDisconnect, ...rest } = opts ?? {};\n\treturn externalProducer<T>(({ emit, error }) => {\n\t\tclient.setNotificationHandler(method, (notification) => emit(notification as T));\n\t\tonDisconnect?.((err?: unknown) => error(err ?? new Error(\"MCP client disconnected\")));\n\t\t// MCP SDKs do not expose handler deregistration — replace with a no-op\n\t\t// on teardown. Caller owns the client lifecycle for full cleanup.\n\t\treturn () => client.setNotificationHandler(method, () => {});\n\t}, rest);\n}\n\n// ——————————————————————————————————————————————————————————————\n// Git adapter (from sources.ts)\n// ——————————————————————————————————————————————————————————————\n\n/** Git hook type for {@link fromGitHook}. */\nexport type GitHookType = \"post-commit\" | \"post-merge\" | \"post-checkout\" | \"post-rewrite\";\n\n/** Structured git event emitted by {@link fromGitHook}. */\nexport type GitEvent = {\n\thook: GitHookType;\n\tcommit: string;\n\tfiles: string[];\n\tmessage: string;\n\tauthor: string;\n\ttimestamp_ns: number;\n};\n\n/** Options for {@link fromGitHook}. */\nexport type FromGitHookOptions = ExtraOpts & {\n\tpollMs?: number;\n\tinclude?: string[];\n\texclude?: string[];\n\t/**\n\t * Maximum consecutive poll errors before terminating the source. Prevents\n\t * error storms when the repository is unavailable (e.g. deleted, corrupt,\n\t * permissions lost). Default: `1` (terminate on first error — preserves pre-switchMap back-compat). Raise it (or set `Infinity`) to keep retrying\n\t * indefinitely (legacy behavior).\n\t */\n\tmaxConsecutiveErrors?: number;\n};\n\n// globToRegExp, matchesAnyPattern imported from ./sources.js\n\n/**\n * Git change detection as a reactive source.\n *\n * @category extra\n */\nexport function fromGitHook(repoPath: string, opts?: FromGitHookOptions): Node<GitEvent> {\n\tconst { pollMs = 5000, include, exclude, maxConsecutiveErrors = 1 } = opts ?? {};\n\tconst includePatterns = include?.map(globToRegExp) ?? [];\n\tconst excludePatterns = exclude?.map(globToRegExp) ?? [];\n\tconst { execFileSync } = require(\"node:child_process\") as typeof import(\"node:child_process\");\n\n\tconst gitQuery = (args: string[]): string =>\n\t\texecFileSync(\"git\", args, { cwd: repoPath, encoding: \"utf-8\" }).trim();\n\n\t// Shared across ticks: the previous HEAD we committed to. Undefined on the\n\t// very first poll (we record the initial HEAD without emitting).\n\tlet lastSeen: string | undefined;\n\t// Circuit breaker: consecutive error count. Resets on any successful poll.\n\tlet consecutiveErrors = 0;\n\n\t// `fromTimer | switchMap(sync-git-diff)` — ticks drive the poll, switchMap\n\t// cancels any in-flight inner on next tick. First tick at t=0 records the\n\t// baseline HEAD silently; subsequent ticks emit `GitEvent` on HEAD change.\n\treturn switchMap(fromTimer(0, { period: pollMs }), () =>\n\t\tproducer<GitEvent>((a) => {\n\t\t\ttry {\n\t\t\t\tconst head = gitQuery([\"rev-parse\", \"HEAD\"]);\n\t\t\t\tif (!head) {\n\t\t\t\t\tconsecutiveErrors = 0;\n\t\t\t\t\treturn () => {};\n\t\t\t\t}\n\t\t\t\tif (lastSeen === undefined) {\n\t\t\t\t\t// First poll: record baseline; stay idle until next tick\n\t\t\t\t\t// disposes this inner.\n\t\t\t\t\tlastSeen = head;\n\t\t\t\t\tconsecutiveErrors = 0;\n\t\t\t\t\treturn () => {};\n\t\t\t\t}\n\t\t\t\tif (head === lastSeen) {\n\t\t\t\t\tconsecutiveErrors = 0;\n\t\t\t\t\treturn () => {};\n\t\t\t\t}\n\t\t\t\tlet files = gitQuery([\"diff\", \"--name-only\", `${lastSeen}..${head}`])\n\t\t\t\t\t.split(\"\\n\")\n\t\t\t\t\t.filter(Boolean);\n\t\t\t\tif (includePatterns.length > 0) {\n\t\t\t\t\tfiles = files.filter((f) => matchesAnyPattern(f, includePatterns));\n\t\t\t\t}\n\t\t\t\tif (excludePatterns.length > 0) {\n\t\t\t\t\tfiles = files.filter((f) => !matchesAnyPattern(f, excludePatterns));\n\t\t\t\t}\n\t\t\t\tconst message = gitQuery([\"log\", \"-1\", \"--format=%s\", head]);\n\t\t\t\tconst author = gitQuery([\"log\", \"-1\", \"--format=%an\", head]);\n\t\t\t\ta.emit({\n\t\t\t\t\thook: \"post-commit\" as GitHookType,\n\t\t\t\t\tcommit: head,\n\t\t\t\t\tfiles,\n\t\t\t\t\tmessage,\n\t\t\t\t\tauthor,\n\t\t\t\t\ttimestamp_ns: wallClockNs(),\n\t\t\t\t});\n\t\t\t\tlastSeen = head;\n\t\t\t\tconsecutiveErrors = 0;\n\t\t\t} catch (err) {\n\t\t\t\tconsecutiveErrors += 1;\n\t\t\t\tif (consecutiveErrors >= maxConsecutiveErrors) {\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t\t// else: transient error — next tick will retry; don't spam ERROR.\n\t\t\t}\n\t\t\treturn () => {};\n\t\t}),\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// 5.2c — Ingest adapters (universal source layer)\n// ——————————————————————————————————————————————————————————————\n\n// ——— Shared helpers ———\n\n/** Standard handler triple for adapters that accept injected registrations. Alias of {@link EmitTriad}. */\nexport type AdapterHandlers<T> = EmitTriad<T>;\n\n/**\n * Message envelope emitted by queue consumers when `autoAck: false`. The\n * caller is responsible for calling `ack()` after successful processing or\n * `nack()` to re-queue / dead-letter. Pairs cleanly with reactive pipelines:\n *\n * ```ts\n * const messages$ = fromPulsar(consumer, { autoAck: false });\n * effect([messages$], ([m]) => {\n * try {\n * process(m.value);\n * m.ack();\n * } catch (err) {\n * m.nack({ requeue: true });\n * }\n * });\n * ```\n *\n * Ack/nack are imperative callbacks (§5.10 boundary) because the underlying\n * SDKs expose them as such. Reactive-all-the-way ack flows can be built by\n * piping `msg.ack` calls into a `reactiveSink` if desired.\n *\n * **Caller contract — must settle every emitted message.** The envelope holds\n * a closure reference to the raw SDK message; unsettled envelopes keep the\n * broker's in-flight window full and leak memory proportional to consumer\n * throughput. Patterns that drop messages (filter, take-first, switchMap\n * discard) must explicitly `nack({ requeue: true })` the discarded ones, or\n * wrap the source to force-settle on teardown.\n *\n * **Ack/nack transport failures.** Both methods route exceptions through\n * the source's `onAckError` option (when provided) — SDK rejections from\n * `acknowledge()`/`negativeAcknowledge()` don't escape as unhandled\n * rejections. Default (no `onAckError`): swallow. The broker handles\n * redelivery on its own timeline.\n *\n * @category extra\n */\nexport type AckableMessage<T> = {\n\t/** The wrapped message body. */\n\tvalue: T;\n\t/** Acknowledge successful processing. Safe to call more than once — idempotent. */\n\tack(): void;\n\t/**\n\t * Negative-acknowledge — signals the broker the message was not processed\n\t * successfully. `requeue: true` asks the broker to redeliver; `requeue: false`\n\t * may route to a dead-letter queue (SDK-specific). Omit `requeue` to\n\t * defer to the SDK's own default.\n\t */\n\tnack(opts?: { requeue?: boolean }): void;\n};\n\n// ——— OpenTelemetry (OTLP/HTTP) ———\n\n/** Structured OTel span. */\nexport type OTelSpan = {\n\ttraceId: string;\n\tspanId: string;\n\toperationName: string;\n\tserviceName: string;\n\tstartTimeNs: number;\n\tendTimeNs: number;\n\tstatus: \"OK\" | \"ERROR\" | \"UNSET\";\n\tattributes: Record<string, unknown>;\n\tevents: Array<{ name: string; timestampNs: number; attributes?: Record<string, unknown> }>;\n};\n\n/** Structured OTel metric data point. */\nexport type OTelMetric = {\n\tname: string;\n\tdescription?: string;\n\tunit?: string;\n\ttype: \"gauge\" | \"sum\" | \"histogram\" | \"summary\";\n\tvalue: number;\n\tattributes: Record<string, unknown>;\n\ttimestampNs: number;\n};\n\n/** Structured OTel log record. */\nexport type OTelLog = {\n\ttimestampNs: number;\n\tseverityNumber?: number;\n\tseverityText?: string;\n\tbody: unknown;\n\tattributes: Record<string, unknown>;\n\ttraceId?: string;\n\tspanId?: string;\n};\n\n/** Registration callback for the OTLP/HTTP receiver. */\nexport type OTelRegister = (handlers: {\n\tonTraces: (spans: OTelSpan[]) => void;\n\tonMetrics: (metrics: OTelMetric[]) => void;\n\tonLogs: (logs: OTelLog[]) => void;\n\tonError: (err: unknown) => void;\n}) => (() => void) | undefined;\n\n/** Options for {@link fromOTel}. */\nexport type FromOTelOptions = ExtraOpts & {};\n\n/** Bundle returned by {@link fromOTel}. */\nexport type OTelBundle = {\n\ttraces: Node<OTelSpan>;\n\tmetrics: Node<OTelMetric>;\n\tlogs: Node<OTelLog>;\n\t/** Unconditional teardown — calls the registrar's cleanup and fires COMPLETE on every channel. */\n\tdispose(): void;\n};\n\n/**\n * OTLP/HTTP receiver — accepts traces, metrics, and logs as separate reactive nodes.\n *\n * The caller owns the HTTP server. `fromOTel` receives a `register` callback that\n * wires OTLP POST endpoints to the three signal handlers. Each signal type gets\n * its own `Node` so downstream can subscribe selectively.\n *\n * @param register - Wires OTLP HTTP routes to `onTraces`, `onMetrics`, `onLogs` handlers.\n * @param opts - Optional producer options.\n * @returns {@link OTelBundle} — `{ traces, metrics, logs }` nodes.\n *\n * @example\n * ```ts\n * import express from \"express\";\n * import { fromOTel } from \"@graphrefly/graphrefly-ts\";\n *\n * const app = express();\n * app.use(express.json());\n *\n * const otel = fromOTel(({ onTraces, onMetrics, onLogs }) => {\n * app.post(\"/v1/traces\", (req, res) => { onTraces(req.body.resourceSpans ?? []); res.sendStatus(200); });\n * app.post(\"/v1/metrics\", (req, res) => { onMetrics(req.body.resourceMetrics ?? []); res.sendStatus(200); });\n * app.post(\"/v1/logs\", (req, res) => { onLogs(req.body.resourceLogs ?? []); res.sendStatus(200); });\n * return () => {};\n * });\n * ```\n *\n * @category extra\n */\nexport function fromOTel(register: OTelRegister, opts?: FromOTelOptions): OTelBundle {\n\ttype OTelChannels = { traces: OTelSpan; metrics: OTelMetric; logs: OTelLog };\n\tconst nodes = externalBundle<OTelChannels>(\n\t\t({ traces, metrics, logs, error }: BundleTriad<OTelChannels>) => {\n\t\t\treturn (\n\t\t\t\tregister({\n\t\t\t\t\tonTraces: (spans) => {\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tfor (const s of spans) traces(s);\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tonMetrics: (ms) => {\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tfor (const m of ms) metrics(m);\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tonLogs: (ls) => {\n\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\tfor (const l of ls) logs(l);\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tonError: error,\n\t\t\t\t}) ?? undefined\n\t\t\t);\n\t\t},\n\t\t[\"traces\", \"metrics\", \"logs\"],\n\t\topts?.name ? { name: opts.name } : undefined,\n\t);\n\treturn nodes;\n}\n\n// ——— Syslog (RFC 5424) ———\n\n/** Parsed syslog message (RFC 5424). */\nexport type SyslogMessage = {\n\tfacility: number;\n\tseverity: number;\n\ttimestamp: string;\n\thostname: string;\n\tappName: string;\n\tprocId: string;\n\tmsgId: string;\n\tmessage: string;\n\ttimestampNs: number;\n};\n\n/** Registration callback for syslog receiver. Alias of {@link ExternalRegister} over {@link EmitTriad}. */\nexport type SyslogRegister = ExternalRegister<EmitTriad<SyslogMessage>>;\n\n/** Options for {@link fromSyslog}. */\nexport type FromSyslogOptions = ExtraOpts & {};\n\n/**\n * RFC 5424 syslog receiver as a reactive source.\n *\n * The caller owns the UDP/TCP socket. `fromSyslog` receives a `register` callback\n * that wires socket data events to the `emit` handler with parsed syslog messages.\n *\n * @param register - Wires socket to emit/error/complete handlers.\n * @param opts - Optional producer options.\n * @returns `Node<SyslogMessage>` — one `DATA` per syslog message.\n *\n * @example\n * ```ts\n * import dgram from \"node:dgram\";\n * import { fromSyslog, parseSyslog } from \"@graphrefly/graphrefly-ts\";\n *\n * const server = dgram.createSocket(\"udp4\");\n * const syslog$ = fromSyslog(({ emit, error }) => {\n * server.on(\"message\", (buf) => {\n * try { emit(parseSyslog(buf.toString())); }\n * catch (e) { error(e); }\n * });\n * server.bind(514);\n * return () => server.close();\n * });\n * ```\n *\n * @category extra\n */\nexport function fromSyslog(\n\tregister: SyslogRegister,\n\topts?: FromSyslogOptions,\n): Node<SyslogMessage> {\n\treturn externalProducer<SyslogMessage>(register, opts);\n}\n\n/**\n * Parses a raw RFC 5424 syslog line into a structured {@link SyslogMessage}.\n *\n * Format: `<PRI>VERSION TIMESTAMP HOSTNAME APP-NAME PROCID MSGID MSG`\n *\n * @category extra\n */\nexport function parseSyslog(raw: string): SyslogMessage {\n\tconst match = raw.match(/^<(\\d{1,3})>\\d?\\s*(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)\\s*(.*)/s);\n\tif (!match) {\n\t\tconst nowNs = wallClockNs();\n\t\treturn {\n\t\t\tfacility: 1,\n\t\t\tseverity: 6,\n\t\t\ttimestamp: new Date(Math.floor(nowNs / 1_000_000)).toISOString(),\n\t\t\thostname: \"-\",\n\t\t\tappName: \"-\",\n\t\t\tprocId: \"-\",\n\t\t\tmsgId: \"-\",\n\t\t\tmessage: raw.trim(),\n\t\t\ttimestampNs: nowNs,\n\t\t};\n\t}\n\tconst pri = Number(match[1]);\n\treturn {\n\t\tfacility: pri >> 3,\n\t\tseverity: pri & 7,\n\t\ttimestamp: match[2],\n\t\thostname: match[3],\n\t\tappName: match[4],\n\t\tprocId: match[5],\n\t\tmsgId: match[6],\n\t\tmessage: (match[7] ?? \"\").trim(),\n\t\ttimestampNs: wallClockNs(),\n\t};\n}\n\n// ——— StatsD / DogStatsD ———\n\n/** Parsed StatsD metric. */\nexport type StatsDMetric = {\n\tname: string;\n\tvalue: number;\n\ttype: \"counter\" | \"gauge\" | \"timer\" | \"histogram\" | \"set\" | \"distribution\";\n\tsampleRate?: number;\n\ttags: Record<string, string>;\n\ttimestampNs: number;\n};\n\n/** Registration callback for StatsD receiver. Alias of {@link ExternalRegister} over {@link EmitTriad}. */\nexport type StatsDRegister = ExternalRegister<EmitTriad<StatsDMetric>>;\n\n/** Options for {@link fromStatsD}. */\nexport type FromStatsDOptions = ExtraOpts & {};\n\n/**\n * StatsD/DogStatsD UDP receiver as a reactive source.\n *\n * The caller owns the UDP socket. `fromStatsD` receives a `register` callback\n * that wires datagrams to the `emit` handler with parsed metrics.\n *\n * @param register - Wires socket to emit/error/complete handlers.\n * @param opts - Optional producer options.\n * @returns `Node<StatsDMetric>` — one `DATA` per metric line.\n *\n * @example\n * ```ts\n * import dgram from \"node:dgram\";\n * import { fromStatsD, parseStatsD } from \"@graphrefly/graphrefly-ts\";\n *\n * const server = dgram.createSocket(\"udp4\");\n * const stats$ = fromStatsD(({ emit, error }) => {\n * server.on(\"message\", (buf) => {\n * for (const line of buf.toString().split(\"\\\\n\")) {\n * if (line.trim()) {\n * try { emit(parseStatsD(line)); }\n * catch (e) { error(e); }\n * }\n * }\n * });\n * server.bind(8125);\n * return () => server.close();\n * });\n * ```\n *\n * @category extra\n */\nexport function fromStatsD(register: StatsDRegister, opts?: FromStatsDOptions): Node<StatsDMetric> {\n\treturn externalProducer<StatsDMetric>(register, opts);\n}\n\nconst STATSD_TYPES: Record<string, StatsDMetric[\"type\"]> = {\n\tc: \"counter\",\n\tg: \"gauge\",\n\tms: \"timer\",\n\th: \"histogram\",\n\ts: \"set\",\n\td: \"distribution\",\n};\n\n/**\n * Parses a raw StatsD/DogStatsD line into a structured {@link StatsDMetric}.\n *\n * Format: `metric.name:value|type|@sampleRate|#tag1:val1,tag2:val2`\n *\n * @category extra\n */\nexport function parseStatsD(line: string): StatsDMetric {\n\tconst parts = line.split(\"|\");\n\tconst [name, valueStr] = (parts[0] ?? \"\").split(\":\");\n\tif (!name || valueStr === undefined) {\n\t\tthrow new Error(`Invalid StatsD line: ${line}`);\n\t}\n\tconst typeCode = parts[1]?.trim() ?? \"c\";\n\tconst type = STATSD_TYPES[typeCode] ?? \"counter\";\n\t// Set type uses string identifiers (e.g. unique user IDs), not numeric values.\n\tconst value = type === \"set\" ? 0 : Number(valueStr);\n\n\tlet sampleRate: number | undefined;\n\tconst tags: Record<string, string> = {};\n\n\tfor (let i = 2; i < parts.length; i++) {\n\t\tconst part = parts[i].trim();\n\t\tif (part.startsWith(\"@\")) {\n\t\t\tsampleRate = Number(part.slice(1));\n\t\t} else if (part.startsWith(\"#\")) {\n\t\t\tfor (const tag of part.slice(1).split(\",\")) {\n\t\t\t\tconst [k, v] = tag.split(\":\");\n\t\t\t\tif (k) tags[k] = v ?? \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { name: name.trim(), value, type, sampleRate, tags, timestampNs: wallClockNs() };\n}\n\n// ——— Prometheus scrape ———\n\n/** Parsed Prometheus metric. */\nexport type PrometheusMetric = {\n\tname: string;\n\tlabels: Record<string, string>;\n\tvalue: number;\n\ttimestampMs?: number;\n\ttype?: \"counter\" | \"gauge\" | \"histogram\" | \"summary\" | \"untyped\";\n\thelp?: string;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromPrometheus}. */\nexport type FromPrometheusOptions = AsyncSourceOpts & {\n\t/** Scrape interval in nanoseconds. Default `15 * NS_PER_SEC` (15s). */\n\tintervalNs?: number;\n\t/** Request headers for the scrape. */\n\theaders?: Record<string, string>;\n\t/** Request timeout in nanoseconds. Default `10 * NS_PER_SEC` (10s). */\n\ttimeoutNs?: number;\n\t/**\n\t * Maximum consecutive scrape errors before terminating the source. Prevents\n\t * error storms when the endpoint is down. Default: `1` (terminate on first error — preserves pre-switchMap back-compat). Raise it (or set `Infinity`)\n\t * to keep retrying indefinitely.\n\t */\n\tmaxConsecutiveErrors?: number;\n};\n\n/**\n * Scrapes a Prometheus `/metrics` endpoint on a reactive timer interval.\n *\n * Each scrape parses the exposition format and emits one `DATA` per metric line.\n * Uses `fromTimer` semantics internally (reactive timer source, not polling).\n *\n * @param endpoint - URL of the Prometheus metrics endpoint.\n * @param opts - Scrape interval, headers, timeout.\n * @returns `Node<PrometheusMetric>` — one `DATA` per metric per scrape.\n *\n * @example\n * ```ts\n * import { fromPrometheus } from \"@graphrefly/graphrefly-ts\";\n *\n * const prom$ = fromPrometheus(\"http://localhost:9090/metrics\", { intervalNs: 30 * NS_PER_SEC });\n * ```\n *\n * @category extra\n */\nexport function fromPrometheus(\n\tendpoint: string,\n\topts?: FromPrometheusOptions,\n): Node<PrometheusMetric> {\n\tconst {\n\t\tintervalNs = 15 * NS_PER_SEC,\n\t\theaders,\n\t\ttimeoutNs = 10 * NS_PER_SEC,\n\t\tsignal: externalSignal,\n\t\tmaxConsecutiveErrors = 1,\n\t} = opts ?? {};\n\tconst intervalMs = Math.ceil(intervalNs / NS_PER_MS);\n\t// Circuit breaker shared across switchMap inners — resets on any successful\n\t// scrape, trips when consecutive errors hit the cap.\n\tlet consecutiveErrors = 0;\n\n\t// Timer drives scrapes: first tick at t=0, then every intervalMs. Each tick\n\t// switches to a fresh inner producer that does one scrape and completes —\n\t// switchMap cancels any in-flight scrape when the next tick arrives.\n\treturn switchMap(fromTimer(0, { period: intervalMs, signal: externalSignal }), () =>\n\t\tproducer<PrometheusMetric>((a) => {\n\t\t\tlet active = true;\n\t\t\tconst abort = new AbortController();\n\t\t\tconst timeoutId = setTimeout(\n\t\t\t\t() => abort.abort(new Error(\"Scrape timeout\")),\n\t\t\t\tMath.ceil(timeoutNs / NS_PER_MS),\n\t\t\t);\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst res = await fetch(endpoint, {\n\t\t\t\t\t\theaders: { Accept: \"text/plain\", ...headers },\n\t\t\t\t\t\tsignal: abort.signal,\n\t\t\t\t\t});\n\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tif (!res.ok) throw new Error(`Prometheus scrape ${res.status}: ${res.statusText}`);\n\t\t\t\t\tconst text = await res.text();\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tconst metrics = parsePrometheusText(text);\n\t\t\t\t\tfor (const m of metrics) a.emit(m);\n\t\t\t\t\tconsecutiveErrors = 0;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tif (err instanceof Error && err.name === \"AbortError\") return;\n\t\t\t\t\tconsecutiveErrors += 1;\n\t\t\t\t\tif (consecutiveErrors >= maxConsecutiveErrors) {\n\t\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\t}\n\t\t\t\t\t// else: swallow transient error; next tick retries.\n\t\t\t\t}\n\t\t\t};\n\t\t\tvoid run();\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\tabort.abort();\n\t\t\t};\n\t\t}),\n\t);\n}\n\n/**\n * Parses Prometheus exposition format text into structured metrics.\n *\n * @category extra\n */\nexport function parsePrometheusText(text: string): PrometheusMetric[] {\n\tconst results: PrometheusMetric[] = [];\n\tconst types = new Map<string, string>();\n\tconst helps = new Map<string, string>();\n\n\tfor (const rawLine of text.split(\"\\n\")) {\n\t\tconst line = rawLine.trim();\n\t\tif (!line) continue;\n\n\t\tif (line.startsWith(\"# TYPE \")) {\n\t\t\tconst rest = line.slice(7);\n\t\t\tconst spaceIdx = rest.indexOf(\" \");\n\t\t\tif (spaceIdx > 0) {\n\t\t\t\ttypes.set(rest.slice(0, spaceIdx), rest.slice(spaceIdx + 1).trim());\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\"# HELP \")) {\n\t\t\tconst rest = line.slice(7);\n\t\t\tconst spaceIdx = rest.indexOf(\" \");\n\t\t\tif (spaceIdx > 0) {\n\t\t\t\thelps.set(rest.slice(0, spaceIdx), rest.slice(spaceIdx + 1).trim());\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (line.startsWith(\"#\")) continue;\n\n\t\t// metric_name{label=\"value\"} 123 timestamp?\n\t\tlet name: string;\n\t\tlet labels: Record<string, string> = {};\n\t\tlet valueStr: string;\n\t\tlet tsStr: string | undefined;\n\n\t\tconst braceIdx = line.indexOf(\"{\");\n\t\tif (braceIdx >= 0) {\n\t\t\tname = line.slice(0, braceIdx);\n\t\t\tconst closeBrace = line.indexOf(\"}\", braceIdx);\n\t\t\tif (closeBrace < 0) continue;\n\t\t\tconst labelStr = line.slice(braceIdx + 1, closeBrace);\n\t\t\tlabels = parsePrometheusLabels(labelStr);\n\t\t\tconst after = line\n\t\t\t\t.slice(closeBrace + 1)\n\t\t\t\t.trim()\n\t\t\t\t.split(/\\s+/);\n\t\t\tvalueStr = after[0] ?? \"\";\n\t\t\ttsStr = after[1];\n\t\t} else {\n\t\t\tconst parts = line.split(/\\s+/);\n\t\t\tname = parts[0] ?? \"\";\n\t\t\tvalueStr = parts[1] ?? \"\";\n\t\t\ttsStr = parts[2];\n\t\t}\n\n\t\tif (!name || !valueStr) continue;\n\n\t\tconst baseName = name.replace(/(_total|_count|_sum|_bucket|_created|_info)$/, \"\");\n\t\tresults.push({\n\t\t\tname,\n\t\t\tlabels,\n\t\t\tvalue: Number(valueStr),\n\t\t\ttimestampMs: tsStr ? Number(tsStr) : undefined,\n\t\t\ttype: (types.get(baseName) ?? types.get(name)) as PrometheusMetric[\"type\"],\n\t\t\thelp: helps.get(baseName) ?? helps.get(name),\n\t\t\ttimestampNs: wallClockNs(),\n\t\t});\n\t}\n\n\treturn results;\n}\n\nfunction parsePrometheusLabels(str: string): Record<string, string> {\n\tconst labels: Record<string, string> = {};\n\tconst re = /(\\w+)=\"((?:[^\"\\\\]|\\\\.)*)\"/g;\n\tlet m: RegExpExecArray | null = re.exec(str);\n\twhile (m !== null) {\n\t\tlabels[m[1]] = m[2].replace(/\\\\(.)/g, \"$1\");\n\t\tm = re.exec(str);\n\t}\n\treturn labels;\n}\n\n// ——— Kafka ———\n\n/** Duck-typed Kafka consumer (compatible with kafkajs, confluent-kafka, Pulsar KoP). */\nexport type KafkaConsumerLike = {\n\tsubscribe(opts: { topic: string; fromBeginning?: boolean }): Promise<void>;\n\trun(opts: {\n\t\teachMessage: (payload: {\n\t\t\ttopic: string;\n\t\t\tpartition: number;\n\t\t\tmessage: {\n\t\t\t\tkey: Buffer | null;\n\t\t\t\tvalue: Buffer | null;\n\t\t\t\theaders?: Record<string, Buffer | string | undefined>;\n\t\t\t\toffset: string;\n\t\t\t\ttimestamp: string;\n\t\t\t};\n\t\t}) => Promise<void>;\n\t}): Promise<void>;\n\tdisconnect(): Promise<void>;\n};\n\n/** Duck-typed Kafka producer. */\nexport type KafkaProducerLike = {\n\tsend(record: {\n\t\ttopic: string;\n\t\tmessages: Array<{\n\t\t\tkey?: string | Buffer | null;\n\t\t\tvalue: string | Buffer | null;\n\t\t\theaders?: Record<string, string | Buffer>;\n\t\t}>;\n\t}): Promise<void>;\n\tdisconnect(): Promise<void>;\n};\n\n/** Structured Kafka message. */\nexport type KafkaMessage<T = unknown> = {\n\ttopic: string;\n\tpartition: number;\n\tkey: string | null;\n\tvalue: T;\n\theaders: Record<string, string>;\n\toffset: string;\n\ttimestamp: string;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromKafka}. */\nexport type FromKafkaOptions = ExtraOpts & {\n\t/** Start from beginning of topic. Default: `false`. */\n\tfromBeginning?: boolean;\n\t/** Deserialize message value. Default: `JSON.parse(buffer.toString())`. */\n\tdeserialize?: (value: Buffer | null) => unknown;\n};\n\n/**\n * Kafka consumer as a reactive source.\n *\n * Wraps a KafkaJS-compatible consumer. Each message becomes a `DATA` emission.\n * Compatible with Pulsar via KoP (Kafka-on-Pulsar).\n *\n * @param consumer - KafkaJS-compatible consumer instance (caller owns connect/disconnect lifecycle).\n * @param topic - Topic to consume from.\n * @param opts - Deserialization and source options.\n * @returns `Node<KafkaMessage<T>>` — one `DATA` per Kafka message.\n *\n * @example\n * ```ts\n * import { Kafka } from \"kafkajs\";\n * import { fromKafka } from \"@graphrefly/graphrefly-ts\";\n *\n * const kafka = new Kafka({ brokers: [\"localhost:9092\"] });\n * const consumer = kafka.consumer({ groupId: \"my-group\" });\n * await consumer.connect();\n *\n * const events$ = fromKafka(consumer, \"events\", { deserialize: (buf) => JSON.parse(buf!.toString()) });\n * ```\n *\n * @category extra\n */\nexport function fromKafka<T = unknown>(\n\tconsumer: KafkaConsumerLike,\n\ttopic: string,\n\topts?: FromKafkaOptions,\n): Node<KafkaMessage<T>> {\n\tconst {\n\t\tfromBeginning = false,\n\t\tdeserialize = (buf: Buffer | null) => {\n\t\t\tif (buf === null) return null;\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(buf.toString());\n\t\t\t} catch {\n\t\t\t\treturn buf.toString();\n\t\t\t}\n\t\t},\n\t\t...rest\n\t} = opts ?? {};\n\n\treturn producer<KafkaMessage<T>>((a) => {\n\t\tlet active = true;\n\n\t\tconst start = async () => {\n\t\t\ttry {\n\t\t\t\tawait consumer.subscribe({ topic, fromBeginning });\n\t\t\t\tawait consumer.run({\n\t\t\t\t\teachMessage: async ({ topic: t, partition, message: msg }) => {\n\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\tconst headers: Record<string, string> = {};\n\t\t\t\t\t\tif (msg.headers) {\n\t\t\t\t\t\t\tfor (const [k, v] of Object.entries(msg.headers)) {\n\t\t\t\t\t\t\t\tif (v !== undefined) headers[k] = typeof v === \"string\" ? v : v.toString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\ta.emit({\n\t\t\t\t\t\t\ttopic: t,\n\t\t\t\t\t\t\tpartition,\n\t\t\t\t\t\t\tkey: msg.key?.toString() ?? null,\n\t\t\t\t\t\t\tvalue: deserialize(msg.value) as T,\n\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\toffset: msg.offset,\n\t\t\t\t\t\t\ttimestamp: msg.timestamp,\n\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\n\t\tvoid start();\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/** Options for {@link toKafka}. */\nexport type ToKafkaOptions<T> = ExtraOpts & {\n\t/** Serialize value for Kafka. Default: `JSON.stringify`. */\n\tserialize?: (value: T) => string | Buffer;\n\t/** Extract message key from value. Default: `null` (no key). */\n\tkeyExtractor?: (value: T) => string | null;\n\t/** Called on serialization or send failures. */\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * Kafka producer sink — forwards upstream `DATA` to a Kafka topic.\n *\n * @param source - Upstream node to forward.\n * @param kafkaProducer - KafkaJS-compatible producer instance.\n * @param topic - Target topic.\n * @param opts - Serialization and key extraction options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toKafka<T>(\n\tsource: Node<T>,\n\tkafkaProducer: KafkaProducerLike,\n\ttopic: string,\n\topts?: ToKafkaOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst { serialize = (v: T) => JSON.stringify(v), keyExtractor, onTransportError } = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tsend: async (value) => {\n\t\t\tconst key = keyExtractor?.(value) ?? null;\n\t\t\tconst serialized = serialize(value);\n\t\t\tawait kafkaProducer.send({\n\t\t\t\ttopic,\n\t\t\t\tmessages: [{ key, value: Buffer.from(serialized as string) }],\n\t\t\t});\n\t\t},\n\t});\n}\n\n// ——— Redis Streams ———\n\n/** Duck-typed Redis client (compatible with ioredis, redis). */\nexport type RedisClientLike = {\n\txadd(key: string, id: string, ...fieldsAndValues: string[]): Promise<string>;\n\txread(\n\t\t...args: Array<string | number>\n\t): Promise<Array<[string, Array<[string, string[]]>]> | null>;\n\tdisconnect(): void;\n};\n\n/** Structured Redis Stream entry. */\nexport type RedisStreamEntry<T = unknown> = {\n\tid: string;\n\tkey: string;\n\tdata: T;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromRedisStream}. */\nexport type FromRedisStreamOptions = ExtraOpts & {\n\t/** Block timeout in ms for XREAD. Default: `5000`. */\n\tblockMs?: number;\n\t/** Start ID. Default: `\"$\"` (new entries only). */\n\tstartId?: string;\n\t/** Parse raw Redis hash fields to structured data. Default: parses `data` field as JSON. */\n\tparse?: (fields: string[]) => unknown;\n};\n\n/**\n * Redis Streams consumer as a reactive source.\n *\n * Uses XREAD with BLOCK to reactively consume stream entries.\n *\n * @param client - ioredis/redis-compatible client (caller owns connection).\n * @param key - Redis stream key.\n * @param opts - Block timeout, start ID, and parsing options.\n * @returns `Node<RedisStreamEntry<T>>` — one `DATA` per stream entry.\n *\n * @remarks\n * **COMPLETE:** This source never emits `COMPLETE` under normal operation — it\n * is a long-lived stream consumer that runs until teardown or error, same as\n * Kafka consumers. If you need a bounded read, wrap with `take()` or\n * `takeUntil()`.\n *\n * **Client lifecycle:** The caller owns the Redis client connection. The adapter\n * does not call `disconnect()` on teardown — the caller is responsible for\n * closing the connection (same contract as `fromKafka`).\n *\n * @category extra\n */\nexport function fromRedisStream<T = unknown>(\n\tclient: RedisClientLike,\n\tkey: string,\n\topts?: FromRedisStreamOptions,\n): Node<RedisStreamEntry<T>> {\n\tconst {\n\t\tblockMs = 5000,\n\t\tstartId = \"$\",\n\t\tparse = (fields: string[]) => {\n\t\t\t// Redis returns flat [field, value, field, value, ...] arrays.\n\t\t\tfor (let i = 0; i < fields.length; i += 2) {\n\t\t\t\tif (fields[i] === \"data\") {\n\t\t\t\t\ttry {\n\t\t\t\t\t\treturn JSON.parse(fields[i + 1]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\treturn fields[i + 1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Return as object if no \"data\" field.\n\t\t\tconst obj: Record<string, string> = {};\n\t\t\tfor (let i = 0; i < fields.length; i += 2) {\n\t\t\t\tobj[fields[i]] = fields[i + 1];\n\t\t\t}\n\t\t\treturn obj;\n\t\t},\n\t\t...rest\n\t} = opts ?? {};\n\n\treturn producer<RedisStreamEntry<T>>((a) => {\n\t\tlet active = true;\n\t\tlet lastId = startId;\n\n\t\tconst poll = async () => {\n\t\t\twhile (active) {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await client.xread(\"BLOCK\", blockMs, \"STREAMS\", key, lastId);\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\tfor (const [_streamKey, entries] of result) {\n\t\t\t\t\t\t\tfor (const [id, fields] of entries) {\n\t\t\t\t\t\t\t\tlastId = id;\n\t\t\t\t\t\t\t\ta.emit({\n\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\t\tdata: parse(fields) as T,\n\t\t\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t\t\t\t});\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} catch (err) {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tvoid poll();\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/** Options for {@link toRedisStream}. */\nexport type ToRedisStreamOptions<T> = ExtraOpts & {\n\t/** Serialize value to Redis hash fields. Default: `[\"data\", JSON.stringify(value)]`. */\n\tserialize?: (value: T) => string[];\n\t/** Max stream length (MAXLEN ~). Default: no trimming. */\n\tmaxLen?: number;\n\t/** Called on serialization or send failures. */\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * Redis Streams producer sink — forwards upstream `DATA` to a Redis stream.\n *\n * @param source - Upstream node to forward.\n * @param client - ioredis/redis-compatible client.\n * @param key - Redis stream key.\n * @param opts - Serialization options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toRedisStream<T>(\n\tsource: Node<T>,\n\tclient: RedisClientLike,\n\tkey: string,\n\topts?: ToRedisStreamOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tserialize = (v: T) => [\"data\", JSON.stringify(v)],\n\t\tmaxLen,\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tsend: async (value) => {\n\t\t\tconst fields = serialize(value);\n\t\t\tawait (maxLen !== undefined\n\t\t\t\t? client.xadd(key, \"MAXLEN\", \"~\", String(maxLen), \"*\", ...fields)\n\t\t\t\t: client.xadd(key, \"*\", ...fields));\n\t\t},\n\t});\n}\n\n// ——— CSV ingest ———\n\n/** Parsed CSV row. */\nexport type CSVRow = Record<string, string>;\n\n/** Options for {@link fromCSV}. */\nexport type FromCSVOptions = ExtraOpts & {\n\t/** Column delimiter. Default: `\",\"`. */\n\tdelimiter?: string;\n\t/** Whether the first row is a header. Default: `true`. */\n\thasHeader?: boolean;\n\t/** Explicit column names (overrides header row). */\n\tcolumns?: string[];\n\t/** Custom line parser (e.g. wrapping a library like `csv-parse`). Overrides built-in parser + delimiter. */\n\tparseLine?: (line: string) => string[];\n};\n\n/**\n * CSV file/stream ingest for batch replay.\n *\n * Reads a CSV from a `ReadableStream<string>` or an `AsyncIterable<string>` of lines,\n * emitting one `DATA` per row. `COMPLETE` after all rows are emitted.\n *\n * @param source - Async iterable of CSV text chunks (lines or multi-line chunks).\n * @param opts - Delimiter, header, and column options.\n * @returns `Node<CSVRow>` — one `DATA` per parsed row.\n *\n * @example\n * ```ts\n * import { createReadStream } from \"node:fs\";\n * import { fromCSV } from \"@graphrefly/graphrefly-ts\";\n *\n * const csv$ = fromCSV(createReadStream(\"data.csv\", \"utf-8\"));\n * ```\n *\n * @category extra\n */\nexport function fromCSV(source: AsyncIterable<string>, opts?: FromCSVOptions): Node<CSVRow> {\n\tconst {\n\t\tdelimiter = \",\",\n\t\thasHeader = true,\n\t\tcolumns: explicitColumns,\n\t\tparseLine,\n\t\t...rest\n\t} = opts ?? {};\n\tconst parse = parseLine ?? ((line: string) => parseCSVLine(line, delimiter));\n\n\treturn producer<CSVRow>((a) => {\n\t\tlet cancelled = false;\n\n\t\tconst run = async () => {\n\t\t\ttry {\n\t\t\t\tlet headers: string[] | undefined = explicitColumns;\n\t\t\t\tlet buffer = \"\";\n\n\t\t\t\tfor await (const chunk of source) {\n\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\tbuffer += chunk;\n\n\t\t\t\t\tconst lines = buffer.split(/\\r?\\n/);\n\t\t\t\t\t// Keep last partial line in buffer.\n\t\t\t\t\tbuffer = lines.pop() ?? \"\";\n\n\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\tif (!line.trim()) continue;\n\n\t\t\t\t\t\tconst values = parse(line);\n\n\t\t\t\t\t\tif (!headers && hasHeader) {\n\t\t\t\t\t\t\theaders = values;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!headers) {\n\t\t\t\t\t\t\theaders = values.map((_, i) => `col${i}`);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst row: CSVRow = {};\n\t\t\t\t\t\tfor (let i = 0; i < headers.length; i++) {\n\t\t\t\t\t\t\trow[headers[i]] = values[i] ?? \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\ta.emit(row);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Process remaining buffer.\n\t\t\t\tif (!cancelled && buffer.trim()) {\n\t\t\t\t\tconst values = parse(buffer);\n\t\t\t\t\tif (headers) {\n\t\t\t\t\t\tconst row: CSVRow = {};\n\t\t\t\t\t\tfor (let i = 0; i < headers.length; i++) {\n\t\t\t\t\t\t\trow[headers[i]] = values[i] ?? \"\";\n\t\t\t\t\t\t}\n\t\t\t\t\t\ta.emit(row);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\tif (!cancelled) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\n\t\tvoid run();\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/**\n * Stateful CSV parser operator — takes a `Node<string>` emitting raw text\n * chunks (from any source: {@link fromAsyncIter}, {@link fromHTTPStream},\n * WebSocket, file watcher, etc.) and emits one `DATA` per parsed row.\n *\n * Buffers incomplete lines across chunks. Mirrors {@link fromCSV}'s parsing\n * logic without committing to an async-iterable-only input.\n *\n * @example\n * ```ts\n * import { fromHTTPStream, csvRows } from \"@graphrefly/graphrefly-ts\";\n * const bytes$ = fromHTTPStream(\"https://example.com/data.csv\");\n * const text$ = decodeText(bytes$); // caller-provided byte→string decoder\n * const rows$ = csvRows(text$, { columns: [\"name\", \"age\"] });\n * ```\n *\n * @category extra\n */\nexport function csvRows(source: Node<string>, opts?: FromCSVOptions): Node<CSVRow> {\n\tconst {\n\t\tdelimiter = \",\",\n\t\thasHeader = true,\n\t\tcolumns: explicitColumns,\n\t\tparseLine,\n\t\t...rest\n\t} = opts ?? {};\n\tconst parse = parseLine ?? ((line: string) => parseCSVLine(line, delimiter));\n\treturn node<CSVRow>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\t\t\t// Parser state lives in `ctx.store` so it resets automatically on\n\t\t\t// deactivation / resubscribable terminal reset (COMPOSITION-GUIDE §20).\n\t\t\t// That lets the operator sit under retry / resubscribe patterns without\n\t\t\t// leaking a stale half-parsed line from a previous run.\n\t\t\tconst s = ctx.store as { buffer: string; headers: string[] | undefined };\n\t\t\tif (typeof s.buffer !== \"string\") s.buffer = \"\";\n\t\t\tif (s.headers === undefined && explicitColumns) s.headers = explicitColumns.slice();\n\t\t\tfor (const chunkRaw of batch0) {\n\t\t\t\ts.buffer = s.buffer + (chunkRaw as string);\n\t\t\t\tconst lines: string[] = s.buffer.split(/\\r?\\n/);\n\t\t\t\ts.buffer = lines.pop() ?? \"\";\n\t\t\t\tfor (const line of lines) {\n\t\t\t\t\tif (!line.trim()) continue;\n\t\t\t\t\tconst values = parse(line);\n\t\t\t\t\tif (!s.headers && hasHeader) {\n\t\t\t\t\t\ts.headers = values;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (!s.headers) s.headers = values.map((_, i) => `col${i}`);\n\t\t\t\t\tconst row: CSVRow = {};\n\t\t\t\t\tfor (let i = 0; i < s.headers.length; i++) row[s.headers[i]] = values[i] ?? \"\";\n\t\t\t\t\ta.emit(row);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ describeKind: \"derived\", ...rest } as NodeOptions<CSVRow>,\n\t);\n}\n\n/**\n * Stateful NDJSON parser operator — takes a `Node<string>` of raw text chunks\n * and emits one `DATA` per parsed JSON object. Buffers partial lines across\n * chunks.\n *\n * @category extra\n */\nexport function ndjsonRows<T = unknown>(source: Node<string>, opts?: ExtraOpts): Node<T> {\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return;\n\t\t\t// Parser buffer in `ctx.store` resets on deactivation / resubscribable\n\t\t\t// reset (COMPOSITION-GUIDE §20) so resubscribing the operator starts\n\t\t\t// clean rather than bleeding a half-line from a previous run.\n\t\t\tconst s = ctx.store as { buffer: string };\n\t\t\tif (typeof s.buffer !== \"string\") s.buffer = \"\";\n\t\t\tfor (const chunkRaw of batch0) {\n\t\t\t\ts.buffer = s.buffer + (chunkRaw as string);\n\t\t\t\tconst lines: string[] = s.buffer.split(/\\r?\\n/);\n\t\t\t\ts.buffer = lines.pop() ?? \"\";\n\t\t\t\tfor (const line of lines) {\n\t\t\t\t\tif (!line.trim()) continue;\n\t\t\t\t\ttry {\n\t\t\t\t\t\ta.emit(JSON.parse(line) as T);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{ describeKind: \"derived\", ...(opts ?? {}) } as NodeOptions<T>,\n\t);\n}\n\nfunction parseCSVLine(line: string, delimiter: string): string[] {\n\tconst values: string[] = [];\n\tlet current = \"\";\n\tlet inQuotes = false;\n\n\tfor (let i = 0; i < line.length; i++) {\n\t\tconst ch = line[i];\n\t\tif (inQuotes) {\n\t\t\tif (ch === '\"') {\n\t\t\t\tif (line[i + 1] === '\"') {\n\t\t\t\t\tcurrent += '\"';\n\t\t\t\t\ti++;\n\t\t\t\t} else {\n\t\t\t\t\tinQuotes = false;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcurrent += ch;\n\t\t\t}\n\t\t} else if (ch === '\"') {\n\t\t\tinQuotes = true;\n\t\t} else if (ch === delimiter) {\n\t\t\tvalues.push(current);\n\t\t\tcurrent = \"\";\n\t\t} else {\n\t\t\tcurrent += ch;\n\t\t}\n\t}\n\tvalues.push(current);\n\treturn values;\n}\n\n// ——— NDJSON ingest ———\n\n/** Options for {@link fromNDJSON}. */\nexport type FromNDJSONOptions = ExtraOpts & {};\n\n/**\n * Newline-delimited JSON stream ingest for batch replay.\n *\n * Reads an async iterable of text chunks, splits by newline, parses each line\n * as JSON, and emits one `DATA` per parsed object. `COMPLETE` after stream ends.\n *\n * @param source - Async iterable of NDJSON text chunks.\n * @param opts - Optional producer options.\n * @returns `Node<T>` — one `DATA` per JSON line.\n *\n * @example\n * ```ts\n * import { createReadStream } from \"node:fs\";\n * import { fromNDJSON } from \"@graphrefly/graphrefly-ts\";\n *\n * const logs$ = fromNDJSON(createReadStream(\"logs.ndjson\", \"utf-8\"));\n * ```\n *\n * @category extra\n */\nexport function fromNDJSON<T = unknown>(\n\tsource: AsyncIterable<string>,\n\topts?: FromNDJSONOptions,\n): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet cancelled = false;\n\n\t\tconst run = async () => {\n\t\t\ttry {\n\t\t\t\tlet buffer = \"\";\n\n\t\t\t\tfor await (const chunk of source) {\n\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\tbuffer += chunk;\n\n\t\t\t\t\tconst lines = buffer.split(/\\r?\\n/);\n\t\t\t\t\tbuffer = lines.pop() ?? \"\";\n\n\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\tconst trimmed = line.trim();\n\t\t\t\t\t\tif (!trimmed) continue;\n\t\t\t\t\t\ta.emit(JSON.parse(trimmed) as T);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Process remaining buffer.\n\t\t\t\tif (!cancelled && buffer.trim()) {\n\t\t\t\t\ta.emit(JSON.parse(buffer.trim()) as T);\n\t\t\t\t}\n\n\t\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\tif (!cancelled) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\n\t\tvoid run();\n\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, sourceOpts(opts));\n}\n\n// ——— ClickHouse live materialized view ———\n\n/** Structured ClickHouse query result row. */\nexport type ClickHouseRow = Record<string, unknown>;\n\n/** Duck-typed ClickHouse client. */\nexport type ClickHouseClientLike = {\n\tquery(opts: { query: string; format?: string }): Promise<{\n\t\tjson<T = unknown>(): Promise<T[]>;\n\t}>;\n};\n\n/** Options for {@link fromClickHouseWatch}. */\nexport type FromClickHouseWatchOptions = AsyncSourceOpts & {\n\t/** Polling interval in nanoseconds. Default: `5 * NS_PER_SEC` (5s). */\n\tintervalNs?: number;\n\t/** JSON format to request. Default: `\"JSONEachRow\"`. */\n\tformat?: string;\n\t/**\n\t * Maximum consecutive query errors before terminating the source. Prevents\n\t * error storms when the database is unavailable. Default: `5`. Set to\n\t * `Infinity` to keep retrying indefinitely.\n\t */\n\tmaxConsecutiveErrors?: number;\n};\n\n/**\n * ClickHouse live materialized view as a reactive source.\n *\n * Polls a ClickHouse query on a reactive timer interval and emits new/changed rows.\n * Uses a timer-driven approach (not busy-wait polling).\n *\n * @param client - ClickHouse client instance (caller owns connection).\n * @param query - SQL query to execute on each interval.\n * @param opts - Polling interval and format options.\n * @returns `Node<ClickHouseRow>` — one `DATA` per result row per scrape.\n *\n * @example\n * ```ts\n * import { createClient } from \"@clickhouse/client\";\n * import { fromClickHouseWatch } from \"@graphrefly/graphrefly-ts\";\n *\n * const client = createClient({ url: \"http://localhost:8123\" });\n * const rows$ = fromClickHouseWatch(client, \"SELECT * FROM errors_mv ORDER BY timestamp DESC LIMIT 100\");\n * ```\n *\n * @category extra\n */\nexport function fromClickHouseWatch(\n\tclient: ClickHouseClientLike,\n\tquery: string,\n\topts?: FromClickHouseWatchOptions,\n): Node<ClickHouseRow> {\n\tconst {\n\t\tintervalNs = 5 * NS_PER_SEC,\n\t\tformat = \"JSONEachRow\",\n\t\tsignal: externalSignal,\n\t\tmaxConsecutiveErrors = 1,\n\t} = opts ?? {};\n\tconst intervalMs = Math.ceil(intervalNs / NS_PER_MS);\n\t// Circuit breaker shared across switchMap inners.\n\tlet consecutiveErrors = 0;\n\n\t// `fromTimer | switchMap(producer(one-query))` — timer ticks drive a single\n\t// query each; switchMap cancels any in-flight inner when the next tick\n\t// arrives. First tick at t=0, then every intervalMs.\n\treturn switchMap(fromTimer(0, { period: intervalMs, signal: externalSignal }), () =>\n\t\tproducer<ClickHouseRow>((a) => {\n\t\t\tlet active = true;\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await client.query({ query, format });\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tconst rows = await result.json<ClickHouseRow>();\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tfor (const row of rows) a.emit(row);\n\t\t\t\t\tconsecutiveErrors = 0;\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tconsecutiveErrors += 1;\n\t\t\t\t\tif (consecutiveErrors >= maxConsecutiveErrors) {\n\t\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t\t}\n\t\t\t\t\t// else: swallow transient error; next tick retries.\n\t\t\t\t}\n\t\t\t};\n\t\t\tvoid run();\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t}),\n\t);\n}\n\n// ——— Apache Pulsar (native client) ———\n\n/** Duck-typed Pulsar consumer (compatible with pulsar-client). */\nexport type PulsarConsumerLike = {\n\treceive(): Promise<{\n\t\tgetData(): Buffer;\n\t\tgetMessageId(): { toString(): string };\n\t\tgetPartitionKey(): string;\n\t\tgetProperties(): Record<string, string>;\n\t\tgetPublishTimestamp(): number;\n\t\tgetEventTimestamp(): number;\n\t\tgetTopicName(): string;\n\t}>;\n\tacknowledge(msg: unknown): Promise<void>;\n\tclose(): Promise<void>;\n};\n\n/** Duck-typed Pulsar producer. */\nexport type PulsarProducerLike = {\n\tsend(msg: {\n\t\tdata: Buffer;\n\t\tpartitionKey?: string;\n\t\tproperties?: Record<string, string>;\n\t}): Promise<void>;\n\tclose(): Promise<void>;\n};\n\n/** Structured Pulsar message. */\nexport type PulsarMessage<T = unknown> = {\n\ttopic: string;\n\tmessageId: string;\n\tkey: string;\n\tvalue: T;\n\tproperties: Record<string, string>;\n\tpublishTime: number;\n\teventTime: number;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromPulsar}. */\nexport type FromPulsarOptions = ExtraOpts & {\n\t/** Deserialize message data. Default: `JSON.parse(buffer.toString())`. */\n\tdeserialize?: (data: Buffer) => unknown;\n\t/** Acknowledge messages automatically. Default: `true`. */\n\tautoAck?: boolean;\n\t/**\n\t * Routes ack/nack transport failures to the caller. Covers:\n\t * - `autoAck: true` — post-emit `acknowledge()` promise rejections.\n\t * - `autoAck: false` — envelope `ack()` / `nack()` promise rejections.\n\t * Default: swallow (SDK handles redelivery on its own).\n\t */\n\tonAckError?: (err: Error) => void;\n};\n\n/**\n * Apache Pulsar consumer as a reactive source (native client).\n *\n * Wraps a `pulsar-client`-compatible consumer. Each message becomes a `DATA` emission.\n * For Kafka-on-Pulsar (KoP), use {@link fromKafka} instead.\n *\n * @param consumer - Pulsar consumer instance (caller owns create/close lifecycle).\n * @param opts - Deserialization and source options.\n * @returns `Node<PulsarMessage<T>>` — one `DATA` per Pulsar message.\n *\n * @remarks\n * Teardown sets an internal flag but cannot interrupt a pending `consumer.receive()`.\n * The loop exits on the next message or when the consumer is closed externally.\n * Callers should call `consumer.close()` after unsubscribing for prompt cleanup.\n *\n * @example\n * ```ts\n * import Pulsar from \"pulsar-client\";\n * import { fromPulsar } from \"@graphrefly/graphrefly-ts\";\n *\n * const client = new Pulsar.Client({ serviceUrl: \"pulsar://localhost:6650\" });\n * const consumer = await client.subscribe({ topic: \"events\", subscription: \"my-sub\" });\n * const events$ = fromPulsar(consumer);\n * ```\n *\n * @category extra\n */\nexport function fromPulsar<T = unknown>(\n\tconsumer: PulsarConsumerLike,\n\topts?: FromPulsarOptions & { autoAck?: true },\n): Node<PulsarMessage<T>>;\nexport function fromPulsar<T = unknown>(\n\tconsumer: PulsarConsumerLike,\n\topts: FromPulsarOptions & { autoAck: false },\n): Node<AckableMessage<PulsarMessage<T>>>;\nexport function fromPulsar<T = unknown>(\n\tconsumer: PulsarConsumerLike,\n\topts?: FromPulsarOptions,\n): Node<PulsarMessage<T> | AckableMessage<PulsarMessage<T>>> {\n\tconst {\n\t\tautoAck = true,\n\t\tdeserialize = (buf: Buffer) => {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(buf.toString());\n\t\t\t} catch {\n\t\t\t\treturn buf.toString();\n\t\t\t}\n\t\t},\n\t\tonAckError,\n\t\t...rest\n\t} = opts ?? {};\n\n\tconst reportAckError = (err: unknown) => {\n\t\tif (!onAckError) return;\n\t\ttry {\n\t\t\tonAckError(err instanceof Error ? err : new Error(String(err)));\n\t\t} catch {\n\t\t\t/* user hook must not escape */\n\t\t}\n\t};\n\n\treturn producer<PulsarMessage<T> | AckableMessage<PulsarMessage<T>>>((a) => {\n\t\tlet active = true;\n\n\t\tconst loop = async () => {\n\t\t\twhile (active) {\n\t\t\t\ttry {\n\t\t\t\t\tconst rawMsg = await consumer.receive();\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tconst structured: PulsarMessage<T> = {\n\t\t\t\t\t\ttopic: rawMsg.getTopicName(),\n\t\t\t\t\t\tmessageId: rawMsg.getMessageId().toString(),\n\t\t\t\t\t\tkey: rawMsg.getPartitionKey(),\n\t\t\t\t\t\tvalue: deserialize(rawMsg.getData()) as T,\n\t\t\t\t\t\tproperties: rawMsg.getProperties(),\n\t\t\t\t\t\tpublishTime: rawMsg.getPublishTimestamp(),\n\t\t\t\t\t\teventTime: rawMsg.getEventTimestamp(),\n\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t};\n\t\t\t\t\tif (autoAck) {\n\t\t\t\t\t\ta.emit(structured);\n\t\t\t\t\t\tvoid consumer.acknowledge(rawMsg).catch(reportAckError);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Manual ack — wrap in AckableMessage. Pulsar's SDK has no\n\t\t\t\t\t\t// per-message nack(requeue=false) — a plain `nack` re-delivers\n\t\t\t\t\t\t// after the subscription's negativeAckRedeliveryDelay. `requeue`\n\t\t\t\t\t\t// is honored as \"always redeliver\" (SDK default).\n\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\tconst envelope: AckableMessage<PulsarMessage<T>> = {\n\t\t\t\t\t\t\tvalue: structured,\n\t\t\t\t\t\t\tack() {\n\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\tvoid consumer.acknowledge(rawMsg).catch(reportAckError);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnack(_opts) {\n\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\tconst anyConsumer = consumer as unknown as {\n\t\t\t\t\t\t\t\t\tnegativeAcknowledge?: (m: unknown) => Promise<void> | void;\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tconst result = anyConsumer.negativeAcknowledge?.(rawMsg);\n\t\t\t\t\t\t\t\t\t// nack may return Promise (some SDKs) — route rejection.\n\t\t\t\t\t\t\t\t\tif (result && typeof (result as Promise<void>).then === \"function\") {\n\t\t\t\t\t\t\t\t\t\tvoid (result as Promise<void>).catch(reportAckError);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t\ta.emit(envelope);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\tvoid loop();\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/** Options for {@link toPulsar}. */\nexport type ToPulsarOptions<T> = ExtraOpts & {\n\t/** Serialize value for Pulsar. Default: `JSON.stringify` → Buffer. */\n\tserialize?: (value: T) => Buffer;\n\t/** Extract partition key from value. Default: none. */\n\tkeyExtractor?: (value: T) => string | undefined;\n\t/** Extract properties from value. */\n\tpropertiesExtractor?: (value: T) => Record<string, string> | undefined;\n\t/** Called on serialization or send failures. */\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * Pulsar producer sink — forwards upstream `DATA` to a Pulsar topic.\n *\n * @param source - Upstream node to forward.\n * @param pulsarProducer - Pulsar producer instance (caller owns lifecycle).\n * @param opts - Serialization options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toPulsar<T>(\n\tsource: Node<T>,\n\tpulsarProducer: PulsarProducerLike,\n\topts?: ToPulsarOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tserialize = (v: T) => Buffer.from(JSON.stringify(v)),\n\t\tkeyExtractor,\n\t\tpropertiesExtractor,\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tsend: async (value) => {\n\t\t\tawait pulsarProducer.send({\n\t\t\t\tdata: serialize(value),\n\t\t\t\tpartitionKey: keyExtractor?.(value),\n\t\t\t\tproperties: propertiesExtractor?.(value),\n\t\t\t});\n\t\t},\n\t});\n}\n\n// ——— NATS ———\n\n/** Duck-typed NATS subscription (compatible with nats.js). */\nexport type NATSSubscriptionLike = AsyncIterable<{\n\tsubject: string;\n\tdata: Uint8Array;\n\theaders?: { get(key: string): string; keys(): string[] };\n\treply?: string;\n\tsid: number;\n}>;\n\n/** Duck-typed NATS client (compatible with nats.js). */\nexport type NATSClientLike = {\n\tsubscribe(subject: string, opts?: { queue?: string }): NATSSubscriptionLike;\n\tpublish(subject: string, data?: Uint8Array, opts?: { headers?: unknown; reply?: string }): void;\n\tdrain(): Promise<void>;\n};\n\n/** Structured NATS message. */\nexport type NATSMessage<T = unknown> = {\n\tsubject: string;\n\tdata: T;\n\theaders: Record<string, string>;\n\treply: string | undefined;\n\tsid: number;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromNATS}. */\nexport type FromNATSOptions = ExtraOpts & {\n\t/** Queue group name for load balancing. */\n\tqueue?: string;\n\t/** Deserialize message data. Default: `JSON.parse(textDecoder.decode(data))`. */\n\tdeserialize?: (data: Uint8Array) => unknown;\n};\n\n/**\n * NATS consumer as a reactive source.\n *\n * Wraps a `nats.js`-compatible client subscription. Each message becomes a `DATA` emission.\n *\n * @param client - NATS client instance (caller owns connect/drain lifecycle).\n * @param subject - Subject to subscribe to (supports wildcards).\n * @param opts - Queue group, deserialization, and source options.\n * @returns `Node<NATSMessage<T>>` — one `DATA` per NATS message.\n *\n * @remarks\n * Teardown sets an internal flag but cannot break the async iterator. The loop\n * exits on the next message or when the subscription is drained/unsubscribed\n * externally. Call `client.drain()` after unsubscribing for prompt cleanup.\n *\n * @example\n * ```ts\n * import { connect } from \"nats\";\n * import { fromNATS } from \"@graphrefly/graphrefly-ts\";\n *\n * const nc = await connect({ servers: \"localhost:4222\" });\n * const events$ = fromNATS(nc, \"events.>\");\n * ```\n *\n * @category extra\n */\nexport function fromNATS<T = unknown>(\n\tclient: NATSClientLike,\n\tsubject: string,\n\topts?: FromNATSOptions,\n): Node<NATSMessage<T>> {\n\tconst decoder = new TextDecoder();\n\tconst {\n\t\tqueue,\n\t\tdeserialize = (data: Uint8Array) => {\n\t\t\tconst text = decoder.decode(data);\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(text);\n\t\t\t} catch {\n\t\t\t\treturn text;\n\t\t\t}\n\t\t},\n\t\t...rest\n\t} = opts ?? {};\n\n\treturn producer<NATSMessage<T>>((a) => {\n\t\tlet active = true;\n\t\tconst sub = client.subscribe(subject, queue ? { queue } : undefined);\n\n\t\tconst loop = async () => {\n\t\t\ttry {\n\t\t\t\tfor await (const msg of sub) {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tconst headers: Record<string, string> = {};\n\t\t\t\t\tif (msg.headers) {\n\t\t\t\t\t\tfor (const k of msg.headers.keys()) {\n\t\t\t\t\t\t\theaders[k] = msg.headers.get(k);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\ta.emit({\n\t\t\t\t\t\tsubject: msg.subject,\n\t\t\t\t\t\tdata: deserialize(msg.data) as T,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\treply: msg.reply,\n\t\t\t\t\t\tsid: msg.sid,\n\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t// Subscription closed (drain or unsubscribe) — complete.\n\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\n\t\tvoid loop();\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/** Options for {@link toNATS}. */\nexport type ToNATSOptions<T> = ExtraOpts & {\n\t/** Serialize value for NATS. Default: `JSON.stringify` → Uint8Array. */\n\tserialize?: (value: T) => Uint8Array;\n\t/** Called on serialization failures. */\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * NATS publisher sink — forwards upstream `DATA` to a NATS subject.\n *\n * @param source - Upstream node to forward.\n * @param client - NATS client instance.\n * @param subject - Target subject.\n * @param opts - Serialization options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toNATS<T>(\n\tsource: Node<T>,\n\tclient: NATSClientLike,\n\tsubject: string,\n\topts?: ToNATSOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst encoder = new TextEncoder();\n\tconst { serialize = (v: T) => encoder.encode(JSON.stringify(v)), onTransportError } = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tsend: (value) => {\n\t\t\t// NATS publish is synchronous; wrap in a resolved Promise for the\n\t\t\t// reactiveSink transport boundary.\n\t\t\tclient.publish(subject, serialize(value));\n\t\t},\n\t});\n}\n\n// ——— RabbitMQ ———\n\n/** Duck-typed RabbitMQ channel (compatible with amqplib). */\nexport type RabbitMQChannelLike = {\n\tconsume(\n\t\tqueue: string,\n\t\tonMessage: (\n\t\t\tmsg: {\n\t\t\t\tcontent: Buffer;\n\t\t\t\tfields: {\n\t\t\t\t\troutingKey: string;\n\t\t\t\t\texchange: string;\n\t\t\t\t\tdeliveryTag: number;\n\t\t\t\t\tredelivered: boolean;\n\t\t\t\t};\n\t\t\t\tproperties: Record<string, unknown>;\n\t\t\t} | null,\n\t\t) => void,\n\t\topts?: { noAck?: boolean },\n\t): Promise<{ consumerTag: string }>;\n\tcancel(consumerTag: string): Promise<void>;\n\tack(msg: unknown): void;\n\tpublish(\n\t\texchange: string,\n\t\troutingKey: string,\n\t\tcontent: Buffer,\n\t\topts?: Record<string, unknown>,\n\t): boolean;\n\tsendToQueue(queue: string, content: Buffer, opts?: Record<string, unknown>): boolean;\n};\n\n/** Structured RabbitMQ message. */\nexport type RabbitMQMessage<T = unknown> = {\n\tqueue: string;\n\troutingKey: string;\n\texchange: string;\n\tcontent: T;\n\tproperties: Record<string, unknown>;\n\tdeliveryTag: number;\n\tredelivered: boolean;\n\ttimestampNs: number;\n};\n\n/** Options for {@link fromRabbitMQ}. */\nexport type FromRabbitMQOptions = ExtraOpts & {\n\t/** Deserialize message content. Default: `JSON.parse(buffer.toString())`. */\n\tdeserialize?: (content: Buffer) => unknown;\n\t/** Auto-acknowledge messages. Default: `true`. */\n\tautoAck?: boolean;\n\t/**\n\t * Routes envelope ack/nack transport failures (including \"SDK exposes no\n\t * `nack` method\") to the caller. Default: swallow.\n\t */\n\tonAckError?: (err: Error) => void;\n};\n\n/**\n * RabbitMQ consumer as a reactive source.\n *\n * Wraps an `amqplib`-compatible channel. Each message becomes a `DATA` emission.\n *\n * @param channel - AMQP channel instance (caller owns connection/channel lifecycle).\n * @param queue - Queue to consume from.\n * @param opts - Deserialization and acknowledgment options.\n * @returns `Node<RabbitMQMessage<T>>` — one `DATA` per RabbitMQ message.\n *\n * @remarks\n * When `autoAck` is `false`, the adapter opens the channel with `noAck: false`\n * (broker requires acks) but does not call `channel.ack()`. The caller must ack\n * messages externally using the `deliveryTag` from the emitted {@link RabbitMQMessage}:\n * ```ts\n * channel.ack({ fields: { deliveryTag: msg.deliveryTag } } as any);\n * ```\n *\n * @example\n * ```ts\n * import amqplib from \"amqplib\";\n * import { fromRabbitMQ } from \"@graphrefly/graphrefly-ts\";\n *\n * const conn = await amqplib.connect(\"amqp://localhost\");\n * const ch = await conn.createChannel();\n * await ch.assertQueue(\"events\");\n * const events$ = fromRabbitMQ(ch, \"events\");\n * ```\n *\n * @category extra\n */\nexport function fromRabbitMQ<T = unknown>(\n\tchannel: RabbitMQChannelLike,\n\tqueue: string,\n\topts?: FromRabbitMQOptions & { autoAck?: true },\n): Node<RabbitMQMessage<T>>;\nexport function fromRabbitMQ<T = unknown>(\n\tchannel: RabbitMQChannelLike,\n\tqueue: string,\n\topts: FromRabbitMQOptions & { autoAck: false },\n): Node<AckableMessage<RabbitMQMessage<T>>>;\nexport function fromRabbitMQ<T = unknown>(\n\tchannel: RabbitMQChannelLike,\n\tqueue: string,\n\topts?: FromRabbitMQOptions,\n): Node<RabbitMQMessage<T> | AckableMessage<RabbitMQMessage<T>>> {\n\tconst {\n\t\tautoAck = true,\n\t\tdeserialize = (buf: Buffer) => {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(buf.toString());\n\t\t\t} catch {\n\t\t\t\treturn buf.toString();\n\t\t\t}\n\t\t},\n\t\tonAckError,\n\t\t...rest\n\t} = opts ?? {};\n\n\tconst reportAckError = (err: unknown) => {\n\t\tif (!onAckError) return;\n\t\ttry {\n\t\t\tonAckError(err instanceof Error ? err : new Error(String(err)));\n\t\t} catch {\n\t\t\t/* user hook must not escape */\n\t\t}\n\t};\n\n\treturn producer<RabbitMQMessage<T> | AckableMessage<RabbitMQMessage<T>>>((a) => {\n\t\tlet active = true;\n\t\tlet consumerTag: string | undefined;\n\n\t\tconst start = async () => {\n\t\t\ttry {\n\t\t\t\tconst result = await channel.consume(\n\t\t\t\t\tqueue,\n\t\t\t\t\t(rawMsg) => {\n\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\tif (rawMsg === null) {\n\t\t\t\t\t\t\t// Broker cancelled the consumer (queue deleted, etc.).\n\t\t\t\t\t\t\tif (active) a.down([[ERROR, new Error(\"Consumer cancelled by broker\")]]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst structured: RabbitMQMessage<T> = {\n\t\t\t\t\t\t\tqueue,\n\t\t\t\t\t\t\troutingKey: rawMsg.fields.routingKey,\n\t\t\t\t\t\t\texchange: rawMsg.fields.exchange,\n\t\t\t\t\t\t\tcontent: deserialize(rawMsg.content) as T,\n\t\t\t\t\t\t\tproperties: rawMsg.properties,\n\t\t\t\t\t\t\tdeliveryTag: rawMsg.fields.deliveryTag,\n\t\t\t\t\t\t\tredelivered: rawMsg.fields.redelivered,\n\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (autoAck) {\n\t\t\t\t\t\t\ta.emit(structured);\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tchannel.ack(rawMsg);\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\tconst channelWithNack = channel as unknown as {\n\t\t\t\t\t\t\t\tnack?: (msg: unknown, allUpTo?: boolean, requeue?: boolean) => void;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tconst envelope: AckableMessage<RabbitMQMessage<T>> = {\n\t\t\t\t\t\t\t\tvalue: structured,\n\t\t\t\t\t\t\t\tack() {\n\t\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tchannel.ack(rawMsg);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnack(nackOpts) {\n\t\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\t// `requeue` passes through to SDK — `undefined` lets the\n\t\t\t\t\t\t\t\t\t// SDK apply its own default (amqplib: true). Explicit\n\t\t\t\t\t\t\t\t\t// `false` routes to DLX if configured.\n\t\t\t\t\t\t\t\t\tconst requeue = nackOpts?.requeue;\n\t\t\t\t\t\t\t\t\tif (!channelWithNack.nack) {\n\t\t\t\t\t\t\t\t\t\treportAckError(\n\t\t\t\t\t\t\t\t\t\t\tnew Error(\"RabbitMQ channel does not expose `nack`; cannot negative-ack\"),\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tchannelWithNack.nack(rawMsg, false, requeue);\n\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\ta.emit(envelope);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{ noAck: false },\n\t\t\t\t);\n\t\t\t\tconsumerTag = result.consumerTag;\n\t\t\t} catch (err) {\n\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t}\n\t\t};\n\n\t\tvoid start();\n\n\t\treturn () => {\n\t\t\tactive = false;\n\t\t\tif (consumerTag !== undefined) {\n\t\t\t\tvoid channel.cancel(consumerTag);\n\t\t\t}\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/** Options for {@link toRabbitMQ}. */\nexport type ToRabbitMQOptions<T> = ExtraOpts & {\n\t/** Serialize value for RabbitMQ. Default: `Buffer.from(JSON.stringify(value))`. */\n\tserialize?: (value: T) => Buffer;\n\t/** Extract routing key from value. Default: `\"\"`. */\n\troutingKeyExtractor?: (value: T) => string;\n\t/** Called on serialization or send failures. */\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * RabbitMQ producer sink — forwards upstream `DATA` to a RabbitMQ exchange/queue.\n *\n * @param source - Upstream node to forward.\n * @param channel - AMQP channel instance.\n * @param exchange - Target exchange (use `\"\"` for default exchange + queue routing).\n * @param opts - Serialization and routing options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toRabbitMQ<T>(\n\tsource: Node<T>,\n\tchannel: RabbitMQChannelLike,\n\texchange: string,\n\topts?: ToRabbitMQOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tserialize = (v: T) => Buffer.from(JSON.stringify(v)),\n\t\troutingKeyExtractor = () => \"\",\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tsend: (value) => {\n\t\t\tconst routingKey = routingKeyExtractor(value);\n\t\t\tconst content = serialize(value);\n\t\t\tchannel.publish(exchange, routingKey, content);\n\t\t},\n\t});\n}\n\n// ——————————————————————————————————————————————————————————————\n// Phase 5.2d — Storage & sink adapters\n// ——————————————————————————————————————————————————————————————\n\n/** Handle returned by buffered sinks. `flush()` drains remaining buffer. */\nexport type BufferedSinkHandle = SinkHandle & {\n\t/** Manually drain the internal buffer. */\n\tflush: () => Promise<void>;\n};\n\n// ——— toFile ———\n\n/** Duck-typed writable file handle (compatible with `fs.createWriteStream`). */\nexport type FileWriterLike = {\n\twrite(data: string | Uint8Array): boolean | undefined;\n\tend(): void;\n};\n\n/** Options for {@link toFile}. */\nexport type ToFileOptions<T> = ExtraOpts & {\n\t/** Serialize a value to a string line. Default: `JSON.stringify(v) + \"\\n\"`. */\n\tserialize?: (value: T) => string;\n\t/** `\"append\"` (default) or `\"overwrite\"` — controls initial file behavior hint. */\n\tmode?: \"append\" | \"overwrite\";\n\t/** Flush interval in ms. `0` = write-through (no buffering). Default: `0`. */\n\tflushIntervalMs?: number;\n\t/** Buffer size (item count) before auto-flush. Default: `Infinity` (timer only). */\n\tbatchSize?: number;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * File sink — writes upstream `DATA` values to a file-like writable.\n *\n * When `flushIntervalMs > 0` or `batchSize` is set, values are buffered and\n * flushed in batches. Otherwise, each value is written immediately.\n *\n * @param source - Upstream node.\n * @param writer - Writable file handle (e.g. `fs.createWriteStream(path, { flags: \"a\" })`).\n * @param opts - Serialization, buffering, and mode options.\n * @returns `BufferedSinkHandle` with `dispose()` and `flush()`.\n *\n * @category extra\n */\nexport function toFile<T>(\n\tsource: Node<T>,\n\twriter: FileWriterLike,\n\topts?: ToFileOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tserialize = (v: T) => `${JSON.stringify(v)}\\n`,\n\t\tflushIntervalMs = 0,\n\t\tbatchSize = Number.POSITIVE_INFINITY,\n\t\tonTransportError,\n\t\tmode: _mode,\n\t} = opts ?? {};\n\n\tconst buffered = flushIntervalMs > 0 || batchSize < Number.POSITIVE_INFINITY;\n\t// Pass `serialize` via reactiveSink's config so sync throws are classified as\n\t// `stage:\"serialize\"` rather than `stage:\"send\"`. Inside send/sendBatch the\n\t// payload is already a string (serialize output).\n\tconst handle: ReactiveSinkHandle<T> = buffered\n\t\t? reactiveSink<T>(source, {\n\t\t\t\tonTransportError,\n\t\t\t\tbatchSize,\n\t\t\t\tflushIntervalMs,\n\t\t\t\tserialize,\n\t\t\t\tsendBatch: (chunk) => {\n\t\t\t\t\twriter.write((chunk as unknown as string[]).join(\"\"));\n\t\t\t\t},\n\t\t\t})\n\t\t: reactiveSink<T>(source, {\n\t\t\t\tonTransportError,\n\t\t\t\tserialize,\n\t\t\t\tsend: (line) => {\n\t\t\t\t\twriter.write(line as unknown as string);\n\t\t\t\t},\n\t\t\t});\n\n\tconst originalDispose = handle.dispose;\n\thandle.dispose = () => {\n\t\toriginalDispose();\n\t\ttry {\n\t\t\twriter.end();\n\t\t} catch {\n\t\t\t/* writer may already be closed */\n\t\t}\n\t};\n\treturn handle;\n}\n\n// ——— toCSV ———\n\n/** Options for {@link toCSV}. */\nexport type ToCSVOptions<T> = ExtraOpts & {\n\t/** Column names. Required — determines header row and field order. */\n\tcolumns: string[];\n\t/** Column delimiter. Default: `\",\"`. */\n\tdelimiter?: string;\n\t/** Whether to write a header row on first flush. Default: `true`. */\n\twriteHeader?: boolean;\n\t/** Extract a cell value from the row object. Default: `String(row[col] ?? \"\")`. */\n\tcellExtractor?: (row: T, column: string) => string;\n\t/** Flush interval in ms. Default: `0` (write-through). */\n\tflushIntervalMs?: number;\n\t/** Buffer size before auto-flush. Default: `Infinity`. */\n\tbatchSize?: number;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\nfunction escapeCSVField(value: string, delimiter: string): string {\n\tif (value.includes(delimiter) || value.includes('\"') || value.includes(\"\\n\")) {\n\t\treturn `\"${value.replace(/\"/g, '\"\"')}\"`;\n\t}\n\treturn value;\n}\n\n/**\n * CSV file sink — writes upstream `DATA` as CSV rows.\n *\n * @param source - Upstream node.\n * @param writer - Writable file handle.\n * @param opts - Column definition, delimiter, and buffering options.\n * @returns `BufferedSinkHandle`.\n *\n * @category extra\n */\nexport function toCSV<T>(\n\tsource: Node<T>,\n\twriter: FileWriterLike,\n\topts: ToCSVOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tcolumns,\n\t\tdelimiter = \",\",\n\t\twriteHeader = true,\n\t\tcellExtractor = (row: T, col: string) => String((row as Record<string, unknown>)[col] ?? \"\"),\n\t\tflushIntervalMs = 0,\n\t\tbatchSize = Number.POSITIVE_INFINITY,\n\t\tonTransportError,\n\t\t...rest\n\t} = opts;\n\n\tlet headerWritten = false;\n\n\tconst serializeRow = (row: T): string => {\n\t\tif (!headerWritten && writeHeader) {\n\t\t\theaderWritten = true;\n\t\t\tconst header = columns.map((c) => escapeCSVField(c, delimiter)).join(delimiter);\n\t\t\tconst data = columns\n\t\t\t\t.map((c) => escapeCSVField(cellExtractor(row, c), delimiter))\n\t\t\t\t.join(delimiter);\n\t\t\treturn `${header}\\n${data}\\n`;\n\t\t}\n\t\treturn `${columns.map((c) => escapeCSVField(cellExtractor(row, c), delimiter)).join(delimiter)}\\n`;\n\t};\n\n\treturn toFile<T>(source, writer, {\n\t\tserialize: serializeRow,\n\t\tflushIntervalMs,\n\t\tbatchSize,\n\t\tonTransportError,\n\t\t...rest,\n\t});\n}\n\n// ——— toClickHouse ———\n\n/** Duck-typed ClickHouse client for batch inserts. */\nexport type ClickHouseInsertClientLike = {\n\tinsert(params: { table: string; values: unknown[]; format?: string }): Promise<void>;\n};\n\n/** Options for {@link toClickHouse}. */\nexport type ToClickHouseOptions<T> = ExtraOpts & {\n\t/** Batch size before auto-flush. Default: `1000`. */\n\tbatchSize?: number;\n\t/** Flush interval in ms. Default: `5000`. */\n\tflushIntervalMs?: number;\n\t/** Insert format. Default: `\"JSONEachRow\"`. */\n\tformat?: string;\n\t/** Transform value before insert. Default: identity. */\n\ttransform?: (value: T) => unknown;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * ClickHouse buffered batch insert sink.\n *\n * Accumulates upstream `DATA` values and inserts in batches.\n *\n * @param source - Upstream node.\n * @param client - ClickHouse client with `insert()`.\n * @param table - Target table name.\n * @param opts - Batch size, flush interval, and transform options.\n * @returns `BufferedSinkHandle`.\n *\n * @category extra\n */\nexport function toClickHouse<T>(\n\tsource: Node<T>,\n\tclient: ClickHouseInsertClientLike,\n\ttable: string,\n\topts?: ToClickHouseOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tbatchSize = 1000,\n\t\tflushIntervalMs = 5000,\n\t\tformat = \"JSONEachRow\",\n\t\ttransform = (v: T) => v,\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tbatchSize,\n\t\tflushIntervalMs,\n\t\tserialize: transform,\n\t\tsendBatch: async (batch) => {\n\t\t\tawait client.insert({ table, values: batch, format });\n\t\t},\n\t});\n}\n\n// ——— toS3 ———\n\n/** Duck-typed S3 client (compatible with AWS SDK v3 `S3Client.send(PutObjectCommand(...))`). */\nexport type S3ClientLike = {\n\tputObject(params: {\n\t\tBucket: string;\n\t\tKey: string;\n\t\tBody: string | Uint8Array;\n\t\tContentType?: string;\n\t}): Promise<unknown>;\n};\n\n/** Options for {@link toS3}. */\nexport type ToS3Options<T> = ExtraOpts & {\n\t/** Output format. Default: `\"ndjson\"`. */\n\tformat?: \"ndjson\" | \"json\";\n\t/** Generate the S3 key for each batch. Receives `(seq, wallClockNs)`. Default: ISO timestamp + sequence. */\n\tkeyGenerator?: (seq: number, timestampNs: number) => string;\n\t/** Batch size before auto-flush. Default: `1000`. */\n\tbatchSize?: number;\n\t/** Flush interval in ms. Default: `10000`. */\n\tflushIntervalMs?: number;\n\t/** Transform value before serialization. Default: identity. */\n\ttransform?: (value: T) => unknown;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * S3 object storage sink — buffers values and uploads as NDJSON or JSON objects.\n *\n * @param source - Upstream node.\n * @param client - S3-compatible client with `putObject()`.\n * @param bucket - S3 bucket name.\n * @param opts - Format, key generation, batching options.\n * @returns `BufferedSinkHandle`.\n *\n * @category extra\n */\nexport function toS3<T>(\n\tsource: Node<T>,\n\tclient: S3ClientLike,\n\tbucket: string,\n\topts?: ToS3Options<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tformat = \"ndjson\",\n\t\tkeyGenerator = (seq: number, timestampNs: number) => {\n\t\t\tconst ms = Math.floor(timestampNs / 1_000_000);\n\t\t\tconst ts = new Date(ms).toISOString().replace(/[:.]/g, \"-\");\n\t\t\treturn `data/${ts}-${seq}.${format === \"ndjson\" ? \"ndjson\" : \"json\"}`;\n\t\t},\n\t\tbatchSize = 1000,\n\t\tflushIntervalMs = 10000,\n\t\ttransform = (v: T) => v,\n\t\tonTransportError,\n\t} = opts ?? {};\n\n\tconst contentType = format === \"ndjson\" ? \"application/x-ndjson\" : \"application/json\";\n\tlet seq = 0;\n\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tbatchSize,\n\t\tflushIntervalMs,\n\t\tserialize: transform,\n\t\tsendBatch: async (batch) => {\n\t\t\tseq += 1;\n\t\t\tconst body =\n\t\t\t\tformat === \"ndjson\"\n\t\t\t\t\t? `${batch.map((v) => JSON.stringify(v)).join(\"\\n\")}\\n`\n\t\t\t\t\t: JSON.stringify(batch);\n\t\t\tconst key = keyGenerator(seq, wallClockNs());\n\t\t\tawait client.putObject({ Bucket: bucket, Key: key, Body: body, ContentType: contentType });\n\t\t},\n\t});\n}\n\n// ——— toPostgres ———\n\n/** Duck-typed Postgres client (compatible with `pg.Client` / `pg.Pool`). */\nexport type PostgresClientLike = {\n\tquery(sql: string, params?: unknown[]): Promise<unknown>;\n};\n\n/** Options for {@link toPostgres}. */\nexport type ToPostgresOptions<T> = ExtraOpts & {\n\t/** Build the SQL + params for an insert. Default: JSON insert into `table`. */\n\ttoSQL?: (value: T, table: string) => { sql: string; params: unknown[] };\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * PostgreSQL sink — inserts each upstream `DATA` value as a row.\n *\n * @param source - Upstream node.\n * @param client - Postgres client with `query()`.\n * @param table - Target table name.\n * @param opts - SQL builder and error options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toPostgres<T>(\n\tsource: Node<T>,\n\tclient: PostgresClientLike,\n\ttable: string,\n\topts?: ToPostgresOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\ttoSQL = (v: T, t: string) => ({\n\t\t\tsql: `INSERT INTO \"${t.replace(/\"/g, '\"\"')}\" (data) VALUES ($1)`,\n\t\t\tparams: [JSON.stringify(v)],\n\t\t}),\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tserialize: (value) => toSQL(value, table),\n\t\tsend: async (q) => {\n\t\t\tconst query = q as unknown as { sql: string; params: unknown[] };\n\t\t\tawait client.query(query.sql, query.params);\n\t\t},\n\t});\n}\n\n// ——— toMongo ———\n\n/** Duck-typed MongoDB collection (compatible with `mongodb` driver). */\nexport type MongoCollectionLike = {\n\tinsertOne(doc: unknown): Promise<unknown>;\n};\n\n/** Options for {@link toMongo}. */\nexport type ToMongoOptions<T> = ExtraOpts & {\n\t/** Transform value to a MongoDB document. Default: identity. */\n\ttoDocument?: (value: T) => unknown;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * MongoDB sink — inserts each upstream `DATA` value as a document.\n *\n * @param source - Upstream node.\n * @param collection - MongoDB collection with `insertOne()`.\n * @param opts - Document transform and error options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toMongo<T>(\n\tsource: Node<T>,\n\tcollection: MongoCollectionLike,\n\topts?: ToMongoOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst { toDocument = (v: T) => v, onTransportError } = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tserialize: toDocument,\n\t\tsend: async (doc) => {\n\t\t\tawait collection.insertOne(doc);\n\t\t},\n\t});\n}\n\n// ——— toLoki ———\n\n/** Loki log stream entry. */\nexport type LokiStream = {\n\tstream: Record<string, string>;\n\tvalues: [string, string][];\n};\n\n/** Duck-typed Loki push client (HTTP push API). */\nexport type LokiClientLike = {\n\tpush(streams: { streams: LokiStream[] }): Promise<unknown>;\n};\n\n/** Options for {@link toLoki}. */\nexport type ToLokiOptions<T> = ExtraOpts & {\n\t/** Static labels applied to every log entry. */\n\tlabels?: Record<string, string>;\n\t/** Extract the log line from a value. Default: `JSON.stringify(v)`. */\n\ttoLine?: (value: T) => string;\n\t/** Extract additional labels from a value. Default: none. */\n\ttoLabels?: (value: T) => Record<string, string>;\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * Grafana Loki sink — pushes upstream `DATA` values as log entries.\n *\n * @param source - Upstream node.\n * @param client - Loki-compatible client with `push()`.\n * @param opts - Label, serialization, and error options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toLoki<T>(\n\tsource: Node<T>,\n\tclient: LokiClientLike,\n\topts?: ToLokiOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst {\n\t\tlabels = {},\n\t\ttoLine = (v: T) => JSON.stringify(v),\n\t\ttoLabels,\n\t\tonTransportError,\n\t} = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tserialize: (value) => ({\n\t\t\tline: toLine(value),\n\t\t\tlabels: toLabels ? { ...labels, ...toLabels(value) } : labels,\n\t\t}),\n\t\tsend: async (payload) => {\n\t\t\tconst { line, labels: streamLabels } = payload as {\n\t\t\t\tline: string;\n\t\t\t\tlabels: Record<string, string>;\n\t\t\t};\n\t\t\tconst ts = `${wallClockNs()}`;\n\t\t\tawait client.push({ streams: [{ stream: streamLabels, values: [[ts, line]] }] });\n\t\t},\n\t});\n}\n\n// ——— toTempo ———\n\n/** Duck-typed Tempo span push client (OTLP/HTTP shape). */\nexport type TempoClientLike = {\n\tpush(payload: { resourceSpans: unknown[] }): Promise<unknown>;\n};\n\n/** Options for {@link toTempo}. */\nexport type ToTempoOptions<T> = ExtraOpts & {\n\t/** Transform a value into OTLP resourceSpans entries. */\n\ttoResourceSpans?: (value: T) => unknown[];\n\tonTransportError?: (err: SinkTransportError) => void;\n};\n\n/**\n * Grafana Tempo sink — pushes upstream `DATA` values as trace spans.\n *\n * @param source - Upstream node.\n * @param client - Tempo-compatible client with `push()`.\n * @param opts - Span transform and error options.\n * @returns Unsubscribe function.\n *\n * @category extra\n */\nexport function toTempo<T>(\n\tsource: Node<T>,\n\tclient: TempoClientLike,\n\topts?: ToTempoOptions<T>,\n): ReactiveSinkHandle<T> {\n\tconst { toResourceSpans = (v: T) => [v], onTransportError } = opts ?? {};\n\treturn reactiveSink<T>(source, {\n\t\tonTransportError,\n\t\tserialize: toResourceSpans,\n\t\tsend: async (spans) => {\n\t\t\tawait client.push({ resourceSpans: spans as unknown[] });\n\t\t},\n\t});\n}\n\n// ——— checkpointToS3 ———\n\n/** Options for {@link checkpointToS3}. */\nexport type CheckpointToS3Options = {\n\t/** S3 key prefix. Default: `\"checkpoints/\"`. */\n\tprefix?: string;\n\t/** Debounce ms on the S3 tier. Default: `500`. */\n\tdebounceMs?: number;\n\t/** Full snapshot compaction interval. Default: `10`. */\n\tcompactEvery?: number;\n\tonError?: (error: unknown) => void;\n};\n\ntype StorageTierLike = {\n\tload(key: string): unknown | Promise<unknown>;\n\tsave(key: string, data: unknown): void | Promise<void>;\n\tclear?(key: string): void | Promise<void>;\n\tdebounceMs?: number;\n\tcompactEvery?: number;\n};\n\ntype AttachStorageGraphLike = {\n\tattachStorage: (tiers: readonly StorageTierLike[], opts?: unknown) => { dispose(): void };\n\tname: string;\n};\n\n/**\n * Wires `graph.attachStorage()` with an S3-backed tier.\n *\n * @param graph - Graph instance to checkpoint.\n * @param client - S3-compatible client with `putObject()`.\n * @param bucket - S3 bucket name.\n * @param opts - Key prefix, debounce, and compaction options.\n * @returns Dispose handle.\n *\n * @category extra\n */\nexport function checkpointToS3(\n\tgraph: AttachStorageGraphLike,\n\tclient: S3ClientLike,\n\tbucket: string,\n\topts?: CheckpointToS3Options,\n): { dispose(): void } {\n\tconst { prefix = \"checkpoints/\", debounceMs = 500, compactEvery = 10, onError } = opts ?? {};\n\tconst tier: StorageTierLike = {\n\t\tdebounceMs,\n\t\tcompactEvery,\n\t\tsave(_key, data) {\n\t\t\tconst ms = Math.floor(wallClockNs() / 1_000_000);\n\t\t\tconst s3Key = `${prefix}${graph.name}/checkpoint-${ms}.json`;\n\t\t\tlet body: string;\n\t\t\ttry {\n\t\t\t\tbody = JSON.stringify(data);\n\t\t\t} catch (err) {\n\t\t\t\tonError?.(err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvoid client\n\t\t\t\t.putObject({\n\t\t\t\t\tBucket: bucket,\n\t\t\t\t\tKey: s3Key,\n\t\t\t\t\tBody: body,\n\t\t\t\t\tContentType: \"application/json\",\n\t\t\t\t})\n\t\t\t\t.catch((err) => onError?.(err));\n\t\t},\n\t\tload() {\n\t\t\t// S3 tier is write-only here — one object per checkpoint timestamp,\n\t\t\t// no canonical \"latest\" key for load.\n\t\t\treturn null;\n\t\t},\n\t};\n\treturn graph.attachStorage([tier], { onError: (err: unknown) => onError?.(err) });\n}\n\n// ——— checkpointToRedis ———\n\n/** Duck-typed Redis client for checkpoint storage. */\nexport type RedisCheckpointClientLike = {\n\tset(key: string, value: string): Promise<unknown>;\n\tget(key: string): Promise<string | null>;\n};\n\n/** Options for {@link checkpointToRedis}. */\nexport type CheckpointToRedisOptions = {\n\t/** Key prefix. Default: `\"graphrefly:checkpoint:\"`. */\n\tprefix?: string;\n\t/** Debounce ms on the Redis tier. Default: `500`. */\n\tdebounceMs?: number;\n\t/** Full snapshot compaction interval. Default: `10`. */\n\tcompactEvery?: number;\n\tonError?: (error: unknown) => void;\n};\n\n/**\n * Wires `graph.attachStorage()` with a Redis-backed tier.\n *\n * @param graph - Graph instance to checkpoint.\n * @param client - Redis client with `set()`/`get()`.\n * @param opts - Key prefix, debounce, and compaction options.\n * @returns Dispose handle.\n *\n * @category extra\n */\nexport function checkpointToRedis(\n\tgraph: AttachStorageGraphLike,\n\tclient: RedisCheckpointClientLike,\n\topts?: CheckpointToRedisOptions,\n): { dispose(): void } {\n\tconst {\n\t\tprefix = \"graphrefly:checkpoint:\",\n\t\tdebounceMs = 500,\n\t\tcompactEvery = 10,\n\t\tonError,\n\t} = opts ?? {};\n\tconst redisKey = `${prefix}${graph.name}`;\n\tconst tier: StorageTierLike = {\n\t\tdebounceMs,\n\t\tcompactEvery,\n\t\tsave(_key, data) {\n\t\t\tlet body: string;\n\t\t\ttry {\n\t\t\t\tbody = JSON.stringify(data);\n\t\t\t} catch (err) {\n\t\t\t\tonError?.(err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvoid client.set(redisKey, body).catch((err) => onError?.(err));\n\t\t},\n\t\tasync load() {\n\t\t\tconst raw = await client.get(redisKey);\n\t\t\tif (raw == null) return null;\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(raw) as unknown;\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t};\n\treturn graph.attachStorage([tier], { onError: (err: unknown) => onError?.(err) });\n}\n\n// ——————————————————————————————————————————————————————————————\n// SQLite adapters (roadmap §5.2b)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Duck-typed synchronous SQLite database.\n *\n * Compatible with `better-sqlite3` (`.prepare().all()` / `.prepare().run()`)\n * and Node.js `node:sqlite` `DatabaseSync`. The user wraps their driver behind\n * this uniform contract — method name `query` matches the project-wide\n * convention (`PostgresClientLike.query`, `ClickHouseClientLike.query`).\n */\nexport type SqliteDbLike = {\n\tquery(sql: string, params?: unknown[]): unknown[];\n};\n\n/** Options for {@link fromSqlite}. */\nexport type FromSqliteOptions<T> = ExtraOpts & {\n\t/** Map a raw row object to the desired type. Default: identity cast. */\n\tmapRow?: (row: unknown) => T;\n\t/** Bind parameters for the query. */\n\tparams?: unknown[];\n};\n\n/**\n * One-shot SQLite query as a reactive source.\n *\n * Executes `query` synchronously via `db.query()`, emits **one `DATA` containing\n * the full result array**, then `COMPLETE`. Downstream flattens with\n * `mergeAll` / a custom operator if per-row semantics are required — the\n * array shape is the simpler default and matches how every SQL driver returns\n * results natively. Use {@link fromSqliteCursor} for streaming row-by-row.\n *\n * @param db - SQLite database (caller owns connection).\n * @param query - SQL string to execute.\n * @param opts - Row mapper, params, and node options.\n * @returns `Node<T[]>` — one `DATA` with the full row array, then `COMPLETE`.\n *\n * @example\n * ```ts\n * import Database from \"better-sqlite3\";\n * import { fromSqlite } from \"@graphrefly/graphrefly-ts\";\n *\n * const raw = new Database(\"app.db\");\n * const db = { query: (sql, params) => raw.prepare(sql).all(...(params ?? [])) };\n * const rows$ = fromSqlite(db, \"SELECT * FROM users WHERE active = ?\", { params: [1] });\n * ```\n *\n * @category extra\n */\nexport function fromSqlite<T = unknown>(\n\tdb: SqliteDbLike,\n\tquery: string,\n\topts?: FromSqliteOptions<T>,\n): Node<T[]> {\n\tconst { mapRow = (r: unknown) => r as T, params, ...rest } = opts ?? {};\n\n\treturn producer<T[]>(\n\t\t(a) => {\n\t\t\ttry {\n\t\t\t\tconst rows = db.query(query, params);\n\t\t\t\tconst mapped = rows.map(mapRow);\n\t\t\t\ta.emit(mapped);\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t} catch (err) {\n\t\t\t\ta.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t\t{ describeKind: \"producer\", completeWhenDepsComplete: false, ...rest } as NodeOptions<T[]>,\n\t);\n}\n\n/**\n * Duck-typed iterable-capable SQLite database — `iterate(sql, params)` returns\n * a synchronous iterator over rows, avoiding the \"all-rows-in-memory\" cost of\n * `db.query`. Compatible with `better-sqlite3`'s `.prepare().iterate()`.\n *\n * @category extra\n */\nexport type SqliteIterableDbLike = {\n\titerate(sql: string, params?: unknown[]): Iterable<unknown>;\n};\n\n/**\n * Cursor-streaming SQLite query — emits one `DATA` per row from a synchronous\n * row iterator, then `COMPLETE`. Use when result sets are too large to\n * materialize fully into an array.\n *\n * @category extra\n */\nexport function fromSqliteCursor<T = unknown>(\n\tdb: SqliteIterableDbLike,\n\tquery: string,\n\topts?: FromSqliteOptions<T>,\n): Node<T> {\n\tconst { mapRow = (r: unknown) => r as T, params, ...rest } = opts ?? {};\n\treturn producer<T>(\n\t\t(a) => {\n\t\t\ttry {\n\t\t\t\tconst it = db.iterate(query, params);\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfor (const row of it) a.emit(mapRow(row));\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\ta.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t\t{ describeKind: \"producer\", completeWhenDepsComplete: false, ...rest } as NodeOptions<T>,\n\t);\n}\n\n/** Options for {@link toSqlite}. */\nexport type ToSqliteOptions<T> = ExtraOpts & {\n\t/** Build SQL + params for an insert. Default: JSON insert into `(data)` column. */\n\ttoSQL?: (value: T, table: string) => { sql: string; params: unknown[] };\n\tonTransportError?: (err: SinkTransportError) => void;\n\t/**\n\t * When `true`, buffer DATA values and execute all inserts inside a single\n\t * `BEGIN`/`COMMIT` transaction when the batch drains. This avoids per-row\n\t * fsync overhead and dramatically reduces event-loop blocking for\n\t * high-throughput sources. The first insert error stops the batch and\n\t * triggers a `ROLLBACK`; the error is reported via `onTransportError`.\n\t */\n\tbatchInsert?: boolean;\n\t/** Auto-flush when buffer reaches this size. Default: `1000`. Only applies when `batchInsert` is `true`. */\n\tmaxBatchSize?: number;\n\t/** Periodic flush interval in ms. `0` = no timer (flush on terminal messages only). Default: `0`. Only applies when `batchInsert` is `true`. */\n\tflushIntervalMs?: number;\n};\n\n/**\n * SQLite sink — inserts each upstream `DATA` value as a row.\n *\n * Follows the same pattern as {@link toPostgres} / {@link toMongo}. Since SQLite\n * is synchronous, errors propagate immediately (no `void promise.catch`).\n *\n * @param source - Upstream node.\n * @param db - SQLite database (caller owns connection).\n * @param table - Target table name.\n * @param opts - SQL builder and error options.\n * @returns Unsubscribe function.\n *\n * @example\n * ```ts\n * import Database from \"better-sqlite3\";\n * import { toSqlite, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const raw = new Database(\"app.db\");\n * const db = { query: (sql, params) => (raw.prepare(sql).run(...(params ?? [])), []) };\n * const source = state({ name: \"Alice\", score: 42 });\n * const unsub = toSqlite(source, db, \"events\");\n * ```\n *\n * @category extra\n */\nexport function toSqlite<T>(\n\tsource: Node<T>,\n\tdb: SqliteDbLike,\n\ttable: string,\n\topts?: ToSqliteOptions<T>,\n): ReactiveSinkHandle<T> {\n\tif (table.includes(\"\\0\") || table.length === 0) {\n\t\tthrow new Error(`toSqlite: invalid table name: ${JSON.stringify(table)}`);\n\t}\n\tconst {\n\t\ttoSQL = (v: T, t: string) => ({\n\t\t\tsql: `INSERT INTO \"${t.replace(/\"/g, '\"\"')}\" (data) VALUES (?)`,\n\t\t\tparams: [JSON.stringify(v)],\n\t\t}),\n\t\tonTransportError,\n\t\tbatchInsert = false,\n\t\tmaxBatchSize = 1000,\n\t\tflushIntervalMs = 0,\n\t} = opts ?? {};\n\n\tconst serialize = (value: T) => toSQL(value, table);\n\ttype Query = { sql: string; params: unknown[] };\n\n\tif (!batchInsert) {\n\t\treturn reactiveSink<T>(source, {\n\t\t\tonTransportError,\n\t\t\tserialize,\n\t\t\tsend: (q) => {\n\t\t\t\tconst query = q as Query;\n\t\t\t\tdb.query(query.sql, query.params);\n\t\t\t},\n\t\t});\n\t}\n\n\t// Batched mode — transactional: BEGIN → inserts → COMMIT (or ROLLBACK on\n\t// first insert error). Must preserve pending queries when BEGIN itself\n\t// fails (e.g. \"database is locked\") so a subsequent `flush()` can retry\n\t// with the same data intact. The generic `reactiveSink` clears its buffer\n\t// before invoking `sendBatch`, so we keep a bespoke transactional loop on\n\t// top of the reactiveSink skeleton: custom `flush()` + local pending\n\t// queue with re-queue semantics on BEGIN failure.\n\tconst errorsNode = state<SinkTransportError | null>(null);\n\tconst sentNode = state<T | undefined>(undefined, { equals: () => false }) as unknown as Node<T>;\n\tconst failedNode = state<SinkFailure<T> | null>(null);\n\tconst inFlightNode = state(0);\n\tconst bufferedNode = state(0);\n\n\tconst reportError = (err: SinkTransportError) => {\n\t\ttry {\n\t\t\tonTransportError?.(err);\n\t\t} catch {\n\t\t\t/* user hook must not escape */\n\t\t}\n\t\ttry {\n\t\t\terrorsNode.down([[DATA, err]]);\n\t\t} catch {\n\t\t\t/* drain re-entrance */\n\t\t}\n\t};\n\n\ttype PendingEntry = { value: T; query: Query };\n\tlet pending: PendingEntry[] = [];\n\tlet flushing = false;\n\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\tlet disposed = false;\n\n\tconst updateBuffered = () => bufferedNode.down([[DATA, pending.length]]);\n\n\t// Guarded emit helpers — drop post-TEARDOWN writes silently (spec §1.3.4\n\t// terminal filter already blocks them downstream; this skips the\n\t// allocation). Prevents \"emit after TEARDOWN\" observable in subscribers\n\t// that race with in-flight flushes.\n\tconst safeEmitSent = (v: T) => {\n\t\tif (disposed) return;\n\t\tsentNode.down([[DATA, v]]);\n\t};\n\tconst safeEmitFailed = (f: SinkFailure<T>) => {\n\t\tif (disposed) return;\n\t\tfailedNode.down([[DATA, f]]);\n\t};\n\tconst safeSetInFlight = (n: number) => {\n\t\tif (disposed) return;\n\t\tinFlightNode.down([[DATA, n]]);\n\t};\n\tconst safeReportError = (err: SinkTransportError) => {\n\t\tif (disposed) return;\n\t\treportError(err);\n\t};\n\n\tconst flushTransaction = () => {\n\t\tif (pending.length === 0 || flushing) return;\n\t\tflushing = true;\n\t\tsafeSetInFlight(1);\n\t\ttry {\n\t\t\tdb.query(\"BEGIN\", []);\n\t\t} catch (err) {\n\t\t\t// BEGIN failed — keep `pending` intact so a later flush can retry.\n\t\t\tflushing = false;\n\t\t\tsafeSetInFlight(0);\n\t\t\tsafeReportError({\n\t\t\t\tstage: \"send\",\n\t\t\t\terror: err instanceof Error ? err : new Error(String(err)),\n\t\t\t\tvalue: undefined,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst chunk = pending;\n\t\tpending = [];\n\t\tupdateBuffered();\n\n\t\tlet firstError: Error | undefined;\n\t\tlet committedCount = 0;\n\t\tfor (const entry of chunk) {\n\t\t\ttry {\n\t\t\t\tdb.query(entry.query.sql, entry.query.params);\n\t\t\t\tcommittedCount += 1;\n\t\t\t} catch (err) {\n\t\t\t\tfirstError = err instanceof Error ? err : new Error(String(err));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (firstError) {\n\t\t\ttry {\n\t\t\t\tdb.query(\"ROLLBACK\", []);\n\t\t\t} catch {\n\t\t\t\t/* ROLLBACK failure — firstError already captured */\n\t\t\t}\n\t\t\tsafeReportError({ stage: \"send\", error: firstError, value: undefined });\n\t\t\tfor (const entry of chunk) {\n\t\t\t\tsafeEmitFailed({ value: entry.value, error: firstError, attempts: 1 });\n\t\t\t}\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tdb.query(\"COMMIT\", []);\n\t\t\t\tfor (const entry of chunk) safeEmitSent(entry.value);\n\t\t\t} catch (err) {\n\t\t\t\tconst error = err instanceof Error ? err : new Error(String(err));\n\t\t\t\tsafeReportError({ stage: \"send\", error, value: undefined });\n\t\t\t\tfor (let i = 0; i < committedCount; i++) {\n\t\t\t\t\tsafeEmitFailed({ value: chunk[i].value, error, attempts: 1 });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tflushing = false;\n\t\tsafeSetInFlight(0);\n\t};\n\n\tconst scheduleFlush = () => {\n\t\tif (flushIntervalMs > 0 && timer === undefined && !disposed) {\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\t/* I/O flush timer — not reactive scheduling (§5.10) */\n\t\t\t\ttimer = undefined;\n\t\t\t\tflushTransaction();\n\t\t\t}, flushIntervalMs);\n\t\t}\n\t};\n\n\tconst unsub = source.subscribe((msgs) => {\n\t\tfor (const msg of msgs) {\n\t\t\tconst t = msg[0];\n\t\t\tif (t === DATA) {\n\t\t\t\tconst value = msg[1] as T;\n\t\t\t\tlet query: Query;\n\t\t\t\ttry {\n\t\t\t\t\tquery = serialize(value);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst error = err instanceof Error ? err : new Error(String(err));\n\t\t\t\t\treportError({ stage: \"serialize\", error, value });\n\t\t\t\t\tfailedNode.down([[DATA, { value, error, attempts: 0 } satisfies SinkFailure<T>]]);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tpending.push({ value, query });\n\t\t\t\tupdateBuffered();\n\t\t\t\tif (pending.length >= maxBatchSize) flushTransaction();\n\t\t\t\telse scheduleFlush();\n\t\t\t} else if (defaultConfig.messageTier(t) >= 3) {\n\t\t\t\tflushTransaction();\n\t\t\t}\n\t\t}\n\t});\n\n\tconst dispose = () => {\n\t\tif (disposed) return;\n\t\tif (timer !== undefined) {\n\t\t\tclearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t}\n\t\tflushTransaction();\n\t\tdisposed = true;\n\t\tunsub();\n\t\tfor (const n of [errorsNode, sentNode, failedNode, inFlightNode, bufferedNode]) {\n\t\t\ttry {\n\t\t\t\t(n as Node<unknown>).down([[TEARDOWN]]);\n\t\t\t} catch {\n\t\t\t\t/* drain re-entrance */\n\t\t\t}\n\t\t}\n\t};\n\n\treturn {\n\t\tdispose,\n\t\tsent: sentNode,\n\t\tfailed: failedNode,\n\t\tinFlight: inFlightNode,\n\t\terrors: errorsNode,\n\t\tbuffered: bufferedNode,\n\t\tflush: async () => {\n\t\t\tif (!disposed) flushTransaction();\n\t\t},\n\t};\n}\n\n// ——————————————————————————————————————————————————————————————\n// Prisma adapter (5.2b)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Duck-typed Prisma model delegate.\n *\n * Compatible with any Prisma model's `findMany` method (e.g. `prisma.user`).\n * The consumer passes the model delegate directly — no dependency on `@prisma/client`.\n */\nexport type PrismaModelLike<T = unknown> = {\n\tfindMany(args?: unknown): Promise<T[]>;\n};\n\n/** Options for {@link fromPrisma}. */\nexport type FromPrismaOptions<T, U = T> = ExtraOpts & {\n\t/** Prisma `findMany` args (where, orderBy, select, include, take, skip, etc.). */\n\targs?: unknown;\n\t/** Map each row to the desired shape. Default: identity cast. */\n\tmapRow?: (row: T) => U;\n};\n\n/**\n * One-shot Prisma query as a reactive source.\n *\n * Calls `model.findMany(args)`, emits one `DATA` per result row, then `COMPLETE`.\n * Compose with `switchMap` + `fromTimer` for periodic re-query.\n *\n * @param model - Prisma model delegate (e.g. `prisma.user`).\n * @param opts - `findMany` args, row mapper, and node options.\n * @returns `Node<U>` — one `DATA` per row, then `COMPLETE`.\n *\n * @example\n * ```ts\n * import { PrismaClient } from \"@prisma/client\";\n * import { fromPrisma } from \"@graphrefly/graphrefly-ts\";\n *\n * const prisma = new PrismaClient();\n * const activeUsers = fromPrisma(prisma.user, {\n * args: { where: { active: true } },\n * });\n * ```\n *\n * @category extra\n */\nexport function fromPrisma<T = unknown, U = T>(\n\tmodel: PrismaModelLike<T>,\n\topts?: FromPrismaOptions<T, U>,\n): Node<U[]> {\n\tconst { args, mapRow = (r: T) => r as unknown as U, ...rest } = opts ?? {};\n\n\treturn producer<U[]>(\n\t\t(a) => {\n\t\t\tlet active = true;\n\n\t\t\tvoid model\n\t\t\t\t.findMany(args)\n\t\t\t\t.then((rows) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ta.emit(rows.map(mapRow));\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\ta.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* node already torn down — swallow */\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t},\n\t\t{ ...rest, describeKind: \"producer\", completeWhenDepsComplete: false } as NodeOptions<U[]>,\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// Drizzle adapter (5.2b)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Duck-typed Drizzle query builder result.\n *\n * Drizzle query builders (e.g. `db.select().from(users)`) expose `.execute()`\n * which returns `Promise<T[]>`. This interface captures that contract without\n * depending on `drizzle-orm`.\n */\nexport type DrizzleQueryLike<T = unknown> = {\n\texecute(): Promise<T[]>;\n};\n\n/** Options for {@link fromDrizzle}. */\nexport type FromDrizzleOptions<T, U = T> = ExtraOpts & {\n\t/** Map each row to the desired shape. Default: identity cast. */\n\tmapRow?: (row: T) => U;\n};\n\n/**\n * One-shot Drizzle query as a reactive source.\n *\n * Calls `query.execute()`, emits one `DATA` per result row, then `COMPLETE`.\n * Compose with `switchMap` + `fromTimer` for periodic re-query.\n *\n * @param query - Drizzle query builder (e.g. `db.select().from(users).where(...)`).\n * @param opts - Row mapper and node options.\n * @returns `Node<U>` — one `DATA` per row, then `COMPLETE`.\n *\n * @example\n * ```ts\n * import { drizzle } from \"drizzle-orm/node-postgres\";\n * import { fromDrizzle } from \"@graphrefly/graphrefly-ts\";\n *\n * const db = drizzle(pool);\n * const rows$ = fromDrizzle(db.select().from(users).where(eq(users.active, true)));\n * ```\n *\n * @category extra\n */\nexport function fromDrizzle<T = unknown, U = T>(\n\tquery: DrizzleQueryLike<T>,\n\topts?: FromDrizzleOptions<T, U>,\n): Node<U[]> {\n\tconst { mapRow = (r: T) => r as unknown as U, ...rest } = opts ?? {};\n\n\treturn producer<U[]>(\n\t\t(a) => {\n\t\t\tlet active = true;\n\n\t\t\tvoid query\n\t\t\t\t.execute()\n\t\t\t\t.then((rows) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ta.emit(rows.map(mapRow));\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\ta.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* node already torn down — swallow */\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t},\n\t\t{ ...rest, describeKind: \"producer\", completeWhenDepsComplete: false } as NodeOptions<U[]>,\n\t);\n}\n\n// ——————————————————————————————————————————————————————————————\n// Kysely adapter (5.2b)\n// ——————————————————————————————————————————————————————————————\n\n/**\n * Duck-typed Kysely query builder result.\n *\n * Kysely query builders expose `.execute()` which returns `Promise<T[]>`.\n * This interface captures that contract without depending on `kysely`.\n */\nexport type KyselyQueryLike<T = unknown> = {\n\texecute(): Promise<T[]>;\n};\n\n/** Options for {@link fromKysely}. */\nexport type FromKyselyOptions<T, U = T> = ExtraOpts & {\n\t/** Map each row to the desired shape. Default: identity cast. */\n\tmapRow?: (row: T) => U;\n};\n\n/**\n * One-shot Kysely query as a reactive source.\n *\n * Calls `query.execute()`, emits one `DATA` per result row, then `COMPLETE`.\n * Compose with `switchMap` + `fromTimer` for periodic re-query.\n *\n * @param query - Kysely query builder (e.g. `db.selectFrom(\"users\").selectAll()`).\n * @param opts - Row mapper and node options.\n * @returns `Node<U>` — one `DATA` per row, then `COMPLETE`.\n *\n * @example\n * ```ts\n * import { Kysely, PostgresDialect } from \"kysely\";\n * import { fromKysely } from \"@graphrefly/graphrefly-ts\";\n *\n * const db = new Kysely<DB>({ dialect: new PostgresDialect({ pool }) });\n * const rows$ = fromKysely(db.selectFrom(\"users\").selectAll().where(\"active\", \"=\", true));\n * ```\n *\n * @category extra\n */\nexport function fromKysely<T = unknown, U = T>(\n\tquery: KyselyQueryLike<T>,\n\topts?: FromKyselyOptions<T, U>,\n): Node<U[]> {\n\tconst { mapRow = (r: T) => r as unknown as U, ...rest } = opts ?? {};\n\n\treturn producer<U[]>(\n\t\t(a) => {\n\t\t\tlet active = true;\n\n\t\t\tvoid query\n\t\t\t\t.execute()\n\t\t\t\t.then((rows) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ta.emit(rows.map(mapRow));\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t})\n\t\t\t\t.catch((err) => {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\ttry {\n\t\t\t\t\t\ta.down([[ERROR, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* node already torn down — swallow */\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t},\n\t\t{ ...rest, describeKind: \"producer\", completeWhenDepsComplete: false } as NodeOptions<U[]>,\n\t);\n}\n","/**\n * Watermark-based backpressure controller — reactive PAUSE/RESUME flow control.\n *\n * Purely synchronous, event-driven. No timers, no polling, no Promises.\n * Each controller instance uses a unique lockId so multiple controllers\n * on the same upstream node do not collide.\n *\n * @module\n */\n\nimport { type Messages, PAUSE, RESUME } from \"../core/messages.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type WatermarkOptions = {\n\t/** Pending count at which PAUSE is sent upstream. */\n\thighWaterMark: number;\n\t/** Pending count at which RESUME is sent upstream (after being paused). */\n\tlowWaterMark: number;\n};\n\nexport type WatermarkController = {\n\t/** Call when a DATA message is buffered/enqueued. Returns `true` if PAUSE was just sent. */\n\tonEnqueue(): boolean;\n\t/** Call when a buffered item is consumed. Returns `true` if RESUME was just sent. */\n\tonDequeue(): boolean;\n\t/** Current un-consumed item count. */\n\treadonly pending: number;\n\t/** Whether upstream is currently paused by this controller. */\n\treadonly paused: boolean;\n\t/** Dispose: if paused, sends RESUME to unblock upstream. */\n\tdispose(): void;\n};\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nlet nextLockId = 0;\n\n/**\n * Creates a watermark-based backpressure controller.\n *\n * @param sendUp - Callback that delivers messages upstream (typically `handle.up`).\n * @param opts - High/low watermark thresholds (item counts).\n * @returns A {@link WatermarkController}.\n *\n * @example\n * ```ts\n * const handle = graph.observe(\"fast-source\");\n * const wm = createWatermarkController(\n * (msgs) => handle.up(msgs),\n * { highWaterMark: 64, lowWaterMark: 16 },\n * );\n *\n * // In sink callback:\n * handle.subscribe((msgs) => {\n * for (const msg of msgs) {\n * if (msg[0] === DATA) {\n * buffer.push(msg[1]);\n * wm.onEnqueue();\n * }\n * }\n * });\n *\n * // When consumer drains:\n * const item = buffer.shift();\n * wm.onDequeue();\n * ```\n *\n * @category extra\n */\nexport function createWatermarkController(\n\tsendUp: (messages: Messages) => void,\n\topts: WatermarkOptions,\n): WatermarkController {\n\tif (opts.highWaterMark < 1) throw new RangeError(\"highWaterMark must be >= 1\");\n\tif (opts.lowWaterMark < 0) throw new RangeError(\"lowWaterMark must be >= 0\");\n\tif (opts.lowWaterMark >= opts.highWaterMark)\n\t\tthrow new RangeError(\"lowWaterMark must be < highWaterMark\");\n\tconst lockId = Symbol(`bp-${++nextLockId}`);\n\tlet pending = 0;\n\tlet paused = false;\n\n\treturn {\n\t\tonEnqueue(): boolean {\n\t\t\tpending += 1;\n\t\t\tif (!paused && pending >= opts.highWaterMark) {\n\t\t\t\tpaused = true;\n\t\t\t\tsendUp([[PAUSE, lockId]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tonDequeue(): boolean {\n\t\t\tif (pending > 0) pending -= 1;\n\t\t\tif (paused && pending <= opts.lowWaterMark) {\n\t\t\t\tpaused = false;\n\t\t\t\tsendUp([[RESUME, lockId]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tget pending() {\n\t\t\treturn pending;\n\t\t},\n\t\tget paused() {\n\t\t\treturn paused;\n\t\t},\n\t\tdispose() {\n\t\t\tif (paused) {\n\t\t\t\tpaused = false;\n\t\t\t\tsendUp([[RESUME, lockId]]);\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * N-tier cascading cache — roadmap §3.1c.\n *\n * Each cached entry is a `state()` node. On miss, tiers are tried in order\n * (tier 0 = hottest). Hits auto-promote to faster tiers. Supports eviction\n * policy and write-through.\n *\n * Consumes {@link StorageTier} directly (the same primitive used by\n * {@link Graph.attachStorage}) — no separate `CacheTier` interface. Async\n * tiers participate via `Promise<unknown>` returns from `load`; sync tiers\n * stay zero-microtask (the cascade inspects the return type and branches).\n */\nimport { DATA, TEARDOWN } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { state } from \"../core/sugar.js\";\nimport type { StorageTier } from \"./storage.js\";\n\n// ——————————————————————————————————————————————————————————————\n// Eviction policy\n// ——————————————————————————————————————————————————————————————\n\n/** Pluggable eviction policy for {@link cascadingCache}. */\nexport interface CacheEvictionPolicy<K> {\n\tinsert(key: K): void;\n\ttouch(key: K): void;\n\tdelete(key: K): void;\n\tevict(count: number): K[];\n\tsize(): number;\n}\n\n/**\n * LRU eviction policy backed by a doubly-linked list + Map.\n *\n * @returns An {@link CacheEvictionPolicy} that evicts least-recently-used entries.\n *\n * @category extra\n */\nexport function lru<K>(): CacheEvictionPolicy<K> {\n\ttype LNode = { key: K; prev: LNode | null; next: LNode | null };\n\tconst map = new Map<K, LNode>();\n\tlet head: LNode | null = null;\n\tlet tail: LNode | null = null;\n\n\tfunction unlink(n: LNode): void {\n\t\tif (n.prev) n.prev.next = n.next;\n\t\telse head = n.next;\n\t\tif (n.next) n.next.prev = n.prev;\n\t\telse tail = n.prev;\n\t\tn.prev = null;\n\t\tn.next = null;\n\t}\n\n\tfunction pushFront(n: LNode): void {\n\t\tn.next = head;\n\t\tn.prev = null;\n\t\tif (head) head.prev = n;\n\t\thead = n;\n\t\tif (tail === null) tail = n;\n\t}\n\n\treturn {\n\t\tinsert(key: K): void {\n\t\t\tif (map.has(key)) {\n\t\t\t\tthis.touch(key);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst n: LNode = { key, prev: null, next: null };\n\t\t\tmap.set(key, n);\n\t\t\tpushFront(n);\n\t\t},\n\t\ttouch(key: K): void {\n\t\t\tconst n = map.get(key);\n\t\t\tif (!n) return;\n\t\t\tunlink(n);\n\t\t\tpushFront(n);\n\t\t},\n\t\tdelete(key: K): void {\n\t\t\tconst n = map.get(key);\n\t\t\tif (!n) return;\n\t\t\tunlink(n);\n\t\t\tmap.delete(key);\n\t\t},\n\t\tevict(count: number): K[] {\n\t\t\tconst victims: K[] = [];\n\t\t\tfor (let i = 0; i < count && tail !== null; i++) {\n\t\t\t\tconst n = tail;\n\t\t\t\tvictims.push(n.key);\n\t\t\t\tunlink(n);\n\t\t\t\tmap.delete(n.key);\n\t\t\t}\n\t\t\treturn victims;\n\t\t},\n\t\tsize(): number {\n\t\t\treturn map.size;\n\t\t},\n\t};\n}\n\n// ——————————————————————————————————————————————————————————————\n// CascadingCache\n// ——————————————————————————————————————————————————————————————\n\nexport interface CascadingCacheOptions {\n\t/** Max entries before eviction. 0 = unlimited (default). */\n\tmaxSize?: number;\n\t/** Eviction policy. Default: LRU. Only used when maxSize > 0. */\n\teviction?: CacheEvictionPolicy<string>;\n\t/** Write-through: save() writes to all tiers, not just tier 0. Default: false. */\n\twriteThrough?: boolean;\n}\n\nexport interface CascadingCache<V> {\n\t/** Get or create a singleton state node for this key. Cascades tiers on miss. */\n\tload(key: string): Node<V | undefined>;\n\t/** Write value to tier(s) and update cache node in-place. */\n\tsave(key: string, value: V): void;\n\t/** Re-cascade tiers into the existing cache node (subscribers see the update). */\n\tinvalidate(key: string): void;\n\t/** Remove from all tiers, teardown the node, and delete cache entry. */\n\tdelete(key: string): void;\n\t/** Check if key exists in cache map. */\n\thas(key: string): boolean;\n\t/** Number of cached entries. */\n\treadonly size: number;\n}\n\nfunction isPromiseLike(v: unknown): v is Promise<unknown> {\n\treturn v != null && typeof (v as Promise<unknown>).then === \"function\";\n}\n\nfunction fireAndForget(result: void | Promise<void>): void {\n\tif (isPromiseLike(result)) {\n\t\t(result as Promise<void>).catch(() => {\n\t\t\t/* ignore — users opt into onError via attachStorage, not cache */\n\t\t});\n\t}\n}\n\n/**\n * Creates a singleton reactive cache with N-tier cascading lookup.\n *\n * Each cached entry is a `state()` node. On cache miss, tiers are tried in order\n * (index 0 = hottest/fastest). When a lower tier hits, the value is auto-promoted\n * to all faster tiers. Concurrent loads for the same key share the same state\n * instance — natural dedup.\n *\n * **Sync vs async tiers:** if `tier.load` returns a plain value, the cache node\n * cache is populated synchronously (`c.load(\"k\").cache` is readable immediately).\n * If it returns a `Promise`, the node emits `DATA` when the promise resolves.\n *\n * **Miss sentinel:** `undefined` and `null` are both treated as misses — the\n * cascade continues to the next tier.\n *\n * @param tiers - Ordered lookup tiers, hottest first.\n * @param opts - Optional configuration (maxSize, eviction policy, writeThrough).\n * @returns A reactive cache where each entry is a `Node<V | undefined>`.\n *\n * @example\n * ```ts\n * import { cascadingCache, memoryStorage, fileStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * const cache = cascadingCache<User>([memoryStorage(), fileStorage(\"./cache\")]);\n * const user = cache.load(\"user:42\"); // Node<User | undefined>\n * user.subscribe(msgs => console.log(msgs));\n * ```\n *\n * @category extra\n */\nexport function cascadingCache<V = unknown>(\n\ttiers: readonly StorageTier[],\n\topts?: CascadingCacheOptions,\n): CascadingCache<V> {\n\tconst entries = new Map<string, Node<V | undefined>>();\n\tconst maxSize = opts?.maxSize ?? 0;\n\tconst policy = maxSize > 0 ? (opts?.eviction ?? lru<string>()) : null;\n\tconst writeThrough = opts?.writeThrough ?? false;\n\n\tfunction promote(key: string, value: V, hitTierIndex: number): void {\n\t\tfor (let i = 0; i < hitTierIndex; i++) {\n\t\t\ttry {\n\t\t\t\tfireAndForget(tiers[i]!.save(key, value));\n\t\t\t} catch {\n\t\t\t\t/* ignore promote failures — cache still serves this request */\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Cascade from `startTier` onward. Sync tiers resolve inline; async tiers\n\t * yield control via Promise chaining and recurse on miss. Both paths end\n\t * by emitting `[[DATA, value]]` on `nd` and promoting to faster tiers.\n\t */\n\tfunction cascade(key: string, nd: Node<V | undefined>, startTier = 0): void {\n\t\tfor (let tierIndex = startTier; tierIndex < tiers.length; tierIndex++) {\n\t\t\tlet result: unknown;\n\t\t\ttry {\n\t\t\t\tresult = tiers[tierIndex]!.load(key);\n\t\t\t} catch {\n\t\t\t\tcontinue; // sync throw — next tier\n\t\t\t}\n\t\t\tif (isPromiseLike(result)) {\n\t\t\t\tconst captured = tierIndex;\n\t\t\t\t(result as Promise<unknown>).then(\n\t\t\t\t\t(val) => {\n\t\t\t\t\t\tif (val !== undefined && val !== null) {\n\t\t\t\t\t\t\tnd.down([[DATA, val]]);\n\t\t\t\t\t\t\tpromote(key, val as V, captured);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcascade(key, nd, captured + 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t() => {\n\t\t\t\t\t\tcascade(key, nd, captured + 1);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\treturn; // async branch continues the cascade\n\t\t\t}\n\t\t\tif (result !== undefined && result !== null) {\n\t\t\t\tnd.down([[DATA, result]]);\n\t\t\t\tpromote(key, result as V, tierIndex);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\t// all tiers missed — value stays undefined\n\t}\n\n\tfunction evictIfNeeded(): void {\n\t\tif (!policy || maxSize <= 0) return;\n\t\twhile (policy.size() >= maxSize) {\n\t\t\tconst victims = policy.evict(1);\n\t\t\tif (victims.length === 0) break;\n\t\t\tfor (const key of victims) {\n\t\t\t\tconst nd = entries.get(key);\n\t\t\t\tif (nd) {\n\t\t\t\t\tconst value = nd.cache;\n\t\t\t\t\tif (nd.status !== \"sentinel\" && tiers.length > 0) {\n\t\t\t\t\t\t// Demote to last tier, clear faster tiers.\n\t\t\t\t\t\tconst lastIndex = tiers.length - 1;\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tfireAndForget(tiers[lastIndex]!.save(key, value as V));\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t/* ignore */\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (let j = 0; j < lastIndex; j++) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst clearFn = tiers[j]!.clear;\n\t\t\t\t\t\t\t\tif (clearFn) fireAndForget(clearFn.call(tiers[j], key));\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\t/* ignore */\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\tnd.down([[TEARDOWN]]);\n\t\t\t\t}\n\t\t\t\tentries.delete(key);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tload(key: string): Node<V | undefined> {\n\t\t\tconst existing = entries.get(key);\n\t\t\tif (existing) {\n\t\t\t\tpolicy?.touch(key);\n\t\t\t\treturn existing;\n\t\t\t}\n\t\t\tif (policy && maxSize > 0 && policy.size() >= maxSize) {\n\t\t\t\tevictIfNeeded();\n\t\t\t}\n\t\t\tconst nd = state<V | undefined>(undefined);\n\t\t\tentries.set(key, nd);\n\t\t\tpolicy?.insert(key);\n\t\t\tcascade(key, nd);\n\t\t\treturn nd;\n\t\t},\n\n\t\tsave(key: string, value: V): void {\n\t\t\tif (writeThrough) {\n\t\t\t\tfor (const tier of tiers) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfireAndForget(tier.save(key, value));\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t/* ignore */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (tiers[0]) {\n\t\t\t\ttry {\n\t\t\t\t\tfireAndForget(tiers[0].save(key, value));\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore */\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst existing = entries.get(key);\n\t\t\tif (existing) {\n\t\t\t\texisting.down([[DATA, value]]);\n\t\t\t\tpolicy?.touch(key);\n\t\t\t} else {\n\t\t\t\tif (policy && maxSize > 0 && policy.size() >= maxSize) {\n\t\t\t\t\tevictIfNeeded();\n\t\t\t\t}\n\t\t\t\tconst nd = state<V | undefined>(value);\n\t\t\t\tentries.set(key, nd);\n\t\t\t\tpolicy?.insert(key);\n\t\t\t}\n\t\t},\n\n\t\tinvalidate(key: string): void {\n\t\t\tconst existing = entries.get(key);\n\t\t\tif (existing) cascade(key, existing);\n\t\t},\n\n\t\tdelete(key: string): void {\n\t\t\tpolicy?.delete(key);\n\t\t\tconst nd = entries.get(key);\n\t\t\tif (nd) nd.down([[TEARDOWN]]);\n\t\t\tentries.delete(key);\n\t\t\tfor (const tier of tiers) {\n\t\t\t\ttry {\n\t\t\t\t\tconst clearFn = tier.clear;\n\t\t\t\t\tif (clearFn) fireAndForget(clearFn.call(tier, key));\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore */\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\thas(key: string): boolean {\n\t\t\treturn entries.has(key);\n\t\t},\n\n\t\tget size(): number {\n\t\t\treturn entries.size;\n\t\t},\n\t};\n}\n","/**\n * Reactive key–value map (roadmap §3.2) — emits `ReadonlyMap` snapshots directly.\n *\n * Internal version counter drives efficient equality without leaking `Versioned`\n * into the public API (spec §5.12).\n *\n * **Wave 4 refactor (2026-04-15):** Introduces the `MapBackend<K, V>` pluggable-backend\n * interface. The default `NativeMapBackend` owns LRU ordering, TTL expiry, and a\n * monotonic `version` counter. Reads that discover expired entries prune them and\n * emit (fixes the former `size`-getter stale-snapshot gap).\n */\nimport { batch } from \"../core/batch.js\";\nimport { monotonicNs } from \"../core/clock.js\";\nimport { DATA, DIRTY } from \"../core/messages.js\";\nimport type { Node, NodeOptions } from \"../core/node.js\";\nimport { state } from \"../core/sugar.js\";\nimport type { VersioningLevel } from \"../core/versioning.js\";\n\nexport type ReactiveMapOptions<K, V> = {\n\t/** Optional registry name for `describe()` / debugging. */\n\tname?: string;\n\t/**\n\t * LRU cap. When set, evicts least-recently-used keys after inserts that exceed this size.\n\t * Forwarded to the default `NativeMapBackend`. Ignored if a custom `backend` is provided.\n\t */\n\tmaxSize?: number;\n\t/**\n\t * Default TTL in seconds. Used when `set`/`setMany` omits per-call `ttl`.\n\t * Forwarded to the default `NativeMapBackend`. Ignored if a custom `backend` is provided.\n\t */\n\tdefaultTtl?: number;\n\t/**\n\t * Storage backend. Defaults to `NativeMapBackend`. Users can plug in persistent\n\t * (HAMT / Immutable.js) or shared-state backends via the {@link MapBackend} interface.\n\t */\n\tbackend?: MapBackend<K, V>;\n\t/**\n\t * Optional versioning level for the underlying `entries` state node. Set at\n\t * construction time; cannot be changed later. Pass `0` for V0 identity +\n\t * monotonic version counter, or `1` for V1 + content-addressed cid.\n\t */\n\tversioning?: VersioningLevel;\n} & Omit<NodeOptions, \"initial\" | \"describeKind\" | \"equals\" | \"versioning\">;\n\nexport type ReactiveMapBundle<K, V> = {\n\t/** Emits `ReadonlyMap<K, V>` on each structural change (two-phase). */\n\tentries: Node<ReadonlyMap<K, V>>;\n\t/**\n\t * Checks existence. O(1) for live keys. If the key is expired, prunes it AND\n\t * emits a snapshot so the reactive surface stays consistent with the return\n\t * value. Reads on expired keys are therefore **observable side effects**.\n\t *\n\t * **LRU touch (F4):** When `maxSize` is configured, a live-key `has` also\n\t * marks the entry as most-recently-used — which rearranges internal insertion\n\t * order without bumping `version` or emitting. If you care about iteration\n\t * order in a downstream subscriber, rely on the `entries` snapshot (a fresh\n\t * `ReadonlyMap` per mutation) rather than iterating the backend directly.\n\t */\n\thas: (key: K) => boolean;\n\t/**\n\t * Gets value. O(1) for live keys. If the key is expired, prunes it AND emits\n\t * a snapshot. Reads on expired keys are therefore **observable side effects**.\n\t *\n\t * **LRU touch (F4):** When `maxSize` is configured, a live-key `get` also\n\t * marks the entry as most-recently-used (no version bump, no emission). See\n\t * `has` for the full note on iteration order.\n\t */\n\tget: (key: K) => V | undefined;\n\t/**\n\t * Sets value with optional TTL (seconds). Throws on `ttl <= 0`. Applies LRU eviction\n\t * if `maxSize` is set. Always emits.\n\t */\n\tset: (key: K, value: V, opts?: { ttl?: number }) => void;\n\t/**\n\t * Bulk set — emits one snapshot for the whole batch. Applies `opts.ttl` (falls back\n\t * to `defaultTtl`) to every entry. No-op if `entries` is empty.\n\t *\n\t * **Iterable consumption:** Consumes `entries` once (single-pass). Pass an array\n\t * or `Set` for multi-shot consumers. If the iterator throws mid-iteration,\n\t * entries already applied remain committed and a snapshot IS emitted (via the\n\t * wrapper's finally-block).\n\t */\n\tsetMany: (entries: Iterable<readonly [K, V]>, opts?: { ttl?: number }) => void;\n\tdelete: (key: K) => void;\n\t/**\n\t * Bulk delete — emits one snapshot. No-op if no keys were present.\n\t *\n\t * **Iterable consumption:** Consumes `keys` once (single-pass).\n\t */\n\tdeleteMany: (keys: Iterable<K>) => void;\n\tclear: () => void;\n\t/**\n\t * Current entry count — O(1), **pure read** (no emission). May include\n\t * expired entries on TTL maps until a mutation or explicit\n\t * `pruneExpired()` / `has(key)` / `get(key)` prunes them. Call\n\t * `pruneExpired()` first if you need a live count.\n\t */\n\treadonly size: number;\n\t/** Explicitly prunes all expired entries. Emits if any were removed. */\n\tpruneExpired: () => void;\n\t/**\n\t * Releases any internal keepalive subscriptions so the bundle can be\n\t * GC'd. `reactiveMap` currently holds none (the `entries` node lives only\n\t * as long as external subscribers keep it alive), so `dispose()` is a\n\t * no-op today — exposed for API parity with `reactiveIndex.dispose` /\n\t * `reactiveList.dispose` / `reactiveLog.dispose`. Idempotent. D6(a).\n\t */\n\tdispose: () => void;\n};\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link reactiveMap}. Implementations own the mutable state,\n * including optional TTL and LRU semantics, and expose a monotonic `version` counter\n * that increments on every change to visible state.\n *\n * The reactive layer reads `version` before and after each backend call; when it\n * advances, a snapshot is emitted. Reads (`has`, `get`) may internally prune the\n * target key if expired and advance `version` — in which case the layer emits so\n * subscribers see state consistent with the read's return value.\n *\n * @remarks Post-1.0 op-log changesets will extend this interface with a\n * `changesSince(version: number): Iterable<Change>` method. Current consumers\n * should treat all methods here as stable.\n *\n * @category extra\n */\nexport interface MapBackend<K, V> {\n\t/** Monotonic mutation counter; increments on every visible state change. */\n\treadonly version: number;\n\t/** Raw entry count (may include expired entries until a read / prune removes them). */\n\treadonly size: number;\n\t/** Checks existence. May prune target key if expired; advances `version` if pruned. */\n\thas(key: K): boolean;\n\t/** Gets value. May prune target key if expired; advances `version` if pruned. */\n\tget(key: K): V | undefined;\n\t/**\n\t * Sets a value with optional TTL (seconds). Throws `RangeError` if `ttl <= 0`.\n\t * Applies LRU eviction if `maxSize` is configured. Advances `version`.\n\t *\n\t * **Atomicity contract:** Either fully succeeds or throws before any state\n\t * change; `version` advances only on success.\n\t */\n\tset(key: K, value: V, ttl?: number): void;\n\t/**\n\t * Atomic bulk set. Pre-validates TTL once, then applies all entries. Advances\n\t * `version` at most once (even for N entries). No-op if iterable is empty.\n\t *\n\t * **Consumes `entries` once** — pass an array if you want repeatability.\n\t *\n\t * **Atomicity contract:** TTL validation throws before any mutation. If the\n\t * iterable itself throws mid-iteration, entries committed before the throw\n\t * remain persisted AND `version` is bumped once (surfaced via finally) so\n\t * the reactive wrapper emits a snapshot reflecting the partial state. \"At\n\t * most once\" invariant is preserved.\n\t */\n\tsetMany(entries: Iterable<readonly [K, V]>, ttl?: number): void;\n\t/** Removes a key. Returns `true` if the key existed. Advances `version` only if true. */\n\tdelete(key: K): boolean;\n\t/**\n\t * Atomic bulk delete. Returns count removed. Advances `version` at most once\n\t * (even for N keys). No-op if no keys were present. Consumes `keys` once.\n\t */\n\tdeleteMany(keys: Iterable<K>): number;\n\t/** Removes all entries. Returns count removed. Advances `version` only if non-zero. */\n\tclear(): number;\n\t/** Removes all expired entries. Returns count removed. Advances `version` only if non-zero. */\n\tpruneExpired(): number;\n\t/** Fresh snapshot of non-expired entries (does NOT mutate state). */\n\ttoMap(): ReadonlyMap<K, V>;\n}\n\nexport type NativeMapBackendOptions = {\n\tmaxSize?: number;\n\t/** Default TTL in seconds. */\n\tdefaultTtl?: number;\n};\n\ntype MapEntry<V> = { value: V; expiresAt?: number };\n\n/**\n * Default `Map<K, {value, expiresAt}>` backend with optional per-key TTL and LRU cap.\n *\n * **Complexity:**\n * - `has`, `get`, `delete`, `size`: O(1)\n * - `set`: O(1) amortized (LRU touch + eviction)\n * - `pruneExpired`, `toMap`: O(n)\n *\n * LRU order uses native `Map` insertion order. `get` / `has` on a live key \"touches\"\n * it by delete-then-reinsert (moving it to the end). This touch does NOT advance\n * `version` — it's an internal optimization; the externally visible snapshot\n * preserves iteration order as of the last mutation. **Note:** because touch\n * reorders the internal `_store` without emitting, an in-process consumer iterating\n * `_store` directly (custom subclasses) could observe changing order; external\n * subscribers only see `toMap()` snapshots which are defensively copied and stable.\n *\n * @category extra\n */\nexport class NativeMapBackend<K, V> implements MapBackend<K, V> {\n\tprivate _version = 0;\n\tprivate readonly _store = new Map<K, MapEntry<V>>();\n\tprivate readonly _maxSize?: number;\n\tprivate readonly _defaultTtl?: number;\n\n\tconstructor(options: NativeMapBackendOptions = {}) {\n\t\tconst { maxSize, defaultTtl } = options;\n\t\tif (maxSize !== undefined && maxSize < 1) {\n\t\t\tthrow new RangeError(\"maxSize must be >= 1\");\n\t\t}\n\t\tif (defaultTtl !== undefined && defaultTtl <= 0) {\n\t\t\tthrow new RangeError(\"defaultTtl must be positive\");\n\t\t}\n\t\tthis._maxSize = maxSize;\n\t\tthis._defaultTtl = defaultTtl;\n\t}\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget size(): number {\n\t\treturn this._store.size;\n\t}\n\n\thas(key: K): boolean {\n\t\tconst e = this._store.get(key);\n\t\tif (e === undefined) return false;\n\t\tif (this._isExpired(e)) {\n\t\t\tthis._store.delete(key);\n\t\t\tthis._version += 1;\n\t\t\treturn false;\n\t\t}\n\t\tthis._touchLru(key, e);\n\t\treturn true;\n\t}\n\n\tget(key: K): V | undefined {\n\t\tconst e = this._store.get(key);\n\t\tif (e === undefined) return undefined;\n\t\tif (this._isExpired(e)) {\n\t\t\tthis._store.delete(key);\n\t\t\tthis._version += 1;\n\t\t\treturn undefined;\n\t\t}\n\t\tthis._touchLru(key, e);\n\t\treturn e.value;\n\t}\n\n\tset(key: K, value: V, ttl?: number): void {\n\t\tconst expiresAt = this._resolveExpiresAt(ttl);\n\t\t// Delete-then-insert to place key at LRU end.\n\t\tif (this._store.has(key)) this._store.delete(key);\n\t\tthis._store.set(key, { value, expiresAt });\n\t\tthis._evictLruWhileOver();\n\t\tthis._version += 1;\n\t}\n\n\tsetMany(entries: Iterable<readonly [K, V]>, ttl?: number): void {\n\t\t// Pre-validate TTL once (throws before any mutation).\n\t\tconst expiresAt = this._resolveExpiresAt(ttl);\n\t\tlet count = 0;\n\t\ttry {\n\t\t\tfor (const [key, value] of entries) {\n\t\t\t\tif (this._store.has(key)) this._store.delete(key);\n\t\t\t\tthis._store.set(key, { value, expiresAt });\n\t\t\t\tcount += 1;\n\t\t\t}\n\t\t} finally {\n\t\t\t// D3: if the iterable threw mid-iteration, entries committed before\n\t\t\t// the throw must still advance `version` so subscribers see the\n\t\t\t// partial state consistently. \"At most once\" is preserved.\n\t\t\tif (count > 0) {\n\t\t\t\tthis._evictLruWhileOver();\n\t\t\t\tthis._version += 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tdelete(key: K): boolean {\n\t\tconst had = this._store.delete(key);\n\t\tif (had) this._version += 1;\n\t\treturn had;\n\t}\n\n\tdeleteMany(keys: Iterable<K>): number {\n\t\tlet removed = 0;\n\t\ttry {\n\t\t\tfor (const k of keys) {\n\t\t\t\tif (this._store.delete(k)) removed += 1;\n\t\t\t}\n\t\t} finally {\n\t\t\tif (removed > 0) this._version += 1;\n\t\t}\n\t\treturn removed;\n\t}\n\n\tclear(): number {\n\t\tconst n = this._store.size;\n\t\tif (n === 0) return 0;\n\t\tthis._store.clear();\n\t\tthis._version += 1;\n\t\treturn n;\n\t}\n\n\tpruneExpired(): number {\n\t\tconst now = monotonicNs();\n\t\tlet removed = 0;\n\t\tfor (const [k, e] of this._store) {\n\t\t\tif (this._isExpired(e, now)) {\n\t\t\t\tthis._store.delete(k);\n\t\t\t\tremoved += 1;\n\t\t\t}\n\t\t}\n\t\tif (removed > 0) this._version += 1;\n\t\treturn removed;\n\t}\n\n\ttoMap(): ReadonlyMap<K, V> {\n\t\tconst now = monotonicNs();\n\t\tconst out = new Map<K, V>();\n\t\tfor (const [k, e] of this._store) {\n\t\t\tif (!this._isExpired(e, now)) out.set(k, e.value);\n\t\t}\n\t\treturn out;\n\t}\n\n\tprivate _resolveExpiresAt(ttl?: number): number | undefined {\n\t\tconst effectiveTtl = ttl ?? this._defaultTtl;\n\t\tif (effectiveTtl === undefined) return undefined;\n\t\tif (!Number.isFinite(effectiveTtl) || effectiveTtl <= 0) {\n\t\t\tthrow new RangeError(\n\t\t\t\t`MapBackend: ttl must be a positive finite number (got ${effectiveTtl})`,\n\t\t\t);\n\t\t}\n\t\treturn monotonicNs() + effectiveTtl * 1_000_000_000;\n\t}\n\n\tprivate _isExpired(e: MapEntry<V>, now?: number): boolean {\n\t\tif (e.expiresAt === undefined) return false;\n\t\treturn (now ?? monotonicNs()) >= e.expiresAt;\n\t}\n\n\tprivate _touchLru(key: K, entry: MapEntry<V>): void {\n\t\t// Move to LRU end. Does NOT advance `version` — internal optimization.\n\t\tthis._store.delete(key);\n\t\tthis._store.set(key, entry);\n\t}\n\n\tprivate _evictLruWhileOver(): void {\n\t\tif (this._maxSize === undefined) return;\n\t\twhile (this._store.size > this._maxSize) {\n\t\t\tconst first = this._store.keys().next().value as K | undefined;\n\t\t\tif (first === undefined) break;\n\t\t\tthis._store.delete(first);\n\t\t}\n\t}\n}\n\n// ── Reactive wrapper ──────────────────────────────────────────────────────\n\n/**\n * Creates a reactive `Map` with optional per-key TTL and optional LRU max size.\n *\n * @param options - `name`, `maxSize`, `defaultTtl` (seconds), or custom `backend`.\n * @returns `ReactiveMapBundle` — imperative methods (`has`/`get`/`set`/`setMany`/`delete`/\n * `deleteMany`/`clear`/`pruneExpired`), reactive `entries` node, and O(1)-ish `size`.\n *\n * @remarks\n * **TTL:** Expiry is checked on `get`, `has`, `size`, `pruneExpired`, and before each\n * snapshot emission (expired keys are pruned first). Reads that discover expired keys\n * emit a snapshot so subscribers see state consistent with the read's return value.\n * There is no background timer; monotonic-clock expiry is immune to wall-clock changes.\n *\n * **LRU:** Uses native `Map` insertion order — `get` / `has` refreshes position via\n * delete-then-reinsert; under `maxSize` pressure the first key in iteration order is\n * evicted. LRU touching does NOT trigger emission (internal optimization).\n *\n * **Backend:** The default {@link NativeMapBackend} owns LRU/TTL. For persistent /\n * HAMT / shared-state semantics plug in a custom {@link MapBackend}. `maxSize` and\n * `defaultTtl` on the options object are only applied to the default backend — if\n * you supply `backend`, configure those on your backend directly.\n *\n * @example\n * ```ts\n * import { reactiveMap } from \"@graphrefly/graphrefly-ts\";\n *\n * const m = reactiveMap<string, number>({ name: \"cache\", maxSize: 100, defaultTtl: 60 });\n * m.set(\"x\", 1);\n * m.setMany([[\"y\", 2], [\"z\", 3]]);\n * m.entries.subscribe((msgs) => { console.log(msgs); });\n * ```\n *\n * @category extra\n */\nexport function reactiveMap<K, V>(options: ReactiveMapOptions<K, V> = {}): ReactiveMapBundle<K, V> {\n\tconst { name, maxSize, defaultTtl, versioning, backend: userBackend } = options;\n\tconst backend: MapBackend<K, V> =\n\t\tuserBackend ?? new NativeMapBackend<K, V>({ maxSize, defaultTtl });\n\n\tconst n = state<ReadonlyMap<K, V>>(backend.toMap(), {\n\t\tname,\n\t\tdescribeKind: \"state\",\n\t\tequals: (a, b) => a === b,\n\t\t...(versioning != null ? { versioning } : {}),\n\t});\n\n\tfunction pushSnapshot(): void {\n\t\tconst map = backend.toMap();\n\t\tbatch(() => {\n\t\t\tn.down([[DIRTY]]);\n\t\t\tn.down([[DATA, map]]);\n\t\t});\n\t}\n\n\t/**\n\t * Defense-in-depth emission guard: compares `version` before/after `op` and\n\t * emits a snapshot if advanced. Uses `try/finally` so partial-mutation state\n\t * from a custom non-atomic backend is still surfaced to subscribers if the\n\t * op throws mid-way (native backends are atomic by contract and won't trip\n\t * this path).\n\t */\n\tfunction wrapMutation<T>(op: () => T): T {\n\t\tconst prev = backend.version;\n\t\ttry {\n\t\t\treturn op();\n\t\t} finally {\n\t\t\tif (backend.version !== prev) pushSnapshot();\n\t\t}\n\t}\n\n\treturn {\n\t\tentries: n,\n\n\t\thas(key: K): boolean {\n\t\t\treturn wrapMutation(() => backend.has(key));\n\t\t},\n\n\t\tget(key: K): V | undefined {\n\t\t\treturn wrapMutation(() => backend.get(key));\n\t\t},\n\n\t\tset(key: K, value: V, opts?: { ttl?: number }): void {\n\t\t\twrapMutation(() => backend.set(key, value, opts?.ttl));\n\t\t},\n\n\t\tsetMany(entries: Iterable<readonly [K, V]>, opts?: { ttl?: number }): void {\n\t\t\twrapMutation(() => backend.setMany(entries, opts?.ttl));\n\t\t},\n\n\t\tdelete(key: K): void {\n\t\t\twrapMutation(() => backend.delete(key));\n\t\t},\n\n\t\tdeleteMany(keys: Iterable<K>): void {\n\t\t\twrapMutation(() => backend.deleteMany(keys));\n\t\t},\n\n\t\tclear(): void {\n\t\t\twrapMutation(() => backend.clear());\n\t\t},\n\n\t\tpruneExpired(): void {\n\t\t\twrapMutation(() => backend.pruneExpired());\n\t\t},\n\n\t\t/**\n\t\t * Current raw entry count — O(1), **pure read**. May include\n\t\t * not-yet-pruned expired entries on TTL maps until the next mutation\n\t\t * or an explicit `pruneExpired()` / `has` / `get` triggers a prune.\n\t\t *\n\t\t * Previously this getter ran `pruneExpired()` inline and emitted a\n\t\t * snapshot as a side effect — that violated spec §5.8 \"no\n\t\t * side-effectful reads\" and created a re-entrancy hazard when a\n\t\t * subscriber to `entries` read `.size` from its own callback. D2(a).\n\t\t *\n\t\t * For a live count that excludes expired entries, call\n\t\t * `bundle.pruneExpired()` first.\n\t\t */\n\t\tget size(): number {\n\t\t\treturn backend.size;\n\t\t},\n\n\t\tdispose(): void {\n\t\t\t// D6(a): no internal keepalives yet — no-op for API parity with\n\t\t\t// reactive-index / reactive-list / reactive-log. If a future\n\t\t\t// refactor adds a keepalive (e.g. on `entries`), wire its\n\t\t\t// disposer here.\n\t\t},\n\t};\n}\n","/**\n * Composite data patterns (roadmap §3.2b).\n *\n * These helpers compose existing primitives (`node`, `switchMap`, `reactiveMap`,\n * `dynamicNode`, `fromAny`) without introducing new protocol semantics.\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { DATA } from \"../core/messages.js\";\nimport type { Node, NodeOptions } from \"../core/node.js\";\nimport { derived, state } from \"../core/sugar.js\";\nimport { merge, switchMap } from \"./operators.js\";\nimport { type ReactiveMapBundle, type ReactiveMapOptions, reactiveMap } from \"./reactive-map.js\";\nimport { forEach, fromAny, type NodeInput } from \"./sources.js\";\n\nfunction isNodeLike<T>(value: unknown): value is Node<T> {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"cache\" in (value as Node<T>) &&\n\t\ttypeof (value as Node<T>).subscribe === \"function\"\n\t);\n}\n\n/**\n * Verification payload shape is intentionally user-defined.\n */\nexport type VerifyValue = unknown;\n\nexport type VerifiableOptions<TVerify = VerifyValue> = Omit<\n\tNodeOptions,\n\t\"describeKind\" | \"initial\"\n> & {\n\t/** Reactive re-verification trigger. */\n\ttrigger?: NodeInput<unknown>;\n\t/** Re-run verification whenever `source` settles. */\n\tautoVerify?: boolean;\n\t/** Initial verification companion value. */\n\tinitialVerified?: TVerify | null;\n};\n\nexport type VerifiableBundle<T, TVerify = VerifyValue> = {\n\t/** Coerced source node. */\n\tnode: Node<T>;\n\t/** Latest verification result (`null` before first verification). */\n\tverified: Node<TVerify | null>;\n\t/** Effective trigger node used for verification, if any. */\n\ttrigger: Node<unknown> | null;\n};\n\n/**\n * Composes a value node with a reactive verification companion.\n *\n * Uses `switchMap` so newer triggers cancel stale in-flight verification work.\n */\nexport function verifiable<T, TVerify = VerifyValue>(\n\tsource: NodeInput<T>,\n\tverifyFn: (value: T) => NodeInput<TVerify>,\n\topts?: VerifiableOptions<TVerify>,\n): VerifiableBundle<T, TVerify> {\n\tconst sourceNode = fromAny(source);\n\tconst hasSourceVersioning = sourceNode.v != null;\n\tconst verified = state<TVerify | null>(opts?.initialVerified ?? null, {\n\t\t...(hasSourceVersioning ? { meta: { sourceVersion: null } } : {}),\n\t});\n\tconst hasTrigger = opts?.trigger !== undefined && opts.trigger !== null;\n\n\tlet triggerNode: Node<unknown> | null = null;\n\tif (hasTrigger && opts?.autoVerify) {\n\t\ttriggerNode = merge(fromAny(opts.trigger) as Node<unknown>, sourceNode as Node<unknown>);\n\t} else if (hasTrigger) {\n\t\ttriggerNode = fromAny(opts.trigger);\n\t} else if (opts?.autoVerify) {\n\t\ttriggerNode = sourceNode as Node<unknown>;\n\t}\n\n\tif (triggerNode !== null) {\n\t\t// Closes P3 audit #2. Two patterns used depending on trigger shape:\n\t\t// - autoVerify-only (triggerNode === sourceNode): the projected\n\t\t// switchMap value IS the source DATA, pass it directly.\n\t\t// - explicit trigger: capture the source value into a closure\n\t\t// (`latestSource`) seeded from `sourceNode.cache` at wiring time\n\t\t// (§3.6 boundary read) and kept current via a subscribe handler.\n\t\t// The switchMap fn reads the closure, never `sourceNode.cache`\n\t\t// from a reactive context.\n\t\tlet verifyStream: Node<TVerify>;\n\t\tif (triggerNode === (sourceNode as Node<unknown>)) {\n\t\t\tverifyStream = switchMap(sourceNode, (src) => verifyFn(src as T));\n\t\t} else {\n\t\t\tlet latestSource: T | undefined = sourceNode.cache as T | undefined;\n\t\t\tsourceNode.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) latestSource = m[1] as T;\n\t\t\t\t}\n\t\t\t});\n\t\t\tverifyStream = switchMap(triggerNode, () => verifyFn(latestSource as T));\n\t\t}\n\t\tforEach(verifyStream, (value) => {\n\t\t\tbatch(() => {\n\t\t\t\tverified.down([[DATA, value]]);\n\t\t\t\t// V0 backfill: stamp which source version was verified (§6.0b).\n\t\t\t\tif (hasSourceVersioning) {\n\t\t\t\t\tconst sv = sourceNode.v;\n\t\t\t\t\tif (sv != null) {\n\t\t\t\t\t\tverified.meta.sourceVersion.down([[DATA, { id: sv.id, version: sv.version }]]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\treturn { node: sourceNode, verified, trigger: triggerNode };\n}\n\nexport type Extraction<TMem> = {\n\tupsert: Array<{ key: string; value: TMem }>;\n\tremove?: string[];\n};\n\nexport type DistillOptions<TMem> = {\n\tscore: (mem: TMem, context: unknown) => number;\n\tcost: (mem: TMem) => number;\n\tbudget?: number;\n\tevict?: (key: string, mem: TMem) => boolean | Node<boolean>;\n\tconsolidate?: (entries: ReadonlyMap<string, TMem>) => NodeInput<Extraction<TMem>>;\n\tconsolidateTrigger?: NodeInput<unknown>;\n\tcontext?: NodeInput<unknown>;\n\tmapOptions?: ReactiveMapOptions<string, TMem>;\n};\n\nexport type DistillBundle<TMem> = {\n\tstore: ReactiveMapBundle<string, TMem>;\n\tcompact: Node<Array<{ key: string; value: TMem; score: number }>>;\n\tsize: Node<number>;\n};\n\nfunction keepalive(node: Node): void {\n\tnode.subscribe(() => undefined);\n}\n\nfunction mapFromSnapshot<TMem>(snapshot: unknown): ReadonlyMap<string, TMem> {\n\tif (snapshot instanceof Map) return snapshot as ReadonlyMap<string, TMem>;\n\treturn new Map<string, TMem>();\n}\n\nfunction applyExtraction<TMem>(\n\tstore: ReactiveMapBundle<string, TMem>,\n\textraction: Extraction<TMem>,\n): void {\n\tif (!Array.isArray(extraction.upsert)) {\n\t\tthrow new TypeError(\"distill extraction requires upsert: Array<{ key, value }>\");\n\t}\n\tbatch(() => {\n\t\tfor (const { key, value } of extraction.upsert) {\n\t\t\tstore.set(key, value);\n\t\t}\n\t\tfor (const key of extraction.remove ?? []) {\n\t\t\tstore.delete(key);\n\t\t}\n\t});\n}\n\n/**\n * Budget-constrained reactive memory composition.\n */\nexport function distill<TRaw, TMem>(\n\tsource: NodeInput<TRaw>,\n\textractFn: (raw: TRaw, existing: ReadonlyMap<string, TMem>) => NodeInput<Extraction<TMem>>,\n\topts: DistillOptions<TMem>,\n): DistillBundle<TMem> {\n\tconst sourceNode = fromAny(source);\n\tconst store = reactiveMap<string, TMem>(opts.mapOptions ?? {});\n\tconst budget = opts.budget ?? 2000;\n\tconst hasContext = opts.context !== undefined && opts.context !== null;\n\tconst contextNode = hasContext ? fromAny(opts.context) : state<unknown>(null);\n\n\t// Closes P3 audit #7. `latestStore` is seeded at wiring time (§3.6\n\t// boundary read) and kept current via a subscribe handler. `extractFn`\n\t// and `consolidate` read the closure, never `store.entries.cache` from\n\t// inside a reactive callback. `withLatestFrom` would swallow the initial\n\t// source emission because primary's push-on-subscribe fires before\n\t// secondary subscribes — same reason stratify/budgetGate use this pattern.\n\tlet latestStore: ReadonlyMap<string, TMem> = mapFromSnapshot<TMem>(store.entries.cache);\n\tstore.entries.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA) latestStore = mapFromSnapshot<TMem>(m[1]);\n\t\t}\n\t});\n\n\tconst extractionStream = switchMap(sourceNode, (raw) => extractFn(raw as TRaw, latestStore));\n\tforEach(extractionStream, (extraction) => {\n\t\tapplyExtraction(store, extraction);\n\t});\n\n\tif (opts.evict) {\n\t\t// Track active verdict-node subscriptions so we can react to Node<boolean> changes.\n\t\tconst verdictUnsubs = new Map<string, () => void>();\n\n\t\tconst evictionKeys = derived([store.entries], ([snapshot]) => {\n\t\t\tconst out: string[] = [];\n\t\t\tconst entries = mapFromSnapshot<TMem>(snapshot);\n\t\t\t// Clean up verdict subscriptions for removed keys.\n\t\t\tfor (const key of verdictUnsubs.keys()) {\n\t\t\t\tif (!entries.has(key)) {\n\t\t\t\t\tverdictUnsubs.get(key)!();\n\t\t\t\t\tverdictUnsubs.delete(key);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const [key, mem] of entries) {\n\t\t\t\tconst verdict = opts.evict!(key, mem);\n\t\t\t\tif (isNodeLike<boolean>(verdict)) {\n\t\t\t\t\t// Subscribe if not already — push-on-subscribe fires with\n\t\t\t\t\t// the verdict's current value on first subscribe, so an\n\t\t\t\t\t// already-true verdict deletes via the callback without\n\t\t\t\t\t// needing a `verdict.cache` read (closes P3 audit #3).\n\t\t\t\t\t// Future transitions to `true` flow through the same path.\n\t\t\t\t\tif (!verdictUnsubs.has(key)) {\n\t\t\t\t\t\tconst unsub = forEach(verdict, (val) => {\n\t\t\t\t\t\t\tif (val === true && store.has(key)) {\n\t\t\t\t\t\t\t\tstore.delete(key);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\tverdictUnsubs.set(key, unsub);\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (typeof verdict === \"boolean\") {\n\t\t\t\t\tif (verdict) out.push(key);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new TypeError(\"distill evict() must return boolean or Node<boolean>\");\n\t\t\t}\n\t\t\treturn out;\n\t\t});\n\t\tforEach(evictionKeys, (keys) => {\n\t\t\tfor (const key of keys) store.delete(key);\n\t\t});\n\t}\n\n\tconst hasConsolidateTrigger =\n\t\topts.consolidateTrigger !== undefined && opts.consolidateTrigger !== null;\n\tif (opts.consolidate && hasConsolidateTrigger) {\n\t\tconst consolidateTriggerNode = fromAny(opts.consolidateTrigger);\n\t\tconst consolidationStream = switchMap(consolidateTriggerNode, () =>\n\t\t\topts.consolidate!(latestStore),\n\t\t);\n\t\tforEach(consolidationStream, (extraction) => {\n\t\t\tapplyExtraction(store, extraction);\n\t\t});\n\t}\n\n\tconst compact = derived([store.entries, contextNode], ([snapshot, context]) => {\n\t\tconst entries = [...mapFromSnapshot<TMem>(snapshot).entries()].map(([key, value]) => ({\n\t\t\tkey,\n\t\t\tvalue,\n\t\t\tscore: opts.score(value, context),\n\t\t\tcost: opts.cost(value),\n\t\t}));\n\t\tentries.sort((a, b) => b.score - a.score);\n\n\t\tconst packed: Array<{ key: string; value: TMem; score: number }> = [];\n\t\tlet remaining = budget;\n\t\tfor (const item of entries) {\n\t\t\tif (item.cost <= remaining) {\n\t\t\t\tpacked.push({ key: item.key, value: item.value, score: item.score });\n\t\t\t\tremaining -= item.cost;\n\t\t\t}\n\t\t}\n\t\treturn packed;\n\t});\n\n\tconst size = derived([store.entries], ([snapshot]) => mapFromSnapshot<TMem>(snapshot).size);\n\tkeepalive(compact);\n\tkeepalive(size);\n\n\treturn { store, compact, size };\n}\n","// ---------------------------------------------------------------------------\n// RxJS bridge — reactive interop between GraphReFly nodes and RxJS Observables.\n// ---------------------------------------------------------------------------\n// Usage:\n// import { toObservable } from '@graphrefly/graphrefly-ts/extra';\n// const values$ = toObservable(myNode); // Observable<T>\n// const msgs$ = toObservable(myNode, { raw: true }); // Observable<Messages>\n// ---------------------------------------------------------------------------\n\nimport { Observable } from \"rxjs\";\nimport { COMPLETE, DATA, ERROR, type Messages } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\n\n/** Options for {@link toObservable}. */\nexport type ToObservableOptions = {\n\t/**\n\t * When `true`, emit raw `Messages` batches instead of extracted `DATA` values.\n\t * Terminal batches are still emitted as the final `next()` before the\n\t * Observable signal (error/complete).\n\t */\n\traw?: boolean;\n};\n\n/**\n * Bridge a `Node<T>` to an RxJS `Observable`.\n *\n * Default mode emits the node's value on each `DATA` message. Maps `ERROR` to\n * `subscriber.error()` and `COMPLETE` to `subscriber.complete()`.\n * Protocol-internal signals (DIRTY, RESOLVED, PAUSE, etc.) are skipped.\n *\n * With `{ raw: true }`, emits full `[[Type, Data?], ...]` message batches.\n * The Observable terminates on ERROR or COMPLETE (the terminal batch is still\n * emitted as the final `next()` before the Observable signal).\n *\n * For graph-level observation, use `toObservable(graph.resolve(path))` or\n * subscribe to `graph.observe()` directly.\n *\n * Unsubscribing the Observable unsubscribes the node.\n */\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions & { raw?: false },\n): Observable<T>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions: ToObservableOptions & { raw: true },\n): Observable<Messages>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions,\n): Observable<T | Messages> {\n\tif (options?.raw) {\n\t\treturn new Observable<Messages>((subscriber) => {\n\t\t\tconst unsub = node.subscribe((msgs) => {\n\t\t\t\tif (subscriber.closed) return;\n\t\t\t\tsubscriber.next(msgs);\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\t\tsubscriber.error(m[1]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\t\tsubscriber.complete();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn unsub;\n\t\t});\n\t}\n\n\treturn new Observable<T>((subscriber) => {\n\t\tconst unsub = node.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (subscriber.closed) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tsubscriber.next(m[1] as T);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tsubscriber.error(m[1]);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tsubscriber.complete();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn unsub;\n\t});\n}\n","/**\n * Lazy per-topic state hub (roadmap §3.2) — lightweight last-value broadcasts.\n *\n * Each topic is a sentinel `node<unknown>()` with push-on-subscribe replay of\n * the most recent published value (no push until the first `publish`). For\n * Pulsar-inspired retained message logs,\n * cursor-based subscriptions, and job-queue semantics, use `messagingHub()` in\n * `patterns/messaging.ts` — built on `TopicGraph` / `SubscriptionGraph` with\n * retention policies, absolute cursor tracking, and per-subscriber state.\n *\n * **Wave 4 refactor (2026-04-15):** Introduces `PubSubBackend` (thin registry\n * with version counter). Converts class-based hub to closure factory for\n * consistency with other `extra/` factories. New bundle APIs: `has(name)`,\n * `size`, `topicNames()`, `publishMany(entries)`. `removeTopic` → `TEARDOWN`\n * semantics preserved.\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { TEARDOWN } from \"../core/messages.js\";\nimport { type Node, node } from \"../core/node.js\";\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link pubsub} — registry only.\n *\n * Tracks the set of topic names plus a monotonic `version` counter that\n * advances on topic create/remove. Does NOT own per-topic message storage —\n * per-topic cached last values live in the topic nodes themselves (sentinel\n * until the first publish).\n *\n * For distributed / persistent per-topic storage, use `messagingHub()` in\n * `patterns/messaging.ts`, which composes `TopicGraph` under a lazy registry.\n *\n * @category extra\n */\nexport interface PubSubBackend {\n\t/** Monotonic counter; advances on topic create/remove. */\n\treadonly version: number;\n\treadonly topicCount: number;\n\thasTopic(name: string): boolean;\n\ttopicNames(): IterableIterator<string>;\n\t/** Records topic creation. Returns `true` if newly added (advances `version`). */\n\tcreateTopic(name: string): boolean;\n\t/** Records topic removal. Returns `true` if it existed (advances `version`). */\n\tremoveTopic(name: string): boolean;\n}\n\n/**\n * Default in-memory registry backend.\n *\n * @category extra\n */\nexport class NativePubSubBackend implements PubSubBackend {\n\tprivate _version = 0;\n\tprivate readonly _topics = new Set<string>();\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget topicCount(): number {\n\t\treturn this._topics.size;\n\t}\n\n\thasTopic(name: string): boolean {\n\t\treturn this._topics.has(name);\n\t}\n\n\ttopicNames(): IterableIterator<string> {\n\t\treturn this._topics.values();\n\t}\n\n\tcreateTopic(name: string): boolean {\n\t\tif (this._topics.has(name)) return false;\n\t\tthis._topics.add(name);\n\t\tthis._version += 1;\n\t\treturn true;\n\t}\n\n\tremoveTopic(name: string): boolean {\n\t\tconst had = this._topics.delete(name);\n\t\tif (had) this._version += 1;\n\t\treturn had;\n\t}\n}\n\n// ── Hub ───────────────────────────────────────────────────────────────────\n\nexport type PubSubHubOptions = {\n\t/**\n\t * Storage backend. Defaults to `NativePubSubBackend`. Pluggable for audit /\n\t * monitoring / mirror-to-external-broker use cases.\n\t */\n\tbackend?: PubSubBackend;\n};\n\n/**\n * Lazy per-topic state hub. Topics are single-value sentinel nodes\n * with push-on-subscribe replay of the most recent publish.\n *\n * @category extra\n */\nexport interface PubSubHub {\n\t/**\n\t * Returns the topic node, creating it on first use.\n\t *\n\t * @param name - Topic key.\n\t * @returns `Node` whose value is the last published payload. Starts in\n\t * sentinel state — no push-on-subscribe until the first publish.\n\t */\n\ttopic(name: string): Node<unknown>;\n\t/** Publishes a value to the topic (lazily creating the topic if missing). */\n\tpublish(name: string, value: unknown): void;\n\t/**\n\t * Bulk publish — single outer batch for all entries. No-op if empty.\n\t *\n\t * **Iterable consumption (F6):** `entries` is consumed once (single-pass).\n\t * Pass an array or `Set` for multi-shot callers. Iteration happens INSIDE\n\t * the batch frame — if the iterator throws mid-way, the batch is discarded\n\t * and NO publishes are visible to subscribers (all-or-nothing within one\n\t * call).\n\t */\n\tpublishMany(entries: Iterable<[string, unknown]>): void;\n\t/** Removes a topic; sends `TEARDOWN` to its node. Returns `true` if it existed. */\n\tremoveTopic(name: string): boolean;\n\t/** Checks topic existence without creating. O(1). */\n\thas(name: string): boolean;\n\t/** Number of topics currently registered. O(1). */\n\treadonly size: number;\n\t/** Iterator over topic names. */\n\ttopicNames(): IterableIterator<string>;\n}\n\n/**\n * Creates a lazy per-topic state hub.\n *\n * @param options - Optional pluggable `backend` (defaults to `NativePubSubBackend`).\n * @returns Hub with lazy `topic()` / `publish()` / `publishMany()` / `removeTopic()` /\n * `has()` / `size` / `topicNames()`.\n *\n * @remarks\n * **Scope:** Each topic is a sentinel node — retains only the last published\n * value (no push-on-subscribe before the first publish). For Pulsar-inspired\n * retention + cursor reading, use\n * `messagingHub()` in `patterns/messaging.ts`.\n *\n * **`removeTopic`:** Sends `TEARDOWN` to the topic node; all subscribers receive\n * the TEARDOWN message. Subsequent `publish(name, value)` silently recreates the\n * topic with a fresh node — existing subscribers to the old node do NOT reconnect.\n *\n * @example\n * ```ts\n * import { pubsub } from \"@graphrefly/graphrefly-ts\";\n *\n * const hub = pubsub();\n * const t = hub.topic(\"events\");\n * t.subscribe((msgs) => console.log(msgs));\n * hub.publish(\"events\", { ok: true });\n * hub.publishMany([[\"events\", 1], [\"status\", \"ready\"]]);\n * ```\n *\n * @category extra\n */\nexport function pubsub(options: PubSubHubOptions = {}): PubSubHub {\n\tconst { backend: userBackend } = options;\n\tconst backend: PubSubBackend = userBackend ?? new NativePubSubBackend();\n\tconst nodes = new Map<string, Node<unknown>>();\n\n\tfunction ensureTopic(name: string): Node<unknown> {\n\t\tlet n = nodes.get(name);\n\t\tif (n === undefined) {\n\t\t\tn = node<unknown>({ describeKind: \"state\" });\n\t\t\tnodes.set(name, n);\n\t\t\tbackend.createTopic(name);\n\t\t}\n\t\treturn n;\n\t}\n\n\treturn {\n\t\ttopic(name: string): Node<unknown> {\n\t\t\treturn ensureTopic(name);\n\t\t},\n\n\t\tpublish(name: string, value: unknown): void {\n\t\t\t// P7: use emit() so the pipeline auto-prefixes DIRTY, runs equals\n\t\t\t// substitution (if user configured one on a custom topic node),\n\t\t\t// and produces the proper two-phase wave.\n\t\t\tensureTopic(name).emit(value);\n\t\t},\n\n\t\tpublishMany(entries: Iterable<[string, unknown]>): void {\n\t\t\t// P1: iterate INSIDE the batch so a mid-iteration throw is\n\t\t\t// contained by the batch frame (no partial-publish leak) and\n\t\t\t// memory stays bounded — no intermediate array from `[...entries]`.\n\t\t\tbatch(() => {\n\t\t\t\tfor (const [name, value] of entries) {\n\t\t\t\t\tensureTopic(name).emit(value);\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tremoveTopic(name: string): boolean {\n\t\t\tconst n = nodes.get(name);\n\t\t\tif (n === undefined) return false;\n\t\t\t// Delete from map + backend BEFORE sending TEARDOWN (P2). A\n\t\t\t// synchronous TEARDOWN handler that calls `hub.publish(name, v)`\n\t\t\t// would otherwise race: `ensureTopic` finds no entry, creates a\n\t\t\t// fresh node, backend records the re-creation — then the cleanup\n\t\t\t// below would delete the NEW node, leaking a subscriber on it.\n\t\t\tnodes.delete(name);\n\t\t\tbackend.removeTopic(name);\n\t\t\tn.down([[TEARDOWN]]);\n\t\t\treturn true;\n\t\t},\n\n\t\thas(name: string): boolean {\n\t\t\treturn backend.hasTopic(name);\n\t\t},\n\n\t\tget size(): number {\n\t\t\treturn backend.topicCount;\n\t\t},\n\n\t\ttopicNames(): IterableIterator<string> {\n\t\t\treturn backend.topicNames();\n\t\t},\n\t};\n}\n","/**\n * Dual-key sorted index (roadmap §3.2) — unique primary key, rows ordered by `(secondary, primary)`.\n *\n * Emits `readonly IndexRow[]` snapshots directly — no `Versioned` wrapper (spec §5.12).\n *\n * **Wave 4 pilot (2026-04-15):** Introduces the `IndexBackend<K, V>` pluggable-backend interface.\n * The default `NativeIndexBackend` maintains a parallel `Map<K, IndexRow>` for O(1) `has`/`get`\n * and eliminates the O(n) filter pass during `upsert`/`delete`. A monotonic `version` counter\n * on the backend tracks mutations — foundation for post-1.0 op-log changesets.\n */\nimport { batch } from \"../core/batch.js\";\nimport { DATA, DIRTY } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { derived, state } from \"../core/sugar.js\";\nimport type { VersioningLevel } from \"../core/versioning.js\";\n\nexport type IndexRow<K, V = unknown> = {\n\treadonly primary: K;\n\treadonly secondary: unknown;\n\treadonly value: V;\n};\n\nexport type ReactiveIndexOptions<K, V = unknown> = {\n\t/** Optional registry name for `describe()` / debugging. */\n\tname?: string;\n\t/**\n\t * Storage backend. Defaults to `NativeIndexBackend` (flat array + parallel `Map<K,IndexRow>`).\n\t * Users can plug in persistent / B-tree backends via the {@link IndexBackend} interface.\n\t */\n\tbackend?: IndexBackend<K, V>;\n\t/**\n\t * Optional versioning level for the underlying `ordered` state node. Set at\n\t * construction time; cannot be changed later. Pass `0` for V0 identity +\n\t * monotonic version counter, or `1` for V1 + content-addressed cid.\n\t * (The `byPrimary` derived node inherits through the dep graph.)\n\t */\n\tversioning?: VersioningLevel;\n\t/**\n\t * Default row-equality used to short-circuit idempotent upserts. When\n\t * provided, every `upsert` / `upsertMany` that finds an existing primary\n\t * compares the stored and candidate rows via `equals(existing, next)` —\n\t * on `true` the call is a no-op (no version bump, no emission). Per-call\n\t * `UpsertOptions.equals` overrides this default. Analogous to\n\t * `NodeOptions.equals` on the core `node()` primitive.\n\t */\n\tequals?: (existing: IndexRow<K, V>, next: IndexRow<K, V>) => boolean;\n};\n\nexport type ReactiveIndexBundle<K, V = unknown> = {\n\t/** Rows sorted by `(secondary, primary)`. */\n\treadonly ordered: Node<readonly IndexRow<K, V>[]>;\n\t/** Map from primary key to stored value. */\n\treadonly byPrimary: Node<ReadonlyMap<K, V>>;\n\t/** O(1) primary-key existence check. */\n\thas: (primary: K) => boolean;\n\t/** O(1) value lookup by primary key. */\n\tget: (primary: K) => V | undefined;\n\t/** Number of rows currently in the index (O(1)). */\n\treadonly size: number;\n\t/**\n\t * Upserts a row. When `opts.equals(existing, next)` returns `true` for an\n\t * existing primary key, the upsert is a no-op (no version bump, no emission).\n\t * Useful for idempotent writes.\n\t *\n\t * @returns `true` if a new row was inserted (primary key was absent),\n\t * `false` if the primary key was already present (updated in place OR\n\t * skipped idempotently via `opts.equals`). D5(a).\n\t */\n\tupsert: (primary: K, secondary: unknown, value: V, opts?: UpsertOptions<K, V>) => boolean;\n\t/**\n\t * Bulk upsert — emits one snapshot for the whole batch. `opts.equals` applied\n\t * per-row. No-op if empty or all rows skipped.\n\t *\n\t * **Iterable consumption:** Consumes `rows` once (single-pass).\n\t */\n\tupsertMany: (\n\t\trows: Iterable<{ primary: K; secondary: unknown; value: V }>,\n\t\topts?: UpsertOptions<K, V>,\n\t) => void;\n\tdelete: (primary: K) => void;\n\t/**\n\t * Bulk delete — emits one snapshot for the whole batch. No-op if nothing was removed.\n\t *\n\t * **Iterable consumption:** Consumes `primaries` once (single-pass).\n\t */\n\tdeleteMany: (primaries: Iterable<K>) => void;\n\tclear: () => void;\n\t/**\n\t * Releases internal keepalive subscriptions (on `byPrimary`) so the bundle\n\t * can be GC'd. Safe to call more than once (subsequent calls are no-ops).\n\t * Subsequent mutations after `dispose()` still execute on the backend but\n\t * `byPrimary` may stop updating if no external subscriber is attached.\n\t * D6(a).\n\t */\n\tdispose: () => void;\n};\n\n// ── Ordering ──────────────────────────────────────────────────────────────\n\n/** Lexicographic ordering for index keys (mirrors Python tuple compare for typical primitives). */\nfunction cmpOrd(a: unknown, b: unknown): number {\n\tif (a === b) return 0;\n\tconst ta = typeof a;\n\tconst tb = typeof b;\n\tif (ta === tb && (ta === \"number\" || ta === \"string\" || ta === \"boolean\" || ta === \"bigint\")) {\n\t\tconst ax = a as number | string | boolean | bigint;\n\t\tconst bx = b as number | string | boolean | bigint;\n\t\tif (ax < bx) return -1;\n\t\tif (ax > bx) return 1;\n\t\treturn 0;\n\t}\n\treturn String(a).localeCompare(String(b));\n}\n\nfunction compareKeys<K>(a: [unknown, K], b: [unknown, K]): number {\n\tconst c = cmpOrd(a[0], b[0]);\n\tif (c !== 0) return c;\n\treturn cmpOrd(a[1], b[1]);\n}\n\nfunction rowKey<K, V>(row: IndexRow<K, V>): [unknown, K] {\n\treturn [row.secondary, row.primary];\n}\n\nfunction bisectLeft<K, V>(rows: readonly IndexRow<K, V>[], row: IndexRow<K, V>): number {\n\tconst k = rowKey(row);\n\tlet lo = 0;\n\tlet hi = rows.length;\n\twhile (lo < hi) {\n\t\tconst mid = (lo + hi) >> 1;\n\t\tif (compareKeys(k, rowKey(rows[mid]!)) > 0) lo = mid + 1;\n\t\telse hi = mid;\n\t}\n\treturn lo;\n}\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link reactiveIndex}. Implementations own the mutable state and\n * expose a monotonic `version` counter that increments on every structural change.\n *\n * The reactive layer reads `version` to decide when to emit; it does not inspect\n * internal representation. Users can plug in B-tree / skip-list / persistent backends\n * without touching the reactive emission logic.\n *\n * @remarks Post-1.0 op-log changesets will extend this interface with a\n * `changesSince(version: number): Iterable<Change>` method. Current consumers\n * should treat all methods here as stable.\n *\n * @category extra\n */\n/**\n * Optional per-call options for {@link IndexBackend.upsert} and bulk upsert.\n *\n * @category extra\n */\nexport type UpsertOptions<K, V> = {\n\t/**\n\t * Skip the upsert if an existing row is considered equal to the proposed row.\n\t * Default: no skip — every upsert advances `version`. Provide for idempotent\n\t * keys (e.g., `(a, b) => a.secondary === b.secondary && a.value === b.value`).\n\t */\n\tequals?: (existing: IndexRow<K, V>, next: IndexRow<K, V>) => boolean;\n};\n\nexport interface IndexBackend<K, V = unknown> {\n\t/** Monotonic mutation counter; increments on every upsert/delete/clear that changes state. */\n\treadonly version: number;\n\t/** Number of rows currently stored. */\n\treadonly size: number;\n\t/** O(1) primary-key existence check. */\n\thas(primary: K): boolean;\n\t/** Value lookup by primary key. */\n\tget(primary: K): V | undefined;\n\t/**\n\t * Insert or replace a row. Returns `true` if a row was inserted (primary\n\t * didn't exist), `false` otherwise (updated OR skipped via `opts.equals`).\n\t *\n\t * **Atomicity contract:** Either fully succeeds or throws before any state\n\t * change; `version` advances only on state change.\n\t */\n\tupsert(primary: K, secondary: unknown, value: V, opts?: UpsertOptions<K, V>): boolean;\n\t/**\n\t * Atomic bulk upsert. Returns the number of rows that caused a state change\n\t * (inserts + non-skipped updates). Advances `version` at most once.\n\t * No-op if iterable is empty or all rows skipped by `opts.equals`.\n\t *\n\t * **Consumes `rows` once** — pass an array for multi-shot consumers.\n\t */\n\tupsertMany(\n\t\trows: Iterable<{ primary: K; secondary: unknown; value: V }>,\n\t\topts?: UpsertOptions<K, V>,\n\t): number;\n\t/** Remove a row by primary key. Returns `true` if the row existed. Advances `version` only if true. */\n\tdelete(primary: K): boolean;\n\t/**\n\t * Atomic bulk delete. Returns count removed. Advances `version` at most once.\n\t * No-op if no keys were present. Consumes `primaries` once.\n\t */\n\tdeleteMany(primaries: Iterable<K>): number;\n\t/** Remove all rows. Returns the number removed. Advances `version` only if non-zero. */\n\tclear(): number;\n\t/** Rows in sorted `(secondary, primary)` order — fresh snapshot suitable for emission. */\n\ttoArray(): readonly IndexRow<K, V>[];\n\t/** Primary-key → value map — fresh snapshot. */\n\ttoPrimaryMap(): ReadonlyMap<K, V>;\n}\n\n/**\n * Default flat-array backend. Maintains `buf: IndexRow[]` sorted by `(secondary, primary)`\n * and a parallel `Map<K, IndexRow>` for O(1) primary-key lookup.\n *\n * **Complexity:**\n * - `has`, `get`: O(1)\n * - `upsert`: up to 2× O(log n) bisect (locate old + locate new) + up to 2× O(n) splice (remove-old + insert-new) = O(n)\n * - `upsertMany(k rows)`: O(k log n) bisect + O(k·n) splice worst case; single version bump\n * - `delete`: O(log n) bisect + O(n) splice = O(n)\n * - `deleteMany(k keys)`: O(k log n) + O(k·n) splice worst case; single version bump\n * - `clear`: O(1)\n * - `toArray`, `toPrimaryMap`: O(n)\n *\n * @category extra\n */\nexport class NativeIndexBackend<K, V = unknown> implements IndexBackend<K, V> {\n\tprivate _version = 0;\n\tprivate readonly _buf: IndexRow<K, V>[] = [];\n\tprivate readonly _byPrimary = new Map<K, IndexRow<K, V>>();\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget size(): number {\n\t\treturn this._buf.length;\n\t}\n\n\thas(primary: K): boolean {\n\t\treturn this._byPrimary.has(primary);\n\t}\n\n\tget(primary: K): V | undefined {\n\t\treturn this._byPrimary.get(primary)?.value;\n\t}\n\n\tupsert(primary: K, secondary: unknown, value: V, opts?: UpsertOptions<K, V>): boolean {\n\t\tconst existing = this._byPrimary.get(primary);\n\t\tconst row: IndexRow<K, V> = { primary, secondary, value };\n\t\tif (existing !== undefined && opts?.equals?.(existing, row)) {\n\t\t\t// Idempotent — no state change, no version advance.\n\t\t\treturn false;\n\t\t}\n\t\tif (existing !== undefined) {\n\t\t\t// Remove from current sorted position via bisect on the stored row.\n\t\t\tconst oldPos = bisectLeft(this._buf, existing);\n\t\t\tthis._buf.splice(oldPos, 1);\n\t\t}\n\t\tconst newPos = bisectLeft(this._buf, row);\n\t\tthis._buf.splice(newPos, 0, row);\n\t\tthis._byPrimary.set(primary, row);\n\t\tthis._version += 1;\n\t\treturn existing === undefined;\n\t}\n\n\tupsertMany(\n\t\trows: Iterable<{ primary: K; secondary: unknown; value: V }>,\n\t\topts?: UpsertOptions<K, V>,\n\t): number {\n\t\tlet changed = 0;\n\t\ttry {\n\t\t\tfor (const r of rows) {\n\t\t\t\tconst existing = this._byPrimary.get(r.primary);\n\t\t\t\tconst row: IndexRow<K, V> = {\n\t\t\t\t\tprimary: r.primary,\n\t\t\t\t\tsecondary: r.secondary,\n\t\t\t\t\tvalue: r.value,\n\t\t\t\t};\n\t\t\t\tif (existing !== undefined && opts?.equals?.(existing, row)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (existing !== undefined) {\n\t\t\t\t\tconst oldPos = bisectLeft(this._buf, existing);\n\t\t\t\t\tthis._buf.splice(oldPos, 1);\n\t\t\t\t}\n\t\t\t\tconst newPos = bisectLeft(this._buf, row);\n\t\t\t\tthis._buf.splice(newPos, 0, row);\n\t\t\t\tthis._byPrimary.set(r.primary, row);\n\t\t\t\tchanged += 1;\n\t\t\t}\n\t\t} finally {\n\t\t\t// D3: surface partial commits on iterator throw; \"at most once\" preserved.\n\t\t\tif (changed > 0) this._version += 1;\n\t\t}\n\t\treturn changed;\n\t}\n\n\tdelete(primary: K): boolean {\n\t\tconst existing = this._byPrimary.get(primary);\n\t\tif (existing === undefined) return false;\n\t\tconst pos = bisectLeft(this._buf, existing);\n\t\tthis._buf.splice(pos, 1);\n\t\tthis._byPrimary.delete(primary);\n\t\tthis._version += 1;\n\t\treturn true;\n\t}\n\n\tdeleteMany(primaries: Iterable<K>): number {\n\t\tlet removed = 0;\n\t\ttry {\n\t\t\tfor (const primary of primaries) {\n\t\t\t\tconst existing = this._byPrimary.get(primary);\n\t\t\t\tif (existing === undefined) continue;\n\t\t\t\tconst pos = bisectLeft(this._buf, existing);\n\t\t\t\tthis._buf.splice(pos, 1);\n\t\t\t\tthis._byPrimary.delete(primary);\n\t\t\t\tremoved += 1;\n\t\t\t}\n\t\t} finally {\n\t\t\tif (removed > 0) this._version += 1;\n\t\t}\n\t\treturn removed;\n\t}\n\n\tclear(): number {\n\t\tconst n = this._buf.length;\n\t\tif (n === 0) return 0;\n\t\tthis._buf.length = 0;\n\t\tthis._byPrimary.clear();\n\t\tthis._version += 1;\n\t\treturn n;\n\t}\n\n\ttoArray(): readonly IndexRow<K, V>[] {\n\t\treturn [...this._buf];\n\t}\n\n\ttoPrimaryMap(): ReadonlyMap<K, V> {\n\t\tconst m = new Map<K, V>();\n\t\tfor (const r of this._buf) m.set(r.primary, r.value);\n\t\treturn m;\n\t}\n}\n\n// ── Reactive wrapper ──────────────────────────────────────────────────────\n\nfunction keepaliveDerived(n: Node<unknown>): () => void {\n\treturn n.subscribe(() => {});\n}\n\n/**\n * Creates a reactive index: unique primary key per row, rows sorted by `(secondary, primary)` for ordered scans.\n *\n * @param options - Optional `name` for `describe()` / debugging, and optional `backend` (see {@link IndexBackend}).\n * @returns Bundle with `ordered` (sorted rows), `byPrimary` (map), O(1) `has` / `get` / `size`,\n * imperative `upsert` / `upsertMany` / `delete` / `deleteMany` / `clear`.\n *\n * @remarks\n * **Ordering:** `secondary` and `primary` are compared via a small total order: same primitive `typeof` uses\n * numeric/string/boolean/bigint comparison; mixed or object keys fall back to `String(a).localeCompare(String(b))`\n * (not identical to Python's rich comparison for exotic types).\n *\n * **Backend:** The default {@link NativeIndexBackend} offers O(1) primary-key lookups and O(n) upserts.\n * For scale beyond a few thousand rows, supply a user-pluggable persistent/B-tree backend via the\n * `backend` option — reactive emission semantics are unchanged.\n *\n * @example\n * ```ts\n * import { reactiveIndex } from \"@graphrefly/graphrefly-ts\";\n *\n * const idx = reactiveIndex<string, string>();\n * idx.upsert(\"id1\", 10, \"row-a\");\n * idx.upsert(\"id2\", 5, \"row-b\");\n * ```\n *\n * @category extra\n */\nexport function reactiveIndex<K, V = unknown>(\n\toptions: ReactiveIndexOptions<K, V> = {},\n): ReactiveIndexBundle<K, V> {\n\tconst { name, versioning, equals: defaultEquals, backend: userBackend } = options;\n\tconst backend: IndexBackend<K, V> = userBackend ?? new NativeIndexBackend<K, V>();\n\n\t// F1 override: merge factory-level `equals` into per-call UpsertOptions\n\t// so callers who set it once at construction get idempotent-key semantics\n\t// on every upsert without repeating the predicate.\n\tfunction withDefaultEquals(opts?: UpsertOptions<K, V>): UpsertOptions<K, V> | undefined {\n\t\tif (opts?.equals !== undefined) return opts;\n\t\tif (defaultEquals === undefined) return opts;\n\t\treturn { ...opts, equals: defaultEquals };\n\t}\n\n\tconst ordered = state<readonly IndexRow<K, V>[]>([], {\n\t\tname,\n\t\tdescribeKind: \"state\",\n\t\tequals: (a, b) => a === b,\n\t\t...(versioning != null ? { versioning } : {}),\n\t});\n\n\tconst byPrimary = derived(\n\t\t[ordered],\n\t\t([s]) => {\n\t\t\tconst rows = s as readonly IndexRow<K, V>[];\n\t\t\tconst m = new Map<K, V>();\n\t\t\tfor (const r of rows) m.set(r.primary, r.value);\n\t\t\treturn m;\n\t\t},\n\t\t{ initial: backend.toPrimaryMap(), describeKind: \"derived\" },\n\t);\n\tconst disposeByPrimaryKeepalive = keepaliveDerived(byPrimary);\n\tlet disposed = false;\n\n\tfunction pushSnapshot(): void {\n\t\tconst snapshot = backend.toArray();\n\t\tbatch(() => {\n\t\t\tordered.down([[DIRTY]]);\n\t\t\tordered.down([[DATA, snapshot]]);\n\t\t});\n\t}\n\n\t/**\n\t * Defense-in-depth emission guard: compares `version` before/after `op` and\n\t * emits a snapshot if advanced. `try/finally` surfaces partial-mutation\n\t * state from non-atomic custom backends even on thrown ops; native backends\n\t * are atomic by contract and won't reach the finally with a changed version.\n\t */\n\tfunction wrapMutation<R>(op: () => R): R {\n\t\tconst prev = backend.version;\n\t\ttry {\n\t\t\treturn op();\n\t\t} finally {\n\t\t\tif (backend.version !== prev) pushSnapshot();\n\t\t}\n\t}\n\n\treturn {\n\t\tordered,\n\t\tbyPrimary,\n\n\t\thas(primary: K): boolean {\n\t\t\treturn backend.has(primary);\n\t\t},\n\n\t\tget(primary: K): V | undefined {\n\t\t\treturn backend.get(primary);\n\t\t},\n\n\t\tget size(): number {\n\t\t\treturn backend.size;\n\t\t},\n\n\t\tupsert(primary: K, secondary: unknown, value: V, opts?: UpsertOptions<K, V>): boolean {\n\t\t\treturn wrapMutation(() => backend.upsert(primary, secondary, value, withDefaultEquals(opts)));\n\t\t},\n\n\t\tupsertMany(\n\t\t\trows: Iterable<{ primary: K; secondary: unknown; value: V }>,\n\t\t\topts?: UpsertOptions<K, V>,\n\t\t): void {\n\t\t\t// Extra: materialize the iterable at the public wrapper so a\n\t\t\t// caller who passes (e.g.) `index.ordered.cache` as input can't\n\t\t\t// have the splice-during-iteration semantics observed by the\n\t\t\t// backend. The backend mutates `_buf` on each upsert; if `rows`\n\t\t\t// aliased `_buf` (directly or via a wrapping iterator), iteration\n\t\t\t// would observe mid-mutation state. Arrays are iterator-snapshot\n\t\t\t// safe.\n\t\t\tconst list = [...rows];\n\t\t\tif (list.length === 0) return;\n\t\t\twrapMutation(() => backend.upsertMany(list, withDefaultEquals(opts)));\n\t\t},\n\n\t\tdelete(primary: K): void {\n\t\t\twrapMutation(() => backend.delete(primary));\n\t\t},\n\n\t\tdeleteMany(primaries: Iterable<K>): void {\n\t\t\t// Extra: materialize before mutating — same reasoning as upsertMany.\n\t\t\tconst list = [...primaries];\n\t\t\tif (list.length === 0) return;\n\t\t\twrapMutation(() => backend.deleteMany(list));\n\t\t},\n\n\t\tclear(): void {\n\t\t\twrapMutation(() => backend.clear());\n\t\t},\n\n\t\tdispose(): void {\n\t\t\tif (disposed) return;\n\t\t\tdisposed = true;\n\t\t\tdisposeByPrimaryKeepalive();\n\t\t},\n\t};\n}\n","/**\n * Reactive positional list (roadmap §3.2) — emits `readonly T[]` snapshots directly.\n *\n * Internal version counter drives efficient equality without leaking `Versioned`\n * into the public API (spec §5.12).\n *\n * **Wave 4 refactor (2026-04-15):** Introduces the `ListBackend<T>` pluggable-backend\n * interface. The default `NativeListBackend` uses a mutable array with a monotonic\n * `version` counter. No `maxSize` cap — bounded append-heavy workloads should use\n * `reactiveLog` (head-trim under cap is unambiguous for append-only; insert-anywhere\n * with a cap is not).\n */\nimport { batch } from \"../core/batch.js\";\nimport { DATA, DIRTY } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { state } from \"../core/sugar.js\";\nimport type { VersioningLevel } from \"../core/versioning.js\";\n\nexport type ReactiveListOptions<T> = {\n\tname?: string;\n\t/**\n\t * Storage backend. Defaults to `NativeListBackend` (flat mutable array).\n\t * Users can plug in persistent / RRB-tree backends via the {@link ListBackend} interface.\n\t */\n\tbackend?: ListBackend<T>;\n\t/**\n\t * Optional versioning level for the underlying `items` state node. Set at\n\t * construction time; cannot be changed later. Pass `0` for V0 identity +\n\t * monotonic version counter, or `1` for V1 + content-addressed cid.\n\t */\n\tversioning?: VersioningLevel;\n};\n\nexport type ReactiveListBundle<T> = {\n\t/** Emits `readonly T[]` on each structural change (two-phase). */\n\treadonly items: Node<readonly T[]>;\n\t/** Current entry count (O(1)). */\n\treadonly size: number;\n\t/** Positional access (O(1)); supports negative indices (Python-style). Returns `undefined` on out-of-range. */\n\tat: (index: number) => T | undefined;\n\tappend: (value: T) => void;\n\t/** Push all values, emit one snapshot. No-op if `values` is empty. */\n\tappendMany: (values: readonly T[]) => void;\n\t/** Insert a value at `index`. Throws `RangeError` on out-of-range. */\n\tinsert: (index: number, value: T) => void;\n\t/** Insert all values at `index` as one bulk op; emits one snapshot. No-op if `values` is empty. */\n\tinsertMany: (index: number, values: readonly T[]) => void;\n\t/** Remove and return the value at `index` (default: last). Negative indices Python-style. Throws on empty / out-of-range. */\n\tpop: (index?: number) => T;\n\tclear: () => void;\n\t/**\n\t * Releases any internal keepalive subscriptions so the bundle can be\n\t * GC'd. `reactiveList` currently holds none (no internal derived nodes),\n\t * so `dispose()` is a no-op today — exposed for API parity with\n\t * `reactiveIndex.dispose` / `reactiveMap.dispose` / `reactiveLog.dispose`.\n\t * Idempotent. D6(a).\n\t */\n\tdispose: () => void;\n};\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link reactiveList}. Implementations own the mutable state\n * and expose a monotonic `version` counter that increments on every structural change.\n *\n * The reactive layer reads `version` before and after each backend call; when it\n * advances, a snapshot is emitted.\n *\n * @remarks Post-1.0 op-log changesets will extend this interface with a\n * `changesSince(version: number): Iterable<Change>` method. Current consumers\n * should treat all methods here as stable.\n *\n * @category extra\n */\nexport interface ListBackend<T> {\n\t/** Monotonic mutation counter; increments on every structural change. */\n\treadonly version: number;\n\t/** Number of items currently stored. */\n\treadonly size: number;\n\t/** Positional access; `undefined` on out-of-range. */\n\tat(index: number): T | undefined;\n\t/** Append a single value. Advances `version`. */\n\tappend(value: T): void;\n\t/** Append a batch. Advances `version` once. No-op if empty. */\n\tappendMany(values: readonly T[]): void;\n\t/** Insert at index; throws `RangeError` on out-of-range `0 <= index <= size`. Advances `version`. */\n\tinsert(index: number, value: T): void;\n\t/** Bulk insert at index; throws on out-of-range. Advances `version` once. No-op if `values` empty. */\n\tinsertMany(index: number, values: readonly T[]): void;\n\t/** Remove and return value at index; throws on empty / out-of-range. Advances `version`. */\n\tpop(index: number): T;\n\t/** Clear all entries. Returns count removed. Advances `version` only if non-zero. */\n\tclear(): number;\n\t/** Full snapshot as a fresh array. */\n\ttoArray(): readonly T[];\n}\n\n/**\n * Default mutable-array backend.\n *\n * **Complexity:**\n * - `at`, `size`: O(1)\n * - `append`: O(1) amortized\n * - `appendMany(values)`, `insertMany(index, values)`: O(n + k) where k = values.length\n * - `insert`, `pop` (middle): O(n) due to splice\n * - `pop` (last): O(1)\n * - `clear`: O(1)\n * - `toArray`: O(n)\n *\n * @category extra\n */\nexport class NativeListBackend<T> implements ListBackend<T> {\n\tprivate _version = 0;\n\tprivate readonly _buf: T[];\n\n\tconstructor(initial?: readonly T[]) {\n\t\tthis._buf = initial ? [...initial] : [];\n\t}\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget size(): number {\n\t\treturn this._buf.length;\n\t}\n\n\tat(index: number): T | undefined {\n\t\tif (!Number.isInteger(index)) return undefined;\n\t\tconst i = index >= 0 ? index : this._buf.length + index;\n\t\tif (i < 0 || i >= this._buf.length) return undefined;\n\t\treturn this._buf[i];\n\t}\n\n\tappend(value: T): void {\n\t\tthis._buf.push(value);\n\t\tthis._version += 1;\n\t}\n\n\tappendMany(values: readonly T[]): void {\n\t\tif (values.length === 0) return;\n\t\t// Extra: avoid `this._buf.push(...values)` — spread-push has an\n\t\t// engine-dependent stack-argument limit (typically ~100k–500k), so\n\t\t// very large bulk inserts can throw \"Maximum call stack size exceeded\".\n\t\t// Indexed write is O(n) and has no spread limit.\n\t\tconst oldLen = this._buf.length;\n\t\tthis._buf.length = oldLen + values.length;\n\t\tfor (let i = 0; i < values.length; i++) {\n\t\t\tthis._buf[oldLen + i] = values[i] as T;\n\t\t}\n\t\tthis._version += 1;\n\t}\n\n\tinsert(index: number, value: T): void {\n\t\tif (!Number.isInteger(index) || index < 0 || index > this._buf.length) {\n\t\t\tthrow new RangeError(`insert: index ${index} out of range [0, ${this._buf.length}]`);\n\t\t}\n\t\tthis._buf.splice(index, 0, value);\n\t\tthis._version += 1;\n\t}\n\n\tinsertMany(index: number, values: readonly T[]): void {\n\t\tif (!Number.isInteger(index) || index < 0 || index > this._buf.length) {\n\t\t\tthrow new RangeError(`insertMany: index ${index} out of range [0, ${this._buf.length}]`);\n\t\t}\n\t\tif (values.length === 0) return;\n\t\tthis._buf.splice(index, 0, ...values);\n\t\tthis._version += 1;\n\t}\n\n\tpop(index: number): T {\n\t\tif (this._buf.length === 0) {\n\t\t\tthrow new RangeError(\"pop from empty list\");\n\t\t}\n\t\tif (!Number.isInteger(index)) {\n\t\t\tthrow new RangeError(`pop: index ${index} must be an integer`);\n\t\t}\n\t\tconst i = index >= 0 ? index : this._buf.length + index;\n\t\tif (i < 0 || i >= this._buf.length) {\n\t\t\tthrow new RangeError(`pop: index ${index} out of range`);\n\t\t}\n\t\tconst [v] = this._buf.splice(i, 1);\n\t\tthis._version += 1;\n\t\treturn v as T;\n\t}\n\n\tclear(): number {\n\t\tconst n = this._buf.length;\n\t\tif (n === 0) return 0;\n\t\tthis._buf.length = 0;\n\t\tthis._version += 1;\n\t\treturn n;\n\t}\n\n\ttoArray(): readonly T[] {\n\t\treturn [...this._buf];\n\t}\n}\n\n// ── Reactive wrapper ──────────────────────────────────────────────────────\n\n/**\n * Creates a reactive list with immutable array snapshots.\n *\n * @param initial - Optional initial items (copied).\n * @param options - Optional `name` for `describe()` / debugging, or pluggable `backend`.\n * @returns Bundle with `items` (state node), `size` / `at`, `append` / `appendMany` / `insert` /\n * `insertMany` / `pop` / `clear`.\n *\n * @remarks\n * **No `maxSize`:** insert/pop-anywhere semantics make eviction-under-cap ambiguous.\n * For bounded append-heavy workloads use `reactiveLog` (head-trim is well-defined for\n * append-only).\n *\n * **Backend:** Default {@link NativeListBackend}. For persistent / RRB-tree semantics\n * supply a custom {@link ListBackend}. If you provide a `backend`, `initial` is ignored\n * — seed the backend directly.\n *\n * @example\n * ```ts\n * import { reactiveList } from \"@graphrefly/graphrefly-ts\";\n *\n * const list = reactiveList<string>([\"a\"], { name: \"queue\" });\n * list.append(\"b\");\n * list.insertMany(1, [\"x\", \"y\"]);\n * ```\n *\n * @category extra\n */\nexport function reactiveList<T>(\n\tinitial?: readonly T[],\n\toptions: ReactiveListOptions<T> = {},\n): ReactiveListBundle<T> {\n\tconst { name, versioning, backend: userBackend } = options;\n\tconst backend: ListBackend<T> = userBackend ?? new NativeListBackend<T>(initial);\n\n\tconst items = state<readonly T[]>(backend.toArray(), {\n\t\tname,\n\t\tdescribeKind: \"state\",\n\t\tequals: (a, b) => a === b,\n\t\t...(versioning != null ? { versioning } : {}),\n\t});\n\n\tfunction pushSnapshot(): void {\n\t\tconst snapshot = backend.toArray();\n\t\tbatch(() => {\n\t\t\titems.down([[DIRTY]]);\n\t\t\titems.down([[DATA, snapshot]]);\n\t\t});\n\t}\n\n\t/**\n\t * D4(a): try/finally defense-in-depth — if a custom backend op throws\n\t * mid-mutation, surface the partial state via pushSnapshot so subscribers\n\t * don't see a stale cache. Native ops are atomic by contract; this only\n\t * matters for user-supplied backends. Mirrors the pattern in reactive-map,\n\t * reactive-index, and reactive-log.\n\t */\n\tfunction wrapMutation<R>(op: () => R): R {\n\t\tconst prev = backend.version;\n\t\ttry {\n\t\t\treturn op();\n\t\t} finally {\n\t\t\tif (backend.version !== prev) pushSnapshot();\n\t\t}\n\t}\n\n\treturn {\n\t\titems,\n\n\t\tget size(): number {\n\t\t\treturn backend.size;\n\t\t},\n\n\t\tat(index: number): T | undefined {\n\t\t\treturn backend.at(index);\n\t\t},\n\n\t\tappend(value: T): void {\n\t\t\twrapMutation(() => backend.append(value));\n\t\t},\n\n\t\tappendMany(values: readonly T[]): void {\n\t\t\twrapMutation(() => backend.appendMany(values));\n\t\t},\n\n\t\tinsert(index: number, value: T): void {\n\t\t\twrapMutation(() => backend.insert(index, value));\n\t\t},\n\n\t\tinsertMany(index: number, values: readonly T[]): void {\n\t\t\twrapMutation(() => backend.insertMany(index, values));\n\t\t},\n\n\t\tpop(index = -1): T {\n\t\t\treturn wrapMutation(() => backend.pop(index));\n\t\t},\n\n\t\tclear(): void {\n\t\t\twrapMutation(() => backend.clear());\n\t\t},\n\n\t\tdispose(): void {\n\t\t\t// D6(a): no internal keepalives — no-op for API parity. If a future\n\t\t\t// refactor adds a keepalive, wire its disposer here.\n\t\t},\n\t};\n}\n","/**\n * Reactive append-only log (roadmap §3.2) — emits `readonly T[]` snapshots directly.\n *\n * Internal version counter drives efficient equality without leaking `Versioned`\n * into the public API (spec §5.12).\n *\n * **Wave 4 refactor (2026-04-15):** Introduces the `LogBackend<T>` pluggable-backend\n * interface. The default `NativeLogBackend` uses a ring buffer when `maxSize` is set\n * (O(1) append + trim) and a flat array otherwise. `tail(n)` and `slice(start, stop)`\n * are memoized — repeat calls with identical arguments return the same derived node,\n * bounding the keepalive-subscription footprint. The standalone `logSlice` factory\n * has been removed; use `log.slice(start, stop)` instead.\n */\nimport { batch } from \"../core/batch.js\";\nimport { DATA, DIRTY } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { derived, state } from \"../core/sugar.js\";\nimport type { VersioningLevel } from \"../core/versioning.js\";\n\nexport type ReactiveLogOptions<T> = {\n\tname?: string;\n\tmaxSize?: number;\n\t/**\n\t * Optional versioning level for the underlying `entries` state node. Set\n\t * at construction time; cannot be changed later. Pass `0` for V0 identity\n\t * + monotonic version counter, or `1` for V1 + content-addressed cid.\n\t */\n\tversioning?: VersioningLevel;\n\t/**\n\t * Storage backend. Defaults to `NativeLogBackend` (ring buffer if `maxSize` is set,\n\t * flat array otherwise). Users can plug in persistent / RRB-tree backends via\n\t * the {@link LogBackend} interface.\n\t */\n\tbackend?: LogBackend<T>;\n};\n\nexport type ReactiveLogBundle<T> = {\n\t/** Emits `readonly T[]` on each append/clear/trim (two-phase). */\n\treadonly entries: Node<readonly T[]>;\n\t/** Current entry count (O(1)). */\n\treadonly size: number;\n\t/** Positional access (O(1)); returns `undefined` on out-of-range. Supports negative indices (Python-style). */\n\tat: (index: number) => T | undefined;\n\tappend: (value: T) => void;\n\t/**\n\t * Push all values, emit one snapshot. No-op if `values` is empty.\n\t * **Iterable consumption:** `values` is a `readonly T[]` — safe to pass arrays.\n\t */\n\tappendMany: (values: readonly T[]) => void;\n\tclear: () => void;\n\t/** Remove the first `n` entries (clamped to `size`). Throws on non-integer or negative `n`. */\n\ttrimHead: (n: number) => void;\n\t/**\n\t * Last `n` entries (or fewer) as a derived reactive view. Memoized with\n\t * an LRU cache (default cap 64) — repeat calls with the same `n` return\n\t * the same node. Throws on non-integer or negative `n`.\n\t *\n\t * **LRU eviction contract (D3(b)):** when a 65th distinct `n` is passed,\n\t * the least-recently-used cached view is evicted and its keepalive is\n\t * disposed. External holders of the evicted node will NOT receive further\n\t * updates — re-call `tail(n)` for a fresh node, or dispose proactively\n\t * via {@link disposeTail} / {@link disposeAllViews}. To avoid surprise:\n\t * resolve `tail(n)` at the point of use rather than caching the returned\n\t * node across many distinct `n`s.\n\t */\n\ttail: (n: number) => Node<readonly T[]>;\n\t/**\n\t * Reactive view of `entries.slice(start, stop)` — non-negative integer\n\t * `start`, non-negative integer `stop` (exclusive) or `undefined` (to end).\n\t * Memoized with an LRU cache (default cap 64) — repeat calls with the\n\t * same `(start, stop)` return the same node.\n\t *\n\t * Throws on non-integer `start`, negative `start`, non-integer `stop`, or\n\t * negative `stop` (P4 — the backend cannot cheaply honor JS-style\n\t * negative `stop` without scanning length; disallowed for a consistent\n\t * contract between backend, derived recomputation, and cached initial).\n\t *\n\t * **LRU eviction contract (D3(b)):** same as {@link tail} — past 64\n\t * distinct `(start, stop)` pairs, the oldest cached view is evicted and\n\t * its keepalive disposed. External holders stop receiving updates.\n\t */\n\tslice: (start: number, stop?: number) => Node<readonly T[]>;\n\t/**\n\t * Releases the cached `tail(n)` view if present (disposes its keepalive\n\t * subscription). Subsequent `tail(n)` calls create a fresh node. No-op if\n\t * `n` was not cached. Returns `true` if a view was disposed.\n\t */\n\tdisposeTail: (n: number) => boolean;\n\t/**\n\t * Releases the cached `slice(start, stop?)` view if present. No-op if not cached.\n\t */\n\tdisposeSlice: (start: number, stop?: number) => boolean;\n\t/** Releases all cached tail/slice views and their keepalive subscriptions. */\n\tdisposeAllViews: () => void;\n\t/**\n\t * Releases all internal keepalive subscriptions so the bundle can be\n\t * GC'd — currently equivalent to {@link disposeAllViews}, but exposed as\n\t * a uniform API across all reactive data structures for lifecycle\n\t * symmetry (mirrors `reactiveMap.dispose` / `reactiveList.dispose` /\n\t * `reactiveIndex.dispose`). Idempotent. D6(a).\n\t */\n\tdispose: () => void;\n};\n\n// ── Backend interface ─────────────────────────────────────────────────────\n\n/**\n * Storage contract for {@link reactiveLog}. Implementations own the mutable state and\n * expose a monotonic `version` counter that increments on every structural change.\n *\n * The reactive layer reads `version` to decide when to emit; it does not inspect\n * internal representation. Users can plug in persistent / ring-buffer / skip-list\n * backends without touching the reactive emission logic.\n *\n * @remarks Post-1.0 op-log changesets will extend this interface with a\n * `changesSince(version: number): Iterable<Change>` method. Current consumers\n * should treat all methods here as stable.\n *\n * @category extra\n */\nexport interface LogBackend<T> {\n\t/** Monotonic mutation counter; increments on every append/trim/clear that changes state. */\n\treadonly version: number;\n\t/** Number of entries currently stored. */\n\treadonly size: number;\n\t/** O(1) positional access; returns `undefined` on out-of-range. */\n\tat(index: number): T | undefined;\n\t/** Append a value. Applies `maxSize` head-drop if configured. Advances `version`. */\n\tappend(value: T): void;\n\t/** Append a batch; advances `version` once. No-op if `values.length === 0`. */\n\tappendMany(values: readonly T[]): void;\n\t/** Remove all entries. Returns count removed. Advances `version` only if non-zero. */\n\tclear(): number;\n\t/** Remove the first `n` entries (clamped). Returns count removed. Throws on negative `n`. */\n\ttrimHead(n: number): number;\n\t/** Fresh snapshot array for `[start, stop)`. Throws on negative `start`. */\n\tslice(start: number, stop?: number): readonly T[];\n\t/** Last `n` entries as a fresh array. Throws on negative `n`. */\n\ttail(n: number): readonly T[];\n\t/** Full snapshot as a fresh array. */\n\ttoArray(): readonly T[];\n}\n\n/**\n * Default append-only log backend.\n *\n * - When `maxSize` is set: uses a **ring buffer** with `_head` index and circular\n * modular arithmetic. Append and trim become O(1); snapshot is O(size) unrolling.\n * - When `maxSize` is unset: uses a flat array with standard push/splice.\n *\n * `appendMany` pre-trims oversize input: if `values.length > maxSize`, only the\n * tail of `values` is pushed (the rest would be immediately evicted).\n *\n * @category extra\n */\nexport class NativeLogBackend<T> implements LogBackend<T> {\n\tprivate _version = 0;\n\tprivate readonly _maxSize?: number;\n\tprivate readonly _buf: T[];\n\tprivate _head = 0;\n\tprivate _size = 0;\n\n\tconstructor(initial?: readonly T[], maxSize?: number) {\n\t\tif (maxSize !== undefined && maxSize < 1) {\n\t\t\tthrow new RangeError(\"maxSize must be >= 1\");\n\t\t}\n\t\tthis._maxSize = maxSize;\n\t\tif (maxSize !== undefined) {\n\t\t\t// Ring buffer mode — pre-allocate fixed size\n\t\t\tthis._buf = new Array(maxSize);\n\t\t\tif (initial && initial.length > 0) {\n\t\t\t\tconst take = Math.min(initial.length, maxSize);\n\t\t\t\tconst start = initial.length - take;\n\t\t\t\tfor (let i = 0; i < take; i++) {\n\t\t\t\t\tthis._buf[i] = initial[start + i]!;\n\t\t\t\t}\n\t\t\t\tthis._size = take;\n\t\t\t}\n\t\t} else {\n\t\t\t// Unbounded mode — dynamic array\n\t\t\tthis._buf = initial ? [...initial] : [];\n\t\t\tthis._size = this._buf.length;\n\t\t}\n\t}\n\n\tget version(): number {\n\t\treturn this._version;\n\t}\n\n\tget size(): number {\n\t\treturn this._size;\n\t}\n\n\tat(index: number): T | undefined {\n\t\tif (!Number.isInteger(index)) return undefined;\n\t\t// P5: Python-style negative index — `-1` returns the last entry.\n\t\tconst i = index >= 0 ? index : this._size + index;\n\t\tif (i < 0 || i >= this._size) return undefined;\n\t\tif (this._maxSize !== undefined) {\n\t\t\treturn this._buf[(this._head + i) % this._maxSize];\n\t\t}\n\t\treturn this._buf[i];\n\t}\n\n\tappend(value: T): void {\n\t\tthis._rawAppend(value);\n\t\tthis._version += 1;\n\t}\n\n\tappendMany(values: readonly T[]): void {\n\t\tif (values.length === 0) return;\n\t\t// Pre-trim oversize input in ring mode — skip values that would be\n\t\t// immediately evicted. Iterate with a start index instead of\n\t\t// allocating an intermediate slice. F2.\n\t\tconst start =\n\t\t\tthis._maxSize !== undefined && values.length > this._maxSize\n\t\t\t\t? values.length - this._maxSize\n\t\t\t\t: 0;\n\t\tfor (let i = start; i < values.length; i++) {\n\t\t\tthis._rawAppend(values[i] as T);\n\t\t}\n\t\tthis._version += 1;\n\t}\n\n\tclear(): number {\n\t\tif (this._size === 0) return 0;\n\t\tconst n = this._size;\n\t\tif (this._maxSize === undefined) {\n\t\t\tthis._buf.length = 0;\n\t\t} else {\n\t\t\t// Ring buffer: only null the currently-live window so the GC can\n\t\t\t// reclaim ref-typed `T`. Iterating the full capacity would be O(cap)\n\t\t\t// even when only a few slots are in use (P6). Non-live slots are\n\t\t\t// already `undefined` (pre-allocation state) or whatever a prior\n\t\t\t// trim/clear left — they hold no live refs.\n\t\t\tfor (let i = 0; i < n; i++) {\n\t\t\t\tthis._buf[(this._head + i) % this._maxSize] = undefined as unknown as T;\n\t\t\t}\n\t\t}\n\t\tthis._head = 0;\n\t\tthis._size = 0;\n\t\tthis._version += 1;\n\t\treturn n;\n\t}\n\n\ttrimHead(n: number): number {\n\t\tif (!Number.isInteger(n) || n < 0) {\n\t\t\tthrow new RangeError(`trimHead: n must be a non-negative integer (got ${n})`);\n\t\t}\n\t\tif (n === 0 || this._size === 0) return 0;\n\t\tconst removed = Math.min(n, this._size);\n\t\tif (this._maxSize === undefined) {\n\t\t\tthis._buf.splice(0, removed);\n\t\t} else {\n\t\t\t// Null trimmed slots so the GC can reclaim ref-typed T (P4 extension).\n\t\t\tfor (let i = 0; i < removed; i++) {\n\t\t\t\tthis._buf[(this._head + i) % this._maxSize] = undefined as unknown as T;\n\t\t\t}\n\t\t\tthis._head = (this._head + removed) % this._maxSize;\n\t\t}\n\t\tthis._size -= removed;\n\t\tthis._version += 1;\n\t\treturn removed;\n\t}\n\n\tslice(start: number, stop?: number): readonly T[] {\n\t\tif (!Number.isInteger(start) || start < 0) {\n\t\t\tthrow new RangeError(`slice: start must be a non-negative integer (got ${start})`);\n\t\t}\n\t\t// P4: reject negative `stop` explicitly so the bundle / backend / derived\n\t\t// contract stays consistent. Previously stop was silently clamped to 0,\n\t\t// producing `[]` in the backend but a different value under JS semantics\n\t\t// in the derived recomputation — a latent bug for negative inputs.\n\t\tif (stop !== undefined && (!Number.isInteger(stop) || stop < 0)) {\n\t\t\tthrow new RangeError(`slice: stop must be a non-negative integer or undefined (got ${stop})`);\n\t\t}\n\t\tconst end = stop === undefined ? this._size : Math.min(Math.max(stop, 0), this._size);\n\t\tconst s = Math.min(start, this._size);\n\t\tif (s >= end) return [];\n\t\tconst len = end - s;\n\t\tif (this._maxSize === undefined) {\n\t\t\treturn this._buf.slice(s, end);\n\t\t}\n\t\tconst out: T[] = new Array(len);\n\t\tfor (let i = 0; i < len; i++) {\n\t\t\tout[i] = this._buf[(this._head + s + i) % this._maxSize]!;\n\t\t}\n\t\treturn out;\n\t}\n\n\ttail(n: number): readonly T[] {\n\t\tif (!Number.isInteger(n) || n < 0) {\n\t\t\tthrow new RangeError(`tail: n must be a non-negative integer (got ${n})`);\n\t\t}\n\t\tif (n === 0 || this._size === 0) return [];\n\t\tconst take = Math.min(n, this._size);\n\t\treturn this.slice(this._size - take, this._size);\n\t}\n\n\ttoArray(): readonly T[] {\n\t\tif (this._maxSize === undefined) {\n\t\t\treturn [...this._buf];\n\t\t}\n\t\tconst out: T[] = new Array(this._size);\n\t\tfor (let i = 0; i < this._size; i++) {\n\t\t\tout[i] = this._buf[(this._head + i) % this._maxSize]!;\n\t\t}\n\t\treturn out;\n\t}\n\n\t/** Internal append without version bump — used by `appendMany`. */\n\tprivate _rawAppend(value: T): void {\n\t\tif (this._maxSize === undefined) {\n\t\t\tthis._buf.push(value);\n\t\t\tthis._size = this._buf.length;\n\t\t\treturn;\n\t\t}\n\t\tif (this._size < this._maxSize) {\n\t\t\tthis._buf[(this._head + this._size) % this._maxSize] = value;\n\t\t\tthis._size += 1;\n\t\t} else {\n\t\t\t// Overwrite slot at head, advance head.\n\t\t\tthis._buf[this._head] = value;\n\t\t\tthis._head = (this._head + 1) % this._maxSize;\n\t\t}\n\t}\n}\n\n// ── Reactive wrapper ──────────────────────────────────────────────────────\n\n/** Installs a keepalive subscription; returns the disposer so callers can release it. */\nfunction keepaliveDerived(n: Node<unknown>): () => void {\n\treturn n.subscribe(() => {});\n}\n\n/** Default cap on the LRU view cache for `tail(n)` / `slice(start, stop?)`. D2(c). */\nconst DEFAULT_VIEW_CACHE_MAX = 64;\n\n/**\n * Creates an append-only reactive log with immutable array snapshots.\n *\n * @param initial - Optional seed entries (copied; pre-trimmed to `maxSize` if set).\n * @param options - `name`, `maxSize`, and optional pluggable `backend`.\n * @returns Bundle with `entries` (state node), `append`/`appendMany`/`clear`/`trimHead`,\n * `size` / `at`, and memoized derived views `tail(n)` / `slice(start, stop?)`.\n *\n * @remarks\n * **Backend:** The default {@link NativeLogBackend} uses a ring buffer when `maxSize`\n * is set (O(1) append + trim) and a flat array otherwise. For persistent/structural-\n * sharing semantics plug in a custom {@link LogBackend}.\n *\n * **`initial` + custom `backend` (F5):** When you supply `options.backend`, the\n * `initial` argument is IGNORED — seed the backend yourself before passing it in.\n * The `initial` seed only applies to the default `NativeLogBackend`.\n *\n * **Memoized views:** {@link ReactiveLogBundle.tail} and {@link ReactiveLogBundle.slice}\n * cache derived nodes per-argument. Repeat calls with the same `n` / `(start, stop)`\n * return the same node, bounding keepalive-subscription count to one per unique argument.\n *\n * @example\n * ```ts\n * import { reactiveLog } from \"@graphrefly/graphrefly-ts\";\n *\n * const lg = reactiveLog<number>([1, 2], { name: \"audit\", maxSize: 100 });\n * lg.append(3);\n * lg.entries.subscribe((msgs) => console.log(msgs));\n * const last5 = lg.tail(5); // derived node\n * const window = lg.slice(10, 20); // derived node\n * ```\n *\n * @category extra\n */\nexport function reactiveLog<T>(\n\tinitial?: readonly T[],\n\toptions: ReactiveLogOptions<T> = {},\n): ReactiveLogBundle<T> {\n\tconst { name, maxSize, versioning, backend: userBackend } = options;\n\tconst backend: LogBackend<T> = userBackend ?? new NativeLogBackend<T>(initial, maxSize);\n\n\tconst entries = state<readonly T[]>(backend.toArray(), {\n\t\tname,\n\t\tdescribeKind: \"state\",\n\t\tequals: (a, b) => a === b,\n\t\t...(versioning != null ? { versioning } : {}),\n\t});\n\n\tfunction pushSnapshot(): void {\n\t\tconst snapshot = backend.toArray();\n\t\tbatch(() => {\n\t\t\tentries.down([[DIRTY]]);\n\t\t\tentries.down([[DATA, snapshot]]);\n\t\t});\n\t}\n\n\t// Memoization caches for derived views (D2(c)). Each cache is an LRU keyed by\n\t// the unique view argument, bounded by `DEFAULT_VIEW_CACHE_MAX`. On cache miss\n\t// past the cap, the least-recently-used entry is evicted and its keepalive\n\t// disposer is called so the underlying derived node can be GC'd. Callers can\n\t// also release views proactively via `disposeTail` / `disposeSlice` /\n\t// `disposeAllViews`. Iteration order of `Map` is insertion order, so moving\n\t// an entry to the end on hit is the LRU \"touch\".\n\ttype ViewEntry = { node: Node<readonly T[]>; dispose: () => void };\n\tconst tailCache = new Map<number, ViewEntry>();\n\tconst sliceCache = new Map<string, ViewEntry>();\n\n\tfunction sliceKey(start: number, stop?: number): string {\n\t\treturn `${start}:${stop === undefined ? \"END\" : stop}`;\n\t}\n\n\tfunction evictOldestIfFull<K>(cache: Map<K, ViewEntry>): void {\n\t\tif (cache.size < DEFAULT_VIEW_CACHE_MAX) return;\n\t\tconst first = cache.keys().next();\n\t\tif (first.done) return;\n\t\tconst oldest = cache.get(first.value);\n\t\tif (oldest !== undefined) oldest.dispose();\n\t\tcache.delete(first.value);\n\t}\n\n\t/**\n\t * D4(a): try/finally defense-in-depth — if a custom backend op throws\n\t * mid-mutation, surface the partial state via pushSnapshot so subscribers\n\t * don't see a stale cache. Matches the pattern in reactive-map and\n\t * reactive-index. Native ops are atomic by contract; this only matters\n\t * for user-supplied backends.\n\t */\n\tfunction wrapMutation<R>(op: () => R): R {\n\t\tconst prev = backend.version;\n\t\ttry {\n\t\t\treturn op();\n\t\t} finally {\n\t\t\tif (backend.version !== prev) pushSnapshot();\n\t\t}\n\t}\n\n\treturn {\n\t\tentries,\n\n\t\tget size(): number {\n\t\t\treturn backend.size;\n\t\t},\n\n\t\tat(index: number): T | undefined {\n\t\t\treturn backend.at(index);\n\t\t},\n\n\t\tappend(value: T): void {\n\t\t\twrapMutation(() => backend.append(value));\n\t\t},\n\n\t\tappendMany(values: readonly T[]): void {\n\t\t\tif (values.length === 0) return;\n\t\t\twrapMutation(() => backend.appendMany(values));\n\t\t},\n\n\t\tclear(): void {\n\t\t\twrapMutation(() => backend.clear());\n\t\t\t// NOTE: cached tail/slice derived views are intentionally NOT\n\t\t\t// disposed here. Disposing would kill the keepalive on any node\n\t\t\t// a caller already holds externally, silently stopping their\n\t\t\t// updates. The derived nodes recompute from the new empty\n\t\t\t// snapshot when `entries` emits post-clear, so `.cache` on an\n\t\t\t// outstanding view settles to `[]` without any manual\n\t\t\t// reset. (Initial snapshots, if inspected before the next wave,\n\t\t\t// may be stale — callers who care can `disposeTail` / `slice`\n\t\t\t// explicitly.)\n\t\t},\n\n\t\ttrimHead(n: number): void {\n\t\t\twrapMutation(() => backend.trimHead(n));\n\t\t},\n\n\t\ttail(n: number): Node<readonly T[]> {\n\t\t\tif (!Number.isInteger(n) || n < 0) {\n\t\t\t\tthrow new RangeError(`tail: n must be a non-negative integer (got ${n})`);\n\t\t\t}\n\t\t\tconst hit = tailCache.get(n);\n\t\t\tif (hit !== undefined) {\n\t\t\t\t// LRU touch: move to end of insertion order.\n\t\t\t\ttailCache.delete(n);\n\t\t\t\ttailCache.set(n, hit);\n\t\t\t\treturn hit.node;\n\t\t\t}\n\t\t\tevictOldestIfFull(tailCache);\n\t\t\tconst node_ = derived(\n\t\t\t\t[entries],\n\t\t\t\t([s]) => {\n\t\t\t\t\tconst list = s as readonly T[];\n\t\t\t\t\tif (n === 0 || list.length === 0) return [];\n\t\t\t\t\treturn list.slice(Math.max(0, list.length - n));\n\t\t\t\t},\n\t\t\t\t{ initial: backend.tail(n), describeKind: \"derived\" },\n\t\t\t);\n\t\t\tconst dispose = keepaliveDerived(node_);\n\t\t\ttailCache.set(n, { node: node_, dispose });\n\t\t\treturn node_;\n\t\t},\n\n\t\tslice(start: number, stop?: number): Node<readonly T[]> {\n\t\t\tif (!Number.isInteger(start) || start < 0) {\n\t\t\t\tthrow new RangeError(`slice: start must be a non-negative integer (got ${start})`);\n\t\t\t}\n\t\t\t// P4: reject negative stop explicitly to keep bundle / backend / derived\n\t\t\t// consistent (JS `Array.prototype.slice` supports negative stop, but the\n\t\t\t// backend can't cheaply honor it without scanning length, so we disallow).\n\t\t\tif (stop !== undefined && (!Number.isInteger(stop) || stop < 0)) {\n\t\t\t\tthrow new RangeError(\n\t\t\t\t\t`slice: stop must be a non-negative integer or undefined (got ${stop})`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst key = sliceKey(start, stop);\n\t\t\tconst hit = sliceCache.get(key);\n\t\t\tif (hit !== undefined) {\n\t\t\t\tsliceCache.delete(key);\n\t\t\t\tsliceCache.set(key, hit);\n\t\t\t\treturn hit.node;\n\t\t\t}\n\t\t\tevictOldestIfFull(sliceCache);\n\t\t\tconst node_ = derived(\n\t\t\t\t[entries],\n\t\t\t\t([s]) => {\n\t\t\t\t\tconst list = s as readonly T[];\n\t\t\t\t\treturn stop === undefined ? list.slice(start) : list.slice(start, stop);\n\t\t\t\t},\n\t\t\t\t{ initial: backend.slice(start, stop), describeKind: \"derived\" },\n\t\t\t);\n\t\t\tconst dispose = keepaliveDerived(node_);\n\t\t\tsliceCache.set(key, { node: node_, dispose });\n\t\t\treturn node_;\n\t\t},\n\n\t\tdisposeTail(n: number): boolean {\n\t\t\tconst hit = tailCache.get(n);\n\t\t\tif (hit === undefined) return false;\n\t\t\thit.dispose();\n\t\t\ttailCache.delete(n);\n\t\t\treturn true;\n\t\t},\n\n\t\tdisposeSlice(start: number, stop?: number): boolean {\n\t\t\tconst key = sliceKey(start, stop);\n\t\t\tconst hit = sliceCache.get(key);\n\t\t\tif (hit === undefined) return false;\n\t\t\thit.dispose();\n\t\t\tsliceCache.delete(key);\n\t\t\treturn true;\n\t\t},\n\n\t\tdisposeAllViews(): void {\n\t\t\tfor (const entry of tailCache.values()) entry.dispose();\n\t\t\ttailCache.clear();\n\t\t\tfor (const entry of sliceCache.values()) entry.dispose();\n\t\t\tsliceCache.clear();\n\t\t},\n\n\t\tdispose(): void {\n\t\t\t// D6(a): currently identical to disposeAllViews. Exposed as a\n\t\t\t// uniform lifecycle API across all 4 reactive data structures.\n\t\t\tfor (const entry of tailCache.values()) entry.dispose();\n\t\t\ttailCache.clear();\n\t\t\tfor (const entry of sliceCache.values()) entry.dispose();\n\t\t\tsliceCache.clear();\n\t\t},\n\t};\n}\n","/**\n * Storage tier primitive — unified persistence surface (roadmap §3.1).\n *\n * A {@link StorageTier} is the single abstraction used by:\n * - {@link Graph.attachStorage} — snapshot cascade with per-tier cadence\n * - {@link Graph.fromStorage} — hot-boot from the first tier that hits\n * - {@link cascadingCache} — keyed lookup cache with auto-promotion\n *\n * Factory functions cover the common backends: {@link memoryStorage},\n * {@link dictStorage}, {@link fileStorage}, {@link sqliteStorage} (sync), and\n * {@link indexedDbStorage} (async). {@link fromIDBRequest} /\n * {@link fromIDBTransaction} wrap raw IndexedDB primitives as reactive sources\n * — they belong here as the browser-runtime neighbors of `indexedDbStorage`.\n */\n/// <reference lib=\"dom\" />\n\nimport { randomBytes } from \"node:crypto\";\nimport { mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { DatabaseSync } from \"node:sqlite\";\nimport { COMPLETE, DATA, ERROR } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { producer } from \"../core/sugar.js\";\n\n/**\n * Single persistence primitive — supports sync and async backends alike via\n * `void | Promise<void>` returns. `debounceMs` / `compactEvery` / `filter`\n * are per-tier cadence controls honored by {@link Graph.attachStorage};\n * {@link cascadingCache} ignores them (it has its own eviction policy).\n */\nexport interface StorageTier {\n\t/** Read a value. Returns `null` (or resolves to `null`) on miss. */\n\tload(key: string): unknown | Promise<unknown>;\n\t/** Write a record. Sync tiers return `void`; async tiers return `Promise<void>`. */\n\tsave(key: string, data: unknown): void | Promise<void>;\n\t/** Delete a value. Optional — tiers without `clear` are append/overwrite-only. */\n\tclear?(key: string): void | Promise<void>;\n\t/**\n\t * Debounce saves on this tier (ms). Hot tier: `0` (sync-through).\n\t * Warm: `1000`. Cold: `60000`. Each tier holds its own last-save baseline,\n\t * so cold flushes aren't penalized by hot flushes.\n\t */\n\tdebounceMs?: number;\n\t/**\n\t * Every Nth record is a full snapshot; others are diffs against this\n\t * tier's own baseline. Default `10`. Set `1` for always-full;\n\t * `Number.POSITIVE_INFINITY` is unsafe — WAL replay needs periodic anchors.\n\t */\n\tcompactEvery?: number;\n\t/** Pre-save filter — return `false` to skip this record on this tier. */\n\tfilter?: (key: string, record: unknown) => boolean;\n}\n\n/** Handle returned by {@link Graph.attachStorage} — dispose to stop observing. */\nexport interface StorageHandle {\n\tdispose(): void;\n}\n\nfunction sortJsonValue(value: unknown): unknown {\n\tif (value === null || typeof value !== \"object\") return value;\n\tif (Array.isArray(value)) return value.map(sortJsonValue);\n\tconst obj = value as Record<string, unknown>;\n\tconst keys = Object.keys(obj).sort();\n\tconst out: Record<string, unknown> = {};\n\tfor (const k of keys) out[k] = sortJsonValue(obj[k]);\n\treturn out;\n}\n\nfunction stableJsonString(data: unknown): string {\n\t// No trailing newline — tiers that want POSIX newline convention (e.g.\n\t// fileStorage) append their own; in-database tiers (sqliteStorage) keep\n\t// the payload byte-identical for cross-tier hash/CID comparison.\n\treturn JSON.stringify(sortJsonValue(data), undefined, 0);\n}\n\n/**\n * In-memory storage tier (process-local; useful for tests and hot tier).\n *\n * @returns Sync {@link StorageTier} with JSON-cloned isolation.\n *\n * @example\n * ```ts\n * import { memoryStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * const hot = memoryStorage();\n * graph.attachStorage([hot]);\n * ```\n *\n * @category extra\n */\nexport function memoryStorage(): StorageTier {\n\tconst data = new Map<string, unknown>();\n\treturn {\n\t\tsave(key, record) {\n\t\t\tdata.set(key, JSON.parse(JSON.stringify(record)));\n\t\t},\n\t\tload(key) {\n\t\t\tconst v = data.get(key);\n\t\t\treturn v === undefined ? null : JSON.parse(JSON.stringify(v));\n\t\t},\n\t\tclear(key) {\n\t\t\tdata.delete(key);\n\t\t},\n\t};\n}\n\n/**\n * Dict-backed storage tier — stores JSON-cloned values under caller keys in\n * a caller-owned plain object. Useful for embedding in a parent state shape.\n *\n * @param storage - Caller-owned object used as the backing store.\n * @returns Sync {@link StorageTier}.\n *\n * @example\n * ```ts\n * import { dictStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * const state: Record<string, unknown> = {};\n * graph.attachStorage([dictStorage(state)]);\n * ```\n *\n * @category extra\n */\nexport function dictStorage(storage: Record<string, unknown>): StorageTier {\n\treturn {\n\t\tsave(key, record) {\n\t\t\tstorage[key] = JSON.parse(JSON.stringify(record));\n\t\t},\n\t\tload(key) {\n\t\t\tconst raw = storage[key];\n\t\t\treturn raw === undefined ? null : JSON.parse(JSON.stringify(raw));\n\t\t},\n\t\tclear(key) {\n\t\t\tdelete storage[key];\n\t\t},\n\t};\n}\n\n/**\n * Atomic JSON file storage tier (one file per key in a directory, temp + rename).\n *\n * Keys are sanitized to filesystem-safe names (`[^a-zA-Z0-9_-]` → `%<hex>`).\n * `load` returns `null` for missing files, empty files, or invalid JSON.\n *\n * @param dir - Directory where per-key JSON files are written.\n * @returns Sync {@link StorageTier}.\n *\n * @example\n * ```ts\n * import { fileStorage, memoryStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * graph.attachStorage([memoryStorage(), fileStorage(\"./checkpoints\")]);\n * ```\n *\n * @category extra\n */\nexport function fileStorage(dir: string): StorageTier {\n\tconst pathFor = (key: string): string => {\n\t\tconst safe = key.replace(\n\t\t\t/[^a-zA-Z0-9_-]/g,\n\t\t\t(c) => `%${c.charCodeAt(0).toString(16).padStart(2, \"0\")}`,\n\t\t);\n\t\treturn join(dir, `${safe}.json`);\n\t};\n\treturn {\n\t\tsave(key, record) {\n\t\t\tmkdirSync(dir, { recursive: true });\n\t\t\tconst filePath = pathFor(key);\n\t\t\t// POSIX newline for file-on-disk convention; does not affect payload hash.\n\t\t\tconst payload = `${stableJsonString(record)}\\n`;\n\t\t\tconst base = basename(filePath);\n\t\t\tconst d = dirname(filePath);\n\t\t\tconst tmp = join(d, `.${base}.${randomBytes(8).toString(\"hex\")}.tmp`);\n\t\t\ttry {\n\t\t\t\twriteFileSync(tmp, payload, \"utf8\");\n\t\t\t\trenameSync(tmp, filePath);\n\t\t\t} catch (e) {\n\t\t\t\ttry {\n\t\t\t\t\tunlinkSync(tmp);\n\t\t\t\t} catch {\n\t\t\t\t\t/* ignore */\n\t\t\t\t}\n\t\t\t\tthrow e;\n\t\t\t}\n\t\t},\n\t\tload(key) {\n\t\t\ttry {\n\t\t\t\tconst text = readFileSync(pathFor(key), \"utf8\").trim();\n\t\t\t\tif (!text) return null;\n\t\t\t\treturn JSON.parse(text) as unknown;\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\tclear(key) {\n\t\t\ttry {\n\t\t\t\tunlinkSync(pathFor(key));\n\t\t\t} catch (e) {\n\t\t\t\tif ((e as NodeJS.ErrnoException).code !== \"ENOENT\") throw e;\n\t\t\t}\n\t\t},\n\t};\n}\n\n/**\n * SQLite storage tier using Node.js `node:sqlite` ({@link DatabaseSync}).\n *\n * Returns a {@link StorageTier} extended with `close()` — the caller owns the\n * connection and should close it when discarding the tier.\n *\n * **Runtime:** Requires Node 22.5+ with `node:sqlite` enabled.\n *\n * @param path - SQLite database file path.\n * @returns Sync {@link StorageTier} with an idempotent `close()` method.\n *\n * @example\n * ```ts\n * import { sqliteStorage, memoryStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * const cold = sqliteStorage(\"./graphs.sqlite\");\n * graph.attachStorage([memoryStorage(), cold]);\n * // ... later, on shutdown:\n * cold.close();\n * ```\n *\n * @category extra\n */\nexport function sqliteStorage(path: string): StorageTier & { close(): void } {\n\tconst db = new DatabaseSync(path);\n\tdb.exec(`CREATE TABLE IF NOT EXISTS graphrefly_checkpoint (k TEXT PRIMARY KEY, v TEXT NOT NULL)`);\n\treturn {\n\t\tsave(key, record) {\n\t\t\tconst payload = stableJsonString(record);\n\t\t\tdb.prepare(`INSERT OR REPLACE INTO graphrefly_checkpoint (k, v) VALUES (?, ?)`).run(\n\t\t\t\tkey,\n\t\t\t\tpayload,\n\t\t\t);\n\t\t},\n\t\tload(key) {\n\t\t\tconst row = db.prepare(`SELECT v FROM graphrefly_checkpoint WHERE k = ?`).get(key) as\n\t\t\t\t| { v: string }\n\t\t\t\t| undefined;\n\t\t\tif (row === undefined || typeof row.v !== \"string\" || row.v.trim() === \"\") return null;\n\t\t\treturn JSON.parse(row.v) as unknown;\n\t\t},\n\t\tclear(key) {\n\t\t\tdb.prepare(`DELETE FROM graphrefly_checkpoint WHERE k = ?`).run(key);\n\t\t},\n\t\tclose() {\n\t\t\ttry {\n\t\t\t\tdb.close();\n\t\t\t} catch {\n\t\t\t\t/* already closed */\n\t\t\t}\n\t\t},\n\t};\n}\n\n// ——————————————————————————————————————————————————————————————\n// IndexedDB — async storage tier + raw reactive sources\n// ——————————————————————————————————————————————————————————————\n\nexport type IndexedDbStorageSpec = {\n\tdbName: string;\n\tstoreName: string;\n\t/** Object-store key under which snapshots are written. @default `\"graphrefly_checkpoint\"`. */\n\tkey?: string;\n\tversion?: number;\n};\n\n/**\n * Wraps an `IDBRequest` as a one-shot reactive source.\n *\n * @param req - Request whose callbacks are converted to protocol messages.\n * @returns `Node<T>` that emits `DATA` once on success then `COMPLETE`;\n * emits `ERROR` on failure.\n *\n * @category extra\n */\nexport function fromIDBRequest<T>(req: IDBRequest<T>): Node<T> {\n\treturn producer<T>((a) => {\n\t\tlet done = false;\n\t\tconst clear = () => {\n\t\t\treq.onsuccess = null;\n\t\t\treq.onerror = null;\n\t\t};\n\t\treq.onsuccess = () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t\ta.down([[DATA, req.result], [COMPLETE]]);\n\t\t};\n\t\treq.onerror = () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t\ta.down([[ERROR, req.error ?? new Error(\"IndexedDB request failed\")]]);\n\t\t};\n\t\treturn () => {\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t};\n\t});\n}\n\n/**\n * Wraps an `IDBTransaction` terminal lifecycle as a one-shot reactive source.\n *\n * @param tx - Transaction to observe.\n * @returns `Node<void>` that emits `DATA` (`undefined`) then `COMPLETE` on\n * success; emits `ERROR` on `error`/`abort`.\n *\n * @category extra\n */\nexport function fromIDBTransaction(tx: IDBTransaction): Node<void> {\n\treturn producer<void>((a) => {\n\t\tlet done = false;\n\t\tconst clear = () => {\n\t\t\ttx.oncomplete = null;\n\t\t\ttx.onerror = null;\n\t\t\ttx.onabort = null;\n\t\t};\n\t\ttx.oncomplete = () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t\ta.down([[DATA, undefined], [COMPLETE]]);\n\t\t};\n\t\ttx.onerror = () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t\ta.down([[ERROR, tx.error ?? new Error(\"IndexedDB transaction failed\")]]);\n\t\t};\n\t\ttx.onabort = () => {\n\t\t\tif (done) return;\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t\ta.down([[ERROR, tx.error ?? new Error(\"IndexedDB transaction aborted\")]]);\n\t\t};\n\t\treturn () => {\n\t\t\tdone = true;\n\t\t\tclear();\n\t\t};\n\t});\n}\n\nfunction openIdb(dbName: string, storeName: string, version: number): Promise<IDBDatabase> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (typeof indexedDB === \"undefined\") {\n\t\t\treject(new TypeError(\"indexedDB is not available in this environment\"));\n\t\t\treturn;\n\t\t}\n\t\tconst req = indexedDB.open(dbName, version);\n\t\treq.onupgradeneeded = () => {\n\t\t\tconst db = req.result;\n\t\t\tif (!db.objectStoreNames.contains(storeName)) {\n\t\t\t\tdb.createObjectStore(storeName);\n\t\t\t}\n\t\t};\n\t\treq.onsuccess = () => resolve(req.result);\n\t\treq.onerror = () => reject(req.error ?? new Error(\"IndexedDB open failed\"));\n\t});\n}\n\nfunction idbOp<T>(\n\tdbName: string,\n\tstoreName: string,\n\tversion: number,\n\tmode: IDBTransactionMode,\n\top: (store: IDBObjectStore) => IDBRequest<T>,\n): Promise<T> {\n\treturn openIdb(dbName, storeName, version).then(\n\t\t(db) =>\n\t\t\tnew Promise<T>((resolve, reject) => {\n\t\t\t\tconst tx = db.transaction(storeName, mode);\n\t\t\t\tconst store = tx.objectStore(storeName);\n\t\t\t\tconst req = op(store);\n\t\t\t\tlet reqResult: T | undefined;\n\t\t\t\tlet reqDone = false;\n\t\t\t\tlet txDone = false;\n\t\t\t\tconst finish = () => {\n\t\t\t\t\tif (!reqDone || !txDone) return;\n\t\t\t\t\tdb.close();\n\t\t\t\t\tresolve(reqResult as T);\n\t\t\t\t};\n\t\t\t\treq.onsuccess = () => {\n\t\t\t\t\treqResult = req.result;\n\t\t\t\t\treqDone = true;\n\t\t\t\t\tfinish();\n\t\t\t\t};\n\t\t\t\treq.onerror = () => {\n\t\t\t\t\tdb.close();\n\t\t\t\t\treject(req.error ?? new Error(\"IndexedDB request failed\"));\n\t\t\t\t};\n\t\t\t\ttx.oncomplete = () => {\n\t\t\t\t\ttxDone = true;\n\t\t\t\t\tif (!reqDone) {\n\t\t\t\t\t\t// Transaction completed without a request success callback —\n\t\t\t\t\t\t// spec guarantees this shouldn't happen for successful tx,\n\t\t\t\t\t\t// but defensively reject so the caller's promise doesn't\n\t\t\t\t\t\t// hang silently.\n\t\t\t\t\t\tdb.close();\n\t\t\t\t\t\treject(new Error(\"IndexedDB transaction completed without request result\"));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tfinish();\n\t\t\t\t};\n\t\t\t\ttx.onerror = () => {\n\t\t\t\t\tdb.close();\n\t\t\t\t\treject(tx.error ?? new Error(\"IndexedDB transaction failed\"));\n\t\t\t\t};\n\t\t\t\ttx.onabort = () => {\n\t\t\t\t\tdb.close();\n\t\t\t\t\treject(tx.error ?? new Error(\"IndexedDB transaction aborted\"));\n\t\t\t\t};\n\t\t\t}),\n\t);\n}\n\n/**\n * IndexedDB-backed async storage tier (browser runtime).\n *\n * All three methods return `Promise`s — pairs naturally with a warm/cold\n * cadence where async writes are debounced per tier via\n * {@link Graph.attachStorage}. Writes use `readwrite` transactions; reads use\n * `readonly`. Missing records resolve to `null`.\n *\n * @param spec - Database name, store name, optional `key` (default\n * `\"graphrefly_checkpoint\"`) and schema `version` (default `1`).\n * @returns Async {@link StorageTier}.\n *\n * @example\n * ```ts\n * import { indexedDbStorage, memoryStorage } from \"@graphrefly/graphrefly-ts\";\n *\n * graph.attachStorage([\n * memoryStorage(),\n * indexedDbStorage({ dbName: \"myApp\", storeName: \"checkpoints\" }),\n * ]);\n * ```\n *\n * @category extra\n */\nexport function indexedDbStorage(spec: IndexedDbStorageSpec): StorageTier {\n\tconst { dbName, storeName } = spec;\n\tconst version = spec.version ?? 1;\n\tconst recordKey = spec.key ?? \"graphrefly_checkpoint\";\n\treturn {\n\t\tasync save(_key, record) {\n\t\t\tawait idbOp(dbName, storeName, version, \"readwrite\", (store) =>\n\t\t\t\tstore.put(record as unknown as IDBValidKey, recordKey),\n\t\t\t);\n\t\t},\n\t\tasync load(_key) {\n\t\t\tconst raw = await idbOp(dbName, storeName, version, \"readonly\", (store) =>\n\t\t\t\tstore.get(recordKey),\n\t\t\t);\n\t\t\tif (raw === undefined || raw === null) return null;\n\t\t\tif (typeof raw !== \"object\" || Array.isArray(raw)) return null;\n\t\t\treturn raw;\n\t\t},\n\t\tasync clear(_key) {\n\t\t\tawait idbOp(dbName, storeName, version, \"readwrite\", (store) => store.delete(recordKey));\n\t\t},\n\t};\n}\n","/**\n * Wire protocol for worker bridge communication.\n *\n * Graph-local signals ({@link isLocalOnly}) stay local to each side's\n * reactive graph. DATA values cross via coalescing; RESOLVED/COMPLETE/TEARDOWN\n * as signals; ERROR as serialized payloads.\n *\n * Lifecycle signals serialize as string names since Symbols can't survive\n * structured clone. Unknown {@link Symbol.for} symbols are round-tripped\n * via their registered key.\n */\n\nimport { COMPLETE, ERROR, INVALIDATE, PAUSE, RESUME, TEARDOWN } from \"../../core/messages.js\";\n\n// ---------------------------------------------------------------------------\n// Wire message types\n// ---------------------------------------------------------------------------\n\n/** Value update — one node changed. */\nexport interface ValueMessage {\n\tt: \"v\";\n\t/** Node name. */\n\ts: string;\n\t/** Serialized value. */\n\td: unknown;\n}\n\n/** Lifecycle signal — serialized symbol name. */\nexport interface SignalMessage {\n\tt: \"s\";\n\t/** Node name, or `\"*\"` for bridge-wide. */\n\ts: string;\n\t/** Signal name string (e.g. \"TEARDOWN\"). */\n\tsig: string;\n\t/** Optional payload for custom symbols (spec §1.3.6 forward unchanged). */\n\td?: unknown;\n}\n\n/** Ready — worker declares its exported nodes with initial values. */\nexport interface ReadyMessage {\n\tt: \"r\";\n\tstores: Record<string, unknown>;\n}\n\n/** Init — main sends initial values of its exposed nodes. */\nexport interface InitMessage {\n\tt: \"i\";\n\tstores: Record<string, unknown>;\n}\n\n/** Batch value update — multiple nodes changed in one reactive cycle. */\nexport interface BatchMessage {\n\tt: \"b\";\n\tu: Record<string, unknown>;\n\t/** V0 versions per node for delta sync — peer skips if version <= lastSeen (§6.0b). */\n\tv?: Record<string, number>;\n}\n\n/** Error payload — serialized since Error objects don't survive structured clone. */\nexport interface ErrorMessage {\n\tt: \"e\";\n\t/** Node name. */\n\ts: string;\n\t/** Serialized error. */\n\terr: { message: string; name: string; stack?: string };\n}\n\nexport type BridgeMessage =\n\t| ValueMessage\n\t| SignalMessage\n\t| ReadyMessage\n\t| InitMessage\n\t| BatchMessage\n\t| ErrorMessage;\n\n// ---------------------------------------------------------------------------\n// Signal serialization — Symbol <-> string for structured clone\n// ---------------------------------------------------------------------------\n\nconst signalToNameMap = new Map<symbol, string>([\n\t[INVALIDATE, \"INVALIDATE\"],\n\t[PAUSE, \"PAUSE\"],\n\t[RESUME, \"RESUME\"],\n\t[TEARDOWN, \"TEARDOWN\"],\n\t[COMPLETE, \"COMPLETE\"],\n\t[ERROR, \"ERROR\"],\n]);\n\nconst nameToSignalMap = new Map<string, symbol>([\n\t[\"INVALIDATE\", INVALIDATE],\n\t[\"PAUSE\", PAUSE],\n\t[\"RESUME\", RESUME],\n\t[\"TEARDOWN\", TEARDOWN],\n\t[\"COMPLETE\", COMPLETE],\n\t[\"ERROR\", ERROR],\n]);\n\n/**\n * Serialize a message type symbol to a string for structured clone transfer.\n *\n * Known GraphReFly symbols map to their canonical names. Unknown symbols\n * registered via {@link Symbol.for} use their registered key. Unregistered\n * symbols return `\"UNKNOWN\"`.\n */\nexport function signalToName(s: symbol): string {\n\tconst known = signalToNameMap.get(s);\n\tif (known) return known;\n\tconst key = Symbol.keyFor(s);\n\treturn key ?? \"UNKNOWN\";\n}\n\n/**\n * Deserialize a string back to a message type symbol.\n *\n * Known GraphReFly names map to their canonical symbols. Other non-empty\n * strings are reconstructed via {@link Symbol.for} (round-trip safe for\n * custom message types). Returns `undefined` for `\"UNKNOWN\"`.\n */\nexport function nameToSignal(name: string): symbol | undefined {\n\tconst known = nameToSignalMap.get(name);\n\tif (known) return known;\n\tif (name && name !== \"UNKNOWN\") return Symbol.for(name);\n\treturn undefined;\n}\n\n/** Serialize an error for structured clone transfer. */\nexport function serializeError(err: unknown): { message: string; name: string; stack?: string } {\n\tif (err instanceof Error) {\n\t\treturn { message: err.message, name: err.name, stack: err.stack };\n\t}\n\treturn { message: String(err), name: \"Error\" };\n}\n\n/** Deserialize an error payload back to an Error object. */\nexport function deserializeError(payload: {\n\tmessage: string;\n\tname: string;\n\tstack?: string;\n}): Error {\n\tconst err = new Error(payload.message);\n\terr.name = payload.name;\n\tif (payload.stack) err.stack = payload.stack;\n\treturn err;\n}\n","/**\n * WorkerTransport — normalized message channel for all worker types.\n *\n * Abstracts Worker, SharedWorker, ServiceWorker, BroadcastChannel, and\n * MessagePort behind a uniform post/listen/terminate interface.\n */\n\n/** Normalized bidirectional message channel. */\nexport interface WorkerTransport {\n\t/** Send data to the other side. Optional transferables for zero-copy. */\n\tpost(data: unknown, transfer?: Transferable[]): void;\n\t/** Listen for incoming messages. Returns unsubscribe function. */\n\tlisten(handler: (data: unknown) => void): () => void;\n\t/** Terminate the connection (if supported by the underlying transport). */\n\tterminate?(): void;\n}\n\n/**\n * Auto-detect transport type and create a normalized WorkerTransport.\n *\n * Supports:\n * - `Worker` — direct postMessage/onmessage\n * - `SharedWorker` — port-based postMessage/onmessage\n * - `ServiceWorker` — postMessage via controller, listen via navigator.serviceWorker\n * - `BroadcastChannel` — postMessage/onmessage (no Transferable support)\n * - `MessagePort` — direct postMessage/onmessage (worker-side SharedWorker port)\n */\nexport function createTransport(target: unknown): WorkerTransport {\n\t// MessagePort (SharedWorker port from inside the worker, or raw MessagePort)\n\tif (typeof MessagePort !== \"undefined\" && target instanceof MessagePort) {\n\t\treturn {\n\t\t\tpost(data, transfer) {\n\t\t\t\ttarget.postMessage(data, transfer ?? []);\n\t\t\t},\n\t\t\tlisten(handler) {\n\t\t\t\tconst h = (e: MessageEvent) => handler(e.data);\n\t\t\t\ttarget.addEventListener(\"message\", h);\n\t\t\t\ttarget.start();\n\t\t\t\treturn () => target.removeEventListener(\"message\", h);\n\t\t\t},\n\t\t\tterminate() {\n\t\t\t\ttarget.close();\n\t\t\t},\n\t\t};\n\t}\n\n\t// SharedWorker — use its port\n\tif (typeof SharedWorker !== \"undefined\" && target instanceof SharedWorker) {\n\t\treturn createTransport(target.port);\n\t}\n\n\t// Web Worker\n\tif (typeof Worker !== \"undefined\" && target instanceof Worker) {\n\t\treturn {\n\t\t\tpost(data, transfer) {\n\t\t\t\ttarget.postMessage(data, transfer ?? []);\n\t\t\t},\n\t\t\tlisten(handler) {\n\t\t\t\tconst h = (e: MessageEvent) => handler(e.data);\n\t\t\t\ttarget.addEventListener(\"message\", h);\n\t\t\t\treturn () => target.removeEventListener(\"message\", h);\n\t\t\t},\n\t\t\tterminate() {\n\t\t\t\ttarget.terminate();\n\t\t\t},\n\t\t};\n\t}\n\n\t// BroadcastChannel — no Transferable support\n\tif (typeof BroadcastChannel !== \"undefined\" && target instanceof BroadcastChannel) {\n\t\treturn {\n\t\t\tpost(data, transfer?) {\n\t\t\t\tif (transfer && transfer.length > 0) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\"[graphrefly] WorkerTransport: BroadcastChannel does not support Transferable objects. The transfer argument is ignored and objects will be cloned instead.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\ttarget.postMessage(data);\n\t\t\t},\n\t\t\tlisten(handler) {\n\t\t\t\tconst h = (e: MessageEvent) => handler(e.data);\n\t\t\t\ttarget.addEventListener(\"message\", h);\n\t\t\t\treturn () => target.removeEventListener(\"message\", h);\n\t\t\t},\n\t\t\tterminate() {\n\t\t\t\ttarget.close();\n\t\t\t},\n\t\t};\n\t}\n\n\t// ServiceWorker\n\tif (typeof ServiceWorker !== \"undefined\" && target instanceof ServiceWorker) {\n\t\treturn {\n\t\t\tpost(data, transfer) {\n\t\t\t\ttarget.postMessage(data, transfer ?? []);\n\t\t\t},\n\t\t\tlisten(handler) {\n\t\t\t\tconst h = (e: MessageEvent) => {\n\t\t\t\t\tif (e.source === target) handler(e.data);\n\t\t\t\t};\n\t\t\t\tnavigator.serviceWorker.addEventListener(\"message\", h);\n\t\t\t\treturn () => navigator.serviceWorker.removeEventListener(\"message\", h);\n\t\t\t},\n\t\t};\n\t}\n\n\tthrow new Error(\n\t\t\"createTransport: unsupported target type. Expected Worker, SharedWorker, ServiceWorker, BroadcastChannel, or MessagePort.\",\n\t);\n}\n","/**\n * workerBridge — main-thread reactive node bridge to a worker.\n *\n * Creates proxy nodes for imported worker nodes, subscribes to exposed\n * nodes and sends values across the wire. Uses derived() + effect() for\n * natural batch coalescing via two-phase push + bitmask resolution.\n *\n * Wire filtering: graph-local signals ({@link isLocalOnly}) stay local;\n * DATA values go through the coalescing path; RESOLVED, COMPLETE, ERROR,\n * TEARDOWN, and unknown {@link Symbol.for} types go through the signal\n * subscription.\n *\n * Handshake:\n * 1. Main creates bridge, starts listening\n * 2. Worker sends { t: 'r', stores: { name: initialValue, ... } }\n * 3. Main creates proxy nodes, marks meta.status \"connected\"\n * 4. Main sends { t: 'i', stores: { name: currentValue, ... } }\n * 5. Bidirectional value flow begins\n */\n\nimport { batch } from \"../../core/batch.js\";\nimport { DATA, ERROR, type Messages, TEARDOWN } from \"../../core/messages.js\";\nimport { defaultConfig, type Node, type NodeSink, node } from \"../../core/node.js\";\nimport { effect, state } from \"../../core/sugar.js\";\nimport { filter, first, map, merge } from \"../operators.js\";\nimport { fromTimer } from \"../sources.js\";\nimport type { BatchMessage, BridgeMessage } from \"./protocol.js\";\nimport { deserializeError, nameToSignal, serializeError, signalToName } from \"./protocol.js\";\nimport type { WorkerTransport } from \"./transport.js\";\nimport { createTransport } from \"./transport.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface WorkerBridgeOptions<\n\tTExpose extends Record<string, Node<any>>,\n\tTImport extends readonly string[],\n> {\n\t/** Nodes to send to the worker. */\n\texpose?: TExpose;\n\t/** Node names the worker will provide. */\n\timport?: TImport;\n\t/** Per-node transferable extractors for zero-copy ArrayBuffer passing. */\n\ttransfer?: Partial<Record<keyof TExpose, (value: any) => Transferable[]>>;\n\t/** Debug name. */\n\tname?: string;\n\t/**\n\t * Handshake timeout in milliseconds. If the worker doesn't send READY\n\t * within this window, `meta.status` transitions to `\"closed\"` and\n\t * `meta.error` is set. Default: no timeout.\n\t */\n\ttimeoutMs?: number;\n}\n\n/** Proxy nodes created from imported worker node names. */\ntype ImportedNodes<T extends readonly string[]> = {\n\treadonly [K in T[number]]: Node<any>;\n};\n\nexport type WorkerBridge<\n\t_TExpose extends Record<string, Node<any>>,\n\tTImport extends readonly string[],\n> = ImportedNodes<TImport> & {\n\t/** Connection status meta node. */\n\tmeta: {\n\t\tstatus: Node<\"connecting\" | \"connected\" | \"closed\">;\n\t\terror: Node<Error | null>;\n\t};\n\t/** Destroy the bridge: sends TEARDOWN, disconnects, terminates worker. */\n\tdestroy(): void;\n};\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nfunction isTransport(t: unknown): t is WorkerTransport {\n\treturn (\n\t\ttypeof t === \"object\" &&\n\t\tt !== null &&\n\t\ttypeof (t as any).post === \"function\" &&\n\t\ttypeof (t as any).listen === \"function\"\n\t);\n}\n\nexport function workerBridge<\n\tTExpose extends Record<string, Node<any>>,\n\tTImport extends readonly string[],\n>(\n\ttarget: unknown | WorkerTransport,\n\topts: WorkerBridgeOptions<TExpose, TImport>,\n): WorkerBridge<TExpose, TImport> {\n\tconst transport = isTransport(target) ? target : createTransport(target);\n\tconst bridgeName = opts.name ?? \"workerBridge\";\n\tconst exposeEntries = Object.entries(opts.expose ?? {});\n\tconst importNames = (opts.import ?? []) as readonly string[];\n\tconst transferFns = opts.transfer ?? {};\n\n\t// -- Meta: connection status -----------------------------------------------\n\tconst statusNode = state<\"connecting\" | \"connected\" | \"closed\">(\"connecting\", {\n\t\tname: `${bridgeName}::meta::status`,\n\t});\n\tconst errorNode = state<Error | null>(null, {\n\t\tname: `${bridgeName}::meta::error`,\n\t});\n\n\t// -- Proxy nodes for imports (worker -> main) ------------------------------\n\tconst proxyNodes = new Map<string, Node<any>>();\n\tconst lastSeenImportVersions = new Map<string, number>();\n\tfor (const name of importNames) {\n\t\tconst proxy = state(undefined, { name: `${bridgeName}::${name}` });\n\t\tproxyNodes.set(name, proxy);\n\t}\n\n\t// -- Send coalescing via raw `node` + `effect` -----------------------------\n\t//\n\t// Aggregator uses raw `node([deps], (data, a) => ...)` so it can inspect\n\t// the full **wave-form** `data[i]`: a per-dep batch of DATA values emitted\n\t// this wave (or `undefined` if the dep was silent). Deps whose `equals`\n\t// absorb a repeat emission send `RESOLVED` instead of `DATA`, so silent\n\t// slots correctly mean \"no change\" and are omitted from the wire message.\n\t//\n\t// Net effect: no `.cache` reads inside fn, no `equals: () => false`, no\n\t// closure `lastSent` Map — Option B shape under v5 semantics.\n\tlet effectUnsub: (() => void) | undefined;\n\n\tif (exposeEntries.length > 0) {\n\t\tconst exposedNodes = exposeEntries.map(([, n]) => n) as Node[];\n\n\t\tconst aggregated = node<Record<string, unknown>>(\n\t\t\texposedNodes,\n\t\t\t(data, a) => {\n\t\t\t\tconst updates: Record<string, unknown> = {};\n\t\t\t\tfor (let i = 0; i < exposeEntries.length; i++) {\n\t\t\t\t\tconst [name] = exposeEntries[i];\n\t\t\t\t\tconst batch0 = data[i];\n\t\t\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\t\t\tupdates[name] = batch0.at(-1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Object.keys(updates).length === 0) return;\n\t\t\t\ta.emit(updates);\n\t\t\t},\n\t\t\t// Each `updates` object is a fresh allocation, so default reference\n\t\t\t// equality correctly propagates every aggregation wave — no\n\t\t\t// `equals: () => false` override needed.\n\t\t\t{ name: `${bridgeName}::aggregated` },\n\t\t);\n\n\t\tconst effectNode = effect([aggregated], (data) => {\n\t\t\tconst updates = data[0] as Record<string, unknown> | undefined;\n\t\t\tif (updates == null || Object.keys(updates).length === 0) return;\n\n\t\t\tconst transferList: Transferable[] = [];\n\t\t\tfor (const name of Object.keys(updates)) {\n\t\t\t\tconst fn = (transferFns as any)[name];\n\t\t\t\tif (fn) transferList.push(...fn(updates[name]));\n\t\t\t}\n\n\t\t\t// V0 delta sync: include version counters when available (§6.0b).\n\t\t\tlet versions: Record<string, number> | undefined;\n\t\t\tfor (const [name, n] of exposeEntries) {\n\t\t\t\tif (name in updates && n.v != null) {\n\t\t\t\t\tif (versions == null) versions = {};\n\t\t\t\t\tversions[name] = n.v.version;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst msg: BatchMessage = { t: \"b\", u: updates, ...(versions ? { v: versions } : {}) };\n\t\t\ttry {\n\t\t\t\ttransport.post(msg, transferList.length > 0 ? transferList : undefined);\n\t\t\t} catch (err) {\n\t\t\t\terrorNode.down([[DATA, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t}\n\t\t});\n\t\t// Effect nodes are lazy — subscribe to activate the chain\n\t\teffectUnsub = effectNode.subscribe(() => {});\n\t}\n\n\t// -- Receive handler -------------------------------------------------------\n\tlet destroyed = false;\n\n\tconst unlisten = transport.listen((data) => {\n\t\tif (destroyed) return;\n\t\tconst msg = data as BridgeMessage;\n\n\t\tswitch (msg.t) {\n\t\t\t// Worker ready — set proxy nodes with initial values.\n\t\t\t// The handshake deadline auto-cancels via the reactive race\n\t\t\t// (`statusNode → \"connected\"` wins) — no explicit clearTimeout.\n\t\t\tcase \"r\": {\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfor (const [name, value] of Object.entries(msg.stores)) {\n\t\t\t\t\t\tconst proxy = proxyNodes.get(name);\n\t\t\t\t\t\tif (proxy) proxy.down([[DATA, value]]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tstatusNode.down([[DATA, \"connected\"]]);\n\n\t\t\t\t// Send initial values of exposed nodes.\n\t\t\t\t// `.cache` here is a documented transport-boundary read: at the\n\t\t\t\t// worker's \"ready\" moment we need a point-in-time snapshot of\n\t\t\t\t// every exposed node, not a reactive wave. (§5.10 boundary.)\n\t\t\t\tconst initValues: Record<string, unknown> = {};\n\t\t\t\tfor (const [name, n] of exposeEntries) {\n\t\t\t\t\tinitValues[name] = n.cache;\n\t\t\t\t}\n\t\t\t\ttransport.post({ t: \"i\", stores: initValues } satisfies BridgeMessage);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Single value update from worker\n\t\t\tcase \"v\": {\n\t\t\t\tconst proxy = proxyNodes.get(msg.s);\n\t\t\t\tif (proxy) proxy.down([[DATA, msg.d]]);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Batch value update from worker\n\t\t\tcase \"b\": {\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfor (const [name, value] of Object.entries(msg.u)) {\n\t\t\t\t\t\tconst incomingVersion = msg.v?.[name];\n\t\t\t\t\t\tif (incomingVersion != null) {\n\t\t\t\t\t\t\tconst lastSeen = lastSeenImportVersions.get(name);\n\t\t\t\t\t\t\tif (lastSeen != null && incomingVersion <= lastSeen) continue;\n\t\t\t\t\t\t\tlastSeenImportVersions.set(name, incomingVersion);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst proxy = proxyNodes.get(name);\n\t\t\t\t\t\tif (proxy) proxy.down([[DATA, value]]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Error from worker node\n\t\t\tcase \"e\": {\n\t\t\t\tconst proxy = proxyNodes.get(msg.s);\n\t\t\t\tif (proxy) proxy.down([[ERROR, deserializeError(msg.err)]]);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Lifecycle signal from worker\n\t\t\tcase \"s\": {\n\t\t\t\tconst sig = nameToSignal(msg.sig);\n\t\t\t\tif (!sig) break;\n\n\t\t\t\tconst targets: Node<any>[] =\n\t\t\t\t\tmsg.s === \"*\"\n\t\t\t\t\t\t? [...proxyNodes.values()]\n\t\t\t\t\t\t: proxyNodes.has(msg.s)\n\t\t\t\t\t\t\t? [proxyNodes.get(msg.s)!]\n\t\t\t\t\t\t\t: [];\n\n\t\t\t\tfor (const proxy of targets) {\n\t\t\t\t\tproxy.down((msg.d === undefined ? [[sig]] : [[sig, msg.d]]) as Messages);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t});\n\n\t// -- Subscribe to exposed nodes: forward tier >= 3 messages -----------------\n\tconst exposeUnsubs: Array<() => void> = [];\n\tfor (const [name, n] of exposeEntries) {\n\t\tconst unsub = n.subscribe(((msgs: Messages) => {\n\t\t\tif (destroyed) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tconst type = m[0] as symbol;\n\t\t\t\t// DATA goes through the coalescing path — skip here\n\t\t\t\tif (type === DATA) continue;\n\t\t\t\t// Block graph-local signals (START, DIRTY, INVALIDATE, PAUSE, RESUME).\n\t\t\t\t// Unknown types forward (spec §1.3.6).\n\t\t\t\tif (defaultConfig.isLocalOnly(type)) continue;\n\t\t\t\t// ERROR: serialize payload\n\t\t\t\tif (type === ERROR) {\n\t\t\t\t\ttransport.post({\n\t\t\t\t\t\tt: \"e\",\n\t\t\t\t\t\ts: name,\n\t\t\t\t\t\terr: serializeError(m[1]),\n\t\t\t\t\t} satisfies BridgeMessage);\n\t\t\t\t} else {\n\t\t\t\t\t// RESOLVED, COMPLETE, TEARDOWN, and unknown Symbol.for types\n\t\t\t\t\ttransport.post({\n\t\t\t\t\t\tt: \"s\",\n\t\t\t\t\t\ts: name,\n\t\t\t\t\t\tsig: signalToName(type),\n\t\t\t\t\t\td: m.length > 1 ? m[1] : undefined,\n\t\t\t\t\t} satisfies BridgeMessage);\n\t\t\t\t}\n\t\t\t}\n\t\t}) as NodeSink);\n\t\texposeUnsubs.push(unsub);\n\t}\n\n\t// -- Handshake timeout — reactive race between status→\"connected\" and a\n\t// one-shot `fromTimer` deadline. Whichever fires first wins via `first()`,\n\t// which completes and auto-unsubs upstream (cancelling the deadline if\n\t// ready arrived first, or vice-versa).\n\tlet handshakeUnsub: (() => void) | undefined;\n\tif (opts.timeoutMs != null && opts.timeoutMs > 0) {\n\t\tconst deadline$ = fromTimer(opts.timeoutMs);\n\t\tconst ready$ = filter(statusNode, (s) => s === \"connected\");\n\t\tconst race$ = first(\n\t\t\tmerge(\n\t\t\t\tmap(deadline$, () => \"timeout\" as const),\n\t\t\t\tmap(ready$, () => \"ready\" as const),\n\t\t\t),\n\t\t);\n\t\thandshakeUnsub = race$.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA && m[1] === \"timeout\") {\n\t\t\t\t\terrorNode.down([[DATA, new Error(\"Worker bridge handshake timeout\")]]);\n\t\t\t\t\tdestroy();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\t// -- Build result object ---------------------------------------------------\n\tfunction destroy() {\n\t\tif (destroyed) return;\n\t\tdestroyed = true;\n\n\t\thandshakeUnsub?.();\n\n\t\t// Send bridge-level TEARDOWN to worker\n\t\ttransport.post({\n\t\t\tt: \"s\",\n\t\t\ts: \"*\",\n\t\t\tsig: signalToName(TEARDOWN),\n\t\t} satisfies BridgeMessage);\n\n\t\t// Cleanup: unsub effect first (stops sending), then unsub expose\n\t\t// listeners, then unlisten on transport\n\t\tif (effectUnsub) effectUnsub();\n\t\tfor (const unsub of exposeUnsubs) unsub();\n\t\texposeUnsubs.length = 0;\n\t\tunlisten();\n\n\t\tstatusNode.down([[DATA, \"closed\"]]);\n\n\t\tlastSeenImportVersions.clear();\n\t\tproxyNodes.clear();\n\t}\n\n\tconst result: any = {\n\t\tmeta: { status: statusNode, error: errorNode },\n\t\tdestroy,\n\t};\n\n\t// Attach proxy nodes as properties\n\tfor (const [name, proxy] of proxyNodes) {\n\t\tresult[name] = proxy;\n\t}\n\n\treturn result as WorkerBridge<TExpose, TImport>;\n}\n","/**\n * workerSelf — worker-side reactive node bridge.\n *\n * Mirror of workerBridge() for the worker side. Creates proxy nodes for\n * imports from main thread, exposes local nodes via the same wire protocol.\n * Uses derived() + effect() for batch coalescing.\n *\n * Wire filtering: graph-local signals ({@link isLocalOnly}) stay local;\n * DATA values go through the coalescing path; RESOLVED, COMPLETE, ERROR,\n * TEARDOWN, and unknown {@link Symbol.for} types go through the signal\n * subscription.\n *\n * Handshake (worker perspective):\n * 1. workerSelf() called — creates proxy nodes for imports\n * 2. Runs expose factory with proxy nodes -> gets nodes to expose\n * 3. Sends { t: 'r', stores: { name: initialValue, ... } } to main\n * 4. Receives { t: 'i', stores: { name: value, ... } } from main\n * 5. Updates proxy nodes -> triggers local effects\n */\n\nimport { batch } from \"../../core/batch.js\";\nimport { DATA, ERROR, type Messages, TEARDOWN } from \"../../core/messages.js\";\nimport { defaultConfig, type Node, type NodeSink, node } from \"../../core/node.js\";\nimport { effect, state } from \"../../core/sugar.js\";\nimport type { BatchMessage, BridgeMessage } from \"./protocol.js\";\nimport { deserializeError, nameToSignal, serializeError, signalToName } from \"./protocol.js\";\nimport type { WorkerTransport } from \"./transport.js\";\nimport { createTransport } from \"./transport.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface WorkerSelfOptions<TImport extends readonly string[]> {\n\t/** Node names that the main thread will provide. */\n\timport?: TImport;\n\t/** Factory that receives imported proxy nodes and returns nodes to expose. */\n\texpose: (imported: WorkerImported<TImport>) => Record<string, Node<any>>;\n\t/** Per-node transferable extractors for zero-copy ArrayBuffer passing. */\n\ttransfer?: Record<string, (value: any) => Transferable[]>;\n}\n\n/** Proxy nodes available inside the worker from main-thread exposed nodes. */\ntype WorkerImported<T extends readonly string[]> = {\n\treadonly [K in T[number]]: Node<any>;\n};\n\nexport interface WorkerSelfHandle {\n\t/** Dispose all subscriptions and stop the bridge. */\n\tdestroy(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Implementation\n// ---------------------------------------------------------------------------\n\nfunction isTransport(t: unknown): t is WorkerTransport {\n\treturn (\n\t\ttypeof t === \"object\" &&\n\t\tt !== null &&\n\t\ttypeof (t as any).post === \"function\" &&\n\t\ttypeof (t as any).listen === \"function\"\n\t);\n}\n\nexport function workerSelf<TImport extends readonly string[]>(\n\ttarget: unknown | WorkerTransport,\n\topts: WorkerSelfOptions<TImport>,\n): WorkerSelfHandle {\n\tconst transport = isTransport(target) ? target : createTransport(target);\n\tconst importNames = (opts.import ?? []) as readonly string[];\n\tconst transferFns = opts.transfer ?? {};\n\n\t// -- Proxy nodes for imports (main -> worker) ------------------------------\n\tconst proxyNodes = new Map<string, Node<any>>();\n\tconst lastSeenImportVersions = new Map<string, number>();\n\tconst importedObj: any = {};\n\tfor (const name of importNames) {\n\t\tconst s = state(undefined, { name: `worker::${name}` });\n\t\tproxyNodes.set(name, s);\n\t\timportedObj[name] = s;\n\t}\n\n\t// -- Run expose factory ----------------------------------------------------\n\tconst exposedNodes = opts.expose(importedObj as WorkerImported<TImport>);\n\tconst exposeEntries = Object.entries(exposedNodes);\n\n\t// -- Send coalescing via raw `node` + `effect` ----------------------------\n\t// See bridge.ts for the Option B rationale — raw `node([deps], fn)` with\n\t// wave-form `data[]` replaces the prior `lastSent` diff + `.cache` reads.\n\tlet effectUnsub: (() => void) | undefined;\n\tlet destroyed = false;\n\n\tif (exposeEntries.length > 0) {\n\t\tconst nodes = exposeEntries.map(([, n]) => n) as Node[];\n\n\t\tconst aggregated = node<Record<string, unknown>>(\n\t\t\tnodes,\n\t\t\t(data, a) => {\n\t\t\t\tconst updates: Record<string, unknown> = {};\n\t\t\t\tfor (let i = 0; i < exposeEntries.length; i++) {\n\t\t\t\t\tconst [name] = exposeEntries[i];\n\t\t\t\t\tconst batch0 = data[i];\n\t\t\t\t\tif (batch0 != null && batch0.length > 0) {\n\t\t\t\t\t\tupdates[name] = batch0.at(-1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (Object.keys(updates).length === 0) return;\n\t\t\t\ta.emit(updates);\n\t\t\t},\n\t\t\t// Fresh `updates` object per wave → default reference equality is\n\t\t\t// correct; no `equals: () => false` override needed.\n\t\t\t{ name: \"workerSelf::aggregated\" },\n\t\t);\n\n\t\tconst effectNode = effect([aggregated], (data) => {\n\t\t\tif (destroyed) return;\n\t\t\tconst updates = data[0] as Record<string, unknown> | undefined;\n\t\t\tif (updates == null || Object.keys(updates).length === 0) return;\n\n\t\t\tconst transferList: Transferable[] = [];\n\t\t\tfor (const name of Object.keys(updates)) {\n\t\t\t\tconst fn = (transferFns as any)[name];\n\t\t\t\tif (fn) transferList.push(...fn(updates[name]));\n\t\t\t}\n\n\t\t\t// V0 delta sync: include version counters when available (§6.0b).\n\t\t\tlet versions: Record<string, number> | undefined;\n\t\t\tfor (const [name, n] of exposeEntries) {\n\t\t\t\tif (name in updates && n.v != null) {\n\t\t\t\t\tif (versions == null) versions = {};\n\t\t\t\t\tversions[name] = n.v.version;\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst msg: BatchMessage = { t: \"b\", u: updates, ...(versions ? { v: versions } : {}) };\n\t\t\ttry {\n\t\t\t\ttransport.post(msg, transferList.length > 0 ? transferList : undefined);\n\t\t\t} catch (_err) {\n\t\t\t\t// Transport failure — bridge is likely destroyed; swallow\n\t\t\t}\n\t\t});\n\t\t// Effect nodes are lazy — subscribe to activate the chain\n\t\teffectUnsub = effectNode.subscribe(() => {});\n\t}\n\n\t// -- Subscribe to exposed nodes: forward tier >= 3 messages -----------------\n\tconst exposeUnsubs: Array<() => void> = [];\n\tfor (const [name, n] of exposeEntries) {\n\t\tconst unsub = n.subscribe(((msgs: Messages) => {\n\t\t\tif (destroyed) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tconst type = m[0] as symbol;\n\t\t\t\t// DATA goes through the coalescing path — skip here\n\t\t\t\tif (type === DATA) continue;\n\t\t\t\t// Block graph-local signals (START, DIRTY, INVALIDATE, PAUSE, RESUME).\n\t\t\t\t// Unknown types forward (spec §1.3.6).\n\t\t\t\tif (defaultConfig.isLocalOnly(type)) continue;\n\t\t\t\t// ERROR: serialize payload\n\t\t\t\tif (type === ERROR) {\n\t\t\t\t\ttransport.post({\n\t\t\t\t\t\tt: \"e\",\n\t\t\t\t\t\ts: name,\n\t\t\t\t\t\terr: serializeError(m[1]),\n\t\t\t\t\t} satisfies BridgeMessage);\n\t\t\t\t} else {\n\t\t\t\t\t// RESOLVED, COMPLETE, TEARDOWN, and unknown Symbol.for types\n\t\t\t\t\ttransport.post({\n\t\t\t\t\t\tt: \"s\",\n\t\t\t\t\t\ts: name,\n\t\t\t\t\t\tsig: signalToName(type),\n\t\t\t\t\t\td: m.length > 1 ? m[1] : undefined,\n\t\t\t\t\t} satisfies BridgeMessage);\n\t\t\t\t}\n\t\t\t}\n\t\t}) as NodeSink);\n\t\texposeUnsubs.push(unsub);\n\t}\n\n\t// -- Receive handler -------------------------------------------------------\n\tconst unlisten = transport.listen((data) => {\n\t\tif (destroyed) return;\n\t\tconst msg = data as BridgeMessage;\n\n\t\tswitch (msg.t) {\n\t\t\t// Init from main — set proxy node values\n\t\t\tcase \"i\": {\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfor (const [name, value] of Object.entries(msg.stores)) {\n\t\t\t\t\t\tconst proxy = proxyNodes.get(name);\n\t\t\t\t\t\tif (proxy) proxy.down([[DATA, value]]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Single value update from main\n\t\t\tcase \"v\": {\n\t\t\t\tconst proxy = proxyNodes.get(msg.s);\n\t\t\t\tif (proxy) proxy.down([[DATA, msg.d]]);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Batch value update from main\n\t\t\tcase \"b\": {\n\t\t\t\tbatch(() => {\n\t\t\t\t\tfor (const [name, value] of Object.entries(msg.u)) {\n\t\t\t\t\t\tconst incomingVersion = msg.v?.[name];\n\t\t\t\t\t\tif (incomingVersion != null) {\n\t\t\t\t\t\t\tconst lastSeen = lastSeenImportVersions.get(name);\n\t\t\t\t\t\t\tif (lastSeen != null && incomingVersion <= lastSeen) continue;\n\t\t\t\t\t\t\tlastSeenImportVersions.set(name, incomingVersion);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst proxy = proxyNodes.get(name);\n\t\t\t\t\t\tif (proxy) proxy.down([[DATA, value]]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Error from main node\n\t\t\tcase \"e\": {\n\t\t\t\tconst proxy = proxyNodes.get(msg.s);\n\t\t\t\tif (proxy) proxy.down([[ERROR, deserializeError(msg.err)]]);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Lifecycle signal from main\n\t\t\tcase \"s\": {\n\t\t\t\tconst sig = nameToSignal(msg.sig);\n\t\t\t\tif (!sig) break;\n\n\t\t\t\tif (sig === TEARDOWN && msg.s === \"*\") {\n\t\t\t\t\tdestroy();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst targets: Node<any>[] =\n\t\t\t\t\tmsg.s === \"*\"\n\t\t\t\t\t\t? [...proxyNodes.values()]\n\t\t\t\t\t\t: proxyNodes.has(msg.s)\n\t\t\t\t\t\t\t? [proxyNodes.get(msg.s)!]\n\t\t\t\t\t\t\t: [];\n\n\t\t\t\tfor (const proxy of targets) {\n\t\t\t\t\tproxy.down((msg.d === undefined ? [[sig]] : [[sig, msg.d]]) as Messages);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t});\n\n\t// -- Send ready message ----------------------------------------------------\n\t// `.cache` is a documented transport-boundary snapshot read here — not a\n\t// reactive access (§5.10 boundary).\n\tconst readyValues: Record<string, unknown> = {};\n\tfor (const [name, n] of exposeEntries) {\n\t\treadyValues[name] = n.cache;\n\t}\n\ttransport.post({ t: \"r\", stores: readyValues } satisfies BridgeMessage);\n\n\t// -- Destroy ---------------------------------------------------------------\n\tfunction destroy() {\n\t\tif (destroyed) return;\n\t\tdestroyed = true;\n\n\t\t// Cleanup: unsub effect first (stops sending), then expose listeners,\n\t\t// then unlisten on transport\n\t\tif (effectUnsub) effectUnsub();\n\t\tfor (const unsub of exposeUnsubs) unsub();\n\t\texposeUnsubs.length = 0;\n\t\tunlisten();\n\t\ttransport.terminate?.();\n\n\t\tlastSeenImportVersions.clear();\n\t\tproxyNodes.clear();\n\t}\n\n\treturn { destroy };\n}\n"],"mappings":"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","names":["buffer","node","cached","batch","batch","delay","last","sourceOpts","debounce","resolvePath","buffer","out","retry","isThenable","buffer","p","operatorOpts","clampNonNegative","isNode","isThenable","sourceOpts","retry","buffer","batch","seq","map","first","map","keepalive","node","node","take","keepaliveDerived","first","import_node_fs","import_node_path","isTransport"]}
|