@graphrefly/ts 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/README.md +135 -0
  2. package/dist/adapters/index.cjs +105 -66
  3. package/dist/adapters/index.cjs.map +1 -1
  4. package/dist/adapters/index.d.cts +11 -136
  5. package/dist/adapters/index.d.ts +11 -136
  6. package/dist/adapters/index.js +27 -225
  7. package/dist/adapters/index.js.map +1 -1
  8. package/dist/adapters/observe-storage.d.cts +4 -4
  9. package/dist/adapters/observe-storage.d.ts +4 -4
  10. package/dist/adapters/observe-storage.js +1 -0
  11. package/dist/adapters/observe-storage.js.map +1 -1
  12. package/dist/adapters/react.cjs +166 -0
  13. package/dist/adapters/react.cjs.map +1 -0
  14. package/dist/adapters/react.d.cts +31 -0
  15. package/dist/adapters/react.d.ts +31 -0
  16. package/dist/adapters/react.js +51 -0
  17. package/dist/adapters/react.js.map +1 -0
  18. package/dist/adapters/solid.cjs +157 -0
  19. package/dist/adapters/solid.cjs.map +1 -0
  20. package/dist/adapters/solid.d.cts +26 -0
  21. package/dist/adapters/solid.d.ts +26 -0
  22. package/dist/adapters/solid.js +48 -0
  23. package/dist/adapters/solid.js.map +1 -0
  24. package/dist/adapters/svelte.cjs +148 -0
  25. package/dist/adapters/svelte.cjs.map +1 -0
  26. package/dist/adapters/svelte.d.cts +31 -0
  27. package/dist/adapters/svelte.d.ts +31 -0
  28. package/dist/adapters/svelte.js +46 -0
  29. package/dist/adapters/svelte.js.map +1 -0
  30. package/dist/adapters/vue.cjs +155 -0
  31. package/dist/adapters/vue.cjs.map +1 -0
  32. package/dist/adapters/vue.d.cts +26 -0
  33. package/dist/adapters/vue.d.ts +26 -0
  34. package/dist/adapters/vue.js +46 -0
  35. package/dist/adapters/vue.js.map +1 -0
  36. package/dist/agent-runtime-BesGDZcB.d.ts +555 -0
  37. package/dist/agent-runtime-DZTJ3C-p.d.cts +555 -0
  38. package/dist/agentic-memory-BmRCvh0d.d.ts +517 -0
  39. package/dist/agentic-memory-DfuVZ-lY.d.cts +517 -0
  40. package/dist/capability-admission-B0BzqAm5.d.cts +102 -0
  41. package/dist/capability-admission-g0mn9hpq.d.ts +102 -0
  42. package/dist/{chunk-JR4IKCR2.js → chunk-2747WN4Y.js} +5 -5
  43. package/dist/{chunk-2ILL7HQI.js → chunk-3JR3EDB2.js} +17 -17
  44. package/dist/{chunk-2ILL7HQI.js.map → chunk-3JR3EDB2.js.map} +1 -1
  45. package/dist/{chunk-GDL26N2T.js → chunk-3KN7NJDR.js} +2 -2
  46. package/dist/{chunk-DJC4CHLQ.js → chunk-43BKLFZU.js} +9 -9
  47. package/dist/chunk-6XAIOL3X.js +2407 -0
  48. package/dist/chunk-6XAIOL3X.js.map +1 -0
  49. package/dist/{chunk-SCRFRCGR.js → chunk-BSQGE5PS.js} +1 -1
  50. package/dist/{chunk-Y3ZLRGHC.js → chunk-CZNV3VXM.js} +16 -16
  51. package/dist/chunk-DGUM43GV.js +11 -0
  52. package/dist/chunk-DGUM43GV.js.map +1 -0
  53. package/dist/{chunk-JIMUDQN3.js → chunk-FBUU43PM.js} +2 -2
  54. package/dist/chunk-H75VXTGT.js +219 -0
  55. package/dist/chunk-H75VXTGT.js.map +1 -0
  56. package/dist/{chunk-RIIOUTGM.js → chunk-HKK2JD7Z.js} +12 -9
  57. package/dist/chunk-HKK2JD7Z.js.map +1 -0
  58. package/dist/{chunk-D6BG7U6A.js → chunk-IXZBUWSP.js} +3 -3
  59. package/dist/chunk-PC3BTTBE.js +3217 -0
  60. package/dist/chunk-PC3BTTBE.js.map +1 -0
  61. package/dist/chunk-QFY4AFY4.js +879 -0
  62. package/dist/chunk-QFY4AFY4.js.map +1 -0
  63. package/dist/{chunk-DK554R7P.js → chunk-S6HXABGL.js} +2 -1
  64. package/dist/chunk-S6HXABGL.js.map +1 -0
  65. package/dist/{chunk-PKVBHGBM.js → chunk-SS2A464I.js} +7 -7
  66. package/dist/chunk-UT3MHJCW.js +49 -0
  67. package/dist/chunk-UT3MHJCW.js.map +1 -0
  68. package/dist/{chunk-G4M3NHRJ.js → chunk-V7CIJE4B.js} +3 -3
  69. package/dist/{chunk-TEW47IVR.js → chunk-VPEFSDME.js} +2 -2
  70. package/dist/chunk-VTHLCFN4.js +368 -0
  71. package/dist/chunk-VTHLCFN4.js.map +1 -0
  72. package/dist/{chunk-SWTLEQL6.js → chunk-WQIA3GFB.js} +2 -2
  73. package/dist/chunk-WQIA3GFB.js.map +1 -0
  74. package/dist/{chunk-I3IHOHCJ.js → chunk-XKXWK2KP.js} +108 -64
  75. package/dist/chunk-XKXWK2KP.js.map +1 -0
  76. package/dist/{chunk-COHO25CZ.js → chunk-YDSIVHRR.js} +553 -7
  77. package/dist/chunk-YDSIVHRR.js.map +1 -0
  78. package/dist/chunk-YXMZ2N6J.js +1884 -0
  79. package/dist/chunk-YXMZ2N6J.js.map +1 -0
  80. package/dist/composition/index.cjs +102 -57
  81. package/dist/composition/index.cjs.map +1 -1
  82. package/dist/composition/index.d.cts +4 -4
  83. package/dist/composition/index.d.ts +4 -4
  84. package/dist/composition/index.js +6 -5
  85. package/dist/core/index.cjs +102 -57
  86. package/dist/core/index.cjs.map +1 -1
  87. package/dist/core/index.d.cts +2 -2
  88. package/dist/core/index.d.ts +2 -2
  89. package/dist/core/index.js +5 -4
  90. package/dist/cqrs/index.cjs.map +1 -1
  91. package/dist/cqrs/index.d.cts +4 -4
  92. package/dist/cqrs/index.d.ts +4 -4
  93. package/dist/cqrs/index.js +3 -2
  94. package/dist/cqrs/index.js.map +1 -1
  95. package/dist/cqrs/messaging.cjs +312 -0
  96. package/dist/cqrs/messaging.cjs.map +1 -0
  97. package/dist/cqrs/messaging.d.cts +57 -0
  98. package/dist/cqrs/messaging.d.ts +57 -0
  99. package/dist/cqrs/messaging.js +274 -0
  100. package/dist/cqrs/messaging.js.map +1 -0
  101. package/dist/cqrs/work-queue.cjs +329 -0
  102. package/dist/cqrs/work-queue.cjs.map +1 -0
  103. package/dist/cqrs/work-queue.d.cts +90 -0
  104. package/dist/cqrs/work-queue.d.ts +90 -0
  105. package/dist/cqrs/work-queue.js +292 -0
  106. package/dist/cqrs/work-queue.js.map +1 -0
  107. package/dist/data/index.cjs +19 -0
  108. package/dist/data/index.cjs.map +1 -0
  109. package/dist/data/index.d.cts +36 -0
  110. package/dist/data/index.d.ts +36 -0
  111. package/dist/data/index.js +1 -0
  112. package/dist/data/index.js.map +1 -0
  113. package/dist/data-structures/index.cjs +105 -57
  114. package/dist/data-structures/index.cjs.map +1 -1
  115. package/dist/data-structures/index.d.cts +8 -8
  116. package/dist/data-structures/index.d.ts +8 -8
  117. package/dist/data-structures/index.js +7 -6
  118. package/dist/{describe-BZb7AS2y.d.ts → describe-BpyJuWkw.d.ts} +1 -1
  119. package/dist/{describe-Ciu8SUnN.d.cts → describe-DYMw_l1C.d.cts} +1 -1
  120. package/dist/executors/work-queue.cjs +342 -0
  121. package/dist/executors/work-queue.cjs.map +1 -0
  122. package/dist/executors/work-queue.d.cts +90 -0
  123. package/dist/executors/work-queue.d.ts +90 -0
  124. package/dist/executors/work-queue.js +306 -0
  125. package/dist/executors/work-queue.js.map +1 -0
  126. package/dist/graph/index.cjs +112 -58
  127. package/dist/graph/index.cjs.map +1 -1
  128. package/dist/graph/index.d.cts +9 -9
  129. package/dist/graph/index.d.ts +9 -9
  130. package/dist/graph/index.js +18 -17
  131. package/dist/{graph-DfdF9zy4.d.ts → graph-D-1-SQeC.d.ts} +3 -3
  132. package/dist/{graph-s23RbbFO.d.cts → graph-DCEWh4T2.d.cts} +3 -3
  133. package/dist/{index-CAEmLCYF.d.cts → index-72VZC0-E.d.cts} +2 -2
  134. package/dist/{index-SnzZu3x7.d.ts → index-Bmxeu0nK.d.ts} +2 -2
  135. package/dist/index.cjs +112 -58
  136. package/dist/index.cjs.map +1 -1
  137. package/dist/index.d.cts +11 -10
  138. package/dist/index.d.ts +11 -10
  139. package/dist/index.js +118 -113
  140. package/dist/inspection/boundary.cjs +98 -0
  141. package/dist/inspection/boundary.cjs.map +1 -0
  142. package/dist/inspection/boundary.d.cts +61 -0
  143. package/dist/inspection/boundary.d.ts +61 -0
  144. package/dist/inspection/boundary.js +75 -0
  145. package/dist/inspection/boundary.js.map +1 -0
  146. package/dist/{messages-BZqrGGm1.d.ts → messages-CAzUPPJM.d.cts} +10 -5
  147. package/dist/{messages-BZqrGGm1.d.cts → messages-CAzUPPJM.d.ts} +10 -5
  148. package/dist/messaging/index.cjs +744 -613
  149. package/dist/messaging/index.cjs.map +1 -1
  150. package/dist/messaging/index.d.cts +216 -160
  151. package/dist/messaging/index.d.ts +216 -160
  152. package/dist/messaging/index.js +19 -749
  153. package/dist/messaging/index.js.map +1 -1
  154. package/dist/operators/index.cjs +102 -57
  155. package/dist/operators/index.cjs.map +1 -1
  156. package/dist/operators/index.d.cts +6 -6
  157. package/dist/operators/index.d.ts +6 -6
  158. package/dist/operators/index.js +8 -7
  159. package/dist/orchestration/index.cjs +3333 -59
  160. package/dist/orchestration/index.cjs.map +1 -1
  161. package/dist/orchestration/index.d.cts +7 -4
  162. package/dist/orchestration/index.d.ts +7 -4
  163. package/dist/orchestration/index.js +49 -8
  164. package/dist/orchestration/index.js.map +1 -1
  165. package/dist/orchestration/messaging.cjs +314 -0
  166. package/dist/orchestration/messaging.cjs.map +1 -0
  167. package/dist/orchestration/messaging.d.cts +59 -0
  168. package/dist/orchestration/messaging.d.ts +59 -0
  169. package/dist/orchestration/messaging.js +276 -0
  170. package/dist/orchestration/messaging.js.map +1 -0
  171. package/dist/orchestration/work-queue.cjs +262 -0
  172. package/dist/orchestration/work-queue.cjs.map +1 -0
  173. package/dist/orchestration/work-queue.d.cts +85 -0
  174. package/dist/orchestration/work-queue.d.ts +85 -0
  175. package/dist/orchestration/work-queue.js +226 -0
  176. package/dist/orchestration/work-queue.js.map +1 -0
  177. package/dist/patterns/event-flow.cjs +447 -0
  178. package/dist/patterns/event-flow.cjs.map +1 -0
  179. package/dist/patterns/event-flow.d.cts +115 -0
  180. package/dist/patterns/event-flow.d.ts +115 -0
  181. package/dist/patterns/event-flow.js +14 -0
  182. package/dist/patterns/event-flow.js.map +1 -0
  183. package/dist/patterns/index.cjs +423 -18
  184. package/dist/patterns/index.cjs.map +1 -1
  185. package/dist/patterns/index.d.cts +8 -5
  186. package/dist/patterns/index.d.ts +8 -5
  187. package/dist/patterns/index.js +13 -4
  188. package/dist/{reactive-collection-Cb1II1Fi.d.ts → reactive-collection-BAmfrGjd.d.ts} +9 -9
  189. package/dist/{reactive-collection-BxBqtIOE.d.cts → reactive-collection-DNV0-gFi.d.cts} +9 -9
  190. package/dist/{reactive-collection-storage-D-KmjE0J.d.cts → reactive-collection-storage-BNEldDyi.d.cts} +5 -5
  191. package/dist/{reactive-collection-storage-BNiEc-Gd.d.ts → reactive-collection-storage-YZsAQsWK.d.ts} +5 -5
  192. package/dist/{reactive-map-D-g3dv8I.d.cts → reactive-map-DRD1LJ2H.d.cts} +6 -6
  193. package/dist/{reactive-map-BcB4KsQR.d.ts → reactive-map-EsDiCmJk.d.ts} +6 -6
  194. package/dist/render/index.d.cts +3 -3
  195. package/dist/render/index.d.ts +3 -3
  196. package/dist/render/index.js +1 -0
  197. package/dist/{semantic-memory-graph-BYoIlP35.d.cts → semantic-memory-graph-DKuNzuWw.d.cts} +2 -2
  198. package/dist/{semantic-memory-graph-CxyXLms3.d.ts → semantic-memory-graph-uwbwJdhe.d.ts} +2 -2
  199. package/dist/solutions/index.cjs +4478 -2
  200. package/dist/solutions/index.cjs.map +1 -1
  201. package/dist/solutions/index.d.cts +13 -519
  202. package/dist/solutions/index.d.ts +13 -519
  203. package/dist/solutions/index.js +90 -6
  204. package/dist/solutions/reactive-layout/browser/index.cjs +449 -0
  205. package/dist/solutions/reactive-layout/browser/index.cjs.map +1 -0
  206. package/dist/solutions/reactive-layout/browser/index.d.cts +44 -0
  207. package/dist/solutions/reactive-layout/browser/index.d.ts +44 -0
  208. package/dist/solutions/reactive-layout/browser/index.js +69 -0
  209. package/dist/solutions/reactive-layout/browser/index.js.map +1 -0
  210. package/dist/solutions/reactive-layout/index.cjs +4266 -0
  211. package/dist/solutions/reactive-layout/index.cjs.map +1 -0
  212. package/dist/solutions/reactive-layout/index.d.cts +581 -0
  213. package/dist/solutions/reactive-layout/index.d.ts +581 -0
  214. package/dist/solutions/reactive-layout/index.js +86 -0
  215. package/dist/solutions/reactive-layout/index.js.map +1 -0
  216. package/dist/solutions/reactive-layout/node-canvas/index.cjs +545 -0
  217. package/dist/solutions/reactive-layout/node-canvas/index.cjs.map +1 -0
  218. package/dist/solutions/reactive-layout/node-canvas/index.d.cts +54 -0
  219. package/dist/solutions/reactive-layout/node-canvas/index.d.ts +54 -0
  220. package/dist/solutions/reactive-layout/node-canvas/index.js +131 -0
  221. package/dist/solutions/reactive-layout/node-canvas/index.js.map +1 -0
  222. package/dist/solutions/reactive-layout/react-native/index.cjs +494 -0
  223. package/dist/solutions/reactive-layout/react-native/index.cjs.map +1 -0
  224. package/dist/solutions/reactive-layout/react-native/index.d.cts +51 -0
  225. package/dist/solutions/reactive-layout/react-native/index.d.ts +51 -0
  226. package/dist/solutions/reactive-layout/react-native/index.js +77 -0
  227. package/dist/solutions/reactive-layout/react-native/index.js.map +1 -0
  228. package/dist/solutions/reactive-layout/skia/index.cjs +547 -0
  229. package/dist/solutions/reactive-layout/skia/index.cjs.map +1 -0
  230. package/dist/solutions/reactive-layout/skia/index.d.cts +64 -0
  231. package/dist/solutions/reactive-layout/skia/index.d.ts +64 -0
  232. package/dist/solutions/reactive-layout/skia/index.js +70 -0
  233. package/dist/solutions/reactive-layout/skia/index.js.map +1 -0
  234. package/dist/solutions/work-item/actions.cjs +2164 -0
  235. package/dist/solutions/work-item/actions.cjs.map +1 -0
  236. package/dist/solutions/work-item/actions.d.cts +201 -0
  237. package/dist/solutions/work-item/actions.d.ts +201 -0
  238. package/dist/solutions/work-item/actions.js +1454 -0
  239. package/dist/solutions/work-item/actions.js.map +1 -0
  240. package/dist/solutions/work-item/scheduling.cjs +2454 -0
  241. package/dist/solutions/work-item/scheduling.cjs.map +1 -0
  242. package/dist/solutions/work-item/scheduling.d.cts +433 -0
  243. package/dist/solutions/work-item/scheduling.d.ts +433 -0
  244. package/dist/solutions/work-item/scheduling.js +32 -0
  245. package/dist/solutions/work-item/scheduling.js.map +1 -0
  246. package/dist/solutions/work-item/work-queue.cjs +306 -0
  247. package/dist/solutions/work-item/work-queue.cjs.map +1 -0
  248. package/dist/solutions/work-item/work-queue.d.cts +71 -0
  249. package/dist/solutions/work-item/work-queue.d.ts +71 -0
  250. package/dist/solutions/work-item/work-queue.js +270 -0
  251. package/dist/solutions/work-item/work-queue.js.map +1 -0
  252. package/dist/sources/browser.cjs +169 -57
  253. package/dist/sources/browser.cjs.map +1 -1
  254. package/dist/sources/browser.d.cts +33 -6
  255. package/dist/sources/browser.d.ts +33 -6
  256. package/dist/sources/browser.js +73 -6
  257. package/dist/sources/browser.js.map +1 -1
  258. package/dist/sources/index.cjs +102 -57
  259. package/dist/sources/index.cjs.map +1 -1
  260. package/dist/sources/index.d.cts +5 -5
  261. package/dist/sources/index.d.ts +5 -5
  262. package/dist/sources/index.js +6 -5
  263. package/dist/sources/node.cjs.map +1 -1
  264. package/dist/sources/node.d.cts +4 -4
  265. package/dist/sources/node.d.ts +4 -4
  266. package/dist/sources/node.js +2 -1
  267. package/dist/sources/node.js.map +1 -1
  268. package/dist/storage/browser.js +1 -0
  269. package/dist/storage/browser.js.map +1 -1
  270. package/dist/storage/index.d.cts +5 -5
  271. package/dist/storage/index.d.ts +5 -5
  272. package/dist/storage/index.js +5 -4
  273. package/dist/storage/node.js +1 -0
  274. package/dist/storage/node.js.map +1 -1
  275. package/dist/store-C-joM4gh.d.ts +123 -0
  276. package/dist/store-CNJwmT-h.d.cts +123 -0
  277. package/dist/testing/index.cjs +1 -0
  278. package/dist/testing/index.cjs.map +1 -1
  279. package/dist/testing/index.d.cts +1 -1
  280. package/dist/testing/index.d.ts +1 -1
  281. package/dist/testing/index.js +3 -2
  282. package/dist/{types-h12mNYbq.d.ts → types-BsJvElYZ.d.ts} +31 -31
  283. package/dist/{types-bNMSWKqF.d.cts → types-CcPIn7sy.d.cts} +31 -31
  284. package/dist/work-item-runtime-C3M79vE9.d.ts +228 -0
  285. package/dist/work-item-runtime-qaVgsL0T.d.cts +228 -0
  286. package/dist/work-queue/index.cjs +1132 -0
  287. package/dist/work-queue/index.cjs.map +1 -0
  288. package/dist/work-queue/index.d.cts +369 -0
  289. package/dist/work-queue/index.d.ts +369 -0
  290. package/dist/work-queue/index.js +1078 -0
  291. package/dist/work-queue/index.js.map +1 -0
  292. package/package.json +266 -2
  293. package/dist/chunk-COHO25CZ.js.map +0 -1
  294. package/dist/chunk-DK554R7P.js.map +0 -1
  295. package/dist/chunk-I3IHOHCJ.js.map +0 -1
  296. package/dist/chunk-RIIOUTGM.js.map +0 -1
  297. package/dist/chunk-SWTLEQL6.js.map +0 -1
  298. /package/dist/{chunk-JR4IKCR2.js.map → chunk-2747WN4Y.js.map} +0 -0
  299. /package/dist/{chunk-GDL26N2T.js.map → chunk-3KN7NJDR.js.map} +0 -0
  300. /package/dist/{chunk-DJC4CHLQ.js.map → chunk-43BKLFZU.js.map} +0 -0
  301. /package/dist/{chunk-SCRFRCGR.js.map → chunk-BSQGE5PS.js.map} +0 -0
  302. /package/dist/{chunk-Y3ZLRGHC.js.map → chunk-CZNV3VXM.js.map} +0 -0
  303. /package/dist/{chunk-JIMUDQN3.js.map → chunk-FBUU43PM.js.map} +0 -0
  304. /package/dist/{chunk-D6BG7U6A.js.map → chunk-IXZBUWSP.js.map} +0 -0
  305. /package/dist/{chunk-PKVBHGBM.js.map → chunk-SS2A464I.js.map} +0 -0
  306. /package/dist/{chunk-G4M3NHRJ.js.map → chunk-V7CIJE4B.js.map} +0 -0
  307. /package/dist/{chunk-TEW47IVR.js.map → chunk-VPEFSDME.js.map} +0 -0
