@ddd-ts-kit/events 0.0.0-stage → 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 (230) hide show
  1. package/README.md +462 -2
  2. package/dist/asyncapi/async-api-document.d.ts +15 -0
  3. package/dist/asyncapi/async-api-document.d.ts.map +1 -0
  4. package/dist/asyncapi/async-api-document.js +2 -0
  5. package/dist/asyncapi/async-api-document.js.map +1 -0
  6. package/dist/asyncapi/async-api-info.d.ts +6 -0
  7. package/dist/asyncapi/async-api-info.d.ts.map +1 -0
  8. package/dist/asyncapi/async-api-info.js +2 -0
  9. package/dist/asyncapi/async-api-info.js.map +1 -0
  10. package/dist/asyncapi/async-api-server.d.ts +7 -0
  11. package/dist/asyncapi/async-api-server.d.ts.map +1 -0
  12. package/dist/asyncapi/async-api-server.js +2 -0
  13. package/dist/asyncapi/async-api-server.js.map +1 -0
  14. package/dist/asyncapi/check-async-api-drift.d.ts +6 -0
  15. package/dist/asyncapi/check-async-api-drift.d.ts.map +1 -0
  16. package/dist/asyncapi/check-async-api-drift.js +6 -0
  17. package/dist/asyncapi/check-async-api-drift.js.map +1 -0
  18. package/dist/asyncapi/generate-async-api.d.ts +16 -0
  19. package/dist/asyncapi/generate-async-api.d.ts.map +1 -0
  20. package/dist/asyncapi/generate-async-api.js +116 -0
  21. package/dist/asyncapi/generate-async-api.js.map +1 -0
  22. package/dist/asyncapi/stringify-async-api.d.ts +4 -0
  23. package/dist/asyncapi/stringify-async-api.d.ts.map +1 -0
  24. package/dist/asyncapi/stringify-async-api.js +5 -0
  25. package/dist/asyncapi/stringify-async-api.js.map +1 -0
  26. package/dist/asyncapi.d.ts +7 -0
  27. package/dist/asyncapi.d.ts.map +1 -0
  28. package/dist/asyncapi.js +7 -0
  29. package/dist/asyncapi.js.map +1 -0
  30. package/dist/catalog/generate-event-catalog.d.ts +12 -0
  31. package/dist/catalog/generate-event-catalog.d.ts.map +1 -0
  32. package/dist/catalog/generate-event-catalog.js +63 -0
  33. package/dist/catalog/generate-event-catalog.js.map +1 -0
  34. package/dist/catalog/payload-field.d.ts +8 -0
  35. package/dist/catalog/payload-field.d.ts.map +1 -0
  36. package/dist/catalog/payload-field.js +2 -0
  37. package/dist/catalog/payload-field.js.map +1 -0
  38. package/dist/catalog/payload-fields.d.ts +7 -0
  39. package/dist/catalog/payload-fields.d.ts.map +1 -0
  40. package/dist/catalog/payload-fields.js +105 -0
  41. package/dist/catalog/payload-fields.js.map +1 -0
  42. package/dist/definition/any-integration-event-definition.d.ts +4 -0
  43. package/dist/definition/any-integration-event-definition.d.ts.map +1 -0
  44. package/dist/definition/any-integration-event-definition.js +2 -0
  45. package/dist/definition/any-integration-event-definition.js.map +1 -0
  46. package/dist/definition/define-integration-event.d.ts +15 -0
  47. package/dist/definition/define-integration-event.d.ts.map +1 -0
  48. package/dist/definition/define-integration-event.js +73 -0
  49. package/dist/definition/define-integration-event.js.map +1 -0
  50. package/dist/definition/event-meta.d.ts +7 -0
  51. package/dist/definition/event-meta.d.ts.map +1 -0
  52. package/dist/definition/event-meta.js +2 -0
  53. package/dist/definition/event-meta.js.map +1 -0
  54. package/dist/definition/event-parse-error.d.ts +14 -0
  55. package/dist/definition/event-parse-error.d.ts.map +1 -0
  56. package/dist/definition/event-parse-error.js +2 -0
  57. package/dist/definition/event-parse-error.js.map +1 -0
  58. package/dist/definition/integration-event-definition.d.ts +20 -0
  59. package/dist/definition/integration-event-definition.d.ts.map +1 -0
  60. package/dist/definition/integration-event-definition.js +2 -0
  61. package/dist/definition/integration-event-definition.js.map +1 -0
  62. package/dist/definition/invalid-event-definition-error.d.ts +4 -0
  63. package/dist/definition/invalid-event-definition-error.d.ts.map +1 -0
  64. package/dist/definition/invalid-event-definition-error.js +7 -0
  65. package/dist/definition/invalid-event-definition-error.js.map +1 -0
  66. package/dist/definition/invalid-event-payload-error.d.ts +9 -0
  67. package/dist/definition/invalid-event-payload-error.d.ts.map +1 -0
  68. package/dist/definition/invalid-event-payload-error.js +16 -0
  69. package/dist/definition/invalid-event-payload-error.js.map +1 -0
  70. package/dist/definition/payload-of.d.ts +3 -0
  71. package/dist/definition/payload-of.d.ts.map +1 -0
  72. package/dist/definition/payload-of.js +2 -0
  73. package/dist/definition/payload-of.js.map +1 -0
  74. package/dist/index.d.ts +37 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +37 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/internal/json-schema/as-schema.d.ts +3 -0
  79. package/dist/internal/json-schema/as-schema.d.ts.map +1 -0
  80. package/dist/internal/json-schema/as-schema.js +5 -0
  81. package/dist/internal/json-schema/as-schema.js.map +1 -0
  82. package/dist/internal/json-schema/compare-text.d.ts +2 -0
  83. package/dist/internal/json-schema/compare-text.d.ts.map +1 -0
  84. package/dist/internal/json-schema/compare-text.js +5 -0
  85. package/dist/internal/json-schema/compare-text.js.map +1 -0
  86. package/dist/internal/json-schema/is-record.d.ts +2 -0
  87. package/dist/internal/json-schema/is-record.d.ts.map +1 -0
  88. package/dist/internal/json-schema/is-record.js +4 -0
  89. package/dist/internal/json-schema/is-record.js.map +1 -0
  90. package/dist/internal/json-schema/local-ref-name.d.ts +3 -0
  91. package/dist/internal/json-schema/local-ref-name.d.ts.map +1 -0
  92. package/dist/internal/json-schema/local-ref-name.js +6 -0
  93. package/dist/internal/json-schema/local-ref-name.js.map +1 -0
  94. package/dist/internal/json-schema/rewrite-local-refs.d.ts +2 -0
  95. package/dist/internal/json-schema/rewrite-local-refs.d.ts.map +1 -0
  96. package/dist/internal/json-schema/rewrite-local-refs.js +19 -0
  97. package/dist/internal/json-schema/rewrite-local-refs.js.map +1 -0
  98. package/dist/internal/json-schema/sort-keys.d.ts +2 -0
  99. package/dist/internal/json-schema/sort-keys.d.ts.map +1 -0
  100. package/dist/internal/json-schema/sort-keys.js +5 -0
  101. package/dist/internal/json-schema/sort-keys.js.map +1 -0
  102. package/dist/internal/json-schema/split-definitions.d.ts +8 -0
  103. package/dist/internal/json-schema/split-definitions.d.ts.map +1 -0
  104. package/dist/internal/json-schema/split-definitions.js +13 -0
  105. package/dist/internal/json-schema/split-definitions.js.map +1 -0
  106. package/dist/outbox/duplicate-outbox-event-error.d.ts +5 -0
  107. package/dist/outbox/duplicate-outbox-event-error.d.ts.map +1 -0
  108. package/dist/outbox/duplicate-outbox-event-error.js +8 -0
  109. package/dist/outbox/duplicate-outbox-event-error.js.map +1 -0
  110. package/dist/outbox/in-memory-outbox-store.d.ts +32 -0
  111. package/dist/outbox/in-memory-outbox-store.d.ts.map +1 -0
  112. package/dist/outbox/in-memory-outbox-store.js +121 -0
  113. package/dist/outbox/in-memory-outbox-store.js.map +1 -0
  114. package/dist/outbox/outbox-publisher.d.ts +14 -0
  115. package/dist/outbox/outbox-publisher.d.ts.map +1 -0
  116. package/dist/outbox/outbox-publisher.js +18 -0
  117. package/dist/outbox/outbox-publisher.js.map +1 -0
  118. package/dist/outbox/outbox-record.d.ts +14 -0
  119. package/dist/outbox/outbox-record.d.ts.map +1 -0
  120. package/dist/outbox/outbox-record.js +2 -0
  121. package/dist/outbox/outbox-record.js.map +1 -0
  122. package/dist/outbox/outbox-stats.d.ts +9 -0
  123. package/dist/outbox/outbox-stats.d.ts.map +1 -0
  124. package/dist/outbox/outbox-stats.js +2 -0
  125. package/dist/outbox/outbox-stats.js.map +1 -0
  126. package/dist/outbox/outbox-status.d.ts +2 -0
  127. package/dist/outbox/outbox-status.d.ts.map +1 -0
  128. package/dist/outbox/outbox-status.js +2 -0
  129. package/dist/outbox/outbox-status.js.map +1 -0
  130. package/dist/outbox/outbox-store.d.ts +33 -0
  131. package/dist/outbox/outbox-store.d.ts.map +1 -0
  132. package/dist/outbox/outbox-store.js +13 -0
  133. package/dist/outbox/outbox-store.js.map +1 -0
  134. package/dist/publishing/unknown-event-error.d.ts +7 -0
  135. package/dist/publishing/unknown-event-error.d.ts.map +1 -0
  136. package/dist/publishing/unknown-event-error.js +12 -0
  137. package/dist/publishing/unknown-event-error.js.map +1 -0
  138. package/dist/publishing/validating-publisher.d.ts +12 -0
  139. package/dist/publishing/validating-publisher.d.ts.map +1 -0
  140. package/dist/publishing/validating-publisher.js +33 -0
  141. package/dist/publishing/validating-publisher.js.map +1 -0
  142. package/dist/registry/create-event-registry.d.ts +4 -0
  143. package/dist/registry/create-event-registry.d.ts.map +1 -0
  144. package/dist/registry/create-event-registry.js +5 -0
  145. package/dist/registry/create-event-registry.js.map +1 -0
  146. package/dist/registry/duplicate-event-definition-error.d.ts +4 -0
  147. package/dist/registry/duplicate-event-definition-error.d.ts.map +1 -0
  148. package/dist/registry/duplicate-event-definition-error.js +7 -0
  149. package/dist/registry/duplicate-event-definition-error.js.map +1 -0
  150. package/dist/registry/event-registry.d.ts +11 -0
  151. package/dist/registry/event-registry.d.ts.map +1 -0
  152. package/dist/registry/event-registry.js +33 -0
  153. package/dist/registry/event-registry.js.map +1 -0
  154. package/dist/relay/claim-window.d.ts +6 -0
  155. package/dist/relay/claim-window.d.ts.map +1 -0
  156. package/dist/relay/claim-window.js +2 -0
  157. package/dist/relay/claim-window.js.map +1 -0
  158. package/dist/relay/error-code.d.ts +6 -0
  159. package/dist/relay/error-code.d.ts.map +1 -0
  160. package/dist/relay/error-code.js +16 -0
  161. package/dist/relay/error-code.js.map +1 -0
  162. package/dist/relay/event-key.d.ts +3 -0
  163. package/dist/relay/event-key.d.ts.map +1 -0
  164. package/dist/relay/event-key.js +2 -0
  165. package/dist/relay/event-key.js.map +1 -0
  166. package/dist/relay/hold-until.d.ts +3 -0
  167. package/dist/relay/hold-until.d.ts.map +1 -0
  168. package/dist/relay/hold-until.js +2 -0
  169. package/dist/relay/hold-until.js.map +1 -0
  170. package/dist/relay/in-memory-relay-signal.d.ts +9 -0
  171. package/dist/relay/in-memory-relay-signal.d.ts.map +1 -0
  172. package/dist/relay/in-memory-relay-signal.js +13 -0
  173. package/dist/relay/in-memory-relay-signal.js.map +1 -0
  174. package/dist/relay/key-order.d.ts +35 -0
  175. package/dist/relay/key-order.d.ts.map +1 -0
  176. package/dist/relay/key-order.js +102 -0
  177. package/dist/relay/key-order.js.map +1 -0
  178. package/dist/relay/keyed-record.d.ts +6 -0
  179. package/dist/relay/keyed-record.d.ts.map +1 -0
  180. package/dist/relay/keyed-record.js +2 -0
  181. package/dist/relay/keyed-record.js.map +1 -0
  182. package/dist/relay/outbox-backoff.d.ts +9 -0
  183. package/dist/relay/outbox-backoff.d.ts.map +1 -0
  184. package/dist/relay/outbox-backoff.js +2 -0
  185. package/dist/relay/outbox-backoff.js.map +1 -0
  186. package/dist/relay/outbox-ordering.d.ts +7 -0
  187. package/dist/relay/outbox-ordering.d.ts.map +1 -0
  188. package/dist/relay/outbox-ordering.js +2 -0
  189. package/dist/relay/outbox-ordering.js.map +1 -0
  190. package/dist/relay/outbox-relay-failure.d.ts +12 -0
  191. package/dist/relay/outbox-relay-failure.d.ts.map +1 -0
  192. package/dist/relay/outbox-relay-failure.js +2 -0
  193. package/dist/relay/outbox-relay-failure.js.map +1 -0
  194. package/dist/relay/outbox-relay.d.ts +85 -0
  195. package/dist/relay/outbox-relay.d.ts.map +1 -0
  196. package/dist/relay/outbox-relay.js +193 -0
  197. package/dist/relay/outbox-relay.js.map +1 -0
  198. package/dist/relay/record-group.d.ts +6 -0
  199. package/dist/relay/record-group.d.ts.map +1 -0
  200. package/dist/relay/record-group.js +2 -0
  201. package/dist/relay/record-group.js.map +1 -0
  202. package/dist/relay/relay-signal.d.ts +15 -0
  203. package/dist/relay/relay-signal.d.ts.map +1 -0
  204. package/dist/relay/relay-signal.js +12 -0
  205. package/dist/relay/relay-signal.js.map +1 -0
  206. package/dist/subscription/consume.d.ts +18 -0
  207. package/dist/subscription/consume.d.ts.map +1 -0
  208. package/dist/subscription/consume.js +10 -0
  209. package/dist/subscription/consume.js.map +1 -0
  210. package/dist/subscription/event-scope-options.d.ts +13 -0
  211. package/dist/subscription/event-scope-options.d.ts.map +1 -0
  212. package/dist/subscription/event-scope-options.js +2 -0
  213. package/dist/subscription/event-scope-options.js.map +1 -0
  214. package/dist/subscription/event-subscription.d.ts +6 -0
  215. package/dist/subscription/event-subscription.d.ts.map +1 -0
  216. package/dist/subscription/event-subscription.js +2 -0
  217. package/dist/subscription/event-subscription.js.map +1 -0
  218. package/dist/subscription/on.d.ts +26 -0
  219. package/dist/subscription/on.d.ts.map +1 -0
  220. package/dist/subscription/on.js +62 -0
  221. package/dist/subscription/on.js.map +1 -0
  222. package/dist/subscription/releasable-processed-event-store.d.ts +14 -0
  223. package/dist/subscription/releasable-processed-event-store.d.ts.map +1 -0
  224. package/dist/subscription/releasable-processed-event-store.js +2 -0
  225. package/dist/subscription/releasable-processed-event-store.js.map +1 -0
  226. package/dist/subscription/subscribe-all.d.ts +5 -0
  227. package/dist/subscription/subscribe-all.d.ts.map +1 -0
  228. package/dist/subscription/subscribe-all.js +12 -0
  229. package/dist/subscription/subscribe-all.js.map +1 -0
  230. package/package.json +37 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-relay-failure.d.ts","sourceRoot":"","sources":["../../src/relay/outbox-relay-failure.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC1B;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outbox-relay-failure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-relay-failure.js","sourceRoot":"","sources":["../../src/relay/outbox-relay-failure.ts"],"names":[],"mappings":""}
