@graphrefly/ts 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/README.md +5 -7
  2. package/dist/{actions-types-DfRob139.d.cts → actions-types-BYzAurt6.d.cts} +1 -1
  3. package/dist/{actions-types-DcDaBRTC.d.ts → actions-types-CFJILlFn.d.ts} +1 -1
  4. package/dist/adapters/index.cjs.map +1 -1
  5. package/dist/adapters/index.d.cts +5 -5
  6. package/dist/adapters/index.d.ts +5 -5
  7. package/dist/adapters/index.js +7 -7
  8. package/dist/adapters/nestjs/microservices.d.cts +1 -1
  9. package/dist/adapters/nestjs/microservices.d.ts +1 -1
  10. package/dist/adapters/nestjs/native.d.cts +2 -2
  11. package/dist/adapters/nestjs/native.d.ts +2 -2
  12. package/dist/adapters/nestjs/native.js +2 -2
  13. package/dist/adapters/nestjs/websockets.d.cts +1 -1
  14. package/dist/adapters/nestjs/websockets.d.ts +1 -1
  15. package/dist/adapters/nestjs.d.cts +1 -1
  16. package/dist/adapters/nestjs.d.ts +1 -1
  17. package/dist/adapters/observe-storage.d.cts +1 -1
  18. package/dist/adapters/observe-storage.d.ts +1 -1
  19. package/dist/adapters/react.cjs.map +1 -1
  20. package/dist/adapters/react.d.cts +1 -1
  21. package/dist/adapters/react.d.ts +1 -1
  22. package/dist/adapters/react.js +1 -1
  23. package/dist/adapters/solid.cjs.map +1 -1
  24. package/dist/adapters/solid.d.cts +1 -1
  25. package/dist/adapters/solid.d.ts +1 -1
  26. package/dist/adapters/solid.js +1 -1
  27. package/dist/adapters/svelte.cjs.map +1 -1
  28. package/dist/adapters/svelte.d.cts +1 -1
  29. package/dist/adapters/svelte.d.ts +1 -1
  30. package/dist/adapters/svelte.js +1 -1
  31. package/dist/adapters/vue.cjs.map +1 -1
  32. package/dist/adapters/vue.d.cts +1 -1
  33. package/dist/adapters/vue.d.ts +1 -1
  34. package/dist/adapters/vue.js +1 -1
  35. package/dist/{agent-runtime-types-tool-CTZx51kE.d.cts → agent-runtime-types-tool-DSzCWLK4.d.cts} +1 -1
  36. package/dist/{agent-runtime-types-tool-B0jR0euI.d.ts → agent-runtime-types-tool-DUZUxrl5.d.ts} +1 -1
  37. package/dist/{capability-admission-CGmtVzfS.d.ts → capability-admission--qmB5qYW.d.ts} +1 -1
  38. package/dist/{capability-admission-BwmsThnQ.d.cts → capability-admission-BbiUMnpF.d.cts} +1 -1
  39. package/dist/{chunk-BIGKAHSX.js → chunk-2U4G3PEU.js} +8 -8
  40. package/dist/{chunk-FLUPPSIP.js → chunk-3KYPNNBH.js} +1 -1
  41. package/dist/chunk-3KYPNNBH.js.map +1 -0
  42. package/dist/{chunk-AVPXWVRL.js → chunk-BOWKPNXS.js} +2 -2
  43. package/dist/{chunk-LRYGIKWY.js → chunk-G3J4KZLK.js} +5 -5
  44. package/dist/{chunk-32WGWBYO.js → chunk-HFPPLLLQ.js} +2 -2
  45. package/dist/{chunk-VYAEEKZ3.js → chunk-IISXKNWE.js} +1 -1
  46. package/dist/chunk-IISXKNWE.js.map +1 -0
  47. package/dist/{chunk-DXBOAAPS.js → chunk-KTJ5LEOL.js} +1 -1
  48. package/dist/chunk-KTJ5LEOL.js.map +1 -0
  49. package/dist/{chunk-HT5R7S47.js → chunk-LPC42V2E.js} +3 -3
  50. package/dist/{chunk-STLRNFU7.js → chunk-T3YMFLRH.js} +3 -3
  51. package/dist/chunk-T3YMFLRH.js.map +1 -0
  52. package/dist/{chunk-V3MSIDUQ.js → chunk-TWOPVCGK.js} +2 -2
  53. package/dist/{chunk-ND43YDGK.js → chunk-V3YEGWSH.js} +1 -1
  54. package/dist/chunk-V3YEGWSH.js.map +1 -0
  55. package/dist/{chunk-2BIF6BQ7.js → chunk-W4ATMMTH.js} +2 -2
  56. package/dist/{committed-fact-log-backend-Cjhgia-O.d.ts → committed-fact-log-backend-B_h6A6cN.d.ts} +1 -1
  57. package/dist/{committed-fact-log-backend-BE3Fx5Zv.d.cts → committed-fact-log-backend-CIhiKL-Q.d.cts} +1 -1
  58. package/dist/composition/index.cjs.map +1 -1
  59. package/dist/composition/index.d.cts +1 -1
  60. package/dist/composition/index.d.ts +1 -1
  61. package/dist/composition/index.js +2 -2
  62. package/dist/cqrs/index.d.cts +1 -1
  63. package/dist/cqrs/index.d.ts +1 -1
  64. package/dist/cqrs/messaging.d.cts +1 -1
  65. package/dist/cqrs/messaging.d.ts +1 -1
  66. package/dist/cqrs/work-queue.d.cts +1 -1
  67. package/dist/cqrs/work-queue.d.ts +1 -1
  68. package/dist/data-structures/index.cjs.map +1 -1
  69. package/dist/data-structures/index.d.cts +5 -5
  70. package/dist/data-structures/index.d.ts +5 -5
  71. package/dist/data-structures/index.js +3 -3
  72. package/dist/executors/tool-provider-adapters.d.cts +3 -3
  73. package/dist/executors/tool-provider-adapters.d.ts +3 -3
  74. package/dist/executors/tool-provider-adapters.js +4 -4
  75. package/dist/executors/tool-provider-runtime.d.cts +4 -4
  76. package/dist/executors/tool-provider-runtime.d.ts +4 -4
  77. package/dist/executors/tool-provider.d.cts +3 -3
  78. package/dist/executors/tool-provider.d.ts +3 -3
  79. package/dist/executors/tool-provider.js +3 -3
  80. package/dist/executors/work-queue.d.cts +1 -1
  81. package/dist/executors/work-queue.d.ts +1 -1
  82. package/dist/graph/index.cjs.map +1 -1
  83. package/dist/graph/index.d.cts +4 -4
  84. package/dist/graph/index.d.ts +4 -4
  85. package/dist/graph/index.js +7 -7
  86. package/dist/{graph-D7DgoW4r.d.ts → graph-BYcUX6Y-.d.ts} +1 -1
  87. package/dist/{graph-BpVjXE3p.d.cts → graph-DpUhfPg-.d.cts} +1 -1
  88. package/dist/{index-NxEHWqYL.d.ts → index-CBXYou1z.d.ts} +1 -1
  89. package/dist/{index-Df4kax8O.d.cts → index-sxZ52y0d.d.cts} +1 -1
  90. package/dist/index.cjs.map +1 -1
  91. package/dist/index.d.cts +6 -6
  92. package/dist/index.d.ts +6 -6
  93. package/dist/index.js +15 -15
  94. package/dist/inspection/boundary.d.cts +2 -2
  95. package/dist/inspection/boundary.d.ts +2 -2
  96. package/dist/{measurements-CIGHDnsE.d.ts → measurements-ByXwo0t6.d.ts} +2 -2
  97. package/dist/{measurements-BwkzVaf4.d.cts → measurements-CQONT7Qg.d.cts} +2 -2
  98. package/dist/memory/index.d.cts +1 -1
  99. package/dist/memory/index.d.ts +1 -1
  100. package/dist/memory/semantic/index.d.cts +1 -1
  101. package/dist/memory/semantic/index.d.ts +1 -1
  102. package/dist/messaging/index.d.cts +1 -1
  103. package/dist/messaging/index.d.ts +1 -1
  104. package/dist/operators/index.cjs.map +1 -1
  105. package/dist/operators/index.d.cts +5 -5
  106. package/dist/operators/index.d.ts +5 -5
  107. package/dist/operators/index.js +3 -3
  108. package/dist/orchestration/index.cjs.map +1 -1
  109. package/dist/orchestration/index.d.cts +5 -5
  110. package/dist/orchestration/index.d.ts +5 -5
  111. package/dist/orchestration/index.js +4 -4
  112. package/dist/orchestration/messaging.d.cts +1 -1
  113. package/dist/orchestration/messaging.d.ts +1 -1
  114. package/dist/orchestration/work-queue.d.cts +2 -2
  115. package/dist/orchestration/work-queue.d.ts +2 -2
  116. package/dist/patterns/event-flow.d.cts +1 -1
  117. package/dist/patterns/event-flow.d.ts +1 -1
  118. package/dist/patterns/index.cjs.map +1 -1
  119. package/dist/patterns/index.d.cts +2 -2
  120. package/dist/patterns/index.d.ts +2 -2
  121. package/dist/patterns/index.js +1 -1
  122. package/dist/{reactive-collection-yjdqrWkb.d.cts → reactive-collection-Bt5117qe.d.cts} +1 -1
  123. package/dist/{reactive-collection-BTdjAVpJ.d.ts → reactive-collection-CZGtOhEp.d.ts} +1 -1
  124. package/dist/{reactive-collection-storage-C1YIW_q2.d.cts → reactive-collection-storage-BzhzmEpP.d.cts} +3 -3
  125. package/dist/{reactive-collection-storage-BZozONHw.d.ts → reactive-collection-storage-NKUpbyyK.d.ts} +3 -3
  126. package/dist/{reactive-map-c-l8bYrl.d.cts → reactive-map-Cf9_oTOT.d.cts} +1 -1
  127. package/dist/{reactive-map-B6sA6p5U.d.ts → reactive-map-DQeA7ThE.d.ts} +1 -1
  128. package/dist/{scheduled-readiness-Batwa3Fm.d.ts → scheduled-readiness-BQdebv1Q.d.ts} +1 -1
  129. package/dist/{scheduled-readiness-BtUBoaGJ.d.cts → scheduled-readiness-D5qPFnZF.d.cts} +1 -1
  130. package/dist/solutions/agentic-memory/browser.d.cts +2 -2
  131. package/dist/solutions/agentic-memory/browser.d.ts +2 -2
  132. package/dist/solutions/agentic-memory/index.d.cts +3 -3
  133. package/dist/solutions/agentic-memory/index.d.ts +3 -3
  134. package/dist/solutions/agentic-memory/node.d.cts +2 -2
  135. package/dist/solutions/agentic-memory/node.d.ts +2 -2
  136. package/dist/solutions/agentic-work-item-memory/index.d.cts +1 -1
  137. package/dist/solutions/agentic-work-item-memory/index.d.ts +1 -1
  138. package/dist/solutions/agentic-work-item-memory-application/index.d.cts +1 -1
  139. package/dist/solutions/agentic-work-item-memory-application/index.d.ts +1 -1
  140. package/dist/solutions/index.d.cts +6 -6
  141. package/dist/solutions/index.d.ts +6 -6
  142. package/dist/solutions/reactive-layout/browser/index.d.cts +2 -2
  143. package/dist/solutions/reactive-layout/browser/index.d.ts +2 -2
  144. package/dist/solutions/reactive-layout/index.d.cts +4 -4
  145. package/dist/solutions/reactive-layout/index.d.ts +4 -4
  146. package/dist/solutions/reactive-layout/node-canvas/index.d.cts +2 -2
  147. package/dist/solutions/reactive-layout/node-canvas/index.d.ts +2 -2
  148. package/dist/solutions/reactive-layout/react-native/index.d.cts +2 -2
  149. package/dist/solutions/reactive-layout/react-native/index.d.ts +2 -2
  150. package/dist/solutions/reactive-layout/skia/index.d.cts +2 -2
  151. package/dist/solutions/reactive-layout/skia/index.d.ts +2 -2
  152. package/dist/solutions/work-item/actions.d.cts +5 -5
  153. package/dist/solutions/work-item/actions.d.ts +5 -5
  154. package/dist/solutions/work-item/index.d.cts +4 -4
  155. package/dist/solutions/work-item/index.d.ts +4 -4
  156. package/dist/solutions/work-item/scheduling.d.cts +4 -4
  157. package/dist/solutions/work-item/scheduling.d.ts +4 -4
  158. package/dist/solutions/work-item/work-queue.d.cts +1 -1
  159. package/dist/solutions/work-item/work-queue.d.ts +1 -1
  160. package/dist/sources/browser.cjs.map +1 -1
  161. package/dist/sources/browser.d.cts +2 -2
  162. package/dist/sources/browser.d.ts +2 -2
  163. package/dist/sources/browser.js +2 -2
  164. package/dist/sources/index.cjs.map +1 -1
  165. package/dist/sources/index.d.cts +2 -2
  166. package/dist/sources/index.d.ts +2 -2
  167. package/dist/sources/index.js +2 -2
  168. package/dist/sources/node.d.cts +1 -1
  169. package/dist/sources/node.d.ts +1 -1
  170. package/dist/storage/index.d.cts +2 -2
  171. package/dist/storage/index.d.ts +2 -2
  172. package/dist/{store-BnjczOv3.d.cts → store-Rxycbh-H.d.cts} +5 -5
  173. package/dist/{store-DEQq1IUZ.d.ts → store-piaqo-AU.d.ts} +5 -5
  174. package/dist/testing/index.cjs.map +1 -1
  175. package/dist/testing/index.d.cts +1 -1
  176. package/dist/testing/index.d.ts +1 -1
  177. package/dist/testing/index.js +1 -1
  178. package/dist/{types-CjoOI5fY.d.cts → types-084NQr4q.d.cts} +1 -1
  179. package/dist/{types-C_rZAUfY.d.ts → types-CIYYkmqF.d.ts} +1 -1
  180. package/dist/work-queue/index.d.cts +1 -1
  181. package/dist/work-queue/index.d.ts +1 -1
  182. package/package.json +2 -2
  183. package/dist/chunk-DXBOAAPS.js.map +0 -1
  184. package/dist/chunk-FLUPPSIP.js.map +0 -1
  185. package/dist/chunk-ND43YDGK.js.map +0 -1
  186. package/dist/chunk-STLRNFU7.js.map +0 -1
  187. package/dist/chunk-VYAEEKZ3.js.map +0 -1
  188. /package/dist/{chunk-BIGKAHSX.js.map → chunk-2U4G3PEU.js.map} +0 -0
  189. /package/dist/{chunk-AVPXWVRL.js.map → chunk-BOWKPNXS.js.map} +0 -0
  190. /package/dist/{chunk-LRYGIKWY.js.map → chunk-G3J4KZLK.js.map} +0 -0
  191. /package/dist/{chunk-32WGWBYO.js.map → chunk-HFPPLLLQ.js.map} +0 -0
  192. /package/dist/{chunk-HT5R7S47.js.map → chunk-LPC42V2E.js.map} +0 -0
  193. /package/dist/{chunk-V3MSIDUQ.js.map → chunk-TWOPVCGK.js.map} +0 -0
  194. /package/dist/{chunk-2BIF6BQ7.js.map → chunk-W4ATMMTH.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/store.ts"],"sourcesContent":["/**\n * Framework-neutral store adapters.\n *\n * Focused framework bindings build on this tiny Node-facing layer without\n * importing framework packages into the dependency-free adapters barrel\n * (D125/D238).\n */\n\nimport type { DeliveryMeta, Sink } from \"../ctx/types.js\";\nimport type { Node } from \"../node/node.js\";\n\n/** A minimal readable store contract shared by Svelte/Nanostores-style adapters. */\nexport interface ReadableStore<T> {\n\tget(): T | undefined;\n\tsubscribe(run: (value: T | undefined) => void): () => void;\n}\n\n/** A minimal writable store contract over a GraphReFly writable node. */\nexport interface WritableStore<T> extends ReadableStore<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\n/** React `useSyncExternalStore`-compatible shape, without importing React. */\nexport interface ExternalStore<T> {\n\tgetSnapshot(): T | undefined;\n\tgetServerSnapshot(): T | undefined;\n\tsubscribe(onStoreChange: () => void): () => void;\n}\n\n/** Object-of-nodes factory used by record subscription adapters. */\nexport type NodeRecordFactory<K extends string, R extends Record<string, unknown>> = (key: K) => {\n\t[P in keyof R]: Node<R[P]>;\n};\n\n/** Zustand-compatible store API over a caller-owned GraphReFly state node. */\nexport interface ZustandStoreApi<T extends object> {\n\tgetState(): T;\n\tsetState(partial: T | Partial<T> | ((state: T) => T | Partial<T>), replace?: boolean): void;\n\tgetInitialState(): T;\n\tsubscribe(listener: (state: T, prevState: T) => void): () => void;\n\tdestroy(): void;\n}\n\n/** Jotai-style atom facade over a caller-owned node. */\nexport interface JotaiAtom<T> {\n\tget(): T | undefined;\n\tsubscribe(callback: (value: T | undefined) => void): () => void;\n\treadonly _node: Node<T>;\n}\n\n/** Writable Jotai-style atom facade over a caller-owned writable node. */\nexport interface WritableJotaiAtom<T> extends JotaiAtom<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\n/** Nanostores-style atom facade over a caller-owned node. */\nexport interface NanoAtom<T> {\n\tget(): T | undefined;\n\tsubscribe(callback: (value: T | undefined) => void): () => void;\n\tlisten(callback: (value: T | undefined) => void): () => void;\n\treadonly _node: Node<T>;\n}\n\n/** Writable Nanostores-style atom facade over a caller-owned writable node. */\nexport interface WritableNanoAtom<T> extends NanoAtom<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\n/** TC39-Signals-style facade over a caller-owned node. */\nexport interface SignalLike<T> {\n\tget(): T | undefined;\n\tsubscribe(callback: (value: T | undefined) => void): () => void;\n\treadonly _node: Node<T>;\n}\n\n/** Writable TC39-Signals-style facade over a caller-owned writable node. */\nexport interface WritableSignalLike<T> extends SignalLike<T> {\n\tset(value: T): void;\n\tupdate(fn: (value: T | undefined) => T): void;\n}\n\nexport interface SubscribeValuesOptions<T> {\n\t/** Emit the current cache snapshot immediately. `undefined` means SENTINEL/no DATA. */\n\timmediate?: boolean;\n\t/** Suppress synchronous push-on-subscribe/replay DATA. Useful for change-only store listeners. */\n\tchangesOnly?: boolean;\n\tonError?: (error: unknown) => void;\n\tonComplete?: () => void;\n\t/** Custom cache reader for wrappers that keep their own snapshot object. */\n\tgetSnapshot?: () => T | undefined;\n}\n\nexport interface WritableNode<T> extends Node<T> {\n\tset(value: T): void;\n}\n\nexport interface WritableStoreOptions<T> extends SubscribeValuesOptions<T> {\n\t/** Override writes for adapters that need a framework-owned reducer. */\n\twrite?: (node: WritableNode<T>, value: T) => void;\n}\n\n/** Read a node cache without activating it.\n * @param node - Node to observe, adapt, or connect.\n * @returns A `T | undefined` value.\n * @category adapters\n * @example\n * ```ts\n * import { nodeSnapshot } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function nodeSnapshot<T>(node: Node<T>): T | undefined {\n\treturn node.cache as T | undefined;\n}\n\n/**\n * Subscribe to DATA values from a Node. Protocol internals stay below the adapter boundary:\n * DATA drives value listeners, ERROR/COMPLETE route to optional lifecycle callbacks.\n * @param node - Node to observe, adapt, or connect.\n * @param run - run value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns A `() => void` value.\n * @category adapters\n * @example\n * ```ts\n * import { subscribeNodeValues } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function subscribeNodeValues<T>(\n\tnode: Node<T>,\n\trun: (value: T | undefined) => void,\n\topts: SubscribeValuesOptions<T> = {},\n): () => void {\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\tif (opts.immediate) run(read());\n\n\tlet subscribing = true;\n\tconst skipSynchronousHandshakeData = opts.changesOnly || opts.immediate;\n\tconst sink: Sink = (msg, delivery?: DeliveryMeta) => {\n\t\tswitch (msg[0]) {\n\t\t\tcase \"DATA\":\n\t\t\t\tif (skipSynchronousHandshakeData && subscribing && delivery === undefined) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\trun(msg[1] as T);\n\t\t\t\treturn;\n\t\t\tcase \"ERROR\":\n\t\t\t\topts.onError?.(msg[1]);\n\t\t\t\treturn;\n\t\t\tcase \"COMPLETE\":\n\t\t\t\topts.onComplete?.();\n\t\t\t\treturn;\n\t\t}\n\t};\n\tconst unsubscribe = node.subscribe(sink);\n\tsubscribing = false;\n\treturn unsubscribe;\n}\n\n/** Build a Svelte/Nanostores-style readable store from a GraphReFly Node.\n * @param node - Node to observe, adapt, or connect.\n * @param opts - Options that configure the helper.\n * @returns A `ReadableStore<T>` value.\n * @category adapters\n * @example\n * ```ts\n * import { readableStore } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function readableStore<T>(\n\tnode: Node<T>,\n\topts: SubscribeValuesOptions<T> = {},\n): ReadableStore<T> {\n\treturn {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (run) => subscribeNodeValues(node, run, { immediate: true, ...opts }),\n\t};\n}\n\nfunction hasWritableSet<T>(node: Node<T>): node is WritableNode<T> {\n\treturn typeof (node as { set?: unknown }).set === \"function\";\n}\n\nfunction defaultWrite<T>(node: WritableNode<T>, value: T): void {\n\tnode.set(value);\n}\n\n/** Build a writable store over a StateNode or compatible GraphReFly writable Node. */\nexport function writableStore<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableStore<T>;\n\n/**\n * Creates a writable store.\n *\n * @param node - node value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns The writable store result.\n * @category adapters\n * @example\n * ```ts\n * import { writableStore } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function writableStore<T>(\n\tnode: Node<T>,\n\topts: WritableStoreOptions<T> & { write: (node: WritableNode<T>, value: T) => void },\n): WritableStore<T>;\n\n/**\n * Creates a writable store.\n *\n * @param node - node value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns The writable store result.\n * @category adapters\n * @example\n * ```ts\n * import { writableStore } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function writableStore<T>(\n\tnode: Node<T>,\n\topts: WritableStoreOptions<T> = {},\n): WritableStore<T> {\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\tconst write = opts.write ?? (hasWritableSet(node) ? defaultWrite : undefined);\n\tif (!write) {\n\t\tthrow new TypeError(\"writableStore: node must expose set(value) or opts.write\");\n\t}\n\tconst writable = node as WritableNode<T>;\n\treturn {\n\t\tget: read,\n\t\tsubscribe: (run) => subscribeNodeValues(node, run, { immediate: true, ...opts }),\n\t\tset: (value) => write(writable, value),\n\t\tupdate: (fn) => write(writable, fn(read())),\n\t};\n}\n\n/** Build the tiny shape React's `useSyncExternalStore` expects, without importing React.\n * @param node - Node to observe, adapt, or connect.\n * @param opts - Options that configure the helper.\n * @returns A `ExternalStore<T>` value.\n * @category adapters\n * @example\n * ```ts\n * import { externalStore } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function externalStore<T>(\n\tnode: Node<T>,\n\topts: Pick<SubscribeValuesOptions<T>, \"getSnapshot\" | \"onError\" | \"onComplete\"> = {},\n): ExternalStore<T> {\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\treturn {\n\t\tgetSnapshot: read,\n\t\tgetServerSnapshot: read,\n\t\tsubscribe: (onStoreChange) =>\n\t\t\tsubscribeNodeValues(node, () => onStoreChange(), {\n\t\t\t\tchangesOnly: true,\n\t\t\t\tonError: opts.onError,\n\t\t\t\tonComplete: opts.onComplete,\n\t\t\t}),\n\t};\n}\n\n/** Build a framework-neutral keyed record store for focused framework record bindings.\n * @param keysNode - keys node value used by the helper.\n * @param factory - factory value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns A `ReadableStore<Record<K, R>>` value.\n * @category adapters\n * @example\n * ```ts\n * import { recordReadableStore } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function recordReadableStore<K extends string, R extends Record<string, unknown>>(\n\tkeysNode: Node<readonly K[]>,\n\tfactory: NodeRecordFactory<K, R>,\n\topts: SubscribeValuesOptions<Record<K, R>> = {},\n): ReadableStore<Record<K, R>> {\n\tconst read = () => {\n\t\tconst keys = keysNode.cache ?? [];\n\t\tconst out = {} as Record<K, R>;\n\t\tfor (const key of keys) {\n\t\t\tconst nodes = factory(key);\n\t\t\tconst values = {} as R;\n\t\t\tfor (const field of Object.keys(nodes) as Array<keyof R>) {\n\t\t\t\tvalues[field] = nodes[field].cache as R[keyof R];\n\t\t\t}\n\t\t\tout[key] = values;\n\t\t}\n\t\treturn out;\n\t};\n\n\treturn {\n\t\tget: read,\n\t\tsubscribe(run) {\n\t\t\tconst entryUnsubs: Array<() => void> = [];\n\t\t\tconst cleanupEntries = () => {\n\t\t\t\tfor (const unsub of entryUnsubs.splice(0)) unsub();\n\t\t\t};\n\t\t\tconst sync = () => {\n\t\t\t\tcleanupEntries();\n\t\t\t\tfor (const key of keysNode.cache ?? []) {\n\t\t\t\t\tconst nodes = factory(key);\n\t\t\t\t\tfor (const field of Object.keys(nodes) as Array<keyof R>) {\n\t\t\t\t\t\tentryUnsubs.push(\n\t\t\t\t\t\t\tsubscribeNodeValues(nodes[field], () => run(read()), {\n\t\t\t\t\t\t\t\tchangesOnly: true,\n\t\t\t\t\t\t\t\tonError: opts.onError,\n\t\t\t\t\t\t\t\tonComplete: opts.onComplete,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trun(read());\n\t\t\t};\n\t\t\tconst keysUnsub = subscribeNodeValues(keysNode, sync, {\n\t\t\t\tchangesOnly: true,\n\t\t\t\tonError: opts.onError,\n\t\t\t\tonComplete: opts.onComplete,\n\t\t\t});\n\t\t\tsync();\n\t\t\treturn () => {\n\t\t\t\tkeysUnsub();\n\t\t\t\tcleanupEntries();\n\t\t\t};\n\t\t},\n\t};\n}\n\n/** Build a Zustand-compatible StoreApi over a caller-owned GraphReFly state node. */\nexport function zustandStore<T extends object>(\n\tnode: WritableNode<T>,\n\tinitialState?: T,\n\topts?: WritableStoreOptions<T>,\n): ZustandStoreApi<T>;\n\n/**\n * Creates a zustand store.\n *\n * @param node - node value used by the helper.\n * @param initialState - initial state value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns The zustand store result.\n * @category adapters\n * @example\n * ```ts\n * import { zustandStore } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function zustandStore<T extends object>(\n\tnode: Node<T>,\n\tinitialState: T | undefined,\n\topts: WritableStoreOptions<T> & { write: (node: WritableNode<T>, value: T) => void },\n): ZustandStoreApi<T>;\n\n/**\n * Creates a zustand store.\n *\n * @param node - node value used by the helper.\n * @param initialState - initial state value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns The zustand store result.\n * @category adapters\n * @example\n * ```ts\n * import { zustandStore } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function zustandStore<T extends object>(\n\tnode: Node<T>,\n\tinitialState: T = nodeSnapshot(node) as T,\n\topts: WritableStoreOptions<T> = {},\n): ZustandStoreApi<T> {\n\tconst listeners = new Set<() => void>();\n\tconst read = opts.getSnapshot ?? (() => nodeSnapshot(node));\n\tconst write = opts.write ?? (hasWritableSet(node) ? defaultWrite : undefined);\n\tif (!write) {\n\t\tthrow new TypeError(\"zustandStore: node must expose set(value) or opts.write\");\n\t}\n\tconst writable = node as WritableNode<T>;\n\tconst api: ZustandStoreApi<T> = {\n\t\tgetState: () => read() as T,\n\t\tsetState(partial, replace) {\n\t\t\tconst prev = api.getState();\n\t\t\tconst next = typeof partial === \"function\" ? partial(prev) : partial;\n\t\t\twrite(writable, replace ? (next as T) : ({ ...prev, ...next } as T));\n\t\t},\n\t\tgetInitialState: () => initialState,\n\t\tsubscribe(listener) {\n\t\t\tlet prev = api.getState();\n\t\t\tconst unsub = subscribeNodeValues(\n\t\t\t\tnode,\n\t\t\t\t() => {\n\t\t\t\t\tconst next = api.getState();\n\t\t\t\t\tlistener(next, prev);\n\t\t\t\t\tprev = next;\n\t\t\t\t},\n\t\t\t\t{ changesOnly: true, onError: opts.onError, onComplete: opts.onComplete },\n\t\t\t);\n\t\t\tlisteners.add(unsub);\n\t\t\treturn () => {\n\t\t\t\tif (!listeners.delete(unsub)) return;\n\t\t\t\tunsub();\n\t\t\t};\n\t\t},\n\t\tdestroy() {\n\t\t\tfor (const unsub of [...listeners]) {\n\t\t\t\tlisteners.delete(unsub);\n\t\t\t\tunsub();\n\t\t\t}\n\t\t},\n\t};\n\treturn api;\n}\n\n/** Build a Jotai-style atom facade over a caller-owned node. */\nexport function jotaiAtom<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableJotaiAtom<T>;\n\n/**\n * Creates a jotai atom.\n *\n * @param node - node value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns The jotai atom result.\n * @category adapters\n * @example\n * ```ts\n * import { jotaiAtom } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function jotaiAtom<T>(node: Node<T>, opts?: SubscribeValuesOptions<T>): JotaiAtom<T>;\n\n/**\n * Creates a jotai atom.\n *\n * @param node - node value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns The jotai atom result.\n * @category adapters\n * @example\n * ```ts\n * import { jotaiAtom } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function jotaiAtom<T>(\n\tnode: Node<T> | WritableNode<T>,\n\topts: SubscribeValuesOptions<T> | WritableStoreOptions<T> = {},\n): JotaiAtom<T> | WritableJotaiAtom<T> {\n\tconst base: JotaiAtom<T> = {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),\n\t\t_node: node,\n\t};\n\tif (hasWritableSet(node) || typeof (opts as WritableStoreOptions<T>).write === \"function\") {\n\t\tconst writable = writableStore(\n\t\t\tnode,\n\t\t\topts as WritableStoreOptions<T> & {\n\t\t\t\twrite: (node: WritableNode<T>, value: T) => void;\n\t\t\t},\n\t\t);\n\t\treturn { ...base, set: writable.set, update: writable.update };\n\t}\n\treturn base;\n}\n\n/** Build a Nanostores-style atom facade over a caller-owned node. */\nexport function nanoAtom<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableNanoAtom<T>;\n\n/**\n * Creates a nano atom.\n *\n * @param node - node value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns The nano atom result.\n * @category adapters\n * @example\n * ```ts\n * import { nanoAtom } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function nanoAtom<T>(node: Node<T>, opts?: SubscribeValuesOptions<T>): NanoAtom<T>;\n\n/**\n * Creates a nano atom.\n *\n * @param node - node value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns The nano atom result.\n * @category adapters\n * @example\n * ```ts\n * import { nanoAtom } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function nanoAtom<T>(\n\tnode: Node<T> | WritableNode<T>,\n\topts: SubscribeValuesOptions<T> | WritableStoreOptions<T> = {},\n): NanoAtom<T> | WritableNanoAtom<T> {\n\tconst base: NanoAtom<T> = {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (callback) => subscribeNodeValues(node, callback, { immediate: true, ...opts }),\n\t\tlisten: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),\n\t\t_node: node,\n\t};\n\tif (hasWritableSet(node) || typeof (opts as WritableStoreOptions<T>).write === \"function\") {\n\t\tconst writable = writableStore(\n\t\t\tnode,\n\t\t\topts as WritableStoreOptions<T> & {\n\t\t\t\twrite: (node: WritableNode<T>, value: T) => void;\n\t\t\t},\n\t\t);\n\t\treturn { ...base, set: writable.set, update: writable.update };\n\t}\n\treturn base;\n}\n\n/** Build a TC39-Signals-style facade over a caller-owned node. */\nexport function signalFromNode<T>(\n\tnode: WritableNode<T>,\n\topts?: WritableStoreOptions<T>,\n): WritableSignalLike<T>;\n\n/**\n * Creates a signal from node.\n *\n * @param node - node value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns The signal from node result.\n * @category adapters\n * @example\n * ```ts\n * import { signalFromNode } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function signalFromNode<T>(node: Node<T>, opts?: SubscribeValuesOptions<T>): SignalLike<T>;\n\n/**\n * Creates a signal from node.\n *\n * @param node - node value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns The signal from node result.\n * @category adapters\n * @example\n * ```ts\n * import { signalFromNode } from \"@graphrefly/ts/adapters\";\n * ```\n */\nexport function signalFromNode<T>(\n\tnode: Node<T> | WritableNode<T>,\n\topts: SubscribeValuesOptions<T> | WritableStoreOptions<T> = {},\n): SignalLike<T> | WritableSignalLike<T> {\n\tconst base: SignalLike<T> = {\n\t\tget: () => (opts.getSnapshot ?? (() => nodeSnapshot(node)))(),\n\t\tsubscribe: (callback) => subscribeNodeValues(node, callback, { changesOnly: true, ...opts }),\n\t\t_node: node,\n\t};\n\tif (hasWritableSet(node) || typeof (opts as WritableStoreOptions<T>).write === \"function\") {\n\t\tconst writable = writableStore(\n\t\t\tnode,\n\t\t\topts as WritableStoreOptions<T> & {\n\t\t\t\twrite: (node: WritableNode<T>, value: T) => void;\n\t\t\t},\n\t\t);\n\t\treturn { ...base, set: writable.set, update: writable.update };\n\t}\n\treturn base;\n}\n"],"mappings":"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","names":[]}