@@ -0,0 +1,879 @@
1
+ import {
2
+ attachMessageBusCommandSource,
3
+ getMessageBusState,
4
+ registerMessageBusState
5
+ } from "./chunk-UT3MHJCW.js";
6
+ import {
7
+ depBatch
8
+ } from "./chunk-WQIA3GFB.js";
9
+
10
+ // src/messaging/index.ts
11
+ function eventMessage(type, payload, opts) {
12
+ assertNonEmpty(type, "eventMessage.type");
13
+ assertNonEmpty(opts.id, "eventMessage.id");
14
+ return {
15
+ id: opts.id,
16
+ type,
17
+ payload,
18
+ ...opts.key === void 0 ? {} : { key: opts.key },
19
+ ...opts.subjectId === void 0 ? {} : { subjectId: opts.subjectId },
20
+ ...opts.correlationId === void 0 ? {} : { correlationId: opts.correlationId },
21
+ ...opts.causationId === void 0 ? {} : { causationId: opts.causationId },
22
+ ...opts.occurredAtMs === void 0 ? {} : { occurredAtMs: opts.occurredAtMs },
23
+ ...opts.actor === void 0 ? {} : { actor: opts.actor },
24
+ ...opts.evidenceRefs === void 0 ? {} : { evidenceRefs: opts.evidenceRefs },
25
+ ...opts.schema === void 0 ? {} : { schema: opts.schema },
26
+ ...opts.metadata === void 0 ? {} : { metadata: opts.metadata }
27
+ };
28
+ }
29
+ function isEventMessage(value) {
30
+ return eventMessageIssue(value) === void 0;
31
+ }
32
+ function eventMessageIssue(value) {
33
+ if (!isObjectRecord(value)) {
34
+ return eventIssue("event message must be an object");
35
+ }
36
+ if (typeof value.id !== "string" || value.id.length === 0) {
37
+ return eventIssue("event message id must be a non-empty string");
38
+ }
39
+ if (typeof value.type !== "string" || value.type.length === 0) {
40
+ return eventIssue("event message type must be a non-empty string");
41
+ }
42
+ if (!("payload" in value)) {
43
+ return eventIssue("event message payload field is required");
44
+ }
45
+ return void 0;
46
+ }
47
+ function eventIssue(message) {
48
+ return {
49
+ kind: "issue",
50
+ code: "malformed-event-message",
51
+ message,
52
+ severity: "error",
53
+ source: "messageBus.eventMessage"
54
+ };
55
+ }
56
+ var PROMPTS_TOPIC = "prompts";
57
+ var RESPONSES_TOPIC = "responses";
58
+ var INJECTIONS_TOPIC = "injections";
59
+ var DEFERRED_TOPIC = "deferred";
60
+ var SPAWNS_TOPIC = "spawns";
61
+ var CONTEXT_TOPIC = "context";
62
+ var TODOS_TOPIC = "todos";
63
+ var STANDARD_TOPICS = Object.freeze([
64
+ PROMPTS_TOPIC,
65
+ RESPONSES_TOPIC,
66
+ INJECTIONS_TOPIC,
67
+ DEFERRED_TOPIC,
68
+ SPAWNS_TOPIC,
69
+ CONTEXT_TOPIC,
70
+ TODOS_TOPIC
71
+ ]);
72
+ function messageBus(graph, opts = {}) {
73
+ const name = opts.name ?? "messageBus";
74
+ const initialTopics = uniqueTopics(opts.topics ?? []);
75
+ const commandSources = [];
76
+ const commandBody = (ctx) => {
77
+ for (let i = 0; i < commandSources.length; i++) {
78
+ for (const command of depBatch(ctx, i) ?? []) ctx.down([["DATA", command]]);
79
+ }
80
+ };
81
+ const commands = graph.node([], commandBody, {
82
+ name: `${name}/commands`,
83
+ factory: "messageBusCommands",
84
+ completeWhenDepsComplete: false,
85
+ errorWhenDepsError: false
86
+ });
87
+ const state = {
88
+ graph,
89
+ name,
90
+ now: opts.now ?? Date.now,
91
+ topicPolicy: opts.topicPolicy ?? "strict",
92
+ retention: opts.retention ?? {},
93
+ dedupe: opts.dedupe ?? { commandId: "status" },
94
+ topics: new Map(initialTopics.map((topic) => [topic, makeTopicState()])),
95
+ subscriptions: /* @__PURE__ */ new Map(),
96
+ seenCommandIds: /* @__PURE__ */ new Set(),
97
+ seenIdempotencyKeys: /* @__PURE__ */ new Set(),
98
+ deadLetters: [],
99
+ deadLetterSeq: 0,
100
+ commandSources,
101
+ commandBody
102
+ };
103
+ const runtime = graph.node(
104
+ [commands],
105
+ (ctx) => {
106
+ for (const command of depBatch(ctx, 0) ?? []) {
107
+ for (const event of reduceMessageBusCommand(state, command)) {
108
+ ctx.down([["DATA", event]]);
109
+ }
110
+ }
111
+ },
112
+ {
113
+ name: `${name}/runtime`,
114
+ factory: "messageBusRuntime",
115
+ completeWhenDepsComplete: false,
116
+ errorWhenDepsError: false
117
+ }
118
+ );
119
+ graph.retain(runtime, { reason: `${name}.messageBus.runtime` });
120
+ const messages = graph.node(
121
+ [runtime],
122
+ (ctx) => {
123
+ for (const event of depBatch(ctx, 0) ?? []) {
124
+ const typed = event;
125
+ if (typed.kind === "message") ctx.down([["DATA", typed.message]]);
126
+ }
127
+ },
128
+ {
129
+ name: `${name}/messages`,
130
+ factory: "messageBusMessages",
131
+ completeWhenDepsComplete: false,
132
+ errorWhenDepsError: false
133
+ }
134
+ );
135
+ const status = graph.node(
136
+ [runtime],
137
+ (ctx) => {
138
+ for (const event of depBatch(ctx, 0) ?? []) {
139
+ const typed = event;
140
+ if (typed.kind === "status") ctx.down([["DATA", typed.status]]);
141
+ }
142
+ },
143
+ {
144
+ name: `${name}/status`,
145
+ factory: "messageBusStatus",
146
+ completeWhenDepsComplete: false,
147
+ errorWhenDepsError: false
148
+ }
149
+ );
150
+ const issues = graph.node(
151
+ [runtime],
152
+ (ctx) => {
153
+ for (const event of depBatch(ctx, 0) ?? []) {
154
+ const typed = event;
155
+ if (typed.kind === "issue") ctx.down([["DATA", typed.issue]]);
156
+ }
157
+ },
158
+ {
159
+ name: `${name}/issues`,
160
+ factory: "messageBusIssues",
161
+ completeWhenDepsComplete: false,
162
+ errorWhenDepsError: false
163
+ }
164
+ );
165
+ const bus = {
166
+ commands,
167
+ messages,
168
+ status,
169
+ issues,
170
+ ensureTopic(topic, commandOpts = {}) {
171
+ return publishCommand(commands, {
172
+ kind: "ensure-topic",
173
+ topic,
174
+ ...commandOpts.commandId === void 0 ? {} : { commandId: commandOpts.commandId }
175
+ });
176
+ },
177
+ closeTopic(topic, commandOpts = {}) {
178
+ return publishCommand(commands, {
179
+ kind: "close-topic",
180
+ topic,
181
+ ...commandOpts.commandId === void 0 ? {} : { commandId: commandOpts.commandId }
182
+ });
183
+ },
184
+ publish(topic, payload, publishOpts = {}) {
185
+ return publishCommand(commands, {
186
+ kind: "publish",
187
+ topic,
188
+ payload,
189
+ ...publishOpts.key === void 0 ? {} : { key: publishOpts.key },
190
+ ...publishOpts.commandId === void 0 ? {} : { commandId: publishOpts.commandId },
191
+ ...publishOpts.idempotencyKey === void 0 ? {} : { idempotencyKey: publishOpts.idempotencyKey }
192
+ });
193
+ },
194
+ topic(topic, projectionOpts = {}) {
195
+ assertTopicKey(topic, "messageBus.topic");
196
+ const snapshotPullId = /* @__PURE__ */ Symbol(`${name}/${topic}/topicSnapshot`);
197
+ const snapshot = graph.node(
198
+ [messages],
199
+ (ctx) => {
200
+ const params = pullParams(ctx.pull);
201
+ ctx.down([["DATA", topicPage(state, topic, params)]]);
202
+ },
203
+ {
204
+ name: projectionOpts.name ?? `${name}/${topic}/topic`,
205
+ factory: "messageBusTopicProjection",
206
+ meta: { topic },
207
+ pullId: snapshotPullId,
208
+ partial: true,
209
+ completeWhenDepsComplete: false,
210
+ errorWhenDepsError: false
211
+ }
212
+ );
213
+ return { snapshot, snapshotPullId, status, issues };
214
+ },
215
+ catalog(projectionOpts = {}) {
216
+ const snapshotPullId = /* @__PURE__ */ Symbol(`${name}/catalogSnapshot`);
217
+ const snapshot = graph.node(
218
+ [runtime],
219
+ (ctx) => {
220
+ const params = pullParams(ctx.pull);
221
+ ctx.down([["DATA", catalogPage(state, params)]]);
222
+ },
223
+ {
224
+ name: projectionOpts.name ?? `${name}/catalog`,
225
+ factory: "messageBusCatalog",
226
+ pullId: snapshotPullId,
227
+ partial: true,
228
+ completeWhenDepsComplete: false,
229
+ errorWhenDepsError: false
230
+ }
231
+ );
232
+ return { snapshot, snapshotPullId, status, issues };
233
+ },
234
+ deadLetter(projectionOpts = {}) {
235
+ const snapshotPullId = /* @__PURE__ */ Symbol(`${name}/deadLetterSnapshot`);
236
+ const snapshot = graph.node(
237
+ [runtime],
238
+ (ctx) => {
239
+ const params = pullParams(ctx.pull);
240
+ ctx.down([["DATA", deadLetterPage(state, params)]]);
241
+ },
242
+ {
243
+ name: projectionOpts.name ?? `${name}/deadLetter`,
244
+ factory: "messageBusDeadLetter",
245
+ pullId: snapshotPullId,
246
+ partial: true,
247
+ completeWhenDepsComplete: false,
248
+ errorWhenDepsError: false
249
+ }
250
+ );
251
+ return { snapshot, snapshotPullId, status, issues };
252
+ },
253
+ subscription(subscriptionOpts) {
254
+ assertTopicKey(subscriptionOpts.topic, "messageBus.subscription");
255
+ assertNonEmpty(subscriptionOpts.subscriptionId, "messageBus.subscriptionId");
256
+ const sub = ensureSubscription(state, {
257
+ topic: subscriptionOpts.topic,
258
+ subscriptionId: subscriptionOpts.subscriptionId,
259
+ from: subscriptionOpts.from ?? "earliest"
260
+ });
261
+ const availablePullId = /* @__PURE__ */ Symbol(
262
+ `${name}/${subscriptionOpts.topic}/${subscriptionOpts.subscriptionId}/available`
263
+ );
264
+ const projectionName = subscriptionOpts.name ?? `${name}/${subscriptionOpts.topic}/${subscriptionOpts.subscriptionId}`;
265
+ const available = graph.node(
266
+ [messages, status],
267
+ (ctx) => {
268
+ const params = pullParams(ctx.pull);
269
+ ctx.down([["DATA", availablePage(state, sub, params)]]);
270
+ },
271
+ {
272
+ name: `${projectionName}/available`,
273
+ factory: "messageBusSubscriptionAvailable",
274
+ meta: { topic: subscriptionOpts.topic, subscriptionId: subscriptionOpts.subscriptionId },
275
+ pullId: availablePullId,
276
+ partial: true,
277
+ completeWhenDepsComplete: false,
278
+ errorWhenDepsError: false
279
+ }
280
+ );
281
+ const cursor = graph.node(
282
+ [status],
283
+ (ctx) => {
284
+ for (const fact of depBatch(ctx, 0) ?? []) {
285
+ const typed = fact;
286
+ const subscriptionMoved = typed.topic === sub.topic && typed.subscriptionId === sub.subscriptionId && (typed.kind === "subscription-acked" || typed.kind === "subscription-sought" || typed.kind === "subscription-closed");
287
+ const retentionMoved = typed.topic === sub.topic && typed.kind === "retention-trimmed";
288
+ if (subscriptionMoved || retentionMoved) {
289
+ ctx.down([["DATA", cursorSnapshot(state, sub)]]);
290
+ }
291
+ }
292
+ },
293
+ {
294
+ name: `${projectionName}/cursor`,
295
+ factory: "messageBusSubscriptionCursor",
296
+ completeWhenDepsComplete: false,
297
+ errorWhenDepsError: false
298
+ }
299
+ );
300
+ return {
301
+ available,
302
+ availablePullId,
303
+ cursor,
304
+ status,
305
+ issues,
306
+ ack(seq, commandOpts = {}) {
307
+ return publishCommand(commands, {
308
+ kind: "ack",
309
+ topic: sub.topic,
310
+ subscriptionId: sub.subscriptionId,
311
+ seq,
312
+ ...commandOpts.commandId === void 0 ? {} : { commandId: commandOpts.commandId }
313
+ });
314
+ },
315
+ seek(nextSeq, commandOpts = {}) {
316
+ return publishCommand(commands, {
317
+ kind: "seek",
318
+ topic: sub.topic,
319
+ subscriptionId: sub.subscriptionId,
320
+ nextSeq,
321
+ ...commandOpts.commandId === void 0 ? {} : { commandId: commandOpts.commandId }
322
+ });
323
+ },
324
+ close(commandOpts = {}) {
325
+ return publishCommand(commands, {
326
+ kind: "close-subscription",
327
+ topic: sub.topic,
328
+ subscriptionId: sub.subscriptionId,
329
+ ...commandOpts.commandId === void 0 ? {} : { commandId: commandOpts.commandId }
330
+ });
331
+ }
332
+ };
333
+ }
334
+ };
335
+ registerMessageBusState(bus, state);
336
+ return bus;
337
+ }
338
+ function fromTopic(bus, topic) {
339
+ return bus.topic(topic).snapshot;
340
+ }
341
+ function toTopic(graph, source, bus, topic, opts = {}) {
342
+ const state = getMessageBusState(bus);
343
+ if (state === void 0) throw new Error("toTopic: unknown message bus implementation");
344
+ if (state.graph !== graph) throw new Error("toTopic: bus and source graph must match");
345
+ assertTopicKey(topic, "toTopic");
346
+ const commands = graph.node(
347
+ [source],
348
+ (ctx) => {
349
+ for (const value of depBatch(ctx, 0) ?? []) {
350
+ const key = opts.keyOf?.(value);
351
+ const commandId = opts.commandIdOf?.(value);
352
+ ctx.down([
353
+ [
354
+ "DATA",
355
+ {
356
+ kind: "publish",
357
+ topic,
358
+ payload: value,
359
+ ...key === void 0 ? {} : { key },
360
+ ...commandId === void 0 ? {} : { commandId }
361
+ }
362
+ ]
363
+ ]);
364
+ }
365
+ },
366
+ {
367
+ name: opts.name ?? `${state.name}/${topic}/toTopic`,
368
+ factory: "toTopic",
369
+ meta: { topic },
370
+ completeWhenDepsComplete: false,
371
+ errorWhenDepsError: false
372
+ }
373
+ );
374
+ const releaseSource = attachMessageBusCommandSource(
375
+ graph,
376
+ bus,
377
+ commands
378
+ );
379
+ let released = false;
380
+ return {
381
+ commands,
382
+ release() {
383
+ if (released) return;
384
+ released = true;
385
+ releaseSource();
386
+ }
387
+ };
388
+ }
389
+ function reduceMessageBusCommand(state, command) {
390
+ const malformed = validateCommand(command);
391
+ if (malformed !== void 0) return rejectCommand(state, command, malformed);
392
+ if (command.commandId !== void 0) {
393
+ if (state.seenCommandIds.has(command.commandId)) {
394
+ return duplicateCommandEvents(state, command, "duplicate commandId");
395
+ }
396
+ state.seenCommandIds.add(command.commandId);
397
+ }
398
+ if (command.kind === "publish" && command.idempotencyKey !== void 0 && state.seenIdempotencyKeys.has(idempotencyKey(command.topic, command.idempotencyKey))) {
399
+ return duplicateCommandEvents(state, command, "duplicate idempotencyKey");
400
+ }
401
+ switch (command.kind) {
402
+ case "ensure-topic":
403
+ return ensureTopic(state, command.topic, command.commandId);
404
+ case "close-topic": {
405
+ const topic = state.topics.get(command.topic);
406
+ if (topic === void 0) {
407
+ return issueEvents(state, command, "unknown-topic", `unknown topic '${command.topic}'`);
408
+ }
409
+ topic.closed = true;
410
+ return [
411
+ {
412
+ kind: "status",
413
+ status: statusFact(state, "topic-closed", {
414
+ topic: command.topic,
415
+ commandId: command.commandId
416
+ })
417
+ }
418
+ ];
419
+ }
420
+ case "topic-policy":
421
+ state.topicPolicy = command.topicPolicy;
422
+ return [
423
+ {
424
+ kind: "status",
425
+ status: statusFact(state, "projection-ready", {
426
+ commandId: command.commandId,
427
+ details: { topicPolicy: command.topicPolicy }
428
+ })
429
+ }
430
+ ];
431
+ case "publish":
432
+ return publishMessage(state, command);
433
+ case "ack":
434
+ return ackSubscription(state, command);
435
+ case "seek":
436
+ return seekSubscription(state, command);
437
+ case "close-subscription":
438
+ return closeSubscription(state, command);
439
+ }
440
+ }
441
+ function publishMessage(state, command) {
442
+ let topic = state.topics.get(command.topic);
443
+ const events = [];
444
+ if (topic === void 0) {
445
+ if (state.topicPolicy !== "create-as-fact") {
446
+ return issueEvents(state, command, "unknown-topic", `unknown topic '${command.topic}'`);
447
+ }
448
+ events.push(...ensureTopic(state, command.topic, command.commandId));
449
+ topic = state.topics.get(command.topic);
450
+ }
451
+ if (topic === void 0)
452
+ return issueEvents(state, command, "unknown-topic", `unknown topic '${command.topic}'`);
453
+ if (topic.closed)
454
+ return issueEvents(state, command, "closed-topic", `closed topic '${command.topic}'`);
455
+ const message = {
456
+ topic: command.topic,
457
+ seq: topic.nextSeq++,
458
+ payload: command.payload,
459
+ timestampMs: state.now(),
460
+ ...command.key === void 0 ? {} : { key: command.key },
461
+ ...command.idempotencyKey === void 0 ? {} : { idempotencyKey: command.idempotencyKey },
462
+ ...command.commandId === void 0 ? {} : { commandId: command.commandId }
463
+ };
464
+ if (command.idempotencyKey !== void 0) {
465
+ state.seenIdempotencyKeys.add(idempotencyKey(command.topic, command.idempotencyKey));
466
+ }
467
+ topic.messages.push(message);
468
+ events.push({ kind: "message", message });
469
+ events.push({
470
+ kind: "status",
471
+ status: statusFact(state, "message-published", {
472
+ topic: command.topic,
473
+ seq: message.seq,
474
+ commandId: command.commandId
475
+ })
476
+ });
477
+ events.push(...trimRetention(state, command.topic, topic));
478
+ return events;
479
+ }
480
+ function ensureTopic(state, topic, commandId) {
481
+ assertTopicKey(topic, "messageBus");
482
+ if (!state.topics.has(topic)) state.topics.set(topic, makeTopicState());
483
+ return [
484
+ {
485
+ kind: "status",
486
+ status: statusFact(state, "topic-created", { topic, commandId })
487
+ }
488
+ ];
489
+ }
490
+ function trimRetention(state, topicName, topic) {
491
+ const max = state.retention.maxMessages;
492
+ if (max === void 0 || topic.messages.length <= max) return [];
493
+ if (!Number.isInteger(max) || max < 1) {
494
+ return issueEvents(
495
+ state,
496
+ { kind: "publish", topic: topicName, payload: void 0 },
497
+ "policy-rejected",
498
+ "retention.maxMessages must be a positive integer"
499
+ );
500
+ }
501
+ const trimCount = topic.messages.length - max;
502
+ topic.messages.splice(0, trimCount);
503
+ topic.headSeq = topic.messages[0]?.seq ?? topic.nextSeq;
504
+ const events = [
505
+ {
506
+ kind: "status",
507
+ status: statusFact(state, "retention-trimmed", {
508
+ topic: topicName,
509
+ headSeq: topic.headSeq,
510
+ details: { trimCount }
511
+ })
512
+ }
513
+ ];
514
+ for (const sub of state.subscriptions.values()) {
515
+ if (sub.closed || sub.topic !== topicName || sub.nextSeq >= topic.headSeq) continue;
516
+ sub.retentionGap = true;
517
+ events.push(
518
+ ...issueEvents(
519
+ state,
520
+ {
521
+ kind: "seek",
522
+ topic: topicName,
523
+ subscriptionId: sub.subscriptionId,
524
+ nextSeq: sub.nextSeq
525
+ },
526
+ "retention-gap",
527
+ `subscription '${sub.subscriptionId}' is before retained headSeq`
528
+ )
529
+ );
530
+ }
531
+ return events;
532
+ }
533
+ function ackSubscription(state, command) {
534
+ const topic = state.topics.get(command.topic);
535
+ if (topic === void 0)
536
+ return issueEvents(state, command, "unknown-topic", `unknown topic '${command.topic}'`);
537
+ const sub = getSubscription(state, command.topic, command.subscriptionId);
538
+ if (sub === void 0)
539
+ return issueEvents(
540
+ state,
541
+ command,
542
+ "unknown-subscription",
543
+ `unknown subscription '${command.subscriptionId}'`
544
+ );
545
+ if (sub.closed)
546
+ return issueEvents(state, command, "subscription-closed", "subscription is closed");
547
+ if (sub.retentionGap)
548
+ return issueEvents(state, command, "retention-gap", "subscription must seek before ack");
549
+ if (command.seq < sub.nextSeq)
550
+ return issueEvents(state, command, "source-cursor-stale", "ack is behind subscription cursor");
551
+ if (command.seq >= topic.nextSeq)
552
+ return issueEvents(state, command, "cursor-out-of-range", "ack is beyond topic tail");
553
+ sub.nextSeq = Math.max(sub.nextSeq, command.seq + 1);
554
+ return [
555
+ {
556
+ kind: "status",
557
+ status: statusFact(state, "subscription-acked", {
558
+ topic: command.topic,
559
+ subscriptionId: command.subscriptionId,
560
+ nextSeq: sub.nextSeq,
561
+ commandId: command.commandId
562
+ })
563
+ }
564
+ ];
565
+ }
566
+ function seekSubscription(state, command) {
567
+ const topic = state.topics.get(command.topic);
568
+ if (topic === void 0)
569
+ return issueEvents(state, command, "unknown-topic", `unknown topic '${command.topic}'`);
570
+ const sub = getSubscription(state, command.topic, command.subscriptionId);
571
+ if (sub === void 0)
572
+ return issueEvents(
573
+ state,
574
+ command,
575
+ "unknown-subscription",
576
+ `unknown subscription '${command.subscriptionId}'`
577
+ );
578
+ if (sub.closed)
579
+ return issueEvents(state, command, "subscription-closed", "subscription is closed");
580
+ if (command.nextSeq < topic.headSeq)
581
+ return issueEvents(state, command, "retention-gap", "seek is before retained headSeq");
582
+ if (command.nextSeq > topic.nextSeq)
583
+ return issueEvents(state, command, "cursor-out-of-range", "seek is beyond topic tail");
584
+ sub.nextSeq = command.nextSeq;
585
+ sub.retentionGap = false;
586
+ return [
587
+ {
588
+ kind: "status",
589
+ status: statusFact(state, "subscription-sought", {
590
+ topic: command.topic,
591
+ subscriptionId: command.subscriptionId,
592
+ nextSeq: sub.nextSeq,
593
+ commandId: command.commandId
594
+ })
595
+ }
596
+ ];
597
+ }
598
+ function closeSubscription(state, command) {
599
+ if (!state.topics.has(command.topic))
600
+ return issueEvents(state, command, "unknown-topic", `unknown topic '${command.topic}'`);
601
+ const sub = getSubscription(state, command.topic, command.subscriptionId);
602
+ if (sub === void 0)
603
+ return issueEvents(
604
+ state,
605
+ command,
606
+ "unknown-subscription",
607
+ `unknown subscription '${command.subscriptionId}'`
608
+ );
609
+ sub.closed = true;
610
+ return [
611
+ {
612
+ kind: "status",
613
+ status: statusFact(state, "subscription-closed", {
614
+ topic: command.topic,
615
+ subscriptionId: command.subscriptionId,
616
+ nextSeq: sub.nextSeq,
617
+ commandId: command.commandId
618
+ })
619
+ }
620
+ ];
621
+ }
622
+ function issueEvents(state, command, code, message) {
623
+ const topic = commandTopic(command);
624
+ const commandId = commandIdOf(command);
625
+ const issue = {
626
+ kind: "issue",
627
+ code,
628
+ message,
629
+ severity: "error",
630
+ source: "messageBus",
631
+ details: command,
632
+ metadata: topic === void 0 ? void 0 : { topic }
633
+ };
634
+ const entry = {
635
+ entrySeq: ++state.deadLetterSeq,
636
+ ...topic === void 0 ? {} : { topic },
637
+ ...isObjectRecord(command) ? { command } : {},
638
+ issue,
639
+ timestampMs: state.now()
640
+ };
641
+ state.deadLetters.push(entry);
642
+ return [
643
+ { kind: "issue", issue },
644
+ { kind: "dead-letter", entry },
645
+ {
646
+ kind: "status",
647
+ status: statusFact(state, "command-rejected", {
648
+ topic,
649
+ commandId,
650
+ issueCode: code
651
+ })
652
+ }
653
+ ];
654
+ }
655
+ function rejectCommand(state, command, reason) {
656
+ return issueEvents(state, command, "malformed-command", reason);
657
+ }
658
+ function duplicateCommandEvents(state, command, message) {
659
+ const status = statusFact(state, "duplicate-command", {
660
+ topic: "topic" in command ? command.topic : void 0,
661
+ commandId: command.commandId
662
+ });
663
+ if (state.dedupe.commandId === "issue") {
664
+ return [
665
+ { kind: "status", status },
666
+ ...issueEvents(state, command, "duplicate-command", message)
667
+ ];
668
+ }
669
+ return [{ kind: "status", status }];
670
+ }
671
+ function statusFact(state, kind, fields) {
672
+ return {
673
+ kind,
674
+ timestampMs: state.now(),
675
+ ...fields.topic === void 0 ? {} : { topic: fields.topic },
676
+ ...fields.seq === void 0 ? {} : { seq: fields.seq },
677
+ ...fields.headSeq === void 0 ? {} : { headSeq: fields.headSeq },
678
+ ...fields.subscriptionId === void 0 ? {} : { subscriptionId: fields.subscriptionId },
679
+ ...fields.nextSeq === void 0 ? {} : { nextSeq: fields.nextSeq },
680
+ ...fields.commandId === void 0 ? {} : { commandId: fields.commandId },
681
+ ...fields.issueCode === void 0 ? {} : { issueCode: fields.issueCode },
682
+ ...fields.details === void 0 ? {} : { details: fields.details }
683
+ };
684
+ }
685
+ function validateCommand(command) {
686
+ if (!isObjectRecord(command)) return "command must be an object";
687
+ if (typeof command.kind !== "string") return "command kind is required";
688
+ if (!isMessageBusCommandKind(command.kind)) return `unknown command kind '${command.kind}'`;
689
+ if ("topic" in command) {
690
+ if (typeof command.topic !== "string") return "messageBus: topic must be a non-empty string";
691
+ const topicError = validateTopicKey(command.topic, "messageBus");
692
+ if (topicError !== void 0) return topicError;
693
+ }
694
+ if ("subscriptionId" in command && typeof command.subscriptionId !== "string") {
695
+ return "subscriptionId must be a string";
696
+ }
697
+ if (command.kind === "publish" && command.payload === void 0)
698
+ return "publish payload is required";
699
+ if (command.kind === "ack" && !isPositiveSeq(command.seq))
700
+ return "ack seq must be a positive integer";
701
+ if (command.kind === "seek" && !isPositiveSeq(command.nextSeq)) {
702
+ return "seek nextSeq must be a positive integer";
703
+ }
704
+ if (command.kind === "topic-policy" && command.topicPolicy !== "strict" && command.topicPolicy !== "create-as-fact") {
705
+ return "topicPolicy is not recognized";
706
+ }
707
+ return void 0;
708
+ }
709
+ function isMessageBusCommandKind(kind) {
710
+ return kind === "ensure-topic" || kind === "close-topic" || kind === "publish" || kind === "topic-policy" || kind === "ack" || kind === "seek" || kind === "close-subscription";
711
+ }
712
+ function catalogPage(state, params) {
713
+ const limit = positiveLimit(params.limit);
714
+ const topics = [...state.topics.entries()].filter(
715
+ ([topic, value]) => (params.includeClosed ? true : !value.closed) && (params.afterTopic === void 0 || topic > params.afterTopic)
716
+ ).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
717
+ const page = topics.slice(0, limit);
718
+ const hasMore = topics.length > limit;
719
+ return {
720
+ topics: page.map(([topic, value]) => ({
721
+ topic,
722
+ closed: value.closed,
723
+ headSeq: value.headSeq,
724
+ nextSeq: value.nextSeq,
725
+ messageCount: value.messages.length
726
+ })),
727
+ ...hasMore && page.length > 0 ? { nextAfterTopic: page[page.length - 1]?.[0] } : {},
728
+ hasMore
729
+ };
730
+ }
731
+ function topicPage(state, topicName, params) {
732
+ const topic = state.topics.get(topicName);
733
+ const start = params.afterSeq === void 0 ? topic?.headSeq ?? 1 : params.afterSeq + 1;
734
+ const all = (topic?.messages ?? []).filter((message) => message.seq >= start);
735
+ const limit = positiveLimit(params.limit);
736
+ const messages = all.slice(0, limit);
737
+ const hasMore = all.length > limit;
738
+ return {
739
+ topic: topicName,
740
+ messages,
741
+ fromSeq: start,
742
+ ...messages.length > 0 ? { throughSeq: messages[messages.length - 1]?.seq } : {},
743
+ ...hasMore && messages.length > 0 ? { nextAfterSeq: messages[messages.length - 1]?.seq } : {},
744
+ hasMore
745
+ };
746
+ }
747
+ function availablePage(state, sub, params) {
748
+ const cursor = cursorSnapshot(state, sub);
749
+ const start = params.afterSeq === void 0 ? sub.nextSeq : params.afterSeq + 1;
750
+ const topic = state.topics.get(sub.topic);
751
+ const all = sub.retentionGap ? [] : (topic?.messages ?? []).filter((message) => message.seq >= start);
752
+ const limit = positiveLimit(params.limit);
753
+ const messages = all.slice(0, limit);
754
+ const hasMore = all.length > limit;
755
+ return {
756
+ topic: sub.topic,
757
+ subscriptionId: sub.subscriptionId,
758
+ cursor,
759
+ messages,
760
+ fromSeq: start,
761
+ ...messages.length > 0 ? { throughSeq: messages[messages.length - 1]?.seq } : {},
762
+ ...hasMore && messages.length > 0 ? { nextAfterSeq: messages[messages.length - 1]?.seq } : {},
763
+ hasMore
764
+ };
765
+ }
766
+ function deadLetterPage(state, params) {
767
+ const limit = positiveLimit(params.limit);
768
+ const entries = state.deadLetters.filter((entry) => {
769
+ if (params.afterEntrySeq !== void 0 && entry.entrySeq <= params.afterEntrySeq) return false;
770
+ if (params.topic !== void 0 && entry.topic !== params.topic) return false;
771
+ if (params.code !== void 0 && entry.issue.code !== params.code) return false;
772
+ return true;
773
+ });
774
+ const page = entries.slice(0, limit);
775
+ const hasMore = entries.length > limit;
776
+ return {
777
+ entries: page,
778
+ ...hasMore && page.length > 0 ? { nextAfterEntrySeq: page[page.length - 1]?.entrySeq } : {},
779
+ hasMore
780
+ };
781
+ }
782
+ function cursorSnapshot(state, sub) {
783
+ const topic = state.topics.get(sub.topic);
784
+ return {
785
+ topic: sub.topic,
786
+ subscriptionId: sub.subscriptionId,
787
+ nextSeq: sub.nextSeq,
788
+ closed: sub.closed,
789
+ retentionGap: sub.retentionGap,
790
+ headSeq: topic?.headSeq ?? 1
791
+ };
792
+ }
793
+ function ensureSubscription(state, opts) {
794
+ const key = `${opts.topic}\0${opts.subscriptionId}`;
795
+ const existing = state.subscriptions.get(key);
796
+ if (existing !== void 0) return existing;
797
+ const topic = state.topics.get(opts.topic);
798
+ const nextSeq = opts.from === "earliest" ? topic?.headSeq ?? 1 : opts.from === "latest" ? topic?.nextSeq ?? 1 : opts.from;
799
+ const sub = {
800
+ topic: opts.topic,
801
+ subscriptionId: opts.subscriptionId,
802
+ nextSeq,
803
+ closed: false,
804
+ retentionGap: topic !== void 0 && nextSeq < topic.headSeq
805
+ };
806
+ state.subscriptions.set(key, sub);
807
+ return sub;
808
+ }
809
+ function getSubscription(state, topic, subscriptionId) {
810
+ return state.subscriptions.get(`${topic}\0${subscriptionId}`);
811
+ }
812
+ function pullParams(pull) {
813
+ return isObjectRecord(pull?.params) ? pull.params : {};
814
+ }
815
+ function publishCommand(commandNode, command) {
816
+ commandNode.down([["DATA", command]]);
817
+ return command;
818
+ }
819
+ function makeTopicState() {
820
+ return { closed: false, headSeq: 1, nextSeq: 1, messages: [] };
821
+ }
822
+ function uniqueTopics(topics) {
823
+ const unique = [...new Set(topics)];
824
+ if (unique.length !== topics.length) throw new Error("messageBus: duplicate topic");
825
+ for (const topic of unique) assertTopicKey(topic, "messageBus");
826
+ return Object.freeze(unique.sort());
827
+ }
828
+ function assertTopicKey(topic, owner) {
829
+ const error = validateTopicKey(topic, owner);
830
+ if (error !== void 0) throw new Error(error);
831
+ }
832
+ function validateTopicKey(topic, owner) {
833
+ if (typeof topic !== "string" || topic.length === 0)
834
+ return `${owner}: topic must be a non-empty string`;
835
+ return void 0;
836
+ }
837
+ function assertNonEmpty(value, owner) {
838
+ if (typeof value !== "string" || value.length === 0)
839
+ throw new Error(`${owner}: must be a non-empty string`);
840
+ }
841
+ function positiveLimit(limit) {
842
+ if (limit === void 0) return 100;
843
+ if (!Number.isInteger(limit) || limit < 1)
844
+ throw new Error("messageBus: limit must be a positive integer");
845
+ return limit;
846
+ }
847
+ function isPositiveSeq(value) {
848
+ return Number.isInteger(value) && value >= 1;
849
+ }
850
+ function isObjectRecord(value) {
851
+ return typeof value === "object" && value !== null && !Array.isArray(value);
852
+ }
853
+ function commandTopic(command) {
854
+ return isObjectRecord(command) && typeof command.topic === "string" ? command.topic : void 0;
855
+ }
856
+ function commandIdOf(command) {
857
+ return isObjectRecord(command) && typeof command.commandId === "string" ? command.commandId : void 0;
858
+ }
859
+ function idempotencyKey(topic, key) {
860
+ return `${topic}\0${key}`;
861
+ }
862
+
863
+ export {
864
+ eventMessage,
865
+ isEventMessage,
866
+ eventMessageIssue,
867
+ PROMPTS_TOPIC,
868
+ RESPONSES_TOPIC,
869
+ INJECTIONS_TOPIC,
870
+ DEFERRED_TOPIC,
871
+ SPAWNS_TOPIC,
872
+ CONTEXT_TOPIC,
873
+ TODOS_TOPIC,
874
+ STANDARD_TOPICS,
875
+ messageBus,
876
+ fromTopic,
877
+ toTopic
878
+ };
879
+ //# sourceMappingURL=chunk-QFY4AFY4.js.map