@vercel/queue 0.0.0-alpha.33 → 0.0.0-alpha.35
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 +286 -85
- package/dist/index.d.mts +203 -127
- package/dist/index.d.ts +203 -127
- package/dist/index.js +680 -453
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +665 -453
- 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 +673 -474
- package/dist/nextjs-pages.js.map +1 -1
- package/dist/nextjs-pages.mjs +663 -474
- package/dist/nextjs-pages.mjs.map +1 -1
- package/dist/types-BLG4ASI_.d.mts +504 -0
- package/dist/types-BLG4ASI_.d.ts +504 -0
- package/package.json +2 -6
- package/bin/local-discover.js +0 -196
- package/dist/types-Dw29Fr9y.d.mts +0 -380
- package/dist/types-Dw29Fr9y.d.ts +0 -380
package/README.md
CHANGED
|
@@ -18,11 +18,6 @@ A TypeScript client library for interacting with the Vercel Queue Service API, d
|
|
|
18
18
|
npm install @vercel/queue
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
The package includes:
|
|
22
|
-
|
|
23
|
-
- **Main Library**: Queue client and utilities for production and development
|
|
24
|
-
- **CLI Tool**: `npx vercel-queue-local-init` for local development handler initialization
|
|
25
|
-
|
|
26
21
|
## Quick Start
|
|
27
22
|
|
|
28
23
|
For local development, you'll need to set up your Vercel project:
|
|
@@ -42,15 +37,7 @@ vc env pull
|
|
|
42
37
|
|
|
43
38
|
**Queues just work locally.** After you have setup your Vercel project, when you `send()` messages in development mode, they automatically trigger your handlers locally - no external queue infrastructure needed.
|
|
44
39
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
For Next.js API routes (or others that are lazy-loaded), run this simple command to initialize handlers:
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
npx vercel-queue-local-init
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
That's it! The script reads your `vercel.json`, finds your queue handlers, and triggers Next.js to load them.
|
|
40
|
+
The library reads your `vercel.json` configuration, discovers your queue handlers, and triggers them automatically when messages are sent.
|
|
54
41
|
|
|
55
42
|
### Example Workflow
|
|
56
43
|
|
|
@@ -58,22 +45,9 @@ That's it! The script reads your `vercel.json`, finds your queue handlers, and t
|
|
|
58
45
|
# Start your dev server
|
|
59
46
|
npm run dev
|
|
60
47
|
|
|
61
|
-
# Initialize handlers (only needed for frameworks that lazy load routes in dev)
|
|
62
|
-
npx vercel-queue-local-init
|
|
63
|
-
|
|
64
48
|
# Send messages - they process locally automatically!
|
|
65
49
|
```
|
|
66
50
|
|
|
67
|
-
### CLI Options
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
# Custom port
|
|
71
|
-
npx vercel-queue-local-init --port 3001
|
|
72
|
-
|
|
73
|
-
# Different config file
|
|
74
|
-
npx vercel-queue-local-init --config ./my-vercel.json
|
|
75
|
-
```
|
|
76
|
-
|
|
77
51
|
### TypeScript Configuration
|
|
78
52
|
|
|
79
53
|
Update your `tsconfig.json` to use `"bundler"` module resolution for proper package export resolution:
|
|
@@ -107,6 +81,7 @@ await send(
|
|
|
107
81
|
{
|
|
108
82
|
idempotencyKey: "unique-key", // Optional: prevent duplicate messages
|
|
109
83
|
retentionSeconds: 3600, // Optional: override retention time (defaults to 24 hours)
|
|
84
|
+
delaySeconds: 60, // Optional: delay message delivery by N seconds
|
|
110
85
|
},
|
|
111
86
|
);
|
|
112
87
|
```
|
|
@@ -146,7 +121,7 @@ export const POST = handleCallback({
|
|
|
146
121
|
// Single topic with one consumer
|
|
147
122
|
"my-topic": {
|
|
148
123
|
"my-consumer": async (message, metadata) => {
|
|
149
|
-
// metadata includes: { messageId, deliveryCount, createdAt }
|
|
124
|
+
// metadata includes: { messageId, deliveryCount, createdAt, topicName, consumerGroup }
|
|
150
125
|
console.log("Processing message:", message);
|
|
151
126
|
|
|
152
127
|
// If this throws an error, the message will be automatically retried
|
|
@@ -157,23 +132,10 @@ export const POST = handleCallback({
|
|
|
157
132
|
// Multiple consumers for different purposes
|
|
158
133
|
"order-events": {
|
|
159
134
|
fulfillment: async (order, metadata) => {
|
|
160
|
-
// By default, errors will trigger automatic retries
|
|
161
|
-
// But you can control retry timing if needed:
|
|
162
|
-
if (!isSystemReady()) {
|
|
163
|
-
// Override default retry with a 5 minute delay
|
|
164
|
-
return { timeoutSeconds: 300 };
|
|
165
|
-
}
|
|
166
|
-
|
|
167
135
|
await processOrder(order);
|
|
168
136
|
},
|
|
169
137
|
analytics: async (order, metadata) => {
|
|
170
|
-
|
|
171
|
-
await trackOrder(order);
|
|
172
|
-
} catch (error) {
|
|
173
|
-
// Optional: Custom exponential backoff instead of default retry timing
|
|
174
|
-
const timeoutSeconds = Math.pow(2, metadata.deliveryCount) * 60;
|
|
175
|
-
return { timeoutSeconds };
|
|
176
|
-
}
|
|
138
|
+
await trackOrder(order);
|
|
177
139
|
},
|
|
178
140
|
},
|
|
179
141
|
});
|
|
@@ -198,9 +160,6 @@ export default handleCallback({
|
|
|
198
160
|
},
|
|
199
161
|
"order-events": {
|
|
200
162
|
fulfillment: async (order, metadata) => {
|
|
201
|
-
if (!isSystemReady()) {
|
|
202
|
-
return { timeoutSeconds: 300 };
|
|
203
|
-
}
|
|
204
163
|
await processOrder(order);
|
|
205
164
|
},
|
|
206
165
|
analytics: async (order, metadata) => {
|
|
@@ -290,6 +249,47 @@ Configure which topics and consumers your API route handles.
|
|
|
290
249
|
|
|
291
250
|
## Advanced Features
|
|
292
251
|
|
|
252
|
+
### Client Class
|
|
253
|
+
|
|
254
|
+
For custom configuration (tokens, headers, etc.), use the `Client` class:
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { Client } from "@vercel/queue";
|
|
258
|
+
|
|
259
|
+
const client = new Client({
|
|
260
|
+
token: "my-token", // Optional: custom auth token
|
|
261
|
+
headers: { "X-Custom": "header" }, // Optional: custom headers
|
|
262
|
+
pinToDeployment: false, // Optional: disable deployment pinning (default: true)
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// Send a message
|
|
266
|
+
await client.send("my-topic", { hello: "world" });
|
|
267
|
+
|
|
268
|
+
// Handle callbacks using the same client
|
|
269
|
+
export const POST = client.handleCallback({
|
|
270
|
+
"my-topic": {
|
|
271
|
+
"my-group": async (msg, meta) => console.log(msg),
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Parsing Callback Requests
|
|
277
|
+
|
|
278
|
+
For custom webhook handling, use `parseCallback` to extract queue information from CloudEvent requests:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import { parseCallback } from "@vercel/queue";
|
|
282
|
+
|
|
283
|
+
export async function POST(request: Request) {
|
|
284
|
+
const { queueName, consumerGroup, messageId } = await parseCallback(request);
|
|
285
|
+
|
|
286
|
+
// Use the parsed information for custom processing...
|
|
287
|
+
await myWorkflow.handleWebhook(queueName, consumerGroup, messageId);
|
|
288
|
+
|
|
289
|
+
return Response.json({ status: "success" });
|
|
290
|
+
}
|
|
291
|
+
```
|
|
292
|
+
|
|
293
293
|
### Serialization (Transport) System
|
|
294
294
|
|
|
295
295
|
The queue client supports customizable serialization through the `Transport` interface:
|
|
@@ -314,36 +314,51 @@ await send(
|
|
|
314
314
|
{ data: "example" },
|
|
315
315
|
{ transport: new JsonTransport() },
|
|
316
316
|
);
|
|
317
|
+
|
|
318
|
+
// JsonTransport with custom serialization
|
|
319
|
+
const transport = new JsonTransport({
|
|
320
|
+
replacer: (key, value) => (key === "password" ? undefined : value),
|
|
321
|
+
reviver: (key, value) => (key === "date" ? new Date(value) : value),
|
|
322
|
+
});
|
|
323
|
+
await send("json-topic", { data: "example" }, { transport });
|
|
317
324
|
```
|
|
318
325
|
|
|
319
326
|
### Transport Selection Guide
|
|
320
327
|
|
|
321
|
-
| Use Case
|
|
322
|
-
|
|
|
323
|
-
| Small JSON objects
|
|
324
|
-
| Binary
|
|
325
|
-
| Large
|
|
326
|
-
| Real-time streams
|
|
328
|
+
| Use Case | Recommended Transport | Memory Usage | Performance |
|
|
329
|
+
| ------------------ | --------------------- | ------------ | ----------- |
|
|
330
|
+
| Small JSON objects | JsonTransport | Low | High |
|
|
331
|
+
| Binary data | BufferTransport | Medium | High |
|
|
332
|
+
| Large payloads | StreamTransport | Very Low | Medium |
|
|
333
|
+
| Real-time streams | StreamTransport | Very Low | High |
|
|
327
334
|
|
|
328
335
|
## Error Handling
|
|
329
336
|
|
|
330
337
|
The queue client provides specific error types:
|
|
331
338
|
|
|
332
|
-
- **`QueueEmptyError`**: No messages available
|
|
333
|
-
- **`MessageLockedError`**: Message
|
|
334
|
-
- **`MessageNotFoundError`**: Message doesn't exist
|
|
335
|
-
- **`MessageNotAvailableError`**: Message exists but
|
|
336
|
-
- **`
|
|
337
|
-
- **`
|
|
338
|
-
- **`
|
|
339
|
-
- **`
|
|
340
|
-
- **`
|
|
339
|
+
- **`QueueEmptyError`**: No messages available in the queue
|
|
340
|
+
- **`MessageLockedError`**: Message is being processed by another consumer
|
|
341
|
+
- **`MessageNotFoundError`**: Message doesn't exist or has expired
|
|
342
|
+
- **`MessageNotAvailableError`**: Message exists but cannot be claimed
|
|
343
|
+
- **`MessageAlreadyProcessedError`**: Message was already successfully processed
|
|
344
|
+
- **`MessageCorruptedError`**: Message data could not be parsed
|
|
345
|
+
- **`BadRequestError`**: Invalid request parameters
|
|
346
|
+
- **`UnauthorizedError`**: Authentication failed (invalid or missing token)
|
|
347
|
+
- **`ForbiddenError`**: Access denied (wrong environment or project)
|
|
348
|
+
- **`DuplicateMessageError`**: Idempotency key was already used
|
|
349
|
+
- **`ConcurrencyLimitError`**: Too many in-flight messages
|
|
350
|
+
- **`ConsumerDiscoveryError`**: Could not reach the consumer deployment
|
|
351
|
+
- **`ConsumerRegistryNotConfiguredError`**: Project not configured for queues
|
|
352
|
+
- **`InternalServerError`**: Unexpected server error
|
|
353
|
+
- **`InvalidLimitError`**: Batch limit outside valid range (1-10)
|
|
341
354
|
|
|
342
355
|
Example error handling:
|
|
343
356
|
|
|
344
357
|
```typescript
|
|
345
358
|
import {
|
|
346
359
|
BadRequestError,
|
|
360
|
+
ConcurrencyLimitError,
|
|
361
|
+
DuplicateMessageError,
|
|
347
362
|
ForbiddenError,
|
|
348
363
|
InternalServerError,
|
|
349
364
|
UnauthorizedError,
|
|
@@ -358,59 +373,131 @@ try {
|
|
|
358
373
|
console.log("Environment mismatch - check configuration");
|
|
359
374
|
} else if (error instanceof BadRequestError) {
|
|
360
375
|
console.log("Invalid parameters:", error.message);
|
|
376
|
+
} else if (error instanceof DuplicateMessageError) {
|
|
377
|
+
console.log("Duplicate message:", error.idempotencyKey);
|
|
378
|
+
} else if (error instanceof ConcurrencyLimitError) {
|
|
379
|
+
console.log(
|
|
380
|
+
"Rate limited:",
|
|
381
|
+
error.currentInflight,
|
|
382
|
+
"/",
|
|
383
|
+
error.maxConcurrency,
|
|
384
|
+
);
|
|
361
385
|
} else if (error instanceof InternalServerError) {
|
|
362
386
|
console.log("Server error - retry with backoff");
|
|
363
387
|
}
|
|
364
388
|
}
|
|
365
389
|
```
|
|
366
390
|
|
|
391
|
+
## Environment Variables
|
|
392
|
+
|
|
393
|
+
The following environment variables can be used to configure the queue client:
|
|
394
|
+
|
|
395
|
+
| Variable | Description | Default |
|
|
396
|
+
| ------------------------ | ------------------------------------ | -------------------------- |
|
|
397
|
+
| `VERCEL_QUEUE_BASE_URL` | Override the queue service URL | `https://vercel-queue.com` |
|
|
398
|
+
| `VERCEL_QUEUE_BASE_PATH` | Override the API base path | `/api/v3/topic` |
|
|
399
|
+
| `VERCEL_QUEUE_DEBUG` | Enable debug logging (`1` or `true`) | - |
|
|
400
|
+
| `VERCEL_DEPLOYMENT_ID` | Deployment ID (auto-set by Vercel) | - |
|
|
401
|
+
|
|
367
402
|
## Advanced Usage
|
|
368
403
|
|
|
369
404
|
### Direct Message Processing
|
|
370
405
|
|
|
371
|
-
> **Note**: The `receive` function is
|
|
406
|
+
> **Note**: The `receive` function is for advanced use cases where you need direct message processing control outside of Vercel's automatic triggering.
|
|
372
407
|
|
|
373
408
|
```typescript
|
|
409
|
+
import { receive } from "@vercel/queue";
|
|
410
|
+
|
|
374
411
|
// Process next available message
|
|
375
412
|
await receive<T>(topicName, consumerGroup, handler);
|
|
376
413
|
|
|
377
414
|
// Process specific message by ID
|
|
378
415
|
await receive<T>(topicName, consumerGroup, handler, {
|
|
379
|
-
messageId: "message-id"
|
|
416
|
+
messageId: "message-id",
|
|
380
417
|
});
|
|
381
418
|
|
|
382
419
|
// Process message with options
|
|
383
420
|
await receive<T>(topicName, consumerGroup, handler, {
|
|
384
|
-
messageId
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
refreshInterval?: number; // Refresh interval for long-running operations
|
|
421
|
+
messageId: "message-id", // Optional: process specific message by ID
|
|
422
|
+
transport: new JsonTransport(), // Optional: custom transport (defaults to JsonTransport)
|
|
423
|
+
visibilityTimeoutSeconds: 30, // Optional: message visibility timeout
|
|
424
|
+
visibilityRefreshInterval: 10, // Optional: how often to refresh the lock
|
|
389
425
|
});
|
|
390
426
|
|
|
391
427
|
// Handler function signature
|
|
392
428
|
type MessageHandler<T = unknown> = (
|
|
393
429
|
message: T,
|
|
394
|
-
metadata: MessageMetadata
|
|
395
|
-
) => Promise<
|
|
396
|
-
|
|
397
|
-
//
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
430
|
+
metadata: MessageMetadata,
|
|
431
|
+
) => Promise<void> | void;
|
|
432
|
+
|
|
433
|
+
// MessageMetadata type
|
|
434
|
+
interface MessageMetadata {
|
|
435
|
+
messageId: string;
|
|
436
|
+
deliveryCount: number;
|
|
437
|
+
createdAt: Date;
|
|
438
|
+
topicName: string;
|
|
439
|
+
consumerGroup: string;
|
|
402
440
|
}
|
|
403
441
|
```
|
|
404
442
|
|
|
405
|
-
## Limits
|
|
443
|
+
## Service Limits & Constraints
|
|
444
|
+
|
|
445
|
+
### Throughput & Storage
|
|
446
|
+
|
|
447
|
+
| Limit | Value | Notes |
|
|
448
|
+
| --------------------------- | --------------------- | ----------------------------------- |
|
|
449
|
+
| Message throughput | 10,000s msg/sec/topic | Scales horizontally |
|
|
450
|
+
| Payload size | 1 GB | Smaller messages have lower latency |
|
|
451
|
+
| Number of topics | Unlimited | No hard limit |
|
|
452
|
+
| Consumer groups per message | ~4,000 | Per-message limit |
|
|
453
|
+
| Messages per queue | Unlimited | No hard limit |
|
|
454
|
+
|
|
455
|
+
### Parameter Constraints
|
|
456
|
+
|
|
457
|
+
#### Publishing Messages
|
|
458
|
+
|
|
459
|
+
| Parameter | Default | Min | Max | Notes |
|
|
460
|
+
| ------------------ | ------------ | --- | ----------- | ----------------------------------- |
|
|
461
|
+
| `retentionSeconds` | 86,400 (24h) | 60 | 86,400 | Message TTL |
|
|
462
|
+
| `delaySeconds` | 0 | 0 | ≤ retention | Cannot exceed retention |
|
|
463
|
+
| `idempotencyKey` | — | — | — | Dedup window: `min(retention, 24h)` |
|
|
406
464
|
|
|
407
|
-
|
|
408
|
-
- **Payload Size**: Maximum payload size is 4.5MB (this limit will be increased soon)
|
|
409
|
-
- **Number of Topics**: No limit on the number of topics you can create
|
|
465
|
+
#### Receiving Messages
|
|
410
466
|
|
|
411
|
-
|
|
467
|
+
| Parameter | Default | Min | Max | Notes |
|
|
468
|
+
| -------------------------- | --------- | --- | ------ | --------------------------- |
|
|
469
|
+
| `visibilityTimeoutSeconds` | 30 | 0 | 3,600 | 0 = immediate re-visibility |
|
|
470
|
+
| `limit` | 1 | 1 | 10 | Messages per request |
|
|
471
|
+
| `maxConcurrency` | unlimited | 1 | 10,000 | In-flight message limit |
|
|
412
472
|
|
|
413
|
-
|
|
473
|
+
#### Visibility Extension
|
|
474
|
+
|
|
475
|
+
| Constraint | Value |
|
|
476
|
+
| -------------------------- | ---------------------------------- |
|
|
477
|
+
| `visibilityTimeoutSeconds` | 0 - 3,600 seconds |
|
|
478
|
+
| Cannot extend beyond | Message's original expiration time |
|
|
479
|
+
| Receipt handle | Must match the receive operation |
|
|
480
|
+
|
|
481
|
+
### Identifier Formats
|
|
482
|
+
|
|
483
|
+
| Identifier | Pattern | Example |
|
|
484
|
+
| ---------------- | ---------------- | -------------------------------- |
|
|
485
|
+
| Topic/Queue name | `[A-Za-z0-9_-]+` | `my-queue`, `task_queue_v2` |
|
|
486
|
+
| Consumer group | `[A-Za-z0-9_-]+` | `worker-1`, `analytics_consumer` |
|
|
487
|
+
| Message ID | Opaque string | `0-1`, `3-7K9mNpQrS` |
|
|
488
|
+
| Receipt handle | Opaque string | Used for delete/visibility ops |
|
|
489
|
+
|
|
490
|
+
### Content-Type Handling
|
|
491
|
+
|
|
492
|
+
| Scenario | Result |
|
|
493
|
+
| ------------------------------- | -------------------------- |
|
|
494
|
+
| Client provides `Content-Type` | Used as-is |
|
|
495
|
+
| No header, magic bytes detected | Auto-detected MIME type |
|
|
496
|
+
| No header, detection fails | `application/octet-stream` |
|
|
497
|
+
|
|
498
|
+
### Wildcard Topics
|
|
499
|
+
|
|
500
|
+
Topic patterns support wildcards for flexible routing:
|
|
414
501
|
|
|
415
502
|
```json
|
|
416
503
|
{
|
|
@@ -428,11 +515,125 @@ If you need more than 1,000 messages per second, you can create multiple topics
|
|
|
428
515
|
}
|
|
429
516
|
```
|
|
430
517
|
|
|
431
|
-
|
|
518
|
+
**Wildcard Rules:**
|
|
519
|
+
|
|
520
|
+
- `*` may only appear **once** in the pattern
|
|
521
|
+
- `*` must be at the **end** of the topic name
|
|
522
|
+
- Valid: `user-*`, `orders-*`
|
|
523
|
+
- Invalid: `*-events`, `user-*-data`
|
|
524
|
+
|
|
525
|
+
## API Reference
|
|
526
|
+
|
|
527
|
+
### Client Configuration
|
|
528
|
+
|
|
529
|
+
```typescript
|
|
530
|
+
import { Client } from "@vercel/queue";
|
|
531
|
+
|
|
532
|
+
const client = new Client({
|
|
533
|
+
// Base URL for the queue service
|
|
534
|
+
// Default: "https://vercel-queue.com"
|
|
535
|
+
// Env: VERCEL_QUEUE_BASE_URL
|
|
536
|
+
baseUrl: "https://vercel-queue.com",
|
|
537
|
+
|
|
538
|
+
// API path prefix
|
|
539
|
+
// Default: "/api/v3/topic"
|
|
540
|
+
// Env: VERCEL_QUEUE_BASE_PATH
|
|
541
|
+
basePath: "/api/v3/topic",
|
|
542
|
+
|
|
543
|
+
// Auth token (auto-fetched via OIDC if not provided)
|
|
544
|
+
token: "my-token",
|
|
545
|
+
|
|
546
|
+
// Custom headers for all requests
|
|
547
|
+
headers: { "X-Custom": "value" },
|
|
548
|
+
|
|
549
|
+
// Deployment ID for message routing
|
|
550
|
+
// Default: process.env.VERCEL_DEPLOYMENT_ID
|
|
551
|
+
deploymentId: "dpl_xxx",
|
|
552
|
+
|
|
553
|
+
// Pin messages to current deployment when publishing
|
|
554
|
+
// Default: true
|
|
555
|
+
pinToDeployment: true,
|
|
556
|
+
});
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Send Options
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
await send("my-topic", payload, {
|
|
563
|
+
// Deduplication key
|
|
564
|
+
// Dedup window: min(retentionSeconds, 24 hours)
|
|
565
|
+
idempotencyKey: "unique-key",
|
|
566
|
+
|
|
567
|
+
// Message TTL in seconds
|
|
568
|
+
// Default: 86400, Min: 60, Max: 86400
|
|
569
|
+
retentionSeconds: 3600,
|
|
570
|
+
|
|
571
|
+
// Delay before message becomes visible
|
|
572
|
+
// Default: 0, Min: 0, Max: retentionSeconds
|
|
573
|
+
delaySeconds: 60,
|
|
574
|
+
|
|
575
|
+
// Custom serializer (default: JsonTransport)
|
|
576
|
+
transport: new JsonTransport(),
|
|
577
|
+
});
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
### Receive Options
|
|
581
|
+
|
|
582
|
+
```typescript
|
|
583
|
+
await receive("my-topic", "my-consumer", handler, {
|
|
584
|
+
// Specific message ID to consume (optional)
|
|
585
|
+
messageId: "0-1",
|
|
586
|
+
|
|
587
|
+
// Message lock duration in seconds
|
|
588
|
+
// Default: 30, Min: 0, Max: 3600
|
|
589
|
+
visibilityTimeoutSeconds: 60,
|
|
432
590
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
591
|
+
// How often to refresh the lock during processing
|
|
592
|
+
// Default: visibilityTimeoutSeconds / 3
|
|
593
|
+
visibilityRefreshInterval: 15,
|
|
594
|
+
|
|
595
|
+
// Custom deserializer (default: JsonTransport)
|
|
596
|
+
transport: new JsonTransport(),
|
|
597
|
+
});
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Receive Options (Advanced)
|
|
601
|
+
|
|
602
|
+
```typescript
|
|
603
|
+
await receive("my-topic", "my-consumer", handler, {
|
|
604
|
+
// Payload deserializer
|
|
605
|
+
// Default: JsonTransport
|
|
606
|
+
transport: new JsonTransport(),
|
|
607
|
+
|
|
608
|
+
// Message lock duration
|
|
609
|
+
// Default: 30, Min: 0, Max: 3600
|
|
610
|
+
visibilityTimeoutSeconds: 60,
|
|
611
|
+
|
|
612
|
+
// How often to refresh the lock during processing
|
|
613
|
+
// Default: visibilityTimeoutSeconds / 3
|
|
614
|
+
visibilityRefreshInterval: 20,
|
|
615
|
+
});
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### handleCallback Options
|
|
619
|
+
|
|
620
|
+
```typescript
|
|
621
|
+
export const POST = handleCallback(
|
|
622
|
+
{
|
|
623
|
+
"my-topic": {
|
|
624
|
+
"my-consumer": async (message, metadata) => {
|
|
625
|
+
await processMessage(message);
|
|
626
|
+
},
|
|
627
|
+
},
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
// Message lock duration for long-running handlers
|
|
631
|
+
// Default: 30, Min: 0, Max: 3600
|
|
632
|
+
// visibilityRefreshInterval defaults to visibilityTimeoutSeconds / 3
|
|
633
|
+
visibilityTimeoutSeconds: 300, // 5 minutes
|
|
634
|
+
},
|
|
635
|
+
);
|
|
636
|
+
```
|
|
436
637
|
|
|
437
638
|
## License
|
|
438
639
|
|