@amqp-contract/contract 0.10.0 → 0.12.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.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- //#region src/builder.ts
2
+ //#region src/builder/exchange.ts
3
3
  /**
4
4
  * Define an AMQP exchange.
5
5
  *
@@ -20,67 +20,9 @@ function defineExchange(name, type, options) {
20
20
  ...options
21
21
  };
22
22
  }
23
- /**
24
- * Define an AMQP queue.
25
- *
26
- * A queue stores messages until they are consumed by workers. Queues can be bound to exchanges
27
- * to receive messages based on routing rules.
28
- *
29
- * @param name - The name of the queue
30
- * @param options - Optional queue configuration
31
- * @param options.durable - If true, the queue survives broker restarts (default: false)
32
- * @param options.exclusive - If true, the queue can only be used by the declaring connection (default: false)
33
- * @param options.autoDelete - If true, the queue is deleted when the last consumer unsubscribes (default: false)
34
- * @param options.deadLetter - Dead letter configuration for handling failed messages
35
- * @param options.maxPriority - Maximum priority level for priority queue (1-255, recommended: 1-10). Sets x-max-priority argument.
36
- * @param options.arguments - Additional AMQP arguments (e.g., x-message-ttl)
37
- * @returns A queue definition
38
- *
39
- * @example
40
- * ```typescript
41
- * // Basic queue
42
- * const orderQueue = defineQueue('order-processing', {
43
- * durable: true,
44
- * });
45
- *
46
- * // Priority queue with max priority of 10
47
- * const taskQueue = defineQueue('urgent-tasks', {
48
- * durable: true,
49
- * maxPriority: 10,
50
- * });
51
- *
52
- * // Queue with dead letter exchange
53
- * const dlx = defineExchange('orders-dlx', 'topic', { durable: true });
54
- * const orderQueueWithDLX = defineQueue('order-processing', {
55
- * durable: true,
56
- * deadLetter: {
57
- * exchange: dlx,
58
- * routingKey: 'order.failed'
59
- * },
60
- * arguments: {
61
- * 'x-message-ttl': 86400000, // 24 hours
62
- * }
63
- * });
64
- * ```
65
- */
66
- function defineQueue(name, options) {
67
- const { maxPriority, ...queueOptions } = options ?? {};
68
- if (maxPriority !== void 0) {
69
- if (maxPriority < 1 || maxPriority > 255) throw new Error(`Invalid maxPriority: ${maxPriority}. Must be between 1 and 255. Recommended range: 1-10.`);
70
- return {
71
- name,
72
- ...queueOptions,
73
- arguments: {
74
- ...queueOptions.arguments,
75
- "x-max-priority": maxPriority
76
- }
77
- };
78
- }
79
- return {
80
- name,
81
- ...queueOptions
82
- };
83
- }
23
+
24
+ //#endregion
25
+ //#region src/builder/message.ts
84
26
  /**
85
27
  * Define a message definition with payload and optional headers/metadata.
86
28
  *
@@ -122,33 +64,63 @@ function defineMessage(payload, options) {
122
64
  ...options
123
65
  };
124
66
  }
67
+
68
+ //#endregion
69
+ //#region src/builder/binding.ts
70
+ /**
71
+ * Type guard to check if a queue entry is a QueueWithTtlBackoffInfrastructure.
72
+ * Duplicated here to avoid circular dependency with queue.ts.
73
+ * @internal
74
+ */
75
+ function isQueueWithTtlBackoffInfrastructure$1(entry) {
76
+ return typeof entry === "object" && entry !== null && "__brand" in entry && entry.__brand === "QueueWithTtlBackoffInfrastructure";
77
+ }
78
+ /**
79
+ * Extract the plain QueueDefinition from a QueueEntry.
80
+ * Duplicated here to avoid circular dependency with queue.ts.
81
+ * @internal
82
+ */
83
+ function extractQueueInternal(entry) {
84
+ if (isQueueWithTtlBackoffInfrastructure$1(entry)) return entry.queue;
85
+ return entry;
86
+ }
125
87
  /**
126
88
  * Define a binding between a queue and an exchange.
127
89
  *
128
90
  * This is the implementation function - use the type-specific overloads for better type safety.
129
91
  *
130
- * @param queue - The queue definition to bind
92
+ * @param queue - The queue definition or queue with infrastructure to bind
131
93
  * @param exchange - The exchange definition
132
94
  * @param options - Optional binding configuration
133
95
  * @returns A queue binding definition
134
96
  * @internal
135
97
  */
