@vercel/queue 0.0.1 → 0.1.0
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 +91 -61
- package/dist/index.d.mts +148 -42
- package/dist/index.d.ts +148 -42
- package/dist/index.js +130 -81
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +129 -81
- 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,29 +19,17 @@ npm install @vercel/queue
|
|
|
19
19
|
|
|
20
20
|
## Quick Start
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
```bash
|
|
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:
|
|
22
|
+
**1. Create a shared queue client:**
|
|
35
23
|
|
|
36
24
|
```typescript
|
|
37
25
|
// lib/queue.ts
|
|
38
26
|
import { QueueClient } from "@vercel/queue";
|
|
39
27
|
|
|
40
|
-
const queue = new QueueClient(
|
|
41
|
-
export const { send,
|
|
28
|
+
const queue = new QueueClient();
|
|
29
|
+
export const { send, handleCallback } = queue;
|
|
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
35
|
import { send } from "@/lib/queue";
|
|
@@ -49,7 +37,7 @@ import { send } from "@/lib/queue";
|
|
|
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
|
|
@@ -60,7 +48,7 @@ export const POST = handleCallback(async (message, metadata) => {
|
|
|
60
48
|
});
|
|
61
49
|
```
|
|
62
50
|
|
|
63
|
-
Configure
|
|
51
|
+
**4. Configure `vercel.json`:**
|
|
64
52
|
|
|
65
53
|
```json
|
|
66
54
|
{
|
|
@@ -72,9 +60,7 @@ Configure your `vercel.json`:
|
|
|
72
60
|
}
|
|
73
61
|
```
|
|
74
62
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
For local development, link your Vercel project:
|
|
63
|
+
**5. Link your project for local development:**
|
|
78
64
|
|
|
79
65
|
```bash
|
|
80
66
|
npm i -g vercel
|
|
@@ -82,6 +68,8 @@ vc link
|
|
|
82
68
|
vc env pull
|
|
83
69
|
```
|
|
84
70
|
|
|
71
|
+
That's it. `new QueueClient()` auto-detects the region from `VERCEL_REGION` (set automatically on Vercel). If the region can't be detected (e.g. local dev), it falls back to `iad1`.
|
|
72
|
+
|
|
85
73
|
## Local Development
|
|
86
74
|
|
|
87
75
|
**Queues just work locally.** When you `send()` messages in development mode, the library sends them to the real Vercel Queue Service, reads your `vercel.json` configuration, discovers your queue handlers, and triggers them automatically via local HTTP requests. This means your local dev environment behaves identically to production — no surprising behavior differences.
|
|
@@ -93,7 +81,7 @@ vc env pull
|
|
|
93
81
|
```typescript
|
|
94
82
|
import { QueueClient } from "@vercel/queue";
|
|
95
83
|
|
|
96
|
-
const { send } = new QueueClient(
|
|
84
|
+
const { send } = new QueueClient();
|
|
97
85
|
|
|
98
86
|
// Simple send
|
|
99
87
|
await send("my-topic", { message: "Hello world" });
|
|
@@ -310,37 +298,62 @@ The `retry` option is available on `handleCallback`, `handleNodeCallback`, and `
|
|
|
310
298
|
|
|
311
299
|
## Custom Client Configuration
|
|
312
300
|
|
|
313
|
-
|
|
301
|
+
### QueueClient (push mode)
|
|
302
|
+
|
|
303
|
+
For push-based workflows where Vercel delivers messages to your route handlers:
|
|
314
304
|
|
|
315
305
|
```typescript
|
|
316
306
|
import { QueueClient, BufferTransport } from "@vercel/queue";
|
|
317
307
|
|
|
318
308
|
const queue = new QueueClient({
|
|
319
|
-
region:
|
|
309
|
+
region: "iad1", // Optional — auto-detected from VERCEL_REGION, falls back to "iad1"
|
|
320
310
|
token: "my-token", // Auth token (default: OIDC auto-detection)
|
|
321
311
|
transport: new BufferTransport(), // Serialization (default: JsonTransport)
|
|
322
312
|
headers: { "X-Custom": "header" }, // Custom headers on all requests
|
|
323
313
|
deploymentId: null, // null = unpinned, omit = auto from env, or explicit string
|
|
324
314
|
});
|
|
325
315
|
|
|
326
|
-
|
|
327
|
-
|
|
316
|
+
export const { send, handleCallback, handleNodeCallback } = queue;
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### PollingQueueClient (poll mode)
|
|
328
320
|
|
|
329
|
-
|
|
330
|
-
|
|
321
|
+
For manual polling workflows where you call `receive` to poll for messages. Works anywhere — on Vercel, self-hosted, or any Node.js environment:
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
import { PollingQueueClient, BufferTransport } from "@vercel/queue";
|
|
325
|
+
|
|
326
|
+
const queue = new PollingQueueClient({
|
|
327
|
+
region: "iad1", // Required — messages must be received from a fixed region
|
|
328
|
+
token: "my-token",
|
|
329
|
+
transport: new BufferTransport(),
|
|
330
|
+
headers: { "X-Custom": "header" },
|
|
331
|
+
deploymentId: null,
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
export const { send, receive } = queue;
|
|
331
335
|
```
|
|
332
336
|
|
|
333
|
-
|
|
337
|
+
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
338
|
|
|
335
|
-
To customize the URL scheme, provide a `resolveBaseUrl`:
|
|
339
|
+
To customize the URL scheme, provide a `resolveBaseUrl` that returns a `URL`:
|
|
336
340
|
|
|
337
341
|
```typescript
|
|
342
|
+
// Custom domain
|
|
338
343
|
const queue = new QueueClient({
|
|
339
|
-
|
|
340
|
-
|
|
344
|
+
resolveBaseUrl: (region) => new URL(`https://${region}.my-proxy.example`),
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// Custom domain with a base path (e.g. reverse proxy prefix)
|
|
348
|
+
const queue = new QueueClient({
|
|
349
|
+
resolveBaseUrl: (region) =>
|
|
350
|
+
new URL(`https://my-proxy.example/queues/${region}`),
|
|
351
|
+
// → requests go to https://my-proxy.example/queues/<region>/api/v3/…
|
|
341
352
|
});
|
|
342
353
|
```
|
|
343
354
|
|
|
355
|
+
The SDK always appends its own API path (`/api/v3/…`) to the returned URL.
|
|
356
|
+
|
|
344
357
|
## Transports
|
|
345
358
|
|
|
346
359
|
The transport controls how message payloads are serialized and deserialized.
|
|
@@ -361,7 +374,6 @@ import {
|
|
|
361
374
|
|
|
362
375
|
// JSON with custom serialization
|
|
363
376
|
const queue = new QueueClient({
|
|
364
|
-
region: process.env.QUEUE_REGION!,
|
|
365
377
|
transport: new JsonTransport({
|
|
366
378
|
replacer: (key, value) => (key === "password" ? undefined : value),
|
|
367
379
|
reviver: (key, value) => (key === "date" ? new Date(value) : value),
|
|
@@ -370,14 +382,12 @@ const queue = new QueueClient({
|
|
|
370
382
|
|
|
371
383
|
// Binary data
|
|
372
384
|
const binQueue = new QueueClient({
|
|
373
|
-
region: process.env.QUEUE_REGION!,
|
|
374
385
|
transport: new BufferTransport(),
|
|
375
386
|
});
|
|
376
387
|
await binQueue.send("binary-topic", myBuffer);
|
|
377
388
|
|
|
378
389
|
// Streaming for large payloads
|
|
379
390
|
const streamQueue = new QueueClient({
|
|
380
|
-
region: process.env.QUEUE_REGION!,
|
|
381
391
|
transport: new StreamTransport(),
|
|
382
392
|
});
|
|
383
393
|
await streamQueue.send("large-file", myReadableStream);
|
|
@@ -385,30 +395,25 @@ await streamQueue.send("large-file", myReadableStream);
|
|
|
385
395
|
|
|
386
396
|
## Manual Receive
|
|
387
397
|
|
|
388
|
-
Use `
|
|
398
|
+
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.
|
|
389
399
|
|
|
390
400
|
### Region considerations
|
|
391
401
|
|
|
392
|
-
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
|
|
393
|
-
|
|
394
|
-
```bash
|
|
395
|
-
# .env.production — fixed region for manual receive workflows
|
|
396
|
-
QUEUE_REGION=iad1
|
|
397
|
-
|
|
398
|
-
# .env.development
|
|
399
|
-
QUEUE_REGION=iad1
|
|
400
|
-
```
|
|
402
|
+
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.
|
|
401
403
|
|
|
402
404
|
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).
|
|
403
405
|
|
|
404
|
-
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.
|
|
406
|
+
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.
|
|
405
407
|
|
|
406
408
|
### Usage
|
|
407
409
|
|
|
408
410
|
```typescript
|
|
409
|
-
import {
|
|
411
|
+
import { PollingQueueClient } from "@vercel/queue";
|
|
410
412
|
|
|
411
|
-
const { receive } = new
|
|
413
|
+
const { send, receive } = new PollingQueueClient({ region: "iad1" });
|
|
414
|
+
|
|
415
|
+
// Send a message
|
|
416
|
+
await send("my-topic", { message: "Hello world" });
|
|
412
417
|
|
|
413
418
|
// Process next available message
|
|
414
419
|
const result = await receive(
|
|
@@ -481,12 +486,11 @@ All error types:
|
|
|
481
486
|
|
|
482
487
|
## Environment Variables
|
|
483
488
|
|
|
484
|
-
| Variable | Description
|
|
485
|
-
| ---------------------- |
|
|
486
|
-
| `
|
|
487
|
-
| `
|
|
488
|
-
| `
|
|
489
|
-
| `VERCEL_DEPLOYMENT_ID` | Deployment ID (auto-set by Vercel) | - |
|
|
489
|
+
| Variable | Description | Default |
|
|
490
|
+
| ---------------------- | ------------------------------------ | ------- |
|
|
491
|
+
| `VERCEL_REGION` | Current region (auto-set by Vercel) | - |
|
|
492
|
+
| `VERCEL_QUEUE_DEBUG` | Enable debug logging (`1` or `true`) | - |
|
|
493
|
+
| `VERCEL_DEPLOYMENT_ID` | Deployment ID (auto-set by Vercel) | - |
|
|
490
494
|
|
|
491
495
|
## Service Limits & Constraints
|
|
492
496
|
|
|
@@ -547,12 +551,14 @@ All error types:
|
|
|
547
551
|
|
|
548
552
|
### `QueueClient`
|
|
549
553
|
|
|
554
|
+
Push-based client for workflows where Vercel delivers messages to your route handlers. Region is auto-detected from `VERCEL_REGION` (set automatically on Vercel), falling back to `"iad1"` with a console warning.
|
|
555
|
+
|
|
550
556
|
```typescript
|
|
551
557
|
import { QueueClient } from "@vercel/queue";
|
|
552
558
|
|
|
553
559
|
const queue = new QueueClient({
|
|
554
|
-
region:
|
|
555
|
-
resolveBaseUrl: (r) => `https://${r}.vercel-queue.com
|
|
560
|
+
region: "iad1", // Optional — auto-detected from VERCEL_REGION, falls back to "iad1"
|
|
561
|
+
resolveBaseUrl: (r) => new URL(`https://${r}.vercel-queue.com`), // Default resolver
|
|
556
562
|
token: "my-token", // Auto-fetched via OIDC if omitted
|
|
557
563
|
headers: { "X-Custom": "value" },
|
|
558
564
|
transport: new JsonTransport(), // Default: JsonTransport
|
|
@@ -560,11 +566,29 @@ const queue = new QueueClient({
|
|
|
560
566
|
});
|
|
561
567
|
|
|
562
568
|
// Methods (arrow functions — safe to destructure)
|
|
563
|
-
const { send,
|
|
569
|
+
const { send, handleCallback, handleNodeCallback } = queue;
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### `PollingQueueClient`
|
|
573
|
+
|
|
574
|
+
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.
|
|
575
|
+
|
|
576
|
+
```typescript
|
|
577
|
+
import { PollingQueueClient } from "@vercel/queue";
|
|
578
|
+
|
|
579
|
+
const queue = new PollingQueueClient({
|
|
580
|
+
region: "iad1", // Required — use a fixed region for polling
|
|
581
|
+
// ... same options as QueueClient (except region is required)
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
// Methods (arrow functions — safe to destructure)
|
|
585
|
+
const { send, receive } = queue;
|
|
564
586
|
```
|
|
565
587
|
|
|
566
588
|
### `send(topicName, payload, options?)`
|
|
567
589
|
|
|
590
|
+
Available on both `QueueClient` and `PollingQueueClient`.
|
|
591
|
+
|
|
568
592
|
Returns `{ messageId: string | null }`. `messageId` is `null` when the server accepted the message for deferred processing (e.g. during a server-side outage).
|
|
569
593
|
|
|
570
594
|
```typescript
|
|
@@ -578,6 +602,8 @@ const { messageId } = await send("my-topic", payload, {
|
|
|
578
602
|
|
|
579
603
|
### `receive(topicName, consumerGroup, handler, options?)`
|
|
580
604
|
|
|
605
|
+
Available on `PollingQueueClient` only.
|
|
606
|
+
|
|
581
607
|
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.
|
|
582
608
|
|
|
583
609
|
For receive-by-id, operational errors are returned instead of thrown:
|
|
@@ -602,7 +628,9 @@ const result = await receive("my-topic", "my-group", handler, {
|
|
|
602
628
|
|
|
603
629
|
### `handleCallback(handler, options?)`
|
|
604
630
|
|
|
605
|
-
|
|
631
|
+
Available on `QueueClient` only. Vercel only.
|
|
632
|
+
|
|
633
|
+
Returns `(request: Request) => Promise<Response>` — for frameworks that export Web API route handlers.
|
|
606
634
|
|
|
607
635
|
```typescript
|
|
608
636
|
export const POST = handleCallback(
|
|
@@ -620,7 +648,9 @@ export const POST = handleCallback(
|
|
|
620
648
|
|
|
621
649
|
### `handleNodeCallback(handler, options?)`
|
|
622
650
|
|
|
623
|
-
|
|
651
|
+
Available on `QueueClient` only. Vercel only.
|
|
652
|
+
|
|
653
|
+
Returns `(req, res) => Promise<void>` — for frameworks that export Connect-style handlers.
|
|
624
654
|
|
|
625
655
|
```typescript
|
|
626
656
|
// pages/api/queue/my-topic.ts
|
package/dist/index.d.mts
CHANGED
|
@@ -37,12 +37,11 @@ interface Transport<T = unknown> {
|
|
|
37
37
|
* @example
|
|
38
38
|
* ```typescript
|
|
39
39
|
* // Default (JsonTransport is used automatically)
|
|
40
|
-
* const queue = new QueueClient(
|
|
40
|
+
* const queue = new QueueClient();
|
|
41
41
|
* await queue.send("topic", { data: "example" });
|
|
42
42
|
*
|
|
43
43
|
* // With custom serialization
|
|
44
44
|
* const queue = new QueueClient({
|
|
45
|
-
* region: process.env.QUEUE_REGION!,
|
|
46
45
|
* transport: new JsonTransport({
|
|
47
46
|
* replacer: (key, value) => key === "password" ? undefined : value,
|
|
48
47
|
* reviver: (key, value) => key === "date" ? new Date(value) : value,
|
|
@@ -75,7 +74,7 @@ declare class JsonTransport<T = unknown> implements Transport<T> {
|
|
|
75
74
|
*
|
|
76
75
|
* @example
|
|
77
76
|
* ```typescript
|
|
78
|
-
* const queue = new QueueClient({
|
|
77
|
+
* const queue = new QueueClient({ transport: new BufferTransport() });
|
|
79
78
|
* await queue.send("binary-topic", myBuffer);
|
|
80
79
|
* ```
|
|
81
80
|
*/
|
|
@@ -95,13 +94,13 @@ declare class BufferTransport implements Transport<Buffer> {
|
|
|
95
94
|
*
|
|
96
95
|
* @example
|
|
97
96
|
* ```typescript
|
|
98
|
-
* const queue = new QueueClient({ region: "iad1", transport: new StreamTransport() });
|
|
99
|
-
*
|
|
100
97
|
* // Sending a stream
|
|
98
|
+
* const queue = new QueueClient({ transport: new StreamTransport() });
|
|
101
99
|
* await queue.send("large-file", myReadableStream);
|
|
102
100
|
*
|
|
103
101
|
* // Receiving - cleanup handled automatically
|
|
104
|
-
*
|
|
102
|
+
* const poller = new PollingQueueClient({ region: "iad1", transport: new StreamTransport() });
|
|
103
|
+
* await poller.receive("large-file", "processor", async (stream, meta) => {
|
|
105
104
|
* const reader = stream.getReader();
|
|
106
105
|
* // Process chunks...
|
|
107
106
|
* });
|
|
@@ -130,11 +129,24 @@ declare class StreamTransport implements Transport<ReadableStream<Uint8Array>> {
|
|
|
130
129
|
*/
|
|
131
130
|
type VercelRegion = "arn1" | "bom1" | "cdg1" | "cle1" | "cpt1" | "dub1" | "dxb1" | "fra1" | "gru1" | "hkg1" | "hnd1" | "iad1" | "icn1" | "kix1" | "lhr1" | "pdx1" | "sfo1" | "sin1" | "syd1" | "yul1" | (string & {});
|
|
132
131
|
/**
|
|
133
|
-
* Resolves a region code to a base URL for the Vercel Queue Service API.
|
|
132
|
+
* Resolves a region code to a base {@link URL} for the Vercel Queue Service API.
|
|
133
|
+
*
|
|
134
|
+
* The SDK appends its own API path (`/api/v3/…`) to the returned URL.
|
|
135
|
+
* To add a prefix (e.g. when routing through a reverse proxy), include it
|
|
136
|
+
* in the pathname of the returned URL:
|
|
134
137
|
*
|
|
135
|
-
*
|
|
138
|
+
* ```ts
|
|
139
|
+
* // Default — domain only, no prefix:
|
|
140
|
+
* (region) => new URL(`https://${region}.vercel-queue.com`)
|
|
141
|
+
*
|
|
142
|
+
* // Custom domain with a base path:
|
|
143
|
+
* (region) => new URL(`https://my-proxy.example/custom-prefix`)
|
|
144
|
+
* // → requests go to https://my-proxy.example/custom-prefix/api/v3/…
|
|
145
|
+
* ```
|
|
146
|
+
*
|
|
147
|
+
* Default: `` (region) => new URL(`https://${region}.vercel-queue.com`) ``
|
|
136
148
|
*/
|
|
137
|
-
type BaseUrlResolver = (region: string) =>
|
|
149
|
+
type BaseUrlResolver = (region: string) => URL;
|
|
138
150
|
interface QueueClientOptions {
|
|
139
151
|
/**
|
|
140
152
|
* Vercel region code for API routing.
|
|
@@ -142,18 +154,28 @@ interface QueueClientOptions {
|
|
|
142
154
|
* Requests are sent to the regional endpoint resolved by
|
|
143
155
|
* {@link BaseUrlResolver} (default: `https://${region}.vercel-queue.com`).
|
|
144
156
|
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
157
|
+
* When omitted, the region is auto-detected from the `VERCEL_REGION`
|
|
158
|
+
* environment variable (set automatically on Vercel). If not available,
|
|
159
|
+
* defaults to `"iad1"` with a console warning.
|
|
147
160
|
*
|
|
148
161
|
* @example
|
|
149
162
|
* ```ts
|
|
150
|
-
* new QueueClient(
|
|
163
|
+
* new QueueClient() // auto-detect, falls back to "iad1"
|
|
164
|
+
* new QueueClient({ region: "iad1" }) // explicit
|
|
151
165
|
* ```
|
|
152
166
|
*/
|
|
153
|
-
region
|
|
167
|
+
region?: VercelRegion;
|
|
154
168
|
/**
|
|
155
|
-
* Custom resolver that maps a region code to a base URL.
|
|
156
|
-
*
|
|
169
|
+
* Custom resolver that maps a region code to a base {@link URL}.
|
|
170
|
+
*
|
|
171
|
+
* The SDK always appends its own API path (`/api/v3/…`) to the returned URL.
|
|
172
|
+
* Include a pathname to add a prefix (e.g. for reverse-proxy routing):
|
|
173
|
+
*
|
|
174
|
+
* ```ts
|
|
175
|
+
* resolveBaseUrl: (region) => new URL(`https://my-proxy.example/prefix`)
|
|
176
|
+
* ```
|
|
177
|
+
*
|
|
178
|
+
* @default (region) => new URL(`https://${region}.vercel-queue.com`)
|
|
157
179
|
*/
|
|
158
180
|
resolveBaseUrl?: BaseUrlResolver;
|
|
159
181
|
/**
|
|
@@ -184,6 +206,28 @@ interface QueueClientOptions {
|
|
|
184
206
|
*/
|
|
185
207
|
transport?: Transport;
|
|
186
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Options for creating a {@link PollingQueueClient}.
|
|
211
|
+
*
|
|
212
|
+
* Identical to {@link QueueClientOptions} except `region` is **required**
|
|
213
|
+
* because messages can only be received from the region they were sent to.
|
|
214
|
+
* Using a fixed region (e.g. `"iad1"`) ensures that `send` and `receive`
|
|
215
|
+
* target the same endpoint.
|
|
216
|
+
*/
|
|
217
|
+
interface PollingQueueClientOptions extends QueueClientOptions {
|
|
218
|
+
/**
|
|
219
|
+
* Vercel region code for API routing — **required** for polling.
|
|
220
|
+
*
|
|
221
|
+
* Messages can only be received from the region they were sent to.
|
|
222
|
+
* Use a fixed region (e.g. `"iad1"`) for both sending and receiving.
|
|
223
|
+
*
|
|
224
|
+
* @example
|
|
225
|
+
* ```ts
|
|
226
|
+
* new PollingQueueClient({ region: "iad1" })
|
|
227
|
+
* ```
|
|
228
|
+
*/
|
|
229
|
+
region: VercelRegion;
|
|
230
|
+
}
|
|
187
231
|
/**
|
|
188
232
|
* Options for sending messages.
|
|
189
233
|
*/
|
|
@@ -475,14 +519,37 @@ declare class ConsumerRegistryNotConfiguredError extends Error {
|
|
|
475
519
|
constructor(message?: string);
|
|
476
520
|
}
|
|
477
521
|
|
|
522
|
+
/**
|
|
523
|
+
* Queue client for push-based (callback) workflows.
|
|
524
|
+
*
|
|
525
|
+
* Use this client when Vercel delivers messages to your route handlers.
|
|
526
|
+
* Provides {@link send}, {@link handleCallback}, and {@link handleNodeCallback}.
|
|
527
|
+
*
|
|
528
|
+
* Region is resolved automatically:
|
|
529
|
+
* 1. Explicit `region` option (highest priority)
|
|
530
|
+
* 2. `VERCEL_REGION` environment variable (set automatically on Vercel)
|
|
531
|
+
* 3. Falls back to `"iad1"` with a console warning
|
|
532
|
+
*
|
|
533
|
+
* The constructor never throws — `new QueueClient()` always works.
|
|
534
|
+
*
|
|
535
|
+
* For manual polling workflows, use {@link PollingQueueClient} instead.
|
|
536
|
+
*
|
|
537
|
+
* @example
|
|
538
|
+
* ```typescript
|
|
539
|
+
* import { QueueClient } from "@vercel/queue";
|
|
540
|
+
*
|
|
541
|
+
* const queue = new QueueClient();
|
|
542
|
+
* export const { send, handleCallback, handleNodeCallback } = queue;
|
|
543
|
+
* ```
|
|
544
|
+
*/
|
|
478
545
|
declare class QueueClient {
|
|
479
|
-
constructor(options
|
|
546
|
+
constructor(options?: QueueClientOptions);
|
|
480
547
|
/**
|
|
481
548
|
* Send a message to a topic.
|
|
482
549
|
*
|
|
483
550
|
* This is an arrow function property so it can be destructured:
|
|
484
551
|
* ```typescript
|
|
485
|
-
* const { send } = new QueueClient(
|
|
552
|
+
* const { send } = new QueueClient();
|
|
486
553
|
* await send("my-topic", payload);
|
|
487
554
|
* ```
|
|
488
555
|
*
|
|
@@ -493,28 +560,6 @@ declare class QueueClient {
|
|
|
493
560
|
* the message for deferred processing (no ID available yet)
|
|
494
561
|
*/
|
|
495
562
|
send: <T = unknown>(topicName: string, payload: T, options?: SendOptions) => Promise<SendResult>;
|
|
496
|
-
/**
|
|
497
|
-
* Receive and process messages from a topic.
|
|
498
|
-
*
|
|
499
|
-
* Each message is automatically locked, kept alive via periodic visibility
|
|
500
|
-
* extensions during processing, and acknowledged upon successful handler completion.
|
|
501
|
-
* The handler is not called when the queue is empty — check `result.ok` instead.
|
|
502
|
-
*
|
|
503
|
-
* This is an arrow function property so it can be destructured:
|
|
504
|
-
* ```typescript
|
|
505
|
-
* const { receive } = new QueueClient({ region: process.env.QUEUE_REGION! });
|
|
506
|
-
* const result = await receive("my-topic", "my-group", handler);
|
|
507
|
-
* if (!result.ok) console.log(result.reason);
|
|
508
|
-
* ```
|
|
509
|
-
*
|
|
510
|
-
* @param topicName - Name of the topic (pattern: `[A-Za-z0-9_-]+`)
|
|
511
|
-
* @param consumerGroup - Name of the consumer group (pattern: `[A-Za-z0-9_-]+`)
|
|
512
|
-
* @param handler - Function to process each message payload and metadata.
|
|
513
|
-
* Not called when the queue is empty.
|
|
514
|
-
* @param options - Optional receive options (visibilityTimeoutSeconds, limit, or messageId)
|
|
515
|
-
* @returns Discriminated result: `{ ok: true }` on success, `{ ok: false, reason }` otherwise
|
|
516
|
-
*/
|
|
517
|
-
receive: <T = unknown>(topicName: string, consumerGroup: string, handler: MessageHandler<T>, options?: ReceiveOptions) => Promise<ReceiveResult>;
|
|
518
563
|
/**
|
|
519
564
|
* Create a Web API route handler for processing queue callback messages.
|
|
520
565
|
*
|
|
@@ -523,7 +568,7 @@ declare class QueueClient {
|
|
|
523
568
|
*
|
|
524
569
|
* This is an arrow function property so it can be destructured:
|
|
525
570
|
* ```typescript
|
|
526
|
-
* const { handleCallback } = new QueueClient(
|
|
571
|
+
* const { handleCallback } = new QueueClient();
|
|
527
572
|
* export const POST = handleCallback(handler);
|
|
528
573
|
* ```
|
|
529
574
|
*
|
|
@@ -547,7 +592,7 @@ declare class QueueClient {
|
|
|
547
592
|
*
|
|
548
593
|
* This is an arrow function property so it can be destructured:
|
|
549
594
|
* ```typescript
|
|
550
|
-
* const { handleNodeCallback } = new QueueClient(
|
|
595
|
+
* const { handleNodeCallback } = new QueueClient();
|
|
551
596
|
* app.post("/api/queue", handleNodeCallback(handler));
|
|
552
597
|
* ```
|
|
553
598
|
*
|
|
@@ -573,6 +618,67 @@ declare class QueueClient {
|
|
|
573
618
|
end(): void;
|
|
574
619
|
}) => Promise<void>);
|
|
575
620
|
}
|
|
621
|
+
/**
|
|
622
|
+
* Queue client for poll-based (manual receive) workflows.
|
|
623
|
+
*
|
|
624
|
+
* Use this client when you manually poll for messages with {@link receive}.
|
|
625
|
+
* Also provides {@link send} for publishing messages.
|
|
626
|
+
*
|
|
627
|
+
* Region is **required** because messages can only be received from the
|
|
628
|
+
* region they were sent to. Use a fixed region (e.g. `"iad1"`) for both
|
|
629
|
+
* sending and receiving.
|
|
630
|
+
*
|
|
631
|
+
* For push-based (callback) workflows on Vercel, use {@link QueueClient} instead.
|
|
632
|
+
*
|
|
633
|
+
* @example
|
|
634
|
+
* ```typescript
|
|
635
|
+
* import { PollingQueueClient } from "@vercel/queue";
|
|
636
|
+
*
|
|
637
|
+
* const queue = new PollingQueueClient({ region: "iad1" });
|
|
638
|
+
* export const { send, receive } = queue;
|
|
639
|
+
* ```
|
|
640
|
+
*/
|
|
641
|
+
declare class PollingQueueClient {
|
|
642
|
+
constructor(options: PollingQueueClientOptions);
|
|
643
|
+
/**
|
|
644
|
+
* Send a message to a topic.
|
|
645
|
+
*
|
|
646
|
+
* This is an arrow function property so it can be destructured:
|
|
647
|
+
* ```typescript
|
|
648
|
+
* const { send } = new PollingQueueClient({ region: "iad1" });
|
|
649
|
+
* await send("my-topic", payload);
|
|
650
|
+
* ```
|
|
651
|
+
*
|
|
652
|
+
* @param topicName - Name of the topic (pattern: `[A-Za-z0-9_-]+`)
|
|
653
|
+
* @param payload - The data to send (serialized via the configured transport)
|
|
654
|
+
* @param options - Optional send options (idempotencyKey, retentionSeconds, delaySeconds, headers)
|
|
655
|
+
* @returns `{ messageId }` — `messageId` is `null` when the server accepted
|
|
656
|
+
* the message for deferred processing (no ID available yet)
|
|
657
|
+
*/
|
|
658
|
+
send: <T = unknown>(topicName: string, payload: T, options?: SendOptions) => Promise<SendResult>;
|
|
659
|
+
/**
|
|
660
|
+
* Receive and process messages from a topic.
|
|
661
|
+
*
|
|
662
|
+
* Each message is automatically locked, kept alive via periodic visibility
|
|
663
|
+
* extensions during processing, and acknowledged upon successful handler completion.
|
|
664
|
+
* The handler is not called when the queue is empty — check `result.ok` instead.
|
|
665
|
+
*
|
|
666
|
+
* This is an arrow function property so it can be destructured:
|
|
667
|
+
* ```typescript
|
|
668
|
+
* const { receive } = new PollingQueueClient({ region: "iad1" });
|
|
669
|
+
* const result = await receive("my-topic", "my-group", handler);
|
|
670
|
+
* if (!result.ok) console.log(result.reason);
|
|
671
|
+
* ```
|
|
672
|
+
*
|
|
673
|
+
* @param topicName - Name of the topic (pattern: `[A-Za-z0-9_-]+`)
|
|
674
|
+
* @param consumerGroup - Name of the consumer group (pattern: `[A-Za-z0-9_-]+`)
|
|
675
|
+
* @param handler - Function to process each message payload and metadata.
|
|
676
|
+
* Not called when the queue is empty.
|
|
677
|
+
* @param options - Optional receive options (visibilityTimeoutSeconds, limit, or messageId)
|
|
678
|
+
* @returns Discriminated result: `{ ok: true }` on success, `{ ok: false, reason }` otherwise
|
|
679
|
+
*/
|
|
680
|
+
receive: <T = unknown>(topicName: string, consumerGroup: string, handler: MessageHandler<T>, options?: ReceiveOptions) => Promise<ReceiveResult>;
|
|
681
|
+
}
|
|
576
682
|
|
|
577
683
|
/**
|
|
578
684
|
* Core queue callback utilities for handling incoming webhook payloads
|
|
@@ -647,4 +753,4 @@ declare function parseRawCallback(body: unknown, headers: Record<string, string
|
|
|
647
753
|
*/
|
|
648
754
|
declare function parseCallback(request: Request): Promise<ParsedCallbackRequest>;
|
|
649
755
|
|
|
650
|
-
export { BadRequestError, type BaseUrlResolver, BufferTransport, CLOUD_EVENT_TYPE_V1BETA, CLOUD_EVENT_TYPE_V2BETA, ConsumerDiscoveryError, ConsumerRegistryNotConfiguredError, DuplicateMessageError, ForbiddenError, InternalServerError, InvalidLimitError, JsonTransport, type Message, MessageAlreadyProcessedError, MessageCorruptedError, type MessageHandler, MessageLockedError, type MessageMetadata, MessageNotAvailableError, MessageNotFoundError, type ParsedCallbackRequest, type ParsedCallbackV1, type ParsedCallbackV2, QueueClient, type QueueClientOptions, QueueEmptyError, type ReceiveBatchOptions, type ReceiveByIdOptions, type ReceiveOptions, type ReceiveResult, type RetryDirective, type RetryHandler, type SendOptions, type SendResult, StreamTransport, type Transport, UnauthorizedError, type VercelRegion, parseCallback, parseRawCallback };
|
|
756
|
+
export { BadRequestError, type BaseUrlResolver, BufferTransport, CLOUD_EVENT_TYPE_V1BETA, CLOUD_EVENT_TYPE_V2BETA, ConsumerDiscoveryError, ConsumerRegistryNotConfiguredError, DuplicateMessageError, ForbiddenError, InternalServerError, InvalidLimitError, JsonTransport, type Message, MessageAlreadyProcessedError, MessageCorruptedError, type MessageHandler, MessageLockedError, type MessageMetadata, MessageNotAvailableError, MessageNotFoundError, type ParsedCallbackRequest, type ParsedCallbackV1, type ParsedCallbackV2, PollingQueueClient, type PollingQueueClientOptions, QueueClient, type QueueClientOptions, QueueEmptyError, type ReceiveBatchOptions, type ReceiveByIdOptions, type ReceiveOptions, type ReceiveResult, type RetryDirective, type RetryHandler, type SendOptions, type SendResult, StreamTransport, type Transport, UnauthorizedError, type VercelRegion, parseCallback, parseRawCallback };
|