@graphrefly/graphrefly 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/{chunk-XUOY3YKN.js → chunk-2L5J6RPM.js} +2 -2
  2. package/dist/{chunk-JC2SN46B.js → chunk-3N2Y6PCR.js} +3 -3
  3. package/dist/{chunk-OO5QOAXI.js → chunk-5PSVTDNZ.js} +22 -9
  4. package/dist/chunk-5PSVTDNZ.js.map +1 -0
  5. package/dist/{chunk-BER7UYLM.js → chunk-BJAOEU4D.js} +10 -6
  6. package/dist/{chunk-BER7UYLM.js.map → chunk-BJAOEU4D.js.map} +1 -1
  7. package/dist/{chunk-UW77D7SP.js → chunk-IAPLC4NR.js} +3 -3
  8. package/dist/{chunk-IRZAGZUB.js → chunk-OOA2UTXF.js} +26 -2
  9. package/dist/chunk-OOA2UTXF.js.map +1 -0
  10. package/dist/{chunk-AHRKWMNI.js → chunk-PGEU5MEH.js} +3 -3
  11. package/dist/{chunk-YLR5JUJZ.js → chunk-R2LPZIY2.js} +3 -3
  12. package/dist/{chunk-YXR3WW3Q.js → chunk-XYL3GLB3.js} +3 -3
  13. package/dist/{chunk-YXR3WW3Q.js.map → chunk-XYL3GLB3.js.map} +1 -1
  14. package/dist/compat/nestjs/index.cjs +14 -5
  15. package/dist/compat/nestjs/index.cjs.map +1 -1
  16. package/dist/compat/nestjs/index.js +7 -7
  17. package/dist/core/index.cjs +2 -2
  18. package/dist/core/index.cjs.map +1 -1
  19. package/dist/core/index.d.cts +1 -1
  20. package/dist/core/index.d.ts +1 -1
  21. package/dist/core/index.js +3 -3
  22. package/dist/extra/index.cjs +31 -5
  23. package/dist/extra/index.cjs.map +1 -1
  24. package/dist/extra/index.d.cts +1 -1
  25. package/dist/extra/index.d.ts +1 -1
  26. package/dist/extra/index.js +7 -3
  27. package/dist/graph/index.cjs.map +1 -1
  28. package/dist/graph/index.js +4 -4
  29. package/dist/{index-CvKzv0AW.d.ts → index-BHfg_Ez3.d.ts} +1 -1
  30. package/dist/{index-BBUYZfJ1.d.cts → index-Bc_diYYJ.d.cts} +1 -1
  31. package/dist/{index-BnkMgNNa.d.ts → index-DuN3bhtm.d.ts} +47 -2
  32. package/dist/{index-Bjh5C1Tp.d.cts → index-SFzE_KTa.d.cts} +47 -2
  33. package/dist/index.cjs +153 -87
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +75 -6
  36. package/dist/index.d.ts +75 -6
  37. package/dist/index.js +126 -90
  38. package/dist/index.js.map +1 -1
  39. package/dist/patterns/reactive-layout/index.cjs.map +1 -1
  40. package/dist/patterns/reactive-layout/index.js +4 -4
  41. package/package.json +2 -2
  42. package/dist/chunk-IRZAGZUB.js.map +0 -1
  43. package/dist/chunk-OO5QOAXI.js.map +0 -1
  44. /package/dist/{chunk-XUOY3YKN.js.map → chunk-2L5J6RPM.js.map} +0 -0
  45. /package/dist/{chunk-JC2SN46B.js.map → chunk-3N2Y6PCR.js.map} +0 -0
  46. /package/dist/{chunk-UW77D7SP.js.map → chunk-IAPLC4NR.js.map} +0 -0
  47. /package/dist/{chunk-AHRKWMNI.js.map → chunk-PGEU5MEH.js.map} +0 -0
  48. /package/dist/{chunk-YLR5JUJZ.js.map → chunk-R2LPZIY2.js.map} +0 -0
