@graphrefly/graphrefly 0.47.2 → 0.48.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 (266) hide show
  1. package/dist/base/composition/index.cjs +4 -3
  2. package/dist/base/composition/index.cjs.map +1 -1
  3. package/dist/base/composition/index.d.cts +14 -5
  4. package/dist/base/composition/index.d.ts +14 -5
  5. package/dist/base/composition/index.js +8 -8
  6. package/dist/base/index.cjs +152 -78
  7. package/dist/base/index.cjs.map +1 -1
  8. package/dist/base/index.d.cts +2 -2
  9. package/dist/base/index.d.ts +2 -2
  10. package/dist/base/index.js +75 -70
  11. package/dist/base/io/index.cjs +31 -17
  12. package/dist/base/io/index.cjs.map +1 -1
  13. package/dist/base/io/index.d.cts +32 -5
  14. package/dist/base/io/index.d.ts +32 -5
  15. package/dist/base/io/index.js +1 -1
  16. package/dist/base/mutation/index.cjs +21 -0
  17. package/dist/base/mutation/index.cjs.map +1 -1
  18. package/dist/base/mutation/index.d.cts +23 -1
  19. package/dist/base/mutation/index.d.ts +23 -1
  20. package/dist/base/mutation/index.js +3 -1
  21. package/dist/base/sources/browser/index.cjs +5 -3
  22. package/dist/base/sources/browser/index.cjs.map +1 -1
  23. package/dist/base/sources/browser/index.d.cts +20 -2
  24. package/dist/base/sources/browser/index.d.ts +20 -2
  25. package/dist/base/sources/browser/index.js +5 -3
  26. package/dist/base/sources/browser/index.js.map +1 -1
  27. package/dist/base/sources/event/index.cjs +28 -0
  28. package/dist/base/sources/event/index.cjs.map +1 -1
  29. package/dist/base/sources/event/index.d.cts +67 -3
  30. package/dist/base/sources/event/index.d.ts +67 -3
  31. package/dist/base/sources/event/index.js +4 -1
  32. package/dist/base/sources/index.cjs +75 -37
  33. package/dist/base/sources/index.cjs.map +1 -1
  34. package/dist/base/sources/index.d.cts +1 -1
  35. package/dist/base/sources/index.d.ts +1 -1
  36. package/dist/base/sources/index.js +5 -2
  37. package/dist/{chunk-R6ZCSXKX.js → chunk-23MAWVOJ.js} +3 -3
  38. package/dist/{chunk-MS3WPRJR.js → chunk-3REMCHSS.js} +6 -6
  39. package/dist/chunk-3REMCHSS.js.map +1 -0
  40. package/dist/{chunk-CEVNQ74M.js → chunk-3YGXPUHW.js} +2 -2
  41. package/dist/{chunk-CEVNQ74M.js.map → chunk-3YGXPUHW.js.map} +1 -1
  42. package/dist/{chunk-6ZLCPUXS.js → chunk-46X2EFQH.js} +15 -4
  43. package/dist/chunk-46X2EFQH.js.map +1 -0
  44. package/dist/{chunk-NY2PYHNC.js → chunk-5UY3PNFY.js} +12 -5
  45. package/dist/chunk-5UY3PNFY.js.map +1 -0
  46. package/dist/{chunk-FQSQONOU.js → chunk-65OM4XLQ.js} +49 -3
  47. package/dist/chunk-65OM4XLQ.js.map +1 -0
  48. package/dist/{chunk-3PSLNJDU.js → chunk-6DQYBIHW.js} +314 -49
  49. package/dist/chunk-6DQYBIHW.js.map +1 -0
  50. package/dist/{chunk-LDCSZ72P.js → chunk-6YBER5UP.js} +3 -3
  51. package/dist/{chunk-LDCSZ72P.js.map → chunk-6YBER5UP.js.map} +1 -1
  52. package/dist/{chunk-3O3NKZJW.js → chunk-7T7WLEPM.js} +24 -3
  53. package/dist/chunk-7T7WLEPM.js.map +1 -0
  54. package/dist/{chunk-PKPO3JTZ.js → chunk-AQAKDE7F.js} +29 -11
  55. package/dist/chunk-AQAKDE7F.js.map +1 -0
  56. package/dist/{chunk-6MRSX3YK.js → chunk-B5Y5GPD5.js} +2 -2
  57. package/dist/{chunk-BXGZFGZ4.js → chunk-C5QD5DQX.js} +22 -1
  58. package/dist/chunk-C5QD5DQX.js.map +1 -0
  59. package/dist/{chunk-4XCHZRUJ.js → chunk-D5YGR4TP.js} +58 -7
  60. package/dist/chunk-D5YGR4TP.js.map +1 -0
  61. package/dist/{chunk-NPRP3MCV.js → chunk-DHDCOOJU.js} +2 -2
  62. package/dist/chunk-DHDCOOJU.js.map +1 -0
  63. package/dist/{chunk-VP3TIUDF.js → chunk-DVTDF5OI.js} +2 -2
  64. package/dist/{chunk-OXD5LFQP.js → chunk-G7H6PN7P.js} +2 -2
  65. package/dist/{chunk-EL5VHUGK.js → chunk-GGKHHG5Y.js} +32 -18
  66. package/dist/chunk-GGKHHG5Y.js.map +1 -0
  67. package/dist/{chunk-446I4EGD.js → chunk-J5TBZFBD.js} +2 -2
  68. package/dist/{chunk-7AVQIGF6.js → chunk-K4ZYJ4EM.js} +554 -460
  69. package/dist/chunk-K4ZYJ4EM.js.map +1 -0
  70. package/dist/{chunk-QFE5BQH7.js → chunk-LTSI7ULC.js} +2 -2
  71. package/dist/{chunk-5GVURVIG.js → chunk-MMHGYX44.js} +12 -2
  72. package/dist/{chunk-5GVURVIG.js.map → chunk-MMHGYX44.js.map} +1 -1
  73. package/dist/{chunk-KRFGO5QH.js → chunk-MQMTRKY3.js} +118 -43
  74. package/dist/chunk-MQMTRKY3.js.map +1 -0
  75. package/dist/{chunk-42FQ27MQ.js → chunk-MTODGQBR.js} +44 -179
  76. package/dist/chunk-MTODGQBR.js.map +1 -0
  77. package/dist/{chunk-FVINAAKA.js → chunk-NBK6QQMG.js} +14 -13
  78. package/dist/{chunk-FVINAAKA.js.map → chunk-NBK6QQMG.js.map} +1 -1
  79. package/dist/{chunk-KNU73RZW.js → chunk-NSA5K5G2.js} +2 -2
  80. package/dist/{chunk-MLTPJMH6.js → chunk-QQYULEZL.js} +2 -2
  81. package/dist/chunk-QSW4DFKE.js +31 -0
  82. package/dist/chunk-QSW4DFKE.js.map +1 -0
  83. package/dist/{chunk-VAZXUK6G.js → chunk-SUNCHMML.js} +2 -2
  84. package/dist/{chunk-EP4WVQLX.js → chunk-T2U6N3FV.js} +6 -6
  85. package/dist/{chunk-T7SP3EYR.js → chunk-T5URUIIY.js} +33 -24
  86. package/dist/chunk-T5URUIIY.js.map +1 -0
  87. package/dist/{chunk-VNXAF2KE.js → chunk-TPTZZV25.js} +6 -6
  88. package/dist/chunk-TPTZZV25.js.map +1 -0
  89. package/dist/{chunk-IOJDYUA7.js → chunk-V46JWFGV.js} +6 -5
  90. package/dist/chunk-V46JWFGV.js.map +1 -0
  91. package/dist/{chunk-WGDEBIP4.js → chunk-X6ESZDR6.js} +5 -6
  92. package/dist/chunk-X6ESZDR6.js.map +1 -0
  93. package/dist/{chunk-N65E26UL.js → chunk-XEWV254I.js} +2 -2
  94. package/dist/{chunk-N65E26UL.js.map → chunk-XEWV254I.js.map} +1 -1
  95. package/dist/{chunk-PTWADEH3.js → chunk-YBJVKMTM.js} +34 -14
  96. package/dist/chunk-YBJVKMTM.js.map +1 -0
  97. package/dist/{chunk-DDTS7F5O.js → chunk-ZW32BPXV.js} +12 -3
  98. package/dist/chunk-ZW32BPXV.js.map +1 -0
  99. package/dist/compat/index.cjs +51 -4
  100. package/dist/compat/index.cjs.map +1 -1
  101. package/dist/compat/index.d.cts +1 -1
  102. package/dist/compat/index.d.ts +1 -1
  103. package/dist/compat/index.js +6 -6
  104. package/dist/compat/nestjs/index.cjs +51 -4
  105. package/dist/compat/nestjs/index.cjs.map +1 -1
  106. package/dist/compat/nestjs/index.d.cts +1 -1
  107. package/dist/compat/nestjs/index.d.ts +1 -1
  108. package/dist/compat/nestjs/index.js +3 -3
  109. package/dist/{fallback-Bx46zqky.d.cts → fallback-BROR6ZhO.d.cts} +1 -1
  110. package/dist/{fallback-pIWW8A2d.d.ts → fallback-DO80aM_3.d.ts} +1 -1
  111. package/dist/{index-B_p8tnvf.d.cts → index-D1z3XcF9.d.cts} +1 -0
  112. package/dist/{index-_HDSmPyp.d.ts → index-DZ6yua0Q.d.ts} +1 -0
  113. package/dist/index.cjs +2215 -1676
  114. package/dist/index.cjs.map +1 -1
  115. package/dist/index.d.cts +10 -10
  116. package/dist/index.d.ts +10 -10
  117. package/dist/index.js +169 -146
  118. package/dist/index.js.map +1 -1
  119. package/dist/presets/ai/index.cjs +46 -0
  120. package/dist/presets/ai/index.cjs.map +1 -1
  121. package/dist/presets/ai/index.js +12 -12
  122. package/dist/presets/harness/index.cjs +130 -18
  123. package/dist/presets/harness/index.cjs.map +1 -1
  124. package/dist/presets/harness/index.d.cts +15 -5
  125. package/dist/presets/harness/index.d.ts +15 -5
  126. package/dist/presets/harness/index.js +22 -22
  127. package/dist/presets/index.cjs +222 -53
  128. package/dist/presets/index.cjs.map +1 -1
  129. package/dist/presets/index.d.cts +2 -2
  130. package/dist/presets/index.d.ts +2 -2
  131. package/dist/presets/index.js +45 -45
  132. package/dist/presets/inspect/index.cjs +63 -14
  133. package/dist/presets/inspect/index.cjs.map +1 -1
  134. package/dist/presets/inspect/index.d.cts +1 -1
  135. package/dist/presets/inspect/index.d.ts +1 -1
  136. package/dist/presets/inspect/index.js +6 -6
  137. package/dist/presets/resilience/index.cjs +29 -21
  138. package/dist/presets/resilience/index.cjs.map +1 -1
  139. package/dist/presets/resilience/index.d.cts +12 -8
  140. package/dist/presets/resilience/index.d.ts +12 -8
  141. package/dist/presets/resilience/index.js +3 -3
  142. package/dist/{rate-limiter-DpVbSYdH.d.cts → rate-limiter-DC26FM8J.d.cts} +10 -1
  143. package/dist/{rate-limiter-CEALq4N1.d.ts → rate-limiter-DyWpwpQP.d.ts} +10 -1
  144. package/dist/{reactive-layout-fswlBUvX.d.ts → reactive-layout-BBBWH0V_.d.cts} +85 -4
  145. package/dist/{reactive-layout-fswlBUvX.d.cts → reactive-layout-BBBWH0V_.d.ts} +85 -4
  146. package/dist/solutions/index.cjs +168 -47
  147. package/dist/solutions/index.cjs.map +1 -1
  148. package/dist/solutions/index.d.cts +2 -2
  149. package/dist/solutions/index.d.ts +2 -2
  150. package/dist/solutions/index.js +28 -28
  151. package/dist/{spawnable-5mDY501F.d.cts → spawnable-B2IlW60f.d.cts} +23 -2
  152. package/dist/{spawnable-D3lR0oQu.d.ts → spawnable-tttFz2Nh.d.ts} +23 -2
  153. package/dist/testing/index.cjs +94 -0
  154. package/dist/testing/index.cjs.map +1 -0
  155. package/dist/testing/index.d.cts +59 -0
  156. package/dist/testing/index.d.ts +59 -0
  157. package/dist/testing/index.js +73 -0
  158. package/dist/testing/index.js.map +1 -0
  159. package/dist/utils/ai/browser.cjs.map +1 -1
  160. package/dist/utils/ai/browser.d.cts +2 -2
  161. package/dist/utils/ai/browser.d.ts +2 -2
  162. package/dist/utils/ai/browser.js +6 -6
  163. package/dist/utils/ai/browser.js.map +1 -1
  164. package/dist/utils/ai/index.cjs +250 -166
  165. package/dist/utils/ai/index.cjs.map +1 -1
  166. package/dist/utils/ai/index.d.cts +108 -12
  167. package/dist/utils/ai/index.d.ts +108 -12
  168. package/dist/utils/ai/index.js +21 -19
  169. package/dist/utils/ai/node.cjs.map +1 -1
  170. package/dist/utils/ai/node.d.cts +5 -5
  171. package/dist/utils/ai/node.d.ts +5 -5
  172. package/dist/utils/ai/node.js +2 -2
  173. package/dist/utils/ai/node.js.map +1 -1
  174. package/dist/utils/cqrs/index.cjs +29 -3
  175. package/dist/utils/cqrs/index.cjs.map +1 -1
  176. package/dist/utils/cqrs/index.d.cts +12 -7
  177. package/dist/utils/cqrs/index.d.ts +12 -7
  178. package/dist/utils/cqrs/index.js +2 -2
  179. package/dist/utils/demo-shell/index.cjs +45 -19
  180. package/dist/utils/demo-shell/index.cjs.map +1 -1
  181. package/dist/utils/demo-shell/index.d.cts +1 -1
  182. package/dist/utils/demo-shell/index.d.ts +1 -1
  183. package/dist/utils/demo-shell/index.js +2 -2
  184. package/dist/utils/domain-templates/index.cjs.map +1 -1
  185. package/dist/utils/domain-templates/index.js +3 -3
  186. package/dist/utils/graphspec/index.cjs.map +1 -1
  187. package/dist/utils/graphspec/index.js +3 -3
  188. package/dist/utils/index.cjs +1642 -1225
  189. package/dist/utils/index.cjs.map +1 -1
  190. package/dist/utils/index.d.cts +7 -7
  191. package/dist/utils/index.d.ts +7 -7
  192. package/dist/utils/index.js +72 -54
  193. package/dist/utils/inspect/index.cjs +52 -4
  194. package/dist/utils/inspect/index.cjs.map +1 -1
  195. package/dist/utils/inspect/index.d.cts +32 -3
  196. package/dist/utils/inspect/index.d.ts +32 -3
  197. package/dist/utils/inspect/index.js +4 -4
  198. package/dist/utils/job-queue/index.cjs +46 -9
  199. package/dist/utils/job-queue/index.cjs.map +1 -1
  200. package/dist/utils/job-queue/index.d.cts +33 -3
  201. package/dist/utils/job-queue/index.d.ts +33 -3
  202. package/dist/utils/job-queue/index.js +2 -2
  203. package/dist/utils/memory/index.cjs +556 -462
  204. package/dist/utils/memory/index.cjs.map +1 -1
  205. package/dist/utils/memory/index.d.cts +203 -24
  206. package/dist/utils/memory/index.d.ts +203 -24
  207. package/dist/utils/memory/index.js +10 -2
  208. package/dist/utils/messaging/index.cjs.map +1 -1
  209. package/dist/utils/messaging/index.d.cts +4 -3
  210. package/dist/utils/messaging/index.d.ts +4 -3
  211. package/dist/utils/messaging/index.js +2 -2
  212. package/dist/utils/orchestration/index.cjs +9 -0
  213. package/dist/utils/orchestration/index.cjs.map +1 -1
  214. package/dist/utils/orchestration/index.js +3 -3
  215. package/dist/utils/process/index.cjs +32 -2
  216. package/dist/utils/process/index.cjs.map +1 -1
  217. package/dist/utils/process/index.d.cts +4 -3
  218. package/dist/utils/process/index.d.ts +4 -3
  219. package/dist/utils/process/index.js +2 -2
  220. package/dist/utils/reactive-layout/index.cjs +184 -55
  221. package/dist/utils/reactive-layout/index.cjs.map +1 -1
  222. package/dist/utils/reactive-layout/index.d.cts +128 -3
  223. package/dist/utils/reactive-layout/index.d.ts +128 -3
  224. package/dist/utils/reactive-layout/index.js +16 -8
  225. package/dist/utils/reduction/index.cjs.map +1 -1
  226. package/dist/utils/reduction/index.js +2 -2
  227. package/dist/utils/resilience/index.cjs +29 -20
  228. package/dist/utils/resilience/index.cjs.map +1 -1
  229. package/dist/utils/resilience/index.d.cts +1 -1
  230. package/dist/utils/resilience/index.d.ts +1 -1
  231. package/dist/utils/resilience/index.js +2 -2
  232. package/dist/utils/surface/index.cjs.map +1 -1
  233. package/dist/utils/surface/index.js +4 -4
  234. package/package.json +15 -3
  235. package/dist/chunk-3O3NKZJW.js.map +0 -1
  236. package/dist/chunk-3PSLNJDU.js.map +0 -1
  237. package/dist/chunk-42FQ27MQ.js.map +0 -1
  238. package/dist/chunk-4XCHZRUJ.js.map +0 -1
  239. package/dist/chunk-6ZLCPUXS.js.map +0 -1
  240. package/dist/chunk-7AVQIGF6.js.map +0 -1
  241. package/dist/chunk-BXGZFGZ4.js.map +0 -1
  242. package/dist/chunk-DDTS7F5O.js.map +0 -1
  243. package/dist/chunk-EL5VHUGK.js.map +0 -1
  244. package/dist/chunk-FQSQONOU.js.map +0 -1
  245. package/dist/chunk-IOJDYUA7.js.map +0 -1
  246. package/dist/chunk-KRFGO5QH.js.map +0 -1
  247. package/dist/chunk-MS3WPRJR.js.map +0 -1
  248. package/dist/chunk-NPRP3MCV.js.map +0 -1
  249. package/dist/chunk-NY2PYHNC.js.map +0 -1
  250. package/dist/chunk-PKPO3JTZ.js.map +0 -1
  251. package/dist/chunk-PTWADEH3.js.map +0 -1
  252. package/dist/chunk-T7SP3EYR.js.map +0 -1
  253. package/dist/chunk-VNXAF2KE.js.map +0 -1
  254. package/dist/chunk-W2BOPXTI.js +0 -1
  255. package/dist/chunk-W2BOPXTI.js.map +0 -1
  256. package/dist/chunk-WGDEBIP4.js.map +0 -1
  257. /package/dist/{chunk-R6ZCSXKX.js.map → chunk-23MAWVOJ.js.map} +0 -0
  258. /package/dist/{chunk-6MRSX3YK.js.map → chunk-B5Y5GPD5.js.map} +0 -0
  259. /package/dist/{chunk-VP3TIUDF.js.map → chunk-DVTDF5OI.js.map} +0 -0
  260. /package/dist/{chunk-OXD5LFQP.js.map → chunk-G7H6PN7P.js.map} +0 -0
  261. /package/dist/{chunk-446I4EGD.js.map → chunk-J5TBZFBD.js.map} +0 -0
  262. /package/dist/{chunk-QFE5BQH7.js.map → chunk-LTSI7ULC.js.map} +0 -0
  263. /package/dist/{chunk-KNU73RZW.js.map → chunk-NSA5K5G2.js.map} +0 -0
  264. /package/dist/{chunk-MLTPJMH6.js.map → chunk-QQYULEZL.js.map} +0 -0
  265. /package/dist/{chunk-VAZXUK6G.js.map → chunk-SUNCHMML.js.map} +0 -0
  266. /package/dist/{chunk-EP4WVQLX.js.map → chunk-T2U6N3FV.js.map} +0 -0
