@kronos-ts/messaging 0.1.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/command-bus.d.ts +30 -0
  2. package/dist/command-bus.d.ts.map +1 -0
  3. package/dist/command-bus.js +2 -0
  4. package/dist/command-bus.js.map +1 -0
  5. package/dist/command-handler.d.ts +58 -0
  6. package/dist/command-handler.d.ts.map +1 -0
  7. package/dist/command-handler.js +12 -0
  8. package/dist/command-handler.js.map +1 -0
  9. package/dist/command-handling-module.d.ts +53 -0
  10. package/dist/command-handling-module.d.ts.map +1 -0
  11. package/dist/command-handling-module.js +130 -0
  12. package/dist/command-handling-module.js.map +1 -0
  13. package/dist/correlation-data.d.ts +79 -0
  14. package/dist/correlation-data.d.ts.map +1 -0
  15. package/dist/correlation-data.js +133 -0
  16. package/dist/correlation-data.js.map +1 -0
  17. package/dist/dead-letter-queue.d.ts +134 -0
  18. package/dist/dead-letter-queue.d.ts.map +1 -0
  19. package/dist/dead-letter-queue.js +176 -0
  20. package/dist/dead-letter-queue.js.map +1 -0
  21. package/dist/dead-lettering-handler.d.ts +42 -0
  22. package/dist/dead-lettering-handler.d.ts.map +1 -0
  23. package/dist/dead-lettering-handler.js +67 -0
  24. package/dist/dead-lettering-handler.js.map +1 -0
  25. package/dist/descriptor.d.ts +135 -0
  26. package/dist/descriptor.d.ts.map +1 -0
  27. package/dist/descriptor.js +36 -0
  28. package/dist/descriptor.js.map +1 -0
  29. package/dist/emit-update.d.ts +22 -0
  30. package/dist/emit-update.d.ts.map +1 -0
  31. package/dist/emit-update.js +23 -0
  32. package/dist/emit-update.js.map +1 -0
  33. package/dist/event-bus.d.ts +29 -0
  34. package/dist/event-bus.d.ts.map +1 -0
  35. package/dist/event-bus.js +22 -0
  36. package/dist/event-bus.js.map +1 -0
  37. package/dist/event-criteria.d.ts +87 -0
  38. package/dist/event-criteria.d.ts.map +1 -0
  39. package/dist/event-criteria.js +90 -0
  40. package/dist/event-criteria.js.map +1 -0
  41. package/dist/event-gateway.d.ts +19 -0
  42. package/dist/event-gateway.d.ts.map +1 -0
  43. package/dist/event-gateway.js +22 -0
  44. package/dist/event-gateway.js.map +1 -0
  45. package/dist/event-handler.d.ts +30 -0
  46. package/dist/event-handler.d.ts.map +1 -0
  47. package/dist/event-handler.js +18 -0
  48. package/dist/event-handler.js.map +1 -0
  49. package/dist/event-processor-builder.d.ts +148 -0
  50. package/dist/event-processor-builder.d.ts.map +1 -0
  51. package/dist/event-processor-builder.js +175 -0
  52. package/dist/event-processor-builder.js.map +1 -0
  53. package/dist/event-processor.d.ts +10 -0
  54. package/dist/event-processor.d.ts.map +1 -0
  55. package/dist/event-processor.js +2 -0
  56. package/dist/event-processor.js.map +1 -0
  57. package/dist/event-sink.d.ts +23 -0
  58. package/dist/event-sink.d.ts.map +1 -0
  59. package/dist/event-sink.js +2 -0
  60. package/dist/event-sink.js.map +1 -0
  61. package/dist/event-source.d.ts +98 -0
  62. package/dist/event-source.d.ts.map +1 -0
  63. package/dist/event-source.js +191 -0
  64. package/dist/event-source.js.map +1 -0
  65. package/dist/gateway.d.ts +68 -0
  66. package/dist/gateway.d.ts.map +1 -0
  67. package/dist/gateway.js +62 -0
  68. package/dist/gateway.js.map +1 -0
  69. package/dist/handler-enhancer.d.ts +53 -0
  70. package/dist/handler-enhancer.d.ts.map +1 -0
  71. package/dist/handler-enhancer.js +17 -0
  72. package/dist/handler-enhancer.js.map +1 -0
  73. package/dist/handler.d.ts +51 -0
  74. package/dist/handler.d.ts.map +1 -0
  75. package/dist/handler.js +26 -0
  76. package/dist/handler.js.map +1 -0
  77. package/dist/index.d.ts +53 -0
  78. package/dist/index.d.ts.map +1 -0
  79. package/dist/index.js +103 -0
  80. package/dist/index.js.map +1 -0
  81. package/dist/intercepting-command-bus.d.ts +17 -0
  82. package/dist/intercepting-command-bus.d.ts.map +1 -0
  83. package/dist/intercepting-command-bus.js +54 -0
  84. package/dist/intercepting-command-bus.js.map +1 -0
  85. package/dist/intercepting-event-bus.d.ts +8 -0
  86. package/dist/intercepting-event-bus.d.ts.map +1 -0
  87. package/dist/intercepting-event-bus.js +22 -0
  88. package/dist/intercepting-event-bus.js.map +1 -0
  89. package/dist/intercepting-query-bus.d.ts +17 -0
  90. package/dist/intercepting-query-bus.d.ts.map +1 -0
  91. package/dist/intercepting-query-bus.js +68 -0
  92. package/dist/intercepting-query-bus.js.map +1 -0
  93. package/dist/interceptor.d.ts +46 -0
  94. package/dist/interceptor.d.ts.map +1 -0
  95. package/dist/interceptor.js +2 -0
  96. package/dist/interceptor.js.map +1 -0
  97. package/dist/message-monitor-registry.d.ts +28 -0
  98. package/dist/message-monitor-registry.d.ts.map +1 -0
  99. package/dist/message-monitor-registry.js +37 -0
  100. package/dist/message-monitor-registry.js.map +1 -0
  101. package/dist/message-monitor.d.ts +36 -0
  102. package/dist/message-monitor.d.ts.map +1 -0
  103. package/dist/message-monitor.js +39 -0
  104. package/dist/message-monitor.js.map +1 -0
  105. package/dist/message.d.ts +42 -0
  106. package/dist/message.d.ts.map +1 -0
  107. package/dist/message.js +2 -0
  108. package/dist/message.js.map +1 -0
  109. package/dist/processing-state.d.ts +115 -0
  110. package/dist/processing-state.d.ts.map +1 -0
  111. package/dist/processing-state.js +205 -0
  112. package/dist/processing-state.js.map +1 -0
  113. package/dist/processor-configuration.d.ts +51 -0
  114. package/dist/processor-configuration.d.ts.map +1 -0
  115. package/dist/processor-configuration.js +2 -0
  116. package/dist/processor-configuration.js.map +1 -0
  117. package/dist/query-bus.d.ts +51 -0
  118. package/dist/query-bus.d.ts.map +1 -0
  119. package/dist/query-bus.js +2 -0
  120. package/dist/query-bus.js.map +1 -0
  121. package/dist/query-handler.d.ts +35 -0
  122. package/dist/query-handler.d.ts.map +1 -0
  123. package/dist/query-handler.js +19 -0
  124. package/dist/query-handler.js.map +1 -0
  125. package/dist/query-handling-module.d.ts +24 -0
  126. package/dist/query-handling-module.d.ts.map +1 -0
  127. package/dist/query-handling-module.js +32 -0
  128. package/dist/query-handling-module.js.map +1 -0
  129. package/dist/replay-token.d.ts +31 -0
  130. package/dist/replay-token.d.ts.map +1 -0
  131. package/dist/replay-token.js +37 -0
  132. package/dist/replay-token.js.map +1 -0
  133. package/dist/retrying-command-bus.d.ts +32 -0
  134. package/dist/retrying-command-bus.d.ts.map +1 -0
  135. package/dist/retrying-command-bus.js +58 -0
  136. package/dist/retrying-command-bus.js.map +1 -0
  137. package/dist/routing-strategy.d.ts +30 -0
  138. package/dist/routing-strategy.d.ts.map +1 -0
  139. package/dist/routing-strategy.js +37 -0
  140. package/dist/routing-strategy.js.map +1 -0
  141. package/dist/segment.d.ts +72 -0
  142. package/dist/segment.d.ts.map +1 -0
  143. package/dist/segment.js +103 -0
  144. package/dist/segment.js.map +1 -0
  145. package/dist/send.d.ts +28 -0
  146. package/dist/send.d.ts.map +1 -0
  147. package/dist/send.js +36 -0
  148. package/dist/send.js.map +1 -0
  149. package/dist/serializer.d.ts +40 -0
  150. package/dist/serializer.d.ts.map +1 -0
  151. package/dist/serializer.js +90 -0
  152. package/dist/serializer.js.map +1 -0
  153. package/dist/simple-command-bus.d.ts +23 -0
  154. package/dist/simple-command-bus.d.ts.map +1 -0
  155. package/dist/simple-command-bus.js +49 -0
  156. package/dist/simple-command-bus.js.map +1 -0
  157. package/dist/simple-query-bus.d.ts +16 -0
  158. package/dist/simple-query-bus.d.ts.map +1 -0
  159. package/dist/simple-query-bus.js +122 -0
  160. package/dist/simple-query-bus.js.map +1 -0
  161. package/dist/span-factory.d.ts +58 -0
  162. package/dist/span-factory.d.ts.map +1 -0
  163. package/dist/span-factory.js +19 -0
  164. package/dist/span-factory.js.map +1 -0
  165. package/dist/streaming-event-processor.d.ts +65 -0
  166. package/dist/streaming-event-processor.d.ts.map +1 -0
  167. package/dist/streaming-event-processor.js +239 -0
  168. package/dist/streaming-event-processor.js.map +1 -0
  169. package/dist/subscribing-event-processor.d.ts +57 -0
  170. package/dist/subscribing-event-processor.d.ts.map +1 -0
  171. package/dist/subscribing-event-processor.js +100 -0
  172. package/dist/subscribing-event-processor.js.map +1 -0
  173. package/dist/subscription-query.d.ts +63 -0
  174. package/dist/subscription-query.d.ts.map +1 -0
  175. package/dist/subscription-query.js +119 -0
  176. package/dist/subscription-query.js.map +1 -0
  177. package/dist/token-store.d.ts +83 -0
  178. package/dist/token-store.d.ts.map +1 -0
  179. package/dist/token-store.js +112 -0
  180. package/dist/token-store.js.map +1 -0
  181. package/dist/tracing-command-bus.d.ts +16 -0
  182. package/dist/tracing-command-bus.d.ts.map +1 -0
  183. package/dist/tracing-command-bus.js +44 -0
  184. package/dist/tracing-command-bus.js.map +1 -0
  185. package/dist/tracing-handler-enhancer.d.ts +11 -0
  186. package/dist/tracing-handler-enhancer.d.ts.map +1 -0
  187. package/dist/tracing-handler-enhancer.js +27 -0
  188. package/dist/tracing-handler-enhancer.js.map +1 -0
  189. package/dist/tracking-event-processor.d.ts +72 -0
  190. package/dist/tracking-event-processor.d.ts.map +1 -0
  191. package/dist/tracking-event-processor.js +223 -0
  192. package/dist/tracking-event-processor.js.map +1 -0
  193. package/dist/tracking-token.d.ts +120 -0
  194. package/dist/tracking-token.d.ts.map +1 -0
  195. package/dist/tracking-token.js +132 -0
  196. package/dist/tracking-token.js.map +1 -0
  197. package/dist/transaction.d.ts +60 -0
  198. package/dist/transaction.d.ts.map +1 -0
  199. package/dist/transaction.js +74 -0
  200. package/dist/transaction.js.map +1 -0
  201. package/dist/unit-of-work.d.ts +41 -0
  202. package/dist/unit-of-work.d.ts.map +1 -0
  203. package/dist/unit-of-work.js +96 -0
  204. package/dist/unit-of-work.js.map +1 -0
  205. package/dist/upcaster.d.ts +91 -0
  206. package/dist/upcaster.d.ts.map +1 -0
  207. package/dist/upcaster.js +114 -0
  208. package/dist/upcaster.js.map +1 -0
  209. package/dist/with-namespace.d.ts +59 -0
  210. package/dist/with-namespace.d.ts.map +1 -0
  211. package/dist/with-namespace.js +42 -0
  212. package/dist/with-namespace.js.map +1 -0
  213. package/package.json +65 -0
  214. package/src/command-bus.ts +34 -0
  215. package/src/command-handler.ts +116 -0
  216. package/src/command-handling-module.ts +183 -0
  217. package/src/correlation-data.ts +169 -0
  218. package/src/dead-letter-queue.ts +330 -0
  219. package/src/dead-lettering-handler.ts +109 -0
  220. package/src/descriptor.ts +176 -0
  221. package/src/emit-update.ts +35 -0
  222. package/src/event-bus.ts +45 -0
  223. package/src/event-criteria.ts +141 -0
  224. package/src/event-gateway.ts +42 -0
  225. package/src/event-handler.ts +44 -0
  226. package/src/event-processor-builder.ts +246 -0
  227. package/src/event-processor.ts +9 -0
  228. package/src/event-sink.ts +23 -0
  229. package/src/event-source.ts +301 -0
  230. package/src/gateway.ts +144 -0
  231. package/src/handler-enhancer.ts +70 -0
  232. package/src/handler.ts +133 -0
  233. package/src/index.ts +356 -0
  234. package/src/intercepting-command-bus.ts +73 -0
  235. package/src/intercepting-event-bus.ts +29 -0
  236. package/src/intercepting-query-bus.ts +104 -0
  237. package/src/interceptor.ts +48 -0
  238. package/src/message-monitor-registry.ts +64 -0
  239. package/src/message-monitor.ts +68 -0
  240. package/src/message.ts +41 -0
  241. package/src/processing-state.ts +258 -0
  242. package/src/processor-configuration.ts +59 -0
  243. package/src/query-bus.ts +69 -0
  244. package/src/query-handler.ts +49 -0
  245. package/src/query-handling-module.ts +44 -0
  246. package/src/replay-token.ts +53 -0
  247. package/src/retrying-command-bus.ts +80 -0
  248. package/src/routing-strategy.ts +59 -0
  249. package/src/segment.ts +136 -0
  250. package/src/send.ts +44 -0
  251. package/src/serializer.ts +122 -0
  252. package/src/simple-command-bus.ts +59 -0
  253. package/src/simple-query-bus.ts +158 -0
  254. package/src/span-factory.ts +81 -0
  255. package/src/streaming-event-processor.ts +351 -0
  256. package/src/subscribing-event-processor.ts +169 -0
  257. package/src/subscription-query.ts +173 -0
  258. package/src/token-store.ts +211 -0
  259. package/src/tracing-command-bus.ts +52 -0
  260. package/src/tracing-handler-enhancer.ts +34 -0
  261. package/src/tracking-event-processor.ts +336 -0
  262. package/src/tracking-token.ts +231 -0
  263. package/src/transaction.ts +98 -0
  264. package/src/unit-of-work.ts +138 -0
  265. package/src/upcaster.ts +174 -0
  266. package/src/with-namespace.ts +75 -0
