@vercel/queue 0.0.0-alpha.37 → 0.0.0-alpha.39
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 +210 -174
- package/dist/{types-CAA8nT8x.d.mts → callback-lq_sorrn.d.mts} +249 -16
- package/dist/{types-CAA8nT8x.d.ts → callback-lq_sorrn.d.ts} +249 -16
- package/dist/index.d.mts +74 -333
- package/dist/index.d.ts +74 -333
- package/dist/index.js +713 -679
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +709 -678
- 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 +320 -313
- package/dist/nextjs-pages.js.map +1 -1
- package/dist/nextjs-pages.mjs +320 -313
- 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
package/README.md
CHANGED
|
@@ -5,12 +5,13 @@ A TypeScript client library for interacting with the Vercel Queue Service API, d
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **Automatic Queue Triggering**: Vercel automatically triggers your API routes when messages are ready
|
|
8
|
-
- **Next.js Integration**: Built-in support for Next.js
|
|
8
|
+
- **Next.js Integration**: Built-in support for Next.js App Router and Pages Router
|
|
9
9
|
- **Generic Payload Support**: Send and receive any type of data with type safety
|
|
10
10
|
- **Pub/Sub Pattern**: Topic-based messaging with consumer groups
|
|
11
11
|
- **Type Safety**: Full TypeScript support with generic types
|
|
12
12
|
- **Streaming Support**: Handle large payloads efficiently
|
|
13
13
|
- **Customizable Serialization**: Use built-in transports (JSON, Buffer, Stream) or create your own
|
|
14
|
+
- **Framework Adapters**: Web API, Next.js App Router, and Pages Router support
|
|
14
15
|
|
|
15
16
|
## Installation
|
|
16
17
|
|
|
@@ -39,6 +40,8 @@ vc env pull
|
|
|
39
40
|
|
|
40
41
|
The library reads your `vercel.json` configuration, discovers your queue handlers, and triggers them automatically when messages are sent.
|
|
41
42
|
|
|
43
|
+
> **Note:** Local dev mode is enabled when `NODE_ENV=development`. Most frameworks (Next.js, etc.) set this automatically when running `npm run dev`.
|
|
44
|
+
|
|
42
45
|
### Example Workflow
|
|
43
46
|
|
|
44
47
|
```bash
|
|
@@ -48,18 +51,6 @@ npm run dev
|
|
|
48
51
|
# Send messages - they process locally automatically!
|
|
49
52
|
```
|
|
50
53
|
|
|
51
|
-
### TypeScript Configuration
|
|
52
|
-
|
|
53
|
-
Update your `tsconfig.json` to use `"bundler"` module resolution for proper package export resolution:
|
|
54
|
-
|
|
55
|
-
```json
|
|
56
|
-
{
|
|
57
|
-
"compilerOptions": {
|
|
58
|
-
"moduleResolution": "bundler"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
54
|
### Publishing Messages
|
|
64
55
|
|
|
65
56
|
The `send` function can be used anywhere in your codebase to publish messages to a queue:
|
|
@@ -109,126 +100,107 @@ Messages are consumed using API routes that Vercel automatically triggers when m
|
|
|
109
100
|
|
|
110
101
|
#### 1. Create API Routes
|
|
111
102
|
|
|
112
|
-
#####
|
|
103
|
+
##### Web API (`@vercel/queue/web`)
|
|
104
|
+
|
|
105
|
+
The `handleCallback` from `@vercel/queue/web` returns a standard `(Request) => Promise<Response>` handler. It works with any framework that uses the Web API `Request`/`Response` types, including Next.js App Router, Hono, and others.
|
|
113
106
|
|
|
114
|
-
|
|
107
|
+
**Next.js App Router:**
|
|
115
108
|
|
|
116
109
|
```typescript
|
|
117
|
-
// app/api/queue/route.ts
|
|
118
|
-
import { handleCallback } from "@vercel/queue";
|
|
119
|
-
|
|
120
|
-
export const POST = handleCallback({
|
|
121
|
-
// Single topic with one consumer
|
|
122
|
-
"my-topic": {
|
|
123
|
-
"my-consumer": async (message, metadata) => {
|
|
124
|
-
// metadata includes: { messageId, deliveryCount, createdAt, topicName, consumerGroup }
|
|
125
|
-
console.log("Processing message:", message);
|
|
126
|
-
|
|
127
|
-
// If this throws an error, the message will be automatically retried
|
|
128
|
-
await processMessage(message);
|
|
129
|
-
},
|
|
130
|
-
},
|
|
110
|
+
// app/api/queue/my-topic/route.ts
|
|
111
|
+
import { handleCallback } from "@vercel/queue/web";
|
|
131
112
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
await trackOrder(order);
|
|
139
|
-
},
|
|
140
|
-
},
|
|
113
|
+
export const POST = handleCallback(async (message, metadata) => {
|
|
114
|
+
// metadata includes: { messageId, deliveryCount, createdAt, topicName, consumerGroup }
|
|
115
|
+
console.log("Processing message:", message);
|
|
116
|
+
|
|
117
|
+
// If this throws an error, the message will be automatically retried
|
|
118
|
+
await processMessage(message);
|
|
141
119
|
});
|
|
142
120
|
```
|
|
143
121
|
|
|
144
|
-
|
|
122
|
+
**Hono:**
|
|
145
123
|
|
|
146
|
-
|
|
124
|
+
```typescript
|
|
125
|
+
import { Hono } from "hono";
|
|
126
|
+
import { handleCallback } from "@vercel/queue/web";
|
|
127
|
+
|
|
128
|
+
const app = new Hono();
|
|
129
|
+
|
|
130
|
+
app.post(
|
|
131
|
+
"/api/queue",
|
|
132
|
+
handleCallback(async (message, metadata) => {
|
|
133
|
+
console.log("Processing:", message);
|
|
134
|
+
}),
|
|
135
|
+
);
|
|
147
136
|
|
|
148
|
-
|
|
137
|
+
export default app;
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
For multiple topics/consumers, create separate route files:
|
|
149
141
|
|
|
150
142
|
```typescript
|
|
151
|
-
//
|
|
152
|
-
import { handleCallback } from "@vercel/queue/
|
|
143
|
+
// app/api/queue/orders/fulfillment/route.ts
|
|
144
|
+
import { handleCallback } from "@vercel/queue/web";
|
|
153
145
|
|
|
154
|
-
export
|
|
155
|
-
|
|
156
|
-
"my-consumer": async (message, metadata) => {
|
|
157
|
-
console.log("Processing message:", message);
|
|
158
|
-
await processMessage(message);
|
|
159
|
-
},
|
|
160
|
-
},
|
|
161
|
-
"order-events": {
|
|
162
|
-
fulfillment: async (order, metadata) => {
|
|
163
|
-
await processOrder(order);
|
|
164
|
-
},
|
|
165
|
-
analytics: async (order, metadata) => {
|
|
166
|
-
await trackOrder(order);
|
|
167
|
-
},
|
|
168
|
-
},
|
|
146
|
+
export const POST = handleCallback(async (order, metadata) => {
|
|
147
|
+
await processOrder(order);
|
|
169
148
|
});
|
|
170
149
|
```
|
|
171
150
|
|
|
172
|
-
|
|
151
|
+
```typescript
|
|
152
|
+
// app/api/queue/orders/analytics/route.ts
|
|
153
|
+
import { handleCallback } from "@vercel/queue/web";
|
|
173
154
|
|
|
174
|
-
|
|
155
|
+
export const POST = handleCallback(async (order, metadata) => {
|
|
156
|
+
await trackOrder(order);
|
|
157
|
+
});
|
|
158
|
+
```
|
|
175
159
|
|
|
176
|
-
|
|
160
|
+
##### Pages Router (`@vercel/queue/nextjs/pages`)
|
|
177
161
|
|
|
178
|
-
|
|
162
|
+
For Next.js Pages Router, import from `@vercel/queue/nextjs/pages`. This returns a `(req, res) => Promise<void>` handler:
|
|
179
163
|
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
"consumer": "my-consumer",
|
|
189
|
-
"retryAfterSeconds": 60,
|
|
190
|
-
"initialDelaySeconds": 0
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
"type": "queue/v1beta",
|
|
194
|
-
"topic": "order-events",
|
|
195
|
-
"consumer": "fulfillment"
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
"type": "queue/v1beta",
|
|
199
|
-
"topic": "order-events",
|
|
200
|
-
"consumer": "analytics",
|
|
201
|
-
"retryAfterSeconds": 300
|
|
202
|
-
}
|
|
203
|
-
]
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
164
|
+
```typescript
|
|
165
|
+
// pages/api/queue/my-topic.ts
|
|
166
|
+
import { handleCallback } from "@vercel/queue/nextjs/pages";
|
|
167
|
+
|
|
168
|
+
export default handleCallback(async (message, metadata) => {
|
|
169
|
+
console.log("Processing message:", message);
|
|
170
|
+
await processMessage(message);
|
|
171
|
+
});
|
|
207
172
|
```
|
|
208
173
|
|
|
209
|
-
|
|
174
|
+
#### 2. Configure vercel.json
|
|
175
|
+
|
|
176
|
+
Configure which topics and consumers your API routes handle.
|
|
210
177
|
|
|
211
178
|
```json
|
|
212
179
|
{
|
|
213
180
|
"functions": {
|
|
214
|
-
"
|
|
181
|
+
"app/api/queue/my-topic/route.ts": {
|
|
215
182
|
"experimentalTriggers": [
|
|
216
183
|
{
|
|
217
|
-
"type": "queue/
|
|
184
|
+
"type": "queue/v2beta",
|
|
218
185
|
"topic": "my-topic",
|
|
219
|
-
"consumer": "my-consumer",
|
|
220
186
|
"retryAfterSeconds": 60,
|
|
221
187
|
"initialDelaySeconds": 0
|
|
222
|
-
}
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
"app/api/queue/orders/fulfillment/route.ts": {
|
|
192
|
+
"experimentalTriggers": [
|
|
223
193
|
{
|
|
224
|
-
"type": "queue/
|
|
225
|
-
"topic": "order-events"
|
|
226
|
-
|
|
227
|
-
|
|
194
|
+
"type": "queue/v2beta",
|
|
195
|
+
"topic": "order-events"
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
"app/api/queue/orders/analytics/route.ts": {
|
|
200
|
+
"experimentalTriggers": [
|
|
228
201
|
{
|
|
229
|
-
"type": "queue/
|
|
202
|
+
"type": "queue/v2beta",
|
|
230
203
|
"topic": "order-events",
|
|
231
|
-
"consumer": "analytics",
|
|
232
204
|
"retryAfterSeconds": 300
|
|
233
205
|
}
|
|
234
206
|
]
|
|
@@ -246,47 +218,48 @@ Configure which topics and consumers your API route handles.
|
|
|
246
218
|
- **Automatic Triggering**: Vercel triggers your API routes when messages are available
|
|
247
219
|
- **Message Processing**: Your API routes receive message metadata via headers
|
|
248
220
|
- **Configuration**: The `vercel.json` file tells Vercel which routes handle which topics/consumers
|
|
221
|
+
- **Delivery Modes**: The server uses CloudEvents binary content mode to deliver messages. For small messages, the full payload and receipt handle are pushed directly in the HTTP body and headers, avoiding an extra API fetch. For large messages, only the message ID is sent and the SDK fetches the payload.
|
|
249
222
|
|
|
250
223
|
## Advanced Features
|
|
251
224
|
|
|
252
|
-
### Client
|
|
225
|
+
### Custom Client Configuration
|
|
253
226
|
|
|
254
|
-
For custom configuration (tokens, headers,
|
|
227
|
+
For custom configuration (tokens, headers, transport), create a `QueueClient` and pass it via options:
|
|
255
228
|
|
|
256
229
|
```typescript
|
|
257
|
-
import {
|
|
230
|
+
import { QueueClient, send } from "@vercel/queue";
|
|
231
|
+
import { handleCallback } from "@vercel/queue/web";
|
|
258
232
|
|
|
259
|
-
const client = new
|
|
260
|
-
token: "my-token",
|
|
261
|
-
headers: { "X-Custom": "header" },
|
|
262
|
-
pinToDeployment: false, // Optional: disable deployment pinning (default: true)
|
|
233
|
+
const client = new QueueClient({
|
|
234
|
+
token: "my-token",
|
|
235
|
+
headers: { "X-Custom": "header" },
|
|
263
236
|
});
|
|
264
237
|
|
|
265
|
-
// Send
|
|
266
|
-
await
|
|
238
|
+
// Send with custom client
|
|
239
|
+
await send("my-topic", { hello: "world" }, { client });
|
|
267
240
|
|
|
268
|
-
// Handle callbacks
|
|
269
|
-
export const POST =
|
|
270
|
-
|
|
271
|
-
"my-group": async (msg, meta) => console.log(msg),
|
|
272
|
-
},
|
|
241
|
+
// Handle callbacks with custom client
|
|
242
|
+
export const POST = handleCallback(async (msg, meta) => console.log(msg), {
|
|
243
|
+
client,
|
|
273
244
|
});
|
|
274
245
|
```
|
|
275
246
|
|
|
276
|
-
###
|
|
247
|
+
### Core Handler (Framework Agnostic)
|
|
277
248
|
|
|
278
|
-
For custom
|
|
249
|
+
For custom framework integration, use the core `handleCallback` from `@vercel/queue`. It takes parsed request data and throws on errors:
|
|
279
250
|
|
|
280
251
|
```typescript
|
|
281
|
-
import {
|
|
252
|
+
import { handleCallback, parseRawCallback } from "@vercel/queue";
|
|
282
253
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
254
|
+
// In your framework handler:
|
|
255
|
+
const parsed = parseRawCallback(body, headers);
|
|
256
|
+
try {
|
|
257
|
+
await handleCallback(async (msg, meta) => {
|
|
258
|
+
console.log("Processing:", msg);
|
|
259
|
+
}, parsed);
|
|
260
|
+
// success
|
|
261
|
+
} catch (error) {
|
|
262
|
+
// handle error → 500
|
|
290
263
|
}
|
|
291
264
|
```
|
|
292
265
|
|
|
@@ -332,11 +305,41 @@ await send("json-topic", { data: "example" }, { transport });
|
|
|
332
305
|
| Large payloads | StreamTransport | Very Low | Medium |
|
|
333
306
|
| Real-time streams | StreamTransport | Very Low | High |
|
|
334
307
|
|
|
308
|
+
## Handling Empty Queues
|
|
309
|
+
|
|
310
|
+
When no messages are available in the queue, the handler receives `null` for both the message and metadata parameters. This allows graceful handling without exceptions:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
await receive("my-topic", "my-consumer", async (message, metadata) => {
|
|
314
|
+
if (!message) {
|
|
315
|
+
console.log("No message received - queue is empty");
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Process the message
|
|
320
|
+
console.log("Processing:", message);
|
|
321
|
+
console.log("Message ID:", metadata.messageId);
|
|
322
|
+
});
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
The same pattern works with `handleCallback`:
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
import { handleCallback } from "@vercel/queue/web";
|
|
329
|
+
|
|
330
|
+
export const POST = handleCallback(async (message, metadata) => {
|
|
331
|
+
if (!message) {
|
|
332
|
+
// No message available - handle gracefully
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
await processMessage(message);
|
|
336
|
+
});
|
|
337
|
+
```
|
|
338
|
+
|
|
335
339
|
## Error Handling
|
|
336
340
|
|
|
337
341
|
The queue client provides specific error types:
|
|
338
342
|
|
|
339
|
-
- **`QueueEmptyError`**: No messages available in the queue
|
|
340
343
|
- **`MessageLockedError`**: Message is being processed by another consumer
|
|
341
344
|
- **`MessageNotFoundError`**: Message doesn't exist or has expired
|
|
342
345
|
- **`MessageNotAvailableError`**: Message exists but cannot be claimed
|
|
@@ -399,26 +402,32 @@ The following environment variables can be used to configure the queue client:
|
|
|
399
402
|
```typescript
|
|
400
403
|
import { receive } from "@vercel/queue";
|
|
401
404
|
|
|
402
|
-
// Process next available message
|
|
403
|
-
await receive<T>(topicName, consumerGroup,
|
|
405
|
+
// Process next available message (or null if queue is empty)
|
|
406
|
+
await receive<T>(topicName, consumerGroup, async (message, metadata) => {
|
|
407
|
+
if (!message) {
|
|
408
|
+
console.log("Queue is empty");
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
// Process message
|
|
412
|
+
});
|
|
404
413
|
|
|
405
|
-
//
|
|
414
|
+
// Batch processing: fetch up to 10 messages in one request
|
|
406
415
|
await receive<T>(topicName, consumerGroup, handler, {
|
|
407
|
-
|
|
416
|
+
limit: 10, // Default: 1, Min: 1, Max: 10
|
|
408
417
|
});
|
|
409
418
|
|
|
410
|
-
// Process message
|
|
419
|
+
// Process specific message by ID
|
|
411
420
|
await receive<T>(topicName, consumerGroup, handler, {
|
|
412
|
-
messageId: "message-id",
|
|
413
|
-
transport: new JsonTransport(), // Optional: custom transport (defaults to JsonTransport)
|
|
414
|
-
visibilityTimeoutSeconds: 30, // Optional: message visibility timeout
|
|
415
|
-
visibilityRefreshInterval: 10, // Optional: how often to refresh the lock
|
|
421
|
+
messageId: "message-id",
|
|
416
422
|
});
|
|
417
423
|
|
|
424
|
+
// Note: limit and messageId are mutually exclusive options
|
|
425
|
+
|
|
418
426
|
// Handler function signature
|
|
427
|
+
// When queue is empty, both message and metadata are null
|
|
419
428
|
type MessageHandler<T = unknown> = (
|
|
420
|
-
message: T,
|
|
421
|
-
metadata: MessageMetadata,
|
|
429
|
+
message: T | null,
|
|
430
|
+
metadata: MessageMetadata | null,
|
|
422
431
|
) => Promise<void> | void;
|
|
423
432
|
|
|
424
433
|
// MessageMetadata type
|
|
@@ -437,7 +446,7 @@ interface MessageMetadata {
|
|
|
437
446
|
|
|
438
447
|
| Limit | Value | Notes |
|
|
439
448
|
| --------------------------- | --------------------- | ----------------------------------- |
|
|
440
|
-
| Message throughput | 10,
|
|
449
|
+
| Message throughput | 10,000+ msg/sec/topic | Scales horizontally |
|
|
441
450
|
| Payload size | 1 GB | Smaller messages have lower latency |
|
|
442
451
|
| Number of topics | Unlimited | No hard limit |
|
|
443
452
|
| Consumer groups per message | ~4,000 | Per-message limit |
|
|
@@ -495,9 +504,8 @@ Topic patterns support wildcards for flexible routing:
|
|
|
495
504
|
"app/api/queue/route.ts": {
|
|
496
505
|
"experimentalTriggers": [
|
|
497
506
|
{
|
|
498
|
-
"type": "queue/
|
|
499
|
-
"topic": "user-*"
|
|
500
|
-
"consumer": "processor"
|
|
507
|
+
"type": "queue/v2beta",
|
|
508
|
+
"topic": "user-*"
|
|
501
509
|
}
|
|
502
510
|
]
|
|
503
511
|
}
|
|
@@ -514,12 +522,28 @@ Topic patterns support wildcards for flexible routing:
|
|
|
514
522
|
|
|
515
523
|
## API Reference
|
|
516
524
|
|
|
517
|
-
###
|
|
525
|
+
### Export Structure
|
|
526
|
+
|
|
527
|
+
| Import Path | `handleCallback` |
|
|
528
|
+
| ---------------------------- | ---------------------------------------------------------------- |
|
|
529
|
+
| `@vercel/queue` | Core async function: `(handler, parsed, opts?) => Promise<void>` |
|
|
530
|
+
| `@vercel/queue/web` | Returns `(request: Request) => Promise<Response>` |
|
|
531
|
+
| `@vercel/queue/nextjs/pages` | Returns `(req, res) => Promise<void>` |
|
|
532
|
+
|
|
533
|
+
Additional exports from `@vercel/queue`:
|
|
534
|
+
|
|
535
|
+
| Export | Description |
|
|
536
|
+
| ------------------------- | ------------------------------------------------------------- |
|
|
537
|
+
| `parseCallback` | Parse a Web API `Request` into a `ParsedCallbackRequest` |
|
|
538
|
+
| `parseRawCallback` | Parse a pre-parsed body + headers (e.g. Pages Router) |
|
|
539
|
+
| `CLOUD_EVENT_TYPE_V2BETA` | `"com.vercel.queue.v2beta"` — binary CloudEvent type constant |
|
|
540
|
+
|
|
541
|
+
### QueueClient Configuration
|
|
518
542
|
|
|
519
543
|
```typescript
|
|
520
|
-
import {
|
|
544
|
+
import { QueueClient } from "@vercel/queue";
|
|
521
545
|
|
|
522
|
-
const client = new
|
|
546
|
+
const client = new QueueClient({
|
|
523
547
|
// Base URL for the queue service
|
|
524
548
|
// Default: "https://vercel-queue.com"
|
|
525
549
|
// Env: VERCEL_QUEUE_BASE_URL
|
|
@@ -544,6 +568,10 @@ const client = new Client({
|
|
|
544
568
|
// Default: true
|
|
545
569
|
pinToDeployment: true,
|
|
546
570
|
});
|
|
571
|
+
|
|
572
|
+
// Pass to any function via options
|
|
573
|
+
await send("my-topic", payload, { client });
|
|
574
|
+
export const POST = handleCallback(handler, { client });
|
|
547
575
|
```
|
|
548
576
|
|
|
549
577
|
### Send Options
|
|
@@ -569,62 +597,70 @@ await send("my-topic", payload, {
|
|
|
569
597
|
|
|
570
598
|
### Receive Options
|
|
571
599
|
|
|
600
|
+
The `receive` function supports two mutually exclusive modes:
|
|
601
|
+
|
|
572
602
|
```typescript
|
|
603
|
+
// Batch mode: receive multiple messages
|
|
573
604
|
await receive("my-topic", "my-consumer", handler, {
|
|
574
|
-
//
|
|
575
|
-
|
|
605
|
+
// Maximum messages to retrieve in a single request
|
|
606
|
+
// Default: 1, Min: 1, Max: 10
|
|
607
|
+
limit: 10,
|
|
576
608
|
|
|
577
609
|
// Message lock duration in seconds
|
|
578
|
-
// Default:
|
|
610
|
+
// Default: 300, Min: 30, Max: 3600
|
|
579
611
|
visibilityTimeoutSeconds: 60,
|
|
580
|
-
|
|
581
|
-
// How often to refresh the lock during processing
|
|
582
|
-
// Default: visibilityTimeoutSeconds / 3
|
|
583
|
-
visibilityRefreshInterval: 15,
|
|
584
|
-
|
|
585
|
-
// Custom deserializer (default: JsonTransport)
|
|
586
|
-
transport: new JsonTransport(),
|
|
587
612
|
});
|
|
588
|
-
```
|
|
589
613
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
```typescript
|
|
614
|
+
// By-ID mode: receive a specific message
|
|
593
615
|
await receive("my-topic", "my-consumer", handler, {
|
|
594
|
-
//
|
|
595
|
-
|
|
596
|
-
transport: new JsonTransport(),
|
|
616
|
+
// Specific message ID to consume
|
|
617
|
+
messageId: "0-1",
|
|
597
618
|
|
|
598
|
-
// Message lock duration
|
|
599
|
-
// Default:
|
|
619
|
+
// Message lock duration in seconds
|
|
620
|
+
// Default: 300, Min: 30, Max: 3600
|
|
600
621
|
visibilityTimeoutSeconds: 60,
|
|
601
|
-
|
|
602
|
-
// How often to refresh the lock during processing
|
|
603
|
-
// Default: visibilityTimeoutSeconds / 3
|
|
604
|
-
visibilityRefreshInterval: 20,
|
|
605
622
|
});
|
|
606
623
|
```
|
|
607
624
|
|
|
625
|
+
> **Note**: `limit` and `messageId` cannot be used together - they are mutually exclusive options.
|
|
626
|
+
|
|
608
627
|
### handleCallback Options
|
|
609
628
|
|
|
610
629
|
```typescript
|
|
630
|
+
import { handleCallback } from "@vercel/queue/web";
|
|
631
|
+
|
|
611
632
|
export const POST = handleCallback(
|
|
612
|
-
{
|
|
613
|
-
|
|
614
|
-
"my-consumer": async (message, metadata) => {
|
|
615
|
-
await processMessage(message);
|
|
616
|
-
},
|
|
617
|
-
},
|
|
633
|
+
async (message, metadata) => {
|
|
634
|
+
await processMessage(message);
|
|
618
635
|
},
|
|
619
636
|
{
|
|
620
637
|
// Message lock duration for long-running handlers
|
|
621
|
-
// Default:
|
|
622
|
-
// visibilityRefreshInterval defaults to visibilityTimeoutSeconds / 3
|
|
638
|
+
// Default: 300, Min: 30, Max: 3600
|
|
623
639
|
visibilityTimeoutSeconds: 300, // 5 minutes
|
|
624
640
|
},
|
|
625
641
|
);
|
|
626
642
|
```
|
|
627
643
|
|
|
644
|
+
### Core handleCallback
|
|
645
|
+
|
|
646
|
+
The core `handleCallback` is an async function that takes already-parsed request data. Use it to build custom framework integrations:
|
|
647
|
+
|
|
648
|
+
```typescript
|
|
649
|
+
import { handleCallback, parseCallback, parseRawCallback } from "@vercel/queue";
|
|
650
|
+
|
|
651
|
+
// Web API Request
|
|
652
|
+
const parsed = await parseCallback(request);
|
|
653
|
+
|
|
654
|
+
// Or, for frameworks that pre-parse the body (e.g. Pages Router)
|
|
655
|
+
const parsed = parseRawCallback(req.body, req.headers);
|
|
656
|
+
|
|
657
|
+
try {
|
|
658
|
+
await handleCallback(handler, parsed);
|
|
659
|
+
} catch (error) {
|
|
660
|
+
// handle error → 500
|
|
661
|
+
}
|
|
662
|
+
```
|
|
663
|
+
|
|
628
664
|
## License
|
|
629
665
|
|
|
630
666
|
MIT
|