@zdavison/matador 2.0.9 → 2.0.11

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 (259) hide show
  1. package/dist/checkpoint/context.d.ts +59 -0
  2. package/dist/checkpoint/context.d.ts.map +1 -0
  3. package/dist/checkpoint/context.js +140 -0
  4. package/dist/checkpoint/context.test.d.ts +2 -0
  5. package/dist/checkpoint/context.test.d.ts.map +1 -0
  6. package/dist/checkpoint/context.test.js +424 -0
  7. package/dist/checkpoint/index.d.ts +7 -0
  8. package/dist/checkpoint/index.d.ts.map +1 -0
  9. package/dist/checkpoint/index.js +6 -0
  10. package/dist/checkpoint/stores/memory.d.ts +29 -0
  11. package/dist/checkpoint/stores/memory.d.ts.map +1 -0
  12. package/dist/checkpoint/stores/memory.js +39 -0
  13. package/{src/checkpoint/stores/noop.ts → dist/checkpoint/stores/noop.d.ts} +5 -13
  14. package/dist/checkpoint/stores/noop.d.ts.map +1 -0
  15. package/dist/checkpoint/stores/noop.js +18 -0
  16. package/dist/checkpoint/stores/stores.test.d.ts +2 -0
  17. package/dist/checkpoint/stores/stores.test.d.ts.map +1 -0
  18. package/dist/checkpoint/stores/stores.test.js +146 -0
  19. package/dist/checkpoint/types.d.ts +119 -0
  20. package/dist/checkpoint/types.d.ts.map +1 -0
  21. package/dist/checkpoint/types.js +1 -0
  22. package/dist/codec/codec.d.ts +29 -0
  23. package/dist/codec/codec.d.ts.map +1 -0
  24. package/dist/codec/codec.js +15 -0
  25. package/dist/codec/header-aware-codec.d.ts +36 -0
  26. package/dist/codec/header-aware-codec.d.ts.map +1 -0
  27. package/dist/codec/header-aware-codec.js +1 -0
  28. package/{src/codec/index.ts → dist/codec/index.d.ts} +2 -7
  29. package/dist/codec/index.d.ts.map +1 -0
  30. package/dist/codec/index.js +3 -0
  31. package/dist/codec/json-codec.d.ts +13 -0
  32. package/dist/codec/json-codec.d.ts.map +1 -0
  33. package/dist/codec/json-codec.js +64 -0
  34. package/dist/codec/rabbitmq-codec.d.ts +28 -0
  35. package/dist/codec/rabbitmq-codec.d.ts.map +1 -0
  36. package/dist/codec/rabbitmq-codec.js +242 -0
  37. package/dist/codec/rabbitmq-codec.test.d.ts +2 -0
  38. package/dist/codec/rabbitmq-codec.test.d.ts.map +1 -0
  39. package/dist/codec/rabbitmq-codec.test.js +433 -0
  40. package/dist/core/fanout.d.ts +59 -0
  41. package/dist/core/fanout.d.ts.map +1 -0
  42. package/dist/core/fanout.js +121 -0
  43. package/dist/core/fanout.test.d.ts +2 -0
  44. package/dist/core/fanout.test.d.ts.map +1 -0
  45. package/dist/core/fanout.test.js +1054 -0
  46. package/{src/core/index.ts → dist/core/index.d.ts} +2 -7
  47. package/dist/core/index.d.ts.map +1 -0
  48. package/dist/core/index.js +3 -0
  49. package/dist/core/matador.d.ts +133 -0
  50. package/dist/core/matador.d.ts.map +1 -0
  51. package/dist/core/matador.js +228 -0
  52. package/dist/core/matador.test.d.ts +2 -0
  53. package/dist/core/matador.test.d.ts.map +1 -0
  54. package/dist/core/matador.test.js +446 -0
  55. package/dist/core/shutdown.d.ts +78 -0
  56. package/dist/core/shutdown.d.ts.map +1 -0
  57. package/dist/core/shutdown.js +111 -0
  58. package/dist/core/shutdown.test.d.ts +2 -0
  59. package/dist/core/shutdown.test.d.ts.map +1 -0
  60. package/dist/core/shutdown.test.js +524 -0
  61. package/dist/errors/checkpoint-errors.d.ts +30 -0
  62. package/dist/errors/checkpoint-errors.d.ts.map +1 -0
  63. package/dist/errors/checkpoint-errors.js +49 -0
  64. package/dist/errors/has-description.d.ts +18 -0
  65. package/dist/errors/has-description.d.ts.map +1 -0
  66. package/dist/errors/has-description.js +9 -0
  67. package/dist/errors/index.d.ts +6 -0
  68. package/dist/errors/index.d.ts.map +1 -0
  69. package/dist/errors/index.js +22 -0
  70. package/dist/errors/matador-errors.d.ts +183 -0
  71. package/dist/errors/matador-errors.d.ts.map +1 -0
  72. package/dist/errors/matador-errors.js +376 -0
  73. package/dist/errors/retry-errors.d.ts +102 -0
  74. package/dist/errors/retry-errors.d.ts.map +1 -0
  75. package/dist/errors/retry-errors.js +155 -0
  76. package/dist/errors/retry-errors.test.d.ts +2 -0
  77. package/dist/errors/retry-errors.test.d.ts.map +1 -0
  78. package/dist/errors/retry-errors.test.js +136 -0
  79. package/dist/hooks/index.d.ts +4 -0
  80. package/dist/hooks/index.d.ts.map +1 -0
  81. package/dist/hooks/index.js +2 -0
  82. package/dist/hooks/safe-hooks.d.ts +32 -0
  83. package/dist/hooks/safe-hooks.d.ts.map +1 -0
  84. package/dist/hooks/safe-hooks.js +120 -0
  85. package/dist/hooks/types.d.ts +172 -0
  86. package/dist/hooks/types.d.ts.map +1 -0
  87. package/dist/hooks/types.js +9 -0
  88. package/dist/index.cjs +3228 -0
  89. package/dist/index.cjs.map +1 -0
  90. package/dist/index.d.cts +23 -0
  91. package/dist/index.d.ts +23 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +31 -0
  94. package/dist/index.js.map +1 -0
  95. package/{src/pipeline/index.ts → dist/pipeline/index.d.ts} +1 -0
  96. package/dist/pipeline/index.d.ts.map +1 -0
  97. package/dist/pipeline/index.js +1 -0
  98. package/dist/pipeline/pipeline.d.ts +63 -0
  99. package/dist/pipeline/pipeline.d.ts.map +1 -0
  100. package/dist/pipeline/pipeline.js +273 -0
  101. package/dist/pipeline/pipeline.test.d.ts +2 -0
  102. package/dist/pipeline/pipeline.test.d.ts.map +1 -0
  103. package/dist/pipeline/pipeline.test.js +1112 -0
  104. package/{src/retry/index.ts → dist/retry/index.d.ts} +1 -1
  105. package/dist/retry/index.d.ts.map +1 -0
  106. package/dist/retry/index.js +1 -0
  107. package/dist/retry/policy.d.ts +43 -0
  108. package/dist/retry/policy.d.ts.map +1 -0
  109. package/dist/retry/policy.js +1 -0
  110. package/dist/retry/standard-policy.d.ts +44 -0
  111. package/dist/retry/standard-policy.d.ts.map +1 -0
  112. package/dist/retry/standard-policy.js +102 -0
  113. package/dist/retry/standard-policy.test.d.ts +2 -0
  114. package/dist/retry/standard-policy.test.d.ts.map +1 -0
  115. package/dist/retry/standard-policy.test.js +196 -0
  116. package/dist/schema/index.d.ts +4 -0
  117. package/dist/schema/index.d.ts.map +1 -0
  118. package/dist/schema/index.js +2 -0
  119. package/dist/schema/registry.d.ts +63 -0
  120. package/dist/schema/registry.d.ts.map +1 -0
  121. package/dist/schema/registry.js +174 -0
  122. package/dist/schema/registry.test.d.ts +2 -0
  123. package/dist/schema/registry.test.d.ts.map +1 -0
  124. package/dist/schema/registry.test.js +278 -0
  125. package/{src/schema/types.ts → dist/schema/types.d.ts} +29 -88
  126. package/dist/schema/types.d.ts.map +1 -0
  127. package/dist/schema/types.js +74 -0
  128. package/dist/schema/types.test.d.ts +2 -0
  129. package/dist/schema/types.test.d.ts.map +1 -0
  130. package/dist/schema/types.test.js +242 -0
  131. package/dist/topology/builder.d.ts +80 -0
  132. package/dist/topology/builder.d.ts.map +1 -0
  133. package/dist/topology/builder.js +165 -0
  134. package/dist/topology/builder.test.d.ts +2 -0
  135. package/dist/topology/builder.test.d.ts.map +1 -0
  136. package/dist/topology/builder.test.js +360 -0
  137. package/dist/topology/index.d.ts +5 -0
  138. package/dist/topology/index.d.ts.map +1 -0
  139. package/dist/topology/index.js +2 -0
  140. package/dist/topology/types.d.ts +128 -0
  141. package/dist/topology/types.d.ts.map +1 -0
  142. package/dist/topology/types.js +28 -0
  143. package/dist/transport/capabilities.d.ts +66 -0
  144. package/dist/transport/capabilities.d.ts.map +1 -0
  145. package/dist/transport/capabilities.js +18 -0
  146. package/dist/transport/connection-manager.d.ts +95 -0
  147. package/dist/transport/connection-manager.d.ts.map +1 -0
  148. package/dist/transport/connection-manager.js +144 -0
  149. package/dist/transport/index.d.ts +11 -0
  150. package/dist/transport/index.d.ts.map +1 -0
  151. package/dist/transport/index.js +5 -0
  152. package/dist/transport/local/local-transport.d.ts +62 -0
  153. package/dist/transport/local/local-transport.d.ts.map +1 -0
  154. package/dist/transport/local/local-transport.js +241 -0
  155. package/dist/transport/local/local-transport.test.d.ts +2 -0
  156. package/dist/transport/local/local-transport.test.d.ts.map +1 -0
  157. package/dist/transport/local/local-transport.test.js +192 -0
  158. package/dist/transport/multi/multi-transport.d.ts +94 -0
  159. package/dist/transport/multi/multi-transport.d.ts.map +1 -0
  160. package/dist/transport/multi/multi-transport.js +184 -0
  161. package/dist/transport/multi/multi-transport.test.d.ts +2 -0
  162. package/dist/transport/multi/multi-transport.test.d.ts.map +1 -0
  163. package/dist/transport/multi/multi-transport.test.js +236 -0
  164. package/dist/transport/rabbitmq/rabbitmq-transport.d.ts +83 -0
  165. package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -0
  166. package/dist/transport/rabbitmq/rabbitmq-transport.js +541 -0
  167. package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts +2 -0
  168. package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts.map +1 -0
  169. package/dist/transport/rabbitmq/rabbitmq-transport.test.js +100 -0
  170. package/dist/transport/transport.d.ts +152 -0
  171. package/dist/transport/transport.d.ts.map +1 -0
  172. package/dist/transport/transport.js +1 -0
  173. package/{src/types/common.ts → dist/types/common.d.ts} +8 -20
  174. package/dist/types/common.d.ts.map +1 -0
  175. package/dist/types/common.js +12 -0
  176. package/dist/types/dispatcher.d.ts +14 -0
  177. package/dist/types/dispatcher.d.ts.map +1 -0
  178. package/dist/types/dispatcher.js +1 -0
  179. package/dist/types/envelope.d.ts +131 -0
  180. package/dist/types/envelope.d.ts.map +1 -0
  181. package/dist/types/envelope.js +99 -0
  182. package/dist/types/event.d.ts +92 -0
  183. package/dist/types/event.d.ts.map +1 -0
  184. package/dist/types/event.js +26 -0
  185. package/dist/types/event.test.d.ts +2 -0
  186. package/dist/types/event.test.d.ts.map +1 -0
  187. package/dist/types/event.test.js +130 -0
  188. package/dist/types/index.d.ts +11 -0
  189. package/dist/types/index.d.ts.map +1 -0
  190. package/dist/types/index.js +4 -0
  191. package/dist/types/subscriber.d.ts +227 -0
  192. package/dist/types/subscriber.d.ts.map +1 -0
  193. package/dist/types/subscriber.js +97 -0
  194. package/package.json +6 -2
  195. package/examples/config.ts +0 -126
  196. package/examples/event.ts +0 -26
  197. package/examples/order-event.json +0 -19
  198. package/src/checkpoint/context.test.ts +0 -510
  199. package/src/checkpoint/context.ts +0 -213
  200. package/src/checkpoint/index.ts +0 -30
  201. package/src/checkpoint/stores/memory.ts +0 -47
  202. package/src/checkpoint/stores/stores.test.ts +0 -177
  203. package/src/checkpoint/types.ts +0 -147
  204. package/src/codec/codec.ts +0 -42
  205. package/src/codec/header-aware-codec.ts +0 -41
  206. package/src/codec/json-codec.ts +0 -69
  207. package/src/codec/rabbitmq-codec.test.ts +0 -516
  208. package/src/codec/rabbitmq-codec.ts +0 -336
  209. package/src/core/fanout.test.ts +0 -1350
  210. package/src/core/fanout.ts +0 -184
  211. package/src/core/matador.test.ts +0 -575
  212. package/src/core/matador.ts +0 -357
  213. package/src/core/shutdown.test.ts +0 -853
  214. package/src/core/shutdown.ts +0 -165
  215. package/src/errors/checkpoint-errors.ts +0 -62
  216. package/src/errors/has-description.ts +0 -25
  217. package/src/errors/index.ts +0 -58
  218. package/src/errors/matador-errors.ts +0 -477
  219. package/src/errors/retry-errors.test.ts +0 -175
  220. package/src/errors/retry-errors.ts +0 -188
  221. package/src/hooks/index.ts +0 -14
  222. package/src/hooks/safe-hooks.ts +0 -200
  223. package/src/hooks/types.ts +0 -226
  224. package/src/index.ts +0 -242
  225. package/src/pipeline/pipeline.test.ts +0 -1377
  226. package/src/pipeline/pipeline.ts +0 -393
  227. package/src/retry/policy.ts +0 -46
  228. package/src/retry/standard-policy.test.ts +0 -290
  229. package/src/retry/standard-policy.ts +0 -156
  230. package/src/schema/index.ts +0 -16
  231. package/src/schema/registry.test.ts +0 -339
  232. package/src/schema/registry.ts +0 -229
  233. package/src/schema/types.test.ts +0 -280
  234. package/src/topology/builder.test.ts +0 -451
  235. package/src/topology/builder.ts +0 -238
  236. package/src/topology/index.ts +0 -19
  237. package/src/topology/types.ts +0 -183
  238. package/src/transport/capabilities.ts +0 -88
  239. package/src/transport/connection-manager.ts +0 -218
  240. package/src/transport/index.ts +0 -42
  241. package/src/transport/local/local-transport.test.ts +0 -262
  242. package/src/transport/local/local-transport.ts +0 -330
  243. package/src/transport/multi/multi-transport.test.ts +0 -320
  244. package/src/transport/multi/multi-transport.ts +0 -294
  245. package/src/transport/rabbitmq/rabbitmq-transport.test.ts +0 -120
  246. package/src/transport/rabbitmq/rabbitmq-transport.ts +0 -782
  247. package/src/transport/transport.ts +0 -200
  248. package/src/types/dispatcher.ts +0 -18
  249. package/src/types/envelope.ts +0 -244
  250. package/src/types/event.test.ts +0 -157
  251. package/src/types/event.ts +0 -112
  252. package/src/types/index.ts +0 -62
  253. package/src/types/subscriber.ts +0 -333
  254. package/test/e2e/multi-transport.e2e.test.ts +0 -237
  255. package/test/e2e/rabbitmq-transport.e2e.test.ts +0 -618
  256. package/test/e2e/transport-compliance.e2e.test.ts +0 -506
  257. package/test/integration/matador.integration.test.ts +0 -634
  258. package/tsconfig.json +0 -29
  259. package/tsup.config.ts +0 -13