136
98
  function defineQueueBinding(queue, exchange, options) {
99
+ const queueDef = extractQueueInternal(queue);
137
100
  if (exchange.type === "fanout") return {
138
101
  type: "queue",
139
- queue,
102
+ queue: queueDef,
140
103
  exchange,
141
104
  ...options?.arguments && { arguments: options.arguments }
142
105
  };
143
106
  return {
144
107
  type: "queue",
145
- queue,
108
+ queue: queueDef,
146
109
  exchange,
147
110
  routingKey: options?.routingKey,
148
111
  ...options?.arguments && { arguments: options.arguments }
149
112
  };
150
113
  }
151
114
  /**
115
+ * Internal helper to call defineQueueBinding with proper type handling.
116
+ * Used by queue.ts to avoid circular dependency.
117
+ * @internal
118
+ */
119
+ function defineQueueBindingInternal(queue, exchange, options) {
120
+ if (exchange.type === "fanout") return defineQueueBinding(queue, exchange, options);
121
+ return defineQueueBinding(queue, exchange, options);
122
+ }
123
+ /**
152
124
  * Define a binding between two exchanges (exchange-to-exchange routing).
153
125
  *
154
126
  * This is the implementation function - use the type-specific overloads for better type safety.
@@ -174,6 +146,185 @@ function defineExchangeBinding(destination, source, options) {
174
146
  ...options?.arguments && { arguments: options.arguments }
175
147
  };
176
148
  }
149
+
150
+ //#endregion
151
+ //#region src/builder/queue.ts
152
+ /**
153
+ * Resolve TTL-backoff retry options with defaults applied.
154
+ * @internal
155
+ */
156
+ function resolveTtlBackoffOptions(options) {
157
+ return {
158
+ mode: "ttl-backoff",
159
+ maxRetries: options?.maxRetries ?? 3,
160
+ initialDelayMs: options?.initialDelayMs ?? 1e3,
161
+ maxDelayMs: options?.maxDelayMs ?? 3e4,
162
+ backoffMultiplier: options?.backoffMultiplier ?? 2,
163
+ jitter: options?.jitter ?? true
164
+ };
165
+ }
166
+ /**
167
+ * Type guard to check if a queue entry is a QueueWithTtlBackoffInfrastructure.
168
+ * @internal
169
+ */
170
+ function isQueueWithTtlBackoffInfrastructure(entry) {
171
+ return typeof entry === "object" && entry !== null && "__brand" in entry && entry.__brand === "QueueWithTtlBackoffInfrastructure";
172
+ }
173
+ /**
174
+ * Extract the plain QueueDefinition from a QueueEntry.
175
+ * If the entry is a QueueWithTtlBackoffInfrastructure, returns the inner queue.
176
+ * Otherwise, returns the entry as-is.
177
+ *
178
+ * @param entry - The queue entry (either plain QueueDefinition or QueueWithTtlBackoffInfrastructure)
179
+ * @returns The plain QueueDefinition
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * const queue = defineQueue('orders', { retry: { mode: 'ttl-backoff' }, deadLetter: { exchange: dlx } });
184
+ * const plainQueue = extractQueue(queue); // Returns the inner QueueDefinition
185
+ * ```
186
+ */
187
+ function extractQueue(entry) {
188
+ if (isQueueWithTtlBackoffInfrastructure(entry)) return entry.queue;
189
+ return entry;
190
+ }
191
+ /**
192
+ * Wrap a queue definition with TTL-backoff retry infrastructure.
193
+ * @internal
194
+ */
195
+ function wrapWithTtlBackoffInfrastructure(queue) {
196
+ if (!queue.deadLetter) throw new Error(`Queue "${queue.name}" does not have a dead letter exchange configured. TTL-backoff retry requires deadLetter to be set on the queue.`);
197
+ const dlx = queue.deadLetter.exchange;
198
+ const waitQueueName = `${queue.name}-wait`;
199
+ const waitQueue = {
200
+ name: waitQueueName,
201
+ type: "quorum",
202
+ durable: queue.durable ?? true,
203
+ deadLetter: {
204
+ exchange: dlx,
205
+ routingKey: queue.name
206
+ },
207
+ retry: resolveTtlBackoffOptions(void 0)
208
+ };
209
+ return {
210
+ __brand: "QueueWithTtlBackoffInfrastructure",
211
+ queue,
212
+ waitQueue,
213
+ waitQueueBinding: defineQueueBindingInternal(waitQueue, dlx, { routingKey: waitQueueName }),
214
+ mainQueueRetryBinding: defineQueueBindingInternal(queue, dlx, { routingKey: queue.name })
215
+ };
216
+ }
217
+ /**
218
+ * Define an AMQP queue.
219
+ *
220
+ * A queue stores messages until they are consumed by workers. Queues can be bound to exchanges
221
+ * to receive messages based on routing rules.
222
+ *
223
+ * By default, queues are created as quorum queues which provide better durability and
224
+ * high-availability. Use `type: 'classic'` for special cases like non-durable queues
225
+ * or priority queues.
226
+ *
227
+ * @param name - The name of the queue
228
+ * @param options - Optional queue configuration
229
+ * @param options.type - Queue type: 'quorum' (default, recommended) or 'classic'
230
+ * @param options.durable - If true, the queue survives broker restarts. Quorum queues are always durable.
231
+ * @param options.exclusive - If true, the queue can only be used by the declaring connection. Only supported with classic queues.
232
+ * @param options.autoDelete - If true, the queue is deleted when the last consumer unsubscribes (default: false)
233
+ * @param options.deadLetter - Dead letter configuration for handling failed messages
234
+ * @param options.maxPriority - Maximum priority level for priority queue (1-255, recommended: 1-10). Only supported with classic queues.
235
+ * @param options.arguments - Additional AMQP arguments (e.g., x-message-ttl)
236
+ * @returns A queue definition
237
+ *
238
+ * @example
239
+ * ```typescript
240
+ * // Quorum queue (default, recommended for production)
241
+ * const orderQueue = defineQueue('order-processing');
242
+ *
243
+ * // Explicit quorum queue with dead letter exchange
244
+ * const dlx = defineExchange('orders-dlx', 'topic', { durable: true });
245
+ * const orderQueueWithDLX = defineQueue('order-processing', {
246
+ * type: 'quorum',
247
+ * deadLetter: {
248
+ * exchange: dlx,
249
+ * routingKey: 'order.failed'
250
+ * },
251
+ * arguments: {
252
+ * 'x-message-ttl': 86400000, // 24 hours
253
+ * }
254
+ * });
255
+ *
256
+ * // Classic queue (for special cases)
257
+ * const tempQueue = defineQueue('temp-queue', {
258
+ * type: 'classic',
259
+ * durable: false,
260
+ * autoDelete: true,
261
+ * });
262
+ *
263
+ * // Priority queue (requires classic type)
264
+ * const taskQueue = defineQueue('urgent-tasks', {
265
+ * type: 'classic',
266
+ * durable: true,
267
+ * maxPriority: 10,
268
+ * });
269
+ *
270
+ * // Queue with TTL-backoff retry (returns infrastructure automatically)
271
+ * const dlx = defineExchange('orders-dlx', 'direct', { durable: true });
272
+ * const orderQueue = defineQueue('order-processing', {
273
+ * deadLetter: { exchange: dlx },
274
+ * retry: { mode: 'ttl-backoff', maxRetries: 5 },
275
+ * });
276
+ * // orderQueue is QueueWithTtlBackoffInfrastructure, pass directly to defineContract
277
+ * ```
278
+ */
279
+ function defineQueue(name, options) {
280
+ const opts = options ?? {};
281
+ const type = opts.type ?? "quorum";
282
+ const baseProps = { name };
283
+ if (opts.durable !== void 0) baseProps.durable = opts.durable;
284
+ if (opts.autoDelete !== void 0) baseProps.autoDelete = opts.autoDelete;
285
+ if (opts.deadLetter !== void 0) baseProps.deadLetter = opts.deadLetter;
286
+ if (opts.arguments !== void 0) baseProps.arguments = opts.arguments;
287
+ if (type === "quorum") {
288
+ const quorumOpts = opts;
289
+ const inputRetry = quorumOpts.retry ?? { mode: "ttl-backoff" };
290
+ if (inputRetry.mode === "quorum-native") {
291
+ if (quorumOpts.deliveryLimit === void 0) throw new Error(`Queue "${name}" uses quorum-native retry mode but deliveryLimit is not configured. Quorum-native retry requires deliveryLimit to be set.`);
292
+ }
293
+ const retry$1 = inputRetry.mode === "quorum-native" ? inputRetry : resolveTtlBackoffOptions(inputRetry);
294
+ const queueDefinition$1 = {
295
+ ...baseProps,
296
+ type: "quorum",
297
+ retry: retry$1
298
+ };
299
+ if (quorumOpts.deliveryLimit !== void 0) {
300
+ if (quorumOpts.deliveryLimit < 1 || !Number.isInteger(quorumOpts.deliveryLimit)) throw new Error(`Invalid deliveryLimit: ${quorumOpts.deliveryLimit}. Must be a positive integer.`);
301
+ queueDefinition$1.deliveryLimit = quorumOpts.deliveryLimit;
302
+ }
303
+ if (retry$1.mode === "ttl-backoff" && queueDefinition$1.deadLetter) return wrapWithTtlBackoffInfrastructure(queueDefinition$1);
304
+ return queueDefinition$1;
305
+ }
306
+ const classicOpts = opts;
307
+ if (classicOpts.retry?.mode === "quorum-native") throw new Error(`Queue "${name}" uses quorum-native retry mode but is a classic queue. Quorum-native retry requires quorum queues (type: "quorum").`);
308
+ const retry = resolveTtlBackoffOptions(classicOpts.retry);
309
+ const queueDefinition = {
310
+ ...baseProps,
311
+ type: "classic",
312
+ retry
313
+ };
314
+ if (classicOpts.exclusive !== void 0) queueDefinition.exclusive = classicOpts.exclusive;
315
+ if (classicOpts.maxPriority !== void 0) {
316
+ if (classicOpts.maxPriority < 1 || classicOpts.maxPriority > 255) throw new Error(`Invalid maxPriority: ${classicOpts.maxPriority}. Must be between 1 and 255. Recommended range: 1-10.`);
317
+ queueDefinition.arguments = {
318
+ ...queueDefinition.arguments,
319
+ "x-max-priority": classicOpts.maxPriority
320
+ };
321
+ }
322
+ if (retry.mode === "ttl-backoff" && queueDefinition.deadLetter) return wrapWithTtlBackoffInfrastructure(queueDefinition);
323
+ return queueDefinition;
324
+ }
325
+
326
+ //#endregion
327
+ //#region src/builder/publisher.ts
177
328
  /**
178
329
  * Define a message publisher.
179
330
  *
@@ -197,6 +348,18 @@ function definePublisher(exchange, message, options) {
197
348
  };
198
349
  }
199
350
  /**
351
+ * Helper to call definePublisher with proper type handling.
352
+ * Type safety is enforced by overloaded public function signatures.
353
+ * @internal
354
+ */
355
+ function definePublisherInternal(exchange, message, options) {
356
+ if (exchange.type === "fanout") return definePublisher(exchange, message, options);
357
+ return definePublisher(exchange, message, options);
358
+ }
359
+
360
+ //#endregion
361
+ //#region src/builder/consumer.ts
362
+ /**
200
363
  * Define a message consumer.
201
364
  *
202
365
  * A consumer receives and processes messages from a queue. The message schema is validated
@@ -240,11 +403,14 @@ function definePublisher(exchange, message, options) {
240
403
  */
