@vercel/queue 0.0.0-alpha.39 → 0.0.0-alpha.40
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 +367 -375
- package/dist/index.d.mts +603 -111
- package/dist/index.d.ts +603 -111
- package/dist/index.js +370 -238
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +369 -234
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -21
- package/dist/callback-lq_sorrn.d.mts +0 -718
- package/dist/callback-lq_sorrn.d.ts +0 -718
- package/dist/nextjs-pages.d.mts +0 -68
- package/dist/nextjs-pages.d.ts +0 -68
- package/dist/nextjs-pages.js +0 -1438
- package/dist/nextjs-pages.js.map +0 -1
- package/dist/nextjs-pages.mjs +0 -1401
- package/dist/nextjs-pages.mjs.map +0 -1
- package/dist/web.d.mts +0 -60
- package/dist/web.d.ts +0 -60
- package/dist/web.js +0 -1457
- package/dist/web.js.map +0 -1
- package/dist/web.mjs +0 -1420
- package/dist/web.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -71,7 +71,7 @@ var StreamTransport = class {
|
|
|
71
71
|
}
|
|
72
72
|
};
|
|
73
73
|
|
|
74
|
-
// src/client.ts
|
|
74
|
+
// src/api-client.ts
|
|
75
75
|
import { parseMultipartStream } from "mixpart";
|
|
76
76
|
|
|
77
77
|
// src/dev.ts
|
|
@@ -196,7 +196,7 @@ var ConsumerGroup = class {
|
|
|
196
196
|
/**
|
|
197
197
|
* Create a new ConsumerGroup instance.
|
|
198
198
|
*
|
|
199
|
-
* @param client -
|
|
199
|
+
* @param client - ApiClient instance to use for API calls (transport is configured on the client)
|
|
200
200
|
* @param topicName - Name of the topic to consume from (pattern: `[A-Za-z0-9_-]+`)
|
|
201
201
|
* @param consumerGroupName - Name of the consumer group (pattern: `[A-Za-z0-9_-]+`)
|
|
202
202
|
* @param options - Optional configuration
|
|
@@ -321,35 +321,84 @@ var ConsumerGroup = class {
|
|
|
321
321
|
}
|
|
322
322
|
};
|
|
323
323
|
}
|
|
324
|
+
/**
|
|
325
|
+
* Clean up the message payload if the transport supports it and payload exists.
|
|
326
|
+
*/
|
|
327
|
+
async finalizePayload(payload) {
|
|
328
|
+
const transport = this.client.getTransport();
|
|
329
|
+
if (transport.finalize && payload !== void 0 && payload !== null) {
|
|
330
|
+
try {
|
|
331
|
+
await transport.finalize(payload);
|
|
332
|
+
} catch (finalizeError) {
|
|
333
|
+
console.warn("Failed to finalize message payload:", finalizeError);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
324
337
|
async processMessage(message, handler, options) {
|
|
325
338
|
const stopExtension = this.startVisibilityExtension(
|
|
326
339
|
message.receiptHandle,
|
|
327
340
|
options
|
|
328
341
|
);
|
|
342
|
+
const metadata = {
|
|
343
|
+
messageId: message.messageId,
|
|
344
|
+
deliveryCount: message.deliveryCount,
|
|
345
|
+
createdAt: message.createdAt,
|
|
346
|
+
expiresAt: message.expiresAt,
|
|
347
|
+
topicName: this.topicName,
|
|
348
|
+
consumerGroup: this.consumerGroupName,
|
|
349
|
+
region: this.client.getRegion()
|
|
350
|
+
};
|
|
329
351
|
try {
|
|
330
|
-
await handler(message.payload,
|
|
331
|
-
messageId: message.messageId,
|
|
332
|
-
deliveryCount: message.deliveryCount,
|
|
333
|
-
createdAt: message.createdAt,
|
|
334
|
-
topicName: this.topicName,
|
|
335
|
-
consumerGroup: this.consumerGroupName
|
|
336
|
-
});
|
|
352
|
+
await handler(message.payload, metadata);
|
|
337
353
|
await stopExtension();
|
|
338
|
-
await this.client.
|
|
354
|
+
await this.client.acknowledgeMessage({
|
|
339
355
|
queueName: this.topicName,
|
|
340
356
|
consumerGroup: this.consumerGroupName,
|
|
341
357
|
receiptHandle: message.receiptHandle
|
|
342
358
|
});
|
|
343
359
|
} catch (error) {
|
|
344
360
|
await stopExtension();
|
|
345
|
-
|
|
346
|
-
|
|
361
|
+
if (options?.retry) {
|
|
362
|
+
let directive;
|
|
347
363
|
try {
|
|
348
|
-
|
|
349
|
-
} catch (
|
|
350
|
-
console.warn("
|
|
364
|
+
directive = options.retry(error, metadata);
|
|
365
|
+
} catch (retryError) {
|
|
366
|
+
console.warn("retry handler threw:", retryError);
|
|
367
|
+
}
|
|
368
|
+
if (directive) {
|
|
369
|
+
if ("acknowledge" in directive && directive.acknowledge) {
|
|
370
|
+
try {
|
|
371
|
+
await this.client.acknowledgeMessage({
|
|
372
|
+
queueName: this.topicName,
|
|
373
|
+
consumerGroup: this.consumerGroupName,
|
|
374
|
+
receiptHandle: message.receiptHandle
|
|
375
|
+
});
|
|
376
|
+
} catch (ackError) {
|
|
377
|
+
console.warn("Failed to acknowledge message:", ackError);
|
|
378
|
+
}
|
|
379
|
+
await this.finalizePayload(message.payload);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
if ("afterSeconds" in directive && typeof directive.afterSeconds === "number") {
|
|
383
|
+
try {
|
|
384
|
+
await this.client.changeVisibility({
|
|
385
|
+
queueName: this.topicName,
|
|
386
|
+
consumerGroup: this.consumerGroupName,
|
|
387
|
+
receiptHandle: message.receiptHandle,
|
|
388
|
+
visibilityTimeoutSeconds: directive.afterSeconds
|
|
389
|
+
});
|
|
390
|
+
} catch (changeError) {
|
|
391
|
+
console.warn(
|
|
392
|
+
"Failed to reschedule message for retry:",
|
|
393
|
+
changeError
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
await this.finalizePayload(message.payload);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
351
399
|
}
|
|
352
400
|
}
|
|
401
|
+
await this.finalizePayload(message.payload);
|
|
353
402
|
throw error;
|
|
354
403
|
}
|
|
355
404
|
}
|
|
@@ -360,7 +409,7 @@ var ConsumerGroup = class {
|
|
|
360
409
|
* pushes the full message payload in the callback request. The message is
|
|
361
410
|
* processed with the same lifecycle guarantees as `consume()`:
|
|
362
411
|
* - Visibility timeout is extended periodically during processing
|
|
363
|
-
* - Message is
|
|
412
|
+
* - Message is acknowledged on successful handler completion
|
|
364
413
|
* - Payload is finalized on error if the transport supports it
|
|
365
414
|
*
|
|
366
415
|
* @param handler - Function to process the message payload and metadata
|
|
@@ -374,6 +423,7 @@ var ConsumerGroup = class {
|
|
|
374
423
|
await this.processMessage(message, handler, options);
|
|
375
424
|
}
|
|
376
425
|
async consume(handler, options) {
|
|
426
|
+
const retry = options?.retry;
|
|
377
427
|
if (options && "messageId" in options) {
|
|
378
428
|
const response = await this.client.receiveMessageById({
|
|
379
429
|
queueName: this.topicName,
|
|
@@ -381,22 +431,21 @@ var ConsumerGroup = class {
|
|
|
381
431
|
messageId: options.messageId,
|
|
382
432
|
visibilityTimeoutSeconds: this.visibilityTimeout
|
|
383
433
|
});
|
|
384
|
-
await this.processMessage(response.message, handler);
|
|
434
|
+
await this.processMessage(response.message, handler, { retry });
|
|
435
|
+
return 1;
|
|
385
436
|
} else {
|
|
386
437
|
const limit = options && "limit" in options ? options.limit : 1;
|
|
387
|
-
let
|
|
438
|
+
let messagesProcessed = 0;
|
|
388
439
|
for await (const message of this.client.receiveMessages({
|
|
389
440
|
queueName: this.topicName,
|
|
390
441
|
consumerGroup: this.consumerGroupName,
|
|
391
442
|
visibilityTimeoutSeconds: this.visibilityTimeout,
|
|
392
443
|
limit
|
|
393
444
|
})) {
|
|
394
|
-
|
|
395
|
-
await this.processMessage(message, handler);
|
|
396
|
-
}
|
|
397
|
-
if (!messageFound) {
|
|
398
|
-
await handler(null, null);
|
|
445
|
+
messagesProcessed++;
|
|
446
|
+
await this.processMessage(message, handler, { retry });
|
|
399
447
|
}
|
|
448
|
+
return messagesProcessed;
|
|
400
449
|
}
|
|
401
450
|
}
|
|
402
451
|
/**
|
|
@@ -418,8 +467,7 @@ var Topic = class {
|
|
|
418
467
|
client;
|
|
419
468
|
topicName;
|
|
420
469
|
/**
|
|
421
|
-
*
|
|
422
|
-
* @param client QueueClient instance to use for API calls (transport is configured on the client)
|
|
470
|
+
* @param client ApiClient instance to use for API calls
|
|
423
471
|
* @param topicName Name of the topic to work with
|
|
424
472
|
*/
|
|
425
473
|
constructor(client, topicName) {
|
|
@@ -430,7 +478,7 @@ var Topic = class {
|
|
|
430
478
|
* Publish a message to the topic
|
|
431
479
|
* @param payload The data to publish
|
|
432
480
|
* @param options Optional publish options
|
|
433
|
-
* @returns
|
|
481
|
+
* @returns `{ messageId }` — `messageId` is `null` when deferred
|
|
434
482
|
* @throws {BadRequestError} When request parameters are invalid
|
|
435
483
|
* @throws {UnauthorizedError} When authentication fails
|
|
436
484
|
* @throws {ForbiddenError} When access is denied (environment mismatch)
|
|
@@ -445,8 +493,12 @@ var Topic = class {
|
|
|
445
493
|
delaySeconds: options?.delaySeconds,
|
|
446
494
|
headers: options?.headers
|
|
447
495
|
});
|
|
448
|
-
if (isDevMode()) {
|
|
449
|
-
triggerDevCallbacks(
|
|
496
|
+
if (result.messageId && isDevMode()) {
|
|
497
|
+
triggerDevCallbacks(
|
|
498
|
+
this.topicName,
|
|
499
|
+
result.messageId,
|
|
500
|
+
this.client.getRegion()
|
|
501
|
+
);
|
|
450
502
|
}
|
|
451
503
|
return { messageId: result.messageId };
|
|
452
504
|
}
|
|
@@ -539,10 +591,12 @@ function parseBinaryHeaders(headers) {
|
|
|
539
591
|
`Missing required CloudEvent headers: ${missingFields.join(", ")}`
|
|
540
592
|
);
|
|
541
593
|
}
|
|
594
|
+
const region = getHeader(headers, "ce-vqsregion") ?? void 0;
|
|
542
595
|
const base = {
|
|
543
596
|
queueName,
|
|
544
597
|
consumerGroup,
|
|
545
|
-
messageId
|
|
598
|
+
messageId,
|
|
599
|
+
region
|
|
546
600
|
};
|
|
547
601
|
const receiptHandle = getHeader(headers, "ce-vqsreceipthandle");
|
|
548
602
|
if (!receiptHandle) {
|
|
@@ -557,6 +611,10 @@ function parseBinaryHeaders(headers) {
|
|
|
557
611
|
if (createdAt) {
|
|
558
612
|
result.createdAt = createdAt;
|
|
559
613
|
}
|
|
614
|
+
const expiresAt = getHeader(headers, "ce-vqsexpiresat");
|
|
615
|
+
if (expiresAt) {
|
|
616
|
+
result.expiresAt = expiresAt;
|
|
617
|
+
}
|
|
560
618
|
const contentType = getHeader(headers, "content-type");
|
|
561
619
|
if (contentType) {
|
|
562
620
|
result.contentType = contentType;
|
|
@@ -601,14 +659,20 @@ async function parseCallback(request) {
|
|
|
601
659
|
}
|
|
602
660
|
async function handleCallback(handler, request, options) {
|
|
603
661
|
const { queueName, consumerGroup, messageId } = request;
|
|
604
|
-
|
|
605
|
-
|
|
662
|
+
if (!options?.client) {
|
|
663
|
+
throw new Error("HandleCallbackOptions.client is required");
|
|
664
|
+
}
|
|
665
|
+
let api = getApiClient(options.client);
|
|
666
|
+
if (request.region) {
|
|
667
|
+
api = api.withRegion(request.region);
|
|
668
|
+
}
|
|
669
|
+
const topic = new Topic(api, queueName);
|
|
606
670
|
const cg = topic.consumerGroup(
|
|
607
671
|
consumerGroup,
|
|
608
672
|
options?.visibilityTimeoutSeconds !== void 0 ? { visibilityTimeoutSeconds: options.visibilityTimeoutSeconds } : void 0
|
|
609
673
|
);
|
|
610
674
|
if ("receiptHandle" in request) {
|
|
611
|
-
const transport =
|
|
675
|
+
const transport = api.getTransport();
|
|
612
676
|
let payload;
|
|
613
677
|
if (request.rawBody) {
|
|
614
678
|
payload = await transport.deserialize(request.rawBody);
|
|
@@ -624,13 +688,17 @@ async function handleCallback(handler, request, options) {
|
|
|
624
688
|
payload,
|
|
625
689
|
deliveryCount: request.deliveryCount ?? 1,
|
|
626
690
|
createdAt: request.createdAt ? new Date(request.createdAt) : /* @__PURE__ */ new Date(),
|
|
691
|
+
expiresAt: request.expiresAt ? new Date(request.expiresAt) : void 0,
|
|
627
692
|
contentType: request.contentType ?? transport.contentType,
|
|
628
693
|
receiptHandle: request.receiptHandle
|
|
629
694
|
};
|
|
630
695
|
const visibilityDeadline = request.visibilityDeadline ? new Date(request.visibilityDeadline) : void 0;
|
|
631
|
-
await cg.consumeMessage(handler, message, {
|
|
696
|
+
await cg.consumeMessage(handler, message, {
|
|
697
|
+
visibilityDeadline,
|
|
698
|
+
retry: options?.retry
|
|
699
|
+
});
|
|
632
700
|
} else {
|
|
633
|
-
await cg.consume(handler, { messageId });
|
|
701
|
+
await cg.consume(handler, { messageId, retry: options?.retry });
|
|
634
702
|
}
|
|
635
703
|
}
|
|
636
704
|
|
|
@@ -701,8 +769,8 @@ function isDevMode() {
|
|
|
701
769
|
var DEV_VISIBILITY_POLL_INTERVAL = 50;
|
|
702
770
|
var DEV_VISIBILITY_MAX_WAIT = 5e3;
|
|
703
771
|
var DEV_VISIBILITY_BACKOFF_MULTIPLIER = 2;
|
|
704
|
-
async function waitForMessageVisibility(topicName, consumerGroup, messageId) {
|
|
705
|
-
const client = new
|
|
772
|
+
async function waitForMessageVisibility(topicName, consumerGroup, messageId, region) {
|
|
773
|
+
const client = new ApiClient({ region });
|
|
706
774
|
let elapsed = 0;
|
|
707
775
|
let interval = DEV_VISIBILITY_POLL_INTERVAL;
|
|
708
776
|
while (elapsed < DEV_VISIBILITY_MAX_WAIT) {
|
|
@@ -742,13 +810,13 @@ async function waitForMessageVisibility(topicName, consumerGroup, messageId) {
|
|
|
742
810
|
);
|
|
743
811
|
return false;
|
|
744
812
|
}
|
|
745
|
-
function triggerDevCallbacks(topicName, messageId, delaySeconds) {
|
|
813
|
+
function triggerDevCallbacks(topicName, messageId, region, delaySeconds) {
|
|
746
814
|
if (delaySeconds && delaySeconds > 0) {
|
|
747
815
|
console.log(
|
|
748
816
|
`[Dev Mode] Message sent with delay: topic="${topicName}" messageId="${messageId}" delay=${delaySeconds}s`
|
|
749
817
|
);
|
|
750
818
|
setTimeout(() => {
|
|
751
|
-
triggerDevCallbacks(topicName, messageId);
|
|
819
|
+
triggerDevCallbacks(topicName, messageId, region);
|
|
752
820
|
}, delaySeconds * 1e3);
|
|
753
821
|
return;
|
|
754
822
|
}
|
|
@@ -771,7 +839,8 @@ function triggerDevCallbacks(topicName, messageId, delaySeconds) {
|
|
|
771
839
|
const isVisible = await waitForMessageVisibility(
|
|
772
840
|
topicName,
|
|
773
841
|
firstRoute.consumer,
|
|
774
|
-
messageId
|
|
842
|
+
messageId,
|
|
843
|
+
region
|
|
775
844
|
);
|
|
776
845
|
if (!isVisible) {
|
|
777
846
|
console.warn(
|
|
@@ -793,7 +862,8 @@ function triggerDevCallbacks(topicName, messageId, delaySeconds) {
|
|
|
793
862
|
"ce-type": CLOUD_EVENT_TYPE_V2BETA,
|
|
794
863
|
"ce-vqsqueuename": topicName,
|
|
795
864
|
"ce-vqsconsumergroup": route.consumer,
|
|
796
|
-
"ce-vqsmessageid": messageId
|
|
865
|
+
"ce-vqsmessageid": messageId,
|
|
866
|
+
"ce-vqsregion": region
|
|
797
867
|
}
|
|
798
868
|
});
|
|
799
869
|
if (response.ok) {
|
|
@@ -841,7 +911,7 @@ if (process.env.NODE_ENV === "test" || process.env.VITEST) {
|
|
|
841
911
|
// src/oidc.ts
|
|
842
912
|
import { getVercelOidcToken } from "@vercel/oidc";
|
|
843
913
|
|
|
844
|
-
// src/client.ts
|
|
914
|
+
// src/api-client.ts
|
|
845
915
|
function isDebugEnabled() {
|
|
846
916
|
return process.env.VERCEL_QUEUE_DEBUG === "1" || process.env.VERCEL_QUEUE_DEBUG === "true";
|
|
847
917
|
}
|
|
@@ -894,40 +964,80 @@ function parseQueueHeaders(headers) {
|
|
|
894
964
|
receiptHandle
|
|
895
965
|
};
|
|
896
966
|
}
|
|
897
|
-
var
|
|
967
|
+
var DEFAULT_BASE_URL_RESOLVER = (region) => `https://${region}.vercel-queue.com`;
|
|
968
|
+
function resolveBaseUrl(region, resolver) {
|
|
969
|
+
return (resolver ?? DEFAULT_BASE_URL_RESOLVER)(region);
|
|
970
|
+
}
|
|
971
|
+
var BASE_PATH = "/api/v3/topic";
|
|
972
|
+
var ApiClient = class _ApiClient {
|
|
898
973
|
baseUrl;
|
|
899
|
-
basePath;
|
|
900
974
|
customHeaders;
|
|
901
975
|
providedToken;
|
|
902
|
-
|
|
903
|
-
|
|
976
|
+
resolvedDeploymentId;
|
|
977
|
+
pinSends;
|
|
978
|
+
explicitlyUnpinned;
|
|
904
979
|
transport;
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
980
|
+
region;
|
|
981
|
+
baseUrlResolver;
|
|
982
|
+
constructor(options) {
|
|
983
|
+
this.region = options.region;
|
|
984
|
+
this.baseUrlResolver = options.resolveBaseUrl;
|
|
985
|
+
this.baseUrl = resolveBaseUrl(this.region, this.baseUrlResolver);
|
|
908
986
|
this.customHeaders = options.headers || {};
|
|
909
987
|
this.providedToken = options.token;
|
|
910
|
-
this.defaultDeploymentId = options.deploymentId || process.env.VERCEL_DEPLOYMENT_ID;
|
|
911
|
-
this.pinToDeployment = options.pinToDeployment ?? true;
|
|
912
988
|
this.transport = options.transport || new JsonTransport();
|
|
989
|
+
if (options.deploymentId === null) {
|
|
990
|
+
this.pinSends = false;
|
|
991
|
+
this.explicitlyUnpinned = true;
|
|
992
|
+
} else {
|
|
993
|
+
this.resolvedDeploymentId = options.deploymentId || process.env.VERCEL_DEPLOYMENT_ID;
|
|
994
|
+
this.pinSends = true;
|
|
995
|
+
this.explicitlyUnpinned = false;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Return a new ApiClient targeting the given region, sharing all other
|
|
1000
|
+
* configuration (token, transport, headers, deployment ID, resolver).
|
|
1001
|
+
* Used internally by handleCallback to route follow-up API calls to the
|
|
1002
|
+
* region indicated by the incoming `ce-vqsregion` header.
|
|
1003
|
+
*/
|
|
1004
|
+
withRegion(region) {
|
|
1005
|
+
return new _ApiClient({
|
|
1006
|
+
region,
|
|
1007
|
+
resolveBaseUrl: this.baseUrlResolver,
|
|
1008
|
+
token: this.providedToken,
|
|
1009
|
+
headers: { ...this.customHeaders },
|
|
1010
|
+
deploymentId: this.explicitlyUnpinned ? null : this.resolvedDeploymentId,
|
|
1011
|
+
transport: this.transport
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
getRegion() {
|
|
1015
|
+
return this.region;
|
|
913
1016
|
}
|
|
914
1017
|
getTransport() {
|
|
915
1018
|
return this.transport;
|
|
916
1019
|
}
|
|
1020
|
+
requireDeploymentId() {
|
|
1021
|
+
if (isDevMode() || this.explicitlyUnpinned || this.resolvedDeploymentId) {
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
throw new Error(
|
|
1025
|
+
'No deployment ID available. VERCEL_DEPLOYMENT_ID is not set.\n\nThis usually means the code is running outside a Vercel deployment (e.g. during build or in a non-Vercel environment).\n\nTo fix this, create a new QueueClient with an explicit deploymentId:\n new QueueClient({ region: "iad1", deploymentId: "dpl_xxx" })\nOr explicitly opt out of deployment pinning:\n new QueueClient({ region: "iad1", deploymentId: null })'
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
917
1028
|
getSendDeploymentId() {
|
|
918
1029
|
if (isDevMode()) {
|
|
919
1030
|
return void 0;
|
|
920
1031
|
}
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
}
|
|
924
|
-
return void 0;
|
|
1032
|
+
this.requireDeploymentId();
|
|
1033
|
+
return this.pinSends ? this.resolvedDeploymentId : void 0;
|
|
925
1034
|
}
|
|
926
1035
|
getConsumeDeploymentId() {
|
|
927
1036
|
if (isDevMode()) {
|
|
928
1037
|
return void 0;
|
|
929
1038
|
}
|
|
930
|
-
|
|
1039
|
+
this.requireDeploymentId();
|
|
1040
|
+
return this.resolvedDeploymentId;
|
|
931
1041
|
}
|
|
932
1042
|
async getToken() {
|
|
933
1043
|
if (this.providedToken) {
|
|
@@ -945,7 +1055,7 @@ var QueueClient = class {
|
|
|
945
1055
|
const encodedQueue = encodeURIComponent(queueName);
|
|
946
1056
|
const segments = pathSegments.map((s) => encodeURIComponent(s));
|
|
947
1057
|
const path2 = segments.length > 0 ? "/" + segments.join("/") : "";
|
|
948
|
-
return `${this.baseUrl}${
|
|
1058
|
+
return `${this.baseUrl}${BASE_PATH}/${encodedQueue}${path2}`;
|
|
949
1059
|
}
|
|
950
1060
|
async fetch(url, init) {
|
|
951
1061
|
const method = init.method || "GET";
|
|
@@ -969,7 +1079,7 @@ var QueueClient = class {
|
|
|
969
1079
|
}
|
|
970
1080
|
console.debug("[VQS Debug] Request:", JSON.stringify(logData, null, 2));
|
|
971
1081
|
}
|
|
972
|
-
init.headers.set("User-Agent", `@vercel/queue/${"0.0.0-alpha.
|
|
1082
|
+
init.headers.set("User-Agent", `@vercel/queue/${"0.0.0-alpha.40"}`);
|
|
973
1083
|
init.headers.set("Vqs-Client-Ts", (/* @__PURE__ */ new Date()).toISOString());
|
|
974
1084
|
const response = await fetch(url, init);
|
|
975
1085
|
if (isDebugEnabled()) {
|
|
@@ -984,24 +1094,6 @@ var QueueClient = class {
|
|
|
984
1094
|
}
|
|
985
1095
|
return response;
|
|
986
1096
|
}
|
|
987
|
-
/**
|
|
988
|
-
* Send a message to a topic.
|
|
989
|
-
*
|
|
990
|
-
* @param options - Message options including queue name, payload, and optional settings
|
|
991
|
-
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
992
|
-
* @param options.payload - Message payload
|
|
993
|
-
* @param options.idempotencyKey - Optional deduplication key (dedup window: min(retention, 24h))
|
|
994
|
-
* @param options.retentionSeconds - Message TTL (default: 86400, min: 60, max: 86400)
|
|
995
|
-
* @param options.delaySeconds - Delivery delay (default: 0, max: retentionSeconds)
|
|
996
|
-
* @returns Promise with the generated messageId
|
|
997
|
-
* @throws {DuplicateMessageError} When idempotency key was already used
|
|
998
|
-
* @throws {ConsumerDiscoveryError} When consumer discovery fails
|
|
999
|
-
* @throws {ConsumerRegistryNotConfiguredError} When registry not configured
|
|
1000
|
-
* @throws {BadRequestError} When parameters are invalid
|
|
1001
|
-
* @throws {UnauthorizedError} When authentication fails
|
|
1002
|
-
* @throws {ForbiddenError} When access is denied
|
|
1003
|
-
* @throws {InternalServerError} When server encounters an error
|
|
1004
|
-
*/
|
|
1005
1097
|
async sendMessage(options) {
|
|
1006
1098
|
const transport = this.transport;
|
|
1007
1099
|
const {
|
|
@@ -1079,28 +1171,12 @@ var QueueClient = class {
|
|
|
1079
1171
|
"send message"
|
|
1080
1172
|
);
|
|
1081
1173
|
}
|
|
1174
|
+
if (response.status === 202) {
|
|
1175
|
+
return { messageId: null };
|
|
1176
|
+
}
|
|
1082
1177
|
const responseData = await response.json();
|
|
1083
1178
|
return responseData;
|
|
1084
1179
|
}
|
|
1085
|
-
/**
|
|
1086
|
-
* Receive messages from a topic as an async generator.
|
|
1087
|
-
*
|
|
1088
|
-
* When the queue is empty, the generator completes without yielding any
|
|
1089
|
-
* messages. Callers should handle the case where no messages are yielded.
|
|
1090
|
-
*
|
|
1091
|
-
* @param options - Receive options
|
|
1092
|
-
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
1093
|
-
* @param options.consumerGroup - Consumer group name (pattern: `[A-Za-z0-9_-]+`)
|
|
1094
|
-
* @param options.visibilityTimeoutSeconds - Lock duration (default: 30, min: 0, max: 3600)
|
|
1095
|
-
* @param options.limit - Max messages to retrieve (default: 1, min: 1, max: 10)
|
|
1096
|
-
* @yields Message objects with payload, messageId, receiptHandle, etc.
|
|
1097
|
-
* Yields nothing if queue is empty.
|
|
1098
|
-
* @throws {InvalidLimitError} When limit is outside 1-10 range
|
|
1099
|
-
* @throws {BadRequestError} When parameters are invalid
|
|
1100
|
-
* @throws {UnauthorizedError} When authentication fails
|
|
1101
|
-
* @throws {ForbiddenError} When access is denied
|
|
1102
|
-
* @throws {InternalServerError} When server encounters an error
|
|
1103
|
-
*/
|
|
1104
1180
|
async *receiveMessages(options) {
|
|
1105
1181
|
const transport = this.transport;
|
|
1106
1182
|
const { queueName, consumerGroup, visibilityTimeoutSeconds, limit } = options;
|
|
@@ -1166,23 +1242,6 @@ var QueueClient = class {
|
|
|
1166
1242
|
}
|
|
1167
1243
|
}
|
|
1168
1244
|
}
|
|
1169
|
-
/**
|
|
1170
|
-
* Receive a specific message by its ID.
|
|
1171
|
-
*
|
|
1172
|
-
* @param options - Receive options
|
|
1173
|
-
* @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)
|
|
1174
|
-
* @param options.consumerGroup - Consumer group name (pattern: `[A-Za-z0-9_-]+`)
|
|
1175
|
-
* @param options.messageId - Message ID to retrieve
|
|
1176
|
-
* @param options.visibilityTimeoutSeconds - Lock duration (default: 30, min: 0, max: 3600)
|
|
1177
|
-
* @returns Promise with the message
|
|
1178
|
-
* @throws {MessageNotFoundError} When message doesn't exist
|
|
1179
|
-
* @throws {MessageNotAvailableError} When message is in wrong state or was a duplicate
|
|
1180
|
-
* @throws {MessageAlreadyProcessedError} When message was already processed
|
|
1181
|
-
* @throws {BadRequestError} When parameters are invalid
|
|
1182
|
-
* @throws {UnauthorizedError} When authentication fails
|
|
1183
|
-
* @throws {ForbiddenError} When access is denied
|
|
1184
|
-
* @throws {InternalServerError} When server encounters an error
|
|
1185
|
-
*/
|
|
1186
1245
|
async receiveMessageById(options) {
|
|
1187
1246
|
const transport = this.transport;
|
|
1188
1247
|
const { queueName, consumerGroup, messageId, visibilityTimeoutSeconds } = options;
|
|
@@ -1257,22 +1316,7 @@ var QueueClient = class {
|
|
|
1257
1316
|
}
|
|
1258
1317
|
throw new MessageNotFoundError(messageId);
|
|
1259
1318
|
}
|
|
1260
|
-
|
|
1261
|
-
* Delete (acknowledge) a message after successful processing.
|
|
1262
|
-
*
|
|
1263
|
-
* @param options - Delete options
|
|
1264
|
-
* @param options.queueName - Topic name
|
|
1265
|
-
* @param options.consumerGroup - Consumer group name
|
|
1266
|
-
* @param options.receiptHandle - Receipt handle from the received message (must use same deployment ID as receive)
|
|
1267
|
-
* @returns Promise indicating deletion success
|
|
1268
|
-
* @throws {MessageNotFoundError} When receipt handle not found
|
|
1269
|
-
* @throws {MessageNotAvailableError} When receipt handle invalid or message already processed
|
|
1270
|
-
* @throws {BadRequestError} When parameters are invalid
|
|
1271
|
-
* @throws {UnauthorizedError} When authentication fails
|
|
1272
|
-
* @throws {ForbiddenError} When access is denied
|
|
1273
|
-
* @throws {InternalServerError} When server encounters an error
|
|
1274
|
-
*/
|
|
1275
|
-
async deleteMessage(options) {
|
|
1319
|
+
async acknowledgeMessage(options) {
|
|
1276
1320
|
const { queueName, consumerGroup, receiptHandle } = options;
|
|
1277
1321
|
const headers = new Headers({
|
|
1278
1322
|
Authorization: `Bearer ${await this.getToken()}`,
|
|
@@ -1310,29 +1354,12 @@ var QueueClient = class {
|
|
|
1310
1354
|
response.status,
|
|
1311
1355
|
response.statusText,
|
|
1312
1356
|
errorText,
|
|
1313
|
-
"
|
|
1357
|
+
"acknowledge message",
|
|
1314
1358
|
"Missing or invalid receipt handle"
|
|
1315
1359
|
);
|
|
1316
1360
|
}
|
|
1317
|
-
return {
|
|
1361
|
+
return { acknowledged: true };
|
|
1318
1362
|
}
|
|
1319
|
-
/**
|
|
1320
|
-
* Extend or change the visibility timeout of a message.
|
|
1321
|
-
* Used to prevent message redelivery while still processing.
|
|
1322
|
-
*
|
|
1323
|
-
* @param options - Visibility options
|
|
1324
|
-
* @param options.queueName - Topic name
|
|
1325
|
-
* @param options.consumerGroup - Consumer group name
|
|
1326
|
-
* @param options.receiptHandle - Receipt handle from the received message (must use same deployment ID as receive)
|
|
1327
|
-
* @param options.visibilityTimeoutSeconds - New timeout (min: 0, max: 3600, cannot exceed message expiration)
|
|
1328
|
-
* @returns Promise indicating success
|
|
1329
|
-
* @throws {MessageNotFoundError} When receipt handle not found
|
|
1330
|
-
* @throws {MessageNotAvailableError} When receipt handle invalid or message already processed
|
|
1331
|
-
* @throws {BadRequestError} When parameters are invalid
|
|
1332
|
-
* @throws {UnauthorizedError} When authentication fails
|
|
1333
|
-
* @throws {ForbiddenError} When access is denied
|
|
1334
|
-
* @throws {InternalServerError} When server encounters an error
|
|
1335
|
-
*/
|
|
1336
1363
|
async changeVisibility(options) {
|
|
1337
1364
|
const {
|
|
1338
1365
|
queueName,
|
|
@@ -1384,100 +1411,211 @@ var QueueClient = class {
|
|
|
1384
1411
|
}
|
|
1385
1412
|
return { success: true };
|
|
1386
1413
|
}
|
|
1414
|
+
};
|
|
1415
|
+
|
|
1416
|
+
// src/client.ts
|
|
1417
|
+
var apiClients = /* @__PURE__ */ new WeakMap();
|
|
1418
|
+
function getApiClient(client) {
|
|
1419
|
+
const api = apiClients.get(client);
|
|
1420
|
+
if (!api) {
|
|
1421
|
+
throw new Error("QueueClient not initialized");
|
|
1422
|
+
}
|
|
1423
|
+
return api;
|
|
1424
|
+
}
|
|
1425
|
+
var QueueClient = class {
|
|
1426
|
+
constructor(options) {
|
|
1427
|
+
apiClients.set(this, new ApiClient(options));
|
|
1428
|
+
}
|
|
1387
1429
|
/**
|
|
1388
|
-
*
|
|
1389
|
-
*
|
|
1390
|
-
*
|
|
1430
|
+
* Send a message to a topic.
|
|
1431
|
+
*
|
|
1432
|
+
* This is an arrow function property so it can be destructured:
|
|
1433
|
+
* ```typescript
|
|
1434
|
+
* const { send } = new QueueClient({ region: process.env.QUEUE_REGION! });
|
|
1435
|
+
* await send("my-topic", payload);
|
|
1436
|
+
* ```
|
|
1391
1437
|
*
|
|
1392
|
-
* @param
|
|
1393
|
-
* @
|
|
1438
|
+
* @param topicName - Name of the topic (pattern: `[A-Za-z0-9_-]+`)
|
|
1439
|
+
* @param payload - The data to send (serialized via the configured transport)
|
|
1440
|
+
* @param options - Optional send options (idempotencyKey, retentionSeconds, delaySeconds, headers)
|
|
1441
|
+
* @returns `{ messageId }` — `messageId` is `null` when the server accepted
|
|
1442
|
+
* the message for deferred processing (no ID available yet)
|
|
1394
1443
|
*/
|
|
1395
|
-
async
|
|
1396
|
-
const
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
"Content-Type": "application/json",
|
|
1405
|
-
...this.customHeaders
|
|
1444
|
+
send = async (topicName, payload, options) => {
|
|
1445
|
+
const api = getApiClient(this);
|
|
1446
|
+
const result = await api.sendMessage({
|
|
1447
|
+
queueName: topicName,
|
|
1448
|
+
payload,
|
|
1449
|
+
idempotencyKey: options?.idempotencyKey,
|
|
1450
|
+
retentionSeconds: options?.retentionSeconds,
|
|
1451
|
+
delaySeconds: options?.delaySeconds,
|
|
1452
|
+
headers: options?.headers
|
|
1406
1453
|
});
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1454
|
+
if (result.messageId && isDevMode()) {
|
|
1455
|
+
triggerDevCallbacks(
|
|
1456
|
+
topicName,
|
|
1457
|
+
result.messageId,
|
|
1458
|
+
api.getRegion(),
|
|
1459
|
+
options?.delaySeconds
|
|
1460
|
+
);
|
|
1410
1461
|
}
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1462
|
+
return { messageId: result.messageId };
|
|
1463
|
+
};
|
|
1464
|
+
/**
|
|
1465
|
+
* Receive and process messages from a topic.
|
|
1466
|
+
*
|
|
1467
|
+
* Each message is automatically locked, kept alive via periodic visibility
|
|
1468
|
+
* extensions during processing, and acknowledged upon successful handler completion.
|
|
1469
|
+
* The handler is not called when the queue is empty — check `result.ok` instead.
|
|
1470
|
+
*
|
|
1471
|
+
* This is an arrow function property so it can be destructured:
|
|
1472
|
+
* ```typescript
|
|
1473
|
+
* const { receive } = new QueueClient({ region: process.env.QUEUE_REGION! });
|
|
1474
|
+
* const result = await receive("my-topic", "my-group", handler);
|
|
1475
|
+
* if (!result.ok) console.log(result.reason);
|
|
1476
|
+
* ```
|
|
1477
|
+
*
|
|
1478
|
+
* @param topicName - Name of the topic (pattern: `[A-Za-z0-9_-]+`)
|
|
1479
|
+
* @param consumerGroup - Name of the consumer group (pattern: `[A-Za-z0-9_-]+`)
|
|
1480
|
+
* @param handler - Function to process each message payload and metadata.
|
|
1481
|
+
* Not called when the queue is empty.
|
|
1482
|
+
* @param options - Optional receive options (visibilityTimeoutSeconds, limit, or messageId)
|
|
1483
|
+
* @returns Discriminated result: `{ ok: true }` on success, `{ ok: false, reason }` otherwise
|
|
1484
|
+
*/
|
|
1485
|
+
receive = async (topicName, consumerGroup, handler, options) => {
|
|
1486
|
+
const api = getApiClient(this);
|
|
1487
|
+
const topic = new Topic(api, topicName);
|
|
1488
|
+
const visibilityTimeoutSeconds = options && "visibilityTimeoutSeconds" in options ? options.visibilityTimeoutSeconds : void 0;
|
|
1489
|
+
const consumer = topic.consumerGroup(
|
|
1490
|
+
consumerGroup,
|
|
1491
|
+
visibilityTimeoutSeconds !== void 0 ? { visibilityTimeoutSeconds } : {}
|
|
1425
1492
|
);
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1493
|
+
try {
|
|
1494
|
+
let count;
|
|
1495
|
+
const retry = options?.retry;
|
|
1496
|
+
if (options && "messageId" in options) {
|
|
1497
|
+
count = await consumer.consume(handler, {
|
|
1498
|
+
messageId: options.messageId,
|
|
1499
|
+
retry
|
|
1500
|
+
});
|
|
1501
|
+
} else {
|
|
1502
|
+
const limit = options && "limit" in options ? options.limit : void 0;
|
|
1503
|
+
count = await consumer.consume(handler, {
|
|
1504
|
+
...limit !== void 0 ? { limit } : {},
|
|
1505
|
+
retry
|
|
1506
|
+
});
|
|
1430
1507
|
}
|
|
1431
|
-
if (
|
|
1432
|
-
|
|
1433
|
-
receiptHandle,
|
|
1434
|
-
errorText || "Invalid receipt handle, message not in correct state, or already processed"
|
|
1435
|
-
);
|
|
1508
|
+
if (count === 0) {
|
|
1509
|
+
return { ok: false, reason: "empty" };
|
|
1436
1510
|
}
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1511
|
+
return { ok: true };
|
|
1512
|
+
} catch (error) {
|
|
1513
|
+
if (options && "messageId" in options && error instanceof MessageNotFoundError) {
|
|
1514
|
+
return { ok: false, reason: "not_found", messageId: options.messageId };
|
|
1515
|
+
}
|
|
1516
|
+
if (options && "messageId" in options && error instanceof MessageNotAvailableError) {
|
|
1517
|
+
return {
|
|
1518
|
+
ok: false,
|
|
1519
|
+
reason: "not_available",
|
|
1520
|
+
messageId: options.messageId
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
if (options && "messageId" in options && error instanceof MessageAlreadyProcessedError) {
|
|
1524
|
+
return {
|
|
1525
|
+
ok: false,
|
|
1526
|
+
reason: "already_processed",
|
|
1527
|
+
messageId: options.messageId
|
|
1528
|
+
};
|
|
1529
|
+
}
|
|
1530
|
+
throw error;
|
|
1444
1531
|
}
|
|
1445
|
-
|
|
1446
|
-
|
|
1532
|
+
};
|
|
1533
|
+
/**
|
|
1534
|
+
* Create a Web API route handler for processing queue callback messages.
|
|
1535
|
+
*
|
|
1536
|
+
* Parses incoming `Request` as a CloudEvent and invokes the handler.
|
|
1537
|
+
* For use on Vercel — Vercel invokes this route when messages are available.
|
|
1538
|
+
*
|
|
1539
|
+
* This is an arrow function property so it can be destructured:
|
|
1540
|
+
* ```typescript
|
|
1541
|
+
* const { handleCallback } = new QueueClient({ region: process.env.QUEUE_REGION! });
|
|
1542
|
+
* export const POST = handleCallback(handler);
|
|
1543
|
+
* ```
|
|
1544
|
+
*
|
|
1545
|
+
* @param handler - Function to process the message payload and metadata
|
|
1546
|
+
* @param options - Optional configuration
|
|
1547
|
+
* @param options.visibilityTimeoutSeconds - Message lock duration (default: 300, max: 3600)
|
|
1548
|
+
* @param options.retry - Called when the handler throws. Return `{ afterSeconds: N }` to
|
|
1549
|
+
* reschedule the message for redelivery after N seconds.
|
|
1550
|
+
* @returns A `(request: Request) => Promise<Response>` route handler
|
|
1551
|
+
*/
|
|
1552
|
+
handleCallback = (handler, options) => {
|
|
1553
|
+
return async (request) => {
|
|
1554
|
+
try {
|
|
1555
|
+
const parsed = await parseCallback(request);
|
|
1556
|
+
await handleCallback(handler, parsed, {
|
|
1557
|
+
client: this,
|
|
1558
|
+
visibilityTimeoutSeconds: options?.visibilityTimeoutSeconds,
|
|
1559
|
+
retry: options?.retry
|
|
1560
|
+
});
|
|
1561
|
+
return Response.json({ status: "success" });
|
|
1562
|
+
} catch (error) {
|
|
1563
|
+
console.error("Queue callback error:", error);
|
|
1564
|
+
if (error instanceof Error && (error.message.includes("Invalid content type") || error.message.includes("Invalid CloudEvent") || error.message.includes("Missing required CloudEvent") || error.message.includes("Failed to parse CloudEvent") || error.message.includes("Binary mode callback"))) {
|
|
1565
|
+
return Response.json({ error: error.message }, { status: 400 });
|
|
1566
|
+
}
|
|
1567
|
+
return Response.json(
|
|
1568
|
+
{ error: "Failed to process queue message" },
|
|
1569
|
+
{ status: 500 }
|
|
1570
|
+
);
|
|
1571
|
+
}
|
|
1572
|
+
};
|
|
1573
|
+
};
|
|
1574
|
+
/**
|
|
1575
|
+
* Create a Connect-style route handler for processing queue callback messages.
|
|
1576
|
+
* For use on Vercel — Vercel invokes this route when messages are available.
|
|
1577
|
+
*
|
|
1578
|
+
* For frameworks using the `(req, res)` middleware pattern where `req.body`
|
|
1579
|
+
* is pre-parsed (Next.js Pages Router, etc.).
|
|
1580
|
+
*
|
|
1581
|
+
* This is an arrow function property so it can be destructured:
|
|
1582
|
+
* ```typescript
|
|
1583
|
+
* const { handleNodeCallback } = new QueueClient({ region: process.env.QUEUE_REGION! });
|
|
1584
|
+
* app.post("/api/queue", handleNodeCallback(handler));
|
|
1585
|
+
* ```
|
|
1586
|
+
*
|
|
1587
|
+
* @param handler - Function to process the message payload and metadata
|
|
1588
|
+
* @param options - Optional configuration
|
|
1589
|
+
* @param options.visibilityTimeoutSeconds - Message lock duration (default: 300, max: 3600)
|
|
1590
|
+
* @param options.retry - Called when the handler throws. Return `{ afterSeconds: N }` to
|
|
1591
|
+
* reschedule the message for redelivery after N seconds.
|
|
1592
|
+
* @returns A `(req, res) => Promise<void>` route handler
|
|
1593
|
+
*/
|
|
1594
|
+
handleNodeCallback = (handler, options) => {
|
|
1595
|
+
return async (req, res) => {
|
|
1596
|
+
if (req.method !== "POST") {
|
|
1597
|
+
res.status(200).end();
|
|
1598
|
+
return;
|
|
1599
|
+
}
|
|
1600
|
+
try {
|
|
1601
|
+
const parsed = parseRawCallback(req.body, req.headers);
|
|
1602
|
+
await handleCallback(handler, parsed, {
|
|
1603
|
+
client: this,
|
|
1604
|
+
visibilityTimeoutSeconds: options?.visibilityTimeoutSeconds,
|
|
1605
|
+
retry: options?.retry
|
|
1606
|
+
});
|
|
1607
|
+
res.status(200).json({ status: "success" });
|
|
1608
|
+
} catch (error) {
|
|
1609
|
+
console.error("Queue callback error:", error);
|
|
1610
|
+
if (error instanceof Error && (error.message.includes("Invalid content type") || error.message.includes("Invalid CloudEvent") || error.message.includes("Missing required CloudEvent") || error.message.includes("Failed to parse CloudEvent") || error.message.includes("Binary mode callback"))) {
|
|
1611
|
+
res.status(400).json({ error: error.message });
|
|
1612
|
+
return;
|
|
1613
|
+
}
|
|
1614
|
+
res.status(500).json({ error: "Failed to process queue message" });
|
|
1615
|
+
}
|
|
1616
|
+
};
|
|
1617
|
+
};
|
|
1447
1618
|
};
|
|
1448
|
-
|
|
1449
|
-
// src/factory.ts
|
|
1450
|
-
async function send(topicName, payload, options) {
|
|
1451
|
-
const client = options?.client || new QueueClient();
|
|
1452
|
-
const result = await client.sendMessage({
|
|
1453
|
-
queueName: topicName,
|
|
1454
|
-
payload,
|
|
1455
|
-
idempotencyKey: options?.idempotencyKey,
|
|
1456
|
-
retentionSeconds: options?.retentionSeconds,
|
|
1457
|
-
delaySeconds: options?.delaySeconds,
|
|
1458
|
-
headers: options?.headers
|
|
1459
|
-
});
|
|
1460
|
-
if (isDevMode()) {
|
|
1461
|
-
triggerDevCallbacks(topicName, result.messageId, options?.delaySeconds);
|
|
1462
|
-
}
|
|
1463
|
-
return { messageId: result.messageId };
|
|
1464
|
-
}
|
|
1465
|
-
async function receive(topicName, consumerGroup, handler, options) {
|
|
1466
|
-
const client = options?.client || new QueueClient();
|
|
1467
|
-
const topic = new Topic(client, topicName);
|
|
1468
|
-
const { client: _, ...rest } = options || {};
|
|
1469
|
-
const { visibilityTimeoutSeconds } = rest;
|
|
1470
|
-
const consumer = topic.consumerGroup(
|
|
1471
|
-
consumerGroup,
|
|
1472
|
-
visibilityTimeoutSeconds !== void 0 ? { visibilityTimeoutSeconds } : {}
|
|
1473
|
-
);
|
|
1474
|
-
if (options && "messageId" in options) {
|
|
1475
|
-
return consumer.consume(handler, { messageId: options.messageId });
|
|
1476
|
-
} else {
|
|
1477
|
-
const limit = options && "limit" in options ? options.limit : void 0;
|
|
1478
|
-
return consumer.consume(handler, limit !== void 0 ? { limit } : {});
|
|
1479
|
-
}
|
|
1480
|
-
}
|
|
1481
1619
|
export {
|
|
1482
1620
|
BadRequestError,
|
|
1483
1621
|
BufferTransport,
|
|
@@ -1499,10 +1637,7 @@ export {
|
|
|
1499
1637
|
QueueEmptyError,
|
|
1500
1638
|
StreamTransport,
|
|
1501
1639
|
UnauthorizedError,
|
|
1502
|
-
handleCallback,
|
|
1503
1640
|
parseCallback,
|
|
1504
|
-
parseRawCallback
|
|
1505
|
-
receive,
|
|
1506
|
-
send
|
|
1641
|
+
parseRawCallback
|
|
1507
1642
|
};
|
|
1508
1643
|
//# sourceMappingURL=index.mjs.map
|