@vercel/queue 0.0.0-alpha.5 → 0.0.0-alpha.7

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.ts CHANGED
@@ -71,36 +71,6 @@ 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
- * If not provided, will automatically attempt to retrieve from Vercel Function environment
84
- */
85
- token?: string;
86
- }
87
- /**
88
- * Callback configuration for a consumer group
89
- */
90
- interface CallbackConfig {
91
- /**
92
- * Webhook URL to notify when messages are available
93
- */
94
- url: string;
95
- /**
96
- * Delay in seconds before sending the first callback
97
- */
98
- delay?: number;
99
- /**
100
- * Delay in seconds between retry attempts when the callback fails
101
- */
102
- frequency?: number;
103
- }
104
74
  /**
105
75
  * Shared options for publishing messages
106
76
  */
@@ -117,12 +87,6 @@ interface PublishOptions {
117
87
  * @max 86400
118
88
  */
119
89
  retentionSeconds?: number;
120
- /**
121
- * Callback configuration
122
- * - If a single CallbackConfig is provided, it will use the "default" consumer group
123
- * - If an object is provided, keys are consumer group names with their respective callback configs
124
- */
125
- callback?: Record<string, CallbackConfig> | CallbackConfig;
126
90
  }
127
91
  interface SendMessageOptions<T = unknown> extends PublishOptions {
128
92
  /**
@@ -168,80 +132,6 @@ interface Message<T = unknown> {
168
132
  */
169
133
  ticket: string;
170
134
  }
171
- interface ReceiveMessagesOptions<T = unknown> {
172
- /**
173
- * The queue name to receive messages from
174
- */
175
- queueName: string;
176
- /**
177
- * Consumer group name
178
- */
179
- consumerGroup: string;
180
- /**
181
- * Time in seconds that messages will be invisible to other consumers
182
- * @default 900 (15 minutes)
183
- */
184
- visibilityTimeoutSeconds?: number;
185
- /**
186
- * Maximum number of messages to retrieve
187
- * @default 10
188
- * @max 10
189
- * @note FIFO queues must use limit=1
190
- */
191
- limit?: number;
192
- }
193
- interface DeleteMessageOptions {
194
- /**
195
- * The queue name the message belongs to
196
- */
197
- queueName: string;
198
- /**
199
- * Consumer group name
200
- */
201
- consumerGroup: string;
202
- /**
203
- * The message ID to delete
204
- */
205
- messageId: string;
206
- /**
207
- * Ticket received from the message
208
- */
209
- ticket: string;
210
- }
211
- interface DeleteMessageResponse {
212
- /**
213
- * Whether the message was successfully deleted
214
- */
215
- deleted: boolean;
216
- }
217
- interface ChangeVisibilityOptions {
218
- /**
219
- * The queue name the message belongs to
220
- */
221
- queueName: string;
222
- /**
223
- * Consumer group name
224
- */
225
- consumerGroup: string;
226
- /**
227
- * The message ID to update
228
- */
229
- messageId: string;
230
- /**
231
- * Ticket received from the message
232
- */
233
- ticket: string;
234
- /**
235
- * New visibility timeout in seconds
236
- */
237
- visibilityTimeoutSeconds: number;
238
- }
239
- interface ChangeVisibilityResponse {
240
- /**
241
- * Whether the visibility was successfully updated
242
- */
243
- updated: boolean;
244
- }
245
135
  /**
246
136
  * Result indicating the message should be timed out for retry later
247
137
  */
@@ -287,34 +177,6 @@ interface ConsumerGroupOptions<T = unknown> {
287
177
  */
288
178
  refreshInterval?: number;
289
179
  }