@@ -46,4 +46,4 @@ function describeWave(wave, around) {
46
46
  export {
47
47
  assertDirtyPrecedesTerminalData
48
48
  };
49
- //# sourceMappingURL=chunk-DXBOAAPS.js.map
49
+ //# sourceMappingURL=chunk-KTJ5LEOL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/assertions.ts"],"sourcesContent":["/**\n * Public testing assertions for GraphReFly message streams.\n *\n * These helpers validate captured protocol output; they do not participate in propagation.\n */\n\nimport { isValueTier, type Message, type Wave } from \"../protocol/messages.js\";\n\n/** Captured subscriber messages grouped by wave. START/replay handshake messages occupy one wave. */\nexport type MessageSequence = readonly Wave[];\n\n/**\n * Assert that observed tier-3 settlements (DATA/RESOLVED) are preceded by DIRTY.\n *\n * This encodes R-dirty-before-data for wave-framed subscriber traces. The leading\n * START push-on-subscribe/replay handshake wave is exempt because cached/replay DATA is\n * advertised to a new subscriber without opening a propagation wave.\n * @param messages - messages value used by the helper.\n * @returns The narrowed, validated value.\n * @category testing\n * @example\n * ```ts\n * import { assertDirtyPrecedesTerminalData } from \"@graphrefly/ts/testing\";\n * ```\n */\nexport function assertDirtyPrecedesTerminalData(messages: MessageSequence): void {\n\tfor (let waveIndex = 0; waveIndex < messages.length; waveIndex += 1) {\n\t\tconst wave = messages[waveIndex];\n\t\tlet handshake = false;\n\t\tlet openedByDirty = false;\n\n\t\tfor (let msgIndex = 0; msgIndex < wave.length; msgIndex += 1) {\n\t\t\tconst msg = wave[msgIndex] as Message;\n\t\t\tconst type = msg[0];\n\n\t\t\tif (msgIndex === 0 && type === \"START\") {\n\t\t\t\thandshake = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (handshake && type === \"DATA\") {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\thandshake = false;\n\n\t\t\tif (type === \"DIRTY\") {\n\t\t\t\topenedByDirty = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (isValueTier(type)) {\n\t\t\t\tif (!openedByDirty) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`assertDirtyPrecedesTerminalData: ${type} at wave ${waveIndex}, index ${msgIndex} arrived without a preceding DIRTY in the same wave (R-dirty-before-data). Wave: ${describeWave(wave, msgIndex)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\topenedByDirty = false;\n\t\t}\n\t}\n}\n\nfunction describeWave(wave: Wave, around: number): string {\n\tconst parts: string[] = [];\n\tfor (let i = 0; i < wave.length; i += 1) {\n\t\tparts.push(`${i === around ? \"-> \" : \" \"}[${wave[i]?.[0] ?? \"?\"}]`);\n\t}\n\treturn parts.join(\", \");\n}\n"],"mappings":";;;;;AAyBO,SAAS,gCAAgC,UAAiC;AAChF,WAAS,YAAY,GAAG,YAAY,SAAS,QAAQ,aAAa,GAAG;AACpE,UAAM,OAAO,SAAS,SAAS;AAC/B,QAAI,YAAY;AAChB,QAAI,gBAAgB;AAEpB,aAAS,WAAW,GAAG,WAAW,KAAK,QAAQ,YAAY,GAAG;AAC7D,YAAM,MAAM,KAAK,QAAQ;AACzB,YAAM,OAAO,IAAI,CAAC;AAElB,UAAI,aAAa,KAAK,SAAS,SAAS;AACvC,oBAAY;AACZ;AAAA,MACD;AAEA,UAAI,aAAa,SAAS,QAAQ;AACjC;AAAA,MACD;AACA,kBAAY;AAEZ,UAAI,SAAS,SAAS;AACrB,wBAAgB;AAChB;AAAA,MACD;AAEA,UAAI,YAAY,IAAI,GAAG;AACtB,YAAI,CAAC,eAAe;AACnB,gBAAM,IAAI;AAAA,YACT,oCAAoC,IAAI,YAAY,SAAS,WAAW,QAAQ,oFAAoF,aAAa,MAAM,QAAQ,CAAC;AAAA,UACjM;AAAA,QACD;AACA;AAAA,MACD;AAEA,sBAAgB;AAAA,IACjB;AAAA,EACD;AACD;AAEA,SAAS,aAAa,MAAY,QAAwB;AACzD,QAAM,QAAkB,CAAC;AACzB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACxC,UAAM,KAAK,GAAG,MAAM,SAAS,QAAQ,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG;AAAA,EACrE;AACA,SAAO,MAAM,KAAK,IAAI;AACvB;","names":[]}
@@ -11,13 +11,13 @@ import {
11
11
  } from "./chunk-SFHOKKAT.js";
12
12
  import {
13
13
  assertGraphLocalNode
14
- } from "./chunk-V3MSIDUQ.js";
14
+ } from "./chunk-TWOPVCGK.js";
15
15
  import {
16
16
  restoreReactiveIndex,
17
17
  restoreReactiveList,
18
18
  restoreReactiveLog,
19
19
  restoreReactiveMap
20
- } from "./chunk-BIGKAHSX.js";
20
+ } from "./chunk-2U4G3PEU.js";
21
21
 
