@graphrefly/graphrefly 0.47.0 → 0.47.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/dist/base/composition/index.cjs +24 -16
  2. package/dist/base/composition/index.cjs.map +1 -1
  3. package/dist/base/composition/index.js +6 -6
  4. package/dist/base/index.cjs +142 -86
  5. package/dist/base/index.cjs.map +1 -1
  6. package/dist/base/index.js +11 -11
  7. package/dist/base/io/index.cjs +114 -68
  8. package/dist/base/io/index.cjs.map +1 -1
  9. package/dist/base/io/index.js +5 -5
  10. package/dist/base/sources/browser/index.cjs +13 -9
  11. package/dist/base/sources/browser/index.cjs.map +1 -1
  12. package/dist/base/sources/browser/index.js +13 -9
  13. package/dist/base/sources/browser/index.js.map +1 -1
  14. package/dist/base/sources/event/index.cjs +1 -1
  15. package/dist/base/sources/event/index.cjs.map +1 -1
  16. package/dist/base/sources/event/index.js +1 -1
  17. package/dist/base/sources/index.cjs +21 -13
  18. package/dist/base/sources/index.cjs.map +1 -1
  19. package/dist/base/sources/index.js +3 -3
  20. package/dist/base/sources/node/index.cjs +43 -37
  21. package/dist/base/sources/node/index.cjs.map +1 -1
  22. package/dist/base/sources/node/index.js +43 -37
  23. package/dist/base/sources/node/index.js.map +1 -1
  24. package/dist/{chunk-VLAGJZSL.js → chunk-3O3NKZJW.js} +2 -2
  25. package/dist/{chunk-YJ4U2D2C.js → chunk-446I4EGD.js} +9 -7
  26. package/dist/chunk-446I4EGD.js.map +1 -0
  27. package/dist/{chunk-DKNHAICT.js → chunk-5GVURVIG.js} +14 -8
  28. package/dist/chunk-5GVURVIG.js.map +1 -0
  29. package/dist/{chunk-2OB3CEJS.js → chunk-6MRSX3YK.js} +2 -2
  30. package/dist/{chunk-EVYY4X5A.js → chunk-6ZLCPUXS.js} +2 -2
  31. package/dist/{chunk-ZVXXDWIB.js → chunk-7AVQIGF6.js} +514 -33
  32. package/dist/chunk-7AVQIGF6.js.map +1 -0
  33. package/dist/{chunk-7EGRP2VX.js → chunk-7BULJTL6.js} +2 -2
  34. package/dist/{chunk-7EGRP2VX.js.map → chunk-7BULJTL6.js.map} +1 -1
  35. package/dist/{chunk-FW23JYNQ.js → chunk-CEVNQ74M.js} +2 -2
  36. package/dist/{chunk-CGHORL6G.js → chunk-DDTS7F5O.js} +7 -5
  37. package/dist/chunk-DDTS7F5O.js.map +1 -0
  38. package/dist/{chunk-OCUDSN63.js → chunk-EL5VHUGK.js} +79 -47
  39. package/dist/chunk-EL5VHUGK.js.map +1 -0
  40. package/dist/{chunk-4GYMCUDZ.js → chunk-EP4WVQLX.js} +5 -5
  41. package/dist/{chunk-SOOKUYVM.js → chunk-F7EKHR32.js} +13 -9
  42. package/dist/chunk-F7EKHR32.js.map +1 -0
  43. package/dist/{chunk-JKTC747G.js → chunk-FQSQONOU.js} +4 -4
  44. package/dist/{chunk-JGFRAFDL.js → chunk-FVINAAKA.js} +3 -3
  45. package/dist/{chunk-RAGGHLCV.js → chunk-GUNIRPEJ.js} +8 -6
  46. package/dist/{chunk-RAGGHLCV.js.map → chunk-GUNIRPEJ.js.map} +1 -1
  47. package/dist/{chunk-BU3SEFA5.js → chunk-IOJDYUA7.js} +2 -2
  48. package/dist/{chunk-Y52CS6YA.js → chunk-JA67ZQG2.js} +2 -2
  49. package/dist/{chunk-Y52CS6YA.js.map → chunk-JA67ZQG2.js.map} +1 -1
  50. package/dist/{chunk-DM4OMPWK.js → chunk-KNU73RZW.js} +2 -2
  51. package/dist/{chunk-GWRNLJNW.js → chunk-KRFGO5QH.js} +19 -15
  52. package/dist/{chunk-GWRNLJNW.js.map → chunk-KRFGO5QH.js.map} +1 -1
  53. package/dist/{chunk-Z4YXAUDN.js → chunk-KUFXLAEY.js} +11 -7
  54. package/dist/{chunk-Z4YXAUDN.js.map → chunk-KUFXLAEY.js.map} +1 -1
  55. package/dist/{chunk-Z6EGP5D7.js → chunk-LDCSZ72P.js} +2 -2
  56. package/dist/{chunk-5IMMNARC.js → chunk-MS3WPRJR.js} +37 -25
  57. package/dist/chunk-MS3WPRJR.js.map +1 -0
  58. package/dist/{chunk-CXANAIZU.js → chunk-N65E26UL.js} +3 -3
  59. package/dist/{chunk-O3MT7DYI.js → chunk-N6MNJNHB.js} +2 -2
  60. package/dist/{chunk-Q3EYOCZB.js → chunk-NPRP3MCV.js} +111 -2
  61. package/dist/chunk-NPRP3MCV.js.map +1 -0
  62. package/dist/{chunk-A7KV5UK4.js → chunk-OXD5LFQP.js} +2 -2
  63. package/dist/{chunk-ZT4WMQW4.js → chunk-PTWADEH3.js} +9 -7
  64. package/dist/chunk-PTWADEH3.js.map +1 -0
  65. package/dist/{chunk-IHTWQEDR.js → chunk-QFE5BQH7.js} +2 -2
  66. package/dist/{chunk-IHTWQEDR.js.map → chunk-QFE5BQH7.js.map} +1 -1
  67. package/dist/{chunk-22SG74BD.js → chunk-R6ZCSXKX.js} +3 -3
  68. package/dist/{chunk-PZWISPIQ.js → chunk-S7HN5FHL.js} +17 -11
  69. package/dist/chunk-S7HN5FHL.js.map +1 -0
  70. package/dist/{chunk-RJOG4IJU.js → chunk-T7SP3EYR.js} +18 -12
  71. package/dist/chunk-T7SP3EYR.js.map +1 -0
  72. package/dist/{chunk-4S53H2KR.js → chunk-VAZXUK6G.js} +2 -2
  73. package/dist/{chunk-IJRR6YAI.js → chunk-VLDRAMP7.js} +18 -12
  74. package/dist/chunk-VLDRAMP7.js.map +1 -0
  75. package/dist/{chunk-TNX5ZGDJ.js → chunk-VNXAF2KE.js} +4 -4
  76. package/dist/{chunk-EHRRQ4IC.js → chunk-VP3TIUDF.js} +2 -2
  77. package/dist/{chunk-6XZYT4SW.js → chunk-WGDEBIP4.js} +5 -5
  78. package/dist/{chunk-E5OZPDIW.js → chunk-X7BA5PWG.js} +7 -5
  79. package/dist/chunk-X7BA5PWG.js.map +1 -0
  80. package/dist/compat/index.cjs +1 -1
  81. package/dist/compat/index.cjs.map +1 -1
  82. package/dist/compat/index.js +2 -2
  83. package/dist/compat/nestjs/index.cjs +1 -1
  84. package/dist/compat/nestjs/index.cjs.map +1 -1
  85. package/dist/compat/nestjs/index.js +2 -2
  86. package/dist/index.cjs +1657 -982
  87. package/dist/index.cjs.map +1 -1
  88. package/dist/index.d.cts +2 -2
  89. package/dist/index.d.ts +2 -2
  90. package/dist/index.js +58 -36
  91. package/dist/index.js.map +1 -1
  92. package/dist/presets/ai/index.cjs +42 -26
  93. package/dist/presets/ai/index.cjs.map +1 -1
  94. package/dist/presets/ai/index.js +11 -11
  95. package/dist/presets/harness/index.cjs +53 -33
  96. package/dist/presets/harness/index.cjs.map +1 -1
  97. package/dist/presets/harness/index.js +22 -22
  98. package/dist/presets/index.cjs +76 -48
  99. package/dist/presets/index.cjs.map +1 -1
  100. package/dist/presets/index.js +28 -28
  101. package/dist/presets/inspect/index.cjs.map +1 -1
  102. package/dist/presets/inspect/index.js +4 -4
  103. package/dist/presets/resilience/index.cjs +35 -23
  104. package/dist/presets/resilience/index.cjs.map +1 -1
  105. package/dist/presets/resilience/index.js +5 -5
  106. package/dist/solutions/index.cjs +71 -45
  107. package/dist/solutions/index.cjs.map +1 -1
  108. package/dist/solutions/index.js +24 -24
  109. package/dist/{timeout-U5O4ESK3.js → timeout-BEABACRP.js} +2 -2
  110. package/dist/utils/ai/browser.cjs.map +1 -1
  111. package/dist/utils/ai/browser.js +9 -9
  112. package/dist/utils/ai/index.cjs +41 -25
  113. package/dist/utils/ai/index.cjs.map +1 -1
  114. package/dist/utils/ai/index.js +18 -18
  115. package/dist/utils/ai/node.js +3 -3
  116. package/dist/utils/domain-templates/index.cjs +1 -1
  117. package/dist/utils/domain-templates/index.cjs.map +1 -1
  118. package/dist/utils/domain-templates/index.js +2 -2
  119. package/dist/utils/graphspec/index.cjs +1 -1
  120. package/dist/utils/graphspec/index.cjs.map +1 -1
  121. package/dist/utils/graphspec/index.js +2 -2
  122. package/dist/utils/harness/index.cjs +16 -10
  123. package/dist/utils/harness/index.cjs.map +1 -1
  124. package/dist/utils/harness/index.js +1 -1
  125. package/dist/utils/index.cjs +1069 -452
  126. package/dist/utils/index.cjs.map +1 -1
  127. package/dist/utils/index.d.cts +2 -2
  128. package/dist/utils/index.d.ts +2 -2
  129. package/dist/utils/index.js +45 -23
  130. package/dist/utils/inspect/index.cjs.map +1 -1
  131. package/dist/utils/inspect/index.js +2 -2
  132. package/dist/utils/memory/index.cjs +513 -37
  133. package/dist/utils/memory/index.cjs.map +1 -1
  134. package/dist/utils/memory/index.d.cts +641 -3
  135. package/dist/utils/memory/index.d.ts +641 -3
  136. package/dist/utils/memory/index.js +19 -1
  137. package/dist/utils/messaging/index.cjs +109 -0
  138. package/dist/utils/messaging/index.cjs.map +1 -1
  139. package/dist/utils/messaging/index.d.cts +115 -2
  140. package/dist/utils/messaging/index.d.ts +115 -2
  141. package/dist/utils/messaging/index.js +5 -1
  142. package/dist/utils/orchestration/index.cjs +5 -3
  143. package/dist/utils/orchestration/index.cjs.map +1 -1
  144. package/dist/utils/orchestration/index.js +2 -2
  145. package/dist/utils/process/index.js +2 -2
  146. package/dist/utils/reduction/index.cjs +1 -1
  147. package/dist/utils/reduction/index.cjs.map +1 -1
  148. package/dist/utils/reduction/index.js +1 -1
  149. package/dist/utils/resilience/index.cjs +35 -23
  150. package/dist/utils/resilience/index.cjs.map +1 -1
  151. package/dist/utils/resilience/index.js +4 -4
  152. package/dist/utils/surface/index.cjs +1 -1
  153. package/dist/utils/surface/index.cjs.map +1 -1
  154. package/dist/utils/surface/index.js +3 -3
  155. package/package.json +1 -1
  156. package/dist/chunk-5IMMNARC.js.map +0 -1
  157. package/dist/chunk-CGHORL6G.js.map +0 -1
  158. package/dist/chunk-DKNHAICT.js.map +0 -1
  159. package/dist/chunk-E5OZPDIW.js.map +0 -1
  160. package/dist/chunk-IJRR6YAI.js.map +0 -1
  161. package/dist/chunk-OCUDSN63.js.map +0 -1
  162. package/dist/chunk-PZWISPIQ.js.map +0 -1
  163. package/dist/chunk-Q3EYOCZB.js.map +0 -1
  164. package/dist/chunk-RJOG4IJU.js.map +0 -1
  165. package/dist/chunk-SOOKUYVM.js.map +0 -1
  166. package/dist/chunk-YJ4U2D2C.js.map +0 -1
  167. package/dist/chunk-ZT4WMQW4.js.map +0 -1
  168. package/dist/chunk-ZVXXDWIB.js.map +0 -1
  169. /package/dist/{chunk-VLAGJZSL.js.map → chunk-3O3NKZJW.js.map} +0 -0
  170. /package/dist/{chunk-2OB3CEJS.js.map → chunk-6MRSX3YK.js.map} +0 -0
  171. /package/dist/{chunk-EVYY4X5A.js.map → chunk-6ZLCPUXS.js.map} +0 -0
  172. /package/dist/{chunk-FW23JYNQ.js.map → chunk-CEVNQ74M.js.map} +0 -0
  173. /package/dist/{chunk-4GYMCUDZ.js.map → chunk-EP4WVQLX.js.map} +0 -0
  174. /package/dist/{chunk-JKTC747G.js.map → chunk-FQSQONOU.js.map} +0 -0
  175. /package/dist/{chunk-JGFRAFDL.js.map → chunk-FVINAAKA.js.map} +0 -0
  176. /package/dist/{chunk-BU3SEFA5.js.map → chunk-IOJDYUA7.js.map} +0 -0
  177. /package/dist/{chunk-DM4OMPWK.js.map → chunk-KNU73RZW.js.map} +0 -0
  178. /package/dist/{chunk-Z6EGP5D7.js.map → chunk-LDCSZ72P.js.map} +0 -0
  179. /package/dist/{chunk-CXANAIZU.js.map → chunk-N65E26UL.js.map} +0 -0
  180. /package/dist/{chunk-O3MT7DYI.js.map → chunk-N6MNJNHB.js.map} +0 -0
  181. /package/dist/{chunk-A7KV5UK4.js.map → chunk-OXD5LFQP.js.map} +0 -0
  182. /package/dist/{chunk-22SG74BD.js.map → chunk-R6ZCSXKX.js.map} +0 -0
  183. /package/dist/{chunk-4S53H2KR.js.map → chunk-VAZXUK6G.js.map} +0 -0
  184. /package/dist/{chunk-TNX5ZGDJ.js.map → chunk-VNXAF2KE.js.map} +0 -0
  185. /package/dist/{chunk-EHRRQ4IC.js.map → chunk-VP3TIUDF.js.map} +0 -0
  186. /package/dist/{chunk-6XZYT4SW.js.map → chunk-WGDEBIP4.js.map} +0 -0
  187. /package/dist/{timeout-U5O4ESK3.js.map → timeout-BEABACRP.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/base/resilience/_internal.ts","../../src/base/resilience/backoff.ts","../../src/base/resilience/timeout.ts","../../src/base/index.ts","../../src/base/composition/backpressure.ts","../../src/base/composition/distill.ts","../../src/base/sources/async.ts","../../src/base/composition/external-register.ts","../../src/base/composition/materialize.ts","../../src/base/composition/observable.ts","../../src/base/composition/pubsub.ts","../../src/base/composition/single-from-any.ts","../../src/base/sources/settled.ts","../../src/base/composition/verifiable.ts","../../src/base/io/checkpoint.ts","../../src/base/io/clickhouse-watch.ts","../../src/base/io/csv.ts","../../src/base/io/_internal.ts","../../src/base/io/drizzle.ts","../../src/base/io/http.ts","../../src/base/resilience/status.ts","../../src/base/io/_sink.ts","../../src/base/io/kafka.ts","../../src/base/io/kysely.ts","../../src/base/io/mcp.ts","../../src/base/io/nats.ts","../../src/base/io/ndjson.ts","../../src/base/io/otel.ts","../../src/base/io/prisma.ts","../../src/base/io/prometheus.ts","../../src/base/io/pulsar.ts","../../src/base/io/rabbitmq.ts","../../src/base/io/redis-stream.ts","../../src/base/io/sqlite.ts","../../src/base/io/sse.ts","../../src/base/io/statsd.ts","../../src/base/io/syslog.ts","../../src/base/io/to-clickhouse.ts","../../src/base/io/to-file.ts","../../src/base/io/to-csv.ts","../../src/base/io/to-loki.ts","../../src/base/io/to-mongo.ts","../../src/base/io/to-postgres.ts","../../src/base/io/to-s3.ts","../../src/base/io/to-tempo.ts","../../src/base/io/webhook.ts","../../src/base/io/websocket.ts","../../src/base/resilience/retry.ts","../../src/base/meta/domain-meta.ts","../../src/base/meta/emit-to-meta.ts","../../src/base/mutation/index.ts","../../src/base/render/_ascii-width.ts","../../src/base/render/_ascii-grid.ts","../../src/base/render/_layout-sugiyama.ts","../../src/base/render/graph-spec-to-ascii.ts","../../src/base/render/_internal.ts","../../src/base/render/graph-spec-to-d2.ts","../../src/base/render/graph-spec-to-json.ts","../../src/base/render/graph-spec-to-mermaid.ts","../../src/base/render/graph-spec-to-mermaid-url.ts","../../src/base/render/graph-spec-to-pretty.ts","../../src/base/render/layout-frame-to-svg.ts","../../src/base/sources/event/cron.ts","../../src/base/utils/decay.ts","../../src/base/worker/bridge.ts","../../src/base/worker/protocol.ts","../../src/base/worker/transport.ts","../../src/base/worker/self.ts"],"sourcesContent":["/**\n * Internal helpers shared by resilience sub-files.\n *\n * Not part of the public surface. The base-layer resilience operators\n * co-located here (`retry.ts`, `status.ts`, `timeout.ts`) import what they\n * need from this file directly; the utils-layer resilience primitives that\n * stayed in `utils/resilience/` (`breaker.ts`, `rate-limiter.ts`,\n * `fallback.ts`) import it top-down via `../../base/resilience/_internal.js`.\n *\n * `NodeOrValue<T>` is the only export re-surfaced publicly — there is no\n * `base/resilience/index.ts`; it ships through `utils/resilience/index.ts`\n * (and `utils/memory/index.ts`). Every resilience primitive that accepts\n * reactive options uses it as the option-arg shape.\n */\n\nimport type { Node, NodeOptions } from \"@graphrefly/pure-ts/core\";\nimport { DATA, type Message } from \"@graphrefly/pure-ts/core\";\n\nexport type ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nexport function operatorOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"derived\", ...opts } as NodeOptions<T>;\n}\n\nexport function clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nexport function msgVal(m: Message): unknown {\n\treturn m[1];\n}\n\nexport function 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 function 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 * Either a literal value or a reactive Node carrying it. Mirrors\n * {@link FallbackInput}'s precedent for \"options that may be reactive.\"\n *\n * Used by {@link timeout} / {@link retry} / {@link rateLimiter} /\n * {@link circuitBreaker} / {@link budgetGate} to accept reactive option\n * configurations (Tier 6.5 3.2, 2026-04-29). Each primitive subscribes\n * to the option Node via {@link resolveReactiveOption} and rebinds\n * internal state per its locked swap-semantic rule (see each primitive's\n * JSDoc for the rule).\n *\n * @category extra\n */\nexport type NodeOrValue<T> = T | Node<T>;\n\n/**\n * Closure-mirror helper for `NodeOrValue<T>` options\n * (COMPOSITION-GUIDE §28). Returns:\n * - `current()` — read the latest value (cached at construction; updated\n * on each Node DATA emission).\n * - `unsub()` — release the subscription. Static-form arg never\n * subscribes; `unsub` is a no-op there.\n *\n * `onChange` fires on each DATA after the initial value (skips the\n * cache-seed read). Use to rebind primitive-internal state per the\n * primitive's locked swap-semantic rule.\n *\n * @internal\n */\nexport function resolveReactiveOption<T>(\n\targ: NodeOrValue<T>,\n\tonChange?: (next: T) => void,\n): { current: () => T; unsub: () => void } {\n\tif (!isNode(arg)) {\n\t\treturn { current: () => arg, unsub: () => undefined };\n\t}\n\tconst node = arg as Node<T>;\n\tlet latest: T = node.cache as T;\n\tconst unsub = node.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA) {\n\t\t\t\tlatest = m[1] as T;\n\t\t\t\tif (onChange) onChange(latest);\n\t\t\t}\n\t\t}\n\t});\n\treturn {\n\t\tcurrent: () => latest,\n\t\tunsub,\n\t};\n}\n\nexport function isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nexport function 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 * 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 * Timeout — emits `ERROR` with `TimeoutError` if no `DATA` arrives within the deadline.\n *\n * §3.1c — caching, fallback & composition sugar. Uses\n * `core/clock.js`-style nanoseconds and a `ResettableTimer` so the deadline\n * resets on each DATA. Distinct from the `operators/control.ts` timeout\n * (which forwards a caller-supplied error/value) — this one is the\n * resilience family's \"deadline → ERROR\" primitive.\n *\n * **DS-13.5.B (locked 2026-05-01).** Pre-1.0 break: returns\n * {@link TimeoutBundle} with `node` + `timeoutState` companion. Opts\n * accept `Partial<TimeoutOptions>` or `Node<Partial<TimeoutOptions>>`\n * (object-shape, replacing the old `NodeOrValue<number>` flat shape).\n * State preservation across rebind: `ns` change does NOT reset the\n * in-flight deadline — new `ns` applies to next attempt only.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\tmonotonicNs,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport { isNode, operatorOpts } from \"./_internal.js\";\nimport { NS_PER_MS } from \"./backoff.js\";\n\n/**\n * Thrown by {@link withTimeout} 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\n/**\n * Options accepted by {@link withTimeout}.\n *\n * - `ns` — deadline in nanoseconds (must be `> 0`). Required at the\n * first opts settle; missing / non-positive values throw at\n * construction.\n * - `meta` — optional metadata merged onto the result node's `meta`\n * for describe()/explain() introspection. Reactive `meta` updates\n * are picked up on the next attempt's emission.\n *\n * @category extra/resilience\n */\nexport interface TimeoutOptions {\n\tns: number;\n\tmeta?: Record<string, unknown>;\n}\n\n/**\n * Lifecycle-shaped state companion emitted by {@link withTimeout}.\n *\n * Default `equals` dedups on the `status` field — subscribers don't\n * re-fire on identical-shape transitions, but DO fire on every state\n * transition AND on payload changes within the same status (e.g. when\n * `running.startedAt_ns` advances on a fresh attempt).\n *\n * @category extra/resilience\n */\nexport type TimeoutState =\n\t| { status: \"pending\" }\n\t| { status: \"running\"; startedAt_ns: number; deadline_ns: number }\n\t| { status: \"completed\"; settledAt_ns: number }\n\t| { status: \"errored\"; firedAt_ns: number; deadline_ns: number };\n\n/**\n * Bundle returned by {@link withTimeout}: the timeout-wrapped output node and\n * its lifecycle-shaped state companion.\n *\n * **Single-subscriber / pipeline-only contract (DS-13.5.B QA, N1, 2026-05-03).**\n * The `timeoutState` companion is allocated once at factory time and shared\n * across all subscribers to `node`. With one subscriber (the typical use\n * case — wire `node` into your downstream chain, optionally observe\n * `timeoutState` separately) the companion reflects a coherent timeline.\n * With **two or more subscribers** to `node`, each subscriber re-runs the\n * producer body and writes into the same `timeoutState`, which can flip\n * between states from different in-flight machines. Don't fan out\n * `node` to multiple subscribers and rely on `timeoutState` accuracy\n * unless you use {@link keepalive} / {@link share}-style consolidation.\n *\n * @category extra/resilience\n */\nexport interface TimeoutBundle<T> {\n\tnode: Node<T>;\n\ttimeoutState: Node<TimeoutState>;\n}\n\ninterface TimeoutExtraOpts {\n\tmeta?: Record<string, unknown>;\n}\n\n/**\n * Wrap `source` with a deadline. If no `DATA` arrives within `opts.ns`\n * nanoseconds, the result node emits `[[ERROR, TimeoutError]]` and\n * transitions `timeoutState` to `\"errored\"`.\n *\n * The timer starts on subscription and resets on each `DATA`. `DIRTY`\n * does NOT reset the timer. Terminal messages (`COMPLETE` / `ERROR`)\n * cancel the timer.\n *\n * **Reactive opts (DS-13.5.B, locked 2026-05-01).**\n *\n * - Static-form callers pass `Partial<TimeoutOptions>` (today's path).\n * `ns` is validated at construction; missing / non-positive throws\n * `RangeError`.\n * - Reactive-form callers pass `Node<Partial<TimeoutOptions>>` — each\n * emission shallow-merges over the prior opts. Empty `{}` emissions\n * are no-ops (no rebind, no companion fire). Mid-flight opts swap\n * does NOT reset the in-flight deadline; new `ns` applies to the\n * next `startTimer()` call.\n * - When the opts Node has `cache === undefined` (SENTINEL: no opts\n * emitted yet), the source is paused until the first valid opts\n * settle. The first valid settle must carry `ns > 0` or the timer\n * layer emits an ERROR (downstream observable) — distinct from the\n * construction-time `RangeError` thrown for static / cache-defined\n * invalid values.\n *\n * @param source - Upstream node.\n * @param opts - `Partial<TimeoutOptions>` (static) or\n * `Node<Partial<TimeoutOptions>>` (reactive).\n * @param extraOpts - Forwarded factory metadata (meta field merged\n * onto the result node).\n * @returns {@link TimeoutBundle} with `node` and `timeoutState`.\n *\n * @throws {RangeError} when the first opts settle is missing or has\n * non-positive `ns`.\n *\n * @category extra\n */\nexport function withTimeout<T>(\n\tsource: Node<T>,\n\topts: Partial<TimeoutOptions> | Node<Partial<TimeoutOptions>>,\n\textraOpts?: TimeoutExtraOpts,\n): TimeoutBundle<T> {\n\tconst isReactive = isNode(opts);\n\n\t// Construction-time validation:\n\t// - Static form: validate the supplied object eagerly.\n\t// - Node form with defined cache: validate the cache value eagerly.\n\t// - Node form with `cache === undefined`: defer validation to first\n\t// DATA emission; source is paused in the meantime.\n\tlet latestOpts: TimeoutOptions | null = null;\n\tif (!isReactive) {\n\t\tconst staticOpts = opts as Partial<TimeoutOptions>;\n\t\tif (\n\t\t\tstaticOpts.ns === undefined ||\n\t\t\ttypeof staticOpts.ns !== \"number\" ||\n\t\t\t!Number.isFinite(staticOpts.ns) ||\n\t\t\tstaticOpts.ns <= 0\n\t\t) {\n\t\t\tthrow new RangeError(\"withTimeout: opts.ns must be a positive finite number\");\n\t\t}\n\t\tlatestOpts = {\n\t\t\tns: staticOpts.ns,\n\t\t\t...(staticOpts.meta != null ? { meta: staticOpts.meta } : {}),\n\t\t};\n\t} else {\n\t\tconst cached = (opts as Node<Partial<TimeoutOptions>>).cache as\n\t\t\t| Partial<TimeoutOptions>\n\t\t\t| undefined;\n\t\tif (cached !== undefined) {\n\t\t\tif (\n\t\t\t\tcached.ns === undefined ||\n\t\t\t\ttypeof cached.ns !== \"number\" ||\n\t\t\t\t!Number.isFinite(cached.ns) ||\n\t\t\t\tcached.ns <= 0\n\t\t\t) {\n\t\t\t\tthrow new RangeError(\n\t\t\t\t\t\"withTimeout: opts.ns must be a positive finite number on first settle\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tlatestOpts = {\n\t\t\t\tns: cached.ns,\n\t\t\t\t...(cached.meta != null ? { meta: cached.meta } : {}),\n\t\t\t};\n\t\t}\n\t}\n\n\tconst callerMeta = extraOpts?.meta;\n\tconst factoryArgs: Record<string, unknown> = isReactive\n\t\t? { ns: \"Node<Partial<TimeoutOptions>>\" }\n\t\t: { ns: latestOpts!.ns };\n\n\t// Companion state node — lifecycle-shaped. Default Object.is-on-status\n\t// dedup so identical-shape transitions don't re-fire downstream.\n\tconst timeoutState = node<TimeoutState>([], {\n\t\tname: \"timeoutState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: { status: \"pending\" },\n\t\tequals: (a, b) =>\n\t\t\ta === b ||\n\t\t\t(a != null &&\n\t\t\t\tb != null &&\n\t\t\t\ttypeof a === \"object\" &&\n\t\t\t\ttypeof b === \"object\" &&\n\t\t\t\t(a as { status: string }).status === (b as { status: string }).status &&\n\t\t\t\tJSON.stringify(a) === JSON.stringify(b)),\n\t});\n\n\tconst out = node<T>(\n\t\t(_data, a) => {\n\t\t\tlet stopped = false;\n\t\t\tlet lastDeadlineNs = 0;\n\t\t\tconst timer = new ResettableTimer();\n\t\t\tlet optsUnsub: (() => void) | null = null;\n\t\t\tlet srcUnsub: (() => void) | null = null;\n\n\t\t\tfunction emitState(next: TimeoutState): void {\n\t\t\t\ttimeoutState.down([[DIRTY], [DATA, next]]);\n\t\t\t}\n\n\t\t\tfunction startTimer(): void {\n\t\t\t\tif (stopped) return;\n\t\t\t\t// QA A4 (2026-05-03): defensive guard — `latestOpts.ns`\n\t\t\t\t// reaching `undefined` / `NaN` / non-finite is a Class-of-\n\t\t\t\t// bugs source: an explicit `{ ns: undefined }` emit would\n\t\t\t\t// pass the per-key validation (which only checks\n\t\t\t\t// `next.ns !== undefined`) and shallow-merge over a valid\n\t\t\t\t// prior `ns`. Without this guard, `delayMs = NaN`, which\n\t\t\t\t// `setTimeout` treats as `0` → spurious immediate timeout.\n\t\t\t\tif (\n\t\t\t\t\tlatestOpts == null ||\n\t\t\t\t\ttypeof latestOpts.ns !== \"number\" ||\n\t\t\t\t\t!Number.isFinite(latestOpts.ns) ||\n\t\t\t\t\tlatestOpts.ns <= 0\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst ns = latestOpts.ns;\n\t\t\t\tlastDeadlineNs = ns;\n\t\t\t\tconst startedAt = monotonicNs();\n\t\t\t\tconst delayMs = ns / NS_PER_MS;\n\t\t\t\temitState({\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\tstartedAt_ns: startedAt,\n\t\t\t\t\tdeadline_ns: ns,\n\t\t\t\t});\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\tsrcUnsub?.();\n\t\t\t\t\temitState({\n\t\t\t\t\t\tstatus: \"errored\",\n\t\t\t\t\t\tfiredAt_ns: monotonicNs(),\n\t\t\t\t\t\tdeadline_ns: ns,\n\t\t\t\t\t});\n\t\t\t\t\ta.down([[ERROR, new TimeoutError(ns)]]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction attachSource(): void {\n\t\t\t\tif (srcUnsub != null || stopped) return;\n\t\t\t\tsrcUnsub = source.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (stopped) return;\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\tstartTimer();\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\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\temitState({\n\t\t\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\t\t\tsettledAt_ns: monotonicNs(),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\temitState({\n\t\t\t\t\t\t\t\tstatus: \"errored\",\n\t\t\t\t\t\t\t\tfiredAt_ns: monotonicNs(),\n\t\t\t\t\t\t\t\tdeadline_ns: lastDeadlineNs,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\ta.down([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\t// Kick the initial timer if we already have valid opts.\n\t\t\t\tif (latestOpts != null && latestOpts.ns > 0) {\n\t\t\t\t\tstartTimer();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isReactive) {\n\t\t\t\tconst optsNode = opts as Node<Partial<TimeoutOptions>>;\n\t\t\t\toptsUnsub = optsNode.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\t\t\tconst next = m[1] as Partial<TimeoutOptions>;\n\t\t\t\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\t\t\t\t// Empty `{}` emit is a no-op (lock spec).\n\t\t\t\t\t\tconst keys = Object.keys(next);\n\t\t\t\t\t\tif (keys.length === 0) continue;\n\t\t\t\t\t\t// QA A4 (2026-05-03): validate ns whenever it APPEARS\n\t\t\t\t\t\t// in the emit's keys — including `{ ns: undefined }`,\n\t\t\t\t\t\t// which would otherwise skip validation and shallow-\n\t\t\t\t\t\t// merge over a valid prior `ns` with `undefined`,\n\t\t\t\t\t\t// producing `delayMs = NaN` ≈ 0 ms in startTimer().\n\t\t\t\t\t\t// `'ns' in next` covers both \"explicitly undefined\"\n\t\t\t\t\t\t// and \"explicitly invalid\" forms.\n\t\t\t\t\t\tif (\"ns\" in next) {\n\t\t\t\t\t\t\tif (typeof next.ns !== \"number\" || !Number.isFinite(next.ns) || next.ns <= 0) {\n\t\t\t\t\t\t\t\tif (latestOpts == null) {\n\t\t\t\t\t\t\t\t\t// First settle invalid — emit ERROR rather\n\t\t\t\t\t\t\t\t\t// than throw (mid-subscribe; sync throw\n\t\t\t\t\t\t\t\t\t// would corrupt the host scheduler).\n\t\t\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\t\t\ta.down([\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\tERROR,\n\t\t\t\t\t\t\t\t\t\t\tnew RangeError(\n\t\t\t\t\t\t\t\t\t\t\t\t\"withTimeout: opts.ns must be a positive finite number on first settle\",\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Ignore invalid mid-flight ns updates; keep\n\t\t\t\t\t\t\t\t// prior latestOpts.\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst wasNull = latestOpts == null;\n\t\t\t\t\t\tlatestOpts = {\n\t\t\t\t\t\t\t...(latestOpts ?? { ns: 0 }),\n\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t} as TimeoutOptions;\n\t\t\t\t\t\t// First valid settle activates the source attach.\n\t\t\t\t\t\tif (wasNull && latestOpts.ns > 0) {\n\t\t\t\t\t\t\tattachSource();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Static form: attach immediately. Reactive form with defined\n\t\t\t// cache also attaches immediately (latestOpts pre-populated).\n\t\t\tif (latestOpts != null) {\n\t\t\t\tattachSource();\n\t\t\t}\n\n\t\t\treturn () => {\n\t\t\t\tstopped = true;\n\t\t\t\ttimer.cancel();\n\t\t\t\tif (srcUnsub) srcUnsub();\n\t\t\t\tif (optsUnsub) optsUnsub();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t\tmeta: { ...(callerMeta ?? {}), ...factoryTag(\"withTimeout\", factoryArgs) },\n\t\t},\n\t);\n\n\treturn { node: out, timeoutState };\n}\n","/**\n * Base layer — domain-agnostic infrastructure.\n *\n * Exports: io, composition, mutation, worker, render, meta, sources, utils.\n *\n * Node-only subpath: @graphrefly/graphrefly/base/sources/node\n * Browser-only subpath: @graphrefly/graphrefly/base/sources/browser\n *\n * @module\n */\n\nexport * from \"./composition/index.js\";\nexport * from \"./io/index.js\";\nexport * from \"./meta/index.js\";\nexport * from \"./mutation/index.js\";\nexport * from \"./render/index.js\";\nexport * from \"./sources/index.js\";\nexport * from \"./utils/index.js\";\nexport * from \"./worker/index.js\";\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 \"@graphrefly/pure-ts/core\";\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 * Budget-constrained reactive memory composition (roadmap §3.2b).\n *\n * Moved to base/composition/distill.ts during cleave A2.\n */\n\nimport { batch, factoryTag, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport {\n\tfromAny,\n\ttype NodeInput,\n\ttype ReactiveMapBundle,\n\ttype ReactiveMapOptions,\n\treactiveMap,\n\tswitchMap,\n\twithLatestFrom,\n} from \"@graphrefly/pure-ts/extra\";\nimport { forEach } from \"../sources/async.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\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\n/**\n * Defensive snapshot → ReadonlyMap coercion (D2 /qa lock, Tier 9.1).\n *\n * `ReactiveMapBundle.entries` always emits a real `Map` on the live emit\n * path. The non-Map case happens on snapshot **restore**: the default\n * `JsonGraphCodec` serializes a `Map` to `null`/`{}`/`[]` depending on the\n * codec configuration, and `Graph.restore` writes that decoded value back\n * to the cache. A naive `(snapshot as ReadonlyMap) ?? new Map()` would\n * pass a plain object through and then `.entries()` / `.size` access would\n * silently yield wrong results (or throw). The runtime `instanceof Map`\n * check below restores the safety net the previous `mapFromSnapshot` helper\n * provided before its initial deletion in Tier 10.1.\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 *\n * **Tier 1.5.4 (Session A.5 lock, 2026-04-27):** `extractFn` receives the\n * source and existing-store as `Node`s. Distill calls `extractFn` ONCE at\n * wiring time and consumes the returned stream of extractions. The user\n * controls reactive composition — wrap with `switchMap` for cancel-on-new-input,\n * `mergeMap` for parallel, `derived` for sync transforms. See COMPOSITION-GUIDE\n * §40 for the recipe.\n */\nexport function distill<TRaw, TMem>(\n\tsource: NodeInput<TRaw>,\n\textractFn: (\n\t\traw: Node<TRaw>,\n\t\texisting: Node<ReadonlyMap<string, TMem>>,\n\t) => 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) : node<unknown>([], { initial: null });\n\n\t// `latestStore` (formerly a §28 closure-mirror) is no longer needed —\n\t// Phase 10.5 (`withLatestFrom` flipped to `partial: false`) fixed the\n\t// W1 initial-pair drop. `consolidate` now uses\n\t// `withLatestFrom(trigger, store.entries)` below to pair each trigger\n\t// with the latest store snapshot via a real reactive edge (visible in\n\t// `describe()`). The `mapFromSnapshot` transform runs inside the\n\t// switchMap fn body.\n\n\t// Tier 1.5.4: one-shot wire. User's `extractFn` returns the reactive\n\t// extraction stream — distill just `forEach`s and applies. No internal\n\t// switchMap; user picks the cancellation / queueing semantics.\n\tconst extractionStream = fromAny(\n\t\textractFn(sourceNode, store.entries as Node<ReadonlyMap<string, TMem>>),\n\t);\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 = node<string[]>(\n\t\t\t[store.entries],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\tconst snapshot = batch0 != null && batch0.length > 0 ? batch0.at(-1) : ctx.prevData[0];\n\t\t\t\tconst out: string[] = [];\n\t\t\t\tconst entries = mapFromSnapshot<TMem>(snapshot);\n\t\t\t\t// Clean up verdict subscriptions for removed keys.\n\t\t\t\tfor (const key of verdictUnsubs.keys()) {\n\t\t\t\t\tif (!entries.has(key)) {\n\t\t\t\t\t\tverdictUnsubs.get(key)!();\n\t\t\t\t\t\tverdictUnsubs.delete(key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (const [key, mem] of entries) {\n\t\t\t\t\tconst verdict = opts.evict!(key, mem);\n\t\t\t\t\tif (isNodeLike<boolean>(verdict)) {\n\t\t\t\t\t\t// Subscribe if not already — push-on-subscribe fires with\n\t\t\t\t\t\t// the verdict's current value on first subscribe, so an\n\t\t\t\t\t\t// already-true verdict deletes via the callback without\n\t\t\t\t\t\t// needing a `verdict.cache` read (closes P3 audit #3).\n\t\t\t\t\t\t// Future transitions to `true` flow through the same path.\n\t\t\t\t\t\tif (!verdictUnsubs.has(key)) {\n\t\t\t\t\t\t\tconst unsub = forEach(verdict, (val) => {\n\t\t\t\t\t\t\t\tif (val === true && store.has(key)) {\n\t\t\t\t\t\t\t\t\tstore.delete(key);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tverdictUnsubs.set(key, unsub);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof verdict === \"boolean\") {\n\t\t\t\t\t\tif (verdict) out.push(key);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthrow new TypeError(\"distill evict() must return boolean or Node<boolean>\");\n\t\t\t\t}\n\t\t\t\tactions.emit(out);\n\t\t\t},\n\t\t\t{ describeKind: \"derived\" },\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 consolidatePaired = withLatestFrom(\n\t\t\tconsolidateTriggerNode,\n\t\t\tstore.entries as Node<unknown>,\n\t\t);\n\t\tconst consolidationStream = switchMap(consolidatePaired, ([, entries]) =>\n\t\t\topts.consolidate!(mapFromSnapshot<TMem>(entries)),\n\t\t);\n\t\tforEach(consolidationStream, (extraction) => {\n\t\t\tapplyExtraction(store, extraction);\n\t\t});\n\t}\n\n\tconst compact = node<Array<{ key: string; value: TMem; score: number }>>(\n\t\t[store.entries, contextNode],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst snapshot = data[0];\n\t\t\tconst context = data[1];\n\t\t\tconst map = mapFromSnapshot<TMem>(snapshot);\n\t\t\tconst entries = [...map.entries()].map(([key, value]) => ({\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t\tscore: opts.score(value, context),\n\t\t\t\tcost: opts.cost(value),\n\t\t\t}));\n\t\t\tentries.sort((a, b) => b.score - a.score);\n\n\t\t\tconst packed: Array<{ key: string; value: TMem; score: number }> = [];\n\t\t\tlet remaining = budget;\n\t\t\tfor (const item of entries) {\n\t\t\t\tif (item.cost <= remaining) {\n\t\t\t\t\tpacked.push({ key: item.key, value: item.value, score: item.score });\n\t\t\t\t\tremaining -= item.cost;\n\t\t\t\t}\n\t\t\t}\n\t\t\tactions.emit(packed);\n\t\t},\n\t\t{ describeKind: \"derived\", meta: { ...factoryTag(\"distill\", { budget }) } },\n\t);\n\n\tconst size = node<number>(\n\t\t[store.entries],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst batch0 = batchData[0];\n\t\t\tconst snapshot = batch0 != null && batch0.length > 0 ? batch0.at(-1) : ctx.prevData[0];\n\t\t\tactions.emit(mapFromSnapshot<TMem>(snapshot).size);\n\t\t},\n\t\t{ describeKind: \"derived\" },\n\t);\n\tkeepalive(compact);\n\tkeepalive(size);\n\n\treturn { store, compact, size };\n}\n","/**\n * Async sources, sinks, and multicast — presentation layer.\n *\n * `fromPromise`, `fromAsyncIter`, `fromAny` are substrate primitives; they are\n * re-exported here from `@graphrefly/pure-ts` for ergonomic single-import use.\n * This file owns the presentation-only async utilities: `defer`, `forEach`,\n * `toArray`, `share`, `replay`, `cached`, `shareReplay`.\n *\n * `singleFromAny` and `singleNodeFromAny` (keyed singleflight) live in\n * `base/composition/single-from-any.ts`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tRESOLVED,\n\tSTART,\n} from \"@graphrefly/pure-ts/core\";\nimport { type AsyncSourceOpts, type NodeInput, sourceOpts } from \"@graphrefly/pure-ts/extra\";\n\n/** Options for presentation-layer async operators: NodeOptions without `describeKind`. */\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\n// Import fromAny from substrate — used internally by defer. The three async\n// substrate sources (fromAny, fromAsyncIter, fromPromise) are already\n// re-exported from @graphrefly/pure-ts; do NOT re-export here to avoid\n// duplicate-export conflicts at the root barrel level.\nimport { fromAny } from \"@graphrefly/pure-ts/extra\";\n\n/**\n * Lazily constructs a {@link Node} from a thunk that runs at **activation\n * time** (first subscriber after a teardown to zero sinks), not factory time.\n *\n * **Resubscribable by default.** Diverges from `fromPromise` / `fromIter` /\n * `fromAsyncIter` (which are single-shot — second subscriber sees the cached\n * terminal value). `defer`'s contract matches RxJS `defer`: every fresh\n * activation cycle re-runs the thunk. To opt out and get one-shot semantics,\n * pass `{ resubscribable: false }`.\n *\n * **Sharing across overlapping subscribers.** The thunk only re-runs on a\n * fresh activation cycle (zero → one sink). Overlapping subscribers share\n * the single activation; the thunk does NOT re-run for each subscriber. If\n * the thunk returns an existing `Node`, that Node is shared across activations\n * — `defer` will subscribe to it on each activation but does not isolate state\n * across subscribers. For per-subscriber isolation, the thunk must construct\n * a fresh source (`state(...)`, `fromPromise(fetch(...))`, etc.) on each call.\n *\n * **Use cases:**\n * - Lazy upstream construction (avoid eager evaluation of expensive factories\n * at module load — the thunk runs only when something subscribes).\n * - Per-activation resource construction (open a connection / file handle on\n * subscribe, when paired with full teardown between sessions).\n * - Bridging non-Node inputs (Promise, AsyncIterable, Iterable, scalar) into\n * the graph behind a lazy boundary.\n *\n * The thunk's return value is bridged via {@link fromAny}. Errors thrown by\n * the thunk surface as a single `[[ERROR, err]]` on the output (with `err`\n * coerced to a non-`undefined` value to satisfy spec §1.3 — bare `throw` and\n * `throw undefined` are wrapped in a `defer: thunk threw undefined` Error).\n *\n * Upstream messages are forwarded transparently (DIRTY / DATA / RESOLVED /\n * COMPLETE / ERROR / INVALIDATE / PAUSE / RESUME / TEARDOWN), preserving\n * batch boundaries. The producer's own `START` handshake is delivered to\n * subscribers automatically; the upstream's `START` is filtered.\n *\n * @param thunk - Called on each activation; returns the upstream input.\n * @param opts - Forwarded to `fromAny` (e.g. `signal` for async inputs).\n * `signal` is only consumed by `fromAny` for async input shapes (Promise,\n * AsyncIterable); it does NOT abort a Node-input or scalar-input defer.\n * @returns `Node<T>` — lazy upstream-on-activation.\n *\n * @example\n * ```ts\n * import { defer } from \"@graphrefly/graphrefly-ts\";\n *\n * // Lazy fetch — runs on the first activation, NOT at factory time.\n * // Each fresh activation cycle (after teardown) re-runs the thunk →\n * // a new fetch. Overlapping subscribers share the single activation.\n * const live = defer(() => fetch(\"/api/feed\").then((r) => r.json()));\n * ```\n *\n * @category extra\n */\nexport function defer<T>(thunk: () => NodeInput<T>, opts?: AsyncSourceOpts): Node<T> {\n\t// A4: strip `signal` before forwarding to NodeOptions — sibling sources\n\t// (fromTimer / fromPromise / fromAsyncIter) destructure first; signal\n\t// continues to flow into fromAny(input, opts) for async input shapes.\n\tconst { signal: _sig, ...nodeOpts } = (opts ?? {}) as AsyncSourceOpts;\n\tconst sOpts = sourceOpts<T>(nodeOpts);\n\tconst merged = sOpts.resubscribable === undefined ? { ...sOpts, resubscribable: true } : sOpts;\n\treturn node<T>((_data, a) => {\n\t\tlet unsub: (() => void) | undefined;\n\t\tlet stopped = false;\n\t\ttry {\n\t\t\tconst input = thunk();\n\t\t\t// `iter: true` preserves defer's RxJS-aligned per-element\n\t\t\t// streaming for sync iterable thunk returns (post DS-13.5\n\t\t\t// fromAny default flip; defer's documented contract is\n\t\t\t// \"forwards iterable values\" per-element).\n\t\t\tconst src = fromAny(input, { ...opts, iter: true });\n\t\t\tunsub = src.subscribe((msgs) => {\n\t\t\t\tif (stopped) return;\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 === START) continue; // producer's own START is delivered separately\n\t\t\t\t\tif (t === DATA) {\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (t === COMPLETE) {\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\tbreak; // A2: don't forward post-terminal messages in the same batch\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([[ERROR, m[1]]]);\n\t\t\t\t\t\tbreak; // A2\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Forward DIRTY / RESOLVED / INVALIDATE / PAUSE / RESUME /\n\t\t\t\t\t\t// TEARDOWN, plus any unknown types (spec §1.3.6 forward-compat).\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} catch (err) {\n\t\t\t// A5: spec §1.3 — ERROR payload must not be undefined. Wrap a\n\t\t\t// `throw` or `throw undefined` so dispatch doesn't reject the emit.\n\t\t\tconst safe = err === undefined ? new Error(\"defer: thunk threw undefined\") : err;\n\t\t\ta.down([[ERROR, safe]]);\n\t\t}\n\t\treturn () => {\n\t\t\tstopped = true;\n\t\t\tunsub?.();\n\t\t};\n\t}, merged);\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\t// Lock 6.D (Phase 13.6.B): clear the accumulator buffer on\n\t// deactivation so a resubscribable toArray restarts with an empty\n\t// array on the next cycle — pre-flip this came for free via\n\t// `_deactivate`'s store wipe.\n\tlet cleanup: { onDeactivation: () => void } | undefined;\n\treturn node<T[]>(\n\t\t[source as Node],\n\t\t(data, actions, ctx) => {\n\t\t\tif (cleanup === undefined) {\n\t\t\t\tconst store = ctx.store;\n\t\t\t\tcleanup = {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tdelete store.buf;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\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 cleanup;\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\treturn cleanup;\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 node<T>(\n\t\t(_data, 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\t// Spec §2.5 / Lock 6.G: the built-in `replayBuffer` NodeOption retains the\n\t// last-N outgoing DATA and `defaultOnSubscribe` delivers them to a late\n\t// subscriber INSTEAD of the cache-DATA push — so there is no double-deliver\n\t// of the most-recent value. Supersedes the old `wrapSubscribeHook` +\n\t// manual-buffer pattern (which flushed the buffer AND then push-on-\n\t// subscribed the cache, double-delivering the last value).\n\treturn node<T>(\n\t\t(_data, 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, replayBuffer: bufferSize },\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// 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 * 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 {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n} from \"@graphrefly/pure-ts/core\";\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 node<T>((_data, 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 = node<TChannels[typeof ch]>(\n\t\t\t(_data, _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 * Phase 13.C — `selector` + `materialize` composers (DS-13.C / G2 lock C).\n *\n * Two paired primitives for dynamic-mount routing:\n *\n * - {@link selector} — projects an input value to a routing key, deduped.\n * Equivalent to `map + distinctUntilChanged`, but the dedup is the\n * semantic point: the key changes ONLY when the routed-to slot should\n * change. Fires `materialize` re-mounts efficiently.\n *\n * - {@link materialize} — given a reactive `key` and a reactive map of\n * `key → factory` thunks, mounts the matching factory's Graph under\n * `parent` at a stable slot name. When `key` changes, unmounts the old\n * slot and mounts the new factory's output. When `factories` mutates but\n * `key` stays the same, the current slot continues to run on the OLD\n * factory (\"current sessions complete on old factory; new sessions use\n * new factory\" — full hot-swap correctness deferred to G10, parked).\n *\n * Reusable beyond the agent layer:\n * - `harnessLoop` strategy routing — the strategy node IS a `selector`.\n * - `pipelineGraph` dynamic stage selection.\n * - `refineLoop` strategy swap.\n * - Phase 13.I `spawnable()` mounts agent slots via `materialize`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\tfactoryTag,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport type { Graph } from \"@graphrefly/pure-ts/graph\";\n\n/** Options for operator nodes: NodeOptions without `describeKind` (set internally). */\nexport type 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// selector\n// ---------------------------------------------------------------------------\n\n/** Options for {@link selector}. */\nexport type SelectorOpts<TKey> = ExtraOpts & {\n\t/**\n\t * Equality comparator for the projected key. Defaults to {@link Object.is}.\n\t * Used to suppress re-emits when the input changes but the projected key\n\t * does not — this is the load-bearing behavior that lets downstream\n\t * `materialize` skip unnecessary unmount/remount cycles.\n\t */\n\tequals?: (a: TKey, b: TKey) => boolean;\n};\n\n/**\n * Projects each upstream value to a routing key, deduped on the key. The\n * output node emits a key only when the projected key actually changes —\n * pairs cleanly with {@link materialize}, which re-mounts only on key\n * change.\n *\n * **Differs from `map`:** `map(input, fn)` fires on every upstream wave\n * regardless of output value. `selector(input, fn)` fires only when the\n * projected key CHANGES (under `equals`), so downstream re-mount logic is\n * stable.\n *\n * @param input - Upstream node carrying the value to project.\n * @param fn - Synchronous projection function.\n * @param opts - Optional {@link SelectorOpts}.\n * @returns `Node<TKey>` carrying the latest projected key (deduped).\n *\n * @example\n * ```ts\n * import { selector, materialize, state } from \"@graphrefly/graphrefly-ts\";\n *\n * type Request = { kind: \"research\" | \"summarize\" | \"code\"; payload: unknown };\n * const requestNode = state<Request>({ kind: \"research\", payload: {} });\n *\n * const presetId = selector(requestNode, (req) => req.kind);\n * // presetId is `Node<\"research\" | \"summarize\" | \"code\">`, deduped.\n * // Downstream materialize re-mounts ONLY when the kind axis changes.\n * ```\n *\n * @category extra\n */\nexport function selector<TIn, TKey>(\n\tinput: Node<TIn>,\n\tfn: (input: TIn) => TKey,\n\topts?: SelectorOpts<TKey>,\n): Node<TKey> {\n\tconst equals = opts?.equals ?? Object.is;\n\t// Lock 6.D (Phase 13.6.B): clear prev/hasPrev on deactivation so a\n\t// resubscribable selector doesn't dedupe the next cycle's first\n\t// projected key against a stale prev from the prior cycle.\n\tlet cleanup: { onDeactivation: () => void } | undefined;\n\treturn node<TKey>(\n\t\t[input as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (cleanup === undefined) {\n\t\t\t\tconst store = ctx.store;\n\t\t\t\tcleanup = {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tdelete store.prev;\n\t\t\t\t\t\tdelete store.hasPrev;\n\t\t\t\t\t},\n\t\t\t\t};\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 cleanup;\n\t\t\t}\n\t\t\t// A11 (QA fix 2026-05-01): pre-pass — compute every projected\n\t\t\t// key + dedup decision FIRST, surface any user `equals` throw\n\t\t\t// as ERROR before any DATA goes out. The previous in-loop\n\t\t\t// emission interleaved partial DATA with ERROR mid-batch; that\n\t\t\t// left subscribers inconsistent (some had read the early DATA,\n\t\t\t// some treated ERROR as \"discard everything since RESOLVED\")\n\t\t\t// and left `ctx.store.prev` mutated to the last successful key,\n\t\t\t// which made selector \"stuck\" until the next throw-free batch.\n\t\t\tconst toEmit: TKey[] = [];\n\t\t\tlet prev: TKey | undefined = ctx.store.hasPrev ? (ctx.store.prev as TKey) : undefined;\n\t\t\tlet hasPrev = ctx.store.hasPrev;\n\t\t\tfor (const v of batch0 as TIn[]) {\n\t\t\t\tconst key = fn(v);\n\t\t\t\tif (hasPrev) {\n\t\t\t\t\tlet same: boolean;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tsame = equals(prev as TKey, key);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t// Pre-pass throw — abandon the whole batch (no DATA emits)\n\t\t\t\t\t\t// and surface ERROR. ctx.store stays at its pre-batch\n\t\t\t\t\t\t// state so the next batch starts from a known-good prev.\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\tif (same) continue;\n\t\t\t\t}\n\t\t\t\tprev = key;\n\t\t\t\thasPrev = true;\n\t\t\t\ttoEmit.push(key);\n\t\t\t}\n\t\t\tif (toEmit.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn cleanup;\n\t\t\t}\n\t\t\tctx.store.prev = prev as TKey;\n\t\t\tctx.store.hasPrev = true;\n\t\t\tfor (const k of toEmit) a.emit(k);\n\t\t\treturn cleanup;\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tmeta: { ...factoryTag(\"selector\"), ...(opts?.meta ?? {}) },\n\t\t},\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// materialize\n// ---------------------------------------------------------------------------\n\n/**\n * Factory thunk for a {@link materialize} slot. Called once per mount cycle\n * to mint a fresh `TGraph` instance. The instance is mounted under\n * `parent.mount(slotName, ...)` and unmounted via `parent.remove(slotName)`\n * when `key` next changes.\n *\n * Each invocation MUST return a fresh, never-before-mounted Graph instance —\n * `Graph.mount` rejects re-mounting an instance that is already mounted\n * elsewhere in the tree. Caching factory output is unsafe.\n */\nexport type GraphFactory<TGraph extends Graph> = () => TGraph;\n\n/** Options for {@link materialize}. */\nexport type MaterializeOpts = ExtraOpts & {\n\t/**\n\t * Local mount name on the parent graph. Default `\"materialized\"`.\n\t *\n\t * Two materialize calls on the SAME parent must use distinct `slotName`\n\t * values, otherwise the second mount throws \"mount already exists\".\n\t * For a hub mounting many slots (e.g. {@link spawnable}'s preset\n\t * registry), use `slotName: \\`preset-\\${id}\\`` or similar.\n\t */\n\tslotName?: string;\n};\n\n/**\n * Reactive dynamic mount: mounts the Graph instance for `key` under\n * `parent.mount(slotName, ...)`, and re-mounts when `key` changes.\n *\n * **Lifecycle.** First DATA on `key` triggers a mount: look up\n * `factories.get(key)`, call the factory thunk, mount the result under\n * `parent`. Each subsequent `key` change unmounts the previous slot and\n * mounts the new one. When this materialize node terminates (subscriber\n * teardown, `COMPLETE` from `key`, `Graph.destroy`), the active slot is\n * unmounted via `parent.remove(slotName)`.\n *\n * **Hot-swap policy (G10 deferred).** When `factories` mutates but `key`\n * stays the same, the currently-mounted slot is NOT re-instantiated —\n * \"current sessions complete on old factory; new sessions use new\n * factory.\" Atomic disconnect/reconnect of an in-flight slot to a new\n * factory is parked under G10 (see `optimizations.md` \"G10 atomic\n * registry hot-swap\").\n *\n * **Output.** The returned `Node<TGraph>` emits the currently-mounted\n * Graph reference whenever a mount occurs. Consumers can subscribe to\n * watch slot changes, or read `.cache` for the active mount. SENTINEL\n * (no DATA) when no slot is currently mounted (e.g. `key` has no matching\n * factory).\n *\n * **Spec compliance.**\n * - No polling: mount transitions are reactive on `key` / `factories`.\n * - No raw async: factory invocation is synchronous; if a factory needs\n * async setup, it returns a Graph that handles its own setup internally.\n * - Mount/unmount happens as side-effects inside the reactive `subscribe`\n * handler — sanctioned per spec §5.9 (Graph topology mutations are\n * imperative writes at the system boundary, not in-flight reactive\n * triggers).\n *\n * @param key - Reactive routing key. Re-mounts on each key change (deduped\n * by reference; pair with {@link selector} for projection-based dedup).\n * @param factories - Reactive map of `key → factory thunk`. Factory map\n * mutations don't disturb the active slot until the next key change.\n * @param parent - Graph to mount slots under. The `slotName` (default\n * `\"materialized\"`) must be free on `parent` at construction time.\n * @param opts - Optional {@link MaterializeOpts}.\n * @returns `Node<TGraph>` carrying the active mount.\n *\n * @example\n * ```ts\n * import { materialize, selector, state, Graph } from \"@graphrefly/graphrefly-ts\";\n *\n * const parent = new Graph(\"parent\");\n * const factories = state<ReadonlyMap<string, () => Graph>>(new Map([\n * [\"researcher\", () => new ResearchAgentGraph()],\n * [\"coder\", () => new CoderAgentGraph()],\n * ]));\n * const key = selector(requestNode, (r) => r.kind);\n * const slot = materialize(key, factories, parent, { slotName: \"agent\" });\n * // `slot.cache` is the active agent graph; `parent.node(\"agent::out\")`\n * // resolves into whichever agent is currently mounted.\n * ```\n *\n * @category extra\n */\nexport function materialize<TKey, TGraph extends Graph>(\n\tkey: Node<TKey>,\n\tfactories: Node<ReadonlyMap<TKey, GraphFactory<TGraph>>>,\n\tparent: Graph,\n\topts?: MaterializeOpts,\n): Node<TGraph> {\n\tconst slotName = opts?.slotName ?? \"materialized\";\n\treturn node<TGraph>(\n\t\t(_data, a) => {\n\t\t\tlet currentKey: TKey | undefined;\n\t\t\tlet hasCurrentKey = false;\n\t\t\tlet currentGraph: TGraph | undefined;\n\t\t\tlet latestFactories: ReadonlyMap<TKey, GraphFactory<TGraph>> | undefined;\n\t\t\tlet terminated = false;\n\n\t\t\tfunction unmountCurrent(): void {\n\t\t\t\tif (currentGraph === undefined) return;\n\t\t\t\ttry {\n\t\t\t\t\tparent.remove(slotName);\n\t\t\t\t} catch {\n\t\t\t\t\t// Slot already gone (parent destroyed, or external `remove`).\n\t\t\t\t}\n\t\t\t\tcurrentGraph = undefined;\n\t\t\t}\n\n\t\t\t// Closure mirror for the factories map. Subscribed FIRST so\n\t\t\t// `latestFactories` is populated by the time the first `key` DATA\n\t\t\t// arrives. Same §28 factory-time-seed pattern used elsewhere.\n\t\t\tconst facUnsub = factories.subscribe((msgs) => {\n\t\t\t\tif (terminated) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tlatestFactories = m[1] as ReadonlyMap<TKey, GraphFactory<TGraph>>;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Primary trigger: key DATA drives mount transitions.\n\t\t\tconst keyUnsub = key.subscribe((msgs) => {\n\t\t\t\tif (terminated) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tconst newKey = m[1] as TKey;\n\t\t\t\t\t\tconst keyChanged = !hasCurrentKey || newKey !== currentKey;\n\t\t\t\t\t\tif (keyChanged) {\n\t\t\t\t\t\t\tunmountCurrent();\n\t\t\t\t\t\t\tif (latestFactories !== undefined) {\n\t\t\t\t\t\t\t\tconst factory = latestFactories.get(newKey);\n\t\t\t\t\t\t\t\tif (factory !== undefined) {\n\t\t\t\t\t\t\t\t\tcurrentGraph = factory();\n\t\t\t\t\t\t\t\t\tparent.mount(slotName, currentGraph);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcurrentKey = newKey;\n\t\t\t\t\t\t\thasCurrentKey = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (currentGraph !== undefined) {\n\t\t\t\t\t\t\ta.emit(currentGraph);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\tterminated = 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\n\t\t\treturn () => {\n\t\t\t\tterminated = true;\n\t\t\t\tkeyUnsub();\n\t\t\t\tfacUnsub();\n\t\t\t\tunmountCurrent();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tmeta: { ...factoryTag(\"materialize\"), slotName, ...(opts?.meta ?? {}) },\n\t\t},\n\t);\n}\n","// ---------------------------------------------------------------------------\n// Observable bridge — reactive interop between GraphReFly nodes and the TC39\n// Observable contract (the well-known `Symbol.observable` / \"@@observable\"\n// method). **Zero runtime dependency on rxjs**: the returned value is a\n// spec-interop observable that rxjs `from()`, Angular, the NestJS compat\n// layer, and any `Symbol.observable` consumer can adopt. Consumers wanting\n// rxjs operators do `from(toObservable(node))`.\n//\n// Usage:\n// import { toObservable } from '@graphrefly/graphrefly/base';\n// import { from } from 'rxjs';\n// const values$ = from(toObservable(myNode)); // Observable<T>\n// const msgs$ = from(toObservable(myNode, { raw: true })); // Observable<Messages>\n// ---------------------------------------------------------------------------\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { COMPLETE, DATA, ERROR, type Messages } from \"@graphrefly/pure-ts/core\";\n\n/** Observer passed to {@link InteropObservable.subscribe}. */\nexport interface InteropObserver<T> {\n\tnext?(value: T): void;\n\terror?(err: unknown): void;\n\tcomplete?(): void;\n\t/** rxjs `Subscriber` sets this; we short-circuit delivery when closed. */\n\tclosed?: boolean;\n}\n\n/** Teardown handle returned by {@link InteropObservable.subscribe}. */\nexport interface InteropSubscription {\n\tunsubscribe(): void;\n}\n\n/**\n * Minimal TC39 Observable. rxjs `from()` (and any `Symbol.observable`\n * consumer) adopts it at runtime via the well-known interop method attached\n * by {@link toObservable}. Pass the result through `from(...)` to get a\n * pipeable rxjs `Observable`.\n */\nexport interface InteropObservable<T> {\n\tsubscribe(observer: InteropObserver<T> | ((value: T) => void)): InteropSubscription;\n}\n\n/** Options for {@link toObservable}. */\nexport type ToObservableOptions = {\n\t/**\n\t * When `true`, emit raw `Messages` batches instead of extracted `DATA`\n\t * values. Terminal batches are still emitted as the final `next()` before\n\t * the error/complete signal.\n\t */\n\traw?: boolean;\n};\n\n// Well-known Observable interop key. Mirrors the rxjs / `symbol-observable`\n// resolution (the global `Symbol.observable` when the runtime or a polyfill\n// provides it, otherwise the `\"@@observable\"` string) so rxjs `from()` adopts\n// our object regardless of polyfill state.\nconst OBSERVABLE_KEY: PropertyKey =\n\t(typeof Symbol === \"function\" && (Symbol as unknown as { observable?: symbol }).observable) ||\n\t\"@@observable\";\n\nfunction normalizeObserver<T>(\n\tobserver: InteropObserver<T> | ((value: T) => void),\n): InteropObserver<T> {\n\treturn typeof observer === \"function\" ? { next: observer } : observer;\n}\n\nfunction makeInterop<T>(\n\tonSubscribe: (observer: InteropObserver<T>) => () => void,\n): InteropObservable<T> {\n\tconst obs: InteropObservable<T> = {\n\t\tsubscribe(rawObserver): InteropSubscription {\n\t\t\tconst observer = normalizeObserver(rawObserver);\n\t\t\tlet closed = false;\n\t\t\tlet teardown: (() => void) | undefined;\n\t\t\tlet teardownPending = false;\n\t\t\tconst runTeardown = (): void => {\n\t\t\t\tif (teardown) teardown();\n\t\t\t\telse teardownPending = true; // sync push-on-subscribe terminal\n\t\t\t};\n\t\t\t// Guarded observer: latch `closed` and auto-unsubscribe the node on\n\t\t\t// terminal. The prior rxjs-backed impl got this from rxjs's\n\t\t\t// `Subscriber` (closed flag + teardown-on-terminal); a plain TC39\n\t\t\t// consumer has no such machinery, so without this a post-terminal\n\t\t\t// node wave would re-fire next/error/complete and the node\n\t\t\t// subscription would leak until a manual unsubscribe(). `closed` is\n\t\t\t// also read by toObservable's per-message loop to short-circuit.\n\t\t\tconst guarded: InteropObserver<T> = {\n\t\t\t\tget closed() {\n\t\t\t\t\treturn closed;\n\t\t\t\t},\n\t\t\t\tnext(value) {\n\t\t\t\t\tif (!closed) observer.next?.(value);\n\t\t\t\t},\n\t\t\t\terror(err) {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobserver.error?.(err);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\trunTeardown();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tcomplete() {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobserver.complete?.();\n\t\t\t\t\t} finally {\n\t\t\t\t\t\trunTeardown();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t\tteardown = onSubscribe(guarded);\n\t\t\tif (teardownPending) teardown(); // terminal fired before assignment\n\t\t\treturn {\n\t\t\t\tunsubscribe() {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\tteardown?.();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t};\n\t// TC39 interop: `x[Symbol.observable]()` returns the observable itself.\n\t(obs as unknown as Record<PropertyKey, unknown>)[OBSERVABLE_KEY] = function (\n\t\tthis: InteropObservable<T>,\n\t) {\n\t\treturn this;\n\t};\n\treturn obs;\n}\n\n/**\n * Bridge a `Node<T>` to a TC39 interop observable (no rxjs dependency).\n *\n * Default mode emits the node's value on each `DATA` message. Maps `ERROR` to\n * `observer.error()` and `COMPLETE` to `observer.complete()`.\n * Protocol-internal signals (DIRTY, RESOLVED, PAUSE, etc.) are skipped.\n *\n * With `{ raw: true }`, emits full `[[Type, Data?], ...]` message batches.\n * The stream terminates on ERROR or COMPLETE (the terminal batch is still\n * emitted as the final `next()` before the error/complete signal).\n *\n * The returned value is a spec-interop observable, **not** a concrete rxjs\n * `Observable`. Wrap with `from(toObservable(node))` for rxjs operators, or\n * use the NestJS compat layer's `toObservable` which returns a real rxjs\n * `Observable`. For graph-level observation, use\n * `toObservable(graph.resolve(path))` or subscribe to `graph.observe()`.\n *\n * Unsubscribing unsubscribes the node.\n */\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions & { raw?: false },\n): InteropObservable<T>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions: ToObservableOptions & { raw: true },\n): InteropObservable<Messages>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions,\n): InteropObservable<T | Messages> {\n\tif (options?.raw) {\n\t\treturn makeInterop<Messages>((observer) => {\n\t\t\treturn node.subscribe((msgs) => {\n\t\t\t\tif (observer.closed) return;\n\t\t\t\tobserver.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\tobserver.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\tobserver.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});\n\t}\n\n\treturn makeInterop<T>((observer) => {\n\t\treturn node.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (observer.closed) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tobserver.next?.(m[1] as T);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tobserver.error?.(m[1]);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tobserver.complete?.();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\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 * `utils/messaging` — built on `TopicGraph` / `SubscriptionGraph` with\n * retention policies, absolute cursor tracking, and per-subscriber state.\n *\n * Presentation layer (base/composition). Moved from pure-ts during cleave A3\n * (no substrate core/graph dependency on pubsub found).\n */\n\nimport { batch, type Node, node, TEARDOWN, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype PubSubChange,\n\ttype PubSubChangePayload,\n\ttype ReactiveLogBundle,\n\treactiveLog,\n} from \"@graphrefly/pure-ts/extra\";\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 * `utils/messaging`, which composes `TopicGraph` under a lazy registry.\n *\n * @category base\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 base\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\t/**\n\t * DS-14 / DS14R2 — opt-in delta companion. When set, the hub appends a\n\t * typed {@link PubSubChange} record in the **same batch frame** as the\n\t * topic emission / teardown (same-wave consistency — subscribers reading\n\t * both a topic and `mutationLog` never see torn state).\n\t *\n\t * Records the locked `PubSubChange` verbs that apply to this last-value\n\t * hub: `publish` (per `publish` / `publishMany`) and `remove` (per\n\t * `removeTopic`). The `ack` verb is a cursor concern of `messagingHub()`\n\t * and does not apply here. **Note:** the locked `publish` payload carries\n\t * `value` only (no topic name) — callers needing per-topic delta\n\t * correlation should embed identity in the value or use `messagingHub()`.\n\t *\n\t * `true` = defaults; object form forwards `maxSize` / `name` to the inner\n\t * `reactiveLog`.\n\t */\n\tmutationLog?: true | { maxSize?: number; name?: string };\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 base\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\t/**\n\t * DS14R2 — present iff `mutationLog` was configured. Append-only log of\n\t * `publish` / `remove` deltas, same-wave-consistent with topic emissions.\n\t */\n\treadonly mutationLog?: ReactiveLogBundle<PubSubChange>;\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 `messagingHub()` in `utils/messaging`.\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\";\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 base\n */\nexport function pubsub(options: PubSubHubOptions = {}): PubSubHub {\n\tconst { backend: userBackend, mutationLog: mutLogOpt } = options;\n\tconst backend: PubSubBackend = userBackend ?? new NativePubSubBackend();\n\tconst nodes = new Map<string, Node<unknown>>();\n\n\t// ── DS14R2 — mutation log companion ──────────────────────────────────────\n\tconst mutLog: ReactiveLogBundle<PubSubChange> | undefined = mutLogOpt\n\t\t? reactiveLog<PubSubChange>(undefined, {\n\t\t\t\tname: mutLogOpt === true ? \"pubsub.mutationLog\" : (mutLogOpt.name ?? \"pubsub.mutationLog\"),\n\t\t\t\tmaxSize: mutLogOpt === true ? undefined : mutLogOpt.maxSize,\n\t\t\t})\n\t\t: undefined;\n\tlet mutVersion = 0;\n\tfunction recordChange(change: PubSubChangePayload): void {\n\t\tif (!mutLog) return;\n\t\tmutLog.append({\n\t\t\tstructure: \"pubsub\",\n\t\t\tversion: ++mutVersion,\n\t\t\tt_ns: wallClockNs(),\n\t\t\tlifecycle: \"data\",\n\t\t\tchange,\n\t\t});\n\t}\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\tif (!mutLog) {\n\t\t\t\tensureTopic(name).emit(value);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Same-wave: topic emit + change record in one batch frame.\n\t\t\tbatch(() => {\n\t\t\t\tensureTopic(name).emit(value);\n\t\t\t\trecordChange({ kind: \"publish\", value });\n\t\t\t});\n\t\t},\n\n\t\tpublishMany(entries: Iterable<[string, unknown]>): void {\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\trecordChange({ kind: \"publish\", 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\tnodes.delete(name);\n\t\t\tbackend.removeTopic(name);\n\t\t\tif (!mutLog) {\n\t\t\t\tn.down([[TEARDOWN]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tbatch(() => {\n\t\t\t\t// QA P3: record BEFORE TEARDOWN. A subscriber wired to both a\n\t\t\t\t// topic and `mutationLog` that self-detaches on TEARDOWN would\n\t\t\t\t// otherwise miss the `remove` delta (same-wave consistency).\n\t\t\t\trecordChange({ kind: \"remove\", name });\n\t\t\t\tn.down([[TEARDOWN]]);\n\t\t\t});\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\n\t\tmutationLog: mutLog,\n\t};\n}\n","/**\n * `singleFromAny` — keyed promise/Node de-duplication (\"singleflight\").\n *\n * Given a `factory: (key) => NodeInput<T>`, returns a callable that dedupes\n * concurrent invocations sharing the same key — all callers with the same\n * key while a request is in-flight receive the same `Promise<T>`. Once the\n * underlying source settles (DATA, ERROR, or COMPLETE), the cache entry is\n * cleared so the next call re-invokes the factory.\n *\n * This is the classic \"singleflight\" pattern from Go, generalised over the\n * library's `NodeInput<T>` bridge so callers can pass Promise-returning\n * factories, Node-returning factories, or plain value factories with\n * identical semantics.\n *\n * Use cases:\n * - `withReplayCache` cache-miss thundering-herd dedup\n * - Shared HTTP fetches keyed by URL\n * - Expensive compute keyed by request fingerprint\n *\n * @example\n * ```ts\n * const fetchUser = singleFromAny<string, User>((id) => fetch(`/users/${id}`).then(r => r.json()));\n * // Two concurrent callers with id=\"42\" → one underlying fetch, two Promises resolving to the same User.\n * const [a, b] = await Promise.all([fetchUser(\"42\"), fetchUser(\"42\")]);\n * ```\n *\n * @category extra\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { COMPLETE, ERROR } from \"@graphrefly/pure-ts/core\";\n// Import directly from the source sub-files (rather than the `./sources.js`\n// barrel) so the `single-from-any` module is NOT part of any cycle that runs\n// through `extra/sources/index.ts` — eager re-exports through the barrel were\n// observed to leave `firstValueFrom` / `keepalive` unresolved during nested\n// import chains under vite-node.\nimport { fromAny, type NodeInput } from \"@graphrefly/pure-ts/extra\";\nimport { firstValueFrom } from \"../sources/settled.js\";\n\nexport interface SingleFromAnyOptions<K> {\n\t/**\n\t * Convert a typed key into a cache-string. Defaults to `String(key)`, which\n\t * works for primitive keys; callers with object keys should provide a\n\t * stable serializer (e.g., canonical JSON).\n\t */\n\tkeyFn?: (key: K) => string;\n}\n\n/**\n * Dedupe concurrent `factory(key)` invocations. Returns a bound callable.\n *\n * @param factory - Produces a `NodeInput<T>` for each unique key.\n * @param opts - Optional key-stringification.\n * @returns A function `(key: K) => Promise<T>` whose inflight results are shared per key.\n */\nexport function singleFromAny<K, T>(\n\tfactory: (key: K) => NodeInput<T>,\n\topts: SingleFromAnyOptions<K> = {},\n): (key: K) => Promise<T> {\n\tconst keyFn = opts.keyFn ?? ((k: K) => String(k));\n\tconst inFlight = new Map<string, Promise<T>>();\n\n\treturn (key: K): Promise<T> => {\n\t\tconst k = keyFn(key);\n\t\tconst existing = inFlight.get(k);\n\t\tif (existing) return existing;\n\n\t\tconst input = factory(key);\n\n\t\t// Resolve the NodeInput to a Promise<T>. Different input shapes need\n\t\t// different bridges — Promise/Node/AsyncIterable/Iterable/plain value.\n\t\tlet rawPromise: Promise<T>;\n\t\tif (input != null && typeof (input as PromiseLike<T>).then === \"function\") {\n\t\t\trawPromise = Promise.resolve(input as PromiseLike<T>);\n\t\t} else if (\n\t\t\tinput != null &&\n\t\t\ttypeof input === \"object\" &&\n\t\t\t\"subscribe\" in (input as object) &&\n\t\t\t\"cache\" in (input as object)\n\t\t) {\n\t\t\t// Node: bridge via firstValueFrom.\n\t\t\trawPromise = firstValueFrom(input as Node<T>);\n\t\t} else if (\n\t\t\tinput != null &&\n\t\t\ttypeof input === \"object\" &&\n\t\t\tSymbol.asyncIterator in (input as object)\n\t\t) {\n\t\t\t// AsyncIterable — take the first value, then close the iterator so\n\t\t\t// any owned resources (HTTP body, subscription, timer) are released.\n\t\t\trawPromise = (async () => {\n\t\t\t\tconst iter = (input as AsyncIterable<T>)[Symbol.asyncIterator]();\n\t\t\t\ttry {\n\t\t\t\t\tconst { value, done } = await iter.next();\n\t\t\t\t\tif (done) throw new Error(\"singleFromAny: factory returned empty async iterable\");\n\t\t\t\t\treturn value as T;\n\t\t\t\t} finally {\n\t\t\t\t\tawait iter.return?.();\n\t\t\t\t}\n\t\t\t})();\n\t\t} else if (input != null && typeof input === \"object\" && Symbol.iterator in (input as object)) {\n\t\t\t// Iterable — take the first value, close the iterator.\n\t\t\trawPromise = (async () => {\n\t\t\t\tconst iter = (input as Iterable<T>)[Symbol.iterator]();\n\t\t\t\ttry {\n\t\t\t\t\tconst { value, done } = iter.next();\n\t\t\t\t\tif (done) throw new Error(\"singleFromAny: factory returned empty iterable\");\n\t\t\t\t\treturn value as T;\n\t\t\t\t} finally {\n\t\t\t\t\titer.return?.();\n\t\t\t\t}\n\t\t\t})();\n\t\t} else {\n\t\t\t// Plain value.\n\t\t\trawPromise = Promise.resolve(input as T);\n\t\t}\n\n\t\t// Install the cache entry BEFORE attaching `.finally`. Otherwise a\n\t\t// sync-resolved Promise's finally microtask could run before the\n\t\t// `inFlight.set` below, leaving a stale entry installed afterwards.\n\t\t// We wrap in a holder whose reference we capture *before* chaining.\n\t\tlet tracked!: Promise<T>;\n\t\tconst cleanup = (): void => {\n\t\t\tif (inFlight.get(k) === tracked) inFlight.delete(k);\n\t\t};\n\t\ttracked = rawPromise.then(\n\t\t\t(v) => {\n\t\t\t\tcleanup();\n\t\t\t\treturn v;\n\t\t\t},\n\t\t\t(e) => {\n\t\t\t\tcleanup();\n\t\t\t\tthrow e;\n\t\t\t},\n\t\t);\n\t\tinFlight.set(k, tracked);\n\t\treturn tracked;\n\t};\n}\n\n/**\n * Reactive variant: returns a bound callable that hands out `Node<T>` values.\n * All concurrent callers with the same key during an in-flight source share\n * the same Node. When the underlying source **terminally** settles (ERROR\n * or COMPLETE), the Node is removed from the cache so the next call\n * re-invokes `factory`. DATA is NOT terminal — callers subscribing after\n * the first DATA still receive the shared Node (and push-on-subscribe per\n * the spec's cached-DATA contract).\n *\n * Use when downstream wants reactive subscription (not a one-shot Promise).\n *\n * @category extra\n */\nexport function singleNodeFromAny<K, T>(\n\tfactory: (key: K) => NodeInput<T>,\n\topts: SingleFromAnyOptions<K> = {},\n): (key: K) => Node<T> {\n\tconst keyFn = opts.keyFn ?? ((k: K) => String(k));\n\tconst inFlight = new Map<string, Node<T>>();\n\n\treturn (key: K): Node<T> => {\n\t\tconst k = keyFn(key);\n\t\tconst existing = inFlight.get(k);\n\t\tif (existing) return existing;\n\n\t\tconst node = fromAny(factory(key));\n\t\tinFlight.set(k, node);\n\n\t\t// Evict on terminal settle only — ERROR or COMPLETE. DATA is a value\n\t\t// emission, not a lifecycle transition; multi-emitting Nodes should\n\t\t// continue to share across subscribers after the first value.\n\t\tconst unsub = node.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === ERROR || m[0] === COMPLETE) {\n\t\t\t\t\tif (inFlight.get(k) === node) inFlight.delete(k);\n\t\t\t\t\tunsub();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn node;\n\t};\n}\n","/**\n * Settled/signal helpers.\n *\n * Moved from extra/sources/settled.ts during cleave A2.\n * `keepalive` is substrate — it lives at `@graphrefly/pure-ts`\n * (`packages/pure-ts/src/extra/sources/_keepalive.ts`), not here.\n */\n\n/**\n * Settled / signal helpers — boundary primitives for converting reactive\n * sources into Promise/AbortSignal endpoints.\n *\n * - {@link firstValueFrom} / {@link firstWhere} — Promise of the first\n * matching DATA.\n * - {@link awaitSettled} — composition over `firstWhere` + reactive\n * `timeout` from `extra/resilience` (lazy import to avoid a\n * resilience → sources cycle).\n * - {@link nodeSignal} — `Node<boolean>` → `AbortSignal` bridge.\n * - {@link reactiveCounter} — capped counter exposed as a `Node<number>`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\tnode,\n} from \"@graphrefly/pure-ts/core\";\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.snapshot, snap => snap.size > 0);\n * ```\n *\n * @param source - Upstream node to observe.\n * @param predicate - Returns `true` for the value to resolve on.\n * @param opts - `{ skipCurrent?: boolean }`. When `skipCurrent: true`, any DATA\n * delivered during the synchronous `subscribe()` call (push-on-subscribe §2.2\n * replay of the cached value) is ignored — the promise resolves only on the\n * next future emission. Useful when the caller wants to await the next\n * settlement event after an imperative action (e.g. `run()` minting a new\n * runVersion, where the currently-cached value belongs to the previous run).\n *\n * @category extra\n */\nexport function firstWhere<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: { skipCurrent?: boolean; kick?: () => void },\n): Promise<T> {\n\t// Lock 3.A (Phase 13.6.B): subscribe synchronously inside the function\n\t// body — NOT inside the Promise executor. Subscribing inside the\n\t// executor would defer the subscription past any synchronous `kick()`\n\t// the caller fires after the call returns, race-losing the very wave\n\t// the caller wants to observe.\n\t//\n\t// To bridge sync-subscribe with the async Promise contract, we record\n\t// any settlement that fires *before* the Promise constructor runs, and\n\t// the executor immediately resolves/rejects with the recorded value.\n\t// Settlements after the executor runs go straight through resolve/reject.\n\ttype Pending =\n\t\t| { kind: \"data\"; value: T }\n\t\t| { kind: \"error\"; err: unknown }\n\t\t| { kind: \"complete\" };\n\tlet pending: Pending | undefined;\n\tlet resolveFn: ((value: T) => void) | undefined;\n\tlet rejectFn: ((err: unknown) => void) | undefined;\n\tlet settled = false;\n\tlet shouldUnsub = false;\n\tlet unsub: (() => void) | undefined;\n\tlet inInitialSyncPhase = opts?.skipCurrent === true;\n\n\t// QA P1: every settler short-circuits when `settled === true` so a\n\t// later settle attempt (e.g. `kick()` throwing AFTER it synchronously\n\t// fired matching DATA, OR a `[DATA matched, ERROR]` wave during\n\t// push-on-subscribe) cannot overwrite an earlier `pending` outcome.\n\t// Without this gate, a kick that races sink-callback settlement could\n\t// reject a Promise the user already has resolved-DATA for.\n\tconst settleData = (v: T): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (resolveFn != null) resolveFn(v);\n\t\telse pending = { kind: \"data\", value: v };\n\t};\n\tconst settleError = (err: unknown): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (rejectFn != null) rejectFn(err);\n\t\telse pending = { kind: \"error\", err };\n\t};\n\tconst settleComplete = (): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tconst err = new Error(\"completed without matching value\");\n\t\tif (rejectFn != null) rejectFn(err);\n\t\telse pending = { kind: \"complete\" };\n\t};\n\tconst detach = (): void => {\n\t\tif (unsub) {\n\t\t\tunsub();\n\t\t\tunsub = undefined;\n\t\t} else shouldUnsub = true;\n\t};\n\n\tconst sink: (msgs: Messages) => void = (msgs) => {\n\t\tif (settled) return;\n\t\tfor (const m of msgs) {\n\t\t\tif (settled) return;\n\t\t\t// During the initial sync phase, swallow only cached DATA\n\t\t\t// (push-on-subscribe §2.2). Terminal ERROR / COMPLETE must\n\t\t\t// still reject the promise — otherwise an already-terminated\n\t\t\t// source synchronously delivering `[[ERROR, ...]]` or\n\t\t\t// `[[COMPLETE]]` during `subscribe()` would hang forever\n\t\t\t// under `skipCurrent: true`.\n\t\t\tif (inInitialSyncPhase && m[0] === DATA) continue;\n\t\t\tif (m[0] === DATA) {\n\t\t\t\tconst v = m[1] as T;\n\t\t\t\tif (predicate(v)) {\n\t\t\t\t\tsettleData(v);\n\t\t\t\t\tdetach();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (m[0] === ERROR) {\n\t\t\t\tsettleError(m[1]);\n\t\t\t\tdetach();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\tsettleComplete();\n\t\t\t\tdetach();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t};\n\tunsub = source.subscribe(sink);\n\tinInitialSyncPhase = false;\n\t// Lock 3.A: fire `kick` AFTER subscribe is in place. With sync\n\t// subscribe + sync kick, the resulting wave reaches `sink` before\n\t// control returns — making subscribe-before-kick ordering structurally\n\t// impossible to misuse.\n\tif (opts?.kick != null && !settled) {\n\t\ttry {\n\t\t\topts.kick();\n\t\t} catch (err) {\n\t\t\tsettleError(err);\n\t\t\tdetach();\n\t\t}\n\t}\n\tif (shouldUnsub) {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\t// If a settlement landed synchronously before the executor runs,\n\t\t// flush it through immediately.\n\t\tif (pending != null) {\n\t\t\tif (pending.kind === \"data\") resolve(pending.value);\n\t\t\telse if (pending.kind === \"error\") reject(pending.err);\n\t\t\telse reject(new Error(\"completed without matching value\"));\n\t\t\treturn;\n\t\t}\n\t\tresolveFn = resolve;\n\t\trejectFn = reject;\n\t});\n}\n\n/**\n * Await the first non-nullish DATA value from `source`, with optional\n * timeout. Composition sugar over `firstWhere` + reactive timeout.\n *\n * Designed as the CLI/boundary sink for reactive pipelines that end in a\n * nullable node (e.g. `promptNode` — per COMPOSITION-GUIDE §8, it emits\n * `null` before it settles with a real value). Replaces the common pattern\n * `firstValueFrom(filter(source, v => v != null))` with a deadline.\n *\n * - Rejects with `TimeoutError` (from `extra/resilience`) if no matching\n * value arrives within `timeoutMs`. Omit `timeoutMs` for unbounded wait.\n * - `predicate` defaults to `v => v != null`. Pass a custom predicate to\n * gate on a stronger condition (e.g. `v => typeof v === \"string\"`).\n * - Pass `skipCurrent: true` to ignore the currently-cached value delivered\n * synchronously via push-on-subscribe and resolve only on the *next*\n * matching emission. Useful after an imperative action that should produce\n * a fresh settlement (e.g. `run()` minting a new version — the stale\n * cached value from the previous run must not resolve the new caller).\n *\n * ```ts\n * const brief = await awaitSettled(briefNode, { timeoutMs: 120_000 });\n * // or with a predicate:\n * const rich = await awaitSettled(node, {\n * predicate: (v): v is MyShape => typeof v === \"object\" && v != null && \"key\" in v,\n * timeoutMs: 60_000,\n * });\n * // or after kicking off a fresh run:\n * kickOff();\n * const fresh = await awaitSettled(resultNode, { skipCurrent: true });\n * ```\n *\n * Reactive inside, sync propagation — the one async boundary is the\n * returned `Promise<T>` (spec §5.10: async belongs at sources and\n * boundaries, not in the graph).\n *\n * @param source - Upstream node to observe.\n * @param opts - `{ predicate?, timeoutMs?, skipCurrent? }`.\n * @returns Promise that resolves with the first matching value, or rejects on timeout / ERROR / COMPLETE-without-DATA.\n *\n * @category extra\n */\n// Lazy module-cache for the `withTimeout` resilience operator. The dynamic\n// import keeps `settled` free of an eager edge into the resilience family;\n// first call pays the one-shot import, subsequent calls hit cached refs.\nlet _timeoutOp: typeof import(\"../resilience/timeout.js\").withTimeout | undefined;\nlet _nsPerMs: number | undefined;\n\nexport async function awaitSettled<T>(\n\tsource: Node<T>,\n\topts?: {\n\t\tpredicate?: (value: T) => boolean;\n\t\ttimeoutMs?: number;\n\t\tskipCurrent?: boolean;\n\t\t/**\n\t\t * Lock 3.A (Phase 13.6.B): fired AFTER subscribe is in place but\n\t\t * BEFORE the helper's async boundary is exposed to the caller.\n\t\t * Subscribe-before-kick is structurally enforced — the kick's\n\t\t * synchronous wave reaches `sink` before control returns. Replaces\n\t\t * the prior load-bearing-comment pattern (M.20-load-bearing) with\n\t\t * a misuse-impossible API shape.\n\t\t *\n\t\t * Common pattern:\n\t\t * await awaitSettled(node, {\n\t\t * skipCurrent: true,\n\t\t * kick: () => producer.emit(value),\n\t\t * });\n\t\t *\n\t\t * Omit `kick` for external-trigger cases where the wave is fired\n\t\t * by code outside the helper's caller; subscribe still lands\n\t\t * synchronously inside the helper body so the next external wave\n\t\t * is not lost.\n\t\t */\n\t\tkick?: () => void;\n\t},\n): Promise<NonNullable<T>> {\n\tconst predicate = opts?.predicate ?? ((v: T) => v != null);\n\tconst skipCurrent = opts?.skipCurrent;\n\tconst kick = opts?.kick;\n\tif (opts?.timeoutMs == null || opts.timeoutMs <= 0) {\n\t\treturn (await firstWhere(source, predicate, { skipCurrent, kick })) as NonNullable<T>;\n\t}\n\t// Reactive composition: `timeout()` wraps the source as a Node that\n\t// emits ERROR(TimeoutError) on deadline. `firstWhere` then resolves on\n\t// the first matching DATA or rejects on that ERROR. One async boundary\n\t// (the returned Promise), everything inside is sync reactive.\n\tif (_timeoutOp === undefined) {\n\t\tconst [timeoutMod, backoff] = await Promise.all([\n\t\t\timport(\"../resilience/timeout.js\"),\n\t\t\timport(\"../resilience/backoff.js\"),\n\t\t]);\n\t\t_timeoutOp = timeoutMod.withTimeout;\n\t\t_nsPerMs = backoff.NS_PER_MS;\n\t}\n\tconst guarded = _timeoutOp(source, { ns: opts.timeoutMs * (_nsPerMs as number) }).node;\n\treturn (await firstWhere(guarded, predicate, { skipCurrent, kick })) as NonNullable<T>;\n}\n\n/**\n * Converts a reactive `Node<boolean>` into a browser-standard `AbortSignal`\n * that fires when the node settles on `true`. Useful for threading a reactive\n * \"cancel\" flag into any async boundary that accepts a signal (fetch, LLM SDK\n * calls, child-process APIs, timers).\n *\n * **Contract.**\n * - `signal.abort(reason)` fires exactly once, on the first DATA emission with\n * a truthy value. Subsequent emissions are ignored (AbortSignal is\n * single-shot).\n * - Null / `false` / sentinel values are ignored. Push-on-subscribe will\n * check the currently-cached value on subscribe and abort immediately if\n * it's already `true`.\n * - `reason` defaults to `\"cancelled via nodeSignal\"`; pass `opts.reason` to\n * override (`DOMException`, `Error`, or any value accepted by\n * `AbortController.abort`).\n *\n * **Lifecycle.**\n * - Returns a `{signal, dispose}` bundle. Call `dispose()` when you're done\n * with the signal (e.g. in a `finally` after the async operation completes).\n * `dispose()` unsubscribes from the node and is a no-op once the signal has\n * fired.\n * - **Memory note:** without `dispose()` the subscription keeps the reactive\n * node alive for the lifetime of the process. For bridge calls inside a\n * `switchMap` project fn, the switchMap supersede tears the inner subgraph\n * down, which is usually the right lifetime — but still call `dispose()`\n * from the caller's `finally` for clarity.\n *\n * @example\n * ```ts\n * const aborted = state(false);\n * const { signal, dispose } = nodeSignal(aborted);\n * try {\n * const resp = await adapter.invoke(msgs, { signal });\n * return resp;\n * } finally {\n * dispose();\n * }\n * ```\n *\n * @category extra\n */\nexport function nodeSignal(\n\tsource: Node<boolean>,\n\topts?: { reason?: unknown },\n): { signal: AbortSignal; dispose: () => void } {\n\tconst ctrl = new AbortController();\n\tconst reason = opts?.reason ?? new Error(\"cancelled via nodeSignal\");\n\tlet unsub: (() => void) | undefined;\n\tlet shouldUnsub = false;\n\tconst done = () => {\n\t\tif (unsub) {\n\t\t\tunsub();\n\t\t\tunsub = undefined;\n\t\t} else shouldUnsub = true;\n\t};\n\tunsub = source.subscribe((msgs) => {\n\t\tif (ctrl.signal.aborted) return;\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA && m[1] === true) {\n\t\t\t\tctrl.abort(reason);\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === ERROR) {\n\t\t\t\t// Treat an ERROR on the abort source as a cancel signal too —\n\t\t\t\t// a broken control channel should fail closed, not leak the\n\t\t\t\t// in-flight call. Use the error as the abort reason.\n\t\t\t\tctrl.abort(m[1]);\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t// Source completed without aborting — no-op. `done()` already\n\t\t\t\t// released the subscription here, so a later `dispose()` call\n\t\t\t\t// from the caller is a no-op (safe / idempotent).\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\tif (shouldUnsub) {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\treturn {\n\t\tsignal: ctrl.signal,\n\t\tdispose: () => {\n\t\t\tif (unsub) {\n\t\t\t\tunsub();\n\t\t\t\tunsub = undefined;\n\t\t\t}\n\t\t},\n\t};\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 = node([], { initial: 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 * 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 {\n\tbatch,\n\tDATA,\n\tfactoryTag,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\tfromAny,\n\tmerge,\n\ttype NodeInput,\n\tswitchMap,\n\twithLatestFrom,\n} from \"@graphrefly/pure-ts/extra\";\nimport { forEach } from \"../sources/async.js\";\n\n// Re-export distill from its canonical module (co-located here pre-split;\n// moved to distill.ts to avoid duplicate-export conflict at the barrel level).\nexport {\n\ttype DistillBundle,\n\ttype DistillOptions,\n\tdistill,\n\ttype Extraction,\n} from \"./distill.js\";\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 = node<TVerify | null>([], {\n\t\tinitial: opts?.initialVerified ?? null,\n\t\tmeta: {\n\t\t\t...factoryTag(\"verifiable\"),\n\t\t\t...(hasSourceVersioning ? { sourceVersion: null } : {}),\n\t\t},\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// Two patterns 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: `withLatestFrom(trigger, source)` pairs each\n\t\t// trigger emission with the latest source value. Phase 10.5\n\t\t// (`withLatestFrom` flipped to `partial: false`) fixed the W1\n\t\t// initial-pair drop — both deps settle before fn fires, so the\n\t\t// first trigger correctly pairs with the seeded source cache.\n\t\t// Replaces the §28 closure-mirror that was canonical pre-10.5.\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\tconst paired = withLatestFrom(triggerNode, sourceNode);\n\t\t\tverifyStream = switchMap(paired, ([, source]) => verifyFn(source 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","/**\n * Graph checkpoint sinks — `checkpointToS3` and `checkpointToRedis` wire a\n * graph's `attachSnapshotStorage` with an S3- or Redis-backed\n * {@link SnapshotStorageTier}.\n */\n\nimport { wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { SnapshotStorageTier } from \"@graphrefly/pure-ts/extra/storage\";\nimport type { GraphCheckpointRecord } from \"@graphrefly/pure-ts/graph\";\nimport type { AttachStorageGraphLike } from \"./_internal.js\";\nimport type { S3ClientLike } from \"./to-s3.js\";\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\n/**\n * Wires `graph.attachSnapshotStorage()` 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: SnapshotStorageTier<GraphCheckpointRecord> = {\n\t\tname: `s3:${bucket}`,\n\t\tdebounceMs,\n\t\tcompactEvery,\n\t\tsave(record) {\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(record);\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\t// S3 tier is write-only here — one object per checkpoint timestamp,\n\t\t// no canonical \"latest\" key for load.\n\t};\n\treturn graph.attachSnapshotStorage([{ snapshot: tier }], {\n\t\tonError: (err: unknown) => onError?.(err),\n\t});\n}\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.attachSnapshotStorage()` 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: SnapshotStorageTier<GraphCheckpointRecord> = {\n\t\tname: `redis:${redisKey}`,\n\t\tdebounceMs,\n\t\tcompactEvery,\n\t\tsave(record) {\n\t\t\tlet body: string;\n\t\t\ttry {\n\t\t\t\tbody = JSON.stringify(record);\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 undefined;\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(raw) as GraphCheckpointRecord;\n\t\t\t} catch {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t},\n\t};\n\treturn graph.attachSnapshotStorage([{ snapshot: tier }], {\n\t\tonError: (err: unknown) => onError?.(err),\n\t});\n}\n","/**\n * ClickHouse live materialized view IO — `fromClickHouseWatch` polls a query\n * via `fromTimer + switchMap` (reactive timer, switch semantics cancel\n * in-flight queries) and emits one `DATA` per result row per scrape.\n */\n\nimport { COMPLETE, ERROR, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { type AsyncSourceOpts, fromTimer, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { NS_PER_MS, NS_PER_SEC } from \"../resilience/backoff.js\";\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\tnode<ClickHouseRow>([], (_data, 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 * CSV ingest IO — `fromCSV` reads an `AsyncIterable<string>` of CSV chunks\n * (one node per row), and `csvRows` is the stateful operator variant for\n * existing reactive `Node<string>` upstreams. Both share the local\n * `parseCSVLine` helper so quoted fields and embedded delimiters are handled\n * uniformly.\n */\n\nimport { COMPLETE, ERROR, type Node, type NodeOptions, node } from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\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 node<CSVRow>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet cancelled = false;\n\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tlet headers: string[] | undefined = explicitColumns;\n\t\t\t\t\tlet buffer = \"\";\n\n\t\t\t\t\tfor await (const chunk of source) {\n\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\tbuffer += chunk;\n\n\t\t\t\t\t\tconst lines = buffer.split(/\\r?\\n/);\n\t\t\t\t\t\t// Keep last partial line in buffer.\n\t\t\t\t\t\tbuffer = lines.pop() ?? \"\";\n\n\t\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\t\tif (!line.trim()) continue;\n\n\t\t\t\t\t\t\tconst values = parse(line);\n\n\t\t\t\t\t\t\tif (!headers && hasHeader) {\n\t\t\t\t\t\t\t\theaders = values;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!headers) {\n\t\t\t\t\t\t\t\theaders = values.map((_, i) => `col${i}`);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst row: CSVRow = {};\n\t\t\t\t\t\t\tfor (let i = 0; i < headers.length; i++) {\n\t\t\t\t\t\t\t\trow[headers[i]] = values[i] ?? \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ta.emit(row);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Process remaining buffer.\n\t\t\t\t\tif (!cancelled && buffer.trim()) {\n\t\t\t\t\t\tconst values = parse(buffer);\n\t\t\t\t\t\tif (headers) {\n\t\t\t\t\t\t\tconst row: CSVRow = {};\n\t\t\t\t\t\t\tfor (let i = 0; i < headers.length; i++) {\n\t\t\t\t\t\t\t\trow[headers[i]] = values[i] ?? \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ta.emit(row);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (!cancelled) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid run();\n\n\t\t\treturn () => {\n\t\t\t\tcancelled = true;\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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\t// Lock 6.D (Phase 13.6.B): clear parser state on deactivation so\n\t// `csvRows` under retry/resubscribe patterns doesn't leak a stale\n\t// half-parsed line or sticky header detection from a prior run.\n\tlet cleanup: { onDeactivation: () => void } | undefined;\n\treturn node<CSVRow>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (cleanup === undefined) {\n\t\t\t\tconst store = ctx.store;\n\t\t\t\tcleanup = {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tdelete store.buffer;\n\t\t\t\t\t\tdelete store.headers;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return cleanup;\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\treturn cleanup;\n\t\t},\n\t\t{ describeKind: \"derived\", ...rest } as NodeOptions<CSVRow>,\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 * Internal helpers shared by IO sub-files.\n *\n * - `ExtraOpts` / `sourceOpts` — common opts + the `describeKind: \"producer\"`\n * wrapper used by every producer-shaped IO source.\n * - `SinkHandle` / `BufferedSinkHandle` — public sink handle shapes shared by\n * per-record and buffered sinks across multiple protocols.\n * - `AdapterHandlers` / `AckableMessage` — alias of `EmitTriad` and the\n * manual-ack envelope used by Pulsar / RabbitMQ ingest sub-files.\n * - `AttachStorageGraphLike` — duck-typed graph shape used by\n * `checkpointToS3` / `checkpointToRedis`.\n */\n\nimport type { Node, NodeOptions } from \"@graphrefly/pure-ts/core\";\nimport type { SnapshotStorageTier } from \"@graphrefly/pure-ts/extra/storage\";\nimport type { GraphCheckpointRecord } from \"@graphrefly/pure-ts/graph\";\nimport type { EmitTriad } from \"../composition/external-register.js\";\nimport type { SinkTransportError } from \"./_sink.js\";\n\nexport type ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nexport function sourceOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\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\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/** 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/** Duck-typed graph shape consumed by `checkpointToS3` / `checkpointToRedis`. */\nexport type AttachStorageGraphLike = {\n\tattachSnapshotStorage: (\n\t\tpairs: readonly { snapshot: SnapshotStorageTier<GraphCheckpointRecord> }[],\n\t\topts?: unknown,\n\t) => { dispose(): void };\n\tname: string;\n};\n","/**\n * Drizzle adapter (5.2b) — `fromDrizzle` runs `query.execute()` and emits one\n * `DATA` containing the full mapped row array, then `COMPLETE`.\n */\n\nimport { COMPLETE, ERROR, type Node, type NodeOptions, node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 node<U[]>(\n\t\t[],\n\t\t(_data, 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 * HTTP IO — `fromHTTP` (one-shot fetch with `withStatus` companion bundle),\n * `toHTTP` (per-record / buffered sink with retry support), `fromHTTPStream`\n * (raw `Uint8Array` byte stream), `fromHTTPPoll` (interval-driven re-fetch).\n *\n * Uses the platform `fetch` API (Node 18+, browsers, Deno, Bun). Timeouts use\n * `AbortController` driven by `setTimeout` per spec §5.10's resilience-operator\n * carve-out.\n */\n\nimport {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Node,\n\tnode,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport { type AsyncSourceOpts, fromTimer, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { NS_PER_MS, NS_PER_SEC } from \"../resilience/backoff.js\";\nimport { type WithStatusBundle, withStatus } from \"../resilience/status.js\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 = node<number>([], { initial: 0, name: `${rest.name ?? \"http\"}/fetchCount` });\n\tconst lastUpdated = node<number>([], { initial: 0, name: `${rest.name ?? \"http\"}/lastUpdated` });\n\tconst fetched = node<boolean>([], { initial: 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 = node<T>(\n\t\t[],\n\t\t(_data, 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/** 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/** 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 node<Uint8Array>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tconst abort = new AbortController();\n\t\t\tif (externalSignal?.aborted) {\n\t\t\t\ta.down([[ERROR, externalSignal.reason ?? new Error(\"Aborted\")]]);\n\t\t\t\treturn () => {};\n\t\t\t}\n\t\t\texternalSignal?.addEventListener(\"abort\", () => abort.abort(externalSignal.reason), {\n\t\t\t\tonce: true,\n\t\t\t});\n\t\t\tconst body =\n\t\t\t\tbodyOpt !== undefined\n\t\t\t\t\t? typeof bodyOpt === \"string\"\n\t\t\t\t\t\t? bodyOpt\n\t\t\t\t\t\t: JSON.stringify(bodyOpt)\n\t\t\t\t\t: undefined;\n\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst res = await fetch(url, { method, headers, body, signal: abort.signal });\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tif (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\t\t\t\tif (!res.body) throw new Error(\"HTTP response has no body\");\n\t\t\t\t\tconst reader = res.body.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\tif (value) a.emit(value);\n\t\t\t\t\t}\n\t\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tif (err && (err as Error).name === \"AbortError\") return;\n\t\t\t\t\ta.down([[ERROR, err]]);\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\tabort.abort();\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * Status wrapper — surface lifecycle state alongside output.\n *\n * `withStatus` mirrors a source `Node<T>` and produces companion `status` /\n * `error` reactive nodes for UI and meta-snapshot consumers.\n */\n\nimport {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport { msgVal, operatorOpts } from \"./_internal.js\";\n\n/**\n * Central lifecycle vocabulary for resilience primitives + `processManager`.\n *\n * **DS-13.5.B follow-on (2026-05-01).** Widened from\n * `\"pending\" | \"running\" | \"completed\" | \"errored\"` to add `\"cancelled\"`\n * (replaces `processManager`'s prior `\"compensated\"` semantics) and\n * `\"paused\"` (carried by `<Primitive>State` lifecycle-shaped companions\n * on `retry` / `circuitBreaker` / `rateLimiter`).\n *\n * Resilience primitives use this enum as the literal vocabulary inside\n * lifecycle-shaped state nodes; `withStatus` (legacy) only emits the\n * original four (pre-widening) — the cancelled / paused values are added\n * for downstream consumers that need richer lifecycle reporting.\n */\nexport type StatusValue = \"pending\" | \"running\" | \"completed\" | \"errored\" | \"cancelled\" | \"paused\";\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 `out` is the mirrored stream, `status` is a\n * reactive `Node<StatusValue>` (`\"pending\" | \"running\" | \"completed\" | \"errored\"`),\n * and `error` holds the last `ERROR` payload (cleared to `null` on the next `DATA`\n * after `errored`).\n *\n * @remarks\n * **Lifecycle:** `pending` (no DATA yet) → `running` (on first DATA) → `completed`\n * (on COMPLETE) or `errored` (on ERROR). After `errored`, the next `DATA` clears\n * `error` and re-enters `running` inside a {@link batch} so subscribers see one\n * consistent transition (matches graphrefly-py).\n *\n * **Producer-pattern visibility:** `out` is built via `node([], fn, …)`, so `src`\n * appears as the source dependency in `describe()` traversal but the `status` /\n * `error` companions are mirrored via subscribe-callback effects — they appear\n * under `out.meta.status` / `out.meta.error` (and as `<name>::__meta__::status`\n * paths in `describe()`) rather than as separate top-level edges. Subscribers\n * to `out` see the throttled DATA stream; `status` / `error` companions may not\n * appear as edges in `describe()` if no consumer subscribes to them (per\n * COMPOSITION-GUIDE §1, push-on-subscribe semantics).\n *\n * **Per-subscribe lifecycle (DF8, 2026-04-29 doc lock).** When the wrapped\n * source is `resubscribable: true` and multiple consumers attach in\n * sequence, each new subscription cycle re-runs the producer fn AND\n * re-emits the initial `pending` + `null` companion DATAs. Downstream\n * subscribers to the `status` / `error` companions see thrash:\n * `pending → running → completed → pending → running …`. This is the\n * intended fresh-cycle semantic (each subscription cycle reports its own\n * lifecycle); consumers that need a \"stable\" status across cycles should\n * derive a snapshot via a separate `state()` mirror rather than depending\n * on the per-cycle reset.\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 → \"running\"\n * ```\n *\n * @category extra\n */\nexport function withStatus<T>(\n\tsrc: Node<T>,\n\toptions?: { initialStatus?: StatusValue; meta?: Record<string, unknown> },\n): WithStatusBundle<T> {\n\tconst initialStatus = options?.initialStatus ?? \"pending\";\n\tconst callerMeta = options?.meta;\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, \"running\"]]);\n\t\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcurrentStatus = \"running\";\n\t\t\t\t\t\t} else if (currentStatus !== \"running\") {\n\t\t\t\t\t\t\t// First DATA after `pending` (or another non-running state):\n\t\t\t\t\t\t\t// flip status to \"running\" alongside the DATA emit so external\n\t\t\t\t\t\t\t// observers see one coherent wave (no torn reads between the\n\t\t\t\t\t\t\t// status companion and the mirrored stream).\n\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"running\"]]);\n\t\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcurrentStatus = \"running\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// A9 (QA fix 2026-05-01): already in \"running\" — skip the\n\t\t\t\t\t\t\t// redundant status emit that the previous code did on every\n\t\t\t\t\t\t\t// DATA. Saves a wave walk per DATA on hot streams (e.g. SSE\n\t\t\t\t\t\t\t// token streams through withStatus).\n\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\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: {\n\t\t\t\t...(callerMeta ?? {}),\n\t\t\t\tstatus: initialStatus,\n\t\t\t\terror: null,\n\t\t\t\t...factoryTag(\"withStatus\", { initialStatus }),\n\t\t\t},\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 * {@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 {\n\tCOMPLETE,\n\tDATA,\n\tdefaultConfig,\n\tERROR,\n\ttype Message,\n\ttype Node,\n\tnode,\n\tRingBuffer,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tresolveBackoffPreset,\n} from \"../resilience/backoff.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 = node<T | undefined>([], {\n\t\tinitial: undefined,\n\t\tequals: () => false,\n\t\tname: nameFor(\"sent\"),\n\t}) as unknown as Node<T>;\n\tconst failed = node<SinkFailure<T> | null>([], { initial: null, name: nameFor(\"failed\") });\n\tconst inFlightCountNode = node([], { initial: 0, name: nameFor(\"inFlight\") });\n\tconst errorsNode = node<SinkTransportError | null>([], {\n\t\tinitial: null,\n\t\tname: nameFor(\"errors\"),\n\t});\n\tconst bufferedNode = useBuffering\n\t\t? node([], { initial: 0, name: nameFor(\"buffered\") })\n\t\t: undefined;\n\tconst pausedNode = backpressure\n\t\t? node([], { initial: false, name: nameFor(\"paused\") })\n\t\t: 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 * Kafka IO — `fromKafka` (KafkaJS-compatible consumer source) and\n * `toKafka` (producer sink). Compatible with Pulsar via KoP (Kafka-on-Pulsar).\n */\n\nimport { ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<KafkaMessage<T>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\n\t\t\tconst start = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait consumer.subscribe({ topic, fromBeginning });\n\t\t\t\t\tawait consumer.run({\n\t\t\t\t\t\teachMessage: async ({ topic: t, partition, message: msg }) => {\n\t\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\t\tconst headers: Record<string, string> = {};\n\t\t\t\t\t\t\tif (msg.headers) {\n\t\t\t\t\t\t\t\tfor (const [k, v] of Object.entries(msg.headers)) {\n\t\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\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ta.emit({\n\t\t\t\t\t\t\t\ttopic: t,\n\t\t\t\t\t\t\t\tpartition,\n\t\t\t\t\t\t\t\tkey: msg.key?.toString() ?? null,\n\t\t\t\t\t\t\t\tvalue: deserialize(msg.value) as T,\n\t\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\t\toffset: msg.offset,\n\t\t\t\t\t\t\t\ttimestamp: msg.timestamp,\n\t\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\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) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid start();\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * Kysely adapter (5.2b) — `fromKysely` runs `query.execute()` and emits one\n * `DATA` containing the full mapped row array, then `COMPLETE`.\n */\n\nimport { COMPLETE, ERROR, type Node, type NodeOptions, node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 node<U[]>(\n\t\t[],\n\t\t(_data, 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 * MCP (Model Context Protocol) IO — `fromMCP` wraps an MCP client's\n * notification surface as a reactive source via `externalProducer`.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { externalProducer } from \"../composition/external-register.js\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 * NATS IO — `fromNATS` (subject-subscription consumer source) and `toNATS`\n * (publish sink). Compatible with `nats.js`-style clients.\n */\n\nimport { COMPLETE, ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<NATSMessage<T>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tconst sub = client.subscribe(subject, queue ? { queue } : undefined);\n\n\t\t\tconst loop = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tfor await (const msg of sub) {\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 of msg.headers.keys()) {\n\t\t\t\t\t\t\t\theaders[k] = msg.headers.get(k);\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\tsubject: msg.subject,\n\t\t\t\t\t\t\tdata: deserialize(msg.data) as T,\n\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\treply: msg.reply,\n\t\t\t\t\t\t\tsid: msg.sid,\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\t// Subscription closed (drain or unsubscribe) — complete.\n\t\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid loop();\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * NDJSON (newline-delimited JSON) IO — `fromNDJSON` reads an\n * `AsyncIterable<string>` of NDJSON chunks (one node per line) and\n * `ndjsonRows` is the stateful operator variant for existing reactive\n * `Node<string>` upstreams.\n */\n\nimport { COMPLETE, ERROR, type Node, type NodeOptions, node } from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\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\t// Lock 6.D (Phase 13.6.B): clear parser buffer on deactivation so a\n\t// resubscribed operator doesn't bleed a half-line from a prior run.\n\tlet cleanup: { onDeactivation: () => void } | undefined;\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (cleanup === undefined) {\n\t\t\t\tconst store = ctx.store;\n\t\t\t\tcleanup = {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tdelete store.buffer;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return cleanup;\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 cleanup;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cleanup;\n\t\t},\n\t\t{ describeKind: \"derived\", ...(opts ?? {}) } as NodeOptions<T>,\n\t);\n}\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 node<T>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet cancelled = false;\n\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tlet buffer = \"\";\n\n\t\t\t\t\tfor await (const chunk of source) {\n\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\tbuffer += chunk;\n\n\t\t\t\t\t\tconst lines = buffer.split(/\\r?\\n/);\n\t\t\t\t\t\tbuffer = lines.pop() ?? \"\";\n\n\t\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\t\tconst trimmed = line.trim();\n\t\t\t\t\t\t\tif (!trimmed) continue;\n\t\t\t\t\t\t\ta.emit(JSON.parse(trimmed) as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Process remaining buffer.\n\t\t\t\t\tif (!cancelled && buffer.trim()) {\n\t\t\t\t\t\ta.emit(JSON.parse(buffer.trim()) as T);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (!cancelled) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid run();\n\n\t\t\treturn () => {\n\t\t\t\tcancelled = true;\n\t\t\t};\n\t\t},\n\t\tsourceOpts(opts),\n\t);\n}\n","/**\n * OpenTelemetry (OTLP/HTTP) IO — `fromOTel` exposes traces/metrics/logs as\n * three reactive nodes via `externalBundle`. The caller owns the HTTP server\n * and wires the registrar callback to OTLP routes.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { batch } from \"@graphrefly/pure-ts/core\";\nimport { type BundleTriad, externalBundle } from \"../composition/external-register.js\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 * Prisma adapter (5.2b) — `fromPrisma` runs `model.findMany(args)` and emits\n * one `DATA` containing the full mapped row array, then `COMPLETE`.\n */\n\nimport { COMPLETE, ERROR, type Node, type NodeOptions, node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 node<U[]>(\n\t\t[],\n\t\t(_data, 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 * Prometheus scrape IO — `fromPrometheus` polls a `/metrics` endpoint via\n * `fromTimer + switchMap` (reactive timer, not bare `setInterval`) and emits\n * one `DATA` per parsed metric per scrape. `parsePrometheusText` exposes the\n * exposition-format parser as a pure helper.\n */\n\nimport { COMPLETE, ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { AsyncSourceOpts } from \"@graphrefly/pure-ts/extra\";\nimport { fromTimer, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { NS_PER_MS, NS_PER_SEC } from \"../resilience/backoff.js\";\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\tnode<PrometheusMetric>([], (_data, 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 * Apache Pulsar IO — `fromPulsar` (native-client consumer source with optional\n * manual ack via {@link AckableMessage} envelopes) and `toPulsar` (producer\n * sink). For Kafka-on-Pulsar (KoP), use the Kafka adapter instead.\n */\n\nimport { ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type AckableMessage, type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<PulsarMessage<T> | AckableMessage<PulsarMessage<T>>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\n\t\t\tconst loop = async () => {\n\t\t\t\twhile (active) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst rawMsg = await consumer.receive();\n\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\tconst structured: PulsarMessage<T> = {\n\t\t\t\t\t\t\ttopic: rawMsg.getTopicName(),\n\t\t\t\t\t\t\tmessageId: rawMsg.getMessageId().toString(),\n\t\t\t\t\t\t\tkey: rawMsg.getPartitionKey(),\n\t\t\t\t\t\t\tvalue: deserialize(rawMsg.getData()) as T,\n\t\t\t\t\t\t\tproperties: rawMsg.getProperties(),\n\t\t\t\t\t\t\tpublishTime: rawMsg.getPublishTimestamp(),\n\t\t\t\t\t\t\teventTime: rawMsg.getEventTimestamp(),\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\tvoid consumer.acknowledge(rawMsg).catch(reportAckError);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Manual ack — wrap in AckableMessage. Pulsar's SDK has no\n\t\t\t\t\t\t\t// per-message nack(requeue=false) — a plain `nack` re-delivers\n\t\t\t\t\t\t\t// after the subscription's negativeAckRedeliveryDelay. `requeue`\n\t\t\t\t\t\t\t// is honored as \"always redeliver\" (SDK default).\n\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\tconst envelope: AckableMessage<PulsarMessage<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\tvoid consumer.acknowledge(rawMsg).catch(reportAckError);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnack(_opts) {\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\tconst anyConsumer = consumer as unknown as {\n\t\t\t\t\t\t\t\t\t\tnegativeAcknowledge?: (m: unknown) => Promise<void> | void;\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\tconst result = anyConsumer.negativeAcknowledge?.(rawMsg);\n\t\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\t\tif (result && typeof (result as Promise<void>).then === \"function\") {\n\t\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\t}\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} catch (err) {\n\t\t\t\t\t\tif (active) a.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\n\t\t\tvoid loop();\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * RabbitMQ IO — `fromRabbitMQ` (queue-consumer source with optional manual\n * ack via {@link AckableMessage} envelopes) and `toRabbitMQ` (publisher\n * sink). Compatible with `amqplib`-style channels.\n */\n\nimport { ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type AckableMessage, type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<RabbitMQMessage<T> | AckableMessage<RabbitMQMessage<T>>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tlet consumerTag: string | undefined;\n\n\t\t\tconst start = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await channel.consume(\n\t\t\t\t\t\tqueue,\n\t\t\t\t\t\t(rawMsg) => {\n\t\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\t\tif (rawMsg === null) {\n\t\t\t\t\t\t\t\t// Broker cancelled the consumer (queue deleted, etc.).\n\t\t\t\t\t\t\t\tif (active) a.down([[ERROR, new Error(\"Consumer cancelled by broker\")]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst structured: RabbitMQMessage<T> = {\n\t\t\t\t\t\t\t\tqueue,\n\t\t\t\t\t\t\t\troutingKey: rawMsg.fields.routingKey,\n\t\t\t\t\t\t\t\texchange: rawMsg.fields.exchange,\n\t\t\t\t\t\t\t\tcontent: deserialize(rawMsg.content) as T,\n\t\t\t\t\t\t\t\tproperties: rawMsg.properties,\n\t\t\t\t\t\t\t\tdeliveryTag: rawMsg.fields.deliveryTag,\n\t\t\t\t\t\t\t\tredelivered: rawMsg.fields.redelivered,\n\t\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tif (autoAck) {\n\t\t\t\t\t\t\t\ta.emit(structured);\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tchannel.ack(rawMsg);\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} else {\n\t\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\t\tconst channelWithNack = channel as unknown as {\n\t\t\t\t\t\t\t\t\tnack?: (msg: unknown, allUpTo?: boolean, requeue?: boolean) => void;\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tconst envelope: AckableMessage<RabbitMQMessage<T>> = {\n\t\t\t\t\t\t\t\t\tvalue: structured,\n\t\t\t\t\t\t\t\t\tack() {\n\t\t\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tchannel.ack(rawMsg);\n\t\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tnack(nackOpts) {\n\t\t\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\t\t\tsettled = true;\n\t\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\t// SDK apply its own default (amqplib: true). Explicit\n\t\t\t\t\t\t\t\t\t\t// `false` routes to DLX if configured.\n\t\t\t\t\t\t\t\t\t\tconst requeue = nackOpts?.requeue;\n\t\t\t\t\t\t\t\t\t\tif (!channelWithNack.nack) {\n\t\t\t\t\t\t\t\t\t\t\treportAckError(\n\t\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\t);\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tchannelWithNack.nack(rawMsg, false, requeue);\n\t\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t\t\t\t}\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\ta.emit(envelope);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ noAck: false },\n\t\t\t\t\t);\n\t\t\t\t\tconsumerTag = result.consumerTag;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid start();\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t\tif (consumerTag !== undefined) {\n\t\t\t\t\tvoid channel.cancel(consumerTag);\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * Redis Streams IO — `fromRedisStream` (XREAD-BLOCK consumer source) and\n * `toRedisStream` (XADD producer sink). Caller owns the Redis client\n * lifecycle.\n */\n\nimport { ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<RedisStreamEntry<T>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tlet lastId = startId;\n\n\t\t\tconst poll = async () => {\n\t\t\t\twhile (active) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await client.xread(\"BLOCK\", blockMs, \"STREAMS\", key, lastId);\n\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\tif (result) {\n\t\t\t\t\t\t\tfor (const [_streamKey, entries] of result) {\n\t\t\t\t\t\t\t\tfor (const [id, fields] of entries) {\n\t\t\t\t\t\t\t\t\tlastId = id;\n\t\t\t\t\t\t\t\t\ta.emit({\n\t\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\t\t\tdata: parse(fields) as T,\n\t\t\t\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\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}\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tif (!active) return;\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\n\t\t\tvoid poll();\n\n\t\t\treturn () => {\n\t\t\t\tactive = false;\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * SQLite IO (roadmap §5.2b) — `fromSqlite` (one-shot synchronous query),\n * `fromSqliteCursor` (row-by-row streaming via `iterate()`), and `toSqlite`\n * (insert sink with optional transactional batching).\n *\n * Synchronous boundaries: SQLite drivers are typically synchronous\n * (`better-sqlite3`, `node:sqlite`), so errors propagate immediately rather\n * than via promise rejection. The duck-typed `SqliteDbLike.query` matches the\n * project-wide `query(sql, params)` convention used by Postgres/ClickHouse.\n */\n\nimport {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tdefaultConfig,\n\tERROR,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport {\n\ttype ReactiveSinkHandle,\n\treactiveSink,\n\ttype SinkFailure,\n\ttype SinkTransportError,\n} from \"./_sink.js\";\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 node<T[]>(\n\t\t[],\n\t\t(_data, 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 node<T>(\n\t\t[],\n\t\t(_data, 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 = node<SinkTransportError | null>([], { initial: null });\n\tconst sentNode = node<T | undefined>([], {\n\t\tinitial: undefined,\n\t\tequals: () => false,\n\t}) as unknown as Node<T>;\n\tconst failedNode = node<SinkFailure<T> | null>([], { initial: null });\n\tconst inFlightNode = node<number>([], { initial: 0 });\n\tconst bufferedNode = node<number>([], { initial: 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 * Server-Sent Events IO — `toSSE` / `toSSEBytes` (encode any node into the\n * `text/event-stream` wire format), `toReadableStream` (web-stream sink),\n * `parseSSEStream` (async-iterator parser), `fromSSE` (line-delimited parser\n * source).\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tdefaultConfig,\n\tERROR,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\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 node<Uint8Array>([], (_data, 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/** 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/** Options for {@link parseSSEStream}. */\nexport type ParseSSEStreamOptions<T = string> = {\n\t/** Parse the raw `data:` payload. Default: identity (string). */\n\tparse?: (raw: string) => T;\n\t/**\n\t * External abort signal. If aborted, the generator returns early after\n\t * cancelling the underlying reader / iterator. Does not emit an error —\n\t * the generator simply ends.\n\t */\n\tsignal?: AbortSignal;\n};\n\n/**\n * Parses a Server-Sent Events byte stream into an async-iterator of structured\n * `{event, data, id, retry}` records. Pure async generator with no reactive\n * dependency — safe to consume anywhere an `AsyncIterable<SSEEvent>` is\n * expected (LLM provider adapters, tests, non-reactive transports).\n *\n * Handles:\n * - Arbitrary chunk boundaries (internal text buffer + `TextDecoder` streaming).\n * - `\\n` and `\\r\\n` line endings.\n * - `event:` / `data:` (multi-line via repeated fields) / `id:` / `retry:`.\n * - Comments (`:` prefix).\n * - Cancels the underlying reader / iterator on external abort or consumer\n * break, so a quiet stream doesn't leak pending `read()` calls.\n *\n * Used internally by {@link fromSSE} (reactive `Node<SSEEvent>`) — exposed as a\n * pure helper so LLM provider adapters (Anthropic, OpenAI, Google) can parse\n * their SSE streams without building a reactive node per call.\n *\n * @param source - SSE byte source (`ReadableStream`, `Response`, or `AsyncIterable<Uint8Array>`).\n * @param opts - `{ parse?, signal? }`.\n * @returns `AsyncGenerator<SSEEvent<T>>` — yields one event per SSE block; returns on stream end / abort.\n *\n * @category extra\n */\nexport async function* parseSSEStream<T = string>(\n\tsource: ReadableStream<Uint8Array> | Response | AsyncIterable<Uint8Array>,\n\topts?: ParseSSEStreamOptions<T>,\n): AsyncGenerator<SSEEvent<T>, void, unknown> {\n\tconst parse = opts?.parse ?? ((raw: string) => raw as unknown as T);\n\tconst externalSignal = opts?.signal;\n\n\tconst decoder = new TextDecoder();\n\tlet buffer = \"\";\n\tlet currentEvent = \"message\";\n\tlet currentData: string[] = [];\n\tlet currentId: string | undefined;\n\tlet currentRetry: number | undefined;\n\tconst queue: SSEEvent<T>[] = [];\n\n\tconst flushEvent = () => {\n\t\tif (currentData.length === 0 && currentEvent === \"message\" && currentId === undefined) {\n\t\t\tcurrentData = [];\n\t\t\treturn;\n\t\t}\n\t\tconst raw = currentData.join(\"\\n\");\n\t\tqueue.push({\n\t\t\tevent: currentEvent,\n\t\t\tdata: parse(raw),\n\t\t\tid: currentId,\n\t\t\tretry: currentRetry,\n\t\t});\n\t\tcurrentEvent = \"message\";\n\t\tcurrentData = [];\n\t\tcurrentId = undefined;\n\t\tcurrentRetry = undefined;\n\t};\n\n\tconst processLine = (line: string) => {\n\t\tif (line === \"\") {\n\t\t\tflushEvent();\n\t\t\treturn;\n\t\t}\n\t\tif (line.startsWith(\":\")) return; // comment\n\t\tconst colon = line.indexOf(\":\");\n\t\tconst field = colon < 0 ? line : line.slice(0, colon);\n\t\tlet value = colon < 0 ? \"\" : line.slice(colon + 1);\n\t\tif (value.startsWith(\" \")) value = value.slice(1);\n\t\tswitch (field) {\n\t\t\tcase \"event\":\n\t\t\t\tcurrentEvent = value;\n\t\t\t\tbreak;\n\t\t\tcase \"data\":\n\t\t\t\tcurrentData.push(value);\n\t\t\t\tbreak;\n\t\t\tcase \"id\":\n\t\t\t\tif (!value.includes(\"\\0\")) currentId = value;\n\t\t\t\tbreak;\n\t\t\tcase \"retry\": {\n\t\t\t\tconst n = Number(value);\n\t\t\t\tif (Number.isFinite(n)) currentRetry = n;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tconst processChunk = (chunk: Uint8Array, done: boolean) => {\n\t\tbuffer += decoder.decode(chunk, { stream: !done });\n\t\tconst parts = buffer.split(/\\r?\\n/);\n\t\tbuffer = parts.pop() ?? \"\";\n\t\tfor (const line of parts) processLine(line);\n\t};\n\n\t// Resolve the underlying byte source into either a `ReadableStream` or an\n\t// `AsyncIterator<Uint8Array>` — identical dispatch as the legacy fromSSE.\n\tconst resp = source as Response;\n\tconst stream =\n\t\tsource instanceof ReadableStream\n\t\t\t? source\n\t\t\t: resp && typeof resp === \"object\" && resp.body instanceof ReadableStream\n\t\t\t\t? resp.body\n\t\t\t\t: null;\n\n\tlet reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n\tlet iter: AsyncIterator<Uint8Array> | undefined;\n\t// `cleanupDone` flips once we've invoked `reader.cancel()` / `iter.return()`\n\t// — guards against the `onAbort` listener + the `finally` path both\n\t// cancelling the same underlying resource (WHATWG streams allow double-\n\t// cancel but custom `AsyncIterator.return` implementations are not\n\t// required to be idempotent).\n\tlet cleanupDone = false;\n\tconst cleanupReader = (): void => {\n\t\tif (cleanupDone) return;\n\t\tcleanupDone = true;\n\t\tif (reader) {\n\t\t\tvoid reader.cancel().catch(() => undefined);\n\t\t}\n\t\tif (iter && typeof iter.return === \"function\") {\n\t\t\tvoid Promise.resolve(iter.return()).catch(() => undefined);\n\t\t}\n\t};\n\n\t// Wire the external abort signal to cancel the reader / iterator promptly\n\t// instead of waiting for the next chunk.\n\tconst onAbort = (): void => {\n\t\tcleanupReader();\n\t};\n\tif (externalSignal) {\n\t\tif (externalSignal.aborted) return;\n\t\texternalSignal.addEventListener(\"abort\", onAbort, { once: true });\n\t}\n\n\ttry {\n\t\tif (stream) {\n\t\t\treader = stream.getReader();\n\t\t\twhile (!externalSignal?.aborted) {\n\t\t\t\tconst { value, done } = await reader.read();\n\t\t\t\tif (done) break;\n\t\t\t\tprocessChunk(value, false);\n\t\t\t\twhile (queue.length > 0) {\n\t\t\t\t\tconst ev = queue.shift() as SSEEvent<T>;\n\t\t\t\t\tyield ev;\n\t\t\t\t}\n\t\t\t}\n\t\t\tprocessChunk(new Uint8Array(), true);\n\t\t} else {\n\t\t\tconst asyncIter = source as AsyncIterable<Uint8Array>;\n\t\t\titer = asyncIter[Symbol.asyncIterator]();\n\t\t\twhile (!externalSignal?.aborted) {\n\t\t\t\tconst step = await iter.next();\n\t\t\t\tif (step.done) break;\n\t\t\t\tprocessChunk(step.value, false);\n\t\t\t\twhile (queue.length > 0) {\n\t\t\t\t\tconst ev = queue.shift() as SSEEvent<T>;\n\t\t\t\t\tyield ev;\n\t\t\t\t}\n\t\t\t}\n\t\t\tprocessChunk(new Uint8Array(), true);\n\t\t}\n\t\tif (buffer.trim()) {\n\t\t\tfor (const line of buffer.split(/\\r?\\n/)) processLine(line);\n\t\t\tflushEvent();\n\t\t}\n\t\twhile (queue.length > 0) {\n\t\t\tconst ev = queue.shift() as SSEEvent<T>;\n\t\t\tyield ev;\n\t\t}\n\t} finally {\n\t\tif (externalSignal) {\n\t\t\texternalSignal.removeEventListener(\"abort\", onAbort);\n\t\t}\n\t\t// Idempotent cleanup — if `onAbort` already ran the cancel, this is a\n\t\t// no-op. Covers the normal consumer-break path (generator exits → finally\n\t\t// runs → cancel underlying reader / iterator so a quiet upstream\n\t\t// doesn't leak its `read()` call).\n\t\tcleanupReader();\n\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, ...rest } = opts ?? {};\n\treturn node<SSEEvent<T>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tconst ctrl = new AbortController();\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tfor await (const ev of parseSSEStream<T>(source, { parse, signal: ctrl.signal })) {\n\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\ta.emit(ev);\n\t\t\t\t\t}\n\t\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (active) a.down([[ERROR, err]]);\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\tctrl.abort();\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\n}\n","/**\n * StatsD / DogStatsD IO — `fromStatsD` registrar-based source plus\n * `parseStatsD` helper for the line format. The caller owns the UDP socket;\n * the adapter only wires the `emit` triad.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype EmitTriad,\n\ttype ExternalRegister,\n\texternalProducer,\n} from \"../composition/external-register.js\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 * Syslog (RFC 5424) IO — `fromSyslog` registrar-based source plus\n * `parseSyslog` helper for the line format. The caller owns the UDP/TCP\n * socket; the adapter only wires the `emit` triad.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype EmitTriad,\n\ttype ExternalRegister,\n\texternalProducer,\n} from \"../composition/external-register.js\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 * ClickHouse insert sink IO — `toClickHouse` accumulates upstream `DATA`\n * values and inserts them in batches via the duck-typed\n * {@link ClickHouseInsertClientLike}.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * File-writer sink IO — `toFile` writes upstream `DATA` to any\n * `FileWriterLike` (e.g. `fs.createWriteStream`). Buffered or write-through\n * depending on `flushIntervalMs` / `batchSize`.\n *\n * Uses a duck-typed writable so the universal `extra/io` entry stays\n * browser-safe — the caller injects the Node `fs` writer at the boundary.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * CSV file sink IO — `toCSV` adds CSV row formatting on top of\n * {@link toFile}. Uses the local `escapeCSVField` helper to quote cells that\n * contain delimiters / quotes / newlines.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport type { ReactiveSinkHandle, SinkTransportError } from \"./_sink.js\";\nimport { type FileWriterLike, toFile } from \"./to-file.js\";\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 * Grafana Loki sink IO — `toLoki` pushes upstream `DATA` values as log\n * entries via the duck-typed {@link LokiClientLike} `push()` surface.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * MongoDB insert sink IO — `toMongo` inserts each upstream `DATA` value via\n * the duck-typed {@link MongoCollectionLike} `insertOne()`.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * Postgres insert sink IO — `toPostgres` inserts each upstream `DATA` value\n * via the duck-typed {@link PostgresClientLike} `query()` surface.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * S3 object-storage sink IO — `toS3` buffers upstream `DATA` values and\n * uploads them as NDJSON or JSON objects via the duck-typed\n * {@link S3ClientLike}.\n *\n * `S3ClientLike` is also used by `checkpointToS3` (in `./checkpoint.ts`).\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * Grafana Tempo sink IO — `toTempo` pushes upstream `DATA` values as trace\n * spans (OTLP/HTTP shape) via the duck-typed {@link TempoClientLike}.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * Webhook IO — `fromWebhook` is a thin wrapper over `externalProducer` that\n * exposes the standard `EmitTriad` (`emit` / `error` / `complete`) callback\n * shape to the caller's framework integration (Express, Fastify, Hono,\n * Cloudflare Workers, etc.).\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype EmitTriad,\n\ttype ExternalRegister,\n\texternalProducer,\n} from \"../composition/external-register.js\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 * WebSocket IO — `fromWebSocket` (DOM-style `WebSocketLike` source / register\n * variant), `toWebSocket` (sink with optional ack-tracking + retry),\n * `fromWebSocketReconnect` (`fromWebSocket` wrapped in retry-on-disconnect with\n * exponential backoff).\n */\n\nimport { COMPLETE, ERROR, type Message, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { retry } from \"../resilience/retry.js\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<T>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tlet cleanup: (() => void) | undefined;\n\t\t\tconst runCleanup = () => {\n\t\t\t\tconst fn = cleanup;\n\t\t\t\tcleanup = undefined;\n\t\t\t\tfn?.();\n\t\t\t};\n\t\t\tconst terminate = (message: Message) => {\n\t\t\t\tif (!active) return;\n\t\t\t\tactive = false;\n\t\t\t\ta.down([message]);\n\t\t\t\trunCleanup();\n\t\t\t};\n\t\t\tconst emit = (raw: unknown, event: unknown = raw) => {\n\t\t\t\tif (!active) return;\n\t\t\t\ttry {\n\t\t\t\t\tconst payload =\n\t\t\t\t\t\traw !== null && typeof raw === \"object\" && \"data\" in (raw as Record<string, unknown>)\n\t\t\t\t\t\t\t? (raw as WebSocketMessageEventLike).data\n\t\t\t\t\t\t\t: raw;\n\t\t\t\t\tconst parsed = parse ? parse(payload, event) : (payload as T);\n\t\t\t\t\ta.emit(parsed);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tterminate([ERROR, err]);\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst error = (err: unknown) => {\n\t\t\t\tterminate([ERROR, err]);\n\t\t\t};\n\t\t\tconst complete = () => {\n\t\t\t\tterminate([COMPLETE]);\n\t\t\t};\n\t\t\tif (typeof socketOrRegister === \"function\") {\n\t\t\t\ttry {\n\t\t\t\t\tcleanup = socketOrRegister(emit, error, complete);\n\t\t\t\t\tif (typeof cleanup !== \"function\") {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"fromWebSocket register contract violation: register must return cleanup callable\",\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\tterminate([ERROR, err]);\n\t\t\t\t}\n\t\t\t\treturn () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t\trunCleanup();\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst ws = socketOrRegister;\n\t\t\tconst onMessage = (event: unknown) => emit(event, event);\n\t\t\tconst onError = (event: unknown) => error(event);\n\t\t\tconst onClose = () => complete();\n\t\t\tws.addEventListener(\"message\", onMessage);\n\t\t\tws.addEventListener(\"error\", onError);\n\t\t\tws.addEventListener(\"close\", onClose);\n\t\t\tcleanup = () => {\n\t\t\t\tws.removeEventListener(\"message\", onMessage);\n\t\t\t\tws.removeEventListener(\"error\", onError);\n\t\t\t\tws.removeEventListener(\"close\", onClose);\n\t\t\t\tif (closeOnTeardown) ws.close();\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\t\tsourceOpts(rest),\n\t);\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: retryOpt,\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: retryOpt,\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/** 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 retry>[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 retry} rebuilds the inner source and reconnects.\n *\n * For transient errors, {@link retry} 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 retry<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).node;\n}\n","/**\n * Retry — re-attempt a node on terminal failure.\n *\n * Two modes selected by the type of `input`:\n * - **Source mode** (`Node<T>`): resubscribes the same node after each ERROR.\n * Upstream must be `resubscribable: true` or retries are silent no-ops.\n * - **Factory mode** (`() => Node<T>`): builds a fresh node per attempt.\n *\n * Shared with `circuitBreaker` / `rateLimiter`: `NodeOrValue<RetryOptions>`\n * lets callers swap retry config reactively (re-validates on each attempt).\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\ttype Message,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n} from \"@graphrefly/pure-ts/core\";\nimport { coerceDelayNs, isNode, msgVal, type NodeOrValue, operatorOpts } from \"./_internal.js\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tresolveBackoffPreset,\n} from \"./backoff.js\";\nimport type { StatusValue } from \"./status.js\";\n\n/**\n * Lifecycle-shaped state companion emitted by {@link retry} (DS-13.5.B,\n * locked 2026-05-01). Tracks the retry state machine's current status,\n * the attempt counter, and the last scheduled delay (null before the\n * first retry).\n *\n * @category extra/resilience\n */\nexport interface RetryState {\n\tstatus: StatusValue;\n\tattempt: number;\n\tlastDelay_ns: number | null;\n}\n\n/**\n * Bundle returned by {@link retry}: the retry-wrapped output node and its\n * lifecycle state companion. Pre-1.0 break vs the prior `Node<T>` return.\n *\n * **Single-subscriber / pipeline-only contract (DS-13.5.B QA, N1, 2026-05-03).**\n * The `retryState` companion is allocated once at factory time and shared\n * across all subscribers to `node`. With one subscriber (the typical use\n * case — wire `node` into your downstream chain, optionally observe\n * `retryState` separately) the companion reflects a coherent timeline.\n * With **two or more subscribers** to `node`, each subscriber re-runs the\n * producer body and writes into the same `retryState`, including\n * `publish(\"pending\")` resets that can clobber an in-flight machine's\n * `running`/`paused` state. Don't fan out `node` to multiple subscribers\n * and rely on `retryState` accuracy unless you use\n * {@link keepalive} / `share`-style consolidation.\n *\n * @category extra/resilience\n */\nexport interface RetryBundle<T> {\n\tnode: Node<T>;\n\tretryState: Node<RetryState>;\n}\n\nexport type RetryOptions = {\n\t/**\n\t * Max retry attempts after each terminal `ERROR` (not counting the first failure).\n\t *\n\t * **Required when `backoff` is set.** Pass `Infinity` to opt in to unbounded retries\n\t * — the explicit value rules out the silent-infinite-budget footgun (a flaky provider\n\t * + exponential backoff + omitted `count` would previously default to ~2.1B retries).\n\t */\n\tcount?: number;\n\t/** Delay between attempts; strategies use **nanoseconds**. */\n\tbackoff?: BackoffStrategy | BackoffPreset;\n\t/**\n\t * Caller-supplied metadata merged into the produced node's `meta` (Tier 5.2\n\t * D8 widening). Use {@link domainMeta} to tag the layer for `describe()`\n\t * grouping. The primitive's `factoryTag(\"retry\", …)` always wins against\n\t * caller keys.\n\t */\n\tmeta?: Record<string, unknown>;\n};\n\n/** Factory-mode-only options. `initial` seeds the outer node's cache before the first attempt. */\nexport type RetryFactoryOptions<T> = RetryOptions & {\n\t/** Initial cache value for the outer node before the factory runs the first time. */\n\tinitial?: T;\n};\n\n/**\n * Resolved retry config shared by source-mode and factory-mode wrappers.\n * Centralises the unbounded-retry footgun guard and strategy resolution.\n */\ntype ResolvedRetryConfig = {\n\tmaxRetries: number;\n\tstrategy: BackoffStrategy | null;\n};\n\nfunction resolveRetryConfig(opts?: RetryOptions): ResolvedRetryConfig {\n\tconst count = opts?.count;\n\tconst backoffOpt = opts?.backoff;\n\n\t// Unbounded-retry footgun fix: if `backoff` is set without explicit `count`,\n\t// throw at construction time. Caller must opt in to `Infinity` for unbounded.\n\tif (backoffOpt !== undefined && count === undefined) {\n\t\tthrow new RangeError(\n\t\t\t\"retry({ backoff }) requires explicit count to prevent unbounded retries; pass { count: <n>, backoff: ... }\",\n\t\t);\n\t}\n\n\tconst maxRetries = count !== undefined ? count : 0;\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 { maxRetries, strategy };\n}\n\nfunction retryFactoryArgs(opts?: RetryOptions): Record<string, unknown> | undefined {\n\tconst args: Record<string, unknown> = {};\n\tif (opts?.count !== undefined) args.count = opts.count;\n\tif (typeof opts?.backoff === \"string\") args.backoff = opts.backoff;\n\treturn Object.keys(args).length > 0 ? args : undefined;\n}\n\n/**\n * Shared retry state machine. Both `_retrySource` and `_retryFactory` thin-wrap this:\n * the only per-mode logic is supplied via `acquireSource` (returns a fresh `Node<T>`\n * per attempt — for source-mode it just returns the captured `Node`; for factory-mode\n * it calls the user factory and forwards synchronous throws into the same retry path).\n *\n * **Reactive cfg (Tier 6.5 3.2.2, 2026-04-29).** `getCfg` is invoked at\n * every decision point (`scheduleRetryOrFinish` count + strategy reads)\n * so option swaps mid-flight take effect at the next attempt boundary\n * per the locked semantic rule: \"next attempt fails immediately if\n * already exhausted under new count; `backoff` swap takes effect at next\n * retry's delay calculation.\"\n */\nfunction _runRetryStateMachine<T>(\n\tgetCfg: () => ResolvedRetryConfig,\n\tacquireSource: () => Node<T>,\n\ta: { emit: (v: T) => void; down: (msgs: Message[]) => void },\n\temitState?: (next: RetryState) => void,\n): () => void {\n\tlet attempt = 0;\n\tlet stopped = false;\n\tlet prevDelay: number | null = null;\n\tlet unsub: (() => void) | undefined;\n\tconst timer = new ResettableTimer();\n\tconst publish = (status: StatusValue): void => {\n\t\temitState?.({ status, attempt, lastDelay_ns: prevDelay });\n\t};\n\tpublish(\"pending\");\n\n\tfunction disconnectUpstream(): void {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\n\tfunction scheduleRetryOrFinish(err: unknown): void {\n\t\tif (stopped) return;\n\t\tconst cfg = getCfg();\n\t\tif (attempt >= cfg.maxRetries) {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\tconst raw = cfg.strategy === null ? 0 : cfg.strategy(attempt, err, prevDelay);\n\t\t// null from strategy = \"stop retrying\" (e.g. withMaxAttempts cap reached)\n\t\tif (raw === null || raw === undefined) {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\t// A misbehaving strategy (returns NaN / non-finite / negative) MUST NOT\n\t\t// escape into the upstream drain. Treat it like `strategy === null`\n\t\t// (stop retrying) and emit the original error — the strategy bug is a\n\t\t// separate concern the user can inspect via the emitted error's stack.\n\t\tlet delayNs: number;\n\t\ttry {\n\t\t\tdelayNs = coerceDelayNs(raw);\n\t\t} catch {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\tprevDelay = delayNs;\n\t\tattempt += 1;\n\t\tdisconnectUpstream();\n\t\tpublish(\"paused\");\n\t\t// `Math.max(1, …)` floor: every backoff schedule floors at 1ms even when\n\t\t// the strategy returns 0ns. Avoids 0-delay re-entrancy on the active\n\t\t// stack frame (which would risk stack overflow on a tight ERROR loop).\n\t\tconst delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;\n\t\t// §5.10: setTimeout (not fromTimer) — retry delay needs clearTimeout/setTimeout;\n\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\ttimer.start(delayMs, () => {\n\t\t\tif (stopped) return;\n\t\t\tconnect();\n\t\t});\n\t}\n\n\tfunction connect(): void {\n\t\ttimer.cancel();\n\t\tdisconnectUpstream();\n\t\tlet src: Node<T>;\n\t\ttry {\n\t\t\tsrc = acquireSource();\n\t\t} catch (err) {\n\t\t\tscheduleRetryOrFinish(err);\n\t\t\treturn;\n\t\t}\n\t\tpublish(\"running\");\n\t\tunsub = src.subscribe((msgs) => {\n\t\t\tif (stopped) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tconst t = m[0];\n\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\telse if (t === DATA) {\n\t\t\t\t\tattempt = 0;\n\t\t\t\t\tprevDelay = null;\n\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\tpublish(\"running\");\n\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t// DF2 (2026-04-29): set `stopped = true` BEFORE\n\t\t\t\t\t// `disconnectUpstream()` so a re-entrant ERROR delivered\n\t\t\t\t\t// in the same wave (after disconnect runs but before the\n\t\t\t\t\t// teardown closure fires `stopped = true`) hits the\n\t\t\t\t\t// `if (stopped) return` guard at line 159 and cannot\n\t\t\t\t\t// schedule a new retry timer.\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\tpublish(\"completed\");\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\tscheduleRetryOrFinish(msgVal(m));\n\t\t\t\t\treturn;\n\t\t\t\t} else a.down([m]);\n\t\t\t}\n\t\t});\n\t}\n\n\tconnect();\n\n\treturn () => {\n\t\tconst wasStopped = stopped;\n\t\tstopped = true;\n\t\ttimer.cancel();\n\t\tdisconnectUpstream();\n\t\tif (!wasStopped) publish(\"cancelled\");\n\t};\n}\n\n/**\n * Retry operator — two modes selected by the type of `input`:\n *\n * **Source mode** (`input: Node<T>`): resubscribes to the same node after each terminal\n * `ERROR`. The upstream should use `resubscribable: true` if it must emit again after `ERROR`.\n *\n * **Factory mode** (`input: () => Node<T>`): invokes the factory to build a fresh `Node<T>`\n * on every connect / reconnect. Ideal for producers that capture per-attempt resources\n * (sockets, clients, file handles) that become unusable after an error. Synchronous\n * exceptions thrown by the factory are treated as terminal ERROR and run through the\n * same retry pipeline as inner-node ERROR.\n *\n * @param input - Upstream node or factory that returns a fresh node per attempt.\n * @param opts - `count` caps attempts (**required when `backoff` is set**; pass `Infinity` to opt in to unbounded); `backoff` supplies delay in **nanoseconds** (or a preset name); `initial` seeds the outer node cache (factory mode only).\n * @returns Node that retries on error.\n *\n * @throws {RangeError} when `backoff` is provided without an explicit `count` (unbounded-retry footgun guard) or when `count < 0`.\n *\n * @remarks\n * **Protocol:** Forwards unknown message tuples unchanged; handles `DIRTY`, `DATA`, `RESOLVED`, `COMPLETE`, `ERROR`.\n *\n * **Backoff floor:** every scheduled delay is floored at 1ms via `Math.max(1, delayNs / NS_PER_MS)` even when the strategy returns 0ns. This avoids 0-delay re-entrancy on the active stack frame on a tight ERROR loop. Strategies that return `null`/`undefined` stop retrying immediately and forward the original error.\n *\n * @example\n * ```ts\n * // Source mode — resubscribe the same node:\n * import { ERROR, NS_PER_SEC, producer, retry, constant } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = producer(\n * (a) => { a.down([[ERROR, new Error(\"x\")]]); },\n * { resubscribable: true },\n * );\n * const out = retry(src, { count: 2, backoff: constant(0.25 * NS_PER_SEC) });\n *\n * // Factory mode — fresh node per attempt (e.g. reconnecting WebSocket):\n * import { NS_PER_SEC, exponential, retry, fromWebSocket } from \"@graphrefly/graphrefly-ts\";\n *\n * const connected$ = retry(\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 retry<T>(input: Node<T>, opts?: NodeOrValue<RetryOptions>): RetryBundle<T>;\nexport function retry<T>(\n\tinput: () => Node<T>,\n\topts?: NodeOrValue<RetryFactoryOptions<T>>,\n): RetryBundle<T>;\nexport function retry<T>(\n\tinput: Node<T> | (() => Node<T>),\n\topts?: NodeOrValue<RetryOptions | RetryFactoryOptions<T>>,\n): RetryBundle<T> {\n\tconst retryState = node<RetryState>([], {\n\t\tname: \"retryState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: { status: \"pending\", attempt: 0, lastDelay_ns: null },\n\t\tequals: (a, b) =>\n\t\t\ta === b ||\n\t\t\t(a != null &&\n\t\t\t\tb != null &&\n\t\t\t\ttypeof a === \"object\" &&\n\t\t\t\ttypeof b === \"object\" &&\n\t\t\t\tJSON.stringify(a) === JSON.stringify(b)),\n\t});\n\tconst emit = (s: RetryState): void => {\n\t\tretryState.down([[DIRTY], [DATA, s]]);\n\t};\n\tif (typeof input === \"function\") {\n\t\treturn {\n\t\t\tnode: _retryFactory(input, opts as NodeOrValue<RetryFactoryOptions<T>> | undefined, emit),\n\t\t\tretryState,\n\t\t};\n\t}\n\treturn {\n\t\tnode: _retrySource(input, opts as NodeOrValue<RetryOptions> | undefined, emit),\n\t\tretryState,\n\t};\n}\n\n// DS-13.5.B helper: like `resolveReactiveOption` but shallow-merges each\n// reactive emit over the prior opts and treats empty `{}` as a no-op\n// (per the locked cross-cutting rule). Static-form arg returns the value\n// as-is and never subscribes.\nfunction makeMergedOptsMirror<R extends Record<string, unknown>>(\n\targ: NodeOrValue<R> | undefined,\n): { current: () => R | undefined; unsub: () => void } {\n\tif (arg === undefined) {\n\t\treturn { current: () => undefined, unsub: () => undefined };\n\t}\n\tif (!isNode(arg)) {\n\t\treturn { current: () => arg as R, unsub: () => undefined };\n\t}\n\tconst optsNode = arg as Node<R>;\n\tlet merged: R | undefined = (optsNode.cache as R | undefined) ?? undefined;\n\tconst unsub = optsNode.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] !== DATA) continue;\n\t\t\tconst next = m[1] as R | undefined;\n\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\tif (Object.keys(next).length === 0) continue; // empty {} no-op\n\t\t\tmerged = { ...(merged ?? ({} as R)), ...next } as R;\n\t\t}\n\t});\n\treturn { current: () => merged, unsub };\n}\n\n// DF6 (2026-04-29): once-per-source dedup for the source-mode-retry warn.\n// Mirrors the `_bumpCursorWarned` pattern in `extra/mutation/index.ts`.\nconst _retrySourceNonResubscribableWarned = new WeakSet<Node<unknown>>();\n\nfunction _retrySource<T>(\n\tsource: Node<T>,\n\topts?: NodeOrValue<RetryOptions>,\n\temitState?: (s: RetryState) => void,\n): Node<T> {\n\t// Source-mode retry re-subscribes to the SAME source node after each\n\t// terminal ERROR. If the upstream was constructed with the default\n\t// `resubscribable: false`, the second subscribe-after-terminal is a\n\t// silent no-op and retries effectively never re-deliver. Surface\n\t// once-per-source so misconfigurations fail loud without log spam.\n\tconst sourceWithFlag = source as unknown as { _resubscribable?: boolean };\n\tif (\n\t\tsourceWithFlag._resubscribable === false &&\n\t\t!_retrySourceNonResubscribableWarned.has(source)\n\t) {\n\t\t_retrySourceNonResubscribableWarned.add(source);\n\t\tconsole.warn(\n\t\t\t\"retry(source, opts): source-mode requires `resubscribable: true` on the upstream \" +\n\t\t\t\t\"node. Retries will be silent no-ops after the first ERROR. Either pass \" +\n\t\t\t\t\"`resubscribable: true` to the source factory, OR use factory-mode retry \" +\n\t\t\t\t\"`retry(() => buildSource(), opts)` so each attempt builds a fresh node.\",\n\t\t);\n\t}\n\tconst staticOpts = isNode(opts) ? undefined : (opts as RetryOptions | undefined);\n\t// Eager validation for static-form opts (preserves construction-time\n\t// \"backoff without count\" RangeError). Reactive-form opts re-validate\n\t// per `getCfg()` call inside the state machine.\n\tif (!isNode(opts)) resolveRetryConfig(staticOpts);\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tconst merged = makeMergedOptsMirror<RetryOptions>(opts);\n\t\t\tconst getCfg = (): ResolvedRetryConfig => resolveRetryConfig(merged.current());\n\t\t\tconst inner = _runRetryStateMachine(getCfg, () => source, a, emitState);\n\t\t\treturn () => {\n\t\t\t\tinner();\n\t\t\t\tmerged.unsub();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t\tmeta: {\n\t\t\t\t...(staticOpts?.meta ?? {}),\n\t\t\t\t...factoryTag(\n\t\t\t\t\t\"retry\",\n\t\t\t\t\tisNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t);\n}\n\nfunction _retryFactory<T>(\n\tfactory: () => Node<T>,\n\topts?: NodeOrValue<RetryFactoryOptions<T>>,\n\temitState?: (s: RetryState) => void,\n): Node<T> {\n\tconst staticOpts = isNode(opts) ? undefined : (opts as RetryFactoryOptions<T> | undefined);\n\t// Eager validation for static-form opts (Tier 3.1 footgun preservation).\n\tif (!isNode(opts)) resolveRetryConfig(staticOpts);\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tconst merged = makeMergedOptsMirror<RetryFactoryOptions<T>>(opts);\n\t\t\tconst getCfg = (): ResolvedRetryConfig => resolveRetryConfig(merged.current());\n\t\t\tconst inner = _runRetryStateMachine(getCfg, factory, a, emitState);\n\t\t\treturn () => {\n\t\t\t\tinner();\n\t\t\t\tmerged.unsub();\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: staticOpts?.initial as T | undefined,\n\t\t\tmeta: {\n\t\t\t\t...(staticOpts?.meta ?? {}),\n\t\t\t\t...factoryTag(\n\t\t\t\t\t\"retry\",\n\t\t\t\t\tisNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t);\n}\n","/**\n * Metadata helpers for pattern-layer nodes (Tier 2.2 promotion from\n * `patterns/_internal/`).\n *\n * Each domain (orchestration, messaging, reduction, ai, cqrs, domain_template,\n * memory, lens, audit, harness) shares the same metadata convention. Promoted\n * to `extra/` so non-patterns code (and downstream consumers building their\n * own domain primitives) can use the same shape.\n *\n * @module\n */\n\n/**\n * Build a domain metadata object for pattern-layer nodes.\n *\n * Each domain follows the same shape: `{ [domain]: true, [domain]_type: kind, ...extra }`.\n *\n * @param domain - The domain tag (e.g. `\"orchestration\"`, `\"ai\"`, `\"cqrs\"`).\n * @param kind - The specific type within the domain (e.g. `\"gate\"`, `\"prompt\"`).\n * @param extra - Additional metadata to merge.\n * @returns Metadata object.\n */\nexport function domainMeta(\n\tdomain: string,\n\tkind: string,\n\textra?: Record<string, unknown>,\n): Record<string, unknown> {\n\treturn {\n\t\t[domain]: true,\n\t\t[`${domain}_type`]: kind,\n\t\t...(extra ?? {}),\n\t};\n}\n","/**\n * emitToMeta — forward DATA to a meta companion node via tier-3 deferral.\n *\n * Extracted from patterns/_internal/index.ts during cleave A2.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { DATA, defaultConfig, downWithBatch } from \"@graphrefly/pure-ts/core\";\n\n// emitToMeta\n// ---------------------------------------------------------------------------\n\n/**\n * Forward a single `[DATA, value]` to a meta companion node via tier-3\n * deferral, tolerating absent companions. Used by patterns that publish\n * per-wave statistics alongside their main output (cache-hit-rate,\n * segment-count, layout-time-ns, etc.) — subscribers see the parent's\n * DATA first because phase-2 completes before phase-3 during drain.\n *\n * // Expands to: `if (meta) downWithBatch(meta, [[Type, value]])` with null-guard.\n *\n * @internal\n */\nexport function emitToMeta<T>(metaNode: Node<T> | undefined, value: T): void {\n\tif (metaNode == null) return;\n\tdownWithBatch((msgs) => metaNode.down(msgs), [[DATA, value]], defaultConfig.tierOf);\n}\n\n// ---------------------------------------------------------------------------\n","/**\n * Universal mutation framework (Phase 14 — DS-14 locked 2026-05-05).\n *\n * Single `mutate(act, opts)` factory replaces the prior `lightMutation` +\n * `wrapMutation` two-tier split (pre-1.0 break per Q-O2).\n *\n * Two frames:\n * - `\"inline\"` — no batch; up() runs raw. Seq bumps before action; persists\n * on throw. Hot-path-friendly for atomic single-write mutations.\n * - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n * deferred deliveries, then `down()` runs (if provided), then failure record.\n *\n * Phase-4 primitives share the same shape: imperative mutation methods +\n * closure state + reactive audit log + freeze-at-entry + rollback-on-throw.\n * This module factors out the common machinery so each primitive becomes\n * declarative wiring over typed audit records.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tDIRTY,\n\ttype Node,\n\ttype NodeGuard,\n\tnode,\n\tpolicy,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype ReactiveLogBundle,\n\ttype ReactiveLogOptions,\n\treactiveLog,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\n\n// ── tryIncrementBounded ──────────────────────────────────────────────────\n\n/**\n * Bounded increment for a self-owned counter state node.\n *\n * Reads `counter.cache`, bumps by `by` (default 1) if `cur + by <= cap`,\n * writes back. Returns `false` when the cap would be exceeded (no-op write).\n * Documented P3 exception: the counter is not a declared dep of the caller —\n * it's a private budget read+written from a single call site. This helper\n * keeps the `.cache` access in one named place so caller bodies (which may\n * be inside reactive fn execution paths) stay free of cross-node `.cache`\n * reads.\n *\n * **Safety today:**\n * 1. Single-threaded JS runner never invokes the caller concurrently.\n * 2. `counter.down` writes the cache synchronously before returning, so\n * synchronous re-entry through a downstream publish reads the\n * freshly-incremented value — no double-count.\n *\n * **Future risk:** under a free-threaded runner (PY no-GIL or hypothetical\n * concurrent TS runner), two concurrent firings could still race. Revisit\n * when that surfaces.\n *\n * @param counter - Self-owned counter Node. Caller is the sole writer.\n * @param cap - Upper bound (inclusive). Pass `Number.MAX_SAFE_INTEGER` for\n * \"effectively unbounded\" use cases (e.g. token meters).\n * @param by - Delta to add (default `1`). Must be a finite non-negative\n * number; callers should pre-validate. Overflow-safe via\n * `by > cap - cur` check rather than `cur + by >= cap`.\n */\nexport function tryIncrementBounded(counter: Node<number>, cap: number, by = 1): boolean {\n\tconst cur = (counter.cache as number | undefined) ?? 0;\n\tif (by > cap - cur) return false;\n\tcounter.down([[DIRTY], [DATA, cur + by]]);\n\treturn true;\n}\n\n// ── Audit record schema ──────────────────────────────────────────────────\n\n/** Shared base shape for every audit record. Per-primitive types extend this. */\nexport interface BaseAuditRecord {\n\treadonly t_ns: number;\n\treadonly seq?: number;\n\treadonly handlerVersion?: { id: string; version: string | number };\n}\n\n// ── Default audit guard ──────────────────────────────────────────────────\n\n/**\n * Allow `observe` and `signal`; deny external `write` on the audit log so\n * consumers can subscribe + signal-bridge but cannot inject fake records.\n */\nexport const DEFAULT_AUDIT_GUARD: NodeGuard = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n// ── createAuditLog ───────────────────────────────────────────────────────\n\nexport type AuditLogOpts<R extends BaseAuditRecord> = {\n\tname: string;\n\t/** Bounded retention; default 1024 per Audit 2 / cross-cutting bounded-default policy. */\n\tretainedLimit?: number;\n\t/** Override the default audit guard. */\n\tguard?: NodeGuard;\n\t/** Mount the audit `entries` Node under this graph (and activate withLatest). */\n\tgraph?: Graph;\n\t/** Pass-through to {@link reactiveLog}. */\n\tversioning?: ReactiveLogOptions<R>[\"versioning\"];\n};\n\n/**\n * Build a reactive audit log with sane defaults: bounded retention, deny-write\n * guard, `withLatest()` companions activated. Returns the {@link ReactiveLogBundle}\n * directly — primitives expose this as `<primitive>.events` / `.decisions` /\n * `.dispatches` / `.invocations` and alias it as `.audit`.\n *\n * @category internal\n */\nexport function createAuditLog<R extends BaseAuditRecord>(\n\topts: AuditLogOpts<R>,\n): ReactiveLogBundle<R> {\n\tconst log = reactiveLog<R>([], {\n\t\tname: opts.name,\n\t\tmaxSize: opts.retainedLimit ?? 1024,\n\t\tguard: opts.guard ?? DEFAULT_AUDIT_GUARD,\n\t\t...(opts.versioning != null ? { versioning: opts.versioning } : {}),\n\t});\n\t// Lazy companion activation up-front so `bundle.lastValue` / `hasLatest`\n\t// are queryable without an explicit `withLatest()` call.\n\tlog.withLatest();\n\tif (opts.graph) {\n\t\topts.graph.add(log.entries, { name: opts.name });\n\t}\n\treturn log;\n}\n\n// ── Universal mutation factory (Phase 14 — DS-14 lock Q-O2/Q-O3) ────────\n//\n// Single `mutate(act, opts)` factory. Two frames:\n//\n// - `\"inline\"` — no batch frame; up() runs raw. Seq bumps before action;\n// persists on throw. Hot-path-friendly for atomic single-write mutations.\n//\n// - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n// deferred deliveries, then `down()` runs, then failure record persists.\n//\n// **Heuristic:** if your imperative method's body is one or two lines (mutate\n// state, emit), use `frame: \"inline\"`. If it runs a user-supplied handler or\n// has multiple steps that could leave inconsistent state mid-throw, use\n// `frame: \"transactional\"`.\n\nexport type FailureMeta = {\n\tt_ns: number;\n\tseq?: number;\n\terrorType: string;\n};\n\nexport type SuccessMeta = {\n\tt_ns: number;\n\tseq?: number;\n};\n\n/**\n * Mutation action shape. Plain function shorthand auto-wraps as `{ up: fn }`.\n *\n * - `up` — the mutation action (the \"up migration\").\n * - `down` — optional rollback for closure mutations that `batch()` can't\n * reach. Receives the SAME frozen args as `up`. Runs AFTER batch reactive\n * rollback, BEFORE the failure record. Throws inside `down` are\n * console.error'd without masking the original error. Only meaningful\n * with `frame: \"transactional\"`.\n */\nexport type MutationAct<TArgs extends readonly unknown[], TResult> = {\n\tup: (...args: TArgs) => TResult;\n\tdown?: (...args: TArgs) => void;\n};\n\nexport type MutationFrame = \"inline\" | \"transactional\";\n\nexport type MutateOpts<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord> = {\n\t/** Frame mode. `\"inline\"` = no batch; `\"transactional\"` = batch + rollback. */\n\tframe: MutationFrame;\n\t/**\n\t * Optional log to append records to. When omitted, the wrapper still\n\t * provides freeze / seq-advance / rollback-on-throw but skips record\n\t * emission — useful for primitives that want centralized mutation\n\t * semantics without a dedicated log surface (e.g. `Topic.publish`).\n\t */\n\tlog?: ReactiveLogBundle<R>;\n\t/** Build the success record from the action's args + result + meta. */\n\tonSuccessRecord?: (args: TArgs, result: TResult, meta: SuccessMeta) => R | undefined;\n\t/** Build the failure record from the args + error + meta. */\n\tonFailureRecord?: (args: TArgs, error: unknown, meta: FailureMeta) => R | undefined;\n\t/** Deep-freeze args at entry (default `true`). Opt out for hot paths. */\n\tfreeze?: boolean;\n\t/** Optional sequence cursor — auto-advanced and stamped onto records. */\n\tseq?: Node<number>;\n\t/** Optional handler version — stamped per Audit 5. */\n\thandlerVersion?: { id: string; version: string | number };\n};\n\nfunction deepFreeze<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tfor (const k of Object.keys(value as Record<string, unknown>)) {\n\t\tdeepFreeze((value as Record<string, unknown>)[k]);\n\t}\n\treturn Object.freeze(value);\n}\n\n/**\n * Universal mutation factory (Phase 14 — DS-14 Q-O2).\n *\n * Replaces the prior `lightMutation` + `wrapMutation` two-tier split.\n * Single factory with `frame: \"inline\" | \"transactional\"` discriminant.\n *\n * @param act - The mutation action. Either a plain function (auto-wrapped as\n * `{ up: fn }`) or a `{ up, down? }` object for explicit rollback.\n * @param opts - Configuration: frame, log, record builders, freeze, seq.\n * @returns A typed wrapper function with the same signature as `act.up`.\n */\nexport function mutate<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord>(\n\tact: MutationAct<TArgs, TResult> | ((...args: TArgs) => TResult),\n\topts: MutateOpts<TArgs, TResult, R>,\n): (...args: TArgs) => TResult {\n\tconst { up, down } = typeof act === \"function\" ? { up: act, down: undefined } : act;\n\tconst freeze = opts.freeze ?? true;\n\n\tif (opts.frame === \"inline\") {\n\t\treturn function wrapped(...args: TArgs): TResult {\n\t\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\t\tconst t_ns = wallClockNs();\n\t\t\tconst seq = opts.seq ? bumpCursor(opts.seq) : undefined;\n\t\t\ttry {\n\t\t\t\tconst result = up(...sealed);\n\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\tresult,\n\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} catch (err) {\n\t\t\t\tif (opts.log && opts.onFailureRecord) {\n\t\t\t\t\tconst errorType = err instanceof Error ? err.name : typeof err;\n\t\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\t\topts.handlerVersion,\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\t}\n\n\t// frame === \"transactional\"\n\treturn function wrapped(...args: TArgs): TResult {\n\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\tconst t_ns = wallClockNs();\n\t\tlet result: TResult;\n\t\tlet captured: unknown;\n\t\tlet captureSet = false;\n\t\tlet seq: number | undefined;\n\t\ttry {\n\t\t\tbatch(() => {\n\t\t\t\tif (opts.seq) seq = bumpCursor(opts.seq);\n\t\t\t\ttry {\n\t\t\t\t\tresult = up(...sealed);\n\t\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\t\topts.log,\n\t\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\t\tsealed,\n\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\t\topts.handlerVersion,\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\tcaptured = err;\n\t\t\t\t\tcaptureSet = true;\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (outerErr) {\n\t\t\t// Fire `down` AFTER batch's reactive rollback, BEFORE failure record.\n\t\t\t// Gate on `captureSet` — if the throw came from outside the inner try\n\t\t\t// (framework-level batch error before action ran), don't fire down.\n\t\t\tif (captureSet && down) {\n\t\t\t\ttry {\n\t\t\t\t\tdown(...sealed);\n\t\t\t\t} catch (downErr) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`mutate: down hook threw — original action error preserved (${\n\t\t\t\t\t\t\tcaptured instanceof Error ? captured.name : typeof captured\n\t\t\t\t\t\t}). Down error:`,\n\t\t\t\t\t\tdownErr,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (captureSet && opts.log && opts.onFailureRecord) {\n\t\t\t\tconst errorType = captured instanceof Error ? captured.name : typeof captured;\n\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\topts.log,\n\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\tsealed,\n\t\t\t\t\tcaptured,\n\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\topts.handlerVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow captureSet ? captured : outerErr;\n\t\t}\n\t\treturn result!;\n\t};\n}\n\n/**\n * Advance a cursor node and return the new value. Emits `[DIRTY], [DATA, next]`\n * directly on the cursor — atomic outside a batch, rollback-discardable inside.\n *\n * Resets to `0` if the cursor cache is missing, non-numeric, `NaN`, or\n * non-finite (e.g. corrupted by `restore()` from a malformed snapshot, or\n * by a misbehaving codec). `??` alone would let `NaN` and `\"\"` pass through\n * and silently corrupt audit ordering downstream.\n *\n * **Silent reset diagnostic (EH-12).** When the cache holds a non-numeric\n * value at bump time, the cursor restarts at 0 and the next bump returns 1\n * — colliding with the seq stamped on the very first record after construct.\n * To make seq-monotonicity violations after a restore visible to operators,\n * the helper emits a one-shot `console.warn` per cursor instance describing\n * the offending value. The cursor is identified by a `WeakSet<Node<number>>`\n * so the warning fires exactly once per node — repeat malformed bumps stay\n * quiet to avoid log spam. Production callers wanting to suppress can swap\n * the global `console` (universal-safe code path; no Node-only API used).\n *\n * Works whether or not the cursor has any subscribers — `down` updates the\n * cache regardless, so primitives that bump before consumers attach (e.g.\n * `JobQueueGraph.enqueue`) still see a coherent sequence.\n *\n * @category internal\n */\nconst _bumpCursorWarned = new WeakSet<Node<number>>();\nexport function bumpCursor(seq: Node<number>): number {\n\tconst raw = seq.cache;\n\tconst valid = typeof raw === \"number\" && Number.isFinite(raw);\n\tif (!valid && raw !== undefined && !_bumpCursorWarned.has(seq)) {\n\t\t_bumpCursorWarned.add(seq);\n\t\tconsole.warn(\n\t\t\t`bumpCursor: cursor cache held a non-numeric value (${String(raw)}); resetting to 0. ` +\n\t\t\t\t\"Causes include: a snapshot codec round-tripping the cursor as a string / null / NaN, \" +\n\t\t\t\t\"OR a malformed initial seed (e.g. state<number>(NaN)). \" +\n\t\t\t\t\"Audit consumers may see colliding seq values after this point.\",\n\t\t);\n\t}\n\tconst cur = valid ? raw : 0;\n\tconst next = cur + 1;\n\tseq.down([[DIRTY], [DATA, next]]);\n\treturn next;\n}\n\n/**\n * Build a record via the supplied builder, stamp `handlerVersion` if present,\n * and append it to the audit log. `undefined` records are skipped (callers\n * pass an `onSuccess` / `onFailure` that returns `undefined` to opt out per\n * call).\n *\n * @category internal\n */\nexport function appendAudit<\n\tTArgs extends readonly unknown[],\n\tTValue,\n\tR extends BaseAuditRecord,\n\tM extends SuccessMeta | FailureMeta,\n>(\n\taudit: ReactiveLogBundle<R>,\n\tbuilder: (args: TArgs, value: TValue, meta: M) => R | undefined,\n\targs: TArgs,\n\tvalue: TValue,\n\tmeta: M,\n\thandlerVersion?: { id: string; version: string | number },\n): void {\n\tconst record = builder(args, value, meta);\n\tif (record === undefined) return;\n\tconst stamped = handlerVersion != null ? ({ ...record, handlerVersion } as R) : record;\n\taudit.append(stamped);\n}\n\n// ── registerCursor / registerCursorMap ───────────────────────────────────\n\n/**\n * Promote a closure counter to a state node mounted under `graph`.\n * Replaces ad-hoc `let _seq = 0` patterns with a node observable in\n * `describe()` and persistable via storage tiers.\n *\n * @category internal\n */\nexport function registerCursor(graph: Graph, name: string, initial = 0): Node<number> {\n\tconst cursor = node<number>([], { initial, name, describeKind: \"state\" });\n\tgraph.add(cursor, { name });\n\treturn cursor;\n}\n\n/**\n * Promote a closure `Map<K, number>` to N state nodes (one per key) mounted\n * under `<graph>::<name>::<key>`. Used by saga (per-event-type cursor).\n *\n * @category internal\n */\nexport function registerCursorMap<K extends string>(\n\tgraph: Graph,\n\tname: string,\n\tkeys: readonly K[],\n\tinitial = 0,\n): { readonly [P in K]: Node<number> } {\n\tconst out = {} as { [P in K]: Node<number> };\n\t// Mount cursors under a child plain-Graph so per-key node names stay flat\n\t// (path-separator `::` is reserved by Graph.add). Using `Graph` directly\n\t// rather than `graph.constructor` avoids spawning a typed subclass with\n\t// an incompatible constructor signature (e.g., CqrsGraph(name, opts)).\n\tconst sub = new Graph(name);\n\tfor (const k of keys) {\n\t\tconst cursor = node<number>([], {\n\t\t\tinitial,\n\t\t\tname: k,\n\t\t\tdescribeKind: \"state\",\n\t\t});\n\t\tsub.add(cursor, { name: k });\n\t\tout[k] = cursor;\n\t}\n\tgraph.mount(name, sub);\n\treturn out;\n}\n","/**\n * Monospace-terminal cell-width utilities shared by the CLI measurement\n * adapter ([src/patterns/reactive-layout/measurement-adapters.ts](../patterns/reactive-layout/measurement-adapters.ts))\n * and the ASCII describe renderer ([graph-spec-to-ascii.ts](./graph-spec-to-ascii.ts)).\n *\n * Approximates UAX #11 East_Asian_Width (W/F → 2) plus known combining-mark\n * ranges (→ 0). Not a full EAW table — covers CJK, Hangul, fullwidth forms,\n * common emoji, and Extensions B-G. Does not handle ZWJ emoji sequences\n * (multi-codepoint clusters rendered as a single glyph) — terminal support\n * for those varies widely.\n */\n\nexport function cellWidth(code: number): 0 | 1 | 2 {\n\t// Combining marks (Mn, Mc, Me) → 0 cells\n\tif (\n\t\t(code >= 0x0300 && code <= 0x036f) || // Combining Diacritical Marks\n\t\t(code >= 0x0483 && code <= 0x0489) || // Cyrillic combining marks\n\t\t(code >= 0x0591 && code <= 0x05bd) || // Hebrew combining marks\n\t\t(code >= 0x0610 && code <= 0x061a) || // Arabic combining marks\n\t\t(code >= 0x064b && code <= 0x065f) || // Arabic combining marks\n\t\t(code >= 0x0670 && code === 0x0670) || // Arabic superscript alef\n\t\t(code >= 0x06d6 && code <= 0x06dc) || // Arabic combining marks\n\t\t(code >= 0x06df && code <= 0x06e4) || // Arabic combining marks\n\t\t(code >= 0x06e7 && code <= 0x06e8) || // Arabic combining marks\n\t\t(code >= 0x06ea && code <= 0x06ed) || // Arabic combining marks\n\t\t(code >= 0x0730 && code <= 0x074a) || // Syriac combining marks\n\t\t(code >= 0x07a6 && code <= 0x07b0) || // Thaana combining marks\n\t\t(code >= 0x0900 && code <= 0x0903) || // Devanagari combining marks\n\t\t(code >= 0x093a && code <= 0x094f) || // Devanagari combining marks\n\t\t(code >= 0x0951 && code <= 0x0957) || // Devanagari combining marks\n\t\t(code >= 0x0962 && code <= 0x0963) || // Devanagari combining marks\n\t\t(code >= 0x0981 && code <= 0x0983) || // Bengali combining marks\n\t\t(code >= 0x09bc && code <= 0x09cd) || // Bengali combining marks\n\t\t(code >= 0x0a01 && code <= 0x0a03) || // Gurmukhi combining marks\n\t\t(code >= 0x0a3c && code <= 0x0a51) || // Gurmukhi combining marks\n\t\t(code >= 0x0a70 && code <= 0x0a71) || // Gurmukhi combining marks\n\t\t(code >= 0x0a75 && code === 0x0a75) || // Gurmukhi combining mark\n\t\t(code >= 0x0e31 && code === 0x0e31) || // Thai combining mark\n\t\t(code >= 0x0e34 && code <= 0x0e3a) || // Thai combining marks\n\t\t(code >= 0x0e47 && code <= 0x0e4e) || // Thai combining marks\n\t\t(code >= 0x0eb1 && code === 0x0eb1) || // Lao combining mark\n\t\t(code >= 0x0eb4 && code <= 0x0ebc) || // Lao combining marks\n\t\t(code >= 0x0ec8 && code <= 0x0ece) || // Lao combining marks\n\t\t(code >= 0x1dc0 && code <= 0x1dff) || // Combining Diacritical Marks Supplement\n\t\t(code >= 0x20d0 && code <= 0x20ff) || // Combining Diacritical Marks for Symbols\n\t\t(code >= 0xfe00 && code <= 0xfe0f) || // Variation Selectors\n\t\t(code >= 0xfe20 && code <= 0xfe2f) || // Combining Half Marks\n\t\tcode === 0x200d // Zero Width Joiner\n\t) {\n\t\treturn 0;\n\t}\n\t// Wide / fullwidth → 2 cells\n\tif (\n\t\t(code >= 0x1100 && code <= 0x115f) || // Hangul Jamo\n\t\t(code >= 0x231a && code <= 0x231b) || // Watch, Hourglass\n\t\t(code >= 0x2329 && code <= 0x232a) || // Angle brackets\n\t\t(code >= 0x23e9 && code <= 0x23f3) || // Media control symbols\n\t\t(code >= 0x23f8 && code <= 0x23fa) || // Media control symbols\n\t\t(code >= 0x25fd && code <= 0x25fe) || // Medium squares\n\t\t(code >= 0x2614 && code <= 0x2615) || // Umbrella, Hot Beverage\n\t\t(code >= 0x2648 && code <= 0x2653) || // Zodiac symbols\n\t\tcode === 0x267f || // Wheelchair\n\t\tcode === 0x2693 || // Anchor\n\t\tcode === 0x26a1 || // High Voltage\n\t\t(code >= 0x26aa && code <= 0x26ab) || // Medium circles\n\t\t(code >= 0x26bd && code <= 0x26be) || // Soccer, Baseball\n\t\t(code >= 0x26c4 && code <= 0x26c5) || // Snowman, Sun behind cloud\n\t\tcode === 0x26ce || // Ophiuchus\n\t\tcode === 0x26d4 || // No Entry\n\t\tcode === 0x26ea || // Church\n\t\t(code >= 0x26f2 && code <= 0x26f3) || // Fountain, Golf\n\t\tcode === 0x26f5 || // Sailboat\n\t\tcode === 0x26fa || // Tent\n\t\tcode === 0x26fd || // Fuel Pump\n\t\tcode === 0x2702 || // Scissors\n\t\tcode === 0x2705 || // Check Mark\n\t\t(code >= 0x2708 && code <= 0x270d) || // Airplane...Writing Hand\n\t\tcode === 0x270f || // Pencil\n\t\t(code >= 0x2753 && code <= 0x2755) || // Question marks\n\t\tcode === 0x2757 || // Exclamation\n\t\t(code >= 0x2795 && code <= 0x2797) || // Plus, Minus, Divide\n\t\tcode === 0x27b0 || // Curly Loop\n\t\tcode === 0x27bf || // Double Curly Loop\n\t\t(code >= 0x2934 && code <= 0x2935) || // Arrows\n\t\t(code >= 0x2b05 && code <= 0x2b07) || // Arrows\n\t\t(code >= 0x2b1b && code <= 0x2b1c) || // Squares\n\t\tcode === 0x2b50 || // Star\n\t\tcode === 0x2b55 || // Circle\n\t\t(code >= 0x2e80 && code <= 0x303e) || // CJK Radicals, Symbols, Punctuation\n\t\t(code >= 0x3040 && code <= 0x309f) || // Hiragana\n\t\t(code >= 0x30a0 && code <= 0x30ff) || // Katakana\n\t\t(code >= 0x3105 && code <= 0x312f) || // Bopomofo\n\t\t(code >= 0x3131 && code <= 0x318e) || // Hangul Compatibility Jamo\n\t\t(code >= 0x3190 && code <= 0x31e3) || // Kanbun, CJK Strokes\n\t\t(code >= 0x31f0 && code <= 0x321e) || // Katakana Phonetic Extensions\n\t\t(code >= 0x3220 && code <= 0x3247) || // Enclosed CJK\n\t\t(code >= 0x3250 && code <= 0x4dbf) || // CJK Extensions + Unified block\n\t\t(code >= 0x4e00 && code <= 0x9fff) || // CJK Unified Ideographs\n\t\t(code >= 0xa960 && code <= 0xa97c) || // Hangul Jamo Extended-A\n\t\t(code >= 0xac00 && code <= 0xd7a3) || // Hangul Syllables\n\t\t(code >= 0xf900 && code <= 0xfaff) || // CJK Compatibility Ideographs\n\t\t(code >= 0xfe10 && code <= 0xfe19) || // Vertical forms\n\t\t(code >= 0xfe30 && code <= 0xfe6b) || // CJK Compatibility Forms\n\t\t(code >= 0xff01 && code <= 0xff60) || // Fullwidth Forms (excl. halfwidth)\n\t\t(code >= 0xffe0 && code <= 0xffe6) || // Fullwidth Signs\n\t\t(code >= 0x1f004 && code === 0x1f004) || // Mahjong Red Dragon\n\t\tcode === 0x1f0cf || // Joker\n\t\t(code >= 0x1f170 && code <= 0x1f171) || // A/B buttons\n\t\tcode === 0x1f17e || // O button\n\t\tcode === 0x1f17f || // P button\n\t\tcode === 0x1f18e || // AB button\n\t\t(code >= 0x1f191 && code <= 0x1f19a) || // Squared symbols\n\t\t(code >= 0x1f1e0 && code <= 0x1f1ff) || // Regional Indicator Symbols\n\t\t(code >= 0x1f200 && code <= 0x1f202) || // Enclosed ideographic\n\t\tcode === 0x1f21a || // Squared CJK\n\t\tcode === 0x1f22f || // Squared CJK\n\t\t(code >= 0x1f232 && code <= 0x1f23a) || // Squared CJK\n\t\t(code >= 0x1f250 && code <= 0x1f251) || // Circled ideographic\n\t\t(code >= 0x1f300 && code <= 0x1f9ff) || // Misc Symbols / Emoticons / Emoji\n\t\t(code >= 0x1fa00 && code <= 0x1faff) || // Chess, Symbols Extended-A\n\t\t(code >= 0x1fb00 && code <= 0x1fbff) || // Symbols for Legacy Computing\n\t\t(code >= 0x20000 && code <= 0x2fffd) || // CJK Extension B-F (excl. nonchars)\n\t\t(code >= 0x30000 && code <= 0x3fffd) // CJK Extension G+ (excl. nonchars)\n\t) {\n\t\treturn 2;\n\t}\n\treturn 1;\n}\n\n/**\n * Count total display cells for a string in a monospace terminal.\n *\n * Combining marks contribute 0 cells; CJK / fullwidth contribute 2.\n * Does not handle ZWJ emoji sequences.\n */\nexport function countCells(text: string): number {\n\tlet cells = 0;\n\tfor (const ch of text) {\n\t\tcells += cellWidth(ch.codePointAt(0)!);\n\t}\n\treturn cells;\n}\n\n/**\n * Truncate `text` to at most `maxCells` terminal cells, appending an ellipsis\n * (\"…\" → 1 cell) when truncation occurs. Grapheme-unaware — splits at\n * codepoints; ZWJ sequences may be cut mid-cluster.\n */\nexport function truncateToCells(text: string, maxCells: number): string {\n\tif (maxCells <= 0) return \"\";\n\tlet cells = 0;\n\tlet out = \"\";\n\tfor (const ch of text) {\n\t\tconst w = cellWidth(ch.codePointAt(0)!);\n\t\tif (cells + w > maxCells) {\n\t\t\tif (maxCells <= 1) return \"…\";\n\t\t\t// Drop last wide char if we'd exceed budget with the ellipsis\n\t\t\twhile (cells + 1 > maxCells && out.length > 0) {\n\t\t\t\tconst last = [...out].pop()!;\n\t\t\t\tout = out.slice(0, -last.length);\n\t\t\t\tcells -= cellWidth(last.codePointAt(0)!);\n\t\t\t}\n\t\t\treturn `${out}…`;\n\t\t}\n\t\tout += ch;\n\t\tcells += w;\n\t}\n\treturn out;\n}\n","/**\n * Character-grid blitter for the ASCII describe renderer.\n *\n * Given a [LayoutResult](./_layout-sugiyama.ts) (boxes + polyline edges on\n * an integer cell grid), produce a newline-joined string using Unicode\n * box-drawing glyphs (or plain ASCII when `charset: \"ascii\"` is requested).\n *\n * Invariants:\n * - Multi-cell CJK labels still count as 2 cells via\n * [_ascii-width.ts](./_ascii-width.ts).\n * - Edge crossings (two segments perpendicular at the same cell) collapse\n * to `┼` / `+`. Corner-vs-line collisions resolve to a corner glyph.\n * - Boxes overwrite edge glyphs — boxes are blitted last so an edge that\n * happens to pass under a box body is hidden.\n */\n\nimport { countCells } from \"./_ascii-width.js\";\nimport type { LayoutBox, LayoutEdge, LayoutResult } from \"./_layout-sugiyama.js\";\n\nexport type AsciiCharset = \"unicode\" | \"ascii\";\n\nexport type GridOptions = {\n\treadonly charset: AsciiCharset;\n\treadonly labelOf: (id: string) => string;\n};\n\ntype Glyphs = {\n\treadonly horizontal: string;\n\treadonly vertical: string;\n\treadonly cornerTL: string;\n\treadonly cornerTR: string;\n\treadonly cornerBL: string;\n\treadonly cornerBR: string;\n\treadonly tDown: string;\n\treadonly tUp: string;\n\treadonly tRight: string;\n\treadonly tLeft: string;\n\treadonly cross: string;\n\treadonly arrowRight: string;\n\treadonly arrowDown: string;\n\treadonly arrowLeft: string;\n\treadonly arrowUp: string;\n\treadonly boxTL: string;\n\treadonly boxTR: string;\n\treadonly boxBL: string;\n\treadonly boxBR: string;\n\treadonly boxH: string;\n\treadonly boxV: string;\n};\n\nconst UNICODE: Glyphs = {\n\thorizontal: \"─\",\n\tvertical: \"│\",\n\tcornerTL: \"┌\",\n\tcornerTR: \"┐\",\n\tcornerBL: \"└\",\n\tcornerBR: \"┘\",\n\ttDown: \"┬\",\n\ttUp: \"┴\",\n\ttRight: \"├\",\n\ttLeft: \"┤\",\n\tcross: \"┼\",\n\tarrowRight: \"▶\",\n\tarrowDown: \"▼\",\n\tarrowLeft: \"◀\",\n\tarrowUp: \"▲\",\n\tboxTL: \"┌\",\n\tboxTR: \"┐\",\n\tboxBL: \"└\",\n\tboxBR: \"┘\",\n\tboxH: \"─\",\n\tboxV: \"│\",\n};\n\nconst ASCII: Glyphs = {\n\thorizontal: \"-\",\n\tvertical: \"|\",\n\tcornerTL: \"+\",\n\tcornerTR: \"+\",\n\tcornerBL: \"+\",\n\tcornerBR: \"+\",\n\ttDown: \"+\",\n\ttUp: \"+\",\n\ttRight: \"+\",\n\ttLeft: \"+\",\n\tcross: \"+\",\n\tarrowRight: \">\",\n\tarrowDown: \"v\",\n\tarrowLeft: \"<\",\n\tarrowUp: \"^\",\n\tboxTL: \"+\",\n\tboxTR: \"+\",\n\tboxBL: \"+\",\n\tboxBR: \"+\",\n\tboxH: \"-\",\n\tboxV: \"|\",\n};\n\n// Set of glyphs considered \"edge lines\" when resolving collisions. A later\n// put() into an edge cell that conflicts produces `cross`; corners and\n// T-junctions are preserved (they carry more information).\ntype CellKind =\n\t| \"empty\"\n\t| \"boxH\"\n\t| \"boxV\"\n\t| \"boxCorner\"\n\t| \"edgeH\"\n\t| \"edgeV\"\n\t| \"edgeCorner\"\n\t| \"arrow\"\n\t| \"label\";\n\nexport function renderGrid(layout: LayoutResult, options: GridOptions): string {\n\tconst glyphs = options.charset === \"ascii\" ? ASCII : UNICODE;\n\tconst width = layout.width;\n\tconst height = layout.height;\n\tconst grid: string[][] = Array.from({ length: height }, () =>\n\t\tArray.from({ length: width }, () => \" \"),\n\t);\n\tconst kind: CellKind[][] = Array.from({ length: height }, () =>\n\t\tArray.from({ length: width }, () => \"empty\" as CellKind),\n\t);\n\n\t// 1. Draw edges first (boxes overwrite).\n\tfor (const edge of layout.edges) {\n\t\tdrawEdge(grid, kind, glyphs, edge);\n\t}\n\n\t// 2. Draw boxes on top.\n\tfor (const box of layout.boxes) {\n\t\tdrawBox(grid, kind, glyphs, box, options.labelOf(box.id));\n\t}\n\n\treturn grid.map((row) => stripTrailing(row.join(\"\"))).join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Box drawing\n// ---------------------------------------------------------------------------\n\nfunction drawBox(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tglyphs: Glyphs,\n\tbox: LayoutBox,\n\tlabel: string,\n): void {\n\tconst { x, y, w, h } = box;\n\tif (w < 2 || h < 2) {\n\t\t// Degenerate — just paint the label.\n\t\tif (h > 0) writeLabel(grid, kind, x, y, w, label);\n\t\treturn;\n\t}\n\t// Top border\n\tputBoxCell(grid, kind, x, y, glyphs.boxTL);\n\tfor (let cx = x + 1; cx < x + w - 1; cx += 1) putBoxCell(grid, kind, cx, y, glyphs.boxH);\n\tputBoxCell(grid, kind, x + w - 1, y, glyphs.boxTR);\n\t// Middle rows — side borders + content (only middle row carries the label)\n\tfor (let cy = y + 1; cy < y + h - 1; cy += 1) {\n\t\tputBoxCell(grid, kind, x, cy, glyphs.boxV);\n\t\tfor (let cx = x + 1; cx < x + w - 1; cx += 1) {\n\t\t\tputBoxCellAs(grid, kind, cx, cy, \" \", \"empty\");\n\t\t}\n\t\tputBoxCell(grid, kind, x + w - 1, cy, glyphs.boxV);\n\t}\n\t// Bottom border\n\tputBoxCell(grid, kind, x, y + h - 1, glyphs.boxBL);\n\tfor (let cx = x + 1; cx < x + w - 1; cx += 1) putBoxCell(grid, kind, cx, y + h - 1, glyphs.boxH);\n\tputBoxCell(grid, kind, x + w - 1, y + h - 1, glyphs.boxBR);\n\t// Label in vertical middle (h >= 3 expected)\n\tconst midY = y + Math.floor(h / 2);\n\twriteLabel(grid, kind, x + 1, midY, w - 2, label);\n}\n\nfunction putBoxCell(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tx: number,\n\ty: number,\n\tglyph: string,\n): void {\n\tconst k: CellKind =\n\t\tglyph === \" \"\n\t\t\t? \"empty\"\n\t\t\t: glyph === \"─\" || glyph === \"-\"\n\t\t\t\t? \"boxH\"\n\t\t\t\t: glyph === \"│\" || glyph === \"|\"\n\t\t\t\t\t? \"boxV\"\n\t\t\t\t\t: \"boxCorner\";\n\tputBoxCellAs(grid, kind, x, y, glyph, k);\n}\n\nfunction putBoxCellAs(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tx: number,\n\ty: number,\n\tglyph: string,\n\tk: CellKind,\n): void {\n\tif (y < 0 || y >= grid.length) return;\n\tconst row = grid[y]!;\n\tif (x < 0 || x >= row.length) return;\n\trow[x] = glyph;\n\tkind[y]![x] = k;\n}\n\nfunction writeLabel(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tx: number,\n\ty: number,\n\tmaxWidthCells: number,\n\tlabel: string,\n): void {\n\t// The grid is cell-indexed (one array slot per terminal cell). Wide\n\t// characters (CJK, fullwidth) occupy TWO cells visually; we store the\n\t// char in the first slot and an empty string in the second slot so\n\t// join(\"\") collapses to a single visible wide glyph and neighboring\n\t// writes don't add spurious narrow spaces next to the wide char.\n\tif (y < 0 || y >= grid.length) return;\n\tlet cursor = x;\n\tlet cellsLeft = maxWidthCells;\n\tfor (const ch of label) {\n\t\tconst cw = countCells(ch);\n\t\tif (cw === 0) continue;\n\t\tif (cellsLeft < cw) break;\n\t\tif (cursor >= 0 && cursor < grid[y]!.length) {\n\t\t\tgrid[y]![cursor] = ch;\n\t\t\tkind[y]![cursor] = \"label\";\n\t\t\tif (cw === 2 && cursor + 1 < grid[y]!.length) {\n\t\t\t\tgrid[y]![cursor + 1] = \"\";\n\t\t\t\tkind[y]![cursor + 1] = \"label\";\n\t\t\t}\n\t\t}\n\t\tcursor += cw;\n\t\tcellsLeft -= cw;\n\t}\n\t// Pad remaining cells with spaces so any edge glyphs lurking under the\n\t// box body don't leak into the label row.\n\twhile (cellsLeft > 0) {\n\t\tif (cursor >= 0 && cursor < grid[y]!.length) {\n\t\t\tgrid[y]![cursor] = \" \";\n\t\t\tkind[y]![cursor] = \"empty\";\n\t\t}\n\t\tcursor += 1;\n\t\tcellsLeft -= 1;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Edge drawing\n// ---------------------------------------------------------------------------\n\nfunction drawEdge(grid: string[][], kind: CellKind[][], glyphs: Glyphs, edge: LayoutEdge): void {\n\tconst pts = edge.points;\n\tif (pts.length < 2) return;\n\t// Draw segments\n\tfor (let i = 0; i + 1 < pts.length; i += 1) {\n\t\tdrawSegment(grid, kind, glyphs, pts[i]!, pts[i + 1]!);\n\t}\n\t// Draw corners at interior points\n\tfor (let i = 1; i + 1 < pts.length; i += 1) {\n\t\tconst a = pts[i - 1]!;\n\t\tconst b = pts[i]!;\n\t\tconst c = pts[i + 1]!;\n\t\tconst corner = cornerGlyph(a, b, c, glyphs);\n\t\tif (corner) putEdgeCell(grid, kind, b.x, b.y, corner, \"edgeCorner\");\n\t}\n\t// Arrow tip at the final point, aimed from the penultimate point.\n\t// Four cardinal directions — covers backward and upward tips produced\n\t// by routing past virtual nodes or dense-gutter fallbacks.\n\tconst tip = pts[pts.length - 1]!;\n\tconst prev = pts[pts.length - 2]!;\n\tconst arrow = arrowGlyph(prev, tip, glyphs);\n\tif (arrow) putEdgeCell(grid, kind, tip.x, tip.y, arrow, \"arrow\");\n}\n\nfunction drawSegment(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tglyphs: Glyphs,\n\ta: { x: number; y: number },\n\tb: { x: number; y: number },\n): void {\n\tif (a.x === b.x && a.y === b.y) return;\n\tif (a.y === b.y) {\n\t\t// Horizontal\n\t\tconst y = a.y;\n\t\tconst x0 = Math.min(a.x, b.x);\n\t\tconst x1 = Math.max(a.x, b.x);\n\t\tfor (let x = x0; x <= x1; x += 1) {\n\t\t\tputEdgeLine(grid, kind, x, y, glyphs, \"h\");\n\t\t}\n\t} else if (a.x === b.x) {\n\t\t// Vertical\n\t\tconst x = a.x;\n\t\tconst y0 = Math.min(a.y, b.y);\n\t\tconst y1 = Math.max(a.y, b.y);\n\t\tfor (let y = y0; y <= y1; y += 1) {\n\t\t\tputEdgeLine(grid, kind, x, y, glyphs, \"v\");\n\t\t}\n\t}\n\t// Diagonal shouldn't happen — routing is orthogonal.\n}\n\nfunction putEdgeLine(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tx: number,\n\ty: number,\n\tglyphs: Glyphs,\n\torientation: \"h\" | \"v\",\n): void {\n\tif (y < 0 || y >= grid.length) return;\n\tconst row = grid[y]!;\n\tif (x < 0 || x >= row.length) return;\n\tconst existing = kind[y]![x];\n\tif (\n\t\texisting === \"boxH\" ||\n\t\texisting === \"boxV\" ||\n\t\texisting === \"boxCorner\" ||\n\t\texisting === \"label\"\n\t) {\n\t\t// Box wins — do nothing. Boxes are drawn after edges, but if order\n\t\t// is reversed the edge must not clobber the box.\n\t\treturn;\n\t}\n\tif (existing === \"empty\") {\n\t\trow[x] = orientation === \"h\" ? glyphs.horizontal : glyphs.vertical;\n\t\tkind[y]![x] = orientation === \"h\" ? \"edgeH\" : \"edgeV\";\n\t\treturn;\n\t}\n\tif (existing === \"edgeH\" && orientation === \"v\") {\n\t\trow[x] = glyphs.cross;\n\t\tkind[y]![x] = \"edgeCorner\";\n\t\treturn;\n\t}\n\tif (existing === \"edgeV\" && orientation === \"h\") {\n\t\trow[x] = glyphs.cross;\n\t\tkind[y]![x] = \"edgeCorner\";\n\t\treturn;\n\t}\n\t// Same-orientation overlay: keep existing glyph.\n}\n\nfunction putEdgeCell(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tx: number,\n\ty: number,\n\tglyph: string,\n\tk: CellKind,\n): void {\n\tif (y < 0 || y >= grid.length) return;\n\tconst row = grid[y]!;\n\tif (x < 0 || x >= row.length) return;\n\tconst existing = kind[y]![x];\n\tif (\n\t\texisting === \"boxH\" ||\n\t\texisting === \"boxV\" ||\n\t\texisting === \"boxCorner\" ||\n\t\texisting === \"label\"\n\t)\n\t\treturn;\n\trow[x] = glyph;\n\tkind[y]![x] = k;\n}\n\n// ---------------------------------------------------------------------------\n// Corner + arrow glyph selection\n// ---------------------------------------------------------------------------\n\nfunction cornerGlyph(\n\ta: { x: number; y: number },\n\tb: { x: number; y: number },\n\tc: { x: number; y: number },\n\tglyphs: Glyphs,\n): string | undefined {\n\tconst inHoriz = a.y === b.y;\n\tconst outHoriz = b.y === c.y;\n\tif (inHoriz === outHoriz) return undefined; // not a turn\n\t// In from horizontal, out to vertical (or vice versa). Figure out which\n\t// of the four corners we're at.\n\tif (inHoriz) {\n\t\t// Coming from the left (a.x < b.x) or right (a.x > b.x)\n\t\tconst fromLeft = a.x < b.x;\n\t\tconst goingDown = c.y > b.y;\n\t\tif (fromLeft && goingDown) return glyphs.cornerTR;\n\t\tif (fromLeft && !goingDown) return glyphs.cornerBR;\n\t\tif (!fromLeft && goingDown) return glyphs.cornerTL;\n\t\treturn glyphs.cornerBL;\n\t}\n\t// Vertical in, horizontal out\n\tconst fromAbove = a.y < b.y;\n\tconst goingRight = c.x > b.x;\n\tif (fromAbove && goingRight) return glyphs.cornerBL;\n\tif (fromAbove && !goingRight) return glyphs.cornerBR;\n\tif (!fromAbove && goingRight) return glyphs.cornerTL;\n\treturn glyphs.cornerTR;\n}\n\nfunction arrowGlyph(\n\tprev: { x: number; y: number },\n\ttip: { x: number; y: number },\n\tglyphs: Glyphs,\n): string | undefined {\n\tif (tip.x > prev.x) return glyphs.arrowRight;\n\tif (tip.x < prev.x) return glyphs.arrowLeft;\n\tif (tip.y > prev.y) return glyphs.arrowDown;\n\tif (tip.y < prev.y) return glyphs.arrowUp;\n\treturn undefined; // zero-length segment — no tip\n}\n\n// ---------------------------------------------------------------------------\n// Output trimming\n// ---------------------------------------------------------------------------\n\nfunction stripTrailing(line: string): string {\n\t// Trim trailing spaces only; preserve internal grid alignment.\n\tlet end = line.length;\n\twhile (end > 0 && line.charCodeAt(end - 1) === 32) end -= 1;\n\treturn line.slice(0, end);\n}\n","/**\n * Sugiyama-style layered DAG layout on an integer grid.\n *\n * Pipeline:\n * 1. Longest-path layer assignment (sources at layer 0).\n * 2. Virtual-node splitting — every edge spanning more than one layer\n * becomes a chain of synthetic nodes on intermediate layers. Downstream\n * passes treat real and virtual nodes identically; crossing\n * minimization therefore works on wide + deep DAGs, not only\n * adjacent-layer cases.\n * 3. Crossing minimization — barycenter heuristic with alternating up /\n * down sweeps plus an adjacent-transposition polish pass.\n * 4. Coordinate assignment — greedy median-aligned packing with collision\n * resolution. Straightens vertical runs of virtual nodes so long edges\n * become straight lines where topology allows.\n * 5. Orthogonal edge routing — per-gutter x-track assignment; horizontal\n * segments sit at endpoint centerlines, vertical segments pack into the\n * gutter column range without overlap. Remaining crossings are\n * topologically unavoidable and will render as `┼` at draw time.\n *\n * Output coordinates are cell-grid integers (LR direction). TD rendering\n * swaps axes at draw time — the layout is direction-agnostic by\n * construction.\n *\n * Used only by [graph-spec-to-ascii.ts](./graph-spec-to-ascii.ts); not part of the public\n * `extra/render/index.ts` surface (underscore-prefixed).\n */\n\nexport type LayoutDirection = \"LR\" | \"TD\";\n\nexport type LayoutInput = {\n\t/** Node ids in stable iteration order. Determines initial tie-break. */\n\treadonly nodes: readonly string[];\n\t/** Edges by (from, to) path. Endpoints must be present in `nodes`. */\n\treadonly edges: ReadonlyArray<{ from: string; to: string }>;\n\t/** Label width in cells for each node (independent of direction). */\n\treadonly widthCells: (id: string) => number;\n\t/** Label height in cells for each node (independent of direction). */\n\treadonly heightCells: (id: string) => number;\n\t/**\n\t * Gap between layer \"columns\" (LR) or \"rows\" (TD), in cells.\n\t * Must allow enough room for per-gutter edge tracks.\n\t */\n\treadonly layerGap: number;\n\t/**\n\t * Gap between neighboring nodes *within* a layer, in cells.\n\t * LR: vertical gap; TD: horizontal gap.\n\t */\n\treadonly nodeGap: number;\n\t/**\n\t * Axis orientation. LR: layers = columns (x grows), order = rows (y grows).\n\t * TD: layers = rows (y grows), order = columns (x grows).\n\t */\n\treadonly direction: LayoutDirection;\n};\n\nexport type LayoutBox = {\n\treadonly id: string;\n\treadonly layer: number;\n\treadonly order: number;\n\treadonly x: number;\n\treadonly y: number;\n\treadonly w: number;\n\treadonly h: number;\n};\n\nexport type LayoutEdgePoint = { readonly x: number; readonly y: number };\n\nexport type LayoutEdge = {\n\treadonly from: string;\n\treadonly to: string;\n\t/** Polyline of waypoints (start → corners → end). Minimum 2 entries. */\n\treadonly points: readonly LayoutEdgePoint[];\n};\n\nexport type LayoutResult = {\n\treadonly boxes: readonly LayoutBox[];\n\treadonly edges: readonly LayoutEdge[];\n\treadonly width: number;\n\treadonly height: number;\n};\n\n// ---------------------------------------------------------------------------\n// Internal types — carried through the pipeline\n// ---------------------------------------------------------------------------\n\ntype Hop = {\n\tchainId: number;\n\tchainFrom: string;\n\tchainTo: string;\n\tfromId: string;\n\ttoId: string;\n\t/** 0-based hop index along the chain. */\n\thopIndex: number;\n\t/** Total hops in the chain (1 = direct, 2+ = spans virtuals). */\n\tchainLen: number;\n};\n\ntype InternalNode = {\n\tid: string;\n\tisVirtual: boolean;\n\tlayer: number;\n\torder: number;\n\tx: number;\n\ty: number;\n\tw: number;\n\th: number;\n\tin: Hop[];\n\tout: Hop[];\n};\n\ntype Layer = InternalNode[];\n\ntype PipelineState = {\n\tnodes: Map<string, InternalNode>;\n\tlayers: Layer[];\n\thops: Hop[];\n};\n\n// ---------------------------------------------------------------------------\n// Pipeline entry\n// ---------------------------------------------------------------------------\n\nexport function sugiyamaLayout(input: LayoutInput): LayoutResult {\n\tconst state = buildInitial(input);\n\tassignLayers(state);\n\tinsertVirtualNodes(state);\n\tminimizeCrossings(state);\n\tassignCoordinates(state, input);\n\tconst edges = routeEdges(state, input);\n\tconst { width, height } = boundingBox(state);\n\tconst boxes: LayoutBox[] = [];\n\tfor (const layer of state.layers) {\n\t\tfor (const n of layer) {\n\t\t\tif (n.isVirtual) continue;\n\t\t\tboxes.push({\n\t\t\t\tid: n.id,\n\t\t\t\tlayer: n.layer,\n\t\t\t\torder: n.order,\n\t\t\t\tx: n.x,\n\t\t\t\ty: n.y,\n\t\t\t\tw: n.w,\n\t\t\t\th: n.h,\n\t\t\t});\n\t\t}\n\t}\n\treturn { boxes, edges, width, height };\n}\n\n// ---------------------------------------------------------------------------\n// 1. Build internal graph\n// ---------------------------------------------------------------------------\n\nfunction buildInitial(input: LayoutInput): PipelineState {\n\tconst nodes = new Map<string, InternalNode>();\n\tfor (const id of input.nodes) {\n\t\tnodes.set(id, {\n\t\t\tid,\n\t\t\tisVirtual: false,\n\t\t\tlayer: -1,\n\t\t\torder: 0,\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tw: input.widthCells(id),\n\t\t\th: input.heightCells(id),\n\t\t\tin: [],\n\t\t\tout: [],\n\t\t});\n\t}\n\tconst hops: Hop[] = [];\n\tlet chainId = 0;\n\tfor (const e of input.edges) {\n\t\tif (e.from === e.to) continue; // drop self-loops\n\t\tconst f = nodes.get(e.from);\n\t\tconst t = nodes.get(e.to);\n\t\tif (!f || !t) continue; // drop dangling endpoints\n\t\tconst hop: Hop = {\n\t\t\tchainId: chainId++,\n\t\t\tchainFrom: e.from,\n\t\t\tchainTo: e.to,\n\t\t\tfromId: e.from,\n\t\t\ttoId: e.to,\n\t\t\thopIndex: 0,\n\t\t\tchainLen: 1,\n\t\t};\n\t\tf.out.push(hop);\n\t\tt.in.push(hop);\n\t\thops.push(hop);\n\t}\n\treturn { nodes, layers: [], hops };\n}\n\n// ---------------------------------------------------------------------------\n// 2. Longest-path layer assignment (Kahn's algorithm)\n// ---------------------------------------------------------------------------\n\nfunction assignLayers(state: PipelineState): void {\n\tconst indeg = new Map<string, number>();\n\tfor (const n of state.nodes.values()) indeg.set(n.id, n.in.length);\n\n\tconst queue: InternalNode[] = [];\n\tfor (const n of state.nodes.values()) {\n\t\tif ((indeg.get(n.id) ?? 0) === 0) {\n\t\t\tn.layer = 0;\n\t\t\tqueue.push(n);\n\t\t}\n\t}\n\n\t// Cursor-based BFS — `Array.prototype.shift` is O(n), so the naive form\n\t// is O(n²) and degrades past ~1000 nodes. Cursor keeps it linear.\n\tconst visited = new Set<string>();\n\tlet head = 0;\n\twhile (head < queue.length) {\n\t\tconst n = queue[head++]!;\n\t\tif (visited.has(n.id)) continue;\n\t\tvisited.add(n.id);\n\t\tfor (const hop of n.out) {\n\t\t\tconst t = state.nodes.get(hop.toId)!;\n\t\t\tt.layer = Math.max(t.layer, n.layer + 1);\n\t\t\tconst d = (indeg.get(t.id) ?? 0) - 1;\n\t\t\tindeg.set(t.id, d);\n\t\t\tif (d <= 0) queue.push(t);\n\t\t}\n\t}\n\t// Nodes trapped in a cycle default to layer 0. The edges that would\n\t// close the cycle are dropped in `insertVirtualNodes` (any hop whose\n\t// span is not a positive integer). GraphReFly graphs are DAGs by spec;\n\t// this path is defensive against malformed describe snapshots.\n\tfor (const n of state.nodes.values()) if (n.layer < 0) n.layer = 0;\n}\n\n// ---------------------------------------------------------------------------\n// 3. Virtual-node insertion — critical for scaling past adjacent-layer edges\n// ---------------------------------------------------------------------------\n\nfunction insertVirtualNodes(state: PipelineState): void {\n\tconst maxLayer = Math.max(0, ...Array.from(state.nodes.values(), (n) => n.layer));\n\tconst layers: Layer[] = Array.from({ length: maxLayer + 1 }, () => []);\n\tfor (const n of state.nodes.values()) layers[n.layer]!.push(n);\n\n\tconst newHops: Hop[] = [];\n\tlet virtCounter = 0;\n\tfor (const hop of state.hops) {\n\t\tconst f = state.nodes.get(hop.fromId)!;\n\t\tconst t = state.nodes.get(hop.toId)!;\n\t\tconst span = t.layer - f.layer;\n\t\tif (span <= 0) {\n\t\t\t// Same-layer or back-edge — the input violated the DAG invariant\n\t\t\t// (self-loop was already dropped in `buildInitial`; this catches\n\t\t\t// cycles whose nodes collapsed to layer 0 in `assignLayers`).\n\t\t\t// Drop from both endpoints so routing never sees the hop; same\n\t\t\t// render-best-effort policy as the self-loop / dangling-endpoint\n\t\t\t// filters in `buildInitial`.\n\t\t\tf.out = f.out.filter((h) => h !== hop);\n\t\t\tt.in = t.in.filter((h) => h !== hop);\n\t\t\tcontinue;\n\t\t}\n\t\tif (span === 1) {\n\t\t\thop.hopIndex = 0;\n\t\t\thop.chainLen = 1;\n\t\t\tnewHops.push(hop);\n\t\t\tcontinue;\n\t\t}\n\t\t// Multi-hop: f → v1 → v2 → ... → t\n\t\t// Detach the original edge from f.out / t.in; we rewrite as chain.\n\t\tf.out = f.out.filter((h) => h !== hop);\n\t\tt.in = t.in.filter((h) => h !== hop);\n\n\t\tlet prev = f;\n\t\tfor (let i = 1; i < span; i += 1) {\n\t\t\tconst vid = `__virt_${virtCounter++}__`;\n\t\t\tconst v: InternalNode = {\n\t\t\t\tid: vid,\n\t\t\t\tisVirtual: true,\n\t\t\t\tlayer: f.layer + i,\n\t\t\t\torder: 0,\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tw: 0,\n\t\t\t\th: 1,\n\t\t\t\tin: [],\n\t\t\t\tout: [],\n\t\t\t};\n\t\t\tstate.nodes.set(vid, v);\n\t\t\tlayers[v.layer]!.push(v);\n\t\t\tconst h: Hop = {\n\t\t\t\tchainId: hop.chainId,\n\t\t\t\tchainFrom: hop.chainFrom,\n\t\t\t\tchainTo: hop.chainTo,\n\t\t\t\tfromId: prev.id,\n\t\t\t\ttoId: vid,\n\t\t\t\thopIndex: i - 1,\n\t\t\t\tchainLen: span,\n\t\t\t};\n\t\t\tprev.out.push(h);\n\t\t\tv.in.push(h);\n\t\t\tnewHops.push(h);\n\t\t\tprev = v;\n\t\t}\n\t\tconst finalHop: Hop = {\n\t\t\tchainId: hop.chainId,\n\t\t\tchainFrom: hop.chainFrom,\n\t\t\tchainTo: hop.chainTo,\n\t\t\tfromId: prev.id,\n\t\t\ttoId: t.id,\n\t\t\thopIndex: span - 1,\n\t\t\tchainLen: span,\n\t\t};\n\t\tprev.out.push(finalHop);\n\t\tt.in.push(finalHop);\n\t\tnewHops.push(finalHop);\n\t}\n\n\t// Stable initial order within each layer.\n\tfor (const layer of layers) {\n\t\tfor (let i = 0; i < layer.length; i += 1) layer[i]!.order = i;\n\t}\n\tstate.layers = layers;\n\tstate.hops = newHops;\n}\n\n// ---------------------------------------------------------------------------\n// 4. Crossing minimization\n// ---------------------------------------------------------------------------\n\nfunction minimizeCrossings(state: PipelineState): void {\n\tconst SWEEPS = 4;\n\tfor (let sweep = 0; sweep < SWEEPS; sweep += 1) {\n\t\t// Down-sweep\n\t\tfor (let li = 1; li < state.layers.length; li += 1) {\n\t\t\tsortByBarycenter(state, state.layers[li]!, \"in\");\n\t\t\treindex(state.layers[li]!);\n\t\t}\n\t\t// Up-sweep\n\t\tfor (let li = state.layers.length - 2; li >= 0; li -= 1) {\n\t\t\tsortByBarycenter(state, state.layers[li]!, \"out\");\n\t\t\treindex(state.layers[li]!);\n\t\t}\n\t}\n\t// Polish — adjacent-transposition pass, bounded iterations.\n\tfor (let iter = 0; iter < 2; iter += 1) {\n\t\tlet improved = false;\n\t\tfor (let li = 1; li < state.layers.length; li += 1) {\n\t\t\tconst layer = state.layers[li]!;\n\t\t\tfor (let i = 0; i + 1 < layer.length; i += 1) {\n\t\t\t\tconst before = pairCrossings(state, layer[i]!, layer[i + 1]!, \"in\");\n\t\t\t\t[layer[i], layer[i + 1]] = [layer[i + 1]!, layer[i]!];\n\t\t\t\treindex(layer);\n\t\t\t\tconst after = pairCrossings(state, layer[i]!, layer[i + 1]!, \"in\");\n\t\t\t\tif (after < before) {\n\t\t\t\t\timproved = true;\n\t\t\t\t} else {\n\t\t\t\t\t[layer[i], layer[i + 1]] = [layer[i + 1]!, layer[i]!];\n\t\t\t\t\treindex(layer);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!improved) break;\n\t}\n}\n\nfunction sortByBarycenter(state: PipelineState, layer: Layer, direction: \"in\" | \"out\"): void {\n\tconst bary = new Map<string, number>();\n\tfor (const n of layer) {\n\t\tconst neighbors = direction === \"in\" ? n.in : n.out;\n\t\tif (neighbors.length === 0) {\n\t\t\tbary.set(n.id, n.order);\n\t\t\tcontinue;\n\t\t}\n\t\tlet sum = 0;\n\t\tlet count = 0;\n\t\tfor (const h of neighbors) {\n\t\t\tconst other = state.nodes.get(direction === \"in\" ? h.fromId : h.toId);\n\t\t\tif (!other) continue;\n\t\t\tsum += other.order;\n\t\t\tcount += 1;\n\t\t}\n\t\tbary.set(n.id, count === 0 ? n.order : sum / count);\n\t}\n\tlayer.sort((a, b) => {\n\t\tconst ba = bary.get(a.id)!;\n\t\tconst bb = bary.get(b.id)!;\n\t\tif (ba !== bb) return ba - bb;\n\t\treturn a.order - b.order;\n\t});\n}\n\nfunction reindex(layer: Layer): void {\n\tfor (let i = 0; i < layer.length; i += 1) layer[i]!.order = i;\n}\n\nfunction pairCrossings(\n\tstate: PipelineState,\n\ta: InternalNode,\n\tb: InternalNode,\n\tdirection: \"in\" | \"out\",\n): number {\n\tconst aEdges = direction === \"in\" ? a.in : a.out;\n\tconst bEdges = direction === \"in\" ? b.in : b.out;\n\tlet crossings = 0;\n\tfor (const ea of aEdges) {\n\t\tfor (const eb of bEdges) {\n\t\t\tconst oa = state.nodes.get(direction === \"in\" ? ea.fromId : ea.toId)?.order ?? 0;\n\t\t\tconst ob = state.nodes.get(direction === \"in\" ? eb.fromId : eb.toId)?.order ?? 0;\n\t\t\tif ((a.order < b.order && oa > ob) || (a.order > b.order && oa < ob)) {\n\t\t\t\tcrossings += 1;\n\t\t\t}\n\t\t}\n\t}\n\treturn crossings;\n}\n\n// ---------------------------------------------------------------------------\n// 5. Coordinate assignment (direction-aware)\n// ---------------------------------------------------------------------------\n\nfunction assignCoordinates(state: PipelineState, input: LayoutInput): void {\n\tif (input.direction === \"LR\") assignCoordinatesLR(state, input);\n\telse assignCoordinatesTD(state, input);\n}\n\nfunction assignCoordinatesLR(state: PipelineState, input: LayoutInput): void {\n\t// x: per-layer column based on cumulative max width.\n\tconst layerX: number[] = [];\n\tlet cursorX = 0;\n\tfor (let li = 0; li < state.layers.length; li += 1) {\n\t\tlayerX.push(cursorX);\n\t\tlet maxW = 0;\n\t\tfor (const n of state.layers[li]!) maxW = Math.max(maxW, n.w);\n\t\tcursorX += maxW + input.layerGap;\n\t}\n\tfor (let li = 0; li < state.layers.length; li += 1) {\n\t\tfor (const n of state.layers[li]!) n.x = layerX[li]!;\n\t}\n\t// y: greedy pack per layer.\n\tfor (const layer of state.layers) {\n\t\tlet y = 0;\n\t\tfor (const n of layer) {\n\t\t\tn.y = y;\n\t\t\ty += n.h + input.nodeGap;\n\t\t}\n\t}\n\t// Median alignment — straightens chains through virtuals.\n\trunMedianPasses(state, input, \"y\");\n}\n\nfunction assignCoordinatesTD(state: PipelineState, input: LayoutInput): void {\n\t// y: per-layer row based on cumulative max height.\n\tconst layerY: number[] = [];\n\tlet cursorY = 0;\n\tfor (let li = 0; li < state.layers.length; li += 1) {\n\t\tlayerY.push(cursorY);\n\t\tlet maxH = 0;\n\t\tfor (const n of state.layers[li]!) maxH = Math.max(maxH, n.h);\n\t\tcursorY += maxH + input.layerGap;\n\t}\n\tfor (let li = 0; li < state.layers.length; li += 1) {\n\t\tfor (const n of state.layers[li]!) n.y = layerY[li]!;\n\t}\n\t// x: greedy pack per layer.\n\tfor (const layer of state.layers) {\n\t\tlet x = 0;\n\t\tfor (const n of layer) {\n\t\t\tn.x = x;\n\t\t\tx += n.w + input.nodeGap;\n\t\t}\n\t}\n\trunMedianPasses(state, input, \"x\");\n}\n\n/**\n * Median alignment passes — pulls each node toward the median position of\n * its in-layer neighbors along the private axis (\"y\" for LR, \"x\" for TD),\n * then resolves collisions greedily while preserving layer order.\n */\nfunction runMedianPasses(state: PipelineState, input: LayoutInput, axis: \"x\" | \"y\"): void {\n\tconst sizeOf = (n: InternalNode) => (axis === \"y\" ? n.h : n.w);\n\tconst gap = input.nodeGap;\n\tfor (let pass = 0; pass < 2; pass += 1) {\n\t\tconst walk = pass === 0 ? state.layers.slice(1) : state.layers.slice(0, -1).reverse();\n\t\tfor (const layer of walk) {\n\t\t\tconst preferred = new Map<string, number>();\n\t\t\tfor (const n of layer) {\n\t\t\t\tconst neighbors = pass === 0 ? n.in : n.out;\n\t\t\t\tif (neighbors.length === 0) continue;\n\t\t\t\tconst centers: number[] = [];\n\t\t\t\tfor (const h of neighbors) {\n\t\t\t\t\tconst other = state.nodes.get(pass === 0 ? h.fromId : h.toId);\n\t\t\t\t\tif (!other) continue;\n\t\t\t\t\tconst base = axis === \"y\" ? other.y : other.x;\n\t\t\t\t\tcenters.push(base + Math.floor(sizeOf(other) / 2));\n\t\t\t\t}\n\t\t\t\tif (centers.length === 0) continue;\n\t\t\t\tcenters.sort((a, b) => a - b);\n\t\t\t\tconst mid = centers[Math.floor(centers.length / 2)]!;\n\t\t\t\tpreferred.set(n.id, mid - Math.floor(sizeOf(n) / 2));\n\t\t\t}\n\t\t\tlet floor = 0;\n\t\t\tfor (const n of layer) {\n\t\t\t\tconst p = preferred.get(n.id);\n\t\t\t\tconst current = axis === \"y\" ? n.y : n.x;\n\t\t\t\tconst target = p ?? current;\n\t\t\t\tconst clamped = Math.max(target, floor);\n\t\t\t\tif (axis === \"y\") n.y = clamped;\n\t\t\t\telse n.x = clamped;\n\t\t\t\tfloor = clamped + sizeOf(n) + gap;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// 6. Orthogonal edge routing (direction-aware)\n//\n// For both LR and TD the algorithm is symmetric — it just operates on a\n// different pair of \"primary\" vs \"cross\" axes:\n//\n// LR: primary = x (layer axis); cross = y. Gutters are vertical strips\n// between columns; tracks within a gutter are distinct x-values.\n// TD: primary = y (layer axis); cross = x. Gutters are horizontal strips\n// between rows; tracks within a gutter are distinct y-values.\n// ---------------------------------------------------------------------------\n\nfunction routeEdges(state: PipelineState, input: LayoutInput): LayoutEdge[] {\n\t// Group hops by chainId → one LayoutEdge per user-facing edge.\n\tconst byChain = new Map<number, Hop[]>();\n\tfor (const h of state.hops) {\n\t\tconst arr = byChain.get(h.chainId);\n\t\tif (arr) arr.push(h);\n\t\telse byChain.set(h.chainId, [h]);\n\t}\n\tfor (const arr of byChain.values()) arr.sort((a, b) => a.hopIndex - b.hopIndex);\n\n\tconst isLR = input.direction === \"LR\";\n\tconst primary = (n: InternalNode): number => (isLR ? n.x : n.y);\n\tconst primarySize = (n: InternalNode): number => (isLR ? n.w : n.h);\n\tconst crossCenter = (n: InternalNode): number =>\n\t\tisLR ? n.y + Math.floor(n.h / 2) : n.x + Math.floor(n.w / 2);\n\n\t// Per-gutter cross-axis track assignment. Two passes:\n\t// 1. Assign each hop to a track INDEX using disjoint-interval packing\n\t// (an existing track may host multiple hops as long as their\n\t// cross-axis ranges don't overlap pairwise).\n\t// 2. Map each track index to a primary-axis position using the final\n\t// track count so the distribution is uniform across the gutter —\n\t// per-hop recomputation (old behavior) collapsed late tracks onto\n\t// `gEnd`, producing bundled overlaps in dense gutters.\n\tconst hopTrackCross = new Map<Hop, number>();\n\tfor (let g = 0; g + 1 < state.layers.length; g += 1) {\n\t\tconst srcLayer = state.layers[g]!;\n\t\tconst dstLayer = state.layers[g + 1]!;\n\n\t\tlet gutterStart = 0;\n\t\tfor (const n of srcLayer) gutterStart = Math.max(gutterStart, primary(n) + primarySize(n));\n\t\tlet gutterEnd = Number.POSITIVE_INFINITY;\n\t\tfor (const n of dstLayer) gutterEnd = Math.min(gutterEnd, primary(n));\n\t\tconst gEnd = Number.isFinite(gutterEnd) ? (gutterEnd as number) - 1 : gutterStart;\n\t\tconst gutterWidth = Math.max(1, gEnd - gutterStart + 1);\n\n\t\tconst gutterHops: Hop[] = [];\n\t\tfor (const n of srcLayer) for (const h of n.out) gutterHops.push(h);\n\t\tgutterHops.sort((a, b) => {\n\t\t\tconst sa = crossCenter(state.nodes.get(a.fromId)!);\n\t\t\tconst sb = crossCenter(state.nodes.get(b.fromId)!);\n\t\t\tif (sa !== sb) return sa - sb;\n\t\t\tconst da = crossCenter(state.nodes.get(a.toId)!);\n\t\t\tconst db = crossCenter(state.nodes.get(b.toId)!);\n\t\t\treturn da - db;\n\t\t});\n\n\t\t// Pass 1: assign track indexes. Each track is an ARRAY of disjoint\n\t\t// intervals — two hops share a track iff their cross-axis ranges\n\t\t// don't overlap any existing interval on that track.\n\t\tconst tracks: Array<Array<{ lo: number; hi: number }>> = [];\n\t\tconst hopToTrackIdx = new Map<Hop, number>();\n\t\tfor (const h of gutterHops) {\n\t\t\tconst sc = crossCenter(state.nodes.get(h.fromId)!);\n\t\t\tconst dc = crossCenter(state.nodes.get(h.toId)!);\n\t\t\tconst lo = Math.min(sc, dc);\n\t\t\tconst hi = Math.max(sc, dc);\n\t\t\tlet idx = -1;\n\t\t\tfor (let t = 0; t < tracks.length; t += 1) {\n\t\t\t\tconst intervals = tracks[t]!;\n\t\t\t\tlet fits = true;\n\t\t\t\tfor (const iv of intervals) {\n\t\t\t\t\tif (iv.lo <= hi && lo <= iv.hi) {\n\t\t\t\t\t\tfits = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (fits) {\n\t\t\t\t\tintervals.push({ lo, hi });\n\t\t\t\t\tidx = t;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (idx < 0) {\n\t\t\t\ttracks.push([{ lo, hi }]);\n\t\t\t\tidx = tracks.length - 1;\n\t\t\t}\n\t\t\thopToTrackIdx.set(h, idx);\n\t\t}\n\n\t\t// Pass 2: distribute track indexes uniformly across the gutter's\n\t\t// **interior** (reserve 1-cell margin from each boundary when the\n\t\t// gutter is wide enough). A track placed exactly at `gutterStart`\n\t\t// or `gEnd` collapses the final turn-segment into the adjacent\n\t\t// node's border row, producing a visually misleading arrow; the\n\t\t// margin avoids that whenever geometry allows.\n\t\tconst count = tracks.length;\n\t\tconst hasMargin = gutterWidth >= Math.max(3, count + 2);\n\t\tconst usableStart = hasMargin ? gutterStart + 1 : gutterStart;\n\t\tconst usableEnd = hasMargin ? gEnd - 1 : gEnd;\n\t\tconst usableWidth = Math.max(1, usableEnd - usableStart + 1);\n\t\tfor (const h of gutterHops) {\n\t\t\tconst idx = hopToTrackIdx.get(h)!;\n\t\t\tlet trackPrimary: number;\n\t\t\tif (count <= 1) {\n\t\t\t\ttrackPrimary = usableStart + Math.floor(usableWidth / 2);\n\t\t\t} else {\n\t\t\t\tconst step = (usableWidth - 1) / (count - 1);\n\t\t\t\ttrackPrimary = usableStart + Math.floor(idx * step);\n\t\t\t}\n\t\t\thopTrackCross.set(h, Math.max(gutterStart, Math.min(gEnd, trackPrimary)));\n\t\t}\n\t}\n\n\t// Build polylines.\n\tconst out: LayoutEdge[] = [];\n\tfor (const [, hops] of byChain) {\n\t\tconst points: LayoutEdgePoint[] = [];\n\t\tfor (let i = 0; i < hops.length; i += 1) {\n\t\t\tconst h = hops[i]!;\n\t\t\tconst src = state.nodes.get(h.fromId)!;\n\t\t\tconst dst = state.nodes.get(h.toId)!;\n\t\t\tconst track = hopTrackCross.get(h)!;\n\t\t\t// Endpoints in (primary, cross) space.\n\t\t\tconst srcPrimary = src.isVirtual ? primary(src) : primary(src) + primarySize(src);\n\t\t\tconst dstPrimary = dst.isVirtual ? primary(dst) : primary(dst) - 1;\n\t\t\tconst sc = crossCenter(src);\n\t\t\tconst dc = crossCenter(dst);\n\t\t\tif (i === 0) pushPoint(points, isLR, srcPrimary, sc);\n\t\t\tif (sc !== dc) {\n\t\t\t\tpushPoint(points, isLR, track, sc);\n\t\t\t\tpushPoint(points, isLR, track, dc);\n\t\t\t}\n\t\t\tpushPoint(points, isLR, dstPrimary, dc);\n\t\t}\n\t\tconst chain = hops[0]!;\n\t\tout.push({\n\t\t\tfrom: chain.chainFrom,\n\t\t\tto: chain.chainTo,\n\t\t\tpoints: dedupWaypoints(points),\n\t\t});\n\t}\n\treturn out;\n}\n\nfunction pushPoint(acc: LayoutEdgePoint[], isLR: boolean, primary: number, cross: number): void {\n\tacc.push(isLR ? { x: primary, y: cross } : { x: cross, y: primary });\n}\n\nfunction dedupWaypoints(points: readonly LayoutEdgePoint[]): LayoutEdgePoint[] {\n\tconst out: LayoutEdgePoint[] = [];\n\tfor (const p of points) {\n\t\tconst last = out[out.length - 1];\n\t\tif (!last || last.x !== p.x || last.y !== p.y) out.push(p);\n\t}\n\treturn out;\n}\n\n// ---------------------------------------------------------------------------\n// Bounding box\n// ---------------------------------------------------------------------------\n\nfunction boundingBox(state: PipelineState): { width: number; height: number } {\n\tlet w = 0;\n\tlet h = 0;\n\tfor (const layer of state.layers) {\n\t\tfor (const n of layer) {\n\t\t\tw = Math.max(w, n.x + n.w);\n\t\t\th = Math.max(h, n.y + n.h);\n\t\t}\n\t}\n\treturn { width: w, height: h };\n}\n","/**\n * `graphSpecToAscii(g, opts?)` — stdout-native DAG flowchart renderer for a\n * {@link GraphDescribeOutput}.\n *\n * Zero external dependencies, graph-size independent via proper Sugiyama\n * (layer assignment → virtual-node splitting → barycenter crossing\n * minimization → median-aligned coordinate assignment → per-gutter\n * track-assigned orthogonal routing). See\n * [_layout-sugiyama.ts](./_layout-sugiyama.ts) for the layout pipeline and\n * [_ascii-grid.ts](./_ascii-grid.ts) for the character blitter.\n *\n * Pure function over the describe snapshot; no Graph instance dependency.\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport { renderGrid } from \"./_ascii-grid.js\";\nimport { countCells, truncateToCells } from \"./_ascii-width.js\";\nimport type { LayoutDirection } from \"./_layout-sugiyama.js\";\nimport { sugiyamaLayout } from \"./_layout-sugiyama.js\";\n\nconst DEFAULT_LABEL_WIDTH = 24;\nconst LAYER_GAP = 4;\nconst NODE_GAP = 1;\nconst BOX_HEIGHT = 3;\n\nexport type GraphSpecToAsciiOptions = {\n\t/**\n\t * ASCII layout direction. ASCII grid semantics are meaningful only for\n\t * `\"LR\"` (default) and `\"TD\"`.\n\t */\n\tdirection?: LayoutDirection;\n\t/** Per-box label cell cap; longer labels are truncated with `…`. Default `24`. */\n\tmaxLabelWidth?: number;\n\t/** Glyph set: `\"unicode\"` (default, box-drawing) or `\"ascii\"` (`-|+<>v`). */\n\tasciiCharset?: \"unicode\" | \"ascii\";\n\t/** Optional logger hook; fires with the rendered text before return. */\n\tlogger?: (text: string) => void;\n};\n\nexport function graphSpecToAscii(g: GraphDescribeOutput, opts?: GraphSpecToAsciiOptions): string {\n\tconst direction = normalizeAsciiDirection(opts?.direction);\n\tconst maxLabel = Math.max(3, opts?.maxLabelWidth ?? DEFAULT_LABEL_WIDTH);\n\tconst charset = opts?.asciiCharset ?? \"unicode\";\n\n\t// Deterministic paths ordering — match the rest of describe rendering.\n\tconst paths = Object.keys(g.nodes).sort();\n\t// Drop edges whose endpoints aren't in the current visible path set\n\t// (respects actor filtering that the caller already applied).\n\tconst nodeSet = new Set(paths);\n\tconst edges = g.edges.filter((e) => nodeSet.has(e.from) && nodeSet.has(e.to));\n\n\t// Precompute truncated labels + cell widths so the layout knows box\n\t// dimensions without re-measuring.\n\tconst labels = new Map<string, string>();\n\tconst widths = new Map<string, number>();\n\tfor (const p of paths) {\n\t\tconst label = truncateToCells(p, maxLabel);\n\t\tlabels.set(p, label);\n\t\t// Box width = label cells + 2 side borders + 2 cells of padding.\n\t\twidths.set(p, countCells(label) + 4);\n\t}\n\n\tconst layout = sugiyamaLayout({\n\t\tnodes: paths,\n\t\tedges,\n\t\twidthCells: (id) => widths.get(id) ?? 3,\n\t\theightCells: () => BOX_HEIGHT,\n\t\tlayerGap: LAYER_GAP,\n\t\tnodeGap: NODE_GAP,\n\t\tdirection,\n\t});\n\n\tconst text = renderGrid(layout, {\n\t\tcharset,\n\t\tlabelOf: (id) => labels.get(id) ?? id,\n\t});\n\n\topts?.logger?.(text);\n\treturn text;\n}\n\nfunction normalizeAsciiDirection(direction: unknown): LayoutDirection {\n\tif (direction === undefined || direction === \"LR\") return \"LR\";\n\tif (direction === \"TD\") return \"TD\";\n\t// BT / RL are valid for the vector diagram formats but ASCII grid\n\t// semantics are meaningful only for LR and TD — reject early with a\n\t// clear message rather than silently ignoring.\n\tthrow new Error(`ascii describe supports direction \"LR\" or \"TD\" only; got ${String(direction)}`);\n}\n","/**\n * Internal helpers shared across renderers in `extra/render/`.\n *\n * These are pure functions over `GraphDescribeOutput` — no Graph instance\n * dependency. Extracted from `src/graph/graph.ts` (the consolidated\n * ex-dumpGraph / ex-graphSpecToMermaid / ex-graphSpecToD2 renderers) per\n * Tier 2.1 A2.\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\n\n/** Direction options for diagram exports. */\nexport type DiagramDirection = \"TD\" | \"LR\" | \"BT\" | \"RL\";\n\n/** Recursively sort object keys for deterministic JSON (git-diffable). */\nexport function sortJsonValue(value: unknown): unknown {\n\tif (value === null || typeof value !== \"object\") {\n\t\treturn value;\n\t}\n\tif (Array.isArray(value)) {\n\t\treturn value.map(sortJsonValue);\n\t}\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) {\n\t\tout[k] = sortJsonValue(obj[k]);\n\t}\n\treturn out;\n}\n\n/** Escape characters that are illegal inside a quoted Mermaid label. */\nexport function escapeMermaidLabel(value: string): string {\n\treturn value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"');\n}\n\n/** Escape characters that are illegal inside a quoted D2 label. */\nexport function escapeD2Label(value: string): string {\n\treturn value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"');\n}\n\n/** Map our 4-direction enum to D2's `direction:` keyword. */\nexport function d2DirectionFromGraphDirection(direction: DiagramDirection): string {\n\tif (direction === \"TD\") return \"down\";\n\tif (direction === \"BT\") return \"up\";\n\tif (direction === \"RL\") return \"left\";\n\treturn \"right\";\n}\n\n/** Collect deduplicated (from, to) arrows from deps + edges. */\nexport function collectDiagramArrows(described: GraphDescribeOutput): [string, string][] {\n\tconst seen = new Set<string>();\n\tconst arrows: [string, string][] = [];\n\tfunction add(from: string, to: string): void {\n\t\tconst key = `${from}\\0${to}`;\n\t\tif (seen.has(key)) return;\n\t\tseen.add(key);\n\t\tarrows.push([from, to]);\n\t}\n\tfor (const [path, info] of Object.entries(described.nodes)) {\n\t\tconst deps: string[] | undefined = (info as Record<string, unknown>).deps as\n\t\t\t| string[]\n\t\t\t| undefined;\n\t\tif (deps) {\n\t\t\tfor (const dep of deps) add(dep, path);\n\t\t}\n\t}\n\tfor (const edge of described.edges) add(edge.from, edge.to);\n\treturn arrows;\n}\n\n/** Default to \"LR\"; throw on unknown values to surface caller bugs early. */\nexport function normalizeDiagramDirection(direction: unknown): DiagramDirection {\n\tif (direction === undefined) return \"LR\";\n\tif (direction === \"TD\" || direction === \"LR\" || direction === \"BT\" || direction === \"RL\") {\n\t\treturn direction;\n\t}\n\tthrow new Error(\n\t\t`invalid diagram direction ${String(direction)}; expected one of: TD, LR, BT, RL`,\n\t);\n}\n\n/** JSON-aware single-value formatter (used by `graphSpecToPretty`). */\nexport function describeData(value: unknown): string {\n\tif (typeof value === \"string\") return JSON.stringify(value);\n\tif (typeof value === \"number\" || typeof value === \"boolean\" || value == null)\n\t\treturn String(value);\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch {\n\t\treturn \"[unserializable]\";\n\t}\n}\n","/**\n * `graphSpecToD2(g, opts?)` — render a {@link GraphDescribeOutput} as D2\n * diagram text.\n *\n * Pure function over the describe snapshot; no Graph instance dependency.\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport {\n\tcollectDiagramArrows,\n\ttype DiagramDirection,\n\td2DirectionFromGraphDirection,\n\tescapeD2Label,\n\tnormalizeDiagramDirection,\n} from \"./_internal.js\";\n\nexport type GraphSpecToD2Options = {\n\t/** Diagram direction; default `\"LR\"`. */\n\tdirection?: DiagramDirection;\n};\n\nexport function graphSpecToD2(g: GraphDescribeOutput, opts?: GraphSpecToD2Options): string {\n\tconst direction = normalizeDiagramDirection(opts?.direction);\n\tconst paths = Object.keys(g.nodes).sort();\n\tconst ids = new Map<string, string>();\n\tfor (let i = 0; i < paths.length; i += 1) ids.set(paths[i]!, `n${i}`);\n\tconst lines: string[] = [`direction: ${d2DirectionFromGraphDirection(direction)}`];\n\tfor (const path of paths) {\n\t\tconst id = ids.get(path)!;\n\t\tlines.push(`${id}: \"${escapeD2Label(path)}\"`);\n\t}\n\tfor (const [from, to] of collectDiagramArrows(g)) {\n\t\tconst fromId = ids.get(from);\n\t\tconst toId = ids.get(to);\n\t\tif (!fromId || !toId) continue;\n\t\tlines.push(`${fromId} -> ${toId}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n","/**\n * `graphSpecToJson(g, opts?)` — render a {@link GraphDescribeOutput} as\n * deterministic JSON text with sorted keys.\n *\n * Pure function over the describe snapshot; no Graph instance dependency.\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport { sortJsonValue } from \"./_internal.js\";\n\nexport type GraphSpecToJsonOptions = {\n\t/** Include the Edges section (default `true`). */\n\tincludeEdges?: boolean;\n\t/** Include the Subgraphs section (default `true`). */\n\tincludeSubgraphs?: boolean;\n\t/** JSON indent (default `2`). */\n\tindent?: number;\n\t/** Optional logger hook; fires with the rendered text before return. */\n\tlogger?: (text: string) => void;\n};\n\nexport function graphSpecToJson(g: GraphDescribeOutput, opts?: GraphSpecToJsonOptions): string {\n\tconst includeEdges = opts?.includeEdges ?? true;\n\tconst includeSubgraphs = opts?.includeSubgraphs ?? true;\n\tconst { expand: _expand, ...rest } = g;\n\tconst payload: GraphDescribeOutput = {\n\t\t...rest,\n\t\tedges: includeEdges ? g.edges : [],\n\t\tsubgraphs: includeSubgraphs ? g.subgraphs : [],\n\t};\n\tconst text = JSON.stringify(sortJsonValue(payload), null, opts?.indent ?? 2);\n\topts?.logger?.(text);\n\treturn text;\n}\n","/**\n * `graphSpecToMermaid(g, opts?)` — render a {@link GraphDescribeOutput} as\n * Mermaid flowchart text.\n *\n * Pure function over the describe snapshot; no Graph instance dependency.\n * Compose with `derived` for live formatted output:\n *\n * ```ts\n * import { graphSpecToMermaid } from \"@graphrefly/graphrefly/extra/render\";\n * import { derived } from \"@graphrefly/graphrefly\";\n *\n * const live = derived(\n * [graph.describe({ reactive: true }).node],\n * ([g]) => graphSpecToMermaid(g),\n * );\n * ```\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport {\n\tcollectDiagramArrows,\n\ttype DiagramDirection,\n\tescapeMermaidLabel,\n\tnormalizeDiagramDirection,\n} from \"./_internal.js\";\n\nexport type GraphSpecToMermaidOptions = {\n\t/** Diagram direction; default `\"LR\"`. */\n\tdirection?: DiagramDirection;\n};\n\nexport function graphSpecToMermaid(\n\tg: GraphDescribeOutput,\n\topts?: GraphSpecToMermaidOptions,\n): string {\n\tconst direction = normalizeDiagramDirection(opts?.direction);\n\tconst paths = Object.keys(g.nodes).sort();\n\tconst ids = new Map<string, string>();\n\tfor (let i = 0; i < paths.length; i += 1) ids.set(paths[i]!, `n${i}`);\n\tconst lines: string[] = [`flowchart ${direction}`];\n\tfor (const path of paths) {\n\t\tconst id = ids.get(path)!;\n\t\tlines.push(` ${id}[\"${escapeMermaidLabel(path)}\"]`);\n\t}\n\tfor (const [from, to] of collectDiagramArrows(g)) {\n\t\tconst fromId = ids.get(from);\n\t\tconst toId = ids.get(to);\n\t\tif (!fromId || !toId) continue;\n\t\tlines.push(` ${fromId} --> ${toId}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n","/**\n * `graphSpecToMermaidUrl(g, opts?)` — encode a {@link GraphDescribeOutput}\n * as a `https://mermaid.live/edit#base64:…` deep link.\n *\n * Round-trip with the mermaid.live editor's `/edit#base64:` share format —\n * payload is `base64url(JSON({code, mermaid: {theme}, ...}))`. No network\n * calls; the payload is encoded into the URL fragment.\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport { type GraphSpecToMermaidOptions, graphSpecToMermaid } from \"./graph-spec-to-mermaid.js\";\n\nexport type MermaidLiveTheme = \"default\" | \"dark\" | \"forest\" | \"neutral\" | \"base\";\n\nexport type GraphSpecToMermaidUrlOptions = GraphSpecToMermaidOptions & {\n\ttheme?: MermaidLiveTheme;\n\tautoSync?: boolean;\n};\n\n/**\n * Encode an arbitrary mermaid source string to a `mermaid.live` deep link.\n * Exported separately so callers that already rendered mermaid text can\n * upgrade to a live-editor URL without re-rendering.\n */\nexport function mermaidLiveUrl(\n\tmermaidSrc: string,\n\topts?: { theme?: MermaidLiveTheme; autoSync?: boolean },\n): string {\n\tconst theme = opts?.theme ?? \"default\";\n\tconst autoSync = opts?.autoSync ?? true;\n\tconst payload = { code: mermaidSrc, mermaid: { theme }, autoSync };\n\tconst json = JSON.stringify(payload);\n\t// Browsers + Node both expose globalThis.btoa; encode UTF-8 bytes first so\n\t// non-ASCII node names don't explode btoa. Then url-safe base64 (`+/=`→`-_` strip).\n\tconst bytes = new TextEncoder().encode(json);\n\tlet binary = \"\";\n\tfor (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]!);\n\tconst b64 = globalThis.btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n\treturn `https://mermaid.live/edit#base64:${b64}`;\n}\n\nexport function graphSpecToMermaidUrl(\n\tg: GraphDescribeOutput,\n\topts?: GraphSpecToMermaidUrlOptions,\n): string {\n\tconst mermaidSrc = graphSpecToMermaid(g, opts);\n\treturn mermaidLiveUrl(mermaidSrc, opts);\n}\n","/**\n * `graphSpecToPretty(g, opts?)` — render a {@link GraphDescribeOutput} as\n * human-readable plaintext (Node list with values, plus optional Edges and\n * Subgraphs sections).\n *\n * Pure function over the describe snapshot; no Graph instance dependency.\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport { describeData } from \"./_internal.js\";\n\nexport type GraphSpecToPrettyOptions = {\n\t/** Include the Edges section (default `true`). */\n\tincludeEdges?: boolean;\n\t/** Include the Subgraphs section (default `true`). */\n\tincludeSubgraphs?: boolean;\n\t/** Optional logger hook; fires with the rendered text before return. */\n\tlogger?: (text: string) => void;\n};\n\nexport function graphSpecToPretty(g: GraphDescribeOutput, opts?: GraphSpecToPrettyOptions): string {\n\tconst includeEdges = opts?.includeEdges ?? true;\n\tconst includeSubgraphs = opts?.includeSubgraphs ?? true;\n\tconst lines: string[] = [];\n\tlines.push(`Graph ${g.name}`);\n\tlines.push(\"Nodes:\");\n\tfor (const path of Object.keys(g.nodes).sort()) {\n\t\tconst n = g.nodes[path]!;\n\t\tlines.push(`- ${path} (${n.type}/${n.status}): ${describeData(n.value)}`);\n\t}\n\tif (includeEdges) {\n\t\tlines.push(\"Edges:\");\n\t\tfor (const edge of g.edges) {\n\t\t\tlines.push(`- ${edge.from} -> ${edge.to}`);\n\t\t}\n\t}\n\tif (includeSubgraphs) {\n\t\tlines.push(\"Subgraphs:\");\n\t\tfor (const sg of g.subgraphs) {\n\t\t\tlines.push(`- ${sg}`);\n\t\t}\n\t}\n\tconst text = lines.join(\"\\n\");\n\topts?.logger?.(text);\n\treturn text;\n}\n","/**\n * `layoutFrameToSvg(frame, opts?)` — render a {@link LayoutFrame} as an SVG\n * markup string.\n *\n * Universal-safe — emits a string, not a DOM tree. Browser code embeds via\n * `el.innerHTML = svg`; Node code writes to a file. Cell-grid coordinates from\n * the layout are scaled by `cellWidth` / `cellHeight` (default 12 × 18 px,\n * roughly matching a monospace baseline).\n *\n * Each box gets `data-id=\"<path>\"` for change-event highlighting; each edge\n * gets `data-from=\"<from>\" data-to=\"<to>\"` so renderers can animate flowing\n * data per `LayoutFrame.changes`.\n *\n * @category extra\n */\n\nimport type { LayoutFrame } from \"./layout-types.js\";\n\nexport interface LayoutFrameToSvgOptions {\n\t/** Pixel width of one cell. Default: `12`. */\n\treadonly cellWidth?: number;\n\t/** Pixel height of one cell. Default: `18`. */\n\treadonly cellHeight?: number;\n\t/** Outer margin in pixels. Default: `16`. */\n\treadonly padding?: number;\n\t/** Box stroke color. Default: `\"#444\"`. */\n\treadonly boxStroke?: string;\n\t/** Box fill color. Default: `\"#fff\"`. */\n\treadonly boxFill?: string;\n\t/** Edge stroke color. Default: `\"#888\"`. */\n\treadonly edgeStroke?: string;\n\t/** Box label text color. Default: `\"#111\"`. */\n\treadonly textColor?: string;\n\t/** Font family. Default: `\"ui-monospace, monospace\"`. */\n\treadonly fontFamily?: string;\n\t/** Font size in pixels. Default: `12`. */\n\treadonly fontSize?: number;\n}\n\nconst SPECIAL_CHARS: Record<string, string> = {\n\t\"&\": \"&amp;\",\n\t\"<\": \"&lt;\",\n\t\">\": \"&gt;\",\n\t'\"': \"&quot;\",\n\t\"'\": \"&apos;\",\n};\n\nfunction escapeXml(s: string): string {\n\treturn s.replace(/[&<>\"']/g, (c) => SPECIAL_CHARS[c] ?? c);\n}\n\n/**\n * Render a {@link LayoutFrame} to SVG markup. Pure function — call from\n * `derived` to drive a live `<svg>` element from a `topologyView` output.\n */\nexport function layoutFrameToSvg(frame: LayoutFrame, opts?: LayoutFrameToSvgOptions): string {\n\tconst cellW = opts?.cellWidth ?? 12;\n\tconst cellH = opts?.cellHeight ?? 18;\n\tconst pad = opts?.padding ?? 16;\n\t// /qa F-10: route option-bag string attributes through escapeXml so that\n\t// user-supplied themes (URL params, dashboard config, etc.) cannot inject\n\t// `\"/><script>...` and break out of the attribute. Numeric `fontSize` has\n\t// no XSS surface; escape only when caller passes a string.\n\tconst boxStroke = escapeXml(opts?.boxStroke ?? \"#444\");\n\tconst boxFill = escapeXml(opts?.boxFill ?? \"#fff\");\n\tconst edgeStroke = escapeXml(opts?.edgeStroke ?? \"#888\");\n\tconst textColor = escapeXml(opts?.textColor ?? \"#111\");\n\tconst fontFamily = opts?.fontFamily ?? \"ui-monospace, monospace\";\n\tconst fontSize = opts?.fontSize ?? 12;\n\n\tlet maxX = 0;\n\tlet maxY = 0;\n\tfor (const b of frame.boxes) {\n\t\tmaxX = Math.max(maxX, b.x + b.w);\n\t\tmaxY = Math.max(maxY, b.y + b.h);\n\t}\n\tfor (const e of frame.edges) {\n\t\tfor (const [x, y] of e.points) {\n\t\t\tmaxX = Math.max(maxX, x);\n\t\t\tmaxY = Math.max(maxY, y);\n\t\t}\n\t}\n\tconst width = Math.max(1, maxX) * cellW + pad * 2;\n\tconst height = Math.max(1, maxY) * cellH + pad * 2;\n\n\tconst lines: string[] = [];\n\tlines.push(\n\t\t`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\">`,\n\t);\n\n\t// Edges first (so boxes overlay them at endpoints).\n\tfor (const e of frame.edges) {\n\t\tif (e.points.length < 2) continue;\n\t\tconst pts = e.points.map(([x, y]) => `${x * cellW + pad},${y * cellH + pad}`).join(\" \");\n\t\tlines.push(\n\t\t\t` <polyline points=\"${pts}\" fill=\"none\" stroke=\"${edgeStroke}\" stroke-width=\"1\" data-from=\"${escapeXml(e.from)}\" data-to=\"${escapeXml(e.to)}\" data-dep-index=\"${e.depIndex}\" />`,\n\t\t);\n\t}\n\n\t// Boxes.\n\tfor (const b of frame.boxes) {\n\t\tconst px = b.x * cellW + pad;\n\t\tconst py = b.y * cellH + pad;\n\t\tconst pw = Math.max(1, b.w) * cellW;\n\t\tconst ph = Math.max(1, b.h) * cellH;\n\t\t// Local segment for label so deeply-mounted nodes stay readable.\n\t\tconst local = b.id.includes(\"::\") ? (b.id.split(\"::\").pop() ?? b.id) : b.id;\n\t\tlines.push(\n\t\t\t` <g data-id=\"${escapeXml(b.id)}\">`,\n\t\t\t` <rect x=\"${px}\" y=\"${py}\" width=\"${pw}\" height=\"${ph}\" fill=\"${boxFill}\" stroke=\"${boxStroke}\" stroke-width=\"1\" />`,\n\t\t\t` <text x=\"${px + pw / 2}\" y=\"${py + ph / 2}\" fill=\"${textColor}\" font-family=\"${escapeXml(fontFamily)}\" font-size=\"${fontSize}\" text-anchor=\"middle\" dominant-baseline=\"central\">${escapeXml(local)}</text>`,\n\t\t\t` </g>`,\n\t\t);\n\t}\n\n\tlines.push(\"</svg>\");\n\treturn lines.join(\"\\n\");\n}\n","/**\n * Cron-based reactive sources and schedule types.\n *\n * Merged from extra/cron.ts + extra/sources/event.ts (fromCron) during cleave A2.\n * `fromCron` relocated here from `dom.ts` (post-cleave /qa A1): it uses zero DOM\n * APIs (only `setInterval` + `new Date()`), so it belongs on the universal\n * `event/index.ts` barrel, not the browser-only `dom.ts` subpath.\n */\n\nimport { type Node, type NodeOptions, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\n\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nfunction sourceOpts<T = unknown>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\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/**\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/**\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\";\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 node<number | Date>(\n\t\t(_data, 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 * Pure exponential-decay utility (Tier 2.2 promotion from `patterns/memory/`).\n *\n * Used by `collection`, `agentMemory`, harness `strategy.ts`, and any\n * downstream consumer that needs decay-with-floor scoring. Promoted to\n * `extra/utils/` because the math has zero domain semantics and is reusable\n * by non-memory primitives (e.g. routing weight decay, retry-attempt aging).\n *\n * @module\n */\n\n/**\n * Default exponential-decay rate corresponding to a 7-day half-life.\n *\n * `Math.LN2 / (7 × 86_400)` ≈ `1.146e-6`. Imported by memory tiers + any\n * consumer that wants the same default cadence as `agentMemory`'s active\n * tier. Tier 4.4 (Wave AM Unit 1) — promoted from\n * `patterns/ai/memory/tiers.ts` so non-memory consumers can share the\n * canonical default without reaching across domains.\n */\nexport const DEFAULT_DECAY_RATE = Math.LN2 / (7 * 86_400);\n\n/**\n * Exponential decay with floor: `score = max(minScore, baseScore * exp(-ratePerSecond * ageSeconds))`.\n *\n * Tolerant fallbacks (deliberate for use inside reactive derived fns):\n * - non-finite `baseScore` → `minScore`\n * - non-positive `ageSeconds` (incl. clock skew) → `max(minScore, baseScore)` (no decay)\n * - non-positive `ratePerSecond` → `max(minScore, baseScore)` (no decay; rate=0 disables)\n *\n * Underflow boundary: `Math.exp(-745) === 0`. For very long ages × rates the\n * result clamps to `minScore`; if you need slow decay over years, choose a\n * smaller `ratePerSecond` rather than relying on graceful underflow.\n *\n * Half-life conversion: `ratePerSecond = Math.LN2 / halfLifeSeconds`.\n */\nexport function decay(\n\tbaseScore: number,\n\tageSeconds: number,\n\tratePerSecond: number,\n\tminScore = 0,\n): number {\n\tif (!Number.isFinite(baseScore)) return minScore;\n\tif (!Number.isFinite(ageSeconds) || ageSeconds <= 0) return Math.max(minScore, baseScore);\n\tif (!Number.isFinite(ratePerSecond) || ratePerSecond <= 0) return Math.max(minScore, baseScore);\n\tconst decayed = baseScore * Math.exp(-ratePerSecond * ageSeconds);\n\treturn Math.max(minScore, decayed);\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 {\n\tbatch,\n\tDATA,\n\tdefaultConfig,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\ttype NodeSink,\n\tnode,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport { filter, first, fromTimer, map, merge } from \"@graphrefly/pure-ts/extra\";\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 = node<\"connecting\" | \"connected\" | \"closed\">([], {\n\t\tinitial: \"connecting\",\n\t\tname: `${bridgeName}::meta::status`,\n\t});\n\tconst errorNode = node<Error | null>([], {\n\t\tinitial: 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 = node([], { initial: 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. `partial: true` opts out\n\t\t\t// of the §2.7 first-run gate so the aggregator can fire on\n\t\t\t// any-dep-settles waves (the worker may not expose all sources at\n\t\t\t// the same time).\n\t\t\t{ name: `${bridgeName}::aggregated`, partial: true },\n\t\t);\n\n\t\tconst effectNode = node(\n\t\t\t[aggregated],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\tconst data0 = batch0 != null && batch0.length > 0 ? batch0.at(-1) : ctx.prevData[0];\n\t\t\t\tconst updates = data0 as Record<string, unknown> | undefined;\n\t\t\t\tif (updates == null || Object.keys(updates).length === 0) return undefined;\n\n\t\t\t\tconst transferList: Transferable[] = [];\n\t\t\t\tfor (const name of Object.keys(updates)) {\n\t\t\t\t\tconst fn = (transferFns as any)[name];\n\t\t\t\t\tif (fn) transferList.push(...fn(updates[name]));\n\t\t\t\t}\n\n\t\t\t\t// V0 delta sync: include version counters when available (§6.0b).\n\t\t\t\tlet versions: Record<string, number> | undefined;\n\t\t\t\tfor (const [name, n] of exposeEntries) {\n\t\t\t\t\tif (name in updates && n.v != null) {\n\t\t\t\t\t\tif (versions == null) versions = {};\n\t\t\t\t\t\tversions[name] = n.v.version;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst msg: BatchMessage = { t: \"b\", u: updates, ...(versions ? { v: versions } : {}) };\n\t\t\t\ttry {\n\t\t\t\t\ttransport.post(msg, transferList.length > 0 ? transferList : undefined);\n\t\t\t\t} catch (err) {\n\t\t\t\t\terrorNode.down([[DATA, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t\t{ describeKind: \"effect\" },\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 * 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 \"@graphrefly/pure-ts/core\";\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 * 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 {\n\tbatch,\n\tDATA,\n\tdefaultConfig,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\ttype NodeSink,\n\tnode,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\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 = node([], { initial: 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. `partial: true`\n\t\t\t// opts out of the §2.7 first-run gate so the aggregator can fire on\n\t\t\t// any-dep-settles waves (deps deliver asynchronously).\n\t\t\t{ name: \"workerSelf::aggregated\", partial: true },\n\t\t);\n\n\t\tconst effectNode = node(\n\t\t\t[aggregated],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\tconst data0 = batch0 != null && batch0.length > 0 ? batch0.at(-1) : ctx.prevData[0];\n\t\t\t\tif (destroyed) return undefined;\n\t\t\t\tconst updates = data0 as Record<string, unknown> | undefined;\n\t\t\t\tif (updates == null || Object.keys(updates).length === 0) return undefined;\n\n\t\t\t\tconst transferList: Transferable[] = [];\n\t\t\t\tfor (const name of Object.keys(updates)) {\n\t\t\t\t\tconst fn = (transferFns as any)[name];\n\t\t\t\t\tif (fn) transferList.push(...fn(updates[name]));\n\t\t\t\t}\n\n\t\t\t\t// V0 delta sync: include version counters when available (§6.0b).\n\t\t\t\tlet versions: Record<string, number> | undefined;\n\t\t\t\tfor (const [name, n] of exposeEntries) {\n\t\t\t\t\tif (name in updates && n.v != null) {\n\t\t\t\t\t\tif (versions == null) versions = {};\n\t\t\t\t\t\tversions[name] = n.v.version;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst msg: BatchMessage = { t: \"b\", u: updates, ...(versions ? { v: versions } : {}) };\n\t\t\t\ttry {\n\t\t\t\t\ttransport.post(msg, transferList.length > 0 ? transferList : undefined);\n\t\t\t\t} catch (_err) {\n\t\t\t\t\t// Transport failure — bridge is likely destroyed; swallow\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t\t{ describeKind: \"effect\" },\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":["operatorOpts","import_core","cached","operatorOpts","import_core","import_core","import_extra","import_core","import_extra","node","batch","map","import_core","sourceOpts","import_core","import_core","node","import_core","import_extra","import_core","import_extra","import_core","node","import_core","import_extra","source","import_core","import_core","import_extra","import_core","sourceOpts","sourceOpts","import_core","import_core","import_extra","import_core","operatorOpts","import_core","out","retry","p","sourceOpts","retry","import_core","sourceOpts","import_core","import_core","sourceOpts","import_core","sourceOpts","import_core","import_core","import_core","import_extra","import_core","sourceOpts","import_core","sourceOpts","import_core","sourceOpts","import_core","import_core","sourceOpts","import_core","import_core","batch","import_core","import_core","seq","batch","import_core","import_core","operatorOpts","sourceOpts","import_core","import_core","import_extra","import_core","sourceOpts","import_core","import_extra","import_core","import_core","isTransport"]}
1
+ {"version":3,"sources":["../../src/base/resilience/_internal.ts","../../src/base/resilience/backoff.ts","../../src/base/resilience/timeout.ts","../../src/base/index.ts","../../src/base/composition/backpressure.ts","../../src/base/composition/distill.ts","../../src/base/sources/async.ts","../../src/base/composition/external-register.ts","../../src/base/composition/materialize.ts","../../src/base/composition/observable.ts","../../src/base/composition/pubsub.ts","../../src/base/composition/single-from-any.ts","../../src/base/sources/settled.ts","../../src/base/composition/verifiable.ts","../../src/base/io/checkpoint.ts","../../src/base/io/clickhouse-watch.ts","../../src/base/io/csv.ts","../../src/base/io/_internal.ts","../../src/base/io/drizzle.ts","../../src/base/io/http.ts","../../src/base/resilience/status.ts","../../src/base/io/_sink.ts","../../src/base/io/kafka.ts","../../src/base/io/kysely.ts","../../src/base/io/mcp.ts","../../src/base/io/nats.ts","../../src/base/io/ndjson.ts","../../src/base/io/otel.ts","../../src/base/io/prisma.ts","../../src/base/io/prometheus.ts","../../src/base/io/pulsar.ts","../../src/base/io/rabbitmq.ts","../../src/base/io/redis-stream.ts","../../src/base/io/sqlite.ts","../../src/base/io/sse.ts","../../src/base/io/statsd.ts","../../src/base/io/syslog.ts","../../src/base/io/to-clickhouse.ts","../../src/base/io/to-file.ts","../../src/base/io/to-csv.ts","../../src/base/io/to-loki.ts","../../src/base/io/to-mongo.ts","../../src/base/io/to-postgres.ts","../../src/base/io/to-s3.ts","../../src/base/io/to-tempo.ts","../../src/base/io/webhook.ts","../../src/base/io/websocket.ts","../../src/base/resilience/retry.ts","../../src/base/meta/domain-meta.ts","../../src/base/meta/emit-to-meta.ts","../../src/base/mutation/index.ts","../../src/base/render/_ascii-width.ts","../../src/base/render/_ascii-grid.ts","../../src/base/render/_layout-sugiyama.ts","../../src/base/render/graph-spec-to-ascii.ts","../../src/base/render/_internal.ts","../../src/base/render/graph-spec-to-d2.ts","../../src/base/render/graph-spec-to-json.ts","../../src/base/render/graph-spec-to-mermaid.ts","../../src/base/render/graph-spec-to-mermaid-url.ts","../../src/base/render/graph-spec-to-pretty.ts","../../src/base/render/layout-frame-to-svg.ts","../../src/base/sources/event/cron.ts","../../src/base/utils/decay.ts","../../src/base/worker/bridge.ts","../../src/base/worker/protocol.ts","../../src/base/worker/transport.ts","../../src/base/worker/self.ts"],"sourcesContent":["/**\n * Internal helpers shared by resilience sub-files.\n *\n * Not part of the public surface. The base-layer resilience operators\n * co-located here (`retry.ts`, `status.ts`, `timeout.ts`) import what they\n * need from this file directly; the utils-layer resilience primitives that\n * stayed in `utils/resilience/` (`breaker.ts`, `rate-limiter.ts`,\n * `fallback.ts`) import it top-down via `../../base/resilience/_internal.js`.\n *\n * `NodeOrValue<T>` is the only export re-surfaced publicly — there is no\n * `base/resilience/index.ts`; it ships through `utils/resilience/index.ts`\n * (and `utils/memory/index.ts`). Every resilience primitive that accepts\n * reactive options uses it as the option-arg shape.\n */\n\nimport type { Node, NodeOptions } from \"@graphrefly/pure-ts/core\";\nimport { DATA, type Message } from \"@graphrefly/pure-ts/core\";\n\nexport type ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nexport function operatorOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"derived\", ...opts } as NodeOptions<T>;\n}\n\nexport function clampNonNegative(value: number): number {\n\treturn value < 0 ? 0 : value;\n}\n\nexport function msgVal(m: Message): unknown {\n\treturn m[1];\n}\n\nexport function 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 function 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 * Either a literal value or a reactive Node carrying it. Mirrors\n * {@link FallbackInput}'s precedent for \"options that may be reactive.\"\n *\n * Used by {@link timeout} / {@link retry} / {@link rateLimiter} /\n * {@link circuitBreaker} / {@link budgetGate} to accept reactive option\n * configurations (Tier 6.5 3.2, 2026-04-29). Each primitive subscribes\n * to the option Node via {@link resolveReactiveOption} and rebinds\n * internal state per its locked swap-semantic rule (see each primitive's\n * JSDoc for the rule).\n *\n * @category extra\n */\nexport type NodeOrValue<T> = T | Node<T>;\n\n/**\n * Closure-mirror helper for `NodeOrValue<T>` options\n * (COMPOSITION-GUIDE §28). Returns:\n * - `current()` — read the latest value (cached at construction; updated\n * on each Node DATA emission).\n * - `unsub()` — release the subscription. Static-form arg never\n * subscribes; `unsub` is a no-op there.\n *\n * `onChange` fires on each DATA after the initial value (skips the\n * cache-seed read). Use to rebind primitive-internal state per the\n * primitive's locked swap-semantic rule.\n *\n * @internal\n */\nexport function resolveReactiveOption<T>(\n\targ: NodeOrValue<T>,\n\tonChange?: (next: T) => void,\n): { current: () => T; unsub: () => void } {\n\tif (!isNode(arg)) {\n\t\treturn { current: () => arg, unsub: () => undefined };\n\t}\n\tconst node = arg as Node<T>;\n\tlet latest: T = node.cache as T;\n\tconst unsub = node.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA) {\n\t\t\t\tlatest = m[1] as T;\n\t\t\t\tif (onChange) onChange(latest);\n\t\t\t}\n\t\t}\n\t});\n\treturn {\n\t\tcurrent: () => latest,\n\t\tunsub,\n\t};\n}\n\nexport function isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nexport function 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 * 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 * Timeout — emits `ERROR` with `TimeoutError` if no `DATA` arrives within the deadline.\n *\n * §3.1c — caching, fallback & composition sugar. Uses\n * `core/clock.js`-style nanoseconds and a `ResettableTimer` so the deadline\n * resets on each DATA. Distinct from the `operators/control.ts` timeout\n * (which forwards a caller-supplied error/value) — this one is the\n * resilience family's \"deadline → ERROR\" primitive.\n *\n * **DS-13.5.B (locked 2026-05-01).** Pre-1.0 break: returns\n * {@link TimeoutBundle} with `node` + `timeoutState` companion. Opts\n * accept `Partial<TimeoutOptions>` or `Node<Partial<TimeoutOptions>>`\n * (object-shape, replacing the old `NodeOrValue<number>` flat shape).\n * State preservation across rebind: `ns` change does NOT reset the\n * in-flight deadline — new `ns` applies to next attempt only.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\tmonotonicNs,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport { isNode, operatorOpts } from \"./_internal.js\";\nimport { NS_PER_MS } from \"./backoff.js\";\n\n/**\n * Thrown by {@link withTimeout} 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\n/**\n * Options accepted by {@link withTimeout}.\n *\n * - `ns` — deadline in nanoseconds (must be `> 0`). Required at the\n * first opts settle; missing / non-positive values throw at\n * construction.\n * - `meta` — optional metadata merged onto the result node's `meta`\n * for describe()/explain() introspection. Reactive `meta` updates\n * are picked up on the next attempt's emission.\n *\n * @category extra/resilience\n */\nexport interface TimeoutOptions {\n\tns: number;\n\tmeta?: Record<string, unknown>;\n}\n\n/**\n * Lifecycle-shaped state companion emitted by {@link withTimeout}.\n *\n * Default `equals` dedups on the `status` field — subscribers don't\n * re-fire on identical-shape transitions, but DO fire on every state\n * transition AND on payload changes within the same status (e.g. when\n * `running.startedAt_ns` advances on a fresh attempt).\n *\n * @category extra/resilience\n */\nexport type TimeoutState =\n\t| { status: \"pending\" }\n\t| { status: \"running\"; startedAt_ns: number; deadline_ns: number }\n\t| { status: \"completed\"; settledAt_ns: number }\n\t| { status: \"errored\"; firedAt_ns: number; deadline_ns: number };\n\n/**\n * Bundle returned by {@link withTimeout}: the timeout-wrapped output node and\n * its lifecycle-shaped state companion.\n *\n * **Single-subscriber / pipeline-only contract (DS-13.5.B QA, N1, 2026-05-03).**\n * The `timeoutState` companion is allocated once at factory time and shared\n * across all subscribers to `node`. With one subscriber (the typical use\n * case — wire `node` into your downstream chain, optionally observe\n * `timeoutState` separately) the companion reflects a coherent timeline.\n * With **two or more subscribers** to `node`, each subscriber re-runs the\n * producer body and writes into the same `timeoutState`, which can flip\n * between states from different in-flight machines. Don't fan out\n * `node` to multiple subscribers and rely on `timeoutState` accuracy\n * unless you use {@link keepalive} / {@link share}-style consolidation.\n *\n * @category extra/resilience\n */\nexport interface TimeoutBundle<T> {\n\tnode: Node<T>;\n\ttimeoutState: Node<TimeoutState>;\n}\n\ninterface TimeoutExtraOpts {\n\tmeta?: Record<string, unknown>;\n}\n\n/**\n * Wrap `source` with a deadline. If no `DATA` arrives within `opts.ns`\n * nanoseconds, the result node emits `[[ERROR, TimeoutError]]` and\n * transitions `timeoutState` to `\"errored\"`.\n *\n * The timer starts on subscription and resets on each `DATA`. `DIRTY`\n * does NOT reset the timer. Terminal messages (`COMPLETE` / `ERROR`)\n * cancel the timer.\n *\n * **Reactive opts (DS-13.5.B, locked 2026-05-01).**\n *\n * - Static-form callers pass `Partial<TimeoutOptions>` (today's path).\n * `ns` is validated at construction; missing / non-positive throws\n * `RangeError`.\n * - Reactive-form callers pass `Node<Partial<TimeoutOptions>>` — each\n * emission shallow-merges over the prior opts. Empty `{}` emissions\n * are no-ops (no rebind, no companion fire). Mid-flight opts swap\n * does NOT reset the in-flight deadline; new `ns` applies to the\n * next `startTimer()` call.\n * - When the opts Node has `cache === undefined` (SENTINEL: no opts\n * emitted yet), the source is paused until the first valid opts\n * settle. The first valid settle must carry `ns > 0` or the timer\n * layer emits an ERROR (downstream observable) — distinct from the\n * construction-time `RangeError` thrown for static / cache-defined\n * invalid values.\n *\n * @param source - Upstream node.\n * @param opts - `Partial<TimeoutOptions>` (static) or\n * `Node<Partial<TimeoutOptions>>` (reactive).\n * @param extraOpts - Forwarded factory metadata (meta field merged\n * onto the result node).\n * @returns {@link TimeoutBundle} with `node` and `timeoutState`.\n *\n * @throws {RangeError} when the first opts settle is missing or has\n * non-positive `ns`.\n *\n * @category extra\n */\nexport function withTimeout<T>(\n\tsource: Node<T>,\n\topts: Partial<TimeoutOptions> | Node<Partial<TimeoutOptions>>,\n\textraOpts?: TimeoutExtraOpts,\n): TimeoutBundle<T> {\n\tconst isReactive = isNode(opts);\n\n\t// Construction-time validation:\n\t// - Static form: validate the supplied object eagerly.\n\t// - Node form with defined cache: validate the cache value eagerly.\n\t// - Node form with `cache === undefined`: defer validation to first\n\t// DATA emission; source is paused in the meantime.\n\tlet latestOpts: TimeoutOptions | null = null;\n\tif (!isReactive) {\n\t\tconst staticOpts = opts as Partial<TimeoutOptions>;\n\t\tif (\n\t\t\tstaticOpts.ns === undefined ||\n\t\t\ttypeof staticOpts.ns !== \"number\" ||\n\t\t\t!Number.isFinite(staticOpts.ns) ||\n\t\t\tstaticOpts.ns <= 0\n\t\t) {\n\t\t\tthrow new RangeError(\"withTimeout: opts.ns must be a positive finite number\");\n\t\t}\n\t\tlatestOpts = {\n\t\t\tns: staticOpts.ns,\n\t\t\t...(staticOpts.meta != null ? { meta: staticOpts.meta } : {}),\n\t\t};\n\t} else {\n\t\tconst cached = (opts as Node<Partial<TimeoutOptions>>).cache as\n\t\t\t| Partial<TimeoutOptions>\n\t\t\t| undefined;\n\t\tif (cached !== undefined) {\n\t\t\tif (\n\t\t\t\tcached.ns === undefined ||\n\t\t\t\ttypeof cached.ns !== \"number\" ||\n\t\t\t\t!Number.isFinite(cached.ns) ||\n\t\t\t\tcached.ns <= 0\n\t\t\t) {\n\t\t\t\tthrow new RangeError(\n\t\t\t\t\t\"withTimeout: opts.ns must be a positive finite number on first settle\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tlatestOpts = {\n\t\t\t\tns: cached.ns,\n\t\t\t\t...(cached.meta != null ? { meta: cached.meta } : {}),\n\t\t\t};\n\t\t}\n\t}\n\n\tconst callerMeta = extraOpts?.meta;\n\tconst factoryArgs: Record<string, unknown> = isReactive\n\t\t? { ns: \"Node<Partial<TimeoutOptions>>\" }\n\t\t: { ns: latestOpts!.ns };\n\n\t// Companion state node — lifecycle-shaped. Default Object.is-on-status\n\t// dedup so identical-shape transitions don't re-fire downstream.\n\tconst timeoutState = node<TimeoutState>([], {\n\t\tname: \"timeoutState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: { status: \"pending\" },\n\t\tequals: (a, b) =>\n\t\t\ta === b ||\n\t\t\t(a != null &&\n\t\t\t\tb != null &&\n\t\t\t\ttypeof a === \"object\" &&\n\t\t\t\ttypeof b === \"object\" &&\n\t\t\t\t(a as { status: string }).status === (b as { status: string }).status &&\n\t\t\t\tJSON.stringify(a) === JSON.stringify(b)),\n\t});\n\n\tconst out = node<T>(\n\t\t(_data, a) => {\n\t\t\tlet stopped = false;\n\t\t\tlet lastDeadlineNs = 0;\n\t\t\tconst timer = new ResettableTimer();\n\t\t\tlet optsUnsub: (() => void) | null = null;\n\t\t\tlet srcUnsub: (() => void) | null = null;\n\n\t\t\tfunction emitState(next: TimeoutState): void {\n\t\t\t\ttimeoutState.down([[DIRTY], [DATA, next]]);\n\t\t\t}\n\n\t\t\tfunction startTimer(): void {\n\t\t\t\tif (stopped) return;\n\t\t\t\t// QA A4 (2026-05-03): defensive guard — `latestOpts.ns`\n\t\t\t\t// reaching `undefined` / `NaN` / non-finite is a Class-of-\n\t\t\t\t// bugs source: an explicit `{ ns: undefined }` emit would\n\t\t\t\t// pass the per-key validation (which only checks\n\t\t\t\t// `next.ns !== undefined`) and shallow-merge over a valid\n\t\t\t\t// prior `ns`. Without this guard, `delayMs = NaN`, which\n\t\t\t\t// `setTimeout` treats as `0` → spurious immediate timeout.\n\t\t\t\tif (\n\t\t\t\t\tlatestOpts == null ||\n\t\t\t\t\ttypeof latestOpts.ns !== \"number\" ||\n\t\t\t\t\t!Number.isFinite(latestOpts.ns) ||\n\t\t\t\t\tlatestOpts.ns <= 0\n\t\t\t\t) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst ns = latestOpts.ns;\n\t\t\t\tlastDeadlineNs = ns;\n\t\t\t\tconst startedAt = monotonicNs();\n\t\t\t\tconst delayMs = ns / NS_PER_MS;\n\t\t\t\temitState({\n\t\t\t\t\tstatus: \"running\",\n\t\t\t\t\tstartedAt_ns: startedAt,\n\t\t\t\t\tdeadline_ns: ns,\n\t\t\t\t});\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\tsrcUnsub?.();\n\t\t\t\t\temitState({\n\t\t\t\t\t\tstatus: \"errored\",\n\t\t\t\t\t\tfiredAt_ns: monotonicNs(),\n\t\t\t\t\t\tdeadline_ns: ns,\n\t\t\t\t\t});\n\t\t\t\t\ta.down([[ERROR, new TimeoutError(ns)]]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfunction attachSource(): void {\n\t\t\t\tif (srcUnsub != null || stopped) return;\n\t\t\t\tsrcUnsub = source.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (stopped) return;\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\tstartTimer();\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\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\temitState({\n\t\t\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\t\t\tsettledAt_ns: monotonicNs(),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\temitState({\n\t\t\t\t\t\t\t\tstatus: \"errored\",\n\t\t\t\t\t\t\t\tfiredAt_ns: monotonicNs(),\n\t\t\t\t\t\t\t\tdeadline_ns: lastDeadlineNs,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\ta.down([m]);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t} else if (t === TEARDOWN) {\n\t\t\t\t\t\t\ttimer.cancel();\n\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\ta.down([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\t// Kick the initial timer if we already have valid opts.\n\t\t\t\tif (latestOpts != null && latestOpts.ns > 0) {\n\t\t\t\t\tstartTimer();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isReactive) {\n\t\t\t\tconst optsNode = opts as Node<Partial<TimeoutOptions>>;\n\t\t\t\toptsUnsub = optsNode.subscribe((msgs) => {\n\t\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\t\tif (m[0] !== DATA) continue;\n\t\t\t\t\t\tconst next = m[1] as Partial<TimeoutOptions>;\n\t\t\t\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\t\t\t\t// Empty `{}` emit is a no-op (lock spec).\n\t\t\t\t\t\tconst keys = Object.keys(next);\n\t\t\t\t\t\tif (keys.length === 0) continue;\n\t\t\t\t\t\t// QA A4 (2026-05-03): validate ns whenever it APPEARS\n\t\t\t\t\t\t// in the emit's keys — including `{ ns: undefined }`,\n\t\t\t\t\t\t// which would otherwise skip validation and shallow-\n\t\t\t\t\t\t// merge over a valid prior `ns` with `undefined`,\n\t\t\t\t\t\t// producing `delayMs = NaN` ≈ 0 ms in startTimer().\n\t\t\t\t\t\t// `'ns' in next` covers both \"explicitly undefined\"\n\t\t\t\t\t\t// and \"explicitly invalid\" forms.\n\t\t\t\t\t\tif (\"ns\" in next) {\n\t\t\t\t\t\t\tif (typeof next.ns !== \"number\" || !Number.isFinite(next.ns) || next.ns <= 0) {\n\t\t\t\t\t\t\t\tif (latestOpts == null) {\n\t\t\t\t\t\t\t\t\t// First settle invalid — emit ERROR rather\n\t\t\t\t\t\t\t\t\t// than throw (mid-subscribe; sync throw\n\t\t\t\t\t\t\t\t\t// would corrupt the host scheduler).\n\t\t\t\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\t\t\t\ta.down([\n\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\tERROR,\n\t\t\t\t\t\t\t\t\t\t\tnew RangeError(\n\t\t\t\t\t\t\t\t\t\t\t\t\"withTimeout: opts.ns must be a positive finite number on first settle\",\n\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t]);\n\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Ignore invalid mid-flight ns updates; keep\n\t\t\t\t\t\t\t\t// prior latestOpts.\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst wasNull = latestOpts == null;\n\t\t\t\t\t\tlatestOpts = {\n\t\t\t\t\t\t\t...(latestOpts ?? { ns: 0 }),\n\t\t\t\t\t\t\t...next,\n\t\t\t\t\t\t} as TimeoutOptions;\n\t\t\t\t\t\t// First valid settle activates the source attach.\n\t\t\t\t\t\tif (wasNull && latestOpts.ns > 0) {\n\t\t\t\t\t\t\tattachSource();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Static form: attach immediately. Reactive form with defined\n\t\t\t// cache also attaches immediately (latestOpts pre-populated).\n\t\t\tif (latestOpts != null) {\n\t\t\t\tattachSource();\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tstopped = true;\n\t\t\t\t\ttimer.cancel();\n\t\t\t\t\tif (srcUnsub) srcUnsub();\n\t\t\t\t\tif (optsUnsub) optsUnsub();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t\tmeta: { ...(callerMeta ?? {}), ...factoryTag(\"withTimeout\", factoryArgs) },\n\t\t},\n\t);\n\n\treturn { node: out, timeoutState };\n}\n","/**\n * Base layer — domain-agnostic infrastructure.\n *\n * Exports: io, composition, mutation, worker, render, meta, sources, utils.\n *\n * Node-only subpath: @graphrefly/graphrefly/base/sources/node\n * Browser-only subpath: @graphrefly/graphrefly/base/sources/browser\n *\n * @module\n */\n\nexport * from \"./composition/index.js\";\nexport * from \"./io/index.js\";\nexport * from \"./meta/index.js\";\nexport * from \"./mutation/index.js\";\nexport * from \"./render/index.js\";\nexport * from \"./sources/index.js\";\nexport * from \"./utils/index.js\";\nexport * from \"./worker/index.js\";\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 \"@graphrefly/pure-ts/core\";\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 * Budget-constrained reactive memory composition (roadmap §3.2b).\n *\n * Moved to base/composition/distill.ts during cleave A2.\n */\n\nimport { batch, factoryTag, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport {\n\tfromAny,\n\ttype NodeInput,\n\ttype ReactiveMapBundle,\n\ttype ReactiveMapOptions,\n\treactiveMap,\n\tswitchMap,\n\twithLatestFrom,\n} from \"@graphrefly/pure-ts/extra\";\nimport { forEach } from \"../sources/async.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\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\n/**\n * Defensive snapshot → ReadonlyMap coercion (D2 /qa lock, Tier 9.1).\n *\n * `ReactiveMapBundle.entries` always emits a real `Map` on the live emit\n * path. The non-Map case happens on snapshot **restore**: the default\n * `JsonGraphCodec` serializes a `Map` to `null`/`{}`/`[]` depending on the\n * codec configuration, and `Graph.restore` writes that decoded value back\n * to the cache. A naive `(snapshot as ReadonlyMap) ?? new Map()` would\n * pass a plain object through and then `.entries()` / `.size` access would\n * silently yield wrong results (or throw). The runtime `instanceof Map`\n * check below restores the safety net the previous `mapFromSnapshot` helper\n * provided before its initial deletion in Tier 10.1.\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 *\n * **Tier 1.5.4 (Session A.5 lock, 2026-04-27):** `extractFn` receives the\n * source and existing-store as `Node`s. Distill calls `extractFn` ONCE at\n * wiring time and consumes the returned stream of extractions. The user\n * controls reactive composition — wrap with `switchMap` for cancel-on-new-input,\n * `mergeMap` for parallel, `derived` for sync transforms. See COMPOSITION-GUIDE\n * §40 for the recipe.\n */\nexport function distill<TRaw, TMem>(\n\tsource: NodeInput<TRaw>,\n\textractFn: (\n\t\traw: Node<TRaw>,\n\t\texisting: Node<ReadonlyMap<string, TMem>>,\n\t) => 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) : node<unknown>([], { initial: null });\n\n\t// `latestStore` (formerly a §28 closure-mirror) is no longer needed —\n\t// Phase 10.5 (`withLatestFrom` flipped to `partial: false`) fixed the\n\t// W1 initial-pair drop. `consolidate` now uses\n\t// `withLatestFrom(trigger, store.entries)` below to pair each trigger\n\t// with the latest store snapshot via a real reactive edge (visible in\n\t// `describe()`). The `mapFromSnapshot` transform runs inside the\n\t// switchMap fn body.\n\n\t// Tier 1.5.4: one-shot wire. User's `extractFn` returns the reactive\n\t// extraction stream — distill just `forEach`s and applies. No internal\n\t// switchMap; user picks the cancellation / queueing semantics.\n\tconst extractionStream = fromAny(\n\t\textractFn(sourceNode, store.entries as Node<ReadonlyMap<string, TMem>>),\n\t);\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 = node<string[]>(\n\t\t\t[store.entries],\n\t\t\t(batchData, actions, ctx) => {\n\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\tconst snapshot = batch0 != null && batch0.length > 0 ? batch0.at(-1) : ctx.prevData[0];\n\t\t\t\tconst out: string[] = [];\n\t\t\t\tconst entries = mapFromSnapshot<TMem>(snapshot);\n\t\t\t\t// Clean up verdict subscriptions for removed keys.\n\t\t\t\tfor (const key of verdictUnsubs.keys()) {\n\t\t\t\t\tif (!entries.has(key)) {\n\t\t\t\t\t\tverdictUnsubs.get(key)!();\n\t\t\t\t\t\tverdictUnsubs.delete(key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor (const [key, mem] of entries) {\n\t\t\t\t\tconst verdict = opts.evict!(key, mem);\n\t\t\t\t\tif (isNodeLike<boolean>(verdict)) {\n\t\t\t\t\t\t// Subscribe if not already — push-on-subscribe fires with\n\t\t\t\t\t\t// the verdict's current value on first subscribe, so an\n\t\t\t\t\t\t// already-true verdict deletes via the callback without\n\t\t\t\t\t\t// needing a `verdict.cache` read (closes P3 audit #3).\n\t\t\t\t\t\t// Future transitions to `true` flow through the same path.\n\t\t\t\t\t\tif (!verdictUnsubs.has(key)) {\n\t\t\t\t\t\t\tconst unsub = forEach(verdict, (val) => {\n\t\t\t\t\t\t\t\tif (val === true && store.has(key)) {\n\t\t\t\t\t\t\t\t\tstore.delete(key);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tverdictUnsubs.set(key, unsub);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof verdict === \"boolean\") {\n\t\t\t\t\t\tif (verdict) out.push(key);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tthrow new TypeError(\"distill evict() must return boolean or Node<boolean>\");\n\t\t\t\t}\n\t\t\t\tactions.emit(out);\n\t\t\t},\n\t\t\t{ describeKind: \"derived\" },\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 consolidatePaired = withLatestFrom(\n\t\t\tconsolidateTriggerNode,\n\t\t\tstore.entries as Node<unknown>,\n\t\t);\n\t\tconst consolidationStream = switchMap(consolidatePaired, ([, entries]) =>\n\t\t\topts.consolidate!(mapFromSnapshot<TMem>(entries)),\n\t\t);\n\t\tforEach(consolidationStream, (extraction) => {\n\t\t\tapplyExtraction(store, extraction);\n\t\t});\n\t}\n\n\tconst compact = node<Array<{ key: string; value: TMem; score: number }>>(\n\t\t[store.entries, contextNode],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst data = batchData.map((batch, i) =>\n\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t);\n\t\t\tconst snapshot = data[0];\n\t\t\tconst context = data[1];\n\t\t\tconst map = mapFromSnapshot<TMem>(snapshot);\n\t\t\tconst entries = [...map.entries()].map(([key, value]) => ({\n\t\t\t\tkey,\n\t\t\t\tvalue,\n\t\t\t\tscore: opts.score(value, context),\n\t\t\t\tcost: opts.cost(value),\n\t\t\t}));\n\t\t\tentries.sort((a, b) => b.score - a.score);\n\n\t\t\tconst packed: Array<{ key: string; value: TMem; score: number }> = [];\n\t\t\tlet remaining = budget;\n\t\t\tfor (const item of entries) {\n\t\t\t\tif (item.cost <= remaining) {\n\t\t\t\t\tpacked.push({ key: item.key, value: item.value, score: item.score });\n\t\t\t\t\tremaining -= item.cost;\n\t\t\t\t}\n\t\t\t}\n\t\t\tactions.emit(packed);\n\t\t},\n\t\t{ describeKind: \"derived\", meta: { ...factoryTag(\"distill\", { budget }) } },\n\t);\n\n\tconst size = node<number>(\n\t\t[store.entries],\n\t\t(batchData, actions, ctx) => {\n\t\t\tconst batch0 = batchData[0];\n\t\t\tconst snapshot = batch0 != null && batch0.length > 0 ? batch0.at(-1) : ctx.prevData[0];\n\t\t\tactions.emit(mapFromSnapshot<TMem>(snapshot).size);\n\t\t},\n\t\t{ describeKind: \"derived\" },\n\t);\n\tkeepalive(compact);\n\tkeepalive(size);\n\n\treturn { store, compact, size };\n}\n","/**\n * Async sources, sinks, and multicast — presentation layer.\n *\n * `fromPromise`, `fromAsyncIter`, `fromAny` are substrate primitives; they are\n * re-exported here from `@graphrefly/pure-ts` for ergonomic single-import use.\n * This file owns the presentation-only async utilities: `defer`, `forEach`,\n * `toArray`, `share`, `replay`, `cached`, `shareReplay`.\n *\n * `singleFromAny` and `singleNodeFromAny` (keyed singleflight) live in\n * `base/composition/single-from-any.ts`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tRESOLVED,\n\tSTART,\n} from \"@graphrefly/pure-ts/core\";\nimport { type AsyncSourceOpts, type NodeInput, sourceOpts } from \"@graphrefly/pure-ts/extra\";\n\n/** Options for presentation-layer async operators: NodeOptions without `describeKind`. */\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\n// Import fromAny from substrate — used internally by defer. The three async\n// substrate sources (fromAny, fromAsyncIter, fromPromise) are already\n// re-exported from @graphrefly/pure-ts; do NOT re-export here to avoid\n// duplicate-export conflicts at the root barrel level.\nimport { fromAny } from \"@graphrefly/pure-ts/extra\";\n\n/**\n * Lazily constructs a {@link Node} from a thunk that runs at **activation\n * time** (first subscriber after a teardown to zero sinks), not factory time.\n *\n * **Resubscribable by default.** Diverges from `fromPromise` / `fromIter` /\n * `fromAsyncIter` (which are single-shot — second subscriber sees the cached\n * terminal value). `defer`'s contract matches RxJS `defer`: every fresh\n * activation cycle re-runs the thunk. To opt out and get one-shot semantics,\n * pass `{ resubscribable: false }`.\n *\n * **Sharing across overlapping subscribers.** The thunk only re-runs on a\n * fresh activation cycle (zero → one sink). Overlapping subscribers share\n * the single activation; the thunk does NOT re-run for each subscriber. If\n * the thunk returns an existing `Node`, that Node is shared across activations\n * — `defer` will subscribe to it on each activation but does not isolate state\n * across subscribers. For per-subscriber isolation, the thunk must construct\n * a fresh source (`state(...)`, `fromPromise(fetch(...))`, etc.) on each call.\n *\n * **Use cases:**\n * - Lazy upstream construction (avoid eager evaluation of expensive factories\n * at module load — the thunk runs only when something subscribes).\n * - Per-activation resource construction (open a connection / file handle on\n * subscribe, when paired with full teardown between sessions).\n * - Bridging non-Node inputs (Promise, AsyncIterable, Iterable, scalar) into\n * the graph behind a lazy boundary.\n *\n * The thunk's return value is bridged via {@link fromAny}. Errors thrown by\n * the thunk surface as a single `[[ERROR, err]]` on the output (with `err`\n * coerced to a non-`undefined` value to satisfy spec §1.3 — bare `throw` and\n * `throw undefined` are wrapped in a `defer: thunk threw undefined` Error).\n *\n * Upstream messages are forwarded transparently (DIRTY / DATA / RESOLVED /\n * COMPLETE / ERROR / INVALIDATE / PAUSE / RESUME / TEARDOWN), preserving\n * batch boundaries. The producer's own `START` handshake is delivered to\n * subscribers automatically; the upstream's `START` is filtered.\n *\n * @param thunk - Called on each activation; returns the upstream input.\n * @param opts - Forwarded to `fromAny` (e.g. `signal` for async inputs).\n * `signal` is only consumed by `fromAny` for async input shapes (Promise,\n * AsyncIterable); it does NOT abort a Node-input or scalar-input defer.\n * @returns `Node<T>` — lazy upstream-on-activation.\n *\n * @example\n * ```ts\n * import { defer } from \"@graphrefly/graphrefly-ts\";\n *\n * // Lazy fetch — runs on the first activation, NOT at factory time.\n * // Each fresh activation cycle (after teardown) re-runs the thunk →\n * // a new fetch. Overlapping subscribers share the single activation.\n * const live = defer(() => fetch(\"/api/feed\").then((r) => r.json()));\n * ```\n *\n * @category extra\n */\nexport function defer<T>(thunk: () => NodeInput<T>, opts?: AsyncSourceOpts): Node<T> {\n\t// A4: strip `signal` before forwarding to NodeOptions — sibling sources\n\t// (fromTimer / fromPromise / fromAsyncIter) destructure first; signal\n\t// continues to flow into fromAny(input, opts) for async input shapes.\n\tconst { signal: _sig, ...nodeOpts } = (opts ?? {}) as AsyncSourceOpts;\n\tconst sOpts = sourceOpts<T>(nodeOpts);\n\tconst merged = sOpts.resubscribable === undefined ? { ...sOpts, resubscribable: true } : sOpts;\n\treturn node<T>((_data, a) => {\n\t\tlet unsub: (() => void) | undefined;\n\t\tlet stopped = false;\n\t\ttry {\n\t\t\tconst input = thunk();\n\t\t\t// `iter: true` preserves defer's RxJS-aligned per-element\n\t\t\t// streaming for sync iterable thunk returns (post DS-13.5\n\t\t\t// fromAny default flip; defer's documented contract is\n\t\t\t// \"forwards iterable values\" per-element).\n\t\t\tconst src = fromAny(input, { ...opts, iter: true });\n\t\t\tunsub = src.subscribe((msgs) => {\n\t\t\t\tif (stopped) return;\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 === START) continue; // producer's own START is delivered separately\n\t\t\t\t\tif (t === DATA) {\n\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t} else if (t === COMPLETE) {\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t\tbreak; // A2: don't forward post-terminal messages in the same batch\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tstopped = true;\n\t\t\t\t\t\ta.down([[ERROR, m[1]]]);\n\t\t\t\t\t\tbreak; // A2\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Forward DIRTY / RESOLVED / INVALIDATE / PAUSE / RESUME /\n\t\t\t\t\t\t// TEARDOWN, plus any unknown types (spec §1.3.6 forward-compat).\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} catch (err) {\n\t\t\t// A5: spec §1.3 — ERROR payload must not be undefined. Wrap a\n\t\t\t// `throw` or `throw undefined` so dispatch doesn't reject the emit.\n\t\t\tconst safe = err === undefined ? new Error(\"defer: thunk threw undefined\") : err;\n\t\t\ta.down([[ERROR, safe]]);\n\t\t}\n\t\treturn {\n\t\t\tonDeactivation: () => {\n\t\t\t\tstopped = true;\n\t\t\t\tunsub?.();\n\t\t\t},\n\t\t};\n\t}, merged);\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\t// Lock 6.D (Phase 13.6.B): clear the accumulator buffer on\n\t// deactivation so a resubscribable toArray restarts with an empty\n\t// array on the next cycle — pre-flip this came for free via\n\t// `_deactivate`'s store wipe.\n\tlet cleanup: { onDeactivation: () => void } | undefined;\n\treturn node<T[]>(\n\t\t[source as Node],\n\t\t(data, actions, ctx) => {\n\t\t\tif (cleanup === undefined) {\n\t\t\t\tconst store = ctx.store;\n\t\t\t\tcleanup = {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tdelete store.buf;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\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 cleanup;\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\treturn cleanup;\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 node<T>(\n\t\t(_data, a) => ({\n\t\t\tonDeactivation: source.subscribe((msgs) => {\n\t\t\t\ta.down(msgs);\n\t\t\t}),\n\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\t// Spec §2.5 / Lock 6.G: the built-in `replayBuffer` NodeOption retains the\n\t// last-N outgoing DATA and `defaultOnSubscribe` delivers them to a late\n\t// subscriber INSTEAD of the cache-DATA push — so there is no double-deliver\n\t// of the most-recent value. Supersedes the old `wrapSubscribeHook` +\n\t// manual-buffer pattern (which flushed the buffer AND then push-on-\n\t// subscribed the cache, double-delivering the last value).\n\treturn node<T>(\n\t\t(_data, a) => ({\n\t\t\tonDeactivation: source.subscribe((msgs) => {\n\t\t\t\ta.down(msgs);\n\t\t\t}),\n\t\t}),\n\t\t{ ...sourceOpts<T>(opts), initial: source.cache, replayBuffer: bufferSize },\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// 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 * 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 {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n} from \"@graphrefly/pure-ts/core\";\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 node<T>((_data, 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\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tonDeactivation: () => {\n\t\t\t\tactive = false;\n\t\t\t\ttry {\n\t\t\t\t\tcleanup?.();\n\t\t\t\t} catch {\n\t\t\t\t\t/* registrar cleanup failure is not a reactive signal */\n\t\t\t\t}\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 = node<TChannels[typeof ch]>(\n\t\t\t(_data, _a) => {\n\t\t\t\tactivatedCount++;\n\t\t\t\treturn {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tteardownCount++;\n\t\t\t\t\t\t// Cleanup fires once every channel has activated at least once\n\t\t\t\t\t\t// and then deactivated. Channels that never subscribe do not\n\t\t\t\t\t\t// gate cleanup — use the explicit `.dispose()` method for\n\t\t\t\t\t\t// unconditional teardown.\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tactivatedCount > 0 &&\n\t\t\t\t\t\t\tteardownCount >= activatedCount &&\n\t\t\t\t\t\t\tteardownCount >= channels.length\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tfinishCleanup();\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\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 * Phase 13.C — `selector` + `materialize` composers (DS-13.C / G2 lock C).\n *\n * Two paired primitives for dynamic-mount routing:\n *\n * - {@link selector} — projects an input value to a routing key, deduped.\n * Equivalent to `map + distinctUntilChanged`, but the dedup is the\n * semantic point: the key changes ONLY when the routed-to slot should\n * change. Fires `materialize` re-mounts efficiently.\n *\n * - {@link materialize} — given a reactive `key` and a reactive map of\n * `key → factory` thunks, mounts the matching factory's Graph under\n * `parent` at a stable slot name. When `key` changes, unmounts the old\n * slot and mounts the new factory's output. When `factories` mutates but\n * `key` stays the same, the current slot continues to run on the OLD\n * factory (\"current sessions complete on old factory; new sessions use\n * new factory\" — full hot-swap correctness deferred to G10, parked).\n *\n * Reusable beyond the agent layer:\n * - `harnessLoop` strategy routing — the strategy node IS a `selector`.\n * - `pipelineGraph` dynamic stage selection.\n * - `refineLoop` strategy swap.\n * - Phase 13.I `spawnable()` mounts agent slots via `materialize`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\tfactoryTag,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport type { Graph } from \"@graphrefly/pure-ts/graph\";\n\n/** Options for operator nodes: NodeOptions without `describeKind` (set internally). */\nexport type 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// selector\n// ---------------------------------------------------------------------------\n\n/** Options for {@link selector}. */\nexport type SelectorOpts<TKey> = ExtraOpts & {\n\t/**\n\t * Equality comparator for the projected key. Defaults to {@link Object.is}.\n\t * Used to suppress re-emits when the input changes but the projected key\n\t * does not — this is the load-bearing behavior that lets downstream\n\t * `materialize` skip unnecessary unmount/remount cycles.\n\t */\n\tequals?: (a: TKey, b: TKey) => boolean;\n};\n\n/**\n * Projects each upstream value to a routing key, deduped on the key. The\n * output node emits a key only when the projected key actually changes —\n * pairs cleanly with {@link materialize}, which re-mounts only on key\n * change.\n *\n * **Differs from `map`:** `map(input, fn)` fires on every upstream wave\n * regardless of output value. `selector(input, fn)` fires only when the\n * projected key CHANGES (under `equals`), so downstream re-mount logic is\n * stable.\n *\n * @param input - Upstream node carrying the value to project.\n * @param fn - Synchronous projection function.\n * @param opts - Optional {@link SelectorOpts}.\n * @returns `Node<TKey>` carrying the latest projected key (deduped).\n *\n * @example\n * ```ts\n * import { selector, materialize, state } from \"@graphrefly/graphrefly-ts\";\n *\n * type Request = { kind: \"research\" | \"summarize\" | \"code\"; payload: unknown };\n * const requestNode = state<Request>({ kind: \"research\", payload: {} });\n *\n * const presetId = selector(requestNode, (req) => req.kind);\n * // presetId is `Node<\"research\" | \"summarize\" | \"code\">`, deduped.\n * // Downstream materialize re-mounts ONLY when the kind axis changes.\n * ```\n *\n * @category extra\n */\nexport function selector<TIn, TKey>(\n\tinput: Node<TIn>,\n\tfn: (input: TIn) => TKey,\n\topts?: SelectorOpts<TKey>,\n): Node<TKey> {\n\tconst equals = opts?.equals ?? Object.is;\n\t// Lock 6.D (Phase 13.6.B): clear prev/hasPrev on deactivation so a\n\t// resubscribable selector doesn't dedupe the next cycle's first\n\t// projected key against a stale prev from the prior cycle.\n\tlet cleanup: { onDeactivation: () => void } | undefined;\n\treturn node<TKey>(\n\t\t[input as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (cleanup === undefined) {\n\t\t\t\tconst store = ctx.store;\n\t\t\t\tcleanup = {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tdelete store.prev;\n\t\t\t\t\t\tdelete store.hasPrev;\n\t\t\t\t\t},\n\t\t\t\t};\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 cleanup;\n\t\t\t}\n\t\t\t// A11 (QA fix 2026-05-01): pre-pass — compute every projected\n\t\t\t// key + dedup decision FIRST, surface any user `equals` throw\n\t\t\t// as ERROR before any DATA goes out. The previous in-loop\n\t\t\t// emission interleaved partial DATA with ERROR mid-batch; that\n\t\t\t// left subscribers inconsistent (some had read the early DATA,\n\t\t\t// some treated ERROR as \"discard everything since RESOLVED\")\n\t\t\t// and left `ctx.store.prev` mutated to the last successful key,\n\t\t\t// which made selector \"stuck\" until the next throw-free batch.\n\t\t\tconst toEmit: TKey[] = [];\n\t\t\tlet prev: TKey | undefined = ctx.store.hasPrev ? (ctx.store.prev as TKey) : undefined;\n\t\t\tlet hasPrev = ctx.store.hasPrev;\n\t\t\tfor (const v of batch0 as TIn[]) {\n\t\t\t\tconst key = fn(v);\n\t\t\t\tif (hasPrev) {\n\t\t\t\t\tlet same: boolean;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tsame = equals(prev as TKey, key);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t// Pre-pass throw — abandon the whole batch (no DATA emits)\n\t\t\t\t\t\t// and surface ERROR. ctx.store stays at its pre-batch\n\t\t\t\t\t\t// state so the next batch starts from a known-good prev.\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\tif (same) continue;\n\t\t\t\t}\n\t\t\t\tprev = key;\n\t\t\t\thasPrev = true;\n\t\t\t\ttoEmit.push(key);\n\t\t\t}\n\t\t\tif (toEmit.length === 0) {\n\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\treturn cleanup;\n\t\t\t}\n\t\t\tctx.store.prev = prev as TKey;\n\t\t\tctx.store.hasPrev = true;\n\t\t\tfor (const k of toEmit) a.emit(k);\n\t\t\treturn cleanup;\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tmeta: { ...factoryTag(\"selector\"), ...(opts?.meta ?? {}) },\n\t\t},\n\t);\n}\n\n// ---------------------------------------------------------------------------\n// materialize\n// ---------------------------------------------------------------------------\n\n/**\n * Factory thunk for a {@link materialize} slot. Called once per mount cycle\n * to mint a fresh `TGraph` instance. The instance is mounted under\n * `parent.mount(slotName, ...)` and unmounted via `parent.remove(slotName)`\n * when `key` next changes.\n *\n * Each invocation MUST return a fresh, never-before-mounted Graph instance —\n * `Graph.mount` rejects re-mounting an instance that is already mounted\n * elsewhere in the tree. Caching factory output is unsafe.\n */\nexport type GraphFactory<TGraph extends Graph> = () => TGraph;\n\n/** Options for {@link materialize}. */\nexport type MaterializeOpts = ExtraOpts & {\n\t/**\n\t * Local mount name on the parent graph. Default `\"materialized\"`.\n\t *\n\t * Two materialize calls on the SAME parent must use distinct `slotName`\n\t * values, otherwise the second mount throws \"mount already exists\".\n\t * For a hub mounting many slots (e.g. {@link spawnable}'s preset\n\t * registry), use `slotName: \\`preset-\\${id}\\`` or similar.\n\t */\n\tslotName?: string;\n};\n\n/**\n * Reactive dynamic mount: mounts the Graph instance for `key` under\n * `parent.mount(slotName, ...)`, and re-mounts when `key` changes.\n *\n * **Lifecycle.** First DATA on `key` triggers a mount: look up\n * `factories.get(key)`, call the factory thunk, mount the result under\n * `parent`. Each subsequent `key` change unmounts the previous slot and\n * mounts the new one. When this materialize node terminates (subscriber\n * teardown, `COMPLETE` from `key`, `Graph.destroy`), the active slot is\n * unmounted via `parent.remove(slotName)`.\n *\n * **Hot-swap policy (G10 deferred).** When `factories` mutates but `key`\n * stays the same, the currently-mounted slot is NOT re-instantiated —\n * \"current sessions complete on old factory; new sessions use new\n * factory.\" Atomic disconnect/reconnect of an in-flight slot to a new\n * factory is parked under G10 (see `optimizations.md` \"G10 atomic\n * registry hot-swap\").\n *\n * **Output.** The returned `Node<TGraph>` emits the currently-mounted\n * Graph reference whenever a mount occurs. Consumers can subscribe to\n * watch slot changes, or read `.cache` for the active mount. SENTINEL\n * (no DATA) when no slot is currently mounted (e.g. `key` has no matching\n * factory).\n *\n * **Spec compliance.**\n * - No polling: mount transitions are reactive on `key` / `factories`.\n * - No raw async: factory invocation is synchronous; if a factory needs\n * async setup, it returns a Graph that handles its own setup internally.\n * - Mount/unmount happens as side-effects inside the reactive `subscribe`\n * handler — sanctioned per spec §5.9 (Graph topology mutations are\n * imperative writes at the system boundary, not in-flight reactive\n * triggers).\n *\n * @param key - Reactive routing key. Re-mounts on each key change (deduped\n * by reference; pair with {@link selector} for projection-based dedup).\n * @param factories - Reactive map of `key → factory thunk`. Factory map\n * mutations don't disturb the active slot until the next key change.\n * @param parent - Graph to mount slots under. The `slotName` (default\n * `\"materialized\"`) must be free on `parent` at construction time.\n * @param opts - Optional {@link MaterializeOpts}.\n * @returns `Node<TGraph>` carrying the active mount.\n *\n * @example\n * ```ts\n * import { materialize, selector, state, Graph } from \"@graphrefly/graphrefly-ts\";\n *\n * const parent = new Graph(\"parent\");\n * const factories = state<ReadonlyMap<string, () => Graph>>(new Map([\n * [\"researcher\", () => new ResearchAgentGraph()],\n * [\"coder\", () => new CoderAgentGraph()],\n * ]));\n * const key = selector(requestNode, (r) => r.kind);\n * const slot = materialize(key, factories, parent, { slotName: \"agent\" });\n * // `slot.cache` is the active agent graph; `parent.node(\"agent::out\")`\n * // resolves into whichever agent is currently mounted.\n * ```\n *\n * @category extra\n */\nexport function materialize<TKey, TGraph extends Graph>(\n\tkey: Node<TKey>,\n\tfactories: Node<ReadonlyMap<TKey, GraphFactory<TGraph>>>,\n\tparent: Graph,\n\topts?: MaterializeOpts,\n): Node<TGraph> {\n\tconst slotName = opts?.slotName ?? \"materialized\";\n\treturn node<TGraph>(\n\t\t(_data, a) => {\n\t\t\tlet currentKey: TKey | undefined;\n\t\t\tlet hasCurrentKey = false;\n\t\t\tlet currentGraph: TGraph | undefined;\n\t\t\tlet latestFactories: ReadonlyMap<TKey, GraphFactory<TGraph>> | undefined;\n\t\t\tlet terminated = false;\n\n\t\t\tfunction unmountCurrent(): void {\n\t\t\t\tif (currentGraph === undefined) return;\n\t\t\t\ttry {\n\t\t\t\t\tparent.remove(slotName);\n\t\t\t\t} catch {\n\t\t\t\t\t// Slot already gone (parent destroyed, or external `remove`).\n\t\t\t\t}\n\t\t\t\tcurrentGraph = undefined;\n\t\t\t}\n\n\t\t\t// Closure mirror for the factories map. Subscribed FIRST so\n\t\t\t// `latestFactories` is populated by the time the first `key` DATA\n\t\t\t// arrives. Same §28 factory-time-seed pattern used elsewhere.\n\t\t\tconst facUnsub = factories.subscribe((msgs) => {\n\t\t\t\tif (terminated) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tlatestFactories = m[1] as ReadonlyMap<TKey, GraphFactory<TGraph>>;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Primary trigger: key DATA drives mount transitions.\n\t\t\tconst keyUnsub = key.subscribe((msgs) => {\n\t\t\t\tif (terminated) return;\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tconst newKey = m[1] as TKey;\n\t\t\t\t\t\tconst keyChanged = !hasCurrentKey || newKey !== currentKey;\n\t\t\t\t\t\tif (keyChanged) {\n\t\t\t\t\t\t\tunmountCurrent();\n\t\t\t\t\t\t\tif (latestFactories !== undefined) {\n\t\t\t\t\t\t\t\tconst factory = latestFactories.get(newKey);\n\t\t\t\t\t\t\t\tif (factory !== undefined) {\n\t\t\t\t\t\t\t\t\tcurrentGraph = factory();\n\t\t\t\t\t\t\t\t\tparent.mount(slotName, currentGraph);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcurrentKey = newKey;\n\t\t\t\t\t\t\thasCurrentKey = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (currentGraph !== undefined) {\n\t\t\t\t\t\t\ta.emit(currentGraph);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ta.down([[RESOLVED]]);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\t\tterminated = true;\n\t\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\t\tterminated = 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\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tterminated = true;\n\t\t\t\t\tkeyUnsub();\n\t\t\t\t\tfacUnsub();\n\t\t\t\t\tunmountCurrent();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(opts),\n\t\t\tmeta: { ...factoryTag(\"materialize\"), slotName, ...(opts?.meta ?? {}) },\n\t\t},\n\t);\n}\n","// ---------------------------------------------------------------------------\n// Observable bridge — reactive interop between GraphReFly nodes and the TC39\n// Observable contract (the well-known `Symbol.observable` / \"@@observable\"\n// method). **Zero runtime dependency on rxjs**: the returned value is a\n// spec-interop observable that rxjs `from()`, Angular, the NestJS compat\n// layer, and any `Symbol.observable` consumer can adopt. Consumers wanting\n// rxjs operators do `from(toObservable(node))`.\n//\n// Usage:\n// import { toObservable } from '@graphrefly/graphrefly/base';\n// import { from } from 'rxjs';\n// const values$ = from(toObservable(myNode)); // Observable<T>\n// const msgs$ = from(toObservable(myNode, { raw: true })); // Observable<Messages>\n// ---------------------------------------------------------------------------\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { COMPLETE, DATA, ERROR, type Messages } from \"@graphrefly/pure-ts/core\";\n\n/** Observer passed to {@link InteropObservable.subscribe}. */\nexport interface InteropObserver<T> {\n\tnext?(value: T): void;\n\terror?(err: unknown): void;\n\tcomplete?(): void;\n\t/** rxjs `Subscriber` sets this; we short-circuit delivery when closed. */\n\tclosed?: boolean;\n}\n\n/** Teardown handle returned by {@link InteropObservable.subscribe}. */\nexport interface InteropSubscription {\n\tunsubscribe(): void;\n}\n\n/**\n * Minimal TC39 Observable. rxjs `from()` (and any `Symbol.observable`\n * consumer) adopts it at runtime via the well-known interop method attached\n * by {@link toObservable}. Pass the result through `from(...)` to get a\n * pipeable rxjs `Observable`.\n */\nexport interface InteropObservable<T> {\n\tsubscribe(observer: InteropObserver<T> | ((value: T) => void)): InteropSubscription;\n}\n\n/** Options for {@link toObservable}. */\nexport type ToObservableOptions = {\n\t/**\n\t * When `true`, emit raw `Messages` batches instead of extracted `DATA`\n\t * values. Terminal batches are still emitted as the final `next()` before\n\t * the error/complete signal.\n\t */\n\traw?: boolean;\n};\n\n// Well-known Observable interop key. Mirrors the rxjs / `symbol-observable`\n// resolution (the global `Symbol.observable` when the runtime or a polyfill\n// provides it, otherwise the `\"@@observable\"` string) so rxjs `from()` adopts\n// our object regardless of polyfill state.\nconst OBSERVABLE_KEY: PropertyKey =\n\t(typeof Symbol === \"function\" && (Symbol as unknown as { observable?: symbol }).observable) ||\n\t\"@@observable\";\n\nfunction normalizeObserver<T>(\n\tobserver: InteropObserver<T> | ((value: T) => void),\n): InteropObserver<T> {\n\treturn typeof observer === \"function\" ? { next: observer } : observer;\n}\n\nfunction makeInterop<T>(\n\tonSubscribe: (observer: InteropObserver<T>) => () => void,\n): InteropObservable<T> {\n\tconst obs: InteropObservable<T> = {\n\t\tsubscribe(rawObserver): InteropSubscription {\n\t\t\tconst observer = normalizeObserver(rawObserver);\n\t\t\tlet closed = false;\n\t\t\tlet teardown: (() => void) | undefined;\n\t\t\tlet teardownPending = false;\n\t\t\tconst runTeardown = (): void => {\n\t\t\t\tif (teardown) teardown();\n\t\t\t\telse teardownPending = true; // sync push-on-subscribe terminal\n\t\t\t};\n\t\t\t// Guarded observer: latch `closed` and auto-unsubscribe the node on\n\t\t\t// terminal. The prior rxjs-backed impl got this from rxjs's\n\t\t\t// `Subscriber` (closed flag + teardown-on-terminal); a plain TC39\n\t\t\t// consumer has no such machinery, so without this a post-terminal\n\t\t\t// node wave would re-fire next/error/complete and the node\n\t\t\t// subscription would leak until a manual unsubscribe(). `closed` is\n\t\t\t// also read by toObservable's per-message loop to short-circuit.\n\t\t\tconst guarded: InteropObserver<T> = {\n\t\t\t\tget closed() {\n\t\t\t\t\treturn closed;\n\t\t\t\t},\n\t\t\t\tnext(value) {\n\t\t\t\t\tif (!closed) observer.next?.(value);\n\t\t\t\t},\n\t\t\t\terror(err) {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobserver.error?.(err);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\trunTeardown();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tcomplete() {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobserver.complete?.();\n\t\t\t\t\t} finally {\n\t\t\t\t\t\trunTeardown();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t\tteardown = onSubscribe(guarded);\n\t\t\tif (teardownPending) teardown(); // terminal fired before assignment\n\t\t\treturn {\n\t\t\t\tunsubscribe() {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\tteardown?.();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t};\n\t// TC39 interop: `x[Symbol.observable]()` returns the observable itself.\n\t(obs as unknown as Record<PropertyKey, unknown>)[OBSERVABLE_KEY] = function (\n\t\tthis: InteropObservable<T>,\n\t) {\n\t\treturn this;\n\t};\n\treturn obs;\n}\n\n/**\n * Bridge a `Node<T>` to a TC39 interop observable (no rxjs dependency).\n *\n * Default mode emits the node's value on each `DATA` message. Maps `ERROR` to\n * `observer.error()` and `COMPLETE` to `observer.complete()`.\n * Protocol-internal signals (DIRTY, RESOLVED, PAUSE, etc.) are skipped.\n *\n * With `{ raw: true }`, emits full `[[Type, Data?], ...]` message batches.\n * The stream terminates on ERROR or COMPLETE (the terminal batch is still\n * emitted as the final `next()` before the error/complete signal).\n *\n * The returned value is a spec-interop observable, **not** a concrete rxjs\n * `Observable`. Wrap with `from(toObservable(node))` for rxjs operators, or\n * use the NestJS compat layer's `toObservable` which returns a real rxjs\n * `Observable`. For graph-level observation, use\n * `toObservable(graph.resolve(path))` or subscribe to `graph.observe()`.\n *\n * Unsubscribing unsubscribes the node.\n */\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions & { raw?: false },\n): InteropObservable<T>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions: ToObservableOptions & { raw: true },\n): InteropObservable<Messages>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions,\n): InteropObservable<T | Messages> {\n\tif (options?.raw) {\n\t\treturn makeInterop<Messages>((observer) => {\n\t\t\treturn node.subscribe((msgs) => {\n\t\t\t\tif (observer.closed) return;\n\t\t\t\tobserver.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\tobserver.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\tobserver.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});\n\t}\n\n\treturn makeInterop<T>((observer) => {\n\t\treturn node.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (observer.closed) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tobserver.next?.(m[1] as T);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tobserver.error?.(m[1]);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tobserver.complete?.();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\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 * `utils/messaging` — built on `TopicGraph` / `SubscriptionGraph` with\n * retention policies, absolute cursor tracking, and per-subscriber state.\n *\n * Presentation layer (base/composition). Moved from pure-ts during cleave A3\n * (no substrate core/graph dependency on pubsub found).\n */\n\nimport { batch, type Node, node, TEARDOWN, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype PubSubChange,\n\ttype PubSubChangePayload,\n\ttype ReactiveLogBundle,\n\treactiveLog,\n} from \"@graphrefly/pure-ts/extra\";\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 * `utils/messaging`, which composes `TopicGraph` under a lazy registry.\n *\n * @category base\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 base\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\t/**\n\t * DS-14 / DS14R2 — opt-in delta companion. When set, the hub appends a\n\t * typed {@link PubSubChange} record in the **same batch frame** as the\n\t * topic emission / teardown (same-wave consistency — subscribers reading\n\t * both a topic and `mutationLog` never see torn state).\n\t *\n\t * Records the locked `PubSubChange` verbs that apply to this last-value\n\t * hub: `publish` (per `publish` / `publishMany`) and `remove` (per\n\t * `removeTopic`). The `ack` verb is a cursor concern of `messagingHub()`\n\t * and does not apply here. **Note:** the locked `publish` payload carries\n\t * `value` only (no topic name) — callers needing per-topic delta\n\t * correlation should embed identity in the value or use `messagingHub()`.\n\t *\n\t * `true` = defaults; object form forwards `maxSize` / `name` to the inner\n\t * `reactiveLog`.\n\t */\n\tmutationLog?: true | { maxSize?: number; name?: string };\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 base\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\t/**\n\t * DS14R2 — present iff `mutationLog` was configured. Append-only log of\n\t * `publish` / `remove` deltas, same-wave-consistent with topic emissions.\n\t */\n\treadonly mutationLog?: ReactiveLogBundle<PubSubChange>;\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 `messagingHub()` in `utils/messaging`.\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\";\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 base\n */\nexport function pubsub(options: PubSubHubOptions = {}): PubSubHub {\n\tconst { backend: userBackend, mutationLog: mutLogOpt } = options;\n\tconst backend: PubSubBackend = userBackend ?? new NativePubSubBackend();\n\tconst nodes = new Map<string, Node<unknown>>();\n\n\t// ── DS14R2 — mutation log companion ──────────────────────────────────────\n\tconst mutLog: ReactiveLogBundle<PubSubChange> | undefined = mutLogOpt\n\t\t? reactiveLog<PubSubChange>(undefined, {\n\t\t\t\tname: mutLogOpt === true ? \"pubsub.mutationLog\" : (mutLogOpt.name ?? \"pubsub.mutationLog\"),\n\t\t\t\tmaxSize: mutLogOpt === true ? undefined : mutLogOpt.maxSize,\n\t\t\t})\n\t\t: undefined;\n\tlet mutVersion = 0;\n\tfunction recordChange(change: PubSubChangePayload): void {\n\t\tif (!mutLog) return;\n\t\tmutLog.append({\n\t\t\tstructure: \"pubsub\",\n\t\t\tversion: ++mutVersion,\n\t\t\tt_ns: wallClockNs(),\n\t\t\tlifecycle: \"data\",\n\t\t\tchange,\n\t\t});\n\t}\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\tif (!mutLog) {\n\t\t\t\tensureTopic(name).emit(value);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// Same-wave: topic emit + change record in one batch frame.\n\t\t\tbatch(() => {\n\t\t\t\tensureTopic(name).emit(value);\n\t\t\t\trecordChange({ kind: \"publish\", value });\n\t\t\t});\n\t\t},\n\n\t\tpublishMany(entries: Iterable<[string, unknown]>): void {\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\trecordChange({ kind: \"publish\", 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\tnodes.delete(name);\n\t\t\tbackend.removeTopic(name);\n\t\t\tif (!mutLog) {\n\t\t\t\tn.down([[TEARDOWN]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tbatch(() => {\n\t\t\t\t// QA P3: record BEFORE TEARDOWN. A subscriber wired to both a\n\t\t\t\t// topic and `mutationLog` that self-detaches on TEARDOWN would\n\t\t\t\t// otherwise miss the `remove` delta (same-wave consistency).\n\t\t\t\trecordChange({ kind: \"remove\", name });\n\t\t\t\tn.down([[TEARDOWN]]);\n\t\t\t});\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\n\t\tmutationLog: mutLog,\n\t};\n}\n","/**\n * `singleFromAny` — keyed promise/Node de-duplication (\"singleflight\").\n *\n * Given a `factory: (key) => NodeInput<T>`, returns a callable that dedupes\n * concurrent invocations sharing the same key — all callers with the same\n * key while a request is in-flight receive the same `Promise<T>`. Once the\n * underlying source settles (DATA, ERROR, or COMPLETE), the cache entry is\n * cleared so the next call re-invokes the factory.\n *\n * This is the classic \"singleflight\" pattern from Go, generalised over the\n * library's `NodeInput<T>` bridge so callers can pass Promise-returning\n * factories, Node-returning factories, or plain value factories with\n * identical semantics.\n *\n * Use cases:\n * - `withReplayCache` cache-miss thundering-herd dedup\n * - Shared HTTP fetches keyed by URL\n * - Expensive compute keyed by request fingerprint\n *\n * @example\n * ```ts\n * const fetchUser = singleFromAny<string, User>((id) => fetch(`/users/${id}`).then(r => r.json()));\n * // Two concurrent callers with id=\"42\" → one underlying fetch, two Promises resolving to the same User.\n * const [a, b] = await Promise.all([fetchUser(\"42\"), fetchUser(\"42\")]);\n * ```\n *\n * @category extra\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { COMPLETE, ERROR } from \"@graphrefly/pure-ts/core\";\n// Import directly from the source sub-files (rather than the `./sources.js`\n// barrel) so the `single-from-any` module is NOT part of any cycle that runs\n// through `extra/sources/index.ts` — eager re-exports through the barrel were\n// observed to leave `firstValueFrom` / `keepalive` unresolved during nested\n// import chains under vite-node.\nimport { fromAny, type NodeInput } from \"@graphrefly/pure-ts/extra\";\nimport { firstValueFrom } from \"../sources/settled.js\";\n\nexport interface SingleFromAnyOptions<K> {\n\t/**\n\t * Convert a typed key into a cache-string. Defaults to `String(key)`, which\n\t * works for primitive keys; callers with object keys should provide a\n\t * stable serializer (e.g., canonical JSON).\n\t */\n\tkeyFn?: (key: K) => string;\n}\n\n/**\n * Dedupe concurrent `factory(key)` invocations. Returns a bound callable.\n *\n * @param factory - Produces a `NodeInput<T>` for each unique key.\n * @param opts - Optional key-stringification.\n * @returns A function `(key: K) => Promise<T>` whose inflight results are shared per key.\n */\nexport function singleFromAny<K, T>(\n\tfactory: (key: K) => NodeInput<T>,\n\topts: SingleFromAnyOptions<K> = {},\n): (key: K) => Promise<T> {\n\tconst keyFn = opts.keyFn ?? ((k: K) => String(k));\n\tconst inFlight = new Map<string, Promise<T>>();\n\n\treturn (key: K): Promise<T> => {\n\t\tconst k = keyFn(key);\n\t\tconst existing = inFlight.get(k);\n\t\tif (existing) return existing;\n\n\t\tconst input = factory(key);\n\n\t\t// Resolve the NodeInput to a Promise<T>. Different input shapes need\n\t\t// different bridges — Promise/Node/AsyncIterable/Iterable/plain value.\n\t\tlet rawPromise: Promise<T>;\n\t\tif (input != null && typeof (input as PromiseLike<T>).then === \"function\") {\n\t\t\trawPromise = Promise.resolve(input as PromiseLike<T>);\n\t\t} else if (\n\t\t\tinput != null &&\n\t\t\ttypeof input === \"object\" &&\n\t\t\t\"subscribe\" in (input as object) &&\n\t\t\t\"cache\" in (input as object)\n\t\t) {\n\t\t\t// Node: bridge via firstValueFrom.\n\t\t\trawPromise = firstValueFrom(input as Node<T>);\n\t\t} else if (\n\t\t\tinput != null &&\n\t\t\ttypeof input === \"object\" &&\n\t\t\tSymbol.asyncIterator in (input as object)\n\t\t) {\n\t\t\t// AsyncIterable — take the first value, then close the iterator so\n\t\t\t// any owned resources (HTTP body, subscription, timer) are released.\n\t\t\trawPromise = (async () => {\n\t\t\t\tconst iter = (input as AsyncIterable<T>)[Symbol.asyncIterator]();\n\t\t\t\ttry {\n\t\t\t\t\tconst { value, done } = await iter.next();\n\t\t\t\t\tif (done) throw new Error(\"singleFromAny: factory returned empty async iterable\");\n\t\t\t\t\treturn value as T;\n\t\t\t\t} finally {\n\t\t\t\t\tawait iter.return?.();\n\t\t\t\t}\n\t\t\t})();\n\t\t} else if (input != null && typeof input === \"object\" && Symbol.iterator in (input as object)) {\n\t\t\t// Iterable — take the first value, close the iterator.\n\t\t\trawPromise = (async () => {\n\t\t\t\tconst iter = (input as Iterable<T>)[Symbol.iterator]();\n\t\t\t\ttry {\n\t\t\t\t\tconst { value, done } = iter.next();\n\t\t\t\t\tif (done) throw new Error(\"singleFromAny: factory returned empty iterable\");\n\t\t\t\t\treturn value as T;\n\t\t\t\t} finally {\n\t\t\t\t\titer.return?.();\n\t\t\t\t}\n\t\t\t})();\n\t\t} else {\n\t\t\t// Plain value.\n\t\t\trawPromise = Promise.resolve(input as T);\n\t\t}\n\n\t\t// Install the cache entry BEFORE attaching `.finally`. Otherwise a\n\t\t// sync-resolved Promise's finally microtask could run before the\n\t\t// `inFlight.set` below, leaving a stale entry installed afterwards.\n\t\t// We wrap in a holder whose reference we capture *before* chaining.\n\t\tlet tracked!: Promise<T>;\n\t\tconst cleanup = (): void => {\n\t\t\tif (inFlight.get(k) === tracked) inFlight.delete(k);\n\t\t};\n\t\ttracked = rawPromise.then(\n\t\t\t(v) => {\n\t\t\t\tcleanup();\n\t\t\t\treturn v;\n\t\t\t},\n\t\t\t(e) => {\n\t\t\t\tcleanup();\n\t\t\t\tthrow e;\n\t\t\t},\n\t\t);\n\t\tinFlight.set(k, tracked);\n\t\treturn tracked;\n\t};\n}\n\n/**\n * Reactive variant: returns a bound callable that hands out `Node<T>` values.\n * All concurrent callers with the same key during an in-flight source share\n * the same Node. When the underlying source **terminally** settles (ERROR\n * or COMPLETE), the Node is removed from the cache so the next call\n * re-invokes `factory`. DATA is NOT terminal — callers subscribing after\n * the first DATA still receive the shared Node (and push-on-subscribe per\n * the spec's cached-DATA contract).\n *\n * Use when downstream wants reactive subscription (not a one-shot Promise).\n *\n * @category extra\n */\nexport function singleNodeFromAny<K, T>(\n\tfactory: (key: K) => NodeInput<T>,\n\topts: SingleFromAnyOptions<K> = {},\n): (key: K) => Node<T> {\n\tconst keyFn = opts.keyFn ?? ((k: K) => String(k));\n\tconst inFlight = new Map<string, Node<T>>();\n\n\treturn (key: K): Node<T> => {\n\t\tconst k = keyFn(key);\n\t\tconst existing = inFlight.get(k);\n\t\tif (existing) return existing;\n\n\t\tconst node = fromAny(factory(key));\n\t\tinFlight.set(k, node);\n\n\t\t// Evict on terminal settle only — ERROR or COMPLETE. DATA is a value\n\t\t// emission, not a lifecycle transition; multi-emitting Nodes should\n\t\t// continue to share across subscribers after the first value.\n\t\tconst unsub = node.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === ERROR || m[0] === COMPLETE) {\n\t\t\t\t\tif (inFlight.get(k) === node) inFlight.delete(k);\n\t\t\t\t\tunsub();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn node;\n\t};\n}\n","/**\n * Settled/signal helpers.\n *\n * Moved from extra/sources/settled.ts during cleave A2.\n * `keepalive` is substrate — it lives at `@graphrefly/pure-ts`\n * (`packages/pure-ts/src/extra/sources/_keepalive.ts`), not here.\n */\n\n/**\n * Settled / signal helpers — boundary primitives for converting reactive\n * sources into Promise/AbortSignal endpoints.\n *\n * - {@link firstValueFrom} / {@link firstWhere} — Promise of the first\n * matching DATA.\n * - {@link awaitSettled} — composition over `firstWhere` + reactive\n * `timeout` from `extra/resilience` (lazy import to avoid a\n * resilience → sources cycle).\n * - {@link nodeSignal} — `Node<boolean>` → `AbortSignal` bridge.\n * - {@link reactiveCounter} — capped counter exposed as a `Node<number>`.\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\tnode,\n} from \"@graphrefly/pure-ts/core\";\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.snapshot, snap => snap.size > 0);\n * ```\n *\n * @param source - Upstream node to observe.\n * @param predicate - Returns `true` for the value to resolve on.\n * @param opts - `{ skipCurrent?: boolean }`. When `skipCurrent: true`, any DATA\n * delivered during the synchronous `subscribe()` call (push-on-subscribe §2.2\n * replay of the cached value) is ignored — the promise resolves only on the\n * next future emission. Useful when the caller wants to await the next\n * settlement event after an imperative action (e.g. `run()` minting a new\n * runVersion, where the currently-cached value belongs to the previous run).\n *\n * @category extra\n */\nexport function firstWhere<T>(\n\tsource: Node<T>,\n\tpredicate: (value: T) => boolean,\n\topts?: { skipCurrent?: boolean; kick?: () => void },\n): Promise<T> {\n\t// Lock 3.A (Phase 13.6.B): subscribe synchronously inside the function\n\t// body — NOT inside the Promise executor. Subscribing inside the\n\t// executor would defer the subscription past any synchronous `kick()`\n\t// the caller fires after the call returns, race-losing the very wave\n\t// the caller wants to observe.\n\t//\n\t// To bridge sync-subscribe with the async Promise contract, we record\n\t// any settlement that fires *before* the Promise constructor runs, and\n\t// the executor immediately resolves/rejects with the recorded value.\n\t// Settlements after the executor runs go straight through resolve/reject.\n\ttype Pending =\n\t\t| { kind: \"data\"; value: T }\n\t\t| { kind: \"error\"; err: unknown }\n\t\t| { kind: \"complete\" };\n\tlet pending: Pending | undefined;\n\tlet resolveFn: ((value: T) => void) | undefined;\n\tlet rejectFn: ((err: unknown) => void) | undefined;\n\tlet settled = false;\n\tlet shouldUnsub = false;\n\tlet unsub: (() => void) | undefined;\n\tlet inInitialSyncPhase = opts?.skipCurrent === true;\n\n\t// QA P1: every settler short-circuits when `settled === true` so a\n\t// later settle attempt (e.g. `kick()` throwing AFTER it synchronously\n\t// fired matching DATA, OR a `[DATA matched, ERROR]` wave during\n\t// push-on-subscribe) cannot overwrite an earlier `pending` outcome.\n\t// Without this gate, a kick that races sink-callback settlement could\n\t// reject a Promise the user already has resolved-DATA for.\n\tconst settleData = (v: T): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (resolveFn != null) resolveFn(v);\n\t\telse pending = { kind: \"data\", value: v };\n\t};\n\tconst settleError = (err: unknown): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tif (rejectFn != null) rejectFn(err);\n\t\telse pending = { kind: \"error\", err };\n\t};\n\tconst settleComplete = (): void => {\n\t\tif (settled) return;\n\t\tsettled = true;\n\t\tconst err = new Error(\"completed without matching value\");\n\t\tif (rejectFn != null) rejectFn(err);\n\t\telse pending = { kind: \"complete\" };\n\t};\n\tconst detach = (): void => {\n\t\tif (unsub) {\n\t\t\tunsub();\n\t\t\tunsub = undefined;\n\t\t} else shouldUnsub = true;\n\t};\n\n\tconst sink: (msgs: Messages) => void = (msgs) => {\n\t\tif (settled) return;\n\t\tfor (const m of msgs) {\n\t\t\tif (settled) return;\n\t\t\t// During the initial sync phase, swallow only cached DATA\n\t\t\t// (push-on-subscribe §2.2). Terminal ERROR / COMPLETE must\n\t\t\t// still reject the promise — otherwise an already-terminated\n\t\t\t// source synchronously delivering `[[ERROR, ...]]` or\n\t\t\t// `[[COMPLETE]]` during `subscribe()` would hang forever\n\t\t\t// under `skipCurrent: true`.\n\t\t\tif (inInitialSyncPhase && m[0] === DATA) continue;\n\t\t\tif (m[0] === DATA) {\n\t\t\t\tconst v = m[1] as T;\n\t\t\t\tif (predicate(v)) {\n\t\t\t\t\tsettleData(v);\n\t\t\t\t\tdetach();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (m[0] === ERROR) {\n\t\t\t\tsettleError(m[1]);\n\t\t\t\tdetach();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\tsettleComplete();\n\t\t\t\tdetach();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t};\n\tunsub = source.subscribe(sink);\n\tinInitialSyncPhase = false;\n\t// Lock 3.A: fire `kick` AFTER subscribe is in place. With sync\n\t// subscribe + sync kick, the resulting wave reaches `sink` before\n\t// control returns — making subscribe-before-kick ordering structurally\n\t// impossible to misuse.\n\tif (opts?.kick != null && !settled) {\n\t\ttry {\n\t\t\topts.kick();\n\t\t} catch (err) {\n\t\t\tsettleError(err);\n\t\t\tdetach();\n\t\t}\n\t}\n\tif (shouldUnsub) {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\n\treturn new Promise<T>((resolve, reject) => {\n\t\t// If a settlement landed synchronously before the executor runs,\n\t\t// flush it through immediately.\n\t\tif (pending != null) {\n\t\t\tif (pending.kind === \"data\") resolve(pending.value);\n\t\t\telse if (pending.kind === \"error\") reject(pending.err);\n\t\t\telse reject(new Error(\"completed without matching value\"));\n\t\t\treturn;\n\t\t}\n\t\tresolveFn = resolve;\n\t\trejectFn = reject;\n\t});\n}\n\n/**\n * Await the first non-nullish DATA value from `source`, with optional\n * timeout. Composition sugar over `firstWhere` + reactive timeout.\n *\n * Designed as the CLI/boundary sink for reactive pipelines that end in a\n * nullable node (e.g. `promptNode` — per COMPOSITION-GUIDE §8, it emits\n * `null` before it settles with a real value). Replaces the common pattern\n * `firstValueFrom(filter(source, v => v != null))` with a deadline.\n *\n * - Rejects with `TimeoutError` (from `extra/resilience`) if no matching\n * value arrives within `timeoutMs`. Omit `timeoutMs` for unbounded wait.\n * - `predicate` defaults to `v => v != null`. Pass a custom predicate to\n * gate on a stronger condition (e.g. `v => typeof v === \"string\"`).\n * - Pass `skipCurrent: true` to ignore the currently-cached value delivered\n * synchronously via push-on-subscribe and resolve only on the *next*\n * matching emission. Useful after an imperative action that should produce\n * a fresh settlement (e.g. `run()` minting a new version — the stale\n * cached value from the previous run must not resolve the new caller).\n *\n * ```ts\n * const brief = await awaitSettled(briefNode, { timeoutMs: 120_000 });\n * // or with a predicate:\n * const rich = await awaitSettled(node, {\n * predicate: (v): v is MyShape => typeof v === \"object\" && v != null && \"key\" in v,\n * timeoutMs: 60_000,\n * });\n * // or after kicking off a fresh run:\n * kickOff();\n * const fresh = await awaitSettled(resultNode, { skipCurrent: true });\n * ```\n *\n * Reactive inside, sync propagation — the one async boundary is the\n * returned `Promise<T>` (spec §5.10: async belongs at sources and\n * boundaries, not in the graph).\n *\n * @param source - Upstream node to observe.\n * @param opts - `{ predicate?, timeoutMs?, skipCurrent? }`.\n * @returns Promise that resolves with the first matching value, or rejects on timeout / ERROR / COMPLETE-without-DATA.\n *\n * @category extra\n */\n// Lazy module-cache for the `withTimeout` resilience operator. The dynamic\n// import keeps `settled` free of an eager edge into the resilience family;\n// first call pays the one-shot import, subsequent calls hit cached refs.\nlet _timeoutOp: typeof import(\"../resilience/timeout.js\").withTimeout | undefined;\nlet _nsPerMs: number | undefined;\n\nexport async function awaitSettled<T>(\n\tsource: Node<T>,\n\topts?: {\n\t\tpredicate?: (value: T) => boolean;\n\t\ttimeoutMs?: number;\n\t\tskipCurrent?: boolean;\n\t\t/**\n\t\t * Lock 3.A (Phase 13.6.B): fired AFTER subscribe is in place but\n\t\t * BEFORE the helper's async boundary is exposed to the caller.\n\t\t * Subscribe-before-kick is structurally enforced — the kick's\n\t\t * synchronous wave reaches `sink` before control returns. Replaces\n\t\t * the prior load-bearing-comment pattern (M.20-load-bearing) with\n\t\t * a misuse-impossible API shape.\n\t\t *\n\t\t * Common pattern:\n\t\t * await awaitSettled(node, {\n\t\t * skipCurrent: true,\n\t\t * kick: () => producer.emit(value),\n\t\t * });\n\t\t *\n\t\t * Omit `kick` for external-trigger cases where the wave is fired\n\t\t * by code outside the helper's caller; subscribe still lands\n\t\t * synchronously inside the helper body so the next external wave\n\t\t * is not lost.\n\t\t */\n\t\tkick?: () => void;\n\t},\n): Promise<NonNullable<T>> {\n\tconst predicate = opts?.predicate ?? ((v: T) => v != null);\n\tconst skipCurrent = opts?.skipCurrent;\n\tconst kick = opts?.kick;\n\tif (opts?.timeoutMs == null || opts.timeoutMs <= 0) {\n\t\treturn (await firstWhere(source, predicate, { skipCurrent, kick })) as NonNullable<T>;\n\t}\n\t// Reactive composition: `timeout()` wraps the source as a Node that\n\t// emits ERROR(TimeoutError) on deadline. `firstWhere` then resolves on\n\t// the first matching DATA or rejects on that ERROR. One async boundary\n\t// (the returned Promise), everything inside is sync reactive.\n\tif (_timeoutOp === undefined) {\n\t\tconst [timeoutMod, backoff] = await Promise.all([\n\t\t\timport(\"../resilience/timeout.js\"),\n\t\t\timport(\"../resilience/backoff.js\"),\n\t\t]);\n\t\t_timeoutOp = timeoutMod.withTimeout;\n\t\t_nsPerMs = backoff.NS_PER_MS;\n\t}\n\tconst guarded = _timeoutOp(source, { ns: opts.timeoutMs * (_nsPerMs as number) }).node;\n\treturn (await firstWhere(guarded, predicate, { skipCurrent, kick })) as NonNullable<T>;\n}\n\n/**\n * Converts a reactive `Node<boolean>` into a browser-standard `AbortSignal`\n * that fires when the node settles on `true`. Useful for threading a reactive\n * \"cancel\" flag into any async boundary that accepts a signal (fetch, LLM SDK\n * calls, child-process APIs, timers).\n *\n * **Contract.**\n * - `signal.abort(reason)` fires exactly once, on the first DATA emission with\n * a truthy value. Subsequent emissions are ignored (AbortSignal is\n * single-shot).\n * - Null / `false` / sentinel values are ignored. Push-on-subscribe will\n * check the currently-cached value on subscribe and abort immediately if\n * it's already `true`.\n * - `reason` defaults to `\"cancelled via nodeSignal\"`; pass `opts.reason` to\n * override (`DOMException`, `Error`, or any value accepted by\n * `AbortController.abort`).\n *\n * **Lifecycle.**\n * - Returns a `{signal, dispose}` bundle. Call `dispose()` when you're done\n * with the signal (e.g. in a `finally` after the async operation completes).\n * `dispose()` unsubscribes from the node and is a no-op once the signal has\n * fired.\n * - **Memory note:** without `dispose()` the subscription keeps the reactive\n * node alive for the lifetime of the process. For bridge calls inside a\n * `switchMap` project fn, the switchMap supersede tears the inner subgraph\n * down, which is usually the right lifetime — but still call `dispose()`\n * from the caller's `finally` for clarity.\n *\n * @example\n * ```ts\n * const aborted = state(false);\n * const { signal, dispose } = nodeSignal(aborted);\n * try {\n * const resp = await adapter.invoke(msgs, { signal });\n * return resp;\n * } finally {\n * dispose();\n * }\n * ```\n *\n * @category extra\n */\nexport function nodeSignal(\n\tsource: Node<boolean>,\n\topts?: { reason?: unknown },\n): { signal: AbortSignal; dispose: () => void } {\n\tconst ctrl = new AbortController();\n\tconst reason = opts?.reason ?? new Error(\"cancelled via nodeSignal\");\n\tlet unsub: (() => void) | undefined;\n\tlet shouldUnsub = false;\n\tconst done = () => {\n\t\tif (unsub) {\n\t\t\tunsub();\n\t\t\tunsub = undefined;\n\t\t} else shouldUnsub = true;\n\t};\n\tunsub = source.subscribe((msgs) => {\n\t\tif (ctrl.signal.aborted) return;\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] === DATA && m[1] === true) {\n\t\t\t\tctrl.abort(reason);\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === ERROR) {\n\t\t\t\t// Treat an ERROR on the abort source as a cancel signal too —\n\t\t\t\t// a broken control channel should fail closed, not leak the\n\t\t\t\t// in-flight call. Use the error as the abort reason.\n\t\t\t\tctrl.abort(m[1]);\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t// Source completed without aborting — no-op. `done()` already\n\t\t\t\t// released the subscription here, so a later `dispose()` call\n\t\t\t\t// from the caller is a no-op (safe / idempotent).\n\t\t\t\tdone();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\tif (shouldUnsub) {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\treturn {\n\t\tsignal: ctrl.signal,\n\t\tdispose: () => {\n\t\t\tif (unsub) {\n\t\t\t\tunsub();\n\t\t\t\tunsub = undefined;\n\t\t\t}\n\t\t},\n\t};\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 = node([], { initial: 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 * 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 {\n\tbatch,\n\tDATA,\n\tfactoryTag,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\tfromAny,\n\tmerge,\n\ttype NodeInput,\n\tswitchMap,\n\twithLatestFrom,\n} from \"@graphrefly/pure-ts/extra\";\nimport { forEach } from \"../sources/async.js\";\n\n// Re-export distill from its canonical module (co-located here pre-split;\n// moved to distill.ts to avoid duplicate-export conflict at the barrel level).\nexport {\n\ttype DistillBundle,\n\ttype DistillOptions,\n\tdistill,\n\ttype Extraction,\n} from \"./distill.js\";\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 = node<TVerify | null>([], {\n\t\tinitial: opts?.initialVerified ?? null,\n\t\tmeta: {\n\t\t\t...factoryTag(\"verifiable\"),\n\t\t\t...(hasSourceVersioning ? { sourceVersion: null } : {}),\n\t\t},\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// Two patterns 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: `withLatestFrom(trigger, source)` pairs each\n\t\t// trigger emission with the latest source value. Phase 10.5\n\t\t// (`withLatestFrom` flipped to `partial: false`) fixed the W1\n\t\t// initial-pair drop — both deps settle before fn fires, so the\n\t\t// first trigger correctly pairs with the seeded source cache.\n\t\t// Replaces the §28 closure-mirror that was canonical pre-10.5.\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\tconst paired = withLatestFrom(triggerNode, sourceNode);\n\t\t\tverifyStream = switchMap(paired, ([, source]) => verifyFn(source 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","/**\n * Graph checkpoint sinks — `checkpointToS3` and `checkpointToRedis` wire a\n * graph's `attachSnapshotStorage` with an S3- or Redis-backed\n * {@link SnapshotStorageTier}.\n */\n\nimport { wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { SnapshotStorageTier } from \"@graphrefly/pure-ts/extra/storage\";\nimport type { GraphCheckpointRecord } from \"@graphrefly/pure-ts/graph\";\nimport type { AttachStorageGraphLike } from \"./_internal.js\";\nimport type { S3ClientLike } from \"./to-s3.js\";\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\n/**\n * Wires `graph.attachSnapshotStorage()` 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: SnapshotStorageTier<GraphCheckpointRecord> = {\n\t\tname: `s3:${bucket}`,\n\t\tdebounceMs,\n\t\tcompactEvery,\n\t\tsave(record) {\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(record);\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\t// S3 tier is write-only here — one object per checkpoint timestamp,\n\t\t// no canonical \"latest\" key for load.\n\t};\n\treturn graph.attachSnapshotStorage([{ snapshot: tier }], {\n\t\tonError: (err: unknown) => onError?.(err),\n\t});\n}\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.attachSnapshotStorage()` 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: SnapshotStorageTier<GraphCheckpointRecord> = {\n\t\tname: `redis:${redisKey}`,\n\t\tdebounceMs,\n\t\tcompactEvery,\n\t\tsave(record) {\n\t\t\tlet body: string;\n\t\t\ttry {\n\t\t\t\tbody = JSON.stringify(record);\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 undefined;\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(raw) as GraphCheckpointRecord;\n\t\t\t} catch {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t},\n\t};\n\treturn graph.attachSnapshotStorage([{ snapshot: tier }], {\n\t\tonError: (err: unknown) => onError?.(err),\n\t});\n}\n","/**\n * ClickHouse live materialized view IO — `fromClickHouseWatch` polls a query\n * via `fromTimer + switchMap` (reactive timer, switch semantics cancel\n * in-flight queries) and emits one `DATA` per result row per scrape.\n */\n\nimport { COMPLETE, ERROR, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { type AsyncSourceOpts, fromTimer, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { NS_PER_MS, NS_PER_SEC } from \"../resilience/backoff.js\";\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\tnode<ClickHouseRow>([], (_data, 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\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t},\n\t\t\t};\n\t\t}),\n\t);\n}\n","/**\n * CSV ingest IO — `fromCSV` reads an `AsyncIterable<string>` of CSV chunks\n * (one node per row), and `csvRows` is the stateful operator variant for\n * existing reactive `Node<string>` upstreams. Both share the local\n * `parseCSVLine` helper so quoted fields and embedded delimiters are handled\n * uniformly.\n */\n\nimport { COMPLETE, ERROR, type Node, type NodeOptions, node } from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\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 node<CSVRow>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet cancelled = false;\n\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tlet headers: string[] | undefined = explicitColumns;\n\t\t\t\t\tlet buffer = \"\";\n\n\t\t\t\t\tfor await (const chunk of source) {\n\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\tbuffer += chunk;\n\n\t\t\t\t\t\tconst lines = buffer.split(/\\r?\\n/);\n\t\t\t\t\t\t// Keep last partial line in buffer.\n\t\t\t\t\t\tbuffer = lines.pop() ?? \"\";\n\n\t\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\t\tif (!line.trim()) continue;\n\n\t\t\t\t\t\t\tconst values = parse(line);\n\n\t\t\t\t\t\t\tif (!headers && hasHeader) {\n\t\t\t\t\t\t\t\theaders = values;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!headers) {\n\t\t\t\t\t\t\t\theaders = values.map((_, i) => `col${i}`);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst row: CSVRow = {};\n\t\t\t\t\t\t\tfor (let i = 0; i < headers.length; i++) {\n\t\t\t\t\t\t\t\trow[headers[i]] = values[i] ?? \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ta.emit(row);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Process remaining buffer.\n\t\t\t\t\tif (!cancelled && buffer.trim()) {\n\t\t\t\t\t\tconst values = parse(buffer);\n\t\t\t\t\t\tif (headers) {\n\t\t\t\t\t\t\tconst row: CSVRow = {};\n\t\t\t\t\t\t\tfor (let i = 0; i < headers.length; i++) {\n\t\t\t\t\t\t\t\trow[headers[i]] = values[i] ?? \"\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ta.emit(row);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (!cancelled) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid run();\n\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tcancelled = true;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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\t// Lock 6.D (Phase 13.6.B): clear parser state on deactivation so\n\t// `csvRows` under retry/resubscribe patterns doesn't leak a stale\n\t// half-parsed line or sticky header detection from a prior run.\n\tlet cleanup: { onDeactivation: () => void } | undefined;\n\treturn node<CSVRow>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (cleanup === undefined) {\n\t\t\t\tconst store = ctx.store;\n\t\t\t\tcleanup = {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tdelete store.buffer;\n\t\t\t\t\t\tdelete store.headers;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return cleanup;\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\treturn cleanup;\n\t\t},\n\t\t{ describeKind: \"derived\", ...rest } as NodeOptions<CSVRow>,\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 * Internal helpers shared by IO sub-files.\n *\n * - `ExtraOpts` / `sourceOpts` — common opts + the `describeKind: \"producer\"`\n * wrapper used by every producer-shaped IO source.\n * - `SinkHandle` / `BufferedSinkHandle` — public sink handle shapes shared by\n * per-record and buffered sinks across multiple protocols.\n * - `AdapterHandlers` / `AckableMessage` — alias of `EmitTriad` and the\n * manual-ack envelope used by Pulsar / RabbitMQ ingest sub-files.\n * - `AttachStorageGraphLike` — duck-typed graph shape used by\n * `checkpointToS3` / `checkpointToRedis`.\n */\n\nimport type { Node, NodeOptions } from \"@graphrefly/pure-ts/core\";\nimport type { SnapshotStorageTier } from \"@graphrefly/pure-ts/extra/storage\";\nimport type { GraphCheckpointRecord } from \"@graphrefly/pure-ts/graph\";\nimport type { EmitTriad } from \"../composition/external-register.js\";\nimport type { SinkTransportError } from \"./_sink.js\";\n\nexport type ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nexport function sourceOpts<T>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\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\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/** 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/** Duck-typed graph shape consumed by `checkpointToS3` / `checkpointToRedis`. */\nexport type AttachStorageGraphLike = {\n\tattachSnapshotStorage: (\n\t\tpairs: readonly { snapshot: SnapshotStorageTier<GraphCheckpointRecord> }[],\n\t\topts?: unknown,\n\t) => { dispose(): void };\n\tname: string;\n};\n","/**\n * Drizzle adapter (5.2b) — `fromDrizzle` runs `query.execute()` and emits one\n * `DATA` containing the full mapped row array, then `COMPLETE`.\n */\n\nimport { COMPLETE, ERROR, type Node, type NodeOptions, node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 node<U[]>(\n\t\t[],\n\t\t(_data, 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\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...rest, describeKind: \"producer\", completeWhenDepsComplete: false } as NodeOptions<U[]>,\n\t);\n}\n","/**\n * HTTP IO — `fromHTTP` (one-shot fetch with `withStatus` companion bundle),\n * `toHTTP` (per-record / buffered sink with retry support), `fromHTTPStream`\n * (raw `Uint8Array` byte stream), `fromHTTPPoll` (interval-driven re-fetch).\n *\n * Uses the platform `fetch` API (Node 18+, browsers, Deno, Bun). Timeouts use\n * `AbortController` driven by `setTimeout` per spec §5.10's resilience-operator\n * carve-out.\n */\n\nimport {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Node,\n\tnode,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport { type AsyncSourceOpts, fromTimer, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { NS_PER_MS, NS_PER_SEC } from \"../resilience/backoff.js\";\nimport { type WithStatusBundle, withStatus } from \"../resilience/status.js\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 = node<number>([], { initial: 0, name: `${rest.name ?? \"http\"}/fetchCount` });\n\tconst lastUpdated = node<number>([], { initial: 0, name: `${rest.name ?? \"http\"}/lastUpdated` });\n\tconst fetched = node<boolean>([], { initial: 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 = node<T>(\n\t\t[],\n\t\t(_data, a) => ({\n\t\t\tonDeactivation: runFetch({\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{\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/** 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/** 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 node<Uint8Array>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tconst abort = new AbortController();\n\t\t\tif (externalSignal?.aborted) {\n\t\t\t\ta.down([[ERROR, externalSignal.reason ?? new Error(\"Aborted\")]]);\n\t\t\t\treturn { onDeactivation: () => {} };\n\t\t\t}\n\t\t\texternalSignal?.addEventListener(\"abort\", () => abort.abort(externalSignal.reason), {\n\t\t\t\tonce: true,\n\t\t\t});\n\t\t\tconst body =\n\t\t\t\tbodyOpt !== undefined\n\t\t\t\t\t? typeof bodyOpt === \"string\"\n\t\t\t\t\t\t? bodyOpt\n\t\t\t\t\t\t: JSON.stringify(bodyOpt)\n\t\t\t\t\t: undefined;\n\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst res = await fetch(url, { method, headers, body, signal: abort.signal });\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tif (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`);\n\t\t\t\t\tif (!res.body) throw new Error(\"HTTP response has no body\");\n\t\t\t\t\tconst reader = res.body.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\tif (value) a.emit(value);\n\t\t\t\t\t}\n\t\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (!active) return;\n\t\t\t\t\tif (err && (err as Error).name === \"AbortError\") return;\n\t\t\t\t\ta.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\t\t\tvoid run();\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t\tabort.abort();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * Status wrapper — surface lifecycle state alongside output.\n *\n * `withStatus` mirrors a source `Node<T>` and produces companion `status` /\n * `error` reactive nodes for UI and meta-snapshot consumers.\n */\n\nimport {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport { msgVal, operatorOpts } from \"./_internal.js\";\n\n/**\n * Central lifecycle vocabulary for resilience primitives + `processManager`.\n *\n * **DS-13.5.B follow-on (2026-05-01).** Widened from\n * `\"pending\" | \"running\" | \"completed\" | \"errored\"` to add `\"cancelled\"`\n * (replaces `processManager`'s prior `\"compensated\"` semantics) and\n * `\"paused\"` (carried by `<Primitive>State` lifecycle-shaped companions\n * on `retry` / `circuitBreaker` / `rateLimiter`).\n *\n * Resilience primitives use this enum as the literal vocabulary inside\n * lifecycle-shaped state nodes; `withStatus` (legacy) only emits the\n * original four (pre-widening) — the cancelled / paused values are added\n * for downstream consumers that need richer lifecycle reporting.\n */\nexport type StatusValue = \"pending\" | \"running\" | \"completed\" | \"errored\" | \"cancelled\" | \"paused\";\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 `out` is the mirrored stream, `status` is a\n * reactive `Node<StatusValue>` (`\"pending\" | \"running\" | \"completed\" | \"errored\"`),\n * and `error` holds the last `ERROR` payload (cleared to `null` on the next `DATA`\n * after `errored`).\n *\n * @remarks\n * **Lifecycle:** `pending` (no DATA yet) → `running` (on first DATA) → `completed`\n * (on COMPLETE) or `errored` (on ERROR). After `errored`, the next `DATA` clears\n * `error` and re-enters `running` inside a {@link batch} so subscribers see one\n * consistent transition (matches graphrefly-py).\n *\n * **Producer-pattern visibility:** `out` is built via `node([], fn, …)`, so `src`\n * appears as the source dependency in `describe()` traversal but the `status` /\n * `error` companions are mirrored via subscribe-callback effects — they appear\n * under `out.meta.status` / `out.meta.error` (and as `<name>::__meta__::status`\n * paths in `describe()`) rather than as separate top-level edges. Subscribers\n * to `out` see the throttled DATA stream; `status` / `error` companions may not\n * appear as edges in `describe()` if no consumer subscribes to them (per\n * COMPOSITION-GUIDE §1, push-on-subscribe semantics).\n *\n * **Per-subscribe lifecycle (DF8, 2026-04-29 doc lock).** When the wrapped\n * source is `resubscribable: true` and multiple consumers attach in\n * sequence, each new subscription cycle re-runs the producer fn AND\n * re-emits the initial `pending` + `null` companion DATAs. Downstream\n * subscribers to the `status` / `error` companions see thrash:\n * `pending → running → completed → pending → running …`. This is the\n * intended fresh-cycle semantic (each subscription cycle reports its own\n * lifecycle); consumers that need a \"stable\" status across cycles should\n * derive a snapshot via a separate `state()` mirror rather than depending\n * on the per-cycle reset.\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 → \"running\"\n * ```\n *\n * @category extra\n */\nexport function withStatus<T>(\n\tsrc: Node<T>,\n\toptions?: { initialStatus?: StatusValue; meta?: Record<string, unknown> },\n): WithStatusBundle<T> {\n\tconst initialStatus = options?.initialStatus ?? \"pending\";\n\tconst callerMeta = options?.meta;\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, \"running\"]]);\n\t\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcurrentStatus = \"running\";\n\t\t\t\t\t\t} else if (currentStatus !== \"running\") {\n\t\t\t\t\t\t\t// First DATA after `pending` (or another non-running state):\n\t\t\t\t\t\t\t// flip status to \"running\" alongside the DATA emit so external\n\t\t\t\t\t\t\t// observers see one coherent wave (no torn reads between the\n\t\t\t\t\t\t\t// status companion and the mirrored stream).\n\t\t\t\t\t\t\tbatch(() => {\n\t\t\t\t\t\t\t\tout.meta.status.down([[DATA, \"running\"]]);\n\t\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcurrentStatus = \"running\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// A9 (QA fix 2026-05-01): already in \"running\" — skip the\n\t\t\t\t\t\t\t// redundant status emit that the previous code did on every\n\t\t\t\t\t\t\t// DATA. Saves a wave walk per DATA on hot streams (e.g. SSE\n\t\t\t\t\t\t\t// token streams through withStatus).\n\t\t\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\t\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 { onDeactivation: unsub };\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tmeta: {\n\t\t\t\t...(callerMeta ?? {}),\n\t\t\t\tstatus: initialStatus,\n\t\t\t\terror: null,\n\t\t\t\t...factoryTag(\"withStatus\", { initialStatus }),\n\t\t\t},\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 * {@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 {\n\tCOMPLETE,\n\tDATA,\n\tdefaultConfig,\n\tERROR,\n\ttype Message,\n\ttype Node,\n\tnode,\n\tRingBuffer,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tresolveBackoffPreset,\n} from \"../resilience/backoff.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 = node<T | undefined>([], {\n\t\tinitial: undefined,\n\t\tequals: () => false,\n\t\tname: nameFor(\"sent\"),\n\t}) as unknown as Node<T>;\n\tconst failed = node<SinkFailure<T> | null>([], { initial: null, name: nameFor(\"failed\") });\n\tconst inFlightCountNode = node([], { initial: 0, name: nameFor(\"inFlight\") });\n\tconst errorsNode = node<SinkTransportError | null>([], {\n\t\tinitial: null,\n\t\tname: nameFor(\"errors\"),\n\t});\n\tconst bufferedNode = useBuffering\n\t\t? node([], { initial: 0, name: nameFor(\"buffered\") })\n\t\t: undefined;\n\tconst pausedNode = backpressure\n\t\t? node([], { initial: false, name: nameFor(\"paused\") })\n\t\t: 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 * Kafka IO — `fromKafka` (KafkaJS-compatible consumer source) and\n * `toKafka` (producer sink). Compatible with Pulsar via KoP (Kafka-on-Pulsar).\n */\n\nimport { ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<KafkaMessage<T>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\n\t\t\tconst start = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tawait consumer.subscribe({ topic, fromBeginning });\n\t\t\t\t\tawait consumer.run({\n\t\t\t\t\t\teachMessage: async ({ topic: t, partition, message: msg }) => {\n\t\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\t\tconst headers: Record<string, string> = {};\n\t\t\t\t\t\t\tif (msg.headers) {\n\t\t\t\t\t\t\t\tfor (const [k, v] of Object.entries(msg.headers)) {\n\t\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\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ta.emit({\n\t\t\t\t\t\t\t\ttopic: t,\n\t\t\t\t\t\t\t\tpartition,\n\t\t\t\t\t\t\t\tkey: msg.key?.toString() ?? null,\n\t\t\t\t\t\t\t\tvalue: deserialize(msg.value) as T,\n\t\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\t\toffset: msg.offset,\n\t\t\t\t\t\t\t\ttimestamp: msg.timestamp,\n\t\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\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) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid start();\n\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * Kysely adapter (5.2b) — `fromKysely` runs `query.execute()` and emits one\n * `DATA` containing the full mapped row array, then `COMPLETE`.\n */\n\nimport { COMPLETE, ERROR, type Node, type NodeOptions, node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 node<U[]>(\n\t\t[],\n\t\t(_data, 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\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...rest, describeKind: \"producer\", completeWhenDepsComplete: false } as NodeOptions<U[]>,\n\t);\n}\n","/**\n * MCP (Model Context Protocol) IO — `fromMCP` wraps an MCP client's\n * notification surface as a reactive source via `externalProducer`.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { externalProducer } from \"../composition/external-register.js\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 * NATS IO — `fromNATS` (subject-subscription consumer source) and `toNATS`\n * (publish sink). Compatible with `nats.js`-style clients.\n */\n\nimport { COMPLETE, ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<NATSMessage<T>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tconst sub = client.subscribe(subject, queue ? { queue } : undefined);\n\n\t\t\tconst loop = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tfor await (const msg of sub) {\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 of msg.headers.keys()) {\n\t\t\t\t\t\t\t\theaders[k] = msg.headers.get(k);\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\tsubject: msg.subject,\n\t\t\t\t\t\t\tdata: deserialize(msg.data) as T,\n\t\t\t\t\t\t\theaders,\n\t\t\t\t\t\t\treply: msg.reply,\n\t\t\t\t\t\t\tsid: msg.sid,\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\t// Subscription closed (drain or unsubscribe) — complete.\n\t\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid loop();\n\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * NDJSON (newline-delimited JSON) IO — `fromNDJSON` reads an\n * `AsyncIterable<string>` of NDJSON chunks (one node per line) and\n * `ndjsonRows` is the stateful operator variant for existing reactive\n * `Node<string>` upstreams.\n */\n\nimport { COMPLETE, ERROR, type Node, type NodeOptions, node } from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\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\t// Lock 6.D (Phase 13.6.B): clear parser buffer on deactivation so a\n\t// resubscribed operator doesn't bleed a half-line from a prior run.\n\tlet cleanup: { onDeactivation: () => void } | undefined;\n\treturn node<T>(\n\t\t[source as Node],\n\t\t(data, a, ctx) => {\n\t\t\tif (cleanup === undefined) {\n\t\t\t\tconst store = ctx.store;\n\t\t\t\tcleanup = {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tdelete store.buffer;\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst batch0 = data[0];\n\t\t\tif (batch0 == null || batch0.length === 0) return cleanup;\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 cleanup;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cleanup;\n\t\t},\n\t\t{ describeKind: \"derived\", ...(opts ?? {}) } as NodeOptions<T>,\n\t);\n}\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 node<T>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet cancelled = false;\n\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tlet buffer = \"\";\n\n\t\t\t\t\tfor await (const chunk of source) {\n\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\tbuffer += chunk;\n\n\t\t\t\t\t\tconst lines = buffer.split(/\\r?\\n/);\n\t\t\t\t\t\tbuffer = lines.pop() ?? \"\";\n\n\t\t\t\t\t\tfor (const line of lines) {\n\t\t\t\t\t\t\tif (cancelled) return;\n\t\t\t\t\t\t\tconst trimmed = line.trim();\n\t\t\t\t\t\t\tif (!trimmed) continue;\n\t\t\t\t\t\t\ta.emit(JSON.parse(trimmed) as T);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Process remaining buffer.\n\t\t\t\t\tif (!cancelled && buffer.trim()) {\n\t\t\t\t\t\ta.emit(JSON.parse(buffer.trim()) as T);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (!cancelled) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid run();\n\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tcancelled = true;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsourceOpts(opts),\n\t);\n}\n","/**\n * OpenTelemetry (OTLP/HTTP) IO — `fromOTel` exposes traces/metrics/logs as\n * three reactive nodes via `externalBundle`. The caller owns the HTTP server\n * and wires the registrar callback to OTLP routes.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { batch } from \"@graphrefly/pure-ts/core\";\nimport { type BundleTriad, externalBundle } from \"../composition/external-register.js\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 * Prisma adapter (5.2b) — `fromPrisma` runs `model.findMany(args)` and emits\n * one `DATA` containing the full mapped row array, then `COMPLETE`.\n */\n\nimport { COMPLETE, ERROR, type Node, type NodeOptions, node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 node<U[]>(\n\t\t[],\n\t\t(_data, 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\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{ ...rest, describeKind: \"producer\", completeWhenDepsComplete: false } as NodeOptions<U[]>,\n\t);\n}\n","/**\n * Prometheus scrape IO — `fromPrometheus` polls a `/metrics` endpoint via\n * `fromTimer + switchMap` (reactive timer, not bare `setInterval`) and emits\n * one `DATA` per parsed metric per scrape. `parsePrometheusText` exposes the\n * exposition-format parser as a pure helper.\n */\n\nimport { COMPLETE, ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { AsyncSourceOpts } from \"@graphrefly/pure-ts/extra\";\nimport { fromTimer, switchMap } from \"@graphrefly/pure-ts/extra\";\nimport { NS_PER_MS, NS_PER_SEC } from \"../resilience/backoff.js\";\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\tnode<PrometheusMetric>([], (_data, 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\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t\tabort.abort();\n\t\t\t\t},\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 * Apache Pulsar IO — `fromPulsar` (native-client consumer source with optional\n * manual ack via {@link AckableMessage} envelopes) and `toPulsar` (producer\n * sink). For Kafka-on-Pulsar (KoP), use the Kafka adapter instead.\n */\n\nimport { ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type AckableMessage, type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<PulsarMessage<T> | AckableMessage<PulsarMessage<T>>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\n\t\t\tconst loop = async () => {\n\t\t\t\twhile (active) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst rawMsg = await consumer.receive();\n\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\tconst structured: PulsarMessage<T> = {\n\t\t\t\t\t\t\ttopic: rawMsg.getTopicName(),\n\t\t\t\t\t\t\tmessageId: rawMsg.getMessageId().toString(),\n\t\t\t\t\t\t\tkey: rawMsg.getPartitionKey(),\n\t\t\t\t\t\t\tvalue: deserialize(rawMsg.getData()) as T,\n\t\t\t\t\t\t\tproperties: rawMsg.getProperties(),\n\t\t\t\t\t\t\tpublishTime: rawMsg.getPublishTimestamp(),\n\t\t\t\t\t\t\teventTime: rawMsg.getEventTimestamp(),\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\tvoid consumer.acknowledge(rawMsg).catch(reportAckError);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Manual ack — wrap in AckableMessage. Pulsar's SDK has no\n\t\t\t\t\t\t\t// per-message nack(requeue=false) — a plain `nack` re-delivers\n\t\t\t\t\t\t\t// after the subscription's negativeAckRedeliveryDelay. `requeue`\n\t\t\t\t\t\t\t// is honored as \"always redeliver\" (SDK default).\n\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\tconst envelope: AckableMessage<PulsarMessage<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\tvoid consumer.acknowledge(rawMsg).catch(reportAckError);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tnack(_opts) {\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\tconst anyConsumer = consumer as unknown as {\n\t\t\t\t\t\t\t\t\t\tnegativeAcknowledge?: (m: unknown) => Promise<void> | void;\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\tconst result = anyConsumer.negativeAcknowledge?.(rawMsg);\n\t\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\t\tif (result && typeof (result as Promise<void>).then === \"function\") {\n\t\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\t}\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} catch (err) {\n\t\t\t\t\t\tif (active) a.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\n\t\t\tvoid loop();\n\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * RabbitMQ IO — `fromRabbitMQ` (queue-consumer source with optional manual\n * ack via {@link AckableMessage} envelopes) and `toRabbitMQ` (publisher\n * sink). Compatible with `amqplib`-style channels.\n */\n\nimport { ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type AckableMessage, type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<RabbitMQMessage<T> | AckableMessage<RabbitMQMessage<T>>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tlet consumerTag: string | undefined;\n\n\t\t\tconst start = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await channel.consume(\n\t\t\t\t\t\tqueue,\n\t\t\t\t\t\t(rawMsg) => {\n\t\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\t\tif (rawMsg === null) {\n\t\t\t\t\t\t\t\t// Broker cancelled the consumer (queue deleted, etc.).\n\t\t\t\t\t\t\t\tif (active) a.down([[ERROR, new Error(\"Consumer cancelled by broker\")]]);\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst structured: RabbitMQMessage<T> = {\n\t\t\t\t\t\t\t\tqueue,\n\t\t\t\t\t\t\t\troutingKey: rawMsg.fields.routingKey,\n\t\t\t\t\t\t\t\texchange: rawMsg.fields.exchange,\n\t\t\t\t\t\t\t\tcontent: deserialize(rawMsg.content) as T,\n\t\t\t\t\t\t\t\tproperties: rawMsg.properties,\n\t\t\t\t\t\t\t\tdeliveryTag: rawMsg.fields.deliveryTag,\n\t\t\t\t\t\t\t\tredelivered: rawMsg.fields.redelivered,\n\t\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tif (autoAck) {\n\t\t\t\t\t\t\t\ta.emit(structured);\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tchannel.ack(rawMsg);\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} else {\n\t\t\t\t\t\t\t\tlet settled = false;\n\t\t\t\t\t\t\t\tconst channelWithNack = channel as unknown as {\n\t\t\t\t\t\t\t\t\tnack?: (msg: unknown, allUpTo?: boolean, requeue?: boolean) => void;\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tconst envelope: AckableMessage<RabbitMQMessage<T>> = {\n\t\t\t\t\t\t\t\t\tvalue: structured,\n\t\t\t\t\t\t\t\t\tack() {\n\t\t\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tchannel.ack(rawMsg);\n\t\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tnack(nackOpts) {\n\t\t\t\t\t\t\t\t\t\tif (settled) return;\n\t\t\t\t\t\t\t\t\t\tsettled = true;\n\t\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\t// SDK apply its own default (amqplib: true). Explicit\n\t\t\t\t\t\t\t\t\t\t// `false` routes to DLX if configured.\n\t\t\t\t\t\t\t\t\t\tconst requeue = nackOpts?.requeue;\n\t\t\t\t\t\t\t\t\t\tif (!channelWithNack.nack) {\n\t\t\t\t\t\t\t\t\t\t\treportAckError(\n\t\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\t);\n\t\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tchannelWithNack.nack(rawMsg, false, requeue);\n\t\t\t\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\t\t\t\treportAckError(err);\n\t\t\t\t\t\t\t\t\t\t}\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\ta.emit(envelope);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ noAck: false },\n\t\t\t\t\t);\n\t\t\t\t\tconsumerTag = result.consumerTag;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tvoid start();\n\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t\tif (consumerTag !== undefined) {\n\t\t\t\t\t\tvoid channel.cancel(consumerTag);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * Redis Streams IO — `fromRedisStream` (XREAD-BLOCK consumer source) and\n * `toRedisStream` (XADD producer sink). Caller owns the Redis client\n * lifecycle.\n */\n\nimport { ERROR, type Node, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<RedisStreamEntry<T>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tlet lastId = startId;\n\n\t\t\tconst poll = async () => {\n\t\t\t\twhile (active) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await client.xread(\"BLOCK\", blockMs, \"STREAMS\", key, lastId);\n\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\tif (result) {\n\t\t\t\t\t\t\tfor (const [_streamKey, entries] of result) {\n\t\t\t\t\t\t\t\tfor (const [id, fields] of entries) {\n\t\t\t\t\t\t\t\t\tlastId = id;\n\t\t\t\t\t\t\t\t\ta.emit({\n\t\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\t\t\tdata: parse(fields) as T,\n\t\t\t\t\t\t\t\t\t\ttimestampNs: wallClockNs(),\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}\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tif (!active) return;\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\n\t\t\tvoid poll();\n\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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 * SQLite IO (roadmap §5.2b) — `fromSqlite` (one-shot synchronous query),\n * `fromSqliteCursor` (row-by-row streaming via `iterate()`), and `toSqlite`\n * (insert sink with optional transactional batching).\n *\n * Synchronous boundaries: SQLite drivers are typically synchronous\n * (`better-sqlite3`, `node:sqlite`), so errors propagate immediately rather\n * than via promise rejection. The duck-typed `SqliteDbLike.query` matches the\n * project-wide `query(sql, params)` convention used by Postgres/ClickHouse.\n */\n\nimport {\n\tbatch,\n\tCOMPLETE,\n\tDATA,\n\tdefaultConfig,\n\tERROR,\n\ttype Node,\n\ttype NodeOptions,\n\tnode,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport {\n\ttype ReactiveSinkHandle,\n\treactiveSink,\n\ttype SinkFailure,\n\ttype SinkTransportError,\n} from \"./_sink.js\";\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 node<T[]>(\n\t\t[],\n\t\t(_data, 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 node<T>(\n\t\t[],\n\t\t(_data, 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 = node<SinkTransportError | null>([], { initial: null });\n\tconst sentNode = node<T | undefined>([], {\n\t\tinitial: undefined,\n\t\tequals: () => false,\n\t}) as unknown as Node<T>;\n\tconst failedNode = node<SinkFailure<T> | null>([], { initial: null });\n\tconst inFlightNode = node<number>([], { initial: 0 });\n\tconst bufferedNode = node<number>([], { initial: 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 * Server-Sent Events IO — `toSSE` / `toSSEBytes` (encode any node into the\n * `text/event-stream` wire format), `toReadableStream` (web-stream sink),\n * `parseSSEStream` (async-iterator parser), `fromSSE` (line-delimited parser\n * source).\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tdefaultConfig,\n\tERROR,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n} from \"@graphrefly/pure-ts/core\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\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 node<Uint8Array>([], (_data, 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\tonDeactivation: () => {\n\t\t\t\tactive = false;\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},\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/** 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/** Options for {@link parseSSEStream}. */\nexport type ParseSSEStreamOptions<T = string> = {\n\t/** Parse the raw `data:` payload. Default: identity (string). */\n\tparse?: (raw: string) => T;\n\t/**\n\t * External abort signal. If aborted, the generator returns early after\n\t * cancelling the underlying reader / iterator. Does not emit an error —\n\t * the generator simply ends.\n\t */\n\tsignal?: AbortSignal;\n};\n\n/**\n * Parses a Server-Sent Events byte stream into an async-iterator of structured\n * `{event, data, id, retry}` records. Pure async generator with no reactive\n * dependency — safe to consume anywhere an `AsyncIterable<SSEEvent>` is\n * expected (LLM provider adapters, tests, non-reactive transports).\n *\n * Handles:\n * - Arbitrary chunk boundaries (internal text buffer + `TextDecoder` streaming).\n * - `\\n` and `\\r\\n` line endings.\n * - `event:` / `data:` (multi-line via repeated fields) / `id:` / `retry:`.\n * - Comments (`:` prefix).\n * - Cancels the underlying reader / iterator on external abort or consumer\n * break, so a quiet stream doesn't leak pending `read()` calls.\n *\n * Used internally by {@link fromSSE} (reactive `Node<SSEEvent>`) — exposed as a\n * pure helper so LLM provider adapters (Anthropic, OpenAI, Google) can parse\n * their SSE streams without building a reactive node per call.\n *\n * @param source - SSE byte source (`ReadableStream`, `Response`, or `AsyncIterable<Uint8Array>`).\n * @param opts - `{ parse?, signal? }`.\n * @returns `AsyncGenerator<SSEEvent<T>>` — yields one event per SSE block; returns on stream end / abort.\n *\n * @category extra\n */\nexport async function* parseSSEStream<T = string>(\n\tsource: ReadableStream<Uint8Array> | Response | AsyncIterable<Uint8Array>,\n\topts?: ParseSSEStreamOptions<T>,\n): AsyncGenerator<SSEEvent<T>, void, unknown> {\n\tconst parse = opts?.parse ?? ((raw: string) => raw as unknown as T);\n\tconst externalSignal = opts?.signal;\n\n\tconst decoder = new TextDecoder();\n\tlet buffer = \"\";\n\tlet currentEvent = \"message\";\n\tlet currentData: string[] = [];\n\tlet currentId: string | undefined;\n\tlet currentRetry: number | undefined;\n\tconst queue: SSEEvent<T>[] = [];\n\n\tconst flushEvent = () => {\n\t\tif (currentData.length === 0 && currentEvent === \"message\" && currentId === undefined) {\n\t\t\tcurrentData = [];\n\t\t\treturn;\n\t\t}\n\t\tconst raw = currentData.join(\"\\n\");\n\t\tqueue.push({\n\t\t\tevent: currentEvent,\n\t\t\tdata: parse(raw),\n\t\t\tid: currentId,\n\t\t\tretry: currentRetry,\n\t\t});\n\t\tcurrentEvent = \"message\";\n\t\tcurrentData = [];\n\t\tcurrentId = undefined;\n\t\tcurrentRetry = undefined;\n\t};\n\n\tconst processLine = (line: string) => {\n\t\tif (line === \"\") {\n\t\t\tflushEvent();\n\t\t\treturn;\n\t\t}\n\t\tif (line.startsWith(\":\")) return; // comment\n\t\tconst colon = line.indexOf(\":\");\n\t\tconst field = colon < 0 ? line : line.slice(0, colon);\n\t\tlet value = colon < 0 ? \"\" : line.slice(colon + 1);\n\t\tif (value.startsWith(\" \")) value = value.slice(1);\n\t\tswitch (field) {\n\t\t\tcase \"event\":\n\t\t\t\tcurrentEvent = value;\n\t\t\t\tbreak;\n\t\t\tcase \"data\":\n\t\t\t\tcurrentData.push(value);\n\t\t\t\tbreak;\n\t\t\tcase \"id\":\n\t\t\t\tif (!value.includes(\"\\0\")) currentId = value;\n\t\t\t\tbreak;\n\t\t\tcase \"retry\": {\n\t\t\t\tconst n = Number(value);\n\t\t\t\tif (Number.isFinite(n)) currentRetry = n;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t};\n\n\tconst processChunk = (chunk: Uint8Array, done: boolean) => {\n\t\tbuffer += decoder.decode(chunk, { stream: !done });\n\t\tconst parts = buffer.split(/\\r?\\n/);\n\t\tbuffer = parts.pop() ?? \"\";\n\t\tfor (const line of parts) processLine(line);\n\t};\n\n\t// Resolve the underlying byte source into either a `ReadableStream` or an\n\t// `AsyncIterator<Uint8Array>` — identical dispatch as the legacy fromSSE.\n\tconst resp = source as Response;\n\tconst stream =\n\t\tsource instanceof ReadableStream\n\t\t\t? source\n\t\t\t: resp && typeof resp === \"object\" && resp.body instanceof ReadableStream\n\t\t\t\t? resp.body\n\t\t\t\t: null;\n\n\tlet reader: ReadableStreamDefaultReader<Uint8Array> | undefined;\n\tlet iter: AsyncIterator<Uint8Array> | undefined;\n\t// `cleanupDone` flips once we've invoked `reader.cancel()` / `iter.return()`\n\t// — guards against the `onAbort` listener + the `finally` path both\n\t// cancelling the same underlying resource (WHATWG streams allow double-\n\t// cancel but custom `AsyncIterator.return` implementations are not\n\t// required to be idempotent).\n\tlet cleanupDone = false;\n\tconst cleanupReader = (): void => {\n\t\tif (cleanupDone) return;\n\t\tcleanupDone = true;\n\t\tif (reader) {\n\t\t\tvoid reader.cancel().catch(() => undefined);\n\t\t}\n\t\tif (iter && typeof iter.return === \"function\") {\n\t\t\tvoid Promise.resolve(iter.return()).catch(() => undefined);\n\t\t}\n\t};\n\n\t// Wire the external abort signal to cancel the reader / iterator promptly\n\t// instead of waiting for the next chunk.\n\tconst onAbort = (): void => {\n\t\tcleanupReader();\n\t};\n\tif (externalSignal) {\n\t\tif (externalSignal.aborted) return;\n\t\texternalSignal.addEventListener(\"abort\", onAbort, { once: true });\n\t}\n\n\ttry {\n\t\tif (stream) {\n\t\t\treader = stream.getReader();\n\t\t\twhile (!externalSignal?.aborted) {\n\t\t\t\tconst { value, done } = await reader.read();\n\t\t\t\tif (done) break;\n\t\t\t\tprocessChunk(value, false);\n\t\t\t\twhile (queue.length > 0) {\n\t\t\t\t\tconst ev = queue.shift() as SSEEvent<T>;\n\t\t\t\t\tyield ev;\n\t\t\t\t}\n\t\t\t}\n\t\t\tprocessChunk(new Uint8Array(), true);\n\t\t} else {\n\t\t\tconst asyncIter = source as AsyncIterable<Uint8Array>;\n\t\t\titer = asyncIter[Symbol.asyncIterator]();\n\t\t\twhile (!externalSignal?.aborted) {\n\t\t\t\tconst step = await iter.next();\n\t\t\t\tif (step.done) break;\n\t\t\t\tprocessChunk(step.value, false);\n\t\t\t\twhile (queue.length > 0) {\n\t\t\t\t\tconst ev = queue.shift() as SSEEvent<T>;\n\t\t\t\t\tyield ev;\n\t\t\t\t}\n\t\t\t}\n\t\t\tprocessChunk(new Uint8Array(), true);\n\t\t}\n\t\tif (buffer.trim()) {\n\t\t\tfor (const line of buffer.split(/\\r?\\n/)) processLine(line);\n\t\t\tflushEvent();\n\t\t}\n\t\twhile (queue.length > 0) {\n\t\t\tconst ev = queue.shift() as SSEEvent<T>;\n\t\t\tyield ev;\n\t\t}\n\t} finally {\n\t\tif (externalSignal) {\n\t\t\texternalSignal.removeEventListener(\"abort\", onAbort);\n\t\t}\n\t\t// Idempotent cleanup — if `onAbort` already ran the cancel, this is a\n\t\t// no-op. Covers the normal consumer-break path (generator exits → finally\n\t\t// runs → cancel underlying reader / iterator so a quiet upstream\n\t\t// doesn't leak its `read()` call).\n\t\tcleanupReader();\n\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, ...rest } = opts ?? {};\n\treturn node<SSEEvent<T>>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tconst ctrl = new AbortController();\n\t\t\tconst run = async () => {\n\t\t\t\ttry {\n\t\t\t\t\tfor await (const ev of parseSSEStream<T>(source, { parse, signal: ctrl.signal })) {\n\t\t\t\t\t\tif (!active) return;\n\t\t\t\t\t\ta.emit(ev);\n\t\t\t\t\t}\n\t\t\t\t\tif (active) a.down([[COMPLETE]]);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (active) a.down([[ERROR, err]]);\n\t\t\t\t}\n\t\t\t};\n\t\t\tvoid run();\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t\tctrl.abort();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\n}\n","/**\n * StatsD / DogStatsD IO — `fromStatsD` registrar-based source plus\n * `parseStatsD` helper for the line format. The caller owns the UDP socket;\n * the adapter only wires the `emit` triad.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype EmitTriad,\n\ttype ExternalRegister,\n\texternalProducer,\n} from \"../composition/external-register.js\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 * Syslog (RFC 5424) IO — `fromSyslog` registrar-based source plus\n * `parseSyslog` helper for the line format. The caller owns the UDP/TCP\n * socket; the adapter only wires the `emit` triad.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype EmitTriad,\n\ttype ExternalRegister,\n\texternalProducer,\n} from \"../composition/external-register.js\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 * ClickHouse insert sink IO — `toClickHouse` accumulates upstream `DATA`\n * values and inserts them in batches via the duck-typed\n * {@link ClickHouseInsertClientLike}.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * File-writer sink IO — `toFile` writes upstream `DATA` to any\n * `FileWriterLike` (e.g. `fs.createWriteStream`). Buffered or write-through\n * depending on `flushIntervalMs` / `batchSize`.\n *\n * Uses a duck-typed writable so the universal `extra/io` entry stays\n * browser-safe — the caller injects the Node `fs` writer at the boundary.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * CSV file sink IO — `toCSV` adds CSV row formatting on top of\n * {@link toFile}. Uses the local `escapeCSVField` helper to quote cells that\n * contain delimiters / quotes / newlines.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport type { ReactiveSinkHandle, SinkTransportError } from \"./_sink.js\";\nimport { type FileWriterLike, toFile } from \"./to-file.js\";\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 * Grafana Loki sink IO — `toLoki` pushes upstream `DATA` values as log\n * entries via the duck-typed {@link LokiClientLike} `push()` surface.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * MongoDB insert sink IO — `toMongo` inserts each upstream `DATA` value via\n * the duck-typed {@link MongoCollectionLike} `insertOne()`.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * Postgres insert sink IO — `toPostgres` inserts each upstream `DATA` value\n * via the duck-typed {@link PostgresClientLike} `query()` surface.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * S3 object-storage sink IO — `toS3` buffers upstream `DATA` values and\n * uploads them as NDJSON or JSON objects via the duck-typed\n * {@link S3ClientLike}.\n *\n * `S3ClientLike` is also used by `checkpointToS3` (in `./checkpoint.ts`).\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { wallClockNs } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * Grafana Tempo sink IO — `toTempo` pushes upstream `DATA` values as trace\n * spans (OTLP/HTTP shape) via the duck-typed {@link TempoClientLike}.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport type { ExtraOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 * Webhook IO — `fromWebhook` is a thin wrapper over `externalProducer` that\n * exposes the standard `EmitTriad` (`emit` / `error` / `complete`) callback\n * shape to the caller's framework integration (Express, Fastify, Hono,\n * Cloudflare Workers, etc.).\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype EmitTriad,\n\ttype ExternalRegister,\n\texternalProducer,\n} from \"../composition/external-register.js\";\nimport type { ExtraOpts } from \"./_internal.js\";\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 * WebSocket IO — `fromWebSocket` (DOM-style `WebSocketLike` source / register\n * variant), `toWebSocket` (sink with optional ack-tracking + retry),\n * `fromWebSocketReconnect` (`fromWebSocket` wrapped in retry-on-disconnect with\n * exponential backoff).\n */\n\nimport { COMPLETE, ERROR, type Message, type Node, node } from \"@graphrefly/pure-ts/core\";\nimport { retry } from \"../resilience/retry.js\";\nimport { type ExtraOpts, sourceOpts } from \"./_internal.js\";\nimport { type ReactiveSinkHandle, reactiveSink, type SinkTransportError } from \"./_sink.js\";\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 node<T>(\n\t\t[],\n\t\t(_data, a) => {\n\t\t\tlet active = true;\n\t\t\tlet cleanup: (() => void) | undefined;\n\t\t\tconst runCleanup = () => {\n\t\t\t\tconst fn = cleanup;\n\t\t\t\tcleanup = undefined;\n\t\t\t\tfn?.();\n\t\t\t};\n\t\t\tconst terminate = (message: Message) => {\n\t\t\t\tif (!active) return;\n\t\t\t\tactive = false;\n\t\t\t\ta.down([message]);\n\t\t\t\trunCleanup();\n\t\t\t};\n\t\t\tconst emit = (raw: unknown, event: unknown = raw) => {\n\t\t\t\tif (!active) return;\n\t\t\t\ttry {\n\t\t\t\t\tconst payload =\n\t\t\t\t\t\traw !== null && typeof raw === \"object\" && \"data\" in (raw as Record<string, unknown>)\n\t\t\t\t\t\t\t? (raw as WebSocketMessageEventLike).data\n\t\t\t\t\t\t\t: raw;\n\t\t\t\t\tconst parsed = parse ? parse(payload, event) : (payload as T);\n\t\t\t\t\ta.emit(parsed);\n\t\t\t\t} catch (err) {\n\t\t\t\t\tterminate([ERROR, err]);\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst error = (err: unknown) => {\n\t\t\t\tterminate([ERROR, err]);\n\t\t\t};\n\t\t\tconst complete = () => {\n\t\t\t\tterminate([COMPLETE]);\n\t\t\t};\n\t\t\tif (typeof socketOrRegister === \"function\") {\n\t\t\t\ttry {\n\t\t\t\t\tcleanup = socketOrRegister(emit, error, complete);\n\t\t\t\t\tif (typeof cleanup !== \"function\") {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\"fromWebSocket register contract violation: register must return cleanup callable\",\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\tterminate([ERROR, err]);\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tonDeactivation: () => {\n\t\t\t\t\t\tactive = false;\n\t\t\t\t\t\trunCleanup();\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst ws = socketOrRegister;\n\t\t\tconst onMessage = (event: unknown) => emit(event, event);\n\t\t\tconst onError = (event: unknown) => error(event);\n\t\t\tconst onClose = () => complete();\n\t\t\tws.addEventListener(\"message\", onMessage);\n\t\t\tws.addEventListener(\"error\", onError);\n\t\t\tws.addEventListener(\"close\", onClose);\n\t\t\tcleanup = () => {\n\t\t\t\tws.removeEventListener(\"message\", onMessage);\n\t\t\t\tws.removeEventListener(\"error\", onError);\n\t\t\t\tws.removeEventListener(\"close\", onClose);\n\t\t\t\tif (closeOnTeardown) ws.close();\n\t\t\t};\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tactive = false;\n\t\t\t\t\trunCleanup();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tsourceOpts(rest),\n\t);\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: retryOpt,\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: retryOpt,\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/** 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 retry>[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 retry} rebuilds the inner source and reconnects.\n *\n * For transient errors, {@link retry} 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 retry<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).node;\n}\n","/**\n * Retry — re-attempt a node on terminal failure.\n *\n * Two modes selected by the type of `input`:\n * - **Source mode** (`Node<T>`): resubscribes the same node after each ERROR.\n * Upstream must be `resubscribable: true` or retries are silent no-ops.\n * - **Factory mode** (`() => Node<T>`): builds a fresh node per attempt.\n *\n * Shared with `circuitBreaker` / `rateLimiter`: `NodeOrValue<RetryOptions>`\n * lets callers swap retry config reactively (re-validates on each attempt).\n */\n\nimport {\n\tCOMPLETE,\n\tDATA,\n\tDIRTY,\n\tERROR,\n\tfactoryTag,\n\ttype Message,\n\ttype Node,\n\tnode,\n\tRESOLVED,\n\tResettableTimer,\n} from \"@graphrefly/pure-ts/core\";\nimport { coerceDelayNs, isNode, msgVal, type NodeOrValue, operatorOpts } from \"./_internal.js\";\nimport {\n\ttype BackoffPreset,\n\ttype BackoffStrategy,\n\tNS_PER_MS,\n\tresolveBackoffPreset,\n} from \"./backoff.js\";\nimport type { StatusValue } from \"./status.js\";\n\n/**\n * Lifecycle-shaped state companion emitted by {@link retry} (DS-13.5.B,\n * locked 2026-05-01). Tracks the retry state machine's current status,\n * the attempt counter, and the last scheduled delay (null before the\n * first retry).\n *\n * @category extra/resilience\n */\nexport interface RetryState {\n\tstatus: StatusValue;\n\tattempt: number;\n\tlastDelay_ns: number | null;\n}\n\n/**\n * Bundle returned by {@link retry}: the retry-wrapped output node and its\n * lifecycle state companion. Pre-1.0 break vs the prior `Node<T>` return.\n *\n * **Single-subscriber / pipeline-only contract (DS-13.5.B QA, N1, 2026-05-03).**\n * The `retryState` companion is allocated once at factory time and shared\n * across all subscribers to `node`. With one subscriber (the typical use\n * case — wire `node` into your downstream chain, optionally observe\n * `retryState` separately) the companion reflects a coherent timeline.\n * With **two or more subscribers** to `node`, each subscriber re-runs the\n * producer body and writes into the same `retryState`, including\n * `publish(\"pending\")` resets that can clobber an in-flight machine's\n * `running`/`paused` state. Don't fan out `node` to multiple subscribers\n * and rely on `retryState` accuracy unless you use\n * {@link keepalive} / `share`-style consolidation.\n *\n * @category extra/resilience\n */\nexport interface RetryBundle<T> {\n\tnode: Node<T>;\n\tretryState: Node<RetryState>;\n}\n\nexport type RetryOptions = {\n\t/**\n\t * Max retry attempts after each terminal `ERROR` (not counting the first failure).\n\t *\n\t * **Required when `backoff` is set.** Pass `Infinity` to opt in to unbounded retries\n\t * — the explicit value rules out the silent-infinite-budget footgun (a flaky provider\n\t * + exponential backoff + omitted `count` would previously default to ~2.1B retries).\n\t */\n\tcount?: number;\n\t/** Delay between attempts; strategies use **nanoseconds**. */\n\tbackoff?: BackoffStrategy | BackoffPreset;\n\t/**\n\t * Caller-supplied metadata merged into the produced node's `meta` (Tier 5.2\n\t * D8 widening). Use {@link domainMeta} to tag the layer for `describe()`\n\t * grouping. The primitive's `factoryTag(\"retry\", …)` always wins against\n\t * caller keys.\n\t */\n\tmeta?: Record<string, unknown>;\n};\n\n/** Factory-mode-only options. `initial` seeds the outer node's cache before the first attempt. */\nexport type RetryFactoryOptions<T> = RetryOptions & {\n\t/** Initial cache value for the outer node before the factory runs the first time. */\n\tinitial?: T;\n};\n\n/**\n * Resolved retry config shared by source-mode and factory-mode wrappers.\n * Centralises the unbounded-retry footgun guard and strategy resolution.\n */\ntype ResolvedRetryConfig = {\n\tmaxRetries: number;\n\tstrategy: BackoffStrategy | null;\n};\n\nfunction resolveRetryConfig(opts?: RetryOptions): ResolvedRetryConfig {\n\tconst count = opts?.count;\n\tconst backoffOpt = opts?.backoff;\n\n\t// Unbounded-retry footgun fix: if `backoff` is set without explicit `count`,\n\t// throw at construction time. Caller must opt in to `Infinity` for unbounded.\n\tif (backoffOpt !== undefined && count === undefined) {\n\t\tthrow new RangeError(\n\t\t\t\"retry({ backoff }) requires explicit count to prevent unbounded retries; pass { count: <n>, backoff: ... }\",\n\t\t);\n\t}\n\n\tconst maxRetries = count !== undefined ? count : 0;\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 { maxRetries, strategy };\n}\n\nfunction retryFactoryArgs(opts?: RetryOptions): Record<string, unknown> | undefined {\n\tconst args: Record<string, unknown> = {};\n\tif (opts?.count !== undefined) args.count = opts.count;\n\tif (typeof opts?.backoff === \"string\") args.backoff = opts.backoff;\n\treturn Object.keys(args).length > 0 ? args : undefined;\n}\n\n/**\n * Shared retry state machine. Both `_retrySource` and `_retryFactory` thin-wrap this:\n * the only per-mode logic is supplied via `acquireSource` (returns a fresh `Node<T>`\n * per attempt — for source-mode it just returns the captured `Node`; for factory-mode\n * it calls the user factory and forwards synchronous throws into the same retry path).\n *\n * **Reactive cfg (Tier 6.5 3.2.2, 2026-04-29).** `getCfg` is invoked at\n * every decision point (`scheduleRetryOrFinish` count + strategy reads)\n * so option swaps mid-flight take effect at the next attempt boundary\n * per the locked semantic rule: \"next attempt fails immediately if\n * already exhausted under new count; `backoff` swap takes effect at next\n * retry's delay calculation.\"\n */\nfunction _runRetryStateMachine<T>(\n\tgetCfg: () => ResolvedRetryConfig,\n\tacquireSource: () => Node<T>,\n\ta: { emit: (v: T) => void; down: (msgs: Message[]) => void },\n\temitState?: (next: RetryState) => void,\n): () => void {\n\tlet attempt = 0;\n\tlet stopped = false;\n\tlet prevDelay: number | null = null;\n\tlet unsub: (() => void) | undefined;\n\tconst timer = new ResettableTimer();\n\tconst publish = (status: StatusValue): void => {\n\t\temitState?.({ status, attempt, lastDelay_ns: prevDelay });\n\t};\n\tpublish(\"pending\");\n\n\tfunction disconnectUpstream(): void {\n\t\tunsub?.();\n\t\tunsub = undefined;\n\t}\n\n\tfunction scheduleRetryOrFinish(err: unknown): void {\n\t\tif (stopped) return;\n\t\tconst cfg = getCfg();\n\t\tif (attempt >= cfg.maxRetries) {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\tconst raw = cfg.strategy === null ? 0 : cfg.strategy(attempt, err, prevDelay);\n\t\t// null from strategy = \"stop retrying\" (e.g. withMaxAttempts cap reached)\n\t\tif (raw === null || raw === undefined) {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\t// A misbehaving strategy (returns NaN / non-finite / negative) MUST NOT\n\t\t// escape into the upstream drain. Treat it like `strategy === null`\n\t\t// (stop retrying) and emit the original error — the strategy bug is a\n\t\t// separate concern the user can inspect via the emitted error's stack.\n\t\tlet delayNs: number;\n\t\ttry {\n\t\t\tdelayNs = coerceDelayNs(raw);\n\t\t} catch {\n\t\t\tdisconnectUpstream();\n\t\t\tpublish(\"errored\");\n\t\t\ta.down([[ERROR, err]]);\n\t\t\treturn;\n\t\t}\n\t\tprevDelay = delayNs;\n\t\tattempt += 1;\n\t\tdisconnectUpstream();\n\t\tpublish(\"paused\");\n\t\t// `Math.max(1, …)` floor: every backoff schedule floors at 1ms even when\n\t\t// the strategy returns 0ns. Avoids 0-delay re-entrancy on the active\n\t\t// stack frame (which would risk stack overflow on a tight ERROR loop).\n\t\tconst delayMs = delayNs > 0 ? delayNs / NS_PER_MS : 1;\n\t\t// §5.10: setTimeout (not fromTimer) — retry delay needs clearTimeout/setTimeout;\n\t\t// fromTimer creates a new Node per reset, adding lifecycle overhead per retry.\n\t\ttimer.start(delayMs, () => {\n\t\t\tif (stopped) return;\n\t\t\tconnect();\n\t\t});\n\t}\n\n\tfunction connect(): void {\n\t\ttimer.cancel();\n\t\tdisconnectUpstream();\n\t\tlet src: Node<T>;\n\t\ttry {\n\t\t\tsrc = acquireSource();\n\t\t} catch (err) {\n\t\t\tscheduleRetryOrFinish(err);\n\t\t\treturn;\n\t\t}\n\t\tpublish(\"running\");\n\t\tunsub = src.subscribe((msgs) => {\n\t\t\tif (stopped) return;\n\t\t\tfor (const m of msgs) {\n\t\t\t\tconst t = m[0];\n\t\t\t\tif (t === DIRTY) a.down([[DIRTY]]);\n\t\t\t\telse if (t === DATA) {\n\t\t\t\t\tattempt = 0;\n\t\t\t\t\tprevDelay = null;\n\t\t\t\t\ta.emit(m[1] as T);\n\t\t\t\t\tpublish(\"running\");\n\t\t\t\t} else if (t === RESOLVED) a.down([[RESOLVED]]);\n\t\t\t\telse if (t === COMPLETE) {\n\t\t\t\t\t// DF2 (2026-04-29): set `stopped = true` BEFORE\n\t\t\t\t\t// `disconnectUpstream()` so a re-entrant ERROR delivered\n\t\t\t\t\t// in the same wave (after disconnect runs but before the\n\t\t\t\t\t// teardown closure fires `stopped = true`) hits the\n\t\t\t\t\t// `if (stopped) return` guard at line 159 and cannot\n\t\t\t\t\t// schedule a new retry timer.\n\t\t\t\t\tstopped = true;\n\t\t\t\t\tdisconnectUpstream();\n\t\t\t\t\tpublish(\"completed\");\n\t\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\tscheduleRetryOrFinish(msgVal(m));\n\t\t\t\t\treturn;\n\t\t\t\t} else a.down([m]);\n\t\t\t}\n\t\t});\n\t}\n\n\tconnect();\n\n\treturn () => {\n\t\tconst wasStopped = stopped;\n\t\tstopped = true;\n\t\ttimer.cancel();\n\t\tdisconnectUpstream();\n\t\tif (!wasStopped) publish(\"cancelled\");\n\t};\n}\n\n/**\n * Retry operator — two modes selected by the type of `input`:\n *\n * **Source mode** (`input: Node<T>`): resubscribes to the same node after each terminal\n * `ERROR`. The upstream should use `resubscribable: true` if it must emit again after `ERROR`.\n *\n * **Factory mode** (`input: () => Node<T>`): invokes the factory to build a fresh `Node<T>`\n * on every connect / reconnect. Ideal for producers that capture per-attempt resources\n * (sockets, clients, file handles) that become unusable after an error. Synchronous\n * exceptions thrown by the factory are treated as terminal ERROR and run through the\n * same retry pipeline as inner-node ERROR.\n *\n * @param input - Upstream node or factory that returns a fresh node per attempt.\n * @param opts - `count` caps attempts (**required when `backoff` is set**; pass `Infinity` to opt in to unbounded); `backoff` supplies delay in **nanoseconds** (or a preset name); `initial` seeds the outer node cache (factory mode only).\n * @returns Node that retries on error.\n *\n * @throws {RangeError} when `backoff` is provided without an explicit `count` (unbounded-retry footgun guard) or when `count < 0`.\n *\n * @remarks\n * **Protocol:** Forwards unknown message tuples unchanged; handles `DIRTY`, `DATA`, `RESOLVED`, `COMPLETE`, `ERROR`.\n *\n * **Backoff floor:** every scheduled delay is floored at 1ms via `Math.max(1, delayNs / NS_PER_MS)` even when the strategy returns 0ns. This avoids 0-delay re-entrancy on the active stack frame on a tight ERROR loop. Strategies that return `null`/`undefined` stop retrying immediately and forward the original error.\n *\n * @example\n * ```ts\n * // Source mode — resubscribe the same node:\n * import { ERROR, NS_PER_SEC, producer, retry, constant } from \"@graphrefly/graphrefly-ts\";\n *\n * const src = producer(\n * (a) => { a.down([[ERROR, new Error(\"x\")]]); },\n * { resubscribable: true },\n * );\n * const out = retry(src, { count: 2, backoff: constant(0.25 * NS_PER_SEC) });\n *\n * // Factory mode — fresh node per attempt (e.g. reconnecting WebSocket):\n * import { NS_PER_SEC, exponential, retry, fromWebSocket } from \"@graphrefly/graphrefly-ts\";\n *\n * const connected$ = retry(\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 retry<T>(input: Node<T>, opts?: NodeOrValue<RetryOptions>): RetryBundle<T>;\nexport function retry<T>(\n\tinput: () => Node<T>,\n\topts?: NodeOrValue<RetryFactoryOptions<T>>,\n): RetryBundle<T>;\nexport function retry<T>(\n\tinput: Node<T> | (() => Node<T>),\n\topts?: NodeOrValue<RetryOptions | RetryFactoryOptions<T>>,\n): RetryBundle<T> {\n\tconst retryState = node<RetryState>([], {\n\t\tname: \"retryState\",\n\t\tdescribeKind: \"state\",\n\t\tinitial: { status: \"pending\", attempt: 0, lastDelay_ns: null },\n\t\tequals: (a, b) =>\n\t\t\ta === b ||\n\t\t\t(a != null &&\n\t\t\t\tb != null &&\n\t\t\t\ttypeof a === \"object\" &&\n\t\t\t\ttypeof b === \"object\" &&\n\t\t\t\tJSON.stringify(a) === JSON.stringify(b)),\n\t});\n\tconst emit = (s: RetryState): void => {\n\t\tretryState.down([[DIRTY], [DATA, s]]);\n\t};\n\tif (typeof input === \"function\") {\n\t\treturn {\n\t\t\tnode: _retryFactory(input, opts as NodeOrValue<RetryFactoryOptions<T>> | undefined, emit),\n\t\t\tretryState,\n\t\t};\n\t}\n\treturn {\n\t\tnode: _retrySource(input, opts as NodeOrValue<RetryOptions> | undefined, emit),\n\t\tretryState,\n\t};\n}\n\n// DS-13.5.B helper: like `resolveReactiveOption` but shallow-merges each\n// reactive emit over the prior opts and treats empty `{}` as a no-op\n// (per the locked cross-cutting rule). Static-form arg returns the value\n// as-is and never subscribes.\nfunction makeMergedOptsMirror<R extends Record<string, unknown>>(\n\targ: NodeOrValue<R> | undefined,\n): { current: () => R | undefined; unsub: () => void } {\n\tif (arg === undefined) {\n\t\treturn { current: () => undefined, unsub: () => undefined };\n\t}\n\tif (!isNode(arg)) {\n\t\treturn { current: () => arg as R, unsub: () => undefined };\n\t}\n\tconst optsNode = arg as Node<R>;\n\tlet merged: R | undefined = (optsNode.cache as R | undefined) ?? undefined;\n\tconst unsub = optsNode.subscribe((msgs) => {\n\t\tfor (const m of msgs) {\n\t\t\tif (m[0] !== DATA) continue;\n\t\t\tconst next = m[1] as R | undefined;\n\t\t\tif (next == null || typeof next !== \"object\") continue;\n\t\t\tif (Object.keys(next).length === 0) continue; // empty {} no-op\n\t\t\tmerged = { ...(merged ?? ({} as R)), ...next } as R;\n\t\t}\n\t});\n\treturn { current: () => merged, unsub };\n}\n\n// DF6 (2026-04-29): once-per-source dedup for the source-mode-retry warn.\n// Mirrors the `_bumpCursorWarned` pattern in `extra/mutation/index.ts`.\nconst _retrySourceNonResubscribableWarned = new WeakSet<Node<unknown>>();\n\nfunction _retrySource<T>(\n\tsource: Node<T>,\n\topts?: NodeOrValue<RetryOptions>,\n\temitState?: (s: RetryState) => void,\n): Node<T> {\n\t// Source-mode retry re-subscribes to the SAME source node after each\n\t// terminal ERROR. If the upstream was constructed with the default\n\t// `resubscribable: false`, the second subscribe-after-terminal is a\n\t// silent no-op and retries effectively never re-deliver. Surface\n\t// once-per-source so misconfigurations fail loud without log spam.\n\tconst sourceWithFlag = source as unknown as { _resubscribable?: boolean };\n\tif (\n\t\tsourceWithFlag._resubscribable === false &&\n\t\t!_retrySourceNonResubscribableWarned.has(source)\n\t) {\n\t\t_retrySourceNonResubscribableWarned.add(source);\n\t\tconsole.warn(\n\t\t\t\"retry(source, opts): source-mode requires `resubscribable: true` on the upstream \" +\n\t\t\t\t\"node. Retries will be silent no-ops after the first ERROR. Either pass \" +\n\t\t\t\t\"`resubscribable: true` to the source factory, OR use factory-mode retry \" +\n\t\t\t\t\"`retry(() => buildSource(), opts)` so each attempt builds a fresh node.\",\n\t\t);\n\t}\n\tconst staticOpts = isNode(opts) ? undefined : (opts as RetryOptions | undefined);\n\t// Eager validation for static-form opts (preserves construction-time\n\t// \"backoff without count\" RangeError). Reactive-form opts re-validate\n\t// per `getCfg()` call inside the state machine.\n\tif (!isNode(opts)) resolveRetryConfig(staticOpts);\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tconst merged = makeMergedOptsMirror<RetryOptions>(opts);\n\t\t\tconst getCfg = (): ResolvedRetryConfig => resolveRetryConfig(merged.current());\n\t\t\tconst inner = _runRetryStateMachine(getCfg, () => source, a, emitState);\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tinner();\n\t\t\t\t\tmerged.unsub();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: source.cache,\n\t\t\tmeta: {\n\t\t\t\t...(staticOpts?.meta ?? {}),\n\t\t\t\t...factoryTag(\n\t\t\t\t\t\"retry\",\n\t\t\t\t\tisNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t);\n}\n\nfunction _retryFactory<T>(\n\tfactory: () => Node<T>,\n\topts?: NodeOrValue<RetryFactoryOptions<T>>,\n\temitState?: (s: RetryState) => void,\n): Node<T> {\n\tconst staticOpts = isNode(opts) ? undefined : (opts as RetryFactoryOptions<T> | undefined);\n\t// Eager validation for static-form opts (Tier 3.1 footgun preservation).\n\tif (!isNode(opts)) resolveRetryConfig(staticOpts);\n\treturn node<T>(\n\t\t(_data, a) => {\n\t\t\tconst merged = makeMergedOptsMirror<RetryFactoryOptions<T>>(opts);\n\t\t\tconst getCfg = (): ResolvedRetryConfig => resolveRetryConfig(merged.current());\n\t\t\tconst inner = _runRetryStateMachine(getCfg, factory, a, emitState);\n\t\t\treturn {\n\t\t\t\tonDeactivation: () => {\n\t\t\t\t\tinner();\n\t\t\t\t\tmerged.unsub();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\t{\n\t\t\t...operatorOpts(),\n\t\t\tinitial: staticOpts?.initial as T | undefined,\n\t\t\tmeta: {\n\t\t\t\t...(staticOpts?.meta ?? {}),\n\t\t\t\t...factoryTag(\n\t\t\t\t\t\"retry\",\n\t\t\t\t\tisNode(opts) ? { reactiveOpts: true } : retryFactoryArgs(staticOpts),\n\t\t\t\t),\n\t\t\t},\n\t\t},\n\t);\n}\n","/**\n * Metadata helpers for pattern-layer nodes (Tier 2.2 promotion from\n * `patterns/_internal/`).\n *\n * Each domain (orchestration, messaging, reduction, ai, cqrs, domain_template,\n * memory, lens, audit, harness) shares the same metadata convention. Promoted\n * to `extra/` so non-patterns code (and downstream consumers building their\n * own domain primitives) can use the same shape.\n *\n * @module\n */\n\n/**\n * Build a domain metadata object for pattern-layer nodes.\n *\n * Each domain follows the same shape: `{ [domain]: true, [domain]_type: kind, ...extra }`.\n *\n * @param domain - The domain tag (e.g. `\"orchestration\"`, `\"ai\"`, `\"cqrs\"`).\n * @param kind - The specific type within the domain (e.g. `\"gate\"`, `\"prompt\"`).\n * @param extra - Additional metadata to merge.\n * @returns Metadata object.\n */\nexport function domainMeta(\n\tdomain: string,\n\tkind: string,\n\textra?: Record<string, unknown>,\n): Record<string, unknown> {\n\treturn {\n\t\t[domain]: true,\n\t\t[`${domain}_type`]: kind,\n\t\t...(extra ?? {}),\n\t};\n}\n","/**\n * emitToMeta — forward DATA to a meta companion node via tier-3 deferral.\n *\n * Extracted from patterns/_internal/index.ts during cleave A2.\n */\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { DATA, defaultConfig, downWithBatch } from \"@graphrefly/pure-ts/core\";\n\n// emitToMeta\n// ---------------------------------------------------------------------------\n\n/**\n * Forward a single `[DATA, value]` to a meta companion node via tier-3\n * deferral, tolerating absent companions. Used by patterns that publish\n * per-wave statistics alongside their main output (cache-hit-rate,\n * segment-count, layout-time-ns, etc.) — subscribers see the parent's\n * DATA first because phase-2 completes before phase-3 during drain.\n *\n * // Expands to: `if (meta) downWithBatch(meta, [[Type, value]])` with null-guard.\n *\n * @internal\n */\nexport function emitToMeta<T>(metaNode: Node<T> | undefined, value: T): void {\n\tif (metaNode == null) return;\n\tdownWithBatch((msgs) => metaNode.down(msgs), [[DATA, value]], defaultConfig.tierOf);\n}\n\n// ---------------------------------------------------------------------------\n","/**\n * Universal mutation framework (Phase 14 — DS-14 locked 2026-05-05).\n *\n * Single `mutate(act, opts)` factory replaces the prior `lightMutation` +\n * `wrapMutation` two-tier split (pre-1.0 break per Q-O2).\n *\n * Two frames:\n * - `\"inline\"` — no batch; up() runs raw. Seq bumps before action; persists\n * on throw. Hot-path-friendly for atomic single-write mutations.\n * - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n * deferred deliveries, then `down()` runs (if provided), then failure record.\n *\n * Phase-4 primitives share the same shape: imperative mutation methods +\n * closure state + reactive audit log + freeze-at-entry + rollback-on-throw.\n * This module factors out the common machinery so each primitive becomes\n * declarative wiring over typed audit records.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tDIRTY,\n\ttype Node,\n\ttype NodeGuard,\n\tnode,\n\tpolicy,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype ReactiveLogBundle,\n\ttype ReactiveLogOptions,\n\treactiveLog,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\n\n// ── tryIncrementBounded ──────────────────────────────────────────────────\n\n/**\n * Bounded increment for a self-owned counter state node.\n *\n * Reads `counter.cache`, bumps by `by` (default 1) if `cur + by <= cap`,\n * writes back. Returns `false` when the cap would be exceeded (no-op write).\n * Documented P3 exception: the counter is not a declared dep of the caller —\n * it's a private budget read+written from a single call site. This helper\n * keeps the `.cache` access in one named place so caller bodies (which may\n * be inside reactive fn execution paths) stay free of cross-node `.cache`\n * reads.\n *\n * **Safety today:**\n * 1. Single-threaded JS runner never invokes the caller concurrently.\n * 2. `counter.down` writes the cache synchronously before returning, so\n * synchronous re-entry through a downstream publish reads the\n * freshly-incremented value — no double-count.\n *\n * **Future risk:** under a free-threaded runner (PY no-GIL or hypothetical\n * concurrent TS runner), two concurrent firings could still race. Revisit\n * when that surfaces.\n *\n * @param counter - Self-owned counter Node. Caller is the sole writer.\n * @param cap - Upper bound (inclusive). Pass `Number.MAX_SAFE_INTEGER` for\n * \"effectively unbounded\" use cases (e.g. token meters).\n * @param by - Delta to add (default `1`). Must be a finite non-negative\n * number; callers should pre-validate. Overflow-safe via\n * `by > cap - cur` check rather than `cur + by >= cap`.\n */\nexport function tryIncrementBounded(counter: Node<number>, cap: number, by = 1): boolean {\n\tconst cur = (counter.cache as number | undefined) ?? 0;\n\tif (by > cap - cur) return false;\n\tcounter.down([[DIRTY], [DATA, cur + by]]);\n\treturn true;\n}\n\n// ── Audit record schema ──────────────────────────────────────────────────\n\n/** Shared base shape for every audit record. Per-primitive types extend this. */\nexport interface BaseAuditRecord {\n\treadonly t_ns: number;\n\treadonly seq?: number;\n\treadonly handlerVersion?: { id: string; version: string | number };\n}\n\n// ── Default audit guard ──────────────────────────────────────────────────\n\n/**\n * Allow `observe` and `signal`; deny external `write` on the audit log so\n * consumers can subscribe + signal-bridge but cannot inject fake records.\n */\nexport const DEFAULT_AUDIT_GUARD: NodeGuard = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n// ── createAuditLog ───────────────────────────────────────────────────────\n\nexport type AuditLogOpts<R extends BaseAuditRecord> = {\n\tname: string;\n\t/** Bounded retention; default 1024 per Audit 2 / cross-cutting bounded-default policy. */\n\tretainedLimit?: number;\n\t/** Override the default audit guard. */\n\tguard?: NodeGuard;\n\t/** Mount the audit `entries` Node under this graph (and activate withLatest). */\n\tgraph?: Graph;\n\t/** Pass-through to {@link reactiveLog}. */\n\tversioning?: ReactiveLogOptions<R>[\"versioning\"];\n};\n\n/**\n * Build a reactive audit log with sane defaults: bounded retention, deny-write\n * guard, `withLatest()` companions activated. Returns the {@link ReactiveLogBundle}\n * directly — primitives expose this as `<primitive>.events` / `.decisions` /\n * `.dispatches` / `.invocations` and alias it as `.audit`.\n *\n * @category internal\n */\nexport function createAuditLog<R extends BaseAuditRecord>(\n\topts: AuditLogOpts<R>,\n): ReactiveLogBundle<R> {\n\tconst log = reactiveLog<R>([], {\n\t\tname: opts.name,\n\t\tmaxSize: opts.retainedLimit ?? 1024,\n\t\tguard: opts.guard ?? DEFAULT_AUDIT_GUARD,\n\t\t...(opts.versioning != null ? { versioning: opts.versioning } : {}),\n\t});\n\t// Lazy companion activation up-front so `bundle.lastValue` / `hasLatest`\n\t// are queryable without an explicit `withLatest()` call.\n\tlog.withLatest();\n\tif (opts.graph) {\n\t\topts.graph.add(log.entries, { name: opts.name });\n\t}\n\treturn log;\n}\n\n// ── Universal mutation factory (Phase 14 — DS-14 lock Q-O2/Q-O3) ────────\n//\n// Single `mutate(act, opts)` factory. Two frames:\n//\n// - `\"inline\"` — no batch frame; up() runs raw. Seq bumps before action;\n// persists on throw. Hot-path-friendly for atomic single-write mutations.\n//\n// - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n// deferred deliveries, then `down()` runs, then failure record persists.\n//\n// **Heuristic:** if your imperative method's body is one or two lines (mutate\n// state, emit), use `frame: \"inline\"`. If it runs a user-supplied handler or\n// has multiple steps that could leave inconsistent state mid-throw, use\n// `frame: \"transactional\"`.\n\nexport type FailureMeta = {\n\tt_ns: number;\n\tseq?: number;\n\terrorType: string;\n};\n\nexport type SuccessMeta = {\n\tt_ns: number;\n\tseq?: number;\n};\n\n/**\n * Mutation action shape. Plain function shorthand auto-wraps as `{ up: fn }`.\n *\n * - `up` — the mutation action (the \"up migration\").\n * - `down` — optional rollback for closure mutations that `batch()` can't\n * reach. Receives the SAME frozen args as `up`. Runs AFTER batch reactive\n * rollback, BEFORE the failure record. Throws inside `down` are\n * console.error'd without masking the original error. Only meaningful\n * with `frame: \"transactional\"`.\n */\nexport type MutationAct<TArgs extends readonly unknown[], TResult> = {\n\tup: (...args: TArgs) => TResult;\n\tdown?: (...args: TArgs) => void;\n};\n\nexport type MutationFrame = \"inline\" | \"transactional\";\n\nexport type MutateOpts<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord> = {\n\t/** Frame mode. `\"inline\"` = no batch; `\"transactional\"` = batch + rollback. */\n\tframe: MutationFrame;\n\t/**\n\t * Optional log to append records to. When omitted, the wrapper still\n\t * provides freeze / seq-advance / rollback-on-throw but skips record\n\t * emission — useful for primitives that want centralized mutation\n\t * semantics without a dedicated log surface (e.g. `Topic.publish`).\n\t */\n\tlog?: ReactiveLogBundle<R>;\n\t/** Build the success record from the action's args + result + meta. */\n\tonSuccessRecord?: (args: TArgs, result: TResult, meta: SuccessMeta) => R | undefined;\n\t/** Build the failure record from the args + error + meta. */\n\tonFailureRecord?: (args: TArgs, error: unknown, meta: FailureMeta) => R | undefined;\n\t/** Deep-freeze args at entry (default `true`). Opt out for hot paths. */\n\tfreeze?: boolean;\n\t/** Optional sequence cursor — auto-advanced and stamped onto records. */\n\tseq?: Node<number>;\n\t/** Optional handler version — stamped per Audit 5. */\n\thandlerVersion?: { id: string; version: string | number };\n};\n\nfunction deepFreeze<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tfor (const k of Object.keys(value as Record<string, unknown>)) {\n\t\tdeepFreeze((value as Record<string, unknown>)[k]);\n\t}\n\treturn Object.freeze(value);\n}\n\n/**\n * Universal mutation factory (Phase 14 — DS-14 Q-O2).\n *\n * Replaces the prior `lightMutation` + `wrapMutation` two-tier split.\n * Single factory with `frame: \"inline\" | \"transactional\"` discriminant.\n *\n * @param act - The mutation action. Either a plain function (auto-wrapped as\n * `{ up: fn }`) or a `{ up, down? }` object for explicit rollback.\n * @param opts - Configuration: frame, log, record builders, freeze, seq.\n * @returns A typed wrapper function with the same signature as `act.up`.\n */\nexport function mutate<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord>(\n\tact: MutationAct<TArgs, TResult> | ((...args: TArgs) => TResult),\n\topts: MutateOpts<TArgs, TResult, R>,\n): (...args: TArgs) => TResult {\n\tconst { up, down } = typeof act === \"function\" ? { up: act, down: undefined } : act;\n\tconst freeze = opts.freeze ?? true;\n\n\tif (opts.frame === \"inline\") {\n\t\treturn function wrapped(...args: TArgs): TResult {\n\t\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\t\tconst t_ns = wallClockNs();\n\t\t\tconst seq = opts.seq ? bumpCursor(opts.seq) : undefined;\n\t\t\ttry {\n\t\t\t\tconst result = up(...sealed);\n\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\tresult,\n\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} catch (err) {\n\t\t\t\tif (opts.log && opts.onFailureRecord) {\n\t\t\t\t\tconst errorType = err instanceof Error ? err.name : typeof err;\n\t\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\t\topts.handlerVersion,\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\t}\n\n\t// frame === \"transactional\"\n\treturn function wrapped(...args: TArgs): TResult {\n\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\tconst t_ns = wallClockNs();\n\t\tlet result: TResult;\n\t\tlet captured: unknown;\n\t\tlet captureSet = false;\n\t\tlet seq: number | undefined;\n\t\ttry {\n\t\t\tbatch(() => {\n\t\t\t\tif (opts.seq) seq = bumpCursor(opts.seq);\n\t\t\t\ttry {\n\t\t\t\t\tresult = up(...sealed);\n\t\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\t\topts.log,\n\t\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\t\tsealed,\n\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\t\topts.handlerVersion,\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\tcaptured = err;\n\t\t\t\t\tcaptureSet = true;\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (outerErr) {\n\t\t\t// Fire `down` AFTER batch's reactive rollback, BEFORE failure record.\n\t\t\t// Gate on `captureSet` — if the throw came from outside the inner try\n\t\t\t// (framework-level batch error before action ran), don't fire down.\n\t\t\tif (captureSet && down) {\n\t\t\t\ttry {\n\t\t\t\t\tdown(...sealed);\n\t\t\t\t} catch (downErr) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`mutate: down hook threw — original action error preserved (${\n\t\t\t\t\t\t\tcaptured instanceof Error ? captured.name : typeof captured\n\t\t\t\t\t\t}). Down error:`,\n\t\t\t\t\t\tdownErr,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (captureSet && opts.log && opts.onFailureRecord) {\n\t\t\t\tconst errorType = captured instanceof Error ? captured.name : typeof captured;\n\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\topts.log,\n\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\tsealed,\n\t\t\t\t\tcaptured,\n\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\topts.handlerVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow captureSet ? captured : outerErr;\n\t\t}\n\t\treturn result!;\n\t};\n}\n\n/**\n * Advance a cursor node and return the new value. Emits `[DIRTY], [DATA, next]`\n * directly on the cursor — atomic outside a batch, rollback-discardable inside.\n *\n * Resets to `0` if the cursor cache is missing, non-numeric, `NaN`, or\n * non-finite (e.g. corrupted by `restore()` from a malformed snapshot, or\n * by a misbehaving codec). `??` alone would let `NaN` and `\"\"` pass through\n * and silently corrupt audit ordering downstream.\n *\n * **Silent reset diagnostic (EH-12).** When the cache holds a non-numeric\n * value at bump time, the cursor restarts at 0 and the next bump returns 1\n * — colliding with the seq stamped on the very first record after construct.\n * To make seq-monotonicity violations after a restore visible to operators,\n * the helper emits a one-shot `console.warn` per cursor instance describing\n * the offending value. The cursor is identified by a `WeakSet<Node<number>>`\n * so the warning fires exactly once per node — repeat malformed bumps stay\n * quiet to avoid log spam. Production callers wanting to suppress can swap\n * the global `console` (universal-safe code path; no Node-only API used).\n *\n * Works whether or not the cursor has any subscribers — `down` updates the\n * cache regardless, so primitives that bump before consumers attach (e.g.\n * `JobQueueGraph.enqueue`) still see a coherent sequence.\n *\n * @category internal\n */\nconst _bumpCursorWarned = new WeakSet<Node<number>>();\nexport function bumpCursor(seq: Node<number>): number {\n\tconst raw = seq.cache;\n\tconst valid = typeof raw === \"number\" && Number.isFinite(raw);\n\tif (!valid && raw !== undefined && !_bumpCursorWarned.has(seq)) {\n\t\t_bumpCursorWarned.add(seq);\n\t\tconsole.warn(\n\t\t\t`bumpCursor: cursor cache held a non-numeric value (${String(raw)}); resetting to 0. ` +\n\t\t\t\t\"Causes include: a snapshot codec round-tripping the cursor as a string / null / NaN, \" +\n\t\t\t\t\"OR a malformed initial seed (e.g. state<number>(NaN)). \" +\n\t\t\t\t\"Audit consumers may see colliding seq values after this point.\",\n\t\t);\n\t}\n\tconst cur = valid ? raw : 0;\n\tconst next = cur + 1;\n\tseq.down([[DIRTY], [DATA, next]]);\n\treturn next;\n}\n\n/**\n * Build a record via the supplied builder, stamp `handlerVersion` if present,\n * and append it to the audit log. `undefined` records are skipped (callers\n * pass an `onSuccess` / `onFailure` that returns `undefined` to opt out per\n * call).\n *\n * @category internal\n */\nexport function appendAudit<\n\tTArgs extends readonly unknown[],\n\tTValue,\n\tR extends BaseAuditRecord,\n\tM extends SuccessMeta | FailureMeta,\n>(\n\taudit: ReactiveLogBundle<R>,\n\tbuilder: (args: TArgs, value: TValue, meta: M) => R | undefined,\n\targs: TArgs,\n\tvalue: TValue,\n\tmeta: M,\n\thandlerVersion?: { id: string; version: string | number },\n): void {\n\tconst record = builder(args, value, meta);\n\tif (record === undefined) return;\n\tconst stamped = handlerVersion != null ? ({ ...record, handlerVersion } as R) : record;\n\taudit.append(stamped);\n}\n\n// ── registerCursor / registerCursorMap ───────────────────────────────────\n\n/**\n * Promote a closure counter to a state node mounted under `graph`.\n * Replaces ad-hoc `let _seq = 0` patterns with a node observable in\n * `describe()` and persistable via storage tiers.\n *\n * @category internal\n */\nexport function registerCursor(graph: Graph, name: string, initial = 0): Node<number> {\n\tconst cursor = node<number>([], { initial, name, describeKind: \"state\" });\n\tgraph.add(cursor, { name });\n\treturn cursor;\n}\n\n/**\n * Promote a closure `Map<K, number>` to N state nodes (one per key) mounted\n * under `<graph>::<name>::<key>`. Used by saga (per-event-type cursor).\n *\n * @category internal\n */\nexport function registerCursorMap<K extends string>(\n\tgraph: Graph,\n\tname: string,\n\tkeys: readonly K[],\n\tinitial = 0,\n): { readonly [P in K]: Node<number> } {\n\tconst out = {} as { [P in K]: Node<number> };\n\t// Mount cursors under a child plain-Graph so per-key node names stay flat\n\t// (path-separator `::` is reserved by Graph.add). Using `Graph` directly\n\t// rather than `graph.constructor` avoids spawning a typed subclass with\n\t// an incompatible constructor signature (e.g., CqrsGraph(name, opts)).\n\tconst sub = new Graph(name);\n\tfor (const k of keys) {\n\t\tconst cursor = node<number>([], {\n\t\t\tinitial,\n\t\t\tname: k,\n\t\t\tdescribeKind: \"state\",\n\t\t});\n\t\tsub.add(cursor, { name: k });\n\t\tout[k] = cursor;\n\t}\n\tgraph.mount(name, sub);\n\treturn out;\n}\n","/**\n * Monospace-terminal cell-width utilities shared by the CLI measurement\n * adapter ([src/patterns/reactive-layout/measurement-adapters.ts](../patterns/reactive-layout/measurement-adapters.ts))\n * and the ASCII describe renderer ([graph-spec-to-ascii.ts](./graph-spec-to-ascii.ts)).\n *\n * Approximates UAX #11 East_Asian_Width (W/F → 2) plus known combining-mark\n * ranges (→ 0). Not a full EAW table — covers CJK, Hangul, fullwidth forms,\n * common emoji, and Extensions B-G. Does not handle ZWJ emoji sequences\n * (multi-codepoint clusters rendered as a single glyph) — terminal support\n * for those varies widely.\n */\n\nexport function cellWidth(code: number): 0 | 1 | 2 {\n\t// Combining marks (Mn, Mc, Me) → 0 cells\n\tif (\n\t\t(code >= 0x0300 && code <= 0x036f) || // Combining Diacritical Marks\n\t\t(code >= 0x0483 && code <= 0x0489) || // Cyrillic combining marks\n\t\t(code >= 0x0591 && code <= 0x05bd) || // Hebrew combining marks\n\t\t(code >= 0x0610 && code <= 0x061a) || // Arabic combining marks\n\t\t(code >= 0x064b && code <= 0x065f) || // Arabic combining marks\n\t\t(code >= 0x0670 && code === 0x0670) || // Arabic superscript alef\n\t\t(code >= 0x06d6 && code <= 0x06dc) || // Arabic combining marks\n\t\t(code >= 0x06df && code <= 0x06e4) || // Arabic combining marks\n\t\t(code >= 0x06e7 && code <= 0x06e8) || // Arabic combining marks\n\t\t(code >= 0x06ea && code <= 0x06ed) || // Arabic combining marks\n\t\t(code >= 0x0730 && code <= 0x074a) || // Syriac combining marks\n\t\t(code >= 0x07a6 && code <= 0x07b0) || // Thaana combining marks\n\t\t(code >= 0x0900 && code <= 0x0903) || // Devanagari combining marks\n\t\t(code >= 0x093a && code <= 0x094f) || // Devanagari combining marks\n\t\t(code >= 0x0951 && code <= 0x0957) || // Devanagari combining marks\n\t\t(code >= 0x0962 && code <= 0x0963) || // Devanagari combining marks\n\t\t(code >= 0x0981 && code <= 0x0983) || // Bengali combining marks\n\t\t(code >= 0x09bc && code <= 0x09cd) || // Bengali combining marks\n\t\t(code >= 0x0a01 && code <= 0x0a03) || // Gurmukhi combining marks\n\t\t(code >= 0x0a3c && code <= 0x0a51) || // Gurmukhi combining marks\n\t\t(code >= 0x0a70 && code <= 0x0a71) || // Gurmukhi combining marks\n\t\t(code >= 0x0a75 && code === 0x0a75) || // Gurmukhi combining mark\n\t\t(code >= 0x0e31 && code === 0x0e31) || // Thai combining mark\n\t\t(code >= 0x0e34 && code <= 0x0e3a) || // Thai combining marks\n\t\t(code >= 0x0e47 && code <= 0x0e4e) || // Thai combining marks\n\t\t(code >= 0x0eb1 && code === 0x0eb1) || // Lao combining mark\n\t\t(code >= 0x0eb4 && code <= 0x0ebc) || // Lao combining marks\n\t\t(code >= 0x0ec8 && code <= 0x0ece) || // Lao combining marks\n\t\t(code >= 0x1dc0 && code <= 0x1dff) || // Combining Diacritical Marks Supplement\n\t\t(code >= 0x20d0 && code <= 0x20ff) || // Combining Diacritical Marks for Symbols\n\t\t(code >= 0xfe00 && code <= 0xfe0f) || // Variation Selectors\n\t\t(code >= 0xfe20 && code <= 0xfe2f) || // Combining Half Marks\n\t\tcode === 0x200d // Zero Width Joiner\n\t) {\n\t\treturn 0;\n\t}\n\t// Wide / fullwidth → 2 cells\n\tif (\n\t\t(code >= 0x1100 && code <= 0x115f) || // Hangul Jamo\n\t\t(code >= 0x231a && code <= 0x231b) || // Watch, Hourglass\n\t\t(code >= 0x2329 && code <= 0x232a) || // Angle brackets\n\t\t(code >= 0x23e9 && code <= 0x23f3) || // Media control symbols\n\t\t(code >= 0x23f8 && code <= 0x23fa) || // Media control symbols\n\t\t(code >= 0x25fd && code <= 0x25fe) || // Medium squares\n\t\t(code >= 0x2614 && code <= 0x2615) || // Umbrella, Hot Beverage\n\t\t(code >= 0x2648 && code <= 0x2653) || // Zodiac symbols\n\t\tcode === 0x267f || // Wheelchair\n\t\tcode === 0x2693 || // Anchor\n\t\tcode === 0x26a1 || // High Voltage\n\t\t(code >= 0x26aa && code <= 0x26ab) || // Medium circles\n\t\t(code >= 0x26bd && code <= 0x26be) || // Soccer, Baseball\n\t\t(code >= 0x26c4 && code <= 0x26c5) || // Snowman, Sun behind cloud\n\t\tcode === 0x26ce || // Ophiuchus\n\t\tcode === 0x26d4 || // No Entry\n\t\tcode === 0x26ea || // Church\n\t\t(code >= 0x26f2 && code <= 0x26f3) || // Fountain, Golf\n\t\tcode === 0x26f5 || // Sailboat\n\t\tcode === 0x26fa || // Tent\n\t\tcode === 0x26fd || // Fuel Pump\n\t\tcode === 0x2702 || // Scissors\n\t\tcode === 0x2705 || // Check Mark\n\t\t(code >= 0x2708 && code <= 0x270d) || // Airplane...Writing Hand\n\t\tcode === 0x270f || // Pencil\n\t\t(code >= 0x2753 && code <= 0x2755) || // Question marks\n\t\tcode === 0x2757 || // Exclamation\n\t\t(code >= 0x2795 && code <= 0x2797) || // Plus, Minus, Divide\n\t\tcode === 0x27b0 || // Curly Loop\n\t\tcode === 0x27bf || // Double Curly Loop\n\t\t(code >= 0x2934 && code <= 0x2935) || // Arrows\n\t\t(code >= 0x2b05 && code <= 0x2b07) || // Arrows\n\t\t(code >= 0x2b1b && code <= 0x2b1c) || // Squares\n\t\tcode === 0x2b50 || // Star\n\t\tcode === 0x2b55 || // Circle\n\t\t(code >= 0x2e80 && code <= 0x303e) || // CJK Radicals, Symbols, Punctuation\n\t\t(code >= 0x3040 && code <= 0x309f) || // Hiragana\n\t\t(code >= 0x30a0 && code <= 0x30ff) || // Katakana\n\t\t(code >= 0x3105 && code <= 0x312f) || // Bopomofo\n\t\t(code >= 0x3131 && code <= 0x318e) || // Hangul Compatibility Jamo\n\t\t(code >= 0x3190 && code <= 0x31e3) || // Kanbun, CJK Strokes\n\t\t(code >= 0x31f0 && code <= 0x321e) || // Katakana Phonetic Extensions\n\t\t(code >= 0x3220 && code <= 0x3247) || // Enclosed CJK\n\t\t(code >= 0x3250 && code <= 0x4dbf) || // CJK Extensions + Unified block\n\t\t(code >= 0x4e00 && code <= 0x9fff) || // CJK Unified Ideographs\n\t\t(code >= 0xa960 && code <= 0xa97c) || // Hangul Jamo Extended-A\n\t\t(code >= 0xac00 && code <= 0xd7a3) || // Hangul Syllables\n\t\t(code >= 0xf900 && code <= 0xfaff) || // CJK Compatibility Ideographs\n\t\t(code >= 0xfe10 && code <= 0xfe19) || // Vertical forms\n\t\t(code >= 0xfe30 && code <= 0xfe6b) || // CJK Compatibility Forms\n\t\t(code >= 0xff01 && code <= 0xff60) || // Fullwidth Forms (excl. halfwidth)\n\t\t(code >= 0xffe0 && code <= 0xffe6) || // Fullwidth Signs\n\t\t(code >= 0x1f004 && code === 0x1f004) || // Mahjong Red Dragon\n\t\tcode === 0x1f0cf || // Joker\n\t\t(code >= 0x1f170 && code <= 0x1f171) || // A/B buttons\n\t\tcode === 0x1f17e || // O button\n\t\tcode === 0x1f17f || // P button\n\t\tcode === 0x1f18e || // AB button\n\t\t(code >= 0x1f191 && code <= 0x1f19a) || // Squared symbols\n\t\t(code >= 0x1f1e0 && code <= 0x1f1ff) || // Regional Indicator Symbols\n\t\t(code >= 0x1f200 && code <= 0x1f202) || // Enclosed ideographic\n\t\tcode === 0x1f21a || // Squared CJK\n\t\tcode === 0x1f22f || // Squared CJK\n\t\t(code >= 0x1f232 && code <= 0x1f23a) || // Squared CJK\n\t\t(code >= 0x1f250 && code <= 0x1f251) || // Circled ideographic\n\t\t(code >= 0x1f300 && code <= 0x1f9ff) || // Misc Symbols / Emoticons / Emoji\n\t\t(code >= 0x1fa00 && code <= 0x1faff) || // Chess, Symbols Extended-A\n\t\t(code >= 0x1fb00 && code <= 0x1fbff) || // Symbols for Legacy Computing\n\t\t(code >= 0x20000 && code <= 0x2fffd) || // CJK Extension B-F (excl. nonchars)\n\t\t(code >= 0x30000 && code <= 0x3fffd) // CJK Extension G+ (excl. nonchars)\n\t) {\n\t\treturn 2;\n\t}\n\treturn 1;\n}\n\n/**\n * Count total display cells for a string in a monospace terminal.\n *\n * Combining marks contribute 0 cells; CJK / fullwidth contribute 2.\n * Does not handle ZWJ emoji sequences.\n */\nexport function countCells(text: string): number {\n\tlet cells = 0;\n\tfor (const ch of text) {\n\t\tcells += cellWidth(ch.codePointAt(0)!);\n\t}\n\treturn cells;\n}\n\n/**\n * Truncate `text` to at most `maxCells` terminal cells, appending an ellipsis\n * (\"…\" → 1 cell) when truncation occurs. Grapheme-unaware — splits at\n * codepoints; ZWJ sequences may be cut mid-cluster.\n */\nexport function truncateToCells(text: string, maxCells: number): string {\n\tif (maxCells <= 0) return \"\";\n\tlet cells = 0;\n\tlet out = \"\";\n\tfor (const ch of text) {\n\t\tconst w = cellWidth(ch.codePointAt(0)!);\n\t\tif (cells + w > maxCells) {\n\t\t\tif (maxCells <= 1) return \"…\";\n\t\t\t// Drop last wide char if we'd exceed budget with the ellipsis\n\t\t\twhile (cells + 1 > maxCells && out.length > 0) {\n\t\t\t\tconst last = [...out].pop()!;\n\t\t\t\tout = out.slice(0, -last.length);\n\t\t\t\tcells -= cellWidth(last.codePointAt(0)!);\n\t\t\t}\n\t\t\treturn `${out}…`;\n\t\t}\n\t\tout += ch;\n\t\tcells += w;\n\t}\n\treturn out;\n}\n","/**\n * Character-grid blitter for the ASCII describe renderer.\n *\n * Given a [LayoutResult](./_layout-sugiyama.ts) (boxes + polyline edges on\n * an integer cell grid), produce a newline-joined string using Unicode\n * box-drawing glyphs (or plain ASCII when `charset: \"ascii\"` is requested).\n *\n * Invariants:\n * - Multi-cell CJK labels still count as 2 cells via\n * [_ascii-width.ts](./_ascii-width.ts).\n * - Edge crossings (two segments perpendicular at the same cell) collapse\n * to `┼` / `+`. Corner-vs-line collisions resolve to a corner glyph.\n * - Boxes overwrite edge glyphs — boxes are blitted last so an edge that\n * happens to pass under a box body is hidden.\n */\n\nimport { countCells } from \"./_ascii-width.js\";\nimport type { LayoutBox, LayoutEdge, LayoutResult } from \"./_layout-sugiyama.js\";\n\nexport type AsciiCharset = \"unicode\" | \"ascii\";\n\nexport type GridOptions = {\n\treadonly charset: AsciiCharset;\n\treadonly labelOf: (id: string) => string;\n};\n\ntype Glyphs = {\n\treadonly horizontal: string;\n\treadonly vertical: string;\n\treadonly cornerTL: string;\n\treadonly cornerTR: string;\n\treadonly cornerBL: string;\n\treadonly cornerBR: string;\n\treadonly tDown: string;\n\treadonly tUp: string;\n\treadonly tRight: string;\n\treadonly tLeft: string;\n\treadonly cross: string;\n\treadonly arrowRight: string;\n\treadonly arrowDown: string;\n\treadonly arrowLeft: string;\n\treadonly arrowUp: string;\n\treadonly boxTL: string;\n\treadonly boxTR: string;\n\treadonly boxBL: string;\n\treadonly boxBR: string;\n\treadonly boxH: string;\n\treadonly boxV: string;\n};\n\nconst UNICODE: Glyphs = {\n\thorizontal: \"─\",\n\tvertical: \"│\",\n\tcornerTL: \"┌\",\n\tcornerTR: \"┐\",\n\tcornerBL: \"└\",\n\tcornerBR: \"┘\",\n\ttDown: \"┬\",\n\ttUp: \"┴\",\n\ttRight: \"├\",\n\ttLeft: \"┤\",\n\tcross: \"┼\",\n\tarrowRight: \"▶\",\n\tarrowDown: \"▼\",\n\tarrowLeft: \"◀\",\n\tarrowUp: \"▲\",\n\tboxTL: \"┌\",\n\tboxTR: \"┐\",\n\tboxBL: \"└\",\n\tboxBR: \"┘\",\n\tboxH: \"─\",\n\tboxV: \"│\",\n};\n\nconst ASCII: Glyphs = {\n\thorizontal: \"-\",\n\tvertical: \"|\",\n\tcornerTL: \"+\",\n\tcornerTR: \"+\",\n\tcornerBL: \"+\",\n\tcornerBR: \"+\",\n\ttDown: \"+\",\n\ttUp: \"+\",\n\ttRight: \"+\",\n\ttLeft: \"+\",\n\tcross: \"+\",\n\tarrowRight: \">\",\n\tarrowDown: \"v\",\n\tarrowLeft: \"<\",\n\tarrowUp: \"^\",\n\tboxTL: \"+\",\n\tboxTR: \"+\",\n\tboxBL: \"+\",\n\tboxBR: \"+\",\n\tboxH: \"-\",\n\tboxV: \"|\",\n};\n\n// Set of glyphs considered \"edge lines\" when resolving collisions. A later\n// put() into an edge cell that conflicts produces `cross`; corners and\n// T-junctions are preserved (they carry more information).\ntype CellKind =\n\t| \"empty\"\n\t| \"boxH\"\n\t| \"boxV\"\n\t| \"boxCorner\"\n\t| \"edgeH\"\n\t| \"edgeV\"\n\t| \"edgeCorner\"\n\t| \"arrow\"\n\t| \"label\";\n\nexport function renderGrid(layout: LayoutResult, options: GridOptions): string {\n\tconst glyphs = options.charset === \"ascii\" ? ASCII : UNICODE;\n\tconst width = layout.width;\n\tconst height = layout.height;\n\tconst grid: string[][] = Array.from({ length: height }, () =>\n\t\tArray.from({ length: width }, () => \" \"),\n\t);\n\tconst kind: CellKind[][] = Array.from({ length: height }, () =>\n\t\tArray.from({ length: width }, () => \"empty\" as CellKind),\n\t);\n\n\t// 1. Draw edges first (boxes overwrite).\n\tfor (const edge of layout.edges) {\n\t\tdrawEdge(grid, kind, glyphs, edge);\n\t}\n\n\t// 2. Draw boxes on top.\n\tfor (const box of layout.boxes) {\n\t\tdrawBox(grid, kind, glyphs, box, options.labelOf(box.id));\n\t}\n\n\treturn grid.map((row) => stripTrailing(row.join(\"\"))).join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Box drawing\n// ---------------------------------------------------------------------------\n\nfunction drawBox(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tglyphs: Glyphs,\n\tbox: LayoutBox,\n\tlabel: string,\n): void {\n\tconst { x, y, w, h } = box;\n\tif (w < 2 || h < 2) {\n\t\t// Degenerate — just paint the label.\n\t\tif (h > 0) writeLabel(grid, kind, x, y, w, label);\n\t\treturn;\n\t}\n\t// Top border\n\tputBoxCell(grid, kind, x, y, glyphs.boxTL);\n\tfor (let cx = x + 1; cx < x + w - 1; cx += 1) putBoxCell(grid, kind, cx, y, glyphs.boxH);\n\tputBoxCell(grid, kind, x + w - 1, y, glyphs.boxTR);\n\t// Middle rows — side borders + content (only middle row carries the label)\n\tfor (let cy = y + 1; cy < y + h - 1; cy += 1) {\n\t\tputBoxCell(grid, kind, x, cy, glyphs.boxV);\n\t\tfor (let cx = x + 1; cx < x + w - 1; cx += 1) {\n\t\t\tputBoxCellAs(grid, kind, cx, cy, \" \", \"empty\");\n\t\t}\n\t\tputBoxCell(grid, kind, x + w - 1, cy, glyphs.boxV);\n\t}\n\t// Bottom border\n\tputBoxCell(grid, kind, x, y + h - 1, glyphs.boxBL);\n\tfor (let cx = x + 1; cx < x + w - 1; cx += 1) putBoxCell(grid, kind, cx, y + h - 1, glyphs.boxH);\n\tputBoxCell(grid, kind, x + w - 1, y + h - 1, glyphs.boxBR);\n\t// Label in vertical middle (h >= 3 expected)\n\tconst midY = y + Math.floor(h / 2);\n\twriteLabel(grid, kind, x + 1, midY, w - 2, label);\n}\n\nfunction putBoxCell(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tx: number,\n\ty: number,\n\tglyph: string,\n): void {\n\tconst k: CellKind =\n\t\tglyph === \" \"\n\t\t\t? \"empty\"\n\t\t\t: glyph === \"─\" || glyph === \"-\"\n\t\t\t\t? \"boxH\"\n\t\t\t\t: glyph === \"│\" || glyph === \"|\"\n\t\t\t\t\t? \"boxV\"\n\t\t\t\t\t: \"boxCorner\";\n\tputBoxCellAs(grid, kind, x, y, glyph, k);\n}\n\nfunction putBoxCellAs(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tx: number,\n\ty: number,\n\tglyph: string,\n\tk: CellKind,\n): void {\n\tif (y < 0 || y >= grid.length) return;\n\tconst row = grid[y]!;\n\tif (x < 0 || x >= row.length) return;\n\trow[x] = glyph;\n\tkind[y]![x] = k;\n}\n\nfunction writeLabel(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tx: number,\n\ty: number,\n\tmaxWidthCells: number,\n\tlabel: string,\n): void {\n\t// The grid is cell-indexed (one array slot per terminal cell). Wide\n\t// characters (CJK, fullwidth) occupy TWO cells visually; we store the\n\t// char in the first slot and an empty string in the second slot so\n\t// join(\"\") collapses to a single visible wide glyph and neighboring\n\t// writes don't add spurious narrow spaces next to the wide char.\n\tif (y < 0 || y >= grid.length) return;\n\tlet cursor = x;\n\tlet cellsLeft = maxWidthCells;\n\tfor (const ch of label) {\n\t\tconst cw = countCells(ch);\n\t\tif (cw === 0) continue;\n\t\tif (cellsLeft < cw) break;\n\t\tif (cursor >= 0 && cursor < grid[y]!.length) {\n\t\t\tgrid[y]![cursor] = ch;\n\t\t\tkind[y]![cursor] = \"label\";\n\t\t\tif (cw === 2 && cursor + 1 < grid[y]!.length) {\n\t\t\t\tgrid[y]![cursor + 1] = \"\";\n\t\t\t\tkind[y]![cursor + 1] = \"label\";\n\t\t\t}\n\t\t}\n\t\tcursor += cw;\n\t\tcellsLeft -= cw;\n\t}\n\t// Pad remaining cells with spaces so any edge glyphs lurking under the\n\t// box body don't leak into the label row.\n\twhile (cellsLeft > 0) {\n\t\tif (cursor >= 0 && cursor < grid[y]!.length) {\n\t\t\tgrid[y]![cursor] = \" \";\n\t\t\tkind[y]![cursor] = \"empty\";\n\t\t}\n\t\tcursor += 1;\n\t\tcellsLeft -= 1;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Edge drawing\n// ---------------------------------------------------------------------------\n\nfunction drawEdge(grid: string[][], kind: CellKind[][], glyphs: Glyphs, edge: LayoutEdge): void {\n\tconst pts = edge.points;\n\tif (pts.length < 2) return;\n\t// Draw segments\n\tfor (let i = 0; i + 1 < pts.length; i += 1) {\n\t\tdrawSegment(grid, kind, glyphs, pts[i]!, pts[i + 1]!);\n\t}\n\t// Draw corners at interior points\n\tfor (let i = 1; i + 1 < pts.length; i += 1) {\n\t\tconst a = pts[i - 1]!;\n\t\tconst b = pts[i]!;\n\t\tconst c = pts[i + 1]!;\n\t\tconst corner = cornerGlyph(a, b, c, glyphs);\n\t\tif (corner) putEdgeCell(grid, kind, b.x, b.y, corner, \"edgeCorner\");\n\t}\n\t// Arrow tip at the final point, aimed from the penultimate point.\n\t// Four cardinal directions — covers backward and upward tips produced\n\t// by routing past virtual nodes or dense-gutter fallbacks.\n\tconst tip = pts[pts.length - 1]!;\n\tconst prev = pts[pts.length - 2]!;\n\tconst arrow = arrowGlyph(prev, tip, glyphs);\n\tif (arrow) putEdgeCell(grid, kind, tip.x, tip.y, arrow, \"arrow\");\n}\n\nfunction drawSegment(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tglyphs: Glyphs,\n\ta: { x: number; y: number },\n\tb: { x: number; y: number },\n): void {\n\tif (a.x === b.x && a.y === b.y) return;\n\tif (a.y === b.y) {\n\t\t// Horizontal\n\t\tconst y = a.y;\n\t\tconst x0 = Math.min(a.x, b.x);\n\t\tconst x1 = Math.max(a.x, b.x);\n\t\tfor (let x = x0; x <= x1; x += 1) {\n\t\t\tputEdgeLine(grid, kind, x, y, glyphs, \"h\");\n\t\t}\n\t} else if (a.x === b.x) {\n\t\t// Vertical\n\t\tconst x = a.x;\n\t\tconst y0 = Math.min(a.y, b.y);\n\t\tconst y1 = Math.max(a.y, b.y);\n\t\tfor (let y = y0; y <= y1; y += 1) {\n\t\t\tputEdgeLine(grid, kind, x, y, glyphs, \"v\");\n\t\t}\n\t}\n\t// Diagonal shouldn't happen — routing is orthogonal.\n}\n\nfunction putEdgeLine(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tx: number,\n\ty: number,\n\tglyphs: Glyphs,\n\torientation: \"h\" | \"v\",\n): void {\n\tif (y < 0 || y >= grid.length) return;\n\tconst row = grid[y]!;\n\tif (x < 0 || x >= row.length) return;\n\tconst existing = kind[y]![x];\n\tif (\n\t\texisting === \"boxH\" ||\n\t\texisting === \"boxV\" ||\n\t\texisting === \"boxCorner\" ||\n\t\texisting === \"label\"\n\t) {\n\t\t// Box wins — do nothing. Boxes are drawn after edges, but if order\n\t\t// is reversed the edge must not clobber the box.\n\t\treturn;\n\t}\n\tif (existing === \"empty\") {\n\t\trow[x] = orientation === \"h\" ? glyphs.horizontal : glyphs.vertical;\n\t\tkind[y]![x] = orientation === \"h\" ? \"edgeH\" : \"edgeV\";\n\t\treturn;\n\t}\n\tif (existing === \"edgeH\" && orientation === \"v\") {\n\t\trow[x] = glyphs.cross;\n\t\tkind[y]![x] = \"edgeCorner\";\n\t\treturn;\n\t}\n\tif (existing === \"edgeV\" && orientation === \"h\") {\n\t\trow[x] = glyphs.cross;\n\t\tkind[y]![x] = \"edgeCorner\";\n\t\treturn;\n\t}\n\t// Same-orientation overlay: keep existing glyph.\n}\n\nfunction putEdgeCell(\n\tgrid: string[][],\n\tkind: CellKind[][],\n\tx: number,\n\ty: number,\n\tglyph: string,\n\tk: CellKind,\n): void {\n\tif (y < 0 || y >= grid.length) return;\n\tconst row = grid[y]!;\n\tif (x < 0 || x >= row.length) return;\n\tconst existing = kind[y]![x];\n\tif (\n\t\texisting === \"boxH\" ||\n\t\texisting === \"boxV\" ||\n\t\texisting === \"boxCorner\" ||\n\t\texisting === \"label\"\n\t)\n\t\treturn;\n\trow[x] = glyph;\n\tkind[y]![x] = k;\n}\n\n// ---------------------------------------------------------------------------\n// Corner + arrow glyph selection\n// ---------------------------------------------------------------------------\n\nfunction cornerGlyph(\n\ta: { x: number; y: number },\n\tb: { x: number; y: number },\n\tc: { x: number; y: number },\n\tglyphs: Glyphs,\n): string | undefined {\n\tconst inHoriz = a.y === b.y;\n\tconst outHoriz = b.y === c.y;\n\tif (inHoriz === outHoriz) return undefined; // not a turn\n\t// In from horizontal, out to vertical (or vice versa). Figure out which\n\t// of the four corners we're at.\n\tif (inHoriz) {\n\t\t// Coming from the left (a.x < b.x) or right (a.x > b.x)\n\t\tconst fromLeft = a.x < b.x;\n\t\tconst goingDown = c.y > b.y;\n\t\tif (fromLeft && goingDown) return glyphs.cornerTR;\n\t\tif (fromLeft && !goingDown) return glyphs.cornerBR;\n\t\tif (!fromLeft && goingDown) return glyphs.cornerTL;\n\t\treturn glyphs.cornerBL;\n\t}\n\t// Vertical in, horizontal out\n\tconst fromAbove = a.y < b.y;\n\tconst goingRight = c.x > b.x;\n\tif (fromAbove && goingRight) return glyphs.cornerBL;\n\tif (fromAbove && !goingRight) return glyphs.cornerBR;\n\tif (!fromAbove && goingRight) return glyphs.cornerTL;\n\treturn glyphs.cornerTR;\n}\n\nfunction arrowGlyph(\n\tprev: { x: number; y: number },\n\ttip: { x: number; y: number },\n\tglyphs: Glyphs,\n): string | undefined {\n\tif (tip.x > prev.x) return glyphs.arrowRight;\n\tif (tip.x < prev.x) return glyphs.arrowLeft;\n\tif (tip.y > prev.y) return glyphs.arrowDown;\n\tif (tip.y < prev.y) return glyphs.arrowUp;\n\treturn undefined; // zero-length segment — no tip\n}\n\n// ---------------------------------------------------------------------------\n// Output trimming\n// ---------------------------------------------------------------------------\n\nfunction stripTrailing(line: string): string {\n\t// Trim trailing spaces only; preserve internal grid alignment.\n\tlet end = line.length;\n\twhile (end > 0 && line.charCodeAt(end - 1) === 32) end -= 1;\n\treturn line.slice(0, end);\n}\n","/**\n * Sugiyama-style layered DAG layout on an integer grid.\n *\n * Pipeline:\n * 1. Longest-path layer assignment (sources at layer 0).\n * 2. Virtual-node splitting — every edge spanning more than one layer\n * becomes a chain of synthetic nodes on intermediate layers. Downstream\n * passes treat real and virtual nodes identically; crossing\n * minimization therefore works on wide + deep DAGs, not only\n * adjacent-layer cases.\n * 3. Crossing minimization — barycenter heuristic with alternating up /\n * down sweeps plus an adjacent-transposition polish pass.\n * 4. Coordinate assignment — greedy median-aligned packing with collision\n * resolution. Straightens vertical runs of virtual nodes so long edges\n * become straight lines where topology allows.\n * 5. Orthogonal edge routing — per-gutter x-track assignment; horizontal\n * segments sit at endpoint centerlines, vertical segments pack into the\n * gutter column range without overlap. Remaining crossings are\n * topologically unavoidable and will render as `┼` at draw time.\n *\n * Output coordinates are cell-grid integers (LR direction). TD rendering\n * swaps axes at draw time — the layout is direction-agnostic by\n * construction.\n *\n * Used only by [graph-spec-to-ascii.ts](./graph-spec-to-ascii.ts); not part of the public\n * `extra/render/index.ts` surface (underscore-prefixed).\n */\n\nexport type LayoutDirection = \"LR\" | \"TD\";\n\nexport type LayoutInput = {\n\t/** Node ids in stable iteration order. Determines initial tie-break. */\n\treadonly nodes: readonly string[];\n\t/** Edges by (from, to) path. Endpoints must be present in `nodes`. */\n\treadonly edges: ReadonlyArray<{ from: string; to: string }>;\n\t/** Label width in cells for each node (independent of direction). */\n\treadonly widthCells: (id: string) => number;\n\t/** Label height in cells for each node (independent of direction). */\n\treadonly heightCells: (id: string) => number;\n\t/**\n\t * Gap between layer \"columns\" (LR) or \"rows\" (TD), in cells.\n\t * Must allow enough room for per-gutter edge tracks.\n\t */\n\treadonly layerGap: number;\n\t/**\n\t * Gap between neighboring nodes *within* a layer, in cells.\n\t * LR: vertical gap; TD: horizontal gap.\n\t */\n\treadonly nodeGap: number;\n\t/**\n\t * Axis orientation. LR: layers = columns (x grows), order = rows (y grows).\n\t * TD: layers = rows (y grows), order = columns (x grows).\n\t */\n\treadonly direction: LayoutDirection;\n};\n\nexport type LayoutBox = {\n\treadonly id: string;\n\treadonly layer: number;\n\treadonly order: number;\n\treadonly x: number;\n\treadonly y: number;\n\treadonly w: number;\n\treadonly h: number;\n};\n\nexport type LayoutEdgePoint = { readonly x: number; readonly y: number };\n\nexport type LayoutEdge = {\n\treadonly from: string;\n\treadonly to: string;\n\t/** Polyline of waypoints (start → corners → end). Minimum 2 entries. */\n\treadonly points: readonly LayoutEdgePoint[];\n};\n\nexport type LayoutResult = {\n\treadonly boxes: readonly LayoutBox[];\n\treadonly edges: readonly LayoutEdge[];\n\treadonly width: number;\n\treadonly height: number;\n};\n\n// ---------------------------------------------------------------------------\n// Internal types — carried through the pipeline\n// ---------------------------------------------------------------------------\n\ntype Hop = {\n\tchainId: number;\n\tchainFrom: string;\n\tchainTo: string;\n\tfromId: string;\n\ttoId: string;\n\t/** 0-based hop index along the chain. */\n\thopIndex: number;\n\t/** Total hops in the chain (1 = direct, 2+ = spans virtuals). */\n\tchainLen: number;\n};\n\ntype InternalNode = {\n\tid: string;\n\tisVirtual: boolean;\n\tlayer: number;\n\torder: number;\n\tx: number;\n\ty: number;\n\tw: number;\n\th: number;\n\tin: Hop[];\n\tout: Hop[];\n};\n\ntype Layer = InternalNode[];\n\ntype PipelineState = {\n\tnodes: Map<string, InternalNode>;\n\tlayers: Layer[];\n\thops: Hop[];\n};\n\n// ---------------------------------------------------------------------------\n// Pipeline entry\n// ---------------------------------------------------------------------------\n\nexport function sugiyamaLayout(input: LayoutInput): LayoutResult {\n\tconst state = buildInitial(input);\n\tassignLayers(state);\n\tinsertVirtualNodes(state);\n\tminimizeCrossings(state);\n\tassignCoordinates(state, input);\n\tconst edges = routeEdges(state, input);\n\tconst { width, height } = boundingBox(state);\n\tconst boxes: LayoutBox[] = [];\n\tfor (const layer of state.layers) {\n\t\tfor (const n of layer) {\n\t\t\tif (n.isVirtual) continue;\n\t\t\tboxes.push({\n\t\t\t\tid: n.id,\n\t\t\t\tlayer: n.layer,\n\t\t\t\torder: n.order,\n\t\t\t\tx: n.x,\n\t\t\t\ty: n.y,\n\t\t\t\tw: n.w,\n\t\t\t\th: n.h,\n\t\t\t});\n\t\t}\n\t}\n\treturn { boxes, edges, width, height };\n}\n\n// ---------------------------------------------------------------------------\n// 1. Build internal graph\n// ---------------------------------------------------------------------------\n\nfunction buildInitial(input: LayoutInput): PipelineState {\n\tconst nodes = new Map<string, InternalNode>();\n\tfor (const id of input.nodes) {\n\t\tnodes.set(id, {\n\t\t\tid,\n\t\t\tisVirtual: false,\n\t\t\tlayer: -1,\n\t\t\torder: 0,\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tw: input.widthCells(id),\n\t\t\th: input.heightCells(id),\n\t\t\tin: [],\n\t\t\tout: [],\n\t\t});\n\t}\n\tconst hops: Hop[] = [];\n\tlet chainId = 0;\n\tfor (const e of input.edges) {\n\t\tif (e.from === e.to) continue; // drop self-loops\n\t\tconst f = nodes.get(e.from);\n\t\tconst t = nodes.get(e.to);\n\t\tif (!f || !t) continue; // drop dangling endpoints\n\t\tconst hop: Hop = {\n\t\t\tchainId: chainId++,\n\t\t\tchainFrom: e.from,\n\t\t\tchainTo: e.to,\n\t\t\tfromId: e.from,\n\t\t\ttoId: e.to,\n\t\t\thopIndex: 0,\n\t\t\tchainLen: 1,\n\t\t};\n\t\tf.out.push(hop);\n\t\tt.in.push(hop);\n\t\thops.push(hop);\n\t}\n\treturn { nodes, layers: [], hops };\n}\n\n// ---------------------------------------------------------------------------\n// 2. Longest-path layer assignment (Kahn's algorithm)\n// ---------------------------------------------------------------------------\n\nfunction assignLayers(state: PipelineState): void {\n\tconst indeg = new Map<string, number>();\n\tfor (const n of state.nodes.values()) indeg.set(n.id, n.in.length);\n\n\tconst queue: InternalNode[] = [];\n\tfor (const n of state.nodes.values()) {\n\t\tif ((indeg.get(n.id) ?? 0) === 0) {\n\t\t\tn.layer = 0;\n\t\t\tqueue.push(n);\n\t\t}\n\t}\n\n\t// Cursor-based BFS — `Array.prototype.shift` is O(n), so the naive form\n\t// is O(n²) and degrades past ~1000 nodes. Cursor keeps it linear.\n\tconst visited = new Set<string>();\n\tlet head = 0;\n\twhile (head < queue.length) {\n\t\tconst n = queue[head++]!;\n\t\tif (visited.has(n.id)) continue;\n\t\tvisited.add(n.id);\n\t\tfor (const hop of n.out) {\n\t\t\tconst t = state.nodes.get(hop.toId)!;\n\t\t\tt.layer = Math.max(t.layer, n.layer + 1);\n\t\t\tconst d = (indeg.get(t.id) ?? 0) - 1;\n\t\t\tindeg.set(t.id, d);\n\t\t\tif (d <= 0) queue.push(t);\n\t\t}\n\t}\n\t// Nodes trapped in a cycle default to layer 0. The edges that would\n\t// close the cycle are dropped in `insertVirtualNodes` (any hop whose\n\t// span is not a positive integer). GraphReFly graphs are DAGs by spec;\n\t// this path is defensive against malformed describe snapshots.\n\tfor (const n of state.nodes.values()) if (n.layer < 0) n.layer = 0;\n}\n\n// ---------------------------------------------------------------------------\n// 3. Virtual-node insertion — critical for scaling past adjacent-layer edges\n// ---------------------------------------------------------------------------\n\nfunction insertVirtualNodes(state: PipelineState): void {\n\tconst maxLayer = Math.max(0, ...Array.from(state.nodes.values(), (n) => n.layer));\n\tconst layers: Layer[] = Array.from({ length: maxLayer + 1 }, () => []);\n\tfor (const n of state.nodes.values()) layers[n.layer]!.push(n);\n\n\tconst newHops: Hop[] = [];\n\tlet virtCounter = 0;\n\tfor (const hop of state.hops) {\n\t\tconst f = state.nodes.get(hop.fromId)!;\n\t\tconst t = state.nodes.get(hop.toId)!;\n\t\tconst span = t.layer - f.layer;\n\t\tif (span <= 0) {\n\t\t\t// Same-layer or back-edge — the input violated the DAG invariant\n\t\t\t// (self-loop was already dropped in `buildInitial`; this catches\n\t\t\t// cycles whose nodes collapsed to layer 0 in `assignLayers`).\n\t\t\t// Drop from both endpoints so routing never sees the hop; same\n\t\t\t// render-best-effort policy as the self-loop / dangling-endpoint\n\t\t\t// filters in `buildInitial`.\n\t\t\tf.out = f.out.filter((h) => h !== hop);\n\t\t\tt.in = t.in.filter((h) => h !== hop);\n\t\t\tcontinue;\n\t\t}\n\t\tif (span === 1) {\n\t\t\thop.hopIndex = 0;\n\t\t\thop.chainLen = 1;\n\t\t\tnewHops.push(hop);\n\t\t\tcontinue;\n\t\t}\n\t\t// Multi-hop: f → v1 → v2 → ... → t\n\t\t// Detach the original edge from f.out / t.in; we rewrite as chain.\n\t\tf.out = f.out.filter((h) => h !== hop);\n\t\tt.in = t.in.filter((h) => h !== hop);\n\n\t\tlet prev = f;\n\t\tfor (let i = 1; i < span; i += 1) {\n\t\t\tconst vid = `__virt_${virtCounter++}__`;\n\t\t\tconst v: InternalNode = {\n\t\t\t\tid: vid,\n\t\t\t\tisVirtual: true,\n\t\t\t\tlayer: f.layer + i,\n\t\t\t\torder: 0,\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\tw: 0,\n\t\t\t\th: 1,\n\t\t\t\tin: [],\n\t\t\t\tout: [],\n\t\t\t};\n\t\t\tstate.nodes.set(vid, v);\n\t\t\tlayers[v.layer]!.push(v);\n\t\t\tconst h: Hop = {\n\t\t\t\tchainId: hop.chainId,\n\t\t\t\tchainFrom: hop.chainFrom,\n\t\t\t\tchainTo: hop.chainTo,\n\t\t\t\tfromId: prev.id,\n\t\t\t\ttoId: vid,\n\t\t\t\thopIndex: i - 1,\n\t\t\t\tchainLen: span,\n\t\t\t};\n\t\t\tprev.out.push(h);\n\t\t\tv.in.push(h);\n\t\t\tnewHops.push(h);\n\t\t\tprev = v;\n\t\t}\n\t\tconst finalHop: Hop = {\n\t\t\tchainId: hop.chainId,\n\t\t\tchainFrom: hop.chainFrom,\n\t\t\tchainTo: hop.chainTo,\n\t\t\tfromId: prev.id,\n\t\t\ttoId: t.id,\n\t\t\thopIndex: span - 1,\n\t\t\tchainLen: span,\n\t\t};\n\t\tprev.out.push(finalHop);\n\t\tt.in.push(finalHop);\n\t\tnewHops.push(finalHop);\n\t}\n\n\t// Stable initial order within each layer.\n\tfor (const layer of layers) {\n\t\tfor (let i = 0; i < layer.length; i += 1) layer[i]!.order = i;\n\t}\n\tstate.layers = layers;\n\tstate.hops = newHops;\n}\n\n// ---------------------------------------------------------------------------\n// 4. Crossing minimization\n// ---------------------------------------------------------------------------\n\nfunction minimizeCrossings(state: PipelineState): void {\n\tconst SWEEPS = 4;\n\tfor (let sweep = 0; sweep < SWEEPS; sweep += 1) {\n\t\t// Down-sweep\n\t\tfor (let li = 1; li < state.layers.length; li += 1) {\n\t\t\tsortByBarycenter(state, state.layers[li]!, \"in\");\n\t\t\treindex(state.layers[li]!);\n\t\t}\n\t\t// Up-sweep\n\t\tfor (let li = state.layers.length - 2; li >= 0; li -= 1) {\n\t\t\tsortByBarycenter(state, state.layers[li]!, \"out\");\n\t\t\treindex(state.layers[li]!);\n\t\t}\n\t}\n\t// Polish — adjacent-transposition pass, bounded iterations.\n\tfor (let iter = 0; iter < 2; iter += 1) {\n\t\tlet improved = false;\n\t\tfor (let li = 1; li < state.layers.length; li += 1) {\n\t\t\tconst layer = state.layers[li]!;\n\t\t\tfor (let i = 0; i + 1 < layer.length; i += 1) {\n\t\t\t\tconst before = pairCrossings(state, layer[i]!, layer[i + 1]!, \"in\");\n\t\t\t\t[layer[i], layer[i + 1]] = [layer[i + 1]!, layer[i]!];\n\t\t\t\treindex(layer);\n\t\t\t\tconst after = pairCrossings(state, layer[i]!, layer[i + 1]!, \"in\");\n\t\t\t\tif (after < before) {\n\t\t\t\t\timproved = true;\n\t\t\t\t} else {\n\t\t\t\t\t[layer[i], layer[i + 1]] = [layer[i + 1]!, layer[i]!];\n\t\t\t\t\treindex(layer);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!improved) break;\n\t}\n}\n\nfunction sortByBarycenter(state: PipelineState, layer: Layer, direction: \"in\" | \"out\"): void {\n\tconst bary = new Map<string, number>();\n\tfor (const n of layer) {\n\t\tconst neighbors = direction === \"in\" ? n.in : n.out;\n\t\tif (neighbors.length === 0) {\n\t\t\tbary.set(n.id, n.order);\n\t\t\tcontinue;\n\t\t}\n\t\tlet sum = 0;\n\t\tlet count = 0;\n\t\tfor (const h of neighbors) {\n\t\t\tconst other = state.nodes.get(direction === \"in\" ? h.fromId : h.toId);\n\t\t\tif (!other) continue;\n\t\t\tsum += other.order;\n\t\t\tcount += 1;\n\t\t}\n\t\tbary.set(n.id, count === 0 ? n.order : sum / count);\n\t}\n\tlayer.sort((a, b) => {\n\t\tconst ba = bary.get(a.id)!;\n\t\tconst bb = bary.get(b.id)!;\n\t\tif (ba !== bb) return ba - bb;\n\t\treturn a.order - b.order;\n\t});\n}\n\nfunction reindex(layer: Layer): void {\n\tfor (let i = 0; i < layer.length; i += 1) layer[i]!.order = i;\n}\n\nfunction pairCrossings(\n\tstate: PipelineState,\n\ta: InternalNode,\n\tb: InternalNode,\n\tdirection: \"in\" | \"out\",\n): number {\n\tconst aEdges = direction === \"in\" ? a.in : a.out;\n\tconst bEdges = direction === \"in\" ? b.in : b.out;\n\tlet crossings = 0;\n\tfor (const ea of aEdges) {\n\t\tfor (const eb of bEdges) {\n\t\t\tconst oa = state.nodes.get(direction === \"in\" ? ea.fromId : ea.toId)?.order ?? 0;\n\t\t\tconst ob = state.nodes.get(direction === \"in\" ? eb.fromId : eb.toId)?.order ?? 0;\n\t\t\tif ((a.order < b.order && oa > ob) || (a.order > b.order && oa < ob)) {\n\t\t\t\tcrossings += 1;\n\t\t\t}\n\t\t}\n\t}\n\treturn crossings;\n}\n\n// ---------------------------------------------------------------------------\n// 5. Coordinate assignment (direction-aware)\n// ---------------------------------------------------------------------------\n\nfunction assignCoordinates(state: PipelineState, input: LayoutInput): void {\n\tif (input.direction === \"LR\") assignCoordinatesLR(state, input);\n\telse assignCoordinatesTD(state, input);\n}\n\nfunction assignCoordinatesLR(state: PipelineState, input: LayoutInput): void {\n\t// x: per-layer column based on cumulative max width.\n\tconst layerX: number[] = [];\n\tlet cursorX = 0;\n\tfor (let li = 0; li < state.layers.length; li += 1) {\n\t\tlayerX.push(cursorX);\n\t\tlet maxW = 0;\n\t\tfor (const n of state.layers[li]!) maxW = Math.max(maxW, n.w);\n\t\tcursorX += maxW + input.layerGap;\n\t}\n\tfor (let li = 0; li < state.layers.length; li += 1) {\n\t\tfor (const n of state.layers[li]!) n.x = layerX[li]!;\n\t}\n\t// y: greedy pack per layer.\n\tfor (const layer of state.layers) {\n\t\tlet y = 0;\n\t\tfor (const n of layer) {\n\t\t\tn.y = y;\n\t\t\ty += n.h + input.nodeGap;\n\t\t}\n\t}\n\t// Median alignment — straightens chains through virtuals.\n\trunMedianPasses(state, input, \"y\");\n}\n\nfunction assignCoordinatesTD(state: PipelineState, input: LayoutInput): void {\n\t// y: per-layer row based on cumulative max height.\n\tconst layerY: number[] = [];\n\tlet cursorY = 0;\n\tfor (let li = 0; li < state.layers.length; li += 1) {\n\t\tlayerY.push(cursorY);\n\t\tlet maxH = 0;\n\t\tfor (const n of state.layers[li]!) maxH = Math.max(maxH, n.h);\n\t\tcursorY += maxH + input.layerGap;\n\t}\n\tfor (let li = 0; li < state.layers.length; li += 1) {\n\t\tfor (const n of state.layers[li]!) n.y = layerY[li]!;\n\t}\n\t// x: greedy pack per layer.\n\tfor (const layer of state.layers) {\n\t\tlet x = 0;\n\t\tfor (const n of layer) {\n\t\t\tn.x = x;\n\t\t\tx += n.w + input.nodeGap;\n\t\t}\n\t}\n\trunMedianPasses(state, input, \"x\");\n}\n\n/**\n * Median alignment passes — pulls each node toward the median position of\n * its in-layer neighbors along the private axis (\"y\" for LR, \"x\" for TD),\n * then resolves collisions greedily while preserving layer order.\n */\nfunction runMedianPasses(state: PipelineState, input: LayoutInput, axis: \"x\" | \"y\"): void {\n\tconst sizeOf = (n: InternalNode) => (axis === \"y\" ? n.h : n.w);\n\tconst gap = input.nodeGap;\n\tfor (let pass = 0; pass < 2; pass += 1) {\n\t\tconst walk = pass === 0 ? state.layers.slice(1) : state.layers.slice(0, -1).reverse();\n\t\tfor (const layer of walk) {\n\t\t\tconst preferred = new Map<string, number>();\n\t\t\tfor (const n of layer) {\n\t\t\t\tconst neighbors = pass === 0 ? n.in : n.out;\n\t\t\t\tif (neighbors.length === 0) continue;\n\t\t\t\tconst centers: number[] = [];\n\t\t\t\tfor (const h of neighbors) {\n\t\t\t\t\tconst other = state.nodes.get(pass === 0 ? h.fromId : h.toId);\n\t\t\t\t\tif (!other) continue;\n\t\t\t\t\tconst base = axis === \"y\" ? other.y : other.x;\n\t\t\t\t\tcenters.push(base + Math.floor(sizeOf(other) / 2));\n\t\t\t\t}\n\t\t\t\tif (centers.length === 0) continue;\n\t\t\t\tcenters.sort((a, b) => a - b);\n\t\t\t\tconst mid = centers[Math.floor(centers.length / 2)]!;\n\t\t\t\tpreferred.set(n.id, mid - Math.floor(sizeOf(n) / 2));\n\t\t\t}\n\t\t\tlet floor = 0;\n\t\t\tfor (const n of layer) {\n\t\t\t\tconst p = preferred.get(n.id);\n\t\t\t\tconst current = axis === \"y\" ? n.y : n.x;\n\t\t\t\tconst target = p ?? current;\n\t\t\t\tconst clamped = Math.max(target, floor);\n\t\t\t\tif (axis === \"y\") n.y = clamped;\n\t\t\t\telse n.x = clamped;\n\t\t\t\tfloor = clamped + sizeOf(n) + gap;\n\t\t\t}\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// 6. Orthogonal edge routing (direction-aware)\n//\n// For both LR and TD the algorithm is symmetric — it just operates on a\n// different pair of \"primary\" vs \"cross\" axes:\n//\n// LR: primary = x (layer axis); cross = y. Gutters are vertical strips\n// between columns; tracks within a gutter are distinct x-values.\n// TD: primary = y (layer axis); cross = x. Gutters are horizontal strips\n// between rows; tracks within a gutter are distinct y-values.\n// ---------------------------------------------------------------------------\n\nfunction routeEdges(state: PipelineState, input: LayoutInput): LayoutEdge[] {\n\t// Group hops by chainId → one LayoutEdge per user-facing edge.\n\tconst byChain = new Map<number, Hop[]>();\n\tfor (const h of state.hops) {\n\t\tconst arr = byChain.get(h.chainId);\n\t\tif (arr) arr.push(h);\n\t\telse byChain.set(h.chainId, [h]);\n\t}\n\tfor (const arr of byChain.values()) arr.sort((a, b) => a.hopIndex - b.hopIndex);\n\n\tconst isLR = input.direction === \"LR\";\n\tconst primary = (n: InternalNode): number => (isLR ? n.x : n.y);\n\tconst primarySize = (n: InternalNode): number => (isLR ? n.w : n.h);\n\tconst crossCenter = (n: InternalNode): number =>\n\t\tisLR ? n.y + Math.floor(n.h / 2) : n.x + Math.floor(n.w / 2);\n\n\t// Per-gutter cross-axis track assignment. Two passes:\n\t// 1. Assign each hop to a track INDEX using disjoint-interval packing\n\t// (an existing track may host multiple hops as long as their\n\t// cross-axis ranges don't overlap pairwise).\n\t// 2. Map each track index to a primary-axis position using the final\n\t// track count so the distribution is uniform across the gutter —\n\t// per-hop recomputation (old behavior) collapsed late tracks onto\n\t// `gEnd`, producing bundled overlaps in dense gutters.\n\tconst hopTrackCross = new Map<Hop, number>();\n\tfor (let g = 0; g + 1 < state.layers.length; g += 1) {\n\t\tconst srcLayer = state.layers[g]!;\n\t\tconst dstLayer = state.layers[g + 1]!;\n\n\t\tlet gutterStart = 0;\n\t\tfor (const n of srcLayer) gutterStart = Math.max(gutterStart, primary(n) + primarySize(n));\n\t\tlet gutterEnd = Number.POSITIVE_INFINITY;\n\t\tfor (const n of dstLayer) gutterEnd = Math.min(gutterEnd, primary(n));\n\t\tconst gEnd = Number.isFinite(gutterEnd) ? (gutterEnd as number) - 1 : gutterStart;\n\t\tconst gutterWidth = Math.max(1, gEnd - gutterStart + 1);\n\n\t\tconst gutterHops: Hop[] = [];\n\t\tfor (const n of srcLayer) for (const h of n.out) gutterHops.push(h);\n\t\tgutterHops.sort((a, b) => {\n\t\t\tconst sa = crossCenter(state.nodes.get(a.fromId)!);\n\t\t\tconst sb = crossCenter(state.nodes.get(b.fromId)!);\n\t\t\tif (sa !== sb) return sa - sb;\n\t\t\tconst da = crossCenter(state.nodes.get(a.toId)!);\n\t\t\tconst db = crossCenter(state.nodes.get(b.toId)!);\n\t\t\treturn da - db;\n\t\t});\n\n\t\t// Pass 1: assign track indexes. Each track is an ARRAY of disjoint\n\t\t// intervals — two hops share a track iff their cross-axis ranges\n\t\t// don't overlap any existing interval on that track.\n\t\tconst tracks: Array<Array<{ lo: number; hi: number }>> = [];\n\t\tconst hopToTrackIdx = new Map<Hop, number>();\n\t\tfor (const h of gutterHops) {\n\t\t\tconst sc = crossCenter(state.nodes.get(h.fromId)!);\n\t\t\tconst dc = crossCenter(state.nodes.get(h.toId)!);\n\t\t\tconst lo = Math.min(sc, dc);\n\t\t\tconst hi = Math.max(sc, dc);\n\t\t\tlet idx = -1;\n\t\t\tfor (let t = 0; t < tracks.length; t += 1) {\n\t\t\t\tconst intervals = tracks[t]!;\n\t\t\t\tlet fits = true;\n\t\t\t\tfor (const iv of intervals) {\n\t\t\t\t\tif (iv.lo <= hi && lo <= iv.hi) {\n\t\t\t\t\t\tfits = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (fits) {\n\t\t\t\t\tintervals.push({ lo, hi });\n\t\t\t\t\tidx = t;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (idx < 0) {\n\t\t\t\ttracks.push([{ lo, hi }]);\n\t\t\t\tidx = tracks.length - 1;\n\t\t\t}\n\t\t\thopToTrackIdx.set(h, idx);\n\t\t}\n\n\t\t// Pass 2: distribute track indexes uniformly across the gutter's\n\t\t// **interior** (reserve 1-cell margin from each boundary when the\n\t\t// gutter is wide enough). A track placed exactly at `gutterStart`\n\t\t// or `gEnd` collapses the final turn-segment into the adjacent\n\t\t// node's border row, producing a visually misleading arrow; the\n\t\t// margin avoids that whenever geometry allows.\n\t\tconst count = tracks.length;\n\t\tconst hasMargin = gutterWidth >= Math.max(3, count + 2);\n\t\tconst usableStart = hasMargin ? gutterStart + 1 : gutterStart;\n\t\tconst usableEnd = hasMargin ? gEnd - 1 : gEnd;\n\t\tconst usableWidth = Math.max(1, usableEnd - usableStart + 1);\n\t\tfor (const h of gutterHops) {\n\t\t\tconst idx = hopToTrackIdx.get(h)!;\n\t\t\tlet trackPrimary: number;\n\t\t\tif (count <= 1) {\n\t\t\t\ttrackPrimary = usableStart + Math.floor(usableWidth / 2);\n\t\t\t} else {\n\t\t\t\tconst step = (usableWidth - 1) / (count - 1);\n\t\t\t\ttrackPrimary = usableStart + Math.floor(idx * step);\n\t\t\t}\n\t\t\thopTrackCross.set(h, Math.max(gutterStart, Math.min(gEnd, trackPrimary)));\n\t\t}\n\t}\n\n\t// Build polylines.\n\tconst out: LayoutEdge[] = [];\n\tfor (const [, hops] of byChain) {\n\t\tconst points: LayoutEdgePoint[] = [];\n\t\tfor (let i = 0; i < hops.length; i += 1) {\n\t\t\tconst h = hops[i]!;\n\t\t\tconst src = state.nodes.get(h.fromId)!;\n\t\t\tconst dst = state.nodes.get(h.toId)!;\n\t\t\tconst track = hopTrackCross.get(h)!;\n\t\t\t// Endpoints in (primary, cross) space.\n\t\t\tconst srcPrimary = src.isVirtual ? primary(src) : primary(src) + primarySize(src);\n\t\t\tconst dstPrimary = dst.isVirtual ? primary(dst) : primary(dst) - 1;\n\t\t\tconst sc = crossCenter(src);\n\t\t\tconst dc = crossCenter(dst);\n\t\t\tif (i === 0) pushPoint(points, isLR, srcPrimary, sc);\n\t\t\tif (sc !== dc) {\n\t\t\t\tpushPoint(points, isLR, track, sc);\n\t\t\t\tpushPoint(points, isLR, track, dc);\n\t\t\t}\n\t\t\tpushPoint(points, isLR, dstPrimary, dc);\n\t\t}\n\t\tconst chain = hops[0]!;\n\t\tout.push({\n\t\t\tfrom: chain.chainFrom,\n\t\t\tto: chain.chainTo,\n\t\t\tpoints: dedupWaypoints(points),\n\t\t});\n\t}\n\treturn out;\n}\n\nfunction pushPoint(acc: LayoutEdgePoint[], isLR: boolean, primary: number, cross: number): void {\n\tacc.push(isLR ? { x: primary, y: cross } : { x: cross, y: primary });\n}\n\nfunction dedupWaypoints(points: readonly LayoutEdgePoint[]): LayoutEdgePoint[] {\n\tconst out: LayoutEdgePoint[] = [];\n\tfor (const p of points) {\n\t\tconst last = out[out.length - 1];\n\t\tif (!last || last.x !== p.x || last.y !== p.y) out.push(p);\n\t}\n\treturn out;\n}\n\n// ---------------------------------------------------------------------------\n// Bounding box\n// ---------------------------------------------------------------------------\n\nfunction boundingBox(state: PipelineState): { width: number; height: number } {\n\tlet w = 0;\n\tlet h = 0;\n\tfor (const layer of state.layers) {\n\t\tfor (const n of layer) {\n\t\t\tw = Math.max(w, n.x + n.w);\n\t\t\th = Math.max(h, n.y + n.h);\n\t\t}\n\t}\n\treturn { width: w, height: h };\n}\n","/**\n * `graphSpecToAscii(g, opts?)` — stdout-native DAG flowchart renderer for a\n * {@link GraphDescribeOutput}.\n *\n * Zero external dependencies, graph-size independent via proper Sugiyama\n * (layer assignment → virtual-node splitting → barycenter crossing\n * minimization → median-aligned coordinate assignment → per-gutter\n * track-assigned orthogonal routing). See\n * [_layout-sugiyama.ts](./_layout-sugiyama.ts) for the layout pipeline and\n * [_ascii-grid.ts](./_ascii-grid.ts) for the character blitter.\n *\n * Pure function over the describe snapshot; no Graph instance dependency.\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport { renderGrid } from \"./_ascii-grid.js\";\nimport { countCells, truncateToCells } from \"./_ascii-width.js\";\nimport type { LayoutDirection } from \"./_layout-sugiyama.js\";\nimport { sugiyamaLayout } from \"./_layout-sugiyama.js\";\n\nconst DEFAULT_LABEL_WIDTH = 24;\nconst LAYER_GAP = 4;\nconst NODE_GAP = 1;\nconst BOX_HEIGHT = 3;\n\nexport type GraphSpecToAsciiOptions = {\n\t/**\n\t * ASCII layout direction. ASCII grid semantics are meaningful only for\n\t * `\"LR\"` (default) and `\"TD\"`.\n\t */\n\tdirection?: LayoutDirection;\n\t/** Per-box label cell cap; longer labels are truncated with `…`. Default `24`. */\n\tmaxLabelWidth?: number;\n\t/** Glyph set: `\"unicode\"` (default, box-drawing) or `\"ascii\"` (`-|+<>v`). */\n\tasciiCharset?: \"unicode\" | \"ascii\";\n\t/** Optional logger hook; fires with the rendered text before return. */\n\tlogger?: (text: string) => void;\n};\n\nexport function graphSpecToAscii(g: GraphDescribeOutput, opts?: GraphSpecToAsciiOptions): string {\n\tconst direction = normalizeAsciiDirection(opts?.direction);\n\tconst maxLabel = Math.max(3, opts?.maxLabelWidth ?? DEFAULT_LABEL_WIDTH);\n\tconst charset = opts?.asciiCharset ?? \"unicode\";\n\n\t// Deterministic paths ordering — match the rest of describe rendering.\n\tconst paths = Object.keys(g.nodes).sort();\n\t// Drop edges whose endpoints aren't in the current visible path set\n\t// (respects actor filtering that the caller already applied).\n\tconst nodeSet = new Set(paths);\n\tconst edges = g.edges.filter((e) => nodeSet.has(e.from) && nodeSet.has(e.to));\n\n\t// Precompute truncated labels + cell widths so the layout knows box\n\t// dimensions without re-measuring.\n\tconst labels = new Map<string, string>();\n\tconst widths = new Map<string, number>();\n\tfor (const p of paths) {\n\t\tconst label = truncateToCells(p, maxLabel);\n\t\tlabels.set(p, label);\n\t\t// Box width = label cells + 2 side borders + 2 cells of padding.\n\t\twidths.set(p, countCells(label) + 4);\n\t}\n\n\tconst layout = sugiyamaLayout({\n\t\tnodes: paths,\n\t\tedges,\n\t\twidthCells: (id) => widths.get(id) ?? 3,\n\t\theightCells: () => BOX_HEIGHT,\n\t\tlayerGap: LAYER_GAP,\n\t\tnodeGap: NODE_GAP,\n\t\tdirection,\n\t});\n\n\tconst text = renderGrid(layout, {\n\t\tcharset,\n\t\tlabelOf: (id) => labels.get(id) ?? id,\n\t});\n\n\topts?.logger?.(text);\n\treturn text;\n}\n\nfunction normalizeAsciiDirection(direction: unknown): LayoutDirection {\n\tif (direction === undefined || direction === \"LR\") return \"LR\";\n\tif (direction === \"TD\") return \"TD\";\n\t// BT / RL are valid for the vector diagram formats but ASCII grid\n\t// semantics are meaningful only for LR and TD — reject early with a\n\t// clear message rather than silently ignoring.\n\tthrow new Error(`ascii describe supports direction \"LR\" or \"TD\" only; got ${String(direction)}`);\n}\n","/**\n * Internal helpers shared across renderers in `extra/render/`.\n *\n * These are pure functions over `GraphDescribeOutput` — no Graph instance\n * dependency. Extracted from `src/graph/graph.ts` (the consolidated\n * ex-dumpGraph / ex-graphSpecToMermaid / ex-graphSpecToD2 renderers) per\n * Tier 2.1 A2.\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\n\n/** Direction options for diagram exports. */\nexport type DiagramDirection = \"TD\" | \"LR\" | \"BT\" | \"RL\";\n\n/** Recursively sort object keys for deterministic JSON (git-diffable). */\nexport function sortJsonValue(value: unknown): unknown {\n\tif (value === null || typeof value !== \"object\") {\n\t\treturn value;\n\t}\n\tif (Array.isArray(value)) {\n\t\treturn value.map(sortJsonValue);\n\t}\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) {\n\t\tout[k] = sortJsonValue(obj[k]);\n\t}\n\treturn out;\n}\n\n/** Escape characters that are illegal inside a quoted Mermaid label. */\nexport function escapeMermaidLabel(value: string): string {\n\treturn value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"');\n}\n\n/** Escape characters that are illegal inside a quoted D2 label. */\nexport function escapeD2Label(value: string): string {\n\treturn value.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"');\n}\n\n/** Map our 4-direction enum to D2's `direction:` keyword. */\nexport function d2DirectionFromGraphDirection(direction: DiagramDirection): string {\n\tif (direction === \"TD\") return \"down\";\n\tif (direction === \"BT\") return \"up\";\n\tif (direction === \"RL\") return \"left\";\n\treturn \"right\";\n}\n\n/** Collect deduplicated (from, to) arrows from deps + edges. */\nexport function collectDiagramArrows(described: GraphDescribeOutput): [string, string][] {\n\tconst seen = new Set<string>();\n\tconst arrows: [string, string][] = [];\n\tfunction add(from: string, to: string): void {\n\t\tconst key = `${from}\\0${to}`;\n\t\tif (seen.has(key)) return;\n\t\tseen.add(key);\n\t\tarrows.push([from, to]);\n\t}\n\tfor (const [path, info] of Object.entries(described.nodes)) {\n\t\tconst deps: string[] | undefined = (info as Record<string, unknown>).deps as\n\t\t\t| string[]\n\t\t\t| undefined;\n\t\tif (deps) {\n\t\t\tfor (const dep of deps) add(dep, path);\n\t\t}\n\t}\n\tfor (const edge of described.edges) add(edge.from, edge.to);\n\treturn arrows;\n}\n\n/** Default to \"LR\"; throw on unknown values to surface caller bugs early. */\nexport function normalizeDiagramDirection(direction: unknown): DiagramDirection {\n\tif (direction === undefined) return \"LR\";\n\tif (direction === \"TD\" || direction === \"LR\" || direction === \"BT\" || direction === \"RL\") {\n\t\treturn direction;\n\t}\n\tthrow new Error(\n\t\t`invalid diagram direction ${String(direction)}; expected one of: TD, LR, BT, RL`,\n\t);\n}\n\n/** JSON-aware single-value formatter (used by `graphSpecToPretty`). */\nexport function describeData(value: unknown): string {\n\tif (typeof value === \"string\") return JSON.stringify(value);\n\tif (typeof value === \"number\" || typeof value === \"boolean\" || value == null)\n\t\treturn String(value);\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch {\n\t\treturn \"[unserializable]\";\n\t}\n}\n","/**\n * `graphSpecToD2(g, opts?)` — render a {@link GraphDescribeOutput} as D2\n * diagram text.\n *\n * Pure function over the describe snapshot; no Graph instance dependency.\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport {\n\tcollectDiagramArrows,\n\ttype DiagramDirection,\n\td2DirectionFromGraphDirection,\n\tescapeD2Label,\n\tnormalizeDiagramDirection,\n} from \"./_internal.js\";\n\nexport type GraphSpecToD2Options = {\n\t/** Diagram direction; default `\"LR\"`. */\n\tdirection?: DiagramDirection;\n};\n\nexport function graphSpecToD2(g: GraphDescribeOutput, opts?: GraphSpecToD2Options): string {\n\tconst direction = normalizeDiagramDirection(opts?.direction);\n\tconst paths = Object.keys(g.nodes).sort();\n\tconst ids = new Map<string, string>();\n\tfor (let i = 0; i < paths.length; i += 1) ids.set(paths[i]!, `n${i}`);\n\tconst lines: string[] = [`direction: ${d2DirectionFromGraphDirection(direction)}`];\n\tfor (const path of paths) {\n\t\tconst id = ids.get(path)!;\n\t\tlines.push(`${id}: \"${escapeD2Label(path)}\"`);\n\t}\n\tfor (const [from, to] of collectDiagramArrows(g)) {\n\t\tconst fromId = ids.get(from);\n\t\tconst toId = ids.get(to);\n\t\tif (!fromId || !toId) continue;\n\t\tlines.push(`${fromId} -> ${toId}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n","/**\n * `graphSpecToJson(g, opts?)` — render a {@link GraphDescribeOutput} as\n * deterministic JSON text with sorted keys.\n *\n * Pure function over the describe snapshot; no Graph instance dependency.\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport { sortJsonValue } from \"./_internal.js\";\n\nexport type GraphSpecToJsonOptions = {\n\t/** Include the Edges section (default `true`). */\n\tincludeEdges?: boolean;\n\t/** Include the Subgraphs section (default `true`). */\n\tincludeSubgraphs?: boolean;\n\t/** JSON indent (default `2`). */\n\tindent?: number;\n\t/** Optional logger hook; fires with the rendered text before return. */\n\tlogger?: (text: string) => void;\n};\n\nexport function graphSpecToJson(g: GraphDescribeOutput, opts?: GraphSpecToJsonOptions): string {\n\tconst includeEdges = opts?.includeEdges ?? true;\n\tconst includeSubgraphs = opts?.includeSubgraphs ?? true;\n\tconst { expand: _expand, ...rest } = g;\n\tconst payload: GraphDescribeOutput = {\n\t\t...rest,\n\t\tedges: includeEdges ? g.edges : [],\n\t\tsubgraphs: includeSubgraphs ? g.subgraphs : [],\n\t};\n\tconst text = JSON.stringify(sortJsonValue(payload), null, opts?.indent ?? 2);\n\topts?.logger?.(text);\n\treturn text;\n}\n","/**\n * `graphSpecToMermaid(g, opts?)` — render a {@link GraphDescribeOutput} as\n * Mermaid flowchart text.\n *\n * Pure function over the describe snapshot; no Graph instance dependency.\n * Compose with `derived` for live formatted output:\n *\n * ```ts\n * import { graphSpecToMermaid } from \"@graphrefly/graphrefly/extra/render\";\n * import { derived } from \"@graphrefly/graphrefly\";\n *\n * const live = derived(\n * [graph.describe({ reactive: true }).node],\n * ([g]) => graphSpecToMermaid(g),\n * );\n * ```\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport {\n\tcollectDiagramArrows,\n\ttype DiagramDirection,\n\tescapeMermaidLabel,\n\tnormalizeDiagramDirection,\n} from \"./_internal.js\";\n\nexport type GraphSpecToMermaidOptions = {\n\t/** Diagram direction; default `\"LR\"`. */\n\tdirection?: DiagramDirection;\n};\n\nexport function graphSpecToMermaid(\n\tg: GraphDescribeOutput,\n\topts?: GraphSpecToMermaidOptions,\n): string {\n\tconst direction = normalizeDiagramDirection(opts?.direction);\n\tconst paths = Object.keys(g.nodes).sort();\n\tconst ids = new Map<string, string>();\n\tfor (let i = 0; i < paths.length; i += 1) ids.set(paths[i]!, `n${i}`);\n\tconst lines: string[] = [`flowchart ${direction}`];\n\tfor (const path of paths) {\n\t\tconst id = ids.get(path)!;\n\t\tlines.push(` ${id}[\"${escapeMermaidLabel(path)}\"]`);\n\t}\n\tfor (const [from, to] of collectDiagramArrows(g)) {\n\t\tconst fromId = ids.get(from);\n\t\tconst toId = ids.get(to);\n\t\tif (!fromId || !toId) continue;\n\t\tlines.push(` ${fromId} --> ${toId}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n","/**\n * `graphSpecToMermaidUrl(g, opts?)` — encode a {@link GraphDescribeOutput}\n * as a `https://mermaid.live/edit#base64:…` deep link.\n *\n * Round-trip with the mermaid.live editor's `/edit#base64:` share format —\n * payload is `base64url(JSON({code, mermaid: {theme}, ...}))`. No network\n * calls; the payload is encoded into the URL fragment.\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport { type GraphSpecToMermaidOptions, graphSpecToMermaid } from \"./graph-spec-to-mermaid.js\";\n\nexport type MermaidLiveTheme = \"default\" | \"dark\" | \"forest\" | \"neutral\" | \"base\";\n\nexport type GraphSpecToMermaidUrlOptions = GraphSpecToMermaidOptions & {\n\ttheme?: MermaidLiveTheme;\n\tautoSync?: boolean;\n};\n\n/**\n * Encode an arbitrary mermaid source string to a `mermaid.live` deep link.\n * Exported separately so callers that already rendered mermaid text can\n * upgrade to a live-editor URL without re-rendering.\n */\nexport function mermaidLiveUrl(\n\tmermaidSrc: string,\n\topts?: { theme?: MermaidLiveTheme; autoSync?: boolean },\n): string {\n\tconst theme = opts?.theme ?? \"default\";\n\tconst autoSync = opts?.autoSync ?? true;\n\tconst payload = { code: mermaidSrc, mermaid: { theme }, autoSync };\n\tconst json = JSON.stringify(payload);\n\t// Browsers + Node both expose globalThis.btoa; encode UTF-8 bytes first so\n\t// non-ASCII node names don't explode btoa. Then url-safe base64 (`+/=`→`-_` strip).\n\tconst bytes = new TextEncoder().encode(json);\n\tlet binary = \"\";\n\tfor (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]!);\n\tconst b64 = globalThis.btoa(binary).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n\treturn `https://mermaid.live/edit#base64:${b64}`;\n}\n\nexport function graphSpecToMermaidUrl(\n\tg: GraphDescribeOutput,\n\topts?: GraphSpecToMermaidUrlOptions,\n): string {\n\tconst mermaidSrc = graphSpecToMermaid(g, opts);\n\treturn mermaidLiveUrl(mermaidSrc, opts);\n}\n","/**\n * `graphSpecToPretty(g, opts?)` — render a {@link GraphDescribeOutput} as\n * human-readable plaintext (Node list with values, plus optional Edges and\n * Subgraphs sections).\n *\n * Pure function over the describe snapshot; no Graph instance dependency.\n *\n * @category extra\n */\n\nimport type { GraphDescribeOutput } from \"@graphrefly/pure-ts/graph\";\nimport { describeData } from \"./_internal.js\";\n\nexport type GraphSpecToPrettyOptions = {\n\t/** Include the Edges section (default `true`). */\n\tincludeEdges?: boolean;\n\t/** Include the Subgraphs section (default `true`). */\n\tincludeSubgraphs?: boolean;\n\t/** Optional logger hook; fires with the rendered text before return. */\n\tlogger?: (text: string) => void;\n};\n\nexport function graphSpecToPretty(g: GraphDescribeOutput, opts?: GraphSpecToPrettyOptions): string {\n\tconst includeEdges = opts?.includeEdges ?? true;\n\tconst includeSubgraphs = opts?.includeSubgraphs ?? true;\n\tconst lines: string[] = [];\n\tlines.push(`Graph ${g.name}`);\n\tlines.push(\"Nodes:\");\n\tfor (const path of Object.keys(g.nodes).sort()) {\n\t\tconst n = g.nodes[path]!;\n\t\tlines.push(`- ${path} (${n.type}/${n.status}): ${describeData(n.value)}`);\n\t}\n\tif (includeEdges) {\n\t\tlines.push(\"Edges:\");\n\t\tfor (const edge of g.edges) {\n\t\t\tlines.push(`- ${edge.from} -> ${edge.to}`);\n\t\t}\n\t}\n\tif (includeSubgraphs) {\n\t\tlines.push(\"Subgraphs:\");\n\t\tfor (const sg of g.subgraphs) {\n\t\t\tlines.push(`- ${sg}`);\n\t\t}\n\t}\n\tconst text = lines.join(\"\\n\");\n\topts?.logger?.(text);\n\treturn text;\n}\n","/**\n * `layoutFrameToSvg(frame, opts?)` — render a {@link LayoutFrame} as an SVG\n * markup string.\n *\n * Universal-safe — emits a string, not a DOM tree. Browser code embeds via\n * `el.innerHTML = svg`; Node code writes to a file. Cell-grid coordinates from\n * the layout are scaled by `cellWidth` / `cellHeight` (default 12 × 18 px,\n * roughly matching a monospace baseline).\n *\n * Each box gets `data-id=\"<path>\"` for change-event highlighting; each edge\n * gets `data-from=\"<from>\" data-to=\"<to>\"` so renderers can animate flowing\n * data per `LayoutFrame.changes`.\n *\n * @category extra\n */\n\nimport type { LayoutFrame } from \"./layout-types.js\";\n\nexport interface LayoutFrameToSvgOptions {\n\t/** Pixel width of one cell. Default: `12`. */\n\treadonly cellWidth?: number;\n\t/** Pixel height of one cell. Default: `18`. */\n\treadonly cellHeight?: number;\n\t/** Outer margin in pixels. Default: `16`. */\n\treadonly padding?: number;\n\t/** Box stroke color. Default: `\"#444\"`. */\n\treadonly boxStroke?: string;\n\t/** Box fill color. Default: `\"#fff\"`. */\n\treadonly boxFill?: string;\n\t/** Edge stroke color. Default: `\"#888\"`. */\n\treadonly edgeStroke?: string;\n\t/** Box label text color. Default: `\"#111\"`. */\n\treadonly textColor?: string;\n\t/** Font family. Default: `\"ui-monospace, monospace\"`. */\n\treadonly fontFamily?: string;\n\t/** Font size in pixels. Default: `12`. */\n\treadonly fontSize?: number;\n}\n\nconst SPECIAL_CHARS: Record<string, string> = {\n\t\"&\": \"&amp;\",\n\t\"<\": \"&lt;\",\n\t\">\": \"&gt;\",\n\t'\"': \"&quot;\",\n\t\"'\": \"&apos;\",\n};\n\nfunction escapeXml(s: string): string {\n\treturn s.replace(/[&<>\"']/g, (c) => SPECIAL_CHARS[c] ?? c);\n}\n\n/**\n * Render a {@link LayoutFrame} to SVG markup. Pure function — call from\n * `derived` to drive a live `<svg>` element from a `topologyView` output.\n */\nexport function layoutFrameToSvg(frame: LayoutFrame, opts?: LayoutFrameToSvgOptions): string {\n\tconst cellW = opts?.cellWidth ?? 12;\n\tconst cellH = opts?.cellHeight ?? 18;\n\tconst pad = opts?.padding ?? 16;\n\t// /qa F-10: route option-bag string attributes through escapeXml so that\n\t// user-supplied themes (URL params, dashboard config, etc.) cannot inject\n\t// `\"/><script>...` and break out of the attribute. Numeric `fontSize` has\n\t// no XSS surface; escape only when caller passes a string.\n\tconst boxStroke = escapeXml(opts?.boxStroke ?? \"#444\");\n\tconst boxFill = escapeXml(opts?.boxFill ?? \"#fff\");\n\tconst edgeStroke = escapeXml(opts?.edgeStroke ?? \"#888\");\n\tconst textColor = escapeXml(opts?.textColor ?? \"#111\");\n\tconst fontFamily = opts?.fontFamily ?? \"ui-monospace, monospace\";\n\tconst fontSize = opts?.fontSize ?? 12;\n\n\tlet maxX = 0;\n\tlet maxY = 0;\n\tfor (const b of frame.boxes) {\n\t\tmaxX = Math.max(maxX, b.x + b.w);\n\t\tmaxY = Math.max(maxY, b.y + b.h);\n\t}\n\tfor (const e of frame.edges) {\n\t\tfor (const [x, y] of e.points) {\n\t\t\tmaxX = Math.max(maxX, x);\n\t\t\tmaxY = Math.max(maxY, y);\n\t\t}\n\t}\n\tconst width = Math.max(1, maxX) * cellW + pad * 2;\n\tconst height = Math.max(1, maxY) * cellH + pad * 2;\n\n\tconst lines: string[] = [];\n\tlines.push(\n\t\t`<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\">`,\n\t);\n\n\t// Edges first (so boxes overlay them at endpoints).\n\tfor (const e of frame.edges) {\n\t\tif (e.points.length < 2) continue;\n\t\tconst pts = e.points.map(([x, y]) => `${x * cellW + pad},${y * cellH + pad}`).join(\" \");\n\t\tlines.push(\n\t\t\t` <polyline points=\"${pts}\" fill=\"none\" stroke=\"${edgeStroke}\" stroke-width=\"1\" data-from=\"${escapeXml(e.from)}\" data-to=\"${escapeXml(e.to)}\" data-dep-index=\"${e.depIndex}\" />`,\n\t\t);\n\t}\n\n\t// Boxes.\n\tfor (const b of frame.boxes) {\n\t\tconst px = b.x * cellW + pad;\n\t\tconst py = b.y * cellH + pad;\n\t\tconst pw = Math.max(1, b.w) * cellW;\n\t\tconst ph = Math.max(1, b.h) * cellH;\n\t\t// Local segment for label so deeply-mounted nodes stay readable.\n\t\tconst local = b.id.includes(\"::\") ? (b.id.split(\"::\").pop() ?? b.id) : b.id;\n\t\tlines.push(\n\t\t\t` <g data-id=\"${escapeXml(b.id)}\">`,\n\t\t\t` <rect x=\"${px}\" y=\"${py}\" width=\"${pw}\" height=\"${ph}\" fill=\"${boxFill}\" stroke=\"${boxStroke}\" stroke-width=\"1\" />`,\n\t\t\t` <text x=\"${px + pw / 2}\" y=\"${py + ph / 2}\" fill=\"${textColor}\" font-family=\"${escapeXml(fontFamily)}\" font-size=\"${fontSize}\" text-anchor=\"middle\" dominant-baseline=\"central\">${escapeXml(local)}</text>`,\n\t\t\t` </g>`,\n\t\t);\n\t}\n\n\tlines.push(\"</svg>\");\n\treturn lines.join(\"\\n\");\n}\n","/**\n * Cron-based reactive sources and schedule types.\n *\n * Merged from extra/cron.ts + extra/sources/event.ts (fromCron) during cleave A2.\n * `fromCron` relocated here from `dom.ts` (post-cleave /qa A1): it uses zero DOM\n * APIs (only `setInterval` + `new Date()`), so it belongs on the universal\n * `event/index.ts` barrel, not the browser-only `dom.ts` subpath.\n */\n\nimport { type Node, type NodeOptions, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\n\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nfunction sourceOpts<T = unknown>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\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/**\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/**\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\";\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 node<number | Date>(\n\t\t(_data, 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 { onDeactivation: () => clearInterval(id) };\n\t\t},\n\t\t{ ...sourceOpts(rest), name: rest.name ?? `cron:${expr}` },\n\t);\n}\n","/**\n * Pure exponential-decay utility (Tier 2.2 promotion from `patterns/memory/`).\n *\n * Used by `collection`, `agentMemory`, harness `strategy.ts`, and any\n * downstream consumer that needs decay-with-floor scoring. Promoted to\n * `extra/utils/` because the math has zero domain semantics and is reusable\n * by non-memory primitives (e.g. routing weight decay, retry-attempt aging).\n *\n * @module\n */\n\n/**\n * Default exponential-decay rate corresponding to a 7-day half-life.\n *\n * `Math.LN2 / (7 × 86_400)` ≈ `1.146e-6`. Imported by memory tiers + any\n * consumer that wants the same default cadence as `agentMemory`'s active\n * tier. Tier 4.4 (Wave AM Unit 1) — promoted from\n * `patterns/ai/memory/tiers.ts` so non-memory consumers can share the\n * canonical default without reaching across domains.\n */\nexport const DEFAULT_DECAY_RATE = Math.LN2 / (7 * 86_400);\n\n/**\n * Exponential decay with floor: `score = max(minScore, baseScore * exp(-ratePerSecond * ageSeconds))`.\n *\n * Tolerant fallbacks (deliberate for use inside reactive derived fns):\n * - non-finite `baseScore` → `minScore`\n * - non-positive `ageSeconds` (incl. clock skew) → `max(minScore, baseScore)` (no decay)\n * - non-positive `ratePerSecond` → `max(minScore, baseScore)` (no decay; rate=0 disables)\n *\n * Underflow boundary: `Math.exp(-745) === 0`. For very long ages × rates the\n * result clamps to `minScore`; if you need slow decay over years, choose a\n * smaller `ratePerSecond` rather than relying on graceful underflow.\n *\n * Half-life conversion: `ratePerSecond = Math.LN2 / halfLifeSeconds`.\n */\nexport function decay(\n\tbaseScore: number,\n\tageSeconds: number,\n\tratePerSecond: number,\n\tminScore = 0,\n): number {\n\tif (!Number.isFinite(baseScore)) return minScore;\n\tif (!Number.isFinite(ageSeconds) || ageSeconds <= 0) return Math.max(minScore, baseScore);\n\tif (!Number.isFinite(ratePerSecond) || ratePerSecond <= 0) return Math.max(minScore, baseScore);\n\tconst decayed = baseScore * Math.exp(-ratePerSecond * ageSeconds);\n\treturn Math.max(minScore, decayed);\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 {\n\tbatch,\n\tDATA,\n\tdefaultConfig,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\ttype NodeSink,\n\tnode,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport { filter, first, fromTimer, map, merge } from \"@graphrefly/pure-ts/extra\";\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 = node<\"connecting\" | \"connected\" | \"closed\">([], {\n\t\tinitial: \"connecting\",\n\t\tname: `${bridgeName}::meta::status`,\n\t});\n\tconst errorNode = node<Error | null>([], {\n\t\tinitial: 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 = node([], { initial: 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. `partial: true` opts out\n\t\t\t// of the §2.7 first-run gate so the aggregator can fire on\n\t\t\t// any-dep-settles waves (the worker may not expose all sources at\n\t\t\t// the same time).\n\t\t\t{ name: `${bridgeName}::aggregated`, partial: true },\n\t\t);\n\n\t\tconst effectNode = node(\n\t\t\t[aggregated],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\tconst data0 = batch0 != null && batch0.length > 0 ? batch0.at(-1) : ctx.prevData[0];\n\t\t\t\tconst updates = data0 as Record<string, unknown> | undefined;\n\t\t\t\tif (updates == null || Object.keys(updates).length === 0) return undefined;\n\n\t\t\t\tconst transferList: Transferable[] = [];\n\t\t\t\tfor (const name of Object.keys(updates)) {\n\t\t\t\t\tconst fn = (transferFns as any)[name];\n\t\t\t\t\tif (fn) transferList.push(...fn(updates[name]));\n\t\t\t\t}\n\n\t\t\t\t// V0 delta sync: include version counters when available (§6.0b).\n\t\t\t\tlet versions: Record<string, number> | undefined;\n\t\t\t\tfor (const [name, n] of exposeEntries) {\n\t\t\t\t\tif (name in updates && n.v != null) {\n\t\t\t\t\t\tif (versions == null) versions = {};\n\t\t\t\t\t\tversions[name] = n.v.version;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst msg: BatchMessage = { t: \"b\", u: updates, ...(versions ? { v: versions } : {}) };\n\t\t\t\ttry {\n\t\t\t\t\ttransport.post(msg, transferList.length > 0 ? transferList : undefined);\n\t\t\t\t} catch (err) {\n\t\t\t\t\terrorNode.down([[DATA, err instanceof Error ? err : new Error(String(err))]]);\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t\t{ describeKind: \"effect\" },\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 * 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 \"@graphrefly/pure-ts/core\";\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 * 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 {\n\tbatch,\n\tDATA,\n\tdefaultConfig,\n\tERROR,\n\ttype Messages,\n\ttype Node,\n\ttype NodeSink,\n\tnode,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\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 = node([], { initial: 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. `partial: true`\n\t\t\t// opts out of the §2.7 first-run gate so the aggregator can fire on\n\t\t\t// any-dep-settles waves (deps deliver asynchronously).\n\t\t\t{ name: \"workerSelf::aggregated\", partial: true },\n\t\t);\n\n\t\tconst effectNode = node(\n\t\t\t[aggregated],\n\t\t\t(batchData, _actions, ctx) => {\n\t\t\t\tconst batch0 = batchData[0];\n\t\t\t\tconst data0 = batch0 != null && batch0.length > 0 ? batch0.at(-1) : ctx.prevData[0];\n\t\t\t\tif (destroyed) return undefined;\n\t\t\t\tconst updates = data0 as Record<string, unknown> | undefined;\n\t\t\t\tif (updates == null || Object.keys(updates).length === 0) return undefined;\n\n\t\t\t\tconst transferList: Transferable[] = [];\n\t\t\t\tfor (const name of Object.keys(updates)) {\n\t\t\t\t\tconst fn = (transferFns as any)[name];\n\t\t\t\t\tif (fn) transferList.push(...fn(updates[name]));\n\t\t\t\t}\n\n\t\t\t\t// V0 delta sync: include version counters when available (§6.0b).\n\t\t\t\tlet versions: Record<string, number> | undefined;\n\t\t\t\tfor (const [name, n] of exposeEntries) {\n\t\t\t\t\tif (name in updates && n.v != null) {\n\t\t\t\t\t\tif (versions == null) versions = {};\n\t\t\t\t\t\tversions[name] = n.v.version;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst msg: BatchMessage = { t: \"b\", u: updates, ...(versions ? { v: versions } : {}) };\n\t\t\t\ttry {\n\t\t\t\t\ttransport.post(msg, transferList.length > 0 ? transferList : undefined);\n\t\t\t\t} catch (_err) {\n\t\t\t\t\t// Transport failure — bridge is likely destroyed; swallow\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t\t{ describeKind: \"effect\" },\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":["operatorOpts","import_core","cached","operatorOpts","import_core","import_core","import_extra","import_core","import_extra","node","batch","map","import_core","sourceOpts","import_core","import_core","node","import_core","import_extra","import_core","import_extra","import_core","node","import_core","import_extra","source","import_core","import_core","import_extra","import_core","sourceOpts","sourceOpts","import_core","import_core","import_extra","import_core","operatorOpts","import_core","out","retry","p","sourceOpts","retry","import_core","sourceOpts","import_core","import_core","sourceOpts","import_core","sourceOpts","import_core","import_core","import_core","import_extra","import_core","sourceOpts","import_core","sourceOpts","import_core","sourceOpts","import_core","import_core","sourceOpts","import_core","import_core","batch","import_core","import_core","seq","batch","import_core","import_core","operatorOpts","sourceOpts","import_core","import_core","import_extra","import_core","sourceOpts","import_core","import_extra","import_core","import_core","isTransport"]}