@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/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
- * Quorum-Native retry options using RabbitMQ's native delivery limit feature.
71
+ * Immediate-Requeue retry options.
56
72
  *
57
- * Uses quorum queue's `x-delivery-limit` feature. Messages are requeued immediately
58
- * with `nack(requeue=true)`, and RabbitMQ tracks delivery count via `x-delivery-count`
59
- * header. When the count exceeds the queue's `deliveryLimit`, the message is
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 QuorumNativeRetryOptions = {
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
- * Quorum-Native mode uses RabbitMQ's native delivery limit feature.
70
- * Requires the queue to be a quorum queue with `deliveryLimit` configured.
101
+ * None mode disables retry attempts entirely.
71
102
  */
72
- mode: "quorum-native";
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
- * - `ttl-backoff`: Has all TTL-backoff options with defaults applied
95
- * - `quorum-native`: No additional options (uses RabbitMQ native retry)
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 = ResolvedTtlBackoffRetryOptions | QuorumNativeRetryOptions;
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 require `durable: true` and do not support `exclusive: true`.
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 exclusive access
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 via `deliveryLimit`:
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
- * deliveryLimit: 3, // Message dead-lettered after 3 delivery attempts
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: true` - For connection-scoped queues
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 false
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 fanout exchange definition.
391
+ * A topic exchange definition.
381
392
  *
382
- * Fanout exchanges broadcast all messages to all bound queues, ignoring routing keys.
383
- * This is the simplest exchange type for pub/sub messaging patterns.
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 logsExchange: FanoutExchangeDefinition = defineExchange('logs', 'fanout', {
388
- * durable: true
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 FanoutExchangeDefinition<TName extends string = string> = BaseExchangeDefinition<TName> & {
393
- type: "fanout";
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', 'direct', {
404
- * durable: true
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 topic exchange definition.
427
+ * A fanout exchange definition.
413
428
  *
414
- * Topic exchanges route messages to queues based on routing key patterns with wildcards:
415
- * - `*` (star) matches exactly one word
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
- * Words are separated by dots (e.g., `order.created.high-value`).
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 ordersExchange: TopicExchangeDefinition = defineExchange('orders', 'topic', {
423
- * durable: true
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 TopicExchangeDefinition<TName extends string = string> = BaseExchangeDefinition<TName> & {
429
- type: "topic";
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: fanout, direct, or topic.
461
+ * Represents any type of AMQP exchange: topic, direct, fanout, headers.
435
462
  */
436
- type ExchangeDefinition<TName extends string = string> = FanoutExchangeDefinition<TName> | DirectExchangeDefinition<TName> | TopicExchangeDefinition<TName>;
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
- * Classic queues do not support delivery limits.
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
- deliveryLimit?: never;
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
- * Retry configuration for handling failed message processing.
562
- *
563
- * Classic queues only support TTL-backoff retry mode (default).
564
- * When the queue is created, defaults are applied.
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
- retry: ResolvedTtlBackoffRetryOptions;
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
- * with a dead letter exchange. When passed to `defineContract`, the wait queue
583
- * and bindings are automatically added to the contract.
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 dlx = defineExchange('orders-dlx', 'direct', { durable: true });
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, bindings, and DLX exchange are automatically extracted
601
+ * // Wait queue, exchanges, and bindings are automatically extracted
598
602
  * const contract = defineContract({
599
603
  * publishers: { orderCreated },
600
- * consumers: { processOrder: defineEventConsumer(orderCreated, extractQueue(queue)) },
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 retried messages back to the main queue.
635
+ * Binding that routes messages to retry back to the main queue.
629
636
  */
630
- mainQueueRetryBinding: QueueBindingDefinition;
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 as all messages are broadcast.
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 - all bound queues receive the message */
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: QueueDefinition; /** The message definition including the payload schema */
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: QueueDefinition;
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: QueueDefinition;
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 : undefined : undefined;
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 extends EventConsumerResultBase | CommandConsumerConfigBase ? T["deadLetterExchange"] extends ExchangeDefinition ? T["deadLetterExchange"] : never : T extends ConsumerDefinition ? T["queue"] extends {
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]>["name"]]: 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 FanoutExchangeDefinition ? {
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?: never;
1125
+ routingKey: T["routingKey"] & string;
1080
1126
  } : {
1081
1127
  exchange: T["exchange"];
1082
- routingKey: T["routingKey"] & string;
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 fanout exchange.
1258
+ * Define a topic exchange.
1192
1259
  *
1193
- * A fanout exchange routes messages to all bound queues without considering routing keys.
1194
- * This exchange type is ideal for broadcasting messages to multiple consumers.
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.durable - If true, the exchange survives broker restarts (default: false)
1200
- * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)
1201
- * @param options.internal - If true, the exchange cannot be directly published to (default: false)
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 fanout exchange definition
1271
+ * @returns A topic exchange definition
1204
1272
  *
1205
1273
  * @example
1206
1274
  * ```typescript
1207
- * const logsExchange = defineExchange('logs', 'fanout', {
1208
- * durable: true
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, type: "fanout", options?: Omit<BaseExchangeDefinition, "name" | "type">): FanoutExchangeDefinition<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 type - Must be "direct"
1221
- * @param options - Optional exchange configuration
1222
- * @param options.durable - If true, the exchange survives broker restarts (default: false)
1223
- * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)
1224
- * @param options.internal - If true, the exchange cannot be directly published to (default: false)
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, type: "direct", options?: Omit<BaseExchangeDefinition, "name" | "type">): DirectExchangeDefinition<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 topic exchange.
1308
+ * Define a fanout exchange.
1238
1309
  *