241
404
  function defineConsumer(queue, message, options) {
242
405
  return {
243
- queue,
406
+ queue: extractQueue(queue),
244
407
  message,
245
408
  ...options
246
409
  };
247
410
  }
411
+
412
+ //#endregion
413
+ //#region src/builder/contract.ts
248
414
  /**
249
415
  * Define an AMQP contract.
250
416
  *
@@ -315,35 +481,44 @@ function defineConsumer(queue, message, options) {
315
481
  * ```
316
482
  */
317
483
  function defineContract(definition) {
318
- return definition;
319
- }
320
- /**
321
- * Helper to call definePublisher with proper type handling.
322
- * Type safety is enforced by overloaded public function signatures.
323
- * @internal
324
- */
325
- function callDefinePublisher(exchange, message, options) {
326
- if (exchange.type === "fanout") return definePublisher(exchange, message, options);
327
- return definePublisher(exchange, message, options);
328
- }
329
- /**
330
- * Helper to call defineQueueBinding with proper type handling.
331
- * Type safety is enforced by overloaded public function signatures.
332
- * @internal
333
- */
334
- function callDefineQueueBinding(queue, exchange, options) {
335
- if (exchange.type === "fanout") return defineQueueBinding(queue, exchange, options);
336
- return defineQueueBinding(queue, exchange, options);
484
+ if (!definition.queues || Object.keys(definition.queues).length === 0) return definition;
485
+ const queues = definition.queues;
486
+ const expandedQueues = {};
487
+ const autoBindings = {};
488
+ for (const [name, entry] of Object.entries(queues)) if (isQueueWithTtlBackoffInfrastructure(entry)) {
489
+ expandedQueues[name] = entry.queue;
490
+ expandedQueues[`${name}Wait`] = entry.waitQueue;
491
+ autoBindings[`${name}WaitBinding`] = entry.waitQueueBinding;
492
+ autoBindings[`${name}RetryBinding`] = entry.mainQueueRetryBinding;
493
+ } else expandedQueues[name] = entry;
494
+ if (Object.keys(autoBindings).length > 0) {
495
+ const mergedBindings = {
496
+ ...definition.bindings,
497
+ ...autoBindings
498
+ };
499
+ return {
500
+ ...definition,
501
+ queues: expandedQueues,
502
+ bindings: mergedBindings
503
+ };
504
+ }
505
+ return {
506
+ ...definition,
507
+ queues: expandedQueues
508
+ };
337
509
  }