290
- interface ReceiveMessageByIdOptions<T = unknown> {
291
- /**
292
- * The queue name to receive the message from
293
- */
294
- queueName: string;
295
- /**
296
- * Consumer group name
297
- */
298
- consumerGroup: string;
299
- /**
300
- * The message ID to retrieve
301
- */
302
- messageId: string;
303
- /**
304
- * Time in seconds that the message will be invisible to other consumers
305
- * @default 900 (15 minutes)
306
- */
307
- visibilityTimeoutSeconds?: number;
308
- /**
309
- * Skip payload content and only return message metadata
310
- * When true, the server returns a 204 status with headers containing message metadata
311
- * @default false
312
- */
313
- skipPayload?: boolean;
314
- }
315
- interface ReceiveMessageByIdResponse<T = unknown, TSkipPayload extends boolean = false> {
316
- message: TSkipPayload extends true ? Message<void> : Message<T>;
317
- }
318
180
  /**
319
181
  * Error thrown when a message is not found (404)
320
182
  */
@@ -328,12 +190,6 @@ declare class MessageNotFoundError extends Error {
328
190
  declare class MessageNotAvailableError extends Error {
329
191
  constructor(messageId: string, reason?: string);
330
192
  }
331
- /**
332
- * Error thrown when there's a FIFO ordering violation (409)
333
- */
334
- declare class FifoOrderingViolationError extends Error {
335
- constructor(messageId: string, reason: string);
336
- }
337
193
  /**
338
194
  * Error thrown when message data is corrupted or can't be parsed
339
195
  */
@@ -347,7 +203,7 @@ declare class QueueEmptyError extends Error {
347
203
  constructor(queueName: string, consumerGroup: string);
348
204
  }
349
205
  /**
350
- * Error thrown when a message is temporarily locked in a FIFO queue (423)
206
+ * Error thrown when a message is temporarily locked (423)
351
207
  */
352
208
  declare class MessageLockedError extends Error {
353
209
  readonly retryAfter?: number;
@@ -371,12 +227,6 @@ declare class ForbiddenError extends Error {
371
227
  declare class BadRequestError extends Error {
372
228
  constructor(message: string);
373
229
  }
374
- /**
375
- * Error thrown when there's a failed dependency (424) - FIFO ordering violation in receive by ID
376
- */
377
- declare class FailedDependencyError extends Error {
378
- constructor(messageId: string);
379
- }
380
230
  /**
381
231
  * Error thrown for internal server errors (500)
382
232
  */
@@ -389,127 +239,6 @@ declare class InternalServerError extends Error {
389
239
  declare class InvalidLimitError extends Error {
390
240
  constructor(limit: number, min?: number, max?: number);
391
241
  }
392
- /**
393
- * Options extracted from a queue callback request
394
- */
395
- interface CallbackMessageOptions {
396
- /**
397
- * The queue name extracted from Vqs-Queue-Name header
398
- */
399
- queueName: string;
400
- /**
401
- * The consumer group extracted from Vqs-Consumer-Group header
402
- */
403
- consumerGroup: string;
404
- /**
405
- * The message ID extracted from Vqs-Message-Id header
406
- */
407
- messageId: string;
408
- }
409
- /**
410
- * Error thrown when queue callback headers are missing or invalid
411
- */
412
- declare class InvalidCallbackError extends Error {
413
- constructor(message: string);
414
- }
415
-
416
- /**
417
- * Client for interacting with the Vercel Queue Service API
418
- */
419
- declare class QueueClient {
420
- private baseUrl;
421
- private token;
422
- /**
423
- * Internal default instance for use by createTopic and other convenience functions
424
- * @internal
425
- */
426
- private static _defaultInstance;
427
- /**
428
- * Create a new Vercel Queue Service client
429
- * @param options Client configuration options (optional - will auto-detect Vercel Function environment)
430
- */
431
- constructor(options?: QueueClientOptions);
432
- /**
433
- * Get the default client instance for internal use by convenience functions
434
- * @internal
435
- */
436
- static _getDefaultInstance(): QueueClient;
437
- /**
438
- * Synchronously get OIDC token from environment
439
- * Used internally by constructor - mirrors the logic from getVercelOidcToken but synchronously
440
- */
441
- private getVercelOidcTokenSync;
442
- /**
443
- * Send a message to a queue
444
- * @param options Send message options
445
- * @param transport Serializer/deserializer for the payload
446
- * @returns Promise with the message ID
447
- * @throws {BadRequestError} When request parameters are invalid
448
- * @throws {UnauthorizedError} When authentication fails
449
- * @throws {ForbiddenError} When access is denied (environment mismatch)
450
- * @throws {InternalServerError} When server encounters an error
451
- */
452
- sendMessage<T = unknown>(options: SendMessageOptions<T>, transport: Transport<T>): Promise<SendMessageResponse>;
453
- /**
454
- * Receive messages from a queue
455
- * @param options Receive messages options
456
- * @param transport Serializer/deserializer for the payload
457
- * @returns AsyncGenerator that yields messages as they arrive
458
- * @throws {InvalidLimitError} When limit parameter is not between 1 and 10
459
- * @throws {QueueEmptyError} When no messages are available (204)
460
- * @throws {MessageLockedError} When FIFO queue has locked messages (423)
461
- * @throws {BadRequestError} When request parameters are invalid
462
- * @throws {UnauthorizedError} When authentication fails
463
- * @throws {ForbiddenError} When access is denied (environment mismatch)
464
- * @throws {InternalServerError} When server encounters an error
465
- */
466
- receiveMessages<T = unknown>(options: ReceiveMessagesOptions<T>, transport: Transport<T>): AsyncGenerator<Message<T>, void, unknown>;
467
- /**
468
- * Receive a specific message by its ID from a queue
469
- * @param options Receive message by ID options
470
- * @param transport Serializer/deserializer for the payload
471
- * @returns Promise with the message or null if not found/available
472
- * @throws {MessageNotFoundError} When the message doesn't exist (404)
473
- * @throws {MessageLockedError} When the message is temporarily locked (423)
474
- * @throws {FailedDependencyError} When FIFO ordering is violated (424)
475
- * @throws {MessageNotAvailableError} When message exists but isn't available (409)
476
- * @throws {MessageCorruptedError} When message data is corrupted
477
- * @throws {BadRequestError} When request parameters are invalid
478
- * @throws {UnauthorizedError} When authentication fails
479
- * @throws {ForbiddenError} When access is denied (environment mismatch)
480
- * @throws {InternalServerError} When server encounters an error
481
- */
482
- receiveMessageById<T = unknown>(options: ReceiveMessageByIdOptions<T> & {
483
- skipPayload: true;
484
- }, transport?: Transport<T>): Promise<ReceiveMessageByIdResponse<T, true>>;
485
- receiveMessageById<T = unknown>(options: ReceiveMessageByIdOptions<T> & {
486
- skipPayload?: false | undefined;
487
- }, transport: Transport<T>): Promise<ReceiveMessageByIdResponse<T, false>>;
488
- /**
489
- * Delete a message (acknowledge processing)
490
- * @param options Delete message options
491
- * @returns Promise with delete status
492
- * @throws {MessageNotFoundError} When the message doesn't exist (404)
493
- * @throws {MessageNotAvailableError} When message can't be deleted (409)
494
- * @throws {BadRequestError} When ticket is missing or invalid (400)
495
- * @throws {UnauthorizedError} When authentication fails
496
- * @throws {ForbiddenError} When access is denied (environment mismatch)
497
- * @throws {InternalServerError} When server encounters an error
498
- */
499
- deleteMessage(options: DeleteMessageOptions): Promise<DeleteMessageResponse>;
500
- /**
501
- * Change the visibility timeout of a message
502
- * @param options Change visibility options
503
- * @returns Promise with update status
504
- * @throws {MessageNotFoundError} When the message doesn't exist (404)
505
- * @throws {MessageNotAvailableError} When message can't be updated (409)
506
- * @throws {BadRequestError} When ticket is missing or visibility timeout invalid (400)
507
- * @throws {UnauthorizedError} When authentication fails
508
- * @throws {ForbiddenError} When access is denied (environment mismatch)
509
- * @throws {InternalServerError} When server encounters an error
510
- */
511
- changeVisibility(options: ChangeVisibilityOptions): Promise<ChangeVisibilityResponse>;
512
- }
513
242
 
514
243
  /**
515
244
  * Options for the consume method
@@ -520,140 +249,7 @@ interface ConsumeOptions {
520
249
  /** Whether to skip downloading the payload (only allowed when messageId is provided) */
521
250
  skipPayload?: boolean;
522
251
  }
523
- /**
524
- * A ConsumerGroup represents a named group of consumers that process messages from a topic
525
- */
526
- declare class ConsumerGroup<T = unknown> {
527
- private client;
528
- private topicName;
529
- private consumerGroupName;
530
- private visibilityTimeout;
531
- private refreshInterval;
532
- private transport;
533
- /**
534
- * Create a new ConsumerGroup instance
535
- * @param client QueueClient instance to use for API calls
536
- * @param topicName Name of the topic to consume from
537
- * @param consumerGroupName Name of the consumer group
538
- * @param options Optional configuration
539
- */
540
- constructor(client: QueueClient, topicName: string, consumerGroupName: string, options?: ConsumerGroupOptions<T>);
541
- /**
542
- * Starts a background loop that periodically extends the visibility timeout for a message.
543
- * This prevents the message from becoming visible to other consumers while it's being processed.
544
- *
545
- * The extension loop runs every `refreshInterval` seconds and updates the message's
546
- * visibility timeout to `visibilityTimeout` seconds from the current time.
547
- *
548
- * @param messageId - The unique identifier of the message to extend visibility for
549
- * @param ticket - The receipt ticket that proves ownership of the message
550
- * @returns A function that when called will stop the extension loop
551
- *
552
- * @remarks
553
- * - The first extension attempt occurs after `refreshInterval` seconds, not immediately
554
- * - If an extension fails, the loop terminates with an error logged to console
555
- * - The returned stop function is idempotent - calling it multiple times is safe
556
- * - By default, the stop function returns immediately without waiting for in-flight
557
- * - Pass `true` to the stop function to wait for any in-flight extension to complete
558
- */
559
- private startVisibilityExtension;
560
- /**
561
- * Process a single message with the given handler
562
- * @param message The message to process
563
- * @param handler Function to process the message
564
- */
565
- private processMessage;
566
- /**
567
- * Consume the next available message from the queue
568
- * @param handler Function to process the message
569
- * @returns Promise that resolves when the message is processed
570
- * @throws All the same errors as the underlying client methods
571
- */
572
- consume(handler: MessageHandler<T>): Promise<void>;
573
- /**
574
- * Consume a specific message by its ID with full payload
575
- * @param handler Function to process the message
576
- * @param options Consume options with messageId specified
577
- * @returns Promise that resolves when the message is processed
578
- * @throws All the same errors as the underlying client methods
579
- */
580
- consume(handler: MessageHandler<T>, options: {
581
- messageId: string;
582
- skipPayload?: false | undefined;
583
- }): Promise<void>;
584
- /**
585
- * Consume a specific message by its ID without downloading the payload (metadata only)
586
- * @param handler Function to process the message metadata (payload will be void)
587
- * @param options Consume options with messageId and skipPayload specified
588
- * @returns Promise that resolves when the message is processed
589
- * @throws All the same errors as the underlying client methods
590
- */
591
- consume(handler: MessageHandler<void>, options: {
592
- messageId: string;
593
- skipPayload: true;
594
- }): Promise<void>;
595
- /**
596
- * Get the consumer group name
597
- */
598
- get name(): string;
599
- /**
600
- * Get the topic name this consumer group is subscribed to
601
- */
602
- get topic(): string;
603
- }
604
-
605
- /**
606
- * A Topic represents a named channel for publishing messages in a pub/sub pattern
607
- */
608
- declare class Topic<T = unknown> {
609
- private client;
610
- private topicName;
611
- private transport;
612
- /**
613
- * Create a new Topic instance
614
- * @param client QueueClient instance to use for API calls
615
- * @param topicName Name of the topic to work with
616
- * @param transport Optional serializer/deserializer for the payload (defaults to JSON)
617
- */
618
- constructor(client: QueueClient, topicName: string, transport?: Transport<T>);
619
- /**
620
- * Publish a message to the topic
621
- * @param payload The data to publish
622
- * @param options Optional publish options
623
- * @returns An object containing the message ID
624
- * @throws {BadRequestError} When request parameters are invalid
625
- * @throws {UnauthorizedError} When authentication fails
626
- * @throws {ForbiddenError} When access is denied (environment mismatch)
627
- * @throws {InternalServerError} When server encounters an error
628
- */
629
- publish(payload: T, options?: PublishOptions): Promise<{
630
- messageId: string;
631
- }>;
632
- /**
633
- * Create a consumer group for this topic
634
- * @param consumerGroupName Name of the consumer group
635
- * @param options Optional configuration for the consumer group
636
- * @returns A ConsumerGroup instance
637
- */
638
- consumerGroup<U = T>(consumerGroupName: string, options?: ConsumerGroupOptions<U>): ConsumerGroup<U>;
639
- /**
640
- * Get the topic name
641
- */
642
- get name(): string;
643
- /**
644
- * Get the transport used by this topic
645
- */
646
- get serializer(): Transport<T>;
647
- }
648
252
 
649
- /**
650
- * Create a new Topic instance using the default QueueClient
651
- * For custom client configuration, use `new Topic(customClient, topicName, transport)` directly
652
- * @param topicName Name of the topic
653
- * @param transport Optional serializer/deserializer for the payload (defaults to JSON)
654
- * @returns A Topic instance
655
- */
656
- declare function createTopic<T = unknown>(topicName: string, transport?: Transport<T>): Topic<T>;
657
253
  /**
658
254
  * Options for the send function
659
255
  */
@@ -722,77 +318,45 @@ declare function receive<T = unknown>(topicName: string, consumerGroup: string,
722
318
  }): Promise<void>;
723
319
 
724
320
  /**
725
- * Queue Callback utilities for handling incoming webhook payloads
726
- */
727
-
728
- /**
729
- * Parse a queue callback request and extract the required information for receiveMessageById
730
- *
731
- * @param request The incoming Request object from the queue callback
732
- * @returns CallbackMessageOptions that can be used with receiveMessageById
733
- * @throws {InvalidCallbackError} When required queue headers are missing or invalid
734
- *
735
- * @example
736
- * ```typescript
737
- * import { parseCallbackRequest } from '@vercel/queue';
738
- *
739
- * // In your webhook handler
740
- * export async function POST(request: Request) {
741
- * try {
742
- * const callbackOptions = parseCallbackRequest(request);
743
- *
744
- * // Use with receiveMessageById
745
- * const message = await client.receiveMessageById({
746
- * ...callbackOptions,
747
- * visibilityTimeoutSeconds: 30
748
- * }, transport);
749
- *
750
- * // Process the message...
751
- * } catch (error) {
752
- * if (error instanceof InvalidCallbackError) {
753
- * return new Response('Invalid callback', { status: 400 });
754
- * }
755
- * throw error;
756
- * }
757
- * }
758
- * ```
759
- */
760
- declare function parseCallbackRequest(request: Request): CallbackMessageOptions;
761
- /**
762
- * Configuration object with handlers for different topics
763
- * Each topic can have either:
764
- * - A single handler function (uses 'default' consumer group)
765
- * - An object with handlers for specific consumer groups
321
+ * Configuration object with handlers for different topics and consumer groups
766
322
  */
767
323
  type CallbackHandlers = {
768
- [topicName: string]: MessageHandler | {
324
+ [topicName: string]: {
769
325
  [consumerGroup: string]: MessageHandler;
770
326
  };
771
327
  };
772
328
  /**
773
- * Simplified queue callback handler for NextJS route handlers
329
+ * Simplified queue callback handler for Next.js route handlers
330
+ *
331
+ * Automatically extracts queue information from Vercel-provided headers
332
+ * and routes to the appropriate handler based on topic and consumer group.
774
333
  *
775
- * @param handlers Object with topic-specific handlers
776
- * @returns A NextJS route handler function
334
+ * @param handlers Object with topic-specific handlers organized by consumer groups
335
+ * @returns A Next.js route handler function
777
336
  *
778
337
  * @example
779
338
  * ```typescript
780
- * // Topic handler (uses 'default' consumer group)
339
+ * // Single topic with multiple consumer groups
781
340
  * export const POST = handleCallback({
782
- * "new-users": (message, metadata) => {
783
- * console.log(`New user event:`, message, metadata);
341
+ * "image-processing": {
342
+ * "compress": (message, metadata) => console.log("Compressing image", message),
343
+ * "resize": (message, metadata) => console.log("Resizing image", message),
784
344
  * }
785
345
  * });
786
346
  *
787
- * // Consumer group specific handlers
347
+ * // Multiple topics with consumer groups
788
348
  * export const POST = handleCallback({
789
- * "image-processing": {
790
- * "compress": (message, metadata) => console.log("Compressing image", message),
791
- * "resize": (message, metadata) => console.log("Resizing image", message),
349
+ * "user-events": {
350
+ * "welcome": (user, metadata) => console.log("Welcoming user", user),
351
+ * "analytics": (user, metadata) => console.log("Tracking user", user),
352
+ * },
353
+ * "order-events": {
354
+ * "fulfillment": (order, metadata) => console.log("Fulfilling order", order),
355
+ * "notifications": (order, metadata) => console.log("Notifying order", order),
792
356
  * }
793
357
  * });
794
358
  * ```
795
359
  */
796
360
  declare function handleCallback(handlers: CallbackHandlers): (request: Request) => Promise<Response>;
797
361
 
798
- export { BadRequestError, BufferTransport, type CallbackConfig, type CallbackMessageOptions, type ChangeVisibilityOptions, type ChangeVisibilityResponse, type ConsumeOptions, ConsumerGroup, type ConsumerGroupOptions, type DeleteMessageOptions, type DeleteMessageResponse, FailedDependencyError, FifoOrderingViolationError, ForbiddenError, InternalServerError, InvalidCallbackError, InvalidLimitError, JsonTransport, type Message, MessageCorruptedError, type MessageHandler, type MessageHandlerResult, MessageLockedError, type MessageMetadata, MessageNotAvailableError, MessageNotFoundError, type MessageTimeoutResult, type PublishOptions, QueueClient, type QueueClientOptions, QueueEmptyError, type ReceiveMessageByIdOptions, type ReceiveMessageByIdResponse, type ReceiveMessagesOptions, type ReceiveOptions, type SendMessageOptions, type SendMessageResponse, type SendOptions, StreamTransport, Topic, type Transport, UnauthorizedError, createTopic, handleCallback, parseCallbackRequest, receive, send };
362
+ export { BadRequestError, BufferTransport, ForbiddenError, InternalServerError, InvalidLimitError, JsonTransport, type Message, MessageCorruptedError, type MessageHandler, type MessageHandlerResult, MessageLockedError, type MessageMetadata, MessageNotAvailableError, MessageNotFoundError, type MessageTimeoutResult, type PublishOptions, QueueEmptyError, type ReceiveOptions, type SendMessageOptions, type SendMessageResponse, type SendOptions, StreamTransport, type Transport, UnauthorizedError, handleCallback, receive, send };