@vercel/queue 0.0.0-alpha.34 → 0.0.0-alpha.36
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 +284 -34
- package/dist/index.d.mts +208 -54
- package/dist/index.d.ts +208 -54
- package/dist/index.js +173 -38
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +173 -38
- package/dist/index.mjs.map +1 -1
- package/dist/nextjs-pages.d.mts +1 -1
- package/dist/nextjs-pages.d.ts +1 -1
- package/dist/nextjs-pages.js +145 -32
- package/dist/nextjs-pages.js.map +1 -1
- package/dist/nextjs-pages.mjs +145 -32
- package/dist/nextjs-pages.mjs.map +1 -1
- package/dist/types-C7IKe67P.d.mts +509 -0
- package/dist/types-C7IKe67P.d.ts +509 -0
- package/package.json +1 -1
- package/dist/types-BHtRP_i_.d.mts +0 -411
- package/dist/types-BHtRP_i_.d.ts +0 -411
package/dist/index.mjs
CHANGED
|
@@ -19,6 +19,12 @@ var JsonTransport = class {
|
|
|
19
19
|
contentType = "application/json";
|
|
20
20
|
replacer;
|
|
21
21
|
reviver;
|
|
22
|
+
/**
|
|
23
|
+
* Create a new JsonTransport.
|
|
24
|
+
* @param options - Optional JSON serialization options
|
|
25
|
+
* @param options.replacer - Custom replacer for JSON.stringify
|
|
26
|
+
* @param options.reviver - Custom reviver for JSON.parse
|
|
27
|
+
*/
|
|
22
28
|
constructor(options = {}) {
|
|
23
29
|
this.replacer = options.replacer;
|
|
24
30
|
this.reviver = options.reviver;
|
|
@@ -48,6 +54,10 @@ var StreamTransport = class {
|
|
|
48
54
|
async deserialize(stream) {
|
|
49
55
|
return stream;
|
|
50
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Consume any remaining stream data to prevent resource leaks.
|
|
59
|
+
* Called automatically by ConsumerGroup; manual call required for direct client usage.
|
|
60
|
+
*/
|
|
51
61
|
async finalize(payload) {
|
|
52
62
|
const reader = payload.getReader();
|
|
53
63
|
try {
|
|
@@ -98,6 +108,7 @@ var QueueEmptyError = class extends Error {
|
|
|
98
108
|
}
|
|
99
109
|
};
|
|
100
110
|
var MessageLockedError = class extends Error {
|
|
111
|
+
/** Suggested retry delay in seconds, if provided by the server. */
|
|
101
112
|
retryAfter;
|
|
102
113
|
constructor(messageId, retryAfter) {
|
|
103
114
|
const retryMessage = retryAfter ? ` Retry after ${retryAfter} seconds.` : " Try again later.";
|
|
@@ -143,7 +154,9 @@ var MessageAlreadyProcessedError = class extends Error {
|
|
|
143
154
|
}
|
|
144
155
|
};
|
|
145
156
|
var ConcurrencyLimitError = class extends Error {
|
|
157
|
+
/** Current number of in-flight messages for this consumer group. */
|
|
146
158
|
currentInflight;
|
|
159
|
+
/** Maximum allowed concurrent messages (as configured). */
|
|
147
160
|
maxConcurrency;
|
|
148
161
|
constructor(message = "Concurrency limit exceeded", currentInflight, maxConcurrency) {
|
|
149
162
|
super(message);
|
|
@@ -530,19 +543,55 @@ var QueueClient = class {
|
|
|
530
543
|
}
|
|
531
544
|
return response;
|
|
532
545
|
}
|
|
546
|
+
/**
|
|
547
|
+
* Send a message to a topic.
|
|
548
|
+
*
|
|
549
|
+
* @param options - Message options including queue name, payload, and optional settings
|
|
550
|
+
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
551
|
+
* @param options.payload - Message payload
|
|
552
|
+
* @param options.idempotencyKey - Optional deduplication key (dedup window: min(retention, 24h))
|
|
553
|
+
* @param options.retentionSeconds - Message TTL (default: 86400, min: 60, max: 86400)
|
|
554
|
+
* @param options.delaySeconds - Delivery delay (default: 0, max: retentionSeconds)
|
|
555
|
+
* @param transport - Serializer for the payload
|
|
556
|
+
* @returns Promise with the generated messageId
|
|
557
|
+
* @throws {DuplicateMessageError} When idempotency key was already used
|
|
558
|
+
* @throws {ConsumerDiscoveryError} When consumer discovery fails
|
|
559
|
+
* @throws {ConsumerRegistryNotConfiguredError} When registry not configured
|
|
560
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
561
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
562
|
+
* @throws {ForbiddenError} When access is denied
|
|
563
|
+
* @throws {InternalServerError} When server encounters an error
|
|
564
|
+
*/
|
|
533
565
|
async sendMessage(options, transport) {
|
|
534
566
|
const {
|
|
535
567
|
queueName,
|
|
536
568
|
payload,
|
|
537
569
|
idempotencyKey,
|
|
538
570
|
retentionSeconds,
|
|
539
|
-
delaySeconds
|
|
571
|
+
delaySeconds,
|
|
572
|
+
headers: optionHeaders
|
|
540
573
|
} = options;
|
|
541
|
-
const headers = new Headers(
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
574
|
+
const headers = new Headers();
|
|
575
|
+
if (this.customHeaders) {
|
|
576
|
+
for (const [name, value] of Object.entries(this.customHeaders)) {
|
|
577
|
+
headers.append(name, value);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
if (optionHeaders) {
|
|
581
|
+
const protectedHeaderNames = /* @__PURE__ */ new Set(["authorization", "content-type"]);
|
|
582
|
+
const isProtectedHeader = (name) => {
|
|
583
|
+
const lower = name.toLowerCase();
|
|
584
|
+
if (protectedHeaderNames.has(lower)) return true;
|
|
585
|
+
return lower.startsWith("vqs-");
|
|
586
|
+
};
|
|
587
|
+
for (const [name, value] of Object.entries(optionHeaders)) {
|
|
588
|
+
if (!isProtectedHeader(name) && value !== void 0) {
|
|
589
|
+
headers.append(name, value);
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
headers.set("Authorization", `Bearer ${await this.getToken()}`);
|
|
594
|
+
headers.set("Content-Type", transport.contentType);
|
|
546
595
|
const deploymentId = this.getSendDeploymentId();
|
|
547
596
|
if (deploymentId) {
|
|
548
597
|
headers.set("Vqs-Deployment-Id", deploymentId);
|
|
@@ -592,6 +641,25 @@ var QueueClient = class {
|
|
|
592
641
|
const responseData = await response.json();
|
|
593
642
|
return responseData;
|
|
594
643
|
}
|
|
644
|
+
/**
|
|
645
|
+
* Receive messages from a topic as an async generator.
|
|
646
|
+
*
|
|
647
|
+
* @param options - Receive options
|
|
648
|
+
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
649
|
+
* @param options.consumerGroup - Consumer group name (pattern: `[A-Za-z0-9_-]+`)
|
|
650
|
+
* @param options.visibilityTimeoutSeconds - Lock duration (default: 30, min: 0, max: 3600)
|
|
651
|
+
* @param options.limit - Max messages to retrieve (default: 1, min: 1, max: 10)
|
|
652
|
+
* @param options.maxConcurrency - Max in-flight messages (default: unlimited, min: 1)
|
|
653
|
+
* @param transport - Deserializer for message payloads
|
|
654
|
+
* @yields Message objects with payload, messageId, receiptHandle, etc.
|
|
655
|
+
* @throws {QueueEmptyError} When no messages available
|
|
656
|
+
* @throws {InvalidLimitError} When limit is outside 1-10 range
|
|
657
|
+
* @throws {ConcurrencyLimitError} When maxConcurrency exceeded
|
|
658
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
659
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
660
|
+
* @throws {ForbiddenError} When access is denied
|
|
661
|
+
* @throws {InternalServerError} When server encounters an error
|
|
662
|
+
*/
|
|
595
663
|
async *receiveMessages(options, transport) {
|
|
596
664
|
const {
|
|
597
665
|
queueName,
|
|
@@ -677,6 +745,26 @@ var QueueClient = class {
|
|
|
677
745
|
}
|
|
678
746
|
}
|
|
679
747
|
}
|
|
748
|
+
/**
|
|
749
|
+
* Receive a specific message by its ID.
|
|
750
|
+
*
|
|
751
|
+
* @param options - Receive options
|
|
752
|
+
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
753
|
+
* @param options.consumerGroup - Consumer group name (pattern: `[A-Za-z0-9_-]+`)
|
|
754
|
+
* @param options.messageId - Message ID to retrieve
|
|
755
|
+
* @param options.visibilityTimeoutSeconds - Lock duration (default: 30, min: 0, max: 3600)
|
|
756
|
+
* @param options.maxConcurrency - Max in-flight messages (default: unlimited, min: 1)
|
|
757
|
+
* @param transport - Deserializer for the message payload
|
|
758
|
+
* @returns Promise with the message
|
|
759
|
+
* @throws {MessageNotFoundError} When message doesn't exist
|
|
760
|
+
* @throws {MessageNotAvailableError} When message is in wrong state or was a duplicate
|
|
761
|
+
* @throws {MessageAlreadyProcessedError} When message was already processed
|
|
762
|
+
* @throws {ConcurrencyLimitError} When maxConcurrency exceeded
|
|
763
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
764
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
765
|
+
* @throws {ForbiddenError} When access is denied
|
|
766
|
+
* @throws {InternalServerError} When server encounters an error
|
|
767
|
+
*/
|
|
680
768
|
async receiveMessageById(options, transport) {
|
|
681
769
|
const {
|
|
682
770
|
queueName,
|
|
@@ -771,6 +859,21 @@ var QueueClient = class {
|
|
|
771
859
|
}
|
|
772
860
|
throw new MessageNotFoundError(messageId);
|
|
773
861
|
}
|
|
862
|
+
/**
|
|
863
|
+
* Delete (acknowledge) a message after successful processing.
|
|
864
|
+
*
|
|
865
|
+
* @param options - Delete options
|
|
866
|
+
* @param options.queueName - Topic name
|
|
867
|
+
* @param options.consumerGroup - Consumer group name
|
|
868
|
+
* @param options.receiptHandle - Receipt handle from the received message (must use same deployment ID as receive)
|
|
869
|
+
* @returns Promise indicating deletion success
|
|
870
|
+
* @throws {MessageNotFoundError} When receipt handle not found
|
|
871
|
+
* @throws {MessageNotAvailableError} When receipt handle invalid or message already processed
|
|
872
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
873
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
874
|
+
* @throws {ForbiddenError} When access is denied
|
|
875
|
+
* @throws {InternalServerError} When server encounters an error
|
|
876
|
+
*/
|
|
774
877
|
async deleteMessage(options) {
|
|
775
878
|
const { queueName, consumerGroup, receiptHandle } = options;
|
|
776
879
|
const headers = new Headers({
|
|
@@ -815,6 +918,23 @@ var QueueClient = class {
|
|
|
815
918
|
}
|
|
816
919
|
return { deleted: true };
|
|
817
920
|
}
|
|
921
|
+
/**
|
|
922
|
+
* Extend or change the visibility timeout of a message.
|
|
923
|
+
* Used to prevent message redelivery while still processing.
|
|
924
|
+
*
|
|
925
|
+
* @param options - Visibility options
|
|
926
|
+
* @param options.queueName - Topic name
|
|
927
|
+
* @param options.consumerGroup - Consumer group name
|
|
928
|
+
* @param options.receiptHandle - Receipt handle from the received message (must use same deployment ID as receive)
|
|
929
|
+
* @param options.visibilityTimeoutSeconds - New timeout (min: 0, max: 3600, cannot exceed message expiration)
|
|
930
|
+
* @returns Promise indicating success
|
|
931
|
+
* @throws {MessageNotFoundError} When receipt handle not found
|
|
932
|
+
* @throws {MessageNotAvailableError} When receipt handle invalid or message already processed
|
|
933
|
+
* @throws {BadRequestError} When parameters are invalid
|
|
934
|
+
* @throws {UnauthorizedError} When authentication fails
|
|
935
|
+
* @throws {ForbiddenError} When access is denied
|
|
936
|
+
* @throws {InternalServerError} When server encounters an error
|
|
937
|
+
*/
|
|
818
938
|
async changeVisibility(options) {
|
|
819
939
|
const {
|
|
820
940
|
queueName,
|
|
@@ -937,36 +1057,26 @@ var ConsumerGroup = class {
|
|
|
937
1057
|
refreshInterval;
|
|
938
1058
|
transport;
|
|
939
1059
|
/**
|
|
940
|
-
* Create a new ConsumerGroup instance
|
|
941
|
-
*
|
|
942
|
-
* @param
|
|
943
|
-
* @param
|
|
944
|
-
* @param
|
|
1060
|
+
* Create a new ConsumerGroup instance.
|
|
1061
|
+
*
|
|
1062
|
+
* @param client - QueueClient instance to use for API calls
|
|
1063
|
+
* @param topicName - Name of the topic to consume from (pattern: `[A-Za-z0-9_-]+`)
|
|
1064
|
+
* @param consumerGroupName - Name of the consumer group (pattern: `[A-Za-z0-9_-]+`)
|
|
1065
|
+
* @param options - Optional configuration
|
|
1066
|
+
* @param options.transport - Payload serializer (default: JsonTransport)
|
|
1067
|
+
* @param options.visibilityTimeoutSeconds - Message lock duration (default: 30, max: 3600)
|
|
1068
|
+
* @param options.visibilityRefreshInterval - Lock refresh interval in seconds (default: visibilityTimeout / 3)
|
|
945
1069
|
*/
|
|
946
1070
|
constructor(client, topicName, consumerGroupName, options = {}) {
|
|
947
1071
|
this.client = client;
|
|
948
1072
|
this.topicName = topicName;
|
|
949
1073
|
this.consumerGroupName = consumerGroupName;
|
|
950
|
-
this.visibilityTimeout = options.visibilityTimeoutSeconds
|
|
951
|
-
this.refreshInterval = options.
|
|
1074
|
+
this.visibilityTimeout = options.visibilityTimeoutSeconds ?? 30;
|
|
1075
|
+
this.refreshInterval = options.visibilityRefreshInterval ?? Math.floor(this.visibilityTimeout / 3);
|
|
952
1076
|
this.transport = options.transport || new JsonTransport();
|
|
953
1077
|
}
|
|
954
1078
|
/**
|
|
955
1079
|
* Starts a background loop that periodically extends the visibility timeout for a message.
|
|
956
|
-
* This prevents the message from becoming visible to other consumers while it's being processed.
|
|
957
|
-
*
|
|
958
|
-
* The extension loop runs every `refreshInterval` seconds and updates the message's
|
|
959
|
-
* visibility timeout to `visibilityTimeout` seconds from the current time.
|
|
960
|
-
*
|
|
961
|
-
* @param receiptHandle - The receipt handle that proves ownership of the message
|
|
962
|
-
* @returns A function that when called will stop the extension loop
|
|
963
|
-
*
|
|
964
|
-
* @remarks
|
|
965
|
-
* - The first extension attempt occurs after `refreshInterval` seconds, not immediately
|
|
966
|
-
* - If an extension fails, the loop terminates with an error logged to console
|
|
967
|
-
* - The returned stop function is idempotent - calling it multiple times is safe
|
|
968
|
-
* - By default, the stop function returns immediately without waiting for in-flight
|
|
969
|
-
* - Pass `true` to the stop function to wait for any in-flight extension to complete
|
|
970
1080
|
*/
|
|
971
1081
|
startVisibilityExtension(receiptHandle) {
|
|
972
1082
|
let isRunning = true;
|
|
@@ -1128,7 +1238,8 @@ var Topic = class {
|
|
|
1128
1238
|
payload,
|
|
1129
1239
|
idempotencyKey: options?.idempotencyKey,
|
|
1130
1240
|
retentionSeconds: options?.retentionSeconds,
|
|
1131
|
-
delaySeconds: options?.delaySeconds
|
|
1241
|
+
delaySeconds: options?.delaySeconds,
|
|
1242
|
+
headers: options?.headers
|
|
1132
1243
|
},
|
|
1133
1244
|
this.transport
|
|
1134
1245
|
);
|
|
@@ -1238,7 +1349,7 @@ async function parseCallback(request) {
|
|
|
1238
1349
|
messageId
|
|
1239
1350
|
};
|
|
1240
1351
|
}
|
|
1241
|
-
function createCallbackHandler(handlers, client) {
|
|
1352
|
+
function createCallbackHandler(handlers, client, visibilityTimeoutSeconds) {
|
|
1242
1353
|
for (const topicPattern in handlers) {
|
|
1243
1354
|
if (topicPattern.includes("*")) {
|
|
1244
1355
|
if (!validateWildcardPattern(topicPattern)) {
|
|
@@ -1274,7 +1385,10 @@ function createCallbackHandler(handlers, client) {
|
|
|
1274
1385
|
);
|
|
1275
1386
|
}
|
|
1276
1387
|
const topic = new Topic(client, queueName);
|
|
1277
|
-
const cg = topic.consumerGroup(
|
|
1388
|
+
const cg = topic.consumerGroup(
|
|
1389
|
+
consumerGroup,
|
|
1390
|
+
visibilityTimeoutSeconds !== void 0 ? { visibilityTimeoutSeconds } : void 0
|
|
1391
|
+
);
|
|
1278
1392
|
await cg.consume(consumerGroupHandler, { messageId });
|
|
1279
1393
|
return Response.json({ status: "success" });
|
|
1280
1394
|
} catch (error) {
|
|
@@ -1290,8 +1404,12 @@ function createCallbackHandler(handlers, client) {
|
|
|
1290
1404
|
};
|
|
1291
1405
|
return routeHandler;
|
|
1292
1406
|
}
|
|
1293
|
-
function handleCallback(handlers,
|
|
1294
|
-
return createCallbackHandler(
|
|
1407
|
+
function handleCallback(handlers, options) {
|
|
1408
|
+
return createCallbackHandler(
|
|
1409
|
+
handlers,
|
|
1410
|
+
options?.client || new QueueClient(),
|
|
1411
|
+
options?.visibilityTimeoutSeconds
|
|
1412
|
+
);
|
|
1295
1413
|
}
|
|
1296
1414
|
|
|
1297
1415
|
// src/factory.ts
|
|
@@ -1304,7 +1422,8 @@ async function send(topicName, payload, options) {
|
|
|
1304
1422
|
payload,
|
|
1305
1423
|
idempotencyKey: options?.idempotencyKey,
|
|
1306
1424
|
retentionSeconds: options?.retentionSeconds,
|
|
1307
|
-
delaySeconds: options?.delaySeconds
|
|
1425
|
+
delaySeconds: options?.delaySeconds,
|
|
1426
|
+
headers: options?.headers
|
|
1308
1427
|
},
|
|
1309
1428
|
transport
|
|
1310
1429
|
);
|
|
@@ -1354,23 +1473,39 @@ var Client = class {
|
|
|
1354
1473
|
});
|
|
1355
1474
|
}
|
|
1356
1475
|
/**
|
|
1357
|
-
* Create a callback handler for processing queue messages
|
|
1358
|
-
* Returns a Next.js route handler function that routes messages to appropriate handlers
|
|
1359
|
-
*
|
|
1476
|
+
* Create a callback handler for processing queue messages.
|
|
1477
|
+
* Returns a Next.js route handler function that routes messages to appropriate handlers.
|
|
1478
|
+
*
|
|
1479
|
+
* @param handlers - Object with topic-specific handlers organized by consumer groups
|
|
1480
|
+
* @param options - Optional configuration
|
|
1481
|
+
* @param options.visibilityTimeoutSeconds - Message lock duration (default: 30, max: 3600)
|
|
1360
1482
|
* @returns A Next.js route handler function
|
|
1361
1483
|
*
|
|
1362
1484
|
* @example
|
|
1363
1485
|
* ```typescript
|
|
1486
|
+
* // Basic usage
|
|
1364
1487
|
* export const POST = client.handleCallback({
|
|
1365
1488
|
* "user-events": {
|
|
1366
1489
|
* "welcome": (user, metadata) => console.log("Welcoming user", user),
|
|
1367
1490
|
* "analytics": (user, metadata) => console.log("Tracking user", user),
|
|
1368
1491
|
* },
|
|
1369
1492
|
* });
|
|
1493
|
+
*
|
|
1494
|
+
* // With custom visibility timeout
|
|
1495
|
+
* export const POST = client.handleCallback({
|
|
1496
|
+
* "video-processing": {
|
|
1497
|
+
* "transcode": async (video) => await transcodeVideo(video),
|
|
1498
|
+
* },
|
|
1499
|
+
* }, {
|
|
1500
|
+
* visibilityTimeoutSeconds: 300, // 5 minutes for long operations
|
|
1501
|
+
* });
|
|
1370
1502
|
* ```
|
|
1371
1503
|
*/
|
|
1372
|
-
handleCallback(handlers) {
|
|
1373
|
-
return handleCallback(handlers,
|
|
1504
|
+
handleCallback(handlers, options) {
|
|
1505
|
+
return handleCallback(handlers, {
|
|
1506
|
+
...options,
|
|
1507
|
+
client: this.client
|
|
1508
|
+
});
|
|
1374
1509
|
}
|
|
1375
1510
|
};
|
|
1376
1511
|
export {
|