510
+
511
+ //#endregion
512
+ //#region src/builder/publisher-first.ts
338
513
  /**
339
514
  * Implementation of definePublisherFirst.
340
515
  * @internal
341
516
  */
342
517
  function definePublisherFirst(exchange, message, options) {
343
- const publisher = callDefinePublisher(exchange, message, options);
518
+ const publisher = definePublisherInternal(exchange, message, options);
344
519
  if (exchange.type === "topic") {
345
520
  const createConsumer$1 = (queue, routingKey) => {
346
- const binding = callDefineQueueBinding(queue, exchange, routingKey ? {
521
+ const binding = defineQueueBindingInternal(queue, exchange, routingKey ? {
347
522
  ...options,
348
523
  routingKey
349
524
  } : options);
@@ -358,7 +533,7 @@ function definePublisherFirst(exchange, message, options) {
358
533
  };
359
534
  }
360
535
  const createConsumer = (queue) => {
361
- const binding = callDefineQueueBinding(queue, exchange, options);
536
+ const binding = defineQueueBindingInternal(queue, exchange, options);
362
537
  return {
363
538
  consumer: defineConsumer(queue, message),
364
539
  binding
@@ -369,16 +544,19 @@ function definePublisherFirst(exchange, message, options) {
369
544
  createConsumer
370
545
  };
371
546
  }
547
+
548
+ //#endregion
549
+ //#region src/builder/consumer-first.ts
372
550
  /**
373
551
  * Implementation of defineConsumerFirst.
374
552
  * @internal
375
553
  */
376
554
  function defineConsumerFirst(queue, exchange, message, options) {
377
555
  const consumer = defineConsumer(queue, message);
378
- const binding = callDefineQueueBinding(queue, exchange, options);
556
+ const binding = defineQueueBindingInternal(queue, exchange, options);
379
557
  if (exchange.type === "topic") {
380
558
  const createPublisher$1 = (routingKey) => {
381
- return callDefinePublisher(exchange, message, {
559
+ return definePublisherInternal(exchange, message, {
382
560
  ...options,
383
561
  routingKey
384
562
  });
@@ -390,7 +568,7 @@ function defineConsumerFirst(queue, exchange, message, options) {
390
568
  };
391
569
  }
392
570
  const createPublisher = () => {
393
- return callDefinePublisher(exchange, message, options);
571
+ return definePublisherInternal(exchange, message, options);
394
572
  };
395
573
  return {
396
574
  consumer,
@@ -399,6 +577,78 @@ function defineConsumerFirst(queue, exchange, message, options) {
399
577
  };
400
578
  }
401
579
 
580
+ //#endregion
581
+ //#region src/builder/ttl-backoff.ts
582
+ /**
583
+ * Create TTL-backoff retry infrastructure for a queue.
584
+ *
585
+ * This builder helper generates the wait queue and bindings needed for TTL-backoff retry.
586
+ * The generated infrastructure can be spread into a contract definition.
587
+ *
588
+ * TTL-backoff retry works by:
589
+ * 1. Failed messages are sent to the DLX with routing key `{queueName}-wait`
590
+ * 2. The wait queue receives these messages and holds them for a TTL period
591
+ * 3. After TTL expires, messages are dead-lettered back to the DLX with routing key `{queueName}`
592
+ * 4. The main queue receives the retried message via its binding to the DLX
593
+ *
594
+ * @param queue - The main queue definition (must have deadLetter configured)
595
+ * @param options - Optional configuration for the wait queue
596
+ * @param options.waitQueueDurable - Whether the wait queue should be durable (default: same as main queue)
597
+ * @returns TTL-backoff retry infrastructure containing wait queue and bindings
598
+ * @throws {Error} If the queue does not have a dead letter exchange configured
599
+ *
600
+ * @example
601
+ * ```typescript
602
+ * const dlx = defineExchange('orders-dlx', 'direct', { durable: true });
603
+ * const orderQueue = defineQueue('order-processing', {
604
+ * type: 'quorum',
605
+ * deadLetter: { exchange: dlx },
606
+ * retry: {
607
+ * mode: 'ttl-backoff',
608
+ * maxRetries: 5,
609
+ * initialDelayMs: 1000,
610
+ * },
611
+ * });
612
+ *
613
+ * // Generate TTL-backoff infrastructure
614
+ * const retryInfra = defineTtlBackoffRetryInfrastructure(orderQueue);
615
+ *
616
+ * // Spread into contract
617
+ * const contract = defineContract({
618
+ * exchanges: { dlx },
619
+ * queues: {
620
+ * orderProcessing: orderQueue,
621
+ * orderProcessingWait: retryInfra.waitQueue,
622
+ * },
623
+ * bindings: {
624
+ * ...// your other bindings
625
+ * orderWaitBinding: retryInfra.waitQueueBinding,
626
+ * orderRetryBinding: retryInfra.mainQueueRetryBinding,
627
+ * },
628
+ * // ... publishers and consumers
629
+ * });
630
+ * ```
631
+ */
632
+ function defineTtlBackoffRetryInfrastructure(queueEntry, options) {
633
+ const queue = extractQueue(queueEntry);
634
+ if (!queue.deadLetter) throw new Error(`Queue "${queue.name}" does not have a dead letter exchange configured. TTL-backoff retry requires deadLetter to be set on the queue.`);
635
+ const dlx = queue.deadLetter.exchange;
636
+ const waitQueueName = `${queue.name}-wait`;
637
+ const waitQueue = defineQueue(waitQueueName, {
638
+ type: "quorum",
639
+ durable: options?.waitQueueDurable ?? queue.durable ?? true,
640
+ deadLetter: {
641
+ exchange: dlx,
642
+ routingKey: queue.name
643
+ }
644
+ });
645
+ return {
646
+ waitQueue,
647
+ waitQueueBinding: defineQueueBindingInternal(waitQueue, dlx, { routingKey: waitQueueName }),
648
+ mainQueueRetryBinding: defineQueueBindingInternal(queue, dlx, { routingKey: queue.name })
649
+ };
650
+ }
651
+
402
652
  //#endregion
403
653
  exports.defineConsumer = defineConsumer;
404
654
  exports.defineConsumerFirst = defineConsumerFirst;
@@ -409,4 +659,6 @@ exports.defineMessage = defineMessage;
409
659
  exports.definePublisher = definePublisher;
410
660
  exports.definePublisherFirst = definePublisherFirst;
411
661
  exports.defineQueue = defineQueue;
412
- exports.defineQueueBinding = defineQueueBinding;
662
+ exports.defineQueueBinding = defineQueueBinding;
663
+ exports.defineTtlBackoffRetryInfrastructure = defineTtlBackoffRetryInfrastructure;
664
+ exports.extractQueue = extractQueue;