@vercel/queue 0.0.0-alpha.36 → 0.0.0-alpha.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +212 -182
- package/dist/{types-C7IKe67P.d.mts → callback-lq_sorrn.d.mts} +249 -40
- package/dist/{types-C7IKe67P.d.ts → callback-lq_sorrn.d.ts} +249 -40
- package/dist/index.d.mts +74 -338
- package/dist/index.d.ts +74 -338
- package/dist/index.js +904 -930
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +900 -928
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs-pages.d.mts +47 -27
- package/dist/nextjs-pages.d.ts +47 -27
- package/dist/nextjs-pages.js +322 -373
- package/dist/nextjs-pages.js.map +1 -1
- package/dist/nextjs-pages.mjs +322 -373
- package/dist/nextjs-pages.mjs.map +1 -1
- package/dist/web.d.mts +60 -0
- package/dist/web.d.ts +60 -0
- package/dist/web.js +1457 -0
- package/dist/web.js.map +1 -0
- package/dist/web.mjs +1420 -0
- package/dist/web.mjs.map +1 -0
- package/package.json +11 -1
|
@@ -167,6 +167,12 @@ interface QueueClientOptions {
|
|
|
167
167
|
* @default true
|
|
168
168
|
*/
|
|
169
169
|
pinToDeployment?: boolean;
|
|
170
|
+
/**
|
|
171
|
+
* Serializer/deserializer for message payloads.
|
|
172
|
+
* Used for all send and receive operations.
|
|
173
|
+
* @default JsonTransport
|
|
174
|
+
*/
|
|
175
|
+
transport?: Transport;
|
|
170
176
|
}
|
|
171
177
|
/**
|
|
172
178
|
* Options for publishing messages to a topic.
|
|
@@ -273,13 +279,6 @@ interface ReceiveMessagesOptions<T = unknown> {
|
|
|
273
279
|
* @maximum 10
|
|
274
280
|
*/
|
|
275
281
|
limit?: number;
|
|
276
|
-
/**
|
|
277
|
-
* Maximum concurrent in-flight messages for this consumer group.
|
|
278
|
-
* When limit is reached, receive requests throw ConcurrencyLimitError.
|
|
279
|
-
* @default unlimited
|
|
280
|
-
* @minimum 1
|
|
281
|
-
*/
|
|
282
|
-
maxConcurrency?: number;
|
|
283
282
|
}
|
|
284
283
|
interface DeleteMessageOptions {
|
|
285
284
|
/**
|
|
@@ -340,32 +339,25 @@ interface MessageMetadata {
|
|
|
340
339
|
}
|
|
341
340
|
/**
|
|
342
341
|
* Message handler function type
|
|
342
|
+
*
|
|
343
|
+
* When a message is available, both `message` and `metadata` are provided.
|
|
344
|
+
* When the queue is empty, both `message` and `metadata` are `null`.
|
|
345
|
+
* This allows handlers to gracefully handle the empty queue case without
|
|
346
|
+
* catching exceptions.
|
|
343
347
|
*/
|
|
344
|
-
type MessageHandler<T = unknown> = (message: T, metadata: MessageMetadata) => Promise<void> | void;
|
|
348
|
+
type MessageHandler<T = unknown> = (message: T | null, metadata: MessageMetadata | null) => Promise<void> | void;
|
|
345
349
|
/**
|
|
346
350
|
* Options for creating a ConsumerGroup instance.
|
|
347
351
|
*/
|
|
348
352
|
interface ConsumerGroupOptions<T = unknown> {
|
|
349
|
-
/**
|
|
350
|
-
* Serializer/deserializer for the payload.
|
|
351
|
-
* Built-in options: JsonTransport, BufferTransport, StreamTransport.
|
|
352
|
-
* @default JsonTransport
|
|
353
|
-
*/
|
|
354
|
-
transport?: Transport<T>;
|
|
355
353
|
/**
|
|
356
354
|
* Time in seconds that messages will be invisible to other consumers after receipt.
|
|
357
355
|
* The ConsumerGroup will automatically extend this timeout during processing.
|
|
358
|
-
* @default
|
|
359
|
-
* @minimum
|
|
356
|
+
* @default 300 (5 minutes)
|
|
357
|
+
* @minimum 30
|
|
360
358
|
* @maximum 3600 (1 hour)
|
|
361
359
|
*/
|
|
362
360
|
visibilityTimeoutSeconds?: number;
|
|
363
|
-
/**
|
|
364
|
-
* How often (in seconds) to refresh the visibility timeout during message processing.
|
|
365
|
-
* Should be less than visibilityTimeoutSeconds to prevent message redelivery.
|
|
366
|
-
* @default Math.floor(visibilityTimeoutSeconds / 3)
|
|
367
|
-
*/
|
|
368
|
-
visibilityRefreshInterval?: number;
|
|
369
361
|
}
|
|
370
362
|
interface ReceiveMessageByIdOptions<T = unknown> {
|
|
371
363
|
/**
|
|
@@ -389,12 +381,6 @@ interface ReceiveMessageByIdOptions<T = unknown> {
|
|
|
389
381
|
* @maximum 3600 (1 hour)
|
|
390
382
|
*/
|
|
391
383
|
visibilityTimeoutSeconds?: number;
|
|
392
|
-
/**
|
|
393
|
-
* Maximum concurrent in-flight messages for this consumer group.
|
|
394
|
-
* @default unlimited
|
|
395
|
-
* @minimum 1
|
|
396
|
-
*/
|
|
397
|
-
maxConcurrency?: number;
|
|
398
384
|
}
|
|
399
385
|
interface ReceiveMessageByIdResponse<T = unknown> {
|
|
400
386
|
message: Message<T>;
|
|
@@ -472,17 +458,6 @@ declare class InvalidLimitError extends Error {
|
|
|
472
458
|
declare class MessageAlreadyProcessedError extends Error {
|
|
473
459
|
constructor(messageId: string);
|
|
474
460
|
}
|
|
475
|
-
/**
|
|
476
|
-
* Error thrown when the concurrency limit is exceeded.
|
|
477
|
-
* This occurs when maxConcurrency is set and too many messages are already in-flight.
|
|
478
|
-
*/
|
|
479
|
-
declare class ConcurrencyLimitError extends Error {
|
|
480
|
-
/** Current number of in-flight messages for this consumer group. */
|
|
481
|
-
readonly currentInflight?: number;
|
|
482
|
-
/** Maximum allowed concurrent messages (as configured). */
|
|
483
|
-
readonly maxConcurrency?: number;
|
|
484
|
-
constructor(message?: string, currentInflight?: number, maxConcurrency?: number);
|
|
485
|
-
}
|
|
486
461
|
/**
|
|
487
462
|
* Error thrown when a duplicate idempotency key is detected.
|
|
488
463
|
* The message was already sent within the deduplication window.
|
|
@@ -506,4 +481,238 @@ declare class ConsumerRegistryNotConfiguredError extends Error {
|
|
|
506
481
|
constructor(message?: string);
|
|
507
482
|
}
|
|
508
483
|
|
|
509
|
-
|
|
484
|
+
declare class QueueClient {
|
|
485
|
+
private baseUrl;
|
|
486
|
+
private basePath;
|
|
487
|
+
private customHeaders;
|
|
488
|
+
private providedToken?;
|
|
489
|
+
private defaultDeploymentId?;
|
|
490
|
+
private pinToDeployment;
|
|
491
|
+
private transport;
|
|
492
|
+
constructor(options?: QueueClientOptions);
|
|
493
|
+
getTransport(): Transport;
|
|
494
|
+
private getSendDeploymentId;
|
|
495
|
+
private getConsumeDeploymentId;
|
|
496
|
+
private getToken;
|
|
497
|
+
private buildUrl;
|
|
498
|
+
private fetch;
|
|
499
|
+
/**
|
|
500
|
+
* Send a message to a topic.
|
|
501
|
+
*
|
|
502
|
+
* @param options - Message options including queue name, payload, and optional settings
|
|
503
|
+
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
504
|
+
* @param options.payload - Message payload
|
|
505
|
+
* @param options.idempotencyKey - Optional deduplication key (dedup window: min(retention, 24h))
|
|
506
|
+
* @param options.retentionSeconds - Message TTL (default: 86400, min: 60, max: 86400)
|
|
507
|
+
* @param options.delaySeconds - Delivery delay (default: 0, max: retentionSeconds)
|
|
508
|
+
* @returns Promise with the generated messageId
|
|
509
|
+
* @throws {DuplicateMessageError} When idempotency key was already used
|
|
510
|
+
* @throws {ConsumerDiscoveryError} When consumer discovery fails
|
|
511
|
+
* @throws {ConsumerRegistryNotConfiguredError} When registry not configured
|
|
512
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
513
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
514
|
+
* @throws {ForbiddenError} When access is denied
|
|
515
|
+
* @throws {InternalServerError} When server encounters an error
|
|
516
|
+
*/
|
|
517
|
+
sendMessage<T = unknown>(options: SendMessageOptions<T>): Promise<SendMessageResponse>;
|
|
518
|
+
/**
|
|
519
|
+
* Receive messages from a topic as an async generator.
|
|
520
|
+
*
|
|
521
|
+
* When the queue is empty, the generator completes without yielding any
|
|
522
|
+
* messages. Callers should handle the case where no messages are yielded.
|
|
523
|
+
*
|
|
524
|
+
* @param options - Receive options
|
|
525
|
+
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
526
|
+
* @param options.consumerGroup - Consumer group name (pattern: `[A-Za-z0-9_-]+`)
|
|
527
|
+
* @param options.visibilityTimeoutSeconds - Lock duration (default: 30, min: 0, max: 3600)
|
|
528
|
+
* @param options.limit - Max messages to retrieve (default: 1, min: 1, max: 10)
|
|
529
|
+
* @yields Message objects with payload, messageId, receiptHandle, etc.
|
|
530
|
+
* Yields nothing if queue is empty.
|
|
531
|
+
* @throws {InvalidLimitError} When limit is outside 1-10 range
|
|
532
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
533
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
534
|
+
* @throws {ForbiddenError} When access is denied
|
|
535
|
+
* @throws {InternalServerError} When server encounters an error
|
|
536
|
+
*/
|
|
537
|
+
receiveMessages<T = unknown>(options: ReceiveMessagesOptions<T>): AsyncGenerator<Message<T>, void, unknown>;
|
|
538
|
+
/**
|
|
539
|
+
* Receive a specific message by its ID.
|
|
540
|
+
*
|
|
541
|
+
* @param options - Receive options
|
|
542
|
+
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
543
|
+
* @param options.consumerGroup - Consumer group name (pattern: `[A-Za-z0-9_-]+`)
|
|
544
|
+
* @param options.messageId - Message ID to retrieve
|
|
545
|
+
* @param options.visibilityTimeoutSeconds - Lock duration (default: 30, min: 0, max: 3600)
|
|
546
|
+
* @returns Promise with the message
|
|
547
|
+
* @throws {MessageNotFoundError} When message doesn't exist
|
|
548
|
+
* @throws {MessageNotAvailableError} When message is in wrong state or was a duplicate
|
|
549
|
+
* @throws {MessageAlreadyProcessedError} When message was already processed
|
|
550
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
551
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
552
|
+
* @throws {ForbiddenError} When access is denied
|
|
553
|
+
* @throws {InternalServerError} When server encounters an error
|
|
554
|
+
*/
|
|
555
|
+
receiveMessageById<T = unknown>(options: ReceiveMessageByIdOptions<T>): Promise<ReceiveMessageByIdResponse<T>>;
|
|
556
|
+
/**
|
|
557
|
+
* Delete (acknowledge) a message after successful processing.
|
|
558
|
+
*
|
|
559
|
+
* @param options - Delete options
|
|
560
|
+
* @param options.queueName - Topic name
|
|
561
|
+
* @param options.consumerGroup - Consumer group name
|
|
562
|
+
* @param options.receiptHandle - Receipt handle from the received message (must use same deployment ID as receive)
|
|
563
|
+
* @returns Promise indicating deletion success
|
|
564
|
+
* @throws {MessageNotFoundError} When receipt handle not found
|
|
565
|
+
* @throws {MessageNotAvailableError} When receipt handle invalid or message already processed
|
|
566
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
567
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
568
|
+
* @throws {ForbiddenError} When access is denied
|
|
569
|
+
* @throws {InternalServerError} When server encounters an error
|
|
570
|
+
*/
|
|
571
|
+
deleteMessage(options: DeleteMessageOptions): Promise<DeleteMessageResponse>;
|
|
572
|
+
/**
|
|
573
|
+
* Extend or change the visibility timeout of a message.
|
|
574
|
+
* Used to prevent message redelivery while still processing.
|
|
575
|
+
*
|
|
576
|
+
* @param options - Visibility options
|
|
577
|
+
* @param options.queueName - Topic name
|
|
578
|
+
* @param options.consumerGroup - Consumer group name
|
|
579
|
+
* @param options.receiptHandle - Receipt handle from the received message (must use same deployment ID as receive)
|
|
580
|
+
* @param options.visibilityTimeoutSeconds - New timeout (min: 0, max: 3600, cannot exceed message expiration)
|
|
581
|
+
* @returns Promise indicating success
|
|
582
|
+
* @throws {MessageNotFoundError} When receipt handle not found
|
|
583
|
+
* @throws {MessageNotAvailableError} When receipt handle invalid or message already processed
|
|
584
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
585
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
586
|
+
* @throws {ForbiddenError} When access is denied
|
|
587
|
+
* @throws {InternalServerError} When server encounters an error
|
|
588
|
+
*/
|
|
589
|
+
changeVisibility(options: ChangeVisibilityOptions): Promise<ChangeVisibilityResponse>;
|
|
590
|
+
/**
|
|
591
|
+
* Alternative endpoint for changing message visibility timeout.
|
|
592
|
+
* Uses the /visibility path suffix and expects visibilityTimeoutSeconds in the body.
|
|
593
|
+
* Functionally equivalent to changeVisibility but follows an alternative API pattern.
|
|
594
|
+
*
|
|
595
|
+
* @param options - Options for changing visibility
|
|
596
|
+
* @returns Promise resolving to change visibility response
|
|
597
|
+
*/
|
|
598
|
+
changeVisibilityAlt(options: ChangeVisibilityOptions): Promise<ChangeVisibilityResponse>;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Core queue callback utilities for handling incoming webhook payloads
|
|
603
|
+
* from Vercel triggers using the CloudEvent specification.
|
|
604
|
+
*
|
|
605
|
+
* This module provides the framework-agnostic core. For framework-specific
|
|
606
|
+
* wrappers, see `@vercel/queue/web` and `@vercel/queue/nextjs/pages`.
|
|
607
|
+
*/
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Options for configuring `handleCallback` behavior.
|
|
611
|
+
*/
|
|
612
|
+
interface HandleCallbackOptions {
|
|
613
|
+
/**
|
|
614
|
+
* QueueClient instance to use for processing messages.
|
|
615
|
+
* If not provided, a default client is created with OIDC authentication
|
|
616
|
+
* and JsonTransport.
|
|
617
|
+
*/
|
|
618
|
+
client?: QueueClient;
|
|
619
|
+
/**
|
|
620
|
+
* Time in seconds that messages will be invisible to other consumers
|
|
621
|
+
* during processing. The handler will automatically extend this timeout
|
|
622
|
+
* while processing.
|
|
623
|
+
*
|
|
624
|
+
* @default 300 (5 minutes)
|
|
625
|
+
* @minimum 30
|
|
626
|
+
* @maximum 3600 (1 hour)
|
|
627
|
+
*/
|
|
628
|
+
visibilityTimeoutSeconds?: number;
|
|
629
|
+
}
|
|
630
|
+
declare const CLOUD_EVENT_TYPE_V1BETA = "com.vercel.queue.v1beta";
|
|
631
|
+
declare const CLOUD_EVENT_TYPE_V2BETA = "com.vercel.queue.v2beta";
|
|
632
|
+
/**
|
|
633
|
+
* Routing-only callback: the SDK must fetch the message by ID.
|
|
634
|
+
* Produced by v1beta structured mode and v2beta large-body mode.
|
|
635
|
+
*/
|
|
636
|
+
type ParsedCallbackV1 = {
|
|
637
|
+
queueName: string;
|
|
638
|
+
consumerGroup: string;
|
|
639
|
+
messageId: string;
|
|
640
|
+
};
|
|
641
|
+
/**
|
|
642
|
+
* Full-message callback: payload and receipt handle are inlined,
|
|
643
|
+
* so the SDK can process directly without an extra fetch.
|
|
644
|
+
* Produced by v2beta small-body mode.
|
|
645
|
+
*/
|
|
646
|
+
type ParsedCallbackV2 = {
|
|
647
|
+
queueName: string;
|
|
648
|
+
consumerGroup: string;
|
|
649
|
+
messageId: string;
|
|
650
|
+
receiptHandle: string;
|
|
651
|
+
deliveryCount?: number;
|
|
652
|
+
createdAt?: string;
|
|
653
|
+
contentType?: string;
|
|
654
|
+
visibilityDeadline?: string;
|
|
655
|
+
rawBody?: ReadableStream<Uint8Array>;
|
|
656
|
+
parsedPayload?: unknown;
|
|
657
|
+
};
|
|
658
|
+
type ParsedCallbackRequest = ParsedCallbackV1 | ParsedCallbackV2;
|
|
659
|
+
/**
|
|
660
|
+
* Parse a callback from a pre-parsed body and headers.
|
|
661
|
+
*
|
|
662
|
+
* For frameworks like Next.js Pages Router where the body has already been
|
|
663
|
+
* parsed, use this instead of {@link parseCallback}.
|
|
664
|
+
*
|
|
665
|
+
* Detects the CloudEvent version from the `ce-type` header:
|
|
666
|
+
* - `com.vercel.queue.v2beta`: binary content mode (metadata in headers,
|
|
667
|
+
* payload in body). For small messages, the body is attached as `parsedPayload`.
|
|
668
|
+
* - Otherwise: structured content mode (v1beta, entire CloudEvent in JSON body)
|
|
669
|
+
*
|
|
670
|
+
* @param body - The framework-parsed request body. Type depends on Content-Type
|
|
671
|
+
* and framework configuration:
|
|
672
|
+
* - v1beta: parsed CloudEvent JSON object
|
|
673
|
+
* - v2beta: the message payload as parsed by the framework (object, Buffer, or string)
|
|
674
|
+
* @param headers - HTTP headers
|
|
675
|
+
* @returns Parsed callback request with routing metadata and optional payload
|
|
676
|
+
*/
|
|
677
|
+
declare function parseRawCallback(body: unknown, headers: Record<string, string | string[] | undefined>): ParsedCallbackRequest;
|
|
678
|
+
/**
|
|
679
|
+
* Parse and validate a CloudEvent callback from a Web API `Request` object.
|
|
680
|
+
*
|
|
681
|
+
* Detects the CloudEvent version from the `ce-type` header:
|
|
682
|
+
* - `com.vercel.queue.v2beta`: binary content mode (metadata in headers,
|
|
683
|
+
* payload in body). For v2beta, the body is attached as `rawBody` (a
|
|
684
|
+
* ReadableStream) rather than being parsed.
|
|
685
|
+
* - Otherwise: structured content mode (v1beta, entire CloudEvent in JSON body)
|
|
686
|
+
*
|
|
687
|
+
* For frameworks that pre-parse the body (e.g. Next.js Pages Router),
|
|
688
|
+
* use {@link parseRawCallback} instead.
|
|
689
|
+
*/
|
|
690
|
+
declare function parseCallback(request: Request): Promise<ParsedCallbackRequest>;
|
|
691
|
+
/**
|
|
692
|
+
* Core queue callback handler. Processes the message using the provided handler.
|
|
693
|
+
*
|
|
694
|
+
* This is the framework-agnostic core — it takes already-parsed request data
|
|
695
|
+
* and throws on errors. Framework-specific wrappers (in `@vercel/queue/web`
|
|
696
|
+
* and `@vercel/queue/nextjs/pages`) compose around this function to handle
|
|
697
|
+
* request parsing and response formatting.
|
|
698
|
+
*
|
|
699
|
+
* @param handler - Function to process the message payload and metadata
|
|
700
|
+
* @param request - A {@link ParsedCallbackV1} (routing metadata only, message
|
|
701
|
+
* fetched by ID) or {@link ParsedCallbackV2} (full message inlined, no fetch).
|
|
702
|
+
* @param options - Optional configuration (client, visibilityTimeoutSeconds)
|
|
703
|
+
* @throws {Error} If binary mode request has a receipt handle but no payload
|
|
704
|
+
* @throws {Error} If message processing fails
|
|
705
|
+
*
|
|
706
|
+
* @example
|
|
707
|
+
* ```typescript
|
|
708
|
+
* import { handleCallback, parseRawCallback } from "@vercel/queue";
|
|
709
|
+
*
|
|
710
|
+
* const parsed = parseRawCallback(body, headers);
|
|
711
|
+
* await handleCallback(async (message, metadata) => {
|
|
712
|
+
* console.log("Processing:", message);
|
|
713
|
+
* }, parsed);
|
|
714
|
+
* ```
|
|
715
|
+
*/
|
|
716
|
+
declare function handleCallback<T = unknown>(handler: MessageHandler<T>, request: ParsedCallbackRequest, options?: HandleCallbackOptions): Promise<void>;
|
|
717
|
+
|
|
718
|
+
export { BufferTransport as B, type ConsumerGroupOptions as C, DuplicateMessageError as D, ForbiddenError as F, type HandleCallbackOptions as H, InternalServerError as I, JsonTransport as J, type MessageHandler as M, type PublishOptions as P, QueueClient as Q, StreamTransport as S, type Transport as T, UnauthorizedError as U, CLOUD_EVENT_TYPE_V1BETA as a, CLOUD_EVENT_TYPE_V2BETA as b, parseRawCallback as c, type ParsedCallbackRequest as d, type ParsedCallbackV1 as e, type ParsedCallbackV2 as f, BadRequestError as g, handleCallback as h, ConsumerDiscoveryError as i, ConsumerRegistryNotConfiguredError as j, InvalidLimitError as k, MessageAlreadyProcessedError as l, MessageCorruptedError as m, MessageLockedError as n, MessageNotAvailableError as o, parseCallback as p, MessageNotFoundError as q, QueueEmptyError as r, type Message as s, type MessageMetadata as t, type QueueClientOptions as u, type SendMessageOptions as v, type SendMessageResponse as w };
|
|
@@ -167,6 +167,12 @@ interface QueueClientOptions {
|
|
|
167
167
|
* @default true
|
|
168
168
|
*/
|
|
169
169
|
pinToDeployment?: boolean;
|
|
170
|
+
/**
|
|
171
|
+
* Serializer/deserializer for message payloads.
|
|
172
|
+
* Used for all send and receive operations.
|
|
173
|
+
* @default JsonTransport
|
|
174
|
+
*/
|
|
175
|
+
transport?: Transport;
|
|
170
176
|
}
|
|
171
177
|
/**
|
|
172
178
|
* Options for publishing messages to a topic.
|
|
@@ -273,13 +279,6 @@ interface ReceiveMessagesOptions<T = unknown> {
|
|
|
273
279
|
* @maximum 10
|
|
274
280
|
*/
|
|
275
281
|
limit?: number;
|
|
276
|
-
/**
|
|
277
|
-
* Maximum concurrent in-flight messages for this consumer group.
|
|
278
|
-
* When limit is reached, receive requests throw ConcurrencyLimitError.
|
|
279
|
-
* @default unlimited
|
|
280
|
-
* @minimum 1
|
|
281
|
-
*/
|
|
282
|
-
maxConcurrency?: number;
|
|
283
282
|
}
|
|
284
283
|
interface DeleteMessageOptions {
|
|
285
284
|
/**
|
|
@@ -340,32 +339,25 @@ interface MessageMetadata {
|
|
|
340
339
|
}
|
|
341
340
|
/**
|
|
342
341
|
* Message handler function type
|
|
342
|
+
*
|
|
343
|
+
* When a message is available, both `message` and `metadata` are provided.
|
|
344
|
+
* When the queue is empty, both `message` and `metadata` are `null`.
|
|
345
|
+
* This allows handlers to gracefully handle the empty queue case without
|
|
346
|
+
* catching exceptions.
|
|
343
347
|
*/
|
|
344
|
-
type MessageHandler<T = unknown> = (message: T, metadata: MessageMetadata) => Promise<void> | void;
|
|
348
|
+
type MessageHandler<T = unknown> = (message: T | null, metadata: MessageMetadata | null) => Promise<void> | void;
|
|
345
349
|
/**
|
|
346
350
|
* Options for creating a ConsumerGroup instance.
|
|
347
351
|
*/
|
|
348
352
|
interface ConsumerGroupOptions<T = unknown> {
|
|
349
|
-
/**
|
|
350
|
-
* Serializer/deserializer for the payload.
|
|
351
|
-
* Built-in options: JsonTransport, BufferTransport, StreamTransport.
|
|
352
|
-
* @default JsonTransport
|
|
353
|
-
*/
|
|
354
|
-
transport?: Transport<T>;
|
|
355
353
|
/**
|
|
356
354
|
* Time in seconds that messages will be invisible to other consumers after receipt.
|
|
357
355
|
* The ConsumerGroup will automatically extend this timeout during processing.
|
|
358
|
-
* @default
|
|
359
|
-
* @minimum
|
|
356
|
+
* @default 300 (5 minutes)
|
|
357
|
+
* @minimum 30
|
|
360
358
|
* @maximum 3600 (1 hour)
|
|
361
359
|
*/
|
|
362
360
|
visibilityTimeoutSeconds?: number;
|
|
363
|
-
/**
|
|
364
|
-
* How often (in seconds) to refresh the visibility timeout during message processing.
|
|
365
|
-
* Should be less than visibilityTimeoutSeconds to prevent message redelivery.
|
|
366
|
-
* @default Math.floor(visibilityTimeoutSeconds / 3)
|
|
367
|
-
*/
|
|
368
|
-
visibilityRefreshInterval?: number;
|
|
369
361
|
}
|
|
370
362
|
interface ReceiveMessageByIdOptions<T = unknown> {
|
|
371
363
|
/**
|
|
@@ -389,12 +381,6 @@ interface ReceiveMessageByIdOptions<T = unknown> {
|
|
|
389
381
|
* @maximum 3600 (1 hour)
|
|
390
382
|
*/
|
|
391
383
|
visibilityTimeoutSeconds?: number;
|
|
392
|
-
/**
|
|
393
|
-
* Maximum concurrent in-flight messages for this consumer group.
|
|
394
|
-
* @default unlimited
|
|
395
|
-
* @minimum 1
|
|
396
|
-
*/
|
|
397
|
-
maxConcurrency?: number;
|
|
398
384
|
}
|
|
399
385
|
interface ReceiveMessageByIdResponse<T = unknown> {
|
|
400
386
|
message: Message<T>;
|
|
@@ -472,17 +458,6 @@ declare class InvalidLimitError extends Error {
|
|
|
472
458
|
declare class MessageAlreadyProcessedError extends Error {
|
|
473
459
|
constructor(messageId: string);
|
|
474
460
|
}
|
|
475
|
-
/**
|
|
476
|
-
* Error thrown when the concurrency limit is exceeded.
|
|
477
|
-
* This occurs when maxConcurrency is set and too many messages are already in-flight.
|
|
478
|
-
*/
|
|
479
|
-
declare class ConcurrencyLimitError extends Error {
|
|
480
|
-
/** Current number of in-flight messages for this consumer group. */
|
|
481
|
-
readonly currentInflight?: number;
|
|
482
|
-
/** Maximum allowed concurrent messages (as configured). */
|
|
483
|
-
readonly maxConcurrency?: number;
|
|
484
|
-
constructor(message?: string, currentInflight?: number, maxConcurrency?: number);
|
|
485
|
-
}
|
|
486
461
|
/**
|
|
487
462
|
* Error thrown when a duplicate idempotency key is detected.
|
|
488
463
|
* The message was already sent within the deduplication window.
|
|
@@ -506,4 +481,238 @@ declare class ConsumerRegistryNotConfiguredError extends Error {
|
|
|
506
481
|
constructor(message?: string);
|
|
507
482
|
}
|
|
508
483
|
|
|
509
|
-
|
|
484
|
+
declare class QueueClient {
|
|
485
|
+
private baseUrl;
|
|
486
|
+
private basePath;
|
|
487
|
+
private customHeaders;
|
|
488
|
+
private providedToken?;
|
|
489
|
+
private defaultDeploymentId?;
|
|
490
|
+
private pinToDeployment;
|
|
491
|
+
private transport;
|
|
492
|
+
constructor(options?: QueueClientOptions);
|
|
493
|
+
getTransport(): Transport;
|
|
494
|
+
private getSendDeploymentId;
|
|
495
|
+
private getConsumeDeploymentId;
|
|
496
|
+
private getToken;
|
|
497
|
+
private buildUrl;
|
|
498
|
+
private fetch;
|
|
499
|
+
/**
|
|
500
|
+
* Send a message to a topic.
|
|
501
|
+
*
|
|
502
|
+
* @param options - Message options including queue name, payload, and optional settings
|
|
503
|
+
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
504
|
+
* @param options.payload - Message payload
|
|
505
|
+
* @param options.idempotencyKey - Optional deduplication key (dedup window: min(retention, 24h))
|
|
506
|
+
* @param options.retentionSeconds - Message TTL (default: 86400, min: 60, max: 86400)
|
|
507
|
+
* @param options.delaySeconds - Delivery delay (default: 0, max: retentionSeconds)
|
|
508
|
+
* @returns Promise with the generated messageId
|
|
509
|
+
* @throws {DuplicateMessageError} When idempotency key was already used
|
|
510
|
+
* @throws {ConsumerDiscoveryError} When consumer discovery fails
|
|
511
|
+
* @throws {ConsumerRegistryNotConfiguredError} When registry not configured
|
|
512
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
513
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
514
|
+
* @throws {ForbiddenError} When access is denied
|
|
515
|
+
* @throws {InternalServerError} When server encounters an error
|
|
516
|
+
*/
|
|
517
|
+
sendMessage<T = unknown>(options: SendMessageOptions<T>): Promise<SendMessageResponse>;
|
|
518
|
+
/**
|
|
519
|
+
* Receive messages from a topic as an async generator.
|
|
520
|
+
*
|
|
521
|
+
* When the queue is empty, the generator completes without yielding any
|
|
522
|
+
* messages. Callers should handle the case where no messages are yielded.
|
|
523
|
+
*
|
|
524
|
+
* @param options - Receive options
|
|
525
|
+
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
526
|
+
* @param options.consumerGroup - Consumer group name (pattern: `[A-Za-z0-9_-]+`)
|
|
527
|
+
* @param options.visibilityTimeoutSeconds - Lock duration (default: 30, min: 0, max: 3600)
|
|
528
|
+
* @param options.limit - Max messages to retrieve (default: 1, min: 1, max: 10)
|
|
529
|
+
* @yields Message objects with payload, messageId, receiptHandle, etc.
|
|
530
|
+
* Yields nothing if queue is empty.
|
|
531
|
+
* @throws {InvalidLimitError} When limit is outside 1-10 range
|
|
532
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
533
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
534
|
+
* @throws {ForbiddenError} When access is denied
|
|
535
|
+
* @throws {InternalServerError} When server encounters an error
|
|
536
|
+
*/
|
|
537
|
+
receiveMessages<T = unknown>(options: ReceiveMessagesOptions<T>): AsyncGenerator<Message<T>, void, unknown>;
|
|
538
|
+
/**
|
|
539
|
+
* Receive a specific message by its ID.
|
|
540
|
+
*
|
|
541
|
+
* @param options - Receive options
|
|
542
|
+
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
543
|
+
* @param options.consumerGroup - Consumer group name (pattern: `[A-Za-z0-9_-]+`)
|
|
544
|
+
* @param options.messageId - Message ID to retrieve
|
|
545
|
+
* @param options.visibilityTimeoutSeconds - Lock duration (default: 30, min: 0, max: 3600)
|
|
546
|
+
* @returns Promise with the message
|
|
547
|
+
* @throws {MessageNotFoundError} When message doesn't exist
|
|
548
|
+
* @throws {MessageNotAvailableError} When message is in wrong state or was a duplicate
|
|
549
|
+
* @throws {MessageAlreadyProcessedError} When message was already processed
|
|
550
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
551
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
552
|
+
* @throws {ForbiddenError} When access is denied
|
|
553
|
+
* @throws {InternalServerError} When server encounters an error
|
|
554
|
+
*/
|
|
555
|
+
receiveMessageById<T = unknown>(options: ReceiveMessageByIdOptions<T>): Promise<ReceiveMessageByIdResponse<T>>;
|
|
556
|
+
/**
|
|
557
|
+
* Delete (acknowledge) a message after successful processing.
|
|
558
|
+
*
|
|
559
|
+
* @param options - Delete options
|
|
560
|
+
* @param options.queueName - Topic name
|
|
561
|
+
* @param options.consumerGroup - Consumer group name
|
|
562
|
+
* @param options.receiptHandle - Receipt handle from the received message (must use same deployment ID as receive)
|
|
563
|
+
* @returns Promise indicating deletion success
|
|
564
|
+
* @throws {MessageNotFoundError} When receipt handle not found
|
|
565
|
+
* @throws {MessageNotAvailableError} When receipt handle invalid or message already processed
|
|
566
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
567
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
568
|
+
* @throws {ForbiddenError} When access is denied
|
|
569
|
+
* @throws {InternalServerError} When server encounters an error
|
|
570
|
+
*/
|
|
571
|
+
deleteMessage(options: DeleteMessageOptions): Promise<DeleteMessageResponse>;
|
|
572
|
+
/**
|
|
573
|
+
* Extend or change the visibility timeout of a message.
|
|
574
|
+
* Used to prevent message redelivery while still processing.
|
|
575
|
+
*
|
|
576
|
+
* @param options - Visibility options
|
|
577
|
+
* @param options.queueName - Topic name
|
|
578
|
+
* @param options.consumerGroup - Consumer group name
|
|
579
|
+
* @param options.receiptHandle - Receipt handle from the received message (must use same deployment ID as receive)
|
|
580
|
+
* @param options.visibilityTimeoutSeconds - New timeout (min: 0, max: 3600, cannot exceed message expiration)
|
|
581
|
+
* @returns Promise indicating success
|
|
582
|
+
* @throws {MessageNotFoundError} When receipt handle not found
|
|
583
|
+
* @throws {MessageNotAvailableError} When receipt handle invalid or message already processed
|
|
584
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
585
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
586
|
+
* @throws {ForbiddenError} When access is denied
|
|
587
|
+
* @throws {InternalServerError} When server encounters an error
|
|
588
|
+
*/
|
|
589
|
+
changeVisibility(options: ChangeVisibilityOptions): Promise<ChangeVisibilityResponse>;
|
|
590
|
+
/**
|
|
591
|
+
* Alternative endpoint for changing message visibility timeout.
|
|
592
|
+
* Uses the /visibility path suffix and expects visibilityTimeoutSeconds in the body.
|
|
593
|
+
* Functionally equivalent to changeVisibility but follows an alternative API pattern.
|
|
594
|
+
*
|
|
595
|
+
* @param options - Options for changing visibility
|
|
596
|
+
* @returns Promise resolving to change visibility response
|
|
597
|
+
*/
|
|
598
|
+
changeVisibilityAlt(options: ChangeVisibilityOptions): Promise<ChangeVisibilityResponse>;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
* Core queue callback utilities for handling incoming webhook payloads
|
|
603
|
+
* from Vercel triggers using the CloudEvent specification.
|
|
604
|
+
*
|
|
605
|
+
* This module provides the framework-agnostic core. For framework-specific
|
|
606
|
+
* wrappers, see `@vercel/queue/web` and `@vercel/queue/nextjs/pages`.
|
|
607
|
+
*/
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Options for configuring `handleCallback` behavior.
|
|
611
|
+
*/
|
|
612
|
+
interface HandleCallbackOptions {
|
|
613
|
+
/**
|
|
614
|
+
* QueueClient instance to use for processing messages.
|
|
615
|
+
* If not provided, a default client is created with OIDC authentication
|
|
616
|
+
* and JsonTransport.
|
|
617
|
+
*/
|
|
618
|
+
client?: QueueClient;
|
|
619
|
+
/**
|
|
620
|
+
* Time in seconds that messages will be invisible to other consumers
|
|
621
|
+
* during processing. The handler will automatically extend this timeout
|
|
622
|
+
* while processing.
|
|
623
|
+
*
|
|
624
|
+
* @default 300 (5 minutes)
|
|
625
|
+
* @minimum 30
|
|
626
|
+
* @maximum 3600 (1 hour)
|
|
627
|
+
*/
|
|
628
|
+
visibilityTimeoutSeconds?: number;
|
|
629
|
+
}
|
|
630
|
+
declare const CLOUD_EVENT_TYPE_V1BETA = "com.vercel.queue.v1beta";
|
|
631
|
+
declare const CLOUD_EVENT_TYPE_V2BETA = "com.vercel.queue.v2beta";
|
|
632
|
+
/**
|
|
633
|
+
* Routing-only callback: the SDK must fetch the message by ID.
|
|
634
|
+
* Produced by v1beta structured mode and v2beta large-body mode.
|
|
635
|
+
*/
|
|
636
|
+
type ParsedCallbackV1 = {
|
|
637
|
+
queueName: string;
|
|
638
|
+
consumerGroup: string;
|
|
639
|
+
messageId: string;
|
|
640
|
+
};
|
|
641
|
+
/**
|
|
642
|
+
* Full-message callback: payload and receipt handle are inlined,
|
|
643
|
+
* so the SDK can process directly without an extra fetch.
|
|
644
|
+
* Produced by v2beta small-body mode.
|
|
645
|
+
*/
|
|
646
|
+
type ParsedCallbackV2 = {
|
|
647
|
+
queueName: string;
|
|
648
|
+
consumerGroup: string;
|
|
649
|
+
messageId: string;
|
|
650
|
+
receiptHandle: string;
|
|
651
|
+
deliveryCount?: number;
|
|
652
|
+
createdAt?: string;
|
|
653
|
+
contentType?: string;
|
|
654
|
+
visibilityDeadline?: string;
|
|
655
|
+
rawBody?: ReadableStream<Uint8Array>;
|
|
656
|
+
parsedPayload?: unknown;
|
|
657
|
+
};
|
|
658
|
+
type ParsedCallbackRequest = ParsedCallbackV1 | ParsedCallbackV2;
|
|
659
|
+
/**
|
|
660
|
+
* Parse a callback from a pre-parsed body and headers.
|
|
661
|
+
*
|
|
662
|
+
* For frameworks like Next.js Pages Router where the body has already been
|
|
663
|
+
* parsed, use this instead of {@link parseCallback}.
|
|
664
|
+
*
|
|
665
|
+
* Detects the CloudEvent version from the `ce-type` header:
|
|
666
|
+
* - `com.vercel.queue.v2beta`: binary content mode (metadata in headers,
|
|
667
|
+
* payload in body). For small messages, the body is attached as `parsedPayload`.
|
|
668
|
+
* - Otherwise: structured content mode (v1beta, entire CloudEvent in JSON body)
|
|
669
|
+
*
|
|
670
|
+
* @param body - The framework-parsed request body. Type depends on Content-Type
|
|
671
|
+
* and framework configuration:
|
|
672
|
+
* - v1beta: parsed CloudEvent JSON object
|
|
673
|
+
* - v2beta: the message payload as parsed by the framework (object, Buffer, or string)
|
|
674
|
+
* @param headers - HTTP headers
|
|
675
|
+
* @returns Parsed callback request with routing metadata and optional payload
|
|
676
|
+
*/
|
|
677
|
+
declare function parseRawCallback(body: unknown, headers: Record<string, string | string[] | undefined>): ParsedCallbackRequest;
|
|
678
|
+
/**
|
|
679
|
+
* Parse and validate a CloudEvent callback from a Web API `Request` object.
|
|
680
|
+
*
|
|
681
|
+
* Detects the CloudEvent version from the `ce-type` header:
|
|
682
|
+
* - `com.vercel.queue.v2beta`: binary content mode (metadata in headers,
|
|
683
|
+
* payload in body). For v2beta, the body is attached as `rawBody` (a
|
|
684
|
+
* ReadableStream) rather than being parsed.
|
|
685
|
+
* - Otherwise: structured content mode (v1beta, entire CloudEvent in JSON body)
|
|
686
|
+
*
|
|
687
|
+
* For frameworks that pre-parse the body (e.g. Next.js Pages Router),
|
|
688
|
+
* use {@link parseRawCallback} instead.
|
|
689
|
+
*/
|
|
690
|
+
declare function parseCallback(request: Request): Promise<ParsedCallbackRequest>;
|
|
691
|
+
/**
|
|
692
|
+
* Core queue callback handler. Processes the message using the provided handler.
|
|
693
|
+
*
|
|
694
|
+
* This is the framework-agnostic core — it takes already-parsed request data
|
|
695
|
+
* and throws on errors. Framework-specific wrappers (in `@vercel/queue/web`
|
|
696
|
+
* and `@vercel/queue/nextjs/pages`) compose around this function to handle
|
|
697
|
+
* request parsing and response formatting.
|
|
698
|
+
*
|
|
699
|
+
* @param handler - Function to process the message payload and metadata
|
|
700
|
+
* @param request - A {@link ParsedCallbackV1} (routing metadata only, message
|
|
701
|
+
* fetched by ID) or {@link ParsedCallbackV2} (full message inlined, no fetch).
|
|
702
|
+
* @param options - Optional configuration (client, visibilityTimeoutSeconds)
|
|
703
|
+
* @throws {Error} If binary mode request has a receipt handle but no payload
|
|
704
|
+
* @throws {Error} If message processing fails
|
|
705
|
+
*
|
|
706
|
+
* @example
|
|
707
|
+
* ```typescript
|
|
708
|
+
* import { handleCallback, parseRawCallback } from "@vercel/queue";
|
|
709
|
+
*
|
|
710
|
+
* const parsed = parseRawCallback(body, headers);
|
|
711
|
+
* await handleCallback(async (message, metadata) => {
|
|
712
|
+
* console.log("Processing:", message);
|
|
713
|
+
* }, parsed);
|
|
714
|
+
* ```
|
|
715
|
+
*/
|
|
716
|
+
declare function handleCallback<T = unknown>(handler: MessageHandler<T>, request: ParsedCallbackRequest, options?: HandleCallbackOptions): Promise<void>;
|
|
717
|
+
|
|
718
|
+
export { BufferTransport as B, type ConsumerGroupOptions as C, DuplicateMessageError as D, ForbiddenError as F, type HandleCallbackOptions as H, InternalServerError as I, JsonTransport as J, type MessageHandler as M, type PublishOptions as P, QueueClient as Q, StreamTransport as S, type Transport as T, UnauthorizedError as U, CLOUD_EVENT_TYPE_V1BETA as a, CLOUD_EVENT_TYPE_V2BETA as b, parseRawCallback as c, type ParsedCallbackRequest as d, type ParsedCallbackV1 as e, type ParsedCallbackV2 as f, BadRequestError as g, handleCallback as h, ConsumerDiscoveryError as i, ConsumerRegistryNotConfiguredError as j, InvalidLimitError as k, MessageAlreadyProcessedError as l, MessageCorruptedError as m, MessageLockedError as n, MessageNotAvailableError as o, parseCallback as p, MessageNotFoundError as q, QueueEmptyError as r, type Message as s, type MessageMetadata as t, type QueueClientOptions as u, type SendMessageOptions as v, type SendMessageResponse as w };
|