@@ -0,0 +1,85 @@
1
+ import type { Clock, IntegrationEvent, IntegrationEventPublisher } from '@ddd-ts-kit/kernel';
2
+ import type { OutboxStore } from '../outbox/outbox-store.js';
3
+ import type { OutboxBackoff } from './outbox-backoff.js';
4
+ import type { OutboxOrdering } from './outbox-ordering.js';
5
+ import type { OutboxRelayFailure } from './outbox-relay-failure.js';
6
+ import type { RelaySignal } from './relay-signal.js';
7
+ export interface OutboxRelayOptions {
8
+ readonly store: OutboxStore;
9
+ /** The real provider: a broker adapter, or the in-memory bus in a single process. */
10
+ readonly publisher: IntegrationEventPublisher;
11
+ readonly clock: Clock;
12
+ /** Default 100. */
13
+ readonly batchSize?: number;
14
+ /** Attempts after which a record is dead. Default 8. */
15
+ readonly maxAttempts?: number;
16
+ readonly backoff?: OutboxBackoff;
17
+ /** Observability hook. It receives codes only, so it is safe to log as is. */
18
+ readonly onFailure?: (failure: OutboxRelayFailure) => void;
19
+ /**
20
+ * Makes a started relay tick as soon as the store says something was appended, so
21
+ * `intervalMs` can be long. Bursts are coalesced: one tick runs, at most one is queued.
22
+ * The interval stays the safety net: a missed notification delays, it never loses.
23
+ */
24
+ readonly wakeOn?: RelaySignal;
25
+ /** Default `none`. `per-key` needs `keyOf` and a single running relay. */
26
+ readonly ordering?: OutboxOrdering;
27
+ /** The ordering key of an event, typically its aggregate id. No key: no ordering. */
28
+ readonly keyOf?: (event: IntegrationEvent) => string | undefined;
29
+ }
30
+ export interface OutboxTickResult {
31
+ readonly published: number;
32
+ readonly failed: number;
33
+ }
34
+ /** Code stored on a record that waits for an earlier record of its key. It is not a failure. */
35
+ export declare const HELD_FOR_ORDER = "OUTBOX_HELD_FOR_ORDER";
36
+ /**
37
+ * Moves stored events to the provider, at least once.
38
+ *
39
+ * By default ordering is NOT guaranteed, not even per aggregate: a failed event is retried
40
+ * later while its successors go out, and several relays may run side by side. Consumers must
41
+ * not rely on the order of arrival; carry a sequence or a version in the payload when order
42
+ * matters.
43
+ *
44
+ * With `ordering: 'per-key'` the records of one key go out in the order this relay first saw
45
+ * them, and a failed one holds its successors back until it is published or dead. The memory
46
+ * of it lives in the relay: run a single relay, and expect a record in backoff to be
47
+ * overtaken once if the process restarts meanwhile. A dead record no longer blocks its key.
48
+ */
49
+ export declare class OutboxRelay {
50
+ private readonly store;
51
+ private readonly publisher;
52
+ private readonly clock;
53
+ private readonly batchSize;
54
+ private readonly maxAttempts;
55
+ private readonly backoff;
56
+ private readonly onFailure;
57
+ private readonly wakeOn;
58
+ private readonly order;
59
+ private timer;
60
+ private running;
61
+ private wakeSubscription;
62
+ private wakeQueued;
63
+ private intervalMs;
64
+ private started;
65
+ constructor(options: OutboxRelayOptions);
66
+ tick(): Promise<OutboxTickResult>;
67
+ /** Runs a tick, waits `intervalMs` or a wake-up, runs the next: ticks never overlap. */
68
+ start(options: {
69
+ readonly intervalMs: number;
70
+ }): void;
71
+ /** Stops scheduling and resolves once the tick in progress, if any, has finished. */
72
+ stop(): Promise<void>;
73
+ private claim;
74
+ private relayGroup;
75
+ /** Publishes one record; when it fails and has a key, says until when its successors wait. */
76
+ private relayRecord;
77
+ private recordFailure;
78
+ private delayAfter;
79
+ /** Reschedules a record with the head of its key; the claim it cost is not an attempt. */
80
+ private holdBack;
81
+ private wake;
82
+ private loop;
83
+ private scheduleNext;
84
+ }
85
+ //# sourceMappingURL=outbox-relay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-relay.d.ts","sourceRoot":"","sources":["../../src/relay/outbox-relay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE7F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAM7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,qFAAqF;IACrF,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,mBAAmB;IACnB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,wDAAwD;IACxD,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC3D;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,QAAQ,CAAC,EAAE,cAAc,CAAC;IACnC,qFAAqF;IACrF,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,MAAM,GAAG,SAAS,CAAC;CAClE;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,gGAAgG;AAChG,eAAO,MAAM,cAAc,0BAA0B,CAAC;AAStD;;;;;;;;;;;;GAYG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IAEpC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4B;IAEtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAE9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IAErC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAElD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwC;IAElE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IAEjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAE/C,OAAO,CAAC,KAAK,CAA4C;IAEzD,OAAO,CAAC,OAAO,CAA+B;IAE9C,OAAO,CAAC,gBAAgB,CAAsC;IAE9D,OAAO,CAAC,UAAU,CAAS;IAE3B,OAAO,CAAC,UAAU,CAAK;IAEvB,OAAO,CAAC,OAAO,CAAS;IAExB,YAAY,OAAO,EAAE,kBAAkB,EAUtC;IAEK,IAAI,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAmBtC;IAED,wFAAwF;IACxF,KAAK,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAapD;IAED,qFAAqF;IAC/E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ1B;YAEa,KAAK;YAcL,UAAU;IAUxB,8FAA8F;YAChF,WAAW;YAkBX,aAAa;IAqB3B,OAAO,CAAC,UAAU;IAMlB,0FAA0F;YAC5E,QAAQ;IAUtB,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,IAAI;IAWZ,OAAO,CAAC,YAAY;CAgBrB"}
@@ -0,0 +1,193 @@
1
+ import { errorCode } from './error-code.js';
2
+ import { KeyOrder } from './key-order.js';
3
+ /** Code stored on a record that waits for an earlier record of its key. It is not a failure. */
4
+ export const HELD_FOR_ORDER = 'OUTBOX_HELD_FOR_ORDER';
5
+ /**
6
+ * Moves stored events to the provider, at least once.
7
+ *
8
+ * By default ordering is NOT guaranteed, not even per aggregate: a failed event is retried
9
+ * later while its successors go out, and several relays may run side by side. Consumers must
10
+ * not rely on the order of arrival; carry a sequence or a version in the payload when order
11
+ * matters.
12
+ *
13
+ * With `ordering: 'per-key'` the records of one key go out in the order this relay first saw
14
+ * them, and a failed one holds its successors back until it is published or dead. The memory
15
+ * of it lives in the relay: run a single relay, and expect a record in backoff to be
16
+ * overtaken once if the process restarts meanwhile. A dead record no longer blocks its key.
17
+ */
18
+ export class OutboxRelay {
19
+ store;
20
+ publisher;
21
+ clock;
22
+ batchSize;
23
+ maxAttempts;
24
+ backoff;
25
+ onFailure;
26
+ wakeOn;
27
+ order;
28
+ timer;
29
+ running;
30
+ wakeSubscription;
31
+ wakeQueued = false;
32
+ intervalMs = 0;
33
+ started = false;
34
+ constructor(options) {
35
+ this.store = options.store;
36
+ this.publisher = options.publisher;
37
+ this.clock = options.clock;
38
+ this.batchSize = options.batchSize ?? 100;
39
+ this.maxAttempts = options.maxAttempts ?? 8;
40
+ this.backoff = backoffOf(options.backoff);
41
+ this.onFailure = options.onFailure ?? (() => undefined);
42
+ this.wakeOn = options.wakeOn;
43
+ this.order = new KeyOrder(orderingKeyOf(options));
44
+ }
45
+ async tick() {
46
+ const tick = await this.claim();
47
+ try {
48
+ for (const group of tick.groups) {
49
+ await this.relayGroup(group, tick);
50
+ }
51
+ }
52
+ catch (error) {
53
+ this.order.suspend(tick.groups, tick.settled);
54
+ throw error;
55
+ }
56
+ finally {
57
+ // Also when the store fails mid-batch: what did go out must not go out twice for that.
58
+ if (tick.published.length > 0) {
59
+ await this.store.markPublished(tick.published, this.clock.now());
60
+ }
61
+ }
62
+ return { published: tick.published.length, failed: tick.failed };
63
+ }
64
+ /** Runs a tick, waits `intervalMs` or a wake-up, runs the next: ticks never overlap. */
65
+ start(options) {
66
+ if (this.started) {
67
+ return;
68
+ }
69
+ this.started = true;
70
+ this.intervalMs = options.intervalMs;
71
+ this.wakeSubscription = this.wakeOn?.subscribe(() => {
72
+ this.wake();
73
+ });
74
+ this.loop();
75
+ }
76
+ /** Stops scheduling and resolves once the tick in progress, if any, has finished. */
77
+ async stop() {
78
+ this.started = false;
79
+ this.wakeQueued = false;
80
+ this.wakeSubscription?.unsubscribe();
81
+ this.wakeSubscription = undefined;
82
+ clearTimeout(this.timer);
83
+ this.timer = undefined;
84
+ await this.running;
85
+ }
86
+ async claim() {
87
+ const now = this.clock.now();
88
+ const records = await this.store.claimBatch(this.batchSize, now);
89
+ return {
90
+ now,
91
+ complete: records.length < this.batchSize,
92
+ groups: this.order.groups(records),
93
+ published: [],
94
+ settled: new Set(),
95
+ failed: 0,
96
+ };
97
+ }
98
+ async relayGroup(group, tick) {
99
+ let hold = this.order.holdOf(group, tick);
100
+ for (const record of group.records) {
101
+ hold = hold === undefined ? await this.relayRecord(record, group.key, tick) : await this.holdBack(record, hold);
102
+ tick.settled.add(record.event.id);
103
+ }
104
+ }
105
+ /** Publishes one record; when it fails and has a key, says until when its successors wait. */
106
+ async relayRecord(record, key, tick) {
107
+ try {
108
+ // One by one: a batch publication would make one poisoned event fail its neighbours.
109
+ await this.publisher.publish([record.event]);
110
+ }
111
+ catch (error) {
112
+ tick.failed += 1;
113
+ const retryAt = await this.recordFailure(record, key, errorCode(error));
114
+ return key === undefined ? undefined : retryAt;
115
+ }
116
+ tick.published.push(record.event.id);
117
+ this.order.settle(key, record.event.id);
118
+ return undefined;
119
+ }
120
+ async recordFailure(record, key, code) {
121
+ const attempts = this.order.attemptsOf(record);
122
+ const dead = attempts >= this.maxAttempts;
123
+ const nextAttemptAt = dead ? null : new Date(this.clock.now().getTime() + this.delayAfter(attempts));
124
+ if (nextAttemptAt === null) {
125
+ this.order.settle(key, record.event.id);
126
+ }
127
+ else {
128
+ this.order.block(key, record.event.id, nextAttemptAt);
129
+ }
130
+ await this.store.markFailed(record.event.id, { code }, nextAttemptAt);
131
+ const { id: eventId, type: eventType } = record.event;
132
+ this.onFailure({ kind: 'publish', eventId, eventType, code, attempts, dead });
133
+ return nextAttemptAt ?? undefined;
134
+ }
135
+ delayAfter(attempts) {
136
+ const { baseMs, factor, maxMs } = this.backoff;
137
+ return Math.min(maxMs, baseMs * factor ** Math.max(0, attempts - 1));
138
+ }
139
+ /** Reschedules a record with the head of its key; the claim it cost is not an attempt. */
140
+ async holdBack(record, hold) {
141
+ this.order.countHold(record.event.id);
142
+ if (hold !== 'lease-expiry') {
143
+ await this.store.markFailed(record.event.id, { code: HELD_FOR_ORDER }, hold);
144
+ }
145
+ return hold;
146
+ }
147
+ wake() {
148
+ if (!this.started) {
149
+ return;
150
+ }
151
+ if (this.running !== undefined) {
152
+ this.wakeQueued = true;
153
+ return;
154
+ }
155
+ clearTimeout(this.timer);
156
+ this.loop();
157
+ }
158
+ loop() {
159
+ this.running = this.tick()
160
+ .catch((error) => {
161
+ this.onFailure({ kind: 'tick', code: errorCode(error) });
162
+ })
163
+ .finally(() => {
164
+ this.running = undefined;
165
+ this.scheduleNext();
166
+ });
167
+ }
168
+ scheduleNext() {
169
+ if (!this.started) {
170
+ return;
171
+ }
172
+ if (this.wakeQueued) {
173
+ this.wakeQueued = false;
174
+ this.loop();
175
+ return;
176
+ }
177
+ this.timer = setTimeout(() => {
178
+ this.loop();
179
+ }, this.intervalMs);
180
+ }
181
+ }
182
+ function backoffOf(backoff = {}) {
183
+ return {
184
+ baseMs: backoff.baseMs ?? 1_000,
185
+ factor: backoff.factor ?? 2,
186
+ maxMs: backoff.maxMs ?? 300_000,
187
+ };
188
+ }
189
+ function orderingKeyOf(options) {
190
+ const withoutKey = () => undefined;
191
+ return options.ordering === 'per-key' ? (options.keyOf ?? withoutKey) : withoutKey;
192
+ }
193
+ //# sourceMappingURL=outbox-relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-relay.js","sourceRoot":"","sources":["../../src/relay/outbox-relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { KeyedRecord } from './keyed-record.js';
2
+ export interface RecordGroup<R extends KeyedRecord> {
3
+ readonly key: string | undefined;
4
+ readonly records: readonly R[];
5
+ }
6
+ //# sourceMappingURL=record-group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-group.d.ts","sourceRoot":"","sources":["../../src/relay/record-group.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,WAAW;IAChD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC;CAChC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=record-group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"record-group.js","sourceRoot":"","sources":["../../src/relay/record-group.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * How a store tells a relay that records were appended, so the relay can sleep on a long
3
+ * interval and still publish at once: PostgreSQL `LISTEN/NOTIFY`, a change stream, or
4
+ * `InMemoryRelaySignal` in a single process.
5
+ *
6
+ * A signal is a hint, never a delivery guarantee: a notification may be lost (connection
7
+ * dropped, process restarting), which must only delay the publication until the next poll.
8
+ */
9
+ export declare abstract class RelaySignal {
10
+ static readonly tokenKey = "events.RelaySignal";
11
+ abstract subscribe(listener: () => void): {
12
+ unsubscribe(): void;
13
+ };
14
+ }
15
+ //# sourceMappingURL=relay-signal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-signal.d.ts","sourceRoot":"","sources":["../../src/relay/relay-signal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,8BAAsB,WAAW;IAC/B,MAAM,CAAC,QAAQ,CAAC,QAAQ,wBAAwB;IAEhD,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG;QAAE,WAAW,IAAI,IAAI,CAAA;KAAE,CAAC;CACnE"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * How a store tells a relay that records were appended, so the relay can sleep on a long
3
+ * interval and still publish at once: PostgreSQL `LISTEN/NOTIFY`, a change stream, or
4
+ * `InMemoryRelaySignal` in a single process.
5
+ *
6
+ * A signal is a hint, never a delivery guarantee: a notification may be lost (connection
7
+ * dropped, process restarting), which must only delay the publication until the next poll.
8
+ */
9
+ export class RelaySignal {
10
+ static tokenKey = 'events.RelaySignal';
11
+ }
12
+ //# sourceMappingURL=relay-signal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-signal.js","sourceRoot":"","sources":["../../src/relay/relay-signal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,OAAgB,WAAW;IAC/B,MAAM,CAAU,QAAQ,GAAG,oBAAoB,CAAC;CAGjD"}
@@ -0,0 +1,18 @@
1
+ import type { IntegrationEvent, ProcessedEventStore, UnitOfWork } from '@ddd-ts-kit/kernel';
2
+ import type { IntegrationEventDefinition } from '../definition/integration-event-definition.js';
3
+ import type { EventScopeOptions } from './event-scope-options.js';
4
+ import type { EventSubscription } from './event-subscription.js';
5
+ export interface ConsumeOptions extends EventScopeOptions {
6
+ /** Name of the consuming context or handler: the idempotency scope. */
7
+ readonly consumer: string;
8
+ readonly processed: ProcessedEventStore;
9
+ /** The unit of work the mark and the state change of the handler commit in. */
10
+ readonly unitOfWork: UnitOfWork;
11
+ }
12
+ /**
13
+ * The consumer of `events/consumer-idempotent`: deduplication and the handler run in ONE
14
+ * unit of work, so "processed" and the state change it stands for commit or roll back
15
+ * together. An event whose handler threw is handled again when it is redelivered.
16
+ */
17
+ export declare function consume<P>(definition: IntegrationEventDefinition<P>, options: ConsumeOptions, handler: (event: IntegrationEvent<P>) => Promise<void>): EventSubscription;
18
+ //# sourceMappingURL=consume.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consume.d.ts","sourceRoot":"","sources":["../../src/subscription/consume.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC5F,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAGjE,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACvD,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,mBAAmB,CAAC;IACxC,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,UAAU,EAAE,0BAA0B,CAAC,CAAC,CAAC,EACzC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GACrD,iBAAiB,CAEnB"}
@@ -0,0 +1,10 @@
1
+ import { on } from './on.js';
2
+ /**
3
+ * The consumer of `events/consumer-idempotent`: deduplication and the handler run in ONE
4
+ * unit of work, so "processed" and the state change it stands for commit or roll back
5
+ * together. An event whose handler threw is handled again when it is redelivered.
6
+ */
7
+ export function consume(definition, options, handler) {
8
+ return on(definition, handler, options);
9
+ }
10
+ //# sourceMappingURL=consume.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consume.js","sourceRoot":"","sources":["../../src/subscription/consume.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAU7B;;;;GAIG;AACH,MAAM,UAAU,OAAO,CACrB,UAAyC,EACzC,OAAuB,EACvB,OAAsD;IAEtD,OAAO,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Actor, ExecutionScope, IntegrationEvent } from '@ddd-ts-kit/kernel';
2
+ /** How a consumed event becomes the execution context of its handler. */
3
+ export interface EventScopeOptions {
4
+ /**
5
+ * When given, the handler, its idempotency mark and its unit of work run inside
6
+ * `scope.run(...)`: origin `event`, the correlation of the event (its id when it names
7
+ * none), the event as cause, and the consumer as system actor.
8
+ */
9
+ readonly scope?: ExecutionScope;
10
+ /** The actor an event names, for a project whose envelopes carry a reference to one. */
11
+ readonly actorOf?: (event: IntegrationEvent) => Actor | undefined;
12
+ }
13
+ //# sourceMappingURL=event-scope-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-scope-options.d.ts","sourceRoot":"","sources":["../../src/subscription/event-scope-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAElF,yEAAyE;AACzE,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAChC,wFAAwF;IACxF,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,KAAK,GAAG,SAAS,CAAC;CACnE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=event-scope-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-scope-options.js","sourceRoot":"","sources":["../../src/subscription/event-scope-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { IntegrationEventCallback } from '@ddd-ts-kit/kernel';
2
+ export interface EventSubscription {
3
+ readonly type: string;
4
+ readonly handler: IntegrationEventCallback;
5
+ }
6
+ //# sourceMappingURL=event-subscription.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-subscription.d.ts","sourceRoot":"","sources":["../../src/subscription/event-subscription.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,wBAAwB,CAAC;CAC5C"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=event-subscription.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-subscription.js","sourceRoot":"","sources":["../../src/subscription/event-subscription.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ import { type IntegrationEvent, type ProcessedEventStore, type UnitOfWork } from '@ddd-ts-kit/kernel';
2
+ import type { IntegrationEventDefinition } from '../definition/integration-event-definition.js';
3
+ import type { EventScopeOptions } from './event-scope-options.js';
4
+ import type { EventSubscription } from './event-subscription.js';
5
+ export interface OnOptions extends EventScopeOptions {
6
+ /** Name of the consuming context or handler: the idempotency scope. */
7
+ readonly consumer: string;
8
+ /** When given, a redelivered event is handled once per consumer. */
9
+ readonly processed?: ProcessedEventStore;
10
+ /**
11
+ * When given with `processed`, the mark and the handler run in this one unit of work, so
12
+ * they commit together and a failed handler takes its mark back with it.
13
+ */
14
+ readonly unitOfWork?: UnitOfWork;
15
+ }
16
+ /**
17
+ * Typed subscription to one version of one event. Another version of the same type is
18
+ * skipped (subscribe to it with its own definition); an invalid payload throws so that the
19
+ * provider retries or dead-letters instead of silently losing the event.
20
+ *
21
+ * With `processed` alone, the mark is taken before the handler runs and survives its failure
22
+ * unless the store is transactional and already inside a unit of work, or is a
23
+ * `ReleasableProcessedEventStore`. Prefer `consume`, or pass `unitOfWork`.
24
+ */
25
+ export declare function on<P>(definition: IntegrationEventDefinition<P>, handler: (event: IntegrationEvent<P>) => Promise<void>, options?: OnOptions): EventSubscription;
26
+ //# sourceMappingURL=on.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"on.d.ts","sourceRoot":"","sources":["../../src/subscription/on.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAC;AAEhG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAGjE,MAAM,WAAW,SAAU,SAAQ,iBAAiB;IAClD,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,SAAS,CAAC,EAAE,mBAAmB,CAAC;IACzC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,wBAAgB,EAAE,CAAC,CAAC,EAClB,UAAU,EAAE,0BAA0B,CAAC,CAAC,CAAC,EACzC,OAAO,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,EACtD,OAAO,CAAC,EAAE,SAAS,GAClB,iBAAiB,CAmBnB"}
@@ -0,0 +1,62 @@
1
+ import { executionContextOfEvent, } from '@ddd-ts-kit/kernel';
2
+ import { InvalidEventPayloadError } from '../definition/invalid-event-payload-error.js';
3
+ /**
4
+ * Typed subscription to one version of one event. Another version of the same type is
5
+ * skipped (subscribe to it with its own definition); an invalid payload throws so that the
6
+ * provider retries or dead-letters instead of silently losing the event.
7
+ *
8
+ * With `processed` alone, the mark is taken before the handler runs and survives its failure
9
+ * unless the store is transactional and already inside a unit of work, or is a
10
+ * `ReleasableProcessedEventStore`. Prefer `consume`, or pass `unitOfWork`.
11
+ */
12
+ export function on(definition, handler, options) {
13
+ return {
14
+ type: definition.type,
15
+ handler: async (event) => {
16
+ const parsed = definition.parse(event);
17
+ if (!parsed.ok) {
18
+ if (parsed.error.reason === 'invalid-payload') {
19
+ throw new InvalidEventPayloadError(event.type, event.version, parsed.error.issues);
20
+ }
21
+ return;
22
+ }
23
+ // Deduplicated only once the event is known to be ours and valid, so a skipped or
24
+ // rejected delivery never consumes the idempotency key.
25
+ await inScope(event, options, () => handleOnce(event.id, options, () => handler(parsed.value)));
26
+ },
27
+ };
28
+ }
29
+ function inScope(event, options, work) {
30
+ if (options?.scope === undefined) {
31
+ return work();
32
+ }
33
+ return options.scope.run(executionContextOfEvent(event, options), work);
34
+ }
35
+ async function handleOnce(eventId, options, handle) {
36
+ const processed = options?.processed;
37
+ if (options === undefined || processed === undefined) {
38
+ await handle();
39
+ return;
40
+ }
41
+ const mark = { taken: false };
42
+ try {
43
+ await (options.unitOfWork ?? WITHOUT_TRANSACTION).run(async () => {
44
+ mark.taken = await processed.markProcessed(options.consumer, eventId);
45
+ if (mark.taken) {
46
+ await handle();
47
+ }
48
+ });
49
+ }
50
+ catch (error) {
51
+ // Only a mark taken by this delivery: one left by an earlier success must stay.
52
+ if (mark.taken && isReleasable(processed)) {
53
+ await processed.release(options.consumer, eventId);
54
+ }
55
+ throw error;
56
+ }
57
+ }
58
+ const WITHOUT_TRANSACTION = { run: (work) => work() };
59
+ function isReleasable(store) {
60
+ return typeof store.release === 'function';
61
+ }
62
+ //# sourceMappingURL=on.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"on.js","sourceRoot":"","sources":["../../src/subscription/on.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,GAIxB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,wBAAwB,EAAE,MAAM,8CAA8C,CAAC;AAiBxF;;;;;;;;GAQG;AACH,MAAM,UAAU,EAAE,CAChB,UAAyC,EACzC,OAAsD,EACtD,OAAmB;IAEnB,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAEvC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;oBAC9C,MAAM,IAAI,wBAAwB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACrF,CAAC;gBAED,OAAO;YACT,CAAC;YAED,kFAAkF;YAClF,wDAAwD;YACxD,MAAM,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClG,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,KAAuB,EAAE,OAA8B,EAAE,IAAyB;IACjG,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;QACjC,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IAED,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;AAC1E,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,OAAe,EAAE,OAA8B,EAAE,MAA2B;IACpG,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,CAAC;IAErC,IAAI,OAAO,KAAK,SAAS,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QACrD,MAAM,MAAM,EAAE,CAAC;QAEf,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;YAC/D,IAAI,CAAC,KAAK,GAAG,MAAM,SAAS,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAEtE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,MAAM,EAAE,CAAC;YACjB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,gFAAgF;QAChF,IAAI,IAAI,CAAC,KAAK,IAAI,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1C,MAAM,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,mBAAmB,GAAe,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;AAElE,SAAS,YAAY,CAAC,KAA0B;IAC9C,OAAO,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { ProcessedEventStore } from '@ddd-ts-kit/kernel';
2
+ /**
3
+ * A processed-event store that can take a mark back. A store that is not transactional needs
4
+ * it: with no rollback to erase the mark of a handler that failed, the redelivery would be
5
+ * skipped and the event lost.
6
+ *
7
+ * It narrows the `ProcessedEventStore` port, whose `release` is optional, and is not a port
8
+ * itself: a composition root binds its store under `ProcessedEventStore`.
9
+ */
10
+ export interface ReleasableProcessedEventStore extends ProcessedEventStore {
11
+ /** Forgets `(consumer, eventId)`: the next delivery is handled again. */
12
+ release(consumer: string, eventId: string): Promise<void>;
13
+ }
14
+ //# sourceMappingURL=releasable-processed-event-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"releasable-processed-event-store.d.ts","sourceRoot":"","sources":["../../src/subscription/releasable-processed-event-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,WAAW,6BAA8B,SAAQ,mBAAmB;IACxE,yEAAyE;IACzE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=releasable-processed-event-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"releasable-processed-event-store.js","sourceRoot":"","sources":["../../src/subscription/releasable-processed-event-store.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import type { IntegrationEventSubscriber, Subscription } from '@ddd-ts-kit/kernel';
2
+ import type { EventSubscription } from './event-subscription.js';
3
+ /** Registers every subscription and returns one handle that removes them all. */
4
+ export declare function subscribeAll(subscriber: IntegrationEventSubscriber, subscriptions: readonly EventSubscription[]): Subscription;
5
+ //# sourceMappingURL=subscribe-all.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe-all.d.ts","sourceRoot":"","sources":["../../src/subscription/subscribe-all.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,iFAAiF;AACjF,wBAAgB,YAAY,CAC1B,UAAU,EAAE,0BAA0B,EACtC,aAAa,EAAE,SAAS,iBAAiB,EAAE,GAC1C,YAAY,CAUd"}
@@ -0,0 +1,12 @@
1
+ /** Registers every subscription and returns one handle that removes them all. */
2
+ export function subscribeAll(subscriber, subscriptions) {
3
+ const handles = subscriptions.map(({ type, handler }) => subscriber.subscribe(type, handler));
4
+ return {
5
+ unsubscribe: () => {
6
+ for (const handle of handles) {
7
+ handle.unsubscribe();
8
+ }
9
+ },
10
+ };
11
+ }
12
+ //# sourceMappingURL=subscribe-all.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscribe-all.js","sourceRoot":"","sources":["../../src/subscription/subscribe-all.ts"],"names":[],"mappings":"AAGA,iFAAiF;AACjF,MAAM,UAAU,YAAY,CAC1B,UAAsC,EACtC,aAA2C;IAE3C,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAE9F,OAAO;QACL,WAAW,EAAE,GAAG,EAAE;YAChB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}