@@ -0,0 +1,100 @@
1
+ import { emptyMetadata, qualifiedNameToString } from "@kronos-ts/common";
2
+ import { runInNewUoW } from "./unit-of-work.js";
3
+ import { loggingErrorHandler } from "./tracking-event-processor.js";
4
+ import { setResource } from "./processing-state.js";
5
+ import { STATE_MANAGER_KEY } from "@kronos-ts/eventsourcing";
6
+ import { COMMAND_BUS_KEY } from "./send.js";
7
+ import { QUERY_BUS_KEY } from "./emit-update.js";
8
+ /**
9
+ * Creates a subscribing event processor.
10
+ *
11
+ * The processor subscribes to the event source and processes events
12
+ * within a UnitOfWork as they arrive. Events are delivered on the
13
+ * publisher's call stack (synchronous with append).
14
+ */
15
+ export function createSubscribingEventProcessor(options) {
16
+ const { name, eventSource, eventHandlers, stateManager, commandBus, queryBus, onEventDelivery, unitOfWorkRunner = runInNewUoW, errorHandler = loggingErrorHandler(name), handlerEnhancer, } = options;
17
+ // Build handler lookup: eventName → handler[]
18
+ // Plan 09-01: when a handlerEnhancer is supplied, wrap each handler at
19
+ // registration time symmetric to TrackingEventProcessor. Plan 11-02:
20
+ // handlerGroup is now the processor name (no separate group identity).
21
+ const handlerMap = new Map();
22
+ for (const reg of eventHandlers) {
23
+ const eventName = qualifiedNameToString(reg.descriptor.name);
24
+ const enhanced = handlerEnhancer
25
+ ? {
26
+ ...reg,
27
+ handler: handlerEnhancer.wrapHandler(reg.handler, {
28
+ messageType: "event",
29
+ messageName: eventName,
30
+ handlerGroup: name,
31
+ }),
32
+ }
33
+ : reg;
34
+ const existing = handlerMap.get(eventName);
35
+ if (existing) {
36
+ existing.push(enhanced);
37
+ }
38
+ else {
39
+ handlerMap.set(eventName, [enhanced]);
40
+ }
41
+ }
42
+ let isRunning = false;
43
+ let unsubscribe = null;
44
+ async function handleEvents(events) {
45
+ if (!isRunning || events.length === 0)
46
+ return;
47
+ await unitOfWorkRunner(emptyMetadata(), async () => {
48
+ for (const event of events) {
49
+ await deliverEvent(event);
50
+ }
51
+ });
52
+ }
53
+ async function deliverEvent(event) {
54
+ const eventName = qualifiedNameToString(event.name);
55
+ const handlers = handlerMap.get(eventName);
56
+ if (!handlers || handlers.length === 0)
57
+ return;
58
+ // D-44 wiring: write framework components into ALS at per-event invocation entry.
59
+ if (stateManager !== undefined)
60
+ setResource(STATE_MANAGER_KEY, stateManager);
61
+ if (commandBus !== undefined)
62
+ setResource(COMMAND_BUS_KEY, commandBus);
63
+ if (queryBus !== undefined)
64
+ setResource(QUERY_BUS_KEY, queryBus);
65
+ // Optional per-event callback (e.g. monitoring hooks registered inside the UoW).
66
+ if (onEventDelivery)
67
+ onEventDelivery();
68
+ for (const reg of handlers) {
69
+ try {
70
+ await reg.handler(event.payload, event.metadata);
71
+ }
72
+ catch (err) {
73
+ // SubscribingEventProcessor doesn't have position tracking,
74
+ // so pass -1n as position indicator
75
+ await errorHandler.handleError(err, eventName, -1n);
76
+ }
77
+ }
78
+ }
79
+ return {
80
+ get name() { return name; },
81
+ get running() { return isRunning; },
82
+ start() {
83
+ if (isRunning)
84
+ return;
85
+ isRunning = true;
86
+ unsubscribe = eventSource.subscribe(handleEvents);
87
+ },
88
+ stop() {
89
+ isRunning = false;
90
+ if (unsubscribe) {
91
+ unsubscribe();
92
+ unsubscribe = null;
93
+ }
94
+ },
95
+ supportsReset() {
96
+ return false;
97
+ },
98
+ };
99
+ }
100
+ //# sourceMappingURL=subscribing-event-processor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribing-event-processor.js","sourceRoot":"","sources":["../src/subscribing-event-processor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { QueryMessage } from "./message.js";
2
+ /**
3
+ * The result of a subscription query — initial result plus a stream
4
+ * of incremental updates.
5
+ *
6
+ * ```typescript
7
+ * const result = queryGateway.subscriptionQuery(GetCourseView, { courseId: "cs-101" })
8
+ * const initial = await result.initialResult
9
+ * console.log("Initial:", initial)
10
+ *
11
+ * for await (const update of result.updates) {
12
+ * console.log("Update:", update)
13
+ * }
14
+ * ```
15
+ */
16
+ export interface SubscriptionQueryResult {
17
+ /** The initial query result (same as a regular query dispatch). */
18
+ readonly initialResult: Promise<unknown>;
19
+ /** Stream of incremental updates. Completes when the subscription is closed or completed by the emitter. */
20
+ readonly updates: AsyncIterable<unknown>;
21
+ /** Close the subscription and release resources. */
22
+ close(): void;
23
+ }
24
+ /**
25
+ * Internal update handler — receives updates from emitUpdate() calls
26
+ * and buffers them for the AsyncIterable consumer.
27
+ */
28
+ export interface UpdateHandler {
29
+ /** The original subscription query message (for filter matching). */
30
+ readonly query: QueryMessage;
31
+ /** Offer an update to the buffer. Returns false if buffer is full. */
32
+ offer(update: unknown): boolean;
33
+ /** Mark the subscription as complete (no more updates). */
34
+ complete(): void;
35
+ /** Mark the subscription as failed. */
36
+ completeExceptionally(error: Error): void;
37
+ /** Whether this handler is still active. */
38
+ readonly active: boolean;
39
+ }
40
+ /**
41
+ * Defers a task to AFTER_COMMIT if a UnitOfWork is active, otherwise runs
42
+ * it immediately.
43
+ *
44
+ * Ensures subscription query updates are only emitted after the
45
+ * transaction commits successfully.
46
+ *
47
+ * UoW presence is decided by ALS state
48
+ * (`processingStateStorage.getStore() !== undefined`) — same precedent as
49
+ * `correlationDataDispatchInterceptor` (Plan 02-03) and `getActiveTransaction`
50
+ * (Plan 02-04). CTX-01 / Plan 03-03: vestigial `_context` parameter removed.
51
+ */
52
+ export declare function runAfterCommitOrImmediately(task: () => void): void;
53
+ /**
54
+ * Creates a bounded async buffer that implements both UpdateHandler
55
+ * (for the producer side) and provides an AsyncIterable (for the consumer).
56
+ *
57
+ * @param query The subscription query message
58
+ * @param bufferSize Maximum number of buffered updates (default: 256)
59
+ */
60
+ export declare function createUpdateHandler(query: QueryMessage, bufferSize?: number): UpdateHandler & {
61
+ iterable: AsyncIterable<unknown>;
62
+ };
63
+ //# sourceMappingURL=subscription-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-query.d.ts","sourceRoot":"","sources":["../src/subscription-query.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAOhD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,uBAAuB;IACtC,mEAAmE;IACnE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IACxC,4GAA4G;IAC5G,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;IACxC,oDAAoD;IACpD,KAAK,IAAI,IAAI,CAAA;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;IAC5B,sEAAsE;IACtE,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAA;IAC/B,2DAA2D;IAC3D,QAAQ,IAAI,IAAI,CAAA;IAChB,uCAAuC;IACvC,qBAAqB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;IACzC,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CACzB;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAalE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EACnB,UAAU,GAAE,MAAY,GACvB,aAAa,GAAG;IAAE,QAAQ,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;CAAE,CAoFtD"}
@@ -0,0 +1,119 @@
1
+ import { resourceKey } from "@kronos-ts/common";
2
+ import { processingStateStorage, computeIfAbsent, onAfterCommit, } from "./processing-state.js";
3
+ /** Resource key for deferred update tasks in ProcessingContext. */
4
+ const UPDATE_TASKS_KEY = resourceKey("subscriptionQueryUpdateTasks");
5
+ /**
6
+ * Defers a task to AFTER_COMMIT if a UnitOfWork is active, otherwise runs
7
+ * it immediately.
8
+ *
9
+ * Ensures subscription query updates are only emitted after the
10
+ * transaction commits successfully.
11
+ *
12
+ * UoW presence is decided by ALS state
13
+ * (`processingStateStorage.getStore() !== undefined`) — same precedent as
14
+ * `correlationDataDispatchInterceptor` (Plan 02-03) and `getActiveTransaction`
15
+ * (Plan 02-04). CTX-01 / Plan 03-03: vestigial `_context` parameter removed.
16
+ */
17
+ export function runAfterCommitOrImmediately(task) {
18
+ if (processingStateStorage.getStore() !== undefined) {
19
+ const tasks = computeIfAbsent(UPDATE_TASKS_KEY, () => {
20
+ const list = [];
21
+ onAfterCommit(() => {
22
+ for (const t of list)
23
+ t();
24
+ });
25
+ return list;
26
+ });
27
+ tasks.push(task);
28
+ }
29
+ else {
30
+ task();
31
+ }
32
+ }
33
+ /**
34
+ * Creates a bounded async buffer that implements both UpdateHandler
35
+ * (for the producer side) and provides an AsyncIterable (for the consumer).
36
+ *
37
+ * @param query The subscription query message
38
+ * @param bufferSize Maximum number of buffered updates (default: 256)
39
+ */
40
+ export function createUpdateHandler(query, bufferSize = 256) {
41
+ const buffer = [];
42
+ let completed = false;
43
+ let error;
44
+ let waiting = null;
45
+ function wake() {
46
+ if (waiting && (buffer.length > 0 || completed)) {
47
+ const w = waiting;
48
+ waiting = null;
49
+ if (buffer.length > 0) {
50
+ w.resolve({ value: buffer.shift(), done: false });
51
+ }
52
+ else {
53
+ w.resolve({ value: undefined, done: true });
54
+ }
55
+ }
56
+ }
57
+ const handler = {
58
+ query,
59
+ offer(update) {
60
+ if (completed)
61
+ return false;
62
+ if (buffer.length >= bufferSize)
63
+ return false;
64
+ buffer.push(update);
65
+ wake();
66
+ return true;
67
+ },
68
+ complete() {
69
+ completed = true;
70
+ wake();
71
+ },
72
+ completeExceptionally(err) {
73
+ error = err;
74
+ completed = true;
75
+ wake();
76
+ },
77
+ get active() {
78
+ return !completed;
79
+ },
80
+ iterable: {
81
+ [Symbol.asyncIterator]() {
82
+ return {
83
+ next() {
84
+ // If there's buffered data, return immediately
85
+ if (buffer.length > 0) {
86
+ return Promise.resolve({ value: buffer.shift(), done: false });
87
+ }
88
+ // If completed, signal done
89
+ if (completed) {
90
+ if (error)
91
+ return Promise.reject(error);
92
+ return Promise.resolve({ value: undefined, done: true });
93
+ }
94
+ // Wait for data or completion
95
+ return new Promise((resolve, reject) => {
96
+ waiting = {
97
+ resolve(result) {
98
+ if (error && result.done) {
99
+ reject(error);
100
+ }
101
+ else {
102
+ resolve(result);
103
+ }
104
+ },
105
+ };
106
+ });
107
+ },
108
+ return() {
109
+ completed = true;
110
+ buffer.length = 0;
111
+ return Promise.resolve({ value: undefined, done: true });
112
+ },
113
+ };
114
+ },
115
+ },
116
+ };
117
+ return handler;
118
+ }
119
+ //# sourceMappingURL=subscription-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-query.js","sourceRoot":"","sources":["../src/subscription-query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import type { TrackingToken } from "./tracking-token.js";
2
+ /**
3
+ * Stores tracking tokens for event processors and manages segment claims.
4
+ *
5
+ * Each processor has a name and one or more segments. The token
6
+ * represents the processor's position in the event stream.
7
+ *
8
+ * Claim management enables distributed processing: multiple instances
9
+ * of the same processor each claim different segments, preventing
10
+ * double-processing.
11
+ *
12
+ * Implementations should participate in the active transaction when
13
+ * available (via `getActiveTransaction()`) so that token updates
14
+ * and projection updates are atomic.
15
+ */
16
+ export interface TokenStore {
17
+ /**
18
+ * Store the token for a processor segment.
19
+ * Called during PREPARE_COMMIT phase (same transaction as handler work).
20
+ * The caller must own the claim for this segment.
21
+ */
22
+ store(processorName: string, segment: number, token: TrackingToken): Promise<void>;
23
+ /**
24
+ * Get the current token for a processor segment.
25
+ * Returns undefined if no token has been stored (start from beginning).
26
+ */
27
+ get(processorName: string, segment: number): Promise<TrackingToken | undefined>;
28
+ /**
29
+ * Initialize token segments for a processor if they don't exist yet.
30
+ * Called once during processor startup.
31
+ *
32
+ * @param processorName The processor name
33
+ * @param segmentCount Number of segments to initialize
34
+ */
35
+ initializeSegments(processorName: string, segmentCount: number): Promise<void>;
36
+ /**
37
+ * Claim a segment for processing. Returns the current token for
38
+ * that segment. Throws `UnableToClaimTokenError` if the segment
39
+ * is already claimed by another instance.
40
+ *
41
+ * @param processorName The processor name
42
+ * @param segment The segment ID to claim
43
+ * @param ownerId Unique identifier of this instance
44
+ */
45
+ claimToken(processorName: string, segment: number, ownerId: string): Promise<TrackingToken | undefined>;
46
+ /**
47
+ * Extend the claim lease for a segment without processing.
48
+ * Called periodically to prevent claim expiry during long batches.
49
+ */
50
+ extendClaim(processorName: string, segment: number, ownerId: string): Promise<void>;
51
+ /**
52
+ * Release a segment claim, allowing other instances to pick it up.
53
+ */
54
+ releaseClaim(processorName: string, segment: number, ownerId: string): Promise<void>;
55
+ /**
56
+ * Fetch all segment IDs that have tokens for a processor.
57
+ * Used during startup to discover available segments.
58
+ */
59
+ fetchSegments(processorName: string): Promise<number[]>;
60
+ /**
61
+ * Fetch segment IDs that are not currently claimed by any instance.
62
+ * Used to discover segments available for claiming.
63
+ */
64
+ fetchAvailableSegments(processorName: string): Promise<number[]>;
65
+ /**
66
+ * Delete the token for a segment (e.g., after merging).
67
+ */
68
+ deleteToken(processorName: string, segment: number): Promise<void>;
69
+ }
70
+ /**
71
+ * Thrown when a segment claim cannot be acquired (already owned by another instance).
72
+ */
73
+ export declare class UnableToClaimTokenError extends Error {
74
+ constructor(processorName: string, segment: number);
75
+ }
76
+ /**
77
+ * In-memory token store with claim management.
78
+ * Tokens and claims are lost on restart.
79
+ *
80
+ * @param claimTimeoutMs How long a claim lasts before it can be stolen (default: 10000ms)
81
+ */
82
+ export declare function createInMemoryTokenStore(claimTimeoutMs?: number): TokenStore;
83
+ //# sourceMappingURL=token-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../src/token-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,UAAU;IACzB;;;;OAIG;IACH,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAElF;;;OAGG;IACH,GAAG,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAA;IAE/E;;;;;;OAMG;IACH,kBAAkB,CAAC,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE9E;;;;;;;;OAQG;IACH,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAA;IAEvG;;;OAGG;IACH,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEnF;;OAEG;IACH,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEpF;;;OAGG;IACH,aAAa,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAEvD;;;OAGG;IACH,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAEhE;;OAEG;IACH,WAAW,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACnE;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAInD;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,cAAc,GAAE,MAAc,GAAG,UAAU,CAmHnF"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Thrown when a segment claim cannot be acquired (already owned by another instance).
3
+ */
4
+ export class UnableToClaimTokenError extends Error {
5
+ constructor(processorName, segment) {
6
+ super(`Unable to claim token for processor "${processorName}" segment ${segment}: already claimed`);
7
+ this.name = "UnableToClaimTokenError";
8
+ }
9
+ }
10
+ /**
11
+ * In-memory token store with claim management.
12
+ * Tokens and claims are lost on restart.
13
+ *
14
+ * @param claimTimeoutMs How long a claim lasts before it can be stolen (default: 10000ms)
15
+ */
16
+ export function createInMemoryTokenStore(claimTimeoutMs = 10000) {
17
+ const entries = new Map();
18
+ function key(processorName, segment) {
19
+ return `${processorName}:${segment}`;
20
+ }
21
+ function getEntry(processorName, segment) {
22
+ return entries.get(key(processorName, segment));
23
+ }
24
+ function isClaimExpired(entry) {
25
+ if (!entry.ownerId)
26
+ return true;
27
+ return Date.now() - entry.claimedAt > claimTimeoutMs;
28
+ }
29
+ return {
30
+ async store(processorName, segment, token) {
31
+ const k = key(processorName, segment);
32
+ const entry = entries.get(k);
33
+ if (entry) {
34
+ entry.token = token;
35
+ entry.claimedAt = Date.now(); // Refresh claim on store
36
+ }
37
+ else {
38
+ entries.set(k, { token, ownerId: null, claimedAt: Date.now() });
39
+ }
40
+ },
41
+ async get(processorName, segment) {
42
+ return getEntry(processorName, segment)?.token;
43
+ },
44
+ async initializeSegments(processorName, segmentCount) {
45
+ for (let i = 0; i < segmentCount; i++) {
46
+ const k = key(processorName, i);
47
+ if (!entries.has(k)) {
48
+ entries.set(k, { token: undefined, ownerId: null, claimedAt: 0 });
49
+ }
50
+ }
51
+ },
52
+ async claimToken(processorName, segment, ownerId) {
53
+ const k = key(processorName, segment);
54
+ const entry = entries.get(k);
55
+ if (!entry) {
56
+ // Segment doesn't exist yet — create and claim
57
+ const newEntry = { token: undefined, ownerId, claimedAt: Date.now() };
58
+ entries.set(k, newEntry);
59
+ return undefined;
60
+ }
61
+ if (entry.ownerId === ownerId) {
62
+ // Already owned by this instance — refresh claim
63
+ entry.claimedAt = Date.now();
64
+ return entry.token;
65
+ }
66
+ if (isClaimExpired(entry)) {
67
+ // Claim expired — steal it
68
+ entry.ownerId = ownerId;
69
+ entry.claimedAt = Date.now();
70
+ return entry.token;
71
+ }
72
+ throw new UnableToClaimTokenError(processorName, segment);
73
+ },
74
+ async extendClaim(processorName, segment, ownerId) {
75
+ const entry = getEntry(processorName, segment);
76
+ if (entry && entry.ownerId === ownerId) {
77
+ entry.claimedAt = Date.now();
78
+ }
79
+ },
80
+ async releaseClaim(processorName, segment, ownerId) {
81
+ const entry = getEntry(processorName, segment);
82
+ if (entry && entry.ownerId === ownerId) {
83
+ entry.ownerId = null;
84
+ entry.claimedAt = 0;
85
+ }
86
+ },
87
+ async fetchSegments(processorName) {
88
+ const segments = [];
89
+ const prefix = `${processorName}:`;
90
+ for (const k of entries.keys()) {
91
+ if (k.startsWith(prefix)) {
92
+ segments.push(parseInt(k.slice(prefix.length), 10));
93
+ }
94
+ }
95
+ return segments.sort((a, b) => a - b);
96
+ },
97
+ async fetchAvailableSegments(processorName) {
98
+ const segments = [];
99
+ const prefix = `${processorName}:`;
100
+ for (const [k, entry] of entries) {
101
+ if (k.startsWith(prefix) && (!entry.ownerId || isClaimExpired(entry))) {
102
+ segments.push(parseInt(k.slice(prefix.length), 10));
103
+ }
104
+ }
105
+ return segments.sort((a, b) => a - b);
106
+ },
107
+ async deleteToken(processorName, segment) {
108
+ entries.delete(key(processorName, segment));
109
+ },
110
+ };
111
+ }
112
+ //# sourceMappingURL=token-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-store.js","sourceRoot":"","sources":["../src/token-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { CommandBus } from "./command-bus.js";
2
+ import type { SpanFactory } from "./span-factory.js";
3
+ /**
4
+ * A {@link CommandBus} decorator that wraps dispatch and handler invocations
5
+ * with tracing spans.
6
+ *
7
+ * Dispatch creates a "dispatch" span and propagates trace context into the
8
+ * message metadata. Subscribe wraps each handler with a "handle" span.
9
+ *
10
+ *
11
+ * @param delegate The underlying command bus to decorate.
12
+ * @param spanFactory The span factory for creating tracing spans.
13
+ * @returns A decorated command bus with tracing instrumentation.
14
+ */
15
+ export declare function createTracingCommandBus(delegate: CommandBus, spanFactory: SpanFactory): CommandBus;
16
+ //# sourceMappingURL=tracing-command-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing-command-bus.d.ts","sourceRoot":"","sources":["../src/tracing-command-bus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAElD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,UAAU,EACpB,WAAW,EAAE,WAAW,GACvB,UAAU,CAgCZ"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * A {@link CommandBus} decorator that wraps dispatch and handler invocations
3
+ * with tracing spans.
4
+ *
5
+ * Dispatch creates a "dispatch" span and propagates trace context into the
6
+ * message metadata. Subscribe wraps each handler with a "handle" span.
7
+ *
8
+ *
9
+ * @param delegate The underlying command bus to decorate.
10
+ * @param spanFactory The span factory for creating tracing spans.
11
+ * @returns A decorated command bus with tracing instrumentation.
12
+ */
13
+ export function createTracingCommandBus(delegate, spanFactory) {
14
+ return {
15
+ async dispatch(message) {
16
+ const span = spanFactory.createDispatchSpan(`dispatch(${String(message.name)})`, message).start();
17
+ try {
18
+ const propagated = spanFactory.propagateContext(message);
19
+ const result = await delegate.dispatch(propagated);
20
+ span.end();
21
+ return result;
22
+ }
23
+ catch (err) {
24
+ span.recordException(err instanceof Error ? err : new Error(String(err)));
25
+ throw err;
26
+ }
27
+ },
28
+ subscribe(commandName, handler) {
29
+ delegate.subscribe(commandName, async (msg) => {
30
+ const span = spanFactory.createHandlerSpan(`handle(${commandName})`, msg).start();
31
+ try {
32
+ const result = await handler(msg);
33
+ span.end();
34
+ return result;
35
+ }
36
+ catch (err) {
37
+ span.recordException(err instanceof Error ? err : new Error(String(err)));
38
+ throw err;
39
+ }
40
+ });
41
+ },
42
+ };
43
+ }
44
+ //# sourceMappingURL=tracing-command-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing-command-bus.js","sourceRoot":"","sources":["../src/tracing-command-bus.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,uBAAuB,CACrC,QAAoB,EACpB,WAAwB;IAExB,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,OAAuB;YACpC,MAAM,IAAI,GAAG,WAAW,CAAC,kBAAkB,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,KAAK,EAAE,CAAA;YACjG,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,WAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;gBACxD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;gBAClD,IAAI,CAAC,GAAG,EAAE,CAAA;gBACV,OAAO,MAAM,CAAA;YACf,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,eAAe,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;gBACzE,MAAM,GAAG,CAAA;YACX,CAAC;QACH,CAAC;QAED,SAAS,CACP,WAAmB,EACnB,OAAsD;YAEtD,QAAQ,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,EAAE,GAAmB,EAAE,EAAE;gBAC5D,MAAM,IAAI,GAAG,WAAW,CAAC,iBAAiB,CAAC,UAAU,WAAW,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,CAAA;gBACjF,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;oBACjC,IAAI,CAAC,GAAG,EAAE,CAAA;oBACV,OAAO,MAAM,CAAA;gBACf,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,eAAe,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;oBACzE,MAAM,GAAG,CAAA;gBACX,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { HandlerEnhancerDefinition } from "./handler-enhancer.js";
2
+ import type { SpanFactory } from "./span-factory.js";
3
+ /**
4
+ * Handler enhancer that wraps message handler invocations with tracing spans.
5
+ *
6
+ * Creates an internal span per handler invocation, recording the handler
7
+ * name and message type as context. Errors are recorded on the span.
8
+ *
9
+ */
10
+ export declare function tracingHandlerEnhancerDefinition(spanFactory: SpanFactory): HandlerEnhancerDefinition;
11
+ //# sourceMappingURL=tracing-handler-enhancer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing-handler-enhancer.d.ts","sourceRoot":"","sources":["../src/tracing-handler-enhancer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAmB,MAAM,uBAAuB,CAAA;AACvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAEpD;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,WAAW,GACvB,yBAAyB,CAqB3B"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Handler enhancer that wraps message handler invocations with tracing spans.
3
+ *
4
+ * Creates an internal span per handler invocation, recording the handler
5
+ * name and message type as context. Errors are recorded on the span.
6
+ *
7
+ */
8
+ export function tracingHandlerEnhancerDefinition(spanFactory) {
9
+ return {
10
+ wrapHandler(handler, metadata) {
11
+ const spanName = `${metadata.handlerGroup}.${metadata.messageName}`;
12
+ return (async (...args) => {
13
+ const span = spanFactory.createInternalSpan(spanName).start();
14
+ try {
15
+ const result = await handler(...args);
16
+ span.end();
17
+ return result;
18
+ }
19
+ catch (error) {
20
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
21
+ throw error;
22
+ }
23
+ });
24
+ },
25
+ };
26
+ }
27
+ //# sourceMappingURL=tracing-handler-enhancer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing-handler-enhancer.js","sourceRoot":"","sources":["../src/tracing-handler-enhancer.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,UAAU,gCAAgC,CAC9C,WAAwB;IAExB,OAAO;QACL,WAAW,CACT,OAAU,EACV,QAAyB;YAEzB,MAAM,QAAQ,GAAG,GAAG,QAAQ,CAAC,YAAY,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAA;YAEnE,OAAO,CAAC,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;gBAC/B,MAAM,IAAI,GAAG,WAAW,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAA;gBAC7D,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;oBACrC,IAAI,CAAC,GAAG,EAAE,CAAA;oBACV,OAAO,MAAM,CAAA;gBACf,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,IAAI,CAAC,eAAe,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;oBAC/E,MAAM,KAAK,CAAA;gBACb,CAAC;YACH,CAAC,CAAiB,CAAA;QACpB,CAAC;KACF,CAAA;AACH,CAAC"}