@@ -1 +1 @@
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/base/sources/event/cron.ts","../../../src/compat/nestjs/gateway.ts","../../../src/base/composition/backpressure.ts","../../../src/compat/nestjs/guard.ts","../../../src/compat/nestjs/module.ts","../../../src/utils/cqrs/index.ts","../../../src/base/mutation/index.ts","../../../src/utils/_errors/index.ts","../../../src/base/meta/domain-meta.ts","../../../src/compat/nestjs/observable.ts","../../../src/base/composition/observable.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// 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// RxJS bridge — NestJS-flavored: returns a real rxjs `Observable` (the base\n// `toObservable` is dependency-free and returns a Symbol.observable interop;\n// this layer wraps it with rxjs `from()` since `@nestjs/common` pulls rxjs).\nexport { type ToObservableOptions, toObservable } from \"./observable.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, lockId]])`.\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 { DATA, type Messages } from \"@graphrefly/pure-ts/core\";\nimport { fromTimer } from \"@graphrefly/pure-ts/extra\";\nimport type { Graph, GraphObserveOne } from \"@graphrefly/pure-ts/graph\";\nimport type { OnModuleDestroy, OnModuleInit } from \"@nestjs/common\";\nimport type { ModuleRef } from \"@nestjs/core\";\nimport { fromCron } from \"../../base/sources/event/cron.js\";\nimport type { CqrsGraph } from \"../../utils/cqrs/index.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(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(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.cache 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 * Cron-based reactive sources and schedule types.\n *\n * Merged from extra/cron.ts + extra/sources/event.ts (fromCron) during cleave A2.\n * `fromCron` relocated here from `dom.ts` (post-cleave /qa A1): it uses zero DOM\n * APIs (only `setInterval` + `new Date()`), so it belongs on the universal\n * `event/index.ts` barrel, not the browser-only `dom.ts` subpath.\n */\n\nimport { type Node, type NodeOptions, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\n\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nfunction sourceOpts<T = unknown>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\n\n/** Options for {@link fromCron}. */\nexport type FromCronOptions = ExtraOpts & {\n\t/** Polling interval in ms. Default `60_000`. */\n\ttickMs?: number;\n\t/** Output format: `\"timestamp_ns\"` (default) emits wall-clock nanoseconds; `\"date\"` emits a `Date` object. */\n\toutput?: \"timestamp_ns\" | \"date\";\n};\n\n/**\n * Minimal 5-field cron parser and matcher (minute hour day-of-month month day-of-week).\n * Ported from callbag-recharge `extra/cron.ts` for `fromCron` (roadmap §2.3).\n */\nexport interface CronSchedule {\n\tminutes: Set<number>;\n\thours: Set<number>;\n\tdaysOfMonth: Set<number>;\n\tmonths: Set<number>;\n\tdaysOfWeek: Set<number>;\n}\n\nfunction parseField(field: string, min: number, max: number): Set<number> {\n\tconst result = new Set<number>();\n\tfor (const part of field.split(\",\")) {\n\t\tconst [range, stepStr] = part.split(\"/\");\n\t\tconst step = stepStr ? Number.parseInt(stepStr, 10) : 1;\n\t\tif (Number.isNaN(step) || step < 1) throw new Error(`Invalid cron step: ${part}`);\n\t\tlet start: number;\n\t\tlet end: number;\n\t\tif (range === \"*\") {\n\t\t\tstart = min;\n\t\t\tend = max;\n\t\t} else if (range.includes(\"-\")) {\n\t\t\tconst [a, b] = range.split(\"-\");\n\t\t\tstart = Number.parseInt(a, 10);\n\t\t\tend = Number.parseInt(b, 10);\n\t\t} else {\n\t\t\tstart = Number.parseInt(range, 10);\n\t\t\tend = start;\n\t\t}\n\t\tif (Number.isNaN(start) || Number.isNaN(end)) throw new Error(`Invalid cron field: ${field}`);\n\t\tif (start < min || end > max)\n\t\t\tthrow new Error(`Cron field out of range: ${field} (${min}-${max})`);\n\t\tif (start > end) throw new Error(`Invalid cron range: ${start}-${end} in ${field}`);\n\t\tfor (let i = start; i <= end; i += step) result.add(i);\n\t}\n\treturn result;\n}\n\n/**\n * Parses a standard 5-field cron expression into a {@link CronSchedule}.\n *\n * Supports `*`, ranges (`1-5`), steps (`*\\/5`, `0-30/10`), and comma-separated\n * lists. Fields are: minute (0–59), hour (0–23), day-of-month (1–31),\n * month (1–12), day-of-week (0–6, Sunday = 0).\n *\n * @param expr - Five-field whitespace-separated cron string (e.g. `\"0 9 * * 1-5\"`).\n * @returns Parsed {@link CronSchedule} with one `Set<number>` per field.\n * @throws Error when the expression does not have exactly 5 fields, contains\n * out-of-range values, or uses an invalid step.\n *\n * @example\n * ```ts\n * import { parseCron } from \"@graphrefly/graphrefly-ts\";\n *\n * const sched = parseCron(\"0 9 * * 1-5\"); // weekdays at 09:00\n * sched.hours; // Set { 9 }\n * sched.daysOfWeek; // Set { 1, 2, 3, 4, 5 }\n * ```\n */\nexport function parseCron(expr: string): CronSchedule {\n\tconst parts = expr.trim().split(/\\s+/);\n\tif (parts.length !== 5) throw new Error(`Invalid cron: expected 5 fields, got ${parts.length}`);\n\treturn {\n\t\tminutes: parseField(parts[0], 0, 59),\n\t\thours: parseField(parts[1], 0, 23),\n\t\tdaysOfMonth: parseField(parts[2], 1, 31),\n\t\tmonths: parseField(parts[3], 1, 12),\n\t\tdaysOfWeek: parseField(parts[4], 0, 6),\n\t};\n}\n\n/**\n * Returns `true` if `date` satisfies every field of `schedule`.\n *\n * @param schedule - Parsed schedule from {@link parseCron}.\n * @param date - Moment to test (local time via `getMinutes`, `getHours`, etc.).\n * @returns `true` when all five cron fields match the given date.\n *\n * @example\n * ```ts\n * import { parseCron, matchesCron } from \"@graphrefly/graphrefly-ts\";\n *\n * const sched = parseCron(\"30 8 * * 1\"); // Mondays at 08:30\n * const monday = new Date(\"2026-03-30T08:30:00\"); // a Monday\n * matchesCron(sched, monday); // true\n * ```\n */\nexport function matchesCron(schedule: CronSchedule, date: Date): boolean {\n\treturn (\n\t\tschedule.minutes.has(date.getMinutes()) &&\n\t\tschedule.hours.has(date.getHours()) &&\n\t\tschedule.daysOfMonth.has(date.getDate()) &&\n\t\tschedule.months.has(date.getMonth() + 1) &&\n\t\tschedule.daysOfWeek.has(date.getDay())\n\t);\n}\n\n/**\n * Polls on an interval; when the current minute matches a 5-field cron expression, emits once (see {@link parseCron}).\n *\n * @param expr - Cron string (`min hour dom month dow`).\n * @param opts - Producer options plus `tickMs` (default `60_000`) and `output` (`timestamp_ns` default, or `date` for `Date` values).\n * @returns `Node<number>` (nanosecond timestamp) or `Node<Date>` when `output: \"date\"`.\n *\n * @example\n * ```ts\n * import { fromCron } from \"@graphrefly/graphrefly\";\n *\n * fromCron(\"0 9 * * 1\");\n * ```\n *\n * @category extra\n */\nexport function fromCron(expr: string, opts?: FromCronOptions & { output: \"date\" }): Node<Date>;\nexport function fromCron(expr: string, opts?: FromCronOptions): Node<number>;\nexport function fromCron(expr: string, opts?: FromCronOptions): Node<number | Date> {\n\tconst schedule: CronSchedule = parseCron(expr);\n\tconst { tickMs: tickOpt, output, ...rest } = opts ?? {};\n\tconst tickMs = tickOpt ?? 60_000;\n\tconst emitDate = output === \"date\";\n\treturn node<number | Date>(\n\t\t(_data, a) => {\n\t\t\tlet lastFiredKey = -1;\n\t\t\tconst check = () => {\n\t\t\t\tconst now = new Date();\n\t\t\t\tconst key =\n\t\t\t\t\tnow.getFullYear() * 100_000_000 +\n\t\t\t\t\t(now.getMonth() + 1) * 1_000_000 +\n\t\t\t\t\tnow.getDate() * 10_000 +\n\t\t\t\t\tnow.getHours() * 100 +\n\t\t\t\t\tnow.getMinutes();\n\t\t\t\tif (key !== lastFiredKey && matchesCron(schedule, now)) {\n\t\t\t\t\tlastFiredKey = key;\n\t\t\t\t\ta.emit(emitDate ? now : wallClockNs());\n\t\t\t\t}\n\t\t\t};\n\t\t\tcheck();\n\t\t\tconst id = setInterval(check, tickMs);\n\t\t\treturn { onDeactivation: () => clearInterval(id) };\n\t\t},\n\t\t{ ...sourceOpts(rest), name: rest.name ?? `cron:${expr}` },\n\t);\n}\n","// ---------------------------------------------------------------------------\n// 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 {\n\ttype Actor,\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Messages,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport type { Graph, GraphObserveOne } from \"@graphrefly/pure-ts/graph\";\nimport {\n\tcreateWatermarkController,\n\ttype WatermarkController,\n} from \"../../base/composition/backpressure.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 * Watermark-based backpressure controller — reactive PAUSE/RESUME flow control.\n *\n * Purely synchronous, event-driven. No timers, no polling, no Promises.\n * Each controller instance uses a unique lockId so multiple controllers\n * on the same upstream node do not collide.\n *\n * @module\n */\n\nimport { type Messages, PAUSE, RESUME } from \"@graphrefly/pure-ts/core\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type WatermarkOptions = {\n\t/** Pending count at which PAUSE is sent upstream. */\n\thighWaterMark: number;\n\t/** Pending count at which RESUME is sent upstream (after being paused). */\n\tlowWaterMark: number;\n};\n\nexport type WatermarkController = {\n\t/** Call when a DATA message is buffered/enqueued. Returns `true` if PAUSE was just sent. */\n\tonEnqueue(): boolean;\n\t/** Call when a buffered item is consumed. Returns `true` if RESUME was just sent. */\n\tonDequeue(): boolean;\n\t/** Current un-consumed item count. */\n\treadonly pending: number;\n\t/** Whether upstream is currently paused by this controller. */\n\treadonly paused: boolean;\n\t/** Dispose: if paused, sends RESUME to unblock upstream. */\n\tdispose(): void;\n};\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nlet nextLockId = 0;\n\n/**\n * Creates a watermark-based backpressure controller.\n *\n * @param sendUp - Callback that delivers messages upstream (typically `handle.up`).\n * @param opts - High/low watermark thresholds (item counts).\n * @returns A {@link WatermarkController}.\n *\n * @example\n * ```ts\n * const handle = graph.observe(\"fast-source\");\n * const wm = createWatermarkController(\n * (msgs) => handle.up(msgs),\n * { highWaterMark: 64, lowWaterMark: 16 },\n * );\n *\n * // In sink callback:\n * handle.subscribe((msgs) => {\n * for (const msg of msgs) {\n * if (msg[0] === DATA) {\n * buffer.push(msg[1]);\n * wm.onEnqueue();\n * }\n * }\n * });\n *\n * // When consumer drains:\n * const item = buffer.shift();\n * wm.onDequeue();\n * ```\n *\n * @category extra\n */\nexport function createWatermarkController(\n\tsendUp: (messages: Messages) => void,\n\topts: WatermarkOptions,\n): WatermarkController {\n\tif (opts.highWaterMark < 1) throw new RangeError(\"highWaterMark must be >= 1\");\n\tif (opts.lowWaterMark < 0) throw new RangeError(\"lowWaterMark must be >= 0\");\n\tif (opts.lowWaterMark >= opts.highWaterMark)\n\t\tthrow new RangeError(\"lowWaterMark must be < highWaterMark\");\n\tconst lockId = Symbol(`bp-${++nextLockId}`);\n\tlet pending = 0;\n\tlet paused = false;\n\n\treturn {\n\t\tonEnqueue(): boolean {\n\t\t\tpending += 1;\n\t\t\tif (!paused && pending >= opts.highWaterMark) {\n\t\t\t\tpaused = true;\n\t\t\t\tsendUp([[PAUSE, lockId]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tonDequeue(): boolean {\n\t\t\tif (pending > 0) pending -= 1;\n\t\t\tif (paused && pending <= opts.lowWaterMark) {\n\t\t\t\tpaused = false;\n\t\t\t\tsendUp([[RESUME, lockId]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tget pending() {\n\t\t\treturn pending;\n\t\t},\n\t\tget paused() {\n\t\t\treturn paused;\n\t\t},\n\t\tdispose() {\n\t\t\tif (paused) {\n\t\t\t\tpaused = false;\n\t\t\t\tsendUp([[RESUME, lockId]]);\n\t\t\t}\n\t\t},\n\t};\n}\n","// ---------------------------------------------------------------------------\n// 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 Actor, DEFAULT_ACTOR, normalizeActor } from \"@graphrefly/pure-ts/core\";\nimport type { CanActivate, ExecutionContext } from \"@nestjs/common\";\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 type { AppendLogStorageTier } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphPersistSnapshot } from \"@graphrefly/pure-ts/graph\";\nimport {\n\ttype DynamicModule,\n\tModule,\n\ttype OnModuleDestroy,\n\ttype Provider,\n\tScope,\n} from \"@nestjs/common\";\nimport { ModuleRef } from \"@nestjs/core\";\nimport { type CqrsGraph, type CqrsOptions, cqrs } from \"../../utils/cqrs/index.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/** Append-log storage tiers for event persistence (wired via `attachEventStorage()`). */\n\teventStorage?: readonly AppendLogStorageTier<import(\"../../utils/cqrs/index.js\").CqrsEvent>[];\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({ name: \"orderCount\", events: [\"orderPlaced\"], reducer: (_s, evts) => evts.length, initial: 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\tif (opts.eventStorage) g.attachEventStorage(opts.eventStorage);\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 {\n\tDATA,\n\ttype Node,\n\tnode,\n\tplaceholderArgs,\n\tpolicy,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport type { AppendLogStorageTier } from \"@graphrefly/pure-ts/extra\";\nimport { type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport {\n\ttype BaseAuditRecord,\n\tcreateAuditLog,\n\tmutate,\n\tregisterCursor,\n\tregisterCursorMap,\n} from \"../../base/mutation/index.js\";\nimport {\n\tCommandHandlerError,\n\tDuplicateRegistrationError,\n\tOptimisticConcurrencyError,\n\tRebuildError,\n\tUndeclaredEmitError,\n\tUnknownCommandError,\n} from \"../_errors/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\nimport { keepalive } from \"@graphrefly/pure-ts/extra\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\n\nfunction cqrsMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"cqrs\", kind, extra);\n}\n\nfunction deepFreeze<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tfor (const k of Object.keys(value as Record<string, unknown>)) {\n\t\tdeepFreeze((value as Record<string, unknown>)[k]);\n\t}\n\treturn Object.freeze(value);\n}\n\n// ---------------------------------------------------------------------------\n// Event envelope\n// ---------------------------------------------------------------------------\n\n/**\n * Immutable envelope for events emitted by command handlers.\n *\n * **Wave C.1 Unit 17 (locked 2026-04-24):** Extended ES standard fields —\n * `aggregateId` / `aggregateVersion` for per-aggregate streams; correlation /\n * causation IDs for distributed tracing; `metadata` for free-form context.\n * Optional `handlerVersion` (Audit 5) traces which handler version produced\n * the event.\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/** Aggregate identifier (per-aggregate streams). */\n\taggregateId?: string;\n\t/** Per-aggregate monotonic version (set when `aggregateId` is provided). */\n\taggregateVersion?: number;\n\t/** Distributed-trace correlation id. */\n\tcorrelationId?: string;\n\t/** Causation chain id (this event was caused by event `causationId`). */\n\tcausationId?: string;\n\t/** Free-form metadata frozen at append. */\n\tmetadata?: Readonly<Record<string, unknown>>;\n\t/** V0 identity of the event log node at append time (§6.0b). */\n\tv0?: { id: string; version: number };\n\t/** Handler version stamped on emit (Audit 5). */\n\thandlerVersion?: { id: string; version: string | number };\n};\n\n/** Compile-time event-map registry: `{ \"orderPlaced\": OrderPayload, ... }`. */\nexport type CqrsEventMap = Record<string, unknown>;\n\n/** Recommended `keyOf` for CQRS event-store storage tiers (Audit 4). */\nexport const cqrsEventKeyOf = (e: CqrsEvent): string =>\n\t`${e.type}::${e.aggregateId ?? \"__default__\"}`;\n\n// ── Audit records (Audit 2 cross-cutting) ────────────────────────────────\n\nexport interface DispatchRecord<T = unknown> extends BaseAuditRecord {\n\treadonly commandName: string;\n\treadonly payload: T;\n\t/** Action result. Tier 1.6.2 canonical enum (renamed from `status`). */\n\treadonly outcome: \"success\" | \"failure\";\n\treadonly error?: unknown;\n\treadonly errorType?: string;\n\t/**\n\t * Event names emitted by the handler.\n\t * - `outcome: \"success\"`: events that persisted in the event log.\n\t * - `outcome: \"failure\"`: events the handler ATTEMPTED to emit before throwing;\n\t * they were rolled back and did NOT persist. Documents the failed attempt's\n\t * intentions for debugging handler logic. The actual event log shows only\n\t * what's durable.\n\t */\n\treadonly emittedEvents?: readonly string[];\n}\n\nexport const dispatchKeyOf = <T>(r: DispatchRecord<T>): string => r.commandName;\n\nexport interface SagaInvocation<T = unknown> extends BaseAuditRecord {\n\treadonly eventType: string;\n\t/** Action result. Tier 1.6.2 canonical enum (renamed from `status`). */\n\treadonly outcome: \"success\" | \"failure\";\n\treadonly error?: unknown;\n\treadonly errorType?: string;\n\treadonly aggregateId?: string;\n\treadonly event?: CqrsEvent<T>;\n}\n\nexport const sagaInvocationKeyOf = <T>(i: SagaInvocation<T>): string => i.eventType;\n\n/**\n * Saga registration result (M10) — a typed bundle replacing the prior\n * `Node<unknown>` return that side-attached `_saga` via an unsafe cast.\n *\n * `node` is the saga's effect node (subscribe to observe processing\n * activity). `invocations` is the per-event-type audit log; `audit` aliases\n * `invocations` (Audit 2 `.audit` duplication). `cursors` exposes the\n * per-event-type cursor state nodes for monitoring / testing.\n *\n * @category patterns\n */\nexport interface SagaController<T = unknown> {\n\treadonly node: Node<unknown>;\n\treadonly invocations: ReactiveLogBundle<SagaInvocation<T>>;\n\treadonly audit: ReactiveLogBundle<SagaInvocation<T>>;\n\treadonly cursors: { readonly [eventName: string]: Node<number> };\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.\n *\n * - In **`\"replay\"`** mode the `state` parameter is always the original\n * `initial` value (full event-sourcing replay on every recompute).\n * - In **`\"scan\"`** mode the `state` parameter is the _previous_ output\n * (incremental fold); `events` contains only the events appended since\n * the last computation.\n */\nexport type ProjectionReducer<TState = unknown, TEvent = unknown> = (\n\tstate: TState,\n\tevents: readonly CqrsEvent<TEvent>[],\n) => TState;\n\n/**\n * Snapshot integration for {@link ProjectionOptions}.\n *\n * `load` is called once at projection construction and the returned value\n * seeds the initial state. `save` (optional) is called after each reducer\n * run, debounced by `saveDebounceMs` (default 1000 ms) and capped by\n * `saveEvery` (default 1000 events).\n */\nexport type ProjectionSnapshotOpts<TState> = {\n\t/** Load a previously-saved state. `undefined` → start from `initial`. */\n\tload: () => TState | undefined | Promise<TState | undefined>;\n\t/** Persist the current state. Called after reducer; may be async. */\n\tsave?: (state: TState) => void | Promise<void>;\n\t/**\n\t * Debounce window (ms) before `save` fires after the last event. Default 1000.\n\t */\n\tsaveDebounceMs?: number;\n\t/**\n\t * Force a save after every Nth state change regardless of debounce.\n\t * Default 1000. Both knobs compose: save fires at whichever condition is\n\t * met first.\n\t */\n\tsaveEvery?: number;\n};\n\n/**\n * Options for {@link CqrsGraph.projection}.\n *\n * **Wave C.3 Unit 21 (locked 2026-04-24):**\n * - `mode: \"scan\"` (default) — incremental fold; `\"replay\"` — full replay\n * each wave.\n * - `snapshot` — load/save integration for cold-start + auto-checkpoint.\n * - `freezeInputs` (default `true`) — freeze event arrays before passing\n * to reducer (purity enforcement).\n * - `rebuild()` / `reset()` on the returned {@link ProjectionController}.\n *\n * @category patterns\n */\nexport type ProjectionOptions<TState> = {\n\tname: string;\n\tevents: readonly string[];\n\treducer: ProjectionReducer<TState>;\n\tinitial: TState;\n\t/**\n\t * Fold strategy. Default `\"scan\"` (incremental). `\"replay\"` = full replay.\n\t *\n\t * **Scan-mode ordering caveat:** scan-mode assumes monotonic per-stream\n\t * arrival order. When multiple event streams are merged for a projection,\n\t * events arriving with a `timestampNs` earlier than the current sort cursor\n\t * are skipped from the incremental sweep. This is an acceptable trade-off\n\t * for incremental fold; use `mode: \"replay\"` for strict cross-stream\n\t * ordering.\n\t */\n\tmode?: \"replay\" | \"scan\";\n\t/** Snapshot integration for rebuild + auto-checkpoint. */\n\tsnapshot?: ProjectionSnapshotOpts<TState>;\n\t/**\n\t * Freeze event arrays before passing to reducer (default `true`).\n\t * Set to `false` only if your reducer intentionally mutates the input\n\t * (strongly discouraged — prefer immutable reducers).\n\t */\n\tfreezeInputs?: boolean;\n};\n\n/**\n * Controller returned by {@link CqrsGraph.projection}.\n *\n * `node` is the reactive read model. `rebuild()` performs a paginated\n * cold-storage replay (requires `attachEventStorage` tiers). `reset()`\n * reloads from `snapshot.load()` and re-folds the live event log on top.\n *\n * @category patterns\n */\nexport interface ProjectionController<TState> {\n\treadonly node: Node<TState>;\n\t/**\n\t * Async paginated rebuild from attached storage tiers. Throws\n\t * {@link RebuildError} on adapter / decode / reducer failure.\n\t *\n\t * @param opts.fromTier - Storage tier to read from (default: first attached).\n\t * @param opts.pageSize - Entries per page (default 1000).\n\t */\n\trebuild(opts?: {\n\t\tfromTier?: AppendLogStorageTier<CqrsEvent>;\n\t\tpageSize?: number;\n\t}): Promise<TState>;\n\t/**\n\t * Reload from `snapshot.load()` (if configured) and re-fold the live\n\t * in-memory event log on top. Returns the rebuilt state. No-op on the\n\t * reactive node if the state is unchanged.\n\t */\n\treset(): Promise<TState>;\n}\n\nexport type SagaHandler<T = unknown> = (event: CqrsEvent<T>) => void;\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport type CqrsOptions = {\n\tgraph?: GraphOptions;\n\t/** Bounded retention for event streams; default 1024 (cross-cutting). */\n\tretainedLimit?: number;\n\t/** Freeze command payloads on dispatch (default `true`). */\n\tfreezeCommandPayload?: boolean;\n\t/** Freeze event payloads on emit (default `true`). */\n\tfreezeEventPayload?: boolean;\n\t/** LRU eviction threshold for per-aggregate streams (default 10_000). */\n\tmaxAggregates?: number;\n};\n\nexport type CommandRegistration<TPayload = unknown> = {\n\thandler: CommandHandler<TPayload>;\n\temits?: readonly string[];\n\thandlerVersion?: { id: string; version: string | number };\n};\n\nexport type DispatchOptions = {\n\tcorrelationId?: string;\n\tcausationId?: string;\n\tmetadata?: Record<string, unknown>;\n\t/**\n\t * Optimistic-concurrency check: if set, dispatch verifies the aggregate\n\t * (identified by `aggregateId`) is at this version. On mismatch, dispatch\n\t * throws {@link OptimisticConcurrencyError} BEFORE the handler runs.\n\t *\n\t * Requires `aggregateId` to be set. Without it the check is a no-op.\n\t */\n\texpectedAggregateVersion?: number;\n\t/**\n\t * Aggregate this dispatch targets. Events emitted by the handler that\n\t * also carry this `aggregateId` participate in per-aggregate versioning\n\t * and LRU eviction (see {@link CqrsOptions.maxAggregates}). Events whose\n\t * handler-supplied `aggregateId` differs from the dispatch's `aggregateId`\n\t * are emitted untouched (their own `aggregateVersion` is computed from\n\t * their own aggregate's stream).\n\t */\n\taggregateId?: string;\n};\n\nexport type SagaOptions = {\n\taggregateId?: string;\n\terrorPolicy?: \"advance\" | \"hold\";\n\thandlerVersion?: { id: string; version: string | number };\n};\n\n// ---------------------------------------------------------------------------\n// CqrsGraph\n// ---------------------------------------------------------------------------\n\ntype EventEntry = {\n\tlog: ReturnType<typeof reactiveLog<CqrsEvent>>;\n\tnode: Node<readonly CqrsEvent[]>;\n};\n\n/**\n * Eviction record emitted on `aggregateEvictions` when an aggregate's\n * per-aggregate stream is removed under `maxAggregates` LRU pressure. The\n * eviction does NOT delete events from the fan-in stream — only the\n * per-aggregate dedicated stream and its version counter.\n */\nexport interface AggregateEvictionRecord {\n\treadonly aggregateId: string;\n\treadonly type: string;\n\treadonly t_ns: number;\n\t/** The version count the aggregate reached before eviction (for diagnostics). */\n\treadonly lastVersion: number;\n}\n\nexport class CqrsGraph<_EM extends CqrsEventMap = Record<string, unknown>> extends Graph {\n\t/** Fan-in event streams (one per type, all aggregates merged). */\n\tprivate readonly _eventLogs = new Map<string, EventEntry>();\n\t/**\n\t * Per-aggregate event streams: type → aggregateId → entry. Used for\n\t * `event(type, aggregateId)` dual-form access and per-aggregate version\n\t * tracking. Only populated when an event with `aggregateId` is emitted.\n\t */\n\tprivate readonly _eventLogsByAggregate = new Map<string, Map<string, EventEntry>>();\n\t/** Per-aggregate version counters: `${type}::${aggregateId}` → current version. */\n\tprivate readonly _aggregateVersions = new Map<string, number>();\n\t/**\n\t * LRU access order for `${type}::${aggregateId}`. Map insertion order\n\t * tracks recency — `delete` + `set` on access moves to the end.\n\t */\n\tprivate readonly _aggregateLru = new Map<string, true>();\n\tprivate readonly _commandRegs = new Map<\n\t\tstring,\n\t\t{\n\t\t\thandler: CommandHandler<any>;\n\t\t\temits?: readonly string[];\n\t\t\thandlerVersion?: { id: string; version: string | number };\n\t\t}\n\t>();\n\tprivate readonly _projections = new Set<string>();\n\tprivate readonly _sagas = new Set<string>();\n\tprivate _seq = 0;\n\tprivate readonly _retainedLimit: number;\n\tprivate readonly _freezeCommandPayload: boolean;\n\tprivate readonly _freezeEventPayload: boolean;\n\tprivate readonly _maxAggregates: number;\n\tprivate readonly _dispatchSeqCursor: Node<number>;\n\t/** Audit log of every command dispatch (Audit 2). */\n\treadonly dispatches: ReactiveLogBundle<DispatchRecord>;\n\t/** Alias for {@link CqrsGraph.dispatches} (Audit 2 `.audit` duplication). */\n\treadonly audit: ReactiveLogBundle<DispatchRecord>;\n\t/** Per-aggregate LRU eviction observability; secondary log to `dispatches`. */\n\treadonly aggregateEvictions: ReactiveLogBundle<AggregateEvictionRecord>;\n\n\tconstructor(name: string, opts: CqrsOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\tthis._retainedLimit = opts.retainedLimit ?? 1024;\n\t\tthis._freezeCommandPayload = opts.freezeCommandPayload ?? true;\n\t\tthis._freezeEventPayload = opts.freezeEventPayload ?? true;\n\t\tthis._maxAggregates = opts.maxAggregates ?? 10_000;\n\t\tthis.dispatches = createAuditLog<DispatchRecord>({\n\t\t\tname: \"dispatches\",\n\t\t\tretainedLimit: this._retainedLimit,\n\t\t\tgraph: this,\n\t\t});\n\t\tthis.audit = this.dispatches;\n\t\tthis.aggregateEvictions = createAuditLog<AggregateEvictionRecord>({\n\t\t\tname: \"aggregateEvictions\",\n\t\t\tretainedLimit: this._retainedLimit,\n\t\t\tgraph: this,\n\t\t});\n\t\tthis._dispatchSeqCursor = registerCursor(this, \"dispatch_seq\", 0);\n\t}\n\n\t/**\n\t * Read the current per-aggregate version (last emitted `aggregateVersion`\n\t * for that `(type, aggregateId)` pair). Returns `0` if no events have been\n\t * emitted yet for this aggregate. Useful for callers preparing\n\t * {@link DispatchOptions.expectedAggregateVersion}.\n\t */\n\taggregateVersion(type: string, aggregateId: string): number {\n\t\treturn this._aggregateVersions.get(`${type}::${aggregateId}`) ?? 0;\n\t}\n\n\t/** LRU touch — moves the key to the end of the access order. */\n\tprivate _touchAggregate(key: string): void {\n\t\t// Delete + set re-inserts at the end of Map iteration order.\n\t\tthis._aggregateLru.delete(key);\n\t\tthis._aggregateLru.set(key, true);\n\t}\n\n\t/**\n\t * Evict the oldest aggregate streams (least-recently-touched) until the\n\t * aggregate count is back within `_maxAggregates`. Emits one\n\t * `AggregateEvictionRecord` per eviction. The fan-in stream is NOT touched\n\t * — events stay in the type-level log; only the per-aggregate stream and\n\t * version counter are removed.\n\t */\n\tprivate _enforceAggregateLru(): void {\n\t\twhile (this._aggregateLru.size > this._maxAggregates) {\n\t\t\tconst oldest = this._aggregateLru.keys().next();\n\t\t\tif (oldest.done) break;\n\t\t\tconst key = oldest.value;\n\t\t\tthis._aggregateLru.delete(key);\n\t\t\tconst sep = key.indexOf(\"::\");\n\t\t\tif (sep < 0) continue;\n\t\t\tconst type = key.slice(0, sep);\n\t\t\tconst aggregateId = key.slice(sep + 2);\n\t\t\tconst lastVersion = this._aggregateVersions.get(key) ?? 0;\n\t\t\tthis._aggregateVersions.delete(key);\n\t\t\tconst byType = this._eventLogsByAggregate.get(type);\n\t\t\tif (byType) {\n\t\t\t\tbyType.delete(aggregateId);\n\t\t\t\tif (byType.size === 0) this._eventLogsByAggregate.delete(type);\n\t\t\t}\n\t\t\tthis.aggregateEvictions.append({\n\t\t\t\taggregateId,\n\t\t\t\ttype,\n\t\t\t\tlastVersion,\n\t\t\t\tt_ns: wallClockNs(),\n\t\t\t});\n\t\t}\n\t}\n\n\t/** Tiers attached via {@link attachEventStorage}; auto-wired into future event streams. */\n\tprivate readonly _attachedEventTiers: Array<readonly AppendLogStorageTier<CqrsEvent>[]> = [];\n\tprivate readonly _attachedTierDisposers = new Map<string, Array<() => void>>();\n\n\t/**\n\t * Wire append-log storage tiers for ALL CQRS event streams — both currently\n\t * registered AND any future streams created via `event(name)` /\n\t * `event(name, aggregateId)` / handler emit. (M4 fix.)\n\t *\n\t * Returns a disposer that releases all storage subscriptions wired by this\n\t * call (including those for streams that were created after the call).\n\t */\n\tattachEventStorage(tiers: readonly AppendLogStorageTier<CqrsEvent>[]): () => void {\n\t\tthis._attachedEventTiers.push(tiers);\n\t\t// Wire currently-existing streams.\n\t\tfor (const [name, entry] of this._eventLogs) {\n\t\t\tconst dispose = entry.log.attachStorage(tiers);\n\t\t\tlet arr = this._attachedTierDisposers.get(name);\n\t\t\tif (!arr) {\n\t\t\t\tarr = [];\n\t\t\t\tthis._attachedTierDisposers.set(name, arr);\n\t\t\t}\n\t\t\tarr.push(dispose);\n\t\t}\n\t\t// Per-aggregate streams existing now.\n\t\tfor (const [type, byAgg] of this._eventLogsByAggregate) {\n\t\t\tfor (const [aggId, entry] of byAgg) {\n\t\t\t\tconst key = `${type}::${aggId}`;\n\t\t\t\tconst dispose = entry.log.attachStorage(tiers);\n\t\t\t\tlet arr = this._attachedTierDisposers.get(key);\n\t\t\t\tif (!arr) {\n\t\t\t\t\tarr = [];\n\t\t\t\t\tthis._attachedTierDisposers.set(key, arr);\n\t\t\t\t}\n\t\t\t\tarr.push(dispose);\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\t// Remove from auto-wire list so newly-created streams skip.\n\t\t\tconst idx = this._attachedEventTiers.indexOf(tiers);\n\t\t\tif (idx >= 0) this._attachedEventTiers.splice(idx, 1);\n\t\t\t// We can't precisely undo the per-stream attach for THIS tier set\n\t\t\t// alone (Map values commingle disposers across multiple\n\t\t\t// attachEventStorage calls). Caller wanting fine-grained control\n\t\t\t// should call `tier.flush()` / dispose tiers themselves. This\n\t\t\t// disposer is best-effort: it stops auto-wiring future streams.\n\t\t};\n\t}\n\n\t/** Wire newly-created event stream into all currently-attached tier sets. */\n\tprivate _autoWireStreamStorage(\n\t\tkey: string,\n\t\tlog: ReturnType<typeof reactiveLog<CqrsEvent>>,\n\t): void {\n\t\tif (this._attachedEventTiers.length === 0) return;\n\t\tlet arr = this._attachedTierDisposers.get(key);\n\t\tif (!arr) {\n\t\t\tarr = [];\n\t\t\tthis._attachedTierDisposers.set(key, arr);\n\t\t}\n\t\tfor (const tiers of this._attachedEventTiers) {\n\t\t\tarr.push(log.attachStorage(tiers));\n\t\t}\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\tevent(name: string, aggregateId: string): Node<readonly CqrsEvent[]>;\n\tevent(name: string, aggregateId?: string): Node<readonly CqrsEvent[]> {\n\t\tif (aggregateId !== undefined) {\n\t\t\treturn this._ensureAggregateStream(name, aggregateId).node;\n\t\t}\n\t\tconst existing = this._eventLogs.get(name);\n\t\tif (existing) return existing.node;\n\n\t\t// V0 versioning is attached at construction — post-hoc\n\t\t// `_applyVersioning` was deleted because it opened a re-entrance\n\t\t// window where a wave could observe `_versioning` transitioning from\n\t\t// `undefined` to a fresh state. Construction-time-only means the\n\t\t// flag is frozen at birth.\n\t\tconst log = reactiveLog<CqrsEvent>([], {\n\t\t\tname,\n\t\t\tversioning: 0,\n\t\t\tmaxSize: this._retainedLimit,\n\t\t});\n\t\tlog.withLatest();\n\t\tconst entries = log.entries;\n\t\tconst guarded = this.derived<readonly CqrsEvent[]>(\n\t\t\tname,\n\t\t\t[entries],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst latest =\n\t\t\t\t\tbatchData[0] != null && batchData[0].length > 0\n\t\t\t\t\t\t? (batchData[0].at(-1) as readonly CqrsEvent[])\n\t\t\t\t\t\t: (ctx.prevData[0] as readonly CqrsEvent[]);\n\t\t\t\treturn [latest];\n\t\t\t},\n\t\t\t{\n\t\t\t\tmeta: cqrsMeta(\"event\", { event_name: name }),\n\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\tinitial: entries.cache as readonly CqrsEvent[],\n\t\t\t},\n\t\t);\n\t\tthis.addDisposer(keepalive(guarded));\n\t\tthis._eventLogs.set(name, { log, node: guarded });\n\t\t// M4: auto-wire any storage tiers attached via `attachEventStorage`.\n\t\tthis._autoWireStreamStorage(name, log);\n\t\treturn guarded;\n\t}\n\n\t/**\n\t * Get-or-create the per-aggregate event stream for `(type, aggregateId)`.\n\t * Mounts the stream as a sibling node named `<type>_<aggregateId>` so it\n\t * appears in `describe()`. LRU access is touched on every call.\n\t */\n\tprivate _ensureAggregateStream(type: string, aggregateId: string): EventEntry {\n\t\t// Ensure the fan-in stream exists too (call sites usually expect both).\n\t\tif (!this._eventLogs.has(type)) this.event(type);\n\n\t\tlet byType = this._eventLogsByAggregate.get(type);\n\t\tif (!byType) {\n\t\t\tbyType = new Map();\n\t\t\tthis._eventLogsByAggregate.set(type, byType);\n\t\t}\n\t\tconst lruKey = `${type}::${aggregateId}`;\n\t\tthis._touchAggregate(lruKey);\n\t\tconst existing = byType.get(aggregateId);\n\t\tif (existing) return existing;\n\n\t\tconst nodeName = `${type}_${aggregateId.replace(/[^a-zA-Z0-9_-]/g, \"_\")}`;\n\t\tconst log = reactiveLog<CqrsEvent>([], {\n\t\t\tname: nodeName,\n\t\t\tversioning: 0,\n\t\t\tmaxSize: this._retainedLimit,\n\t\t});\n\t\tlog.withLatest();\n\t\tconst entries = log.entries;\n\t\t// Avoid name collisions if multiple aggregates have ids that sanitize\n\t\t// to the same node-name; suffix with a counter when necessary.\n\t\t// Resolve the mount name BEFORE constructing the derived (the\n\t\t// `this.derived(...)` form registers under the supplied `name`).\n\t\tlet mountName = nodeName;\n\t\tlet collisionIdx = 0;\n\t\twhile (this.resolveOptional(mountName) !== undefined) {\n\t\t\tcollisionIdx += 1;\n\t\t\tmountName = `${nodeName}_${collisionIdx}`;\n\t\t}\n\t\tlet guarded: Node<readonly CqrsEvent[]>;\n\t\ttry {\n\t\t\tguarded = this.derived<readonly CqrsEvent[]>(\n\t\t\t\tmountName,\n\t\t\t\t[entries],\n\t\t\t\t(batchData, ctx) => {\n\t\t\t\t\tconst latest =\n\t\t\t\t\t\tbatchData[0] != null && batchData[0].length > 0\n\t\t\t\t\t\t\t? (batchData[0].at(-1) as readonly CqrsEvent[])\n\t\t\t\t\t\t\t: (ctx.prevData[0] as readonly CqrsEvent[]);\n\t\t\t\t\treturn [latest];\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmeta: cqrsMeta(\"event_aggregate\", {\n\t\t\t\t\t\tevent_name: type,\n\t\t\t\t\t\taggregate_id: aggregateId,\n\t\t\t\t\t}),\n\t\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\t\tinitial: entries.cache as readonly CqrsEvent[],\n\t\t\t\t},\n\t\t\t);\n\t\t} catch {\n\t\t\t// Name collision raced with another constructor — fall back to a\n\t\t\t// raw, unmounted node so the per-aggregate stream still functions\n\t\t\t// (just not graph-visible). Mirrors the prior best-effort branch.\n\t\t\tguarded = node<readonly CqrsEvent[]>(\n\t\t\t\t[entries],\n\t\t\t\t(batchData, actions, ctx) => {\n\t\t\t\t\tconst latest =\n\t\t\t\t\t\tbatchData[0] != null && batchData[0].length > 0 ? batchData[0].at(-1) : ctx.prevData[0];\n\t\t\t\t\tactions.emit(latest as readonly CqrsEvent[]);\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: nodeName,\n\t\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\t\tmeta: cqrsMeta(\"event_aggregate\", {\n\t\t\t\t\t\tevent_name: type,\n\t\t\t\t\t\taggregate_id: aggregateId,\n\t\t\t\t\t}),\n\t\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\t\tinitial: entries.cache as readonly CqrsEvent[],\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tthis.addDisposer(keepalive(guarded));\n\t\tconst entry = { log, node: guarded };\n\t\tbyType.set(aggregateId, entry);\n\t\t// M4: auto-wire any tiers attached via `attachEventStorage`.\n\t\tthis._autoWireStreamStorage(`${type}::${aggregateId}`, log);\n\t\tthis._enforceAggregateLru();\n\t\treturn entry;\n\t}\n\n\t/** Try `resolve(path)`; return `undefined` instead of throwing on missing. */\n\tprivate resolveOptional(path: string): Node | undefined {\n\t\ttry {\n\t\t\treturn this.resolve(path);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/** Internal: append to an event log, auto-registering if needed. */\n\tprivate _appendEvent(\n\t\teventName: string,\n\t\tpayload: unknown,\n\t\textra?: {\n\t\t\taggregateId?: string;\n\t\t\tcorrelationId?: string;\n\t\t\tcausationId?: string;\n\t\t\tmetadata?: Readonly<Record<string, unknown>>;\n\t\t\thandlerVersion?: { id: string; version: string | number };\n\t\t},\n\t): CqrsEvent {\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\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\n\t\t// Per-aggregate version + stream wiring (D1).\n\t\tlet aggregateVersion: number | undefined;\n\t\tlet aggregateEntry: EventEntry | undefined;\n\t\tif (extra?.aggregateId !== undefined) {\n\t\t\tconst lruKey = `${eventName}::${extra.aggregateId}`;\n\t\t\taggregateVersion = (this._aggregateVersions.get(lruKey) ?? 0) + 1;\n\t\t\tthis._aggregateVersions.set(lruKey, aggregateVersion);\n\t\t\taggregateEntry = this._ensureAggregateStream(eventName, extra.aggregateId);\n\t\t}\n\n\t\tconst nv = entry.log.entries.v;\n\t\tconst frozenPayload = this._freezeEventPayload ? deepFreeze(payload) : payload;\n\t\tconst evt: CqrsEvent = {\n\t\t\ttype: eventName,\n\t\t\tpayload: frozenPayload,\n\t\t\ttimestampNs: wallClockNs(),\n\t\t\tseq: ++this._seq,\n\t\t\t...(extra?.aggregateId !== undefined ? { aggregateId: extra.aggregateId } : {}),\n\t\t\t...(aggregateVersion !== undefined ? { aggregateVersion } : {}),\n\t\t\t...(extra?.correlationId !== undefined ? { correlationId: extra.correlationId } : {}),\n\t\t\t...(extra?.causationId !== undefined ? { causationId: extra.causationId } : {}),\n\t\t\t...(extra?.metadata !== undefined ? { metadata: Object.freeze({ ...extra.metadata }) } : {}),\n\t\t\t...(extra?.handlerVersion !== undefined ? { handlerVersion: extra.handlerVersion } : {}),\n\t\t\t...(nv != null ? { v0: { id: nv.id, version: nv.version } } : {}),\n\t\t};\n\t\t// Append to fan-in stream (always) and per-aggregate stream (when set).\n\t\tentry.log.append(evt);\n\t\tif (aggregateEntry) {\n\t\t\taggregateEntry.log.append(evt);\n\t\t}\n\t\treturn evt;\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>(\n\t\tname: string,\n\t\thandlerOrReg: CommandHandler<T> | CommandRegistration<T>,\n\t): Node<T> {\n\t\tif (this._commandRegs.has(name)) {\n\t\t\tthrow new DuplicateRegistrationError(\"command\", name);\n\t\t}\n\t\tconst reg: CommandRegistration<T> =\n\t\t\ttypeof handlerOrReg === \"function\" ? { handler: handlerOrReg } : handlerOrReg;\n\t\tconst cmdNode = this.state<T>(name, undefined as T, {\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._commandRegs.set(name, {\n\t\t\thandler: reg.handler as CommandHandler<unknown>,\n\t\t\t...(reg.emits !== undefined ? { emits: reg.emits } : {}),\n\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t});\n\t\t// Pre-register declared event streams so describe() shows them.\n\t\tif (reg.emits) {\n\t\t\tfor (const e of reg.emits) {\n\t\t\t\tif (!this._eventLogs.has(e)) this.event(e);\n\t\t\t}\n\t\t}\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\t * **Tier 8 / COMPOSITION-GUIDE §35:** dispatch routes through the shared\n\t * {@link mutate} framework so freeze / rollback-on-throw / seq-cursor\n\t * advance / audit-record stamping flow through one centralized helper.\n\t * Failure records emit OUTSIDE the rolled-back batch (M5 / C4 invariants\n\t * preserved by the framework).\n\t */\n\tdispatch<T = unknown>(commandName: string, payload: T, opts?: DispatchOptions): void {\n\t\tconst reg = this._commandRegs.get(commandName);\n\t\tif (!reg) throw new UnknownCommandError(commandName);\n\n\t\t// D1: optimistic-concurrency check fires BEFORE the handler runs and\n\t\t// BEFORE the batch opens, so a stale-version dispatch is a clean\n\t\t// no-op (no audit record, no rollback). Only meaningful when both\n\t\t// aggregateId and expectedAggregateVersion are set; otherwise no-op.\n\t\tif (\n\t\t\topts?.aggregateId !== undefined &&\n\t\t\topts.expectedAggregateVersion !== undefined &&\n\t\t\treg.emits !== undefined\n\t\t) {\n\t\t\t// Verify against ANY of the declared `emits` types — the dispatch's\n\t\t\t// aggregate version is per (type, aggregateId), but a single\n\t\t\t// dispatch may emit across multiple types. We check the FIRST\n\t\t\t// declared `emits` type that has a version recorded for this\n\t\t\t// aggregate; if none has a version, the aggregate is considered\n\t\t\t// at version 0.\n\t\t\tlet observedVersion = 0;\n\t\t\tfor (const t of reg.emits) {\n\t\t\t\tconst v = this._aggregateVersions.get(`${t}::${opts.aggregateId}`);\n\t\t\t\tif (v !== undefined && v > observedVersion) observedVersion = v;\n\t\t\t}\n\t\t\tif (observedVersion !== opts.expectedAggregateVersion) {\n\t\t\t\tthrow new OptimisticConcurrencyError(\n\t\t\t\t\topts.aggregateId,\n\t\t\t\t\topts.expectedAggregateVersion,\n\t\t\t\t\tobservedVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst cmdNode = this.resolve(commandName);\n\t\tconst emittedEvents: string[] = [];\n\t\t// `actionThrew` distinguishes user-handler failures (where we want to\n\t\t// stamp `cmdNode.meta.error`) from framework-internal failures (which\n\t\t// shouldn't leak as a \"command failed\" signal).\n\t\tlet actionThrew = false;\n\n\t\tconst action = (sealed: T): void => {\n\t\t\tcmdNode.emit(sealed, { internal: true });\n\t\t\ttry {\n\t\t\t\treg.handler(sealed, {\n\t\t\t\t\temit: (eName, data) => {\n\t\t\t\t\t\t// Wave C.2 Unit 19: if emits was declared, reject undeclared names.\n\t\t\t\t\t\tif (reg.emits !== undefined && !reg.emits.includes(eName)) {\n\t\t\t\t\t\t\tthrow new UndeclaredEmitError(commandName, eName, reg.emits);\n\t\t\t\t\t\t}\n\t\t\t\t\t\temittedEvents.push(eName);\n\t\t\t\t\t\tthis._appendEvent(eName, data, {\n\t\t\t\t\t\t\t// D1: thread the dispatch's aggregateId through so events\n\t\t\t\t\t\t\t// participate in per-aggregate versioning. Handlers can\n\t\t\t\t\t\t\t// override per-emit by passing their own through a richer\n\t\t\t\t\t\t\t// emit signature (future extension).\n\t\t\t\t\t\t\t...(opts?.aggregateId !== undefined ? { aggregateId: opts.aggregateId } : {}),\n\t\t\t\t\t\t\t...(opts?.correlationId !== undefined ? { correlationId: opts.correlationId } : {}),\n\t\t\t\t\t\t\t...(opts?.causationId !== undefined ? { causationId: opts.causationId } : {}),\n\t\t\t\t\t\t\t...(opts?.metadata !== undefined\n\t\t\t\t\t\t\t\t? { metadata: Object.freeze({ ...opts.metadata }) }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tcmdNode.meta.error.emit(null, { internal: true });\n\t\t\t} catch (err) {\n\t\t\t\tactionThrew = true;\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\tmutate<[T], void, DispatchRecord>(action, {\n\t\t\t\tframe: \"transactional\",\n\t\t\t\tlog: this.dispatches,\n\t\t\t\tseq: this._dispatchSeqCursor,\n\t\t\t\tfreeze: this._freezeCommandPayload,\n\t\t\t\tonSuccessRecord: ([sealed], _result, { t_ns, seq }) => ({\n\t\t\t\t\tcommandName,\n\t\t\t\t\tpayload: sealed,\n\t\t\t\t\toutcome: \"success\",\n\t\t\t\t\temittedEvents: [...emittedEvents],\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t\t\t}),\n\t\t\t\tonFailureRecord: ([sealed], err, { t_ns, seq, errorType }) => {\n\t\t\t\t\tconst wrapped =\n\t\t\t\t\t\terr instanceof CommandHandlerError ? err : new CommandHandlerError(commandName, err);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcommandName,\n\t\t\t\t\t\tpayload: sealed,\n\t\t\t\t\t\toutcome: \"failure\",\n\t\t\t\t\t\terror: wrapped,\n\t\t\t\t\t\terrorType,\n\t\t\t\t\t\temittedEvents: [...emittedEvents],\n\t\t\t\t\t\tt_ns,\n\t\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t})(payload);\n\t\t} catch (outerErr) {\n\t\t\t// C4 preservation: only stamp `cmdNode.meta.error` when the user\n\t\t\t// handler threw (not when framework infra threw before the action\n\t\t\t// ran). The framework already routed onFailure for the action-throw\n\t\t\t// case via `mutate` outside the rolled-back batch.\n\t\t\tif (actionThrew) {\n\t\t\t\tcmdNode.meta.error.emit(outerErr, { internal: true });\n\t\t\t}\n\t\t\tthrow outerErr;\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 * **Wave C.3 Unit 21 (locked 2026-04-24):**\n\t * - Object-bag signature replaces the positional `(name, events, reducer, initial)` form.\n\t * - `mode: \"scan\"` (default) — incremental fold; `\"replay\"` — full replay each wave.\n\t * - `snapshot` integration for cold-start load + auto-checkpoint save.\n\t * - `freezeInputs` (default `true`) — freeze the event array before passing to reducer.\n\t * - Returns `ProjectionController<TState>` with `.node`, `.rebuild()`, `.reset()`.\n\t *\n\t * Fan-in across `events` is implemented by depending on all event-type fan-in\n\t * nodes directly, which preserves `describe()` edges (e.g. `orderPlaced →\n\t * orderCount`). Events are sorted by `(timestampNs, seq, aggregateId)` before\n\t * passing to the reducer (Option-3 cross-aggregate ordering, C.3).\n\t */\n\tprojection<TState>(opts: ProjectionOptions<TState>): ProjectionController<TState> {\n\t\tconst { name, events: eventNames, reducer, initial } = opts;\n\t\tconst mode = opts.mode ?? \"scan\";\n\t\tconst freezeInputs = opts.freezeInputs ?? true;\n\t\tconst snapshotOpts = opts.snapshot;\n\n\t\t// Ensure each event stream exists and collect its node.\n\t\t// Using the event-type fan-in nodes directly as deps preserves\n\t\t// `describe()` edges (orderPlaced → orderCount) per Audit 1 §24.\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// Sort comparator: timestampNs → seq → aggregateId lex (Option-3, C.3).\n\t\tfunction sortEvents(evts: CqrsEvent[]): void {\n\t\t\tevts.sort(\n\t\t\t\t(a, b) =>\n\t\t\t\t\ta.timestampNs - b.timestampNs ||\n\t\t\t\t\ta.seq - b.seq ||\n\t\t\t\t\t(a.aggregateId ?? \"\").localeCompare(b.aggregateId ?? \"\"),\n\t\t\t);\n\t\t}\n\n\t\t// Collect all events from the current snapshots (for seeding + rebuild).\n\t\tfunction collectAllEvents(snapshots: readonly (readonly CqrsEvent[])[]): CqrsEvent[] {\n\t\t\tconst evts: CqrsEvent[] = [];\n\t\t\tfor (const snap of snapshots) evts.push(...snap);\n\t\t\tsortEvents(evts);\n\t\t\treturn evts;\n\t\t}\n\n\t\t// Seed: collect any events already present at construction time.\n\t\tconst seedSnapshots = eventNodes.map(\n\t\t\t(n) => (n.cache as readonly CqrsEvent[] | undefined) ?? ([] as readonly CqrsEvent[]),\n\t\t);\n\t\tconst sortedSeed = collectAllEvents(seedSnapshots);\n\t\tconst frozenSeed = (\n\t\t\tfreezeInputs ? Object.freeze(sortedSeed) : sortedSeed\n\t\t) as readonly CqrsEvent[];\n\n\t\t// Scan state: tracks count of events processed in last run.\n\t\tlet lastProcessedCount = 0;\n\t\tlet scanState: TState = initial;\n\n\t\tif (mode === \"scan\" && sortedSeed.length > 0) {\n\t\t\tscanState = reducer(initial, frozenSeed);\n\t\t\tlastProcessedCount = sortedSeed.length;\n\t\t}\n\t\tconst seedState = mode === \"replay\" ? reducer(initial, frozenSeed) : scanState;\n\n\t\t// Snapshot save state — debounce + saveEvery.\n\t\tconst saveDebounceMs = snapshotOpts?.saveDebounceMs ?? 1000;\n\t\tconst saveEvery = snapshotOpts?.saveEvery ?? 1000;\n\t\tlet saveTimer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet savesSinceLastFlush = 0;\n\n\t\tfunction scheduleSave(currentState: TState): void {\n\t\t\tif (!snapshotOpts?.save) return;\n\t\t\tsavesSinceLastFlush += 1;\n\t\t\tif (savesSinceLastFlush >= saveEvery) {\n\t\t\t\tsavesSinceLastFlush = 0;\n\t\t\t\tif (saveTimer !== undefined) {\n\t\t\t\t\tclearTimeout(saveTimer);\n\t\t\t\t\tsaveTimer = undefined;\n\t\t\t\t}\n\t\t\t\tconst result = snapshotOpts.save(currentState);\n\t\t\t\tif (result instanceof Promise) result.catch(() => undefined);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (saveTimer !== undefined) clearTimeout(saveTimer);\n\t\t\tsaveTimer = setTimeout(() => {\n\t\t\t\tsaveTimer = undefined;\n\t\t\t\tsavesSinceLastFlush = 0;\n\t\t\t\tconst result = snapshotOpts!.save!(currentState);\n\t\t\t\tif (result instanceof Promise) result.catch(() => undefined);\n\t\t\t}, saveDebounceMs);\n\t\t}\n\n\t\tconst projNode = this.derived<TState>(\n\t\t\tname,\n\t\t\teventNames as readonly string[],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst snapshots = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst allEvents = collectAllEvents(snapshots as readonly (readonly CqrsEvent[])[]);\n\n\t\t\t\tlet newState: TState;\n\t\t\t\tif (mode === \"replay\") {\n\t\t\t\t\t// m1: freeze only in the replay branch where `frozen` is actually used.\n\t\t\t\t\tconst frozen = (\n\t\t\t\t\t\tfreezeInputs ? Object.freeze(allEvents) : allEvents\n\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\tnewState = reducer(initial, frozen);\n\t\t\t\t} else {\n\t\t\t\t\t// scan: only fold NEW events since last run.\n\t\t\t\t\tconst newOnly = allEvents.slice(lastProcessedCount);\n\t\t\t\t\tlastProcessedCount = allEvents.length;\n\t\t\t\t\tconst frozenNew = (\n\t\t\t\t\t\tfreezeInputs ? Object.freeze(newOnly) : newOnly\n\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\tnewState = reducer(scanState, frozenNew);\n\t\t\t\t\tscanState = newState;\n\t\t\t\t}\n\n\t\t\t\tscheduleSave(newState);\n\t\t\t\treturn [newState];\n\t\t\t},\n\t\t\t{\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: seedState,\n\t\t\t},\n\t\t);\n\n\t\tthis.addDisposer(keepalive(projNode));\n\t\tthis.addDisposer(() => {\n\t\t\tif (saveTimer !== undefined) {\n\t\t\t\tclearTimeout(saveTimer);\n\t\t\t\tsaveTimer = undefined;\n\t\t\t}\n\t\t});\n\t\tthis._projections.add(name);\n\n\t\t// -- Controller methods ---------------------------------------------------\n\n\t\tconst rebuild = async (rebuildOpts?: {\n\t\t\tfromTier?: AppendLogStorageTier<CqrsEvent>;\n\t\t\tpageSize?: number;\n\t\t}): Promise<TState> => {\n\t\t\ttry {\n\t\t\t\tconst pageSize = rebuildOpts?.pageSize ?? 1000;\n\t\t\t\tconst tier = rebuildOpts?.fromTier ?? this._attachedEventTiers[0]?.[0];\n\n\t\t\t\t// M5: snapshot in-memory event count BEFORE any async work so we can\n\t\t\t\t// drain events that arrive concurrently during the paginated rebuild.\n\t\t\t\tconst preBuildCount = collectAllEvents(\n\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t).length;\n\n\t\t\t\t// Seed from snapshot.load if provided.\n\t\t\t\tlet rebuildState: TState = initial;\n\t\t\t\tif (snapshotOpts?.load) {\n\t\t\t\t\tconst loaded = await snapshotOpts.load();\n\t\t\t\t\tif (loaded !== undefined) rebuildState = loaded;\n\t\t\t\t}\n\n\t\t\t\tif (!tier || !tier.loadEntries) {\n\t\t\t\t\t// No storage tier — fold in-memory events as a best-effort rebuild.\n\t\t\t\t\tconst inMemory = collectAllEvents(\n\t\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t\t);\n\t\t\t\t\tconst frozen = (\n\t\t\t\t\t\tfreezeInputs ? Object.freeze(inMemory) : inMemory\n\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\trebuildState = reducer(rebuildState, frozen);\n\t\t\t\t} else {\n\t\t\t\t\t// Paginated load from tier.\n\t\t\t\t\t// m3: only fold events that belong to this projection's event-type set.\n\t\t\t\t\t// Tiers may hold events from other projections; filtering keeps reducer\n\t\t\t\t\t// correctness when the tier is shared across projections.\n\t\t\t\t\tconst watchedEvents = new Set<string>(eventNames as readonly string[]);\n\t\t\t\t\tlet cursor: import(\"@graphrefly/pure-ts/extra\").AppendCursor | undefined;\n\t\t\t\t\tlet done = false;\n\t\t\t\t\twhile (!done) {\n\t\t\t\t\t\tconst result = await tier.loadEntries({ cursor, pageSize });\n\t\t\t\t\t\tconst page = [...result.entries].filter((e) => watchedEvents.has(e.type));\n\t\t\t\t\t\tsortEvents(page);\n\t\t\t\t\t\tconst frozenPage = (freezeInputs ? Object.freeze(page) : page) as readonly CqrsEvent[];\n\t\t\t\t\t\trebuildState = reducer(rebuildState, frozenPage);\n\t\t\t\t\t\tcursor = result.cursor;\n\t\t\t\t\t\tdone = !cursor || result.entries.length === 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Update the live projection node with the rebuilt state.\n\t\t\t\tif (mode === \"scan\") {\n\t\t\t\t\t// M5: drain events that arrived during the async rebuild so they are\n\t\t\t\t\t// not lost (race between paginated load and concurrent dispatch).\n\t\t\t\t\tconst allInMemory = collectAllEvents(\n\t\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEvents = allInMemory.slice(preBuildCount);\n\t\t\t\t\tif (pendingEvents.length > 0) {\n\t\t\t\t\t\tconst frozenPending = (\n\t\t\t\t\t\t\tfreezeInputs ? Object.freeze(pendingEvents) : pendingEvents\n\t\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\t\trebuildState = reducer(rebuildState, frozenPending);\n\t\t\t\t\t}\n\t\t\t\t\tscanState = rebuildState;\n\t\t\t\t\tlastProcessedCount = allInMemory.length;\n\t\t\t\t}\n\t\t\t\tprojNode.emit(rebuildState, { internal: true });\n\t\t\t\treturn rebuildState;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new RebuildError(name, err);\n\t\t\t}\n\t\t};\n\n\t\tconst reset = async (): Promise<TState> => {\n\t\t\ttry {\n\t\t\t\t// Reload from snapshot.load (if configured).\n\t\t\t\tlet baseState: TState = initial;\n\t\t\t\tif (snapshotOpts?.load) {\n\t\t\t\t\tconst loaded = await snapshotOpts.load();\n\t\t\t\t\tif (loaded !== undefined) baseState = loaded;\n\t\t\t\t}\n\n\t\t\t\t// Re-fold all in-memory events on top of the snapshot state.\n\t\t\t\tconst inMemory = collectAllEvents(\n\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t);\n\t\t\t\tconst frozen = (freezeInputs ? Object.freeze(inMemory) : inMemory) as readonly CqrsEvent[];\n\t\t\t\tconst newState = reducer(baseState, frozen);\n\n\t\t\t\tif (mode === \"scan\") {\n\t\t\t\t\tscanState = newState;\n\t\t\t\t\tlastProcessedCount = inMemory.length;\n\t\t\t\t}\n\t\t\t\tprojNode.emit(newState, { internal: true });\n\t\t\t\treturn newState;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new RebuildError(name, err);\n\t\t\t}\n\t\t};\n\n\t\treturn { node: projNode, rebuild, reset };\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\topts: SagaOptions = {},\n\t): SagaController<T> {\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// Audit 2: per-event-type cursor state nodes (replaces closure Map).\n\t\t// Mount under `<saga>_cursor` (no `::` — that's the path separator).\n\t\tconst cursors = registerCursorMap(this, `${name}_cursor`, eventNames as readonly string[], 0);\n\t\t// Audit 2: invocations log (companion + alias).\n\t\tconst invocations = createAuditLog<SagaInvocation<T>>({\n\t\t\tname: `${name}_invocations`,\n\t\t\tretainedLimit: this._retainedLimit,\n\t\t\tgraph: this,\n\t\t});\n\t\tconst aggregateFilter = opts.aggregateId;\n\t\tconst errorPolicy = opts.errorPolicy ?? \"advance\";\n\n\t\t// D2: subscribe-and-capture-mirror for cursor reads — avoid `.cache`\n\t\t// access from inside the saga node's fn. Each cursor mirrors into a\n\t\t// closure variable updated by an external subscription. Cursor writes\n\t\t// (`cursor.emit(advancedTo)`) and `invocations.append(...)` from inside\n\t\t// the fn are sanctioned effect-side-effects (saga's `describeKind:\n\t\t// \"effect\"`) — not §5.9 imperative-trigger violations.\n\t\tconst latestCursors = new Map<string, number>();\n\t\tfor (const eName of eventNames) {\n\t\t\tconst cursor = cursors[eName]!;\n\t\t\tlatestCursors.set(eName, (cursor.cache as number | undefined) ?? 0);\n\t\t\tconst sub = cursor.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) if (m[0] === DATA) latestCursors.set(eName, m[1] as number);\n\t\t\t});\n\t\t\tthis.addDisposer(sub);\n\t\t}\n\n\t\t// Tier 8 / COMPOSITION-GUIDE §35: per-event handler invocation routes\n\t\t// through `mutate` so handler-version stamping + audit-record\n\t\t// shape stay centralized. Failure path re-throws — the saga's outer\n\t\t// try/catch honors `errorPolicy` (\"advance\" vs \"hold\"). Action takes\n\t\t// `(ev, eName)` so the wrapper can be hoisted once for all event types.\n\t\tconst auditedHandler = mutate<[CqrsEvent<T>, string], void, SagaInvocation<T>>(\n\t\t\t(ev, _eName) => {\n\t\t\t\thandler(ev);\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: invocations,\n\t\t\t\tfreeze: false,\n\t\t\t\t...(opts.handlerVersion !== undefined ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t// D5 (qa lock): always include the `aggregateId` key (even when\n\t\t\t\t// undefined) for parity with the pre-Tier-8 saga record shape.\n\t\t\t\t// Consumers using `Object.hasOwn(record, \"aggregateId\")` or JSON\n\t\t\t\t// serialization shape would observe a pre-1.0 break otherwise.\n\t\t\t\tonSuccessRecord: ([ev, eName], _r, { t_ns }) => ({\n\t\t\t\t\teventType: eName,\n\t\t\t\t\toutcome: \"success\",\n\t\t\t\t\taggregateId: ev.aggregateId,\n\t\t\t\t\tevent: ev,\n\t\t\t\t\tt_ns,\n\t\t\t\t}),\n\t\t\t\tonFailureRecord: ([ev, eName], err, { t_ns, errorType }) => ({\n\t\t\t\t\teventType: eName,\n\t\t\t\t\toutcome: \"failure\",\n\t\t\t\t\terror: err,\n\t\t\t\t\terrorType,\n\t\t\t\t\taggregateId: ev.aggregateId,\n\t\t\t\t\tevent: ev,\n\t\t\t\t\tt_ns,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tconst sagaRef: { n?: Node<unknown> } = {};\n\t\tconst sagaNode = this.effect(\n\t\t\tname,\n\t\t\teventNames as readonly string[],\n\t\t\t(snapshots, _up) => {\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 batch = snapshots[i];\n\t\t\t\t\tif (batch == null || batch.length === 0) continue;\n\t\t\t\t\tconst entries = batch.at(-1) as readonly CqrsEvent<T>[] | undefined;\n\t\t\t\t\tif (!entries) continue;\n\t\t\t\t\tconst eName = eventNames[i] as string;\n\t\t\t\t\tconst cursor = cursors[eName]!;\n\t\t\t\t\tconst lastCount = latestCursors.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\tlet advancedTo = lastCount;\n\t\t\t\t\t\tfor (const entry of newEntries) {\n\t\t\t\t\t\t\tconst ev = entry as CqrsEvent<T>;\n\t\t\t\t\t\t\tif (aggregateFilter !== undefined && ev.aggregateId !== aggregateFilter) {\n\t\t\t\t\t\t\t\tadvancedTo += 1;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tauditedHandler(ev, eName);\n\t\t\t\t\t\t\t\terrNode.emit(null, { internal: true });\n\t\t\t\t\t\t\t\tadvancedTo += 1;\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\terrNode.emit(err, { internal: true });\n\t\t\t\t\t\t\t\tif (errorPolicy === \"hold\") break;\n\t\t\t\t\t\t\t\t// \"advance\" — skip past failure, keep going.\n\t\t\t\t\t\t\t\tadvancedTo += 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcursor.emit(advancedTo);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\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.addDisposer(keepalive(sagaNode));\n\t\tthis._sagas.add(name);\n\t\treturn {\n\t\t\tnode: sagaNode,\n\t\t\tinvocations,\n\t\t\taudit: invocations,\n\t\t\tcursors,\n\t\t};\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 * const { node: orderCount } = app.projection({\n * name: \"orderCount\",\n * events: [\"orderPlaced\"],\n * reducer: (_s, events) => events.length,\n * initial: 0,\n * });\n * app.dispatch(\"placeOrder\", { id: \"1\", amount: 100 });\n * ```\n */\nexport function cqrs<EM extends CqrsEventMap = Record<string, unknown>>(\n\tname: string,\n\topts?: CqrsOptions,\n): CqrsGraph<EM> {\n\tconst g = new CqrsGraph<EM>(name, opts);\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` surfaces provenance. Route through\n\t// `placeholderArgs` since `CqrsOptions.graph` may carry non-JSON fields.\n\tconst { factory: _f, factoryArgs: _fa, ...tagArgs } = (opts ?? {}) as Record<string, unknown>;\n\tg.tagFactory(\"cqrs\", placeholderArgs(tagArgs));\n\treturn g;\n}\n","/**\n * Universal mutation framework (Phase 14 — DS-14 locked 2026-05-05).\n *\n * Single `mutate(act, opts)` factory replaces the prior `lightMutation` +\n * `wrapMutation` two-tier split (pre-1.0 break per Q-O2).\n *\n * Two frames:\n * - `\"inline\"` — no batch; up() runs raw. Seq bumps before action; persists\n * on throw. Hot-path-friendly for atomic single-write mutations.\n * - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n * deferred deliveries, then `down()` runs (if provided), then failure record.\n *\n * Phase-4 primitives share the same shape: imperative mutation methods +\n * closure state + reactive audit log + freeze-at-entry + rollback-on-throw.\n * This module factors out the common machinery so each primitive becomes\n * declarative wiring over typed audit records.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tDIRTY,\n\ttype Node,\n\ttype NodeGuard,\n\tnode,\n\tpolicy,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype ReactiveLogBundle,\n\ttype ReactiveLogOptions,\n\treactiveLog,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\n\n// ── tryIncrementBounded ──────────────────────────────────────────────────\n\n/**\n * Bounded increment for a self-owned counter state node.\n *\n * Reads `counter.cache`, bumps by `by` (default 1) if `cur + by <= cap`,\n * writes back. Returns `false` when the cap would be exceeded (no-op write).\n * Documented P3 exception: the counter is not a declared dep of the caller —\n * it's a private budget read+written from a single call site. This helper\n * keeps the `.cache` access in one named place so caller bodies (which may\n * be inside reactive fn execution paths) stay free of cross-node `.cache`\n * reads.\n *\n * **Safety today:**\n * 1. Single-threaded JS runner never invokes the caller concurrently.\n * 2. `counter.down` writes the cache synchronously before returning, so\n * synchronous re-entry through a downstream publish reads the\n * freshly-incremented value — no double-count.\n *\n * **Future risk:** under a free-threaded runner (PY no-GIL or hypothetical\n * concurrent TS runner), two concurrent firings could still race. Revisit\n * when that surfaces.\n *\n * @param counter - Self-owned counter Node. Caller is the sole writer.\n * @param cap - Upper bound (inclusive). Pass `Number.MAX_SAFE_INTEGER` for\n * \"effectively unbounded\" use cases (e.g. token meters).\n * @param by - Delta to add (default `1`). Must be a finite non-negative\n * number; callers should pre-validate. Overflow-safe via\n * `by > cap - cur` check rather than `cur + by >= cap`.\n */\nexport function tryIncrementBounded(counter: Node<number>, cap: number, by = 1): boolean {\n\tconst cur = (counter.cache as number | undefined) ?? 0;\n\tif (by > cap - cur) return false;\n\tcounter.down([[DIRTY], [DATA, cur + by]]);\n\treturn true;\n}\n\n// ── Audit record schema ──────────────────────────────────────────────────\n\n/** Shared base shape for every audit record. Per-primitive types extend this. */\nexport interface BaseAuditRecord {\n\treadonly t_ns: number;\n\treadonly seq?: number;\n\treadonly handlerVersion?: { id: string; version: string | number };\n}\n\n// ── Default audit guard ──────────────────────────────────────────────────\n\n/**\n * Allow `observe` and `signal`; deny external `write` on the audit log so\n * consumers can subscribe + signal-bridge but cannot inject fake records.\n */\nexport const DEFAULT_AUDIT_GUARD: NodeGuard = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n// ── createAuditLog ───────────────────────────────────────────────────────\n\nexport type AuditLogOpts<R extends BaseAuditRecord> = {\n\tname: string;\n\t/** Bounded retention; default 1024 per Audit 2 / cross-cutting bounded-default policy. */\n\tretainedLimit?: number;\n\t/** Override the default audit guard. */\n\tguard?: NodeGuard;\n\t/** Mount the audit `entries` Node under this graph (and activate withLatest). */\n\tgraph?: Graph;\n\t/** Pass-through to {@link reactiveLog}. */\n\tversioning?: ReactiveLogOptions<R>[\"versioning\"];\n};\n\n/**\n * Build a reactive audit log with sane defaults: bounded retention, deny-write\n * guard, `withLatest()` companions activated. Returns the {@link ReactiveLogBundle}\n * directly — primitives expose this as `<primitive>.events` / `.decisions` /\n * `.dispatches` / `.invocations` and alias it as `.audit`.\n *\n * @category internal\n */\nexport function createAuditLog<R extends BaseAuditRecord>(\n\topts: AuditLogOpts<R>,\n): ReactiveLogBundle<R> {\n\tconst log = reactiveLog<R>([], {\n\t\tname: opts.name,\n\t\tmaxSize: opts.retainedLimit ?? 1024,\n\t\tguard: opts.guard ?? DEFAULT_AUDIT_GUARD,\n\t\t...(opts.versioning != null ? { versioning: opts.versioning } : {}),\n\t});\n\t// Lazy companion activation up-front so `bundle.lastValue` / `hasLatest`\n\t// are queryable without an explicit `withLatest()` call.\n\tlog.withLatest();\n\tif (opts.graph) {\n\t\topts.graph.add(log.entries, { name: opts.name });\n\t}\n\treturn log;\n}\n\n// ── Universal mutation factory (Phase 14 — DS-14 lock Q-O2/Q-O3) ────────\n//\n// Single `mutate(act, opts)` factory. Two frames:\n//\n// - `\"inline\"` — no batch frame; up() runs raw. Seq bumps before action;\n// persists on throw. Hot-path-friendly for atomic single-write mutations.\n//\n// - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n// deferred deliveries, then `down()` runs, then failure record persists.\n//\n// **Heuristic:** if your imperative method's body is one or two lines (mutate\n// state, emit), use `frame: \"inline\"`. If it runs a user-supplied handler or\n// has multiple steps that could leave inconsistent state mid-throw, use\n// `frame: \"transactional\"`.\n\nexport type FailureMeta = {\n\tt_ns: number;\n\tseq?: number;\n\terrorType: string;\n};\n\nexport type SuccessMeta = {\n\tt_ns: number;\n\tseq?: number;\n};\n\n/**\n * Mutation action shape. Plain function shorthand auto-wraps as `{ up: fn }`.\n *\n * - `up` — the mutation action (the \"up migration\").\n * - `down` — optional rollback for closure mutations that `batch()` can't\n * reach. Receives the SAME frozen args as `up`. Runs AFTER batch reactive\n * rollback, BEFORE the failure record. Throws inside `down` are\n * console.error'd without masking the original error. Only meaningful\n * with `frame: \"transactional\"`.\n */\nexport type MutationAct<TArgs extends readonly unknown[], TResult> = {\n\tup: (...args: TArgs) => TResult;\n\tdown?: (...args: TArgs) => void;\n};\n\nexport type MutationFrame = \"inline\" | \"transactional\";\n\nexport type MutateOpts<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord> = {\n\t/** Frame mode. `\"inline\"` = no batch; `\"transactional\"` = batch + rollback. */\n\tframe: MutationFrame;\n\t/**\n\t * Optional log to append records to. When omitted, the wrapper still\n\t * provides freeze / seq-advance / rollback-on-throw but skips record\n\t * emission — useful for primitives that want centralized mutation\n\t * semantics without a dedicated log surface (e.g. `Topic.publish`).\n\t */\n\tlog?: ReactiveLogBundle<R>;\n\t/** Build the success record from the action's args + result + meta. */\n\tonSuccessRecord?: (args: TArgs, result: TResult, meta: SuccessMeta) => R | undefined;\n\t/** Build the failure record from the args + error + meta. */\n\tonFailureRecord?: (args: TArgs, error: unknown, meta: FailureMeta) => R | undefined;\n\t/** Deep-freeze args at entry (default `true`). Opt out for hot paths. */\n\tfreeze?: boolean;\n\t/** Optional sequence cursor — auto-advanced and stamped onto records. */\n\tseq?: Node<number>;\n\t/** Optional handler version — stamped per Audit 5. */\n\thandlerVersion?: { id: string; version: string | number };\n};\n\nfunction deepFreeze<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tfor (const k of Object.keys(value as Record<string, unknown>)) {\n\t\tdeepFreeze((value as Record<string, unknown>)[k]);\n\t}\n\treturn Object.freeze(value);\n}\n\n/**\n * Universal mutation factory (Phase 14 — DS-14 Q-O2).\n *\n * Replaces the prior `lightMutation` + `wrapMutation` two-tier split.\n * Single factory with `frame: \"inline\" | \"transactional\"` discriminant.\n *\n * @param act - The mutation action. Either a plain function (auto-wrapped as\n * `{ up: fn }`) or a `{ up, down? }` object for explicit rollback.\n * @param opts - Configuration: frame, log, record builders, freeze, seq.\n * @returns A typed wrapper function with the same signature as `act.up`.\n */\nexport function mutate<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord>(\n\tact: MutationAct<TArgs, TResult> | ((...args: TArgs) => TResult),\n\topts: MutateOpts<TArgs, TResult, R>,\n): (...args: TArgs) => TResult {\n\tconst { up, down } = typeof act === \"function\" ? { up: act, down: undefined } : act;\n\tconst freeze = opts.freeze ?? true;\n\n\tif (opts.frame === \"inline\") {\n\t\treturn function wrapped(...args: TArgs): TResult {\n\t\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\t\tconst t_ns = wallClockNs();\n\t\t\tconst seq = opts.seq ? bumpCursor(opts.seq) : undefined;\n\t\t\ttry {\n\t\t\t\tconst result = up(...sealed);\n\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\tresult,\n\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} catch (err) {\n\t\t\t\tif (opts.log && opts.onFailureRecord) {\n\t\t\t\t\tconst errorType = err instanceof Error ? err.name : typeof err;\n\t\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t};\n\t}\n\n\t// frame === \"transactional\"\n\treturn function wrapped(...args: TArgs): TResult {\n\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\tconst t_ns = wallClockNs();\n\t\tlet result: TResult;\n\t\tlet captured: unknown;\n\t\tlet captureSet = false;\n\t\tlet seq: number | undefined;\n\t\ttry {\n\t\t\tbatch(() => {\n\t\t\t\tif (opts.seq) seq = bumpCursor(opts.seq);\n\t\t\t\ttry {\n\t\t\t\t\tresult = up(...sealed);\n\t\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\t\topts.log,\n\t\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\t\tsealed,\n\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tcaptured = err;\n\t\t\t\t\tcaptureSet = true;\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (outerErr) {\n\t\t\t// Fire `down` AFTER batch's reactive rollback, BEFORE failure record.\n\t\t\t// Gate on `captureSet` — if the throw came from outside the inner try\n\t\t\t// (framework-level batch error before action ran), don't fire down.\n\t\t\tif (captureSet && down) {\n\t\t\t\ttry {\n\t\t\t\t\tdown(...sealed);\n\t\t\t\t} catch (downErr) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`mutate: down hook threw — original action error preserved (${\n\t\t\t\t\t\t\tcaptured instanceof Error ? captured.name : typeof captured\n\t\t\t\t\t\t}). Down error:`,\n\t\t\t\t\t\tdownErr,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (captureSet && opts.log && opts.onFailureRecord) {\n\t\t\t\tconst errorType = captured instanceof Error ? captured.name : typeof captured;\n\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\topts.log,\n\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\tsealed,\n\t\t\t\t\tcaptured,\n\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\topts.handlerVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow captureSet ? captured : outerErr;\n\t\t}\n\t\treturn result!;\n\t};\n}\n\n/**\n * Advance a cursor node and return the new value. Emits `[DIRTY], [DATA, next]`\n * directly on the cursor — atomic outside a batch, rollback-discardable inside.\n *\n * Resets to `0` if the cursor cache is missing, non-numeric, `NaN`, or\n * non-finite (e.g. corrupted by `restore()` from a malformed snapshot, or\n * by a misbehaving codec). `??` alone would let `NaN` and `\"\"` pass through\n * and silently corrupt audit ordering downstream.\n *\n * **Silent reset diagnostic (EH-12).** When the cache holds a non-numeric\n * value at bump time, the cursor restarts at 0 and the next bump returns 1\n * — colliding with the seq stamped on the very first record after construct.\n * To make seq-monotonicity violations after a restore visible to operators,\n * the helper emits a one-shot `console.warn` per cursor instance describing\n * the offending value. The cursor is identified by a `WeakSet<Node<number>>`\n * so the warning fires exactly once per node — repeat malformed bumps stay\n * quiet to avoid log spam. Production callers wanting to suppress can swap\n * the global `console` (universal-safe code path; no Node-only API used).\n *\n * Works whether or not the cursor has any subscribers — `down` updates the\n * cache regardless, so primitives that bump before consumers attach (e.g.\n * `JobQueueGraph.enqueue`) still see a coherent sequence.\n *\n * @category internal\n */\nconst _bumpCursorWarned = new WeakSet<Node<number>>();\nexport function bumpCursor(seq: Node<number>): number {\n\tconst raw = seq.cache;\n\tconst valid = typeof raw === \"number\" && Number.isFinite(raw);\n\tif (!valid && raw !== undefined && !_bumpCursorWarned.has(seq)) {\n\t\t_bumpCursorWarned.add(seq);\n\t\tconsole.warn(\n\t\t\t`bumpCursor: cursor cache held a non-numeric value (${String(raw)}); resetting to 0. ` +\n\t\t\t\t\"Causes include: a snapshot codec round-tripping the cursor as a string / null / NaN, \" +\n\t\t\t\t\"OR a malformed initial seed (e.g. state<number>(NaN)). \" +\n\t\t\t\t\"Audit consumers may see colliding seq values after this point.\",\n\t\t);\n\t}\n\tconst cur = valid ? raw : 0;\n\tconst next = cur + 1;\n\tseq.down([[DIRTY], [DATA, next]]);\n\treturn next;\n}\n\n/**\n * Build a record via the supplied builder, stamp `handlerVersion` if present,\n * and append it to the audit log. `undefined` records are skipped (callers\n * pass an `onSuccess` / `onFailure` that returns `undefined` to opt out per\n * call).\n *\n * @category internal\n */\nexport function appendAudit<\n\tTArgs extends readonly unknown[],\n\tTValue,\n\tR extends BaseAuditRecord,\n\tM extends SuccessMeta | FailureMeta,\n>(\n\taudit: ReactiveLogBundle<R>,\n\tbuilder: (args: TArgs, value: TValue, meta: M) => R | undefined,\n\targs: TArgs,\n\tvalue: TValue,\n\tmeta: M,\n\thandlerVersion?: { id: string; version: string | number },\n): void {\n\tconst record = builder(args, value, meta);\n\tif (record === undefined) return;\n\tconst stamped = handlerVersion != null ? ({ ...record, handlerVersion } as R) : record;\n\taudit.append(stamped);\n}\n\n// ── registerCursor / registerCursorMap ───────────────────────────────────\n\n/**\n * Promote a closure counter to a state node mounted under `graph`.\n * Replaces ad-hoc `let _seq = 0` patterns with a node observable in\n * `describe()` and persistable via storage tiers.\n *\n * @category internal\n */\nexport function registerCursor(graph: Graph, name: string, initial = 0): Node<number> {\n\tconst cursor = node<number>([], { initial, name, describeKind: \"state\" });\n\tgraph.add(cursor, { name });\n\treturn cursor;\n}\n\n/**\n * Promote a closure `Map<K, number>` to N state nodes (one per key) mounted\n * under `<graph>::<name>::<key>`. Used by saga (per-event-type cursor).\n *\n * @category internal\n */\nexport function registerCursorMap<K extends string>(\n\tgraph: Graph,\n\tname: string,\n\tkeys: readonly K[],\n\tinitial = 0,\n): { readonly [P in K]: Node<number> } {\n\tconst out = {} as { [P in K]: Node<number> };\n\t// Mount cursors under a child plain-Graph so per-key node names stay flat\n\t// (path-separator `::` is reserved by Graph.add). Using `Graph` directly\n\t// rather than `graph.constructor` avoids spawning a typed subclass with\n\t// an incompatible constructor signature (e.g., CqrsGraph(name, opts)).\n\tconst sub = new Graph(name);\n\tfor (const k of keys) {\n\t\tconst cursor = node<number>([], {\n\t\t\tinitial,\n\t\t\tname: k,\n\t\t\tdescribeKind: \"state\",\n\t\t});\n\t\tsub.add(cursor, { name: k });\n\t\tout[k] = cursor;\n\t}\n\tgraph.mount(name, sub);\n\treturn out;\n}\n","/**\n * Shared pattern-layer error hierarchy (Audit 2 — locked 2026-04-24).\n *\n * Cross-primitive `instanceof` checks: gate, queue, cqrs.dispatch, saga,\n * projection, subscription, etc. all use these classes so consumer error\n * handlers can branch by kind rather than by message string.\n *\n * @internal — exposed via patterns/index for primitive impls; consumers\n * should import the relevant class from the primitive's barrel.\n */\n\n/** Root error class. All pattern-layer errors extend this. */\nexport class GraphReFlyError extends Error {\n\tconstructor(message: string, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = this.constructor.name;\n\t}\n}\n\n/** Re-registering a name that's already taken (command, gate, queue, saga, projection). */\nexport class DuplicateRegistrationError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly kind: string,\n\t\treadonly registrationName: string,\n\t) {\n\t\tsuper(`Duplicate ${kind} registration: \"${registrationName}\"`);\n\t}\n}\n\n/** CQRS handler emitted an event type not in its declared `emits` set. */\nexport class UndeclaredEmitError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly commandName: string,\n\t\treadonly eventName: string,\n\t\treadonly declaredEmits: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Command \"${commandName}\" emitted undeclared event \"${eventName}\". Declared emits: [${declaredEmits.join(\", \")}]`,\n\t\t);\n\t}\n}\n\n/** Aggregate version expected vs observed mismatch on dispatch. */\nexport class OptimisticConcurrencyError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly aggregateId: string,\n\t\treadonly expected: number,\n\t\treadonly actual: number,\n\t) {\n\t\tsuper(\n\t\t\t`Optimistic concurrency conflict on aggregate \"${aggregateId}\": expected version ${expected}, got ${actual}`,\n\t\t);\n\t}\n}\n\n/** `dispatch(name, ...)` for a name that wasn't registered via `command()`. */\nexport class UnknownCommandError extends GraphReFlyError {\n\tconstructor(readonly commandName: string) {\n\t\tsuper(`Unknown command: \"${commandName}\". Register with command() first.`);\n\t}\n}\n\n/** Wrap any error thrown from inside a command handler. Original on `cause`. */\nexport class CommandHandlerError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly commandName: string,\n\t\tcause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Command handler \"${commandName}\" threw: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n\n/** Mutation method called after the primitive was torn down. */\nexport class TeardownError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly kind: string,\n\t\treadonly method: string,\n\t) {\n\t\tsuper(`${kind}: ${method}() called after teardown`);\n\t}\n}\n\n/** Projection rebuild failure — adapter / decode / reducer error. */\nexport class RebuildError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly projectionName: string,\n\t\tcause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Projection \"${projectionName}\" rebuild failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n","/**\n * Metadata helpers for pattern-layer nodes (Tier 2.2 promotion from\n * `patterns/_internal/`).\n *\n * Each domain (orchestration, messaging, reduction, ai, cqrs, domain_template,\n * memory, lens, audit, harness) shares the same metadata convention. Promoted\n * to `extra/` so non-patterns code (and downstream consumers building their\n * own domain primitives) can use the same shape.\n *\n * @module\n */\n\n/**\n * Build a domain metadata object for pattern-layer nodes.\n *\n * Each domain follows the same shape: `{ [domain]: true, [domain]_type: kind, ...extra }`.\n *\n * @param domain - The domain tag (e.g. `\"orchestration\"`, `\"ai\"`, `\"cqrs\"`).\n * @param kind - The specific type within the domain (e.g. `\"gate\"`, `\"prompt\"`).\n * @param extra - Additional metadata to merge.\n * @returns Metadata object.\n */\nexport function domainMeta(\n\tdomain: string,\n\tkind: string,\n\textra?: Record<string, unknown>,\n): Record<string, unknown> {\n\treturn {\n\t\t[domain]: true,\n\t\t[`${domain}_type`]: kind,\n\t\t...(extra ?? {}),\n\t};\n}\n","// ---------------------------------------------------------------------------\n// NestJS RxJS bridge — returns a real rxjs `Observable` (so NestJS route\n// handlers' `isObservable()` recognizes it and `.pipe()` works directly).\n//\n// rxjs lives ONLY here, under the opt-in `compat/nestjs` subpath, where it is\n// legitimately available (`@nestjs/common` depends on rxjs). The base\n// `toObservable` (`@graphrefly/graphrefly/base`) is dependency-free and is\n// what RN/Hermes/web consumers load — this wrapper just adopts it via\n// rxjs `from()`.\n// ---------------------------------------------------------------------------\n\nimport type { Messages, Node } from \"@graphrefly/pure-ts/core\";\nimport { from, type Observable, type ObservableInput } from \"rxjs\";\nimport {\n\ttoObservable as baseToObservable,\n\ttype ToObservableOptions,\n} from \"../../base/composition/observable.js\";\n\nexport type { ToObservableOptions };\n\n/**\n * Bridge a `Node<T>` to a real rxjs `Observable` for NestJS controllers,\n * gateways, and interceptors. Wraps the dependency-free base interop\n * observable with rxjs `from()` so `isObservable()` / `.pipe()` work.\n *\n * See {@link baseToObservable} for the DATA/ERROR/COMPLETE mapping and the\n * `{ raw: true }` message-batch mode.\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\t// The base interop observable exposes `subscribe` + the well-known\n\t// `Symbol.observable` method at runtime; rxjs `from()` adopts it. Branch\n\t// so each call hits a concrete base overload (the union impl signature is\n\t// not visible to callers), and cast the minimal base type to rxjs input.\n\tconst base = options?.raw ? baseToObservable(node, { raw: true }) : baseToObservable<T>(node);\n\treturn from(base as unknown as ObservableInput<T | Messages>);\n}\n","// ---------------------------------------------------------------------------\n// Observable bridge — reactive interop between GraphReFly nodes and the TC39\n// Observable contract (the well-known `Symbol.observable` / \"@@observable\"\n// method). **Zero runtime dependency on rxjs**: the returned value is a\n// spec-interop observable that rxjs `from()`, Angular, the NestJS compat\n// layer, and any `Symbol.observable` consumer can adopt. Consumers wanting\n// rxjs operators do `from(toObservable(node))`.\n//\n// Usage:\n// import { toObservable } from '@graphrefly/graphrefly/base';\n// import { from } from 'rxjs';\n// const values$ = from(toObservable(myNode)); // Observable<T>\n// const msgs$ = from(toObservable(myNode, { raw: true })); // Observable<Messages>\n// ---------------------------------------------------------------------------\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { COMPLETE, DATA, ERROR, type Messages } from \"@graphrefly/pure-ts/core\";\n\n/** Observer passed to {@link InteropObservable.subscribe}. */\nexport interface InteropObserver<T> {\n\tnext?(value: T): void;\n\terror?(err: unknown): void;\n\tcomplete?(): void;\n\t/** rxjs `Subscriber` sets this; we short-circuit delivery when closed. */\n\tclosed?: boolean;\n}\n\n/** Teardown handle returned by {@link InteropObservable.subscribe}. */\nexport interface InteropSubscription {\n\tunsubscribe(): void;\n}\n\n/**\n * Minimal TC39 Observable. rxjs `from()` (and any `Symbol.observable`\n * consumer) adopts it at runtime via the well-known interop method attached\n * by {@link toObservable}. Pass the result through `from(...)` to get a\n * pipeable rxjs `Observable`.\n */\nexport interface InteropObservable<T> {\n\tsubscribe(observer: InteropObserver<T> | ((value: T) => void)): InteropSubscription;\n}\n\n/** Options for {@link toObservable}. */\nexport type ToObservableOptions = {\n\t/**\n\t * When `true`, emit raw `Messages` batches instead of extracted `DATA`\n\t * values. Terminal batches are still emitted as the final `next()` before\n\t * the error/complete signal.\n\t */\n\traw?: boolean;\n};\n\n// Well-known Observable interop key. Mirrors the rxjs / `symbol-observable`\n// resolution (the global `Symbol.observable` when the runtime or a polyfill\n// provides it, otherwise the `\"@@observable\"` string) so rxjs `from()` adopts\n// our object regardless of polyfill state.\nconst OBSERVABLE_KEY: PropertyKey =\n\t(typeof Symbol === \"function\" && (Symbol as unknown as { observable?: symbol }).observable) ||\n\t\"@@observable\";\n\nfunction normalizeObserver<T>(\n\tobserver: InteropObserver<T> | ((value: T) => void),\n): InteropObserver<T> {\n\treturn typeof observer === \"function\" ? { next: observer } : observer;\n}\n\nfunction makeInterop<T>(\n\tonSubscribe: (observer: InteropObserver<T>) => () => void,\n): InteropObservable<T> {\n\tconst obs: InteropObservable<T> = {\n\t\tsubscribe(rawObserver): InteropSubscription {\n\t\t\tconst observer = normalizeObserver(rawObserver);\n\t\t\tlet closed = false;\n\t\t\tlet teardown: (() => void) | undefined;\n\t\t\tlet teardownPending = false;\n\t\t\tconst runTeardown = (): void => {\n\t\t\t\tif (teardown) teardown();\n\t\t\t\telse teardownPending = true; // sync push-on-subscribe terminal\n\t\t\t};\n\t\t\t// Guarded observer: latch `closed` and auto-unsubscribe the node on\n\t\t\t// terminal. The prior rxjs-backed impl got this from rxjs's\n\t\t\t// `Subscriber` (closed flag + teardown-on-terminal); a plain TC39\n\t\t\t// consumer has no such machinery, so without this a post-terminal\n\t\t\t// node wave would re-fire next/error/complete and the node\n\t\t\t// subscription would leak until a manual unsubscribe(). `closed` is\n\t\t\t// also read by toObservable's per-message loop to short-circuit.\n\t\t\tconst guarded: InteropObserver<T> = {\n\t\t\t\tget closed() {\n\t\t\t\t\treturn closed;\n\t\t\t\t},\n\t\t\t\tnext(value) {\n\t\t\t\t\tif (!closed) observer.next?.(value);\n\t\t\t\t},\n\t\t\t\terror(err) {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobserver.error?.(err);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\trunTeardown();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tcomplete() {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobserver.complete?.();\n\t\t\t\t\t} finally {\n\t\t\t\t\t\trunTeardown();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t\tteardown = onSubscribe(guarded);\n\t\t\tif (teardownPending) teardown(); // terminal fired before assignment\n\t\t\treturn {\n\t\t\t\tunsubscribe() {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\tteardown?.();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t};\n\t// TC39 interop: `x[Symbol.observable]()` returns the observable itself.\n\t(obs as unknown as Record<PropertyKey, unknown>)[OBSERVABLE_KEY] = function (\n\t\tthis: InteropObservable<T>,\n\t) {\n\t\treturn this;\n\t};\n\treturn obs;\n}\n\n/**\n * Bridge a `Node<T>` to a TC39 interop observable (no rxjs dependency).\n *\n * Default mode emits the node's value on each `DATA` message. Maps `ERROR` to\n * `observer.error()` and `COMPLETE` to `observer.complete()`.\n * Protocol-internal signals (DIRTY, RESOLVED, PAUSE, etc.) are skipped.\n *\n * With `{ raw: true }`, emits full `[[Type, Data?], ...]` message batches.\n * The stream terminates on ERROR or COMPLETE (the terminal batch is still\n * emitted as the final `next()` before the error/complete signal).\n *\n * The returned value is a spec-interop observable, **not** a concrete rxjs\n * `Observable`. Wrap with `from(toObservable(node))` for rxjs operators, or\n * use the NestJS compat layer's `toObservable` which returns a real rxjs\n * `Observable`. For graph-level observation, use\n * `toObservable(graph.resolve(path))` or subscribe to `graph.observe()`.\n *\n * Unsubscribing unsubscribes the node.\n */\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions & { raw?: false },\n): InteropObservable<T>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions: ToObservableOptions & { raw: true },\n): InteropObservable<Messages>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions,\n): InteropObservable<T | Messages> {\n\tif (options?.raw) {\n\t\treturn makeInterop<Messages>((observer) => {\n\t\t\treturn node.subscribe((msgs) => {\n\t\t\t\tif (observer.closed) return;\n\t\t\t\tobserver.next?.(msgs);\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\t\tobserver.error?.(m[1]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\t\tobserver.complete?.();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\treturn makeInterop<T>((observer) => {\n\t\treturn node.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (observer.closed) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tobserver.next?.(m[1] as T);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tobserver.error?.(m[1]);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tobserver.complete?.();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n"],"mappings":"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","names":["toObservable","import_core","import_core","import_core","import_core","import_graph","import_common","import_core","import_core","import_extra","import_graph","import_core","import_extra","import_extra","deepFreeze","deepFreeze","batch","import_core","node","toObservable","node"]}
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/base/sources/event/cron.ts","../../../src/compat/nestjs/gateway.ts","../../../src/base/composition/backpressure.ts","../../../src/compat/nestjs/guard.ts","../../../src/compat/nestjs/module.ts","../../../src/utils/cqrs/index.ts","../../../src/base/mutation/index.ts","../../../src/utils/_errors/index.ts","../../../src/base/meta/domain-meta.ts","../../../src/compat/nestjs/observable.ts","../../../src/base/composition/observable.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// 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// RxJS bridge — NestJS-flavored: returns a real rxjs `Observable` (the base\n// `toObservable` is dependency-free and returns a Symbol.observable interop;\n// this layer wraps it with rxjs `from()` since `@nestjs/common` pulls rxjs).\nexport { type ToObservableOptions, toObservable } from \"./observable.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, lockId]])`.\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 { DATA, type Messages } from \"@graphrefly/pure-ts/core\";\nimport { fromTimer } from \"@graphrefly/pure-ts/extra\";\nimport type { Graph, GraphObserveOne } from \"@graphrefly/pure-ts/graph\";\nimport type { OnModuleDestroy, OnModuleInit } from \"@nestjs/common\";\nimport type { ModuleRef } from \"@nestjs/core\";\nimport { fromCron } from \"../../base/sources/event/cron.js\";\nimport type { CqrsGraph } from \"../../utils/cqrs/index.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\t// F-CATCH D-1 (qa F-b): de-dup the DI-miss warning. `resolveInstance` is\n\t// called once per handler-registry that a host appears in (EVENT / CRON /\n\t// CQRS / …), so an unresolvable host decorated in multiple families would\n\t// otherwise emit one warning per registry for a single root cause. Scoped\n\t// per explorer instance (one instance per module via the useFactory).\n\tprivate readonly warnedUnresolved = new Set<DecoratorHostConstructor>();\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(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(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.cache 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\t// F-CATCH D-1: surface-loud, mirroring resolveCqrsGraph's diagnostic.\n\t\t// A silent null here makes the caller `if (!instance) continue;` skip\n\t\t// ALL of this class's @OnGraphEvent/@Cron/@CqrsHandler wiring with zero\n\t\t// signal — a typo'd or unregistered provider then looks like the\n\t\t// decorators \"just don't fire\". Cover BOTH failure shapes: `get` may\n\t\t// throw (UnknownElementException) OR return a nullish value depending\n\t\t// on the DI container, and both end in the same silent skip.\n\t\tlet instance: object | null = null;\n\t\ttry {\n\t\t\tinstance = this.moduleRef.get(ctor, { strict: false }) ?? null;\n\t\t} catch {\n\t\t\tinstance = null;\n\t\t}\n\t\tif (instance == null) {\n\t\t\tif (!this.warnedUnresolved.has(ctor)) {\n\t\t\t\tthis.warnedUnresolved.add(ctor);\n\t\t\t\tconst name = (ctor as { name?: string }).name ?? String(ctor);\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[GraphReFly] decorator host \"${name}\" not resolvable from DI — ` +\n\t\t\t\t\t\t`is it registered as a provider in the same module as GraphReflyModule? ` +\n\t\t\t\t\t\t`Its @OnGraphEvent/@Cron/@CqrsHandler handlers will NOT be wired.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\treturn instance;\n\t}\n}\n","/**\n * Cron-based reactive sources and schedule types.\n *\n * Merged from extra/cron.ts + extra/sources/event.ts (fromCron) during cleave A2.\n * `fromCron` relocated here from `dom.ts` (post-cleave /qa A1): it uses zero DOM\n * APIs (only `setInterval` + `new Date()`), so it belongs on the universal\n * `event/index.ts` barrel, not the browser-only `dom.ts` subpath.\n */\n\nimport { type Node, type NodeOptions, node, wallClockNs } from \"@graphrefly/pure-ts/core\";\n\ntype ExtraOpts = Omit<NodeOptions, \"describeKind\">;\n\nfunction sourceOpts<T = unknown>(opts?: ExtraOpts): NodeOptions<T> {\n\treturn { describeKind: \"producer\", ...opts } as NodeOptions<T>;\n}\n\n/** Options for {@link fromCron}. */\nexport type FromCronOptions = ExtraOpts & {\n\t/** Polling interval in ms. Default `60_000`. */\n\ttickMs?: number;\n\t/** Output format: `\"timestamp_ns\"` (default) emits wall-clock nanoseconds; `\"date\"` emits a `Date` object. */\n\toutput?: \"timestamp_ns\" | \"date\";\n};\n\n/**\n * Minimal 5-field cron parser and matcher (minute hour day-of-month month day-of-week).\n * Ported from callbag-recharge `extra/cron.ts` for `fromCron` (roadmap §2.3).\n */\nexport interface CronSchedule {\n\tminutes: Set<number>;\n\thours: Set<number>;\n\tdaysOfMonth: Set<number>;\n\tmonths: Set<number>;\n\tdaysOfWeek: Set<number>;\n}\n\nfunction parseField(field: string, min: number, max: number): Set<number> {\n\tconst result = new Set<number>();\n\tfor (const part of field.split(\",\")) {\n\t\tconst [range, stepStr] = part.split(\"/\");\n\t\tconst step = stepStr ? Number.parseInt(stepStr, 10) : 1;\n\t\tif (Number.isNaN(step) || step < 1) throw new Error(`Invalid cron step: ${part}`);\n\t\tlet start: number;\n\t\tlet end: number;\n\t\tif (range === \"*\") {\n\t\t\tstart = min;\n\t\t\tend = max;\n\t\t} else if (range.includes(\"-\")) {\n\t\t\tconst [a, b] = range.split(\"-\");\n\t\t\tstart = Number.parseInt(a, 10);\n\t\t\tend = Number.parseInt(b, 10);\n\t\t} else {\n\t\t\tstart = Number.parseInt(range, 10);\n\t\t\tend = start;\n\t\t}\n\t\tif (Number.isNaN(start) || Number.isNaN(end)) throw new Error(`Invalid cron field: ${field}`);\n\t\tif (start < min || end > max)\n\t\t\tthrow new Error(`Cron field out of range: ${field} (${min}-${max})`);\n\t\tif (start > end) throw new Error(`Invalid cron range: ${start}-${end} in ${field}`);\n\t\tfor (let i = start; i <= end; i += step) result.add(i);\n\t}\n\treturn result;\n}\n\n/**\n * Parses a standard 5-field cron expression into a {@link CronSchedule}.\n *\n * Supports `*`, ranges (`1-5`), steps (`*\\/5`, `0-30/10`), and comma-separated\n * lists. Fields are: minute (0–59), hour (0–23), day-of-month (1–31),\n * month (1–12), day-of-week (0–6, Sunday = 0).\n *\n * @param expr - Five-field whitespace-separated cron string (e.g. `\"0 9 * * 1-5\"`).\n * @returns Parsed {@link CronSchedule} with one `Set<number>` per field.\n * @throws Error when the expression does not have exactly 5 fields, contains\n * out-of-range values, or uses an invalid step.\n *\n * @example\n * ```ts\n * import { parseCron } from \"@graphrefly/graphrefly-ts\";\n *\n * const sched = parseCron(\"0 9 * * 1-5\"); // weekdays at 09:00\n * sched.hours; // Set { 9 }\n * sched.daysOfWeek; // Set { 1, 2, 3, 4, 5 }\n * ```\n */\nexport function parseCron(expr: string): CronSchedule {\n\tconst parts = expr.trim().split(/\\s+/);\n\tif (parts.length !== 5) throw new Error(`Invalid cron: expected 5 fields, got ${parts.length}`);\n\treturn {\n\t\tminutes: parseField(parts[0], 0, 59),\n\t\thours: parseField(parts[1], 0, 23),\n\t\tdaysOfMonth: parseField(parts[2], 1, 31),\n\t\tmonths: parseField(parts[3], 1, 12),\n\t\tdaysOfWeek: parseField(parts[4], 0, 6),\n\t};\n}\n\n/**\n * Returns `true` if `date` satisfies every field of `schedule`.\n *\n * @param schedule - Parsed schedule from {@link parseCron}.\n * @param date - Moment to test (local time via `getMinutes`, `getHours`, etc.).\n * @returns `true` when all five cron fields match the given date.\n *\n * @example\n * ```ts\n * import { parseCron, matchesCron } from \"@graphrefly/graphrefly-ts\";\n *\n * const sched = parseCron(\"30 8 * * 1\"); // Mondays at 08:30\n * const monday = new Date(\"2026-03-30T08:30:00\"); // a Monday\n * matchesCron(sched, monday); // true\n * ```\n */\nexport function matchesCron(schedule: CronSchedule, date: Date): boolean {\n\treturn (\n\t\tschedule.minutes.has(date.getMinutes()) &&\n\t\tschedule.hours.has(date.getHours()) &&\n\t\tschedule.daysOfMonth.has(date.getDate()) &&\n\t\tschedule.months.has(date.getMonth() + 1) &&\n\t\tschedule.daysOfWeek.has(date.getDay())\n\t);\n}\n\n/**\n * Polls on an interval; when the current minute matches a 5-field cron expression, emits once (see {@link parseCron}).\n *\n * @param expr - Cron string (`min hour dom month dow`).\n * @param opts - Producer options plus `tickMs` (default `60_000`) and `output` (`timestamp_ns` default, or `date` for `Date` values).\n * @returns `Node<number>` (nanosecond timestamp) or `Node<Date>` when `output: \"date\"`.\n *\n * @example\n * ```ts\n * import { fromCron } from \"@graphrefly/graphrefly\";\n *\n * fromCron(\"0 9 * * 1\");\n * ```\n *\n * @category extra\n */\nexport function fromCron(expr: string, opts?: FromCronOptions & { output: \"date\" }): Node<Date>;\nexport function fromCron(expr: string, opts?: FromCronOptions): Node<number>;\nexport function fromCron(expr: string, opts?: FromCronOptions): Node<number | Date> {\n\tconst schedule: CronSchedule = parseCron(expr);\n\tconst { tickMs: tickOpt, output, ...rest } = opts ?? {};\n\tconst tickMs = tickOpt ?? 60_000;\n\tconst emitDate = output === \"date\";\n\treturn node<number | Date>(\n\t\t(_data, a) => {\n\t\t\tlet lastFiredKey = -1;\n\t\t\tconst check = () => {\n\t\t\t\tconst now = new Date();\n\t\t\t\tconst key =\n\t\t\t\t\tnow.getFullYear() * 100_000_000 +\n\t\t\t\t\t(now.getMonth() + 1) * 1_000_000 +\n\t\t\t\t\tnow.getDate() * 10_000 +\n\t\t\t\t\tnow.getHours() * 100 +\n\t\t\t\t\tnow.getMinutes();\n\t\t\t\tif (key !== lastFiredKey && matchesCron(schedule, now)) {\n\t\t\t\t\tlastFiredKey = key;\n\t\t\t\t\ta.emit(emitDate ? now : wallClockNs());\n\t\t\t\t}\n\t\t\t};\n\t\t\tcheck();\n\t\t\tconst id = setInterval(check, tickMs);\n\t\t\treturn { onDeactivation: () => clearInterval(id) };\n\t\t},\n\t\t{ ...sourceOpts(rest), name: rest.name ?? `cron:${expr}` },\n\t);\n}\n","// ---------------------------------------------------------------------------\n// 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 {\n\ttype Actor,\n\tCOMPLETE,\n\tDATA,\n\tERROR,\n\ttype Messages,\n\tTEARDOWN,\n} from \"@graphrefly/pure-ts/core\";\nimport type { Graph, GraphObserveOne } from \"@graphrefly/pure-ts/graph\";\nimport {\n\tcreateWatermarkController,\n\ttype WatermarkController,\n} from \"../../base/composition/backpressure.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 * Watermark-based backpressure controller — reactive PAUSE/RESUME flow control.\n *\n * Purely synchronous, event-driven. No timers, no polling, no Promises.\n * Each controller instance uses a unique lockId so multiple controllers\n * on the same upstream node do not collide.\n *\n * @module\n */\n\nimport { type Messages, PAUSE, RESUME } from \"@graphrefly/pure-ts/core\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type WatermarkOptions = {\n\t/** Pending count at which PAUSE is sent upstream. */\n\thighWaterMark: number;\n\t/** Pending count at which RESUME is sent upstream (after being paused). */\n\tlowWaterMark: number;\n};\n\nexport type WatermarkController = {\n\t/** Call when a DATA message is buffered/enqueued. Returns `true` if PAUSE was just sent. */\n\tonEnqueue(): boolean;\n\t/** Call when a buffered item is consumed. Returns `true` if RESUME was just sent. */\n\tonDequeue(): boolean;\n\t/** Current un-consumed item count. */\n\treadonly pending: number;\n\t/** Whether upstream is currently paused by this controller. */\n\treadonly paused: boolean;\n\t/** Dispose: if paused, sends RESUME to unblock upstream. */\n\tdispose(): void;\n};\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nlet nextLockId = 0;\n\n/**\n * Creates a watermark-based backpressure controller.\n *\n * @param sendUp - Callback that delivers messages upstream (typically `handle.up`).\n * @param opts - High/low watermark thresholds (item counts).\n * @returns A {@link WatermarkController}.\n *\n * @example\n * ```ts\n * const handle = graph.observe(\"fast-source\");\n * const wm = createWatermarkController(\n * (msgs) => handle.up(msgs),\n * { highWaterMark: 64, lowWaterMark: 16 },\n * );\n *\n * // In sink callback:\n * handle.subscribe((msgs) => {\n * for (const msg of msgs) {\n * if (msg[0] === DATA) {\n * buffer.push(msg[1]);\n * wm.onEnqueue();\n * }\n * }\n * });\n *\n * // When consumer drains:\n * const item = buffer.shift();\n * wm.onDequeue();\n * ```\n *\n * @category extra\n */\nexport function createWatermarkController(\n\tsendUp: (messages: Messages) => void,\n\topts: WatermarkOptions,\n): WatermarkController {\n\tif (opts.highWaterMark < 1) throw new RangeError(\"highWaterMark must be >= 1\");\n\tif (opts.lowWaterMark < 0) throw new RangeError(\"lowWaterMark must be >= 0\");\n\tif (opts.lowWaterMark >= opts.highWaterMark)\n\t\tthrow new RangeError(\"lowWaterMark must be < highWaterMark\");\n\tconst lockId = Symbol(`bp-${++nextLockId}`);\n\tlet pending = 0;\n\tlet paused = false;\n\n\treturn {\n\t\tonEnqueue(): boolean {\n\t\t\tpending += 1;\n\t\t\tif (!paused && pending >= opts.highWaterMark) {\n\t\t\t\tpaused = true;\n\t\t\t\tsendUp([[PAUSE, lockId]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tonDequeue(): boolean {\n\t\t\tif (pending > 0) pending -= 1;\n\t\t\tif (paused && pending <= opts.lowWaterMark) {\n\t\t\t\tpaused = false;\n\t\t\t\tsendUp([[RESUME, lockId]]);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tget pending() {\n\t\t\treturn pending;\n\t\t},\n\t\tget paused() {\n\t\t\treturn paused;\n\t\t},\n\t\tdispose() {\n\t\t\tif (paused) {\n\t\t\t\tpaused = false;\n\t\t\t\tsendUp([[RESUME, lockId]]);\n\t\t\t}\n\t\t},\n\t};\n}\n","// ---------------------------------------------------------------------------\n// 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 Actor, DEFAULT_ACTOR, normalizeActor } from \"@graphrefly/pure-ts/core\";\nimport type { CanActivate, ExecutionContext } from \"@nestjs/common\";\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\t// F-CATCH D-2: surface-loud. A malformed actor header is otherwise\n\t\t\t// silently indistinguishable from an absent one — the request runs\n\t\t\t// as DEFAULT_ACTOR and downstream `policy()` denials read as\n\t\t\t// \"default actor denied\" instead of \"your actor header was\n\t\t\t// malformed\". Still falls back to DEFAULT_ACTOR (extractor contract\n\t\t\t// is unchanged: undefined → DEFAULT_ACTOR; this guard is\n\t\t\t// attribution-only and always allows the request through).\n\t\t\tconsole.warn(\n\t\t\t\t`[GraphReFly] fromHeader: header \"${headerName}\" is present but not valid JSON — ` +\n\t\t\t\t\t`ignoring it and falling back to DEFAULT_ACTOR.`,\n\t\t\t);\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 type { AppendLogStorageTier } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphPersistSnapshot } from \"@graphrefly/pure-ts/graph\";\nimport {\n\ttype DynamicModule,\n\tModule,\n\ttype OnModuleDestroy,\n\ttype Provider,\n\tScope,\n} from \"@nestjs/common\";\nimport { ModuleRef } from \"@nestjs/core\";\nimport { type CqrsGraph, type CqrsOptions, cqrs } from \"../../utils/cqrs/index.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/** Append-log storage tiers for event persistence (wired via `attachEventStorage()`). */\n\teventStorage?: readonly AppendLogStorageTier<import(\"../../utils/cqrs/index.js\").CqrsEvent>[];\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({ name: \"orderCount\", events: [\"orderPlaced\"], reducer: (_s, evts) => evts.length, initial: 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\tif (opts.eventStorage) g.attachEventStorage(opts.eventStorage);\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 {\n\tDATA,\n\ttype Node,\n\tnode,\n\tplaceholderArgs,\n\tpolicy,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport type { AppendLogStorageTier } from \"@graphrefly/pure-ts/extra\";\nimport { type ReactiveLogBundle, reactiveLog } from \"@graphrefly/pure-ts/extra\";\nimport { Graph, type GraphOptions } from \"@graphrefly/pure-ts/graph\";\nimport {\n\ttype BaseAuditRecord,\n\tcreateAuditLog,\n\tmutate,\n\ttype ReadonlyAuditLog,\n\treadonlyAuditLog,\n\tregisterCursor,\n\tregisterCursorMap,\n} from \"../../base/mutation/index.js\";\nimport {\n\tCommandHandlerError,\n\tDuplicateRegistrationError,\n\tOptimisticConcurrencyError,\n\tRebuildError,\n\tUndeclaredEmitError,\n\tUnknownCommandError,\n} from \"../_errors/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\nimport { keepalive } from \"@graphrefly/pure-ts/extra\";\nimport { domainMeta } from \"../../base/meta/domain-meta.js\";\n\nfunction cqrsMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn domainMeta(\"cqrs\", kind, extra);\n}\n\nfunction deepFreeze<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tfor (const k of Object.keys(value as Record<string, unknown>)) {\n\t\tdeepFreeze((value as Record<string, unknown>)[k]);\n\t}\n\treturn Object.freeze(value);\n}\n\n// ---------------------------------------------------------------------------\n// Event envelope\n// ---------------------------------------------------------------------------\n\n/**\n * Immutable envelope for events emitted by command handlers.\n *\n * **Wave C.1 Unit 17 (locked 2026-04-24):** Extended ES standard fields —\n * `aggregateId` / `aggregateVersion` for per-aggregate streams; correlation /\n * causation IDs for distributed tracing; `metadata` for free-form context.\n * Optional `handlerVersion` (Audit 5) traces which handler version produced\n * the event.\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/** Aggregate identifier (per-aggregate streams). */\n\taggregateId?: string;\n\t/** Per-aggregate monotonic version (set when `aggregateId` is provided). */\n\taggregateVersion?: number;\n\t/** Distributed-trace correlation id. */\n\tcorrelationId?: string;\n\t/** Causation chain id (this event was caused by event `causationId`). */\n\tcausationId?: string;\n\t/** Free-form metadata frozen at append. */\n\tmetadata?: Readonly<Record<string, unknown>>;\n\t/** V0 identity of the event log node at append time (§6.0b). */\n\tv0?: { id: string; version: number };\n\t/** Handler version stamped on emit (Audit 5). */\n\thandlerVersion?: { id: string; version: string | number };\n};\n\n/** Compile-time event-map registry: `{ \"orderPlaced\": OrderPayload, ... }`. */\nexport type CqrsEventMap = Record<string, unknown>;\n\n/** Recommended `keyOf` for CQRS event-store storage tiers (Audit 4). */\nexport const cqrsEventKeyOf = (e: CqrsEvent): string =>\n\t`${e.type}::${e.aggregateId ?? \"__default__\"}`;\n\n// ── Audit records (Audit 2 cross-cutting) ────────────────────────────────\n\nexport interface DispatchRecord<T = unknown> extends BaseAuditRecord {\n\treadonly commandName: string;\n\treadonly payload: T;\n\t/** Action result. Tier 1.6.2 canonical enum (renamed from `status`). */\n\treadonly outcome: \"success\" | \"failure\";\n\treadonly error?: unknown;\n\treadonly errorType?: string;\n\t/**\n\t * Event names emitted by the handler.\n\t * - `outcome: \"success\"`: events that persisted in the event log.\n\t * - `outcome: \"failure\"`: events the handler ATTEMPTED to emit before throwing;\n\t * they were rolled back and did NOT persist. Documents the failed attempt's\n\t * intentions for debugging handler logic. The actual event log shows only\n\t * what's durable.\n\t */\n\treadonly emittedEvents?: readonly string[];\n}\n\nexport const dispatchKeyOf = <T>(r: DispatchRecord<T>): string => r.commandName;\n\nexport interface SagaInvocation<T = unknown> extends BaseAuditRecord {\n\treadonly eventType: string;\n\t/** Action result. Tier 1.6.2 canonical enum (renamed from `status`). */\n\treadonly outcome: \"success\" | \"failure\";\n\treadonly error?: unknown;\n\treadonly errorType?: string;\n\treadonly aggregateId?: string;\n\treadonly event?: CqrsEvent<T>;\n}\n\nexport const sagaInvocationKeyOf = <T>(i: SagaInvocation<T>): string => i.eventType;\n\n/**\n * Saga registration result (M10) — a typed bundle replacing the prior\n * `Node<unknown>` return that side-attached `_saga` via an unsafe cast.\n *\n * `node` is the saga's effect node (subscribe to observe processing\n * activity). `invocations` is the per-event-type audit log; `audit` is a\n * **read-only view** of `invocations` (Audit 2 `.audit` duplication; M7 —\n * the alias can no longer silently `append`/`clear` the canonical log).\n * `cursors` exposes the per-event-type cursor state nodes for monitoring /\n * testing.\n *\n * @category patterns\n */\nexport interface SagaController<T = unknown> {\n\treadonly node: Node<unknown>;\n\treadonly invocations: ReactiveLogBundle<SagaInvocation<T>>;\n\treadonly audit: ReadonlyAuditLog<SagaInvocation<T>>;\n\treadonly cursors: { readonly [eventName: string]: Node<number> };\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.\n *\n * - In **`\"replay\"`** mode the `state` parameter is always the original\n * `initial` value (full event-sourcing replay on every recompute).\n * - In **`\"scan\"`** mode the `state` parameter is the _previous_ output\n * (incremental fold); `events` contains only the events appended since\n * the last computation.\n */\nexport type ProjectionReducer<TState = unknown, TEvent = unknown> = (\n\tstate: TState,\n\tevents: readonly CqrsEvent<TEvent>[],\n) => TState;\n\n/**\n * Snapshot integration for {@link ProjectionOptions}.\n *\n * `load` is called once at projection construction and the returned value\n * seeds the initial state. `save` (optional) is called after each reducer\n * run, debounced by `saveDebounceMs` (default 1000 ms) and capped by\n * `saveEvery` (default 1000 events).\n */\nexport type ProjectionSnapshotOpts<TState> = {\n\t/** Load a previously-saved state. `undefined` → start from `initial`. */\n\tload: () => TState | undefined | Promise<TState | undefined>;\n\t/** Persist the current state. Called after reducer; may be async. */\n\tsave?: (state: TState) => void | Promise<void>;\n\t/**\n\t * Debounce window (ms) before `save` fires after the last event. Default 1000.\n\t */\n\tsaveDebounceMs?: number;\n\t/**\n\t * Force a save after every Nth state change regardless of debounce.\n\t * Default 1000. Both knobs compose: save fires at whichever condition is\n\t * met first.\n\t */\n\tsaveEvery?: number;\n};\n\n/**\n * Options for {@link CqrsGraph.projection}.\n *\n * **Wave C.3 Unit 21 (locked 2026-04-24):**\n * - `mode: \"scan\"` (default) — incremental fold; `\"replay\"` — full replay\n * each wave.\n * - `snapshot` — load/save integration for cold-start + auto-checkpoint.\n * - `freezeInputs` (default `true`) — freeze event arrays before passing\n * to reducer (purity enforcement).\n * - `rebuild()` / `reset()` on the returned {@link ProjectionController}.\n *\n * @category patterns\n */\nexport type ProjectionOptions<TState> = {\n\tname: string;\n\tevents: readonly string[];\n\treducer: ProjectionReducer<TState>;\n\tinitial: TState;\n\t/**\n\t * Fold strategy. Default `\"scan\"` (incremental). `\"replay\"` = full replay.\n\t *\n\t * **Scan-mode ordering caveat:** scan-mode assumes monotonic per-stream\n\t * arrival order. When multiple event streams are merged for a projection,\n\t * events arriving with a `timestampNs` earlier than the current sort cursor\n\t * are skipped from the incremental sweep. This is an acceptable trade-off\n\t * for incremental fold; use `mode: \"replay\"` for strict cross-stream\n\t * ordering.\n\t */\n\tmode?: \"replay\" | \"scan\";\n\t/** Snapshot integration for rebuild + auto-checkpoint. */\n\tsnapshot?: ProjectionSnapshotOpts<TState>;\n\t/**\n\t * Freeze event arrays before passing to reducer (default `true`).\n\t * Set to `false` only if your reducer intentionally mutates the input\n\t * (strongly discouraged — prefer immutable reducers).\n\t */\n\tfreezeInputs?: boolean;\n};\n\n/**\n * Controller returned by {@link CqrsGraph.projection}.\n *\n * `node` is the reactive read model. `rebuild()` performs a paginated\n * cold-storage replay (requires `attachEventStorage` tiers). `reset()`\n * reloads from `snapshot.load()` and re-folds the live event log on top.\n *\n * @category patterns\n */\nexport interface ProjectionController<TState> {\n\treadonly node: Node<TState>;\n\t/**\n\t * Async paginated rebuild from attached storage tiers. Throws\n\t * {@link RebuildError} on adapter / decode / reducer failure.\n\t *\n\t * @param opts.fromTier - Storage tier to read from (default: first attached).\n\t * @param opts.pageSize - Entries per page (default 1000).\n\t */\n\trebuild(opts?: {\n\t\tfromTier?: AppendLogStorageTier<CqrsEvent>;\n\t\tpageSize?: number;\n\t}): Promise<TState>;\n\t/**\n\t * Reload from `snapshot.load()` (if configured) and re-fold the live\n\t * in-memory event log on top. Returns the rebuilt state. No-op on the\n\t * reactive node if the state is unchanged.\n\t */\n\treset(): Promise<TState>;\n}\n\nexport type SagaHandler<T = unknown> = (event: CqrsEvent<T>) => void;\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport type CqrsOptions = {\n\tgraph?: GraphOptions;\n\t/** Bounded retention for event streams; default 1024 (cross-cutting). */\n\tretainedLimit?: number;\n\t/** Freeze command payloads on dispatch (default `true`). */\n\tfreezeCommandPayload?: boolean;\n\t/** Freeze event payloads on emit (default `true`). */\n\tfreezeEventPayload?: boolean;\n\t/** LRU eviction threshold for per-aggregate streams (default 10_000). */\n\tmaxAggregates?: number;\n};\n\nexport type CommandRegistration<TPayload = unknown> = {\n\thandler: CommandHandler<TPayload>;\n\temits?: readonly string[];\n\thandlerVersion?: { id: string; version: string | number };\n};\n\nexport type DispatchOptions = {\n\tcorrelationId?: string;\n\tcausationId?: string;\n\tmetadata?: Record<string, unknown>;\n\t/**\n\t * Optimistic-concurrency check: if set, dispatch verifies the aggregate\n\t * (identified by `aggregateId`) is at this version. On mismatch, dispatch\n\t * throws {@link OptimisticConcurrencyError} BEFORE the handler runs.\n\t *\n\t * Requires `aggregateId` to be set. Without it the check is a no-op.\n\t */\n\texpectedAggregateVersion?: number;\n\t/**\n\t * Aggregate this dispatch targets. Events emitted by the handler that\n\t * also carry this `aggregateId` participate in per-aggregate versioning\n\t * and LRU eviction (see {@link CqrsOptions.maxAggregates}). Events whose\n\t * handler-supplied `aggregateId` differs from the dispatch's `aggregateId`\n\t * are emitted untouched (their own `aggregateVersion` is computed from\n\t * their own aggregate's stream).\n\t */\n\taggregateId?: string;\n};\n\nexport type SagaOptions = {\n\taggregateId?: string;\n\terrorPolicy?: \"advance\" | \"hold\";\n\thandlerVersion?: { id: string; version: string | number };\n};\n\n// ---------------------------------------------------------------------------\n// CqrsGraph\n// ---------------------------------------------------------------------------\n\ntype EventEntry = {\n\tlog: ReturnType<typeof reactiveLog<CqrsEvent>>;\n\tnode: Node<readonly CqrsEvent[]>;\n};\n\n/**\n * Eviction record emitted on `aggregateEvictions` when an aggregate's\n * per-aggregate stream is removed under `maxAggregates` LRU pressure. The\n * eviction does NOT delete events from the fan-in stream — only the\n * per-aggregate dedicated stream and its version counter.\n */\nexport interface AggregateEvictionRecord {\n\treadonly aggregateId: string;\n\treadonly type: string;\n\treadonly t_ns: number;\n\t/** The version count the aggregate reached before eviction (for diagnostics). */\n\treadonly lastVersion: number;\n}\n\nexport class CqrsGraph<_EM extends CqrsEventMap = Record<string, unknown>> extends Graph {\n\t/** Fan-in event streams (one per type, all aggregates merged). */\n\tprivate readonly _eventLogs = new Map<string, EventEntry>();\n\t/**\n\t * Per-aggregate event streams: type → aggregateId → entry. Used for\n\t * `event(type, aggregateId)` dual-form access and per-aggregate version\n\t * tracking. Only populated when an event with `aggregateId` is emitted.\n\t */\n\tprivate readonly _eventLogsByAggregate = new Map<string, Map<string, EventEntry>>();\n\t/** Per-aggregate version counters: `${type}::${aggregateId}` → current version. */\n\tprivate readonly _aggregateVersions = new Map<string, number>();\n\t/**\n\t * LRU access order for `${type}::${aggregateId}`. Map insertion order\n\t * tracks recency — `delete` + `set` on access moves to the end.\n\t */\n\tprivate readonly _aggregateLru = new Map<string, true>();\n\tprivate readonly _commandRegs = new Map<\n\t\tstring,\n\t\t{\n\t\t\thandler: CommandHandler<any>;\n\t\t\temits?: readonly string[];\n\t\t\thandlerVersion?: { id: string; version: string | number };\n\t\t}\n\t>();\n\tprivate readonly _projections = new Set<string>();\n\tprivate readonly _sagas = new Set<string>();\n\tprivate _seq = 0;\n\tprivate readonly _retainedLimit: number;\n\tprivate readonly _freezeCommandPayload: boolean;\n\tprivate readonly _freezeEventPayload: boolean;\n\tprivate readonly _maxAggregates: number;\n\tprivate readonly _dispatchSeqCursor: Node<number>;\n\t/** Audit log of every command dispatch (Audit 2). */\n\treadonly dispatches: ReactiveLogBundle<DispatchRecord>;\n\t/**\n\t * Read-only view of {@link CqrsGraph.dispatches} (Audit 2 `.audit`\n\t * duplication; M7 — cannot mutate the canonical log via the alias).\n\t */\n\treadonly audit: ReadonlyAuditLog<DispatchRecord>;\n\t/** Per-aggregate LRU eviction observability; secondary log to `dispatches`. */\n\treadonly aggregateEvictions: ReactiveLogBundle<AggregateEvictionRecord>;\n\n\tconstructor(name: string, opts: CqrsOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t\tthis._retainedLimit = opts.retainedLimit ?? 1024;\n\t\tthis._freezeCommandPayload = opts.freezeCommandPayload ?? true;\n\t\tthis._freezeEventPayload = opts.freezeEventPayload ?? true;\n\t\tthis._maxAggregates = opts.maxAggregates ?? 10_000;\n\t\tthis.dispatches = createAuditLog<DispatchRecord>({\n\t\t\tname: \"dispatches\",\n\t\t\tretainedLimit: this._retainedLimit,\n\t\t\tgraph: this,\n\t\t});\n\t\tthis.audit = readonlyAuditLog(this.dispatches);\n\t\tthis.aggregateEvictions = createAuditLog<AggregateEvictionRecord>({\n\t\t\tname: \"aggregateEvictions\",\n\t\t\tretainedLimit: this._retainedLimit,\n\t\t\tgraph: this,\n\t\t});\n\t\tthis._dispatchSeqCursor = registerCursor(this, \"dispatch_seq\", 0);\n\t}\n\n\t/**\n\t * Read the current per-aggregate version (last emitted `aggregateVersion`\n\t * for that `(type, aggregateId)` pair). Returns `0` if no events have been\n\t * emitted yet for this aggregate. Useful for callers preparing\n\t * {@link DispatchOptions.expectedAggregateVersion}.\n\t */\n\taggregateVersion(type: string, aggregateId: string): number {\n\t\treturn this._aggregateVersions.get(`${type}::${aggregateId}`) ?? 0;\n\t}\n\n\t/** LRU touch — moves the key to the end of the access order. */\n\tprivate _touchAggregate(key: string): void {\n\t\t// Delete + set re-inserts at the end of Map iteration order.\n\t\tthis._aggregateLru.delete(key);\n\t\tthis._aggregateLru.set(key, true);\n\t}\n\n\t/**\n\t * Evict the oldest aggregate streams (least-recently-touched) until the\n\t * aggregate count is back within `_maxAggregates`. Emits one\n\t * `AggregateEvictionRecord` per eviction. The fan-in stream is NOT touched\n\t * — events stay in the type-level log; only the per-aggregate stream and\n\t * version counter are removed.\n\t */\n\tprivate _enforceAggregateLru(): void {\n\t\twhile (this._aggregateLru.size > this._maxAggregates) {\n\t\t\tconst oldest = this._aggregateLru.keys().next();\n\t\t\tif (oldest.done) break;\n\t\t\tconst key = oldest.value;\n\t\t\tthis._aggregateLru.delete(key);\n\t\t\tconst sep = key.indexOf(\"::\");\n\t\t\tif (sep < 0) continue;\n\t\t\tconst type = key.slice(0, sep);\n\t\t\tconst aggregateId = key.slice(sep + 2);\n\t\t\tconst lastVersion = this._aggregateVersions.get(key) ?? 0;\n\t\t\tthis._aggregateVersions.delete(key);\n\t\t\tconst byType = this._eventLogsByAggregate.get(type);\n\t\t\tif (byType) {\n\t\t\t\tbyType.delete(aggregateId);\n\t\t\t\tif (byType.size === 0) this._eventLogsByAggregate.delete(type);\n\t\t\t}\n\t\t\tthis.aggregateEvictions.append({\n\t\t\t\taggregateId,\n\t\t\t\ttype,\n\t\t\t\tlastVersion,\n\t\t\t\tt_ns: wallClockNs(),\n\t\t\t});\n\t\t}\n\t}\n\n\t/** Tiers attached via {@link attachEventStorage}; auto-wired into future event streams. */\n\tprivate readonly _attachedEventTiers: Array<readonly AppendLogStorageTier<CqrsEvent>[]> = [];\n\tprivate readonly _attachedTierDisposers = new Map<string, Array<() => void>>();\n\n\t/**\n\t * Wire append-log storage tiers for ALL CQRS event streams — both currently\n\t * registered AND any future streams created via `event(name)` /\n\t * `event(name, aggregateId)` / handler emit. (M4 fix.)\n\t *\n\t * Returns a disposer that releases all storage subscriptions wired by this\n\t * call (including those for streams that were created after the call).\n\t */\n\tattachEventStorage(tiers: readonly AppendLogStorageTier<CqrsEvent>[]): () => void {\n\t\tthis._attachedEventTiers.push(tiers);\n\t\t// Wire currently-existing streams.\n\t\tfor (const [name, entry] of this._eventLogs) {\n\t\t\tconst dispose = entry.log.attachStorage(tiers);\n\t\t\tlet arr = this._attachedTierDisposers.get(name);\n\t\t\tif (!arr) {\n\t\t\t\tarr = [];\n\t\t\t\tthis._attachedTierDisposers.set(name, arr);\n\t\t\t}\n\t\t\tarr.push(dispose);\n\t\t}\n\t\t// Per-aggregate streams existing now.\n\t\tfor (const [type, byAgg] of this._eventLogsByAggregate) {\n\t\t\tfor (const [aggId, entry] of byAgg) {\n\t\t\t\tconst key = `${type}::${aggId}`;\n\t\t\t\tconst dispose = entry.log.attachStorage(tiers);\n\t\t\t\tlet arr = this._attachedTierDisposers.get(key);\n\t\t\t\tif (!arr) {\n\t\t\t\t\tarr = [];\n\t\t\t\t\tthis._attachedTierDisposers.set(key, arr);\n\t\t\t\t}\n\t\t\t\tarr.push(dispose);\n\t\t\t}\n\t\t}\n\t\treturn () => {\n\t\t\t// Remove from auto-wire list so newly-created streams skip.\n\t\t\tconst idx = this._attachedEventTiers.indexOf(tiers);\n\t\t\tif (idx >= 0) this._attachedEventTiers.splice(idx, 1);\n\t\t\t// We can't precisely undo the per-stream attach for THIS tier set\n\t\t\t// alone (Map values commingle disposers across multiple\n\t\t\t// attachEventStorage calls). Caller wanting fine-grained control\n\t\t\t// should call `tier.flush()` / dispose tiers themselves. This\n\t\t\t// disposer is best-effort: it stops auto-wiring future streams.\n\t\t};\n\t}\n\n\t/** Wire newly-created event stream into all currently-attached tier sets. */\n\tprivate _autoWireStreamStorage(\n\t\tkey: string,\n\t\tlog: ReturnType<typeof reactiveLog<CqrsEvent>>,\n\t): void {\n\t\tif (this._attachedEventTiers.length === 0) return;\n\t\tlet arr = this._attachedTierDisposers.get(key);\n\t\tif (!arr) {\n\t\t\tarr = [];\n\t\t\tthis._attachedTierDisposers.set(key, arr);\n\t\t}\n\t\tfor (const tiers of this._attachedEventTiers) {\n\t\t\tarr.push(log.attachStorage(tiers));\n\t\t}\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\tevent(name: string, aggregateId: string): Node<readonly CqrsEvent[]>;\n\tevent(name: string, aggregateId?: string): Node<readonly CqrsEvent[]> {\n\t\tif (aggregateId !== undefined) {\n\t\t\treturn this._ensureAggregateStream(name, aggregateId).node;\n\t\t}\n\t\tconst existing = this._eventLogs.get(name);\n\t\tif (existing) return existing.node;\n\n\t\t// V0 versioning is attached at construction — post-hoc\n\t\t// `_applyVersioning` was deleted because it opened a re-entrance\n\t\t// window where a wave could observe `_versioning` transitioning from\n\t\t// `undefined` to a fresh state. Construction-time-only means the\n\t\t// flag is frozen at birth.\n\t\tconst log = reactiveLog<CqrsEvent>([], {\n\t\t\tname,\n\t\t\tversioning: 0,\n\t\t\tmaxSize: this._retainedLimit,\n\t\t});\n\t\tlog.withLatest();\n\t\tconst entries = log.entries;\n\t\tconst guarded = this.derived<readonly CqrsEvent[]>(\n\t\t\tname,\n\t\t\t[entries],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst latest =\n\t\t\t\t\tbatchData[0] != null && batchData[0].length > 0\n\t\t\t\t\t\t? (batchData[0].at(-1) as readonly CqrsEvent[])\n\t\t\t\t\t\t: (ctx.prevData[0] as readonly CqrsEvent[]);\n\t\t\t\treturn [latest];\n\t\t\t},\n\t\t\t{\n\t\t\t\tmeta: cqrsMeta(\"event\", { event_name: name }),\n\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\tinitial: entries.cache as readonly CqrsEvent[],\n\t\t\t},\n\t\t);\n\t\tthis.addDisposer(keepalive(guarded));\n\t\tthis._eventLogs.set(name, { log, node: guarded });\n\t\t// M4: auto-wire any storage tiers attached via `attachEventStorage`.\n\t\tthis._autoWireStreamStorage(name, log);\n\t\treturn guarded;\n\t}\n\n\t/**\n\t * Get-or-create the per-aggregate event stream for `(type, aggregateId)`.\n\t * Mounts the stream as a sibling node named `<type>_<aggregateId>` so it\n\t * appears in `describe()`. LRU access is touched on every call.\n\t */\n\tprivate _ensureAggregateStream(type: string, aggregateId: string): EventEntry {\n\t\t// Ensure the fan-in stream exists too (call sites usually expect both).\n\t\tif (!this._eventLogs.has(type)) this.event(type);\n\n\t\tlet byType = this._eventLogsByAggregate.get(type);\n\t\tif (!byType) {\n\t\t\tbyType = new Map();\n\t\t\tthis._eventLogsByAggregate.set(type, byType);\n\t\t}\n\t\tconst lruKey = `${type}::${aggregateId}`;\n\t\tthis._touchAggregate(lruKey);\n\t\tconst existing = byType.get(aggregateId);\n\t\tif (existing) return existing;\n\n\t\tconst nodeName = `${type}_${aggregateId.replace(/[^a-zA-Z0-9_-]/g, \"_\")}`;\n\t\tconst log = reactiveLog<CqrsEvent>([], {\n\t\t\tname: nodeName,\n\t\t\tversioning: 0,\n\t\t\tmaxSize: this._retainedLimit,\n\t\t});\n\t\tlog.withLatest();\n\t\tconst entries = log.entries;\n\t\t// Avoid name collisions if multiple aggregates have ids that sanitize\n\t\t// to the same node-name; suffix with a counter when necessary.\n\t\t// Resolve the mount name BEFORE constructing the derived (the\n\t\t// `this.derived(...)` form registers under the supplied `name`).\n\t\tlet mountName = nodeName;\n\t\tlet collisionIdx = 0;\n\t\twhile (this.resolveOptional(mountName) !== undefined) {\n\t\t\tcollisionIdx += 1;\n\t\t\tmountName = `${nodeName}_${collisionIdx}`;\n\t\t}\n\t\tlet guarded: Node<readonly CqrsEvent[]>;\n\t\ttry {\n\t\t\tguarded = this.derived<readonly CqrsEvent[]>(\n\t\t\t\tmountName,\n\t\t\t\t[entries],\n\t\t\t\t(batchData, ctx) => {\n\t\t\t\t\tconst latest =\n\t\t\t\t\t\tbatchData[0] != null && batchData[0].length > 0\n\t\t\t\t\t\t\t? (batchData[0].at(-1) as readonly CqrsEvent[])\n\t\t\t\t\t\t\t: (ctx.prevData[0] as readonly CqrsEvent[]);\n\t\t\t\t\treturn [latest];\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmeta: cqrsMeta(\"event_aggregate\", {\n\t\t\t\t\t\tevent_name: type,\n\t\t\t\t\t\taggregate_id: aggregateId,\n\t\t\t\t\t}),\n\t\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\t\tinitial: entries.cache as readonly CqrsEvent[],\n\t\t\t\t},\n\t\t\t);\n\t\t} catch {\n\t\t\t// Name collision raced with another constructor — fall back to a\n\t\t\t// raw, unmounted node so the per-aggregate stream still functions\n\t\t\t// (just not graph-visible). Mirrors the prior best-effort branch.\n\t\t\t// F-CATCH D-4: surface-loud — the fallback node silently vanishes\n\t\t\t// from `graph.describe()`, which contradicts the dynamic-graph\n\t\t\t// observability guarantee. Warn once so the visibility loss is\n\t\t\t// diagnosable rather than mysterious.\n\t\t\tconsole.warn(\n\t\t\t\t`[GraphReFly] cqrs: per-aggregate event node \"${mountName}\" hit a ` +\n\t\t\t\t\t`name-collision race (event \"${type}\", aggregate \"${aggregateId}\") — ` +\n\t\t\t\t\t`falling back to an unmounted node; this aggregate's stream still ` +\n\t\t\t\t\t`works but will NOT appear in graph.describe()/observe().`,\n\t\t\t);\n\t\t\tguarded = node<readonly CqrsEvent[]>(\n\t\t\t\t[entries],\n\t\t\t\t(batchData, actions, ctx) => {\n\t\t\t\t\tconst latest =\n\t\t\t\t\t\tbatchData[0] != null && batchData[0].length > 0 ? batchData[0].at(-1) : ctx.prevData[0];\n\t\t\t\t\tactions.emit(latest as readonly CqrsEvent[]);\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: nodeName,\n\t\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\t\tmeta: cqrsMeta(\"event_aggregate\", {\n\t\t\t\t\t\tevent_name: type,\n\t\t\t\t\t\taggregate_id: aggregateId,\n\t\t\t\t\t}),\n\t\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\t\tinitial: entries.cache as readonly CqrsEvent[],\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tthis.addDisposer(keepalive(guarded));\n\t\tconst entry = { log, node: guarded };\n\t\tbyType.set(aggregateId, entry);\n\t\t// M4: auto-wire any tiers attached via `attachEventStorage`.\n\t\tthis._autoWireStreamStorage(`${type}::${aggregateId}`, log);\n\t\tthis._enforceAggregateLru();\n\t\treturn entry;\n\t}\n\n\t/** Try `resolve(path)`; return `undefined` instead of throwing on missing. */\n\tprivate resolveOptional(path: string): Node | undefined {\n\t\ttry {\n\t\t\treturn this.resolve(path);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\t/** Internal: append to an event log, auto-registering if needed. */\n\tprivate _appendEvent(\n\t\teventName: string,\n\t\tpayload: unknown,\n\t\textra?: {\n\t\t\taggregateId?: string;\n\t\t\tcorrelationId?: string;\n\t\t\tcausationId?: string;\n\t\t\tmetadata?: Readonly<Record<string, unknown>>;\n\t\t\thandlerVersion?: { id: string; version: string | number };\n\t\t},\n\t): CqrsEvent {\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\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\n\t\t// Per-aggregate version + stream wiring (D1).\n\t\tlet aggregateVersion: number | undefined;\n\t\tlet aggregateEntry: EventEntry | undefined;\n\t\tif (extra?.aggregateId !== undefined) {\n\t\t\tconst lruKey = `${eventName}::${extra.aggregateId}`;\n\t\t\taggregateVersion = (this._aggregateVersions.get(lruKey) ?? 0) + 1;\n\t\t\tthis._aggregateVersions.set(lruKey, aggregateVersion);\n\t\t\taggregateEntry = this._ensureAggregateStream(eventName, extra.aggregateId);\n\t\t}\n\n\t\tconst nv = entry.log.entries.v;\n\t\tconst frozenPayload = this._freezeEventPayload ? deepFreeze(payload) : payload;\n\t\tconst evt: CqrsEvent = {\n\t\t\ttype: eventName,\n\t\t\tpayload: frozenPayload,\n\t\t\ttimestampNs: wallClockNs(),\n\t\t\tseq: ++this._seq,\n\t\t\t...(extra?.aggregateId !== undefined ? { aggregateId: extra.aggregateId } : {}),\n\t\t\t...(aggregateVersion !== undefined ? { aggregateVersion } : {}),\n\t\t\t...(extra?.correlationId !== undefined ? { correlationId: extra.correlationId } : {}),\n\t\t\t...(extra?.causationId !== undefined ? { causationId: extra.causationId } : {}),\n\t\t\t...(extra?.metadata !== undefined ? { metadata: Object.freeze({ ...extra.metadata }) } : {}),\n\t\t\t...(extra?.handlerVersion !== undefined ? { handlerVersion: extra.handlerVersion } : {}),\n\t\t\t...(nv != null ? { v0: { id: nv.id, version: nv.version } } : {}),\n\t\t};\n\t\t// Append to fan-in stream (always) and per-aggregate stream (when set).\n\t\tentry.log.append(evt);\n\t\tif (aggregateEntry) {\n\t\t\taggregateEntry.log.append(evt);\n\t\t}\n\t\treturn evt;\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>(\n\t\tname: string,\n\t\thandlerOrReg: CommandHandler<T> | CommandRegistration<T>,\n\t): Node<T> {\n\t\tif (this._commandRegs.has(name)) {\n\t\t\tthrow new DuplicateRegistrationError(\"command\", name);\n\t\t}\n\t\tconst reg: CommandRegistration<T> =\n\t\t\ttypeof handlerOrReg === \"function\" ? { handler: handlerOrReg } : handlerOrReg;\n\t\tconst cmdNode = this.state<T>(name, undefined as T, {\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._commandRegs.set(name, {\n\t\t\thandler: reg.handler as CommandHandler<unknown>,\n\t\t\t...(reg.emits !== undefined ? { emits: reg.emits } : {}),\n\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t});\n\t\t// Pre-register declared event streams so describe() shows them.\n\t\tif (reg.emits) {\n\t\t\tfor (const e of reg.emits) {\n\t\t\t\tif (!this._eventLogs.has(e)) this.event(e);\n\t\t\t}\n\t\t}\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\t * **Tier 8 / COMPOSITION-GUIDE §35:** dispatch routes through the shared\n\t * {@link mutate} framework so freeze / rollback-on-throw / seq-cursor\n\t * advance / audit-record stamping flow through one centralized helper.\n\t * Failure records emit OUTSIDE the rolled-back batch (M5 / C4 invariants\n\t * preserved by the framework).\n\t */\n\tdispatch<T = unknown>(commandName: string, payload: T, opts?: DispatchOptions): void {\n\t\tconst reg = this._commandRegs.get(commandName);\n\t\tif (!reg) throw new UnknownCommandError(commandName);\n\n\t\t// D1: optimistic-concurrency check fires BEFORE the handler runs and\n\t\t// BEFORE the batch opens, so a stale-version dispatch is a clean\n\t\t// no-op (no audit record, no rollback). Only meaningful when both\n\t\t// aggregateId and expectedAggregateVersion are set; otherwise no-op.\n\t\tif (\n\t\t\topts?.aggregateId !== undefined &&\n\t\t\topts.expectedAggregateVersion !== undefined &&\n\t\t\treg.emits !== undefined\n\t\t) {\n\t\t\t// Verify against ANY of the declared `emits` types — the dispatch's\n\t\t\t// aggregate version is per (type, aggregateId), but a single\n\t\t\t// dispatch may emit across multiple types. We check the FIRST\n\t\t\t// declared `emits` type that has a version recorded for this\n\t\t\t// aggregate; if none has a version, the aggregate is considered\n\t\t\t// at version 0.\n\t\t\tlet observedVersion = 0;\n\t\t\tfor (const t of reg.emits) {\n\t\t\t\tconst v = this._aggregateVersions.get(`${t}::${opts.aggregateId}`);\n\t\t\t\tif (v !== undefined && v > observedVersion) observedVersion = v;\n\t\t\t}\n\t\t\tif (observedVersion !== opts.expectedAggregateVersion) {\n\t\t\t\tthrow new OptimisticConcurrencyError(\n\t\t\t\t\topts.aggregateId,\n\t\t\t\t\topts.expectedAggregateVersion,\n\t\t\t\t\tobservedVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst cmdNode = this.resolve(commandName);\n\t\tconst emittedEvents: string[] = [];\n\t\t// `actionThrew` distinguishes user-handler failures (where we want to\n\t\t// stamp `cmdNode.meta.error`) from framework-internal failures (which\n\t\t// shouldn't leak as a \"command failed\" signal).\n\t\tlet actionThrew = false;\n\n\t\tconst action = (sealed: T): void => {\n\t\t\tcmdNode.emit(sealed, { internal: true });\n\t\t\ttry {\n\t\t\t\treg.handler(sealed, {\n\t\t\t\t\temit: (eName, data) => {\n\t\t\t\t\t\t// Wave C.2 Unit 19: if emits was declared, reject undeclared names.\n\t\t\t\t\t\tif (reg.emits !== undefined && !reg.emits.includes(eName)) {\n\t\t\t\t\t\t\tthrow new UndeclaredEmitError(commandName, eName, reg.emits);\n\t\t\t\t\t\t}\n\t\t\t\t\t\temittedEvents.push(eName);\n\t\t\t\t\t\tthis._appendEvent(eName, data, {\n\t\t\t\t\t\t\t// D1: thread the dispatch's aggregateId through so events\n\t\t\t\t\t\t\t// participate in per-aggregate versioning. Handlers can\n\t\t\t\t\t\t\t// override per-emit by passing their own through a richer\n\t\t\t\t\t\t\t// emit signature (future extension).\n\t\t\t\t\t\t\t...(opts?.aggregateId !== undefined ? { aggregateId: opts.aggregateId } : {}),\n\t\t\t\t\t\t\t...(opts?.correlationId !== undefined ? { correlationId: opts.correlationId } : {}),\n\t\t\t\t\t\t\t...(opts?.causationId !== undefined ? { causationId: opts.causationId } : {}),\n\t\t\t\t\t\t\t...(opts?.metadata !== undefined\n\t\t\t\t\t\t\t\t? { metadata: Object.freeze({ ...opts.metadata }) }\n\t\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tcmdNode.meta.error.emit(null, { internal: true });\n\t\t\t} catch (err) {\n\t\t\t\tactionThrew = true;\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t};\n\n\t\ttry {\n\t\t\tmutate<[T], void, DispatchRecord>(action, {\n\t\t\t\tframe: \"transactional\",\n\t\t\t\tlog: this.dispatches,\n\t\t\t\tseq: this._dispatchSeqCursor,\n\t\t\t\tfreeze: this._freezeCommandPayload,\n\t\t\t\tonSuccessRecord: ([sealed], _result, { t_ns, seq }) => ({\n\t\t\t\t\tcommandName,\n\t\t\t\t\tpayload: sealed,\n\t\t\t\t\toutcome: \"success\",\n\t\t\t\t\temittedEvents: [...emittedEvents],\n\t\t\t\t\tt_ns,\n\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t\t\t}),\n\t\t\t\tonFailureRecord: ([sealed], err, { t_ns, seq, errorType }) => {\n\t\t\t\t\tconst wrapped =\n\t\t\t\t\t\terr instanceof CommandHandlerError ? err : new CommandHandlerError(commandName, err);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcommandName,\n\t\t\t\t\t\tpayload: sealed,\n\t\t\t\t\t\toutcome: \"failure\",\n\t\t\t\t\t\terror: wrapped,\n\t\t\t\t\t\terrorType,\n\t\t\t\t\t\temittedEvents: [...emittedEvents],\n\t\t\t\t\t\tt_ns,\n\t\t\t\t\t\tseq: seq ?? 0,\n\t\t\t\t\t\t...(reg.handlerVersion !== undefined ? { handlerVersion: reg.handlerVersion } : {}),\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t})(payload);\n\t\t} catch (outerErr) {\n\t\t\t// C4 preservation: only stamp `cmdNode.meta.error` when the user\n\t\t\t// handler threw (not when framework infra threw before the action\n\t\t\t// ran). The framework already routed onFailure for the action-throw\n\t\t\t// case via `mutate` outside the rolled-back batch.\n\t\t\tif (actionThrew) {\n\t\t\t\tcmdNode.meta.error.emit(outerErr, { internal: true });\n\t\t\t}\n\t\t\tthrow outerErr;\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 * **Wave C.3 Unit 21 (locked 2026-04-24):**\n\t * - Object-bag signature replaces the positional `(name, events, reducer, initial)` form.\n\t * - `mode: \"scan\"` (default) — incremental fold; `\"replay\"` — full replay each wave.\n\t * - `snapshot` integration for cold-start load + auto-checkpoint save.\n\t * - `freezeInputs` (default `true`) — freeze the event array before passing to reducer.\n\t * - Returns `ProjectionController<TState>` with `.node`, `.rebuild()`, `.reset()`.\n\t *\n\t * Fan-in across `events` is implemented by depending on all event-type fan-in\n\t * nodes directly, which preserves `describe()` edges (e.g. `orderPlaced →\n\t * orderCount`). Events are sorted by `(timestampNs, seq, aggregateId)` before\n\t * passing to the reducer (Option-3 cross-aggregate ordering, C.3).\n\t */\n\tprojection<TState>(opts: ProjectionOptions<TState>): ProjectionController<TState> {\n\t\tconst { name, events: eventNames, reducer, initial } = opts;\n\t\tconst mode = opts.mode ?? \"scan\";\n\t\tconst freezeInputs = opts.freezeInputs ?? true;\n\t\tconst snapshotOpts = opts.snapshot;\n\n\t\t// Ensure each event stream exists and collect its node.\n\t\t// Using the event-type fan-in nodes directly as deps preserves\n\t\t// `describe()` edges (orderPlaced → orderCount) per Audit 1 §24.\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// Sort comparator: timestampNs → seq → aggregateId lex (Option-3, C.3).\n\t\tfunction sortEvents(evts: CqrsEvent[]): void {\n\t\t\tevts.sort(\n\t\t\t\t(a, b) =>\n\t\t\t\t\ta.timestampNs - b.timestampNs ||\n\t\t\t\t\ta.seq - b.seq ||\n\t\t\t\t\t(a.aggregateId ?? \"\").localeCompare(b.aggregateId ?? \"\"),\n\t\t\t);\n\t\t}\n\n\t\t// Collect all events from the current snapshots (for seeding + rebuild).\n\t\tfunction collectAllEvents(snapshots: readonly (readonly CqrsEvent[])[]): CqrsEvent[] {\n\t\t\tconst evts: CqrsEvent[] = [];\n\t\t\tfor (const snap of snapshots) evts.push(...snap);\n\t\t\tsortEvents(evts);\n\t\t\treturn evts;\n\t\t}\n\n\t\t// Seed: collect any events already present at construction time.\n\t\tconst seedSnapshots = eventNodes.map(\n\t\t\t(n) => (n.cache as readonly CqrsEvent[] | undefined) ?? ([] as readonly CqrsEvent[]),\n\t\t);\n\t\tconst sortedSeed = collectAllEvents(seedSnapshots);\n\t\tconst frozenSeed = (\n\t\t\tfreezeInputs ? Object.freeze(sortedSeed) : sortedSeed\n\t\t) as readonly CqrsEvent[];\n\n\t\t// Scan state: tracks count of events processed in last run.\n\t\tlet lastProcessedCount = 0;\n\t\tlet scanState: TState = initial;\n\n\t\tif (mode === \"scan\" && sortedSeed.length > 0) {\n\t\t\tscanState = reducer(initial, frozenSeed);\n\t\t\tlastProcessedCount = sortedSeed.length;\n\t\t}\n\t\tconst seedState = mode === \"replay\" ? reducer(initial, frozenSeed) : scanState;\n\n\t\t// Snapshot save state — debounce + saveEvery.\n\t\tconst saveDebounceMs = snapshotOpts?.saveDebounceMs ?? 1000;\n\t\tconst saveEvery = snapshotOpts?.saveEvery ?? 1000;\n\t\tlet saveTimer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet savesSinceLastFlush = 0;\n\n\t\tfunction scheduleSave(currentState: TState): void {\n\t\t\tif (!snapshotOpts?.save) return;\n\t\t\tsavesSinceLastFlush += 1;\n\t\t\tif (savesSinceLastFlush >= saveEvery) {\n\t\t\t\tsavesSinceLastFlush = 0;\n\t\t\t\tif (saveTimer !== undefined) {\n\t\t\t\t\tclearTimeout(saveTimer);\n\t\t\t\t\tsaveTimer = undefined;\n\t\t\t\t}\n\t\t\t\tconst result = snapshotOpts.save(currentState);\n\t\t\t\tif (result instanceof Promise) result.catch(() => undefined);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (saveTimer !== undefined) clearTimeout(saveTimer);\n\t\t\tsaveTimer = setTimeout(() => {\n\t\t\t\tsaveTimer = undefined;\n\t\t\t\tsavesSinceLastFlush = 0;\n\t\t\t\tconst result = snapshotOpts!.save!(currentState);\n\t\t\t\tif (result instanceof Promise) result.catch(() => undefined);\n\t\t\t}, saveDebounceMs);\n\t\t}\n\n\t\tconst projNode = this.derived<TState>(\n\t\t\tname,\n\t\t\teventNames as readonly string[],\n\t\t\t(batchData, ctx) => {\n\t\t\t\tconst snapshots = batchData.map((batch, i) =>\n\t\t\t\t\tbatch != null && batch.length > 0 ? batch.at(-1) : ctx.prevData[i],\n\t\t\t\t);\n\t\t\t\tconst allEvents = collectAllEvents(snapshots as readonly (readonly CqrsEvent[])[]);\n\n\t\t\t\tlet newState: TState;\n\t\t\t\tif (mode === \"replay\") {\n\t\t\t\t\t// m1: freeze only in the replay branch where `frozen` is actually used.\n\t\t\t\t\tconst frozen = (\n\t\t\t\t\t\tfreezeInputs ? Object.freeze(allEvents) : allEvents\n\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\tnewState = reducer(initial, frozen);\n\t\t\t\t} else {\n\t\t\t\t\t// scan: only fold NEW events since last run.\n\t\t\t\t\tconst newOnly = allEvents.slice(lastProcessedCount);\n\t\t\t\t\tlastProcessedCount = allEvents.length;\n\t\t\t\t\tconst frozenNew = (\n\t\t\t\t\t\tfreezeInputs ? Object.freeze(newOnly) : newOnly\n\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\tnewState = reducer(scanState, frozenNew);\n\t\t\t\t\tscanState = newState;\n\t\t\t\t}\n\n\t\t\t\tscheduleSave(newState);\n\t\t\t\treturn [newState];\n\t\t\t},\n\t\t\t{\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: seedState,\n\t\t\t},\n\t\t);\n\n\t\tthis.addDisposer(keepalive(projNode));\n\t\tthis.addDisposer(() => {\n\t\t\tif (saveTimer !== undefined) {\n\t\t\t\tclearTimeout(saveTimer);\n\t\t\t\tsaveTimer = undefined;\n\t\t\t}\n\t\t});\n\t\tthis._projections.add(name);\n\n\t\t// -- Controller methods ---------------------------------------------------\n\n\t\tconst rebuild = async (rebuildOpts?: {\n\t\t\tfromTier?: AppendLogStorageTier<CqrsEvent>;\n\t\t\tpageSize?: number;\n\t\t}): Promise<TState> => {\n\t\t\ttry {\n\t\t\t\tconst pageSize = rebuildOpts?.pageSize ?? 1000;\n\t\t\t\tconst tier = rebuildOpts?.fromTier ?? this._attachedEventTiers[0]?.[0];\n\n\t\t\t\t// M5: snapshot in-memory event count BEFORE any async work so we can\n\t\t\t\t// drain events that arrive concurrently during the paginated rebuild.\n\t\t\t\tconst preBuildCount = collectAllEvents(\n\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t).length;\n\n\t\t\t\t// Seed from snapshot.load if provided.\n\t\t\t\tlet rebuildState: TState = initial;\n\t\t\t\tif (snapshotOpts?.load) {\n\t\t\t\t\tconst loaded = await snapshotOpts.load();\n\t\t\t\t\tif (loaded !== undefined) rebuildState = loaded;\n\t\t\t\t}\n\n\t\t\t\tif (!tier || !tier.loadEntries) {\n\t\t\t\t\t// No storage tier — fold in-memory events as a best-effort rebuild.\n\t\t\t\t\tconst inMemory = collectAllEvents(\n\t\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t\t);\n\t\t\t\t\tconst frozen = (\n\t\t\t\t\t\tfreezeInputs ? Object.freeze(inMemory) : inMemory\n\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\trebuildState = reducer(rebuildState, frozen);\n\t\t\t\t} else {\n\t\t\t\t\t// Paginated load from tier.\n\t\t\t\t\t// m3: only fold events that belong to this projection's event-type set.\n\t\t\t\t\t// Tiers may hold events from other projections; filtering keeps reducer\n\t\t\t\t\t// correctness when the tier is shared across projections.\n\t\t\t\t\tconst watchedEvents = new Set<string>(eventNames as readonly string[]);\n\t\t\t\t\tlet cursor: import(\"@graphrefly/pure-ts/extra\").AppendCursor | undefined;\n\t\t\t\t\tlet done = false;\n\t\t\t\t\twhile (!done) {\n\t\t\t\t\t\tconst result = await tier.loadEntries({ cursor, pageSize });\n\t\t\t\t\t\tconst page = [...result.entries].filter((e) => watchedEvents.has(e.type));\n\t\t\t\t\t\tsortEvents(page);\n\t\t\t\t\t\tconst frozenPage = (freezeInputs ? Object.freeze(page) : page) as readonly CqrsEvent[];\n\t\t\t\t\t\trebuildState = reducer(rebuildState, frozenPage);\n\t\t\t\t\t\tcursor = result.cursor;\n\t\t\t\t\t\tdone = !cursor || result.entries.length === 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Update the live projection node with the rebuilt state.\n\t\t\t\tif (mode === \"scan\") {\n\t\t\t\t\t// M5: drain events that arrived during the async rebuild so they are\n\t\t\t\t\t// not lost (race between paginated load and concurrent dispatch).\n\t\t\t\t\tconst allInMemory = collectAllEvents(\n\t\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t\t);\n\t\t\t\t\tconst pendingEvents = allInMemory.slice(preBuildCount);\n\t\t\t\t\tif (pendingEvents.length > 0) {\n\t\t\t\t\t\tconst frozenPending = (\n\t\t\t\t\t\t\tfreezeInputs ? Object.freeze(pendingEvents) : pendingEvents\n\t\t\t\t\t\t) as readonly CqrsEvent[];\n\t\t\t\t\t\trebuildState = reducer(rebuildState, frozenPending);\n\t\t\t\t\t}\n\t\t\t\t\tscanState = rebuildState;\n\t\t\t\t\tlastProcessedCount = allInMemory.length;\n\t\t\t\t}\n\t\t\t\tprojNode.emit(rebuildState, { internal: true });\n\t\t\t\treturn rebuildState;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new RebuildError(name, err);\n\t\t\t}\n\t\t};\n\n\t\tconst reset = async (): Promise<TState> => {\n\t\t\ttry {\n\t\t\t\t// Reload from snapshot.load (if configured).\n\t\t\t\tlet baseState: TState = initial;\n\t\t\t\tif (snapshotOpts?.load) {\n\t\t\t\t\tconst loaded = await snapshotOpts.load();\n\t\t\t\t\tif (loaded !== undefined) baseState = loaded;\n\t\t\t\t}\n\n\t\t\t\t// Re-fold all in-memory events on top of the snapshot state.\n\t\t\t\tconst inMemory = collectAllEvents(\n\t\t\t\t\teventNodes.map((n) => (n.cache as readonly CqrsEvent[] | undefined) ?? []),\n\t\t\t\t);\n\t\t\t\tconst frozen = (freezeInputs ? Object.freeze(inMemory) : inMemory) as readonly CqrsEvent[];\n\t\t\t\tconst newState = reducer(baseState, frozen);\n\n\t\t\t\tif (mode === \"scan\") {\n\t\t\t\t\tscanState = newState;\n\t\t\t\t\tlastProcessedCount = inMemory.length;\n\t\t\t\t}\n\t\t\t\tprojNode.emit(newState, { internal: true });\n\t\t\t\treturn newState;\n\t\t\t} catch (err) {\n\t\t\t\tthrow new RebuildError(name, err);\n\t\t\t}\n\t\t};\n\n\t\treturn { node: projNode, rebuild, reset };\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\topts: SagaOptions = {},\n\t): SagaController<T> {\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// Audit 2: per-event-type cursor state nodes (replaces closure Map).\n\t\t// Mount under `<saga>_cursor` (no `::` — that's the path separator).\n\t\tconst cursors = registerCursorMap(this, `${name}_cursor`, eventNames as readonly string[], 0);\n\t\t// Audit 2: invocations log (companion + alias).\n\t\tconst invocations = createAuditLog<SagaInvocation<T>>({\n\t\t\tname: `${name}_invocations`,\n\t\t\tretainedLimit: this._retainedLimit,\n\t\t\tgraph: this,\n\t\t});\n\t\tconst aggregateFilter = opts.aggregateId;\n\t\tconst errorPolicy = opts.errorPolicy ?? \"advance\";\n\n\t\t// D2: subscribe-and-capture-mirror for cursor reads — avoid `.cache`\n\t\t// access from inside the saga node's fn. Each cursor mirrors into a\n\t\t// closure variable updated by an external subscription. Cursor writes\n\t\t// (`cursor.emit(advancedTo)`) and `invocations.append(...)` from inside\n\t\t// the fn are sanctioned effect-side-effects (saga's `describeKind:\n\t\t// \"effect\"`) — not §5.9 imperative-trigger violations.\n\t\tconst latestCursors = new Map<string, number>();\n\t\tfor (const eName of eventNames) {\n\t\t\tconst cursor = cursors[eName]!;\n\t\t\tlatestCursors.set(eName, (cursor.cache as number | undefined) ?? 0);\n\t\t\tconst sub = cursor.subscribe((msgs) => {\n\t\t\t\tfor (const m of msgs) if (m[0] === DATA) latestCursors.set(eName, m[1] as number);\n\t\t\t});\n\t\t\tthis.addDisposer(sub);\n\t\t}\n\n\t\t// Tier 8 / COMPOSITION-GUIDE §35: per-event handler invocation routes\n\t\t// through `mutate` so handler-version stamping + audit-record\n\t\t// shape stay centralized. Failure path re-throws — the saga's outer\n\t\t// try/catch honors `errorPolicy` (\"advance\" vs \"hold\"). Action takes\n\t\t// `(ev, eName)` so the wrapper can be hoisted once for all event types.\n\t\tconst auditedHandler = mutate<[CqrsEvent<T>, string], void, SagaInvocation<T>>(\n\t\t\t(ev, _eName) => {\n\t\t\t\thandler(ev);\n\t\t\t},\n\t\t\t{\n\t\t\t\tframe: \"inline\",\n\t\t\t\tlog: invocations,\n\t\t\t\tfreeze: false,\n\t\t\t\t...(opts.handlerVersion !== undefined ? { handlerVersion: opts.handlerVersion } : {}),\n\t\t\t\t// D5 (qa lock): always include the `aggregateId` key (even when\n\t\t\t\t// undefined) for parity with the pre-Tier-8 saga record shape.\n\t\t\t\t// Consumers using `Object.hasOwn(record, \"aggregateId\")` or JSON\n\t\t\t\t// serialization shape would observe a pre-1.0 break otherwise.\n\t\t\t\tonSuccessRecord: ([ev, eName], _r, { t_ns }) => ({\n\t\t\t\t\teventType: eName,\n\t\t\t\t\toutcome: \"success\",\n\t\t\t\t\taggregateId: ev.aggregateId,\n\t\t\t\t\tevent: ev,\n\t\t\t\t\tt_ns,\n\t\t\t\t}),\n\t\t\t\tonFailureRecord: ([ev, eName], err, { t_ns, errorType }) => ({\n\t\t\t\t\teventType: eName,\n\t\t\t\t\toutcome: \"failure\",\n\t\t\t\t\terror: err,\n\t\t\t\t\terrorType,\n\t\t\t\t\taggregateId: ev.aggregateId,\n\t\t\t\t\tevent: ev,\n\t\t\t\t\tt_ns,\n\t\t\t\t}),\n\t\t\t},\n\t\t);\n\n\t\tconst sagaRef: { n?: Node<unknown> } = {};\n\t\tconst sagaNode = this.effect(\n\t\t\tname,\n\t\t\teventNames as readonly string[],\n\t\t\t(snapshots, _up) => {\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 batch = snapshots[i];\n\t\t\t\t\tif (batch == null || batch.length === 0) continue;\n\t\t\t\t\tconst entries = batch.at(-1) as readonly CqrsEvent<T>[] | undefined;\n\t\t\t\t\tif (!entries) continue;\n\t\t\t\t\tconst eName = eventNames[i] as string;\n\t\t\t\t\tconst cursor = cursors[eName]!;\n\t\t\t\t\tconst lastCount = latestCursors.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\tlet advancedTo = lastCount;\n\t\t\t\t\t\tfor (const entry of newEntries) {\n\t\t\t\t\t\t\tconst ev = entry as CqrsEvent<T>;\n\t\t\t\t\t\t\tif (aggregateFilter !== undefined && ev.aggregateId !== aggregateFilter) {\n\t\t\t\t\t\t\t\tadvancedTo += 1;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tauditedHandler(ev, eName);\n\t\t\t\t\t\t\t\terrNode.emit(null, { internal: true });\n\t\t\t\t\t\t\t\tadvancedTo += 1;\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\terrNode.emit(err, { internal: true });\n\t\t\t\t\t\t\t\tif (errorPolicy === \"hold\") break;\n\t\t\t\t\t\t\t\t// \"advance\" — skip past failure, keep going.\n\t\t\t\t\t\t\t\tadvancedTo += 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcursor.emit(advancedTo);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\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.addDisposer(keepalive(sagaNode));\n\t\tthis._sagas.add(name);\n\t\treturn {\n\t\t\tnode: sagaNode,\n\t\t\tinvocations,\n\t\t\taudit: readonlyAuditLog(invocations),\n\t\t\tcursors,\n\t\t};\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 * const { node: orderCount } = app.projection({\n * name: \"orderCount\",\n * events: [\"orderPlaced\"],\n * reducer: (_s, events) => events.length,\n * initial: 0,\n * });\n * app.dispatch(\"placeOrder\", { id: \"1\", amount: 100 });\n * ```\n */\nexport function cqrs<EM extends CqrsEventMap = Record<string, unknown>>(\n\tname: string,\n\topts?: CqrsOptions,\n): CqrsGraph<EM> {\n\tconst g = new CqrsGraph<EM>(name, opts);\n\t// Tier 1.5.3 Phase 2.5 (DG1=B): tag the Graph with its constructing\n\t// factory so `describe()` surfaces provenance. Route through\n\t// `placeholderArgs` since `CqrsOptions.graph` may carry non-JSON fields.\n\tconst { factory: _f, factoryArgs: _fa, ...tagArgs } = (opts ?? {}) as Record<string, unknown>;\n\tg.tagFactory(\"cqrs\", placeholderArgs(tagArgs));\n\treturn g;\n}\n","/**\n * Universal mutation framework (Phase 14 — DS-14 locked 2026-05-05).\n *\n * Single `mutate(act, opts)` factory replaces the prior `lightMutation` +\n * `wrapMutation` two-tier split (pre-1.0 break per Q-O2).\n *\n * Two frames:\n * - `\"inline\"` — no batch; up() runs raw. Seq bumps before action; persists\n * on throw. Hot-path-friendly for atomic single-write mutations.\n * - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n * deferred deliveries, then `down()` runs (if provided), then failure record.\n *\n * Phase-4 primitives share the same shape: imperative mutation methods +\n * closure state + reactive audit log + freeze-at-entry + rollback-on-throw.\n * This module factors out the common machinery so each primitive becomes\n * declarative wiring over typed audit records.\n */\n\nimport {\n\tbatch,\n\tDATA,\n\tDIRTY,\n\ttype Node,\n\ttype NodeGuard,\n\tnode,\n\tpolicy,\n\twallClockNs,\n} from \"@graphrefly/pure-ts/core\";\nimport {\n\ttype ReactiveLogBundle,\n\ttype ReactiveLogOptions,\n\treactiveLog,\n} from \"@graphrefly/pure-ts/extra\";\nimport { Graph } from \"@graphrefly/pure-ts/graph\";\n\n// ── tryIncrementBounded ──────────────────────────────────────────────────\n\n/**\n * Bounded increment for a self-owned counter state node.\n *\n * Reads `counter.cache`, bumps by `by` (default 1) if `cur + by <= cap`,\n * writes back. Returns `false` when the cap would be exceeded (no-op write).\n * Documented P3 exception: the counter is not a declared dep of the caller —\n * it's a private budget read+written from a single call site. This helper\n * keeps the `.cache` access in one named place so caller bodies (which may\n * be inside reactive fn execution paths) stay free of cross-node `.cache`\n * reads.\n *\n * **Safety today:**\n * 1. Single-threaded JS runner never invokes the caller concurrently.\n * 2. `counter.down` writes the cache synchronously before returning, so\n * synchronous re-entry through a downstream publish reads the\n * freshly-incremented value — no double-count.\n *\n * **Future risk:** under a free-threaded runner (PY no-GIL or hypothetical\n * concurrent TS runner), two concurrent firings could still race. Revisit\n * when that surfaces.\n *\n * @param counter - Self-owned counter Node. Caller is the sole writer.\n * @param cap - Upper bound (inclusive). Pass `Number.MAX_SAFE_INTEGER` for\n * \"effectively unbounded\" use cases (e.g. token meters).\n * @param by - Delta to add (default `1`). Must be a finite non-negative\n * number; callers should pre-validate. Overflow-safe via\n * `by > cap - cur` check rather than `cur + by >= cap`.\n */\nexport function tryIncrementBounded(counter: Node<number>, cap: number, by = 1): boolean {\n\tconst cur = (counter.cache as number | undefined) ?? 0;\n\tif (by > cap - cur) return false;\n\tcounter.down([[DIRTY], [DATA, cur + by]]);\n\treturn true;\n}\n\n// ── Audit record schema ──────────────────────────────────────────────────\n\n/** Shared base shape for every audit record. Per-primitive types extend this. */\nexport interface BaseAuditRecord {\n\treadonly t_ns: number;\n\treadonly seq?: number;\n\treadonly handlerVersion?: { id: string; version: string | number };\n}\n\n// ── Default audit guard ──────────────────────────────────────────────────\n\n/**\n * Allow `observe` and `signal`; deny external `write` on the audit log so\n * consumers can subscribe + signal-bridge but cannot inject fake records.\n */\nexport const DEFAULT_AUDIT_GUARD: NodeGuard = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n// ── createAuditLog ───────────────────────────────────────────────────────\n\nexport type AuditLogOpts<R extends BaseAuditRecord> = {\n\tname: string;\n\t/** Bounded retention; default 1024 per Audit 2 / cross-cutting bounded-default policy. */\n\tretainedLimit?: number;\n\t/** Override the default audit guard. */\n\tguard?: NodeGuard;\n\t/** Mount the audit `entries` Node under this graph (and activate withLatest). */\n\tgraph?: Graph;\n\t/** Pass-through to {@link reactiveLog}. */\n\tversioning?: ReactiveLogOptions<R>[\"versioning\"];\n};\n\n/**\n * Build a reactive audit log with sane defaults: bounded retention, deny-write\n * guard, `withLatest()` companions activated. Returns the {@link ReactiveLogBundle}\n * directly — primitives expose this as `<primitive>.events` / `.decisions` /\n * `.dispatches` / `.invocations` and alias it as `.audit`.\n *\n * @category internal\n */\nexport function createAuditLog<R extends BaseAuditRecord>(\n\topts: AuditLogOpts<R>,\n): ReactiveLogBundle<R> {\n\tconst log = reactiveLog<R>([], {\n\t\tname: opts.name,\n\t\tmaxSize: opts.retainedLimit ?? 1024,\n\t\tguard: opts.guard ?? DEFAULT_AUDIT_GUARD,\n\t\t...(opts.versioning != null ? { versioning: opts.versioning } : {}),\n\t});\n\t// Lazy companion activation up-front so `bundle.lastValue` / `hasLatest`\n\t// are queryable without an explicit `withLatest()` call.\n\tlog.withLatest();\n\tif (opts.graph) {\n\t\topts.graph.add(log.entries, { name: opts.name });\n\t}\n\treturn log;\n}\n\n/**\n * Read-only projection of a {@link ReactiveLogBundle}. Exposes only the\n * observation surface (`entries` / `size` / `at` / `withLatest` / `lastValue`\n * / `view` / `scan` / `mutationLog`) — the mutators (`append` / `appendMany`\n * / `clear` / `trimHead` / `attach` / `attachStorage`) and the lifecycle\n * disposers are intentionally absent.\n */\nexport type ReadonlyAuditLog<R> = Pick<\n\tReactiveLogBundle<R>,\n\t\"entries\" | \"size\" | \"at\" | \"withLatest\" | \"lastValue\" | \"view\" | \"scan\" | \"mutationLog\"\n>;\n\n/**\n * Wrap an audit log so the `.audit` alias a primitive exposes (the Audit-2\n * `.audit` duplication convention — `saga.audit` / `cqrs.audit` /\n * `jobQueue.audit` / `processManager.audit`) is a **stable read-only view**,\n * not the live mutable bundle. Closes M7: a consumer calling\n * `someGraph.audit.append(...)` would otherwise silently mutate the owning\n * primitive's canonical log. The returned object is frozen and shares the\n * underlying log's nodes (zero copy) — reads are byte-identical to the live\n * bundle; mutators are simply not present (compile-time) and the object is\n * frozen (run-time defense for JS callers).\n *\n * @category internal\n */\nexport function readonlyAuditLog<R>(log: ReactiveLogBundle<R>): ReadonlyAuditLog<R> {\n\treturn Object.freeze({\n\t\tget entries() {\n\t\t\treturn log.entries;\n\t\t},\n\t\tget size() {\n\t\t\treturn log.size;\n\t\t},\n\t\tget lastValue() {\n\t\t\treturn log.lastValue;\n\t\t},\n\t\tget mutationLog() {\n\t\t\treturn log.mutationLog;\n\t\t},\n\t\tat: log.at.bind(log),\n\t\twithLatest: log.withLatest.bind(log),\n\t\tview: log.view.bind(log),\n\t\tscan: log.scan.bind(log),\n\t}) satisfies ReadonlyAuditLog<R>;\n}\n\n// ── Universal mutation factory (Phase 14 — DS-14 lock Q-O2/Q-O3) ────────\n//\n// Single `mutate(act, opts)` factory. Two frames:\n//\n// - `\"inline\"` — no batch frame; up() runs raw. Seq bumps before action;\n// persists on throw. Hot-path-friendly for atomic single-write mutations.\n//\n// - `\"transactional\"` — opens `batch(() => up(...))`. On throw: batch discards\n// deferred deliveries, then `down()` runs, then failure record persists.\n//\n// **Heuristic:** if your imperative method's body is one or two lines (mutate\n// state, emit), use `frame: \"inline\"`. If it runs a user-supplied handler or\n// has multiple steps that could leave inconsistent state mid-throw, use\n// `frame: \"transactional\"`.\n\nexport type FailureMeta = {\n\tt_ns: number;\n\tseq?: number;\n\terrorType: string;\n};\n\nexport type SuccessMeta = {\n\tt_ns: number;\n\tseq?: number;\n};\n\n/**\n * Mutation action shape. Plain function shorthand auto-wraps as `{ up: fn }`.\n *\n * - `up` — the mutation action (the \"up migration\").\n * - `down` — optional rollback for closure mutations that `batch()` can't\n * reach. Receives the SAME frozen args as `up`. Runs AFTER batch reactive\n * rollback, BEFORE the failure record. Throws inside `down` are\n * console.error'd without masking the original error. Only meaningful\n * with `frame: \"transactional\"`.\n */\nexport type MutationAct<TArgs extends readonly unknown[], TResult> = {\n\tup: (...args: TArgs) => TResult;\n\tdown?: (...args: TArgs) => void;\n};\n\nexport type MutationFrame = \"inline\" | \"transactional\";\n\nexport type MutateOpts<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord> = {\n\t/** Frame mode. `\"inline\"` = no batch; `\"transactional\"` = batch + rollback. */\n\tframe: MutationFrame;\n\t/**\n\t * Optional log to append records to. When omitted, the wrapper still\n\t * provides freeze / seq-advance / rollback-on-throw but skips record\n\t * emission — useful for primitives that want centralized mutation\n\t * semantics without a dedicated log surface (e.g. `Topic.publish`).\n\t */\n\tlog?: ReactiveLogBundle<R>;\n\t/** Build the success record from the action's args + result + meta. */\n\tonSuccessRecord?: (args: TArgs, result: TResult, meta: SuccessMeta) => R | undefined;\n\t/** Build the failure record from the args + error + meta. */\n\tonFailureRecord?: (args: TArgs, error: unknown, meta: FailureMeta) => R | undefined;\n\t/** Deep-freeze args at entry (default `true`). Opt out for hot paths. */\n\tfreeze?: boolean;\n\t/** Optional sequence cursor — auto-advanced and stamped onto records. */\n\tseq?: Node<number>;\n\t/** Optional handler version — stamped per Audit 5. */\n\thandlerVersion?: { id: string; version: string | number };\n};\n\nfunction deepFreeze<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || Object.isFrozen(value)) return value;\n\tfor (const k of Object.keys(value as Record<string, unknown>)) {\n\t\tdeepFreeze((value as Record<string, unknown>)[k]);\n\t}\n\treturn Object.freeze(value);\n}\n\n/**\n * Universal mutation factory (Phase 14 — DS-14 Q-O2).\n *\n * Replaces the prior `lightMutation` + `wrapMutation` two-tier split.\n * Single factory with `frame: \"inline\" | \"transactional\"` discriminant.\n *\n * @param act - The mutation action. Either a plain function (auto-wrapped as\n * `{ up: fn }`) or a `{ up, down? }` object for explicit rollback.\n * @param opts - Configuration: frame, log, record builders, freeze, seq.\n * @returns A typed wrapper function with the same signature as `act.up`.\n */\nexport function mutate<TArgs extends readonly unknown[], TResult, R extends BaseAuditRecord>(\n\tact: MutationAct<TArgs, TResult> | ((...args: TArgs) => TResult),\n\topts: MutateOpts<TArgs, TResult, R>,\n): (...args: TArgs) => TResult {\n\tconst { up, down } = typeof act === \"function\" ? { up: act, down: undefined } : act;\n\tconst freeze = opts.freeze ?? true;\n\n\tif (opts.frame === \"inline\") {\n\t\treturn function wrapped(...args: TArgs): TResult {\n\t\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\t\tconst t_ns = wallClockNs();\n\t\t\tconst seq = opts.seq ? bumpCursor(opts.seq) : undefined;\n\t\t\ttry {\n\t\t\t\tconst result = up(...sealed);\n\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\tresult,\n\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t} catch (err) {\n\t\t\t\tif (opts.log && opts.onFailureRecord) {\n\t\t\t\t\tconst errorType = err instanceof Error ? err.name : typeof err;\n\t\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\t\topts.log,\n\t\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\t\tsealed,\n\t\t\t\t\t\terr,\n\t\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t};\n\t}\n\n\t// frame === \"transactional\"\n\treturn function wrapped(...args: TArgs): TResult {\n\t\tconst sealed = freeze ? (args.map(deepFreeze) as unknown as TArgs) : args;\n\t\tconst t_ns = wallClockNs();\n\t\tlet result: TResult;\n\t\tlet captured: unknown;\n\t\tlet captureSet = false;\n\t\tlet seq: number | undefined;\n\t\ttry {\n\t\t\tbatch(() => {\n\t\t\t\tif (opts.seq) seq = bumpCursor(opts.seq);\n\t\t\t\ttry {\n\t\t\t\t\tresult = up(...sealed);\n\t\t\t\t\tif (opts.log && opts.onSuccessRecord) {\n\t\t\t\t\t\tappendAudit<TArgs, TResult, R, SuccessMeta>(\n\t\t\t\t\t\t\topts.log,\n\t\t\t\t\t\t\topts.onSuccessRecord,\n\t\t\t\t\t\t\tsealed,\n\t\t\t\t\t\t\tresult,\n\t\t\t\t\t\t\t{ t_ns, seq },\n\t\t\t\t\t\t\topts.handlerVersion,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tcaptured = err;\n\t\t\t\t\tcaptureSet = true;\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t});\n\t\t} catch (outerErr) {\n\t\t\t// Fire `down` AFTER batch's reactive rollback, BEFORE failure record.\n\t\t\t// Gate on `captureSet` — if the throw came from outside the inner try\n\t\t\t// (framework-level batch error before action ran), don't fire down.\n\t\t\tif (captureSet && down) {\n\t\t\t\ttry {\n\t\t\t\t\tdown(...sealed);\n\t\t\t\t} catch (downErr) {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`mutate: down hook threw — original action error preserved (${\n\t\t\t\t\t\t\tcaptured instanceof Error ? captured.name : typeof captured\n\t\t\t\t\t\t}). Down error:`,\n\t\t\t\t\t\tdownErr,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (captureSet && opts.log && opts.onFailureRecord) {\n\t\t\t\tconst errorType = captured instanceof Error ? captured.name : typeof captured;\n\t\t\t\tappendAudit<TArgs, unknown, R, FailureMeta>(\n\t\t\t\t\topts.log,\n\t\t\t\t\topts.onFailureRecord,\n\t\t\t\t\tsealed,\n\t\t\t\t\tcaptured,\n\t\t\t\t\t{ t_ns, seq, errorType },\n\t\t\t\t\topts.handlerVersion,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow captureSet ? captured : outerErr;\n\t\t}\n\t\treturn result!;\n\t};\n}\n\n/**\n * Advance a cursor node and return the new value. Emits `[DIRTY], [DATA, next]`\n * directly on the cursor — atomic outside a batch, rollback-discardable inside.\n *\n * Resets to `0` if the cursor cache is missing, non-numeric, `NaN`, or\n * non-finite (e.g. corrupted by `restore()` from a malformed snapshot, or\n * by a misbehaving codec). `??` alone would let `NaN` and `\"\"` pass through\n * and silently corrupt audit ordering downstream.\n *\n * **Silent reset diagnostic (EH-12).** When the cache holds a non-numeric\n * value at bump time, the cursor restarts at 0 and the next bump returns 1\n * — colliding with the seq stamped on the very first record after construct.\n * To make seq-monotonicity violations after a restore visible to operators,\n * the helper emits a one-shot `console.warn` per cursor instance describing\n * the offending value. The cursor is identified by a `WeakSet<Node<number>>`\n * so the warning fires exactly once per node — repeat malformed bumps stay\n * quiet to avoid log spam. Production callers wanting to suppress can swap\n * the global `console` (universal-safe code path; no Node-only API used).\n *\n * Works whether or not the cursor has any subscribers — `down` updates the\n * cache regardless, so primitives that bump before consumers attach (e.g.\n * `JobQueueGraph.enqueue`) still see a coherent sequence.\n *\n * @category internal\n */\nconst _bumpCursorWarned = new WeakSet<Node<number>>();\nexport function bumpCursor(seq: Node<number>): number {\n\tconst raw = seq.cache;\n\tconst valid = typeof raw === \"number\" && Number.isFinite(raw);\n\tif (!valid && raw !== undefined && !_bumpCursorWarned.has(seq)) {\n\t\t_bumpCursorWarned.add(seq);\n\t\tconsole.warn(\n\t\t\t`bumpCursor: cursor cache held a non-numeric value (${String(raw)}); resetting to 0. ` +\n\t\t\t\t\"Causes include: a snapshot codec round-tripping the cursor as a string / null / NaN, \" +\n\t\t\t\t\"OR a malformed initial seed (e.g. state<number>(NaN)). \" +\n\t\t\t\t\"Audit consumers may see colliding seq values after this point.\",\n\t\t);\n\t}\n\tconst cur = valid ? raw : 0;\n\tconst next = cur + 1;\n\tseq.down([[DIRTY], [DATA, next]]);\n\treturn next;\n}\n\n/**\n * Build a record via the supplied builder, stamp `handlerVersion` if present,\n * and append it to the audit log. `undefined` records are skipped (callers\n * pass an `onSuccess` / `onFailure` that returns `undefined` to opt out per\n * call).\n *\n * @category internal\n */\nexport function appendAudit<\n\tTArgs extends readonly unknown[],\n\tTValue,\n\tR extends BaseAuditRecord,\n\tM extends SuccessMeta | FailureMeta,\n>(\n\taudit: ReactiveLogBundle<R>,\n\tbuilder: (args: TArgs, value: TValue, meta: M) => R | undefined,\n\targs: TArgs,\n\tvalue: TValue,\n\tmeta: M,\n\thandlerVersion?: { id: string; version: string | number },\n): void {\n\tconst record = builder(args, value, meta);\n\tif (record === undefined) return;\n\tconst stamped = handlerVersion != null ? ({ ...record, handlerVersion } as R) : record;\n\taudit.append(stamped);\n}\n\n// ── registerCursor / registerCursorMap ───────────────────────────────────\n\n/**\n * Promote a closure counter to a state node mounted under `graph`.\n * Replaces ad-hoc `let _seq = 0` patterns with a node observable in\n * `describe()` and persistable via storage tiers.\n *\n * @category internal\n */\nexport function registerCursor(graph: Graph, name: string, initial = 0): Node<number> {\n\tconst cursor = node<number>([], { initial, name, describeKind: \"state\" });\n\tgraph.add(cursor, { name });\n\treturn cursor;\n}\n\n/**\n * Promote a closure `Map<K, number>` to N state nodes (one per key) mounted\n * under `<graph>::<name>::<key>`. Used by saga (per-event-type cursor).\n *\n * @category internal\n */\nexport function registerCursorMap<K extends string>(\n\tgraph: Graph,\n\tname: string,\n\tkeys: readonly K[],\n\tinitial = 0,\n): { readonly [P in K]: Node<number> } {\n\tconst out = {} as { [P in K]: Node<number> };\n\t// Mount cursors under a child plain-Graph so per-key node names stay flat\n\t// (path-separator `::` is reserved by Graph.add). Using `Graph` directly\n\t// rather than `graph.constructor` avoids spawning a typed subclass with\n\t// an incompatible constructor signature (e.g., CqrsGraph(name, opts)).\n\tconst sub = new Graph(name);\n\tfor (const k of keys) {\n\t\tconst cursor = node<number>([], {\n\t\t\tinitial,\n\t\t\tname: k,\n\t\t\tdescribeKind: \"state\",\n\t\t});\n\t\tsub.add(cursor, { name: k });\n\t\tout[k] = cursor;\n\t}\n\tgraph.mount(name, sub);\n\treturn out;\n}\n","/**\n * Shared pattern-layer error hierarchy (Audit 2 — locked 2026-04-24).\n *\n * Cross-primitive `instanceof` checks: gate, queue, cqrs.dispatch, saga,\n * projection, subscription, etc. all use these classes so consumer error\n * handlers can branch by kind rather than by message string.\n *\n * @internal — exposed via patterns/index for primitive impls; consumers\n * should import the relevant class from the primitive's barrel.\n */\n\n/** Root error class. All pattern-layer errors extend this. */\nexport class GraphReFlyError extends Error {\n\tconstructor(message: string, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = this.constructor.name;\n\t}\n}\n\n/** Re-registering a name that's already taken (command, gate, queue, saga, projection). */\nexport class DuplicateRegistrationError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly kind: string,\n\t\treadonly registrationName: string,\n\t) {\n\t\tsuper(`Duplicate ${kind} registration: \"${registrationName}\"`);\n\t}\n}\n\n/** CQRS handler emitted an event type not in its declared `emits` set. */\nexport class UndeclaredEmitError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly commandName: string,\n\t\treadonly eventName: string,\n\t\treadonly declaredEmits: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Command \"${commandName}\" emitted undeclared event \"${eventName}\". Declared emits: [${declaredEmits.join(\", \")}]`,\n\t\t);\n\t}\n}\n\n/** Aggregate version expected vs observed mismatch on dispatch. */\nexport class OptimisticConcurrencyError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly aggregateId: string,\n\t\treadonly expected: number,\n\t\treadonly actual: number,\n\t) {\n\t\tsuper(\n\t\t\t`Optimistic concurrency conflict on aggregate \"${aggregateId}\": expected version ${expected}, got ${actual}`,\n\t\t);\n\t}\n}\n\n/** `dispatch(name, ...)` for a name that wasn't registered via `command()`. */\nexport class UnknownCommandError extends GraphReFlyError {\n\tconstructor(readonly commandName: string) {\n\t\tsuper(`Unknown command: \"${commandName}\". Register with command() first.`);\n\t}\n}\n\n/** Wrap any error thrown from inside a command handler. Original on `cause`. */\nexport class CommandHandlerError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly commandName: string,\n\t\tcause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Command handler \"${commandName}\" threw: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n\n/** Mutation method called after the primitive was torn down. */\nexport class TeardownError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly kind: string,\n\t\treadonly method: string,\n\t) {\n\t\tsuper(`${kind}: ${method}() called after teardown`);\n\t}\n}\n\n/** Projection rebuild failure — adapter / decode / reducer error. */\nexport class RebuildError extends GraphReFlyError {\n\tconstructor(\n\t\treadonly projectionName: string,\n\t\tcause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`Projection \"${projectionName}\" rebuild failed: ${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t\t{ cause },\n\t\t);\n\t}\n}\n","/**\n * Metadata helpers for pattern-layer nodes (Tier 2.2 promotion from\n * `patterns/_internal/`).\n *\n * Each domain (orchestration, messaging, reduction, ai, cqrs, domain_template,\n * memory, lens, audit, harness) shares the same metadata convention. Promoted\n * to `extra/` so non-patterns code (and downstream consumers building their\n * own domain primitives) can use the same shape.\n *\n * @module\n */\n\n/**\n * Build a domain metadata object for pattern-layer nodes.\n *\n * Each domain follows the same shape: `{ [domain]: true, [domain]_type: kind, ...extra }`.\n *\n * @param domain - The domain tag (e.g. `\"orchestration\"`, `\"ai\"`, `\"cqrs\"`).\n * @param kind - The specific type within the domain (e.g. `\"gate\"`, `\"prompt\"`).\n * @param extra - Additional metadata to merge.\n * @returns Metadata object.\n */\nexport function domainMeta(\n\tdomain: string,\n\tkind: string,\n\textra?: Record<string, unknown>,\n): Record<string, unknown> {\n\treturn {\n\t\t[domain]: true,\n\t\t[`${domain}_type`]: kind,\n\t\t...(extra ?? {}),\n\t};\n}\n","// ---------------------------------------------------------------------------\n// NestJS RxJS bridge — returns a real rxjs `Observable` (so NestJS route\n// handlers' `isObservable()` recognizes it and `.pipe()` works directly).\n//\n// rxjs lives ONLY here, under the opt-in `compat/nestjs` subpath, where it is\n// legitimately available (`@nestjs/common` depends on rxjs). The base\n// `toObservable` (`@graphrefly/graphrefly/base`) is dependency-free and is\n// what RN/Hermes/web consumers load — this wrapper just adopts it via\n// rxjs `from()`.\n// ---------------------------------------------------------------------------\n\nimport type { Messages, Node } from \"@graphrefly/pure-ts/core\";\nimport { from, type Observable, type ObservableInput } from \"rxjs\";\nimport {\n\ttoObservable as baseToObservable,\n\ttype ToObservableOptions,\n} from \"../../base/composition/observable.js\";\n\nexport type { ToObservableOptions };\n\n/**\n * Bridge a `Node<T>` to a real rxjs `Observable` for NestJS controllers,\n * gateways, and interceptors. Wraps the dependency-free base interop\n * observable with rxjs `from()` so `isObservable()` / `.pipe()` work.\n *\n * See {@link baseToObservable} for the DATA/ERROR/COMPLETE mapping and the\n * `{ raw: true }` message-batch mode.\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\t// The base interop observable exposes `subscribe` + the well-known\n\t// `Symbol.observable` method at runtime; rxjs `from()` adopts it. Branch\n\t// so each call hits a concrete base overload (the union impl signature is\n\t// not visible to callers), and cast the minimal base type to rxjs input.\n\tconst base = options?.raw ? baseToObservable(node, { raw: true }) : baseToObservable<T>(node);\n\treturn from(base as unknown as ObservableInput<T | Messages>);\n}\n","// ---------------------------------------------------------------------------\n// Observable bridge — reactive interop between GraphReFly nodes and the TC39\n// Observable contract (the well-known `Symbol.observable` / \"@@observable\"\n// method). **Zero runtime dependency on rxjs**: the returned value is a\n// spec-interop observable that rxjs `from()`, Angular, the NestJS compat\n// layer, and any `Symbol.observable` consumer can adopt. Consumers wanting\n// rxjs operators do `from(toObservable(node))`.\n//\n// Usage:\n// import { toObservable } from '@graphrefly/graphrefly/base';\n// import { from } from 'rxjs';\n// const values$ = from(toObservable(myNode)); // Observable<T>\n// const msgs$ = from(toObservable(myNode, { raw: true })); // Observable<Messages>\n// ---------------------------------------------------------------------------\n\nimport type { Node } from \"@graphrefly/pure-ts/core\";\nimport { COMPLETE, DATA, ERROR, type Messages } from \"@graphrefly/pure-ts/core\";\n\n/** Observer passed to {@link InteropObservable.subscribe}. */\nexport interface InteropObserver<T> {\n\tnext?(value: T): void;\n\terror?(err: unknown): void;\n\tcomplete?(): void;\n\t/** rxjs `Subscriber` sets this; we short-circuit delivery when closed. */\n\tclosed?: boolean;\n}\n\n/** Teardown handle returned by {@link InteropObservable.subscribe}. */\nexport interface InteropSubscription {\n\tunsubscribe(): void;\n}\n\n/**\n * Minimal TC39 Observable. rxjs `from()` (and any `Symbol.observable`\n * consumer) adopts it at runtime via the well-known interop method attached\n * by {@link toObservable}. Pass the result through `from(...)` to get a\n * pipeable rxjs `Observable`.\n */\nexport interface InteropObservable<T> {\n\tsubscribe(observer: InteropObserver<T> | ((value: T) => void)): InteropSubscription;\n}\n\n/** Options for {@link toObservable}. */\nexport type ToObservableOptions = {\n\t/**\n\t * When `true`, emit raw `Messages` batches instead of extracted `DATA`\n\t * values. Terminal batches are still emitted as the final `next()` before\n\t * the error/complete signal.\n\t */\n\traw?: boolean;\n};\n\n// Well-known Observable interop key. Mirrors the rxjs / `symbol-observable`\n// resolution (the global `Symbol.observable` when the runtime or a polyfill\n// provides it, otherwise the `\"@@observable\"` string) so rxjs `from()` adopts\n// our object regardless of polyfill state.\nconst OBSERVABLE_KEY: PropertyKey =\n\t(typeof Symbol === \"function\" && (Symbol as unknown as { observable?: symbol }).observable) ||\n\t\"@@observable\";\n\nfunction normalizeObserver<T>(\n\tobserver: InteropObserver<T> | ((value: T) => void),\n): InteropObserver<T> {\n\treturn typeof observer === \"function\" ? { next: observer } : observer;\n}\n\nfunction makeInterop<T>(\n\tonSubscribe: (observer: InteropObserver<T>) => () => void,\n): InteropObservable<T> {\n\tconst obs: InteropObservable<T> = {\n\t\tsubscribe(rawObserver): InteropSubscription {\n\t\t\tconst observer = normalizeObserver(rawObserver);\n\t\t\tlet closed = false;\n\t\t\tlet teardown: (() => void) | undefined;\n\t\t\tlet teardownPending = false;\n\t\t\tconst runTeardown = (): void => {\n\t\t\t\tif (teardown) teardown();\n\t\t\t\telse teardownPending = true; // sync push-on-subscribe terminal\n\t\t\t};\n\t\t\t// Guarded observer: latch `closed` and auto-unsubscribe the node on\n\t\t\t// terminal. The prior rxjs-backed impl got this from rxjs's\n\t\t\t// `Subscriber` (closed flag + teardown-on-terminal); a plain TC39\n\t\t\t// consumer has no such machinery, so without this a post-terminal\n\t\t\t// node wave would re-fire next/error/complete and the node\n\t\t\t// subscription would leak until a manual unsubscribe(). `closed` is\n\t\t\t// also read by toObservable's per-message loop to short-circuit.\n\t\t\tconst guarded: InteropObserver<T> = {\n\t\t\t\tget closed() {\n\t\t\t\t\treturn closed;\n\t\t\t\t},\n\t\t\t\tnext(value) {\n\t\t\t\t\tif (!closed) observer.next?.(value);\n\t\t\t\t},\n\t\t\t\terror(err) {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobserver.error?.(err);\n\t\t\t\t\t} finally {\n\t\t\t\t\t\trunTeardown();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tcomplete() {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tobserver.complete?.();\n\t\t\t\t\t} finally {\n\t\t\t\t\t\trunTeardown();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t};\n\t\t\tteardown = onSubscribe(guarded);\n\t\t\tif (teardownPending) teardown(); // terminal fired before assignment\n\t\t\treturn {\n\t\t\t\tunsubscribe() {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tclosed = true;\n\t\t\t\t\tteardown?.();\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t};\n\t// TC39 interop: `x[Symbol.observable]()` returns the observable itself.\n\t(obs as unknown as Record<PropertyKey, unknown>)[OBSERVABLE_KEY] = function (\n\t\tthis: InteropObservable<T>,\n\t) {\n\t\treturn this;\n\t};\n\treturn obs;\n}\n\n/**\n * Bridge a `Node<T>` to a TC39 interop observable (no rxjs dependency).\n *\n * Default mode emits the node's value on each `DATA` message. Maps `ERROR` to\n * `observer.error()` and `COMPLETE` to `observer.complete()`.\n * Protocol-internal signals (DIRTY, RESOLVED, PAUSE, etc.) are skipped.\n *\n * With `{ raw: true }`, emits full `[[Type, Data?], ...]` message batches.\n * The stream terminates on ERROR or COMPLETE (the terminal batch is still\n * emitted as the final `next()` before the error/complete signal).\n *\n * The returned value is a spec-interop observable, **not** a concrete rxjs\n * `Observable`. Wrap with `from(toObservable(node))` for rxjs operators, or\n * use the NestJS compat layer's `toObservable` which returns a real rxjs\n * `Observable`. For graph-level observation, use\n * `toObservable(graph.resolve(path))` or subscribe to `graph.observe()`.\n *\n * Unsubscribing unsubscribes the node.\n */\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions & { raw?: false },\n): InteropObservable<T>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions: ToObservableOptions & { raw: true },\n): InteropObservable<Messages>;\nexport function toObservable<T>(\n\tnode: Node<T>,\n\toptions?: ToObservableOptions,\n): InteropObservable<T | Messages> {\n\tif (options?.raw) {\n\t\treturn makeInterop<Messages>((observer) => {\n\t\t\treturn node.subscribe((msgs) => {\n\t\t\t\tif (observer.closed) return;\n\t\t\t\tobserver.next?.(msgs);\n\t\t\t\tfor (const m of msgs) {\n\t\t\t\t\tif (m[0] === ERROR) {\n\t\t\t\t\t\tobserver.error?.(m[1]);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (m[0] === COMPLETE) {\n\t\t\t\t\t\tobserver.complete?.();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\treturn makeInterop<T>((observer) => {\n\t\treturn node.subscribe((msgs) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (observer.closed) return;\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tobserver.next?.(m[1] as T);\n\t\t\t\t} else if (m[0] === ERROR) {\n\t\t\t\t\tobserver.error?.(m[1]);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (m[0] === COMPLETE) {\n\t\t\t\t\tobserver.complete?.();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n"],"mappings":"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","names":["toObservable","import_core","import_core","import_core","import_core","import_graph","import_common","import_core","import_core","import_extra","import_graph","import_core","import_extra","import_extra","deepFreeze","deepFreeze","batch","import_core","node","toObservable","node"]}