@@ -1,357 +0,0 @@
1
- import type { CheckpointStore } from '../checkpoint/index.js';
2
- import type { Codec } from '../codec/index.js';
3
- import { JsonCodec } from '../codec/index.js';
4
- import {
5
- InvalidSchemaError,
6
- NotStartedError,
7
- ShutdownInProgressError,
8
- } from '../errors/index.js';
9
- import type { MatadorHooks } from '../hooks/index.js';
10
- import { SafeHooks } from '../hooks/index.js';
11
- import { ProcessingPipeline } from '../pipeline/index.js';
12
- import type { RetryPolicy } from '../retry/index.js';
13
- import { StandardRetryPolicy } from '../retry/index.js';
14
- import type { MatadorSchema } from '../schema/index.js';
15
- import { SchemaRegistry, isSchemaEntryTuple } from '../schema/index.js';
16
- import type { Topology } from '../topology/index.js';
17
- import { getQualifiedQueueName } from '../topology/index.js';
18
- import type { Subscription, Transport } from '../transport/index.js';
19
- import type {
20
- AnySubscriber,
21
- Dispatcher,
22
- Event,
23
- EventClass,
24
- EventOptions,
25
- } from '../types/index.js';
26
- import type { SendResult } from './fanout.js';
27
- import { FanoutEngine } from './fanout.js';
28
- import type { HandlersState, ShutdownConfig } from './shutdown.js';
29
- import { ShutdownManager } from './shutdown.js';
30
-
31
- /**
32
- * Configuration for Matador.
33
- */
34
- export interface MatadorConfig {
35
- /** Transport for message delivery */
36
- readonly transport: Transport;
37
-
38
- /** Topology configuration */
39
- readonly topology: Topology;
40
-
41
- /** Event schema mapping event keys to event classes and subscribers */
42
- readonly schema: MatadorSchema;
43
-
44
- /** Queues to consume from (empty = no consumption) */
45
- readonly consumeFrom?: readonly string[] | undefined;
46
-
47
- /** Custom codec (defaults to JSON) */
48
- readonly codec?: Codec | undefined;
49
-
50
- /** Custom retry policy */
51
- readonly retryPolicy?: RetryPolicy | undefined;
52
-
53
- /** Shutdown configuration */
54
- readonly shutdownConfig?: Partial<ShutdownConfig> | undefined;
55
-
56
- /**
57
- * Checkpoint store for resumable subscribers.
58
- * Required for persisting io() results across retries.
59
- * If not provided, resumable subscribers will work but checkpoints
60
- * won't persist across retries.
61
- */
62
- readonly checkpointStore?: CheckpointStore | undefined;
63
- }
64
-
65
- /**
66
- * Matador - Transport-agnostic event processing library.
67
- *
68
- * Main orchestrator that wires together:
69
- * - Transport: Message delivery
70
- * - Schema: Event-subscriber registry
71
- * - Pipeline: Message processing
72
- * - Fanout: Event sending
73
- * - Shutdown: Graceful termination
74
- */
75
- export class Matador implements Dispatcher {
76
- private readonly transport: Transport;
77
- private readonly topology: Topology;
78
- private readonly schema;
79
- private readonly codec: Codec;
80
- private readonly retryPolicy: RetryPolicy;
81
- private readonly hooks;
82
- private readonly pipeline;
83
- private readonly fanout;
84
- private readonly shutdownManager;
85
- private readonly consumeFrom: readonly string[];
86
- private readonly subscriptions: Subscription[] = [];
87
- private started = false;
88
-
89
- /**
90
- * Creates a new Matador instance.
91
- *
92
- * @param config - Static configuration (transport, topology, schema, etc.)
93
- * @param hooks - Lifecycle hooks for logging, monitoring, and dynamic configuration.
94
- * Passed separately to support NestJS dependency injection.
95
- */
96
- constructor(config: MatadorConfig, hooks?: MatadorHooks) {
97
- this.transport = config.transport;
98
- this.topology = config.topology;
99
- this.consumeFrom = config.consumeFrom ?? [];
100
-
101
- // Initialize components
102
- this.schema = new SchemaRegistry();
103
- this.codec = config.codec ?? new JsonCodec();
104
- this.retryPolicy = config.retryPolicy ?? new StandardRetryPolicy();
105
- this.hooks = new SafeHooks(hooks);
106
-
107
- // Register schema from config
108
- this.registerSchema(config.schema);
109
-
110
- // Create pipeline
111
- this.pipeline = new ProcessingPipeline({
112
- transport: this.transport,
113
- schema: this.schema,
114
- codec: this.codec,
115
- retryPolicy: this.retryPolicy,
116
- hooks: this.hooks,
117
- checkpointStore: config.checkpointStore,
118
- dispatcher: this,
119
- });
120
-
121
- // Create fanout engine
122
- const defaultQueue = this.topology.queues[0]?.name ?? 'default';
123
- this.fanout = new FanoutEngine({
124
- transport: this.transport,
125
- schema: this.schema,
126
- hooks: this.hooks,
127
- namespace: this.topology.namespace,
128
- defaultQueue,
129
- });
130
-
131
- // Create shutdown manager
132
- this.shutdownManager = new ShutdownManager(
133
- () => this.fanout.eventsBeingEnqueuedCount,
134
- () => this.stopReceiving(),
135
- () => this.transport.disconnect(),
136
- config.shutdownConfig,
137
- );
138
- }
139
-
140
- /**
141
- * Registers an event class with its subscribers.
142
- */
143
- register<T>(
144
- eventClass: EventClass<T>,
145
- subscribers: readonly AnySubscriber[],
146
- ): this {
147
- this.schema.register(eventClass, subscribers);
148
- return this;
149
- }
150
-
151
- /**
152
- * Registers events from a schema object.
153
- * Supports both object format and tuple format entries.
154
- *
155
- * @example
156
- * ```typescript
157
- * // Tuple format
158
- * matador.registerSchema({
159
- * [UserCreatedEvent.key]: [UserCreatedEvent, [emailSubscriber]],
160
- * [OrderPlacedEvent.key]: [OrderPlacedEvent, [invoiceSubscriber]],
161
- * });
162
- *
163
- * // Object format
164
- * matador.registerSchema({
165
- * [UserCreatedEvent.key]: { eventClass: UserCreatedEvent, subscribers: [emailSubscriber] },
166
- * });
167
- * ```
168
- */
169
- registerSchema(schema: MatadorSchema): this {
170
- for (const entry of Object.values(schema)) {
171
- if (isSchemaEntryTuple(entry)) {
172
- // Tuple format: [EventClass, Subscriber[]]
173
- const [eventClass, subscribers] = entry;
174
- this.schema.register(eventClass, subscribers);
175
- } else {
176
- // Object format: { eventClass, subscribers }
177
- this.schema.register(entry.eventClass, entry.subscribers);
178
- }
179
- }
180
- return this;
181
- }
182
-
183
- /**
184
- * Starts Matador - connects transport and begins consuming.
185
- * This method is idempotent - calling it multiple times is safe.
186
- */
187
- async start(): Promise<void> {
188
- // Idempotent: if already started, just return
189
- if (this.started) {
190
- return;
191
- }
192
-
193
- // Validate schema
194
- const validation = this.schema.validate();
195
- if (!validation.valid) {
196
- const errors = validation.issues.filter((i) => i.severity === 'error');
197
- throw new InvalidSchemaError(
198
- 'Schema validation failed',
199
- errors.map((e) => e.message).join(', '),
200
- );
201
- }
202
-
203
- // Connect transport
204
- this.hooks.logger.info(
205
- `[Matador] ⏳ Starting backend '${this.transport.name}'...`,
206
- );
207
- await this.transport.connect();
208
- this.hooks.logger.info(
209
- `[Matador] 🟢 Backend '${this.transport.name}' started.`,
210
- );
211
-
212
- // Apply topology
213
- await this.transport.applyTopology(this.topology);
214
-
215
- // Subscribe to queues
216
- if (this.consumeFrom.length > 0) {
217
- this.hooks.logger.info(
218
- `[Matador] 🟢 Worker subscribing to '${this.consumeFrom.join(',')}'.`,
219
- );
220
- }
221
- for (const queueName of this.consumeFrom) {
222
- const qualifiedName = getQualifiedQueueName(
223
- this.topology.namespace,
224
- queueName,
225
- );
226
- const queueDef = this.topology.queues.find((q) => q.name === queueName);
227
-
228
- const subscription = await this.transport.subscribe(
229
- qualifiedName,
230
- async (envelope, receipt) => {
231
- this.shutdownManager.incrementProcessing();
232
- try {
233
- const rawMessage = this.codec.encode(envelope);
234
- await this.pipeline.process(rawMessage, receipt);
235
- } finally {
236
- this.shutdownManager.decrementProcessing();
237
- }
238
- },
239
- queueDef?.concurrency !== undefined
240
- ? { concurrency: queueDef.concurrency }
241
- : undefined,
242
- );
243
-
244
- this.subscriptions.push(subscription);
245
- }
246
-
247
- this.started = true;
248
- }
249
-
250
- /**
251
- * Sends an event to all registered subscribers.
252
- *
253
- * @example
254
- * ```typescript
255
- * // Pass the event class and data directly
256
- * await matador.send(UserCreatedEvent, { userId: '123' });
257
- *
258
- * // Or pass an event instance
259
- * const event = new UserCreatedEvent({ userId: '123' });
260
- * await matador.send(event);
261
- * ```
262
- */
263
- async send<T>(
264
- eventClass: EventClass<T>,
265
- data: T,
266
- options?: EventOptions,
267
- ): Promise<SendResult>;
268
- async send<T>(event: Event<T>, options?: EventOptions): Promise<SendResult>;
269
- async send<T>(
270
- eventOrClass: Event<T> | EventClass<T>,
271
- dataOrOptions?: T | EventOptions,
272
- maybeOptions?: EventOptions,
273
- ): Promise<SendResult> {
274
- if (!this.started) {
275
- throw new NotStartedError('send');
276
- }
277
-
278
- if (!this.shutdownManager.isEnqueueAllowed) {
279
- throw new ShutdownInProgressError();
280
- }
281
-
282
- // Determine if first arg is an event instance or event class
283
- const isEventClass =
284
- typeof eventOrClass === 'function' && 'key' in eventOrClass;
285
-
286
- if (isEventClass) {
287
- // Called as: send(EventClass, data, options?)
288
- const eventClass = eventOrClass as EventClass<T>;
289
- const data = dataOrOptions as T;
290
- const options = maybeOptions;
291
- const event = new eventClass(data);
292
- return this.fanout.send(eventClass, event, options);
293
- } else {
294
- // Called as: send(event, options?)
295
- const event = eventOrClass as Event<T>;
296
- const options = dataOrOptions as EventOptions | undefined;
297
- const eventClass = event.constructor as EventClass<T>;
298
- return this.fanout.send(eventClass, event, options);
299
- }
300
- }
301
-
302
- /**
303
- * Gets current handler state.
304
- */
305
- getHandlersState(): HandlersState {
306
- return this.shutdownManager.getHandlersState();
307
- }
308
-
309
- /**
310
- * Checks if Matador is idle (no processing or enqueuing).
311
- */
312
- isIdle(): boolean {
313
- return this.shutdownManager.getHandlersState().isIdle;
314
- }
315
-
316
- /**
317
- * Waits for all handlers to become idle.
318
- */
319
- async waitForIdle(timeoutMs = 30000): Promise<boolean> {
320
- const deadline = Date.now() + timeoutMs;
321
-
322
- while (!this.isIdle()) {
323
- if (Date.now() > deadline) {
324
- return false;
325
- }
326
- await new Promise((resolve) => setTimeout(resolve, 100));
327
- }
328
-
329
- return true;
330
- }
331
-
332
- /**
333
- * Gracefully shuts down Matador.
334
- */
335
- async shutdown(): Promise<void> {
336
- if (!this.started) {
337
- return;
338
- }
339
-
340
- await this.shutdownManager.shutdown();
341
- this.started = false;
342
- }
343
-
344
- /**
345
- * Checks if transport is connected.
346
- */
347
- isConnected(): boolean {
348
- return this.transport.isConnected();
349
- }
350
-
351
- private async stopReceiving(): Promise<void> {
352
- for (const subscription of this.subscriptions) {
353
- await subscription.unsubscribe();
354
- }
355
- this.subscriptions.length = 0;
356
- }
357
- }