@vercel/queue 0.0.2 → 0.1.1
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 +182 -99
- package/dist/index.d.mts +179 -39
- package/dist/index.d.ts +179 -39
- package/dist/index.js +640 -209
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +635 -208
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,9 +4,9 @@ A TypeScript client library for interacting with the Vercel Queue Service API, d
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Simple API**: `send` and `
|
|
7
|
+
- **Simple API**: `send` and `handleCallback` are all you need for push-based workflows
|
|
8
8
|
- **Automatic Triggering on Vercel**: Vercel invokes your route handlers when messages are ready
|
|
9
|
-
- **Works Anywhere**: `send` and `receive` work in any Node.js environment
|
|
9
|
+
- **Works Anywhere**: `send` and `receive` work in any Node.js environment, including self-hosted and non-Vercel platforms
|
|
10
10
|
- **Type Safety**: Full TypeScript generics support
|
|
11
11
|
- **Customizable Serialization**: Built-in JSON, Buffer, and Stream transports
|
|
12
12
|
- **Local Dev Mode**: Messages sent locally trigger your handlers automatically
|
|
@@ -19,48 +19,36 @@ npm install @vercel/queue
|
|
|
19
19
|
|
|
20
20
|
## Quick Start
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
**1. Link your Vercel project and pull credentials:**
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
# .env.production (on Vercel, inherits the platform's region)
|
|
26
|
-
QUEUE_REGION=${VERCEL_REGION}
|
|
27
|
-
|
|
28
|
-
# .env.development (fixed region for local dev — iad1 is recommended)
|
|
29
|
-
QUEUE_REGION=iad1
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Otherwise, set `QUEUE_REGION` in your environment directly (e.g. via your hosting provider's dashboard or a `dotenv` setup).
|
|
33
|
-
|
|
34
|
-
Create a shared queue client:
|
|
35
|
-
|
|
36
|
-
```typescript
|
|
37
|
-
// lib/queue.ts
|
|
38
|
-
import { QueueClient } from "@vercel/queue";
|
|
24
|
+
The SDK authenticates via OIDC. Link your project if you haven't already, then pull to get fresh tokens:
|
|
39
25
|
|
|
40
|
-
|
|
41
|
-
|
|
26
|
+
```bash
|
|
27
|
+
npm i -g vercel
|
|
28
|
+
vc link # if you haven't already
|
|
29
|
+
vc env pull
|
|
42
30
|
```
|
|
43
31
|
|
|
44
|
-
Send a message anywhere in your app
|
|
32
|
+
**2. Send a message anywhere in your app:**
|
|
45
33
|
|
|
46
34
|
```typescript
|
|
47
|
-
import { send } from "
|
|
35
|
+
import { send } from "@vercel/queue";
|
|
48
36
|
|
|
49
37
|
await send("my-topic", { message: "Hello world" });
|
|
50
38
|
```
|
|
51
39
|
|
|
52
|
-
Handle incoming messages with a route handler
|
|
40
|
+
**3. Handle incoming messages with a route handler:**
|
|
53
41
|
|
|
54
42
|
```typescript
|
|
55
43
|
// app/api/queue/my-topic/route.ts
|
|
56
|
-
import { handleCallback } from "
|
|
44
|
+
import { handleCallback } from "@vercel/queue";
|
|
57
45
|
|
|
58
46
|
export const POST = handleCallback(async (message, metadata) => {
|
|
59
47
|
console.log("Processing:", message);
|
|
60
48
|
});
|
|
61
49
|
```
|
|
62
50
|
|
|
63
|
-
Configure
|
|
51
|
+
**4. Configure `vercel.json`:**
|
|
64
52
|
|
|
65
53
|
```json
|
|
66
54
|
{
|
|
@@ -72,28 +60,26 @@ Configure your `vercel.json`:
|
|
|
72
60
|
}
|
|
73
61
|
```
|
|
74
62
|
|
|
75
|
-
|
|
63
|
+
That's it. The top-level `send` and `handleCallback` use an auto-configured default client. The region is auto-detected from `VERCEL_REGION` (set automatically on Vercel). If the region can't be detected (e.g. local dev), it falls back to `iad1`.
|
|
76
64
|
|
|
77
|
-
|
|
65
|
+
To target a specific region for sending, pass the `region` option:
|
|
78
66
|
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
vc link
|
|
82
|
-
vc env pull
|
|
67
|
+
```typescript
|
|
68
|
+
await send("my-topic", payload, { region: "sfo1" });
|
|
83
69
|
```
|
|
84
70
|
|
|
85
71
|
## Local Development
|
|
86
72
|
|
|
87
|
-
**Queues just work locally.** When you `send()` messages in development mode, the library sends them to the real Vercel Queue Service,
|
|
73
|
+
**Queues just work locally.** When you `send()` messages in development mode, the library sends them to the real Vercel Queue Service, then invokes your registered `handleCallback` handlers directly in-process using the same code path as production. Your handlers are called with the exact same lifecycle (receive, visibility extension, ack) as in production.
|
|
74
|
+
|
|
75
|
+
Works with Next.js (Turbopack and webpack), Nuxt, SvelteKit, and any framework that runs server-side JavaScript. The SDK automatically discovers handlers from your `vercel.json` configuration and loads route modules on demand — no manual setup required beyond `vercel.json`.
|
|
88
76
|
|
|
89
|
-
> **Note:** Local dev mode is enabled when `NODE_ENV=development`. Most frameworks
|
|
77
|
+
> **Note:** Local dev mode is enabled when `NODE_ENV=development`. Most frameworks set this automatically during `npm run dev`.
|
|
90
78
|
|
|
91
79
|
## Publishing Messages
|
|
92
80
|
|
|
93
81
|
```typescript
|
|
94
|
-
import {
|
|
95
|
-
|
|
96
|
-
const { send } = new QueueClient({ region: process.env.QUEUE_REGION! });
|
|
82
|
+
import { send } from "@vercel/queue";
|
|
97
83
|
|
|
98
84
|
// Simple send
|
|
99
85
|
await send("my-topic", { message: "Hello world" });
|
|
@@ -106,6 +92,7 @@ await send(
|
|
|
106
92
|
idempotencyKey: "unique-key", // Prevent duplicate messages
|
|
107
93
|
retentionSeconds: 3600, // 1 hour TTL (default: 24h)
|
|
108
94
|
delaySeconds: 60, // Delay delivery by 1 minute
|
|
95
|
+
region: "sfo1", // Optional — target a specific region
|
|
109
96
|
},
|
|
110
97
|
);
|
|
111
98
|
```
|
|
@@ -114,7 +101,7 @@ Example usage in an API route:
|
|
|
114
101
|
|
|
115
102
|
```typescript
|
|
116
103
|
// app/api/send-message/route.ts
|
|
117
|
-
import { send } from "
|
|
104
|
+
import { send } from "@vercel/queue";
|
|
118
105
|
|
|
119
106
|
export async function POST(request: Request) {
|
|
120
107
|
const body = await request.json();
|
|
@@ -139,7 +126,7 @@ Returns `(Request) => Promise<Response>`. For frameworks that export Web API rou
|
|
|
139
126
|
|
|
140
127
|
```typescript
|
|
141
128
|
// app/api/queue/my-topic/route.ts
|
|
142
|
-
import { handleCallback } from "
|
|
129
|
+
import { handleCallback } from "@vercel/queue";
|
|
143
130
|
|
|
144
131
|
export const POST = handleCallback(async (message, metadata) => {
|
|
145
132
|
// metadata: { messageId, deliveryCount, createdAt, expiresAt?, topicName, consumerGroup, region }
|
|
@@ -148,11 +135,37 @@ export const POST = handleCallback(async (message, metadata) => {
|
|
|
148
135
|
});
|
|
149
136
|
```
|
|
150
137
|
|
|
138
|
+
**Nuxt:**
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// server/api/queue.ts
|
|
142
|
+
import { handleCallback } from "@vercel/queue";
|
|
143
|
+
|
|
144
|
+
const handler = handleCallback(async (message, metadata) => {
|
|
145
|
+
await processMessage(message);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
export default defineEventHandler(async (event) => {
|
|
149
|
+
return handler(toWebRequest(event));
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**SvelteKit:**
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
// src/routes/api/queue/+server.ts
|
|
157
|
+
import { handleCallback } from "@vercel/queue";
|
|
158
|
+
|
|
159
|
+
export const POST = handleCallback(async (message, metadata) => {
|
|
160
|
+
await processMessage(message);
|
|
161
|
+
});
|
|
162
|
+
```
|
|
163
|
+
|
|
151
164
|
**Hono:**
|
|
152
165
|
|
|
153
166
|
```typescript
|
|
154
167
|
import { Hono } from "hono";
|
|
155
|
-
import { handleCallback } from "
|
|
168
|
+
import { handleCallback } from "@vercel/queue";
|
|
156
169
|
|
|
157
170
|
const app = new Hono();
|
|
158
171
|
app.post(
|
|
@@ -166,7 +179,26 @@ export default app;
|
|
|
166
179
|
|
|
167
180
|
#### Connect-style — `handleNodeCallback`
|
|
168
181
|
|
|
169
|
-
Returns `(req, res) => Promise<void>`. For frameworks that export Connect-style handlers (Express, Next.js Pages Router, etc.).
|
|
182
|
+
Returns `(req, res) => Promise<void>`. For frameworks that export Connect-style handlers (Vercel Node.js functions, Express, Next.js Pages Router, etc.). Requires a `QueueClient` instance:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// lib/queue.ts
|
|
186
|
+
import { QueueClient } from "@vercel/queue";
|
|
187
|
+
|
|
188
|
+
const queue = new QueueClient();
|
|
189
|
+
export const { handleNodeCallback } = queue;
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Vercel Node.js Functions (plain `api/` directory):**
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
// api/queue.ts
|
|
196
|
+
import { handleNodeCallback } from "./lib/queue";
|
|
197
|
+
|
|
198
|
+
export default handleNodeCallback(async (message, metadata) => {
|
|
199
|
+
await processMessage(message);
|
|
200
|
+
});
|
|
201
|
+
```
|
|
170
202
|
|
|
171
203
|
**Next.js Pages Router:**
|
|
172
204
|
|
|
@@ -240,6 +272,8 @@ When a handler throws, the message is not acknowledged and becomes available for
|
|
|
240
272
|
For finer control over retry timing, pass a `retry` option:
|
|
241
273
|
|
|
242
274
|
```typescript
|
|
275
|
+
import { handleCallback } from "@vercel/queue";
|
|
276
|
+
|
|
243
277
|
export const POST = handleCallback(
|
|
244
278
|
async (message, metadata) => {
|
|
245
279
|
await processMessage(message);
|
|
@@ -258,6 +292,8 @@ When `retry` returns `{ afterSeconds: N }`, the message is rescheduled for redel
|
|
|
258
292
|
**Exponential backoff** uses `metadata.deliveryCount` (starts at 1, increments each delivery):
|
|
259
293
|
|
|
260
294
|
```typescript
|
|
295
|
+
import { handleCallback } from "@vercel/queue";
|
|
296
|
+
|
|
261
297
|
export const POST = handleCallback(
|
|
262
298
|
async (message, metadata) => {
|
|
263
299
|
await processMessage(message);
|
|
@@ -275,6 +311,8 @@ export const POST = handleCallback(
|
|
|
275
311
|
**Conditional retry** — only retry transient errors:
|
|
276
312
|
|
|
277
313
|
```typescript
|
|
314
|
+
import { handleCallback } from "@vercel/queue";
|
|
315
|
+
|
|
278
316
|
export const POST = handleCallback(
|
|
279
317
|
async (message, metadata) => {
|
|
280
318
|
await processMessage(message);
|
|
@@ -292,6 +330,8 @@ export const POST = handleCallback(
|
|
|
292
330
|
**Acknowledging poison messages** — stop retrying messages that can never succeed:
|
|
293
331
|
|
|
294
332
|
```typescript
|
|
333
|
+
import { handleCallback } from "@vercel/queue";
|
|
334
|
+
|
|
295
335
|
export const POST = handleCallback(
|
|
296
336
|
async (message, metadata) => {
|
|
297
337
|
await processMessage(message);
|
|
@@ -310,40 +350,56 @@ The `retry` option is available on `handleCallback`, `handleNodeCallback`, and `
|
|
|
310
350
|
|
|
311
351
|
## Custom Client Configuration
|
|
312
352
|
|
|
313
|
-
|
|
353
|
+
For most use cases, the top-level `send` and `handleCallback` functions are all you need. For advanced configuration (custom transports, explicit tokens, deployment pinning), create a `QueueClient` instance directly.
|
|
354
|
+
|
|
355
|
+
### QueueClient (push mode)
|
|
356
|
+
|
|
357
|
+
For push-based workflows where Vercel delivers messages to your route handlers:
|
|
314
358
|
|
|
315
359
|
```typescript
|
|
316
360
|
import { QueueClient, BufferTransport } from "@vercel/queue";
|
|
317
361
|
|
|
318
362
|
const queue = new QueueClient({
|
|
319
|
-
region:
|
|
363
|
+
region: "iad1", // Optional — auto-detected from VERCEL_REGION, falls back to "iad1"
|
|
320
364
|
token: "my-token", // Auth token (default: OIDC auto-detection)
|
|
321
365
|
transport: new BufferTransport(), // Serialization (default: JsonTransport)
|
|
322
366
|
headers: { "X-Custom": "header" }, // Custom headers on all requests
|
|
323
367
|
deploymentId: null, // null = unpinned, omit = auto from env, or explicit string
|
|
324
368
|
});
|
|
325
369
|
|
|
326
|
-
|
|
327
|
-
|
|
370
|
+
export const { send, handleCallback, handleNodeCallback } = queue;
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### PollingQueueClient (poll mode)
|
|
328
374
|
|
|
329
|
-
|
|
330
|
-
|
|
375
|
+
For manual polling workflows where you call `receive` to poll for messages. Works anywhere — on Vercel, self-hosted, or any Node.js environment:
|
|
376
|
+
|
|
377
|
+
```typescript
|
|
378
|
+
import { PollingQueueClient, BufferTransport } from "@vercel/queue";
|
|
379
|
+
|
|
380
|
+
const queue = new PollingQueueClient({
|
|
381
|
+
region: "iad1", // Required — messages must be received from a fixed region
|
|
382
|
+
token: "my-token",
|
|
383
|
+
transport: new BufferTransport(),
|
|
384
|
+
headers: { "X-Custom": "header" },
|
|
385
|
+
deploymentId: null,
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
export const { send, receive } = queue;
|
|
331
389
|
```
|
|
332
390
|
|
|
333
|
-
|
|
391
|
+
Both clients send requests to `https://${region}.vercel-queue.com`. When `handleCallback` receives a message, it reads the `ce-vqsregion` header and routes follow-up API calls to the correct regional endpoint.
|
|
334
392
|
|
|
335
393
|
To customize the URL scheme, provide a `resolveBaseUrl` that returns a `URL`:
|
|
336
394
|
|
|
337
395
|
```typescript
|
|
338
396
|
// Custom domain
|
|
339
397
|
const queue = new QueueClient({
|
|
340
|
-
region: process.env.QUEUE_REGION!,
|
|
341
398
|
resolveBaseUrl: (region) => new URL(`https://${region}.my-proxy.example`),
|
|
342
399
|
});
|
|
343
400
|
|
|
344
401
|
// Custom domain with a base path (e.g. reverse proxy prefix)
|
|
345
402
|
const queue = new QueueClient({
|
|
346
|
-
region: process.env.QUEUE_REGION!,
|
|
347
403
|
resolveBaseUrl: (region) =>
|
|
348
404
|
new URL(`https://my-proxy.example/queues/${region}`),
|
|
349
405
|
// → requests go to https://my-proxy.example/queues/<region>/api/v3/…
|
|
@@ -372,7 +428,6 @@ import {
|
|
|
372
428
|
|
|
373
429
|
// JSON with custom serialization
|
|
374
430
|
const queue = new QueueClient({
|
|
375
|
-
region: process.env.QUEUE_REGION!,
|
|
376
431
|
transport: new JsonTransport({
|
|
377
432
|
replacer: (key, value) => (key === "password" ? undefined : value),
|
|
378
433
|
reviver: (key, value) => (key === "date" ? new Date(value) : value),
|
|
@@ -381,14 +436,12 @@ const queue = new QueueClient({
|
|
|
381
436
|
|
|
382
437
|
// Binary data
|
|
383
438
|
const binQueue = new QueueClient({
|
|
384
|
-
region: process.env.QUEUE_REGION!,
|
|
385
439
|
transport: new BufferTransport(),
|
|
386
440
|
});
|
|
387
441
|
await binQueue.send("binary-topic", myBuffer);
|
|
388
442
|
|
|
389
443
|
// Streaming for large payloads
|
|
390
444
|
const streamQueue = new QueueClient({
|
|
391
|
-
region: process.env.QUEUE_REGION!,
|
|
392
445
|
transport: new StreamTransport(),
|
|
393
446
|
});
|
|
394
447
|
await streamQueue.send("large-file", myReadableStream);
|
|
@@ -396,30 +449,25 @@ await streamQueue.send("large-file", myReadableStream);
|
|
|
396
449
|
|
|
397
450
|
## Manual Receive
|
|
398
451
|
|
|
399
|
-
Use `
|
|
452
|
+
Use `PollingQueueClient` to poll for and process messages directly. This is an advanced alternative to `handleCallback` that works in any Node.js environment, both on and off Vercel.
|
|
400
453
|
|
|
401
454
|
### Region considerations
|
|
402
455
|
|
|
403
|
-
Messages can only be received from the region they were sent to. When using `receive`, use a **fixed region** (e.g. `"iad1"`) for both sending and receiving — do not use `VERCEL_REGION
|
|
404
|
-
|
|
405
|
-
```bash
|
|
406
|
-
# .env.production — fixed region for manual receive workflows
|
|
407
|
-
QUEUE_REGION=iad1
|
|
408
|
-
|
|
409
|
-
# .env.development
|
|
410
|
-
QUEUE_REGION=iad1
|
|
411
|
-
```
|
|
456
|
+
Messages can only be received from the region they were sent to. When using `receive`, use a **fixed region** (e.g. `"iad1"`) for both sending and receiving — do not use `VERCEL_REGION`, because Vercel may route requests to different regions due to failover or load balancing, distributing your messages across regions unpredictably.
|
|
412
457
|
|
|
413
458
|
A single region is still highly available — Vercel deploys across 3+ availability zones within each region. If you need multi-region availability, you are responsible for designing your own HA strategy (e.g. sending to multiple regions and receiving from each).
|
|
414
459
|
|
|
415
|
-
For most use cases on Vercel, `handleCallback` is the recommended approach — the platform handles region routing automatically and the SDK routes follow-up calls to the correct region via the `ce-vqsregion` header.
|
|
460
|
+
For most use cases on Vercel, `handleCallback` via `QueueClient` is the recommended approach — the platform handles region routing automatically and the SDK routes follow-up calls to the correct region via the `ce-vqsregion` header.
|
|
416
461
|
|
|
417
462
|
### Usage
|
|
418
463
|
|
|
419
464
|
```typescript
|
|
420
|
-
import {
|
|
465
|
+
import { PollingQueueClient } from "@vercel/queue";
|
|
421
466
|
|
|
422
|
-
const { receive } = new
|
|
467
|
+
const { send, receive } = new PollingQueueClient({ region: "iad1" });
|
|
468
|
+
|
|
469
|
+
// Send a message
|
|
470
|
+
await send("my-topic", { message: "Hello world" });
|
|
423
471
|
|
|
424
472
|
// Process next available message
|
|
425
473
|
const result = await receive(
|
|
@@ -451,8 +499,8 @@ import {
|
|
|
451
499
|
ForbiddenError,
|
|
452
500
|
InternalServerError,
|
|
453
501
|
UnauthorizedError,
|
|
502
|
+
send,
|
|
454
503
|
} from "@vercel/queue";
|
|
455
|
-
import { send } from "@/lib/queue";
|
|
456
504
|
|
|
457
505
|
try {
|
|
458
506
|
await send("my-topic", payload);
|
|
@@ -492,12 +540,11 @@ All error types:
|
|
|
492
540
|
|
|
493
541
|
## Environment Variables
|
|
494
542
|
|
|
495
|
-
| Variable | Description
|
|
496
|
-
| ---------------------- |
|
|
497
|
-
| `
|
|
498
|
-
| `
|
|
499
|
-
| `
|
|
500
|
-
| `VERCEL_DEPLOYMENT_ID` | Deployment ID (auto-set by Vercel) | - |
|
|
543
|
+
| Variable | Description | Default |
|
|
544
|
+
| ---------------------- | ------------------------------------ | ------- |
|
|
545
|
+
| `VERCEL_REGION` | Current region (auto-set by Vercel) | - |
|
|
546
|
+
| `VERCEL_QUEUE_DEBUG` | Enable debug logging (`1` or `true`) | - |
|
|
547
|
+
| `VERCEL_DEPLOYMENT_ID` | Deployment ID (auto-set by Vercel) | - |
|
|
501
548
|
|
|
502
549
|
## Service Limits & Constraints
|
|
503
550
|
|
|
@@ -556,13 +603,55 @@ All error types:
|
|
|
556
603
|
|
|
557
604
|
## API Reference
|
|
558
605
|
|
|
606
|
+
### Top-level `send(topicName, payload, options?)`
|
|
607
|
+
|
|
608
|
+
The simplest way to send a message. Uses an auto-configured default client that detects the region from `VERCEL_REGION`, falling back to `"iad1"` with a console warning on first use.
|
|
609
|
+
|
|
610
|
+
```typescript
|
|
611
|
+
import { send } from "@vercel/queue";
|
|
612
|
+
|
|
613
|
+
const { messageId } = await send("my-topic", payload, {
|
|
614
|
+
idempotencyKey: "unique-key", // Dedup window: min(retention, 24h)
|
|
615
|
+
retentionSeconds: 3600, // Message TTL (default: 86400)
|
|
616
|
+
delaySeconds: 60, // Delay before visible (default: 0)
|
|
617
|
+
headers: { "X-Custom": "val" }, // Custom headers
|
|
618
|
+
region: "sfo1", // Optional — target a specific region
|
|
619
|
+
});
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
Returns `{ messageId: string | null }`. `messageId` is `null` when the server accepted the message for deferred processing (e.g. during a server-side outage).
|
|
623
|
+
|
|
624
|
+
### Top-level `handleCallback(handler, options?)`
|
|
625
|
+
|
|
626
|
+
The simplest way to handle incoming queue messages. Uses the same auto-configured default client as `send`.
|
|
627
|
+
|
|
628
|
+
```typescript
|
|
629
|
+
import { handleCallback } from "@vercel/queue";
|
|
630
|
+
|
|
631
|
+
export const POST = handleCallback(
|
|
632
|
+
async (message, metadata) => {
|
|
633
|
+
await processMessage(message);
|
|
634
|
+
},
|
|
635
|
+
{
|
|
636
|
+
visibilityTimeoutSeconds: 300, // Lock duration (default: 300)
|
|
637
|
+
retry: (error, metadata) => {
|
|
638
|
+
// Optional: return { afterSeconds: N } to reschedule, { acknowledge: true } to ack, or undefined to propagate
|
|
639
|
+
},
|
|
640
|
+
},
|
|
641
|
+
);
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
Returns `(request: Request) => Promise<Response>` — for frameworks that export Web API route handlers. Vercel only. The region for follow-up API calls is determined automatically from the `ce-vqsregion` header in the incoming event.
|
|
645
|
+
|
|
559
646
|
### `QueueClient`
|
|
560
647
|
|
|
648
|
+
Push-based client for workflows where Vercel delivers messages to your route handlers. Use this when you need custom configuration (transport, token, headers, deployment pinning). Region is auto-detected from `VERCEL_REGION` (set automatically on Vercel), falling back to `"iad1"` with a console warning.
|
|
649
|
+
|
|
561
650
|
```typescript
|
|
562
651
|
import { QueueClient } from "@vercel/queue";
|
|
563
652
|
|
|
564
653
|
const queue = new QueueClient({
|
|
565
|
-
region:
|
|
654
|
+
region: "iad1", // Optional — auto-detected from VERCEL_REGION, falls back to "iad1"
|
|
566
655
|
resolveBaseUrl: (r) => new URL(`https://${r}.vercel-queue.com`), // Default resolver
|
|
567
656
|
token: "my-token", // Auto-fetched via OIDC if omitted
|
|
568
657
|
headers: { "X-Custom": "value" },
|
|
@@ -571,24 +660,29 @@ const queue = new QueueClient({
|
|
|
571
660
|
});
|
|
572
661
|
|
|
573
662
|
// Methods (arrow functions — safe to destructure)
|
|
574
|
-
const { send,
|
|
663
|
+
const { send, handleCallback, handleNodeCallback } = queue;
|
|
575
664
|
```
|
|
576
665
|
|
|
577
|
-
### `
|
|
666
|
+
### `PollingQueueClient`
|
|
578
667
|
|
|
579
|
-
|
|
668
|
+
Poll-based client for manually receiving messages. Works in any Node.js environment, including self-hosted and non-Vercel platforms. Region is required to ensure send and receive target the same endpoint.
|
|
580
669
|
|
|
581
670
|
```typescript
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
671
|
+
import { PollingQueueClient } from "@vercel/queue";
|
|
672
|
+
|
|
673
|
+
const queue = new PollingQueueClient({
|
|
674
|
+
region: "iad1", // Required — use a fixed region for polling
|
|
675
|
+
// ... same options as QueueClient (except region is required)
|
|
587
676
|
});
|
|
677
|
+
|
|
678
|
+
// Methods (arrow functions — safe to destructure)
|
|
679
|
+
const { send, receive } = queue;
|
|
588
680
|
```
|
|
589
681
|
|
|
590
682
|
### `receive(topicName, consumerGroup, handler, options?)`
|
|
591
683
|
|
|
684
|
+
Available on `PollingQueueClient` only.
|
|
685
|
+
|
|
592
686
|
Returns a discriminated result: `{ ok: true }` on success, or `{ ok: false, reason }` when no message was processed. The handler is never called when the queue is empty.
|
|
593
687
|
|
|
594
688
|
For receive-by-id, operational errors are returned instead of thrown:
|
|
@@ -611,29 +705,18 @@ const result = await receive("my-topic", "my-group", handler, {
|
|
|
611
705
|
});
|
|
612
706
|
```
|
|
613
707
|
|
|
614
|
-
### `
|
|
708
|
+
### `handleNodeCallback(handler, options?)`
|
|
615
709
|
|
|
616
|
-
|
|
710
|
+
Available on `QueueClient` only. Vercel only.
|
|
617
711
|
|
|
618
|
-
|
|
619
|
-
export const POST = handleCallback(
|
|
620
|
-
async (message, metadata) => {
|
|
621
|
-
await processMessage(message);
|
|
622
|
-
},
|
|
623
|
-
{
|
|
624
|
-
visibilityTimeoutSeconds: 300, // Lock duration (default: 300)
|
|
625
|
-
retry: (error, metadata) => {
|
|
626
|
-
// Optional: return { afterSeconds: N } to reschedule, { acknowledge: true } to ack, or undefined to propagate
|
|
627
|
-
},
|
|
628
|
-
},
|
|
629
|
-
);
|
|
630
|
-
```
|
|
712
|
+
Returns `(req, res) => Promise<void>` — for frameworks that export Connect-style handlers.
|
|
631
713
|
|
|
632
|
-
|
|
714
|
+
```typescript
|
|
715
|
+
import { QueueClient } from "@vercel/queue";
|
|
633
716
|
|
|
634
|
-
|
|
717
|
+
const queue = new QueueClient();
|
|
718
|
+
const { handleNodeCallback } = queue;
|
|
635
719
|
|
|
636
|
-
```typescript
|
|
637
720
|
// pages/api/queue/my-topic.ts
|
|
638
721
|
export default handleNodeCallback(
|
|
639
722
|
async (message, metadata) => {
|