@zdavison/matador 2.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 (256) hide show
  1. package/cli.ts +453 -0
  2. package/dist/checkpoint/context.d.ts +59 -0
  3. package/dist/checkpoint/context.d.ts.map +1 -0
  4. package/dist/checkpoint/context.js +140 -0
  5. package/dist/checkpoint/context.test.d.ts +2 -0
  6. package/dist/checkpoint/context.test.d.ts.map +1 -0
  7. package/dist/checkpoint/context.test.js +424 -0
  8. package/dist/checkpoint/index.d.ts +7 -0
  9. package/dist/checkpoint/index.d.ts.map +1 -0
  10. package/dist/checkpoint/index.js +6 -0
  11. package/dist/checkpoint/stores/memory.d.ts +29 -0
  12. package/dist/checkpoint/stores/memory.d.ts.map +1 -0
  13. package/dist/checkpoint/stores/memory.js +39 -0
  14. package/dist/checkpoint/stores/noop.d.ts +14 -0
  15. package/dist/checkpoint/stores/noop.d.ts.map +1 -0
  16. package/dist/checkpoint/stores/noop.js +18 -0
  17. package/dist/checkpoint/stores/stores.test.d.ts +2 -0
  18. package/dist/checkpoint/stores/stores.test.d.ts.map +1 -0
  19. package/dist/checkpoint/stores/stores.test.js +146 -0
  20. package/dist/checkpoint/types.d.ts +119 -0
  21. package/dist/checkpoint/types.d.ts.map +1 -0
  22. package/dist/checkpoint/types.js +1 -0
  23. package/dist/codec/codec.d.ts +29 -0
  24. package/dist/codec/codec.d.ts.map +1 -0
  25. package/dist/codec/codec.js +15 -0
  26. package/dist/codec/header-aware-codec.d.ts +36 -0
  27. package/dist/codec/header-aware-codec.d.ts.map +1 -0
  28. package/dist/codec/header-aware-codec.js +1 -0
  29. package/dist/codec/index.d.ts +6 -0
  30. package/dist/codec/index.d.ts.map +1 -0
  31. package/dist/codec/index.js +3 -0
  32. package/dist/codec/json-codec.d.ts +13 -0
  33. package/dist/codec/json-codec.d.ts.map +1 -0
  34. package/dist/codec/json-codec.js +64 -0
  35. package/dist/codec/rabbitmq-codec.d.ts +28 -0
  36. package/dist/codec/rabbitmq-codec.d.ts.map +1 -0
  37. package/dist/codec/rabbitmq-codec.js +242 -0
  38. package/dist/codec/rabbitmq-codec.test.d.ts +2 -0
  39. package/dist/codec/rabbitmq-codec.test.d.ts.map +1 -0
  40. package/dist/codec/rabbitmq-codec.test.js +433 -0
  41. package/dist/core/fanout.d.ts +59 -0
  42. package/dist/core/fanout.d.ts.map +1 -0
  43. package/dist/core/fanout.js +121 -0
  44. package/dist/core/fanout.test.d.ts +2 -0
  45. package/dist/core/fanout.test.d.ts.map +1 -0
  46. package/dist/core/fanout.test.js +1055 -0
  47. package/dist/core/index.d.ts +7 -0
  48. package/dist/core/index.d.ts.map +1 -0
  49. package/dist/core/index.js +3 -0
  50. package/dist/core/matador.d.ts +133 -0
  51. package/dist/core/matador.d.ts.map +1 -0
  52. package/dist/core/matador.js +222 -0
  53. package/dist/core/matador.test.d.ts +2 -0
  54. package/dist/core/matador.test.d.ts.map +1 -0
  55. package/dist/core/matador.test.js +446 -0
  56. package/dist/core/shutdown.d.ts +78 -0
  57. package/dist/core/shutdown.d.ts.map +1 -0
  58. package/dist/core/shutdown.js +111 -0
  59. package/dist/core/shutdown.test.d.ts +2 -0
  60. package/dist/core/shutdown.test.d.ts.map +1 -0
  61. package/dist/core/shutdown.test.js +524 -0
  62. package/dist/errors/checkpoint-errors.d.ts +30 -0
  63. package/dist/errors/checkpoint-errors.d.ts.map +1 -0
  64. package/dist/errors/checkpoint-errors.js +49 -0
  65. package/dist/errors/has-description.d.ts +18 -0
  66. package/dist/errors/has-description.d.ts.map +1 -0
  67. package/dist/errors/has-description.js +9 -0
  68. package/dist/errors/index.d.ts +6 -0
  69. package/dist/errors/index.d.ts.map +1 -0
  70. package/dist/errors/index.js +22 -0
  71. package/dist/errors/matador-errors.d.ts +183 -0
  72. package/dist/errors/matador-errors.d.ts.map +1 -0
  73. package/dist/errors/matador-errors.js +376 -0
  74. package/dist/errors/retry-errors.d.ts +67 -0
  75. package/dist/errors/retry-errors.d.ts.map +1 -0
  76. package/dist/errors/retry-errors.js +108 -0
  77. package/dist/hooks/index.d.ts +4 -0
  78. package/dist/hooks/index.d.ts.map +1 -0
  79. package/dist/hooks/index.js +2 -0
  80. package/dist/hooks/safe-hooks.d.ts +34 -0
  81. package/dist/hooks/safe-hooks.d.ts.map +1 -0
  82. package/dist/hooks/safe-hooks.js +135 -0
  83. package/dist/hooks/types.d.ts +189 -0
  84. package/dist/hooks/types.d.ts.map +1 -0
  85. package/dist/hooks/types.js +9 -0
  86. package/dist/index.cjs +3156 -0
  87. package/dist/index.cjs.map +1 -0
  88. package/dist/index.d.cts +23 -0
  89. package/dist/index.d.ts +23 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +31 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/pipeline/index.d.ts +3 -0
  94. package/dist/pipeline/index.d.ts.map +1 -0
  95. package/dist/pipeline/index.js +1 -0
  96. package/dist/pipeline/pipeline.d.ts +60 -0
  97. package/dist/pipeline/pipeline.d.ts.map +1 -0
  98. package/dist/pipeline/pipeline.js +261 -0
  99. package/dist/pipeline/pipeline.test.d.ts +2 -0
  100. package/dist/pipeline/pipeline.test.d.ts.map +1 -0
  101. package/dist/pipeline/pipeline.test.js +1065 -0
  102. package/dist/retry/index.d.ts +4 -0
  103. package/dist/retry/index.d.ts.map +1 -0
  104. package/dist/retry/index.js +1 -0
  105. package/dist/retry/policy.d.ts +43 -0
  106. package/dist/retry/policy.d.ts.map +1 -0
  107. package/dist/retry/policy.js +1 -0
  108. package/dist/retry/standard-policy.d.ts +44 -0
  109. package/dist/retry/standard-policy.d.ts.map +1 -0
  110. package/dist/retry/standard-policy.js +102 -0
  111. package/dist/retry/standard-policy.test.d.ts +2 -0
  112. package/dist/retry/standard-policy.test.d.ts.map +1 -0
  113. package/dist/retry/standard-policy.test.js +190 -0
  114. package/dist/schema/index.d.ts +4 -0
  115. package/dist/schema/index.d.ts.map +1 -0
  116. package/dist/schema/index.js +2 -0
  117. package/dist/schema/registry.d.ts +63 -0
  118. package/dist/schema/registry.d.ts.map +1 -0
  119. package/dist/schema/registry.js +171 -0
  120. package/dist/schema/registry.test.d.ts +2 -0
  121. package/dist/schema/registry.test.d.ts.map +1 -0
  122. package/dist/schema/registry.test.js +278 -0
  123. package/dist/schema/types.d.ts +158 -0
  124. package/dist/schema/types.d.ts.map +1 -0
  125. package/dist/schema/types.js +74 -0
  126. package/dist/schema/types.test.d.ts +2 -0
  127. package/dist/schema/types.test.d.ts.map +1 -0
  128. package/dist/schema/types.test.js +243 -0
  129. package/dist/topology/builder.d.ts +66 -0
  130. package/dist/topology/builder.d.ts.map +1 -0
  131. package/dist/topology/builder.js +156 -0
  132. package/dist/topology/builder.test.d.ts +2 -0
  133. package/dist/topology/builder.test.d.ts.map +1 -0
  134. package/dist/topology/builder.test.js +222 -0
  135. package/dist/topology/index.d.ts +5 -0
  136. package/dist/topology/index.d.ts.map +1 -0
  137. package/dist/topology/index.js +2 -0
  138. package/dist/topology/types.d.ts +76 -0
  139. package/dist/topology/types.d.ts.map +1 -0
  140. package/dist/topology/types.js +18 -0
  141. package/dist/transport/capabilities.d.ts +66 -0
  142. package/dist/transport/capabilities.d.ts.map +1 -0
  143. package/dist/transport/capabilities.js +18 -0
  144. package/dist/transport/connection-manager.d.ts +95 -0
  145. package/dist/transport/connection-manager.d.ts.map +1 -0
  146. package/dist/transport/connection-manager.js +144 -0
  147. package/dist/transport/index.d.ts +11 -0
  148. package/dist/transport/index.d.ts.map +1 -0
  149. package/dist/transport/index.js +5 -0
  150. package/dist/transport/local/local-transport.d.ts +62 -0
  151. package/dist/transport/local/local-transport.d.ts.map +1 -0
  152. package/dist/transport/local/local-transport.js +241 -0
  153. package/dist/transport/local/local-transport.test.d.ts +2 -0
  154. package/dist/transport/local/local-transport.test.d.ts.map +1 -0
  155. package/dist/transport/local/local-transport.test.js +192 -0
  156. package/dist/transport/multi/multi-transport.d.ts +94 -0
  157. package/dist/transport/multi/multi-transport.d.ts.map +1 -0
  158. package/dist/transport/multi/multi-transport.js +184 -0
  159. package/dist/transport/multi/multi-transport.test.d.ts +2 -0
  160. package/dist/transport/multi/multi-transport.test.d.ts.map +1 -0
  161. package/dist/transport/multi/multi-transport.test.js +236 -0
  162. package/dist/transport/rabbitmq/rabbitmq-transport.d.ts +73 -0
  163. package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -0
  164. package/dist/transport/rabbitmq/rabbitmq-transport.js +518 -0
  165. package/dist/transport/transport.d.ts +152 -0
  166. package/dist/transport/transport.d.ts.map +1 -0
  167. package/dist/transport/transport.js +1 -0
  168. package/dist/types/common.d.ts +41 -0
  169. package/dist/types/common.d.ts.map +1 -0
  170. package/dist/types/common.js +12 -0
  171. package/dist/types/envelope.d.ts +82 -0
  172. package/dist/types/envelope.d.ts.map +1 -0
  173. package/dist/types/envelope.js +36 -0
  174. package/dist/types/event.d.ts +96 -0
  175. package/dist/types/event.d.ts.map +1 -0
  176. package/dist/types/event.js +26 -0
  177. package/dist/types/event.test.d.ts +2 -0
  178. package/dist/types/event.test.d.ts.map +1 -0
  179. package/dist/types/event.test.js +130 -0
  180. package/dist/types/index.d.ts +9 -0
  181. package/dist/types/index.d.ts.map +1 -0
  182. package/dist/types/index.js +4 -0
  183. package/dist/types/subscriber.d.ts +207 -0
  184. package/dist/types/subscriber.d.ts.map +1 -0
  185. package/dist/types/subscriber.js +99 -0
  186. package/examples/config.ts +126 -0
  187. package/examples/event.ts +26 -0
  188. package/examples/order-event.json +19 -0
  189. package/package.json +66 -0
  190. package/src/checkpoint/context.test.ts +510 -0
  191. package/src/checkpoint/context.ts +213 -0
  192. package/src/checkpoint/index.ts +30 -0
  193. package/src/checkpoint/stores/memory.ts +47 -0
  194. package/src/checkpoint/stores/noop.ts +22 -0
  195. package/src/checkpoint/stores/stores.test.ts +177 -0
  196. package/src/checkpoint/types.ts +147 -0
  197. package/src/codec/codec.ts +42 -0
  198. package/src/codec/header-aware-codec.ts +41 -0
  199. package/src/codec/index.ts +11 -0
  200. package/src/codec/json-codec.ts +69 -0
  201. package/src/codec/rabbitmq-codec.test.ts +516 -0
  202. package/src/codec/rabbitmq-codec.ts +336 -0
  203. package/src/core/fanout.test.ts +1351 -0
  204. package/src/core/fanout.ts +184 -0
  205. package/src/core/index.ts +12 -0
  206. package/src/core/matador.test.ts +575 -0
  207. package/src/core/matador.ts +344 -0
  208. package/src/core/shutdown.test.ts +853 -0
  209. package/src/core/shutdown.ts +165 -0
  210. package/src/errors/checkpoint-errors.ts +62 -0
  211. package/src/errors/has-description.ts +25 -0
  212. package/src/errors/index.ts +57 -0
  213. package/src/errors/matador-errors.ts +477 -0
  214. package/src/errors/retry-errors.ts +134 -0
  215. package/src/hooks/index.ts +15 -0
  216. package/src/hooks/safe-hooks.ts +223 -0
  217. package/src/hooks/types.ts +248 -0
  218. package/src/index.ts +231 -0
  219. package/src/pipeline/index.ts +2 -0
  220. package/src/pipeline/pipeline.test.ts +1317 -0
  221. package/src/pipeline/pipeline.ts +371 -0
  222. package/src/retry/index.ts +4 -0
  223. package/src/retry/policy.ts +46 -0
  224. package/src/retry/standard-policy.test.ts +282 -0
  225. package/src/retry/standard-policy.ts +156 -0
  226. package/src/schema/index.ts +16 -0
  227. package/src/schema/registry.test.ts +339 -0
  228. package/src/schema/registry.ts +226 -0
  229. package/src/schema/types.test.ts +281 -0
  230. package/src/schema/types.ts +217 -0
  231. package/src/topology/builder.test.ts +275 -0
  232. package/src/topology/builder.ts +199 -0
  233. package/src/topology/index.ts +15 -0
  234. package/src/topology/types.ts +109 -0
  235. package/src/transport/capabilities.ts +88 -0
  236. package/src/transport/connection-manager.ts +218 -0
  237. package/src/transport/index.ts +42 -0
  238. package/src/transport/local/local-transport.test.ts +262 -0
  239. package/src/transport/local/local-transport.ts +327 -0
  240. package/src/transport/multi/multi-transport.test.ts +320 -0
  241. package/src/transport/multi/multi-transport.ts +294 -0
  242. package/src/transport/rabbitmq/rabbitmq-transport.ts +753 -0
  243. package/src/transport/transport.ts +200 -0
  244. package/src/types/common.ts +53 -0
  245. package/src/types/envelope.ts +152 -0
  246. package/src/types/event.test.ts +157 -0
  247. package/src/types/event.ts +118 -0
  248. package/src/types/index.ts +52 -0
  249. package/src/types/subscriber.ts +310 -0
  250. package/test/e2e/multi-transport.e2e.test.ts +236 -0
  251. package/test/e2e/rabbitmq-transport.e2e.test.ts +327 -0
  252. package/test/e2e/transport-compliance.e2e.test.ts +505 -0
  253. package/test/integration/matador.integration.test.ts +634 -0
  254. package/tsconfig.json +29 -0
  255. package/tsconfig.tsbuildinfo +1 -0
  256. package/tsup.config.ts +13 -0
