@amqp-contract/contract 0.20.0 → 0.22.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.
- package/README.md +34 -4
- package/dist/index.cjs +332 -390
- package/dist/index.d.cts +657 -622
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +657 -622
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +331 -385
- package/dist/index.mjs.map +1 -1
- package/docs/index.md +413 -529
- package/package.json +24 -24
package/dist/index.d.cts
CHANGED
|
@@ -27,6 +27,7 @@ type TtlBackoffRetryOptions = {
|
|
|
27
27
|
mode: "ttl-backoff";
|
|
28
28
|
/**
|
|
29
29
|
* Maximum retry attempts before sending to DLQ.
|
|
30
|
+
* @minimum 1 - Must be a positive integer (1 or greater)
|
|
30
31
|
* @default 3
|
|
31
32
|
*/
|
|
32
33
|
maxRetries?: number;
|
|
@@ -50,27 +51,66 @@ type TtlBackoffRetryOptions = {
|
|
|
50
51
|
* @default true
|
|
51
52
|
*/
|
|
52
53
|
jitter?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Name of the wait queue.
|
|
56
|
+
* @default '{queueName}-wait'
|
|
57
|
+
*/
|
|
58
|
+
waitQueueName?: string;
|
|
59
|
+
/**
|
|
60
|
+
* Name of the wait exchange.
|
|
61
|
+
* @default 'wait-exchange'
|
|
62
|
+
*/
|
|
63
|
+
waitExchangeName?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Name of the retry exchange.
|
|
66
|
+
* @default 'retry-exchange'
|
|
67
|
+
*/
|
|
68
|
+
retryExchangeName?: string;
|
|
53
69
|
};
|
|
54
70
|
/**
|
|
55
|
-
*
|
|
71
|
+
* Immediate-Requeue retry options.
|
|
56
72
|
*
|
|
57
|
-
*
|
|
58
|
-
* with `nack(requeue=true)`, and
|
|
59
|
-
*
|
|
60
|
-
* automatically dead-lettered.
|
|
73
|
+
* Failed messages are requeued immediately.
|
|
74
|
+
* For quorum queues, messages are requeued with `nack(requeue=true)`, and the worker tracks delivery count via the native RabbitMQ `x-delivery-count` header.
|
|
75
|
+
* For classic queues, messages are re-published on the same queue, and the worker tracks delivery count via a custom `x-retry-count` header.
|
|
76
|
+
* When the count exceeds `maxRetries`, the message is automatically dead-lettered (if DLX is configured) or dropped.
|
|
61
77
|
*
|
|
62
78
|
* **Benefits:** Simpler architecture, no wait queues needed, no head-of-queue blocking.
|
|
63
79
|
* **Limitation:** Immediate retries only (no exponential backoff).
|
|
64
80
|
*
|
|
65
81
|
* @see https://www.rabbitmq.com/docs/quorum-queues#poison-message-handling
|
|
66
82
|
*/
|
|
67
|
-
type
|
|
83
|
+
type ImmediateRequeueRetryOptions = {
|
|
84
|
+
/**
|
|
85
|
+
* Immediate-Requeue mode.
|
|
86
|
+
*/
|
|
87
|
+
mode: "immediate-requeue";
|
|
88
|
+
/**
|
|
89
|
+
* Maximum retry attempts before sending to DLQ.
|
|
90
|
+
* @minimum 1 - Must be a positive integer (1 or greater)
|
|
91
|
+
* @default 3
|
|
92
|
+
*/
|
|
93
|
+
maxRetries?: number;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* No retry mode. Failed messages are not retried and are sent
|
|
97
|
+
* directly to DLQ (if configured) or rejected.
|
|
98
|
+
*/
|
|
99
|
+
type NoneRetryOptions = {
|
|
68
100
|
/**
|
|
69
|
-
*
|
|
70
|
-
* Requires the queue to be a quorum queue with `deliveryLimit` configured.
|
|
101
|
+
* None mode disables retry attempts entirely.
|
|
71
102
|
*/
|
|
72
|
-
mode: "
|
|
103
|
+
mode: "none";
|
|
73
104
|
};
|
|
105
|
+
/**
|
|
106
|
+
* Retry configuration options.
|
|
107
|
+
*
|
|
108
|
+
* This is a discriminated union based on the `mode` field:
|
|
109
|
+
* - `none` (default): No retry attempts are made; failed messages are handled by DLQ/reject
|
|
110
|
+
* - `immediate-requeue`: Requeues failed messages immediately
|
|
111
|
+
* - `ttl-backoff`: Uses wait queues with exponential backoff
|
|
112
|
+
*/
|
|
113
|
+
type RetryOptions = NoneRetryOptions | ImmediateRequeueRetryOptions | TtlBackoffRetryOptions;
|
|
74
114
|
/**
|
|
75
115
|
* Resolved TTL-Backoff retry options with all defaults applied.
|
|
76
116
|
*
|
|
@@ -86,15 +126,34 @@ type ResolvedTtlBackoffRetryOptions = {
|
|
|
86
126
|
maxDelayMs: number;
|
|
87
127
|
backoffMultiplier: number;
|
|
88
128
|
jitter: boolean;
|
|
129
|
+
waitQueueName: string;
|
|
130
|
+
waitExchangeName: string;
|
|
131
|
+
retryExchangeName: string;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Resolved Immediate-Requeue retry options with all defaults applied.
|
|
135
|
+
*
|
|
136
|
+
* This type is used internally in queue definitions after `defineQueue` has applied
|
|
137
|
+
* default values. All fields are required.
|
|
138
|
+
*
|
|
139
|
+
* @internal
|
|
140
|
+
*/
|
|
141
|
+
type ResolvedImmediateRequeueRetryOptions = {
|
|
142
|
+
mode: "immediate-requeue";
|
|
143
|
+
maxRetries: number;
|
|
89
144
|
};
|
|
90
145
|
/**
|
|
91
146
|
* Resolved retry configuration stored in queue definitions.
|
|
92
147
|
*
|
|
93
148
|
* This is a discriminated union based on the `mode` field:
|
|
94
|
-
* - `
|
|
95
|
-
* - `
|
|
149
|
+
* - `none`: No retry attempts are made; failed messages are handled by DLQ/reject
|
|
150
|
+
* - `immediate-requeue`: Has all immediate-requeue retry options with default applied
|
|
151
|
+
* - `ttl-backoff`: Has all TTL-backoff retry options with defaults applied
|
|
152
|
+
*
|
|
153
|
+
* When using `ttl-backoff` mode, the core package will automatically create
|
|
154
|
+
* a wait queue and the necessary exchanges and bindings.
|
|
96
155
|
*/
|
|
97
|
-
type ResolvedRetryOptions =
|
|
156
|
+
type ResolvedRetryOptions = NoneRetryOptions | ResolvedImmediateRequeueRetryOptions | ResolvedTtlBackoffRetryOptions;
|
|
98
157
|
/**
|
|
99
158
|
* Supported compression algorithms for message payloads.
|
|
100
159
|
*
|
|
@@ -132,8 +191,7 @@ type CompressionAlgorithm = "gzip" | "deflate";
|
|
|
132
191
|
* - `classic`: Classic queues - The traditional RabbitMQ queue type. Use only when you need
|
|
133
192
|
* specific features not supported by quorum queues (e.g., non-durable queues, priority queues).
|
|
134
193
|
*
|
|
135
|
-
* Note: Quorum queues
|
|
136
|
-
* When using quorum queues, `durable` is automatically set to `true`.
|
|
194
|
+
* Note: Quorum queues only support durable queues, and do not support exclusive, auto-deleting, or priority queues.
|
|
137
195
|
*
|
|
138
196
|
* @see https://www.rabbitmq.com/docs/quorum-queues
|
|
139
197
|
*
|
|
@@ -156,21 +214,37 @@ type QueueType = "quorum" | "classic";
|
|
|
156
214
|
* Common queue options shared between quorum and classic queues.
|
|
157
215
|
*/
|
|
158
216
|
type BaseQueueOptions = {
|
|
159
|
-
/**
|
|
160
|
-
* If true, the queue survives broker restarts. Durable queues are persisted to disk.
|
|
161
|
-
* Note: Quorum queues are always durable regardless of this setting.
|
|
162
|
-
* @default false (but forced to true for quorum queues during setup)
|
|
163
|
-
*/
|
|
164
|
-
durable?: boolean;
|
|
165
|
-
/**
|
|
166
|
-
* If true, the queue is deleted when the last consumer unsubscribes.
|
|
167
|
-
* @default false
|
|
168
|
-
*/
|
|
169
|
-
autoDelete?: boolean;
|
|
170
217
|
/**
|
|
171
218
|
* Dead letter configuration for handling failed or rejected messages.
|
|
172
219
|
*/
|
|
173
220
|
deadLetter?: DeadLetterConfig;
|
|
221
|
+
/**
|
|
222
|
+
* Retry configuration for handling failed message processing.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```typescript
|
|
226
|
+
* // No retry
|
|
227
|
+
* const orderQueue = defineQueue('order-processing', {
|
|
228
|
+
* retry: { mode: 'none' },
|
|
229
|
+
* });
|
|
230
|
+
*
|
|
231
|
+
* // Immediate-requeue mode
|
|
232
|
+
* const orderQueue = defineQueue('order-processing', {
|
|
233
|
+
* retry: { mode: 'immediate-requeue', maxRetries: 5 },
|
|
234
|
+
* });
|
|
235
|
+
*
|
|
236
|
+
* // TTL-backoff mode with custom options
|
|
237
|
+
* const orderQueue = defineQueue('order-processing', {
|
|
238
|
+
* retry: {
|
|
239
|
+
* mode: 'ttl-backoff',
|
|
240
|
+
* maxRetries: 5,
|
|
241
|
+
* initialDelayMs: 1000,
|
|
242
|
+
* maxDelayMs: 30000,
|
|
243
|
+
* },
|
|
244
|
+
* });
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
retry?: RetryOptions;
|
|
174
248
|
/**
|
|
175
249
|
* Additional AMQP arguments for advanced configuration.
|
|
176
250
|
*/
|
|
@@ -180,12 +254,14 @@ type BaseQueueOptions = {
|
|
|
180
254
|
* Options for creating a quorum queue.
|
|
181
255
|
*
|
|
182
256
|
* Quorum queues do not support:
|
|
183
|
-
* - `exclusive` - Use classic queues for
|
|
257
|
+
* - `exclusive` - Use classic queues for connection-scoped queues
|
|
258
|
+
* - `autoDelete` - Use classic queues for auto-deleting queues when consumers disconnect
|
|
184
259
|
* - `maxPriority` - Use classic queues for priority queues
|
|
260
|
+
* - `durable: false` - Use classic queues for non-durable queues
|
|
185
261
|
*
|
|
186
|
-
* Quorum queues provide native retry support
|
|
262
|
+
* Quorum queues provide native retry support for immediate-requeue retry mode:
|
|
187
263
|
* - RabbitMQ tracks delivery count automatically via `x-delivery-count` header
|
|
188
|
-
* - When the limit is exceeded, messages are dead-lettered (if DLX is configured)
|
|
264
|
+
* - When the limit is exceeded, messages are dead-lettered (if DLX is configured) or dropped
|
|
189
265
|
* - This is simpler than TTL-based retry and avoids head-of-queue blocking issues
|
|
190
266
|
*
|
|
191
267
|
* @example
|
|
@@ -193,7 +269,7 @@ type BaseQueueOptions = {
|
|
|
193
269
|
* const orderQueue = defineQueue('orders', {
|
|
194
270
|
* type: 'quorum',
|
|
195
271
|
* deadLetter: { exchange: dlx },
|
|
196
|
-
*
|
|
272
|
+
* retry: { mode: 'immediate-requeue', maxRetries: 3 } // Message dead-lettered after 3 retry attempts
|
|
197
273
|
* });
|
|
198
274
|
* ```
|
|
199
275
|
*/
|
|
@@ -202,88 +278,32 @@ type QuorumQueueOptions = BaseQueueOptions & {
|
|
|
202
278
|
* Queue type: quorum (default, recommended)
|
|
203
279
|
*/
|
|
204
280
|
type?: "quorum";
|
|
281
|
+
/**
|
|
282
|
+
* Quorum queues only support durable queues.
|
|
283
|
+
*/
|
|
284
|
+
durable?: true;
|
|
205
285
|
/**
|
|
206
286
|
* Quorum queues do not support exclusive mode.
|
|
207
287
|
* Use type: 'classic' if you need exclusive queues.
|
|
208
288
|
*/
|
|
209
289
|
exclusive?: never;
|
|
290
|
+
/**
|
|
291
|
+
* Quorum queues do not support auto-delete mode.
|
|
292
|
+
* Use type: 'classic' if you need auto-deleting queues.
|
|
293
|
+
*/
|
|
294
|
+
autoDelete?: never;
|
|
210
295
|
/**
|
|
211
296
|
* Quorum queues do not support priority queues.
|
|
212
297
|
* Use type: 'classic' if you need priority queues.
|
|
213
298
|
*/
|
|
214
299
|
maxPriority?: never;
|
|
215
|
-
/**
|
|
216
|
-
* Maximum number of delivery attempts before the message is dead-lettered.
|
|
217
|
-
*
|
|
218
|
-
* When a message is rejected (nacked) and requeued, RabbitMQ increments
|
|
219
|
-
* the `x-delivery-count` header. When this count reaches the delivery limit,
|
|
220
|
-
* the message is automatically dead-lettered (if DLX is configured) or dropped.
|
|
221
|
-
*
|
|
222
|
-
* This is a quorum queue-specific feature that provides native retry handling
|
|
223
|
-
* without the complexity of TTL-based wait queues.
|
|
224
|
-
*
|
|
225
|
-
* **Benefits over TTL-based retry:**
|
|
226
|
-
* - Simpler architecture (no wait queues needed)
|
|
227
|
-
* - No head-of-queue blocking issues (TTL only works at queue head)
|
|
228
|
-
* - Native RabbitMQ feature with atomic guarantees
|
|
229
|
-
*
|
|
230
|
-
* @minimum 1 - Must be a positive integer (1 or greater)
|
|
231
|
-
*
|
|
232
|
-
* @see https://www.rabbitmq.com/docs/quorum-queues#poison-message-handling
|
|
233
|
-
*
|
|
234
|
-
* @example
|
|
235
|
-
* ```typescript
|
|
236
|
-
* const orderQueue = defineQueue('order-processing', {
|
|
237
|
-
* type: 'quorum',
|
|
238
|
-
* deliveryLimit: 5, // Allow up to 5 delivery attempts
|
|
239
|
-
* deadLetter: {
|
|
240
|
-
* exchange: dlx,
|
|
241
|
-
* routingKey: 'order.failed',
|
|
242
|
-
* },
|
|
243
|
-
* });
|
|
244
|
-
* ```
|
|
245
|
-
*/
|
|
246
|
-
deliveryLimit?: number;
|
|
247
|
-
/**
|
|
248
|
-
* Retry configuration for handling failed message processing.
|
|
249
|
-
*
|
|
250
|
-
* Determines how the worker handles retries for consumers using this queue:
|
|
251
|
-
* - `"ttl-backoff"` (default): Uses wait queues with exponential backoff
|
|
252
|
-
* - `"quorum-native"`: Uses RabbitMQ's native delivery limit feature
|
|
253
|
-
*
|
|
254
|
-
* When using `"ttl-backoff"` mode, the core package will automatically create
|
|
255
|
-
* a wait queue (`{queueName}-wait`) and the necessary bindings.
|
|
256
|
-
*
|
|
257
|
-
* @example
|
|
258
|
-
* ```typescript
|
|
259
|
-
* // TTL-backoff mode with custom options
|
|
260
|
-
* const orderQueue = defineQueue('order-processing', {
|
|
261
|
-
* type: 'quorum',
|
|
262
|
-
* deadLetter: { exchange: dlx },
|
|
263
|
-
* retry: {
|
|
264
|
-
* mode: 'ttl-backoff',
|
|
265
|
-
* maxRetries: 5,
|
|
266
|
-
* initialDelayMs: 1000,
|
|
267
|
-
* maxDelayMs: 30000,
|
|
268
|
-
* },
|
|
269
|
-
* });
|
|
270
|
-
*
|
|
271
|
-
* // Quorum-native mode
|
|
272
|
-
* const orderQueue = defineQueue('order-processing', {
|
|
273
|
-
* type: 'quorum',
|
|
274
|
-
* deliveryLimit: 5,
|
|
275
|
-
* deadLetter: { exchange: dlx },
|
|
276
|
-
* retry: { mode: 'quorum-native' },
|
|
277
|
-
* });
|
|
278
|
-
* ```
|
|
279
|
-
*/
|
|
280
|
-
retry?: TtlBackoffRetryOptions | QuorumNativeRetryOptions;
|
|
281
300
|
};
|
|
282
301
|
/**
|
|
283
302
|
* Options for creating a classic queue.
|
|
284
303
|
*
|
|
285
304
|
* Classic queues support all traditional RabbitMQ features including:
|
|
286
|
-
* - `exclusive
|
|
305
|
+
* - `exclusive` - For connection-scoped queues
|
|
306
|
+
* - `autoDelete` - For auto-deleting queues when consumers disconnect
|
|
287
307
|
* - `maxPriority` - For priority queues
|
|
288
308
|
* - `durable: false` - For non-durable queues
|
|
289
309
|
*
|
|
@@ -291,7 +311,6 @@ type QuorumQueueOptions = BaseQueueOptions & {
|
|
|
291
311
|
* ```typescript
|
|
292
312
|
* const priorityQueue = defineQueue('tasks', {
|
|
293
313
|
* type: 'classic',
|
|
294
|
-
* durable: true,
|
|
295
314
|
* maxPriority: 10,
|
|
296
315
|
* });
|
|
297
316
|
* ```
|
|
@@ -301,48 +320,42 @@ type ClassicQueueOptions = BaseQueueOptions & {
|
|
|
301
320
|
* Queue type: classic (for special cases)
|
|
302
321
|
*/
|
|
303
322
|
type: "classic";
|
|
323
|
+
/**
|
|
324
|
+
* If true, the queue survives broker restarts. Durable queues are persisted to disk.
|
|
325
|
+
* @default true
|
|
326
|
+
*/
|
|
327
|
+
durable?: boolean;
|
|
304
328
|
/**
|
|
305
329
|
* If true, the queue can only be used by the declaring connection and is deleted when
|
|
306
330
|
* that connection closes. Exclusive queues are private to the connection.
|
|
307
|
-
* @default false
|
|
308
331
|
*/
|
|
309
332
|
exclusive?: boolean;
|
|
333
|
+
/**
|
|
334
|
+
* If true, the queue is deleted when the last consumer unsubscribes.
|
|
335
|
+
*/
|
|
336
|
+
autoDelete?: boolean;
|
|
310
337
|
/**
|
|
311
338
|
* Maximum priority level for priority queue (1-255, recommended: 1-10).
|
|
312
339
|
* Sets x-max-priority argument.
|
|
313
|
-
* Only supported with classic queues.
|
|
314
340
|
*/
|
|
315
341
|
maxPriority?: number;
|
|
316
|
-
/**
|
|
317
|
-
* Retry configuration for handling failed message processing.
|
|
318
|
-
*
|
|
319
|
-
* Classic queues only support TTL-backoff retry mode, which uses wait queues
|
|
320
|
-
* with exponential backoff. For quorum-native retry, use quorum queues instead.
|
|
321
|
-
*
|
|
322
|
-
* @example
|
|
323
|
-
* ```typescript
|
|
324
|
-
* const orderQueue = defineQueue('order-processing', {
|
|
325
|
-
* type: 'classic',
|
|
326
|
-
* durable: true,
|
|
327
|
-
* deadLetter: { exchange: dlx },
|
|
328
|
-
* retry: {
|
|
329
|
-
* maxRetries: 5,
|
|
330
|
-
* initialDelayMs: 1000,
|
|
331
|
-
* maxDelayMs: 30000,
|
|
332
|
-
* },
|
|
333
|
-
* });
|
|
334
|
-
* ```
|
|
335
|
-
*/
|
|
336
|
-
retry?: TtlBackoffRetryOptions;
|
|
337
342
|
};
|
|
338
343
|
/**
|
|
339
344
|
* Options for defining a queue. Uses a discriminated union based on the `type` property
|
|
340
345
|
* to enforce quorum queue constraints at compile time.
|
|
341
346
|
*
|
|
342
|
-
* - Quorum queues (default): Do not support `exclusive` or `maxPriority`
|
|
343
|
-
* - Classic queues: Support all options including `exclusive` and `maxPriority`
|
|
347
|
+
* - Quorum queues (default): Do not support `exclusive`, `autoDelete`, or `maxPriority`
|
|
348
|
+
* - Classic queues: Support all options including `exclusive`, `autoDelete`, and `maxPriority`
|
|
344
349
|
*/
|
|
345
350
|
type DefineQueueOptions = QuorumQueueOptions | ClassicQueueOptions;
|
|
351
|
+
/**
|
|
352
|
+
* Options for defining a queue with a dead letter exchange.
|
|
353
|
+
*/
|
|
354
|
+
type DefineQueueOptionsWithDeadLetterExchange<TDlx extends ExchangeDefinition = ExchangeDefinition> = DefineQueueOptions & {
|
|
355
|
+
deadLetter: {
|
|
356
|
+
exchange: TDlx;
|
|
357
|
+
};
|
|
358
|
+
};
|
|
346
359
|
/**
|
|
347
360
|
* Base definition of an AMQP exchange.
|
|
348
361
|
*
|
|
@@ -356,18 +369,16 @@ type BaseExchangeDefinition<TName extends string = string> = {
|
|
|
356
369
|
name: TName;
|
|
357
370
|
/**
|
|
358
371
|
* If true, the exchange survives broker restarts. Durable exchanges are persisted to disk.
|
|
359
|
-
* @default
|
|
372
|
+
* @default true
|
|
360
373
|
*/
|
|
361
374
|
durable?: boolean;
|
|
362
375
|
/**
|
|
363
376
|
* If true, the exchange is deleted when all queues have finished using it.
|
|
364
|
-
* @default false
|
|
365
377
|
*/
|
|
366
378
|
autoDelete?: boolean;
|
|
367
379
|
/**
|
|
368
380
|
* If true, the exchange cannot be directly published to by clients.
|
|
369
381
|
* It can only receive messages from other exchanges via exchange-to-exchange bindings.
|
|
370
|
-
* @default false
|
|
371
382
|
*/
|
|
372
383
|
internal?: boolean;
|
|
373
384
|
/**
|
|
@@ -377,20 +388,24 @@ type BaseExchangeDefinition<TName extends string = string> = {
|
|
|
377
388
|
arguments?: Record<string, unknown>;
|
|
378
389
|
};
|
|
379
390
|
/**
|
|
380
|
-
* A
|
|
391
|
+
* A topic exchange definition.
|
|
381
392
|
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
393
|
+
* Topic exchanges route messages to queues based on routing key patterns with wildcards:
|
|
394
|
+
* - `*` (star) matches exactly one word
|
|
395
|
+
* - `#` (hash) matches zero or more words
|
|
396
|
+
*
|
|
397
|
+
* Words are separated by dots (e.g., `order.created.high-value`).
|
|
384
398
|
*
|
|
385
399
|
* @example
|
|
386
400
|
* ```typescript
|
|
387
|
-
* const
|
|
388
|
-
*
|
|
401
|
+
* const ordersExchange: TopicExchangeDefinition = defineExchange('orders', {
|
|
402
|
+
* type: 'topic', // This is the default type, so it can be omitted
|
|
389
403
|
* });
|
|
404
|
+
* // Can be bound with patterns like 'order.*' or 'order.#'
|
|
390
405
|
* ```
|
|
391
406
|
*/
|
|
392
|
-
type
|
|
393
|
-
type: "
|
|
407
|
+
type TopicExchangeDefinition<TName extends string = string> = BaseExchangeDefinition<TName> & {
|
|
408
|
+
type: "topic";
|
|
394
409
|
};
|
|
395
410
|
/**
|
|
396
411
|
* A direct exchange definition.
|
|
@@ -400,8 +415,8 @@ type FanoutExchangeDefinition<TName extends string = string> = BaseExchangeDefin
|
|
|
400
415
|
*
|
|
401
416
|
* @example
|
|
402
417
|
* ```typescript
|
|
403
|
-
* const tasksExchange: DirectExchangeDefinition = defineExchange('tasks',
|
|
404
|
-
*
|
|
418
|
+
* const tasksExchange: DirectExchangeDefinition = defineExchange('tasks', {
|
|
419
|
+
* type: 'direct',
|
|
405
420
|
* });
|
|
406
421
|
* ```
|
|
407
422
|
*/
|
|
@@ -409,31 +424,43 @@ type DirectExchangeDefinition<TName extends string = string> = BaseExchangeDefin
|
|
|
409
424
|
type: "direct";
|
|
410
425
|
};
|
|
411
426
|
/**
|
|
412
|
-
* A
|
|
427
|
+
* A fanout exchange definition.
|
|
413
428
|
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
* - `#` (hash) matches zero or more words
|
|
429
|
+
* Fanout exchanges broadcast all messages to all bound queues, ignoring routing keys.
|
|
430
|
+
* This is the simplest exchange type for pub/sub messaging patterns.
|
|
417
431
|
*
|
|
418
|
-
*
|
|
432
|
+
* @example
|
|
433
|
+
* ```typescript
|
|
434
|
+
* const logsExchange: FanoutExchangeDefinition = defineExchange('logs', {
|
|
435
|
+
* type: 'fanout',
|
|
436
|
+
* });
|
|
437
|
+
* ```
|
|
438
|
+
*/
|
|
439
|
+
type FanoutExchangeDefinition<TName extends string = string> = BaseExchangeDefinition<TName> & {
|
|
440
|
+
type: "fanout";
|
|
441
|
+
};
|
|
442
|
+
/**
|
|
443
|
+
* A headers exchange definition.
|
|
444
|
+
*
|
|
445
|
+
* Headers exchanges route messages based on header values rather than routing keys.
|
|
446
|
+
* This is useful for more complex routing scenarios where metadata is important.
|
|
419
447
|
*
|
|
420
448
|
* @example
|
|
421
449
|
* ```typescript
|
|
422
|
-
* const
|
|
423
|
-
*
|
|
450
|
+
* const routesExchange: HeadersExchangeDefinition = defineExchange('routes', {
|
|
451
|
+
* type: 'headers',
|
|
424
452
|
* });
|
|
425
|
-
* // Can be bound with patterns like 'order.*' or 'order.#'
|
|
426
453
|
* ```
|
|
427
454
|
*/
|
|
428
|
-
type
|
|
429
|
-
type: "
|
|
455
|
+
type HeadersExchangeDefinition<TName extends string = string> = BaseExchangeDefinition<TName> & {
|
|
456
|
+
type: "headers";
|
|
430
457
|
};
|
|
431
458
|
/**
|
|
432
459
|
* Union type of all exchange definitions.
|
|
433
460
|
*
|
|
434
|
-
* Represents any type of AMQP exchange:
|
|
461
|
+
* Represents any type of AMQP exchange: topic, direct, fanout, headers.
|
|
435
462
|
*/
|
|
436
|
-
type ExchangeDefinition<TName extends string = string> =
|
|
463
|
+
type ExchangeDefinition<TName extends string = string> = TopicExchangeDefinition<TName> | DirectExchangeDefinition<TName> | FanoutExchangeDefinition<TName> | HeadersExchangeDefinition<TName>;
|
|
437
464
|
/**
|
|
438
465
|
* Configuration for dead letter exchange (DLX) on a queue.
|
|
439
466
|
*
|
|
@@ -461,17 +488,6 @@ type BaseQueueDefinition<TName extends string = string> = {
|
|
|
461
488
|
* The name of the queue. Must be unique within the RabbitMQ virtual host.
|
|
462
489
|
*/
|
|
463
490
|
name: TName;
|
|
464
|
-
/**
|
|
465
|
-
* If true, the queue survives broker restarts. Durable queues are persisted to disk.
|
|
466
|
-
* Note: Quorum queues are always durable regardless of this setting.
|
|
467
|
-
* @default false (but forced to true for quorum queues during setup)
|
|
468
|
-
*/
|
|
469
|
-
durable?: boolean;
|
|
470
|
-
/**
|
|
471
|
-
* If true, the queue is deleted when the last consumer unsubscribes.
|
|
472
|
-
* @default false
|
|
473
|
-
*/
|
|
474
|
-
autoDelete?: boolean;
|
|
475
491
|
/**
|
|
476
492
|
* Dead letter configuration for handling failed or rejected messages.
|
|
477
493
|
*
|
|
@@ -479,6 +495,11 @@ type BaseQueueDefinition<TName extends string = string> = {
|
|
|
479
495
|
* will be automatically forwarded to the specified dead letter exchange.
|
|
480
496
|
*/
|
|
481
497
|
deadLetter?: DeadLetterConfig;
|
|
498
|
+
/**
|
|
499
|
+
* Retry configuration for handling failed message processing.
|
|
500
|
+
* When the queue is created, defaults are applied.
|
|
501
|
+
*/
|
|
502
|
+
retry: ResolvedRetryOptions;
|
|
482
503
|
/**
|
|
483
504
|
* Additional AMQP arguments for advanced configuration.
|
|
484
505
|
*
|
|
@@ -494,52 +515,37 @@ type BaseQueueDefinition<TName extends string = string> = {
|
|
|
494
515
|
* Definition of a quorum queue.
|
|
495
516
|
*
|
|
496
517
|
* Quorum queues provide better durability and high-availability using the Raft consensus algorithm.
|
|
497
|
-
* They support native retry handling via `deliveryLimit` and both TTL-backoff and quorum-native retry modes.
|
|
498
518
|
*/
|
|
499
519
|
type QuorumQueueDefinition<TName extends string = string> = BaseQueueDefinition<TName> & {
|
|
500
520
|
/**
|
|
501
521
|
* Queue type discriminator: quorum queue.
|
|
502
522
|
*/
|
|
503
523
|
type: "quorum";
|
|
524
|
+
/**
|
|
525
|
+
* Quorum queues only support durable queues.
|
|
526
|
+
*/
|
|
527
|
+
durable: true;
|
|
504
528
|
/**
|
|
505
529
|
* Quorum queues do not support exclusive mode.
|
|
506
530
|
* Use type: 'classic' if you need exclusive queues.
|
|
507
531
|
*/
|
|
508
532
|
exclusive?: never;
|
|
533
|
+
/**
|
|
534
|
+
* Quorum queues do not support auto-delete mode.
|
|
535
|
+
* Use type: 'classic' if you need auto-deleting queues.
|
|
536
|
+
*/
|
|
537
|
+
autoDelete?: never;
|
|
509
538
|
/**
|
|
510
539
|
* Quorum queues do not support priority queues.
|
|
511
540
|
* Use type: 'classic' if you need priority queues.
|
|
512
541
|
*/
|
|
513
542
|
maxPriority?: never;
|
|
514
|
-
/**
|
|
515
|
-
* Maximum number of delivery attempts before the message is dead-lettered.
|
|
516
|
-
*
|
|
517
|
-
* This is a quorum queue-specific feature. When a message is rejected (nacked)
|
|
518
|
-
* and requeued, RabbitMQ increments the `x-delivery-count` header. When this
|
|
519
|
-
* count reaches the delivery limit, the message is automatically dead-lettered
|
|
520
|
-
* (if DLX is configured) or dropped.
|
|
521
|
-
*
|
|
522
|
-
* @minimum 1 - Must be a positive integer (1 or greater)
|
|
523
|
-
*
|
|
524
|
-
* @see https://www.rabbitmq.com/docs/quorum-queues#poison-message-handling
|
|
525
|
-
*/
|
|
526
|
-
deliveryLimit?: number;
|
|
527
|
-
/**
|
|
528
|
-
* Retry configuration for handling failed message processing.
|
|
529
|
-
*
|
|
530
|
-
* Quorum queues support both:
|
|
531
|
-
* - `ttl-backoff`: Uses wait queues with exponential backoff (default)
|
|
532
|
-
* - `quorum-native`: Uses RabbitMQ's native delivery limit feature
|
|
533
|
-
*
|
|
534
|
-
* When the queue is created, defaults are applied for TTL-backoff options.
|
|
535
|
-
*/
|
|
536
|
-
retry: ResolvedRetryOptions;
|
|
537
543
|
};
|
|
538
544
|
/**
|
|
539
545
|
* Definition of a classic queue.
|
|
540
546
|
*
|
|
541
547
|
* Classic queues are the traditional RabbitMQ queue type. Use them when you need
|
|
542
|
-
* specific features not supported by quorum queues (e.g., exclusive queues, priority queues).
|
|
548
|
+
* specific features not supported by quorum queues (e.g., exclusive queues, auto-deleting queues, priority queues).
|
|
543
549
|
*/
|
|
544
550
|
type ClassicQueueDefinition<TName extends string = string> = BaseQueueDefinition<TName> & {
|
|
545
551
|
/**
|
|
@@ -547,23 +553,23 @@ type ClassicQueueDefinition<TName extends string = string> = BaseQueueDefinition
|
|
|
547
553
|
*/
|
|
548
554
|
type: "classic";
|
|
549
555
|
/**
|
|
550
|
-
*
|
|
551
|
-
* Use type: 'quorum' if you need native retry with delivery limits.
|
|
556
|
+
* If true, the queue survives broker restarts. Durable queues are persisted to disk.
|
|
552
557
|
*/
|
|
553
|
-
|
|
558
|
+
durable: boolean;
|
|
554
559
|
/**
|
|
555
560
|
* If true, the queue can only be used by the declaring connection and is deleted when
|
|
556
561
|
* that connection closes. Exclusive queues are private to the connection.
|
|
557
|
-
* @default false
|
|
558
562
|
*/
|
|
559
563
|
exclusive?: boolean;
|
|
560
564
|
/**
|
|
561
|
-
*
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
+
* If true, the queue is deleted when the last consumer unsubscribes.
|
|
566
|
+
*/
|
|
567
|
+
autoDelete?: boolean;
|
|
568
|
+
/**
|
|
569
|
+
* Maximum priority level for priority queue (1-255, recommended: 1-10).
|
|
570
|
+
* Sets x-max-priority argument.
|
|
565
571
|
*/
|
|
566
|
-
|
|
572
|
+
maxPriority?: number;
|
|
567
573
|
};
|
|
568
574
|
/**
|
|
569
575
|
* Definition of an AMQP queue.
|
|
@@ -578,26 +584,24 @@ type QueueDefinition<TName extends string = string> = QuorumQueueDefinition<TNam
|
|
|
578
584
|
/**
|
|
579
585
|
* A queue with automatically generated TTL-backoff retry infrastructure.
|
|
580
586
|
*
|
|
581
|
-
* This type is returned by `defineQueue` when TTL-backoff retry is configured
|
|
582
|
-
*
|
|
583
|
-
*
|
|
587
|
+
* This type is returned by `defineQueue` when TTL-backoff retry is configured.
|
|
588
|
+
* When passed to `defineContract`, the wait queue, exchanges, and bindings are
|
|
589
|
+
* automatically added to the contract.
|
|
584
590
|
*
|
|
585
591
|
* @example
|
|
586
592
|
* ```typescript
|
|
587
|
-
* const
|
|
588
|
-
* const exchange = defineExchange('orders', 'topic', { durable: true });
|
|
593
|
+
* const exchange = defineExchange('orders');
|
|
589
594
|
* const queue = defineQueue('order-processing', {
|
|
590
|
-
* deadLetter: { exchange: dlx },
|
|
591
595
|
* retry: { mode: 'ttl-backoff', maxRetries: 5 },
|
|
592
596
|
* });
|
|
593
597
|
* // queue is QueueWithTtlBackoffInfrastructure
|
|
594
598
|
* const message = defineMessage(z.object({ orderId: z.string() }));
|
|
595
599
|
* const orderCreated = defineEventPublisher(exchange, message, { routingKey: 'order.created' });
|
|
596
600
|
*
|
|
597
|
-
* // Wait queue,
|
|
601
|
+
* // Wait queue, exchanges, and bindings are automatically extracted
|
|
598
602
|
* const contract = defineContract({
|
|
599
603
|
* publishers: { orderCreated },
|
|
600
|
-
* consumers: { processOrder: defineEventConsumer(orderCreated,
|
|
604
|
+
* consumers: { processOrder: defineEventConsumer(orderCreated, queue) },
|
|
601
605
|
* });
|
|
602
606
|
* ```
|
|
603
607
|
*/
|
|
@@ -611,23 +615,26 @@ type QueueWithTtlBackoffInfrastructure<TName extends string = string> = {
|
|
|
611
615
|
* The main queue definition.
|
|
612
616
|
*/
|
|
613
617
|
queue: QueueDefinition<TName>;
|
|
614
|
-
/**
|
|
615
|
-
* Dead letter configuration from the main queue.
|
|
616
|
-
* Always present since TTL-backoff infrastructure requires a dead letter exchange.
|
|
617
|
-
*/
|
|
618
|
-
deadLetter: DeadLetterConfig;
|
|
619
618
|
/**
|
|
620
619
|
* The wait queue for holding messages during backoff delay.
|
|
621
620
|
*/
|
|
622
621
|
waitQueue: QueueDefinition;
|
|
622
|
+
/**
|
|
623
|
+
* Wait exchange used to route failed messages to the wait queue.
|
|
624
|
+
*/
|
|
625
|
+
waitExchange: HeadersExchangeDefinition;
|
|
626
|
+
/**
|
|
627
|
+
* Retry exchange used to route messages to retry back to the main queue.
|
|
628
|
+
*/
|
|
629
|
+
retryExchange: HeadersExchangeDefinition;
|
|
623
630
|
/**
|
|
624
631
|
* Binding that routes failed messages to the wait queue.
|
|
625
632
|
*/
|
|
626
633
|
waitQueueBinding: QueueBindingDefinition;
|
|
627
634
|
/**
|
|
628
|
-
* Binding that routes
|
|
635
|
+
* Binding that routes messages to retry back to the main queue.
|
|
629
636
|
*/
|
|
630
|
-
|
|
637
|
+
retryQueueBinding: QueueBindingDefinition;
|
|
631
638
|
};
|
|
632
639
|
/**
|
|
633
640
|
* A queue entry that can be passed to `defineContract`.
|
|
@@ -635,6 +642,14 @@ type QueueWithTtlBackoffInfrastructure<TName extends string = string> = {
|
|
|
635
642
|
* Can be either a plain queue definition or a queue with TTL-backoff infrastructure.
|
|
636
643
|
*/
|
|
637
644
|
type QueueEntry<TName extends string = string> = QueueDefinition<TName> | QueueWithTtlBackoffInfrastructure<TName>;
|
|
645
|
+
/**
|
|
646
|
+
* A queue entry with a dead letter exchange.
|
|
647
|
+
*/
|
|
648
|
+
type QueueEntryWithDeadLetterExchange<TName extends string = string, TDlx extends ExchangeDefinition = ExchangeDefinition> = QueueEntry<TName> & {
|
|
649
|
+
deadLetter: {
|
|
650
|
+
exchange: TDlx;
|
|
651
|
+
};
|
|
652
|
+
};
|
|
638
653
|
/**
|
|
639
654
|
* Definition of a message with typed payload and optional headers.
|
|
640
655
|
*
|
|
@@ -668,7 +683,7 @@ type MessageDefinition<TPayload extends AnySchema = AnySchema, THeaders extends
|
|
|
668
683
|
*
|
|
669
684
|
* Defines how messages from an exchange should be routed to a queue.
|
|
670
685
|
* For direct and topic exchanges, a routing key is required.
|
|
671
|
-
* For fanout exchanges, no routing key is needed
|
|
686
|
+
* For fanout and headers exchanges, no routing key is needed.
|
|
672
687
|
*/
|
|
673
688
|
type QueueBindingDefinition = {
|
|
674
689
|
/** Discriminator indicating this is a queue-to-exchange binding */type: "queue"; /** The queue that will receive messages */
|
|
@@ -687,7 +702,7 @@ type QueueBindingDefinition = {
|
|
|
687
702
|
*/
|
|
688
703
|
routingKey: string;
|
|
689
704
|
} | {
|
|
690
|
-
/** Fanout exchange (no routing key needed) */exchange: FanoutExchangeDefinition; /** Fanout exchanges don't use routing keys */
|
|
705
|
+
/** Fanout or headers exchange (no routing key needed) */exchange: FanoutExchangeDefinition | HeadersExchangeDefinition; /** Fanout and headers exchanges don't use routing keys */
|
|
691
706
|
routingKey?: never;
|
|
692
707
|
});
|
|
693
708
|
/**
|
|
@@ -722,7 +737,7 @@ type ExchangeBindingDefinition = {
|
|
|
722
737
|
*/
|
|
723
738
|
routingKey: string;
|
|
724
739
|
} | {
|
|
725
|
-
/** Fanout source exchange (no routing key needed) */source: FanoutExchangeDefinition; /** Fanout exchanges don't use routing keys */
|
|
740
|
+
/** Fanout or headers source exchange (no routing key needed) */source: FanoutExchangeDefinition | HeadersExchangeDefinition; /** Fanout and headers exchanges don't use routing keys */
|
|
726
741
|
routingKey?: never;
|
|
727
742
|
});
|
|
728
743
|
/**
|
|
@@ -763,7 +778,7 @@ type PublisherDefinition<TMessage extends MessageDefinition = MessageDefinition>
|
|
|
763
778
|
*/
|
|
764
779
|
routingKey: string;
|
|
765
780
|
} | {
|
|
766
|
-
/** Fanout exchange (no routing key needed) */exchange: FanoutExchangeDefinition; /** Fanout exchanges don't use routing keys
|
|
781
|
+
/** Fanout or headers exchange (no routing key needed) */exchange: FanoutExchangeDefinition | HeadersExchangeDefinition; /** Fanout and headers exchanges don't use routing keys */
|
|
767
782
|
routingKey?: never;
|
|
768
783
|
});
|
|
769
784
|
/**
|
|
@@ -785,7 +800,7 @@ type PublisherDefinition<TMessage extends MessageDefinition = MessageDefinition>
|
|
|
785
800
|
* ```
|
|
786
801
|
*/
|
|
787
802
|
type ConsumerDefinition<TMessage extends MessageDefinition = MessageDefinition> = {
|
|
788
|
-
/** The queue to consume messages from */queue:
|
|
803
|
+
/** The queue to consume messages from */queue: QueueEntry; /** The message definition including the payload schema */
|
|
789
804
|
message: TMessage;
|
|
790
805
|
};
|
|
791
806
|
/**
|
|
@@ -816,8 +831,7 @@ type CommandConsumerConfigBase = {
|
|
|
816
831
|
consumer: ConsumerDefinition;
|
|
817
832
|
binding: QueueBindingDefinition;
|
|
818
833
|
exchange: ExchangeDefinition;
|
|
819
|
-
queue:
|
|
820
|
-
deadLetterExchange: ExchangeDefinition | undefined;
|
|
834
|
+
queue: QueueEntry;
|
|
821
835
|
message: MessageDefinition;
|
|
822
836
|
routingKey: string | undefined;
|
|
823
837
|
};
|
|
@@ -834,8 +848,7 @@ type EventConsumerResultBase = {
|
|
|
834
848
|
consumer: ConsumerDefinition;
|
|
835
849
|
binding: QueueBindingDefinition;
|
|
836
850
|
exchange: ExchangeDefinition;
|
|
837
|
-
queue:
|
|
838
|
-
deadLetterExchange: ExchangeDefinition | undefined;
|
|
851
|
+
queue: QueueEntry;
|
|
839
852
|
exchangeBinding: ExchangeBindingDefinition | undefined;
|
|
840
853
|
bridgeExchange: ExchangeDefinition | undefined;
|
|
841
854
|
};
|
|
@@ -854,6 +867,26 @@ type BridgedPublisherConfigBase = {
|
|
|
854
867
|
bridgeExchange: ExchangeDefinition;
|
|
855
868
|
targetExchange: ExchangeDefinition;
|
|
856
869
|
};
|
|
870
|
+
/**
|
|
871
|
+
* Definition of an RPC operation: a request/response pair flowing over a
|
|
872
|
+
* request queue with replies routed back via direct reply-to.
|
|
873
|
+
*
|
|
874
|
+
* An RPC is bidirectional on both ends — the server consumes requests and
|
|
875
|
+
* publishes responses; the client publishes requests and consumes responses —
|
|
876
|
+
* so it has its own slot in the contract (`rpcs`) rather than being shoehorned
|
|
877
|
+
* into `consumers` or `publishers`.
|
|
878
|
+
*
|
|
879
|
+
* @template TRequestMessage - The request message definition
|
|
880
|
+
* @template TResponseMessage - The response message definition
|
|
881
|
+
* @template TQueue - The request queue entry
|
|
882
|
+
*
|
|
883
|
+
* @see defineRpc for creating RPC definitions
|
|
884
|
+
*/
|
|
885
|
+
type RpcDefinition<TRequestMessage extends MessageDefinition = MessageDefinition, TResponseMessage extends MessageDefinition = MessageDefinition, TQueue extends QueueEntry = QueueEntry> = {
|
|
886
|
+
/** The queue that receives RPC requests. Replies are routed back via direct reply-to. */queue: TQueue; /** Schema for the request payload (validated on both publish and consume). */
|
|
887
|
+
request: TRequestMessage; /** Schema for the response payload (validated on both worker reply and client receive). */
|
|
888
|
+
response: TResponseMessage;
|
|
889
|
+
};
|
|
857
890
|
/**
|
|
858
891
|
* Complete AMQP contract definition (output type).
|
|
859
892
|
*
|
|
@@ -898,7 +931,7 @@ type ContractDefinition = {
|
|
|
898
931
|
* Each key becomes available as a named resource in the contract.
|
|
899
932
|
*
|
|
900
933
|
* When a queue has TTL-backoff retry configured, pass the `QueueWithTtlBackoffInfrastructure`
|
|
901
|
-
* object returned by `defineQueue`. The wait queue and bindings will be automatically added.
|
|
934
|
+
* object returned by `defineQueue`. The wait queue, exchanges, and bindings will be automatically added.
|
|
902
935
|
*/
|
|
903
936
|
queues?: Record<string, QueueEntry>;
|
|
904
937
|
/**
|
|
@@ -918,6 +951,16 @@ type ContractDefinition = {
|
|
|
918
951
|
* The handler will be fully typed based on the message schema.
|
|
919
952
|
*/
|
|
920
953
|
consumers?: Record<string, ConsumerDefinition>;
|
|
954
|
+
/**
|
|
955
|
+
* Named RPC definitions. Each key gets:
|
|
956
|
+
* - A handler in the TypedAmqpWorker that returns the typed response.
|
|
957
|
+
* - A `client.call(name, request, options)` method on the TypedAmqpClient.
|
|
958
|
+
*
|
|
959
|
+
* RPC entries do not appear in `publishers` or `consumers` because each
|
|
960
|
+
* end of an RPC plays both roles (publisher of one direction, consumer of
|
|
961
|
+
* the other).
|
|
962
|
+
*/
|
|
963
|
+
rpcs?: Record<string, RpcDefinition>;
|
|
921
964
|
};
|
|
922
965
|
/**
|
|
923
966
|
* Publisher entry that can be passed to defineContract's publishers section.
|
|
@@ -925,6 +968,7 @@ type ContractDefinition = {
|
|
|
925
968
|
* Can be either:
|
|
926
969
|
* - A plain PublisherDefinition from definePublisher
|
|
927
970
|
* - An EventPublisherConfig from defineEventPublisher (auto-extracted to publisher)
|
|
971
|
+
* - An BridgedPublisherConfig from defineCommandPublisher (auto-extracted to publisher)
|
|
928
972
|
*/
|
|
929
973
|
type PublisherEntry = PublisherDefinition | EventPublisherConfigBase | BridgedPublisherConfigBase;
|
|
930
974
|
/**
|
|
@@ -978,6 +1022,12 @@ type ContractDefinitionInput = {
|
|
|
978
1022
|
* - CommandConsumerConfig from defineCommandConsumer (binding auto-extracted)
|
|
979
1023
|
*/
|
|
980
1024
|
consumers?: Record<string, ConsumerEntry>;
|
|
1025
|
+
/**
|
|
1026
|
+
* Named RPC definitions from `defineRpc`. Each entry contributes its queue
|
|
1027
|
+
* (and DLX if any) to the contract topology and exposes a typed
|
|
1028
|
+
* `client.call(name, ...)` / worker handler pair.
|
|
1029
|
+
*/
|
|
1030
|
+
rpcs?: Record<string, RpcDefinition>;
|
|
981
1031
|
};
|
|
982
1032
|
/**
|
|
983
1033
|
* Extract the exchange from a publisher entry.
|
|
@@ -1005,7 +1055,7 @@ type ExtractDlxFromEntry<T extends QueueEntry> = T extends {
|
|
|
1005
1055
|
deadLetter: {
|
|
1006
1056
|
exchange: infer E extends ExchangeDefinition;
|
|
1007
1057
|
};
|
|
1008
|
-
} ? E :
|
|
1058
|
+
} ? E : never : never;
|
|
1009
1059
|
/**
|
|
1010
1060
|
* Extract the queue from a consumer entry.
|
|
1011
1061
|
* @internal
|
|
@@ -1040,11 +1090,7 @@ type ExtractExchangesFromConsumers<TConsumers extends Record<string, ConsumerEnt
|
|
|
1040
1090
|
* Extract the dead letter exchange from a consumer entry.
|
|
1041
1091
|
* @internal
|
|
1042
1092
|
*/
|
|
1043
|
-
type ExtractDeadLetterExchange<T extends ConsumerEntry> = T
|
|
1044
|
-
deadLetter: {
|
|
1045
|
-
exchange: infer E extends ExchangeDefinition;
|
|
1046
|
-
};
|
|
1047
|
-
} ? E : never : never;
|
|
1093
|
+
type ExtractDeadLetterExchange<T extends ConsumerEntry> = ExtractDlxFromEntry<T["queue"]>;
|
|
1048
1094
|
/**
|
|
1049
1095
|
* Extract dead letter exchanges from all consumers in a contract.
|
|
1050
1096
|
* @internal
|
|
@@ -1054,7 +1100,7 @@ type ExtractDeadLetterExchangesFromConsumers<TConsumers extends Record<string, C
|
|
|
1054
1100
|
* Extract queues from all consumers in a contract.
|
|
1055
1101
|
* @internal
|
|
1056
1102
|
*/
|
|
1057
|
-
type ExtractQueuesFromConsumers<TConsumers extends Record<string, ConsumerEntry>> = { [K in keyof TConsumers as ExtractConsumerQueue<TConsumers[K]
|
|
1103
|
+
type ExtractQueuesFromConsumers<TConsumers extends Record<string, ConsumerEntry>> = { [K in keyof TConsumers as ExtractQueueFromEntry<ExtractConsumerQueue<TConsumers[K]>>["name"]]: ExtractConsumerQueue<TConsumers[K]> };
|
|
1058
1104
|
/**
|
|
1059
1105
|
* Extract bindings from all consumers in a contract.
|
|
1060
1106
|
* @internal
|
|
@@ -1074,12 +1120,12 @@ type ExtractConsumerDefinitions<TConsumers extends Record<string, ConsumerEntry>
|
|
|
1074
1120
|
* Extract the publisher definition from a publisher entry.
|
|
1075
1121
|
* @internal
|
|
1076
1122
|
*/
|
|
1077
|
-
type ExtractPublisherDefinition<T extends PublisherEntry> = T extends BridgedPublisherConfigBase ? T["publisher"] : T extends EventPublisherConfigBase ? PublisherDefinition<T["message"]> & (T["exchange"] extends
|
|
1123
|
+
type ExtractPublisherDefinition<T extends PublisherEntry> = T extends BridgedPublisherConfigBase ? T["publisher"] : T extends EventPublisherConfigBase ? PublisherDefinition<T["message"]> & (T["exchange"] extends DirectExchangeDefinition | TopicExchangeDefinition ? {
|
|
1078
1124
|
exchange: T["exchange"];
|
|
1079
|
-
routingKey
|
|
1125
|
+
routingKey: T["routingKey"] & string;
|
|
1080
1126
|
} : {
|
|
1081
1127
|
exchange: T["exchange"];
|
|
1082
|
-
routingKey
|
|
1128
|
+
routingKey?: never;
|
|
1083
1129
|
}) : T extends PublisherDefinition ? T : never;
|
|
1084
1130
|
/**
|
|
1085
1131
|
* Extract publisher definitions from all publishers in a contract.
|
|
@@ -1136,6 +1182,16 @@ type ExtractPublisherExchangeBinding<T extends PublisherEntry> = T extends Bridg
|
|
|
1136
1182
|
* @internal
|
|
1137
1183
|
*/
|
|
1138
1184
|
type ExtractExchangeBindingsFromPublishers<TPublishers extends Record<string, PublisherEntry>> = { [K in keyof TPublishers as HasPublisherExchangeBinding<TPublishers[K]> extends true ? `${K & string}ExchangeBinding` : never]: ExtractPublisherExchangeBinding<TPublishers[K]> };
|
|
1185
|
+
/**
|
|
1186
|
+
* Extract queues from all RPC entries in a contract.
|
|
1187
|
+
* @internal
|
|
1188
|
+
*/
|
|
1189
|
+
type ExtractQueuesFromRpcs<TRpcs extends Record<string, RpcDefinition>> = { [K in keyof TRpcs as ExtractQueueFromEntry<TRpcs[K]["queue"]>["name"]]: TRpcs[K]["queue"] };
|
|
1190
|
+
/**
|
|
1191
|
+
* Extract dead letter exchanges from all RPC entries in a contract.
|
|
1192
|
+
* @internal
|
|
1193
|
+
*/
|
|
1194
|
+
type ExtractDeadLetterExchangesFromRpcs<TRpcs extends Record<string, RpcDefinition>> = { [K in keyof TRpcs as ExtractDlxFromEntry<TRpcs[K]["queue"]> extends never ? never : ExtractDlxFromEntry<TRpcs[K]["queue"]>["name"]]: ExtractDlxFromEntry<TRpcs[K]["queue"]> };
|
|
1139
1195
|
/**
|
|
1140
1196
|
* Contract output type with all resources extracted and properly typed.
|
|
1141
1197
|
*
|
|
@@ -1147,11 +1203,12 @@ type ExtractExchangeBindingsFromPublishers<TPublishers extends Record<string, Pu
|
|
|
1147
1203
|
* - consumers: Normalized consumer definitions
|
|
1148
1204
|
*/
|
|
1149
1205
|
type ContractOutput<TContract extends ContractDefinitionInput> = {
|
|
1150
|
-
exchanges: (TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractExchangesFromPublishers<TContract["publishers"]> : {}) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractExchangesFromConsumers<TContract["consumers"]> : {}) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractDeadLetterExchangesFromConsumers<TContract["consumers"]> : {}) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractBridgeExchangesFromConsumers<TContract["consumers"]> : {}) & (TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractTargetExchangesFromPublishers<TContract["publishers"]> : {});
|
|
1151
|
-
queues: TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractQueuesFromConsumers<TContract["consumers"]> : {};
|
|
1206
|
+
exchanges: (TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractExchangesFromPublishers<TContract["publishers"]> : {}) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractExchangesFromConsumers<TContract["consumers"]> : {}) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractDeadLetterExchangesFromConsumers<TContract["consumers"]> : {}) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractBridgeExchangesFromConsumers<TContract["consumers"]> : {}) & (TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractTargetExchangesFromPublishers<TContract["publishers"]> : {}) & (TContract["rpcs"] extends Record<string, RpcDefinition> ? ExtractDeadLetterExchangesFromRpcs<TContract["rpcs"]> : {});
|
|
1207
|
+
queues: (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractQueuesFromConsumers<TContract["consumers"]> : {}) & (TContract["rpcs"] extends Record<string, RpcDefinition> ? ExtractQueuesFromRpcs<TContract["rpcs"]> : {});
|
|
1152
1208
|
bindings: (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractBindingsFromConsumers<TContract["consumers"]> : {}) & (TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractExchangeBindingsFromConsumers<TContract["consumers"]> : {}) & (TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractExchangeBindingsFromPublishers<TContract["publishers"]> : {});
|
|
1153
1209
|
publishers: TContract["publishers"] extends Record<string, PublisherEntry> ? ExtractPublisherDefinitions<TContract["publishers"]> : {};
|
|
1154
1210
|
consumers: TContract["consumers"] extends Record<string, ConsumerEntry> ? ExtractConsumerDefinitions<TContract["consumers"]> : {};
|
|
1211
|
+
rpcs: TContract["rpcs"] extends Record<string, RpcDefinition> ? TContract["rpcs"] : {};
|
|
1155
1212
|
};
|
|
1156
1213
|
/**
|
|
1157
1214
|
* Extract publisher names from a contract.
|
|
@@ -1185,31 +1242,45 @@ type InferPublisherNames<TContract extends ContractDefinition> = TContract["publ
|
|
|
1185
1242
|
* ```
|
|
1186
1243
|
*/
|
|
1187
1244
|
type InferConsumerNames<TContract extends ContractDefinition> = TContract["consumers"] extends Record<string, unknown> ? keyof TContract["consumers"] : never;
|
|
1245
|
+
/**
|
|
1246
|
+
* Extract RPC names from a contract.
|
|
1247
|
+
*
|
|
1248
|
+
* Each name in this union has a typed worker handler and a `client.call(name, ...)`
|
|
1249
|
+
* method. RPC names are disjoint from `InferConsumerNames` and `InferPublisherNames`.
|
|
1250
|
+
*
|
|
1251
|
+
* @template TContract - The contract definition
|
|
1252
|
+
* @returns Union of RPC names, or never if no RPCs defined
|
|
1253
|
+
*/
|
|
1254
|
+
type InferRpcNames<TContract extends ContractDefinition> = TContract["rpcs"] extends Record<string, RpcDefinition> ? keyof TContract["rpcs"] : never;
|
|
1188
1255
|
//#endregion
|
|
1189
1256
|
//#region src/builder/exchange.d.ts
|
|
1190
1257
|
/**
|
|
1191
|
-
* Define a
|
|
1258
|
+
* Define a topic exchange.
|
|
1192
1259
|
*
|
|
1193
|
-
* A
|
|
1194
|
-
*
|
|
1260
|
+
* A topic exchange routes messages to queues based on routing key patterns.
|
|
1261
|
+
* Routing keys can use wildcards: `*` matches one word, `#` matches zero or more words.
|
|
1262
|
+
* This exchange type is ideal for flexible message routing based on hierarchical topics.
|
|
1195
1263
|
*
|
|
1196
1264
|
* @param name - The name of the exchange
|
|
1197
|
-
* @param type - Must be "fanout"
|
|
1198
1265
|
* @param options - Optional exchange configuration
|
|
1199
|
-
* @param options.
|
|
1200
|
-
* @param options.
|
|
1201
|
-
* @param options.
|
|
1266
|
+
* @param options.type - Exchange type (must be "topic", or omitted for default topic exchange)
|
|
1267
|
+
* @param options.durable - If true, the exchange survives broker restarts (default: true)
|
|
1268
|
+
* @param options.autoDelete - If true, the exchange is deleted when no queues are bound
|
|
1269
|
+
* @param options.internal - If true, the exchange cannot be directly published to
|
|
1202
1270
|
* @param options.arguments - Additional AMQP arguments for the exchange
|
|
1203
|
-
* @returns A
|
|
1271
|
+
* @returns A topic exchange definition
|
|
1204
1272
|
*
|
|
1205
1273
|
* @example
|
|
1206
1274
|
* ```typescript
|
|
1207
|
-
* const
|
|
1208
|
-
*
|
|
1209
|
-
*
|
|
1275
|
+
* const ordersExchange = defineExchange('orders', { type: 'topic' });
|
|
1276
|
+
*
|
|
1277
|
+
* // Or omit type for default topic exchange
|
|
1278
|
+
* const ordersExchange = defineExchange('orders');
|
|
1210
1279
|
* ```
|
|
1211
1280
|
*/
|
|
1212
|
-
declare function defineExchange<TName extends string>(name: TName,
|
|
1281
|
+
declare function defineExchange<TName extends string>(name: TName, options?: {
|
|
1282
|
+
type?: "topic";
|
|
1283
|
+
} & Omit<BaseExchangeDefinition, "name" | "type">): TopicExchangeDefinition<TName>;
|
|
1213
1284
|
/**
|
|
1214
1285
|
* Define a direct exchange.
|
|
1215
1286
|
*
|
|
@@ -1217,46 +1288,68 @@ declare function defineExchange<TName extends string>(name: TName, type: "fanout
|
|
|
1217
1288
|
* This exchange type is ideal for point-to-point messaging.
|
|
1218
1289
|
*
|
|
1219
1290
|
* @param name - The name of the exchange
|
|
1220
|
-
* @param
|
|
1221
|
-
* @param options -
|
|
1222
|
-
* @param options.durable - If true, the exchange survives broker restarts (default:
|
|
1223
|
-
* @param options.autoDelete - If true, the exchange is deleted when no queues are bound
|
|
1224
|
-
* @param options.internal - If true, the exchange cannot be directly published to
|
|
1291
|
+
* @param options - Exchange configuration
|
|
1292
|
+
* @param options.type - Exchange type (must be "direct")
|
|
1293
|
+
* @param options.durable - If true, the exchange survives broker restarts (default: true)
|
|
1294
|
+
* @param options.autoDelete - If true, the exchange is deleted when no queues are bound
|
|
1295
|
+
* @param options.internal - If true, the exchange cannot be directly published to
|
|
1225
1296
|
* @param options.arguments - Additional AMQP arguments for the exchange
|
|
1226
1297
|
* @returns A direct exchange definition
|
|
1227
1298
|
*
|
|
1228
1299
|
* @example
|
|
1229
1300
|
* ```typescript
|
|
1230
|
-
* const tasksExchange = defineExchange('tasks', 'direct'
|
|
1231
|
-
* durable: true
|
|
1232
|
-
* });
|
|
1301
|
+
* const tasksExchange = defineExchange('tasks', { type: 'direct' });
|
|
1233
1302
|
* ```
|
|
1234
1303
|
*/
|
|
1235
|
-
declare function defineExchange<TName extends string>(name: TName,
|
|
1304
|
+
declare function defineExchange<TName extends string>(name: TName, options: {
|
|
1305
|
+
type: "direct";
|
|
1306
|
+
} & Omit<BaseExchangeDefinition, "name" | "type">): DirectExchangeDefinition<TName>;
|
|
1236
1307
|
/**
|
|
1237
|
-
* Define a
|
|
1308
|
+
* Define a fanout exchange.
|
|
1238
1309
|
*
|
|
1239
|
-
* A
|
|
1240
|
-
*
|
|
1241
|
-
* This exchange type is ideal for flexible message routing based on hierarchical topics.
|
|
1310
|
+
* A fanout exchange routes messages to all bound queues without considering routing keys.
|
|
1311
|
+
* This exchange type is ideal for broadcasting messages to multiple consumers.
|
|
1242
1312
|
*
|
|
1243
1313
|
* @param name - The name of the exchange
|
|
1244
|
-
* @param
|
|
1245
|
-
* @param options -
|
|
1246
|
-
* @param options.durable - If true, the exchange survives broker restarts (default:
|
|
1247
|
-
* @param options.autoDelete - If true, the exchange is deleted when no queues are bound
|
|
1248
|
-
* @param options.internal - If true, the exchange cannot be directly published to
|
|
1314
|
+
* @param options - Exchange configuration
|
|
1315
|
+
* @param options.type - Exchange type (must be "fanout")
|
|
1316
|
+
* @param options.durable - If true, the exchange survives broker restarts (default: true)
|
|
1317
|
+
* @param options.autoDelete - If true, the exchange is deleted when no queues are bound
|
|
1318
|
+
* @param options.internal - If true, the exchange cannot be directly published to
|
|
1249
1319
|
* @param options.arguments - Additional AMQP arguments for the exchange
|
|
1250
|
-
* @returns A
|
|
1320
|
+
* @returns A fanout exchange definition
|
|
1251
1321
|
*
|
|
1252
1322
|
* @example
|
|
1253
1323
|
* ```typescript
|
|
1254
|
-
* const
|
|
1255
|
-
* durable: true
|
|
1256
|
-
* });
|
|
1324
|
+
* const logsExchange = defineExchange('logs', { type: 'fanout' });
|
|
1257
1325
|
* ```
|
|
1258
1326
|
*/
|
|
1259
|
-
declare function defineExchange<TName extends string>(name: TName,
|
|
1327
|
+
declare function defineExchange<TName extends string>(name: TName, options: {
|
|
1328
|
+
type: "fanout";
|
|
1329
|
+
} & Omit<BaseExchangeDefinition, "name" | "type">): FanoutExchangeDefinition<TName>;
|
|
1330
|
+
/**
|
|
1331
|
+
* Define a headers exchange.
|
|
1332
|
+
*
|
|
1333
|
+
* A headers exchange routes messages to all bound queues based on header matching.
|
|
1334
|
+
* This exchange type is ideal for complex routing scenarios.
|
|
1335
|
+
*
|
|
1336
|
+
* @param name - The name of the exchange
|
|
1337
|
+
* @param options - Exchange configuration
|
|
1338
|
+
* @param options.type - Exchange type (must be "headers")
|
|
1339
|
+
* @param options.durable - If true, the exchange survives broker restarts (default: true)
|
|
1340
|
+
* @param options.autoDelete - If true, the exchange is deleted when no queues are bound
|
|
1341
|
+
* @param options.internal - If true, the exchange cannot be directly published to
|
|
1342
|
+
* @param options.arguments - Additional AMQP arguments for the exchange
|
|
1343
|
+
* @returns A headers exchange definition
|
|
1344
|
+
*
|
|
1345
|
+
* @example
|
|
1346
|
+
* ```typescript
|
|
1347
|
+
* const routesExchange = defineExchange('routes', { type: 'headers' });
|
|
1348
|
+
* ```
|
|
1349
|
+
*/
|
|
1350
|
+
declare function defineExchange<TName extends string>(name: TName, options: {
|
|
1351
|
+
type: "headers";
|
|
1352
|
+
} & Omit<BaseExchangeDefinition, "name" | "type">): HeadersExchangeDefinition<TName>;
|
|
1260
1353
|
//#endregion
|
|
1261
1354
|
//#region src/builder/message.d.ts
|
|
1262
1355
|
/**
|
|
@@ -1301,89 +1394,6 @@ declare function defineMessage<TPayload extends MessageDefinition["payload"], TH
|
|
|
1301
1394
|
}): MessageDefinition<TPayload, THeaders>;
|
|
1302
1395
|
//#endregion
|
|
1303
1396
|
//#region src/builder/queue.d.ts
|
|
1304
|
-
/**
|
|
1305
|
-
* Type guard to check if a queue entry is a QueueWithTtlBackoffInfrastructure.
|
|
1306
|
-
*
|
|
1307
|
-
* When you configure a queue with TTL-backoff retry and a dead letter exchange,
|
|
1308
|
-
* `defineQueue` returns a `QueueWithTtlBackoffInfrastructure` instead of a plain
|
|
1309
|
-
* `QueueDefinition`. This type guard helps you distinguish between the two.
|
|
1310
|
-
*
|
|
1311
|
-
* **When to use:**
|
|
1312
|
-
* - When you need to check the type of a queue entry at runtime
|
|
1313
|
-
* - When writing generic code that handles both plain queues and infrastructure wrappers
|
|
1314
|
-
*
|
|
1315
|
-
* **Related functions:**
|
|
1316
|
-
* - `extractQueue()` - Use this to get the underlying queue definition from either type
|
|
1317
|
-
*
|
|
1318
|
-
* @param entry - The queue entry to check
|
|
1319
|
-
* @returns True if the entry is a QueueWithTtlBackoffInfrastructure, false otherwise
|
|
1320
|
-
*
|
|
1321
|
-
* @example
|
|
1322
|
-
* ```typescript
|
|
1323
|
-
* const queue = defineQueue('orders', {
|
|
1324
|
-
* deadLetter: { exchange: dlx },
|
|
1325
|
-
* retry: { mode: 'ttl-backoff' },
|
|
1326
|
-
* });
|
|
1327
|
-
*
|
|
1328
|
-
* if (isQueueWithTtlBackoffInfrastructure(queue)) {
|
|
1329
|
-
* // queue has .queue, .waitQueue, .waitQueueBinding, .mainQueueRetryBinding
|
|
1330
|
-
* console.log('Wait queue:', queue.waitQueue.name);
|
|
1331
|
-
* } else {
|
|
1332
|
-
* // queue is a plain QueueDefinition
|
|
1333
|
-
* console.log('Queue:', queue.name);
|
|
1334
|
-
* }
|
|
1335
|
-
* ```
|
|
1336
|
-
*/
|
|
1337
|
-
declare function isQueueWithTtlBackoffInfrastructure(entry: QueueEntry): entry is QueueWithTtlBackoffInfrastructure;
|
|
1338
|
-
/**
|
|
1339
|
-
* Extract the plain QueueDefinition from a QueueEntry.
|
|
1340
|
-
*
|
|
1341
|
-
* **Why this function exists:**
|
|
1342
|
-
* When you configure a queue with TTL-backoff retry and a dead letter exchange,
|
|
1343
|
-
* `defineQueue` (or `defineTtlBackoffQueue`) returns a wrapper object that includes
|
|
1344
|
-
* the main queue, wait queue, and bindings. This function extracts the underlying
|
|
1345
|
-
* queue definition so you can access properties like `name`, `type`, etc.
|
|
1346
|
-
*
|
|
1347
|
-
* **When to use:**
|
|
1348
|
-
* - When you need to access queue properties (name, type, deadLetter, etc.)
|
|
1349
|
-
* - When passing a queue to functions that expect a plain QueueDefinition
|
|
1350
|
-
* - Works safely on both plain queues and infrastructure wrappers
|
|
1351
|
-
*
|
|
1352
|
-
* **How it works:**
|
|
1353
|
-
* - If the entry is a `QueueWithTtlBackoffInfrastructure`, returns `entry.queue`
|
|
1354
|
-
* - Otherwise, returns the entry as-is (it's already a plain QueueDefinition)
|
|
1355
|
-
*
|
|
1356
|
-
* @param entry - The queue entry (either plain QueueDefinition or QueueWithTtlBackoffInfrastructure)
|
|
1357
|
-
* @returns The plain QueueDefinition
|
|
1358
|
-
*
|
|
1359
|
-
* @example
|
|
1360
|
-
* ```typescript
|
|
1361
|
-
* import { defineQueue, defineTtlBackoffQueue, extractQueue } from '@amqp-contract/contract';
|
|
1362
|
-
*
|
|
1363
|
-
* // TTL-backoff queue returns a wrapper
|
|
1364
|
-
* const orderQueue = defineTtlBackoffQueue('orders', {
|
|
1365
|
-
* deadLetter: { exchange: dlx },
|
|
1366
|
-
* maxRetries: 3,
|
|
1367
|
-
* });
|
|
1368
|
-
*
|
|
1369
|
-
* // Use extractQueue to access the queue name
|
|
1370
|
-
* const queueName = extractQueue(orderQueue).name; // 'orders'
|
|
1371
|
-
*
|
|
1372
|
-
* // Also works safely on plain queues
|
|
1373
|
-
* const plainQueue = defineQueue('simple', { type: 'quorum', retry: { mode: 'quorum-native' } });
|
|
1374
|
-
* const plainName = extractQueue(plainQueue).name; // 'simple'
|
|
1375
|
-
*
|
|
1376
|
-
* // Access other properties
|
|
1377
|
-
* const queueDef = extractQueue(orderQueue);
|
|
1378
|
-
* console.log(queueDef.name); // 'orders'
|
|
1379
|
-
* console.log(queueDef.type); // 'quorum'
|
|
1380
|
-
* console.log(queueDef.deadLetter); // { exchange: dlx, ... }
|
|
1381
|
-
* ```
|
|
1382
|
-
*
|
|
1383
|
-
* @see isQueueWithTtlBackoffInfrastructure - Type guard to check if extraction is needed
|
|
1384
|
-
* @see defineTtlBackoffQueue - Creates queues with TTL-backoff infrastructure
|
|
1385
|
-
*/
|
|
1386
|
-
declare function extractQueue<T extends QueueEntry>(entry: T): ExtractQueueFromEntry<T>;
|
|
1387
1397
|
/**
|
|
1388
1398
|
* Define an AMQP queue.
|
|
1389
1399
|
*
|
|
@@ -1397,11 +1407,12 @@ declare function extractQueue<T extends QueueEntry>(entry: T): ExtractQueueFromE
|
|
|
1397
1407
|
* @param name - The name of the queue
|
|
1398
1408
|
* @param options - Optional queue configuration
|
|
1399
1409
|
* @param options.type - Queue type: 'quorum' (default, recommended) or 'classic'
|
|
1400
|
-
* @param options.durable - If true, the queue survives broker restarts. Quorum queues
|
|
1401
|
-
* @param options.exclusive - If true, the queue can only be used by the declaring connection. Only supported with classic queues.
|
|
1402
|
-
* @param options.autoDelete - If true, the queue is deleted when the last consumer unsubscribes
|
|
1403
|
-
* @param options.deadLetter - Dead letter configuration for handling failed messages
|
|
1410
|
+
* @param options.durable - If true, the queue survives broker restarts. Quorum queues only support durable queues (default: true)
|
|
1411
|
+
* @param options.exclusive - If true, the queue can only be used by the declaring connection and is deleted when that connection closes. Only supported with classic queues.
|
|
1412
|
+
* @param options.autoDelete - If true, the queue is deleted when the last consumer unsubscribes. Only supported with classic queues.
|
|
1404
1413
|
* @param options.maxPriority - Maximum priority level for priority queue (1-255, recommended: 1-10). Only supported with classic queues.
|
|
1414
|
+
* @param options.deadLetter - Dead letter configuration for handling failed messages
|
|
1415
|
+
* @param options.retry - Retry configuration for handling failed message processing
|
|
1405
1416
|
* @param options.arguments - Additional AMQP arguments (e.g., x-message-ttl)
|
|
1406
1417
|
* @returns A queue definition
|
|
1407
1418
|
*
|
|
@@ -1411,7 +1422,7 @@ declare function extractQueue<T extends QueueEntry>(entry: T): ExtractQueueFromE
|
|
|
1411
1422
|
* const orderQueue = defineQueue('order-processing');
|
|
1412
1423
|
*
|
|
1413
1424
|
* // Explicit quorum queue with dead letter exchange
|
|
1414
|
-
* const dlx = defineExchange('orders-dlx'
|
|
1425
|
+
* const dlx = defineExchange('orders-dlx');
|
|
1415
1426
|
* const orderQueueWithDLX = defineQueue('order-processing', {
|
|
1416
1427
|
* type: 'quorum',
|
|
1417
1428
|
* deadLetter: {
|
|
@@ -1433,12 +1444,11 @@ declare function extractQueue<T extends QueueEntry>(entry: T): ExtractQueueFromE
|
|
|
1433
1444
|
* // Priority queue (requires classic type)
|
|
1434
1445
|
* const taskQueue = defineQueue('urgent-tasks', {
|
|
1435
1446
|
* type: 'classic',
|
|
1436
|
-
* durable: true,
|
|
1437
1447
|
* maxPriority: 10,
|
|
1438
1448
|
* });
|
|
1439
1449
|
*
|
|
1440
1450
|
* // Queue with TTL-backoff retry (returns infrastructure automatically)
|
|
1441
|
-
* const dlx = defineExchange('orders-dlx',
|
|
1451
|
+
* const dlx = defineExchange('orders-dlx', { type: 'direct' });
|
|
1442
1452
|
* const orderQueue = defineQueue('order-processing', {
|
|
1443
1453
|
* deadLetter: { exchange: dlx },
|
|
1444
1454
|
* retry: { mode: 'ttl-backoff', maxRetries: 5 },
|
|
@@ -1446,204 +1456,82 @@ declare function extractQueue<T extends QueueEntry>(entry: T): ExtractQueueFromE
|
|
|
1446
1456
|
* // orderQueue is QueueWithTtlBackoffInfrastructure, pass directly to defineContract
|
|
1447
1457
|
* ```
|
|
1448
1458
|
*/
|
|
1449
|
-
declare function defineQueue<TName extends string, TDlx extends ExchangeDefinition>(name: TName, options:
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
}): (QueueDefinition<TName> | QueueWithTtlBackoffInfrastructure<TName>) & {
|
|
1454
|
-
deadLetter: {
|
|
1455
|
-
exchange: TDlx;
|
|
1456
|
-
};
|
|
1457
|
-
};
|
|
1458
|
-
declare function defineQueue<TName extends string>(name: TName, options?: DefineQueueOptions): QueueDefinition<TName> | QueueWithTtlBackoffInfrastructure<TName>;
|
|
1459
|
-
/**
|
|
1460
|
-
* Options for creating a quorum queue with quorum-native retry.
|
|
1461
|
-
*
|
|
1462
|
-
* This simplified helper enforces the required configuration for quorum-native retry:
|
|
1463
|
-
* - Dead letter exchange is required (for failed messages)
|
|
1464
|
-
* - Delivery limit is required (for retry count)
|
|
1465
|
-
*/
|
|
1466
|
-
type DefineQuorumQueueOptions = {
|
|
1467
|
-
/**
|
|
1468
|
-
* Dead letter configuration - required for retry support.
|
|
1469
|
-
* Failed messages will be sent to this exchange.
|
|
1470
|
-
*/
|
|
1471
|
-
deadLetter: DeadLetterConfig;
|
|
1472
|
-
/**
|
|
1473
|
-
* Maximum number of delivery attempts before dead-lettering.
|
|
1474
|
-
* @minimum 1
|
|
1475
|
-
*/
|
|
1476
|
-
deliveryLimit: number;
|
|
1477
|
-
/**
|
|
1478
|
-
* If true, the queue is deleted when the last consumer unsubscribes.
|
|
1479
|
-
* @default false
|
|
1480
|
-
*/
|
|
1481
|
-
autoDelete?: boolean;
|
|
1482
|
-
/**
|
|
1483
|
-
* Additional AMQP arguments for advanced configuration.
|
|
1484
|
-
*/
|
|
1485
|
-
arguments?: Record<string, unknown>;
|
|
1486
|
-
};
|
|
1487
|
-
/**
|
|
1488
|
-
* Create a quorum queue with quorum-native retry.
|
|
1489
|
-
*
|
|
1490
|
-
* This is a simplified helper that enforces best practices:
|
|
1491
|
-
* - Uses quorum queues (recommended for most use cases)
|
|
1492
|
-
* - Requires dead letter exchange for failed message handling
|
|
1493
|
-
* - Uses quorum-native retry mode (simpler than TTL-backoff)
|
|
1494
|
-
*
|
|
1495
|
-
* **When to use:**
|
|
1496
|
-
* - You want simple, immediate retries without exponential backoff
|
|
1497
|
-
* - You don't need configurable delays between retries
|
|
1498
|
-
* - You want the simplest retry configuration
|
|
1499
|
-
*
|
|
1500
|
-
* @param name - The queue name
|
|
1501
|
-
* @param options - Configuration options
|
|
1502
|
-
* @returns A quorum queue definition with quorum-native retry
|
|
1503
|
-
*
|
|
1504
|
-
* @example
|
|
1505
|
-
* ```typescript
|
|
1506
|
-
* const dlx = defineExchange('orders-dlx', 'direct', { durable: true });
|
|
1507
|
-
*
|
|
1508
|
-
* const orderQueue = defineQuorumQueue('order-processing', {
|
|
1509
|
-
* deadLetter: { exchange: dlx },
|
|
1510
|
-
* deliveryLimit: 3, // Retry up to 3 times
|
|
1511
|
-
* });
|
|
1512
|
-
*
|
|
1513
|
-
* // Use in a contract — exchanges, queues, and bindings are auto-extracted
|
|
1514
|
-
* const contract = defineContract({
|
|
1515
|
-
* publishers: { ... },
|
|
1516
|
-
* consumers: { processOrder: defineEventConsumer(event, orderQueue) },
|
|
1517
|
-
* });
|
|
1518
|
-
* ```
|
|
1519
|
-
*
|
|
1520
|
-
* @see defineQueue - For full queue configuration options
|
|
1521
|
-
* @see defineTtlBackoffQueue - For queues with exponential backoff retry
|
|
1522
|
-
*/
|
|
1523
|
-
declare function defineQuorumQueue<TName extends string>(name: TName, options: DefineQuorumQueueOptions): QuorumQueueDefinition<TName>;
|
|
1524
|
-
/**
|
|
1525
|
-
* Options for creating a queue with TTL-backoff retry.
|
|
1526
|
-
*
|
|
1527
|
-
* This simplified helper enforces the required configuration for TTL-backoff retry:
|
|
1528
|
-
* - Dead letter exchange is required (used for retry routing)
|
|
1529
|
-
* - Returns infrastructure that includes wait queue and bindings
|
|
1530
|
-
*/
|
|
1531
|
-
type DefineTtlBackoffQueueOptions = {
|
|
1532
|
-
/**
|
|
1533
|
-
* Dead letter configuration - required for TTL-backoff retry.
|
|
1534
|
-
* Used for routing messages to the wait queue and back.
|
|
1535
|
-
*/
|
|
1536
|
-
deadLetter: DeadLetterConfig;
|
|
1537
|
-
/**
|
|
1538
|
-
* Maximum retry attempts before sending to DLQ.
|
|
1539
|
-
* @default 3
|
|
1540
|
-
*/
|
|
1541
|
-
maxRetries?: number;
|
|
1542
|
-
/**
|
|
1543
|
-
* Initial delay in ms before first retry.
|
|
1544
|
-
* @default 1000
|
|
1545
|
-
*/
|
|
1546
|
-
initialDelayMs?: number;
|
|
1547
|
-
/**
|
|
1548
|
-
* Maximum delay in ms between retries.
|
|
1549
|
-
* @default 30000
|
|
1550
|
-
*/
|
|
1551
|
-
maxDelayMs?: number;
|
|
1552
|
-
/**
|
|
1553
|
-
* Exponential backoff multiplier.
|
|
1554
|
-
* @default 2
|
|
1555
|
-
*/
|
|
1556
|
-
backoffMultiplier?: number;
|
|
1557
|
-
/**
|
|
1558
|
-
* Add jitter to prevent thundering herd.
|
|
1559
|
-
* @default true
|
|
1560
|
-
*/
|
|
1561
|
-
jitter?: boolean;
|
|
1562
|
-
/**
|
|
1563
|
-
* If true, the queue is deleted when the last consumer unsubscribes.
|
|
1564
|
-
* @default false
|
|
1565
|
-
*/
|
|
1566
|
-
autoDelete?: boolean;
|
|
1567
|
-
/**
|
|
1568
|
-
* Additional AMQP arguments for advanced configuration.
|
|
1569
|
-
*/
|
|
1570
|
-
arguments?: Record<string, unknown>;
|
|
1571
|
-
};
|
|
1459
|
+
declare function defineQueue<TName extends string, TDlx extends ExchangeDefinition>(name: TName, options: DefineQueueOptionsWithDeadLetterExchange<TDlx>): QueueEntryWithDeadLetterExchange<TName, TDlx>;
|
|
1460
|
+
declare function defineQueue<TName extends string>(name: TName, options?: DefineQueueOptions): QueueEntry<TName>;
|
|
1461
|
+
//#endregion
|
|
1462
|
+
//#region src/builder/queue-utils.d.ts
|
|
1572
1463
|
/**
|
|
1573
|
-
*
|
|
1464
|
+
* Extract the plain QueueDefinition from a QueueEntry.
|
|
1574
1465
|
*
|
|
1575
|
-
*
|
|
1576
|
-
*
|
|
1577
|
-
*
|
|
1578
|
-
*
|
|
1579
|
-
*
|
|
1466
|
+
* **Why this function exists:**
|
|
1467
|
+
* When you configure a queue with TTL-backoff retry,
|
|
1468
|
+
* `defineQueue` returns a wrapper object that includes
|
|
1469
|
+
* the main queue, wait queue, headers exchanges, and bindings. This function extracts the underlying
|
|
1470
|
+
* queue definition so you can access properties like `name`, `type`, etc.
|
|
1580
1471
|
*
|
|
1581
1472
|
* **When to use:**
|
|
1582
|
-
* -
|
|
1583
|
-
* -
|
|
1584
|
-
* -
|
|
1473
|
+
* - When you need to access queue properties (name, type, etc.)
|
|
1474
|
+
* - When passing a queue to functions that expect a plain QueueDefinition
|
|
1475
|
+
* - Works safely on both plain queues and infrastructure wrappers
|
|
1585
1476
|
*
|
|
1586
|
-
* **
|
|
1587
|
-
*
|
|
1588
|
-
*
|
|
1477
|
+
* **How it works:**
|
|
1478
|
+
* - If the entry is a `QueueWithTtlBackoffInfrastructure`, returns `entry.queue`
|
|
1479
|
+
* - Otherwise, returns the entry as-is (it's already a plain QueueDefinition)
|
|
1589
1480
|
*
|
|
1590
|
-
* @param
|
|
1591
|
-
* @
|
|
1592
|
-
* @returns A queue with TTL-backoff infrastructure
|
|
1481
|
+
* @param entry - The queue entry (either plain QueueDefinition or QueueWithTtlBackoffInfrastructure)
|
|
1482
|
+
* @returns The plain QueueDefinition
|
|
1593
1483
|
*
|
|
1594
1484
|
* @example
|
|
1595
1485
|
* ```typescript
|
|
1596
|
-
*
|
|
1486
|
+
* import { defineQueue, extractQueue } from '@amqp-contract/contract';
|
|
1597
1487
|
*
|
|
1598
|
-
*
|
|
1599
|
-
*
|
|
1600
|
-
* maxRetries:
|
|
1601
|
-
* initialDelayMs: 1000, // Start with 1s delay
|
|
1602
|
-
* maxDelayMs: 30000, // Cap at 30s
|
|
1488
|
+
* // TTL-backoff queue returns a wrapper
|
|
1489
|
+
* const orderQueue = defineQueue('orders', {
|
|
1490
|
+
* retry: { mode: 'ttl-backoff', maxRetries: 3 },
|
|
1603
1491
|
* });
|
|
1604
1492
|
*
|
|
1605
|
-
* // Use
|
|
1606
|
-
* const
|
|
1607
|
-
*
|
|
1608
|
-
*
|
|
1609
|
-
* });
|
|
1493
|
+
* // Use extractQueue to access the queue name
|
|
1494
|
+
* const queueName = extractQueue(orderQueue).name; // 'orders'
|
|
1495
|
+
*
|
|
1496
|
+
* // Also works safely on plain queues
|
|
1497
|
+
* const plainQueue = defineQueue('simple', { type: 'quorum', retry: { mode: 'immediate-requeue' } });
|
|
1498
|
+
* const plainName = extractQueue(plainQueue).name; // 'simple'
|
|
1610
1499
|
*
|
|
1611
|
-
* //
|
|
1612
|
-
*
|
|
1613
|
-
*
|
|
1500
|
+
* // Access other properties
|
|
1501
|
+
* const queueDef = extractQueue(orderQueue);
|
|
1502
|
+
* console.log(queueDef.name); // 'orders'
|
|
1503
|
+
* console.log(queueDef.type); // 'quorum'
|
|
1614
1504
|
* ```
|
|
1615
1505
|
*
|
|
1616
|
-
* @see
|
|
1617
|
-
* @see defineQuorumQueue - For queues with quorum-native retry (simpler, immediate retries)
|
|
1618
|
-
* @see extractQueue - To access the underlying queue definition
|
|
1506
|
+
* @see isQueueWithTtlBackoffInfrastructure - Type guard to check if extraction is needed
|
|
1619
1507
|
*/
|
|
1620
|
-
declare function
|
|
1508
|
+
declare function extractQueue<T extends QueueEntry>(entry: T): ExtractQueueFromEntry<T>;
|
|
1621
1509
|
//#endregion
|
|
1622
1510
|
//#region src/builder/binding.d.ts
|
|
1623
1511
|
/**
|
|
1624
|
-
* Define a binding between a queue and a fanout exchange.
|
|
1512
|
+
* Define a binding between a queue and a fanout or headers exchange.
|
|
1625
1513
|
*
|
|
1626
|
-
* Binds a queue to a fanout
|
|
1627
|
-
* Fanout exchanges ignore routing keys, so this overload doesn't require one.
|
|
1514
|
+
* Binds a queue to a fanout or headers exchange (no routing key needed).
|
|
1515
|
+
* Fanout and headers exchanges ignore routing keys, so this overload doesn't require one.
|
|
1628
1516
|
*
|
|
1629
1517
|
* @param queue - The queue definition or queue with infrastructure to bind
|
|
1630
|
-
* @param exchange - The fanout exchange definition
|
|
1518
|
+
* @param exchange - The fanout or headers exchange definition
|
|
1631
1519
|
* @param options - Optional binding configuration
|
|
1632
1520
|
* @param options.arguments - Additional AMQP arguments for the binding
|
|
1633
1521
|
* @returns A queue binding definition
|
|
1634
1522
|
*
|
|
1635
1523
|
* @example
|
|
1636
1524
|
* ```typescript
|
|
1637
|
-
* const logsQueue = defineQueue('logs-queue'
|
|
1638
|
-
* const logsExchange = defineExchange('logs',
|
|
1525
|
+
* const logsQueue = defineQueue('logs-queue');
|
|
1526
|
+
* const logsExchange = defineExchange('logs', { type: 'fanout' });
|
|
1639
1527
|
*
|
|
1640
1528
|
* const binding = defineQueueBinding(logsQueue, logsExchange);
|
|
1641
1529
|
* ```
|
|
1642
1530
|
*/
|
|
1643
|
-
declare function defineQueueBinding(queue: QueueEntry, exchange: FanoutExchangeDefinition, options?: Omit<Extract<QueueBindingDefinition, {
|
|
1644
|
-
exchange: FanoutExchangeDefinition;
|
|
1531
|
+
declare function defineQueueBinding(queue: QueueEntry, exchange: FanoutExchangeDefinition | HeadersExchangeDefinition, options?: Omit<Extract<QueueBindingDefinition, {
|
|
1532
|
+
exchange: FanoutExchangeDefinition | HeadersExchangeDefinition;
|
|
1645
1533
|
}>, "type" | "queue" | "exchange" | "routingKey">): Extract<QueueBindingDefinition, {
|
|
1646
|
-
exchange: FanoutExchangeDefinition;
|
|
1534
|
+
exchange: FanoutExchangeDefinition | HeadersExchangeDefinition;
|
|
1647
1535
|
}>;
|
|
1648
1536
|
/**
|
|
1649
1537
|
* Define a binding between a queue and a direct or topic exchange.
|
|
@@ -1665,8 +1553,8 @@ declare function defineQueueBinding(queue: QueueEntry, exchange: FanoutExchangeD
|
|
|
1665
1553
|
*
|
|
1666
1554
|
* @example
|
|
1667
1555
|
* ```typescript
|
|
1668
|
-
* const orderQueue = defineQueue('order-processing'
|
|
1669
|
-
* const ordersExchange = defineExchange('orders'
|
|
1556
|
+
* const orderQueue = defineQueue('order-processing');
|
|
1557
|
+
* const ordersExchange = defineExchange('orders');
|
|
1670
1558
|
*
|
|
1671
1559
|
* // Bind with exact routing key
|
|
1672
1560
|
* const binding = defineQueueBinding(orderQueue, ordersExchange, {
|
|
@@ -1687,28 +1575,28 @@ declare function defineQueueBinding(queue: QueueEntry, exchange: DirectExchangeD
|
|
|
1687
1575
|
/**
|
|
1688
1576
|
* Define a binding between two exchanges (exchange-to-exchange routing).
|
|
1689
1577
|
*
|
|
1690
|
-
* Binds a destination exchange to a fanout source exchange.
|
|
1578
|
+
* Binds a destination exchange to a fanout or headers source exchange.
|
|
1691
1579
|
* Messages published to the source exchange will be forwarded to the destination exchange.
|
|
1692
|
-
* Fanout exchanges ignore routing keys, so this overload doesn't require one.
|
|
1580
|
+
* Fanout and headers exchanges ignore routing keys, so this overload doesn't require one.
|
|
1693
1581
|
*
|
|
1694
1582
|
* @param destination - The destination exchange definition
|
|
1695
|
-
* @param source - The fanout source exchange definition
|
|
1583
|
+
* @param source - The fanout or headers source exchange definition
|
|
1696
1584
|
* @param options - Optional binding configuration
|
|
1697
1585
|
* @param options.arguments - Additional AMQP arguments for the binding
|
|
1698
1586
|
* @returns An exchange binding definition
|
|
1699
1587
|
*
|
|
1700
1588
|
* @example
|
|
1701
1589
|
* ```typescript
|
|
1702
|
-
* const sourceExchange = defineExchange('logs',
|
|
1703
|
-
* const destExchange = defineExchange('all-logs',
|
|
1590
|
+
* const sourceExchange = defineExchange('logs', { type: 'fanout' });
|
|
1591
|
+
* const destExchange = defineExchange('all-logs', { type: 'fanout' });
|
|
1704
1592
|
*
|
|
1705
1593
|
* const binding = defineExchangeBinding(destExchange, sourceExchange);
|
|
1706
1594
|
* ```
|
|
1707
1595
|
*/
|
|
1708
|
-
declare function defineExchangeBinding(destination: ExchangeDefinition, source: FanoutExchangeDefinition, options?: Omit<Extract<ExchangeBindingDefinition, {
|
|
1709
|
-
source: FanoutExchangeDefinition;
|
|
1596
|
+
declare function defineExchangeBinding(destination: ExchangeDefinition, source: FanoutExchangeDefinition | HeadersExchangeDefinition, options?: Omit<Extract<ExchangeBindingDefinition, {
|
|
1597
|
+
source: FanoutExchangeDefinition | HeadersExchangeDefinition;
|
|
1710
1598
|
}>, "type" | "source" | "destination" | "routingKey">): Extract<ExchangeBindingDefinition, {
|
|
1711
|
-
source: FanoutExchangeDefinition;
|
|
1599
|
+
source: FanoutExchangeDefinition | HeadersExchangeDefinition;
|
|
1712
1600
|
}>;
|
|
1713
1601
|
/**
|
|
1714
1602
|
* Define a binding between two exchanges (exchange-to-exchange routing).
|
|
@@ -1725,8 +1613,8 @@ declare function defineExchangeBinding(destination: ExchangeDefinition, source:
|
|
|
1725
1613
|
*
|
|
1726
1614
|
* @example
|
|
1727
1615
|
* ```typescript
|
|
1728
|
-
* const ordersExchange = defineExchange('orders'
|
|
1729
|
-
* const importantExchange = defineExchange('important-orders'
|
|
1616
|
+
* const ordersExchange = defineExchange('orders');
|
|
1617
|
+
* const importantExchange = defineExchange('important-orders');
|
|
1730
1618
|
*
|
|
1731
1619
|
* // Forward only high-value orders
|
|
1732
1620
|
* const binding = defineExchangeBinding(importantExchange, ordersExchange, {
|
|
@@ -1742,10 +1630,11 @@ declare function defineExchangeBinding(destination: ExchangeDefinition, source:
|
|
|
1742
1630
|
//#endregion
|
|
1743
1631
|
//#region src/builder/publisher.d.ts
|
|
1744
1632
|
/**
|
|
1745
|
-
* Define a message publisher for a fanout exchange.
|
|
1633
|
+
* Define a message publisher for a fanout or headers exchange.
|
|
1746
1634
|
*
|
|
1747
1635
|
* A publisher sends messages to an exchange. For fanout exchanges, messages are broadcast
|
|
1748
|
-
* to all bound queues regardless of routing key, so no routing key is required.
|
|
1636
|
+
* to all bound queues regardless of routing key, so no routing key is required. For headers exchanges,
|
|
1637
|
+
* routing is based on message headers rather than routing keys, so no routing key is required either.
|
|
1749
1638
|
*
|
|
1750
1639
|
* The message schema is validated when publishing to ensure type safety.
|
|
1751
1640
|
*
|
|
@@ -1762,7 +1651,7 @@ declare function defineExchangeBinding(destination: ExchangeDefinition, source:
|
|
|
1762
1651
|
* - You want automatic schema consistency between publisher and consumers
|
|
1763
1652
|
* - You're building event-driven architectures
|
|
1764
1653
|
*
|
|
1765
|
-
* @param exchange - The fanout exchange definition to publish to
|
|
1654
|
+
* @param exchange - The fanout or headers exchange definition to publish to
|
|
1766
1655
|
* @param message - The message definition with payload schema
|
|
1767
1656
|
* @param options - Optional publisher configuration
|
|
1768
1657
|
* @returns A publisher definition with inferred message types
|
|
@@ -1771,7 +1660,7 @@ declare function defineExchangeBinding(destination: ExchangeDefinition, source:
|
|
|
1771
1660
|
* ```typescript
|
|
1772
1661
|
* import { z } from 'zod';
|
|
1773
1662
|
*
|
|
1774
|
-
* const logsExchange = defineExchange('logs',
|
|
1663
|
+
* const logsExchange = defineExchange('logs', { type: 'fanout' });
|
|
1775
1664
|
* const logMessage = defineMessage(
|
|
1776
1665
|
* z.object({
|
|
1777
1666
|
* level: z.enum(['info', 'warn', 'error']),
|
|
@@ -1786,10 +1675,10 @@ declare function defineExchangeBinding(destination: ExchangeDefinition, source:
|
|
|
1786
1675
|
* @see defineEventPublisher - For event-driven patterns with automatic schema consistency
|
|
1787
1676
|
* @see defineCommandConsumer - For task queue patterns with automatic schema consistency
|
|
1788
1677
|
*/
|
|
1789
|
-
declare function definePublisher<TMessage extends MessageDefinition>(exchange: FanoutExchangeDefinition, message: TMessage, options?: Omit<Extract<PublisherDefinition<TMessage>, {
|
|
1790
|
-
exchange: FanoutExchangeDefinition;
|
|
1678
|
+
declare function definePublisher<TMessage extends MessageDefinition>(exchange: FanoutExchangeDefinition | HeadersExchangeDefinition, message: TMessage, options?: Omit<Extract<PublisherDefinition<TMessage>, {
|
|
1679
|
+
exchange: FanoutExchangeDefinition | HeadersExchangeDefinition;
|
|
1791
1680
|
}>, "exchange" | "message" | "routingKey">): Extract<PublisherDefinition<TMessage>, {
|
|
1792
|
-
exchange: FanoutExchangeDefinition;
|
|
1681
|
+
exchange: FanoutExchangeDefinition | HeadersExchangeDefinition;
|
|
1793
1682
|
}>;
|
|
1794
1683
|
/**
|
|
1795
1684
|
* Define a message publisher for a direct or topic exchange.
|
|
@@ -1822,7 +1711,7 @@ declare function definePublisher<TMessage extends MessageDefinition>(exchange: F
|
|
|
1822
1711
|
* ```typescript
|
|
1823
1712
|
* import { z } from 'zod';
|
|
1824
1713
|
*
|
|
1825
|
-
* const ordersExchange = defineExchange('orders'
|
|
1714
|
+
* const ordersExchange = defineExchange('orders');
|
|
1826
1715
|
* const orderMessage = defineMessage(
|
|
1827
1716
|
* z.object({
|
|
1828
1717
|
* orderId: z.string().uuid(),
|
|
@@ -1911,7 +1800,7 @@ declare function extractConsumer(entry: ConsumerEntry): ConsumerDefinition;
|
|
|
1911
1800
|
* ```typescript
|
|
1912
1801
|
* import { z } from 'zod';
|
|
1913
1802
|
*
|
|
1914
|
-
* const orderQueue = defineQueue('order-processing'
|
|
1803
|
+
* const orderQueue = defineQueue('order-processing');
|
|
1915
1804
|
* const orderMessage = defineMessage(
|
|
1916
1805
|
* z.object({
|
|
1917
1806
|
* orderId: z.string().uuid(),
|
|
@@ -1970,12 +1859,11 @@ declare function defineConsumer<TMessage extends MessageDefinition>(queue: Queue
|
|
|
1970
1859
|
* import { z } from 'zod';
|
|
1971
1860
|
*
|
|
1972
1861
|
* // Define resources
|
|
1973
|
-
* const ordersExchange = defineExchange('orders'
|
|
1974
|
-
* const dlx = defineExchange('orders-dlx',
|
|
1862
|
+
* const ordersExchange = defineExchange('orders');
|
|
1863
|
+
* const dlx = defineExchange('orders-dlx', { type: 'direct' });
|
|
1975
1864
|
* const orderQueue = defineQueue('order-processing', {
|
|
1976
1865
|
* deadLetter: { exchange: dlx },
|
|
1977
|
-
* retry: { mode: '
|
|
1978
|
-
* deliveryLimit: 3,
|
|
1866
|
+
* retry: { mode: 'immediate-requeue', maxRetries: 3 },
|
|
1979
1867
|
* });
|
|
1980
1868
|
* const orderMessage = defineMessage(
|
|
1981
1869
|
* z.object({
|
|
@@ -2097,7 +1985,7 @@ type MatchingRoutingKey<Pattern extends string, Key extends string> = RoutingKey
|
|
|
2097
1985
|
*
|
|
2098
1986
|
* @template TMessage - The message definition
|
|
2099
1987
|
* @template TExchange - The exchange definition
|
|
2100
|
-
* @template TRoutingKey - The routing key type (undefined for fanout)
|
|
1988
|
+
* @template TRoutingKey - The routing key type (undefined for fanout and headers exchanges)
|
|
2101
1989
|
*/
|
|
2102
1990
|
type EventPublisherConfig<TMessage extends MessageDefinition, TExchange extends ExchangeDefinition, TRoutingKey extends string | undefined = undefined> = {
|
|
2103
1991
|
/** Discriminator to identify this as an event publisher config */__brand: "EventPublisherConfig"; /** The exchange to publish to */
|
|
@@ -2115,13 +2003,12 @@ type EventPublisherConfig<TMessage extends MessageDefinition, TExchange extends
|
|
|
2115
2003
|
*
|
|
2116
2004
|
* @template TMessage - The message definition
|
|
2117
2005
|
*/
|
|
2118
|
-
type EventConsumerResult<TMessage extends MessageDefinition, TExchange extends ExchangeDefinition = ExchangeDefinition, TQueue extends
|
|
2006
|
+
type EventConsumerResult<TMessage extends MessageDefinition, TExchange extends ExchangeDefinition = ExchangeDefinition, TQueue extends QueueEntry = QueueEntry, TExchangeBinding extends ExchangeBindingDefinition | undefined = ExchangeBindingDefinition | undefined, TBridgeExchange extends ExchangeDefinition | undefined = ExchangeDefinition | undefined> = {
|
|
2119
2007
|
/** Discriminator to identify this as an event consumer result */__brand: "EventConsumerResult"; /** The consumer definition for processing messages */
|
|
2120
2008
|
consumer: ConsumerDefinition<TMessage>; /** The binding connecting the queue to the exchange */
|
|
2121
2009
|
binding: QueueBindingDefinition; /** The source exchange this consumer subscribes to */
|
|
2122
2010
|
exchange: TExchange; /** The queue this consumer reads from */
|
|
2123
|
-
queue: TQueue; /** The
|
|
2124
|
-
deadLetterExchange: TDlxExchange; /** The exchange-to-exchange binding when bridging, if configured */
|
|
2011
|
+
queue: TQueue; /** The exchange-to-exchange binding when bridging, if configured */
|
|
2125
2012
|
exchangeBinding: TExchangeBinding; /** The bridge (local domain) exchange when bridging, if configured */
|
|
2126
2013
|
bridgeExchange: TBridgeExchange;
|
|
2127
2014
|
};
|
|
@@ -2133,11 +2020,46 @@ type EventConsumerResult<TMessage extends MessageDefinition, TExchange extends E
|
|
|
2133
2020
|
*
|
|
2134
2021
|
* @param exchange - The fanout exchange to publish to
|
|
2135
2022
|
* @param message - The message definition (schema and metadata)
|
|
2023
|
+
* @param options - Optional binding configuration
|
|
2024
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2025
|
+
* @returns An event publisher configuration
|
|
2026
|
+
*
|
|
2027
|
+
* @example
|
|
2028
|
+
* ```typescript
|
|
2029
|
+
* const logsExchange = defineExchange('logs', { type: 'fanout' });
|
|
2030
|
+
* const logMessage = defineMessage(z.object({
|
|
2031
|
+
* level: z.enum(['info', 'warn', 'error']),
|
|
2032
|
+
* message: z.string(),
|
|
2033
|
+
* }));
|
|
2034
|
+
*
|
|
2035
|
+
* // Create event publisher
|
|
2036
|
+
* const logEvent = defineEventPublisher(logsExchange, logMessage);
|
|
2037
|
+
*
|
|
2038
|
+
* // Multiple consumers can subscribe
|
|
2039
|
+
* const { consumer: fileConsumer, binding: fileBinding } =
|
|
2040
|
+
* defineEventConsumer(logEvent, fileLogsQueue);
|
|
2041
|
+
* const { consumer: alertConsumer, binding: alertBinding } =
|
|
2042
|
+
* defineEventConsumer(logEvent, alertsQueue);
|
|
2043
|
+
* ```
|
|
2044
|
+
*/
|
|
2045
|
+
declare function defineEventPublisher<TMessage extends MessageDefinition, TExchange extends FanoutExchangeDefinition>(exchange: TExchange, message: TMessage, options?: {
|
|
2046
|
+
arguments?: Record<string, unknown>;
|
|
2047
|
+
}): EventPublisherConfig<TMessage, TExchange, undefined>;
|
|
2048
|
+
/**
|
|
2049
|
+
* Define an event publisher for broadcasting messages via headers exchange.
|
|
2050
|
+
*
|
|
2051
|
+
* Events are published without knowing who consumes them. Multiple consumers
|
|
2052
|
+
* can subscribe to the same event using `defineEventConsumer`.
|
|
2053
|
+
*
|
|
2054
|
+
* @param exchange - The headers exchange to publish to
|
|
2055
|
+
* @param message - The message definition (schema and metadata)
|
|
2056
|
+
* @param options - Optional binding configuration
|
|
2057
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2136
2058
|
* @returns An event publisher configuration
|
|
2137
2059
|
*
|
|
2138
2060
|
* @example
|
|
2139
2061
|
* ```typescript
|
|
2140
|
-
* const logsExchange = defineExchange('logs',
|
|
2062
|
+
* const logsExchange = defineExchange('logs', { type: 'headers' });
|
|
2141
2063
|
* const logMessage = defineMessage(z.object({
|
|
2142
2064
|
* level: z.enum(['info', 'warn', 'error']),
|
|
2143
2065
|
* message: z.string(),
|
|
@@ -2153,7 +2075,9 @@ type EventConsumerResult<TMessage extends MessageDefinition, TExchange extends E
|
|
|
2153
2075
|
* defineEventConsumer(logEvent, alertsQueue);
|
|
2154
2076
|
* ```
|
|
2155
2077
|
*/
|
|
2156
|
-
declare function defineEventPublisher<TMessage extends MessageDefinition, TExchange extends
|
|
2078
|
+
declare function defineEventPublisher<TMessage extends MessageDefinition, TExchange extends HeadersExchangeDefinition>(exchange: TExchange, message: TMessage, options?: {
|
|
2079
|
+
arguments?: Record<string, unknown>;
|
|
2080
|
+
}): EventPublisherConfig<TMessage, TExchange, undefined>;
|
|
2157
2081
|
/**
|
|
2158
2082
|
* Define an event publisher for broadcasting messages via direct exchange.
|
|
2159
2083
|
*
|
|
@@ -2169,7 +2093,7 @@ declare function defineEventPublisher<TMessage extends MessageDefinition, TExcha
|
|
|
2169
2093
|
*
|
|
2170
2094
|
* @example
|
|
2171
2095
|
* ```typescript
|
|
2172
|
-
* const tasksExchange = defineExchange('tasks',
|
|
2096
|
+
* const tasksExchange = defineExchange('tasks', { type: 'direct' });
|
|
2173
2097
|
* const taskMessage = defineMessage(z.object({ taskId: z.string() }));
|
|
2174
2098
|
*
|
|
2175
2099
|
* const taskEvent = defineEventPublisher(tasksExchange, taskMessage, {
|
|
@@ -2196,7 +2120,7 @@ declare function defineEventPublisher<TMessage extends MessageDefinition, TRouti
|
|
|
2196
2120
|
*
|
|
2197
2121
|
* @example
|
|
2198
2122
|
* ```typescript
|
|
2199
|
-
* const ordersExchange = defineExchange('orders',
|
|
2123
|
+
* const ordersExchange = defineExchange('orders', { type: 'topic' });
|
|
2200
2124
|
* const orderMessage = defineMessage(z.object({
|
|
2201
2125
|
* orderId: z.string(),
|
|
2202
2126
|
* amount: z.number(),
|
|
@@ -2229,12 +2153,30 @@ declare function defineEventPublisher<TMessage extends MessageDefinition, TRouti
|
|
|
2229
2153
|
* @param queue - The queue that will receive messages
|
|
2230
2154
|
* @param options - Binding configuration with required bridgeExchange
|
|
2231
2155
|
* @param options.bridgeExchange - The fanout bridge exchange (must be fanout to match source)
|
|
2156
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2232
2157
|
* @returns An object with the consumer definition, queue binding, and exchange binding
|
|
2233
2158
|
*/
|
|
2234
2159
|
declare function defineEventConsumer<TMessage extends MessageDefinition, TExchange extends FanoutExchangeDefinition, TQueueEntry extends QueueEntry, TBridgeExchange extends FanoutExchangeDefinition>(eventPublisher: EventPublisherConfig<TMessage, TExchange, undefined>, queue: TQueueEntry, options: {
|
|
2235
2160
|
bridgeExchange: TBridgeExchange;
|
|
2236
2161
|
arguments?: Record<string, unknown>;
|
|
2237
|
-
}): EventConsumerResult<TMessage, TExchange,
|
|
2162
|
+
}): EventConsumerResult<TMessage, TExchange, TQueueEntry, ExchangeBindingDefinition, TBridgeExchange>;
|
|
2163
|
+
/**
|
|
2164
|
+
* Create a consumer that subscribes to an event from a headers exchange via a bridge exchange.
|
|
2165
|
+
*
|
|
2166
|
+
* When `bridgeExchange` is provided, the queue binds to the bridge exchange instead of the
|
|
2167
|
+
* source exchange, and an exchange-to-exchange binding is created from the source to the bridge.
|
|
2168
|
+
*
|
|
2169
|
+
* @param eventPublisher - The event publisher configuration
|
|
2170
|
+
* @param queue - The queue that will receive messages
|
|
2171
|
+
* @param options - Binding configuration with required bridgeExchange
|
|
2172
|
+
* @param options.bridgeExchange - The headers bridge exchange (must be headers to match source)
|
|
2173
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2174
|
+
* @returns An object with the consumer definition, queue binding, and exchange binding
|
|
2175
|
+
*/
|
|
2176
|
+
declare function defineEventConsumer<TMessage extends MessageDefinition, TExchange extends HeadersExchangeDefinition, TQueueEntry extends QueueEntry, TBridgeExchange extends HeadersExchangeDefinition>(eventPublisher: EventPublisherConfig<TMessage, TExchange, undefined>, queue: TQueueEntry, options: {
|
|
2177
|
+
bridgeExchange: TBridgeExchange;
|
|
2178
|
+
arguments?: Record<string, unknown>;
|
|
2179
|
+
}): EventConsumerResult<TMessage, TExchange, TQueueEntry, ExchangeBindingDefinition, TBridgeExchange>;
|
|
2238
2180
|
/**
|
|
2239
2181
|
* Create a consumer that subscribes to an event from a direct exchange via a bridge exchange.
|
|
2240
2182
|
*
|
|
@@ -2242,12 +2184,13 @@ declare function defineEventConsumer<TMessage extends MessageDefinition, TExchan
|
|
|
2242
2184
|
* @param queue - The queue that will receive messages
|
|
2243
2185
|
* @param options - Binding configuration with required bridgeExchange
|
|
2244
2186
|
* @param options.bridgeExchange - The bridge exchange (must be direct or topic to preserve routing keys)
|
|
2187
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2245
2188
|
* @returns An object with the consumer definition, queue binding, and exchange binding
|
|
2246
2189
|
*/
|
|
2247
2190
|
declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TExchange extends DirectExchangeDefinition, TQueueEntry extends QueueEntry, TBridgeExchange extends DirectExchangeDefinition | TopicExchangeDefinition>(eventPublisher: EventPublisherConfig<TMessage, TExchange, TRoutingKey>, queue: TQueueEntry, options: {
|
|
2248
2191
|
bridgeExchange: TBridgeExchange;
|
|
2249
2192
|
arguments?: Record<string, unknown>;
|
|
2250
|
-
}): EventConsumerResult<TMessage, TExchange,
|
|
2193
|
+
}): EventConsumerResult<TMessage, TExchange, TQueueEntry, ExchangeBindingDefinition, TBridgeExchange>;
|
|
2251
2194
|
/**
|
|
2252
2195
|
* Create a consumer that subscribes to an event from a topic exchange via a bridge exchange.
|
|
2253
2196
|
*
|
|
@@ -2256,19 +2199,21 @@ declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutin
|
|
|
2256
2199
|
* @param options - Binding configuration with required bridgeExchange
|
|
2257
2200
|
* @param options.bridgeExchange - The bridge exchange (must be direct or topic to preserve routing keys)
|
|
2258
2201
|
* @param options.routingKey - Override routing key with pattern (defaults to publisher's key)
|
|
2202
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2259
2203
|
* @returns An object with the consumer definition, queue binding, and exchange binding
|
|
2260
2204
|
*/
|
|
2261
2205
|
declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TExchange extends TopicExchangeDefinition, TQueueEntry extends QueueEntry, TBridgeExchange extends DirectExchangeDefinition | TopicExchangeDefinition, TConsumerRoutingKey extends string = TRoutingKey>(eventPublisher: EventPublisherConfig<TMessage, TExchange, TRoutingKey>, queue: TQueueEntry, options: {
|
|
2262
2206
|
bridgeExchange: TBridgeExchange;
|
|
2263
2207
|
routingKey?: BindingPattern<TConsumerRoutingKey>;
|
|
2264
2208
|
arguments?: Record<string, unknown>;
|
|
2265
|
-
}): EventConsumerResult<TMessage, TExchange,
|
|
2209
|
+
}): EventConsumerResult<TMessage, TExchange, TQueueEntry, ExchangeBindingDefinition, TBridgeExchange>;
|
|
2266
2210
|
/**
|
|
2267
2211
|
* Create a consumer that subscribes to an event from a fanout exchange.
|
|
2268
2212
|
*
|
|
2269
2213
|
* @param eventPublisher - The event publisher configuration
|
|
2270
2214
|
* @param queue - The queue that will receive messages
|
|
2271
2215
|
* @param options - Optional binding configuration
|
|
2216
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2272
2217
|
* @returns An object with the consumer definition and binding
|
|
2273
2218
|
*
|
|
2274
2219
|
* @example
|
|
@@ -2279,18 +2224,37 @@ declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutin
|
|
|
2279
2224
|
*/
|
|
2280
2225
|
declare function defineEventConsumer<TMessage extends MessageDefinition, TExchange extends FanoutExchangeDefinition, TQueueEntry extends QueueEntry>(eventPublisher: EventPublisherConfig<TMessage, TExchange, undefined>, queue: TQueueEntry, options?: {
|
|
2281
2226
|
arguments?: Record<string, unknown>;
|
|
2282
|
-
}): EventConsumerResult<TMessage, TExchange,
|
|
2227
|
+
}): EventConsumerResult<TMessage, TExchange, TQueueEntry>;
|
|
2228
|
+
/**
|
|
2229
|
+
* Create a consumer that subscribes to an event from a headers exchange.
|
|
2230
|
+
*
|
|
2231
|
+
* @param eventPublisher - The event publisher configuration
|
|
2232
|
+
* @param queue - The queue that will receive messages
|
|
2233
|
+
* @param options - Optional binding configuration
|
|
2234
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2235
|
+
* @returns An object with the consumer definition and binding
|
|
2236
|
+
*
|
|
2237
|
+
* @example
|
|
2238
|
+
* ```typescript
|
|
2239
|
+
* const logEvent = defineEventPublisher(logsExchange, logMessage);
|
|
2240
|
+
* const { consumer, binding } = defineEventConsumer(logEvent, logsQueue);
|
|
2241
|
+
* ```
|
|
2242
|
+
*/
|
|
2243
|
+
declare function defineEventConsumer<TMessage extends MessageDefinition, TExchange extends HeadersExchangeDefinition, TQueueEntry extends QueueEntry>(eventPublisher: EventPublisherConfig<TMessage, TExchange, undefined>, queue: TQueueEntry, options?: {
|
|
2244
|
+
arguments?: Record<string, unknown>;
|
|
2245
|
+
}): EventConsumerResult<TMessage, TExchange, TQueueEntry>;
|
|
2283
2246
|
/**
|
|
2284
2247
|
* Create a consumer that subscribes to an event from a direct exchange.
|
|
2285
2248
|
*
|
|
2286
2249
|
* @param eventPublisher - The event publisher configuration
|
|
2287
2250
|
* @param queue - The queue that will receive messages
|
|
2288
2251
|
* @param options - Optional binding configuration
|
|
2252
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2289
2253
|
* @returns An object with the consumer definition and binding
|
|
2290
2254
|
*/
|
|
2291
2255
|
declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TExchange extends DirectExchangeDefinition, TQueueEntry extends QueueEntry>(eventPublisher: EventPublisherConfig<TMessage, TExchange, TRoutingKey>, queue: TQueueEntry, options?: {
|
|
2292
2256
|
arguments?: Record<string, unknown>;
|
|
2293
|
-
}): EventConsumerResult<TMessage, TExchange,
|
|
2257
|
+
}): EventConsumerResult<TMessage, TExchange, TQueueEntry>;
|
|
2294
2258
|
/**
|
|
2295
2259
|
* Create a consumer that subscribes to an event from a topic exchange.
|
|
2296
2260
|
*
|
|
@@ -2301,6 +2265,7 @@ declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutin
|
|
|
2301
2265
|
* @param queue - The queue that will receive messages
|
|
2302
2266
|
* @param options - Optional binding configuration
|
|
2303
2267
|
* @param options.routingKey - Override routing key with pattern (defaults to publisher's key)
|
|
2268
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2304
2269
|
* @returns An object with the consumer definition and binding
|
|
2305
2270
|
*
|
|
2306
2271
|
* @example
|
|
@@ -2321,7 +2286,7 @@ declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutin
|
|
|
2321
2286
|
declare function defineEventConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TExchange extends TopicExchangeDefinition, TQueueEntry extends QueueEntry, TConsumerRoutingKey extends string = TRoutingKey>(eventPublisher: EventPublisherConfig<TMessage, TExchange, TRoutingKey>, queue: TQueueEntry, options?: {
|
|
2322
2287
|
routingKey?: BindingPattern<TConsumerRoutingKey>;
|
|
2323
2288
|
arguments?: Record<string, unknown>;
|
|
2324
|
-
}): EventConsumerResult<TMessage, TExchange,
|
|
2289
|
+
}): EventConsumerResult<TMessage, TExchange, TQueueEntry>;
|
|
2325
2290
|
/**
|
|
2326
2291
|
* Type guard to check if a value is an EventPublisherConfig.
|
|
2327
2292
|
*
|
|
@@ -2346,15 +2311,14 @@ declare function isEventConsumerResult(value: unknown): value is EventConsumerRe
|
|
|
2346
2311
|
*
|
|
2347
2312
|
* @template TMessage - The message definition
|
|
2348
2313
|
* @template TExchange - The exchange definition
|
|
2349
|
-
* @template TRoutingKey - The routing key type (undefined for fanout)
|
|
2314
|
+
* @template TRoutingKey - The routing key type (undefined for fanout and headers exchanges)
|
|
2350
2315
|
*/
|
|
2351
|
-
type CommandConsumerConfig<TMessage extends MessageDefinition, TExchange extends ExchangeDefinition, TRoutingKey extends string | undefined = undefined, TQueue extends
|
|
2316
|
+
type CommandConsumerConfig<TMessage extends MessageDefinition, TExchange extends ExchangeDefinition, TRoutingKey extends string | undefined = undefined, TQueue extends QueueEntry = QueueEntry> = {
|
|
2352
2317
|
/** Discriminator to identify this as a command consumer config */__brand: "CommandConsumerConfig"; /** The consumer definition for processing commands */
|
|
2353
2318
|
consumer: ConsumerDefinition<TMessage>; /** The binding connecting the queue to the exchange */
|
|
2354
2319
|
binding: QueueBindingDefinition; /** The exchange that receives commands */
|
|
2355
2320
|
exchange: TExchange; /** The queue this consumer reads from */
|
|
2356
|
-
queue: TQueue; /** The
|
|
2357
|
-
deadLetterExchange: TDlxExchange; /** The message definition */
|
|
2321
|
+
queue: TQueue; /** The message definition */
|
|
2358
2322
|
message: TMessage; /** The routing key pattern for the binding */
|
|
2359
2323
|
routingKey: TRoutingKey;
|
|
2360
2324
|
};
|
|
@@ -2384,11 +2348,41 @@ type BridgedPublisherConfig<TMessage extends MessageDefinition, TBridgeExchange
|
|
|
2384
2348
|
* @param queue - The queue that will receive commands
|
|
2385
2349
|
* @param exchange - The fanout exchange that routes commands
|
|
2386
2350
|
* @param message - The message definition (schema and metadata)
|
|
2351
|
+
* @param options - Optional binding configuration
|
|
2352
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2353
|
+
* @returns A command consumer configuration
|
|
2354
|
+
*
|
|
2355
|
+
* @example
|
|
2356
|
+
* ```typescript
|
|
2357
|
+
* const tasksExchange = defineExchange('tasks', { type: 'fanout' });
|
|
2358
|
+
* const taskMessage = defineMessage(z.object({ taskId: z.string() }));
|
|
2359
|
+
*
|
|
2360
|
+
* // Consumer owns the queue
|
|
2361
|
+
* const executeTask = defineCommandConsumer(taskQueue, tasksExchange, taskMessage);
|
|
2362
|
+
*
|
|
2363
|
+
* // Publishers send commands to it
|
|
2364
|
+
* const sendTask = defineCommandPublisher(executeTask);
|
|
2365
|
+
* ```
|
|
2366
|
+
*/
|
|
2367
|
+
declare function defineCommandConsumer<TMessage extends MessageDefinition, TQueueEntry extends QueueEntry, TExchange extends FanoutExchangeDefinition>(queue: TQueueEntry, exchange: TExchange, message: TMessage, options?: {
|
|
2368
|
+
arguments?: Record<string, unknown>;
|
|
2369
|
+
}): CommandConsumerConfig<TMessage, TExchange, undefined, TQueueEntry>;
|
|
2370
|
+
/**
|
|
2371
|
+
* Define a command consumer for receiving commands via headers exchange.
|
|
2372
|
+
*
|
|
2373
|
+
* Commands are sent by publishers to a specific queue. The consumer "owns" the
|
|
2374
|
+
* queue and defines what commands it accepts.
|
|
2375
|
+
*
|
|
2376
|
+
* @param queue - The queue that will receive commands
|
|
2377
|
+
* @param exchange - The headers exchange that routes commands
|
|
2378
|
+
* @param message - The message definition (schema and metadata)
|
|
2379
|
+
* @param options - Optional binding configuration
|
|
2380
|
+
* @param options.arguments - Additional AMQP arguments
|
|
2387
2381
|
* @returns A command consumer configuration
|
|
2388
2382
|
*
|
|
2389
2383
|
* @example
|
|
2390
2384
|
* ```typescript
|
|
2391
|
-
* const tasksExchange = defineExchange('tasks',
|
|
2385
|
+
* const tasksExchange = defineExchange('tasks', { type: 'headers' });
|
|
2392
2386
|
* const taskMessage = defineMessage(z.object({ taskId: z.string() }));
|
|
2393
2387
|
*
|
|
2394
2388
|
* // Consumer owns the queue
|
|
@@ -2398,7 +2392,9 @@ type BridgedPublisherConfig<TMessage extends MessageDefinition, TBridgeExchange
|
|
|
2398
2392
|
* const sendTask = defineCommandPublisher(executeTask);
|
|
2399
2393
|
* ```
|
|
2400
2394
|
*/
|
|
2401
|
-
declare function defineCommandConsumer<TMessage extends MessageDefinition, TQueueEntry extends QueueEntry, TExchange extends
|
|
2395
|
+
declare function defineCommandConsumer<TMessage extends MessageDefinition, TQueueEntry extends QueueEntry, TExchange extends HeadersExchangeDefinition>(queue: TQueueEntry, exchange: TExchange, message: TMessage, options?: {
|
|
2396
|
+
arguments?: Record<string, unknown>;
|
|
2397
|
+
}): CommandConsumerConfig<TMessage, TExchange, undefined, TQueueEntry>;
|
|
2402
2398
|
/**
|
|
2403
2399
|
* Define a command consumer for receiving commands via direct exchange.
|
|
2404
2400
|
*
|
|
@@ -2415,7 +2411,7 @@ declare function defineCommandConsumer<TMessage extends MessageDefinition, TQueu
|
|
|
2415
2411
|
*
|
|
2416
2412
|
* @example
|
|
2417
2413
|
* ```typescript
|
|
2418
|
-
* const tasksExchange = defineExchange('tasks',
|
|
2414
|
+
* const tasksExchange = defineExchange('tasks', { type: 'direct' });
|
|
2419
2415
|
* const taskMessage = defineMessage(z.object({ taskId: z.string() }));
|
|
2420
2416
|
*
|
|
2421
2417
|
* const executeTask = defineCommandConsumer(taskQueue, tasksExchange, taskMessage, {
|
|
@@ -2428,7 +2424,7 @@ declare function defineCommandConsumer<TMessage extends MessageDefinition, TQueu
|
|
|
2428
2424
|
declare function defineCommandConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TQueueEntry extends QueueEntry, TExchange extends DirectExchangeDefinition>(queue: TQueueEntry, exchange: TExchange, message: TMessage, options: {
|
|
2429
2425
|
routingKey: RoutingKey<TRoutingKey>;
|
|
2430
2426
|
arguments?: Record<string, unknown>;
|
|
2431
|
-
}): CommandConsumerConfig<TMessage, TExchange, TRoutingKey,
|
|
2427
|
+
}): CommandConsumerConfig<TMessage, TExchange, TRoutingKey, TQueueEntry>;
|
|
2432
2428
|
/**
|
|
2433
2429
|
* Define a command consumer for receiving commands via topic exchange.
|
|
2434
2430
|
*
|
|
@@ -2445,7 +2441,7 @@ declare function defineCommandConsumer<TMessage extends MessageDefinition, TRout
|
|
|
2445
2441
|
*
|
|
2446
2442
|
* @example
|
|
2447
2443
|
* ```typescript
|
|
2448
|
-
* const ordersExchange = defineExchange('orders',
|
|
2444
|
+
* const ordersExchange = defineExchange('orders', { type: 'topic' });
|
|
2449
2445
|
* const orderMessage = defineMessage(z.object({ orderId: z.string() }));
|
|
2450
2446
|
*
|
|
2451
2447
|
* // Consumer uses pattern to receive multiple command types
|
|
@@ -2465,18 +2461,29 @@ declare function defineCommandConsumer<TMessage extends MessageDefinition, TRout
|
|
|
2465
2461
|
declare function defineCommandConsumer<TMessage extends MessageDefinition, TRoutingKey extends string, TQueueEntry extends QueueEntry, TExchange extends TopicExchangeDefinition>(queue: TQueueEntry, exchange: TExchange, message: TMessage, options: {
|
|
2466
2462
|
routingKey: BindingPattern<TRoutingKey>;
|
|
2467
2463
|
arguments?: Record<string, unknown>;
|
|
2468
|
-
}): CommandConsumerConfig<TMessage, TExchange, TRoutingKey,
|
|
2464
|
+
}): CommandConsumerConfig<TMessage, TExchange, TRoutingKey, TQueueEntry>;
|
|
2469
2465
|
/**
|
|
2470
2466
|
* Create a bridged publisher that sends commands to a fanout exchange consumer via a bridge exchange.
|
|
2471
2467
|
*
|
|
2472
2468
|
* @param commandConsumer - The command consumer configuration
|
|
2473
2469
|
* @param options - Configuration with required bridgeExchange
|
|
2474
|
-
* @param options.bridgeExchange - The local domain exchange to bridge through
|
|
2470
|
+
* @param options.bridgeExchange - The local domain exchange to bridge through (must be fanout to match target)
|
|
2475
2471
|
* @returns A bridged publisher configuration
|
|
2476
2472
|
*/
|
|
2477
2473
|
declare function defineCommandPublisher<TMessage extends MessageDefinition, TExchange extends FanoutExchangeDefinition, TBridgeExchange extends FanoutExchangeDefinition>(commandConsumer: CommandConsumerConfig<TMessage, TExchange, undefined>, options: {
|
|
2478
2474
|
bridgeExchange: TBridgeExchange;
|
|
2479
2475
|
}): BridgedPublisherConfig<TMessage, TBridgeExchange, TExchange>;
|
|
2476
|
+
/**
|
|
2477
|
+
* Create a bridged publisher that sends commands to a headers exchange consumer via a bridge exchange.
|
|
2478
|
+
*
|
|
2479
|
+
* @param commandConsumer - The command consumer configuration
|
|
2480
|
+
* @param options - Configuration with required bridgeExchange
|
|
2481
|
+
* @param options.bridgeExchange - The local domain exchange to bridge through (must be headers to match target)
|
|
2482
|
+
* @returns A bridged publisher configuration
|
|
2483
|
+
*/
|
|
2484
|
+
declare function defineCommandPublisher<TMessage extends MessageDefinition, TExchange extends HeadersExchangeDefinition, TBridgeExchange extends HeadersExchangeDefinition>(commandConsumer: CommandConsumerConfig<TMessage, TExchange, undefined>, options: {
|
|
2485
|
+
bridgeExchange: TBridgeExchange;
|
|
2486
|
+
}): BridgedPublisherConfig<TMessage, TBridgeExchange, TExchange>;
|
|
2480
2487
|
/**
|
|
2481
2488
|
* Create a bridged publisher that sends commands to a direct exchange consumer via a bridge exchange.
|
|
2482
2489
|
*
|
|
@@ -2517,6 +2524,22 @@ declare function defineCommandPublisher<TMessage extends MessageDefinition>(comm
|
|
|
2517
2524
|
message: TMessage;
|
|
2518
2525
|
exchange: FanoutExchangeDefinition;
|
|
2519
2526
|
};
|
|
2527
|
+
/**
|
|
2528
|
+
* Create a publisher that sends commands to a headers exchange consumer.
|
|
2529
|
+
*
|
|
2530
|
+
* @param commandConsumer - The command consumer configuration
|
|
2531
|
+
* @returns A publisher definition
|
|
2532
|
+
*
|
|
2533
|
+
* @example
|
|
2534
|
+
* ```typescript
|
|
2535
|
+
* const executeTask = defineCommandConsumer(taskQueue, headersExchange, taskMessage);
|
|
2536
|
+
* const sendTask = defineCommandPublisher(executeTask);
|
|
2537
|
+
* ```
|
|
2538
|
+
*/
|
|
2539
|
+
declare function defineCommandPublisher<TMessage extends MessageDefinition>(commandConsumer: CommandConsumerConfig<TMessage, HeadersExchangeDefinition, undefined>): {
|
|
2540
|
+
message: TMessage;
|
|
2541
|
+
exchange: HeadersExchangeDefinition;
|
|
2542
|
+
};
|
|
2520
2543
|
/**
|
|
2521
2544
|
* Create a publisher that sends commands to a direct exchange consumer.
|
|
2522
2545
|
*
|
|
@@ -2535,7 +2558,7 @@ declare function defineCommandPublisher<TMessage extends MessageDefinition, TRou
|
|
|
2535
2558
|
* optionally specify a concrete routing key that matches the pattern.
|
|
2536
2559
|
*
|
|
2537
2560
|
* @param commandConsumer - The command consumer configuration
|
|
2538
|
-
* @param options - Optional
|
|
2561
|
+
* @param options - Optional binding configuration
|
|
2539
2562
|
* @param options.routingKey - Override routing key (must match consumer's pattern)
|
|
2540
2563
|
* @returns A publisher definition
|
|
2541
2564
|
*
|
|
@@ -2574,72 +2597,84 @@ declare function isCommandConsumerConfig(value: unknown): value is CommandConsum
|
|
|
2574
2597
|
*/
|
|
2575
2598
|
declare function isBridgedPublisherConfig(value: unknown): value is BridgedPublisherConfig<MessageDefinition, ExchangeDefinition, ExchangeDefinition>;
|
|
2576
2599
|
//#endregion
|
|
2577
|
-
//#region src/builder/
|
|
2600
|
+
//#region src/builder/rpc.d.ts
|
|
2578
2601
|
/**
|
|
2579
|
-
*
|
|
2602
|
+
* Define an RPC operation: a request/response pair flowing over a request
|
|
2603
|
+
* queue with replies routed back via RabbitMQ direct reply-to.
|
|
2604
|
+
*
|
|
2605
|
+
* RPC is bidirectional on both ends — the worker handler consumes the request
|
|
2606
|
+
* and produces the response; `client.call(name, request, options)` publishes
|
|
2607
|
+
* the request and awaits the typed response. Both sides share the same
|
|
2608
|
+
* definition, so request and response schemas cannot drift between them.
|
|
2609
|
+
*
|
|
2610
|
+
* Plug the result into `defineContract({ rpcs: { name: ... } })`. RPCs do not
|
|
2611
|
+
* appear in `publishers` or `consumers`.
|
|
2612
|
+
*
|
|
2613
|
+
* @param queue - The queue that receives RPC requests. The queue name is
|
|
2614
|
+
* used as the routing key on the AMQP default direct exchange.
|
|
2615
|
+
* @param messages.request - Schema validated against incoming request payloads
|
|
2616
|
+
* (server side) and outgoing requests (client side).
|
|
2617
|
+
* @param messages.response - Schema validated against handler return values
|
|
2618
|
+
* (server side) and incoming replies (client side).
|
|
2619
|
+
*
|
|
2620
|
+
* @example
|
|
2621
|
+
* ```typescript
|
|
2622
|
+
* import { defineQueue, defineMessage, defineRpc, defineContract } from '@amqp-contract/contract';
|
|
2623
|
+
* import { z } from 'zod';
|
|
2624
|
+
*
|
|
2625
|
+
* const calculate = defineRpc(defineQueue('rpc.calculate'), {
|
|
2626
|
+
* request: defineMessage(z.object({ a: z.number(), b: z.number() })),
|
|
2627
|
+
* response: defineMessage(z.object({ sum: z.number() })),
|
|
2628
|
+
* });
|
|
2629
|
+
*
|
|
2630
|
+
* const contract = defineContract({ rpcs: { calculate } });
|
|
2580
2631
|
*
|
|
2581
|
-
*
|
|
2632
|
+
* // Server (worker): handler returns the typed response
|
|
2633
|
+
* // handlers: { calculate: ({ payload }) => Future.value(Result.Ok({ sum: payload.a + payload.b })) }
|
|
2634
|
+
*
|
|
2635
|
+
* // Client: typed call with required timeout
|
|
2636
|
+
* // const result = await client.call('calculate', { a: 1, b: 2 }, { timeoutMs: 5_000 }).toPromise();
|
|
2637
|
+
* ```
|
|
2582
2638
|
*/
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
/**
|
|
2590
|
-
* Binding that routes failed messages to the wait queue.
|
|
2591
|
-
*/
|
|
2592
|
-
waitQueueBinding: QueueBindingDefinition;
|
|
2593
|
-
/**
|
|
2594
|
-
* Binding that routes retried messages back to the main queue.
|
|
2595
|
-
*/
|
|
2596
|
-
mainQueueRetryBinding: QueueBindingDefinition;
|
|
2597
|
-
};
|
|
2639
|
+
declare function defineRpc<TRequestMessage extends MessageDefinition, TResponseMessage extends MessageDefinition, TQueue extends QueueEntry>(queue: TQueue, messages: {
|
|
2640
|
+
request: TRequestMessage;
|
|
2641
|
+
response: TResponseMessage;
|
|
2642
|
+
}): RpcDefinition<TRequestMessage, TResponseMessage, TQueue>;
|
|
2643
|
+
//#endregion
|
|
2644
|
+
//#region src/builder/ttl-backoff.d.ts
|
|
2598
2645
|
/**
|
|
2599
|
-
*
|
|
2646
|
+
* Type guard to check if a queue entry is a QueueWithTtlBackoffInfrastructure.
|
|
2647
|
+
*
|
|
2648
|
+
* When you configure a queue with TTL-backoff retry,
|
|
2649
|
+
* `defineQueue` returns a `QueueWithTtlBackoffInfrastructure` instead of a plain
|
|
2650
|
+
* `QueueDefinition`. This type guard helps you distinguish between the two.
|
|
2600
2651
|
*
|
|
2601
|
-
*
|
|
2602
|
-
*
|
|
2652
|
+
* **When to use:**
|
|
2653
|
+
* - When you need to check the type of a queue entry at runtime
|
|
2654
|
+
* - When writing generic code that handles both plain queues and infrastructure wrappers
|
|
2603
2655
|
*
|
|
2604
|
-
*
|
|
2605
|
-
*
|
|
2606
|
-
* 2. The wait queue receives these messages and holds them for a TTL period
|
|
2607
|
-
* 3. After TTL expires, messages are dead-lettered back to the DLX with routing key `{queueName}`
|
|
2608
|
-
* 4. The main queue receives the retried message via its binding to the DLX
|
|
2656
|
+
* **Related functions:**
|
|
2657
|
+
* - `extractQueue()` - Use this to get the underlying queue definition from either type
|
|
2609
2658
|
*
|
|
2610
|
-
* @param
|
|
2611
|
-
* @
|
|
2612
|
-
* @param options.waitQueueDurable - Whether the wait queue should be durable (default: same as main queue)
|
|
2613
|
-
* @returns TTL-backoff retry infrastructure containing wait queue and bindings
|
|
2614
|
-
* @throws {Error} If the queue does not have a dead letter exchange configured
|
|
2659
|
+
* @param entry - The queue entry to check
|
|
2660
|
+
* @returns True if the entry is a QueueWithTtlBackoffInfrastructure, false otherwise
|
|
2615
2661
|
*
|
|
2616
2662
|
* @example
|
|
2617
2663
|
* ```typescript
|
|
2618
|
-
* const
|
|
2619
|
-
*
|
|
2620
|
-
* type: 'quorum',
|
|
2621
|
-
* deadLetter: { exchange: dlx },
|
|
2622
|
-
* retry: {
|
|
2623
|
-
* mode: 'ttl-backoff',
|
|
2624
|
-
* maxRetries: 5,
|
|
2625
|
-
* initialDelayMs: 1000,
|
|
2626
|
-
* },
|
|
2627
|
-
* });
|
|
2628
|
-
*
|
|
2629
|
-
* // Infrastructure is auto-extracted when using defineContract:
|
|
2630
|
-
* const contract = defineContract({
|
|
2631
|
-
* publishers: { ... },
|
|
2632
|
-
* consumers: { processOrder: defineEventConsumer(event, extractQueue(orderQueue)) },
|
|
2664
|
+
* const queue = defineQueue('orders', {
|
|
2665
|
+
* retry: { mode: 'ttl-backoff' },
|
|
2633
2666
|
* });
|
|
2634
|
-
* // contract.queues includes the wait queue, contract.bindings includes retry bindings
|
|
2635
2667
|
*
|
|
2636
|
-
*
|
|
2637
|
-
*
|
|
2668
|
+
* if (isQueueWithTtlBackoffInfrastructure(queue)) {
|
|
2669
|
+
* // queue has .queue, .waitQueue, .waitQueueBinding, .retryQueueBinding, .waitExchange, .retryExchange
|
|
2670
|
+
* console.log('Wait queue:', queue.waitQueue.name);
|
|
2671
|
+
* } else {
|
|
2672
|
+
* // queue is a plain QueueDefinition
|
|
2673
|
+
* console.log('Queue:', queue.name);
|
|
2674
|
+
* }
|
|
2638
2675
|
* ```
|
|
2639
2676
|
*/
|
|
2640
|
-
declare function
|
|
2641
|
-
waitQueueDurable?: boolean;
|
|
2642
|
-
}): TtlBackoffRetryInfrastructure;
|
|
2677
|
+
declare function isQueueWithTtlBackoffInfrastructure(entry: QueueEntry): entry is QueueWithTtlBackoffInfrastructure;
|
|
2643
2678
|
//#endregion
|
|
2644
|
-
export { type AnySchema, type BaseExchangeDefinition, type BindingDefinition, type BindingPattern, type BridgedPublisherConfig, type BridgedPublisherConfigBase, type ClassicQueueDefinition, type ClassicQueueOptions, type CommandConsumerConfig, type CommandConsumerConfigBase, type CompressionAlgorithm, type ConsumerDefinition, type ConsumerEntry, type ContractDefinition, type ContractDefinitionInput, type ContractOutput, type DeadLetterConfig, type DefineQueueOptions, type
|
|
2679
|
+
export { type AnySchema, type BaseExchangeDefinition, type BindingDefinition, type BindingPattern, type BridgedPublisherConfig, type BridgedPublisherConfigBase, type ClassicQueueDefinition, type ClassicQueueOptions, type CommandConsumerConfig, type CommandConsumerConfigBase, type CompressionAlgorithm, type ConsumerDefinition, type ConsumerEntry, type ContractDefinition, type ContractDefinitionInput, type ContractOutput, type DeadLetterConfig, type DefineQueueOptions, type DirectExchangeDefinition, type EventConsumerResult, type EventConsumerResultBase, type EventPublisherConfig, type EventPublisherConfigBase, type ExchangeBindingDefinition, type ExchangeDefinition, type FanoutExchangeDefinition, type HeadersExchangeDefinition, type ImmediateRequeueRetryOptions, type InferConsumerNames, type InferPublisherNames, type InferRpcNames, type MatchingRoutingKey, type MessageDefinition, type PublisherDefinition, type PublisherEntry, type QueueBindingDefinition, type QueueDefinition, type QueueEntry, type QueueType, type QueueWithTtlBackoffInfrastructure, type QuorumQueueDefinition, type QuorumQueueOptions, type ResolvedImmediateRequeueRetryOptions, type ResolvedRetryOptions, type ResolvedTtlBackoffRetryOptions, type RoutingKey, type RpcDefinition, type TopicExchangeDefinition, type TtlBackoffRetryOptions, defineCommandConsumer, defineCommandPublisher, defineConsumer, defineContract, defineEventConsumer, defineEventPublisher, defineExchange, defineExchangeBinding, defineMessage, definePublisher, defineQueue, defineQueueBinding, defineRpc, extractConsumer, extractQueue, isBridgedPublisherConfig, isCommandConsumerConfig, isEventConsumerResult, isEventPublisherConfig, isQueueWithTtlBackoffInfrastructure };
|
|
2645
2680
|
//# sourceMappingURL=index.d.cts.map
|