@vercel/queue 0.0.0-alpha.34 → 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 +284 -34
- package/dist/index.d.mts +208 -54
- package/dist/index.d.ts +208 -54
- package/dist/index.js +146 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +146 -30
- 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 +120 -25
- package/dist/nextjs-pages.js.map +1 -1
- package/dist/nextjs-pages.mjs +120 -25
- 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 +1 -1
- package/dist/types-BHtRP_i_.d.mts +0 -411
- package/dist/types-BHtRP_i_.d.ts +0 -411
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/transports.ts","../src/client.ts","../src/dev.ts","../src/types.ts","../src/oidc.ts","../src/consumer-group.ts","../src/topic.ts","../src/callback.ts","../src/factory.ts","../src/queue-client.ts"],"sourcesContent":["// Export transport classes\nexport { BufferTransport, JsonTransport, StreamTransport } from \"./transports\";\n\n// Export Client for user-facing wrapper\nexport { Client } from \"./queue-client\";\n\n// Export factory functions\nexport { receive, send } from \"./factory\";\nexport type { ReceiveOptions, SendOptions } from \"./factory\";\n\n// Export callback utilities\nexport { handleCallback, parseCallback } from \"./callback\";\nexport type { CallbackHandlers, ParsedCallbackRequest } from \"./callback\";\n\n// Export error classes\nexport {\n BadRequestError,\n ConcurrencyLimitError,\n ConsumerDiscoveryError,\n ConsumerRegistryNotConfiguredError,\n DuplicateMessageError,\n ForbiddenError,\n InternalServerError,\n InvalidLimitError,\n MessageAlreadyProcessedError,\n MessageCorruptedError,\n MessageLockedError,\n MessageNotAvailableError,\n MessageNotFoundError,\n QueueEmptyError,\n UnauthorizedError,\n} from \"./types\";\n\n// Export types used by send/receive functions and message handlers\nexport type {\n Message,\n MessageHandler,\n MessageMetadata,\n PublishOptions,\n QueueClientOptions,\n SendMessageOptions,\n SendMessageResponse,\n Transport,\n} from \"./types\";\n","/**\n * Serializer/Deserializer interface for message payloads\n */\nexport interface Transport<T = unknown> {\n /**\n * Serialize a value to a buffer or stream for transmission\n */\n serialize(value: T): Buffer | ReadableStream<Uint8Array>;\n\n /**\n * Deserialize a readable stream back to the original value\n */\n deserialize(stream: ReadableStream<Uint8Array>): Promise<T>;\n\n /**\n * Optional cleanup method for deserialized payloads that may contain resources\n * Should be called when the payload is no longer needed, especially in error cases\n * @param payload The deserialized payload to clean up\n */\n finalize?(payload: T): Promise<void>;\n\n /**\n * MIME type for this serialization format\n */\n contentType: string;\n}\n\nasync function streamToBuffer(\n stream: ReadableStream<Uint8Array>,\n): Promise<Buffer> {\n let totalLength = 0;\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalLength += value.length;\n }\n } finally {\n reader.releaseLock();\n }\n\n // Combine chunks into a single buffer\n return Buffer.concat(chunks, totalLength);\n}\n\n/**\n * Built-in JSON serializer/deserializer\n * This implementation reads the entire stream into memory for JSON parsing\n */\nexport class JsonTransport<T = unknown> implements Transport<T> {\n readonly contentType = \"application/json\";\n readonly replacer?: Parameters<typeof JSON.parse>[1];\n readonly reviver?: Parameters<typeof JSON.parse>[1];\n\n constructor(\n options: {\n replacer?: Parameters<typeof JSON.parse>[1];\n reviver?: Parameters<typeof JSON.parse>[1];\n } = {},\n ) {\n this.replacer = options.replacer;\n this.reviver = options.reviver;\n }\n\n serialize(value: T): Buffer {\n return Buffer.from(JSON.stringify(value, this.replacer), \"utf8\");\n }\n\n async deserialize(stream: ReadableStream<Uint8Array>): Promise<T> {\n // JSON requires reading the entire payload to parse\n const buffer = await streamToBuffer(stream);\n return JSON.parse(buffer.toString(\"utf8\"), this.reviver);\n }\n}\n\n/**\n * Built-in Buffer serializer/deserializer (reads entire stream into a Buffer)\n */\nexport class BufferTransport implements Transport<Buffer> {\n readonly contentType = \"application/octet-stream\";\n\n serialize(value: Buffer): Buffer {\n return value;\n }\n\n async deserialize(stream: ReadableStream<Uint8Array>): Promise<Buffer> {\n // Buffer transport reads the entire stream into memory\n return await streamToBuffer(stream);\n }\n}\n\n/**\n * Stream serializer/deserializer (pass-through for streaming binary data)\n * This is ideal for large payloads that don't need to be buffered in memory\n *\n * IMPORTANT: When using StreamTransport, you must call finalize(payload) when done\n * processing the message to prevent resource leaks, especially in error cases.\n * ConsumerGroup handles this automatically, but direct Client usage requires manual cleanup.\n *\n * Example usage:\n * ```typescript\n * const transport = new StreamTransport();\n * try {\n * for await (const message of client.receiveMessages(options, transport)) {\n * // Process the stream...\n * const reader = message.payload.getReader();\n * // ... handle stream data\n * }\n * } catch (error) {\n * // Cleanup is handled automatically by ConsumerGroup\n * // or manually: await transport.finalize(message.payload);\n * }\n */\nexport class StreamTransport implements Transport<ReadableStream<Uint8Array>> {\n readonly contentType = \"application/octet-stream\";\n\n serialize(value: ReadableStream<Uint8Array>): ReadableStream<Uint8Array> {\n // Pass through the stream directly without buffering\n return value;\n }\n\n async deserialize(\n stream: ReadableStream<Uint8Array>,\n ): Promise<ReadableStream<Uint8Array>> {\n // Pass through the stream directly without buffering\n return stream;\n }\n\n async finalize(payload: ReadableStream<Uint8Array>): Promise<void> {\n // Consume any remaining stream data to prevent resource leaks\n const reader = payload.getReader();\n try {\n while (true) {\n const { done } = await reader.read();\n if (done) break;\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n","import { parseMultipartStream } from \"mixpart\";\nimport { isDevMode } from \"./dev\";\nimport { getVercelOidcToken } from \"./oidc\";\nimport type {\n ChangeVisibilityOptions,\n ChangeVisibilityResponse,\n DeleteMessageOptions,\n DeleteMessageResponse,\n Message,\n QueueClientOptions,\n ReceiveMessageByIdOptions,\n ReceiveMessageByIdResponse,\n ReceiveMessagesOptions,\n SendMessageOptions,\n SendMessageResponse,\n Transport,\n} from \"./types\";\nimport {\n BadRequestError,\n ConcurrencyLimitError,\n ConsumerDiscoveryError,\n ConsumerRegistryNotConfiguredError,\n DuplicateMessageError,\n ForbiddenError,\n InternalServerError,\n InvalidLimitError,\n MessageAlreadyProcessedError,\n MessageCorruptedError,\n MessageNotAvailableError,\n MessageNotFoundError,\n QueueEmptyError,\n UnauthorizedError,\n} from \"./types\";\n\nfunction isDebugEnabled(): boolean {\n return (\n process.env.VERCEL_QUEUE_DEBUG === \"1\" ||\n process.env.VERCEL_QUEUE_DEBUG === \"true\"\n );\n}\n\nasync function consumeStream(\n stream: ReadableStream<Uint8Array>,\n): Promise<void> {\n const reader = stream.getReader();\n try {\n while (true) {\n const { done } = await reader.read();\n if (done) break;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction throwCommonHttpError(\n status: number,\n statusText: string,\n errorText: string,\n operation: string,\n badRequestDefault: string = \"Invalid parameters\",\n): never {\n if (status === 400) {\n throw new BadRequestError(errorText || badRequestDefault);\n }\n if (status === 401) {\n throw new UnauthorizedError(errorText || undefined);\n }\n if (status === 403) {\n throw new ForbiddenError(errorText || undefined);\n }\n if (status >= 500) {\n throw new InternalServerError(\n errorText || `Server error: ${status} ${statusText}`,\n );\n }\n throw new Error(`Failed to ${operation}: ${status} ${statusText}`);\n}\n\nfunction parseQueueHeaders(\n headers: Headers,\n): Omit<Message<unknown>, \"payload\"> | null {\n const messageId = headers.get(\"Vqs-Message-Id\");\n const deliveryCountStr = headers.get(\"Vqs-Delivery-Count\") || \"0\";\n const timestamp = headers.get(\"Vqs-Timestamp\");\n const contentType = headers.get(\"Content-Type\") || \"application/octet-stream\";\n const receiptHandle = headers.get(\"Vqs-Receipt-Handle\");\n\n if (!messageId || !timestamp || !receiptHandle) {\n return null;\n }\n\n const deliveryCount = parseInt(deliveryCountStr, 10);\n if (Number.isNaN(deliveryCount)) {\n return null;\n }\n\n return {\n messageId,\n deliveryCount,\n createdAt: new Date(timestamp),\n contentType,\n receiptHandle,\n };\n}\n\nexport class QueueClient {\n private baseUrl: string;\n private basePath: string;\n private customHeaders: Record<string, string>;\n private providedToken?: string;\n private defaultDeploymentId?: string;\n private pinToDeployment: boolean;\n\n constructor(options: QueueClientOptions = {}) {\n this.baseUrl =\n options.baseUrl ||\n process.env.VERCEL_QUEUE_BASE_URL ||\n \"https://vercel-queue.com\";\n this.basePath =\n options.basePath || process.env.VERCEL_QUEUE_BASE_PATH || \"/api/v3/topic\";\n this.customHeaders = options.headers || {};\n this.providedToken = options.token;\n this.defaultDeploymentId =\n options.deploymentId || process.env.VERCEL_DEPLOYMENT_ID;\n this.pinToDeployment = options.pinToDeployment ?? true;\n }\n\n private getSendDeploymentId(): string | undefined {\n if (isDevMode()) {\n return undefined;\n }\n if (this.pinToDeployment) {\n return this.defaultDeploymentId;\n }\n return undefined;\n }\n\n private getConsumeDeploymentId(): string | undefined {\n if (isDevMode()) {\n return undefined;\n }\n return this.defaultDeploymentId;\n }\n\n private async getToken(): Promise<string> {\n if (this.providedToken) {\n return this.providedToken;\n }\n\n const token = await getVercelOidcToken();\n if (!token) {\n throw new Error(\n \"Failed to get OIDC token from Vercel Functions. \" +\n \"Make sure you are running in a Vercel Function environment, or provide a token explicitly.\\n\\n\" +\n \"To set up your environment:\\n\" +\n \"1. Link your project: 'vercel link'\\n\" +\n \"2. Pull environment variables: 'vercel env pull'\\n\" +\n \"3. Run with environment: 'dotenv -e .env.local -- your-command'\",\n );\n }\n return token;\n }\n\n private buildUrl(queueName: string, ...pathSegments: string[]): string {\n const encodedQueue = encodeURIComponent(queueName);\n const segments = pathSegments.map((s) => encodeURIComponent(s));\n const path = segments.length > 0 ? \"/\" + segments.join(\"/\") : \"\";\n return `${this.baseUrl}${this.basePath}/${encodedQueue}${path}`;\n }\n\n private async fetch(\n url: string,\n init: RequestInit & { headers: Headers },\n ): Promise<Response> {\n const method = init.method || \"GET\";\n\n if (isDebugEnabled()) {\n const logData: Record<string, unknown> = {\n method,\n url,\n headers: init.headers,\n };\n\n const body = init.body;\n if (body !== undefined && body !== null) {\n if (body instanceof ArrayBuffer) {\n logData.bodySize = body.byteLength;\n } else if (body instanceof Uint8Array) {\n logData.bodySize = body.byteLength;\n } else if (typeof body === \"string\") {\n logData.bodySize = body.length;\n } else {\n logData.bodyType = typeof body;\n }\n }\n\n console.debug(\"[VQS Debug] Request:\", JSON.stringify(logData, null, 2));\n }\n\n const response = await fetch(url, init);\n\n if (isDebugEnabled()) {\n const logData: Record<string, unknown> = {\n method,\n url,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n };\n\n console.debug(\"[VQS Debug] Response:\", JSON.stringify(logData, null, 2));\n }\n\n return response;\n }\n\n async sendMessage<T = unknown>(\n options: SendMessageOptions<T>,\n transport: Transport<T>,\n ): Promise<SendMessageResponse> {\n const {\n queueName,\n payload,\n idempotencyKey,\n retentionSeconds,\n delaySeconds,\n } = options;\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n \"Content-Type\": transport.contentType,\n ...this.customHeaders,\n });\n\n const deploymentId = this.getSendDeploymentId();\n if (deploymentId) {\n headers.set(\"Vqs-Deployment-Id\", deploymentId);\n }\n\n if (idempotencyKey) {\n headers.set(\"Vqs-Idempotency-Key\", idempotencyKey);\n }\n\n if (retentionSeconds !== undefined) {\n headers.set(\"Vqs-Retention-Seconds\", retentionSeconds.toString());\n }\n\n if (delaySeconds !== undefined) {\n headers.set(\"Vqs-Delay-Seconds\", delaySeconds.toString());\n }\n\n const serialized = transport.serialize(payload);\n const body = Buffer.isBuffer(serialized)\n ? new Uint8Array(serialized)\n : serialized;\n\n const response = await this.fetch(this.buildUrl(queueName), {\n method: \"POST\",\n body,\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 409) {\n throw new DuplicateMessageError(\n errorText || \"Duplicate idempotency key detected\",\n idempotencyKey,\n );\n }\n if (response.status === 502) {\n throw new ConsumerDiscoveryError(\n errorText || \"Consumer discovery failed\",\n deploymentId,\n );\n }\n if (response.status === 503) {\n throw new ConsumerRegistryNotConfiguredError(\n errorText || \"Consumer registry not configured\",\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"send message\",\n );\n }\n\n const responseData = (await response.json()) as SendMessageResponse;\n\n return responseData;\n }\n\n async *receiveMessages<T = unknown>(\n options: ReceiveMessagesOptions<T>,\n transport: Transport<T>,\n ): AsyncGenerator<Message<T>, void, unknown> {\n const {\n queueName,\n consumerGroup,\n visibilityTimeoutSeconds,\n limit,\n maxConcurrency,\n } = options;\n\n if (limit !== undefined && (limit < 1 || limit > 10)) {\n throw new InvalidLimitError(limit);\n }\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n Accept: \"multipart/mixed\",\n ...this.customHeaders,\n });\n\n if (visibilityTimeoutSeconds !== undefined) {\n headers.set(\n \"Vqs-Visibility-Timeout-Seconds\",\n visibilityTimeoutSeconds.toString(),\n );\n }\n\n if (limit !== undefined) {\n headers.set(\"Vqs-Max-Messages\", limit.toString());\n }\n\n if (maxConcurrency !== undefined) {\n headers.set(\"Vqs-Max-Concurrency\", maxConcurrency.toString());\n }\n\n const effectiveDeploymentId = this.getConsumeDeploymentId();\n if (effectiveDeploymentId) {\n headers.set(\"Vqs-Deployment-Id\", effectiveDeploymentId);\n }\n\n const response = await this.fetch(\n this.buildUrl(queueName, \"consumer\", consumerGroup),\n {\n method: \"POST\",\n headers,\n },\n );\n\n if (response.status === 204) {\n throw new QueueEmptyError(queueName, consumerGroup);\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 429) {\n let errorData: {\n error?: string;\n currentInflight?: number;\n maxConcurrency?: number;\n } = {};\n try {\n errorData = JSON.parse(errorText);\n } catch {\n // ignore parse errors\n }\n throw new ConcurrencyLimitError(\n errorData.error || \"Concurrency limit exceeded or throttled\",\n errorData.currentInflight,\n errorData.maxConcurrency,\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"receive messages\",\n );\n }\n\n for await (const multipartMessage of parseMultipartStream(response)) {\n try {\n const parsedHeaders = parseQueueHeaders(multipartMessage.headers);\n\n if (!parsedHeaders) {\n console.warn(\"Missing required queue headers in multipart part\");\n await consumeStream(multipartMessage.payload);\n continue;\n }\n\n const deserializedPayload = await transport.deserialize(\n multipartMessage.payload,\n );\n\n const message: Message<T> = {\n ...parsedHeaders,\n payload: deserializedPayload,\n };\n\n yield message;\n } catch (error) {\n console.warn(\"Failed to process multipart message:\", error);\n await consumeStream(multipartMessage.payload);\n }\n }\n }\n\n async receiveMessageById<T = unknown>(\n options: ReceiveMessageByIdOptions<T>,\n transport: Transport<T>,\n ): Promise<ReceiveMessageByIdResponse<T>> {\n const {\n queueName,\n consumerGroup,\n messageId,\n visibilityTimeoutSeconds,\n maxConcurrency,\n } = options;\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n Accept: \"multipart/mixed\",\n ...this.customHeaders,\n });\n\n if (visibilityTimeoutSeconds !== undefined) {\n headers.set(\n \"Vqs-Visibility-Timeout-Seconds\",\n visibilityTimeoutSeconds.toString(),\n );\n }\n\n if (maxConcurrency !== undefined) {\n headers.set(\"Vqs-Max-Concurrency\", maxConcurrency.toString());\n }\n\n const effectiveDeploymentId = this.getConsumeDeploymentId();\n if (effectiveDeploymentId) {\n headers.set(\"Vqs-Deployment-Id\", effectiveDeploymentId);\n }\n\n const response = await this.fetch(\n this.buildUrl(queueName, \"consumer\", consumerGroup, \"id\", messageId),\n {\n method: \"POST\",\n headers,\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 404) {\n throw new MessageNotFoundError(messageId);\n }\n if (response.status === 409) {\n let errorData: { error?: string; originalMessageId?: string } = {};\n try {\n errorData = JSON.parse(errorText);\n } catch {\n // ignore parse errors\n }\n\n if (errorData.originalMessageId) {\n throw new MessageNotAvailableError(\n messageId,\n `This message was a duplicate - use originalMessageId: ${errorData.originalMessageId}`,\n );\n }\n throw new MessageNotAvailableError(messageId);\n }\n if (response.status === 410) {\n throw new MessageAlreadyProcessedError(messageId);\n }\n if (response.status === 429) {\n let errorData: {\n error?: string;\n currentInflight?: number;\n maxConcurrency?: number;\n } = {};\n try {\n errorData = JSON.parse(errorText);\n } catch {\n // ignore parse errors\n }\n throw new ConcurrencyLimitError(\n errorData.error || \"Concurrency limit exceeded or throttled\",\n errorData.currentInflight,\n errorData.maxConcurrency,\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"receive message by ID\",\n );\n }\n\n for await (const multipartMessage of parseMultipartStream(response)) {\n const parsedHeaders = parseQueueHeaders(multipartMessage.headers);\n\n if (!parsedHeaders) {\n await consumeStream(multipartMessage.payload);\n throw new MessageCorruptedError(\n messageId,\n \"Missing required queue headers in response\",\n );\n }\n\n const deserializedPayload = await transport.deserialize(\n multipartMessage.payload,\n );\n\n const message: Message<T> = {\n ...parsedHeaders,\n payload: deserializedPayload,\n };\n\n return { message };\n }\n\n throw new MessageNotFoundError(messageId);\n }\n\n async deleteMessage(\n options: DeleteMessageOptions,\n ): Promise<DeleteMessageResponse> {\n const { queueName, consumerGroup, receiptHandle } = options;\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n ...this.customHeaders,\n });\n\n const effectiveDeploymentId = this.getConsumeDeploymentId();\n if (effectiveDeploymentId) {\n headers.set(\"Vqs-Deployment-Id\", effectiveDeploymentId);\n }\n\n const response = await this.fetch(\n this.buildUrl(\n queueName,\n \"consumer\",\n consumerGroup,\n \"lease\",\n receiptHandle,\n ),\n {\n method: \"DELETE\",\n headers,\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 404) {\n throw new MessageNotFoundError(receiptHandle);\n }\n if (response.status === 409) {\n throw new MessageNotAvailableError(\n receiptHandle,\n errorText ||\n \"Invalid receipt handle, message not in correct state, or already processed\",\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"delete message\",\n \"Missing or invalid receipt handle\",\n );\n }\n\n return { deleted: true };\n }\n\n async changeVisibility(\n options: ChangeVisibilityOptions,\n ): Promise<ChangeVisibilityResponse> {\n const {\n queueName,\n consumerGroup,\n receiptHandle,\n visibilityTimeoutSeconds,\n } = options;\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n \"Content-Type\": \"application/json\",\n ...this.customHeaders,\n });\n\n const effectiveDeploymentId = this.getConsumeDeploymentId();\n if (effectiveDeploymentId) {\n headers.set(\"Vqs-Deployment-Id\", effectiveDeploymentId);\n }\n\n const response = await this.fetch(\n this.buildUrl(\n queueName,\n \"consumer\",\n consumerGroup,\n \"lease\",\n receiptHandle,\n ),\n {\n method: \"PATCH\",\n headers,\n body: JSON.stringify({ visibilityTimeoutSeconds }),\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 404) {\n throw new MessageNotFoundError(receiptHandle);\n }\n if (response.status === 409) {\n throw new MessageNotAvailableError(\n receiptHandle,\n errorText ||\n \"Invalid receipt handle, message not in correct state, or already processed\",\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"change visibility\",\n \"Missing receipt handle or invalid visibility timeout\",\n );\n }\n\n return { success: true };\n }\n\n /**\n * Alternative endpoint for changing message visibility timeout.\n * Uses the /visibility path suffix and expects visibilityTimeoutSeconds in the body.\n * Functionally equivalent to changeVisibility but follows an alternative API pattern.\n *\n * @param options - Options for changing visibility\n * @returns Promise resolving to change visibility response\n */\n async changeVisibilityAlt(\n options: ChangeVisibilityOptions,\n ): Promise<ChangeVisibilityResponse> {\n const {\n queueName,\n consumerGroup,\n receiptHandle,\n visibilityTimeoutSeconds,\n } = options;\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n \"Content-Type\": \"application/json\",\n ...this.customHeaders,\n });\n\n const effectiveDeploymentId = this.getConsumeDeploymentId();\n if (effectiveDeploymentId) {\n headers.set(\"Vqs-Deployment-Id\", effectiveDeploymentId);\n }\n\n const response = await this.fetch(\n this.buildUrl(\n queueName,\n \"consumer\",\n consumerGroup,\n \"lease\",\n receiptHandle,\n \"visibility\",\n ),\n {\n method: \"PATCH\",\n headers,\n body: JSON.stringify({ visibilityTimeoutSeconds }),\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 404) {\n throw new MessageNotFoundError(receiptHandle);\n }\n if (response.status === 409) {\n throw new MessageNotAvailableError(\n receiptHandle,\n errorText ||\n \"Invalid receipt handle, message not in correct state, or already processed\",\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"change visibility (alt)\",\n \"Missing receipt handle or invalid visibility timeout\",\n );\n }\n\n return { success: true };\n }\n}\n","/**\n * Development mode utilities for local queue compatibility\n * This file contains helpers that enable local callback triggering in development mode\n *\n * Key behaviors:\n * - Discovers queue routes from vercel.json experimentalTriggers config\n * - Makes HTTP requests to trigger callbacks instead of calling registered handlers\n * - Supports wildcard topic patterns\n * - V3 compatibility: Polls for message visibility before triggering callbacks\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { CloudEvent } from \"./callback\";\nimport { matchesWildcardPattern } from \"./callback\";\nimport { QueueClient } from \"./client\";\nimport { JsonTransport } from \"./transports\";\nimport { MessageNotFoundError, MessageAlreadyProcessedError } from \"./types\";\n\n/**\n * Global key for cached route mappings from vercel.json\n */\nconst ROUTE_MAPPINGS_KEY = Symbol.for(\"@vercel/queue.devRouteMappings\");\n\n/**\n * Route mapping from vercel.json experimentalTriggers\n */\ninterface DevRouteMapping {\n urlPath: string;\n topic: string;\n consumer: string;\n}\n\n/**\n * Convert a file path from vercel.json to a URL path\n * e.g., \"app/api/vm/queue/route.ts\" → \"/api/vm/queue\"\n */\nfunction filePathToUrlPath(filePath: string): string {\n let urlPath = filePath\n .replace(/^app\\//, \"/\")\n .replace(/^pages\\//, \"/\")\n .replace(/\\/route\\.(ts|js|tsx|jsx)$/, \"\")\n .replace(/\\.(ts|js|tsx|jsx)$/, \"\");\n\n if (!urlPath.startsWith(\"/\")) {\n urlPath = \"/\" + urlPath;\n }\n\n return urlPath;\n}\n\n/**\n * Read and cache route mappings from vercel.json\n * Returns null if vercel.json doesn't exist or has no queue triggers\n */\nfunction getDevRouteMappings(): DevRouteMapping[] | null {\n const g = globalThis as typeof globalThis & {\n [ROUTE_MAPPINGS_KEY]?: DevRouteMapping[] | null;\n };\n\n if (ROUTE_MAPPINGS_KEY in g) {\n return g[ROUTE_MAPPINGS_KEY] ?? null;\n }\n\n try {\n const vercelJsonPath = path.join(process.cwd(), \"vercel.json\");\n if (!fs.existsSync(vercelJsonPath)) {\n g[ROUTE_MAPPINGS_KEY] = null;\n return null;\n }\n\n const vercelJson = JSON.parse(fs.readFileSync(vercelJsonPath, \"utf-8\")) as {\n functions?: {\n [filePath: string]: {\n experimentalTriggers?: Array<{\n type: string;\n topic?: string;\n consumer?: string;\n }>;\n };\n };\n };\n\n if (!vercelJson.functions) {\n g[ROUTE_MAPPINGS_KEY] = null;\n return null;\n }\n\n const mappings: DevRouteMapping[] = [];\n\n for (const [filePath, config] of Object.entries(vercelJson.functions)) {\n if (!config.experimentalTriggers) continue;\n\n for (const trigger of config.experimentalTriggers) {\n if (\n trigger.type?.startsWith(\"queue/\") &&\n trigger.topic &&\n trigger.consumer\n ) {\n mappings.push({\n urlPath: filePathToUrlPath(filePath),\n topic: trigger.topic,\n consumer: trigger.consumer,\n });\n }\n }\n }\n\n g[ROUTE_MAPPINGS_KEY] = mappings.length > 0 ? mappings : null;\n return g[ROUTE_MAPPINGS_KEY];\n } catch (error) {\n console.warn(\"[Dev Mode] Failed to read vercel.json:\", error);\n g[ROUTE_MAPPINGS_KEY] = null;\n return null;\n }\n}\n\n/**\n * Find routes that match a topic name (supports wildcards)\n */\nfunction findMatchingRoutes(topicName: string): DevRouteMapping[] {\n const mappings = getDevRouteMappings();\n if (!mappings) {\n return [];\n }\n\n return mappings.filter((mapping) => {\n if (mapping.topic.includes(\"*\")) {\n return matchesWildcardPattern(topicName, mapping.topic);\n }\n return mapping.topic === topicName;\n });\n}\n\n/**\n * Check if running in development mode\n */\nexport function isDevMode(): boolean {\n return process.env.NODE_ENV === \"development\";\n}\n\n/**\n * Configuration for visibility polling in V3\n */\nconst DEV_VISIBILITY_POLL_INTERVAL = 50;\nconst DEV_VISIBILITY_MAX_WAIT = 5000;\nconst DEV_VISIBILITY_BACKOFF_MULTIPLIER = 2;\n\n/**\n * Wait for a message to become visible in the queue (V3 eventual consistency)\n * Polls receiveMessageById with visibilityTimeoutSeconds=0 until the message is available\n * @returns true if message became visible, false if timed out\n * @internal\n */\nasync function waitForMessageVisibility(\n topicName: string,\n consumerGroup: string,\n messageId: string,\n): Promise<boolean> {\n const client = new QueueClient();\n const transport = new JsonTransport();\n\n let elapsed = 0;\n let interval = DEV_VISIBILITY_POLL_INTERVAL;\n\n while (elapsed < DEV_VISIBILITY_MAX_WAIT) {\n try {\n await client.receiveMessageById(\n {\n queueName: topicName,\n consumerGroup,\n messageId,\n visibilityTimeoutSeconds: 0,\n },\n transport,\n );\n return true;\n } catch (error) {\n if (error instanceof MessageNotFoundError) {\n await new Promise((resolve) => setTimeout(resolve, interval));\n elapsed += interval;\n interval = Math.min(\n interval * DEV_VISIBILITY_BACKOFF_MULTIPLIER,\n DEV_VISIBILITY_MAX_WAIT - elapsed,\n );\n continue;\n }\n if (error instanceof MessageAlreadyProcessedError) {\n console.log(\n `[Dev Mode] Message already processed: topic=\"${topicName}\" messageId=\"${messageId}\"`,\n );\n return false;\n }\n console.error(\n `[Dev Mode] Error polling for message visibility: topic=\"${topicName}\" messageId=\"${messageId}\"`,\n error,\n );\n return false;\n }\n }\n\n console.warn(\n `[Dev Mode] Message visibility timeout after ${DEV_VISIBILITY_MAX_WAIT}ms: topic=\"${topicName}\" messageId=\"${messageId}\"`,\n );\n return false;\n}\n\n/**\n * Trigger development mode callbacks for a topic\n * Discovers routes from vercel.json and makes HTTP requests to trigger callbacks\n * Waits for message visibility in V3 before making requests\n * @internal\n */\nexport function triggerDevCallbacks(\n topicName: string,\n messageId: string,\n delaySeconds?: number,\n): void {\n if (delaySeconds && delaySeconds > 0) {\n console.log(\n `[Dev Mode] Message sent with delay: topic=\"${topicName}\" messageId=\"${messageId}\" delay=${delaySeconds}s`,\n );\n setTimeout(() => {\n triggerDevCallbacks(topicName, messageId);\n }, delaySeconds * 1000);\n return;\n }\n\n console.log(\n `[Dev Mode] Message sent: topic=\"${topicName}\" messageId=\"${messageId}\"`,\n );\n\n const matchingRoutes = findMatchingRoutes(topicName);\n\n if (matchingRoutes.length === 0) {\n console.log(\n `[Dev Mode] No matching routes in vercel.json for topic \"${topicName}\"`,\n );\n return;\n }\n\n const consumerGroups = matchingRoutes.map((r) => r.consumer);\n\n console.log(\n `[Dev Mode] Scheduling callbacks for topic=\"${topicName}\" messageId=\"${messageId}\" → consumers: [${consumerGroups.join(\", \")}]`,\n );\n\n (async () => {\n const firstRoute = matchingRoutes[0];\n const isVisible = await waitForMessageVisibility(\n topicName,\n firstRoute.consumer,\n messageId,\n );\n\n if (!isVisible) {\n console.warn(\n `[Dev Mode] Skipping callbacks - message not visible: topic=\"${topicName}\" messageId=\"${messageId}\"`,\n );\n return;\n }\n\n const port = process.env.PORT || 3000;\n const baseUrl = `http://localhost:${port}`;\n\n for (const route of matchingRoutes) {\n const url = `${baseUrl}${route.urlPath}`;\n\n console.log(\n `[Dev Mode] Invoking handler: topic=\"${topicName}\" consumer=\"${route.consumer}\" messageId=\"${messageId}\" url=\"${url}\"`,\n );\n\n const cloudEvent: CloudEvent = {\n type: \"com.vercel.queue.v1beta\",\n source: `/topic/${topicName}/consumer/${route.consumer}`,\n id: messageId,\n datacontenttype: \"application/json\",\n data: {\n messageId,\n queueName: topicName,\n consumerGroup: route.consumer,\n },\n time: new Date().toISOString(),\n specversion: \"1.0\",\n };\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/cloudevents+json\",\n },\n body: JSON.stringify(cloudEvent),\n });\n\n if (response.ok) {\n try {\n const responseData = (await response.json()) as {\n status?: string;\n };\n if (responseData.status === \"success\") {\n console.log(\n `[Dev Mode] ✓ Message processed successfully: topic=\"${topicName}\" consumer=\"${route.consumer}\" messageId=\"${messageId}\"`,\n );\n }\n } catch {\n console.warn(\n `[Dev Mode] Handler returned OK but response was not JSON: topic=\"${topicName}\" consumer=\"${route.consumer}\"`,\n );\n }\n } else {\n try {\n const errorData = (await response.json()) as { error?: string };\n console.error(\n `[Dev Mode] ✗ Handler failed: topic=\"${topicName}\" consumer=\"${route.consumer}\" messageId=\"${messageId}\" error=\"${errorData.error || response.statusText}\"`,\n );\n } catch {\n console.error(\n `[Dev Mode] ✗ Handler failed: topic=\"${topicName}\" consumer=\"${route.consumer}\" messageId=\"${messageId}\" status=${response.status}`,\n );\n }\n }\n } catch (error) {\n console.error(\n `[Dev Mode] ✗ HTTP request failed: topic=\"${topicName}\" consumer=\"${route.consumer}\" messageId=\"${messageId}\" url=\"${url}\"`,\n error,\n );\n }\n }\n })();\n}\n\n/**\n * Clear cached route mappings - for testing only\n * @internal\n */\nfunction clearDevRouteMappings(): void {\n const g = globalThis as typeof globalThis & {\n [ROUTE_MAPPINGS_KEY]?: DevRouteMapping[] | null;\n };\n delete g[ROUTE_MAPPINGS_KEY];\n}\n\n// Export for testing\nif (process.env.NODE_ENV === \"test\" || process.env.VITEST) {\n (globalThis as any).__clearDevRouteMappings = clearDevRouteMappings;\n}\n","/**\n * Vercel Queue Service client types\n */\nimport type { Transport } from \"./transports\";\n\n// Re-export transport interface for convenience\nexport type { Transport };\n\nexport interface QueueClientOptions {\n /**\n * Base URL for the Vercel Queue Service API\n * Can also be set via VERCEL_QUEUE_BASE_URL environment variable\n * @default \"https://vercel-queue.com\"\n */\n baseUrl?: string;\n /**\n * Base path for API endpoints\n * Can also be set via VERCEL_QUEUE_BASE_PATH environment variable\n * @default \"/api/v3/topic\"\n */\n basePath?: string;\n /**\n * Authentication token for the Vercel Queue Service API\n * If not provided, the client will attempt to get a token via OIDC\n */\n token?: string;\n /**\n * Custom headers to include in all requests\n */\n headers?: Record<string, string>;\n /**\n * Default deployment ID to include in requests\n * If not provided, defaults to VERCEL_DEPLOYMENT_ID environment variable\n */\n deploymentId?: string;\n /**\n * Whether to pin messages to the current deployment when publishing.\n * When true, sends VERCEL_DEPLOYMENT_ID from environment, ensuring\n * messages are routed to consumers on the same deployment.\n * Only affects send/publish operations - consume operations always\n * send deployment ID in production to identify the processing deployment.\n * Ignored in development mode (deployment ID is never sent locally).\n * @default true\n */\n pinToDeployment?: boolean;\n}\n\n/**\n * Shared options for publishing messages\n */\nexport interface PublishOptions {\n /**\n * Unique key to prevent duplicate message submissions\n * @default random UUID\n */\n idempotencyKey?: string;\n /**\n * Message retention time in seconds\n * @default 86400 (24 hours)\n * @min 60\n * @max 86400\n */\n retentionSeconds?: number;\n /**\n * Delay delivery of the message by this many seconds\n * @min 0\n * @max retentionSeconds\n */\n delaySeconds?: number;\n}\n\nexport interface SendMessageOptions<T = unknown> extends PublishOptions {\n /**\n * The queue name to send the message to\n */\n queueName: string;\n /**\n * The message payload\n */\n payload: T;\n}\n\nexport interface SendMessageResponse {\n /**\n * The generated message ID\n */\n messageId: string;\n}\n\nexport interface Message<T = unknown> {\n /**\n * The message ID\n */\n messageId: string;\n /**\n * The deserialized message payload\n * Note: If using streaming transports, ensure proper cleanup by calling transport.finalize(payload)\n * when done processing, especially in error cases\n */\n payload: T;\n /**\n * Number of times this message has been delivered\n */\n deliveryCount: number;\n /**\n * When the message was created\n */\n createdAt: Date;\n /**\n * MIME type of the message content\n */\n contentType: string;\n /**\n * Receipt handle for this message delivery (required for delete/patch operations)\n */\n receiptHandle: string;\n}\n\nexport interface ReceiveMessagesOptions<T = unknown> {\n /**\n * The queue name to receive messages from\n */\n queueName: string;\n /**\n * Consumer group name\n */\n consumerGroup: string;\n /**\n * Time in seconds that messages will be invisible to other consumers\n * @default 30\n */\n visibilityTimeoutSeconds?: number;\n /**\n * Maximum number of messages to retrieve\n * @default 1\n * @max 10\n */\n limit?: number;\n /**\n * Maximum concurrent in-flight messages\n */\n maxConcurrency?: number;\n}\n\nexport interface DeleteMessageOptions {\n /**\n * The queue name the message belongs to\n */\n queueName: string;\n /**\n * Consumer group name\n */\n consumerGroup: string;\n /**\n * Receipt handle received from the message\n */\n receiptHandle: string;\n}\n\nexport interface DeleteMessageResponse {\n /**\n * Whether the message was successfully deleted\n */\n deleted: boolean;\n}\n\nexport interface ChangeVisibilityOptions {\n /**\n * The queue name the message belongs to\n */\n queueName: string;\n /**\n * Consumer group name\n */\n consumerGroup: string;\n /**\n * Receipt handle received from the message\n */\n receiptHandle: string;\n /**\n * New visibility timeout in seconds\n */\n visibilityTimeoutSeconds: number;\n}\n\nexport interface ChangeVisibilityResponse {\n /**\n * Whether the visibility was successfully updated\n */\n success: boolean;\n}\n\n/**\n * Message metadata provided to handlers\n */\nexport interface MessageMetadata {\n messageId: string;\n deliveryCount: number;\n createdAt: Date;\n topicName: string;\n consumerGroup: string;\n}\n\n/**\n * Message handler function type\n */\nexport type MessageHandler<T = unknown> = (\n message: T,\n metadata: MessageMetadata,\n) => Promise<void> | void;\n\n/**\n * Options for creating a ConsumerGroup instance\n */\nexport interface ConsumerGroupOptions<T = unknown> {\n /**\n * Serializer/deserializer for the payload\n * @default JsonTransport instance\n */\n transport?: Transport<T>;\n /**\n * Time in seconds that messages will be invisible to other consumers\n * @default 30\n */\n visibilityTimeoutSeconds?: number;\n /**\n * How often to refresh the visibility timeout during processing (in seconds)\n * @default 10\n */\n refreshInterval?: number;\n}\n\nexport interface ReceiveMessageByIdOptions<T = unknown> {\n /**\n * The queue name to receive the message from\n */\n queueName: string;\n /**\n * Consumer group name\n */\n consumerGroup: string;\n /**\n * The message ID to retrieve\n */\n messageId: string;\n /**\n * Time in seconds that the message will be invisible to other consumers\n * @default 30\n */\n visibilityTimeoutSeconds?: number;\n /**\n * Maximum concurrent in-flight messages\n */\n maxConcurrency?: number;\n}\n\nexport interface ReceiveMessageByIdResponse<T = unknown> {\n message: Message<T>;\n}\n\n/**\n * Error thrown when a message is not found (404)\n */\nexport class MessageNotFoundError extends Error {\n constructor(messageId: string) {\n super(`Message ${messageId} not found`);\n this.name = \"MessageNotFoundError\";\n }\n}\n\n/**\n * Error thrown when a message is not available for processing (409)\n * This can happen when the message is in the wrong state, already claimed, etc.\n */\nexport class MessageNotAvailableError extends Error {\n constructor(messageId: string, reason?: string) {\n super(\n `Message ${messageId} not available for processing${reason ? `: ${reason}` : \"\"}`,\n );\n this.name = \"MessageNotAvailableError\";\n }\n}\n\n/**\n * Error thrown when message data is corrupted or can't be parsed\n */\nexport class MessageCorruptedError extends Error {\n constructor(messageId: string, reason: string) {\n super(`Message ${messageId} is corrupted: ${reason}`);\n this.name = \"MessageCorruptedError\";\n }\n}\n\n/**\n * Error thrown when there are no messages available in the queue (204)\n */\nexport class QueueEmptyError extends Error {\n constructor(queueName: string, consumerGroup: string) {\n super(\n `No messages available in queue \"${queueName}\" for consumer group \"${consumerGroup}\"`,\n );\n this.name = \"QueueEmptyError\";\n }\n}\n\n/**\n * Error thrown when a message is temporarily locked (423)\n */\nexport class MessageLockedError extends Error {\n public readonly retryAfter?: number;\n\n constructor(messageId: string, retryAfter?: number) {\n const retryMessage = retryAfter\n ? ` Retry after ${retryAfter} seconds.`\n : \" Try again later.\";\n super(`Message ${messageId} is temporarily locked.${retryMessage}`);\n this.name = \"MessageLockedError\";\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Error thrown when authentication fails (401)\n */\nexport class UnauthorizedError extends Error {\n constructor(message: string = \"Missing or invalid authentication token\") {\n super(message);\n this.name = \"UnauthorizedError\";\n }\n}\n\n/**\n * Error thrown when access is forbidden (403)\n */\nexport class ForbiddenError extends Error {\n constructor(\n message: string = \"Queue environment doesn't match token environment\",\n ) {\n super(message);\n this.name = \"ForbiddenError\";\n }\n}\n\n/**\n * Error thrown for bad requests (400)\n */\nexport class BadRequestError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"BadRequestError\";\n }\n}\n\n/**\n * Error thrown for internal server errors (500)\n */\nexport class InternalServerError extends Error {\n constructor(message: string = \"Unexpected server error\") {\n super(message);\n this.name = \"InternalServerError\";\n }\n}\n\n/**\n * Error thrown when batch limit parameter is invalid\n */\nexport class InvalidLimitError extends Error {\n constructor(limit: number, min: number = 1, max: number = 10) {\n super(`Invalid limit: ${limit}. Limit must be between ${min} and ${max}.`);\n this.name = \"InvalidLimitError\";\n }\n}\n\n/**\n * Error thrown when a message has already been processed (410)\n */\nexport class MessageAlreadyProcessedError extends Error {\n constructor(messageId: string) {\n super(`Message ${messageId} has already been processed`);\n this.name = \"MessageAlreadyProcessedError\";\n }\n}\n\n/**\n * Error thrown when concurrency limit is exceeded (429)\n */\nexport class ConcurrencyLimitError extends Error {\n public readonly currentInflight?: number;\n public readonly maxConcurrency?: number;\n\n constructor(\n message: string = \"Concurrency limit exceeded\",\n currentInflight?: number,\n maxConcurrency?: number,\n ) {\n super(message);\n this.name = \"ConcurrencyLimitError\";\n this.currentInflight = currentInflight;\n this.maxConcurrency = maxConcurrency;\n }\n}\n\n/**\n * Error thrown when a duplicate idempotency key is detected (409)\n */\nexport class DuplicateMessageError extends Error {\n public readonly idempotencyKey?: string;\n\n constructor(message: string, idempotencyKey?: string) {\n super(message);\n this.name = \"DuplicateMessageError\";\n this.idempotencyKey = idempotencyKey;\n }\n}\n\n/**\n * Error thrown when consumer discovery fails (502)\n */\nexport class ConsumerDiscoveryError extends Error {\n public readonly deploymentId?: string;\n\n constructor(message: string, deploymentId?: string) {\n super(message);\n this.name = \"ConsumerDiscoveryError\";\n this.deploymentId = deploymentId;\n }\n}\n\n/**\n * Error thrown when consumer registry is not configured (503)\n */\nexport class ConsumerRegistryNotConfiguredError extends Error {\n constructor(message: string = \"Consumer registry not configured\") {\n super(message);\n this.name = \"ConsumerRegistryNotConfiguredError\";\n }\n}\n","export { getVercelOidcToken } from \"@vercel/oidc\";\n","import { QueueClient } from \"./client\";\nimport { JsonTransport } from \"./transports\";\nimport type {\n ConsumerGroupOptions,\n Message,\n MessageHandler,\n Transport,\n} from \"./types\";\n\n/**\n * Options for the consume method\n */\nexport interface ConsumeOptions {\n /** The specific message ID to consume (if not provided, consumes next available message) */\n messageId?: string;\n}\n\n/**\n * A ConsumerGroup represents a named group of consumers that process messages from a topic\n */\nexport class ConsumerGroup<T = unknown> {\n private client: QueueClient;\n private topicName: string;\n private consumerGroupName: string;\n private visibilityTimeout: number;\n private refreshInterval: number;\n private transport: Transport<T>;\n\n /**\n * Create a new ConsumerGroup instance\n * @param client QueueClient instance to use for API calls\n * @param topicName Name of the topic to consume from\n * @param consumerGroupName Name of the consumer group\n * @param options Optional configuration\n */\n constructor(\n client: QueueClient,\n topicName: string,\n consumerGroupName: string,\n options: ConsumerGroupOptions<T> = {},\n ) {\n this.client = client;\n this.topicName = topicName;\n this.consumerGroupName = consumerGroupName;\n this.visibilityTimeout = options.visibilityTimeoutSeconds || 30; // 30 seconds default\n this.refreshInterval = options.refreshInterval || 10; // 10 seconds default\n this.transport = options.transport || new JsonTransport<T>();\n }\n\n /**\n * Starts a background loop that periodically extends the visibility timeout for a message.\n * This prevents the message from becoming visible to other consumers while it's being processed.\n *\n * The extension loop runs every `refreshInterval` seconds and updates the message's\n * visibility timeout to `visibilityTimeout` seconds from the current time.\n *\n * @param receiptHandle - The receipt handle that proves ownership of the message\n * @returns A function that when called will stop the extension loop\n *\n * @remarks\n * - The first extension attempt occurs after `refreshInterval` seconds, not immediately\n * - If an extension fails, the loop terminates with an error logged to console\n * - The returned stop function is idempotent - calling it multiple times is safe\n * - By default, the stop function returns immediately without waiting for in-flight\n * - Pass `true` to the stop function to wait for any in-flight extension to complete\n */\n private startVisibilityExtension(\n receiptHandle: string,\n ): (waitForCompletion?: boolean) => Promise<void> {\n let isRunning = true;\n let isResolved = false;\n let resolveLifecycle: () => void;\n let timeoutId: NodeJS.Timeout | null = null;\n\n // Promise that tracks the actual termination of the extension loop\n const lifecyclePromise = new Promise<void>((resolve) => {\n resolveLifecycle = resolve;\n });\n\n const safeResolve = () => {\n if (!isResolved) {\n isResolved = true;\n resolveLifecycle();\n }\n };\n\n const extend = async (): Promise<void> => {\n // Check if we should stop before attempting extension\n if (!isRunning) {\n safeResolve();\n return;\n }\n\n try {\n await this.client.changeVisibility({\n queueName: this.topicName,\n consumerGroup: this.consumerGroupName,\n receiptHandle,\n visibilityTimeoutSeconds: this.visibilityTimeout,\n });\n\n // Schedule next extension if still running\n if (isRunning) {\n timeoutId = setTimeout(() => extend(), this.refreshInterval * 1000);\n } else {\n safeResolve();\n }\n } catch (error) {\n console.error(\n `Failed to extend visibility for receipt handle ${receiptHandle}:`,\n error,\n );\n safeResolve();\n }\n };\n\n // Schedule the first extension attempt\n timeoutId = setTimeout(() => extend(), this.refreshInterval * 1000);\n\n // Return a function to stop the extension loop\n return async (waitForCompletion: boolean = false) => {\n // Signal the loop to stop\n isRunning = false;\n\n // Cancel any pending timeout to avoid unnecessary waiting\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n // Only wait for in-flight operations if explicitly requested\n if (waitForCompletion) {\n // Wait for the loop to actually terminate\n // This ensures any in-progress extension completes or fails\n await lifecyclePromise;\n } else {\n safeResolve();\n }\n };\n }\n\n private async processMessage<TPayload>(\n message: Message<TPayload>,\n handler: MessageHandler<TPayload>,\n ): Promise<void> {\n const stopExtension = this.startVisibilityExtension(message.receiptHandle);\n\n try {\n await handler(message.payload, {\n messageId: message.messageId,\n deliveryCount: message.deliveryCount,\n createdAt: message.createdAt,\n topicName: this.topicName,\n consumerGroup: this.consumerGroupName,\n });\n // Stop extensions immediately - we don't need to wait for in-flight extensions\n // since we're about to delete the message anyway\n await stopExtension();\n\n await this.client.deleteMessage({\n queueName: this.topicName,\n consumerGroup: this.consumerGroupName,\n receiptHandle: message.receiptHandle,\n });\n } catch (error) {\n // Stop extensions immediately on error - fail fast without waiting\n // for any in-flight extension attempts\n await stopExtension();\n\n // Clean up the message payload if the transport supports it and payload exists\n // Only call finalize for non-void payloads since transport is typed for T, not void\n if (\n this.transport.finalize &&\n message.payload !== undefined &&\n message.payload !== null\n ) {\n try {\n // Safe cast: when processMessage<T> is called, TPayload is T\n // when processMessage<void> is called, payload is undefined so this won't execute\n await this.transport.finalize(message.payload as T);\n } catch (finalizeError) {\n console.warn(\"Failed to finalize message payload:\", finalizeError);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Consume the next available message from the queue\n * @param handler Function to process the message\n * @returns Promise that resolves when the message is processed\n * @throws All the same errors as the underlying client methods\n */\n async consume(handler: MessageHandler<T>): Promise<void>;\n\n /**\n * Consume a specific message by its ID\n * @param handler Function to process the message\n * @param options Consume options with messageId specified\n * @returns Promise that resolves when the message is processed\n * @throws All the same errors as the underlying client methods\n */\n async consume(\n handler: MessageHandler<T>,\n options: { messageId: string },\n ): Promise<void>;\n\n async consume(\n handler: MessageHandler<T>,\n options?: ConsumeOptions,\n ): Promise<void> {\n if (options?.messageId) {\n const response = await this.client.receiveMessageById(\n {\n queueName: this.topicName,\n consumerGroup: this.consumerGroupName,\n messageId: options.messageId,\n visibilityTimeoutSeconds: this.visibilityTimeout,\n },\n this.transport,\n );\n await this.processMessage<T>(response.message, handler);\n } else {\n let messageFound = false;\n\n for await (const message of this.client.receiveMessages<T>(\n {\n queueName: this.topicName,\n consumerGroup: this.consumerGroupName,\n visibilityTimeoutSeconds: this.visibilityTimeout,\n limit: 1,\n },\n this.transport,\n )) {\n messageFound = true;\n await this.processMessage<T>(message, handler);\n break;\n }\n\n if (!messageFound) {\n throw new Error(\"No messages available\");\n }\n }\n }\n\n /**\n * Get the consumer group name\n */\n get name(): string {\n return this.consumerGroupName;\n }\n\n /**\n * Get the topic name this consumer group is subscribed to\n */\n get topic(): string {\n return this.topicName;\n }\n}\n","import { QueueClient } from \"./client\";\nimport { ConsumerGroup } from \"./consumer-group\";\nimport { JsonTransport } from \"./transports\";\nimport type { ConsumerGroupOptions, PublishOptions, Transport } from \"./types\";\nimport { isDevMode, triggerDevCallbacks } from \"./dev\";\n\n/**\n * A Topic represents a named channel for publishing messages in a pub/sub pattern\n */\nexport class Topic<T = unknown> {\n private client: QueueClient;\n private topicName: string;\n private transport: Transport<T>;\n\n /**\n * Create a new Topic instance\n * @param client QueueClient instance to use for API calls\n * @param topicName Name of the topic to work with\n * @param transport Optional serializer/deserializer for the payload (defaults to JSON)\n */\n constructor(\n client: QueueClient,\n topicName: string,\n transport?: Transport<T>,\n ) {\n this.client = client;\n this.topicName = topicName;\n this.transport = transport || new JsonTransport<T>();\n }\n\n /**\n * Publish a message to the topic\n * @param payload The data to publish\n * @param options Optional publish options\n * @returns An object containing the message ID\n * @throws {BadRequestError} When request parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied (environment mismatch)\n * @throws {InternalServerError} When server encounters an error\n */\n async publish(\n payload: T,\n options?: PublishOptions,\n ): Promise<{ messageId: string }> {\n const result = await this.client.sendMessage<T>(\n {\n queueName: this.topicName,\n payload,\n idempotencyKey: options?.idempotencyKey,\n retentionSeconds: options?.retentionSeconds,\n delaySeconds: options?.delaySeconds,\n },\n this.transport,\n );\n\n // In development mode, automatically trigger registered callbacks after 1s\n if (isDevMode()) {\n triggerDevCallbacks(this.topicName, result.messageId);\n }\n\n return { messageId: result.messageId };\n }\n\n /**\n * Create a consumer group for this topic\n * @param consumerGroupName Name of the consumer group\n * @param options Optional configuration for the consumer group\n * @returns A ConsumerGroup instance\n */\n consumerGroup<U = T>(\n consumerGroupName: string,\n options?: ConsumerGroupOptions<U>,\n ): ConsumerGroup<U> {\n // If no transport is provided in options, use the topic's transport if types match\n const consumerOptions: ConsumerGroupOptions<U> = {\n ...options,\n transport:\n options?.transport || (this.transport as unknown as Transport<U>),\n };\n\n return new ConsumerGroup<U>(\n this.client,\n this.topicName,\n consumerGroupName,\n consumerOptions,\n );\n }\n\n /**\n * Get the topic name\n */\n get name(): string {\n return this.topicName;\n }\n\n /**\n * Get the transport used by this topic\n */\n get serializer(): Transport<T> {\n return this.transport;\n }\n}\n","/**\n * Queue Callback utilities for handling incoming webhook payloads from Vercel triggers\n */\nimport { QueueClient } from \"./client\";\nimport { Topic } from \"./topic\";\nimport type { MessageHandler } from \"./types\";\n\n/**\n * CloudEvent specification for queue callbacks\n */\nexport interface CloudEvent<T = unknown> {\n type: string;\n source: string;\n id: string;\n datacontenttype: string;\n data: T;\n time?: string;\n specversion?: string;\n}\n\n/**\n * Configuration object with handlers for different topics and consumer groups\n */\nexport type CallbackHandlers = {\n [topicName: string]: { [consumerGroup: string]: MessageHandler };\n};\n\n/**\n * Parsed callback request information\n */\nexport type ParsedCallbackRequest = {\n queueName: string;\n consumerGroup: string;\n messageId: string;\n};\n\n/**\n * Validate wildcard pattern according to rules:\n * - * may only appear once\n * - * may only appear at the end of the topic name\n */\nfunction validateWildcardPattern(pattern: string): boolean {\n const firstIndex = pattern.indexOf(\"*\");\n const lastIndex = pattern.lastIndexOf(\"*\");\n\n // Rule 1: * may only appear once (first and last index should be the same)\n if (firstIndex !== lastIndex) {\n return false;\n }\n\n // If no asterisk found, this is not a wildcard pattern\n if (firstIndex === -1) {\n return false;\n }\n\n // Rule 2: * may only appear at the end (index should equal length - 1)\n if (firstIndex !== pattern.length - 1) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Check if a topic name matches a wildcard pattern\n */\nexport function matchesWildcardPattern(\n topicName: string,\n pattern: string,\n): boolean {\n // No need to validate here since patterns are pre-validated at setup time\n const prefix = pattern.slice(0, -1); // Remove the trailing *\n return topicName.startsWith(prefix);\n}\n\n/**\n * Find handler for a topic name, supporting wildcard patterns\n */\nfunction findTopicHandler(\n queueName: string,\n handlers: CallbackHandlers,\n): { [consumerGroup: string]: MessageHandler } | null {\n // First, try exact match\n const exactHandler = handlers[queueName];\n if (exactHandler) {\n return exactHandler;\n }\n\n // Then try wildcard patterns (all patterns are pre-validated)\n for (const pattern in handlers) {\n if (pattern.includes(\"*\") && matchesWildcardPattern(queueName, pattern)) {\n return handlers[pattern];\n }\n }\n\n return null;\n}\n\n/**\n * Parse and validate callback request using CloudEvent specification\n *\n * Extracts queue information from CloudEvent format and validates\n * that all required fields are present.\n *\n * @param request The incoming webhook request\n * @returns Parsed queue information\n * @throws Error if required fields are missing\n *\n * @example\n * ```typescript\n * // In Next.js API route\n * export async function POST(request: Request) {\n * try {\n * const { queueName, consumerGroup, messageId } = parseCallback(request);\n *\n * // Use the parsed information...\n * await myWorkflow.handleWebhook(queueName, consumerGroup, messageId);\n *\n * return Response.json({ status: \"success\" });\n * } catch (error) {\n * return Response.json({ error: error.message }, { status: 400 });\n * }\n * }\n * ```\n */\nexport async function parseCallback(\n request: Request,\n): Promise<ParsedCallbackRequest> {\n // Validate content type header\n const contentType = request.headers.get(\"content-type\");\n if (!contentType || !contentType.includes(\"application/cloudevents+json\")) {\n throw new Error(\n \"Invalid content type: expected 'application/cloudevents+json'\",\n );\n }\n\n let cloudEvent: CloudEvent;\n\n try {\n cloudEvent = (await request.json()) as CloudEvent;\n } catch (error) {\n throw new Error(\"Failed to parse CloudEvent from request body\");\n }\n\n // Validate CloudEvent structure\n if (\n !cloudEvent.type ||\n !cloudEvent.source ||\n !cloudEvent.id ||\n typeof cloudEvent.data !== \"object\" ||\n cloudEvent.data == null\n ) {\n throw new Error(\"Invalid CloudEvent: missing required fields\");\n }\n\n // Validate CloudEvent type\n if (cloudEvent.type !== \"com.vercel.queue.v1beta\") {\n throw new Error(\n `Invalid CloudEvent type: expected 'com.vercel.queue.v1beta', got '${cloudEvent.type}'`,\n );\n }\n\n // Check for required data fields before destructuring\n const missingFields: string[] = [];\n if (!(\"queueName\" in cloudEvent.data)) missingFields.push(\"queueName\");\n if (!(\"consumerGroup\" in cloudEvent.data))\n missingFields.push(\"consumerGroup\");\n if (!(\"messageId\" in cloudEvent.data)) missingFields.push(\"messageId\");\n if (missingFields.length > 0) {\n throw new Error(\n `Missing required CloudEvent data fields: ${missingFields.join(\", \")}`,\n );\n }\n\n const { messageId, queueName, consumerGroup } = cloudEvent.data as {\n messageId: string;\n queueName: string;\n consumerGroup: string;\n };\n\n return {\n queueName,\n consumerGroup,\n messageId,\n };\n}\n\nexport function createCallbackHandler(\n handlers: CallbackHandlers,\n client: QueueClient,\n): (request: Request) => Promise<Response> {\n // Validate all wildcard patterns at setup time\n for (const topicPattern in handlers) {\n if (topicPattern.includes(\"*\")) {\n if (!validateWildcardPattern(topicPattern)) {\n throw new Error(\n `Invalid wildcard pattern \"${topicPattern}\": * may only appear once and must be at the end of the topic name`,\n );\n }\n }\n }\n\n const routeHandler = async (request: Request): Promise<Response> => {\n try {\n // Parse the callback request\n const { queueName, consumerGroup, messageId } =\n await parseCallback(request);\n\n // Find the topic handler\n const topicHandler = findTopicHandler(queueName, handlers);\n\n if (!topicHandler) {\n const availableTopics = Object.keys(handlers).join(\", \");\n return Response.json(\n {\n error: `No handler found for topic: ${queueName}`,\n availableTopics,\n },\n { status: 404 },\n );\n }\n\n // Find the consumer group handler\n const consumerGroupHandler = topicHandler[consumerGroup];\n\n if (!consumerGroupHandler) {\n const availableGroups = Object.keys(topicHandler).join(\", \");\n return Response.json(\n {\n error: `No handler found for consumer group \"${consumerGroup}\" in topic \"${queueName}\".`,\n availableGroups,\n },\n { status: 404 },\n );\n }\n\n // Use the provided client to process the message\n const topic = new Topic(client, queueName);\n const cg = topic.consumerGroup(consumerGroup);\n\n await cg.consume(consumerGroupHandler, { messageId });\n\n return Response.json({ status: \"success\" });\n } catch (error) {\n console.error(\"Queue callback error:\", error);\n\n // Handle parsing errors with appropriate status codes\n if (\n error instanceof Error &&\n (error.message.includes(\"Missing required CloudEvent data fields\") ||\n error.message.includes(\"Invalid CloudEvent\") ||\n error.message.includes(\"Invalid CloudEvent type\") ||\n error.message.includes(\"Invalid content type\") ||\n error.message.includes(\"Failed to parse CloudEvent\"))\n ) {\n return Response.json({ error: error.message }, { status: 400 });\n }\n\n return Response.json(\n { error: \"Failed to process queue message\" },\n { status: 500 },\n );\n }\n };\n\n return routeHandler;\n}\n\n/**\n * Simplified queue callback handler for Next.js route handlers\n *\n * Automatically extracts queue information from CloudEvent format\n * and routes to the appropriate handler based on topic and consumer group.\n *\n * @param handlers Object with topic-specific handlers organized by consumer groups\n * @param client Optional QueueClient instance to use. If not provided, a default client is created.\n * @returns A Next.js route handler function\n *\n * @example\n * ```typescript\n * // Single topic with multiple consumer groups\n * export const POST = handleCallback({\n * \"image-processing\": {\n * \"compress\": (message, metadata) => console.log(\"Compressing image\", message),\n * \"resize\": (message, metadata) => console.log(\"Resizing image\", message),\n * }\n * });\n *\n * // Multiple topics with consumer groups\n * export const POST = handleCallback({\n * \"user-events\": {\n * \"welcome\": (user, metadata) => console.log(\"Welcoming user\", user),\n * \"analytics\": (user, metadata) => console.log(\"Tracking user\", user),\n * },\n * \"order-events\": {\n * \"fulfillment\": (order, metadata) => console.log(\"Fulfilling order\", order),\n * \"notifications\": (order, metadata) => console.log(\"Notifying order\", order),\n * }\n * });\n * ```\n */\nexport function handleCallback(\n handlers: CallbackHandlers,\n client?: QueueClient,\n): (request: Request) => Promise<Response> {\n return createCallbackHandler(handlers, client || new QueueClient());\n}\n","import { QueueClient } from \"./client\";\nimport type { ConsumeOptions } from \"./consumer-group\";\nimport { Topic } from \"./topic\";\nimport { JsonTransport } from \"./transports\";\nimport type {\n ConsumerGroupOptions,\n MessageHandler,\n PublishOptions,\n Transport,\n} from \"./types\";\nimport { isDevMode, triggerDevCallbacks } from \"./dev\";\n\n/**\n * Options for the send function\n */\nexport interface SendOptions<T = unknown> extends PublishOptions {\n /**\n * Serializer/deserializer for the payload\n * @default JsonTransport instance\n */\n transport?: Transport<T>;\n /**\n * QueueClient instance to use for sending the message\n * If not provided, a default client is created\n */\n client?: QueueClient;\n}\n\n/**\n * Send a message to a topic (shorthand for topic creation and publishing)\n * Uses the default QueueClient with automatic OIDC token detection, or a provided client\n * @param topicName Name of the topic to send to\n * @param payload The data to send\n * @param options Optional send options including transport, publish settings, and client\n * @returns Promise with the message ID\n * @throws {BadRequestError} When request parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied (environment mismatch)\n * @throws {InternalServerError} When server encounters an error\n *\n * @example\n * ```typescript\n * // Using default client (OIDC token)\n * await send(\"my-topic\", { hello: \"world\" });\n *\n * // Using custom client\n * const client = new QueueClient({ token: \"my-token\" });\n * await send(\"my-topic\", { hello: \"world\" }, { client });\n * ```\n */\nexport async function send<T = unknown>(\n topicName: string,\n payload: T,\n options?: SendOptions<T>,\n): Promise<{ messageId: string }> {\n const transport = options?.transport || new JsonTransport<T>();\n const client = options?.client || new QueueClient();\n\n const result = await client.sendMessage<T>(\n {\n queueName: topicName,\n payload,\n idempotencyKey: options?.idempotencyKey,\n retentionSeconds: options?.retentionSeconds,\n delaySeconds: options?.delaySeconds,\n },\n transport,\n );\n\n // In development mode, trigger callbacks (respecting any delay)\n if (isDevMode()) {\n triggerDevCallbacks(topicName, result.messageId, options?.delaySeconds);\n }\n\n return { messageId: result.messageId };\n}\n\n/**\n * Options for the receive function\n */\nexport interface ReceiveOptions<T = unknown>\n extends ConsumerGroupOptions<T>,\n ConsumeOptions {\n /**\n * QueueClient instance to use for receiving the message\n * If not provided, a default client is created\n */\n client?: QueueClient;\n}\n\n/**\n * Receive a message from a topic (shorthand for topic and consumer group creation)\n * Uses the default QueueClient with automatic OIDC token detection\n * @param topicName Name of the topic to receive from\n * @param consumerGroup Name of the consumer group\n * @param handler Function to process the message\n * @returns Promise that resolves when the message is processed\n * @throws All the same errors as the underlying client methods\n */\nexport async function receive<T = unknown>(\n topicName: string,\n consumerGroup: string,\n handler: MessageHandler<T>,\n options?: ReceiveOptions<T>,\n): Promise<void>;\n\n/**\n * Receive a specific message by its ID\n * @param topicName Name of the topic to receive from\n * @param consumerGroup Name of the consumer group\n * @param handler Function to process the message\n * @param options Receive options with messageId specified\n * @returns Promise that resolves when the message is processed\n * @throws All the same errors as the underlying client methods\n */\nexport async function receive<T = unknown>(\n topicName: string,\n consumerGroup: string,\n handler: MessageHandler<T>,\n options: ReceiveOptions<T> & { messageId: string },\n): Promise<void>;\n\nexport async function receive<T = unknown>(\n topicName: string,\n consumerGroup: string,\n handler: MessageHandler<T>,\n options?: ReceiveOptions<T>,\n): Promise<void> {\n const transport = options?.transport || new JsonTransport<T>();\n\n const client = options?.client || new QueueClient();\n const topic = new Topic<T>(client, topicName, transport);\n\n const { messageId, client: _, ...consumerGroupOptions } = options || {};\n const consumer = topic.consumerGroup(consumerGroup, consumerGroupOptions);\n\n if (messageId) {\n return consumer.consume(handler, { messageId });\n } else {\n return consumer.consume(handler);\n }\n}\n","/**\n * Client - User-facing wrapper for the Vercel Queue Service\n *\n * This provides a simple interface with send() and handleCallback() methods\n * while delegating to the internal QueueClient and factory functions.\n */\nimport type { CallbackHandlers } from \"./callback\";\nimport { handleCallback as handleCallbackFactory } from \"./callback\";\nimport { QueueClient } from \"./client\";\nimport { send as sendFactory } from \"./factory\";\nimport type { PublishOptions, QueueClientOptions, Transport } from \"./types\";\n\n/**\n * Client provides a simple interface to the Vercel Queue Service.\n *\n * @example\n * ```typescript\n * // Create a client with custom options\n * const client = new Client({\n * token: \"my-token\",\n * headers: { \"X-Custom\": \"header\" },\n * });\n *\n * // Send a message\n * await client.send(\"my-topic\", { hello: \"world\" });\n *\n * // Handle callbacks\n * export const POST = client.handleCallback({\n * \"my-topic\": {\n * \"my-group\": async (msg, meta) => console.log(msg),\n * },\n * });\n * ```\n */\nexport class Client {\n private client: QueueClient;\n\n /**\n * Create a new Client\n * @param options QueueClient configuration options\n */\n constructor(options: QueueClientOptions = {}) {\n this.client = new QueueClient(options);\n }\n\n /**\n * Send a message to a topic\n * @param topicName Name of the topic to send to\n * @param payload The data to send\n * @param options Optional publish options and transport\n * @returns Promise with the message ID\n * @throws {BadRequestError} When request parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied (environment mismatch)\n * @throws {InternalServerError} When server encounters an error\n */\n async send<T = unknown>(\n topicName: string,\n payload: T,\n options?: PublishOptions & { transport?: Transport<T> },\n ): Promise<{ messageId: string }> {\n return sendFactory(topicName, payload, {\n ...options,\n client: this.client,\n });\n }\n\n /**\n * Create a callback handler for processing queue messages\n * Returns a Next.js route handler function that routes messages to appropriate handlers\n * @param handlers Object with topic-specific handlers organized by consumer groups\n * @returns A Next.js route handler function\n *\n * @example\n * ```typescript\n * export const POST = client.handleCallback({\n * \"user-events\": {\n * \"welcome\": (user, metadata) => console.log(\"Welcoming user\", user),\n * \"analytics\": (user, metadata) => console.log(\"Tracking user\", user),\n * },\n * });\n * ```\n */\n handleCallback(\n handlers: CallbackHandlers,\n ): (request: Request) => Promise<Response> {\n return handleCallbackFactory(handlers, this.client);\n }\n}\n"],"mappings":"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","names":["path"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/transports.ts","../src/client.ts","../src/dev.ts","../src/types.ts","../src/oidc.ts","../src/consumer-group.ts","../src/topic.ts","../src/callback.ts","../src/factory.ts","../src/queue-client.ts"],"sourcesContent":["// Export transport classes\nexport { BufferTransport, JsonTransport, StreamTransport } from \"./transports\";\n\n// Export Client for user-facing wrapper\nexport { Client } from \"./queue-client\";\n\n// Export factory functions\nexport { receive, send } from \"./factory\";\nexport type { ReceiveOptions, SendOptions } from \"./factory\";\n\n// Export callback utilities\nexport { handleCallback, parseCallback } from \"./callback\";\nexport type {\n CallbackHandlers,\n HandleCallbackOptions,\n ParsedCallbackRequest,\n} from \"./callback\";\n\n// Export error classes\nexport {\n BadRequestError,\n ConcurrencyLimitError,\n ConsumerDiscoveryError,\n ConsumerRegistryNotConfiguredError,\n DuplicateMessageError,\n ForbiddenError,\n InternalServerError,\n InvalidLimitError,\n MessageAlreadyProcessedError,\n MessageCorruptedError,\n MessageLockedError,\n MessageNotAvailableError,\n MessageNotFoundError,\n QueueEmptyError,\n UnauthorizedError,\n} from \"./types\";\n\n// Export types used by send/receive functions and message handlers\nexport type {\n Message,\n MessageHandler,\n MessageMetadata,\n PublishOptions,\n QueueClientOptions,\n SendMessageOptions,\n SendMessageResponse,\n Transport,\n} from \"./types\";\n","/**\n * Serializer/Deserializer interface for message payloads.\n *\n * Built-in implementations:\n * - `JsonTransport` - JSON serialization (default, buffers entire payload)\n * - `BufferTransport` - Binary data (buffers entire payload)\n * - `StreamTransport` - Pass-through streaming (no buffering, ideal for large payloads)\n */\nexport interface Transport<T = unknown> {\n /**\n * Serialize a value to a buffer or stream for transmission.\n * The result is sent as the request body with the `contentType` header.\n */\n serialize(value: T): Buffer | ReadableStream<Uint8Array>;\n\n /**\n * Deserialize a readable stream back to the original value.\n * Called when receiving messages from the queue.\n */\n deserialize(stream: ReadableStream<Uint8Array>): Promise<T>;\n\n /**\n * Optional cleanup method for deserialized payloads that may contain resources.\n * Called automatically by ConsumerGroup on error; manual cleanup required for direct client usage.\n * @param payload The deserialized payload to clean up\n */\n finalize?(payload: T): Promise<void>;\n\n /**\n * MIME type for this serialization format.\n * Sent as the Content-Type header when publishing messages.\n */\n contentType: string;\n}\n\nasync function streamToBuffer(\n stream: ReadableStream<Uint8Array>,\n): Promise<Buffer> {\n let totalLength = 0;\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n totalLength += value.length;\n }\n } finally {\n reader.releaseLock();\n }\n\n // Combine chunks into a single buffer\n return Buffer.concat(chunks, totalLength);\n}\n\n/**\n * JSON serializer/deserializer (default transport).\n *\n * Ideal for structured data. Buffers the entire payload in memory for parsing.\n *\n * @example\n * ```typescript\n * // Default usage\n * await send(\"topic\", { data: \"example\" });\n *\n * // With custom serialization\n * const transport = new JsonTransport({\n * replacer: (key, value) => key === \"password\" ? undefined : value,\n * reviver: (key, value) => key === \"date\" ? new Date(value) : value,\n * });\n * await send(\"topic\", { data: \"example\" }, { transport });\n * ```\n */\nexport class JsonTransport<T = unknown> implements Transport<T> {\n readonly contentType = \"application/json\";\n readonly replacer?: Parameters<typeof JSON.stringify>[1];\n readonly reviver?: Parameters<typeof JSON.parse>[1];\n\n /**\n * Create a new JsonTransport.\n * @param options - Optional JSON serialization options\n * @param options.replacer - Custom replacer for JSON.stringify\n * @param options.reviver - Custom reviver for JSON.parse\n */\n constructor(\n options: {\n replacer?: Parameters<typeof JSON.stringify>[1];\n reviver?: Parameters<typeof JSON.parse>[1];\n } = {},\n ) {\n this.replacer = options.replacer;\n this.reviver = options.reviver;\n }\n\n serialize(value: T): Buffer {\n return Buffer.from(JSON.stringify(value, this.replacer), \"utf8\");\n }\n\n async deserialize(stream: ReadableStream<Uint8Array>): Promise<T> {\n const buffer = await streamToBuffer(stream);\n return JSON.parse(buffer.toString(\"utf8\"), this.reviver);\n }\n}\n\n/**\n * Binary data serializer/deserializer.\n *\n * Ideal for binary data that fits in memory. Buffers the entire payload.\n *\n * @example\n * ```typescript\n * const transport = new BufferTransport();\n * await send(\"binary-topic\", myBuffer, { transport });\n * ```\n */\nexport class BufferTransport implements Transport<Buffer> {\n readonly contentType = \"application/octet-stream\";\n\n serialize(value: Buffer): Buffer {\n return value;\n }\n\n async deserialize(stream: ReadableStream<Uint8Array>): Promise<Buffer> {\n return await streamToBuffer(stream);\n }\n}\n\n/**\n * Pass-through stream serializer/deserializer.\n *\n * Ideal for large files and real-time streams. Does not buffer data in memory.\n *\n * **Important:** When using StreamTransport, you must call `finalize(payload)` when done\n * processing to prevent resource leaks. ConsumerGroup handles this automatically;\n * direct client usage requires manual cleanup.\n *\n * @example\n * ```typescript\n * const transport = new StreamTransport();\n *\n * // Sending a stream\n * await send(\"large-file\", myReadableStream, { transport });\n *\n * // Receiving - cleanup handled by ConsumerGroup\n * await receive(\"large-file\", \"processor\", async (stream, meta) => {\n * const reader = stream.getReader();\n * // Process chunks...\n * }, { transport });\n *\n * // Direct client usage - manual cleanup required\n * try {\n * for await (const msg of client.receiveMessages(options, transport)) {\n * // Process stream...\n * }\n * } catch (error) {\n * await transport.finalize(msg.payload); // Manual cleanup\n * }\n * ```\n */\nexport class StreamTransport implements Transport<ReadableStream<Uint8Array>> {\n readonly contentType = \"application/octet-stream\";\n\n serialize(value: ReadableStream<Uint8Array>): ReadableStream<Uint8Array> {\n return value;\n }\n\n async deserialize(\n stream: ReadableStream<Uint8Array>,\n ): Promise<ReadableStream<Uint8Array>> {\n return stream;\n }\n\n /**\n * Consume any remaining stream data to prevent resource leaks.\n * Called automatically by ConsumerGroup; manual call required for direct client usage.\n */\n async finalize(payload: ReadableStream<Uint8Array>): Promise<void> {\n const reader = payload.getReader();\n try {\n while (true) {\n const { done } = await reader.read();\n if (done) break;\n }\n } finally {\n reader.releaseLock();\n }\n }\n}\n","import { parseMultipartStream } from \"mixpart\";\nimport { isDevMode } from \"./dev\";\nimport { getVercelOidcToken } from \"./oidc\";\nimport type {\n ChangeVisibilityOptions,\n ChangeVisibilityResponse,\n DeleteMessageOptions,\n DeleteMessageResponse,\n Message,\n QueueClientOptions,\n ReceiveMessageByIdOptions,\n ReceiveMessageByIdResponse,\n ReceiveMessagesOptions,\n SendMessageOptions,\n SendMessageResponse,\n Transport,\n} from \"./types\";\nimport {\n BadRequestError,\n ConcurrencyLimitError,\n ConsumerDiscoveryError,\n ConsumerRegistryNotConfiguredError,\n DuplicateMessageError,\n ForbiddenError,\n InternalServerError,\n InvalidLimitError,\n MessageAlreadyProcessedError,\n MessageCorruptedError,\n MessageNotAvailableError,\n MessageNotFoundError,\n QueueEmptyError,\n UnauthorizedError,\n} from \"./types\";\n\nfunction isDebugEnabled(): boolean {\n return (\n process.env.VERCEL_QUEUE_DEBUG === \"1\" ||\n process.env.VERCEL_QUEUE_DEBUG === \"true\"\n );\n}\n\nasync function consumeStream(\n stream: ReadableStream<Uint8Array>,\n): Promise<void> {\n const reader = stream.getReader();\n try {\n while (true) {\n const { done } = await reader.read();\n if (done) break;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nfunction throwCommonHttpError(\n status: number,\n statusText: string,\n errorText: string,\n operation: string,\n badRequestDefault: string = \"Invalid parameters\",\n): never {\n if (status === 400) {\n throw new BadRequestError(errorText || badRequestDefault);\n }\n if (status === 401) {\n throw new UnauthorizedError(errorText || undefined);\n }\n if (status === 403) {\n throw new ForbiddenError(errorText || undefined);\n }\n if (status >= 500) {\n throw new InternalServerError(\n errorText || `Server error: ${status} ${statusText}`,\n );\n }\n throw new Error(`Failed to ${operation}: ${status} ${statusText}`);\n}\n\nfunction parseQueueHeaders(\n headers: Headers,\n): Omit<Message<unknown>, \"payload\"> | null {\n const messageId = headers.get(\"Vqs-Message-Id\");\n const deliveryCountStr = headers.get(\"Vqs-Delivery-Count\") || \"0\";\n const timestamp = headers.get(\"Vqs-Timestamp\");\n const contentType = headers.get(\"Content-Type\") || \"application/octet-stream\";\n const receiptHandle = headers.get(\"Vqs-Receipt-Handle\");\n\n if (!messageId || !timestamp || !receiptHandle) {\n return null;\n }\n\n const deliveryCount = parseInt(deliveryCountStr, 10);\n if (Number.isNaN(deliveryCount)) {\n return null;\n }\n\n return {\n messageId,\n deliveryCount,\n createdAt: new Date(timestamp),\n contentType,\n receiptHandle,\n };\n}\n\nexport class QueueClient {\n private baseUrl: string;\n private basePath: string;\n private customHeaders: Record<string, string>;\n private providedToken?: string;\n private defaultDeploymentId?: string;\n private pinToDeployment: boolean;\n\n constructor(options: QueueClientOptions = {}) {\n this.baseUrl =\n options.baseUrl ||\n process.env.VERCEL_QUEUE_BASE_URL ||\n \"https://vercel-queue.com\";\n this.basePath =\n options.basePath || process.env.VERCEL_QUEUE_BASE_PATH || \"/api/v3/topic\";\n this.customHeaders = options.headers || {};\n this.providedToken = options.token;\n this.defaultDeploymentId =\n options.deploymentId || process.env.VERCEL_DEPLOYMENT_ID;\n this.pinToDeployment = options.pinToDeployment ?? true;\n }\n\n private getSendDeploymentId(): string | undefined {\n if (isDevMode()) {\n return undefined;\n }\n if (this.pinToDeployment) {\n return this.defaultDeploymentId;\n }\n return undefined;\n }\n\n private getConsumeDeploymentId(): string | undefined {\n if (isDevMode()) {\n return undefined;\n }\n return this.defaultDeploymentId;\n }\n\n private async getToken(): Promise<string> {\n if (this.providedToken) {\n return this.providedToken;\n }\n\n const token = await getVercelOidcToken();\n if (!token) {\n throw new Error(\n \"Failed to get OIDC token from Vercel Functions. \" +\n \"Make sure you are running in a Vercel Function environment, or provide a token explicitly.\\n\\n\" +\n \"To set up your environment:\\n\" +\n \"1. Link your project: 'vercel link'\\n\" +\n \"2. Pull environment variables: 'vercel env pull'\\n\" +\n \"3. Run with environment: 'dotenv -e .env.local -- your-command'\",\n );\n }\n return token;\n }\n\n private buildUrl(queueName: string, ...pathSegments: string[]): string {\n const encodedQueue = encodeURIComponent(queueName);\n const segments = pathSegments.map((s) => encodeURIComponent(s));\n const path = segments.length > 0 ? \"/\" + segments.join(\"/\") : \"\";\n return `${this.baseUrl}${this.basePath}/${encodedQueue}${path}`;\n }\n\n private async fetch(\n url: string,\n init: RequestInit & { headers: Headers },\n ): Promise<Response> {\n const method = init.method || \"GET\";\n\n if (isDebugEnabled()) {\n const logData: Record<string, unknown> = {\n method,\n url,\n headers: init.headers,\n };\n\n const body = init.body;\n if (body !== undefined && body !== null) {\n if (body instanceof ArrayBuffer) {\n logData.bodySize = body.byteLength;\n } else if (body instanceof Uint8Array) {\n logData.bodySize = body.byteLength;\n } else if (typeof body === \"string\") {\n logData.bodySize = body.length;\n } else {\n logData.bodyType = typeof body;\n }\n }\n\n console.debug(\"[VQS Debug] Request:\", JSON.stringify(logData, null, 2));\n }\n\n const response = await fetch(url, init);\n\n if (isDebugEnabled()) {\n const logData: Record<string, unknown> = {\n method,\n url,\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n };\n\n console.debug(\"[VQS Debug] Response:\", JSON.stringify(logData, null, 2));\n }\n\n return response;\n }\n\n /**\n * Send a message to a topic.\n *\n * @param options - Message options including queue name, payload, and optional settings\n * @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)\n * @param options.payload - Message payload\n * @param options.idempotencyKey - Optional deduplication key (dedup window: min(retention, 24h))\n * @param options.retentionSeconds - Message TTL (default: 86400, min: 60, max: 86400)\n * @param options.delaySeconds - Delivery delay (default: 0, max: retentionSeconds)\n * @param transport - Serializer for the payload\n * @returns Promise with the generated messageId\n * @throws {DuplicateMessageError} When idempotency key was already used\n * @throws {ConsumerDiscoveryError} When consumer discovery fails\n * @throws {ConsumerRegistryNotConfiguredError} When registry not configured\n * @throws {BadRequestError} When parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied\n * @throws {InternalServerError} When server encounters an error\n */\n async sendMessage<T = unknown>(\n options: SendMessageOptions<T>,\n transport: Transport<T>,\n ): Promise<SendMessageResponse> {\n const {\n queueName,\n payload,\n idempotencyKey,\n retentionSeconds,\n delaySeconds,\n } = options;\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n \"Content-Type\": transport.contentType,\n ...this.customHeaders,\n });\n\n const deploymentId = this.getSendDeploymentId();\n if (deploymentId) {\n headers.set(\"Vqs-Deployment-Id\", deploymentId);\n }\n\n if (idempotencyKey) {\n headers.set(\"Vqs-Idempotency-Key\", idempotencyKey);\n }\n\n if (retentionSeconds !== undefined) {\n headers.set(\"Vqs-Retention-Seconds\", retentionSeconds.toString());\n }\n\n if (delaySeconds !== undefined) {\n headers.set(\"Vqs-Delay-Seconds\", delaySeconds.toString());\n }\n\n const serialized = transport.serialize(payload);\n const body = Buffer.isBuffer(serialized)\n ? new Uint8Array(serialized)\n : serialized;\n\n const response = await this.fetch(this.buildUrl(queueName), {\n method: \"POST\",\n body,\n headers,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 409) {\n throw new DuplicateMessageError(\n errorText || \"Duplicate idempotency key detected\",\n idempotencyKey,\n );\n }\n if (response.status === 502) {\n throw new ConsumerDiscoveryError(\n errorText || \"Consumer discovery failed\",\n deploymentId,\n );\n }\n if (response.status === 503) {\n throw new ConsumerRegistryNotConfiguredError(\n errorText || \"Consumer registry not configured\",\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"send message\",\n );\n }\n\n const responseData = (await response.json()) as SendMessageResponse;\n\n return responseData;\n }\n\n /**\n * Receive messages from a topic as an async generator.\n *\n * @param options - Receive options\n * @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)\n * @param options.consumerGroup - Consumer group name (pattern: `[A-Za-z0-9_-]+`)\n * @param options.visibilityTimeoutSeconds - Lock duration (default: 30, min: 0, max: 3600)\n * @param options.limit - Max messages to retrieve (default: 1, min: 1, max: 10)\n * @param options.maxConcurrency - Max in-flight messages (default: unlimited, min: 1)\n * @param transport - Deserializer for message payloads\n * @yields Message objects with payload, messageId, receiptHandle, etc.\n * @throws {QueueEmptyError} When no messages available\n * @throws {InvalidLimitError} When limit is outside 1-10 range\n * @throws {ConcurrencyLimitError} When maxConcurrency exceeded\n * @throws {BadRequestError} When parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied\n * @throws {InternalServerError} When server encounters an error\n */\n async *receiveMessages<T = unknown>(\n options: ReceiveMessagesOptions<T>,\n transport: Transport<T>,\n ): AsyncGenerator<Message<T>, void, unknown> {\n const {\n queueName,\n consumerGroup,\n visibilityTimeoutSeconds,\n limit,\n maxConcurrency,\n } = options;\n\n if (limit !== undefined && (limit < 1 || limit > 10)) {\n throw new InvalidLimitError(limit);\n }\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n Accept: \"multipart/mixed\",\n ...this.customHeaders,\n });\n\n if (visibilityTimeoutSeconds !== undefined) {\n headers.set(\n \"Vqs-Visibility-Timeout-Seconds\",\n visibilityTimeoutSeconds.toString(),\n );\n }\n\n if (limit !== undefined) {\n headers.set(\"Vqs-Max-Messages\", limit.toString());\n }\n\n if (maxConcurrency !== undefined) {\n headers.set(\"Vqs-Max-Concurrency\", maxConcurrency.toString());\n }\n\n const effectiveDeploymentId = this.getConsumeDeploymentId();\n if (effectiveDeploymentId) {\n headers.set(\"Vqs-Deployment-Id\", effectiveDeploymentId);\n }\n\n const response = await this.fetch(\n this.buildUrl(queueName, \"consumer\", consumerGroup),\n {\n method: \"POST\",\n headers,\n },\n );\n\n if (response.status === 204) {\n throw new QueueEmptyError(queueName, consumerGroup);\n }\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 429) {\n let errorData: {\n error?: string;\n currentInflight?: number;\n maxConcurrency?: number;\n } = {};\n try {\n errorData = JSON.parse(errorText);\n } catch {\n // ignore parse errors\n }\n throw new ConcurrencyLimitError(\n errorData.error || \"Concurrency limit exceeded or throttled\",\n errorData.currentInflight,\n errorData.maxConcurrency,\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"receive messages\",\n );\n }\n\n for await (const multipartMessage of parseMultipartStream(response)) {\n try {\n const parsedHeaders = parseQueueHeaders(multipartMessage.headers);\n\n if (!parsedHeaders) {\n console.warn(\"Missing required queue headers in multipart part\");\n await consumeStream(multipartMessage.payload);\n continue;\n }\n\n const deserializedPayload = await transport.deserialize(\n multipartMessage.payload,\n );\n\n const message: Message<T> = {\n ...parsedHeaders,\n payload: deserializedPayload,\n };\n\n yield message;\n } catch (error) {\n console.warn(\"Failed to process multipart message:\", error);\n await consumeStream(multipartMessage.payload);\n }\n }\n }\n\n /**\n * Receive a specific message by its ID.\n *\n * @param options - Receive options\n * @param options.queueName - Topic name (pattern: `[A-Za-z0-9_-]+`)\n * @param options.consumerGroup - Consumer group name (pattern: `[A-Za-z0-9_-]+`)\n * @param options.messageId - Message ID to retrieve\n * @param options.visibilityTimeoutSeconds - Lock duration (default: 30, min: 0, max: 3600)\n * @param options.maxConcurrency - Max in-flight messages (default: unlimited, min: 1)\n * @param transport - Deserializer for the message payload\n * @returns Promise with the message\n * @throws {MessageNotFoundError} When message doesn't exist\n * @throws {MessageNotAvailableError} When message is in wrong state or was a duplicate\n * @throws {MessageAlreadyProcessedError} When message was already processed\n * @throws {ConcurrencyLimitError} When maxConcurrency exceeded\n * @throws {BadRequestError} When parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied\n * @throws {InternalServerError} When server encounters an error\n */\n async receiveMessageById<T = unknown>(\n options: ReceiveMessageByIdOptions<T>,\n transport: Transport<T>,\n ): Promise<ReceiveMessageByIdResponse<T>> {\n const {\n queueName,\n consumerGroup,\n messageId,\n visibilityTimeoutSeconds,\n maxConcurrency,\n } = options;\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n Accept: \"multipart/mixed\",\n ...this.customHeaders,\n });\n\n if (visibilityTimeoutSeconds !== undefined) {\n headers.set(\n \"Vqs-Visibility-Timeout-Seconds\",\n visibilityTimeoutSeconds.toString(),\n );\n }\n\n if (maxConcurrency !== undefined) {\n headers.set(\"Vqs-Max-Concurrency\", maxConcurrency.toString());\n }\n\n const effectiveDeploymentId = this.getConsumeDeploymentId();\n if (effectiveDeploymentId) {\n headers.set(\"Vqs-Deployment-Id\", effectiveDeploymentId);\n }\n\n const response = await this.fetch(\n this.buildUrl(queueName, \"consumer\", consumerGroup, \"id\", messageId),\n {\n method: \"POST\",\n headers,\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 404) {\n throw new MessageNotFoundError(messageId);\n }\n if (response.status === 409) {\n let errorData: { error?: string; originalMessageId?: string } = {};\n try {\n errorData = JSON.parse(errorText);\n } catch {\n // ignore parse errors\n }\n\n if (errorData.originalMessageId) {\n throw new MessageNotAvailableError(\n messageId,\n `This message was a duplicate - use originalMessageId: ${errorData.originalMessageId}`,\n );\n }\n throw new MessageNotAvailableError(messageId);\n }\n if (response.status === 410) {\n throw new MessageAlreadyProcessedError(messageId);\n }\n if (response.status === 429) {\n let errorData: {\n error?: string;\n currentInflight?: number;\n maxConcurrency?: number;\n } = {};\n try {\n errorData = JSON.parse(errorText);\n } catch {\n // ignore parse errors\n }\n throw new ConcurrencyLimitError(\n errorData.error || \"Concurrency limit exceeded or throttled\",\n errorData.currentInflight,\n errorData.maxConcurrency,\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"receive message by ID\",\n );\n }\n\n for await (const multipartMessage of parseMultipartStream(response)) {\n const parsedHeaders = parseQueueHeaders(multipartMessage.headers);\n\n if (!parsedHeaders) {\n await consumeStream(multipartMessage.payload);\n throw new MessageCorruptedError(\n messageId,\n \"Missing required queue headers in response\",\n );\n }\n\n const deserializedPayload = await transport.deserialize(\n multipartMessage.payload,\n );\n\n const message: Message<T> = {\n ...parsedHeaders,\n payload: deserializedPayload,\n };\n\n return { message };\n }\n\n throw new MessageNotFoundError(messageId);\n }\n\n /**\n * Delete (acknowledge) a message after successful processing.\n *\n * @param options - Delete options\n * @param options.queueName - Topic name\n * @param options.consumerGroup - Consumer group name\n * @param options.receiptHandle - Receipt handle from the received message (must use same deployment ID as receive)\n * @returns Promise indicating deletion success\n * @throws {MessageNotFoundError} When receipt handle not found\n * @throws {MessageNotAvailableError} When receipt handle invalid or message already processed\n * @throws {BadRequestError} When parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied\n * @throws {InternalServerError} When server encounters an error\n */\n async deleteMessage(\n options: DeleteMessageOptions,\n ): Promise<DeleteMessageResponse> {\n const { queueName, consumerGroup, receiptHandle } = options;\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n ...this.customHeaders,\n });\n\n const effectiveDeploymentId = this.getConsumeDeploymentId();\n if (effectiveDeploymentId) {\n headers.set(\"Vqs-Deployment-Id\", effectiveDeploymentId);\n }\n\n const response = await this.fetch(\n this.buildUrl(\n queueName,\n \"consumer\",\n consumerGroup,\n \"lease\",\n receiptHandle,\n ),\n {\n method: \"DELETE\",\n headers,\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 404) {\n throw new MessageNotFoundError(receiptHandle);\n }\n if (response.status === 409) {\n throw new MessageNotAvailableError(\n receiptHandle,\n errorText ||\n \"Invalid receipt handle, message not in correct state, or already processed\",\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"delete message\",\n \"Missing or invalid receipt handle\",\n );\n }\n\n return { deleted: true };\n }\n\n /**\n * Extend or change the visibility timeout of a message.\n * Used to prevent message redelivery while still processing.\n *\n * @param options - Visibility options\n * @param options.queueName - Topic name\n * @param options.consumerGroup - Consumer group name\n * @param options.receiptHandle - Receipt handle from the received message (must use same deployment ID as receive)\n * @param options.visibilityTimeoutSeconds - New timeout (min: 0, max: 3600, cannot exceed message expiration)\n * @returns Promise indicating success\n * @throws {MessageNotFoundError} When receipt handle not found\n * @throws {MessageNotAvailableError} When receipt handle invalid or message already processed\n * @throws {BadRequestError} When parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied\n * @throws {InternalServerError} When server encounters an error\n */\n async changeVisibility(\n options: ChangeVisibilityOptions,\n ): Promise<ChangeVisibilityResponse> {\n const {\n queueName,\n consumerGroup,\n receiptHandle,\n visibilityTimeoutSeconds,\n } = options;\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n \"Content-Type\": \"application/json\",\n ...this.customHeaders,\n });\n\n const effectiveDeploymentId = this.getConsumeDeploymentId();\n if (effectiveDeploymentId) {\n headers.set(\"Vqs-Deployment-Id\", effectiveDeploymentId);\n }\n\n const response = await this.fetch(\n this.buildUrl(\n queueName,\n \"consumer\",\n consumerGroup,\n \"lease\",\n receiptHandle,\n ),\n {\n method: \"PATCH\",\n headers,\n body: JSON.stringify({ visibilityTimeoutSeconds }),\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 404) {\n throw new MessageNotFoundError(receiptHandle);\n }\n if (response.status === 409) {\n throw new MessageNotAvailableError(\n receiptHandle,\n errorText ||\n \"Invalid receipt handle, message not in correct state, or already processed\",\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"change visibility\",\n \"Missing receipt handle or invalid visibility timeout\",\n );\n }\n\n return { success: true };\n }\n\n /**\n * Alternative endpoint for changing message visibility timeout.\n * Uses the /visibility path suffix and expects visibilityTimeoutSeconds in the body.\n * Functionally equivalent to changeVisibility but follows an alternative API pattern.\n *\n * @param options - Options for changing visibility\n * @returns Promise resolving to change visibility response\n */\n async changeVisibilityAlt(\n options: ChangeVisibilityOptions,\n ): Promise<ChangeVisibilityResponse> {\n const {\n queueName,\n consumerGroup,\n receiptHandle,\n visibilityTimeoutSeconds,\n } = options;\n\n const headers = new Headers({\n Authorization: `Bearer ${await this.getToken()}`,\n \"Content-Type\": \"application/json\",\n ...this.customHeaders,\n });\n\n const effectiveDeploymentId = this.getConsumeDeploymentId();\n if (effectiveDeploymentId) {\n headers.set(\"Vqs-Deployment-Id\", effectiveDeploymentId);\n }\n\n const response = await this.fetch(\n this.buildUrl(\n queueName,\n \"consumer\",\n consumerGroup,\n \"lease\",\n receiptHandle,\n \"visibility\",\n ),\n {\n method: \"PATCH\",\n headers,\n body: JSON.stringify({ visibilityTimeoutSeconds }),\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n if (response.status === 404) {\n throw new MessageNotFoundError(receiptHandle);\n }\n if (response.status === 409) {\n throw new MessageNotAvailableError(\n receiptHandle,\n errorText ||\n \"Invalid receipt handle, message not in correct state, or already processed\",\n );\n }\n throwCommonHttpError(\n response.status,\n response.statusText,\n errorText,\n \"change visibility (alt)\",\n \"Missing receipt handle or invalid visibility timeout\",\n );\n }\n\n return { success: true };\n }\n}\n","/**\n * Development mode utilities for local queue compatibility\n * This file contains helpers that enable local callback triggering in development mode\n *\n * Key behaviors:\n * - Discovers queue routes from vercel.json experimentalTriggers config\n * - Makes HTTP requests to trigger callbacks instead of calling registered handlers\n * - Supports wildcard topic patterns\n * - V3 compatibility: Polls for message visibility before triggering callbacks\n */\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { CloudEvent } from \"./callback\";\nimport { matchesWildcardPattern } from \"./callback\";\nimport { QueueClient } from \"./client\";\nimport { JsonTransport } from \"./transports\";\nimport { MessageNotFoundError, MessageAlreadyProcessedError } from \"./types\";\n\n/**\n * Global key for cached route mappings from vercel.json\n */\nconst ROUTE_MAPPINGS_KEY = Symbol.for(\"@vercel/queue.devRouteMappings\");\n\n/**\n * Route mapping from vercel.json experimentalTriggers\n */\ninterface DevRouteMapping {\n urlPath: string;\n topic: string;\n consumer: string;\n}\n\n/**\n * Convert a file path from vercel.json to a URL path\n * e.g., \"app/api/vm/queue/route.ts\" → \"/api/vm/queue\"\n */\nfunction filePathToUrlPath(filePath: string): string {\n let urlPath = filePath\n .replace(/^app\\//, \"/\")\n .replace(/^pages\\//, \"/\")\n .replace(/\\/route\\.(ts|js|tsx|jsx)$/, \"\")\n .replace(/\\.(ts|js|tsx|jsx)$/, \"\");\n\n if (!urlPath.startsWith(\"/\")) {\n urlPath = \"/\" + urlPath;\n }\n\n return urlPath;\n}\n\n/**\n * Read and cache route mappings from vercel.json\n * Returns null if vercel.json doesn't exist or has no queue triggers\n */\nfunction getDevRouteMappings(): DevRouteMapping[] | null {\n const g = globalThis as typeof globalThis & {\n [ROUTE_MAPPINGS_KEY]?: DevRouteMapping[] | null;\n };\n\n if (ROUTE_MAPPINGS_KEY in g) {\n return g[ROUTE_MAPPINGS_KEY] ?? null;\n }\n\n try {\n const vercelJsonPath = path.join(process.cwd(), \"vercel.json\");\n if (!fs.existsSync(vercelJsonPath)) {\n g[ROUTE_MAPPINGS_KEY] = null;\n return null;\n }\n\n const vercelJson = JSON.parse(fs.readFileSync(vercelJsonPath, \"utf-8\")) as {\n functions?: {\n [filePath: string]: {\n experimentalTriggers?: Array<{\n type: string;\n topic?: string;\n consumer?: string;\n }>;\n };\n };\n };\n\n if (!vercelJson.functions) {\n g[ROUTE_MAPPINGS_KEY] = null;\n return null;\n }\n\n const mappings: DevRouteMapping[] = [];\n\n for (const [filePath, config] of Object.entries(vercelJson.functions)) {\n if (!config.experimentalTriggers) continue;\n\n for (const trigger of config.experimentalTriggers) {\n if (\n trigger.type?.startsWith(\"queue/\") &&\n trigger.topic &&\n trigger.consumer\n ) {\n mappings.push({\n urlPath: filePathToUrlPath(filePath),\n topic: trigger.topic,\n consumer: trigger.consumer,\n });\n }\n }\n }\n\n g[ROUTE_MAPPINGS_KEY] = mappings.length > 0 ? mappings : null;\n return g[ROUTE_MAPPINGS_KEY];\n } catch (error) {\n console.warn(\"[Dev Mode] Failed to read vercel.json:\", error);\n g[ROUTE_MAPPINGS_KEY] = null;\n return null;\n }\n}\n\n/**\n * Find routes that match a topic name (supports wildcards)\n */\nfunction findMatchingRoutes(topicName: string): DevRouteMapping[] {\n const mappings = getDevRouteMappings();\n if (!mappings) {\n return [];\n }\n\n return mappings.filter((mapping) => {\n if (mapping.topic.includes(\"*\")) {\n return matchesWildcardPattern(topicName, mapping.topic);\n }\n return mapping.topic === topicName;\n });\n}\n\n/**\n * Check if running in development mode\n */\nexport function isDevMode(): boolean {\n return process.env.NODE_ENV === \"development\";\n}\n\n/**\n * Configuration for visibility polling in V3\n */\nconst DEV_VISIBILITY_POLL_INTERVAL = 50;\nconst DEV_VISIBILITY_MAX_WAIT = 5000;\nconst DEV_VISIBILITY_BACKOFF_MULTIPLIER = 2;\n\n/**\n * Wait for a message to become visible in the queue (V3 eventual consistency)\n * Polls receiveMessageById with visibilityTimeoutSeconds=0 until the message is available\n * @returns true if message became visible, false if timed out\n * @internal\n */\nasync function waitForMessageVisibility(\n topicName: string,\n consumerGroup: string,\n messageId: string,\n): Promise<boolean> {\n const client = new QueueClient();\n const transport = new JsonTransport();\n\n let elapsed = 0;\n let interval = DEV_VISIBILITY_POLL_INTERVAL;\n\n while (elapsed < DEV_VISIBILITY_MAX_WAIT) {\n try {\n await client.receiveMessageById(\n {\n queueName: topicName,\n consumerGroup,\n messageId,\n visibilityTimeoutSeconds: 0,\n },\n transport,\n );\n return true;\n } catch (error) {\n if (error instanceof MessageNotFoundError) {\n await new Promise((resolve) => setTimeout(resolve, interval));\n elapsed += interval;\n interval = Math.min(\n interval * DEV_VISIBILITY_BACKOFF_MULTIPLIER,\n DEV_VISIBILITY_MAX_WAIT - elapsed,\n );\n continue;\n }\n if (error instanceof MessageAlreadyProcessedError) {\n console.log(\n `[Dev Mode] Message already processed: topic=\"${topicName}\" messageId=\"${messageId}\"`,\n );\n return false;\n }\n console.error(\n `[Dev Mode] Error polling for message visibility: topic=\"${topicName}\" messageId=\"${messageId}\"`,\n error,\n );\n return false;\n }\n }\n\n console.warn(\n `[Dev Mode] Message visibility timeout after ${DEV_VISIBILITY_MAX_WAIT}ms: topic=\"${topicName}\" messageId=\"${messageId}\"`,\n );\n return false;\n}\n\n/**\n * Trigger development mode callbacks for a topic\n * Discovers routes from vercel.json and makes HTTP requests to trigger callbacks\n * Waits for message visibility in V3 before making requests\n * @internal\n */\nexport function triggerDevCallbacks(\n topicName: string,\n messageId: string,\n delaySeconds?: number,\n): void {\n if (delaySeconds && delaySeconds > 0) {\n console.log(\n `[Dev Mode] Message sent with delay: topic=\"${topicName}\" messageId=\"${messageId}\" delay=${delaySeconds}s`,\n );\n setTimeout(() => {\n triggerDevCallbacks(topicName, messageId);\n }, delaySeconds * 1000);\n return;\n }\n\n console.log(\n `[Dev Mode] Message sent: topic=\"${topicName}\" messageId=\"${messageId}\"`,\n );\n\n const matchingRoutes = findMatchingRoutes(topicName);\n\n if (matchingRoutes.length === 0) {\n console.log(\n `[Dev Mode] No matching routes in vercel.json for topic \"${topicName}\"`,\n );\n return;\n }\n\n const consumerGroups = matchingRoutes.map((r) => r.consumer);\n\n console.log(\n `[Dev Mode] Scheduling callbacks for topic=\"${topicName}\" messageId=\"${messageId}\" → consumers: [${consumerGroups.join(\", \")}]`,\n );\n\n (async () => {\n const firstRoute = matchingRoutes[0];\n const isVisible = await waitForMessageVisibility(\n topicName,\n firstRoute.consumer,\n messageId,\n );\n\n if (!isVisible) {\n console.warn(\n `[Dev Mode] Skipping callbacks - message not visible: topic=\"${topicName}\" messageId=\"${messageId}\"`,\n );\n return;\n }\n\n const port = process.env.PORT || 3000;\n const baseUrl = `http://localhost:${port}`;\n\n for (const route of matchingRoutes) {\n const url = `${baseUrl}${route.urlPath}`;\n\n console.log(\n `[Dev Mode] Invoking handler: topic=\"${topicName}\" consumer=\"${route.consumer}\" messageId=\"${messageId}\" url=\"${url}\"`,\n );\n\n const cloudEvent: CloudEvent = {\n type: \"com.vercel.queue.v1beta\",\n source: `/topic/${topicName}/consumer/${route.consumer}`,\n id: messageId,\n datacontenttype: \"application/json\",\n data: {\n messageId,\n queueName: topicName,\n consumerGroup: route.consumer,\n },\n time: new Date().toISOString(),\n specversion: \"1.0\",\n };\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/cloudevents+json\",\n },\n body: JSON.stringify(cloudEvent),\n });\n\n if (response.ok) {\n try {\n const responseData = (await response.json()) as {\n status?: string;\n };\n if (responseData.status === \"success\") {\n console.log(\n `[Dev Mode] ✓ Message processed successfully: topic=\"${topicName}\" consumer=\"${route.consumer}\" messageId=\"${messageId}\"`,\n );\n }\n } catch {\n console.warn(\n `[Dev Mode] Handler returned OK but response was not JSON: topic=\"${topicName}\" consumer=\"${route.consumer}\"`,\n );\n }\n } else {\n try {\n const errorData = (await response.json()) as { error?: string };\n console.error(\n `[Dev Mode] ✗ Handler failed: topic=\"${topicName}\" consumer=\"${route.consumer}\" messageId=\"${messageId}\" error=\"${errorData.error || response.statusText}\"`,\n );\n } catch {\n console.error(\n `[Dev Mode] ✗ Handler failed: topic=\"${topicName}\" consumer=\"${route.consumer}\" messageId=\"${messageId}\" status=${response.status}`,\n );\n }\n }\n } catch (error) {\n console.error(\n `[Dev Mode] ✗ HTTP request failed: topic=\"${topicName}\" consumer=\"${route.consumer}\" messageId=\"${messageId}\" url=\"${url}\"`,\n error,\n );\n }\n }\n })();\n}\n\n/**\n * Clear cached route mappings - for testing only\n * @internal\n */\nfunction clearDevRouteMappings(): void {\n const g = globalThis as typeof globalThis & {\n [ROUTE_MAPPINGS_KEY]?: DevRouteMapping[] | null;\n };\n delete g[ROUTE_MAPPINGS_KEY];\n}\n\n// Export for testing\nif (process.env.NODE_ENV === \"test\" || process.env.VITEST) {\n (globalThis as any).__clearDevRouteMappings = clearDevRouteMappings;\n}\n","/**\n * Vercel Queue Service client types\n */\nimport type { Transport } from \"./transports\";\n\n// Re-export transport interface for convenience\nexport type { Transport };\n\nexport interface QueueClientOptions {\n /**\n * Base URL for the Vercel Queue Service API.\n * Can also be set via VERCEL_QUEUE_BASE_URL environment variable.\n * @default \"https://vercel-queue.com\"\n */\n baseUrl?: string;\n\n /**\n * Base path for API endpoints.\n * Can also be set via VERCEL_QUEUE_BASE_PATH environment variable.\n * @default \"/api/v3/topic\"\n */\n basePath?: string;\n\n /**\n * Authentication token for the Vercel Queue Service API.\n * If not provided, the client will attempt to get a token via OIDC\n * when running in a Vercel Function environment.\n */\n token?: string;\n\n /**\n * Custom headers to include in all requests.\n */\n headers?: Record<string, string>;\n\n /**\n * Deployment ID to include in requests.\n * Used for message routing and lease validation.\n * @default process.env.VERCEL_DEPLOYMENT_ID if pinToDeployment is true\n */\n deploymentId?: string;\n\n /**\n * Whether to pin messages to the current deployment when publishing.\n * When true, sends VERCEL_DEPLOYMENT_ID from environment, ensuring\n * messages are routed to consumers on the same deployment.\n *\n * - Only affects send/publish operations\n * - Consume operations always send deployment ID in production\n * - Ignored in development mode (deployment ID is never sent locally)\n * @default true\n */\n pinToDeployment?: boolean;\n}\n\n/**\n * Options for publishing messages to a topic.\n */\nexport interface PublishOptions {\n /**\n * Unique key to prevent duplicate message submissions.\n * Deduplication window: `min(message retention, 24 hours)`.\n */\n idempotencyKey?: string;\n\n /**\n * Message retention time in seconds. After this period, the message expires.\n * @default 86400 (24 hours)\n * @minimum 60 (1 minute)\n * @maximum 86400 (24 hours)\n */\n retentionSeconds?: number;\n\n /**\n * Delay delivery of the message by this many seconds.\n * The message will not be visible to consumers until the delay has passed.\n * @default 0\n * @minimum 0\n * @maximum Value of retentionSeconds (delay cannot exceed retention)\n */\n delaySeconds?: number;\n}\n\nexport interface SendMessageOptions<T = unknown> extends PublishOptions {\n /**\n * The topic/queue name to send the message to.\n * Must match pattern: `[A-Za-z0-9_-]+`\n */\n queueName: string;\n\n /**\n * The message payload. Will be serialized using the provided transport.\n */\n payload: T;\n}\n\nexport interface SendMessageResponse {\n /**\n * The generated message ID\n */\n messageId: string;\n}\n\nexport interface Message<T = unknown> {\n /**\n * Unique message identifier. Used for receive-by-ID operations.\n */\n messageId: string;\n\n /**\n * The deserialized message payload.\n * Note: If using StreamTransport, ensure proper cleanup by calling\n * `transport.finalize(payload)` when done processing, especially in error cases.\n */\n payload: T;\n\n /**\n * Number of times this message has been delivered.\n * Starts at 1 for the first delivery, increments on each retry.\n */\n deliveryCount: number;\n\n /**\n * Timestamp when the message was created/published.\n */\n createdAt: Date;\n\n /**\n * MIME type of the message content.\n * Set by the transport's `contentType` property during publish.\n */\n contentType: string;\n\n /**\n * Receipt handle (lease token) for this message delivery.\n * Required for delete and visibility extension operations.\n * Valid only until the visibility timeout expires.\n */\n receiptHandle: string;\n}\n\nexport interface ReceiveMessagesOptions<T = unknown> {\n /**\n * The topic/queue name to receive messages from.\n * Must match pattern: `[A-Za-z0-9_-]+`\n */\n queueName: string;\n\n /**\n * Consumer group name. Each consumer group maintains independent message state.\n * Must match pattern: `[A-Za-z0-9_-]+`\n */\n consumerGroup: string;\n\n /**\n * Time in seconds that messages will be invisible to other consumers after receipt.\n * Set to 0 for immediate re-visibility (useful for peeking).\n * @default 30\n * @minimum 0\n * @maximum 3600 (1 hour)\n */\n visibilityTimeoutSeconds?: number;\n\n /**\n * Maximum number of messages to retrieve in a single request.\n * @default 1\n * @minimum 1\n * @maximum 10\n */\n limit?: number;\n\n /**\n * Maximum concurrent in-flight messages for this consumer group.\n * When limit is reached, receive requests throw ConcurrencyLimitError.\n * @default unlimited\n * @minimum 1\n */\n maxConcurrency?: number;\n}\n\nexport interface DeleteMessageOptions {\n /**\n * The topic/queue name the message belongs to.\n */\n queueName: string;\n\n /**\n * Consumer group name.\n */\n consumerGroup: string;\n\n /**\n * Receipt handle received when the message was consumed.\n */\n receiptHandle: string;\n}\n\nexport interface DeleteMessageResponse {\n /**\n * Whether the message was successfully deleted\n */\n deleted: boolean;\n}\n\nexport interface ChangeVisibilityOptions {\n /**\n * The topic/queue name the message belongs to.\n */\n queueName: string;\n\n /**\n * Consumer group name.\n */\n consumerGroup: string;\n\n /**\n * Receipt handle received when the message was consumed.\n */\n receiptHandle: string;\n\n /**\n * New visibility timeout in seconds.\n * Cannot extend beyond the message's original expiration time.\n * @minimum 0\n * @maximum 3600 (1 hour)\n */\n visibilityTimeoutSeconds: number;\n}\n\nexport interface ChangeVisibilityResponse {\n /**\n * Whether the visibility was successfully updated\n */\n success: boolean;\n}\n\n/**\n * Message metadata provided to handlers\n */\nexport interface MessageMetadata {\n messageId: string;\n deliveryCount: number;\n createdAt: Date;\n topicName: string;\n consumerGroup: string;\n}\n\n/**\n * Message handler function type\n */\nexport type MessageHandler<T = unknown> = (\n message: T,\n metadata: MessageMetadata,\n) => Promise<void> | void;\n\n/**\n * Options for creating a ConsumerGroup instance.\n */\nexport interface ConsumerGroupOptions<T = unknown> {\n /**\n * Serializer/deserializer for the payload.\n * Built-in options: JsonTransport, BufferTransport, StreamTransport.\n * @default JsonTransport\n */\n transport?: Transport<T>;\n\n /**\n * Time in seconds that messages will be invisible to other consumers after receipt.\n * The ConsumerGroup will automatically extend this timeout during processing.\n * @default 30\n * @minimum 0\n * @maximum 3600 (1 hour)\n */\n visibilityTimeoutSeconds?: number;\n\n /**\n * How often (in seconds) to refresh the visibility timeout during message processing.\n * Should be less than visibilityTimeoutSeconds to prevent message redelivery.\n * @default Math.floor(visibilityTimeoutSeconds / 3)\n */\n visibilityRefreshInterval?: number;\n}\n\nexport interface ReceiveMessageByIdOptions<T = unknown> {\n /**\n * The topic/queue name to receive the message from.\n * Must match pattern: `[A-Za-z0-9_-]+`\n */\n queueName: string;\n\n /**\n * Consumer group name.\n * Must match pattern: `[A-Za-z0-9_-]+`\n */\n consumerGroup: string;\n\n /**\n * The specific message ID to retrieve.\n */\n messageId: string;\n\n /**\n * Time in seconds that the message will be invisible to other consumers after receipt.\n * @default 30\n * @minimum 0\n * @maximum 3600 (1 hour)\n */\n visibilityTimeoutSeconds?: number;\n\n /**\n * Maximum concurrent in-flight messages for this consumer group.\n * @default unlimited\n * @minimum 1\n */\n maxConcurrency?: number;\n}\n\nexport interface ReceiveMessageByIdResponse<T = unknown> {\n message: Message<T>;\n}\n\n/**\n * Error thrown when a message does not exist or has expired.\n */\nexport class MessageNotFoundError extends Error {\n constructor(messageId: string) {\n super(`Message ${messageId} not found`);\n this.name = \"MessageNotFoundError\";\n }\n}\n\n/**\n * Error thrown when a message exists but cannot be processed.\n * This can happen when the message is in the wrong state or already claimed by another consumer.\n */\nexport class MessageNotAvailableError extends Error {\n constructor(messageId: string, reason?: string) {\n super(\n `Message ${messageId} not available for processing${reason ? `: ${reason}` : \"\"}`,\n );\n this.name = \"MessageNotAvailableError\";\n }\n}\n\n/**\n * Error thrown when message data is corrupted or can't be parsed\n */\nexport class MessageCorruptedError extends Error {\n constructor(messageId: string, reason: string) {\n super(`Message ${messageId} is corrupted: ${reason}`);\n this.name = \"MessageCorruptedError\";\n }\n}\n\n/**\n * Error thrown when there are no messages available in the queue.\n */\nexport class QueueEmptyError extends Error {\n constructor(queueName: string, consumerGroup: string) {\n super(\n `No messages available in queue \"${queueName}\" for consumer group \"${consumerGroup}\"`,\n );\n this.name = \"QueueEmptyError\";\n }\n}\n\n/**\n * Error thrown when a message is temporarily locked by another consumer.\n * The message is currently being processed and cannot be claimed.\n */\nexport class MessageLockedError extends Error {\n /** Suggested retry delay in seconds, if provided by the server. */\n public readonly retryAfter?: number;\n\n constructor(messageId: string, retryAfter?: number) {\n const retryMessage = retryAfter\n ? ` Retry after ${retryAfter} seconds.`\n : \" Try again later.\";\n super(`Message ${messageId} is temporarily locked.${retryMessage}`);\n this.name = \"MessageLockedError\";\n this.retryAfter = retryAfter;\n }\n}\n\n/**\n * Error thrown when authentication fails.\n * This typically means the token is missing, invalid, or expired.\n */\nexport class UnauthorizedError extends Error {\n constructor(message: string = \"Missing or invalid authentication token\") {\n super(message);\n this.name = \"UnauthorizedError\";\n }\n}\n\n/**\n * Error thrown when access is forbidden.\n * This typically means the queue belongs to a different environment or project.\n */\nexport class ForbiddenError extends Error {\n constructor(\n message: string = \"Queue environment doesn't match token environment\",\n ) {\n super(message);\n this.name = \"ForbiddenError\";\n }\n}\n\n/**\n * Error thrown when request parameters are invalid.\n */\nexport class BadRequestError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"BadRequestError\";\n }\n}\n\n/**\n * Error thrown when the server encounters an unexpected error.\n */\nexport class InternalServerError extends Error {\n constructor(message: string = \"Unexpected server error\") {\n super(message);\n this.name = \"InternalServerError\";\n }\n}\n\n/**\n * Error thrown when the batch limit parameter is outside the valid range.\n * The limit must be between 1 and 10 (inclusive).\n */\nexport class InvalidLimitError extends Error {\n constructor(limit: number, min: number = 1, max: number = 10) {\n super(`Invalid limit: ${limit}. Limit must be between ${min} and ${max}.`);\n this.name = \"InvalidLimitError\";\n }\n}\n\n/**\n * Error thrown when attempting to process a message that has already been successfully processed.\n */\nexport class MessageAlreadyProcessedError extends Error {\n constructor(messageId: string) {\n super(`Message ${messageId} has already been processed`);\n this.name = \"MessageAlreadyProcessedError\";\n }\n}\n\n/**\n * Error thrown when the concurrency limit is exceeded.\n * This occurs when maxConcurrency is set and too many messages are already in-flight.\n */\nexport class ConcurrencyLimitError extends Error {\n /** Current number of in-flight messages for this consumer group. */\n public readonly currentInflight?: number;\n /** Maximum allowed concurrent messages (as configured). */\n public readonly maxConcurrency?: number;\n\n constructor(\n message: string = \"Concurrency limit exceeded\",\n currentInflight?: number,\n maxConcurrency?: number,\n ) {\n super(message);\n this.name = \"ConcurrencyLimitError\";\n this.currentInflight = currentInflight;\n this.maxConcurrency = maxConcurrency;\n }\n}\n\n/**\n * Error thrown when a duplicate idempotency key is detected.\n * The message was already sent within the deduplication window.\n */\nexport class DuplicateMessageError extends Error {\n public readonly idempotencyKey?: string;\n\n constructor(message: string, idempotencyKey?: string) {\n super(message);\n this.name = \"DuplicateMessageError\";\n this.idempotencyKey = idempotencyKey;\n }\n}\n\n/**\n * Error thrown when consumer discovery fails.\n * This typically means the deployment could not be reached or is not configured correctly.\n */\nexport class ConsumerDiscoveryError extends Error {\n public readonly deploymentId?: string;\n\n constructor(message: string, deploymentId?: string) {\n super(message);\n this.name = \"ConsumerDiscoveryError\";\n this.deploymentId = deploymentId;\n }\n}\n\n/**\n * Error thrown when the consumer registry is not configured for the project.\n */\nexport class ConsumerRegistryNotConfiguredError extends Error {\n constructor(message: string = \"Consumer registry not configured\") {\n super(message);\n this.name = \"ConsumerRegistryNotConfiguredError\";\n }\n}\n","export { getVercelOidcToken } from \"@vercel/oidc\";\n","import { QueueClient } from \"./client\";\nimport { JsonTransport } from \"./transports\";\nimport type {\n ConsumerGroupOptions,\n Message,\n MessageHandler,\n Transport,\n} from \"./types\";\n\n/**\n * Options for the consume method\n */\nexport interface ConsumeOptions {\n /** The specific message ID to consume (if not provided, consumes next available message) */\n messageId?: string;\n}\n\n/**\n * A ConsumerGroup processes messages from a topic with automatic lifecycle management.\n *\n * Features:\n * - Independent message state per group (each group receives a copy of every message)\n * - Automatic visibility timeout extension during processing\n * - Automatic message deletion on successful handler completion\n */\nexport class ConsumerGroup<T = unknown> {\n private client: QueueClient;\n private topicName: string;\n private consumerGroupName: string;\n private visibilityTimeout: number;\n private refreshInterval: number;\n private transport: Transport<T>;\n\n /**\n * Create a new ConsumerGroup instance.\n *\n * @param client - QueueClient instance to use for API calls\n * @param topicName - Name of the topic to consume from (pattern: `[A-Za-z0-9_-]+`)\n * @param consumerGroupName - Name of the consumer group (pattern: `[A-Za-z0-9_-]+`)\n * @param options - Optional configuration\n * @param options.transport - Payload serializer (default: JsonTransport)\n * @param options.visibilityTimeoutSeconds - Message lock duration (default: 30, max: 3600)\n * @param options.visibilityRefreshInterval - Lock refresh interval in seconds (default: visibilityTimeout / 3)\n */\n constructor(\n client: QueueClient,\n topicName: string,\n consumerGroupName: string,\n options: ConsumerGroupOptions<T> = {},\n ) {\n this.client = client;\n this.topicName = topicName;\n this.consumerGroupName = consumerGroupName;\n this.visibilityTimeout = options.visibilityTimeoutSeconds ?? 30;\n this.refreshInterval =\n options.visibilityRefreshInterval ??\n Math.floor(this.visibilityTimeout / 3);\n this.transport = options.transport || new JsonTransport<T>();\n }\n\n /**\n * Starts a background loop that periodically extends the visibility timeout for a message.\n */\n private startVisibilityExtension(\n receiptHandle: string,\n ): (waitForCompletion?: boolean) => Promise<void> {\n let isRunning = true;\n let isResolved = false;\n let resolveLifecycle: () => void;\n let timeoutId: NodeJS.Timeout | null = null;\n\n // Promise that tracks the actual termination of the extension loop\n const lifecyclePromise = new Promise<void>((resolve) => {\n resolveLifecycle = resolve;\n });\n\n const safeResolve = () => {\n if (!isResolved) {\n isResolved = true;\n resolveLifecycle();\n }\n };\n\n const extend = async (): Promise<void> => {\n // Check if we should stop before attempting extension\n if (!isRunning) {\n safeResolve();\n return;\n }\n\n try {\n await this.client.changeVisibility({\n queueName: this.topicName,\n consumerGroup: this.consumerGroupName,\n receiptHandle,\n visibilityTimeoutSeconds: this.visibilityTimeout,\n });\n\n // Schedule next extension if still running\n if (isRunning) {\n timeoutId = setTimeout(() => extend(), this.refreshInterval * 1000);\n } else {\n safeResolve();\n }\n } catch (error) {\n console.error(\n `Failed to extend visibility for receipt handle ${receiptHandle}:`,\n error,\n );\n safeResolve();\n }\n };\n\n // Schedule the first extension attempt\n timeoutId = setTimeout(() => extend(), this.refreshInterval * 1000);\n\n // Return a function to stop the extension loop\n return async (waitForCompletion: boolean = false) => {\n // Signal the loop to stop\n isRunning = false;\n\n // Cancel any pending timeout to avoid unnecessary waiting\n if (timeoutId) {\n clearTimeout(timeoutId);\n timeoutId = null;\n }\n\n // Only wait for in-flight operations if explicitly requested\n if (waitForCompletion) {\n // Wait for the loop to actually terminate\n // This ensures any in-progress extension completes or fails\n await lifecyclePromise;\n } else {\n safeResolve();\n }\n };\n }\n\n private async processMessage<TPayload>(\n message: Message<TPayload>,\n handler: MessageHandler<TPayload>,\n ): Promise<void> {\n const stopExtension = this.startVisibilityExtension(message.receiptHandle);\n\n try {\n await handler(message.payload, {\n messageId: message.messageId,\n deliveryCount: message.deliveryCount,\n createdAt: message.createdAt,\n topicName: this.topicName,\n consumerGroup: this.consumerGroupName,\n });\n // Stop extensions immediately - we don't need to wait for in-flight extensions\n // since we're about to delete the message anyway\n await stopExtension();\n\n await this.client.deleteMessage({\n queueName: this.topicName,\n consumerGroup: this.consumerGroupName,\n receiptHandle: message.receiptHandle,\n });\n } catch (error) {\n // Stop extensions immediately on error - fail fast without waiting\n // for any in-flight extension attempts\n await stopExtension();\n\n // Clean up the message payload if the transport supports it and payload exists\n // Only call finalize for non-void payloads since transport is typed for T, not void\n if (\n this.transport.finalize &&\n message.payload !== undefined &&\n message.payload !== null\n ) {\n try {\n // Safe cast: when processMessage<T> is called, TPayload is T\n // when processMessage<void> is called, payload is undefined so this won't execute\n await this.transport.finalize(message.payload as T);\n } catch (finalizeError) {\n console.warn(\"Failed to finalize message payload:\", finalizeError);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Consume the next available message from the queue.\n *\n * The message is automatically:\n * - Locked with the configured visibility timeout\n * - Kept alive via periodic visibility extensions during processing\n * - Deleted upon successful handler completion\n * - Released for retry if the handler throws an error\n *\n * @param handler - Function to process the message payload and metadata\n * @returns Promise that resolves when the message is processed and deleted\n * @throws {QueueEmptyError} When no messages available\n * @throws {ConcurrencyLimitError} When maxConcurrency exceeded\n * @throws Handler errors are re-thrown after cleanup\n */\n async consume(handler: MessageHandler<T>): Promise<void>;\n\n /**\n * Consume a specific message by its ID.\n *\n * Used for targeted message processing, typically from webhook callbacks.\n *\n * @param handler - Function to process the message payload and metadata\n * @param options - Options containing the messageId to consume\n * @param options.messageId - Specific message ID to consume\n * @returns Promise that resolves when the message is processed and deleted\n * @throws {MessageNotFoundError} When message doesn't exist\n * @throws {MessageNotAvailableError} When message in wrong state\n * @throws {MessageAlreadyProcessedError} When already processed\n * @throws Handler errors are re-thrown after cleanup\n */\n async consume(\n handler: MessageHandler<T>,\n options: { messageId: string },\n ): Promise<void>;\n\n async consume(\n handler: MessageHandler<T>,\n options?: ConsumeOptions,\n ): Promise<void> {\n if (options?.messageId) {\n const response = await this.client.receiveMessageById(\n {\n queueName: this.topicName,\n consumerGroup: this.consumerGroupName,\n messageId: options.messageId,\n visibilityTimeoutSeconds: this.visibilityTimeout,\n },\n this.transport,\n );\n await this.processMessage<T>(response.message, handler);\n } else {\n let messageFound = false;\n\n for await (const message of this.client.receiveMessages<T>(\n {\n queueName: this.topicName,\n consumerGroup: this.consumerGroupName,\n visibilityTimeoutSeconds: this.visibilityTimeout,\n limit: 1,\n },\n this.transport,\n )) {\n messageFound = true;\n await this.processMessage<T>(message, handler);\n break;\n }\n\n if (!messageFound) {\n throw new Error(\"No messages available\");\n }\n }\n }\n\n /**\n * Get the consumer group name\n */\n get name(): string {\n return this.consumerGroupName;\n }\n\n /**\n * Get the topic name this consumer group is subscribed to\n */\n get topic(): string {\n return this.topicName;\n }\n}\n","import { QueueClient } from \"./client\";\nimport { ConsumerGroup } from \"./consumer-group\";\nimport { JsonTransport } from \"./transports\";\nimport type { ConsumerGroupOptions, PublishOptions, Transport } from \"./types\";\nimport { isDevMode, triggerDevCallbacks } from \"./dev\";\n\n/**\n * A Topic represents a named channel for publishing messages in a pub/sub pattern\n */\nexport class Topic<T = unknown> {\n private client: QueueClient;\n private topicName: string;\n private transport: Transport<T>;\n\n /**\n * Create a new Topic instance\n * @param client QueueClient instance to use for API calls\n * @param topicName Name of the topic to work with\n * @param transport Optional serializer/deserializer for the payload (defaults to JSON)\n */\n constructor(\n client: QueueClient,\n topicName: string,\n transport?: Transport<T>,\n ) {\n this.client = client;\n this.topicName = topicName;\n this.transport = transport || new JsonTransport<T>();\n }\n\n /**\n * Publish a message to the topic\n * @param payload The data to publish\n * @param options Optional publish options\n * @returns An object containing the message ID\n * @throws {BadRequestError} When request parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied (environment mismatch)\n * @throws {InternalServerError} When server encounters an error\n */\n async publish(\n payload: T,\n options?: PublishOptions,\n ): Promise<{ messageId: string }> {\n const result = await this.client.sendMessage<T>(\n {\n queueName: this.topicName,\n payload,\n idempotencyKey: options?.idempotencyKey,\n retentionSeconds: options?.retentionSeconds,\n delaySeconds: options?.delaySeconds,\n },\n this.transport,\n );\n\n // In development mode, automatically trigger registered callbacks after 1s\n if (isDevMode()) {\n triggerDevCallbacks(this.topicName, result.messageId);\n }\n\n return { messageId: result.messageId };\n }\n\n /**\n * Create a consumer group for this topic\n * @param consumerGroupName Name of the consumer group\n * @param options Optional configuration for the consumer group\n * @returns A ConsumerGroup instance\n */\n consumerGroup<U = T>(\n consumerGroupName: string,\n options?: ConsumerGroupOptions<U>,\n ): ConsumerGroup<U> {\n // If no transport is provided in options, use the topic's transport if types match\n const consumerOptions: ConsumerGroupOptions<U> = {\n ...options,\n transport:\n options?.transport || (this.transport as unknown as Transport<U>),\n };\n\n return new ConsumerGroup<U>(\n this.client,\n this.topicName,\n consumerGroupName,\n consumerOptions,\n );\n }\n\n /**\n * Get the topic name\n */\n get name(): string {\n return this.topicName;\n }\n\n /**\n * Get the transport used by this topic\n */\n get serializer(): Transport<T> {\n return this.transport;\n }\n}\n","/**\n * Queue Callback utilities for handling incoming webhook payloads from Vercel triggers\n */\nimport { QueueClient } from \"./client\";\nimport { Topic } from \"./topic\";\nimport type { MessageHandler } from \"./types\";\n\n/**\n * CloudEvent specification for queue callbacks\n */\nexport interface CloudEvent<T = unknown> {\n type: string;\n source: string;\n id: string;\n datacontenttype: string;\n data: T;\n time?: string;\n specversion?: string;\n}\n\n/**\n * Configuration object with handlers for different topics and consumer groups\n */\nexport type CallbackHandlers = {\n [topicName: string]: { [consumerGroup: string]: MessageHandler };\n};\n\n/**\n * Options for handleCallback.\n */\nexport interface HandleCallbackOptions {\n /**\n * QueueClient instance to use for processing messages.\n * If not provided, a default client is created with OIDC authentication.\n */\n client?: QueueClient;\n\n /**\n * Time in seconds that messages will be invisible to other consumers during processing.\n * The handler will automatically extend this timeout while processing.\n * @default 30\n * @minimum 0\n * @maximum 3600 (1 hour)\n */\n visibilityTimeoutSeconds?: number;\n}\n\n/**\n * Parsed callback request information\n */\nexport type ParsedCallbackRequest = {\n queueName: string;\n consumerGroup: string;\n messageId: string;\n};\n\n/**\n * Validate wildcard pattern according to rules:\n * - * may only appear once\n * - * may only appear at the end of the topic name\n */\nfunction validateWildcardPattern(pattern: string): boolean {\n const firstIndex = pattern.indexOf(\"*\");\n const lastIndex = pattern.lastIndexOf(\"*\");\n\n // Rule 1: * may only appear once (first and last index should be the same)\n if (firstIndex !== lastIndex) {\n return false;\n }\n\n // If no asterisk found, this is not a wildcard pattern\n if (firstIndex === -1) {\n return false;\n }\n\n // Rule 2: * may only appear at the end (index should equal length - 1)\n if (firstIndex !== pattern.length - 1) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Check if a topic name matches a wildcard pattern.\n * @param topicName - The topic name to test\n * @param pattern - A wildcard pattern ending with `*`\n * @returns true if topicName starts with the pattern prefix\n */\nexport function matchesWildcardPattern(\n topicName: string,\n pattern: string,\n): boolean {\n // No need to validate here since patterns are pre-validated at setup time\n const prefix = pattern.slice(0, -1); // Remove the trailing *\n return topicName.startsWith(prefix);\n}\n\n/**\n * Find handler for a topic name, supporting wildcard patterns\n */\nfunction findTopicHandler(\n queueName: string,\n handlers: CallbackHandlers,\n): { [consumerGroup: string]: MessageHandler } | null {\n // First, try exact match\n const exactHandler = handlers[queueName];\n if (exactHandler) {\n return exactHandler;\n }\n\n // Then try wildcard patterns (all patterns are pre-validated)\n for (const pattern in handlers) {\n if (pattern.includes(\"*\") && matchesWildcardPattern(queueName, pattern)) {\n return handlers[pattern];\n }\n }\n\n return null;\n}\n\n/**\n * Parse and validate callback request using CloudEvent specification\n *\n * Extracts queue information from CloudEvent format and validates\n * that all required fields are present.\n *\n * @param request The incoming webhook request\n * @returns Parsed queue information\n * @throws Error if required fields are missing\n *\n * @example\n * ```typescript\n * // In Next.js API route\n * export async function POST(request: Request) {\n * try {\n * const { queueName, consumerGroup, messageId } = parseCallback(request);\n *\n * // Use the parsed information...\n * await myWorkflow.handleWebhook(queueName, consumerGroup, messageId);\n *\n * return Response.json({ status: \"success\" });\n * } catch (error) {\n * return Response.json({ error: error.message }, { status: 400 });\n * }\n * }\n * ```\n */\nexport async function parseCallback(\n request: Request,\n): Promise<ParsedCallbackRequest> {\n // Validate content type header\n const contentType = request.headers.get(\"content-type\");\n if (!contentType || !contentType.includes(\"application/cloudevents+json\")) {\n throw new Error(\n \"Invalid content type: expected 'application/cloudevents+json'\",\n );\n }\n\n let cloudEvent: CloudEvent;\n\n try {\n cloudEvent = (await request.json()) as CloudEvent;\n } catch (error) {\n throw new Error(\"Failed to parse CloudEvent from request body\");\n }\n\n // Validate CloudEvent structure\n if (\n !cloudEvent.type ||\n !cloudEvent.source ||\n !cloudEvent.id ||\n typeof cloudEvent.data !== \"object\" ||\n cloudEvent.data == null\n ) {\n throw new Error(\"Invalid CloudEvent: missing required fields\");\n }\n\n // Validate CloudEvent type\n if (cloudEvent.type !== \"com.vercel.queue.v1beta\") {\n throw new Error(\n `Invalid CloudEvent type: expected 'com.vercel.queue.v1beta', got '${cloudEvent.type}'`,\n );\n }\n\n // Check for required data fields before destructuring\n const missingFields: string[] = [];\n if (!(\"queueName\" in cloudEvent.data)) missingFields.push(\"queueName\");\n if (!(\"consumerGroup\" in cloudEvent.data))\n missingFields.push(\"consumerGroup\");\n if (!(\"messageId\" in cloudEvent.data)) missingFields.push(\"messageId\");\n if (missingFields.length > 0) {\n throw new Error(\n `Missing required CloudEvent data fields: ${missingFields.join(\", \")}`,\n );\n }\n\n const { messageId, queueName, consumerGroup } = cloudEvent.data as {\n messageId: string;\n queueName: string;\n consumerGroup: string;\n };\n\n return {\n queueName,\n consumerGroup,\n messageId,\n };\n}\n\nexport function createCallbackHandler(\n handlers: CallbackHandlers,\n client: QueueClient,\n visibilityTimeoutSeconds?: number,\n): (request: Request) => Promise<Response> {\n // Validate all wildcard patterns at setup time\n for (const topicPattern in handlers) {\n if (topicPattern.includes(\"*\")) {\n if (!validateWildcardPattern(topicPattern)) {\n throw new Error(\n `Invalid wildcard pattern \"${topicPattern}\": * may only appear once and must be at the end of the topic name`,\n );\n }\n }\n }\n\n const routeHandler = async (request: Request): Promise<Response> => {\n try {\n // Parse the callback request\n const { queueName, consumerGroup, messageId } =\n await parseCallback(request);\n\n // Find the topic handler\n const topicHandler = findTopicHandler(queueName, handlers);\n\n if (!topicHandler) {\n const availableTopics = Object.keys(handlers).join(\", \");\n return Response.json(\n {\n error: `No handler found for topic: ${queueName}`,\n availableTopics,\n },\n { status: 404 },\n );\n }\n\n // Find the consumer group handler\n const consumerGroupHandler = topicHandler[consumerGroup];\n\n if (!consumerGroupHandler) {\n const availableGroups = Object.keys(topicHandler).join(\", \");\n return Response.json(\n {\n error: `No handler found for consumer group \"${consumerGroup}\" in topic \"${queueName}\".`,\n availableGroups,\n },\n { status: 404 },\n );\n }\n\n // Use the provided client to process the message\n const topic = new Topic(client, queueName);\n const cg = topic.consumerGroup(\n consumerGroup,\n visibilityTimeoutSeconds !== undefined\n ? { visibilityTimeoutSeconds }\n : undefined,\n );\n\n await cg.consume(consumerGroupHandler, { messageId });\n\n return Response.json({ status: \"success\" });\n } catch (error) {\n console.error(\"Queue callback error:\", error);\n\n // Handle parsing errors with appropriate status codes\n if (\n error instanceof Error &&\n (error.message.includes(\"Missing required CloudEvent data fields\") ||\n error.message.includes(\"Invalid CloudEvent\") ||\n error.message.includes(\"Invalid CloudEvent type\") ||\n error.message.includes(\"Invalid content type\") ||\n error.message.includes(\"Failed to parse CloudEvent\"))\n ) {\n return Response.json({ error: error.message }, { status: 400 });\n }\n\n return Response.json(\n { error: \"Failed to process queue message\" },\n { status: 500 },\n );\n }\n };\n\n return routeHandler;\n}\n\n/**\n * Simplified queue callback handler for Next.js route handlers.\n *\n * Automatically extracts queue information from CloudEvent format\n * and routes to the appropriate handler based on topic and consumer group.\n *\n * @param handlers - Object with topic-specific handlers organized by consumer groups\n * @param options - Optional configuration\n * @param options.client - QueueClient instance (default: new client with OIDC auth)\n * @param options.visibilityTimeoutSeconds - Message lock duration (default: 30, max: 3600)\n * @returns A Next.js route handler function\n *\n * @example\n * ```typescript\n * // Basic usage\n * export const POST = handleCallback({\n * \"image-processing\": {\n * \"compress\": (message, metadata) => console.log(\"Compressing\", message),\n * \"resize\": (message, metadata) => console.log(\"Resizing\", message),\n * }\n * });\n *\n * // With custom visibility timeout for long-running handlers\n * export const POST = handleCallback({\n * \"video-processing\": {\n * \"transcode\": async (video, metadata) => {\n * // Long-running transcoding operation\n * await transcodeVideo(video);\n * },\n * }\n * }, {\n * visibilityTimeoutSeconds: 300, // 5 minutes\n * });\n * ```\n */\nexport function handleCallback(\n handlers: CallbackHandlers,\n options?: HandleCallbackOptions,\n): (request: Request) => Promise<Response> {\n return createCallbackHandler(\n handlers,\n options?.client || new QueueClient(),\n options?.visibilityTimeoutSeconds,\n );\n}\n","import { QueueClient } from \"./client\";\nimport type { ConsumeOptions } from \"./consumer-group\";\nimport { Topic } from \"./topic\";\nimport { JsonTransport } from \"./transports\";\nimport type {\n ConsumerGroupOptions,\n MessageHandler,\n PublishOptions,\n Transport,\n} from \"./types\";\nimport { isDevMode, triggerDevCallbacks } from \"./dev\";\n\n/**\n * Options for the send function.\n */\nexport interface SendOptions<T = unknown> extends PublishOptions {\n /**\n * Serializer for the payload.\n * @default JsonTransport\n */\n transport?: Transport<T>;\n\n /**\n * QueueClient instance to use for sending the message.\n * If not provided, a default client is created with OIDC authentication.\n */\n client?: QueueClient;\n}\n\n/**\n * Send a message to a topic.\n *\n * Uses the default QueueClient with automatic OIDC token detection, or a provided client.\n *\n * @param topicName - Name of the topic (pattern: `[A-Za-z0-9_-]+`)\n * @param payload - The data to send\n * @param options - Optional send options\n * @param options.idempotencyKey - Deduplication key (dedup window: min(retention, 24h))\n * @param options.retentionSeconds - Message TTL (default: 86400, min: 60, max: 86400)\n * @param options.delaySeconds - Delivery delay (default: 0, max: retentionSeconds)\n * @param options.transport - Payload serializer (default: JsonTransport)\n * @param options.client - Custom QueueClient instance\n * @returns Promise with the generated messageId\n * @throws {DuplicateMessageError} When idempotency key was already used\n * @throws {BadRequestError} When parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied\n * @throws {InternalServerError} When server encounters an error\n *\n * @example\n * ```typescript\n * // Basic usage (OIDC auth)\n * await send(\"my-topic\", { hello: \"world\" });\n *\n * // With options\n * await send(\"my-topic\", payload, {\n * idempotencyKey: \"unique-key\",\n * retentionSeconds: 3600, // 1 hour TTL\n * delaySeconds: 60, // Delay 1 minute\n * });\n *\n * // Using custom client\n * const client = new QueueClient({ token: \"my-token\" });\n * await send(\"my-topic\", payload, { client });\n * ```\n */\nexport async function send<T = unknown>(\n topicName: string,\n payload: T,\n options?: SendOptions<T>,\n): Promise<{ messageId: string }> {\n const transport = options?.transport || new JsonTransport<T>();\n const client = options?.client || new QueueClient();\n\n const result = await client.sendMessage<T>(\n {\n queueName: topicName,\n payload,\n idempotencyKey: options?.idempotencyKey,\n retentionSeconds: options?.retentionSeconds,\n delaySeconds: options?.delaySeconds,\n },\n transport,\n );\n\n // In development mode, trigger callbacks (respecting any delay)\n if (isDevMode()) {\n triggerDevCallbacks(topicName, result.messageId, options?.delaySeconds);\n }\n\n return { messageId: result.messageId };\n}\n\n/**\n * Options for the receive function.\n */\nexport interface ReceiveOptions<T = unknown>\n extends ConsumerGroupOptions<T>,\n ConsumeOptions {\n /**\n * QueueClient instance to use for receiving the message.\n * If not provided, a default client is created with OIDC authentication.\n */\n client?: QueueClient;\n}\n\n/**\n * Receive a message from a topic.\n *\n * Shorthand for creating a topic and consumer group. The message is automatically:\n * - Locked with the configured visibility timeout\n * - Kept alive via periodic visibility extensions during processing\n * - Deleted upon successful handler completion\n *\n * @param topicName - Name of the topic (pattern: `[A-Za-z0-9_-]+`)\n * @param consumerGroup - Name of the consumer group (pattern: `[A-Za-z0-9_-]+`)\n * @param handler - Function to process the message payload and metadata\n * @param options - Optional receive options\n * @param options.visibilityTimeoutSeconds - Message lock duration (default: 30, max: 3600)\n * @param options.visibilityRefreshInterval - Lock refresh interval (default: visibilityTimeout / 3)\n * @param options.transport - Payload deserializer (default: JsonTransport)\n * @returns Promise that resolves when the message is processed and deleted\n * @throws {QueueEmptyError} When no messages available\n * @throws {ConcurrencyLimitError} When maxConcurrency exceeded\n */\nexport async function receive<T = unknown>(\n topicName: string,\n consumerGroup: string,\n handler: MessageHandler<T>,\n options?: ReceiveOptions<T>,\n): Promise<void>;\n\n/**\n * Receive a specific message by its ID.\n *\n * Used for targeted message processing, typically from webhook callbacks.\n *\n * @param topicName - Name of the topic (pattern: `[A-Za-z0-9_-]+`)\n * @param consumerGroup - Name of the consumer group (pattern: `[A-Za-z0-9_-]+`)\n * @param handler - Function to process the message payload and metadata\n * @param options - Receive options with messageId\n * @param options.messageId - Specific message ID to consume\n * @returns Promise that resolves when the message is processed and deleted\n * @throws {MessageNotFoundError} When message doesn't exist\n * @throws {MessageNotAvailableError} When message in wrong state\n * @throws {MessageAlreadyProcessedError} When already processed\n */\nexport async function receive<T = unknown>(\n topicName: string,\n consumerGroup: string,\n handler: MessageHandler<T>,\n options: ReceiveOptions<T> & { messageId: string },\n): Promise<void>;\n\nexport async function receive<T = unknown>(\n topicName: string,\n consumerGroup: string,\n handler: MessageHandler<T>,\n options?: ReceiveOptions<T>,\n): Promise<void> {\n const transport = options?.transport || new JsonTransport<T>();\n\n const client = options?.client || new QueueClient();\n const topic = new Topic<T>(client, topicName, transport);\n\n const { messageId, client: _, ...consumerGroupOptions } = options || {};\n const consumer = topic.consumerGroup(consumerGroup, consumerGroupOptions);\n\n if (messageId) {\n return consumer.consume(handler, { messageId });\n } else {\n return consumer.consume(handler);\n }\n}\n","/**\n * Client - User-facing wrapper for the Vercel Queue Service\n *\n * This provides a simple interface with send() and handleCallback() methods\n * while delegating to the internal QueueClient and factory functions.\n */\nimport type { CallbackHandlers, HandleCallbackOptions } from \"./callback\";\nimport { handleCallback as handleCallbackFactory } from \"./callback\";\nimport { QueueClient } from \"./client\";\nimport { send as sendFactory } from \"./factory\";\nimport type { PublishOptions, QueueClientOptions, Transport } from \"./types\";\n\n/**\n * Client provides a simple interface to the Vercel Queue Service.\n *\n * @example\n * ```typescript\n * // Create a client with custom options\n * const client = new Client({\n * token: \"my-token\",\n * headers: { \"X-Custom\": \"header\" },\n * });\n *\n * // Send a message\n * await client.send(\"my-topic\", { hello: \"world\" });\n *\n * // Handle callbacks\n * export const POST = client.handleCallback({\n * \"my-topic\": {\n * \"my-group\": async (msg, meta) => console.log(msg),\n * },\n * });\n * ```\n */\nexport class Client {\n private client: QueueClient;\n\n /**\n * Create a new Client\n * @param options QueueClient configuration options\n */\n constructor(options: QueueClientOptions = {}) {\n this.client = new QueueClient(options);\n }\n\n /**\n * Send a message to a topic\n * @param topicName Name of the topic to send to\n * @param payload The data to send\n * @param options Optional publish options and transport\n * @returns Promise with the message ID\n * @throws {BadRequestError} When request parameters are invalid\n * @throws {UnauthorizedError} When authentication fails\n * @throws {ForbiddenError} When access is denied (environment mismatch)\n * @throws {InternalServerError} When server encounters an error\n */\n async send<T = unknown>(\n topicName: string,\n payload: T,\n options?: PublishOptions & { transport?: Transport<T> },\n ): Promise<{ messageId: string }> {\n return sendFactory(topicName, payload, {\n ...options,\n client: this.client,\n });\n }\n\n /**\n * Create a callback handler for processing queue messages.\n * Returns a Next.js route handler function that routes messages to appropriate handlers.\n *\n * @param handlers - Object with topic-specific handlers organized by consumer groups\n * @param options - Optional configuration\n * @param options.visibilityTimeoutSeconds - Message lock duration (default: 30, max: 3600)\n * @returns A Next.js route handler function\n *\n * @example\n * ```typescript\n * // Basic usage\n * export const POST = client.handleCallback({\n * \"user-events\": {\n * \"welcome\": (user, metadata) => console.log(\"Welcoming user\", user),\n * \"analytics\": (user, metadata) => console.log(\"Tracking user\", user),\n * },\n * });\n *\n * // With custom visibility timeout\n * export const POST = client.handleCallback({\n * \"video-processing\": {\n * \"transcode\": async (video) => await transcodeVideo(video),\n * },\n * }, {\n * visibilityTimeoutSeconds: 300, // 5 minutes for long operations\n * });\n * ```\n */\n handleCallback(\n handlers: CallbackHandlers,\n options?: Omit<HandleCallbackOptions, \"client\">,\n ): (request: Request) => Promise<Response> {\n return handleCallbackFactory(handlers, {\n ...options,\n client: this.client,\n });\n }\n}\n"],"mappings":"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","names":["path"]}
|