@@ -14,10 +14,10 @@ import {
14
14
  measureBlocks,
15
15
  reactiveBlockLayout,
16
16
  reactiveLayout
17
- } from "../../chunk-UW77D7SP.js";
18
- import "../../chunk-JC2SN46B.js";
19
- import "../../chunk-XUOY3YKN.js";
20
- import "../../chunk-YXR3WW3Q.js";
17
+ } from "../../chunk-IAPLC4NR.js";
18
+ import "../../chunk-3N2Y6PCR.js";
19
+ import "../../chunk-2L5J6RPM.js";
20
+ import "../../chunk-XYL3GLB3.js";
21
21
  export {
22
22
  CanvasMeasureAdapter,
23
23
  CliMeasureAdapter,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@graphrefly/graphrefly",
3
- "version": "0.19.0",
4
- "packageManager": "pnpm@10.32.1+sha512.a706938f0e89ac1456b6563eab4edf1d1faf3368d1191fc5c59790e96dc918e4456ab2e67d613de1043d2e8c81f87303e6b40d4ffeca9df15ef1ad567348f2be",
3
+ "version": "0.20.0",
4
+ "packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319",
5
5
  "description": "Reactive harness layer for agent workflows. Describe automations in plain language, trace every decision, enforce policies, persist checkpoints. Zero dependencies.",
6
6
  "repository": {
7
7
  "type": "git",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/extra/observable.ts","../src/extra/cron.ts","../src/extra/sources.ts","../src/extra/backpressure.ts","../src/extra/reactive-log.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// RxJS bridge — reactive interop between GraphReFly nodes and RxJS Observables.\n// ---------------------------------------------------------------------------\n// Usage:\n// import { toObservable } from '@graphrefly/graphrefly-ts/extra';\n// const values$ = toObservable(myNode); // Observable<T>\n// const msgs$ = toObservable(myNode, { raw: true }); // Observable<Messages>\n// ---------------------------------------------------------------------------\n\nimport { Observable } from \"rxjs\";\nimport { COMPLETE, DATA, ERROR, type Messages } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\n\n/** Options for {@link toObservable}. */\nexport type ToObservableOptions = {\n\t/**\n\t * When `true`, emit raw `Messages` batches instead of extracted `DATA` values.\n\t * Terminal batches are still emitted as the final `next()` before the\n\t * Observable signal (error/complete).\n\t */\n\traw?: boolean;\n};\n\n/**\n * Bridge a `Node<T>` to an RxJS `Observable`.\n *\n * Default mode emits the node's value on each `DATA` message. Maps `ERROR` to\n * `subscriber.error()` and `COMPLETE` to `subscriber.complete()`.\n * Protocol-internal signals (DIRTY, RESOLVED, PAUSE, etc.) are skipped.\n *\n * With `{ raw: true }`, emits full `[[Type, Data?], ...]` message batches.\n * The Observable terminates on ERROR or COMPLETE (the terminal batch is still\n * emitted as the final `next()` before the Observable signal).\n *\n * For graph-level observation, use `toObservable(graph.resolve(path))` or\n * subscribe to `graph.observe()` directly.\n *\n * Unsubscribing the Observable unsubscribes the node.\n */\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions & { raw?: false },\n): Observable<T>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions: ToObservableOptions & { raw: true },\n): Observable<Messages>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions,\n): Observable<T | Messages> {\n\tif (options?.raw) {\n\t\treturn new Observable<Messages>((subscriber) => {\n\t\t\tconst unsub = node.subscribe((msgs) => {\n\t\t\t\tif (subscriber.closed) return;\n\t\t\t\tsubscriber.next(msgs);\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\t\tsubscriber.error(m[1]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\t\tsubscriber.complete();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn unsub;\n\t\t});\n\t}\n\n\treturn new Observable<T>((subscriber) => {\n\t\tconst unsub = node.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (subscriber.closed) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tsubscriber.next(m[1] as T);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tsubscriber.error(m[1]);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tsubscriber.complete();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\treturn unsub;\n\t});\n}\n","/**\n * 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 * Core reactive sources, sinks, and utilities (roadmap §2.3).\n *\n * Each API returns a {@link Node} built with {@link node}, {@link producer},\n * {@link derived}, or {@link effect} — no second protocol.\n *\n * Protocol/system/ingest adapters (fromHTTP, fromWebSocket, fromKafka, etc.)\n * live in {@link ./adapters.ts}.\n */\n\nimport { existsSync, watch } from \"node:fs\";\nimport { resolve as resolvePath } from \"node:path\";\nimport { wallClockNs } from \"../core/clock.js\";\nimport { COMPLETE, DATA, ERROR, type Message } from \"../core/messages.js\";\nimport { type Node, type NodeOptions, type NodeSink, node } from \"../core/node.js\";\nimport { producer } from \"../core/sugar.js\";\nimport { type CronSchedule, matchesCron, parseCron } from \"./cron.js\";\n\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nfunction sourceOpts(opts?: ExtraOpts): NodeOptions {\n\treturn { describeKind: \"producer\", ...opts };\n}\n\n/** @internal kept for toArray which is an operator, not a producer */\nfunction operatorOpts(opts?: ExtraOpts): NodeOptions {\n\treturn { describeKind: \"operator\", ...opts };\n}\n\n/** Options for {@link fromTimer} / {@link fromPromise} / {@link fromAsyncIter}. */\nexport type AsyncSourceOpts = ExtraOpts & { signal?: AbortSignal };\n\n/**\n * Values accepted by {@link fromAny}.\n *\n * @category extra\n */\nexport type NodeInput<T> = Node<T> | PromiseLike<T> | AsyncIterable<T> | Iterable<T> | T;\n\n/** Options for {@link fromCron}. */\nexport type FromCronOptions = ExtraOpts & {\n\t/** Polling interval in ms. Default `60_000`. */\n\ttickMs?: number;\n\t/** Output format: `\"timestamp_ns\"` (default) emits wall-clock nanoseconds; `\"date\"` emits a `Date` object. */\n\toutput?: \"timestamp_ns\" | \"date\";\n};\n\n/** DOM-style event target (browser or `node:events`). */\nexport type EventTargetLike = {\n\taddEventListener(\n\t\ttype: string,\n\t\tlistener: (ev: unknown) => void,\n\t\toptions?: boolean | { capture?: boolean; passive?: boolean; once?: boolean },\n\t): void;\n\tremoveEventListener(\n\t\ttype: string,\n\t\tlistener: (ev: unknown) => void,\n\t\toptions?: boolean | { capture?: boolean; passive?: boolean; once?: boolean },\n\t): void;\n};\n\nexport type FSEventType = \"change\" | \"rename\" | \"create\" | \"delete\";\nexport type FSEvent = {\n\ttype: FSEventType;\n\tpath: string;\n\troot: string;\n\trelative_path: string;\n\tsrc_path?: string;\n\tdest_path?: string;\n\ttimestamp_ns: number;\n};\n\nexport type FromFSWatchOptions = ExtraOpts & {\n\trecursive?: boolean;\n\tdebounce?: number;\n\tinclude?: string[];\n\texclude?: string[];\n};\n\n/** @internal Shared with adapters.ts for glob matching in fromFSWatch / fromGitHook. */\nexport function escapeRegexChar(ch: string): string {\n\treturn /[\\\\^$+?.()|[\\]{}]/.test(ch) ? `\\\\${ch}` : ch;\n}\n\n/** @internal */\nexport function globToRegExp(glob: string): RegExp {\n\tlet out = \"^\";\n\tfor (let i = 0; i < glob.length; i += 1) {\n\t\tconst ch = glob[i];\n\t\tif (ch === \"*\") {\n\t\t\tconst next = glob[i + 1];\n\t\t\tif (next === \"*\") {\n\t\t\t\tout += \".*\";\n\t\t\t\ti += 1;\n\t\t\t} else {\n\t\t\t\tout += \"[^/]*\";\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tout += escapeRegexChar(ch);\n\t}\n\tout += \"$\";\n\treturn new RegExp(out);\n}\n\n/** @internal */\nexport function matchesAnyPattern(path: string, patterns: RegExp[]): boolean {\n\tfor (const pattern of patterns) {\n\t\tif (pattern.test(path)) return true;\n\t}\n\treturn false;\n}\n\nfunction wrapSubscribeHook<T>(inner: Node<T>, before: (sink: NodeSink) => void): Node<T> {\n\tconst wrapper = node<T>([inner], ([val]) => val as T, {\n\t\tdescribeKind: \"operator\",\n\t\tinitial: inner.get(),\n\t});\n\tconst origSubscribe = wrapper.subscribe.bind(wrapper);\n\t(wrapper as { subscribe: typeof wrapper.subscribe }).subscribe = (sink, hints) => {\n\t\tbefore(sink);\n\t\treturn origSubscribe(sink, hints);\n\t};\n\treturn wrapper;\n}\n\n/**\n * Builds a timer-driven source: one-shot (first tick then `COMPLETE`) or periodic (`0`, `1`, `2`, …).\n *\n * @param ms - Milliseconds before the first emission.\n * @param opts - Producer options plus optional `period` for repeating ticks and optional `signal` (`AbortSignal`) to cancel with `ERROR`.\n * @returns `Node<number>` — tick counter from `0`; teardown clears timers.\n *\n * @example\n * ```ts\n * import { fromTimer } from \"@graphrefly/graphrefly-ts\";\n *\n * fromTimer(250, { period: 1_000 });\n * ```\n *\n * @category extra\n */\nexport function fromTimer(ms: number, opts?: AsyncSourceOpts & { period?: number }): Node<number> {\n\tconst { signal, period, ...rest } = opts ?? {};\n\treturn producer<number>((_d, a) => {\n\t\tlet done = false;\n\t\tlet count = 0;\n\t\tlet t: ReturnType<typeof setTimeout> | undefined;\n\t\tlet iv: ReturnType<typeof setInterval> | undefined;\n\t\tconst cleanup = () => {\n\t\t\tdone = true;\n\t\t\tif (t !== undefined) clearTimeout(t);\n\t\t\tif (iv !== undefined) clearInterval(iv);\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\t\tconst finish = () => {\n\t\t\tif (done) return;\n\t\t\ta.emit(count++);\n\t\t\tif (period != null) {\n\t\t\t\tiv = setInterval(() => {\n\t\t\t\t\tif (done) return;\n\t\t\t\t\ta.emit(count++);\n\t\t\t\t}, period);\n\t\t\t} else {\n\t\t\t\tdone = true;\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tqueueMicrotask(() => a.down([[COMPLETE]]));\n\t\t\t}\n\t\t};\n\t\tconst onAbort = () => {\n\t\t\tif (done) return;\n\t\t\tcleanup();\n\t\t\ta.down([[ERROR, signal!.reason]]);\n\t\t};\n\t\tif (signal?.aborted) {\n\t\t\tonAbort();\n\t\t\treturn;\n\t\t}\n\t\tt = setTimeout(finish, ms);\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\treturn cleanup;\n\t}, sourceOpts(rest));\n}\n\n/**\n * Polls on an interval; when the current minute matches a 5-field cron expression, emits once (see {@link parseCron}).\n *\n * @param expr - Cron string (`min hour dom month dow`).\n * @param opts - Producer options plus `tickMs` (default `60_000`) and `output` (`timestamp_ns` default, or `date` for `Date` values).\n * @returns `Node<number>` (nanosecond timestamp) or `Node<Date>` when `output: \"date\"`.\n *\n * @example\n * ```ts\n * import { fromCron } from \"@graphrefly/graphrefly-ts\";\n *\n * fromCron(\"0 9 * * 1\");\n * ```\n *\n * @category extra\n */\nexport function fromCron(expr: string, opts?: FromCronOptions & { output: \"date\" }): Node<Date>;\nexport function fromCron(expr: string, opts?: FromCronOptions): Node<number>;\nexport function fromCron(expr: string, opts?: FromCronOptions): Node<number | Date> {\n\tconst schedule: CronSchedule = parseCron(expr);\n\tconst { tickMs: tickOpt, output, ...rest } = opts ?? {};\n\tconst tickMs = tickOpt ?? 60_000;\n\tconst emitDate = output === \"date\";\n\treturn producer<number | Date>(\n\t\t(_d, a) => {\n\t\t\tlet lastFiredKey = -1;\n\t\t\tconst check = () => {\n\t\t\t\tconst now = new Date();\n\t\t\t\tconst key =\n\t\t\t\t\tnow.getFullYear() * 100_000_000 +\n\t\t\t\t\t(now.getMonth() + 1) * 1_000_000 +\n\t\t\t\t\tnow.getDate() * 10_000 +\n\t\t\t\t\tnow.getHours() * 100 +\n\t\t\t\t\tnow.getMinutes();\n\t\t\t\tif (key !== lastFiredKey && matchesCron(schedule, now)) {\n\t\t\t\t\tlastFiredKey = key;\n\t\t\t\t\ta.emit(emitDate ? now : wallClockNs());\n\t\t\t\t}\n\t\t\t};\n\t\t\tcheck();\n\t\t\tconst id = setInterval(check, tickMs);\n\t\t\treturn () => clearInterval(id);\n\t\t},\n\t\t{ ...sourceOpts(rest), name: rest.name ?? `cron:${expr}` },\n\t);\n}\n\n/**\n * Wraps a DOM-style `addEventListener` target; each event becomes a `DATA` emission.\n *\n * @param target - Object with `addEventListener` / `removeEventListener`.\n * @param type - Event name (e.g. `\"click\"`).\n * @param opts - Producer options plus listener options (`capture`, `passive`, `once`).\n * @returns `Node<T>` — event payloads; teardown removes the listener.\n *\n * @example\n * ```ts\n * import { fromEvent } from \"@graphrefly/graphrefly-ts\";\n *\n * fromEvent(document.body, \"click\");\n * ```\n *\n * @category extra\n */\nexport function fromEvent<T = unknown>(\n\ttarget: EventTargetLike,\n\ttype: string,\n\topts?: ExtraOpts & { capture?: boolean; passive?: boolean; once?: boolean },\n): Node<T> {\n\tconst { capture, passive, once, ...rest } = opts ?? {};\n\treturn producer<T>((_d, a) => {\n\t\tconst handler = (e: unknown) => {\n\t\t\ta.emit(e as T);\n\t\t};\n\t\tconst options = { capture, passive, once };\n\t\ttarget.addEventListener(type, handler, options);\n\t\treturn () => target.removeEventListener(type, handler, options);\n\t}, sourceOpts(rest));\n}\n\n/**\n * Watches filesystem paths and emits debounced change events.\n *\n * Uses `fs.watch` only (no polling fallback). Teardown closes all watchers.\n *\n * @category extra\n */\nexport function fromFSWatch(paths: string | string[], opts?: FromFSWatchOptions): Node<FSEvent> {\n\tconst list = Array.isArray(paths) ? paths : [paths];\n\tif (list.length === 0) {\n\t\tthrow new RangeError(\"fromFSWatch expects at least one path\");\n\t}\n\tconst { recursive = true, debounce = 100, include, exclude, ...rest } = opts ?? {};\n\tconst includePatterns = include?.map(globToRegExp) ?? [];\n\tconst excludePatterns = (exclude ?? [\"**/node_modules/**\", \"**/.git/**\", \"**/dist/**\"]).map(\n\t\tglobToRegExp,\n\t);\n\treturn producer<FSEvent>((_d, a) => {\n\t\tconst pending = new Map<string, FSEvent>();\n\t\tconst watchers: ReturnType<typeof watch>[] = [];\n\t\tlet stopped = false;\n\t\tlet terminalEmitted = false;\n\t\tlet generation = 0;\n\t\tconst closeWatchers = () => {\n\t\t\tfor (const watcher of watchers.splice(0)) watcher.close();\n\t\t};\n\t\tconst emitError = (err: unknown) => {\n\t\t\tif (terminalEmitted) return;\n\t\t\tterminalEmitted = true;\n\t\t\tstopped = true;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t\tpending.clear();\n\t\t\tcloseWatchers();\n\t\t\ta.down([[ERROR, err]]);\n\t\t};\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tconst flush = (token: number) => {\n\t\t\ttimer = undefined;\n\t\t\tif (stopped || terminalEmitted) return;\n\t\t\tif (pending.size === 0) return;\n\t\t\tconst batchMessages: Message[] = [];\n\t\t\tfor (const evt of pending.values()) batchMessages.push([DATA, evt]);\n\t\t\tpending.clear();\n\t\t\tif (stopped || terminalEmitted || token !== generation) return;\n\t\t\ta.down(batchMessages);\n\t\t};\n\t\ttry {\n\t\t\tfor (const basePath of list) {\n\t\t\t\tconst watcher = watch(\n\t\t\t\t\tbasePath,\n\t\t\t\t\t{ recursive },\n\t\t\t\t\t(eventType: \"rename\" | \"change\", fileName: string | Buffer | null) => {\n\t\t\t\t\t\tif (stopped || terminalEmitted) return;\n\t\t\t\t\t\tif (fileName == null) return;\n\t\t\t\t\t\tconst rel = String(fileName).replaceAll(\"\\\\\", \"/\");\n\t\t\t\t\t\tconst abs = resolvePath(basePath, String(fileName));\n\t\t\t\t\t\tconst normalized = abs.replaceAll(\"\\\\\", \"/\");\n\t\t\t\t\t\tconst root = resolvePath(basePath).replaceAll(\"\\\\\", \"/\");\n\t\t\t\t\t\tconst relForMatch = rel.startsWith(\"./\") ? rel.slice(2) : rel;\n\t\t\t\t\t\tconst included =\n\t\t\t\t\t\t\tincludePatterns.length === 0 ||\n\t\t\t\t\t\t\tmatchesAnyPattern(normalized, includePatterns) ||\n\t\t\t\t\t\t\tmatchesAnyPattern(relForMatch, includePatterns);\n\t\t\t\t\t\tif (!included) return;\n\t\t\t\t\t\tconst excluded =\n\t\t\t\t\t\t\tmatchesAnyPattern(normalized, excludePatterns) ||\n\t\t\t\t\t\t\tmatchesAnyPattern(relForMatch, excludePatterns);\n\t\t\t\t\t\tif (excluded) return;\n\t\t\t\t\t\tlet kind: FSEventType = \"change\";\n\t\t\t\t\t\tif (eventType === \"rename\") {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tkind = existsSync(normalized) ? \"create\" : \"delete\";\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tkind = \"rename\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpending.set(normalized, {\n\t\t\t\t\t\t\ttype: kind,\n\t\t\t\t\t\t\tpath: normalized,\n\t\t\t\t\t\t\troot,\n\t\t\t\t\t\t\trelative_path: relForMatch,\n\t\t\t\t\t\t\ttimestamp_ns: wallClockNs(),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\t\t\t\tconst token = generation;\n\t\t\t\t\t\ttimer = setTimeout(() => flush(token), debounce);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\twatcher.on(\"error\", (err) => emitError(err));\n\t\t\t\twatchers.push(watcher);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\temitError(err);\n\t\t}\n\t\treturn () => {\n\t\t\tstopped = true;\n\t\t\tgeneration += 1;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t\tcloseWatchers();\n\t\t\tpending.clear();\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/**\n * Drains a synchronous iterable; each item is `DATA`, then `COMPLETE`, or `ERROR` if iteration throws.\n *\n * @param iterable - Values to emit in order.\n * @param opts - Optional producer options.\n * @returns `Node<T>` — one emission per element.\n *\n * @example\n * ```ts\n * import { fromIter } from \"@graphrefly/graphrefly-ts\";\n *\n * fromIter([1, 2, 3]);\n * ```\n *\n * @category extra\n */\nexport function fromIter<T>(iterable: Iterable<T>, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((_d, a) => {\n\t\tlet cancelled = false;\n\t\ttry {\n\t\t\tfor (const x of iterable) {\n\t\t\t\tif (cancelled) return;\n\t\t\t\ta.emit(x);\n\t\t\t}\n\t\t\tif (!cancelled) a.down([[COMPLETE]]);\n\t\t} catch (e) {\n\t\t\tif (!cancelled) a.down([[ERROR, e]]);\n\t\t}\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t};\n\t}, sourceOpts(opts));\n}\n\nfunction isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\n/**\n * Lifts a Promise (or thenable) to a single-value stream: one `DATA` then `COMPLETE`, or `ERROR` on rejection.\n *\n * @param p - Promise to await.\n * @param opts - Producer options plus optional `signal` for abort → `ERROR` with reason.\n * @returns `Node<T>` — settles once.\n *\n * @example\n * ```ts\n * import { fromPromise } from \"@graphrefly/graphrefly-ts\";\n *\n * fromPromise(Promise.resolve(42));\n * ```\n *\n * @category extra\n */\nexport function fromPromise<T>(p: Promise<T> | PromiseLike<T>, opts?: AsyncSourceOpts): Node<T> {\n\tconst { signal, ...rest } = opts ?? {};\n\treturn producer<T>((_d, a) => {\n\t\tlet settled = false;\n\t\tconst onAbort = () => {\n\t\t\tif (settled) return;\n\t\t\tsettled = true;\n\t\t\ta.down([[ERROR, signal!.reason]]);\n\t\t};\n\t\tif (signal?.aborted) {\n\t\t\tonAbort();\n\t\t\treturn;\n\t\t}\n\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\tvoid Promise.resolve(p).then(\n\t\t\t(v) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\ta.emit(v as T);\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t},\n\t\t\t(e) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\ta.down([[ERROR, e]]);\n\t\t\t},\n\t\t);\n\t\treturn () => {\n\t\t\tsettled = true;\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\t}, sourceOpts(rest));\n}\n\n/**\n * Reads an async iterable; each `next()` value becomes `DATA`; `COMPLETE` when done; `ERROR` on failure.\n *\n * @param iterable - Async source (`for await` shape).\n * @param opts - Producer options plus optional `signal` to abort the pump.\n * @returns `Node<T>` — async pull stream.\n *\n * @example\n * ```ts\n * import { fromAsyncIter } from \"@graphrefly/graphrefly-ts\";\n *\n * async function* gen() {\n * yield 1;\n * }\n * fromAsyncIter(gen());\n * ```\n *\n * @category extra\n */\nexport function fromAsyncIter<T>(iterable: AsyncIterable<T>, opts?: AsyncSourceOpts): Node<T> {\n\tconst { signal: outerSignal, ...rest } = opts ?? {};\n\treturn producer<T>((_d, a) => {\n\t\tconst ac = new AbortController();\n\t\tconst onOuterAbort = () => ac.abort(outerSignal?.reason);\n\t\tif (outerSignal?.aborted) {\n\t\t\tac.abort(outerSignal.reason);\n\t\t} else {\n\t\t\touterSignal?.addEventListener(\"abort\", onOuterAbort, { once: true });\n\t\t}\n\t\tconst signal = outerSignal ?? ac.signal;\n\t\tlet cancelled = false;\n\t\tconst it = iterable[Symbol.asyncIterator]();\n\t\tconst pump = (): void => {\n\t\t\tif (cancelled || signal.aborted) return;\n\t\t\tvoid Promise.resolve(it.next()).then(\n\t\t\t\t(step) => {\n\t\t\t\t\tif (cancelled || signal.aborted) return;\n\t\t\t\t\tif (step.done) {\n\t\t\t\t\t\tqueueMicrotask(() => a.down([[COMPLETE]]));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\ta.emit(step.value as T);\n\t\t\t\t\tqueueMicrotask(pump);\n\t\t\t\t},\n\t\t\t\t(e) => {\n\t\t\t\t\tif (!cancelled && !signal.aborted) a.down([[ERROR, e]]);\n\t\t\t\t},\n\t\t\t);\n\t\t};\n\t\tqueueMicrotask(pump);\n\t\treturn () => {\n\t\t\tcancelled = true;\n\t\t\touterSignal?.removeEventListener(\"abort\", onOuterAbort);\n\t\t\tac.abort();\n\t\t\tvoid Promise.resolve(it.return?.()).catch(() => undefined);\n\t\t};\n\t}, sourceOpts(rest));\n}\n\nfunction isNode(x: unknown): x is Node {\n\treturn (\n\t\tx != null &&\n\t\ttypeof (x as Node).subscribe === \"function\" &&\n\t\ttypeof (x as Node).get === \"function\"\n\t);\n}\n\n/**\n * Coerces a value to a `Node` by shape: existing `Node` passthrough, thenable → {@link fromPromise},\n * async iterable → {@link fromAsyncIter}, sync iterable → {@link fromIter}, else scalar → {@link of}.\n *\n * @param input - Any value to wrap.\n * @param opts - Passed through when a Promise/async path is chosen.\n * @returns `Node` of the inferred element type.\n *\n * @example\n * ```ts\n * import { fromAny, state } from \"@graphrefly/graphrefly-ts\";\n *\n * fromAny(state(1));\n * fromAny(Promise.resolve(2));\n * ```\n *\n * @category extra\n */\nexport function fromAny<T>(input: NodeInput<T>, opts?: AsyncSourceOpts): Node<T> {\n\tif (isNode(input)) {\n\t\treturn input as Node<T>;\n\t}\n\tif (isThenable(input)) {\n\t\treturn fromPromise(input as PromiseLike<T>, opts);\n\t}\n\tif (input !== null && input !== undefined) {\n\t\tconst candidate = input as { [Symbol.asyncIterator]?: unknown; [Symbol.iterator]?: unknown };\n\t\tif (typeof candidate[Symbol.asyncIterator] === \"function\") {\n\t\t\treturn fromAsyncIter(input as AsyncIterable<T>, opts);\n\t\t}\n\t\tif (typeof candidate[Symbol.iterator] === \"function\") {\n\t\t\treturn fromIter(input as Iterable<T>, opts);\n\t\t}\n\t}\n\t// scalar fallback\n\treturn of(input as T);\n}\n\n/**\n * Emits each argument as `DATA` in order, then `COMPLETE` (implemented via {@link fromIter}).\n *\n * @param values - Values to emit.\n * @returns `Node<T>` — finite sequence.\n *\n * @example\n * ```ts\n * import { of } from \"@graphrefly/graphrefly-ts\";\n *\n * of(1, 2, 3);\n * ```\n *\n * @category extra\n */\nexport function of<T>(...values: T[]): Node<T> {\n\treturn fromIter(values, undefined);\n}\n\n/**\n * Completes immediately with no `DATA` (cold `EMPTY` analogue).\n *\n * @param opts - Optional producer options.\n * @returns `Node<T>` — terminal `COMPLETE` only.\n *\n * @example\n * ```ts\n * import { empty } from \"@graphrefly/graphrefly-ts\";\n *\n * empty();\n * ```\n *\n * @category extra\n */\nexport function empty<T = never>(opts?: ExtraOpts): Node<T> {\n\treturn producer<T>((_d, a) => {\n\t\ta.down([[COMPLETE]]);\n\t\treturn undefined;\n\t}, sourceOpts(opts));\n}\n\n/**\n * Never emits and never completes until teardown (cold `NEVER` analogue).\n *\n * @param opts - Optional producer options.\n * @returns `Node<T>` — silent until unsubscribed.\n *\n * @example\n * ```ts\n * import { never } from \"@graphrefly/graphrefly-ts\";\n *\n * never();\n * ```\n *\n * @category extra\n */\nexport function never<T = never>(opts?: ExtraOpts): Node<T> {\n\treturn producer<T>(() => undefined, sourceOpts(opts));\n}\n\n/**\n * Emits `ERROR` as soon as the producer starts (cold error source).\n *\n * @param err - Error payload forwarded as `ERROR` data.\n * @param opts - Optional producer options.\n * @returns `Node<never>` — terminates with `ERROR`.\n *\n * @example\n * ```ts\n * import { throwError } from \"@graphrefly/graphrefly-ts\";\n *\n * throwError(new Error(\"fail\"));\n * ```\n *\n * @category extra\n */\nexport function throwError(err: unknown, opts?: ExtraOpts): Node<never> {\n\treturn producer<never>((_d, a) => {\n\t\ta.down([[ERROR, err]]);\n\t\treturn undefined;\n\t}, sourceOpts(opts));\n}\n\n/**\n * Subscribes immediately and runs `fn` for each upstream `DATA`; returns unsubscribe.\n *\n * @param source - Upstream node.\n * @param fn - Side effect per value.\n * @param opts - Effect node options.\n * @returns Unsubscribe function (idempotent).\n *\n * @example\n * ```ts\n * import { forEach, state } from \"@graphrefly/graphrefly-ts\";\n *\n * const u = forEach(state(1), (v) => console.log(v));\n * u();\n * ```\n *\n * @category extra\n */\nexport function forEach<T>(source: Node<T>, fn: (value: T) => void, opts?: ExtraOpts): () => void {\n\tconst inner = node([source as Node], () => undefined, {\n\t\tdescribeKind: \"effect\",\n\t\t...opts,\n\t\tonMessage(msg: Message, _i, _a) {\n\t\t\tif (msg[0] === DATA) {\n\t\t\t\tfn(msg[1] as T);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\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 (operator 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\tconst acc: T[] = [];\n\treturn node<T[]>([source as Node], () => undefined, {\n\t\t...operatorOpts(opts),\n\t\tcompleteWhenDepsComplete: false,\n\t\tonMessage(msg: Message, _i, a) {\n\t\t\tif (msg[0] === DATA) {\n\t\t\t\tacc.push(msg[1] as T);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif (msg[0] === COMPLETE) {\n\t\t\t\ta.emit([...acc]);\n\t\t\t\ta.down([[COMPLETE]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\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.get()` when set by factory.\n * @returns `Node<T>` — hot ref-counted bridge.\n *\n * @example\n * ```ts\n * import { share, state } from \"@graphrefly/graphrefly-ts\";\n *\n * share(state(0));\n * ```\n *\n * @category extra\n */\nexport function share<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn producer<T>(\n\t\t(_d, a) =>\n\t\t\tsource.subscribe((msgs) => {\n\t\t\t\ta.down(msgs);\n\t\t\t}),\n\t\t{ ...sourceOpts(opts), initial: source.get() },\n\t);\n}\n\n/**\n * Like {@link share} with a bounded replay buffer: new subscribers receive the last `bufferSize`\n * `DATA` payloads (as separate batches) before live updates.\n *\n * @param source - Upstream node.\n * @param bufferSize - Maximum past values to replay (≥ 1).\n * @param opts - Producer options.\n * @returns `Node<T>` — multicast with replay on subscribe.\n *\n * @example\n * ```ts\n * import { replay, state } from \"@graphrefly/graphrefly-ts\";\n *\n * replay(state(0), 3);\n * ```\n *\n * @category extra\n */\nexport function replay<T>(source: Node<T>, bufferSize: number, opts?: ExtraOpts): Node<T> {\n\tif (bufferSize < 1) throw new RangeError(\"replay expects bufferSize >= 1\");\n\tconst buf: T[] = [];\n\tconst inner = producer<T>(\n\t\t(_d, a) =>\n\t\t\tsource.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\t\tbuf.push(m[1] as T);\n\t\t\t\t\t\tif (buf.length > bufferSize) buf.shift();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ta.down(msgs);\n\t\t\t}),\n\t\t{ ...sourceOpts(opts), initial: source.get() },\n\t);\n\treturn wrapSubscribeHook(inner, (sink) => {\n\t\tfor (const v of buf) {\n\t\t\tsink([[DATA, v]]);\n\t\t}\n\t});\n}\n\n/**\n * {@link replay} with `bufferSize === 1` — replays the latest `DATA` to new subscribers.\n *\n * @param source - Upstream node.\n * @param opts - Producer options.\n * @returns `Node<T>` — share + last-value replay.\n *\n * @example\n * ```ts\n * import { cached, state } from \"@graphrefly/graphrefly-ts\";\n *\n * cached(state(0));\n * ```\n *\n * @category extra\n */\nexport function cached<T>(source: Node<T>, opts?: ExtraOpts): Node<T> {\n\treturn replay(source, 1, opts);\n}\n\n/**\n * Converts the first `DATA` on `source` into a Promise; rejects on `ERROR` or `COMPLETE` without data.\n *\n * **Important:** This subscribes and waits for a **future** emission. Data that\n * has already flowed is gone and will not be seen. Call this *before* the upstream\n * emits, or use `source.get()` / `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\tconst unsub = 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\tqueueMicrotask(() => unsub());\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\tqueueMicrotask(() => unsub());\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\tqueueMicrotask(() => unsub());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\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.get()` / `source.status`.\n * See COMPOSITION-GUIDE §2 (subscription ordering).\n *\n * ```ts\n * const val = await firstWhere(strategy.node, snap => snap.size > 0);\n * ```\n *\n * @category extra\n */\nexport function firstWhere<T>(source: Node<T>, predicate: (value: T) => boolean): Promise<T> {\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst unsub = source.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (settled) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tconst v = m[1] as T;\n\t\t\t\t\tif (predicate(v)) {\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tresolve(v);\n\t\t\t\t\t\tqueueMicrotask(() => unsub());\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(m[1]);\n\t\t\t\t\tqueueMicrotask(() => unsub());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(new Error(\"completed without matching value\"));\n\t\t\t\t\tqueueMicrotask(() => unsub());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n// ——————————————————————————————————————————————————————————————\n// RxJS-compatible aliases\n// ——————————————————————————————————————————————————————————————\n\n/**\n * RxJS-named alias for {@link replay} — multicast with a replay buffer of size `bufferSize`.\n *\n * @param source - Upstream node.\n * @param bufferSize - Replay depth (≥ 1).\n * @param opts - Producer options.\n * @returns Same behavior as `replay`.\n *\n * @example\n * ```ts\n * import { shareReplay, state } from \"@graphrefly/graphrefly-ts\";\n *\n * shareReplay(state(0), 5);\n * ```\n *\n * @category extra\n */\nexport const shareReplay = replay;\n","/**\n * Watermark-based backpressure controller — reactive PAUSE/RESUME flow control.\n *\n * Purely synchronous, event-driven. No timers, no polling, no Promises.\n * Each controller instance uses a unique lockId so multiple controllers\n * on the same upstream node do not collide.\n *\n * @module\n */\n\nimport { type Messages, PAUSE, RESUME } from \"../core/messages.js\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type WatermarkOptions = {\n\t/** Pending count at which PAUSE is sent upstream. */\n\thighWaterMark: number;\n\t/** Pending count at which RESUME is sent upstream (after being paused). */\n\tlowWaterMark: number;\n};\n\nexport type WatermarkController = {\n\t/** Call when a DATA message is buffered/enqueued. Returns `true` if PAUSE was just sent. */\n\tonEnqueue(): boolean;\n\t/** Call when a buffered item is consumed. Returns `true` if RESUME was just sent. */\n\tonDequeue(): boolean;\n\t/** Current un-consumed item count. */\n\treadonly pending: number;\n\t/** Whether upstream is currently paused by this controller. */\n\treadonly paused: boolean;\n\t/** Dispose: if paused, sends RESUME to unblock upstream. */\n\tdispose(): void;\n};\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nlet nextLockId = 0;\n\n/**\n * Creates a watermark-based backpressure controller.\n *\n * @param sendUp - Callback that delivers messages upstream (typically `handle.up`).\n * @param opts - High/low watermark thresholds (item counts).\n * @returns A {@link WatermarkController}.\n *\n * @example\n * ```ts\n * const handle = graph.observe(\"fast-source\");\n * const wm = createWatermarkController(\n * (msgs) => handle.up(msgs),\n * { highWaterMark: 64, lowWaterMark: 16 },\n * );\n *\n * // In sink callback:\n * handle.subscribe((msgs) => {\n * for (const msg of msgs) {\n * if (msg[0] === DATA) {\n * buffer.push(msg[1]);\n * wm.onEnqueue();\n * }\n * }\n * });\n *\n * // When consumer drains:\n * const item = buffer.shift();\n * wm.onDequeue();\n * ```\n *\n * @category extra\n */\nexport function createWatermarkController(\n\tsendUp: (messages: Messages) => void,\n\topts: WatermarkOptions,\n): WatermarkController {\n\tif (opts.highWaterMark < 1) throw new RangeError(\"highWaterMark must be >= 1\");\n\tif (opts.lowWaterMark < 0) throw new RangeError(\"lowWaterMark must be >= 0\");\n\tif (opts.lowWaterMark >= opts.highWaterMark)\n\t\tthrow new RangeError(\"lowWaterMark must be < highWaterMark\");\n\tconst lockId = Symbol(`bp-${++nextLockId}`);\n\tlet pending = 0;\n\tlet paused = false;\n\n\treturn {\n\t\tonEnqueue(): boolean {\n\t\t\tpending += 1;\n\t\t\tif (!paused && pending >= opts.highWaterMark) {\n\t\t\t\tpaused = true;\n\t\t\t\tsendUp([[PAUSE, lockId]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tonDequeue(): boolean {\n\t\t\tif (pending > 0) pending -= 1;\n\t\t\tif (paused && pending <= opts.lowWaterMark) {\n\t\t\t\tpaused = false;\n\t\t\t\tsendUp([[RESUME, lockId]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tget pending() {\n\t\t\treturn pending;\n\t\t},\n\t\tget paused() {\n\t\t\treturn paused;\n\t\t},\n\t\tdispose() {\n\t\t\tif (paused) {\n\t\t\t\tpaused = false;\n\t\t\t\tsendUp([[RESUME, lockId]]);\n\t\t\t}\n\t\t},\n\t};\n}\n","/**\n * Reactive append-only log (roadmap §3.2) — emits `readonly T[]` snapshots directly.\n *\n * Internal version counter drives efficient equality without leaking `Versioned`\n * into the public API (spec §5.12).\n */\nimport { batch } from \"../core/batch.js\";\nimport { DATA, DIRTY } from \"../core/messages.js\";\nimport type { Node } from \"../core/node.js\";\nimport { derived, state } from \"../core/sugar.js\";\n\nexport type ReactiveLogOptions = {\n\tname?: string;\n\tmaxSize?: number;\n};\n\nexport type ReactiveLogBundle<T> = {\n\t/** Emits `readonly T[]` on each append/clear (two-phase). */\n\treadonly entries: Node<readonly T[]>;\n\tappend: (value: T) => void;\n\t/** Push all values, trim once, emit one snapshot. */\n\tappendMany: (values: readonly T[]) => void;\n\tclear: () => void;\n\t/** Remove the first `n` entries; emits snapshot. */\n\ttrimHead: (n: number) => void;\n\t/** Last `n` entries (or fewer); updates when the log changes. */\n\ttail: (n: number) => Node<readonly T[]>;\n};\n\n/**\n * Keep a derived node's dep wiring alive for `get()` without a user sink.\n * Returns the unsubscribe handle so callers can clean up.\n *\n * @remarks Derived views (`tail`, `logSlice`) install this so `get()` stays\n * wired without an external sink. The returned disposer is currently not\n * exposed on the bundle — subscriptions are released when the log bundle\n * becomes unreachable and the GC collects the closure.\n */\nfunction keepaliveDerived(n: Node<unknown>): () => void {\n\treturn n.subscribe(() => {});\n}\n\n/**\n * Creates an append-only reactive log with immutable array snapshots.\n *\n * @param initial - Optional seed entries (copied).\n * @param options - Optional `name` for `describe()` / debugging.\n * @returns Bundle with `entries` (state node), `append`, `clear`, and {@link ReactiveLogBundle.tail}.\n *\n * @remarks\n * **Derived views:** {@link tail} and {@link logSlice} install an internal noop subscription so\n * `get()` stays wired without an external sink; creating very many disposable derived nodes can\n * retain subscriptions until the log bundle is unreachable.\n *\n * @example\n * ```ts\n * import { reactiveLog } from \"@graphrefly/graphrefly-ts\";\n *\n * const lg = reactiveLog<number>([1, 2], { name: \"audit\" });\n * lg.append(3);\n * lg.entries.subscribe((msgs) => console.log(msgs));\n * ```\n *\n * @category extra\n */\nexport function reactiveLog<T>(\n\tinitial?: readonly T[],\n\toptions: ReactiveLogOptions = {},\n): ReactiveLogBundle<T> {\n\tconst { name, maxSize } = options;\n\tif (maxSize !== undefined && maxSize < 1) {\n\t\tthrow new RangeError(\"maxSize must be >= 1\");\n\t}\n\tconst buf: T[] = initial ? [...initial] : [];\n\tif (maxSize !== undefined && buf.length > maxSize) {\n\t\tbuf.splice(0, buf.length - maxSize);\n\t}\n\n\tconst entries = state<readonly T[]>(buf.length > 0 ? [...buf] : [], {\n\t\tname,\n\t\tdescribeKind: \"state\",\n\t\tequals: (a, b) => a === b,\n\t});\n\n\tfunction pushSnapshot(): void {\n\t\tconst snapshot: readonly T[] = [...buf];\n\t\tbatch(() => {\n\t\t\tentries.down([[DIRTY]]);\n\t\t\tentries.down([[DATA, snapshot]]);\n\t\t});\n\t}\n\n\tfunction trimBuf(): void {\n\t\tif (maxSize !== undefined && buf.length > maxSize) {\n\t\t\tbuf.splice(0, buf.length - maxSize);\n\t\t}\n\t}\n\n\tconst bundle: ReactiveLogBundle<T> = {\n\t\tentries,\n\n\t\tappend(value: T): void {\n\t\t\tbuf.push(value);\n\t\t\ttrimBuf();\n\t\t\tpushSnapshot();\n\t\t},\n\n\t\tappendMany(values: readonly T[]): void {\n\t\t\tif (values.length === 0) return;\n\t\t\tbuf.push(...values);\n\t\t\ttrimBuf();\n\t\t\tpushSnapshot();\n\t\t},\n\n\t\tclear(): void {\n\t\t\tif (buf.length === 0) return;\n\t\t\tbuf.length = 0;\n\t\t\tpushSnapshot();\n\t\t},\n\n\t\ttrimHead(n: number): void {\n\t\t\tif (n < 0) {\n\t\t\t\tthrow new RangeError(\"n must be >= 0\");\n\t\t\t}\n\t\t\tif (n === 0) return;\n\t\t\tif (n >= buf.length) {\n\t\t\t\tif (buf.length === 0) return;\n\t\t\t\tbuf.length = 0;\n\t\t\t} else {\n\t\t\t\tbuf.splice(0, n);\n\t\t\t}\n\t\t\tpushSnapshot();\n\t\t},\n\n\t\ttail(n: number): Node<readonly T[]> {\n\t\t\tif (n < 0) {\n\t\t\t\tthrow new RangeError(\"n must be >= 0\");\n\t\t\t}\n\t\t\tconst e = entries.get() as readonly T[];\n\t\t\tconst init = n === 0 ? [] : e.slice(Math.max(0, e.length - n));\n\t\t\tconst out = derived(\n\t\t\t\t[entries],\n\t\t\t\t([s]) => {\n\t\t\t\t\tconst list = s as readonly T[];\n\t\t\t\t\treturn n === 0 ? [] : list.slice(Math.max(0, list.length - n));\n\t\t\t\t},\n\t\t\t\t{ initial: init, describeKind: \"derived\" },\n\t\t\t);\n\t\t\tkeepaliveDerived(out);\n\t\t\treturn out;\n\t\t},\n\t};\n\n\treturn bundle;\n}\n\n/**\n * Builds a derived node for `entries.slice(start, stop)` (same semantics as `Array.prototype.slice`; `stop` exclusive).\n *\n * @param log - Log from {@link reactiveLog}.\n * @param start - Start index (must be `>= 0`).\n * @param stop - End index (exclusive); omit to slice to the end.\n * @returns Derived node emitting the sliced readonly array.\n *\n * @example\n * ```ts\n * import { reactiveLog, logSlice } from \"@graphrefly/graphrefly-ts\";\n *\n * const lg = reactiveLog<number>([10, 20, 30, 40, 50]);\n * const slice$ = logSlice(lg, 1, 4); // reactive view of [20, 30, 40]\n * slice$.subscribe((msgs) => console.log(msgs));\n *\n * lg.append(60); // slice$ now reflects [20, 30, 40] (indices 1–3 of updated log)\n * ```\n *\n * @category extra\n */\nexport function logSlice<T>(\n\tlog: ReactiveLogBundle<T>,\n\tstart: number,\n\tstop?: number,\n): Node<readonly T[]> {\n\tif (start < 0) {\n\t\tthrow new RangeError(\"start must be >= 0\");\n\t}\n\tconst e = log.entries.get() as readonly T[];\n\tconst init = stop === undefined ? e.slice(start) : e.slice(start, stop);\n\tconst out = derived(\n\t\t[log.entries],\n\t\t([s]) => {\n\t\t\tconst list = s as readonly T[];\n\t\t\treturn stop === undefined ? list.slice(start) : list.slice(start, stop);\n\t\t},\n\t\t{ initial: init, describeKind: \"derived\" },\n\t);\n\tkeepaliveDerived(out);\n\treturn out;\n}\n"],"mappings":"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","names":["node"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/compat/nestjs/index.ts","../src/compat/nestjs/decorators.ts","../src/compat/nestjs/tokens.ts","../src/compat/nestjs/explorer.ts","../src/compat/nestjs/gateway.ts","../src/compat/nestjs/guard.ts","../src/compat/nestjs/module.ts","../src/patterns/cqrs.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// NestJS integration — Module, DI, Lifecycle, RxJS bridge (Phase 5.5)\n// ---------------------------------------------------------------------------\n// Bridges GraphReFly into NestJS's DI container and RxJS-based ecosystem.\n// NestJS and RxJS are peer dependencies — install them in your NestJS app.\n//\n// Usage:\n// import { GraphReflyModule, InjectGraph, InjectNode, toObservable }\n// from '@graphrefly/graphrefly-ts/compat/nestjs';\n// ---------------------------------------------------------------------------\n\n// RxJS bridge (re-exported from extra for convenience)\nexport { type ToObservableOptions, toObservable } from \"../../extra/observable.js\";\n\n// Decorators\nexport {\n\tCOMMAND_HANDLERS,\n\tCommandHandler,\n\ttype CommandHandlerMeta,\n\tCQRS_EVENT_HANDLERS,\n\tCRON_HANDLERS,\n\tEVENT_HANDLERS,\n\tEventHandler,\n\ttype EventHandlerMeta,\n\tGraphCron,\n\ttype GraphCronMeta,\n\tGraphInterval,\n\ttype GraphIntervalMeta,\n\tINTERVAL_HANDLERS,\n\tInjectCqrsGraph,\n\tInjectGraph,\n\tInjectNode,\n\tOnGraphEvent,\n\ttype OnGraphEventMeta,\n\tQUERY_HANDLERS,\n\tQueryHandler,\n\ttype QueryHandlerMeta,\n\tSAGA_HANDLERS,\n\tSagaHandler,\n\ttype SagaHandlerMeta,\n} from \"./decorators.js\";\n// Explorer (event/schedule discovery)\nexport { GraphReflyEventExplorer } from \"./explorer.js\";\n// Gateway helpers (Phase 5.1)\nexport {\n\tObserveGateway,\n\ttype ObserveGatewayOptions,\n\ttype ObserveSSEOptions,\n\ttype ObserveSubscriptionOptions,\n\ttype ObserveWsCommand,\n\ttype ObserveWsMessage,\n\tobserveSSE,\n\tobserveSubscription,\n} from \"./gateway.js\";\n// Actor bridge (Phase 5.1)\nexport {\n\tACTOR_KEY,\n\ttype ActorExtractor,\n\tfromHeader,\n\tfromJwtPayload,\n\tGraphReflyGuard,\n\tGraphReflyGuardImpl,\n\tgetActor,\n} from \"./guard.js\";\n// Module & DI\nexport {\n\ttype GraphReflyCqrsOptions,\n\ttype GraphReflyFeatureOptions,\n\tGraphReflyModule,\n\ttype GraphReflyRootOptions,\n} from \"./module.js\";\n// Injection tokens\nexport {\n\tGRAPHREFLY_REQUEST_GRAPH,\n\tGRAPHREFLY_ROOT_GRAPH,\n\tgetGraphToken,\n\tgetNodeToken,\n} from \"./tokens.js\";\n","// ---------------------------------------------------------------------------\n// NestJS decorators for GraphReFly DI, events, and scheduling.\n// ---------------------------------------------------------------------------\n// NOTE: esbuild (used by vitest/vite) uses TC39 Stage 3 decorators, not\n// legacy TypeScript experimental decorators. Method decorators receive\n// (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext). We use\n// context.addInitializer() to register metadata when the class instance is\n// created, which runs before NestJS lifecycle hooks.\n// ---------------------------------------------------------------------------\n\nimport { Inject } from \"@nestjs/common\";\nimport {\n\tGRAPHREFLY_REQUEST_GRAPH,\n\tGRAPHREFLY_ROOT_GRAPH,\n\tgetGraphToken,\n\tgetNodeToken,\n} from \"./tokens.js\";\n\n/** Class constructor key for decorator registries and Nest `ModuleRef.get()`. */\nexport type DecoratorHostConstructor = abstract new (...args: unknown[]) => unknown;\n\n/**\n * TC39 Stage 3 class method decorator first argument (the method itself).\n * Narrower than `Function` for Biome `noBannedTypes`.\n */\nexport type DecoratorBoundMethod = (...args: unknown[]) => unknown;\n\n// ---------------------------------------------------------------------------\n// Global registries (populated by decorator initializers, read by explorer)\n// ---------------------------------------------------------------------------\n\nexport interface OnGraphEventMeta {\n\tnodeName: string;\n\tmethodKey: string | symbol;\n}\n\nexport interface GraphIntervalMeta {\n\tms: number;\n\tmethodKey: string | symbol;\n}\n\nexport interface GraphCronMeta {\n\texpr: string;\n\tmethodKey: string | symbol;\n}\n\n/** Registry: constructor → event handler metadata. */\nexport const EVENT_HANDLERS = new Map<DecoratorHostConstructor, OnGraphEventMeta[]>();\n/** Registry: constructor → interval metadata. */\nexport const INTERVAL_HANDLERS = new Map<DecoratorHostConstructor, GraphIntervalMeta[]>();\n/** Registry: constructor → cron metadata. */\nexport const CRON_HANDLERS = new Map<DecoratorHostConstructor, GraphCronMeta[]>();\n\n// ---------------------------------------------------------------------------\n// CQRS decorator metadata & registries (Phase 5.5 — CQRS replacement)\n// ---------------------------------------------------------------------------\n\nexport interface CommandHandlerMeta {\n\tcqrsName: string;\n\tcommandName: string;\n\tmethodKey: string | symbol;\n}\n\nexport interface EventHandlerMeta {\n\tcqrsName: string;\n\teventName: string;\n\tmethodKey: string | symbol;\n}\n\nexport interface QueryHandlerMeta {\n\tcqrsName: string;\n\tprojectionName: string;\n\tmethodKey: string | symbol;\n}\n\nexport interface SagaHandlerMeta {\n\tcqrsName: string;\n\teventNames: readonly string[];\n\tsagaName: string;\n\tmethodKey: string | symbol;\n}\n\n/** Registry: constructor → command handler metadata. */\nexport const COMMAND_HANDLERS = new Map<DecoratorHostConstructor, CommandHandlerMeta[]>();\n/** Registry: constructor → event handler metadata. */\nexport const CQRS_EVENT_HANDLERS = new Map<DecoratorHostConstructor, EventHandlerMeta[]>();\n/** Registry: constructor → query handler metadata. */\nexport const QUERY_HANDLERS = new Map<DecoratorHostConstructor, QueryHandlerMeta[]>();\n/** Registry: constructor → saga handler metadata. */\nexport const SAGA_HANDLERS = new Map<DecoratorHostConstructor, SagaHandlerMeta[]>();\n\n// ---------------------------------------------------------------------------\n// DI decorators\n// ---------------------------------------------------------------------------\n\n/**\n * Inject a `Graph` instance into a NestJS service or controller.\n *\n * - No argument → injects the root graph (from `forRoot()`).\n * - With `name` → injects the named feature graph (from `forFeature({ name })`).\n * - With `\"request\"` → injects the request-scoped graph (requires `requestScope: true`).\n *\n * @example\n * ```ts\n * @Injectable()\n * export class PaymentService {\n * constructor(\n * @InjectGraph() private root: Graph,\n * @InjectGraph(\"payments\") private payments: Graph,\n * ) {}\n * }\n * ```\n */\nexport function InjectGraph(name?: string): ParameterDecorator & PropertyDecorator {\n\tif (name === \"request\") return Inject(GRAPHREFLY_REQUEST_GRAPH);\n\treturn Inject(name ? getGraphToken(name) : GRAPHREFLY_ROOT_GRAPH);\n}\n\n/**\n * Inject a `CqrsGraph` instance into a NestJS service or controller.\n *\n * Typed alternative to `@InjectGraph(name)` — returns `CqrsGraph` instead of `Graph`,\n * giving access to `.command()`, `.dispatch()`, `.event()`, `.projection()`, `.saga()`.\n *\n * @param name - The CQRS graph name (from `forCqrs({ name })`).\n *\n * @example\n * ```ts\n * @Injectable()\n * export class OrderService {\n * constructor(@InjectCqrsGraph(\"orders\") private orders: CqrsGraph) {\n * orders.dispatch(\"placeOrder\", { id: \"1\" }); // fully typed\n * }\n * }\n * ```\n */\nexport function InjectCqrsGraph(name: string): ParameterDecorator & PropertyDecorator {\n\treturn Inject(getGraphToken(name));\n}\n\n/**\n * Inject a `Node` from the graph by its qualified path.\n *\n * The path must be declared in the `nodes` array of `forRoot()` or `forFeature()`.\n * The module registers a factory provider that resolves the node from the root graph\n * at injection time.\n *\n * @example\n * ```ts\n * GraphReflyModule.forRoot({ nodes: [\"payment::validate\"] })\n *\n * @Injectable()\n * export class PaymentService {\n * constructor(@InjectNode(\"payment::validate\") private validate: Node<boolean>) {}\n * }\n * ```\n */\nexport function InjectNode(path: string): ParameterDecorator & PropertyDecorator {\n\treturn Inject(getNodeToken(path));\n}\n\n// ---------------------------------------------------------------------------\n// Event & schedule method decorators (TC39 Stage 3 decorator API)\n// ---------------------------------------------------------------------------\n\n/**\n * Subscribe a method to a graph node's DATA emissions — replaces `@OnEvent()`.\n *\n * The method is called with the value payload on each `DATA` message from the\n * named node. Routes through `graph.observe()` so actor guards are respected.\n * Subscription is created on module init and disposed on destroy.\n *\n * For full protocol access (DIRTY, COMPLETE, ERROR, custom types), use\n * `graph.observe()` directly instead of this decorator.\n *\n * @param nodeName - Qualified node path (e.g. `\"orders::placed\"`).\n *\n * @example\n * ```ts\n * @Injectable()\n * export class OrderService {\n * @OnGraphEvent(\"orders::placed\")\n * handleOrder(value: Order) { ... }\n * }\n * ```\n */\nexport function OnGraphEvent(\n\tnodeName: string,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = EVENT_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ nodeName, methodKey });\n\t\t\tEVENT_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n/**\n * Run a method on a fixed interval — replaces `@Interval()` from `@nestjs/schedule`.\n *\n * Backed by a `fromTimer` node added to the root graph as `__schedule__.<className>.<methodName>`.\n * Visible in `graph.describe()`, pausable via `graph.signal(name, [[PAUSE]])`.\n *\n * @param ms - Interval in milliseconds.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class CleanupService {\n * @GraphInterval(5000)\n * pruneStale() { ... }\n * }\n * ```\n */\nexport function GraphInterval(\n\tms: number,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = INTERVAL_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ ms, methodKey });\n\t\t\tINTERVAL_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n/**\n * Run a method on a cron schedule — replaces `@Cron()` from `@nestjs/schedule`.\n *\n * Backed by a `fromCron` node added to the root graph as `__schedule__.<className>.<methodName>`.\n * Visible in `graph.describe()`, pausable via PAUSE/RESUME signals.\n *\n * @param expr - 5-field cron expression (`min hour dom month dow`).\n *\n * @example\n * ```ts\n * @Injectable()\n * export class ReportService {\n * @GraphCron(\"0 9 * * 1\")\n * weeklyReport() { ... }\n * }\n * ```\n */\nexport function GraphCron(\n\texpr: string,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = CRON_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ expr, methodKey });\n\t\t\tCRON_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// CQRS method decorators (Phase 5.5 — CQRS replacement)\n// ---------------------------------------------------------------------------\n\n/**\n * Register a method as a CQRS command handler — replaces `@CommandHandler()` from `@nestjs/cqrs`.\n *\n * The method receives `(payload, { emit })` — same signature as `CqrsGraph.command()` handlers.\n * Wired reactively via the explorer on module init.\n *\n * @param cqrsName - Name of the CQRS graph (from `forCqrs({ name })`).\n * @param commandName - Command to handle.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class OrderService {\n * @CommandHandler(\"orders\", \"placeOrder\")\n * handlePlace(payload: PlaceOrderDto, { emit }: CommandActions) {\n * emit(\"orderPlaced\", { orderId: payload.id, amount: payload.amount });\n * }\n * }\n * ```\n */\nexport function CommandHandler(\n\tcqrsName: string,\n\tcommandName: string,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = COMMAND_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ cqrsName, commandName, methodKey });\n\t\t\tCOMMAND_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n/**\n * Subscribe a method to CQRS event stream DATA — replaces `@EventsHandler()` from `@nestjs/cqrs`.\n *\n * The method receives each `CqrsEvent` envelope as events arrive. Subscription is reactive\n * via `graph.observe()` — actor guards are respected.\n *\n * @param cqrsName - Name of the CQRS graph.\n * @param eventName - Event stream to subscribe to.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class NotificationService {\n * @EventHandler(\"orders\", \"orderPlaced\")\n * onOrderPlaced(event: CqrsEvent<{ orderId: string }>) {\n * console.log(\"Order placed:\", event.payload.orderId);\n * }\n * }\n * ```\n */\nexport function EventHandler(\n\tcqrsName: string,\n\teventName: string,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = CQRS_EVENT_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ cqrsName, eventName, methodKey });\n\t\t\tCQRS_EVENT_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n/**\n * Subscribe a method to CQRS projection changes — replaces `@QueryHandler()` from `@nestjs/cqrs`.\n *\n * The method is called reactively whenever the projection's value changes (DATA emission).\n * This is push-based, not request-response — the projection recomputes on upstream events.\n *\n * @param cqrsName - Name of the CQRS graph.\n * @param projectionName - Projection to observe.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class DashboardService {\n * @QueryHandler(\"orders\", \"orderCount\")\n * onCountChanged(count: number) {\n * this.broadcast({ type: \"orderCount\", value: count });\n * }\n * }\n * ```\n */\nexport function QueryHandler(\n\tcqrsName: string,\n\tprojectionName: string,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = QUERY_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ cqrsName, projectionName, methodKey });\n\t\t\tQUERY_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n/**\n * Register a method as a CQRS saga — replaces RxJS saga streams from `@nestjs/cqrs`.\n *\n * The method receives each new `CqrsEvent` from the specified event streams. Backed by\n * `CqrsGraph.saga()` — tracks last-processed entry, only delivers new events.\n *\n * @param cqrsName - Name of the CQRS graph.\n * @param sagaName - Name for this saga node in the graph.\n * @param eventNames - Event streams to react to.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class FulfillmentService {\n * @SagaHandler(\"orders\", \"fulfillment\", [\"orderPlaced\", \"paymentConfirmed\"])\n * onOrderFlow(event: CqrsEvent) {\n * if (event.type === \"paymentConfirmed\") this.shipOrder(event.payload);\n * }\n * }\n * ```\n */\nexport function SagaHandler(\n\tcqrsName: string,\n\tsagaName: string,\n\teventNames: readonly string[],\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = SAGA_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ cqrsName, eventNames, sagaName, methodKey });\n\t\t\tSAGA_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n","// ---------------------------------------------------------------------------\n// NestJS DI tokens for GraphReFly integration.\n// ---------------------------------------------------------------------------\n\n/** Injection token for the root `Graph` singleton created by `forRoot()`. */\nexport const GRAPHREFLY_ROOT_GRAPH = Symbol.for(\"graphrefly:root-graph\");\n\n/** Injection token for `forRoot()` / `forFeature()` options. */\nexport const GRAPHREFLY_MODULE_OPTIONS = Symbol.for(\"graphrefly:module-options\");\n\n/** Injection token for the request-scoped `Graph` created by request scope config. */\nexport const GRAPHREFLY_REQUEST_GRAPH = Symbol.for(\"graphrefly:request-graph\");\n\n/**\n * Get the injection token for a named feature graph.\n *\n * Feature graphs registered via `GraphReflyModule.forFeature({ name })` are\n * injectable using this token (or via the `@InjectGraph(name)` decorator).\n */\nexport function getGraphToken(name: string): symbol {\n\treturn Symbol.for(`graphrefly:graph:${name}`);\n}\n\n/**\n * Get the injection token for a node at a qualified path.\n *\n * Nodes declared in `forRoot({ nodes })` or `forFeature({ nodes })` are\n * injectable using this token (or via the `@InjectNode(path)` decorator).\n */\nexport function getNodeToken(path: string): symbol {\n\treturn Symbol.for(`graphrefly:node:${path}`);\n}\n","// ---------------------------------------------------------------------------\n// GraphReflyEventExplorer — discovers @OnGraphEvent, @GraphInterval, @GraphCron\n// decorated methods and wires them to the root graph.\n// ---------------------------------------------------------------------------\n// Registered by `forRoot()`. On module init, reads global decorator registries,\n// resolves provider instances via ModuleRef, and creates reactive subscriptions\n// / timer nodes. On module destroy, disposes all subscriptions and removes\n// schedule nodes from the graph.\n//\n// Runtime is fully reactive — push-based via graph.observe().\n// No polling, no microtasks, no promises. Timer nodes use central fromTimer /\n// fromCron primitives.\n// ---------------------------------------------------------------------------\n\nimport type { OnModuleDestroy, OnModuleInit } from \"@nestjs/common\";\nimport type { ModuleRef } from \"@nestjs/core\";\nimport { DATA, type Messages } from \"../../core/messages.js\";\nimport { fromCron, fromTimer } from \"../../extra/sources.js\";\nimport type { Graph, GraphObserveOne } from \"../../graph/graph.js\";\nimport type { CqrsGraph } from \"../../patterns/cqrs.js\";\nimport {\n\tCOMMAND_HANDLERS,\n\ttype CommandHandlerMeta,\n\tCQRS_EVENT_HANDLERS,\n\tCRON_HANDLERS,\n\ttype DecoratorBoundMethod,\n\ttype DecoratorHostConstructor,\n\tEVENT_HANDLERS,\n\ttype EventHandlerMeta,\n\ttype GraphCronMeta,\n\ttype GraphIntervalMeta,\n\tINTERVAL_HANDLERS,\n\ttype OnGraphEventMeta,\n\tQUERY_HANDLERS,\n\ttype QueryHandlerMeta,\n\tSAGA_HANDLERS,\n\ttype SagaHandlerMeta,\n} from \"./decorators.js\";\nimport { getGraphToken } from \"./tokens.js\";\n\n/** Monotonic counter for schedule node name disambiguation. */\nlet scheduleSeq = 0;\n\nexport class GraphReflyEventExplorer implements OnModuleInit, OnModuleDestroy {\n\tprivate readonly disposers: Array<() => void> = [];\n\tprivate readonly scheduleNodeNames: string[] = [];\n\n\tconstructor(\n\t\tprivate readonly graph: Graph,\n\t\tprivate readonly moduleRef: ModuleRef,\n\t) {}\n\n\tonModuleInit(): void {\n\t\tthis.wireEvents();\n\t\tthis.wireIntervals();\n\t\tthis.wireCrons();\n\t\tthis.wireCqrsCommands();\n\t\tthis.wireCqrsEvents();\n\t\tthis.wireCqrsQueries();\n\t\tthis.wireCqrsSagas();\n\t}\n\n\tonModuleDestroy(): void {\n\t\tfor (const dispose of this.disposers) dispose();\n\t\tthis.disposers.length = 0;\n\n\t\tfor (const name of this.scheduleNodeNames) {\n\t\t\ttry {\n\t\t\t\tthis.graph.remove(name);\n\t\t\t} catch {\n\t\t\t\t// Node may already be gone if graph.destroy() ran first.\n\t\t\t}\n\t\t}\n\t\tthis.scheduleNodeNames.length = 0;\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @OnGraphEvent — reactive subscription via graph.observe()\n\t// -----------------------------------------------------------------------\n\n\tprivate wireEvents(): void {\n\t\tfor (const [ctor, metas] of EVENT_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireEventHandler(instance, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireEventHandler(instance: object, meta: OnGraphEventMeta): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\n\t\t// Route through graph.observe() so actor guards are respected.\n\t\tconst handle = this.observeNode(meta.nodeName);\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tbound(m[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.disposers.push(unsub);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @GraphInterval — reactive via fromTimer central timer primitive\n\t// -----------------------------------------------------------------------\n\n\tprivate wireIntervals(): void {\n\t\tfor (const [ctor, metas] of INTERVAL_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireIntervalHandler(instance, ctor, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireIntervalHandler(\n\t\tinstance: object,\n\t\tctor: DecoratorHostConstructor,\n\t\tmeta: GraphIntervalMeta,\n\t): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst className = ctor.name ?? \"anonymous\";\n\t\tconst nodeName = `__schedule__.${className}.${String(meta.methodKey)}.${scheduleSeq++}`;\n\n\t\tconst timerNode = fromTimer(meta.ms, { period: meta.ms, name: nodeName });\n\t\tthis.graph.add(nodeName, timerNode);\n\t\tthis.scheduleNodeNames.push(nodeName);\n\n\t\t// Subscribe through graph.observe() for consistency.\n\t\tconst handle = this.observeNode(nodeName);\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) bound(m[1]);\n\t\t\t}\n\t\t});\n\t\tthis.disposers.push(unsub);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @GraphCron — reactive via fromCron central timer primitive\n\t// -----------------------------------------------------------------------\n\n\tprivate wireCrons(): void {\n\t\tfor (const [ctor, metas] of CRON_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireCronHandler(instance, ctor, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireCronHandler(\n\t\tinstance: object,\n\t\tctor: DecoratorHostConstructor,\n\t\tmeta: GraphCronMeta,\n\t): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst className = ctor.name ?? \"anonymous\";\n\t\tconst nodeName = `__schedule__.${className}.${String(meta.methodKey)}.${scheduleSeq++}`;\n\n\t\tconst cronNode = fromCron(meta.expr, { name: nodeName });\n\t\tthis.graph.add(nodeName, cronNode);\n\t\tthis.scheduleNodeNames.push(nodeName);\n\n\t\t// Subscribe through graph.observe() for consistency.\n\t\tconst handle = this.observeNode(nodeName);\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) bound(m[1]);\n\t\t\t}\n\t\t});\n\t\tthis.disposers.push(unsub);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @CommandHandler — register method as CqrsGraph command handler\n\t// -----------------------------------------------------------------------\n\n\tprivate wireCqrsCommands(): void {\n\t\tfor (const [ctor, metas] of COMMAND_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireCqrsCommand(instance, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireCqrsCommand(instance: object, meta: CommandHandlerMeta): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst cqrsGraph = this.resolveCqrsGraph(meta.cqrsName);\n\t\tif (!cqrsGraph) return;\n\n\t\tcqrsGraph.command(meta.commandName, bound);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @EventHandler — subscribe method to CQRS event stream\n\t// -----------------------------------------------------------------------\n\n\tprivate wireCqrsEvents(): void {\n\t\tfor (const [ctor, metas] of CQRS_EVENT_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireCqrsEventHandler(instance, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireCqrsEventHandler(instance: object, meta: EventHandlerMeta): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst cqrsGraph = this.resolveCqrsGraph(meta.cqrsName);\n\t\tif (!cqrsGraph) return;\n\n\t\t// Ensure the event stream exists.\n\t\tcqrsGraph.event(meta.eventName);\n\n\t\t// Snapshot the highest seq already in the log so we only deliver new events.\n\t\t// Tracking by seq (monotonic per-graph) is robust against reactive log trim.\n\t\tconst eventNode = cqrsGraph.resolve(meta.eventName);\n\t\tconst existingEntries = eventNode.get() as readonly { seq: number }[] | undefined;\n\t\tlet lastSeq =\n\t\t\texistingEntries && existingEntries.length > 0\n\t\t\t\t? existingEntries[existingEntries.length - 1].seq\n\t\t\t\t: 0;\n\n\t\t// Subscribe reactively via graph.observe() — respects actor guards.\n\t\tconst handle = this.observeNodeOn(cqrsGraph, meta.eventName);\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tconst entries = m[1] as readonly { seq: number }[];\n\t\t\t\t\tfor (const entry of entries) {\n\t\t\t\t\t\tif (entry.seq > lastSeq) {\n\t\t\t\t\t\t\tbound(entry);\n\t\t\t\t\t\t\tlastSeq = entry.seq;\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});\n\t\tthis.disposers.push(unsub);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @QueryHandler — subscribe method to CQRS projection changes\n\t// -----------------------------------------------------------------------\n\n\tprivate wireCqrsQueries(): void {\n\t\tfor (const [ctor, metas] of QUERY_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireCqrsQuery(instance, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireCqrsQuery(instance: object, meta: QueryHandlerMeta): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst cqrsGraph = this.resolveCqrsGraph(meta.cqrsName);\n\t\tif (!cqrsGraph) return;\n\n\t\t// Subscribe reactively to the projection node — push on every DATA.\n\t\tconst handle = this.observeNodeOn(cqrsGraph, meta.projectionName);\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tbound(m[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.disposers.push(unsub);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @SagaHandler — register method as CqrsGraph saga (subgraph side effect)\n\t// -----------------------------------------------------------------------\n\n\tprivate wireCqrsSagas(): void {\n\t\tfor (const [ctor, metas] of SAGA_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireCqrsSaga(instance, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireCqrsSaga(instance: object, meta: SagaHandlerMeta): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst cqrsGraph = this.resolveCqrsGraph(meta.cqrsName);\n\t\tif (!cqrsGraph) return;\n\n\t\tcqrsGraph.saga(meta.sagaName, meta.eventNames, bound);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Helpers\n\t// -----------------------------------------------------------------------\n\n\tprivate observeNode(name: string): GraphObserveOne {\n\t\t// Overload resolution picks ObserveResult; cast to the correct single-node type.\n\t\treturn this.graph.observe(name) as unknown as GraphObserveOne;\n\t}\n\n\tprivate observeNodeOn(graph: Graph, name: string): GraphObserveOne {\n\t\treturn graph.observe(name) as unknown as GraphObserveOne;\n\t}\n\n\tprivate resolveCqrsGraph(name: string): CqrsGraph | null {\n\t\ttry {\n\t\t\treturn this.moduleRef.get(getGraphToken(name), { strict: false }) as CqrsGraph;\n\t\t} catch {\n\t\t\tconsole.warn(\n\t\t\t\t`[GraphReFly] CqrsGraph \"${name}\" not found in DI — ` +\n\t\t\t\t\t`did you import GraphReflyModule.forCqrs({ name: \"${name}\" })?`,\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate resolveInstance(ctor: DecoratorHostConstructor): object | null {\n\t\ttry {\n\t\t\treturn this.moduleRef.get(ctor, { strict: false });\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n}\n","// ---------------------------------------------------------------------------\n// NestJS Gateway helpers — reactive bridges from graph.observe() to transports.\n// ---------------------------------------------------------------------------\n// All helpers are push-based: they subscribe to `graph.observe()` with actor\n// context and forward DATA messages to the transport. No polling.\n//\n// Actor-scoped observation respects node guards (Phase 1.5). Clients only\n// see DATA values from nodes their Actor is allowed to observe.\n// ---------------------------------------------------------------------------\n\nimport type { Actor } from \"../../core/actor.js\";\nimport { COMPLETE, DATA, ERROR, type Messages, TEARDOWN } from \"../../core/messages.js\";\nimport { createWatermarkController, type WatermarkController } from \"../../extra/backpressure.js\";\nimport type { Graph, GraphObserveOne } from \"../../graph/graph.js\";\n\n// ---------------------------------------------------------------------------\n// Shared types\n// ---------------------------------------------------------------------------\n\n/**\n * Client-to-server commands for the WebSocket observe protocol.\n */\nexport type ObserveWsCommand =\n\t| { type: \"subscribe\"; path: string }\n\t| { type: \"unsubscribe\"; path: string }\n\t| { type: \"ack\"; path: string; count?: number };\n\n/**\n * Server-to-client messages for the WebSocket observe protocol.\n */\nexport type ObserveWsMessage<T = unknown> =\n\t| { type: \"data\"; path: string; value: T }\n\t| { type: \"error\"; path: string; error: string }\n\t| { type: \"complete\"; path: string }\n\t| { type: \"subscribed\"; path: string }\n\t| { type: \"unsubscribed\"; path: string }\n\t| { type: \"err\"; message: string };\n\n// ---------------------------------------------------------------------------\n// observeSSE — graph.observe() → SSE ReadableStream\n// ---------------------------------------------------------------------------\n\nexport type ObserveSSEOptions = {\n\tactor?: Actor;\n\tserialize?: (value: unknown) => string;\n\tkeepAliveMs?: number;\n\tsignal?: AbortSignal;\n\t/** Pending DATA count at which PAUSE is sent upstream. Enables backpressure when set. */\n\thighWaterMark?: number;\n\t/** Pending DATA count at which RESUME is sent upstream. Defaults to `Math.floor(highWaterMark / 2)`. */\n\tlowWaterMark?: number;\n};\n\n/**\n * Creates an SSE `ReadableStream` that streams DATA values from a graph node.\n *\n * Routes through `graph.observe(path, { actor })` so node guards are respected.\n * The stream emits `event: data` for DATA, `event: error` for ERROR, and\n * `event: complete` for COMPLETE (then closes). TEARDOWN also closes the stream.\n *\n * @param graph - The graph to observe.\n * @param path - Qualified node path to observe.\n * @param opts - Actor context, serialization, keep-alive.\n * @returns A `ReadableStream<Uint8Array>` suitable for NestJS SSE endpoints.\n *\n * @example\n * ```ts\n * @Sse(\"events/:path\")\n * streamEvents(@Param(\"path\") path: string, @Req() req: Request) {\n * return observeSSE(this.graph, path, { actor: getActor(req) });\n * }\n * ```\n */\nexport function observeSSE(\n\tgraph: Graph,\n\tpath: string,\n\topts?: ObserveSSEOptions,\n): ReadableStream<Uint8Array> {\n\tconst { actor, serialize = defaultSerialize, keepAliveMs, signal } = opts ?? {};\n\tconst encoder = new TextEncoder();\n\tlet stop: (() => void) | undefined;\n\tconst useBackpressure = opts?.highWaterMark != null;\n\n\tlet wm: WatermarkController | undefined;\n\tlet pullResolve: (() => void) | undefined;\n\n\t// When backpressure is enabled we tag buffered entries so pull() only calls\n\t// onDequeue for DATA frames (not keepalive, ERROR, or COMPLETE frames).\n\ttype BufEntry = { frame: Uint8Array; counted: boolean };\n\tconst taggedBuf: BufEntry[] = [];\n\tlet closed = false;\n\n\treturn new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\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\t// Unsub first to prevent further sink callbacks during dispose.\n\t\t\t\tunsub();\n\t\t\t\twm?.dispose();\n\t\t\t\t// Resolve any parked pull() promise so the stream can finish.\n\t\t\t\tpullResolve?.();\n\t\t\t\tpullResolve = undefined;\n\t\t\t\t// Flush remaining buffered frames before closing.\n\t\t\t\tfor (const entry of taggedBuf) controller.enqueue(entry.frame);\n\t\t\t\ttaggedBuf.length = 0;\n\t\t\t\tcontroller.close();\n\t\t\t};\n\t\t\tstop = close;\n\t\t\tconst onAbort = () => close();\n\n\t\t\tconst handle = graph.observe(path, { actor }) as unknown as GraphObserveOne;\n\n\t\t\tif (useBackpressure) {\n\t\t\t\twm = createWatermarkController((msgs) => handle.up(msgs), {\n\t\t\t\t\thighWaterMark: opts!.highWaterMark!,\n\t\t\t\t\tlowWaterMark: opts!.lowWaterMark ?? Math.floor(opts!.highWaterMark! / 2),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tunsub = handle.subscribe((msgs: Messages) => {\n\t\t\t\tfor (const msg of msgs) {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tconst t = msg[0];\n\t\t\t\t\tif (t === DATA) {\n\t\t\t\t\t\tconst frame = encoder.encode(sseFrame(\"data\", serialize(msg[1])));\n\t\t\t\t\t\tif (useBackpressure) {\n\t\t\t\t\t\t\ttaggedBuf.push({ frame, counted: true });\n\t\t\t\t\t\t\twm!.onEnqueue();\n\t\t\t\t\t\t\tpullResolve?.();\n\t\t\t\t\t\t\tpullResolve = undefined;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontroller.enqueue(frame);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tconst frame = encoder.encode(sseFrame(\"error\", serialize(msg[1])));\n\t\t\t\t\t\tif (useBackpressure) {\n\t\t\t\t\t\t\ttaggedBuf.push({ frame, counted: false });\n\t\t\t\t\t\t\tpullResolve?.();\n\t\t\t\t\t\t\tpullResolve = undefined;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontroller.enqueue(frame);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tclose();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === COMPLETE || t === TEARDOWN) {\n\t\t\t\t\t\tif (t === COMPLETE) {\n\t\t\t\t\t\t\tconst frame = encoder.encode(sseFrame(\"complete\"));\n\t\t\t\t\t\t\tif (useBackpressure) {\n\t\t\t\t\t\t\t\ttaggedBuf.push({ frame, counted: false });\n\t\t\t\t\t\t\t\tpullResolve?.();\n\t\t\t\t\t\t\t\tpullResolve = undefined;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcontroller.enqueue(frame);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\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// DIRTY, RESOLVED, and other protocol internals are not exposed to SSE clients\n\t\t\t\t}\n\t\t\t});\n\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\tif (useBackpressure) {\n\t\t\t\t\t\t// Keepalive frames bypass watermark accounting entirely.\n\t\t\t\t\t\ttaggedBuf.push({ frame: encoder.encode(\": keepalive\\n\\n\"), counted: false });\n\t\t\t\t\t\tpullResolve?.();\n\t\t\t\t\t\tpullResolve = undefined;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontroller.enqueue(encoder.encode(\": keepalive\\n\\n\"));\n\t\t\t\t\t}\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\tpull(controller) {\n\t\t\tif (!useBackpressure) return;\n\t\t\tif (closed) return;\n\t\t\tif (taggedBuf.length > 0) {\n\t\t\t\tconst entry = taggedBuf.shift()!;\n\t\t\t\tcontroller.enqueue(entry.frame);\n\t\t\t\tif (entry.counted) wm!.onDequeue();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// No data available — park until the sink callback pushes more.\n\t\t\treturn new Promise<void>((resolve) => {\n\t\t\t\tpullResolve = resolve;\n\t\t\t});\n\t\t},\n\t\tcancel() {\n\t\t\t// Guard against double-close (cancel may fire after COMPLETE/ERROR already closed).\n\t\t\ttry {\n\t\t\t\tstop?.();\n\t\t\t} catch {\n\t\t\t\t/* already closed */\n\t\t\t}\n\t\t},\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// observeSubscription — graph.observe() → AsyncIterableIterator (GraphQL)\n// ---------------------------------------------------------------------------\n\nexport type ObserveSubscriptionOptions<T = unknown> = {\n\tactor?: Actor;\n\t/**\n\t * Optional value filter. Only matching DATA values are enqueued.\n\t *\n\t * **Note:** `filter` and `highWaterMark` are semantically decoupled — the\n\t * watermark counts items that pass the filter, not total upstream work.\n\t * If the filter rejects most items, backpressure may never engage despite\n\t * high upstream throughput. For upstream-level resource protection, place a\n\t * filtering derived node in the graph before the observe point instead.\n\t */\n\tfilter?: (value: T) => boolean;\n\t/** Pending DATA count at which PAUSE is sent upstream. Enables backpressure when set. */\n\thighWaterMark?: number;\n\t/** Pending DATA count at which RESUME is sent upstream. Defaults to `Math.floor(highWaterMark / 2)`. */\n\tlowWaterMark?: number;\n};\n\n/**\n * Creates an `AsyncIterableIterator` that yields DATA values from a graph node.\n *\n * Designed for GraphQL subscription resolvers (Apollo, Mercurius, etc.).\n * Routes through `graph.observe(path, { actor })` for guard-scoped access.\n *\n * The iterator completes on COMPLETE/TEARDOWN and throws on ERROR.\n *\n * @param graph - The graph to observe.\n * @param path - Qualified node path to observe.\n * @param opts - Actor context, optional value filter.\n * @returns An async iterable that yields DATA payloads.\n *\n * @example\n * ```ts\n * // Apollo-style resolver\n * Subscription: {\n * orderStatus: {\n * subscribe: (_parent, args, ctx) =>\n * observeSubscription(ctx.graph, `orders::${args.id}::status`, {\n * actor: ctx.actor,\n * }),\n * },\n * }\n * ```\n */\nexport function observeSubscription<T = unknown>(\n\tgraph: Graph,\n\tpath: string,\n\topts?: ObserveSubscriptionOptions<T>,\n): AsyncIterableIterator<T> {\n\tconst { actor, filter } = opts ?? {};\n\n\ttype QueueItem = { done: false; value: T } | { done: true; value?: undefined; error?: Error };\n\n\tconst queue: QueueItem[] = [];\n\tconst waiters: Array<{\n\t\tresolve: (result: IteratorResult<T>) => void;\n\t\treject: (err: unknown) => void;\n\t}> = [];\n\tlet disposed = false;\n\n\tconst handle = graph.observe(path, { actor }) as unknown as GraphObserveOne;\n\n\tconst wm =\n\t\topts?.highWaterMark != null\n\t\t\t? createWatermarkController((msgs) => handle.up(msgs), {\n\t\t\t\t\thighWaterMark: opts.highWaterMark,\n\t\t\t\t\tlowWaterMark: opts.lowWaterMark ?? Math.floor(opts.highWaterMark / 2),\n\t\t\t\t})\n\t\t\t: undefined;\n\n\tconst dispose = () => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\twm?.dispose();\n\t\tunsub();\n\t};\n\n\tconst push = (item: QueueItem) => {\n\t\tif (disposed) return;\n\t\tif (waiters.length > 0) {\n\t\t\tconst w = waiters.shift()!;\n\t\t\tif (item.done && item.error) w.reject(item.error);\n\t\t\telse if (item.done) w.resolve({ done: true, value: undefined });\n\t\t\telse w.resolve({ done: false, value: item.value as T });\n\t\t\t// Direct handoff to waiter — no queue growth, no watermark increment.\n\t\t} else {\n\t\t\tqueue.push(item);\n\t\t\tif (!item.done) wm?.onEnqueue();\n\t\t}\n\t};\n\n\tconst unsub = handle.subscribe((msgs: Messages) => {\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\tif (filter && !filter(value)) continue;\n\t\t\t\tpush({ done: false, value });\n\t\t\t} else if (t === ERROR) {\n\t\t\t\tconst err = msg[1] instanceof Error ? msg[1] : new Error(String(msg[1]));\n\t\t\t\tpush({ done: true, error: err });\n\t\t\t\tdispose();\n\t\t\t\treturn;\n\t\t\t} else if (t === COMPLETE || t === TEARDOWN) {\n\t\t\t\tpush({ done: true });\n\t\t\t\tdispose();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\n\tconst iterator: AsyncIterableIterator<T> = {\n\t\tnext(): Promise<IteratorResult<T>> {\n\t\t\tif (queue.length > 0) {\n\t\t\t\tconst item = queue.shift()!;\n\t\t\t\tif (!item.done) wm?.onDequeue();\n\t\t\t\tif (item.done && item.error) return Promise.reject(item.error);\n\t\t\t\treturn Promise.resolve(\n\t\t\t\t\titem.done ? { done: true, value: undefined } : { done: false, value: item.value as T },\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (disposed) return Promise.resolve({ done: true, value: undefined });\n\t\t\treturn new Promise<IteratorResult<T>>((resolve, reject) => {\n\t\t\t\twaiters.push({ resolve, reject });\n\t\t\t});\n\t\t},\n\t\treturn(): Promise<IteratorReturnResult<undefined>> {\n\t\t\tdispose();\n\t\t\t// Resolve any pending waiters\n\t\t\tfor (const w of waiters) w.resolve({ done: true, value: undefined });\n\t\t\twaiters.length = 0;\n\t\t\treturn Promise.resolve({ done: true, value: undefined });\n\t\t},\n\t\tthrow(err: unknown): Promise<IteratorResult<T>> {\n\t\t\tdispose();\n\t\t\treturn Promise.reject(err);\n\t\t},\n\t\t[Symbol.asyncIterator]() {\n\t\t\treturn this;\n\t\t},\n\t};\n\n\treturn iterator;\n}\n\n// ---------------------------------------------------------------------------\n// ObserveGateway — graph.observe() → WebSocket (multi-path subscription)\n// ---------------------------------------------------------------------------\n\nexport type ObserveGatewayOptions = {\n\textractActor?: (client: unknown) => Actor | undefined;\n\tparse?: (data: string) => ObserveWsCommand;\n\t/** Pending DATA count per subscription at which PAUSE is sent upstream. Enables backpressure when set. */\n\thighWaterMark?: number;\n\t/** Pending DATA count per subscription at which RESUME is sent upstream. Defaults to `Math.floor(highWaterMark / 2)`. */\n\tlowWaterMark?: number;\n};\n\n/**\n * Manages per-client WebSocket subscriptions to graph nodes via `observe()`.\n *\n * Not a NestJS decorator or base class — a standalone helper that can be\n * wired into any WebSocket gateway. Each client can subscribe/unsubscribe\n * to individual node paths. Actor-scoped observation respects node guards.\n *\n * @example\n * ```ts\n * @WebSocketGateway()\n * export class GraphGateway {\n * private gw = new ObserveGateway(this.graph);\n *\n * constructor(@InjectGraph() private graph: Graph) {}\n *\n * handleConnection(client: WebSocket) {\n * this.gw.handleConnection(client);\n * }\n *\n * handleDisconnect(client: WebSocket) {\n * this.gw.handleDisconnect(client);\n * }\n *\n * @SubscribeMessage(\"observe\")\n * onObserve(client: WebSocket, data: unknown) {\n * this.gw.handleMessage(client, data);\n * }\n * }\n * ```\n */\nexport class ObserveGateway {\n\tprivate readonly clients = new Map<\n\t\tunknown,\n\t\tMap<string, { unsub: () => void; wm?: WatermarkController }>\n\t>();\n\tprivate readonly extractActor: (client: unknown) => Actor | undefined;\n\tprivate readonly parse: (data: string) => ObserveWsCommand;\n\tprivate readonly highWaterMark: number | undefined;\n\tprivate readonly lowWaterMark: number | undefined;\n\n\tconstructor(\n\t\tprivate readonly graph: Graph,\n\t\topts?: ObserveGatewayOptions,\n\t) {\n\t\tthis.extractActor = opts?.extractActor ?? (() => undefined);\n\t\tthis.parse = opts?.parse ?? defaultParseCommand;\n\t\tthis.highWaterMark = opts?.highWaterMark;\n\t\tthis.lowWaterMark = opts?.lowWaterMark;\n\t}\n\n\t/**\n\t * Register a new client. Call from `handleConnection`.\n\t */\n\thandleConnection(client: unknown): void {\n\t\tif (!this.clients.has(client)) {\n\t\t\tthis.clients.set(client, new Map());\n\t\t}\n\t}\n\n\t/**\n\t * Unregister a client and dispose all its subscriptions. Call from `handleDisconnect`.\n\t */\n\thandleDisconnect(client: unknown): void {\n\t\tconst subs = this.clients.get(client);\n\t\tif (!subs) return;\n\t\tfor (const entry of subs.values()) {\n\t\t\tentry.wm?.dispose();\n\t\t\tentry.unsub();\n\t\t}\n\t\tthis.clients.delete(client);\n\t}\n\n\t/**\n\t * Handle an incoming client message (subscribe/unsubscribe/ack command).\n\t *\n\t * @param client - The WebSocket client reference.\n\t * @param raw - Raw message data (string or parsed object).\n\t * @param send - Function to send a message back to the client.\n\t * Defaults to `client.send(JSON.stringify(msg))`.\n\t */\n\thandleMessage(client: unknown, raw: unknown, send?: (msg: ObserveWsMessage) => void): void {\n\t\tconst sender = send ?? defaultSend.bind(null, client);\n\t\tlet cmd: ObserveWsCommand;\n\t\ttry {\n\t\t\tcmd = typeof raw === \"string\" ? this.parse(raw) : (raw as ObserveWsCommand);\n\t\t} catch {\n\t\t\tsender({ type: \"err\", message: \"invalid command\" });\n\t\t\treturn;\n\t\t}\n\n\t\tif (cmd.type === \"subscribe\") {\n\t\t\tthis.subscribe(client, cmd.path, sender);\n\t\t} else if (cmd.type === \"unsubscribe\") {\n\t\t\tthis.unsubscribe(client, cmd.path, sender);\n\t\t} else if (cmd.type === \"ack\") {\n\t\t\tthis.ack(client, cmd.path, cmd.count ?? 1);\n\t\t} else {\n\t\t\tsender({ type: \"err\", message: `unknown command type: ${(cmd as { type: string }).type}` });\n\t\t}\n\t}\n\n\t/**\n\t * Number of active subscriptions for a client. Useful for tests.\n\t */\n\tsubscriptionCount(client: unknown): number {\n\t\treturn this.clients.get(client)?.size ?? 0;\n\t}\n\n\t/**\n\t * Dispose all clients and subscriptions.\n\t */\n\tdestroy(): void {\n\t\tfor (const [client] of this.clients) {\n\t\t\tthis.handleDisconnect(client);\n\t\t}\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Internal\n\t// -----------------------------------------------------------------------\n\n\tprivate subscribe(client: unknown, path: string, send: (msg: ObserveWsMessage) => void): void {\n\t\tlet subs = this.clients.get(client);\n\t\tif (!subs) {\n\t\t\tsubs = new Map();\n\t\t\tthis.clients.set(client, subs);\n\t\t}\n\t\tif (subs.has(path)) {\n\t\t\tsend({ type: \"subscribed\", path });\n\t\t\treturn;\n\t\t}\n\n\t\tconst actor = this.extractActor(client);\n\t\tlet handle: GraphObserveOne;\n\t\ttry {\n\t\t\thandle = this.graph.observe(path, { actor }) as unknown as GraphObserveOne;\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tsend({ type: \"err\", message });\n\t\t\treturn;\n\t\t}\n\n\t\tconst wm =\n\t\t\tthis.highWaterMark != null\n\t\t\t\t? createWatermarkController((msgs) => handle.up(msgs), {\n\t\t\t\t\t\thighWaterMark: this.highWaterMark,\n\t\t\t\t\t\tlowWaterMark: this.lowWaterMark ?? Math.floor(this.highWaterMark / 2),\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\n\t\tconst cleanup = () => {\n\t\t\twm?.dispose();\n\t\t\tunsub();\n\t\t\tsubs!.delete(path);\n\t\t};\n\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const msg of msgs) {\n\t\t\t\tconst t = msg[0];\n\t\t\t\tif (t === DATA) {\n\t\t\t\t\twm?.onEnqueue();\n\t\t\t\t\ttrySend(send, { type: \"data\", path, value: msg[1] });\n\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\tconst errMsg = msg[1] instanceof Error ? msg[1].message : String(msg[1]);\n\t\t\t\t\ttrySend(send, { type: \"error\", path, error: errMsg });\n\t\t\t\t\tcleanup();\n\t\t\t\t\treturn;\n\t\t\t\t} else if (t === COMPLETE || t === TEARDOWN) {\n\t\t\t\t\ttrySend(send, { type: \"complete\", path });\n\t\t\t\t\tcleanup();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// DIRTY, RESOLVED not exposed to WS clients\n\t\t\t}\n\t\t});\n\n\t\tsubs.set(path, { unsub, wm });\n\t\tsend({ type: \"subscribed\", path });\n\t}\n\n\tprivate unsubscribe(client: unknown, path: string, send: (msg: ObserveWsMessage) => void): void {\n\t\tconst subs = this.clients.get(client);\n\t\tconst entry = subs?.get(path);\n\t\tif (entry) {\n\t\t\tentry.wm?.dispose();\n\t\t\tentry.unsub();\n\t\t\tsubs!.delete(path);\n\t\t}\n\t\tsend({ type: \"unsubscribed\", path });\n\t}\n\n\tprivate ack(client: unknown, path: string, count: number): void {\n\t\tconst entry = this.clients.get(client)?.get(path);\n\t\tif (!entry?.wm) return;\n\t\tconst n = Math.min(Math.max(0, Math.floor(count)), 1024);\n\t\tfor (let i = 0; i < n; i++) entry.wm.onDequeue();\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction defaultSerialize(value: unknown): string {\n\tif (value instanceof Error) return value.message;\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n\nfunction sseFrame(event: string, data?: string): string {\n\tlet frame = `event: ${event}\\n`;\n\tif (data !== undefined) {\n\t\tfor (const line of data.split(\"\\n\")) {\n\t\t\tframe += `data: ${line}\\n`;\n\t\t}\n\t}\n\tframe += \"\\n\";\n\treturn frame;\n}\n\nfunction defaultParseCommand(data: string): ObserveWsCommand {\n\treturn JSON.parse(data) as ObserveWsCommand;\n}\n\nfunction defaultSend(client: unknown, msg: ObserveWsMessage): void {\n\ttry {\n\t\t(client as { send: (data: string) => void }).send(JSON.stringify(msg));\n\t} catch {\n\t\t/* client may have disconnected — swallow transport errors */\n\t}\n}\n\nfunction trySend(send: (msg: ObserveWsMessage) => void, msg: ObserveWsMessage): void {\n\ttry {\n\t\tsend(msg);\n\t} catch {\n\t\t/* transport error — client may have disconnected */\n\t}\n}\n","// ---------------------------------------------------------------------------\n// NestJS Actor bridge — maps NestJS ExecutionContext to GraphReFly Actor.\n// ---------------------------------------------------------------------------\n// Implements the NestJS `CanActivate` interface to extract an `Actor` from the\n// request (JWT payload, session, custom header, etc.) and attach it to the\n// request object for downstream graph operations.\n//\n// The decorator does NOT enforce access control — it merely bridges the NestJS\n// authentication context to GraphReFly's ABAC model. Actual access control\n// flows through node `policy()` guards reactively.\n// ---------------------------------------------------------------------------\n\nimport type { CanActivate, ExecutionContext } from \"@nestjs/common\";\nimport { type Actor, DEFAULT_ACTOR, normalizeActor } from \"../../core/actor.js\";\n\n/**\n * Property name under which the extracted {@link Actor} is stored on the\n * request object. Downstream code (controllers, gateways) reads\n * `req[ACTOR_KEY]` to pass actor context to graph operations.\n */\nexport const ACTOR_KEY = \"graphReflyActor\" as const;\n\n/**\n * Extracts a GraphReFly {@link Actor} from a NestJS {@link ExecutionContext}.\n *\n * Return `undefined` to fall back to {@link DEFAULT_ACTOR}.\n */\nexport type ActorExtractor = (context: ExecutionContext) => Actor | undefined;\n\n/**\n * Creates an {@link ActorExtractor} that reads a JWT payload from `req.user`\n * (the standard Passport.js location) and maps it to a GraphReFly {@link Actor}.\n *\n * @param mapping - Optional transform from the JWT payload to an Actor.\n * When omitted, the payload is used directly (must have `type` and `id`).\n *\n * @example\n * ```ts\n * // Default: req.user is already { type, id, ... }\n * GraphReflyGuard(fromJwtPayload())\n *\n * // Custom mapping from your JWT claims\n * GraphReflyGuard(fromJwtPayload((payload) => ({\n * type: payload.role === \"admin\" ? \"human\" : \"llm\",\n * id: payload.sub,\n * org: payload.org_id,\n * })))\n * ```\n */\nexport function fromJwtPayload(mapping?: (payload: unknown) => Actor): ActorExtractor {\n\treturn (context: ExecutionContext): Actor | undefined => {\n\t\tconst req = context.switchToHttp().getRequest();\n\t\tconst user = req?.user;\n\t\tif (user == null) return undefined;\n\t\tif (mapping) return mapping(user);\n\t\treturn user as Actor;\n\t};\n}\n\n/**\n * Creates an {@link ActorExtractor} that reads an Actor from a request header.\n *\n * The header value is parsed as JSON. Useful for service-to-service calls\n * where the caller embeds actor context in a custom header.\n *\n * @param headerName - HTTP header name (case-insensitive). Default: `\"x-graphrefly-actor\"`.\n *\n * @example\n * ```ts\n * GraphReflyGuard(fromHeader(\"x-actor\"))\n * ```\n */\nexport function fromHeader(headerName = \"x-graphrefly-actor\"): ActorExtractor {\n\treturn (context: ExecutionContext): Actor | undefined => {\n\t\tconst req = context.switchToHttp().getRequest();\n\t\tconst raw = req?.headers?.[headerName.toLowerCase()];\n\t\tif (typeof raw !== \"string\" || raw.length === 0) return undefined;\n\t\ttry {\n\t\t\treturn JSON.parse(raw) as Actor;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t};\n}\n\n/**\n * Reads the extracted {@link Actor} from a request object (set by {@link GraphReflyGuardImpl}).\n *\n * Returns {@link DEFAULT_ACTOR} if no actor was attached.\n *\n * @example\n * ```ts\n * @Get(\"status\")\n * getStatus(@Req() req: Request) {\n * const actor = getActor(req);\n * return this.graph.describe({ actor });\n * }\n * ```\n */\nexport function getActor(req: unknown): Actor {\n\tconst actor = (req as Record<string, unknown>)?.[ACTOR_KEY];\n\treturn actor != null ? normalizeActor(actor as Actor) : DEFAULT_ACTOR;\n}\n\n/**\n * NestJS guard that extracts a GraphReFly {@link Actor} from the execution\n * context and attaches it to the request as `req.graphReflyActor`.\n *\n * This guard always returns `true` (allows the request through). Access\n * control is handled by GraphReFly node guards (`policy()`), not by this\n * NestJS guard. The purpose is purely to **bridge** authentication context.\n *\n * @example\n * ```ts\n * // Global guard — every request gets an Actor\n * app.useGlobalGuards(new GraphReflyGuardImpl(fromJwtPayload()));\n *\n * // Controller-scoped\n * @UseGuards(GraphReflyGuard(fromJwtPayload()))\n * @Controller(\"api\")\n * export class ApiController { ... }\n * ```\n */\nexport class GraphReflyGuardImpl implements CanActivate {\n\tconstructor(private readonly extractor: ActorExtractor) {}\n\n\tcanActivate(context: ExecutionContext): boolean {\n\t\tconst actor = normalizeActor(this.extractor(context));\n\t\tconst req = context.switchToHttp().getRequest();\n\t\tif (req != null) {\n\t\t\t(req as Record<string, unknown>)[ACTOR_KEY] = actor;\n\t\t}\n\t\treturn true;\n\t}\n}\n\n/**\n * Factory that creates a {@link GraphReflyGuardImpl} instance. Use with\n * NestJS `@UseGuards()` or `app.useGlobalGuards()`.\n *\n * @param extractor - How to extract an Actor from the request context.\n * Defaults to {@link fromJwtPayload} (reads `req.user`).\n *\n * @example\n * ```ts\n * import { GraphReflyGuard, fromJwtPayload } from \"@graphrefly/graphrefly-ts/compat/nestjs\";\n *\n * @UseGuards(GraphReflyGuard())\n * @Controller(\"graph\")\n * export class GraphController { ... }\n * ```\n */\nexport function GraphReflyGuard(extractor?: ActorExtractor): GraphReflyGuardImpl {\n\treturn new GraphReflyGuardImpl(extractor ?? fromJwtPayload());\n}\n","// ---------------------------------------------------------------------------\n// GraphReflyModule — NestJS dynamic module for GraphReFly integration.\n// ---------------------------------------------------------------------------\n// Provides `forRoot()` and `forFeature()` following the standard NestJS\n// dynamic-module pattern. Lifecycle hooks wire graph creation on init and\n// `graph.destroy()` on teardown — TEARDOWN propagates through the graph\n// per GRAPHREFLY-SPEC §3.7.\n//\n// No decorator usage in this file — all DI is done via factory providers\n// so the library doesn't require `experimentalDecorators` in consumer's\n// tsconfig (only the consumer's NestJS app needs it).\n// ---------------------------------------------------------------------------\n\nimport {\n\ttype DynamicModule,\n\tModule,\n\ttype OnModuleDestroy,\n\ttype Provider,\n\tScope,\n} from \"@nestjs/common\";\nimport { ModuleRef } from \"@nestjs/core\";\nimport { Graph, type GraphPersistSnapshot } from \"../../graph/graph.js\";\nimport {\n\ttype CqrsGraph,\n\ttype CqrsOptions,\n\tcqrs,\n\ttype EventStoreAdapter,\n} from \"../../patterns/cqrs.js\";\nimport { GraphReflyEventExplorer } from \"./explorer.js\";\nimport {\n\tGRAPHREFLY_REQUEST_GRAPH,\n\tGRAPHREFLY_ROOT_GRAPH,\n\tgetGraphToken,\n\tgetNodeToken,\n} from \"./tokens.js\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport interface GraphReflyRootOptions {\n\t/** Root graph name (default: `\"root\"`). */\n\tname?: string;\n\t/** Snapshot to hydrate via `graph.restore()` after build. */\n\tsnapshot?: GraphPersistSnapshot;\n\t/** Build callback — registers nodes/mounts on the graph. */\n\tbuild?: (graph: Graph) => void;\n\t/** Qualified node paths to expose as injectable providers. */\n\tnodes?: readonly string[];\n\t/** Enable a request-scoped graph (injectable via `@InjectGraph(\"request\")`). */\n\trequestScope?: boolean;\n}\n\nexport interface GraphReflyCqrsOptions {\n\t/** Feature name — becomes the mount name in the root graph. */\n\tname: string;\n\t/** CQRS graph options (forwarded to `cqrs()` factory). */\n\tcqrs?: CqrsOptions;\n\t/** Build callback — registers commands, events, projections, sagas on the CqrsGraph. */\n\tbuild?: (graph: CqrsGraph) => void;\n\t/** Event store adapter for persistence (wired via `useEventStore()`). */\n\teventStore?: EventStoreAdapter;\n\t/**\n\t * Node paths (local to this feature) to expose as injectable providers.\n\t * Tokens are auto-qualified as `featureName::path`.\n\t */\n\tnodes?: readonly string[];\n}\n\nexport interface GraphReflyFeatureOptions {\n\t/** Feature name — becomes the mount name in the root graph. */\n\tname: string;\n\t/** Build callback — registers nodes/mounts on the feature graph. */\n\tbuild?: (graph: Graph) => void;\n\t/** Snapshot to hydrate after build. */\n\tsnapshot?: GraphPersistSnapshot;\n\t/**\n\t * Node paths (local to this feature) to expose as injectable providers.\n\t * Tokens are auto-qualified as `featureName::path` to avoid collisions.\n\t */\n\tnodes?: readonly string[];\n}\n\n// ---------------------------------------------------------------------------\n// Lifecycle classes (no decorators — DI is handled via factory providers)\n// ---------------------------------------------------------------------------\n\nclass GraphReflyRootLifecycle implements OnModuleDestroy {\n\tconstructor(readonly graph: Graph) {}\n\n\tonModuleDestroy(): void {\n\t\tthis.graph.destroy();\n\t}\n}\n\nclass GraphReflyRequestLifecycle implements OnModuleDestroy {\n\treadonly graph = new Graph(\"request\");\n\n\tonModuleDestroy(): void {\n\t\tthis.graph.destroy();\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Module\n// ---------------------------------------------------------------------------\n\n// NestJS dynamic modules convention: static `forRoot` / `forFeature` factories on a `@Module` class.\n@Module({})\n// biome-ignore lint/complexity/noStaticOnlyClass: NestJS `DynamicModule` pattern (`@Module` + static factories)\nexport class GraphReflyModule {\n\t/**\n\t * Register the root `Graph` singleton in the NestJS DI container.\n\t *\n\t * The root graph is `@Global()` — injectable everywhere without importing\n\t * the module again. Use `@InjectGraph()` to inject it.\n\t *\n\t * Lifecycle:\n\t * - **init:** Graph created in factory. If `build` is provided, it runs\n\t * first (registers nodes/mounts). If `snapshot` is provided, values\n\t * are restored via `graph.restore()`.\n\t * - **destroy:** Calls `graph.destroy()` — sends `[[TEARDOWN]]` to all\n\t * nodes, including mounted feature subgraphs (cascading teardown).\n\t */\n\tstatic forRoot(opts?: GraphReflyRootOptions): DynamicModule {\n\t\tconst options = opts ?? {};\n\t\tconst graphName = options.name ?? \"root\";\n\n\t\tconst providers: Provider[] = [\n\t\t\t{\n\t\t\t\tprovide: GRAPHREFLY_ROOT_GRAPH,\n\t\t\t\tuseFactory: () => {\n\t\t\t\t\tconst g = new Graph(graphName);\n\t\t\t\t\tif (options.build) options.build(g);\n\t\t\t\t\tif (options.snapshot) g.restore(options.snapshot);\n\t\t\t\t\treturn g;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tprovide: Symbol.for(\"graphrefly:root-lifecycle\"),\n\t\t\t\tuseFactory: (graph: Graph) => new GraphReflyRootLifecycle(graph),\n\t\t\t\tinject: [GRAPHREFLY_ROOT_GRAPH],\n\t\t\t},\n\t\t\t{\n\t\t\t\tprovide: GraphReflyEventExplorer,\n\t\t\t\tuseFactory: (graph: Graph, moduleRef: InstanceType<typeof ModuleRef>) =>\n\t\t\t\t\tnew GraphReflyEventExplorer(graph, moduleRef),\n\t\t\t\tinject: [GRAPHREFLY_ROOT_GRAPH, ModuleRef],\n\t\t\t},\n\t\t];\n\n\t\t// Node factory providers — each declared path gets a factory that\n\t\t// resolves the node from the root graph at injection time.\n\t\tif (options.nodes) {\n\t\t\tfor (const path of options.nodes) {\n\t\t\t\tproviders.push({\n\t\t\t\t\tprovide: getNodeToken(path),\n\t\t\t\t\tuseFactory: (graph: Graph) => graph.resolve(path),\n\t\t\t\t\tinject: [GRAPHREFLY_ROOT_GRAPH],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Request-scoped graph provider (opt-in).\n\t\tif (options.requestScope) {\n\t\t\tproviders.push(\n\t\t\t\t{\n\t\t\t\t\tprovide: Symbol.for(\"graphrefly:request-lifecycle\"),\n\t\t\t\t\tuseFactory: () => new GraphReflyRequestLifecycle(),\n\t\t\t\t\tscope: Scope.REQUEST,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tprovide: GRAPHREFLY_REQUEST_GRAPH,\n\t\t\t\t\tuseFactory: (lifecycle: GraphReflyRequestLifecycle) => lifecycle.graph,\n\t\t\t\t\tinject: [Symbol.for(\"graphrefly:request-lifecycle\")],\n\t\t\t\t\tscope: Scope.REQUEST,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tmodule: GraphReflyModule,\n\t\t\tglobal: true,\n\t\t\tproviders,\n\t\t\texports: [\n\t\t\t\tGRAPHREFLY_ROOT_GRAPH,\n\t\t\t\t...(options.nodes ?? []).map(getNodeToken),\n\t\t\t\t...(options.requestScope ? [GRAPHREFLY_REQUEST_GRAPH] : []),\n\t\t\t],\n\t\t};\n\t}\n\n\t/**\n\t * Register a feature subgraph that auto-mounts into the root graph.\n\t *\n\t * The feature graph is created in the factory, built/restored, then\n\t * mounted into root via `root.mount(name, featureGraph)`. On app\n\t * shutdown, root's `graph.destroy()` cascades TEARDOWN through all\n\t * mounted subgraphs (no explicit remove needed).\n\t *\n\t * Node tokens are auto-qualified as `featureName::path` to prevent\n\t * collisions between features declaring nodes with the same local name.\n\t *\n\t * Injectable via `@InjectGraph(name)`.\n\t */\n\tstatic forFeature(opts: GraphReflyFeatureOptions): DynamicModule {\n\t\tconst providers: Provider[] = [\n\t\t\t{\n\t\t\t\tprovide: getGraphToken(opts.name),\n\t\t\t\tuseFactory: (rootGraph: Graph) => {\n\t\t\t\t\tconst g = new Graph(opts.name);\n\t\t\t\t\tif (opts.build) opts.build(g);\n\t\t\t\t\tif (opts.snapshot) g.restore(opts.snapshot);\n\t\t\t\t\trootGraph.mount(opts.name, g);\n\t\t\t\t\treturn g;\n\t\t\t\t},\n\t\t\t\tinject: [GRAPHREFLY_ROOT_GRAPH],\n\t\t\t},\n\t\t];\n\n\t\t// Node factory providers for feature-scoped nodes.\n\t\t// Tokens are qualified as `featureName::path` to avoid cross-feature collisions.\n\t\tif (opts.nodes) {\n\t\t\tfor (const path of opts.nodes) {\n\t\t\t\tproviders.push({\n\t\t\t\t\tprovide: getNodeToken(`${opts.name}::${path}`),\n\t\t\t\t\tuseFactory: (graph: Graph) => graph.resolve(path),\n\t\t\t\t\tinject: [getGraphToken(opts.name)],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tmodule: GraphReflyModule,\n\t\t\tproviders,\n\t\t\texports: [\n\t\t\t\tgetGraphToken(opts.name),\n\t\t\t\t...(opts.nodes ?? []).map((p) => getNodeToken(`${opts.name}::${p}`)),\n\t\t\t],\n\t\t};\n\t}\n\n\t/**\n\t * Register a CQRS subgraph that auto-mounts into the root graph.\n\t *\n\t * Creates a `CqrsGraph` via the `cqrs()` factory (roadmap §4.5), mounts it\n\t * into the root graph, and exposes it for DI via `@InjectGraph(name)`.\n\t *\n\t * CQRS decorators (`@CommandHandler`, `@EventHandler`, `@QueryHandler`,\n\t * `@SagaHandler`) are discovered by the explorer and wired to this graph\n\t * on module init.\n\t *\n\t * @example\n\t * ```ts\n\t * GraphReflyModule.forCqrs({\n\t * name: \"orders\",\n\t * build: (g) => {\n\t * g.event(\"orderPlaced\");\n\t * g.projection(\"orderCount\", [\"orderPlaced\"], (_s, evts) => evts.length, 0);\n\t * },\n\t * })\n\t * ```\n\t */\n\tstatic forCqrs(opts: GraphReflyCqrsOptions): DynamicModule {\n\t\tconst providers: Provider[] = [\n\t\t\t{\n\t\t\t\tprovide: getGraphToken(opts.name),\n\t\t\t\tuseFactory: (rootGraph: Graph) => {\n\t\t\t\t\tconst g = cqrs(opts.name, opts.cqrs);\n\t\t\t\t\t// `useEventStore` is CqrsGraph API, not a React hook (Biome false positive).\n\t\t\t\t\t// biome-ignore lint/correctness/useHookAtTopLevel: not React; Nest provider factory\n\t\t\t\t\tif (opts.eventStore) g.useEventStore(opts.eventStore);\n\t\t\t\t\tif (opts.build) opts.build(g);\n\t\t\t\t\trootGraph.mount(opts.name, g);\n\t\t\t\t\treturn g;\n\t\t\t\t},\n\t\t\t\tinject: [GRAPHREFLY_ROOT_GRAPH],\n\t\t\t},\n\t\t];\n\n\t\tif (opts.nodes) {\n\t\t\tfor (const path of opts.nodes) {\n\t\t\t\tproviders.push({\n\t\t\t\t\tprovide: getNodeToken(`${opts.name}::${path}`),\n\t\t\t\t\tuseFactory: (graph: Graph) => graph.resolve(path),\n\t\t\t\t\tinject: [getGraphToken(opts.name)],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tmodule: GraphReflyModule,\n\t\t\tproviders,\n\t\t\texports: [\n\t\t\t\tgetGraphToken(opts.name),\n\t\t\t\t...(opts.nodes ?? []).map((p) => getNodeToken(`${opts.name}::${p}`)),\n\t\t\t],\n\t\t};\n\t}\n}\n","/**\n * CQRS patterns (roadmap §4.5).\n *\n * Composition layer over reactiveLog (3.2), pipeline/sagas (4.1), event bus (4.2),\n * projections (4.3). Guards (1.5) enforce command/query boundary.\n *\n * - `cqrs(name, opts?)` → `CqrsGraph` — top-level factory\n * - `CqrsGraph.command(name, handler)` — write-only node; guard rejects `observe`\n * - `CqrsGraph.event(name)` — backed by `reactiveLog`; append-only\n * - `CqrsGraph.projection(name, events, reducer, initial)` — read-only derived; guard rejects `write`\n * - `CqrsGraph.saga(name, events, handler)` — event-driven side effects\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { wallClockNs } from \"../core/clock.js\";\nimport { policy } from \"../core/guard.js\";\nimport { DATA, derived, type Node, node, state } from \"../core/index.js\";\nimport { reactiveLog } from \"../extra/reactive-log.js\";\nimport { Graph, type GraphOptions } from \"../graph/index.js\";\n\n// ---------------------------------------------------------------------------\n// Guards\n// ---------------------------------------------------------------------------\n\n/** Commands: write + signal allowed, observe denied. */\nconst COMMAND_GUARD = policy((allow, deny) => {\n\tallow(\"write\");\n\tallow(\"signal\");\n\tdeny(\"observe\");\n});\n\n/** Projections: observe + signal allowed, write denied. */\nconst PROJECTION_GUARD = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n/** Events: observe + signal allowed, write denied (appended internally). */\nconst EVENT_GUARD = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction cqrsMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn { cqrs: true, cqrs_type: kind, ...(extra ?? {}) };\n}\n\n/**\n * Keep a derived node's dep wiring alive for `get()` without a user sink.\n * Returns the unsubscribe handle so callers can clean up.\n */\nfunction keepalive(n: Node<unknown>): () => void {\n\treturn n.subscribe(() => {});\n}\n\n// ---------------------------------------------------------------------------\n// Event envelope\n// ---------------------------------------------------------------------------\n\n/**\n * Immutable envelope for events emitted by command handlers.\n *\n * `seq` is a per-graph monotonic counter that provides stable ordering when\n * multiple events share the same `timestampNs` (same wall-clock tick).\n */\nexport type CqrsEvent<T = unknown> = {\n\ttype: string;\n\tpayload: T;\n\t/** Wall-clock nanoseconds (via `wallClockNs()`). */\n\ttimestampNs: number;\n\t/** Monotonic sequence within this CqrsGraph instance. */\n\tseq: number;\n\t/** V0 identity of the event log node at append time (§6.0b). */\n\tv0?: { id: string; version: number };\n};\n\n// ---------------------------------------------------------------------------\n// Event store adapter\n// ---------------------------------------------------------------------------\n\n/**\n * Opaque replay cursor returned by `loadEvents`. Pass it back to\n * `loadEvents` to resume from the last position.\n */\nexport type EventStoreCursor = {\n\treadonly __brand?: \"EventStoreCursor\";\n\t[key: string]: unknown;\n};\n\n/**\n * Result of `loadEvents` — events plus an opaque cursor for resumption.\n */\nexport type LoadEventsResult = {\n\tevents: CqrsEvent[];\n\tcursor: EventStoreCursor | undefined;\n};\n\n/**\n * Pluggable persistence for CQRS events.\n *\n * **`persist`:** Must be synchronous. Called from the dispatch path inside\n * `batch()`. Adapters that need async I/O should buffer internally and\n * expose a `flush()` method for explicit drain.\n */\nexport interface EventStoreAdapter {\n\tpersist(event: CqrsEvent): void;\n\t/**\n\t * Load persisted events. When `cursor` is provided, returns only events\n\t * after that position. The returned `cursor` should be passed to the next\n\t * `loadEvents` call for incremental replay.\n\t */\n\tloadEvents(\n\t\teventType: string,\n\t\tcursor?: EventStoreCursor,\n\t): LoadEventsResult | Promise<LoadEventsResult>;\n\t/** Optional explicit flush for adapters with async I/O. */\n\tflush?(): Promise<void>;\n}\n\nexport class MemoryEventStore implements EventStoreAdapter {\n\tprivate readonly _store = new Map<string, CqrsEvent[]>();\n\n\tpersist(event: CqrsEvent): void {\n\t\tlet list = this._store.get(event.type);\n\t\tif (!list) {\n\t\t\tlist = [];\n\t\t\tthis._store.set(event.type, list);\n\t\t}\n\t\tlist.push(event);\n\t}\n\n\tloadEvents(eventType: string, cursor?: EventStoreCursor): LoadEventsResult {\n\t\tconst list = this._store.get(eventType) ?? [];\n\t\tconst sinceTs = (cursor as { timestampNs?: number } | undefined)?.timestampNs;\n\t\tconst sinceSeq = (cursor as { seq?: number } | undefined)?.seq;\n\t\tconst events =\n\t\t\tsinceTs == null\n\t\t\t\t? [...list]\n\t\t\t\t: list.filter(\n\t\t\t\t\t\t(e) =>\n\t\t\t\t\t\t\te.timestampNs > sinceTs || (e.timestampNs === sinceTs && e.seq > (sinceSeq ?? -1)),\n\t\t\t\t\t);\n\t\tconst lastEvent = events.length > 0 ? events[events.length - 1] : undefined;\n\t\treturn {\n\t\t\tevents,\n\t\t\tcursor: lastEvent ? { timestampNs: lastEvent.timestampNs, seq: lastEvent.seq } : cursor,\n\t\t};\n\t}\n\n\tclear(): void {\n\t\tthis._store.clear();\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Handler types\n// ---------------------------------------------------------------------------\n\nexport type CommandActions = {\n\t/** Append an event to a named event log (bypasses event guard). */\n\temit: (eventName: string, payload: unknown) => void;\n};\n\n/**\n * Command handler receives the dispatch payload and actions to emit events.\n *\n * **Purity:** Handlers should not mutate the payload. Event emission via\n * `actions.emit()` is the only sanctioned side effect.\n */\nexport type CommandHandler<T = unknown> = (payload: T, actions: CommandActions) => void;\n\n/**\n * Projection reducer folds events into a read model.\n *\n * **Purity contract:** Reducers MUST be pure — return a new state value\n * without mutating `state` or any event. The `state` parameter is the\n * original `initial` value on every invocation (full event-sourcing replay),\n * so mutation would corrupt future recomputations.\n */\nexport type ProjectionReducer<TState = unknown, TEvent = unknown> = (\n\tstate: TState,\n\tevents: readonly CqrsEvent<TEvent>[],\n) => TState;\n\nexport type SagaHandler<T = unknown> = (event: CqrsEvent<T>) => void;\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport type CqrsOptions = {\n\tgraph?: GraphOptions;\n};\n\n// ---------------------------------------------------------------------------\n// CqrsGraph\n// ---------------------------------------------------------------------------\n\ntype EventEntry = {\n\tlog: ReturnType<typeof reactiveLog<CqrsEvent>>;\n\tnode: Node<readonly CqrsEvent[]>;\n};\n\nexport class CqrsGraph extends Graph {\n\tprivate readonly _eventLogs = new Map<string, EventEntry>();\n\tprivate readonly _commandHandlers = new Map<string, CommandHandler<any>>();\n\tprivate readonly _projections = new Set<string>();\n\tprivate readonly _sagas = new Set<string>();\n\tprivate readonly _keepaliveDisposers: Array<() => void> = [];\n\tprivate _eventStore: EventStoreAdapter | undefined;\n\tprivate _seq = 0;\n\n\tconstructor(name: string, opts: CqrsOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t}\n\n\toverride destroy(): void {\n\t\tfor (const dispose of this._keepaliveDisposers) dispose();\n\t\tthis._keepaliveDisposers.length = 0;\n\t\tsuper.destroy();\n\t}\n\n\t// -- Events ---------------------------------------------------------------\n\n\t/**\n\t * Register a named event stream backed by `reactiveLog`.\n\t * Guard denies external `write` — only commands append internally.\n\t */\n\tevent(name: string): Node<readonly CqrsEvent[]> {\n\t\tconst existing = this._eventLogs.get(name);\n\t\tif (existing) return existing.node;\n\n\t\tconst log = reactiveLog<CqrsEvent>([], { name });\n\t\tconst entries = log.entries;\n\t\tconst guarded = derived<readonly CqrsEvent[]>(\n\t\t\t[entries],\n\t\t\t([snapshot]) => snapshot as readonly CqrsEvent[],\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"state\",\n\t\t\t\tmeta: cqrsMeta(\"event\", { event_name: name }),\n\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\tinitial: entries.get() as readonly CqrsEvent[],\n\t\t\t},\n\t\t);\n\t\tthis.add(name, guarded);\n\t\tthis._keepaliveDisposers.push(keepalive(guarded));\n\t\tthis._eventLogs.set(name, { log, node: guarded });\n\t\treturn guarded;\n\t}\n\n\t/** Internal: append to an event log, auto-registering if needed. */\n\tprivate _appendEvent(eventName: string, payload: unknown): void {\n\t\tlet entry = this._eventLogs.get(eventName);\n\t\tif (!entry) {\n\t\t\tthis.event(eventName);\n\t\t\tentry = this._eventLogs.get(eventName)!;\n\t\t}\n\t\t// Guard: reject dispatch to terminated event streams\n\t\tif (entry.node.status === \"completed\" || entry.node.status === \"errored\") {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot dispatch to terminated event stream \"${eventName}\" (status: ${entry.node.status}).`,\n\t\t\t);\n\t\t}\n\t\tconst nv = entry.log.entries.v;\n\t\tconst evt: CqrsEvent = {\n\t\t\ttype: eventName,\n\t\t\tpayload,\n\t\t\ttimestampNs: wallClockNs(),\n\t\t\tseq: ++this._seq,\n\t\t\t...(nv != null ? { v0: { id: nv.id, version: nv.version } } : {}),\n\t\t};\n\t\tentry.log.append(evt);\n\t\tif (this._eventStore) {\n\t\t\tthis._eventStore.persist(evt);\n\t\t}\n\t}\n\n\t// -- Commands -------------------------------------------------------------\n\n\t/**\n\t * Register a command with its handler. Guard denies `observe` (write-only).\n\t * Use `dispatch(name, payload)` to execute.\n\t *\n\t * The command node carries dynamic `meta.error` — a reactive companion\n\t * that holds the last handler error (or `null` on success).\n\t */\n\tcommand<T = unknown>(name: string, handler: CommandHandler<T>): Node<T> {\n\t\tconst cmdNode = state<T>(undefined as T, {\n\t\t\tname,\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: {\n\t\t\t\t...cqrsMeta(\"command\", { command_name: name }),\n\t\t\t\terror: null,\n\t\t\t},\n\t\t\tguard: COMMAND_GUARD,\n\t\t});\n\t\tthis.add(name, cmdNode);\n\t\tthis._commandHandlers.set(name, handler as CommandHandler<any>);\n\t\treturn cmdNode;\n\t}\n\n\t/**\n\t * Execute a registered command. Wraps the entire dispatch in `batch()` so\n\t * the command node DATA and all emitted events settle atomically.\n\t *\n\t * If the handler throws, `meta.error` on the command node is set to the\n\t * error and the exception is re-thrown.\n\t */\n\tdispatch<T = unknown>(commandName: string, payload: T): void {\n\t\tconst handler = this._commandHandlers.get(commandName);\n\t\tif (!handler) {\n\t\t\tthrow new Error(`Unknown command: \"${commandName}\". Register with .command() first.`);\n\t\t}\n\t\tconst cmdNode = this.resolve(commandName);\n\t\tbatch(() => {\n\t\t\tcmdNode.down([[DATA, payload]], { internal: true });\n\t\t\ttry {\n\t\t\t\thandler(payload, { emit: (eName, data) => this._appendEvent(eName, data) });\n\t\t\t\tcmdNode.meta.error.down([[DATA, null]], { internal: true });\n\t\t\t} catch (err) {\n\t\t\t\tcmdNode.meta.error.down([[DATA, err]], { internal: true });\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t});\n\t}\n\n\t// -- Projections ----------------------------------------------------------\n\n\t/**\n\t * Register a read-only projection derived from event streams.\n\t * Guard denies `write` — value is computed from events only.\n\t *\n\t * **Purity contract:** The `reducer` must be a pure function — it receives\n\t * the original `initial` on every invocation (full event-sourcing replay).\n\t * Never mutate `initial`; always return a new value.\n\t */\n\tprojection<TState>(\n\t\tname: string,\n\t\teventNames: readonly string[],\n\t\treducer: ProjectionReducer<TState>,\n\t\tinitial: TState,\n\t): Node<TState> {\n\t\tconst eventNodes = eventNames.map((eName) => {\n\t\t\tif (!this._eventLogs.has(eName)) this.event(eName);\n\t\t\treturn this._eventLogs.get(eName)!.node;\n\t\t});\n\n\t\tconst projNode = derived<TState>(\n\t\t\teventNodes,\n\t\t\t(snapshots) => {\n\t\t\t\tconst allEvents: CqrsEvent[] = [];\n\t\t\t\tfor (const snapshot of snapshots) {\n\t\t\t\t\tconst entries = snapshot as readonly CqrsEvent[];\n\t\t\t\t\tallEvents.push(...entries);\n\t\t\t\t}\n\t\t\t\tallEvents.sort((a, b) => a.timestampNs - b.timestampNs || a.seq - b.seq);\n\t\t\t\treturn reducer(initial, allEvents);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: cqrsMeta(\"projection\", { projection_name: name, source_events: eventNames }),\n\t\t\t\tguard: PROJECTION_GUARD,\n\t\t\t\tinitial,\n\t\t\t},\n\t\t);\n\n\t\tthis.add(name, projNode);\n\t\tfor (const eName of eventNames) this.connect(eName, name);\n\t\tthis._keepaliveDisposers.push(keepalive(projNode));\n\t\tthis._projections.add(name);\n\t\treturn projNode;\n\t}\n\n\t// -- Sagas ----------------------------------------------------------------\n\n\t/**\n\t * Register an event-driven side effect. Runs handler for each **new** event\n\t * from the specified streams (tracks last-processed entry count per stream).\n\t *\n\t * The saga node carries dynamic `meta.error` — a reactive companion that\n\t * holds the last handler error (or `null` on success). Handler errors do\n\t * not propagate out of the saga run (the event cursor still advances so\n\t * the same entry is not delivered twice).\n\t */\n\tsaga<T = unknown>(\n\t\tname: string,\n\t\teventNames: readonly string[],\n\t\thandler: SagaHandler<T>,\n\t): Node<unknown> {\n\t\tconst eventNodes = eventNames.map((eName) => {\n\t\t\tif (!this._eventLogs.has(eName)) this.event(eName);\n\t\t\treturn this._eventLogs.get(eName)!.node;\n\t\t});\n\n\t\t// Track last-processed entry count per event to only process new entries\n\t\tconst lastCounts = new Map<string, number>();\n\n\t\tconst sagaRef: { n?: Node<unknown> } = {};\n\t\tconst sagaNode = node(\n\t\t\teventNodes,\n\t\t\t(snapshots) => {\n\t\t\t\tconst errNode = sagaRef.n!.meta.error as Node<unknown>;\n\t\t\t\tfor (let i = 0; i < snapshots.length; i++) {\n\t\t\t\t\tconst entries = snapshots[i] as readonly CqrsEvent<T>[];\n\t\t\t\t\tconst eName = eventNames[i];\n\t\t\t\t\tconst lastCount = lastCounts.get(eName) ?? 0;\n\t\t\t\t\tif (entries.length > lastCount) {\n\t\t\t\t\t\tconst newEntries = entries.slice(lastCount);\n\t\t\t\t\t\tfor (const entry of newEntries) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\thandler(entry as CqrsEvent<T>);\n\t\t\t\t\t\t\t\terrNode.down([[DATA, null]], { internal: true });\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\terrNode.down([[DATA, err]], { internal: true });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlastCounts.set(eName, entries.length);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"effect\",\n\t\t\t\tmeta: {\n\t\t\t\t\t...cqrsMeta(\"saga\", { saga_name: name, source_events: eventNames }),\n\t\t\t\t\terror: null,\n\t\t\t\t},\n\t\t\t},\n\t\t) as Node<unknown>;\n\t\tsagaRef.n = sagaNode;\n\n\t\tthis.add(name, sagaNode);\n\t\tfor (const eName of eventNames) this.connect(eName, name);\n\t\tthis._keepaliveDisposers.push(keepalive(sagaNode));\n\t\tthis._sagas.add(name);\n\t\treturn sagaNode;\n\t}\n\n\t// -- Event store ----------------------------------------------------------\n\n\tuseEventStore(adapter: EventStoreAdapter): void {\n\t\tthis._eventStore = adapter;\n\t}\n\n\t/**\n\t * Replay persisted events through a reducer to rebuild a read model.\n\t * Requires an event store adapter wired via `useEventStore()`.\n\t */\n\tasync rebuildProjection<TState>(\n\t\teventNames: readonly string[],\n\t\treducer: ProjectionReducer<TState>,\n\t\tinitial: TState,\n\t): Promise<TState> {\n\t\tif (!this._eventStore) {\n\t\t\tthrow new Error(\"No event store wired. Call useEventStore() first.\");\n\t\t}\n\t\tconst allEvents: CqrsEvent[] = [];\n\t\tfor (const eName of eventNames) {\n\t\t\tconst result = await this._eventStore.loadEvents(eName);\n\t\t\tallEvents.push(...result.events);\n\t\t}\n\t\tallEvents.sort((a, b) => a.timestampNs - b.timestampNs || a.seq - b.seq);\n\t\treturn reducer(initial, allEvents);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a CQRS graph container.\n *\n * @example\n * ```ts\n * const app = cqrs(\"orders\");\n * app.event(\"orderPlaced\");\n * app.command(\"placeOrder\", (payload, { emit }) => {\n * emit(\"orderPlaced\", { orderId: payload.id, amount: payload.amount });\n * });\n * app.projection(\"orderCount\", [\"orderPlaced\"], (_s, events) => events.length, 0);\n * app.dispatch(\"placeOrder\", { id: \"1\", amount: 100 });\n * ```\n */\nexport function cqrs(name: string, opts?: CqrsOptions): CqrsGraph {\n\treturn new CqrsGraph(name, opts);\n}\n"],"mappings":"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","names":[]}