@@ -0,0 +1,223 @@
1
+ import type {
2
+ CheckpointClearedContext,
3
+ CheckpointHitContext,
4
+ CheckpointLoadedContext,
5
+ CheckpointMissContext,
6
+ } from '../checkpoint/index.js';
7
+ import type { ConnectionState } from '../transport/index.js';
8
+ import type { Envelope, SubscriberDefinition } from '../types/index.js';
9
+ import {
10
+ type DecodeErrorContext,
11
+ type EnqueueErrorContext,
12
+ type EnqueueSuccessContext,
13
+ type EnqueueWarningContext,
14
+ type Logger,
15
+ type MatadorHooks,
16
+ type WorkerErrorContext,
17
+ type WorkerExecuteFn,
18
+ type WorkerSuccessContext,
19
+ consoleLogger,
20
+ } from './types.js';
21
+
22
+ /**
23
+ * Wraps hooks with error handling to prevent hook errors from breaking processing.
24
+ * All hooks become safe to call and will catch any errors internally.
25
+ */
26
+ export class SafeHooks {
27
+ private readonly hooks: MatadorHooks;
28
+
29
+ /** The logger instance used by Matador. */
30
+ readonly logger: Logger;
31
+
32
+ constructor(hooks: MatadorHooks = {}) {
33
+ this.hooks = hooks;
34
+ this.logger = hooks.logger ?? consoleLogger;
35
+ }
36
+
37
+ async onEnqueueSuccess(context: EnqueueSuccessContext): Promise<void> {
38
+ await this.safeCall('onEnqueueSuccess', () =>
39
+ this.hooks.onEnqueueSuccess?.(context),
40
+ );
41
+ }
42
+
43
+ async onEnqueueWarning(context: EnqueueWarningContext): Promise<void> {
44
+ await this.safeCall('onEnqueueWarning', () =>
45
+ this.hooks.onEnqueueWarning?.(context),
46
+ );
47
+ }
48
+
49
+ async onEnqueueError(context: EnqueueErrorContext): Promise<void> {
50
+ await this.safeCall('onEnqueueError', () =>
51
+ this.hooks.onEnqueueError?.(context),
52
+ );
53
+ }
54
+
55
+ async onWorkerWrap(
56
+ envelope: Envelope,
57
+ subscriber: SubscriberDefinition,
58
+ execute: WorkerExecuteFn,
59
+ ): Promise<void> {
60
+ if (this.hooks.onWorkerWrap) {
61
+ try {
62
+ await this.hooks.onWorkerWrap(envelope, subscriber, execute);
63
+ } catch (error) {
64
+ this.logger.warn(
65
+ '[Matador] 🟡 Hook onWorkerWrap threw an error',
66
+ error,
67
+ );
68
+ // Still try to execute if wrap failed
69
+ await execute();
70
+ }
71
+ } else {
72
+ await execute();
73
+ }
74
+ }
75
+
76
+ async onWorkerBeforeProcess(
77
+ envelope: Envelope,
78
+ subscriber: SubscriberDefinition,
79
+ ): Promise<void> {
80
+ await this.safeCall('onWorkerBeforeProcess', () =>
81
+ this.hooks.onWorkerBeforeProcess?.(envelope, subscriber),
82
+ );
83
+ }
84
+
85
+ async onWorkerSuccess(context: WorkerSuccessContext): Promise<void> {
86
+ await this.safeCall('onWorkerSuccess', () =>
87
+ this.hooks.onWorkerSuccess?.(context),
88
+ );
89
+ }
90
+
91
+ async onWorkerError(context: WorkerErrorContext): Promise<void> {
92
+ await this.safeCall('onWorkerError', () =>
93
+ this.hooks.onWorkerError?.(context),
94
+ );
95
+ }
96
+
97
+ async onDecodeError(context: DecodeErrorContext): Promise<void> {
98
+ await this.safeCall('onDecodeError', () =>
99
+ this.hooks.onDecodeError?.(context),
100
+ );
101
+ }
102
+
103
+ async onConnectionStateChange(state: ConnectionState): Promise<void> {
104
+ await this.safeCall('onConnectionStateChange', () =>
105
+ this.hooks.onConnectionStateChange?.(state),
106
+ );
107
+ }
108
+
109
+ async loadUniversalMetadata(): Promise<Record<string, unknown>> {
110
+ if (!this.hooks.loadUniversalMetadata) {
111
+ return {};
112
+ }
113
+
114
+ try {
115
+ const result = await this.hooks.loadUniversalMetadata();
116
+ return result ?? {};
117
+ } catch (error) {
118
+ this.logger.warn(
119
+ '[Matador] 🟡 Hook loadUniversalMetadata threw an error',
120
+ error,
121
+ );
122
+ return {};
123
+ }
124
+ }
125
+
126
+ async getQueueConcurrency(queueName: string): Promise<number | undefined> {
127
+ if (!this.hooks.getQueueConcurrency) {
128
+ return undefined;
129
+ }
130
+
131
+ try {
132
+ return await this.hooks.getQueueConcurrency(queueName);
133
+ } catch (error) {
134
+ this.logger.warn(
135
+ '[Matador] 🟡 Hook getQueueConcurrency threw an error',
136
+ error,
137
+ );
138
+ return undefined;
139
+ }
140
+ }
141
+
142
+ async getRetryDelay(
143
+ envelope: Envelope,
144
+ attemptNumber: number,
145
+ ): Promise<number | undefined> {
146
+ if (!this.hooks.getRetryDelay) {
147
+ return undefined;
148
+ }
149
+
150
+ try {
151
+ return await this.hooks.getRetryDelay(envelope, attemptNumber);
152
+ } catch (error) {
153
+ this.logger.warn('[Matador] 🟡 Hook getRetryDelay threw an error', error);
154
+ return undefined;
155
+ }
156
+ }
157
+
158
+ async getAttempts(envelope: Envelope): Promise<number | undefined> {
159
+ if (!this.hooks.getAttempts) {
160
+ return undefined;
161
+ }
162
+
163
+ try {
164
+ return await this.hooks.getAttempts(envelope);
165
+ } catch (error) {
166
+ this.logger.warn('[Matador] 🟡 Hook getAttempts threw an error', error);
167
+ return undefined;
168
+ }
169
+ }
170
+
171
+ async getMaxDeliveries(envelope: Envelope): Promise<number | undefined> {
172
+ if (!this.hooks.getMaxDeliveries) {
173
+ return undefined;
174
+ }
175
+
176
+ try {
177
+ return await this.hooks.getMaxDeliveries(envelope);
178
+ } catch (error) {
179
+ this.logger.warn(
180
+ '[Matador] 🟡 Hook getMaxDeliveries threw an error',
181
+ error,
182
+ );
183
+ return undefined;
184
+ }
185
+ }
186
+
187
+ // === Checkpoint Hooks ===
188
+
189
+ async onCheckpointLoaded(context: CheckpointLoadedContext): Promise<void> {
190
+ await this.safeCall('onCheckpointLoaded', () =>
191
+ this.hooks.onCheckpointLoaded?.(context),
192
+ );
193
+ }
194
+
195
+ async onCheckpointHit(context: CheckpointHitContext): Promise<void> {
196
+ await this.safeCall('onCheckpointHit', () =>
197
+ this.hooks.onCheckpointHit?.(context),
198
+ );
199
+ }
200
+
201
+ async onCheckpointMiss(context: CheckpointMissContext): Promise<void> {
202
+ await this.safeCall('onCheckpointMiss', () =>
203
+ this.hooks.onCheckpointMiss?.(context),
204
+ );
205
+ }
206
+
207
+ async onCheckpointCleared(context: CheckpointClearedContext): Promise<void> {
208
+ await this.safeCall('onCheckpointCleared', () =>
209
+ this.hooks.onCheckpointCleared?.(context),
210
+ );
211
+ }
212
+
213
+ private async safeCall(
214
+ hookName: string,
215
+ fn: () => void | Promise<void> | undefined,
216
+ ): Promise<void> {
217
+ try {
218
+ await fn();
219
+ } catch (error) {
220
+ this.logger.warn(`[Matador] 🟡 Hook ${hookName} threw an error`, error);
221
+ }
222
+ }
223
+ }
@@ -0,0 +1,248 @@
1
+ import type {
2
+ CheckpointClearedContext,
3
+ CheckpointHitContext,
4
+ CheckpointLoadedContext,
5
+ CheckpointMissContext,
6
+ } from '../checkpoint/index.js';
7
+ import type { RetryDecision } from '../retry/index.js';
8
+ import type { ConnectionState, Transport } from '../transport/index.js';
9
+ import type { Envelope, SubscriberDefinition } from '../types/index.js';
10
+
11
+ /**
12
+ * Logger interface for Matador internal logging.
13
+ */
14
+ export interface Logger {
15
+ debug(message: string, ...args: unknown[]): void;
16
+ info(message: string, ...args: unknown[]): void;
17
+ warn(message: string, ...args: unknown[]): void;
18
+ error(message: string, ...args: unknown[]): void;
19
+ }
20
+
21
+ /**
22
+ * Default logger that uses console.
23
+ */
24
+ export const consoleLogger: Logger = {
25
+ debug: (message, ...args) => console.debug(message, ...args),
26
+ info: (message, ...args) => console.info(message, ...args),
27
+ warn: (message, ...args) => console.warn(message, ...args),
28
+ error: (message, ...args) => console.error(message, ...args),
29
+ };
30
+
31
+ /**
32
+ * Context for enqueue success hook.
33
+ */
34
+ export interface EnqueueSuccessContext {
35
+ readonly envelope: Envelope;
36
+ readonly queue: string;
37
+ /** The transport that was used (e.g., 'local', 'rabbitmq') */
38
+ readonly transport: string;
39
+ }
40
+
41
+ /**
42
+ * Context for enqueue warning hook (fallback used).
43
+ */
44
+ export interface EnqueueWarningContext {
45
+ readonly envelope: Envelope;
46
+ readonly originalQueue: string;
47
+ readonly fallbackQueue: string;
48
+ readonly error: Error;
49
+ }
50
+
51
+ /**
52
+ * Context for transport fallback hook.
53
+ */
54
+ export interface TransportFallbackContext {
55
+ /** The envelope that was being sent */
56
+ readonly envelope: Envelope;
57
+ /** The queue the message was being sent to */
58
+ readonly queue: string;
59
+ /** The transport that failed */
60
+ readonly failedTransport: Transport['name'];
61
+ /** The transport that will be tried next */
62
+ readonly nextTransport: Transport['name'];
63
+ /** The error from the failed transport */
64
+ readonly error: Error;
65
+ }
66
+
67
+ /**
68
+ * Context for enqueue error hook.
69
+ */
70
+ export interface EnqueueErrorContext {
71
+ readonly envelope: Envelope;
72
+ readonly error: Error;
73
+ /** The transport that failed (e.g., 'local', 'rabbitmq') */
74
+ readonly transport: string;
75
+ }
76
+
77
+ /**
78
+ * Context for decode error hook.
79
+ */
80
+ export interface DecodeErrorContext {
81
+ readonly error: Error;
82
+ readonly rawMessage: Uint8Array;
83
+ readonly sourceQueue: string;
84
+ /** The transport that received the message (e.g., 'local', 'rabbitmq') */
85
+ readonly transport: string;
86
+ }
87
+
88
+ /**
89
+ * Context for worker success hook.
90
+ */
91
+ export interface WorkerSuccessContext {
92
+ readonly envelope: Envelope;
93
+ readonly subscriber: SubscriberDefinition;
94
+ readonly result: unknown;
95
+ readonly durationMs: number;
96
+ /** The transport that received the message (e.g., 'local', 'rabbitmq') */
97
+ readonly transport: string;
98
+ }
99
+
100
+ /**
101
+ * Context for worker error hook.
102
+ */
103
+ export interface WorkerErrorContext {
104
+ readonly envelope: Envelope;
105
+ readonly subscriber: SubscriberDefinition;
106
+ readonly error: Error;
107
+ readonly durationMs: number;
108
+ readonly decision: RetryDecision;
109
+ /** The transport that received the message (e.g., 'local', 'rabbitmq') */
110
+ readonly transport: string;
111
+ }
112
+
113
+ /**
114
+ * Execution function passed to onWorkerWrap for APM wrapping.
115
+ */
116
+ export type WorkerExecuteFn = () => Promise<void>;
117
+
118
+ /**
119
+ * All available hooks for Matador.
120
+ */
121
+ export interface MatadorHooks {
122
+ /**
123
+ * Logger for internal Matador logging.
124
+ * Defaults to console logger if not provided.
125
+ */
126
+ logger?: Logger;
127
+
128
+ /**
129
+ * Called when an event is successfully enqueued.
130
+ */
131
+ onEnqueueSuccess?(context: EnqueueSuccessContext): void | Promise<void>;
132
+
133
+ /**
134
+ * Called when enqueue falls back to a secondary queue.
135
+ */
136
+ onEnqueueWarning?(context: EnqueueWarningContext): void | Promise<void>;
137
+
138
+ /**
139
+ * Called when transport fallback occurs during send.
140
+ * Only fires when using MultiTransport with fallbackEnabled=true.
141
+ */
142
+ onTransportFallback?(context: TransportFallbackContext): void | Promise<void>;
143
+
144
+ /**
145
+ * Called when enqueue fails completely.
146
+ */
147
+ onEnqueueError?(context: EnqueueErrorContext): void | Promise<void>;
148
+
149
+ /**
150
+ * Wraps entire worker processing (for APM context).
151
+ * Must call execute() to run the actual processing.
152
+ */
153
+ onWorkerWrap?(
154
+ envelope: Envelope,
155
+ subscriber: SubscriberDefinition,
156
+ execute: WorkerExecuteFn,
157
+ ): Promise<void>;
158
+
159
+ /**
160
+ * Called before processing begins.
161
+ */
162
+ onWorkerBeforeProcess?(
163
+ envelope: Envelope,
164
+ subscriber: SubscriberDefinition,
165
+ ): void | Promise<void>;
166
+
167
+ /**
168
+ * Called after successful processing.
169
+ */
170
+ onWorkerSuccess?(context: WorkerSuccessContext): void | Promise<void>;
171
+
172
+ /**
173
+ * Called after processing error.
174
+ */
175
+ onWorkerError?(context: WorkerErrorContext): void | Promise<void>;
176
+
177
+ /**
178
+ * Called when message decoding fails.
179
+ */
180
+ onDecodeError?(context: DecodeErrorContext): void | Promise<void>;
181
+
182
+ /**
183
+ * Called when transport connection state changes.
184
+ */
185
+ onConnectionStateChange?(state: ConnectionState): void | Promise<void>;
186
+
187
+ /**
188
+ * Loads universal metadata to add to all envelopes.
189
+ */
190
+ loadUniversalMetadata?():
191
+ | Record<string, unknown>
192
+ | Promise<Record<string, unknown>>;
193
+
194
+ /**
195
+ * Dynamic queue concurrency lookup.
196
+ */
197
+ getQueueConcurrency?(
198
+ queueName: string,
199
+ ): number | undefined | Promise<number | undefined>;
200
+
201
+ /**
202
+ * Dynamic retry delay lookup.
203
+ */
204
+ getRetryDelay?(
205
+ envelope: Envelope,
206
+ attemptNumber: number,
207
+ ): number | undefined | Promise<number | undefined>;
208
+
209
+ /**
210
+ * Dynamic max attempts lookup.
211
+ */
212
+ getAttempts?(
213
+ envelope: Envelope,
214
+ ): number | undefined | Promise<number | undefined>;
215
+
216
+ /**
217
+ * Dynamic max deliveries (poison threshold) lookup.
218
+ */
219
+ getMaxDeliveries?(
220
+ envelope: Envelope,
221
+ ): number | undefined | Promise<number | undefined>;
222
+
223
+ // === Checkpoint Hooks (Resumable Subscribers) ===
224
+
225
+ /**
226
+ * Called when a checkpoint is loaded for a retry.
227
+ * Only fires for resumable subscribers on retry attempts.
228
+ */
229
+ onCheckpointLoaded?(context: CheckpointLoadedContext): void | Promise<void>;
230
+
231
+ /**
232
+ * Called when an io() operation uses a cached value (checkpoint hit).
233
+ * Useful for observability and metrics.
234
+ */
235
+ onCheckpointHit?(context: CheckpointHitContext): void | Promise<void>;
236
+
237
+ /**
238
+ * Called when an io() operation executes (cache miss).
239
+ * Useful for observability and metrics.
240
+ */
241
+ onCheckpointMiss?(context: CheckpointMissContext): void | Promise<void>;
242
+
243
+ /**
244
+ * Called when a checkpoint is cleared.
245
+ * Fires on successful completion or when moving to dead-letter queue.
246
+ */
247
+ onCheckpointCleared?(context: CheckpointClearedContext): void | Promise<void>;
248
+ }
package/src/index.ts ADDED
@@ -0,0 +1,231 @@
1
+ // Core
2
+ export type {
3
+ FanoutConfig,
4
+ HandlersState,
5
+ MatadorConfig,
6
+ SendError,
7
+ SendResult,
8
+ ShutdownConfig,
9
+ ShutdownState,
10
+ } from './core/index.js';
11
+ export {
12
+ defaultShutdownConfig,
13
+ FanoutEngine,
14
+ Matador,
15
+ ShutdownManager,
16
+ } from './core/index.js';
17
+
18
+ // Types
19
+ export type {
20
+ AnySubscriber,
21
+ BaseSubscriberOptions,
22
+ CreateEnvelopeOptions,
23
+ DeliveryMode,
24
+ Docket,
25
+ Envelope,
26
+ EnvelopeOf,
27
+ Event,
28
+ EventClass,
29
+ EventData,
30
+ EventKey,
31
+ EventOptions,
32
+ EventStatic,
33
+ Idempotency,
34
+ Importance,
35
+ JsonRecord,
36
+ Subscriber,
37
+ SubscriberCallback,
38
+ SubscriberDefinition,
39
+ SubscriberOptions,
40
+ SubscriberStub,
41
+ ValidationError,
42
+ ValidationResult,
43
+ } from './types/index.js';
44
+ export {
45
+ MatadorEvent,
46
+ createEnvelope,
47
+ createSubscriber,
48
+ createSubscriberStub,
49
+ invalidResult,
50
+ isSubscriber,
51
+ isSubscriberStub,
52
+ validResult,
53
+ } from './types/index.js';
54
+
55
+ // Transport
56
+ export type {
57
+ ConnectFn,
58
+ ConnectionManagerConfig,
59
+ ConnectionState,
60
+ DisconnectFn,
61
+ MessageHandler,
62
+ MessageReceipt,
63
+ RabbitMQSendOptions,
64
+ RabbitMQSubscribeOptions,
65
+ RabbitMQTransportConfig,
66
+ SendOptions,
67
+ StateChangeCallback,
68
+ SubscribeOptions,
69
+ Subscription,
70
+ Transport,
71
+ TransportCapabilities,
72
+ TransportSendOptions,
73
+ TransportSubscribeOptions,
74
+ } from './transport/index.js';
75
+ export {
76
+ ConnectionManager,
77
+ defaultConnectionConfig,
78
+ hasNativeDeadLetter,
79
+ LocalTransport,
80
+ RabbitMQTransport,
81
+ MultiTransport,
82
+ type MultiTransportConfig,
83
+ type MultiTransportHooks,
84
+ supportsDeliveryMode,
85
+ supportsDelayedMessages,
86
+ } from './transport/index.js';
87
+
88
+ // Topology
89
+ export type {
90
+ DeadLetterConfig,
91
+ DeadLetterQueueConfig,
92
+ QueueDefinition,
93
+ QueueOptions,
94
+ RetryConfig,
95
+ Topology,
96
+ } from './topology/index.js';
97
+ export {
98
+ getDeadLetterQueueName,
99
+ getQualifiedQueueName,
100
+ getRetryQueueName,
101
+ TopologyBuilder,
102
+ TopologyValidationError,
103
+ } from './topology/index.js';
104
+
105
+ // Codec
106
+ export type {
107
+ Codec,
108
+ EncodedMessage,
109
+ HeaderAwareCodec,
110
+ } from './codec/index.js';
111
+ export { CodecDecodeError, JsonCodec, RabbitMQCodec } from './codec/index.js';
112
+
113
+ // Schema
114
+ export type {
115
+ MatadorSchema,
116
+ RegisterOptions,
117
+ SchemaEntry,
118
+ SchemaEntryTuple,
119
+ SchemaIssue,
120
+ SchemaPlugin,
121
+ SchemaValidationResult,
122
+ } from './schema/index.js';
123
+ export {
124
+ bind,
125
+ installPlugins,
126
+ isSchemaEntryTuple,
127
+ SchemaError,
128
+ SchemaRegistry,
129
+ } from './schema/index.js';
130
+
131
+ // Retry
132
+ export type {
133
+ RetryContext,
134
+ RetryDecision,
135
+ RetryPolicy,
136
+ StandardRetryPolicyConfig,
137
+ } from './retry/index.js';
138
+ export {
139
+ defaultRetryConfig,
140
+ StandardRetryPolicy,
141
+ } from './retry/index.js';
142
+
143
+ // Hooks
144
+ export type {
145
+ DecodeErrorContext,
146
+ EnqueueErrorContext,
147
+ EnqueueSuccessContext,
148
+ EnqueueWarningContext,
149
+ Logger,
150
+ MatadorHooks,
151
+ WorkerErrorContext,
152
+ WorkerExecuteFn,
153
+ WorkerSuccessContext,
154
+ } from './hooks/index.js';
155
+ export { consoleLogger, SafeHooks } from './hooks/index.js';
156
+
157
+ // Pipeline
158
+ export type { PipelineConfig, ProcessResult } from './pipeline/index.js';
159
+ export { ProcessingPipeline } from './pipeline/index.js';
160
+
161
+ // Errors
162
+ export type { HasDescription } from './errors/index.js';
163
+ export {
164
+ // Retry control errors
165
+ DontRetry,
166
+ DoRetry,
167
+ EventAssertionError,
168
+ RetryControlError,
169
+ isAssertionError,
170
+ isDontRetry,
171
+ isDoRetry,
172
+ // Matador errors with descriptions
173
+ MatadorError,
174
+ isMatadorError,
175
+ // Lifecycle errors
176
+ NotStartedError,
177
+ isNotStartedError,
178
+ ShutdownInProgressError,
179
+ // Transport errors
180
+ TransportNotConnectedError,
181
+ isTransportNotConnectedError,
182
+ TransportClosedError,
183
+ TransportSendError,
184
+ AllTransportsFailedError,
185
+ DelayedMessagesNotSupportedError,
186
+ // Schema & configuration errors
187
+ EventNotRegisteredError,
188
+ isEventNotRegisteredError,
189
+ SubscriberNotRegisteredError,
190
+ isSubscriberNotRegisteredError,
191
+ NoSubscribersExistError,
192
+ InvalidSchemaError,
193
+ SubscriberIsStubError,
194
+ LocalTransportCannotProcessStubError,
195
+ // Queue errors
196
+ QueueNotFoundError,
197
+ // Event validation errors
198
+ InvalidEventError,
199
+ // Message processing errors
200
+ MessageMaybePoisonedError,
201
+ isMessageMaybePoisonedError,
202
+ IdempotentMessageCannotRetryError,
203
+ isIdempotentMessageCannotRetryError,
204
+ // Timeout errors
205
+ TimeoutError,
206
+ // Utility
207
+ hasDescription,
208
+ } from './errors/index.js';
209
+
210
+ // Checkpoint (Resumable Subscribers)
211
+ export type {
212
+ Checkpoint,
213
+ CheckpointClearedContext,
214
+ CheckpointHitContext,
215
+ CheckpointLoadedContext,
216
+ CheckpointMissContext,
217
+ CheckpointStore,
218
+ JsonSerializable,
219
+ ResumableContextConfig,
220
+ ResumableContextHooks,
221
+ SubscriberContext,
222
+ } from './checkpoint/index.js';
223
+ export {
224
+ CheckpointStoreError,
225
+ DuplicateIoKeyError,
226
+ MemoryCheckpointStore,
227
+ NoOpCheckpointStore,
228
+ ResumableContext,
229
+ isCheckpointStoreError,
230
+ isDuplicateIoKeyError,
231
+ } from './checkpoint/index.js';
@@ -0,0 +1,2 @@
1
+ export type { PipelineConfig, ProcessResult } from './pipeline.js';
2
+ export { ProcessingPipeline } from './pipeline.js';