@vercel/queue 0.0.0-alpha.12 → 0.0.0-alpha.3

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.mts CHANGED
@@ -71,10 +71,44 @@ declare class StreamTransport implements Transport<ReadableStream<Uint8Array>> {
71
71
  * Vercel Queue Service client types
72
72
  */
73
73
 
74
+ interface QueueClientOptions {
75
+ /**
76
+ * Base URL for the Vercel Queue Service API
77
+ * @default "https://vqs.vercel.sh"
78
+ */
79
+ baseUrl?: string;
80
+ /**
81
+ * Vercel function OIDC token
82
+ * Can be obtained from x-vercel-oidc-token header in Vercel Serverless Functions
83
+ */
84
+ token: string;
85
+ }
74
86
  /**
75
- * Shared options for publishing messages
87
+ * Callback configuration for a consumer group
76
88
  */
77
- interface PublishOptions {
89
+ interface CallbackConfig {
90
+ /**
91
+ * Webhook URL to notify when messages are available
92
+ */
93
+ url: string;
94
+ /**
95
+ * Delay in seconds before sending the first callback
96
+ */
97
+ delay?: number;
98
+ /**
99
+ * Delay in seconds between retry attempts when the callback fails
100
+ */
101
+ frequency?: number;
102
+ }
103
+ interface SendMessageOptions<T = unknown> {
104
+ /**
105
+ * The queue name to send the message to
106
+ */
107
+ queueName: string;
108
+ /**
109
+ * The message payload
110
+ */
111
+ payload: T;
78
112
  /**
79
113
  * Unique key to prevent duplicate message submissions
80
114
  * @default random UUID
@@ -87,16 +121,13 @@ interface PublishOptions {
87
121
  * @max 86400
88
122
  */
89
123
  retentionSeconds?: number;
90
- }
91
- interface SendMessageOptions<T = unknown> extends PublishOptions {
92
124
  /**
93
- * The queue name to send the message to
94
- */
95
- queueName: string;
96
- /**
97
- * The message payload
125
+ * Callback configuration
126
+ * - If a single CallbackConfig is provided, it will use the "default" consumer group
127
+ * - If an object is provided, keys are consumer group names with their respective callback configs
128
+ * Format: { consumerGroup: { url, delay?, frequency? } } or { url, delay?, frequency? }
98
129
  */
99
- payload: T;
130
+ callback?: Record<string, CallbackConfig> | CallbackConfig;
100
131
  }
101
132
  interface SendMessageResponse {
102
133
  /**
@@ -120,9 +151,9 @@ interface Message<T = unknown> {
120
151
  */
121
152
  deliveryCount: number;
122
153
  /**
123
- * When the message was created
154
+ * Timestamp when the message was created
124
155
  */
125
- createdAt: Date;
156
+ timestamp: string;
126
157
  /**
127
158
  * MIME type of the message content
128
159
  */
@@ -132,6 +163,80 @@ interface Message<T = unknown> {
132
163
  */
133
164
  ticket: string;
134
165
  }
166
+ interface ReceiveMessagesOptions<T = unknown> {
167
+ /**
168
+ * The queue name to receive messages from
169
+ */
170
+ queueName: string;
171
+ /**
172
+ * Consumer group name
173
+ */
174
+ consumerGroup: string;
175
+ /**
176
+ * Time in seconds that messages will be invisible to other consumers
177
+ * @default 900 (15 minutes)
178
+ */
179
+ visibilityTimeoutSeconds?: number;
180
+ /**
181
+ * Maximum number of messages to retrieve
182
+ * @default 10
183
+ * @max 10
184
+ * @note FIFO queues must use limit=1
185
+ */
186
+ limit?: number;
187
+ }
188
+ interface DeleteMessageOptions {
189
+ /**
190
+ * The queue name the message belongs to
191
+ */
192
+ queueName: string;
193
+ /**
194
+ * Consumer group name
195
+ */
196
+ consumerGroup: string;
197
+ /**
198
+ * The message ID to delete
199
+ */
200
+ messageId: string;
201
+ /**
202
+ * Ticket received from the message
203
+ */
204
+ ticket: string;
205
+ }
206
+ interface DeleteMessageResponse {
207
+ /**
208
+ * Whether the message was successfully deleted
209
+ */
210
+ deleted: boolean;
211
+ }
212
+ interface ChangeVisibilityOptions {
213
+ /**
214
+ * The queue name the message belongs to
215
+ */
216
+ queueName: string;
217
+ /**
218
+ * Consumer group name
219
+ */
220
+ consumerGroup: string;
221
+ /**
222
+ * The message ID to update
223
+ */
224
+ messageId: string;
225
+ /**
226
+ * Ticket received from the message
227
+ */
228
+ ticket: string;
229
+ /**
230
+ * New visibility timeout in seconds
231
+ */
232
+ visibilityTimeoutSeconds: number;
233
+ }
234
+ interface ChangeVisibilityResponse {
235
+ /**
236
+ * Whether the visibility was successfully updated
237
+ */
238
+ updated: boolean;
239
+ }
135
240
  /**
136
241
  * Result indicating the message should be timed out for retry later
137
242
  */
@@ -145,20 +250,10 @@ interface MessageTimeoutResult {
145
250
  * Result returned by message handlers
146
251
  */
147
252
  type MessageHandlerResult = void | MessageTimeoutResult;
148
- /**
149
- * Message metadata provided to handlers
150
- */
151
- interface MessageMetadata {
152
- messageId: string;
153
- deliveryCount: number;
154
- createdAt: Date;
155
- topicName: string;
156
- consumerGroup: string;
157
- }
158
253
  /**
159
254
  * Message handler function type
160
255
  */
161
- type MessageHandler<T = unknown> = (message: T, metadata: MessageMetadata) => Promise<MessageHandlerResult> | MessageHandlerResult;
256
+ type MessageHandler<T = unknown> = (message: Message<T>) => Promise<MessageHandlerResult> | MessageHandlerResult;
162
257
  /**
163
258
  * Options for creating a ConsumerGroup instance
164
259
  */
@@ -179,6 +274,44 @@ interface ConsumerGroupOptions<T = unknown> {
179
274
  */
180
275
  refreshInterval?: number;
181
276
  }
277
+ interface ReceiveMessageByIdOptions<T = unknown> {
278
+ /**
279
+ * The queue name to receive the message from
280
+ */
281
+ queueName: string;
282
+ /**
283
+ * Consumer group name
284
+ */
285
+ consumerGroup: string;
286
+ /**
287
+ * The message ID to retrieve
288
+ */
289
+ messageId: string;
290
+ /**
291
+ * Time in seconds that the message will be invisible to other consumers
292
+ * @default 900 (15 minutes)
293
+ */
294
+ visibilityTimeoutSeconds?: number;
295
+ /**
296
+ * Skip payload content and only return message metadata
297
+ * When true, the server returns a 204 status with headers containing message metadata
298
+ * @default false
299
+ */
300
+ skipPayload?: boolean;
301
+ }
302
+ interface ReceiveMessageByIdResponse<T = unknown, TSkipPayload extends boolean = false> {
303
+ message: TSkipPayload extends true ? Message<void> : Message<T>;
304
+ }
305
+ interface FifoOrderingError {
306
+ /**
307
+ * Error message describing the FIFO ordering violation
308
+ */
309
+ error: string;
310
+ /**
311
+ * The message ID that must be processed first
312
+ */
313
+ nextMessageId: string;
314
+ }
182
315
  /**
183
316
  * Error thrown when a message is not found (404)
184
317
  */
@@ -192,6 +325,13 @@ declare class MessageNotFoundError extends Error {
192
325
  declare class MessageNotAvailableError extends Error {
193
326
  constructor(messageId: string, reason?: string);
194
327
  }
328
+ /**
329
+ * Error thrown when there's a FIFO ordering violation (409 with nextMessageId)
330
+ */
331
+ declare class FifoOrderingViolationError extends Error {
332
+ readonly nextMessageId: string;
333
+ constructor(messageId: string, nextMessageId: string, reason: string);
334
+ }
195
335
  /**
196
336
  * Error thrown when message data is corrupted or can't be parsed
197
337
  */
@@ -205,7 +345,7 @@ declare class QueueEmptyError extends Error {
205
345
  constructor(queueName: string, consumerGroup: string);
206
346
  }
207
347
  /**
208
- * Error thrown when a message is temporarily locked (423)
348
+ * Error thrown when a message is temporarily locked in a FIFO queue (423)
209
349
  */
210
350
  declare class MessageLockedError extends Error {
211
351
  readonly retryAfter?: number;
@@ -229,6 +369,13 @@ declare class ForbiddenError extends Error {
229
369
  declare class BadRequestError extends Error {
230
370
  constructor(message: string);
231
371
  }
372
+ /**
373
+ * Error thrown when there's a failed dependency (424) - FIFO ordering violation in receive by ID
374
+ */
375
+ declare class FailedDependencyError extends Error {
376
+ readonly nextMessageId: string;
377
+ constructor(messageId: string, nextMessageId: string);
378
+ }
232
379
  /**
233
380
  * Error thrown for internal server errors (500)
234
381
  */
@@ -241,160 +388,388 @@ declare class InternalServerError extends Error {
241
388
  declare class InvalidLimitError extends Error {
242
389
  constructor(limit: number, min?: number, max?: number);
243
390
  }
244
-
245
- /**
246
- * Options for the consume method
247
- */
248
- interface ConsumeOptions {
249
- /** The specific message ID to consume (if not provided, consumes next available message) */
250
- messageId?: string;
251
- /** Whether to skip downloading the payload (only allowed when messageId is provided) */
252
- skipPayload?: boolean;
253
- }
254
-
255
391
  /**
256
- * Options for the send function
392
+ * Options extracted from a queue callback request
257
393
  */
258
- interface SendOptions<T = unknown> extends PublishOptions {
394
+ interface CallbackMessageOptions {
259
395
  /**
260
- * Serializer/deserializer for the payload
261
- * @default JsonTransport instance
396
+ * The queue name extracted from Vqs-Queue-Name header
262
397
  */
263
- transport?: Transport<T>;
398
+ queueName: string;
399
+ /**
400
+ * The consumer group extracted from Vqs-Consumer-Group header
401
+ */
402
+ consumerGroup: string;
403
+ /**
404
+ * The message ID extracted from Vqs-Message-Id header
405
+ */
406
+ messageId: string;
264
407
  }
265
408
  /**
266
- * Send a message to a topic (shorthand for topic creation and publishing)
267
- * Uses the default QueueClient with automatic OIDC token detection
268
- * @param topicName Name of the topic to send to
269
- * @param payload The data to send
270
- * @param options Optional send options including transport and publish settings
271
- * @returns Promise with the message ID
272
- * @throws {BadRequestError} When request parameters are invalid
273
- * @throws {UnauthorizedError} When authentication fails
274
- * @throws {ForbiddenError} When access is denied (environment mismatch)
275
- * @throws {InternalServerError} When server encounters an error
409
+ * Error thrown when queue callback headers are missing or invalid
276
410
  */
277
- declare function send<T = unknown>(topicName: string, payload: T, options?: SendOptions<T>): Promise<{
278
- messageId: string;
279
- }>;
411
+ declare class InvalidCallbackError extends Error {
412
+ constructor(message: string);
413
+ }
414
+
280
415
  /**
281
- * Options for the receive function
416
+ * Client for interacting with the Vercel Queue Service API
282
417
  */
283
- interface ReceiveOptions<T = unknown> extends ConsumerGroupOptions<T>, ConsumeOptions {
418
+ declare class QueueClient {
419
+ private baseUrl;
420
+ private token;
421
+ /**
422
+ * Create a new Vercel Queue Service client
423
+ * @param options Client configuration options
424
+ */
425
+ constructor(options: QueueClientOptions);
426
+ /**
427
+ * Create a QueueClient automatically configured for Vercel Functions
428
+ * This method automatically retrieves the OIDC token from the Vercel Function environment
429
+ * Always creates a fresh instance since OIDC tokens expire after 15 minutes
430
+ * @param baseUrl Optional base URL override
431
+ * @returns Promise resolving to a new QueueClient instance
432
+ */
433
+ static fromVercelFunction(baseUrl?: string): Promise<QueueClient>;
434
+ /**
435
+ * Send a message to a queue
436
+ * @param options Send message options
437
+ * @param transport Serializer/deserializer for the payload
438
+ * @returns Promise with the message ID
439
+ * @throws {BadRequestError} When request parameters are invalid
440
+ * @throws {UnauthorizedError} When authentication fails
441
+ * @throws {ForbiddenError} When access is denied (environment mismatch)
442
+ * @throws {InternalServerError} When server encounters an error
443
+ */
444
+ sendMessage<T = unknown>(options: SendMessageOptions<T>, transport: Transport<T>): Promise<SendMessageResponse>;
445
+ /**
446
+ * Receive messages from a queue
447
+ * @param options Receive messages options
448
+ * @param transport Serializer/deserializer for the payload
449
+ * @returns AsyncGenerator that yields messages as they arrive
450
+ * @throws {InvalidLimitError} When limit parameter is not between 1 and 10
451
+ * @throws {QueueEmptyError} When no messages are available (204)
452
+ * @throws {MessageLockedError} When FIFO queue has locked messages (423)
453
+ * @throws {BadRequestError} When request parameters are invalid
454
+ * @throws {UnauthorizedError} When authentication fails
455
+ * @throws {ForbiddenError} When access is denied (environment mismatch)
456
+ * @throws {InternalServerError} When server encounters an error
457
+ */
458
+ receiveMessages<T = unknown>(options: ReceiveMessagesOptions<T>, transport: Transport<T>): AsyncGenerator<Message<T>, void, unknown>;
459
+ /**
460
+ * Receive a specific message by its ID from a queue
461
+ * @param options Receive message by ID options
462
+ * @param transport Serializer/deserializer for the payload
463
+ * @returns Promise with the message or null if not found/available
464
+ * @throws {MessageNotFoundError} When the message doesn't exist (404)
465
+ * @throws {MessageLockedError} When the message is temporarily locked (423)
466
+ * @throws {FailedDependencyError} When FIFO ordering is violated (424)
467
+ * @throws {MessageNotAvailableError} When message exists but isn't available (409)
468
+ * @throws {FifoOrderingViolationError} When FIFO ordering is violated (409 with nextMessageId)
469
+ * @throws {MessageCorruptedError} When message data is corrupted
470
+ * @throws {BadRequestError} When request parameters are invalid
471
+ * @throws {UnauthorizedError} When authentication fails
472
+ * @throws {ForbiddenError} When access is denied (environment mismatch)
473
+ * @throws {InternalServerError} When server encounters an error
474
+ */
475
+ receiveMessageById<T = unknown>(options: ReceiveMessageByIdOptions<T> & {
476
+ skipPayload: true;
477
+ }, transport?: Transport<T>): Promise<ReceiveMessageByIdResponse<T, true>>;
478
+ receiveMessageById<T = unknown>(options: ReceiveMessageByIdOptions<T> & {
479
+ skipPayload?: false | undefined;
480
+ }, transport: Transport<T>): Promise<ReceiveMessageByIdResponse<T, false>>;
481
+ /**
482
+ * Delete a message (acknowledge processing)
483
+ * @param options Delete message options
484
+ * @returns Promise with delete status
485
+ * @throws {MessageNotFoundError} When the message doesn't exist (404)
486
+ * @throws {MessageNotAvailableError} When message can't be deleted (409)
487
+ * @throws {BadRequestError} When ticket is missing or invalid (400)
488
+ * @throws {UnauthorizedError} When authentication fails
489
+ * @throws {ForbiddenError} When access is denied (environment mismatch)
490
+ * @throws {InternalServerError} When server encounters an error
491
+ */
492
+ deleteMessage(options: DeleteMessageOptions): Promise<DeleteMessageResponse>;
493
+ /**
494
+ * Change the visibility timeout of a message
495
+ * @param options Change visibility options
496
+ * @returns Promise with update status
497
+ * @throws {MessageNotFoundError} When the message doesn't exist (404)
498
+ * @throws {MessageNotAvailableError} When message can't be updated (409)
499
+ * @throws {BadRequestError} When ticket is missing or visibility timeout invalid (400)
500
+ * @throws {UnauthorizedError} When authentication fails
501
+ * @throws {ForbiddenError} When access is denied (environment mismatch)
502
+ * @throws {InternalServerError} When server encounters an error
503
+ */
504
+ changeVisibility(options: ChangeVisibilityOptions): Promise<ChangeVisibilityResponse>;
284
505
  }
506
+
285
507
  /**
286
- * Receive a message from a topic (shorthand for topic and consumer group creation)
287
- * Uses the default QueueClient with automatic OIDC token detection
288
- * @param topicName Name of the topic to receive from
289
- * @param consumerGroup Name of the consumer group
290
- * @param handler Function to process the message
291
- * @returns Promise that resolves when the message is processed
292
- * @throws All the same errors as the underlying client methods
508
+ * A ConsumerGroup represents a named group of consumers that process messages from a topic
293
509
  */
294
- declare function receive<T = unknown>(topicName: string, consumerGroup: string, handler: MessageHandler<T>, options?: ReceiveOptions<T>): Promise<void>;
510
+ declare class ConsumerGroup<T = unknown> {
511
+ private client;
512
+ private topicName;
513
+ private consumerGroupName;
514
+ private visibilityTimeout;
515
+ private refreshInterval;
516
+ private transport;
517
+ /**
518
+ * Create a new ConsumerGroup instance
519
+ * @param client QueueClient instance to use for API calls
520
+ * @param topicName Name of the topic to consume from
521
+ * @param consumerGroupName Name of the consumer group
522
+ * @param options Optional configuration
523
+ */
524
+ constructor(client: QueueClient, topicName: string, consumerGroupName: string, options?: ConsumerGroupOptions<T>);
525
+ /**
526
+ * Starts a background loop that periodically extends the visibility timeout for a message.
527
+ * This prevents the message from becoming visible to other consumers while it's being processed.
528
+ *
529
+ * The extension loop runs every `refreshInterval` seconds and updates the message's
530
+ * visibility timeout to `visibilityTimeout` seconds from the current time.
531
+ *
532
+ * @param messageId - The unique identifier of the message to extend visibility for
533
+ * @param ticket - The receipt ticket that proves ownership of the message
534
+ * @returns A function that when called will stop the extension loop
535
+ *
536
+ * @remarks
537
+ * - The first extension attempt occurs after `refreshInterval` seconds, not immediately
538
+ * - If an extension fails, the loop terminates with an error logged to console
539
+ * - The returned stop function is idempotent - calling it multiple times is safe
540
+ * - By default, the stop function returns immediately without waiting for in-flight
541
+ * - Pass `true` to the stop function to wait for any in-flight extension to complete
542
+ */
543
+ private startVisibilityExtension;
544
+ /**
545
+ * Process a single message with the given handler
546
+ * @param message The message to process
547
+ * @param handler Function to process the message
548
+ */
549
+ private processMessage;
550
+ /**
551
+ * Start continuous processing of messages from the topic
552
+ * @param signal AbortSignal to control when to stop processing
553
+ * @param handler Function to process each message
554
+ * @param options Processing options
555
+ * @returns Promise that resolves when processing stops (due to signal or error)
556
+ */
557
+ subscribe(signal: AbortSignal, handler: MessageHandler<T>, options?: {
558
+ pollingInterval?: number;
559
+ }): Promise<void>;
560
+ /**
561
+ * Receive and process a specific message by its ID with full payload
562
+ * @param messageId The ID of the message to receive and process
563
+ * @param handler Function to process the message with full payload
564
+ * @returns Promise that resolves when the message is processed or rejects with specific errors
565
+ * @throws {MessageNotFoundError} When the message doesn't exist (404)
566
+ * @throws {MessageNotAvailableError} When the message exists but isn't available for processing (409)
567
+ * @throws {MessageLockedError} When the message is temporarily locked (423)
568
+ * @throws {FifoOrderingViolationError} When there's a FIFO ordering violation (409 with nextMessageId)
569
+ * @throws {FailedDependencyError} When FIFO ordering is violated (424)
570
+ * @throws {MessageCorruptedError} When the message data is corrupted
571
+ * @throws {BadRequestError} When request parameters are invalid
572
+ * @throws {UnauthorizedError} When authentication fails
573
+ * @throws {ForbiddenError} When access is denied
574
+ * @throws {InternalServerError} When server encounters an error
575
+ */
576
+ receiveMessage(messageId: string, handler: MessageHandler<T>): Promise<void>;
577
+ /**
578
+ * Receive and process the next available message from the queue
579
+ * @param handler Function to process the message
580
+ * @returns Promise that resolves when the message is processed or rejects with specific errors
581
+ * @throws {QueueEmptyError} When no messages are available in the queue (204)
582
+ * @throws {MessageLockedError} When the next message in a FIFO queue is locked (423)
583
+ * @throws {BadRequestError} When request parameters are invalid
584
+ * @throws {UnauthorizedError} When authentication fails
585
+ * @throws {ForbiddenError} When access is denied
586
+ * @throws {InternalServerError} When server encounters an error
587
+ */
588
+ receiveNextMessage(handler: MessageHandler<T>): Promise<void>;
589
+ /**
590
+ * Receive and process multiple next available messages from the queue
591
+ * @param limit Number of messages to process (1-10)
592
+ * @param handler Function to process each message
593
+ * @returns Promise that resolves to an array of PromiseSettledResult (same as Promise.allSettled)
594
+ * @throws {InvalidLimitError} When limit parameter is not between 1 and 10
595
+ * @throws {QueueEmptyError} When no messages are available in the queue (204)
596
+ * @throws {MessageLockedError} When the next message in a FIFO queue is locked (423)
597
+ * @throws {BadRequestError} When request parameters are invalid
598
+ * @throws {UnauthorizedError} When authentication fails
599
+ * @throws {ForbiddenError} When access is denied
600
+ * @throws {InternalServerError} When server encounters an error
601
+ */
602
+ receiveNextMessages(limit: number, handler: MessageHandler<T>): Promise<PromiseSettledResult<void>[]>;
603
+ /**
604
+ * Handle a specific message by its ID without downloading the payload (metadata only)
605
+ * @param messageId The ID of the message to handle
606
+ * @param handler Function to process the message metadata (payload will be void)
607
+ * @returns Promise that resolves when the message is handled or rejects with specific errors
608
+ * @throws {MessageNotFoundError} When the message doesn't exist (404)
609
+ * @throws {MessageNotAvailableError} When the message exists but isn't available for processing (409)
610
+ * @throws {MessageLockedError} When the message is temporarily locked (423)
611
+ * @throws {FifoOrderingViolationError} When there's a FIFO ordering violation (409 with nextMessageId)
612
+ * @throws {FailedDependencyError} When FIFO ordering is violated (424)
613
+ * @throws {MessageCorruptedError} When the message data is corrupted
614
+ * @throws {BadRequestError} When request parameters are invalid
615
+ * @throws {UnauthorizedError} When authentication fails
616
+ * @throws {ForbiddenError} When access is denied
617
+ * @throws {InternalServerError} When server encounters an error
618
+ */
619
+ handleMessage(messageId: string, handler: MessageHandler<void>): Promise<void>;
620
+ /**
621
+ * Get the consumer group name
622
+ */
623
+ get name(): string;
624
+ /**
625
+ * Get the topic name this consumer group is subscribed to
626
+ */
627
+ get topic(): string;
628
+ }
629
+
295
630
  /**
296
- * Receive a specific message by its ID with full payload
297
- * @param topicName Name of the topic to receive from
298
- * @param consumerGroup Name of the consumer group
299
- * @param handler Function to process the message
300
- * @param options Receive options with messageId specified
301
- * @returns Promise that resolves when the message is processed
302
- * @throws All the same errors as the underlying client methods
631
+ * A Topic represents a named channel for publishing messages in a pub/sub pattern
303
632
  */
304
- declare function receive<T = unknown>(topicName: string, consumerGroup: string, handler: MessageHandler<T>, options: ReceiveOptions<T> & {
305
- messageId: string;
306
- skipPayload?: false | undefined;
307
- }): Promise<void>;
308
- /**
309
- * Receive a specific message by its ID without downloading the payload (metadata only)
310
- * @param topicName Name of the topic to receive from
311
- * @param consumerGroup Name of the consumer group
312
- * @param handler Function to process the message metadata (payload will be void)
313
- * @param options Receive options with messageId and skipPayload specified
314
- * @returns Promise that resolves when the message is processed
315
- * @throws All the same errors as the underlying client methods
316
- */
317
- declare function receive<T = unknown>(topicName: string, consumerGroup: string, handler: MessageHandler<void>, options: ReceiveOptions<T> & {
318
- messageId: string;
319
- skipPayload: true;
320
- }): Promise<void>;
633
+ declare class Topic<T = unknown> {
634
+ private client;
635
+ private topicName;
636
+ private transport;
637
+ /**
638
+ * Create a new Topic instance
639
+ * @param client QueueClient instance to use for API calls
640
+ * @param topicName Name of the topic to work with
641
+ * @param transport Optional serializer/deserializer for the payload (defaults to JSON)
642
+ */
643
+ constructor(client: QueueClient, topicName: string, transport?: Transport<T>);
644
+ /**
645
+ * Publish a message to the topic
646
+ * @param payload The data to publish
647
+ * @param options Optional publish options
648
+ * @returns An object containing the message ID
649
+ * @throws {BadRequestError} When request parameters are invalid
650
+ * @throws {UnauthorizedError} When authentication fails
651
+ * @throws {ForbiddenError} When access is denied (environment mismatch)
652
+ * @throws {InternalServerError} When server encounters an error
653
+ */
654
+ publish(payload: T, options?: {
655
+ idempotencyKey?: string;
656
+ retentionSeconds?: number;
657
+ callback?: Record<string, CallbackConfig> | CallbackConfig;
658
+ }): Promise<{
659
+ messageId: string;
660
+ }>;
661
+ /**
662
+ * Create a consumer group for this topic
663
+ * @param consumerGroupName Name of the consumer group
664
+ * @param options Optional configuration for the consumer group
665
+ * @returns A ConsumerGroup instance
666
+ */
667
+ consumerGroup<U = T>(consumerGroupName: string, options?: ConsumerGroupOptions<U>): ConsumerGroup<U>;
668
+ /**
669
+ * Get the topic name
670
+ */
671
+ get name(): string;
672
+ /**
673
+ * Get the transport used by this topic
674
+ */
675
+ get serializer(): Transport<T>;
676
+ }
321
677
 
322
678
  /**
323
- * Configuration object with handlers for different topics and consumer groups
679
+ * Create a new Topic instance
680
+ * @param client QueueClient instance to use for API calls
681
+ * @param topicName Name of the topic
682
+ * @param transport Optional serializer/deserializer for the payload (defaults to JSON)
683
+ * @returns A Topic instance
324
684
  */
325
- type CallbackHandlers = {
326
- [topicName: string]: {
327
- [consumerGroup: string]: MessageHandler;
328
- };
329
- };
685
+ declare function createTopic<T = unknown>(client: QueueClient, topicName: string, transport?: Transport<T>): Topic<T>;
686
+
330
687
  /**
331
- * Parsed callback request information
688
+ * Queue Callback utilities for handling incoming webhook payloads
332
689
  */
333
- type ParsedCallbackRequest = {
334
- queueName: string;
335
- consumerGroup: string;
336
- messageId: string;
337
- };
690
+
338
691
  /**
339
- * Parse and validate callback request using CloudEvent specification
692
+ * Parse a queue callback request and extract the required information for receiveMessageById
340
693
  *
341
- * Extracts queue information from CloudEvent format and validates
342
- * that all required fields are present.
343
- *
344
- * @param request The incoming webhook request
345
- * @returns Parsed queue information
346
- * @throws Error if required fields are missing
694
+ * @param request The incoming Request object from the queue callback
695
+ * @returns CallbackMessageOptions that can be used with receiveMessageById
696
+ * @throws {InvalidCallbackError} When required queue headers are missing or invalid
347
697
  *
348
698
  * @example
349
699
  * ```typescript
350
- * // In Next.js API route
700
+ * import { parseCallbackRequest } from '@vercel/queue';
701
+ *
702
+ * // In your webhook handler
351
703
  * export async function POST(request: Request) {
352
704
  * try {
353
- * const { queueName, consumerGroup, messageId } = parseCallback(request);
705
+ * const callbackOptions = parseCallbackRequest(request);
354
706
  *
355
- * // Use the parsed information...
356
- * await myWorkflow.handleWebhook(queueName, consumerGroup, messageId);
707
+ * // Use with receiveMessageById
708
+ * const message = await client.receiveMessageById({
709
+ * ...callbackOptions,
710
+ * visibilityTimeoutSeconds: 30
711
+ * }, transport);
357
712
  *
358
- * return Response.json({ status: "success" });
713
+ * // Process the message...
359
714
  * } catch (error) {
360
- * return Response.json({ error: error.message }, { status: 400 });
715
+ * if (error instanceof InvalidCallbackError) {
716
+ * return new Response('Invalid callback', { status: 400 });
717
+ * }
718
+ * throw error;
361
719
  * }
362
720
  * }
363
721
  * ```
364
722
  */
365
- declare function parseCallback(request: Request): Promise<ParsedCallbackRequest>;
723
+ declare function parseCallbackRequest(request: Request): CallbackMessageOptions;
366
724
  /**
367
- * Simplified queue callback handler for Next.js route handlers
368
- *
369
- * Automatically extracts queue information from CloudEvent format
370
- * and routes to the appropriate handler based on topic and consumer group.
725
+ * Message metadata provided to handlers
726
+ */
727
+ interface MessageMetadata {
728
+ messageId: string;
729
+ deliveryCount: number;
730
+ timestamp: string;
731
+ }
732
+ /**
733
+ * Handler function signature
734
+ */
735
+ type Handler<T = unknown> = (payload: T, metadata: MessageMetadata) => Promise<MessageHandlerResult> | MessageHandlerResult;
736
+ /**
737
+ * Configuration object with handlers for different topics
738
+ * Each topic can have either:
739
+ * - A single handler function (uses 'default' consumer group)
740
+ * - An object with handlers for specific consumer groups
741
+ */
742
+ type CallbackHandlers = {
743
+ [topicName: string]: Handler | {
744
+ [consumerGroup: string]: Handler;
745
+ };
746
+ };
747
+ /**
748
+ * Simplified queue callback handler for NextJS route handlers
371
749
  *
372
- * @param handlers Object with topic-specific handlers organized by consumer groups
373
- * @returns A Next.js route handler function
750
+ * @param handlers Object with topic-specific handlers
751
+ * @returns A NextJS route handler function
374
752
  *
375
753
  * @example
376
754
  * ```typescript
377
- * // Single topic with multiple consumer groups
755
+ * // Topic handler (uses 'default' consumer group)
378
756
  * export const POST = handleCallback({
379
- * "image-processing": {
380
- * "compress": (message, metadata) => console.log("Compressing image", message),
381
- * "resize": (message, metadata) => console.log("Resizing image", message),
757
+ * "new-users": (message, metadata) => {
758
+ * console.log(`New user event:`, message, metadata);
382
759
  * }
383
760
  * });
384
761
  *
385
- * // Multiple topics with consumer groups
762
+ * // Consumer group specific handlers
386
763
  * export const POST = handleCallback({
387
- * "user-events": {
388
- * "welcome": (user, metadata) => console.log("Welcoming user", user),
389
- * "analytics": (user, metadata) => console.log("Tracking user", user),
390
- * },
391
- * "order-events": {
392
- * "fulfillment": (order, metadata) => console.log("Fulfilling order", order),
393
- * "notifications": (order, metadata) => console.log("Notifying order", order),
764
+ * "image-processing": {
765
+ * "compress": (message, metadata) => console.log("Compressing image", message),
766
+ * "resize": (message, metadata) => console.log("Resizing image", message),
394
767
  * }
395
768
  * });
396
769
  * ```
397
770
  */
398
771
  declare function handleCallback(handlers: CallbackHandlers): (request: Request) => Promise<Response>;
399
772
 
400
- export { BadRequestError, BufferTransport, ForbiddenError, InternalServerError, InvalidLimitError, JsonTransport, type Message, MessageCorruptedError, type MessageHandler, type MessageHandlerResult, MessageLockedError, type MessageMetadata, MessageNotAvailableError, MessageNotFoundError, type MessageTimeoutResult, type ParsedCallbackRequest, type PublishOptions, QueueEmptyError, type ReceiveOptions, type SendMessageOptions, type SendMessageResponse, type SendOptions, StreamTransport, type Transport, UnauthorizedError, handleCallback, parseCallback, receive, send };
773
+ declare function getVercelOidcToken(): Promise<string>;
774
+
775
+ export { BadRequestError, BufferTransport, type CallbackConfig, type CallbackMessageOptions, type ChangeVisibilityOptions, type ChangeVisibilityResponse, ConsumerGroup, type ConsumerGroupOptions, type DeleteMessageOptions, type DeleteMessageResponse, FailedDependencyError, type FifoOrderingError, FifoOrderingViolationError, ForbiddenError, InternalServerError, InvalidCallbackError, InvalidLimitError, JsonTransport, type Message, MessageCorruptedError, type MessageHandler, type MessageHandlerResult, MessageLockedError, type MessageMetadata, MessageNotAvailableError, MessageNotFoundError, type MessageTimeoutResult, QueueClient, type QueueClientOptions, QueueEmptyError, type ReceiveMessageByIdOptions, type ReceiveMessageByIdResponse, type ReceiveMessagesOptions, type SendMessageOptions, type SendMessageResponse, StreamTransport, Topic, type Transport, UnauthorizedError, createTopic, getVercelOidcToken, handleCallback, parseCallbackRequest };