1239
- * A topic exchange routes messages to queues based on routing key patterns.
1240
- * Routing keys can use wildcards: `*` matches one word, `#` matches zero or more words.
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 type - Must be "topic"
1245
- * @param options - Optional exchange configuration
1246
- * @param options.durable - If true, the exchange survives broker restarts (default: false)
1247
- * @param options.autoDelete - If true, the exchange is deleted when no queues are bound (default: false)
1248
- * @param options.internal - If true, the exchange cannot be directly published to (default: false)
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 topic exchange definition
1320
+ * @returns A fanout exchange definition
1251
1321
  *
1252
1322
  * @example
1253
1323
  * ```typescript
1254
- * const ordersExchange = defineExchange('orders', 'topic', {
1255
- * durable: true
1256
- * });
1324
+ * const logsExchange = defineExchange('logs', { type: 'fanout' });
1257
1325
  * ```
1258
1326
  */
1259
- declare function defineExchange<TName extends string>(name: TName, type: "topic", options?: Omit<BaseExchangeDefinition, "name" | "type">): TopicExchangeDefinition<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 are always durable.
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 (default: false)
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', 'topic', { durable: true });
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', 'direct', { durable: true });
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: DefineQueueOptions & {
1450
- deadLetter: {
1451
- exchange: TDlx;
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
- * Create a queue with TTL-backoff retry (exponential backoff).
1464
+ * Extract the plain QueueDefinition from a QueueEntry.
1574
1465
  *
1575
- * This is a simplified helper that enforces best practices:
1576
- * - Uses quorum queues (recommended for most use cases)
1577
- * - Requires dead letter exchange for retry routing
1578
- * - Uses TTL-backoff retry mode with configurable delays
1579
- * - Automatically generates wait queue and bindings
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
- * - You need exponential backoff between retries
1583
- * - You want configurable delays (initial delay, max delay, jitter)
1584
- * - You're processing messages that may need time before retry
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
- * **Returns:** A `QueueWithTtlBackoffInfrastructure` object that includes the
1587
- * main queue, wait queue, and bindings. Pass this directly to `defineContract`
1588
- * and it will be expanded automatically.
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 name - The queue name
1591
- * @param options - Configuration options
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
- * const dlx = defineExchange('orders-dlx', 'direct', { durable: true });
1486
+ * import { defineQueue, extractQueue } from '@amqp-contract/contract';
1597
1487
  *
1598
- * const orderQueue = defineTtlBackoffQueue('order-processing', {
1599
- * deadLetter: { exchange: dlx },
1600
- * maxRetries: 5,
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 in a contract wait queue, bindings, and DLX are auto-extracted
1606
- * const contract = defineContract({
1607
- * publishers: { ... },
1608
- * consumers: { processOrder: defineEventConsumer(event, extractQueue(orderQueue)) },
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
- * // To access the underlying queue definition (e.g., for the queue name):
1612
- * import { extractQueue } from '@amqp-contract/contract';
1613
- * const queueName = extractQueue(orderQueue).name;
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 defineQueue - For full queue configuration options
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 defineTtlBackoffQueue<TName extends string>(name: TName, options: DefineTtlBackoffQueueOptions): QueueWithTtlBackoffInfrastructure<TName>;
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 exchange to receive all messages published to the exchange.
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', { durable: true });
1638
- * const logsExchange = defineExchange('logs', 'fanout', { durable: true });
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', { durable: true });
1669
- * const ordersExchange = defineExchange('orders', 'topic', { durable: true });
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', 'fanout', { durable: true });
1703
- * const destExchange = defineExchange('all-logs', 'fanout', { durable: true });
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', 'topic', { durable: true });
1729
- * const importantExchange = defineExchange('important-orders', 'topic', { durable: true });
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', 'fanout', { durable: true });
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', 'topic', { durable: true });
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', { durable: true });
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', 'topic', { durable: true });
1974
- * const dlx = defineExchange('orders-dlx', 'direct', { durable: true });
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: 'quorum-native' },
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 QueueDefinition = QueueDefinition, TDlxExchange extends ExchangeDefinition | undefined = ExchangeDefinition | undefined, TExchangeBinding extends ExchangeBindingDefinition | undefined = ExchangeBindingDefinition | undefined, TBridgeExchange extends ExchangeDefinition | undefined = ExchangeDefinition | undefined> = {
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 dead letter exchange from the queue, if configured */
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', 'fanout', { durable: true });
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 FanoutExchangeDefinition>(exchange: TExchange, message: TMessage): EventPublisherConfig<TMessage, TExchange, undefined>;
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', 'direct', { durable: true });
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', 'topic', { durable: true });
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, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>, ExchangeBindingDefinition, TBridgeExchange>;
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, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>, ExchangeBindingDefinition, TBridgeExchange>;
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, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>, ExchangeBindingDefinition, TBridgeExchange>;
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, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
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, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
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, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
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 QueueDefinition = QueueDefinition, TDlxExchange extends ExchangeDefinition | undefined = ExchangeDefinition | undefined> = {
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 dead letter exchange from the queue, if configured */
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', 'fanout', { durable: true });
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 FanoutExchangeDefinition>(queue: TQueueEntry, exchange: TExchange, message: TMessage): CommandConsumerConfig<TMessage, TExchange, undefined, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
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', 'direct', { durable: true });
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, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
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', 'topic', { durable: true });
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, ExtractQueueFromEntry<TQueueEntry>, ExtractDlxFromEntry<TQueueEntry>>;
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 publisher configuration
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/ttl-backoff.d.ts
2600
+ //#region src/builder/rpc.d.ts
2578
2601
  /**
2579
- * Result type for TTL-backoff retry infrastructure builder.
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
- * Contains the wait queue and bindings needed for TTL-backoff retry.
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
- type TtlBackoffRetryInfrastructure = {
2584
- /**
2585
- * The wait queue for holding messages during backoff delay.
2586
- * This is a classic queue with a dead letter exchange pointing back to the main queue.
2587
- */
2588
- waitQueue: QueueDefinition;
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
- * Create TTL-backoff retry infrastructure for a queue.
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
- * This builder helper generates the wait queue and bindings needed for TTL-backoff retry.
2602
- * The generated infrastructure can be spread into a contract definition.
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
- * TTL-backoff retry works by:
2605
- * 1. Failed messages are sent to the DLX with routing key `{queueName}-wait`
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 queue - The main queue definition (must have deadLetter configured)
2611
- * @param options - Optional configuration for the wait queue
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 dlx = defineExchange('orders-dlx', 'direct', { durable: true });
2619
- * const orderQueue = defineQueue('order-processing', {
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
- * // Or generate manually for advanced use cases:
2637
- * const retryInfra = defineTtlBackoffRetryInfrastructure(orderQueue);
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 defineTtlBackoffRetryInfrastructure(queueEntry: QueueEntry, options?: {
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 DefineQuorumQueueOptions, type DefineTtlBackoffQueueOptions, type DirectExchangeDefinition, type EventConsumerResult, type EventConsumerResultBase, type EventPublisherConfig, type EventPublisherConfigBase, type ExchangeBindingDefinition, type ExchangeDefinition, type FanoutExchangeDefinition, type InferConsumerNames, type InferPublisherNames, type MatchingRoutingKey, type MessageDefinition, type PublisherDefinition, type PublisherEntry, type QueueBindingDefinition, type QueueDefinition, type QueueEntry, type QueueType, type QueueWithTtlBackoffInfrastructure, type QuorumNativeRetryOptions, type QuorumQueueDefinition, type QuorumQueueOptions, type ResolvedRetryOptions, type ResolvedTtlBackoffRetryOptions, type RoutingKey, type TopicExchangeDefinition, type TtlBackoffRetryInfrastructure, type TtlBackoffRetryOptions, defineCommandConsumer, defineCommandPublisher, defineConsumer, defineContract, defineEventConsumer, defineEventPublisher, defineExchange, defineExchangeBinding, defineMessage, definePublisher, defineQueue, defineQueueBinding, defineQuorumQueue, defineTtlBackoffQueue, defineTtlBackoffRetryInfrastructure, extractConsumer, extractQueue, isBridgedPublisherConfig, isCommandConsumerConfig, isEventConsumerResult, isEventPublisherConfig, isQueueWithTtlBackoffInfrastructure };
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