22
22
  // src/adapters/reactive-collection-storage.ts
23
23
  function emptyCursor(collection) {
@@ -382,4 +382,4 @@ export {
382
382
  openPersistentReactiveMap,
383
383
  openPersistentReactiveIndex
384
384
  };
385
- //# sourceMappingURL=chunk-HT5R7S47.js.map
385
+ //# sourceMappingURL=chunk-LPC42V2E.js.map
@@ -6,13 +6,13 @@ import {
6
6
  interval,
7
7
  of,
8
8
  timer
9
- } from "./chunk-32WGWBYO.js";
9
+ } from "./chunk-HFPPLLLQ.js";
10
10
  import {
11
11
  filter,
12
12
  initNode,
13
13
  map,
14
14
  merge
15
- } from "./chunk-FLUPPSIP.js";
15
+ } from "./chunk-3KYPNNBH.js";
16
16
  import {
17
17
  CTX_NODE_BINDING,
18
18
  depBatch,
@@ -459,4 +459,4 @@ export {
459
459
  timeout,
460
460
  bufferTime
461
461
  };
462
- //# sourceMappingURL=chunk-STLRNFU7.js.map
462
+ //# sourceMappingURL=chunk-T3YMFLRH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/graph/higher-order.ts","../src/graph/time.ts"],"sourcesContent":["/**\n * Higher-order operators — switchMap / mergeMap / concatMap / exhaustMap / flatMap\n * (D47 / R-rewire-deferred / CSP-2.7; per-language sugar, D6/D24, never in parity).\n *\n * Each projects every outer value to an INNER source and flattens the inners' emissions. The\n * inner sources are wired as runtime DEPS via the deferred-self-rewire substrate affordance\n * (`ctx.rewireNext`, D47) — NOT an internal subscribe (D45 bans that; it would create a describe\n * island). Growing/shrinking the dep set is deferred to the committed wave boundary, so a fn\n * never mutates its own topology mid-run (that is the D37 feedback-cycle ERROR). An inner that\n * COMPLETEs is `unsubscribeDep`'d → its source `_deactivate`s + fires `onDeactivation`: that is the\n * cancellation / abortInFlight basis (switchMap drops the superseded inner's WORK, not just its\n * output; mergeMap bounds memory). Built on the bare `node` primitive via the {@link Operator}\n * factory shape + the `g.initNode` funnel (D43), so the real factory name shows in describe.\n *\n * Lifecycle folding (D47/D81): completeWhenDepsComplete:false + terminalAsRealInput:true +\n * errorWhenDepsError:false — the operator owns completion (emit COMPLETE only when the SOURCE is\n * done AND no inner is live / pending), and observes source/inner ERROR so it can remove every live\n * inner before emitting ERROR. Those removals drain after terminal via D62: terminal seals output,\n * while helper-owned upstream work still sees unsubscribeDep->_deactivate->onDeactivation teardown.\n *\n * Alignment: each run issues REMOVES before ADDS so the per-node FIFO drain keeps the operator's\n * tracked inner list aligned with the live dep order across the intermediate boundary waves (a\n * removed dep is silent — no settle — and applies before any added dep's push-on-subscribe wave).\n */\n\nimport {\n\tCTX_NODE_BINDING,\n\ttype Ctx,\n\tdepBatch,\n\tdepCount,\n\tdepTerminal,\n\tisTerminalComplete,\n\tisTerminalError,\n\ttype NodeFn,\n\tterminalErrorValue,\n} from \"../ctx/types.js\";\nimport type { Node } from \"../node/node.js\";\nimport { errorPayload } from \"../protocol/messages.js\";\nimport { initNode, type Operator } from \"./operators.js\";\nimport { fromAsyncIter, fromIter, fromPromise, type NodeInput, of } from \"./sources.js\";\n\n/** Project an outer value to an inner source (a Node, Promise, (a)sync iterable, or scalar). */\nexport type Project<TIn, TOut> = (value: TIn) => NodeInput<TOut>;\n\ntype Mode = \"merge\" | \"switch\" | \"concat\" | \"exhaust\";\n\n/** Options for {@link mergeMap}. */\nexport interface MergeMapOptions {\n\t/**\n\t * Maximum number of live inner deps at once. `undefined`/`Infinity` keeps the default\n\t * unbounded mergeMap behavior; finite values queue outer values until an inner COMPLETEs.\n\t */\n\treadonly concurrent?: number;\n}\n\n/** Per-node bookkeeping (ctx.state): the live inner deps (aligned with deps[1..]) + pending queue. */\ninterface MapState<TIn> {\n\tinners: Node<unknown>[];\n\tqueue: TIn[]; // concatMap / bounded mergeMap pending values (lazy projection)\n\tsourceDone: boolean;\n}\n\nfunction uniqueNodes(nodes: readonly Node<unknown>[]): Node<unknown>[] {\n\tconst seen = new Set<Node<unknown>>();\n\tconst out: Node<unknown>[] = [];\n\tfor (const n of nodes) {\n\t\tif (seen.has(n)) continue;\n\t\tseen.add(n);\n\t\tout.push(n);\n\t}\n\treturn out;\n}\n\nfunction cleanupAllInners<TIn>(ctx: Ctx, st: MapState<TIn>, body: NodeFn): void {\n\tfor (const inner of uniqueNodes(st.inners)) ctx.rewireNext.unsubscribeDep(inner, body);\n\tst.inners = [];\n\tst.queue.length = 0;\n\tst.sourceDone = true;\n\tctx.state.set(st);\n}\n\nfunction firstErrorTerminal(ctx: Ctx): unknown {\n\tfor (let i = 0; i < depCount(ctx); i++) {\n\t\tconst terminal = depTerminal(ctx, i);\n\t\tif (isTerminalError(terminal)) return terminalErrorValue(terminal);\n\t}\n\treturn undefined;\n}\n\nfunction fromAnyInCtx<T>(ctx: Ctx, input: NodeInput<T>): Node<unknown> {\n\tconst binding = ctx[CTX_NODE_BINDING];\n\tif (isNode(input)) return input as Node<unknown>;\n\n\tconst nodeOpts = binding ? { dispatcher: binding.dispatcher } : {};\n\tconst make = (op: Operator<never, T>) =>\n\t\t(binding\n\t\t\t? binding.create(() => initNode(op, [], nodeOpts))\n\t\t\t: initNode(op, [], nodeOpts)) as Node<unknown>;\n\n\tif (isThenable(input)) return make(fromPromise(input as PromiseLike<T>));\n\tif (input !== null && input !== undefined) {\n\t\tconst candidate = input as {\n\t\t\t[Symbol.asyncIterator]?: unknown;\n\t\t\t[Symbol.iterator]?: unknown;\n\t\t};\n\t\tif (typeof candidate[Symbol.asyncIterator] === \"function\") {\n\t\t\treturn make(fromAsyncIter(input as AsyncIterable<T>));\n\t\t}\n\t\tif (typeof candidate[Symbol.iterator] === \"function\") {\n\t\t\treturn make(fromIter(input as Iterable<T>));\n\t\t}\n\t}\n\treturn make(of(input as T));\n}\n\nfunction isNode(x: unknown): x is Node {\n\treturn (\n\t\tx != null &&\n\t\ttypeof x === \"object\" &&\n\t\t\"cache\" in x &&\n\t\ttypeof (x as Node).subscribe === \"function\"\n\t);\n}\n\nfunction isThenable(x: unknown): x is PromiseLike<unknown> {\n\treturn x != null && typeof (x as PromiseLike<unknown>).then === \"function\";\n}\n\nfunction normalizeConcurrent(factory: string, concurrent: number | undefined): number {\n\tif (concurrent === undefined || concurrent === Number.POSITIVE_INFINITY) {\n\t\treturn Number.POSITIVE_INFINITY;\n\t}\n\tif (!Number.isInteger(concurrent) || concurrent < 1) {\n\t\tthrow new RangeError(`${factory}: concurrent must be a positive integer or Infinity`);\n\t}\n\treturn concurrent;\n}\n\n/**\n * The shared higher-order machinery. The operator depends on the source S at index 0; inner\n * sources occupy indices 1.. (added/removed at runtime via ctx.rewireNext). The body is\n * SELF-CATCHING (D30) and re-supplies itself on every rewire (the initNode wrap covers only the\n * first run; the re-supplied fn must stay self-catching).\n */\nfunction mapOperator<TIn, TOut>(\n\tfactory: string,\n\tproject: Project<TIn, TOut>,\n\tmode: Mode,\n\topts: { concurrent?: number } = {},\n): Operator<TIn, TOut> {\n\tconst maxConcurrent = normalizeConcurrent(factory, opts.concurrent);\n\tconst body: NodeFn = (ctx: Ctx) => {\n\t\tlet st: MapState<TIn> | undefined;\n\t\ttry {\n\t\t\tst = (ctx.state.get<MapState<TIn>>() ?? {\n\t\t\t\tinners: [],\n\t\t\t\tqueue: [],\n\t\t\t\tsourceDone: false,\n\t\t\t}) as MapState<TIn>;\n\t\t\tlet inners = st.inners;\n\t\t\tconst queue = st.queue;\n\n\t\t\t// 1. forward any inner DATA this wave (index-independent — flatten whichever inner fired).\n\t\t\tfor (let i = 1; i < depCount(ctx); i++) {\n\t\t\t\tconst b = depBatch(ctx, i);\n\t\t\t\tif (b && b.length > 0) for (const v of b) ctx.down([[\"DATA\", v]]);\n\t\t\t}\n\n\t\t\t// D81: source ERROR / inner ERROR are terminal operator edges. Detach live inners first,\n\t\t\t// then emit ERROR. Same-wave inner DATA that preceded the terminal is forwarded above.\n\t\t\t// Do not send COMPLETE/ERROR to those inner sources.\n\t\t\tconst terminalError = firstErrorTerminal(ctx);\n\t\t\tif (terminalError !== undefined) {\n\t\t\t\tcleanupAllInners(ctx, st, body);\n\t\t\t\tctx.down([[\"ERROR\", terminalError]]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (isTerminalComplete(depTerminal(ctx, 0))) st.sourceDone = true;\n\n\t\t\t// 2. drop inners that terminated this/any wave (bounding); `inners` aligns with deps[1..].\n\t\t\tconst toRemove: Node<unknown>[] = [];\n\t\t\tconst survivors: Node<unknown>[] = [];\n\t\t\tfor (let i = 0; i < inners.length; i++) {\n\t\t\t\tif (isTerminalComplete(depTerminal(ctx, i + 1))) toRemove.push(inners[i]);\n\t\t\t\telse survivors.push(inners[i]);\n\t\t\t}\n\t\t\tinners = survivors;\n\n\t\t\t// 3. project the source's new value(s) per mode.\n\t\t\tconst toAdd: Node<unknown>[] = [];\n\t\t\tconst make = (v: TIn): Node<unknown> => fromAnyInCtx(ctx, project(v));\n\t\t\tconst isRemovedThisWave = (inner: Node<unknown>): boolean => toRemove.includes(inner);\n\t\t\tconst canTrackInner = (inner: Node<unknown>): boolean =>\n\t\t\t\t!inners.includes(inner) && !isRemovedThisWave(inner);\n\t\t\tconst enqueueMerge = (v: TIn) => {\n\t\t\t\tif (maxConcurrent === Number.POSITIVE_INFINITY && queue.length === 0) {\n\t\t\t\t\tconst inner = make(v);\n\t\t\t\t\t// a projector returning an ALREADY-LIVE Node is already merged: subscribeDep is\n\t\t\t\t\t// set-idempotent, so double-tracking it in `inners` would desync the\n\t\t\t\t\t// inners[i] <-> deps[i+1] map permanently. Skip the duplicate.\n\t\t\t\t\tif (!canTrackInner(inner)) return;\n\t\t\t\t\tinners.push(inner);\n\t\t\t\t\ttoAdd.push(inner);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tqueue.push(v);\n\t\t\t};\n\t\t\tconst drainMergeQueue = () => {\n\t\t\t\twhile (queue.length > 0 && inners.length < maxConcurrent) {\n\t\t\t\t\tconst inner = make(queue.shift() as TIn);\n\t\t\t\t\tif (!canTrackInner(inner)) continue;\n\t\t\t\t\tinners.push(inner);\n\t\t\t\t\ttoAdd.push(inner);\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst sb = depBatch(ctx, 0) as readonly TIn[] | null;\n\t\t\tif (sb && sb.length > 0) {\n\t\t\t\tif (mode === \"switch\") {\n\t\t\t\t\t// switch to the latest value: cancel every current inner EXCEPT a (re-projected)\n\t\t\t\t\t// already-live one — the dep set is unique, so removing+re-adding the same Node\n\t\t\t\t\t// would needlessly tear down + re-subscribe it. Superseded sources torn down.\n\t\t\t\t\tconst inner = make(sb[sb.length - 1]);\n\t\t\t\t\tfor (const live of inners) if (live !== inner) toRemove.push(live);\n\t\t\t\t\tif (isRemovedThisWave(inner)) {\n\t\t\t\t\t\tinners = [];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif (!inners.includes(inner)) toAdd.push(inner);\n\t\t\t\t\t\tinners = [inner];\n\t\t\t\t\t}\n\t\t\t\t} else if (mode === \"merge\") {\n\t\t\t\t\tfor (const v of sb) {\n\t\t\t\t\t\tenqueueMerge(v);\n\t\t\t\t\t}\n\t\t\t\t} else if (mode === \"concat\") {\n\t\t\t\t\tfor (const v of sb) queue.push(v); // lazy: project on activation\n\t\t\t\t} else {\n\t\t\t\t\t// exhaust: ignore the source while an inner is active.\n\t\t\t\t\tif (inners.length === 0) {\n\t\t\t\t\t\tconst inner = make(sb[0]);\n\t\t\t\t\t\tif (canTrackInner(inner)) {\n\t\t\t\t\t\t\tinners.push(inner);\n\t\t\t\t\t\t\ttoAdd.push(inner);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 3a. bounded mergeMap: drain queued outer values as inner COMPLETEs free slots.\n\t\t\tif (mode === \"merge\" && queue.length > 0) drainMergeQueue();\n\n\t\t\t// 3b. concat: activate the queue head when the single slot is free.\n\t\t\tif (mode === \"concat\" && inners.length === 0 && toAdd.length === 0 && queue.length > 0) {\n\t\t\t\tconst inner = make(queue.shift() as TIn);\n\t\t\t\tif (canTrackInner(inner)) {\n\t\t\t\t\tinners.push(inner);\n\t\t\t\t\ttoAdd.push(inner);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.state.set({ inners, queue, sourceDone: st.sourceDone });\n\n\t\t\t// 4. issue REMOVES before ADDS (alignment): a removed dep is silent + applies before the\n\t\t\t// added dep's push-on-subscribe settle wave, so the tracked list stays aligned.\n\t\t\tfor (const r of toRemove) ctx.rewireNext.unsubscribeDep(r, body);\n\t\t\tfor (const a of toAdd) ctx.rewireNext.subscribeDep(a, body);\n\n\t\t\t// 5. completion: the SOURCE is done AND nothing is live or pending → COMPLETE (D47 folding;\n\t\t\t// a queued/just-added inner keeps it open). If terminal output happens in a wave that\n\t\t\t// also queued cleanup rewire, D62 still drains that queue after terminal.\n\t\t\tif (st.sourceDone && inners.length === 0 && toAdd.length === 0 && queue.length === 0) {\n\t\t\t\tctx.down([[\"COMPLETE\"]]);\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tif (st) cleanupAllInners(ctx, st, body);\n\t\t\tctx.down([[\"ERROR\", errorPayload(e, \"projector threw without a valid error payload\")]]); // D30/D81: a throwing projector → cleanup inners, then ERROR\n\t\t}\n\t};\n\n\treturn {\n\t\tfactory,\n\t\tbody,\n\t\t// D47/D81 folding: the operator owns completion + terminal ERROR cleanup.\n\t\topts: { completeWhenDepsComplete: false, terminalAsRealInput: true, errorWhenDepsError: false },\n\t};\n}\n\n/**\n * switchMap: project each source value to an inner; on a new source value, CANCEL the in-flight\n * inner (its source `_deactivate`s — abortInFlight) and switch to the new one. Only the current\n * inner's emissions are forwarded.\n * @param project - project value used by the helper.\n * @returns A `Operator<TIn, TOut>` value.\n * @category operators\n * @example\n * ```ts\n * import { switchMap } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function switchMap<TIn, TOut>(project: Project<TIn, TOut>): Operator<TIn, TOut> {\n\treturn mapOperator(\"switchMap\", project, \"switch\");\n}\n\n/**\n * mergeMap (a.k.a. flatMap): project each source value to an inner and keep ALL inners live,\n * interleaving their emissions. A completed inner is removed (memory bounding). On source/inner\n * ERROR or projector failure, every live inner is removed before the operator emits ERROR (D81).\n * @param project - project value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns A `Operator<TIn, TOut>` value.\n * @category operators\n * @example\n * ```ts\n * import { mergeMap } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function mergeMap<TIn, TOut>(\n\tproject: Project<TIn, TOut>,\n\topts: MergeMapOptions = {},\n): Operator<TIn, TOut> {\n\treturn mapOperator(\"mergeMap\", project, \"merge\", opts);\n}\n\n/** flatMap: alias of {@link mergeMap} (RxJS naming parity).\n * @param project - project value used by the helper.\n * @param opts - Options that configure the helper.\n * @returns A `Operator<TIn, TOut>` value.\n * @category operators\n * @example\n * ```ts\n * import { flatMap } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function flatMap<TIn, TOut>(\n\tproject: Project<TIn, TOut>,\n\topts: MergeMapOptions = {},\n): Operator<TIn, TOut> {\n\treturn mapOperator(\"flatMap\", project, \"merge\", opts);\n}\n\n/**\n * concatMap: project each source value to an inner, but run AT MOST ONE inner at a time — queue\n * later source values (lazy projection) and activate the next only when the active inner COMPLETEs.\n * Preserves source order.\n * @param project - project value used by the helper.\n * @returns A `Operator<TIn, TOut>` value.\n * @category operators\n * @example\n * ```ts\n * import { concatMap } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function concatMap<TIn, TOut>(project: Project<TIn, TOut>): Operator<TIn, TOut> {\n\treturn mapOperator(\"concatMap\", project, \"concat\");\n}\n\n/**\n * exhaustMap: while an inner is active, DROP new source values; project the next source value only\n * after the active inner COMPLETEs.\n * @param project - project value used by the helper.\n * @returns A `Operator<TIn, TOut>` value.\n * @category operators\n * @example\n * ```ts\n * import { exhaustMap } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function exhaustMap<TIn, TOut>(project: Project<TIn, TOut>): Operator<TIn, TOut> {\n\treturn mapOperator(\"exhaustMap\", project, \"exhaust\");\n}\n\n/** Per-node bookkeeping for {@link repeat}: the round index + the current live inner. */\ninterface RepeatState {\n\tstarted: boolean;\n\tround: number;\n\tinner: Node<unknown> | null;\n}\n\n/**\n * repeat: play a source `count` times in sequence (RxJS `repeat`). A DEPLESS self-driving operator\n * (Operator<never, S>, instantiate via `g.initNode(repeat(factory, count), [])`) — NOT a dep-operator.\n *\n * It takes a `factory: () => NodeInput<S>` (a RECIPE), not a source Node, because GraphReFly Nodes\n * are HOT/shared (multicast + cache): re-subscribing the SAME node replays its cache, it does not\n * re-RUN the source. RxJS `repeat` re-subscribes the COLD source = a fresh subscription each round;\n * the GraphReFly analogue is a fresh node per round → a factory. (A `repeat(count)`-over-a-Node\n * shape remains deferred: D47's no-net-change-is-a-no-op makes\n * `unsubscribeDep(S)+subscribeDep(S)` on the SAME boundary cancel out. D115 keeps the model to\n * ordinary unsubscribe plus a later subscribe, so same-node repeat needs a separate future design.)\n *\n * Mechanism (reuses the D47 self-rewire substrate, like the *Map family; NOT an internal subscribe,\n * D45): on activation it mints round 0's inner via `ctx.rewireNext.subscribeDep`; each round's inner DATA\n * is forwarded; on the inner's COMPLETE (`completeWhenDepsComplete:false + terminalAsRealInput:true`)\n * it unsubscribeDep's the finished inner and, if rounds remain, subscribeDep's a FRESH `factory()` inner (a\n * distinct node → a real net change, not the no-op same-node case); after the last round it emits\n * COMPLETE. An inner ERROR auto-forwards (errorWhenDepsError default → repeat errors). The body is\n * SELF-CATCHING (D30) and re-supplied on every rewire. The factory MUST mint a FRESH node per call\n * (a factory returning the same Node makes unsubscribeDep+subscribeDep a net-zero no-op → repeat wedges).\n * @param factory - factory value used by the helper.\n * @param count - count value used by the helper.\n * @returns A `Operator<never, S>` value.\n * @category operators\n * @example\n * ```ts\n * import { repeat } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function repeat<S>(factory: () => NodeInput<S>, count: number): Operator<never, S> {\n\tif (!Number.isInteger(count) || count < 1) {\n\t\tthrow new RangeError(`repeat: count must be a positive integer (got ${count})`);\n\t}\n\tconst body: NodeFn = (ctx: Ctx) => {\n\t\ttry {\n\t\t\tconst st = (ctx.state.get<RepeatState>() ?? {\n\t\t\t\tstarted: false,\n\t\t\t\tround: 0,\n\t\t\t\tinner: null,\n\t\t\t}) as RepeatState;\n\t\t\t// 1. forward the current inner's DATA this wave (the inner is the sole dep once wired).\n\t\t\tfor (let i = 0; i < depCount(ctx); i++) {\n\t\t\t\tconst b = depBatch(ctx, i);\n\t\t\t\tif (b && b.length > 0) for (const v of b) ctx.down([[\"DATA\", v]]);\n\t\t\t}\n\t\t\t// 2. activation: mint round 0's inner.\n\t\t\tif (!st.started) {\n\t\t\t\tst.started = true;\n\t\t\t\tst.round = 0;\n\t\t\t\tconst inner = fromAnyInCtx(ctx, factory());\n\t\t\t\tst.inner = inner;\n\t\t\t\tctx.state.set(st);\n\t\t\t\tctx.rewireNext.subscribeDep(inner, body);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// 3. inner COMPLETE → next round or terminal COMPLETE.\n\t\t\tif (st.inner !== null && isTerminalComplete(depTerminal(ctx, 0))) {\n\t\t\t\tconst old = st.inner;\n\t\t\t\tctx.rewireNext.unsubscribeDep(old, body); // bound the finished round's inner\n\t\t\t\tif (st.round + 1 < count) {\n\t\t\t\t\tst.round += 1;\n\t\t\t\t\tconst next = fromAnyInCtx(ctx, factory());\n\t\t\t\t\tst.inner = next;\n\t\t\t\t\tctx.state.set(st);\n\t\t\t\t\tctx.rewireNext.subscribeDep(next, body);\n\t\t\t\t} else {\n\t\t\t\t\tst.inner = null;\n\t\t\t\t\tctx.state.set(st);\n\t\t\t\t\tctx.down([[\"COMPLETE\"]]);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tctx.down([[\"ERROR\", errorPayload(e, \"repeat threw without a valid error payload\")]]); // D30 (self-catch survives rewire)\n\t\t}\n\t};\n\treturn {\n\t\tfactory: \"repeat\",\n\t\tbody,\n\t\topts: { completeWhenDepsComplete: false, terminalAsRealInput: true },\n\t};\n}\n","/**\n * Wall-clock time operators (CSP-2.7 / D52 / B23). Authored as COMPOSITIONS over the already-active\n * higher-order *Map machinery (D47) + the `timer` source — NO raw `setTimeout` in any operator body\n * (R-no-raw-async / check-no-raw-async; `setTimeout` stays confined to `sources.ts`'s `timer`). The\n * timer source's `onDeactivation` clearTimeout IS the reset/cancel: switchMap's unsubscribeDep on a new\n * source value tears the in-flight timer down (the declarative equivalent of the frozen reference's\n * imperative clearTimeout-then-setTimeout). Per-language (D6/D24), never in parity.\n *\n * Shipped this cut (clean *Map+timer):\n * - delay = mergeMap(v → timer(ms)→v) (every value delayed ms, ALL kept, order preserved)\n * - debounce(Time) = switchMap(v → timer(ms)→v) (cancel-and-restart; emit the latest after quiet ms)\n * - throttle(Time) = exhaustMap(v → [v now, alive ms]) (leading edge: emit v, ignore for ms)\n *\n * Behavior on source COMPLETE (per-operator, NOT a uniform DROP): debounce/debounceTime EMIT their\n * pending trailing value — switchMap does not cancel the in-flight inner on source COMPLETE (only a\n * superseding source value cancels it via unsubscribeDep→onDeactivation→clearTimeout), so the timer still\n * fires at `ms`, emits the debounced value, and only THEN does the operator COMPLETE (RxJS\n * debounceTime parity). delay emits every still-pending delayed value then COMPLETEs (mergeMap keeps\n * all inners). throttle/throttleTime have NO trailing value (leading-edge only, RxJS default\n * trailing:false) — an open window inner is dropped when the operator completes.\n *\n * B41 tail (landed 2026-05-31, the two shapes reflect WHEN the clock arms):\n * - audit / auditTime — VALUE-TRIGGERED trailing edge: a source value opens a duration window\n * (`audit(durationSelector)` = the general/notifier form, mirroring the *Map\n * `Project` idiom + D46; `auditTime(ms)` = `audit(() => timer(ms))`), emits the\n * window's LATEST value at the window's close. Self-wires the notifier via\n * ctx.rewireNext — a normal `g.initNode(audit(sel), [source])` operator.\n * - timeout / bufferTime — SUBSCRIBE-ARMED (RxJS-cold): the clock must run from activation, before\n * any source value, so the timer/interval is a CONSTRUCTION-time dep (a depless\n * source arms lazily on subscribe per node `_activate`). A dep-bearing operator\n * body never runs at activation (only depless nodes do, node.ts), so these ship\n * as graph composition HELPERS `timeout(source, ms)` / `bufferTime(source, ms)`\n * returning a Node — NOT `g.initNode(op, [deps])` operators. timeout resets its\n * idle timer per source value via ctx.rewireNext (ERROR on the gap); bufferTime\n * is buffer-over-interval with terminal cleanup via ctx.rewireNext.\n *\n * NOT ported (D58): window/windowCount/windowTime — the Node<Node<T>> higher-order forms are a D45\n * describe island; the array forms (buffer/bufferCount/bufferTime) are the graph-first equivalent.\n *\n * Inspection caveat (timeout/bufferTime): the helper returns a BARE node (free initNode) self-carrying\n * its factory for describe auto-discovery (D51), but it is NOT in a graph's _entries — so g.describe()\n * lists it only when it is a live dep of a registered node (a first-cut limit, like the *Map inners).\n */\n\nimport {\n\ttype Ctx,\n\tdepBatch,\n\tdepTerminal,\n\tisTerminalComplete,\n\tisTerminalError,\n\ttype NodeFn,\n\tterminalErrorValue,\n} from \"../ctx/types.js\";\nimport type { Node } from \"../node/node.js\";\nimport { errorPayload } from \"../protocol/messages.js\";\nimport { exhaustMap, mergeMap, switchMap } from \"./higher-order.js\";\nimport { filter, initNode, map, merge, type Operator } from \"./operators.js\";\nimport { fromAny, interval, type NodeInput, of, timer } from \"./sources.js\";\n\n/** A bare inner that emits `v` once after `ms`, then COMPLETEs (timer(ms)→map(v); auto-completes). */\nfunction delayedValue<S>(v: S, ms: number): Node<S> {\n\treturn initNode(\n\t\tmap(() => v),\n\t\t[initNode(timer(ms), [])],\n\t);\n}\n\n/**\n * An inner that emits `v` IMMEDIATELY (on activation) and stays alive for `ms` (then COMPLETEs),\n * emitting nothing more — the leading-edge throttle window. `merge(of(v), silentTimer)`: `of(v)`\n * emits v + COMPLETE at t=0; `filter(()=>false)` over `timer(ms)` emits no DATA and COMPLETEs at\n * t=ms; merge forwards v at t=0 and COMPLETEs (all deps complete) at t=ms.\n */\nfunction throttleWindow<S>(v: S, ms: number): Node<S> {\n\tconst silentTimer = initNode(\n\t\tfilter<number>(() => false),\n\t\t[initNode(timer(ms), [])],\n\t) as Node<S>;\n\treturn initNode(merge<S>(), [initNode(of(v), []), silentTimer]);\n}\n\n/**\n * delay: shift every value by `ms`, preserving all values + order. `mergeMap` keeps every inner\n * timer live (equal `ms`, so they fire in arrival order).\n * @param ms - Duration or timestamp in milliseconds.\n * @returns A `Operator<S, S>` value.\n * @category operators\n * @example\n * ```ts\n * import { delay } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function delay<S>(ms: number): Operator<S, S> {\n\treturn { ...mergeMap<S, S>((v) => delayedValue(v, ms)), factory: \"delay\" };\n}\n\n/**\n * debounce (alias `debounceTime`): emit the latest value only after `ms` of quiet. `switchMap`\n * cancels the prior timer (its onDeactivation clearTimeout) on each new source value and restarts —\n * the declarative debounce.\n *\n * RxJS-7 divergence (reference rxjs@7.8, B44): RxJS `debounceTime` FLUSHES the pending value\n * IMMEDIATELY when the source COMPLETEs (its `_complete` calls `debouncedNext()` before\n * `complete()`). This composition instead emits the pending value when the in-flight `timer(ms)`\n * fires — i.e. at `(last-value-time + ms)` — so if the source completes mid-window the trailing\n * value arrives up to `ms` later than RxJS. Inherent to the `*Map`+`timer` form (the composition\n * cannot flush early without detecting COMPLETE inside the switchMap inner); accepted, not a bug.\n * @param ms - Duration or timestamp in milliseconds.\n * @returns A `Operator<S, S>` value.\n * @category operators\n * @example\n * ```ts\n * import { debounce } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function debounce<S>(ms: number): Operator<S, S> {\n\treturn { ...switchMap<S, S>((v) => delayedValue(v, ms)), factory: \"debounce\" };\n}\n\n/** debounceTime: RxJS-named alias of {@link debounce}.\n * @param ms - Duration or timestamp in milliseconds.\n * @returns A `Operator<S, S>` value.\n * @category operators\n * @example\n * ```ts\n * import { debounceTime } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function debounceTime<S>(ms: number): Operator<S, S> {\n\treturn { ...switchMap<S, S>((v) => delayedValue(v, ms)), factory: \"debounceTime\" };\n}\n\n/**\n * throttle (alias `throttleTime`): leading-edge — emit a value immediately, then ignore the source\n * for `ms`. `exhaustMap` drops new source values while the current window inner is alive; the\n * window emits v at its leading edge and stays alive `ms`.\n *\n * Matches the RxJS-7 `throttleTime` DEFAULT (leading:true, trailing:false). The leading/trailing\n * OPTIONS RxJS exposes are NOT provided (a capability gap, not a behavior divergence; B44) — add a\n * trailing-window form if a consumer needs it.\n * @param ms - Duration or timestamp in milliseconds.\n * @returns A `Operator<S, S>` value.\n * @category operators\n * @example\n * ```ts\n * import { throttle } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function throttle<S>(ms: number): Operator<S, S> {\n\treturn { ...exhaustMap<S, S>((v) => throttleWindow(v, ms)), factory: \"throttle\" };\n}\n\n/** throttleTime: RxJS-named alias of {@link throttle}.\n * @param ms - Duration or timestamp in milliseconds.\n * @returns A `Operator<S, S>` value.\n * @category operators\n * @example\n * ```ts\n * import { throttleTime } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function throttleTime<S>(ms: number): Operator<S, S> {\n\treturn { ...exhaustMap<S, S>((v) => throttleWindow(v, ms)), factory: \"throttleTime\" };\n}\n\n// ── B41 tail: value-triggered (audit) + subscribe-armed (timeout/bufferTime) ──\n\n/** Per-node bookkeeping for {@link audit}: the open window's notifier + the latest value seen. */\ninterface AuditState<S> {\n\twindowOpen: boolean;\n\tlatest: { v: S } | undefined;\n\tnotifier: Node<unknown> | null;\n}\n\n/**\n * audit: VALUE-TRIGGERED trailing throttle. A source value (when no window is open) opens a duration\n * window via `durationSelector(value)` → a notifier `NodeInput` wired as dep 1 with `ctx.rewireNext`\n * (D47 — the *Map self-rewire idiom, NOT an internal subscribe, D45); during the window new source\n * values only UPDATE the tracked latest (no emit); when the notifier fires (its first DATA / COMPLETE)\n * the window closes and the LATEST value is emitted. This is throttle's trailing-edge twin\n * (throttle emits the window's FIRST value at the leading edge; audit emits the LAST at the close).\n *\n * `durationSelector` is the general/notifier form (mirrors the *Map `Project` idiom + D46); the source\n * is dep 0, the live notifier (if any) is dep 1. On source COMPLETE the pending latest is FLUSHED then\n * COMPLETE (RxJS-7 audit flush-on-complete, B44). A source/notifier ERROR is read as a real terminal\n * input so the live notifier can be removed before ERROR. Self-catching (D30); re-supplies its body on\n * every rewire.\n * @param durationSelector - duration selector value used by the helper.\n * @returns A `Operator<S, S>` value.\n * @category operators\n * @example\n * ```ts\n * import { audit } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function audit<S>(durationSelector: (v: S) => NodeInput<unknown>): Operator<S, S> {\n\tconst body: NodeFn = (ctx: Ctx) => {\n\t\ttry {\n\t\t\tconst st: AuditState<S> = ctx.state.get<AuditState<S>>() ?? {\n\t\t\t\twindowOpen: false,\n\t\t\t\tlatest: undefined,\n\t\t\t\tnotifier: null,\n\t\t\t};\n\t\t\tconst sourceBatch = depBatch(ctx, 0);\n\t\t\tconst notifierBatch = depBatch(ctx, 1); // live duration notifier while a window is open\n\t\t\tconst sourceTerminal = depTerminal(ctx, 0);\n\t\t\tconst notifierTerminal = depTerminal(ctx, 1);\n\n\t\t\t// every source value updates the window's latest (the value emitted at the window's close).\n\t\t\tconst sb = sourceBatch as readonly S[] | null;\n\t\t\tif (sb) for (const v of sb) st.latest = { v };\n\n\t\t\t// the window closes when its duration notifier fires (DATA or COMPLETE) → emit the latest.\n\t\t\tconst notifierFired =\n\t\t\t\tst.windowOpen &&\n\t\t\t\t((notifierBatch != null && notifierBatch.length > 0) ||\n\t\t\t\t\tisTerminalComplete(notifierTerminal));\n\t\t\tif (notifierFired) {\n\t\t\t\tif (st.latest !== undefined) ctx.down([[\"DATA\", st.latest.v]]);\n\t\t\t\tconst old = st.notifier;\n\t\t\t\tst.windowOpen = false;\n\t\t\t\tst.notifier = null;\n\t\t\t\tst.latest = undefined;\n\t\t\t\tif (old) ctx.rewireNext.unsubscribeDep(old, body);\n\t\t\t}\n\n\t\t\t// source/notifier ERROR → forward ERROR, but first remove the helper-owned notifier.\n\t\t\tconst sourceError = isTerminalError(sourceTerminal);\n\t\t\tconst notifierError = isTerminalError(notifierTerminal);\n\t\t\tif (sourceError || notifierError) {\n\t\t\t\tconst err = terminalErrorValue(sourceError ? sourceTerminal : notifierTerminal);\n\t\t\t\tif (st.notifier) ctx.rewireNext.unsubscribeDep(st.notifier, body);\n\t\t\t\tctx.state.set({ windowOpen: false, latest: undefined, notifier: null });\n\t\t\t\tctx.down([[\"ERROR\", err]]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// source COMPLETE → flush the pending latest (B44 audit flush-on-complete) then COMPLETE.\n\t\t\tif (isTerminalComplete(sourceTerminal)) {\n\t\t\t\tif (st.windowOpen && st.latest !== undefined) ctx.down([[\"DATA\", st.latest.v]]);\n\t\t\t\tif (st.notifier) ctx.rewireNext.unsubscribeDep(st.notifier, body);\n\t\t\t\tctx.state.set({ windowOpen: false, latest: undefined, notifier: null });\n\t\t\t\tctx.down([[\"COMPLETE\"]]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// a fresh source value with no open window → open one (value-triggered, trailing edge).\n\t\t\tif (!st.windowOpen && sb != null && sb.length > 0 && st.latest !== undefined) {\n\t\t\t\tconst n = fromAny<unknown>(durationSelector(st.latest.v), { iter: true });\n\t\t\t\tst.windowOpen = true;\n\t\t\t\tst.notifier = n;\n\t\t\t\tctx.rewireNext.subscribeDep(n, body); // (a same-wave close+reopen issues remove-before-add)\n\t\t\t}\n\n\t\t\tctx.state.set(st);\n\t\t} catch (e) {\n\t\t\tctx.down([[\"ERROR\", errorPayload(e, \"audit threw without a valid error payload\")]]);\n\t\t}\n\t};\n\treturn {\n\t\tfactory: \"audit\",\n\t\tbody,\n\t\topts: {\n\t\t\tpartial: true,\n\t\t\tcompleteWhenDepsComplete: false,\n\t\t\terrorWhenDepsError: false,\n\t\t\tterminalAsRealInput: true,\n\t\t},\n\t};\n}\n\n/** auditTime: the `ms`-specialization of {@link audit} — the window is a `timer(ms)`.\n * @param ms - Duration or timestamp in milliseconds.\n * @returns A `Operator<S, S>` value.\n * @category operators\n * @example\n * ```ts\n * import { auditTime } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function auditTime<S>(ms: number): Operator<S, S> {\n\treturn { ...audit<S>(() => initNode(timer(ms), [])), factory: \"auditTime\" };\n}\n\n/** Per-node bookkeeping for {@link timeout}: the live idle timer (reset on each source value). */\ninterface TimeoutState {\n\ttimer: Node<unknown> | null;\n}\n\n/**\n * timeout: idle watchdog — forward every source value, but ERROR if more than `ms` elapses with no\n * value (RxJS `timeout(ms)`, `first === each === ms`). SUBSCRIBE-ARMED: the first `timer(ms)` is a\n * CONSTRUCTION-time dep, so it arms when `timeout`'s node is subscribed/activated (a depless source\n * runs lazily on `_activate`) — i.e. a source that never emits its FIRST value within `ms` still\n * errors. A dep-bearing operator body never runs at activation (only depless nodes do, node.ts), which\n * is why this is a HELPER returning a Node, not a `g.initNode(op, [source])` operator.\n *\n * Each source value forwards as-is and RESETS the idle timer (unsubscribeDep the current `timer(ms)`,\n * subscribeDep a fresh one — its `onDeactivation` clearTimeout cancels the prior countdown). The timer\n * firing (its DATA/COMPLETE) is the timeout → `[[ERROR]]`. Source COMPLETE forwards COMPLETE (no\n * error) and removes the idle timer during the terminal wave (D62 terminal-drains-queued-rewire);\n * a source ERROR forwards likewise. The idle timer is also torn down when the consumer unsubscribes\n * (timeout deactivates → dep unsub → timer onDeactivation). Self-catching (D30).\n * @param source - Source node that provides graph-visible input.\n * @param ms - Duration or timestamp in milliseconds.\n * @returns A `Node<S>` value.\n * @category operators\n * @example\n * ```ts\n * import { timeout } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function timeout<S>(source: Node<S>, ms: number): Node<S> {\n\tconst makeTimer = (): Node<unknown> => initNode(timer(ms), []);\n\tconst initial = makeTimer();\n\tconst body: NodeFn = (ctx: Ctx) => {\n\t\ttry {\n\t\t\tconst st: TimeoutState = ctx.state.get<TimeoutState>() ?? { timer: initial };\n\t\t\tconst srcBatch = depBatch(ctx, 0);\n\t\t\tconst srcTerminal = depTerminal(ctx, 0);\n\n\t\t\t// a source value forwards as-is and resets the idle window.\n\t\t\tconst sb = srcBatch as readonly S[] | null;\n\t\t\tif (sb != null && sb.length > 0) {\n\t\t\t\tfor (const v of sb) ctx.down([[\"DATA\", v]]);\n\t\t\t\tconst old = st.timer;\n\t\t\t\tconst next = makeTimer();\n\t\t\t\tst.timer = next;\n\t\t\t\tctx.state.set(st);\n\t\t\t\tif (old) ctx.rewireNext.unsubscribeDep(old, body); // remove-before-add (alignment)\n\t\t\t\tctx.rewireNext.subscribeDep(next, body);\n\t\t\t\treturn; // a value-bearing wave is never also a timeout-fire wave\n\t\t\t}\n\n\t\t\t// source COMPLETE → forward COMPLETE (no timeout fires).\n\t\t\tif (isTerminalComplete(srcTerminal)) {\n\t\t\t\tif (st.timer) ctx.rewireNext.unsubscribeDep(st.timer, body);\n\t\t\t\tctx.down([[\"COMPLETE\"]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// source ERROR (absorbed via errorWhenDepsError:false) → forward it.\n\t\t\tif (isTerminalError(srcTerminal)) {\n\t\t\t\tif (st.timer) ctx.rewireNext.unsubscribeDep(st.timer, body);\n\t\t\t\tctx.down([[\"ERROR\", terminalErrorValue(srcTerminal)]]);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// otherwise this wave is the idle timer firing → timeout ERROR.\n\t\t\tconst timerBatch = depBatch(ctx, 1);\n\t\t\tif (\n\t\t\t\t(timerBatch != null && timerBatch.length > 0) ||\n\t\t\t\tisTerminalComplete(depTerminal(ctx, 1))\n\t\t\t) {\n\t\t\t\tctx.down([[\"ERROR\", new Error(`timeout: no value within ${ms}ms`)]]);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tctx.state.set(st);\n\t\t} catch (e) {\n\t\t\tctx.down([[\"ERROR\", errorPayload(e, \"timeout threw without a valid error payload\")]]);\n\t\t}\n\t};\n\treturn initNode<S, S>(\n\t\t{\n\t\t\tfactory: \"timeout\",\n\t\t\tbody,\n\t\t\topts: {\n\t\t\t\tpartial: true,\n\t\t\t\tcompleteWhenDepsComplete: false,\n\t\t\t\terrorWhenDepsError: false,\n\t\t\t\tterminalAsRealInput: true,\n\t\t\t},\n\t\t},\n\t\t[source as Node<unknown>, initial],\n\t);\n}\n\n/**\n * bufferTime: buffer source values and flush them as an array every `ms` (RxJS `bufferTime(ms)`).\n * SUBSCRIBE-ARMED: the `interval(ms)` notifier is a CONSTRUCTION-time dep (arms on subscribe), so an\n * empty window flushes `[]` even before the first source value — matching the landed {@link buffer}\n * (which flushes on every notifier signal). On source COMPLETE the remainder flushes then COMPLETE\n * (B44), and D62 lets the terminal wave still drain `unsubscribeDep(interval)` so the helper-owned\n * interval source deactivates instead of ticking forever.\n * @param source - Source node that provides graph-visible input.\n * @param ms - Duration or timestamp in milliseconds.\n * @returns A `Node<S[]>` value.\n * @category operators\n * @example\n * ```ts\n * import { bufferTime } from \"@graphrefly/ts/operators\";\n * ```\n */\nexport function bufferTime<S>(source: Node<S>, ms: number): Node<S[]> {\n\tconst iv: Node<unknown> = initNode(interval(ms), []);\n\tconst body: NodeFn = (ctx: Ctx) => {\n\t\tconst srcBatch = depBatch(ctx, 0);\n\t\tconst tickBatch = depBatch(ctx, 1);\n\t\tconst srcTerminal = depTerminal(ctx, 0);\n\t\tconst buf = ctx.state.get<S[]>() ?? [];\n\t\tif (srcBatch) for (const v of srcBatch) buf.push(v as S);\n\t\tif (isTerminalComplete(srcTerminal)) {\n\t\t\tif (buf.length > 0) ctx.down([[\"DATA\", [...buf]]]);\n\t\t\tctx.state.set([]);\n\t\t\tctx.rewireNext.unsubscribeDep(iv, body);\n\t\t\tctx.down([[\"COMPLETE\"]]);\n\t\t\treturn;\n\t\t}\n\t\tif (isTerminalError(srcTerminal)) {\n\t\t\tctx.state.set([]);\n\t\t\tctx.rewireNext.unsubscribeDep(iv, body);\n\t\t\tctx.down([[\"ERROR\", terminalErrorValue(srcTerminal)]]);\n\t\t\treturn;\n\t\t}\n\t\tif (tickBatch && tickBatch.length > 0) {\n\t\t\tctx.down([[\"DATA\", [...buf]]]);\n\t\t\tctx.state.set([]);\n\t\t\treturn;\n\t\t}\n\t\tctx.state.set(buf);\n\t};\n\treturn initNode<unknown, S[]>(\n\t\t{\n\t\t\tfactory: \"bufferTime\",\n\t\t\tbody,\n\t\t\topts: {\n\t\t\t\tpartial: true,\n\t\t\t\tcompleteWhenDepsComplete: false,\n\t\t\t\terrorWhenDepsError: false,\n\t\t\t\tterminalAsRealInput: true,\n\t\t\t},\n\t\t},\n\t\t[source as Node<unknown>, iv],\n\t);\n}\n"],"mappings":"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","names":[]}
@@ -5,7 +5,7 @@ import {
5
5
  checkpointValue,
6
6
  initNodeWithCore,
7
7
  toCheckpointJson
8
- } from "./chunk-FLUPPSIP.js";
8
+ } from "./chunk-3KYPNNBH.js";
9
9
  import {
10
10
  EnvironmentDrivers,
11
11
  Node,
@@ -1195,4 +1195,4 @@ export {
1195
1195
  restoreStateNodeInGraph,
1196
1196
  restoreNodeInGraph
1197
1197
  };
1198
- //# sourceMappingURL=chunk-V3MSIDUQ.js.map
1198
+ //# sourceMappingURL=chunk-TWOPVCGK.js.map
@@ -30,4 +30,4 @@ function profileSummary(graph, opts = {}) {
30
30
  export {
31
31
  profileSummary
32
32
  };
33
- //# sourceMappingURL=chunk-ND43YDGK.js.map
33
+ //# sourceMappingURL=chunk-V3YEGWSH.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/patterns/inspection.ts"],"sourcesContent":["/**\n * Horizontal inspection patterns re-derived from old presets (B62 / D125).\n *\n * These helpers compose GraphReFly graph inspection egresses. They do not\n * add graph nodes, hidden subscriptions, policy gates, or storage ownership.\n */\n\nimport type { Graph } from \"../graph/graph.js\";\nimport type { NodeProfile } from \"../graph/inspect.js\";\n\nexport interface ProfileSummaryNode {\n\tpath: string;\n\tinvokes: number;\n\ttotalDurationNs: number;\n\tlastDurationNs: number;\n\tstatus: NodeProfile[\"status\"];\n}\n\nexport interface ProfileSummary {\n\t/** Number of nodes in describe(), including nodes with zero invokes. */\n\tnodeCount: number;\n\ttotalInvokes: number;\n\tbyStatus: Partial<Record<NodeProfile[\"status\"], number>>;\n\t/** Nodes sorted by invokes desc, then path asc. */\n\thotNodes: ProfileSummaryNode[];\n}\n\n/**\n * Summarize an opt-in Graph.profile() snapshot while keeping describe() as the\n * source of node cardinality. No counters are stored on nodes (R-profile).\n * @param graph - Graph that owns the created nodes or projector.\n * @param opts - Options that configure the helper.\n * @returns A `ProfileSummary` value.\n * @category patterns\n * @example\n * ```ts\n * import { profileSummary } from \"@graphrefly/ts/patterns\";\n * ```\n */\nexport function profileSummary(graph: Graph, opts: { limit?: number } = {}): ProfileSummary {\n\tconst profile = graph.profile();\n\tconst described = graph.describe();\n\tconst nodeIds = new Set(described.nodes.map((node) => node.id));\n\tfor (const id of Object.keys(profile.nodes)) nodeIds.add(id);\n\n\tconst byStatus: Partial<Record<NodeProfile[\"status\"], number>> = {};\n\tconst hotNodes: ProfileSummaryNode[] = [];\n\tfor (const path of [...nodeIds].sort()) {\n\t\tconst nodeProfile = profile.nodes[path];\n\t\tif (nodeProfile === undefined) continue;\n\t\tbyStatus[nodeProfile.status] = (byStatus[nodeProfile.status] ?? 0) + 1;\n\t\thotNodes.push({\n\t\t\tpath,\n\t\t\tinvokes: nodeProfile.invokes,\n\t\t\ttotalDurationNs: nodeProfile.totalDurationNs,\n\t\t\tlastDurationNs: nodeProfile.lastDurationNs,\n\t\t\tstatus: nodeProfile.status,\n\t\t});\n\t}\n\thotNodes.sort((a, b) => b.invokes - a.invokes || a.path.localeCompare(b.path));\n\treturn {\n\t\tnodeCount: nodeIds.size,\n\t\ttotalInvokes: profile.totalInvokes,\n\t\tbyStatus,\n\t\thotNodes: hotNodes.slice(0, opts.limit ?? hotNodes.length),\n\t};\n}\n"],"mappings":";AAuCO,SAAS,eAAe,OAAc,OAA2B,CAAC,GAAmB;AAC3F,QAAM,UAAU,MAAM,QAAQ;AAC9B,QAAM,YAAY,MAAM,SAAS;AACjC,QAAM,UAAU,IAAI,IAAI,UAAU,MAAM,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC;AAC9D,aAAW,MAAM,OAAO,KAAK,QAAQ,KAAK,EAAG,SAAQ,IAAI,EAAE;AAE3D,QAAM,WAA2D,CAAC;AAClE,QAAM,WAAiC,CAAC;AACxC,aAAW,QAAQ,CAAC,GAAG,OAAO,EAAE,KAAK,GAAG;AACvC,UAAM,cAAc,QAAQ,MAAM,IAAI;AACtC,QAAI,gBAAgB,OAAW;AAC/B,aAAS,YAAY,MAAM,KAAK,SAAS,YAAY,MAAM,KAAK,KAAK;AACrE,aAAS,KAAK;AAAA,MACb;AAAA,MACA,SAAS,YAAY;AAAA,MACrB,iBAAiB,YAAY;AAAA,MAC7B,gBAAgB,YAAY;AAAA,MAC5B,QAAQ,YAAY;AAAA,IACrB,CAAC;AAAA,EACF;AACA,WAAS,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAC7E,SAAO;AAAA,IACN,WAAW,QAAQ;AAAA,IACnB,cAAc,QAAQ;AAAA,IACtB;AAAA,IACA,UAAU,SAAS,MAAM,GAAG,KAAK,SAAS,SAAS,MAAM;AAAA,EAC1D;AACD;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  initNode
3
- } from "./chunk-FLUPPSIP.js";
3
+ } from "./chunk-3KYPNNBH.js";
4
4
  import {
5
5
  depBatch,
6
6
  depLatest,
@@ -161,4 +161,4 @@ export {
161
161
  stratifyBranch,
162
162
  stratify
163
163
  };
164
- //# sourceMappingURL=chunk-2BIF6BQ7.js.map
164
+ //# sourceMappingURL=chunk-W4ATMMTH.js.map
@@ -1,7 +1,7 @@
1
1
  import { DataIssue } from './data/index.js';
2
2
  import { C as Codec } from './codec-C22dT0kb.js';
3
3
  import { F as FactId } from './semantic-memory-BkTM1jyQ.js';
4
- import { d as Graph } from './graph-D7DgoW4r.js';
4
+ import { d as Graph } from './graph-BYcUX6Y-.js';
5
5
  import { N as Node } from './index-D9ATwlam.js';
6
6
  import { bq as StrictJsonValue, az as AgenticMemoryRecordApplicationDecision, a_ as AgenticMemoryRecordFrame, J as AgenticMemoryFactRef, aQ as AgenticMemoryRecordApplicationPriorEvidence, aB as AgenticMemoryRecordApplicationEvidence, a8 as AgenticMemoryRecord } from './types-DeNVUK0W.js';
7
7
 
@@ -1,7 +1,7 @@
1
1
  import { DataIssue } from './data/index.cjs';
2
2
  import { C as Codec } from './codec-C22dT0kb.cjs';
3
3
  import { F as FactId } from './semantic-memory-Dk3E-GiC.cjs';
4
- import { d as Graph } from './graph-BpVjXE3p.cjs';
4
+ import { d as Graph } from './graph-DpUhfPg-.cjs';
5
5
  import { N as Node } from './index-BNyz3GBZ.cjs';
6
6
  import { bq as StrictJsonValue, az as AgenticMemoryRecordApplicationDecision, a_ as AgenticMemoryRecordFrame, J as AgenticMemoryFactRef, aQ as AgenticMemoryRecordApplicationPriorEvidence, aB as AgenticMemoryRecordApplicationEvidence, a8 as AgenticMemoryRecord } from './types-DeoCwsyw.cjs';
7
7