better-cf 0.2.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +22 -18
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +194 -129
- package/dist/index.js.map +1 -1
- package/dist/queue/index.d.ts +3 -3
- package/dist/queue/index.js +194 -129
- package/dist/queue/index.js.map +1 -1
- package/dist/queue/internal.d.ts +1 -1
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.js.map +1 -1
- package/dist/{types-D44i92Zf.d.ts → types-CcW1NyB-.d.ts} +96 -29
- package/package.json +1 -1
package/dist/queue/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/queue/utils.ts","../../src/queue/consumer.ts","../../src/queue/internal.ts","../../src/queue/types.ts","../../src/queue/define-queue.ts","../../src/queue/define-worker.ts","../../src/queue/create-sdk.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Duration, SendOptions } from './types.js';\n\nexport function parseDurationSeconds(value: Duration): number {\n if (typeof value === 'number') {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`Invalid duration number: ${value}`);\n }\n return value;\n }\n\n const match = value.match(/^(\\d+)(s|m|h)$/);\n if (!match) {\n throw new Error(`Invalid duration string: ${value}`);\n }\n\n const numberValue = Number.parseInt(match[1], 10);\n const unit = match[2];\n\n if (unit === 's') {\n return numberValue;\n }\n\n if (unit === 'm') {\n return numberValue * 60;\n }\n\n return numberValue * 3600;\n}\n\nexport function mergeSendOptions(entry?: SendOptions, batch?: SendOptions): SendOptions | undefined {\n if (!entry && !batch) {\n return undefined;\n }\n\n return {\n delay: entry?.delay ?? batch?.delay,\n contentType: entry?.contentType ?? batch?.contentType\n };\n}\n\nexport function toCloudflareSendOptions(options: SendOptions | undefined): {\n delaySeconds?: number;\n contentType?: SendOptions['contentType'];\n} {\n if (!options) {\n return {};\n }\n\n const result: { delaySeconds?: number; contentType?: SendOptions['contentType'] } = {};\n\n if (options.delay !== undefined) {\n result.delaySeconds = parseDurationSeconds(options.delay);\n }\n\n if (options.contentType !== undefined) {\n result.contentType = options.contentType;\n }\n\n return result;\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import { parseDurationSeconds } from './utils.js';\nimport type {\n AnyJobConfig,\n AnyPushQueueConfig,\n BatchContext,\n Duration,\n QueueContext,\n QueueDefinition,\n QueueEnv\n} from './types.js';\n\nexport async function consumeQueueDefinition<E>(\n definition: QueueDefinition<E>,\n batch: MessageBatch<unknown>,\n env: E,\n executionCtx: ExecutionContext\n): Promise<void> {\n if (definition.kind === 'single') {\n if (definition.mode === 'pull') {\n console.warn(\n `[better-cf] Queue \"${batch.queue}\" configured as http_pull. Worker queue handler is disabled; acking batch.`\n );\n batch.ackAll();\n return;\n }\n\n await consumeSingle(definition.config, batch, env as QueueEnv<E>, executionCtx);\n return;\n }\n\n await consumeMulti(definition.jobs, definition.shared, batch, env as QueueEnv<E>, executionCtx);\n}\n\nasync function consumeSingle<E>(\n config: AnyPushQueueConfig<E>,\n batch: MessageBatch<unknown>,\n env: QueueEnv<E>,\n executionCtx: ExecutionContext\n): Promise<void> {\n if ('processBatch' in config && config.processBatch) {\n let ackOrRetryHandled = false;\n const batchCtx: BatchContext<E> = {\n env,\n executionCtx,\n batch: {\n queue: batch.queue,\n receivedAt: new Date(),\n firstMessageTimestamp: batch.messages[0]?.timestamp,\n ackAll: () => {\n ackOrRetryHandled = true;\n batch.ackAll();\n },\n retryAll: (options?: { delaySeconds?: number }) => {\n ackOrRetryHandled = true;\n batch.retryAll(options);\n }\n }\n };\n\n const typedMessages = batch.messages.map((msg) => ({\n data: msg.body,\n id: msg.id,\n timestamp: msg.timestamp,\n attempts: msg.attempts\n }));\n\n try {\n await config.processBatch(batchCtx, typedMessages as never);\n if (!ackOrRetryHandled) {\n batch.ackAll();\n }\n } catch (error) {\n await callFailureHandler(config.onFailure as HandlerLike<BatchContext<E>>, batchCtx, null, error);\n if (!ackOrRetryHandled) {\n const retryOptions =\n config.retryDelay !== undefined\n ? { delaySeconds: parseDurationSeconds(config.retryDelay) }\n : undefined;\n batch.retryAll(retryOptions);\n }\n }\n return;\n }\n\n for (const message of batch.messages) {\n const queueCtx: QueueContext<E> = {\n env,\n executionCtx,\n message: {\n id: message.id,\n timestamp: message.timestamp,\n attempts: message.attempts,\n queue: batch.queue\n }\n };\n\n try {\n const parsed = config.message.safeParse(message.body);\n if (!parsed.success) {\n throw new Error(`Queue message validation failed: ${parsed.error.message}`);\n }\n\n await config.process(queueCtx, parsed.data as never);\n message.ack();\n } catch (error) {\n await callFailureHandler(\n config.onFailure as HandlerLike<QueueContext<E>>,\n queueCtx,\n message.body,\n error\n );\n const retryOptions =\n config.retryDelay !== undefined\n ? { delaySeconds: parseDurationSeconds(config.retryDelay) }\n : undefined;\n message.retry(retryOptions);\n }\n }\n}\n\nasync function consumeMulti<E>(\n jobs: Record<string, AnyJobConfig<E>>,\n shared: { retryDelay?: Duration },\n batch: MessageBatch<unknown>,\n env: QueueEnv<E>,\n executionCtx: ExecutionContext\n): Promise<void> {\n for (const message of batch.messages) {\n const envelope = message.body as { _job?: string; data?: unknown };\n const jobName = envelope?._job;\n\n if (!jobName || !jobs[jobName]) {\n console.error(`[better-cf] Unknown job type for queue ${batch.queue}: ${String(jobName)}`);\n message.ack();\n continue;\n }\n\n const job = jobs[jobName];\n const queueCtx: QueueContext<E> = {\n env,\n executionCtx,\n message: {\n id: message.id,\n timestamp: message.timestamp,\n attempts: message.attempts,\n queue: batch.queue\n }\n };\n\n try {\n const parsed = job.message.safeParse(envelope.data);\n if (!parsed.success) {\n throw new Error(`Queue job validation failed for ${jobName}: ${parsed.error.message}`);\n }\n await job.process(queueCtx, parsed.data);\n message.ack();\n } catch (error) {\n await callFailureHandler(\n job.onFailure as HandlerLike<QueueContext<E>>,\n queueCtx,\n envelope.data,\n error\n );\n const retryOptions =\n shared.retryDelay !== undefined\n ? { delaySeconds: parseDurationSeconds(shared.retryDelay) }\n : undefined;\n message.retry(retryOptions);\n }\n }\n}\n\ntype HandlerLike<TContext> = ((ctx: TContext, message: unknown, error: Error) => Promise<void>) | undefined;\n\nasync function callFailureHandler<TContext>(\n handler: HandlerLike<TContext>,\n context: TContext,\n message: unknown,\n rawError: unknown\n): Promise<void> {\n if (!handler) {\n return;\n }\n\n const error = rawError instanceof Error ? rawError : new Error(String(rawError));\n try {\n await handler(context, message, error);\n } catch {\n // Do not fail consume flow because failure hook failed.\n }\n}\n","import type { QueueDefinition } from './types.js';\n\n/**\n * Symbol used to store non-enumerable queue internals on queue handles.\n */\nexport const kQueueInternals = Symbol.for('better-cf.queue.internals');\n\n/**\n * Internal queue API used by runtime/testing/CLI internals.\n */\nexport interface QueueInternalApi<E> {\n setBinding(name: string): void;\n getBinding(): string | null;\n getDefinition(): QueueDefinition<E>;\n consume(batch: MessageBatch<unknown>, env: E, executionCtx: ExecutionContext): Promise<void>;\n}\n\nexport type QueueWithInternals<E> = {\n [kQueueInternals]: QueueInternalApi<E>;\n};\n\n/**\n * Reads internal queue metadata from a queue handle.\n */\nexport function getQueueInternals<E>(value: unknown): QueueInternalApi<E> {\n if (!value || typeof value !== 'object') {\n throw new Error('Queue handle is not an object.');\n }\n\n const internals = (value as QueueWithInternals<E>)[kQueueInternals];\n if (!internals) {\n throw new Error('Object is not a better-cf queue handle.');\n }\n\n return internals;\n}\n\n/**\n * Input module shape accepted when resolving worker handlers.\n */\nexport interface WorkerModuleLike {\n default?: unknown;\n fetch?: (request: Request, env: unknown, ctx: ExecutionContext) => Promise<Response>;\n scheduled?: (\n event: ScheduledEvent,\n env: unknown,\n ctx: ExecutionContext\n ) => Promise<void>;\n}\n\n/**\n * Normalized handler pair resolved from a worker module export.\n */\nexport interface ResolvedWorkerHandlers {\n fetch: (request: Request, env: unknown, ctx: ExecutionContext) => Promise<Response>;\n scheduled?: (event: ScheduledEvent, env: unknown, ctx: ExecutionContext) => Promise<void>;\n}\n\n/**\n * Resolves `fetch`/`scheduled` handlers from various worker export styles.\n */\nexport function resolveWorkerHandlers(moduleLike: WorkerModuleLike): ResolvedWorkerHandlers {\n const root = moduleLike.default ?? moduleLike;\n\n let fetchHandler: ResolvedWorkerHandlers['fetch'] | undefined;\n if (typeof root === 'function') {\n fetchHandler = root as ResolvedWorkerHandlers['fetch'];\n } else if (root && typeof root === 'object' && 'fetch' in root) {\n const maybeFetch = (root as { fetch?: unknown }).fetch;\n if (typeof maybeFetch === 'function') {\n fetchHandler = maybeFetch.bind(root) as ResolvedWorkerHandlers['fetch'];\n }\n }\n\n if (!fetchHandler && typeof moduleLike.fetch === 'function') {\n fetchHandler = moduleLike.fetch;\n }\n\n if (!fetchHandler) {\n throw new Error(\n 'Could not resolve worker fetch handler. Export default app/object/function or named fetch.'\n );\n }\n\n let scheduledHandler: ResolvedWorkerHandlers['scheduled'] | undefined;\n if (root && typeof root === 'object' && 'scheduled' in root) {\n const maybeScheduled = (root as { scheduled?: unknown }).scheduled;\n if (typeof maybeScheduled === 'function') {\n scheduledHandler = maybeScheduled.bind(root) as ResolvedWorkerHandlers['scheduled'];\n }\n }\n\n if (!scheduledHandler && typeof moduleLike.scheduled === 'function') {\n scheduledHandler = moduleLike.scheduled;\n }\n\n return {\n fetch: fetchHandler,\n scheduled: scheduledHandler\n };\n}\n","import type { z } from 'zod';\n\n/**\n * Marker interface that generated env bindings extend.\n */\nexport interface BetterCfGeneratedBindings {}\n\n/**\n * Default env type used when `createSDK()` is called without a generic.\n */\nexport interface BetterCfAutoEnv extends BetterCfGeneratedBindings {\n [binding: string]: unknown;\n}\n\n/**\n * Runtime env shape available inside queue and worker handlers.\n */\nexport type QueueEnv<E> = E & BetterCfGeneratedBindings;\n\n/**\n * Duration in seconds/minutes/hours shorthand or raw seconds.\n */\nexport type Duration = number | `${number}s` | `${number}m` | `${number}h`;\n\n/**\n * Cloudflare Queue message content type.\n */\nexport type ContentType = 'json' | 'text' | 'bytes' | 'v8';\n\n/**\n * Per-message send options.\n */\nexport interface SendOptions {\n /** Delay before message becomes visible to consumers. */\n delay?: Duration;\n /** Explicit content type for Cloudflare queue delivery. */\n contentType?: ContentType;\n}\n\n/**\n * Shared send options for `sendBatch`.\n */\nexport type SendBatchOptions = SendOptions;\n\n/**\n * Per-message input for `sendBatch`.\n */\nexport interface SendBatchEntry<T> {\n data: T;\n delay?: Duration;\n contentType?: ContentType;\n}\n\n/**\n * Context passed to per-message queue consumers.\n */\nexport interface QueueContext<E> {\n env: QueueEnv<E>;\n executionCtx: ExecutionContext;\n message: {\n id: string;\n timestamp: Date;\n attempts: number;\n queue: string;\n };\n}\n\n/**\n * Context passed to batch queue consumers.\n */\nexport interface BatchContext<E> {\n env: QueueEnv<E>;\n executionCtx: ExecutionContext;\n batch: {\n queue: string;\n receivedAt: Date;\n firstMessageTimestamp?: Date;\n ackAll: () => void;\n retryAll: (options?: { delaySeconds?: number }) => void;\n };\n}\n\n/**\n * Context passed to worker handlers.\n */\nexport interface WorkerContext<E> {\n env: QueueEnv<E>;\n executionCtx: ExecutionContext;\n}\n\n/**\n * Message shape received by batch consumers.\n */\nexport interface ConsumerBatchEntry<T> {\n data: T;\n id: string;\n timestamp: Date;\n attempts: number;\n}\n\n/**\n * Queue settings shared across worker-consumer and pull-consumer modes.\n */\nexport interface QueueCommonConfig {\n /** Number of retry attempts before dead-lettering. */\n retry?: number;\n /** Delay between retries. */\n retryDelay?: Duration;\n /** Dead-letter queue name. */\n deadLetter?: string;\n /** Delivery delay applied to newly sent messages. */\n deliveryDelay?: Duration;\n /** Message visibility timeout (worker consumer mode only). */\n visibilityTimeout?: Duration;\n /** Batch processing tuning (worker consumer mode only). */\n batch?: {\n maxSize?: number;\n timeout?: Duration;\n maxConcurrency?: number;\n };\n}\n\n/**\n * Pull consumer mode configuration.\n */\nexport interface PullConsumerConfig {\n /** Pull mode marker. */\n type: 'http_pull';\n /** Pull visibility timeout in seconds. */\n visibilityTimeout?: Duration;\n}\n\n/**\n * Per-message queue handler.\n */\nexport type QueueProcessHandler<E, TSchema extends z.ZodTypeAny> = (\n ctx: QueueContext<E>,\n message: z.infer<TSchema>\n) => Promise<void>;\n\n/**\n * Batch queue handler.\n */\nexport type QueueBatchProcessHandler<E, TSchema extends z.ZodTypeAny> = (\n ctx: BatchContext<E>,\n messages: ConsumerBatchEntry<z.infer<TSchema>>[]\n) => Promise<void>;\n\n/**\n * Optional failure handler for queue processing.\n */\nexport type QueueFailureHandler<E, TSchema extends z.ZodTypeAny> = (\n ctx: QueueContext<E> | BatchContext<E>,\n message: z.infer<TSchema> | null,\n error: Error\n) => Promise<void>;\n\n/**\n * Worker-consumer queue with per-message processing.\n */\nexport type QueueProcessConfig<E, TSchema extends z.ZodTypeAny> = QueueCommonConfig & {\n message: TSchema;\n consumer?: { type?: 'worker' };\n process: QueueProcessHandler<E, TSchema>;\n processBatch?: never;\n onFailure?: QueueFailureHandler<E, TSchema>;\n};\n\n/**\n * Worker-consumer queue with batch processing.\n */\nexport type QueueBatchConfig<E, TSchema extends z.ZodTypeAny> = QueueCommonConfig & {\n message: TSchema;\n consumer?: { type?: 'worker' };\n process?: never;\n processBatch: QueueBatchProcessHandler<E, TSchema>;\n onFailure?: QueueFailureHandler<E, TSchema>;\n};\n\n/**\n * HTTP pull consumer queue (producer-only declaration).\n */\nexport type QueuePullConfig<E, TSchema extends z.ZodTypeAny> = Omit<\n QueueCommonConfig,\n 'visibilityTimeout' | 'batch'\n> & {\n message: TSchema;\n consumer: PullConsumerConfig;\n batch?: never;\n visibilityTimeout?: never;\n process?: never;\n processBatch?: never;\n onFailure?: never;\n};\n\n/**\n * Single-queue config union for worker and pull consumer modes.\n */\nexport type QueueConfig<E, TSchema extends z.ZodTypeAny> =\n | QueueProcessConfig<E, TSchema>\n | QueueBatchConfig<E, TSchema>\n | QueuePullConfig<E, TSchema>;\n\n/**\n * Per-job declaration inside a multi-job queue.\n */\nexport interface JobConfig<E, TSchema extends z.ZodTypeAny> {\n message: TSchema;\n process: (ctx: QueueContext<E>, message: z.infer<TSchema>) => Promise<void>;\n onFailure?: (\n ctx: QueueContext<E>,\n message: z.infer<TSchema>,\n error: Error\n ) => Promise<void>;\n}\n\n/**\n * Internal helper alias for any job config.\n */\nexport type AnyJobConfig<E> = JobConfig<E, z.ZodTypeAny>;\n\n/**\n * Extracts only job keys from a multi-job config object.\n */\nexport type ExtractJobMap<E, TConfig extends Record<string, unknown>> = {\n [K in keyof TConfig as TConfig[K] extends AnyJobConfig<E> ? K : never]: TConfig[K] extends AnyJobConfig<E>\n ? TConfig[K]\n : never;\n};\n\n/**\n * Multi-job queue declaration object.\n */\nexport type MultiJobQueueConfig<E, TConfig extends Record<string, unknown>> = QueueCommonConfig & {\n consumer?: never;\n message?: never;\n process?: never;\n processBatch?: never;\n onFailure?: never;\n} & TConfig;\n\n/**\n * Producer handle for a single queue declaration.\n */\nexport interface QueueHandle<E, TMessage> {\n /** Sends one message to the queue. */\n send(ctx: { env: QueueEnv<E> }, data: TMessage, options?: SendOptions): Promise<void>;\n /** Sends multiple messages in one request. */\n sendBatch(\n ctx: { env: QueueEnv<E> },\n messages: SendBatchEntry<TMessage>[],\n options?: SendBatchOptions\n ): Promise<void>;\n}\n\n/**\n * Producer handles keyed by job name for a multi-job queue.\n */\nexport type MultiJobQueueHandle<\n E,\n TJobs extends Record<string, AnyJobConfig<E>>\n> = {\n [K in keyof TJobs]: {\n /** Sends one message to a named job. */\n send(\n ctx: { env: QueueEnv<E> },\n data: z.infer<TJobs[K]['message']>,\n options?: SendOptions\n ): Promise<void>;\n /** Sends many messages to a named job. */\n sendBatch(\n ctx: { env: QueueEnv<E> },\n messages: SendBatchEntry<z.infer<TJobs[K]['message']>>[],\n options?: SendBatchOptions\n ): Promise<void>;\n };\n};\n\n/**\n * Worker handlers used to define module exports.\n */\nexport interface WorkerConfig<E> {\n /** Main fetch handler. */\n fetch: (request: Request, ctx: WorkerContext<E>) => Promise<Response>;\n /** Optional scheduled handler. */\n scheduled?: (event: ScheduledEvent, ctx: WorkerContext<E>) => Promise<void>;\n}\n\n/**\n * Worker module shape returned by `defineWorker`.\n */\nexport interface WorkerEntrypoint<E> {\n fetch(request: Request, env: E, executionCtx: ExecutionContext): Promise<Response>;\n scheduled?: (event: ScheduledEvent, env: E, executionCtx: ExecutionContext) => Promise<void>;\n}\n\n/**\n * Defines a worker module with typed queue-aware context.\n */\nexport type DefineWorker<E> = (config: WorkerConfig<E>) => WorkerEntrypoint<E>;\n\n/**\n * Defines queue contracts and returns typed producer handles.\n */\nexport interface DefineQueue<E> {\n /**\n * Declare a single queue (worker consumer or http pull consumer).\n *\n * @example\n * defineQueue({\n * message: z.object({ id: z.string() }),\n * process: async (ctx, message) => {}\n * })\n */\n <TSchema extends z.ZodTypeAny>(config: QueueConfig<E, TSchema>): QueueHandle<E, z.infer<TSchema>>;\n\n /**\n * Declare a multi-job queue where each top-level key is a job definition.\n *\n * @example\n * defineQueue({\n * email: { message: z.object({ to: z.string() }), process: async () => {} },\n * audit: { message: z.object({ id: z.string() }), process: async () => {} }\n * })\n */\n <const TConfig extends Record<string, unknown>>(\n config: MultiJobQueueConfig<E, TConfig>\n ): MultiJobQueueHandle<E, ExtractJobMap<E, TConfig>>;\n}\n\n/**\n * SDK helpers returned by `createSDK`.\n */\nexport interface BetterCfSDK<E> {\n /** Queue declaration helper with schema-inferred producer types. */\n defineQueue: DefineQueue<E>;\n /** Worker declaration helper that maps to Cloudflare module handlers. */\n defineWorker: DefineWorker<E>;\n}\n\n/**\n * Internal helper alias for any queue config mode.\n */\nexport type AnyQueueConfig<E> = QueueConfig<E, z.ZodTypeAny>;\n/**\n * Internal helper alias for worker-consumer queue modes.\n */\nexport type AnyPushQueueConfig<E> = QueueProcessConfig<E, z.ZodTypeAny> | QueueBatchConfig<E, z.ZodTypeAny>;\n/**\n * Internal helper alias for pull-consumer queue mode.\n */\nexport type AnyPullQueueConfig<E> = QueuePullConfig<E, z.ZodTypeAny>;\n\n/**\n * Internal helper alias for any multi-job queue config.\n */\nexport type AnyMultiJobQueueConfig<E> = MultiJobQueueConfig<E, Record<string, unknown>>;\n\n/**\n * Normalized queue definition used by runtime internals.\n */\nexport type QueueDefinition<E> =\n | { kind: 'single'; mode: 'push'; config: AnyPushQueueConfig<E> }\n | { kind: 'single'; mode: 'pull'; config: AnyPullQueueConfig<E> }\n | {\n kind: 'multi';\n jobs: Record<string, AnyJobConfig<E>>;\n shared: QueueCommonConfig;\n };\n\n/**\n * Reserved top-level keys treated as shared config in multi-job mode.\n */\nexport const RESERVED_MULTI_JOB_KEYS = new Set([\n 'retry',\n 'retryDelay',\n 'deadLetter',\n 'deliveryDelay',\n 'visibilityTimeout',\n 'batch',\n 'consumer'\n]);\n","import { consumeQueueDefinition } from './consumer.js';\nimport { getQueueInternals, kQueueInternals } from './internal.js';\nimport {\n RESERVED_MULTI_JOB_KEYS,\n type AnyMultiJobQueueConfig,\n type AnyPullQueueConfig,\n type AnyPushQueueConfig,\n type ExtractJobMap,\n type DefineQueue,\n type JobConfig,\n type MultiJobQueueConfig,\n type MultiJobQueueHandle,\n type QueueConfig,\n type QueueDefinition,\n type QueueHandle,\n type SendBatchEntry,\n type SendBatchOptions,\n type SendOptions\n} from './types.js';\nimport { isPlainObject, mergeSendOptions, toCloudflareSendOptions } from './utils.js';\nimport type { z } from 'zod';\n\n/**\n * Creates a typed `defineQueue` helper bound to the SDK env generic.\n */\nexport function defineQueueFactory<E>(): DefineQueue<E> {\n /**\n * Declare a single queue contract.\n */\n function defineQueue<TSchema extends z.ZodTypeAny>(\n config: QueueConfig<E, TSchema>\n ): QueueHandle<E, z.infer<TSchema>>;\n\n /**\n * Declare a multi-job queue contract.\n */\n function defineQueue<const TConfig extends Record<string, unknown>>(\n config: MultiJobQueueConfig<E, TConfig>\n ): MultiJobQueueHandle<E, ExtractJobMap<E, TConfig>>;\n\n function defineQueue(\n config: QueueConfig<E, z.ZodTypeAny> | AnyMultiJobQueueConfig<E>\n ): QueueHandle<E, unknown> | MultiJobQueueHandle<E, Record<string, JobConfig<E, z.ZodTypeAny>>> {\n const definition = toQueueDefinition(config);\n\n let bindingName: string | null = null;\n\n const sendBase = async (ctx: { env: E }, body: unknown, options?: SendOptions): Promise<void> => {\n if (!bindingName) {\n throw new Error(\n 'Queue binding not initialized. Run through better-cf dev/generate/deploy generated entry.'\n );\n }\n\n const binding = (ctx.env as Record<string, unknown>)[bindingName] as\n | {\n send: (value: unknown, opts?: { delaySeconds?: number; contentType?: SendOptions['contentType'] }) => Promise<void>;\n }\n | undefined;\n\n if (!binding || typeof binding.send !== 'function') {\n throw new Error(`Queue binding ${bindingName} not found in env.`);\n }\n\n await binding.send(body, toCloudflareSendOptions(options));\n };\n\n const sendBatchBase = async (\n ctx: { env: E },\n messages: Array<{ body: unknown; options?: SendOptions }>\n ): Promise<void> => {\n if (!bindingName) {\n throw new Error(\n 'Queue binding not initialized. Run through better-cf dev/generate/deploy generated entry.'\n );\n }\n\n const binding = (ctx.env as Record<string, unknown>)[bindingName] as\n | {\n sendBatch: (entries: Array<{ body: unknown; delaySeconds?: number; contentType?: SendOptions['contentType'] }>) => Promise<void>;\n }\n | undefined;\n\n if (!binding || typeof binding.sendBatch !== 'function') {\n throw new Error(`Queue binding ${bindingName} not found in env.`);\n }\n\n const payload = messages.map((item) => ({\n body: item.body,\n ...toCloudflareSendOptions(item.options)\n }));\n await binding.sendBatch(payload);\n };\n\n const baseHandle: Record<string | symbol, unknown> = {\n async send(ctx: { env: E }, data: unknown, options?: SendOptions): Promise<void> {\n if (definition.kind === 'single') {\n await sendBase(ctx, data, options);\n return;\n }\n\n await sendBase(ctx, { _job: '__default', data }, options);\n },\n\n async sendBatch(\n ctx: { env: E },\n messages: SendBatchEntry<unknown>[],\n options?: SendBatchOptions\n ): Promise<void> {\n if (definition.kind === 'single') {\n await sendBatchBase(\n ctx,\n messages.map((message) => ({\n body: message.data,\n options: mergeSendOptions(message, options)\n }))\n );\n return;\n }\n\n await sendBatchBase(\n ctx,\n messages.map((message) => ({\n body: { _job: '__default', data: message.data },\n options: mergeSendOptions(message, options)\n }))\n );\n }\n };\n\n if (definition.kind === 'multi') {\n for (const jobName of Object.keys(definition.jobs)) {\n baseHandle[jobName] = {\n async send(ctx: { env: E }, data: unknown, options?: SendOptions) {\n await sendBase(ctx, { _job: jobName, data }, options);\n },\n async sendBatch(\n ctx: { env: E },\n messages: SendBatchEntry<unknown>[],\n options?: SendBatchOptions\n ) {\n await sendBatchBase(\n ctx,\n messages.map((message) => ({\n body: { _job: jobName, data: message.data },\n options: mergeSendOptions(message, options)\n }))\n );\n }\n };\n }\n }\n\n Object.defineProperty(baseHandle, kQueueInternals, {\n enumerable: false,\n configurable: false,\n writable: false,\n value: {\n setBinding(name: string) {\n bindingName = name;\n },\n getBinding() {\n return bindingName;\n },\n getDefinition() {\n return definition;\n },\n consume(batch: MessageBatch<unknown>, env: E, executionCtx: ExecutionContext) {\n return consumeQueueDefinition(definition, batch, env, executionCtx);\n }\n }\n });\n\n return baseHandle as unknown as QueueHandle<E, unknown>;\n }\n\n return defineQueue;\n}\n\n/**\n * Attaches the generated Cloudflare binding name to a queue handle.\n */\nexport function setQueueBinding<E>(handle: unknown, binding: string): void {\n getQueueInternals<E>(handle).setBinding(binding);\n}\n\n/**\n * Reads normalized queue metadata from a queue handle.\n */\nexport function readQueueDefinition<E>(handle: unknown): QueueDefinition<E> {\n return getQueueInternals<E>(handle).getDefinition();\n}\n\nfunction toQueueDefinition<E>(\n config: QueueConfig<E, z.ZodTypeAny> | AnyMultiJobQueueConfig<E>\n): QueueDefinition<E> {\n if (isSingleQueue(config)) {\n if (isPullQueue(config)) {\n if ('process' in config || 'processBatch' in config) {\n throw new Error('Queue config with consumer.type=\"http_pull\" cannot define process/processBatch.');\n }\n return {\n kind: 'single',\n mode: 'pull',\n config: config as AnyPullQueueConfig<E>\n };\n }\n\n if (hasProcess(config) && hasProcessBatch(config)) {\n throw new Error('Queue config cannot define both process and processBatch.');\n }\n\n if (!hasProcess(config) && !hasProcessBatch(config)) {\n throw new Error('Queue config must define one of process or processBatch in worker consumer mode.');\n }\n\n return {\n kind: 'single',\n mode: 'push',\n config: config as AnyPushQueueConfig<E>\n };\n }\n\n const shared = {\n retry: config.retry,\n retryDelay: config.retryDelay,\n deadLetter: config.deadLetter,\n deliveryDelay: config.deliveryDelay,\n visibilityTimeout: config.visibilityTimeout,\n batch: config.batch\n };\n\n const jobs: Record<string, JobConfig<E, z.ZodTypeAny>> = {};\n for (const [key, value] of Object.entries(config)) {\n if (RESERVED_MULTI_JOB_KEYS.has(key)) {\n continue;\n }\n if (isJobConfig(value)) {\n jobs[key] = value;\n }\n }\n\n if (Object.keys(jobs).length === 0) {\n throw new Error('Multi-job queue config must define at least one job.');\n }\n\n return {\n kind: 'multi',\n jobs,\n shared\n };\n}\n\nfunction isSingleQueue<E>(\n config: QueueConfig<E, z.ZodTypeAny> | AnyMultiJobQueueConfig<E>\n): config is QueueConfig<E, z.ZodTypeAny> {\n return 'message' in config;\n}\n\nfunction isPullQueue<E>(config: QueueConfig<E, z.ZodTypeAny>): boolean {\n return 'consumer' in config && Boolean(config.consumer && config.consumer.type === 'http_pull');\n}\n\nfunction hasProcess<E>(config: QueueConfig<E, z.ZodTypeAny>): boolean {\n return 'process' in config && typeof config.process === 'function';\n}\n\nfunction hasProcessBatch<E>(config: QueueConfig<E, z.ZodTypeAny>): boolean {\n return 'processBatch' in config && typeof config.processBatch === 'function';\n}\n\nfunction isJobConfig<E>(value: unknown): value is JobConfig<E, z.ZodTypeAny> {\n if (!isPlainObject(value)) {\n return false;\n }\n\n return 'message' in value && 'process' in value;\n}\n","import type { DefineWorker, QueueEnv, WorkerConfig, WorkerEntrypoint } from './types.js';\n\n/**\n * Creates a typed `defineWorker` helper bound to the SDK env generic.\n */\nexport function defineWorkerFactory<E>(): DefineWorker<E> {\n return function defineWorker(config: WorkerConfig<E>): WorkerEntrypoint<E> {\n return {\n async fetch(request: Request, env: E, executionCtx: ExecutionContext): Promise<Response> {\n return config.fetch(request, {\n env: env as QueueEnv<E>,\n executionCtx\n });\n },\n ...(config.scheduled\n ? {\n async scheduled(event: ScheduledEvent, env: E, executionCtx: ExecutionContext): Promise<void> {\n await config.scheduled?.(event, {\n env: env as QueueEnv<E>,\n executionCtx\n });\n }\n }\n : {})\n };\n };\n}\n","import { defineQueueFactory } from './define-queue.js';\nimport { defineWorkerFactory } from './define-worker.js';\nimport type { BetterCfAutoEnv, BetterCfSDK } from './types.js';\n\n/**\n * Creates typed queue + worker helpers for your Cloudflare Worker app.\n *\n * @example\n * const { defineQueue, defineWorker } = createSDK<Env>();\n */\nexport function createSDK<E extends Record<string, unknown> = BetterCfAutoEnv>(): BetterCfSDK<E> {\n return {\n defineQueue: defineQueueFactory<E>(),\n defineWorker: defineWorkerFactory<E>()\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/queue/utils.ts","../../src/queue/consumer.ts","../../src/queue/internal.ts","../../src/queue/types.ts","../../src/queue/define-queue.ts","../../src/queue/define-worker.ts","../../src/queue/create-sdk.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { Duration, SendOptions } from './types.js';\n\nexport function parseDurationSeconds(value: Duration): number {\n if (typeof value === 'number') {\n if (!Number.isFinite(value) || value < 0) {\n throw new Error(`Invalid duration number: ${value}`);\n }\n return value;\n }\n\n const match = value.match(/^(\\d+)(s|m|h)$/);\n if (!match) {\n throw new Error(`Invalid duration string: ${value}`);\n }\n\n const numberValue = Number.parseInt(match[1], 10);\n const unit = match[2];\n\n if (unit === 's') {\n return numberValue;\n }\n\n if (unit === 'm') {\n return numberValue * 60;\n }\n\n return numberValue * 3600;\n}\n\nexport function mergeSendOptions(entry?: SendOptions, batch?: SendOptions): SendOptions | undefined {\n if (!entry && !batch) {\n return undefined;\n }\n\n return {\n delay: entry?.delay ?? batch?.delay,\n contentType: entry?.contentType ?? batch?.contentType\n };\n}\n\nexport function toCloudflareSendOptions(options: SendOptions | undefined): {\n delaySeconds?: number;\n contentType?: SendOptions['contentType'];\n} {\n if (!options) {\n return {};\n }\n\n const result: { delaySeconds?: number; contentType?: SendOptions['contentType'] } = {};\n\n if (options.delay !== undefined) {\n result.delaySeconds = parseDurationSeconds(options.delay);\n }\n\n if (options.contentType !== undefined) {\n result.contentType = options.contentType;\n }\n\n return result;\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n","import { parseDurationSeconds } from './utils.js';\nimport type {\n AnyJobConfig,\n AnyPushQueueConfig,\n BatchContext,\n ConsumerBatchEntry,\n Duration,\n QueueContext,\n QueueDefinition,\n QueueEnv\n} from './types.js';\n\nexport async function consumeQueueDefinition<E>(\n definition: QueueDefinition<E>,\n batch: MessageBatch<unknown>,\n env: E,\n executionCtx: ExecutionContext\n): Promise<void> {\n if (definition.kind === 'single') {\n if (definition.mode === 'pull') {\n console.warn(\n `[better-cf] Queue \"${batch.queue}\" configured as http_pull. Worker queue handler is disabled; acking batch.`\n );\n batch.ackAll();\n return;\n }\n\n await consumeSingle(definition.config, batch, env as QueueEnv<E>, executionCtx);\n return;\n }\n\n await consumeMulti(definition.jobs, definition.shared, batch, env as QueueEnv<E>, executionCtx);\n}\n\nasync function consumeSingle<E>(\n config: AnyPushQueueConfig<E>,\n batch: MessageBatch<unknown>,\n env: QueueEnv<E>,\n executionCtx: ExecutionContext\n): Promise<void> {\n if ('batchHandler' in config && config.batchHandler) {\n let ackOrRetryHandled = false;\n const batchCtx: BatchContext<E> = {\n env,\n executionCtx,\n batch: {\n queue: batch.queue,\n receivedAt: new Date(),\n firstMessageTimestamp: batch.messages[0]?.timestamp,\n ackAll: () => {\n ackOrRetryHandled = true;\n batch.ackAll();\n },\n retryAll: (options?: { delaySeconds?: number }) => {\n ackOrRetryHandled = true;\n batch.retryAll(options);\n }\n }\n };\n\n try {\n const typedMessages: ConsumerBatchEntry<unknown>[] = batch.messages.map((msg) => {\n const parsed = config.args.safeParse(msg.body);\n if (!parsed.success) {\n throw new Error(`Queue batch validation failed for ${msg.id}: ${parsed.error.message}`);\n }\n\n return {\n data: parsed.data,\n id: msg.id,\n timestamp: msg.timestamp,\n attempts: msg.attempts\n };\n });\n\n await config.batchHandler(batchCtx, typedMessages as never);\n if (!ackOrRetryHandled) {\n batch.ackAll();\n }\n } catch (error) {\n await callFailureHandler(config.onFailure as HandlerLike<BatchContext<E>>, batchCtx, null, error);\n if (!ackOrRetryHandled) {\n const retryOptions =\n config.retryDelay !== undefined\n ? { delaySeconds: parseDurationSeconds(config.retryDelay) }\n : undefined;\n batch.retryAll(retryOptions);\n }\n }\n return;\n }\n\n for (const message of batch.messages) {\n const queueCtx: QueueContext<E> = {\n env,\n executionCtx,\n message: {\n id: message.id,\n timestamp: message.timestamp,\n attempts: message.attempts,\n queue: batch.queue\n }\n };\n\n try {\n const parsed = config.args.safeParse(message.body);\n if (!parsed.success) {\n throw new Error(`Queue args validation failed: ${parsed.error.message}`);\n }\n\n await config.handler(queueCtx, parsed.data as never);\n message.ack();\n } catch (error) {\n await callFailureHandler(\n config.onFailure as HandlerLike<QueueContext<E>>,\n queueCtx,\n message.body,\n error\n );\n const retryOptions =\n config.retryDelay !== undefined\n ? { delaySeconds: parseDurationSeconds(config.retryDelay) }\n : undefined;\n message.retry(retryOptions);\n }\n }\n}\n\nasync function consumeMulti<E>(\n jobs: Record<string, AnyJobConfig<E>>,\n shared: { retryDelay?: Duration },\n batch: MessageBatch<unknown>,\n env: QueueEnv<E>,\n executionCtx: ExecutionContext\n): Promise<void> {\n for (const message of batch.messages) {\n const envelope = message.body as { _job?: string; data?: unknown };\n const jobName = envelope?._job;\n\n if (!jobName || !jobs[jobName]) {\n console.error(`[better-cf] Unknown job type for queue ${batch.queue}: ${String(jobName)}`);\n message.ack();\n continue;\n }\n\n const job = jobs[jobName];\n const queueCtx: QueueContext<E> = {\n env,\n executionCtx,\n message: {\n id: message.id,\n timestamp: message.timestamp,\n attempts: message.attempts,\n queue: batch.queue\n }\n };\n\n try {\n const parsed = job.args.safeParse(envelope.data);\n if (!parsed.success) {\n throw new Error(`Queue job validation failed for ${jobName}: ${parsed.error.message}`);\n }\n await job.handler(queueCtx, parsed.data);\n message.ack();\n } catch (error) {\n await callFailureHandler(\n job.onFailure as HandlerLike<QueueContext<E>>,\n queueCtx,\n envelope.data,\n error\n );\n const retryOptions =\n shared.retryDelay !== undefined\n ? { delaySeconds: parseDurationSeconds(shared.retryDelay) }\n : undefined;\n message.retry(retryOptions);\n }\n }\n}\n\ntype HandlerLike<TContext> = ((ctx: TContext, args: unknown, error: Error) => Promise<void>) | undefined;\n\nasync function callFailureHandler<TContext>(\n handler: HandlerLike<TContext>,\n context: TContext,\n args: unknown,\n rawError: unknown\n): Promise<void> {\n if (!handler) {\n return;\n }\n\n const error = rawError instanceof Error ? rawError : new Error(String(rawError));\n try {\n await handler(context, args, error);\n } catch {\n // Do not fail consume flow because failure hook failed.\n }\n}\n","import type { QueueDefinition } from './types.js';\n\n/**\n * Symbol used to store non-enumerable queue internals on queue handles.\n */\nexport const kQueueInternals = Symbol.for('better-cf.queue.internals');\n\n/**\n * Internal queue API used by runtime/testing/CLI internals.\n */\nexport interface QueueInternalApi<E> {\n setBinding(name: string): void;\n getBinding(): string | null;\n getDefinition(): QueueDefinition<E>;\n consume(batch: MessageBatch<unknown>, env: E, executionCtx: ExecutionContext): Promise<void>;\n}\n\nexport type QueueWithInternals<E> = {\n [kQueueInternals]: QueueInternalApi<E>;\n};\n\n/**\n * Reads internal queue metadata from a queue handle.\n */\nexport function getQueueInternals<E>(value: unknown): QueueInternalApi<E> {\n if (!value || typeof value !== 'object') {\n throw new Error('Queue handle is not an object.');\n }\n\n const internals = (value as QueueWithInternals<E>)[kQueueInternals];\n if (!internals) {\n throw new Error('Object is not a better-cf queue handle.');\n }\n\n return internals;\n}\n\n/**\n * Input module shape accepted when resolving worker handlers.\n */\nexport interface WorkerModuleLike {\n default?: unknown;\n fetch?: (request: Request, env: unknown, ctx: ExecutionContext) => Promise<Response>;\n scheduled?: (\n event: ScheduledEvent,\n env: unknown,\n ctx: ExecutionContext\n ) => Promise<void>;\n}\n\n/**\n * Normalized handler pair resolved from a worker module export.\n */\nexport interface ResolvedWorkerHandlers {\n fetch: (request: Request, env: unknown, ctx: ExecutionContext) => Promise<Response>;\n scheduled?: (event: ScheduledEvent, env: unknown, ctx: ExecutionContext) => Promise<void>;\n}\n\n/**\n * Resolves `fetch`/`scheduled` handlers from various worker export styles.\n */\nexport function resolveWorkerHandlers(moduleLike: WorkerModuleLike): ResolvedWorkerHandlers {\n const root = moduleLike.default ?? moduleLike;\n\n let fetchHandler: ResolvedWorkerHandlers['fetch'] | undefined;\n if (typeof root === 'function') {\n fetchHandler = root as ResolvedWorkerHandlers['fetch'];\n } else if (root && typeof root === 'object' && 'fetch' in root) {\n const maybeFetch = (root as { fetch?: unknown }).fetch;\n if (typeof maybeFetch === 'function') {\n fetchHandler = maybeFetch.bind(root) as ResolvedWorkerHandlers['fetch'];\n }\n }\n\n if (!fetchHandler && typeof moduleLike.fetch === 'function') {\n fetchHandler = moduleLike.fetch;\n }\n\n if (!fetchHandler) {\n throw new Error(\n 'Could not resolve worker fetch handler. Export default app/object/function or named fetch.'\n );\n }\n\n let scheduledHandler: ResolvedWorkerHandlers['scheduled'] | undefined;\n if (root && typeof root === 'object' && 'scheduled' in root) {\n const maybeScheduled = (root as { scheduled?: unknown }).scheduled;\n if (typeof maybeScheduled === 'function') {\n scheduledHandler = maybeScheduled.bind(root) as ResolvedWorkerHandlers['scheduled'];\n }\n }\n\n if (!scheduledHandler && typeof moduleLike.scheduled === 'function') {\n scheduledHandler = moduleLike.scheduled;\n }\n\n return {\n fetch: fetchHandler,\n scheduled: scheduledHandler\n };\n}\n","import type { z } from 'zod';\n\n/**\n * Marker interface that generated env bindings extend.\n */\nexport interface BetterCfGeneratedBindings {}\n\n/**\n * Default env type used when `createSDK()` is called without a generic.\n */\nexport interface BetterCfAutoEnv extends BetterCfGeneratedBindings {\n [binding: string]: unknown;\n}\n\n/**\n * Runtime env shape available inside queue and worker handlers.\n */\nexport type QueueEnv<E> = E & BetterCfGeneratedBindings;\n\n/**\n * Duration in seconds/minutes/hours shorthand or raw seconds.\n */\nexport type Duration = number | `${number}s` | `${number}m` | `${number}h`;\n\n/**\n * Cloudflare Queue message content type.\n */\nexport type ContentType = 'json' | 'text' | 'bytes' | 'v8';\n\n/**\n * Per-message send options.\n */\nexport interface SendOptions {\n /** Delay before message becomes visible to consumers. */\n delay?: Duration;\n /** Explicit content type for Cloudflare queue delivery. */\n contentType?: ContentType;\n}\n\n/**\n * Shared send options for `sendBatch`.\n */\nexport type SendBatchOptions = SendOptions;\n\n/**\n * Per-message input for `sendBatch`.\n */\nexport interface SendBatchEntry<T> {\n /** Payload to enqueue. */\n data: T;\n /** Per-message delay override (takes precedence over batch-level `options.delay`). */\n delay?: Duration;\n /** Per-message content type override (takes precedence over batch-level `options.contentType`). */\n contentType?: ContentType;\n}\n\n/**\n * Context passed to per-message queue consumers.\n */\nexport interface QueueContext<E> {\n /** Queue-aware runtime environment (`env` + generated bindings). */\n env: QueueEnv<E>;\n /** Cloudflare execution context. */\n executionCtx: ExecutionContext;\n /** Metadata for the currently processed message. */\n message: {\n /** Unique Cloudflare queue message id. */\n id: string;\n /** Message enqueue timestamp. */\n timestamp: Date;\n /** Delivery attempt count for this message. */\n attempts: number;\n /** Queue name currently being consumed. */\n queue: string;\n };\n}\n\n/**\n * Context passed to batch queue consumers.\n */\nexport interface BatchContext<E> {\n /** Queue-aware runtime environment (`env` + generated bindings). */\n env: QueueEnv<E>;\n /** Cloudflare execution context. */\n executionCtx: ExecutionContext;\n /** Batch metadata + helpers for explicit ack/retry control. */\n batch: {\n /** Queue name currently being consumed. */\n queue: string;\n /** When the batch was received by this worker invocation. */\n receivedAt: Date;\n /** Timestamp of first message in this batch (if present). */\n firstMessageTimestamp?: Date;\n /** Ack every message in the current batch. */\n ackAll: () => void;\n /** Retry every message in the current batch. */\n retryAll: (options?: { delaySeconds?: number }) => void;\n };\n}\n\n/**\n * Context passed to worker handlers.\n */\nexport interface WorkerContext<E> {\n /** Queue-aware runtime environment (`env` + generated bindings). */\n env: QueueEnv<E>;\n /** Cloudflare execution context. */\n executionCtx: ExecutionContext;\n}\n\n/**\n * Message shape received by batch consumers.\n */\nexport interface ConsumerBatchEntry<T> {\n /** Validated payload data. */\n data: T;\n /** Unique Cloudflare queue message id. */\n id: string;\n /** Message enqueue timestamp. */\n timestamp: Date;\n /** Delivery attempt count for this message. */\n attempts: number;\n}\n\n/**\n * Queue settings shared across worker-consumer and pull-consumer modes.\n */\nexport interface QueueCommonConfig {\n /** Number of retry attempts before dead-lettering. */\n retry?: number;\n /** Delay between retries. */\n retryDelay?: Duration;\n /** Dead-letter queue name. */\n deadLetter?: string;\n /** Delivery delay applied to newly sent messages. */\n deliveryDelay?: Duration;\n /** Message visibility timeout (worker consumer mode only). */\n visibilityTimeout?: Duration;\n /** Batch processing tuning (worker consumer mode only). */\n batch?: {\n /** Maximum number of messages per delivered batch. */\n maxSize?: number;\n /** Maximum time to wait before delivering a partial batch. */\n timeout?: Duration;\n /** Maximum concurrent batch invocations. */\n maxConcurrency?: number;\n };\n}\n\n/**\n * Pull consumer mode configuration.\n */\nexport interface PullConsumerConfig {\n /** Pull mode marker. */\n type: 'http_pull';\n /** Pull visibility timeout (seconds or duration shorthand). */\n visibilityTimeout?: Duration;\n}\n\n/**\n * Per-message queue handler.\n */\nexport type QueueHandler<E, TSchema extends z.ZodTypeAny> = (\n ctx: QueueContext<E>,\n args: z.infer<TSchema>\n) => Promise<void>;\n\n/**\n * Batch queue handler.\n */\nexport type QueueBatchHandler<E, TSchema extends z.ZodTypeAny> = (\n ctx: BatchContext<E>,\n args: ConsumerBatchEntry<z.infer<TSchema>>[]\n) => Promise<void>;\n\n/**\n * Optional failure handler for queue processing.\n */\nexport type QueueFailureHandler<E, TSchema extends z.ZodTypeAny> = (\n ctx: QueueContext<E> | BatchContext<E>,\n args: z.infer<TSchema> | null,\n error: Error\n) => Promise<void>;\n\n/**\n * Worker-consumer queue with per-message processing.\n */\nexport type QueueProcessConfig<E, TSchema extends z.ZodTypeAny> = QueueCommonConfig & {\n /** Zod schema used to validate each incoming payload. */\n args: TSchema;\n /** Optional explicit worker consumer marker. */\n consumer?: { type?: 'worker' };\n /** Per-message push handler. */\n handler: QueueHandler<E, TSchema>;\n /** Not allowed in single-message mode. */\n batchHandler?: never;\n /** Optional failure hook when `handler` throws or payload validation fails. */\n onFailure?: QueueFailureHandler<E, TSchema>;\n};\n\n/**\n * Worker-consumer queue with batch processing.\n */\nexport type QueueBatchConfig<E, TSchema extends z.ZodTypeAny> = QueueCommonConfig & {\n /** Zod schema used to validate each payload before `batchHandler` runs. */\n args: TSchema;\n /** Optional explicit worker consumer marker. */\n consumer?: { type?: 'worker' };\n /** Not allowed in batch mode. */\n handler?: never;\n /** Batch push handler. */\n batchHandler: QueueBatchHandler<E, TSchema>;\n /** Optional failure hook when `batchHandler` throws or batch validation fails. */\n onFailure?: QueueFailureHandler<E, TSchema>;\n};\n\n/**\n * HTTP pull consumer queue (producer-only declaration).\n */\nexport type QueuePullConfig<E, TSchema extends z.ZodTypeAny> = Omit<\n QueueCommonConfig,\n 'visibilityTimeout' | 'batch'\n> & {\n /** Zod schema for producer payload typing in pull mode. */\n args: TSchema;\n /** Required pull consumer configuration. */\n consumer: PullConsumerConfig;\n /** Not allowed in pull mode. */\n batch?: never;\n /** Not allowed in pull mode. */\n visibilityTimeout?: never;\n /** Not allowed in pull mode. */\n handler?: never;\n /** Not allowed in pull mode. */\n batchHandler?: never;\n /** Not allowed in pull mode. */\n onFailure?: never;\n};\n\n/**\n * Single-queue config union for worker and pull consumer modes.\n */\nexport type QueueConfig<E, TSchema extends z.ZodTypeAny> =\n | QueueProcessConfig<E, TSchema>\n | QueueBatchConfig<E, TSchema>\n | QueuePullConfig<E, TSchema>;\n\n/**\n * Per-job declaration inside a multi-job queue.\n */\nexport interface JobConfig<E, TSchema extends z.ZodTypeAny> {\n /** Zod schema used to validate this job's payload. */\n args: TSchema;\n /** Job handler for this job key. */\n handler: (ctx: QueueContext<E>, args: z.infer<TSchema>) => Promise<void>;\n /** Optional failure hook for this job handler. */\n onFailure?: (\n ctx: QueueContext<E>,\n args: z.infer<TSchema>,\n error: Error\n ) => Promise<void>;\n}\n\n/**\n * Internal helper alias for any job config.\n */\nexport type AnyJobConfig<E> = JobConfig<E, z.ZodTypeAny>;\n\n/**\n * Extracts only job keys from a multi-job config object.\n */\nexport type ExtractJobMap<E, TConfig extends Record<string, unknown>> = {\n [K in keyof TConfig as TConfig[K] extends AnyJobConfig<E> ? K : never]: TConfig[K] extends AnyJobConfig<E>\n ? TConfig[K]\n : never;\n};\n\n/**\n * Multi-job queue declaration object.\n */\nexport type MultiJobQueueConfig<E, TConfig extends Record<string, unknown>> = QueueCommonConfig & {\n /** Not allowed at top level in multi-job mode; define `args` per job key. */\n consumer?: never;\n /** Not allowed at top level in multi-job mode; define `args` per job key. */\n args?: never;\n /** Not allowed at top level in multi-job mode; define `handler` per job key. */\n handler?: never;\n /** Not allowed in multi-job mode. */\n batchHandler?: never;\n /** Not allowed at top level in multi-job mode; define `onFailure` per job key. */\n onFailure?: never;\n} & TConfig;\n\n/**\n * Producer handle for a single queue declaration.\n */\nexport interface QueueHandle<E, TMessage> {\n /** Sends one message to the queue. */\n send(ctx: { env: QueueEnv<E> }, data: TMessage, options?: SendOptions): Promise<void>;\n /** Sends multiple messages in one request. */\n sendBatch(\n ctx: { env: QueueEnv<E> },\n messages: SendBatchEntry<TMessage>[],\n options?: SendBatchOptions\n ): Promise<void>;\n}\n\n/**\n * Producer handles keyed by job name for a multi-job queue.\n */\nexport type MultiJobQueueHandle<\n E,\n TJobs extends Record<string, AnyJobConfig<E>>\n> = {\n [K in keyof TJobs]: {\n /** Sends one message to a named job. */\n send(\n ctx: { env: QueueEnv<E> },\n data: z.infer<TJobs[K]['args']>,\n options?: SendOptions\n ): Promise<void>;\n /** Sends many messages to a named job. */\n sendBatch(\n ctx: { env: QueueEnv<E> },\n messages: SendBatchEntry<z.infer<TJobs[K]['args']>>[],\n options?: SendBatchOptions\n ): Promise<void>;\n };\n};\n\n/**\n * Worker handlers used to define module exports.\n */\nexport interface WorkerConfig<E> {\n /** Main fetch handler. */\n fetch: (request: Request, ctx: WorkerContext<E>) => Promise<Response>;\n /** Optional scheduled handler. */\n scheduled?: (event: ScheduledEvent, ctx: WorkerContext<E>) => Promise<void>;\n}\n\n/**\n * Worker module shape returned by `defineWorker`.\n */\nexport interface WorkerEntrypoint<E> {\n /** Cloudflare module `fetch` entrypoint. */\n fetch(request: Request, env: E, executionCtx: ExecutionContext): Promise<Response>;\n /** Optional Cloudflare module `scheduled` entrypoint. */\n scheduled?: (event: ScheduledEvent, env: E, executionCtx: ExecutionContext) => Promise<void>;\n}\n\n/**\n * Defines a worker module with typed queue-aware context.\n */\nexport type DefineWorker<E> = (config: WorkerConfig<E>) => WorkerEntrypoint<E>;\n\n/**\n * Defines a single queue contract and returns a typed producer handle.\n */\nexport interface DefineQueue<E> {\n /**\n * Declare a single queue (worker consumer or http pull consumer).\n *\n * @example\n * defineQueue({\n * args: z.object({ id: z.string() }),\n * handler: async (ctx, args) => {}\n * })\n *\n * @remarks\n * Use exactly one of `handler` or `batchHandler` for worker-consumer queues.\n */\n <TSchema extends z.ZodTypeAny>(config: QueueConfig<E, TSchema>): QueueHandle<E, z.infer<TSchema>>;\n}\n\n/**\n * Defines a multi-job queue contract and returns job-keyed producer handles.\n */\nexport interface DefineQueues<E> {\n /**\n * Declare a multi-job queue where each top-level key is a job definition.\n *\n * @example\n * defineQueues({\n * email: { args: z.object({ to: z.string() }), handler: async () => {} },\n * audit: { args: z.object({ id: z.string() }), handler: async () => {} }\n * })\n *\n * @remarks\n * Shared queue settings (for example `retry`, `retryDelay`, `batch`) stay at the top level.\n */\n <const TConfig extends Record<string, unknown>>(\n config: MultiJobQueueConfig<E, TConfig>\n ): MultiJobQueueHandle<E, ExtractJobMap<E, TConfig>>;\n}\n\n/**\n * Internal helper type that supports both single and multi-job queue declarations.\n */\nexport interface DefineAnyQueue<E> extends DefineQueue<E>, DefineQueues<E> {}\n\n/**\n * SDK helpers returned by `createSDK`.\n */\nexport interface BetterCfSDK<E> {\n /** Single-queue helper. */\n defineQueue: DefineQueue<E>;\n /** Multi-job helper where each top-level key is a job declaration. */\n defineQueues: DefineQueues<E>;\n /** Worker declaration helper that maps to Cloudflare module handlers. */\n defineWorker: DefineWorker<E>;\n}\n\n/**\n * Internal helper alias for any queue config mode.\n */\nexport type AnyQueueConfig<E> = QueueConfig<E, z.ZodTypeAny>;\n/**\n * Internal helper alias for worker-consumer queue modes.\n */\nexport type AnyPushQueueConfig<E> = QueueProcessConfig<E, z.ZodTypeAny> | QueueBatchConfig<E, z.ZodTypeAny>;\n/**\n * Internal helper alias for pull-consumer queue mode.\n */\nexport type AnyPullQueueConfig<E> = QueuePullConfig<E, z.ZodTypeAny>;\n\n/**\n * Internal helper alias for any multi-job queue config.\n */\nexport type AnyMultiJobQueueConfig<E> = MultiJobQueueConfig<E, Record<string, unknown>>;\n\n/**\n * Normalized queue definition used by runtime internals.\n */\nexport type QueueDefinition<E> =\n | { kind: 'single'; mode: 'push'; config: AnyPushQueueConfig<E> }\n | { kind: 'single'; mode: 'pull'; config: AnyPullQueueConfig<E> }\n | {\n kind: 'multi';\n jobs: Record<string, AnyJobConfig<E>>;\n shared: QueueCommonConfig;\n };\n\n/**\n * Reserved top-level keys treated as shared config in multi-job mode.\n */\nexport const RESERVED_MULTI_JOB_KEYS = new Set([\n 'retry',\n 'retryDelay',\n 'deadLetter',\n 'deliveryDelay',\n 'visibilityTimeout',\n 'batch',\n 'consumer',\n 'args',\n 'handler',\n 'batchHandler',\n 'onFailure',\n 'message',\n 'process',\n 'processBatch'\n]);\n","import { consumeQueueDefinition } from './consumer.js';\nimport { getQueueInternals, kQueueInternals } from './internal.js';\nimport {\n RESERVED_MULTI_JOB_KEYS,\n type AnyMultiJobQueueConfig,\n type AnyPullQueueConfig,\n type AnyPushQueueConfig,\n type DefineQueue,\n type DefineQueues,\n type ExtractJobMap,\n type JobConfig,\n type MultiJobQueueConfig,\n type MultiJobQueueHandle,\n type QueueConfig,\n type QueueDefinition,\n type QueueHandle,\n type SendBatchEntry,\n type SendBatchOptions,\n type SendOptions\n} from './types.js';\nimport { isPlainObject, mergeSendOptions, toCloudflareSendOptions } from './utils.js';\nimport type { z } from 'zod';\n\nconst LEGACY_SCHEMA_KEY = 'message';\nconst LEGACY_SINGLE_HANDLER_KEYS = ['process', 'processBatch'] as const;\n\n/**\n * Creates a typed `defineQueue` helper bound to the SDK env generic.\n */\nexport function defineQueueFactory<E>(): DefineQueue<E> {\n return function defineQueue<TSchema extends z.ZodTypeAny>(\n config: QueueConfig<E, TSchema>\n ): QueueHandle<E, z.infer<TSchema>> {\n assertNoLegacySingleQueueKeys(config);\n const definition = toSingleQueueDefinition(config as QueueConfig<E, z.ZodTypeAny>);\n return createQueueHandle(definition) as QueueHandle<E, z.infer<TSchema>>;\n };\n}\n\n/**\n * Creates a typed `defineQueues` helper bound to the SDK env generic.\n */\nexport function defineQueuesFactory<E>(): DefineQueues<E> {\n return function defineQueues<const TConfig extends Record<string, unknown>>(\n config: MultiJobQueueConfig<E, TConfig>\n ): MultiJobQueueHandle<E, ExtractJobMap<E, TConfig>> {\n assertNoLegacyMultiQueueKeys(config as AnyMultiJobQueueConfig<E>);\n const definition = toMultiQueueDefinition(config as AnyMultiJobQueueConfig<E>);\n return createQueueHandle(definition) as MultiJobQueueHandle<E, ExtractJobMap<E, TConfig>>;\n };\n}\n\nfunction createQueueHandle<E>(\n definition: QueueDefinition<E>\n): QueueHandle<E, unknown> | MultiJobQueueHandle<E, Record<string, JobConfig<E, z.ZodTypeAny>>> {\n let bindingName: string | null = null;\n\n const sendBase = async (ctx: { env: E }, body: unknown, options?: SendOptions): Promise<void> => {\n if (!bindingName) {\n throw new Error('Queue binding not initialized. Run through better-cf dev/generate/deploy generated entry.');\n }\n\n const binding = (ctx.env as Record<string, unknown>)[bindingName] as\n | {\n send: (value: unknown, opts?: { delaySeconds?: number; contentType?: SendOptions['contentType'] }) => Promise<void>;\n }\n | undefined;\n\n if (!binding || typeof binding.send !== 'function') {\n throw new Error(`Queue binding ${bindingName} not found in env.`);\n }\n\n await binding.send(body, toCloudflareSendOptions(options));\n };\n\n const sendBatchBase = async (\n ctx: { env: E },\n messages: Array<{ body: unknown; options?: SendOptions }>\n ): Promise<void> => {\n if (!bindingName) {\n throw new Error('Queue binding not initialized. Run through better-cf dev/generate/deploy generated entry.');\n }\n\n const binding = (ctx.env as Record<string, unknown>)[bindingName] as\n | {\n sendBatch: (entries: Array<{ body: unknown; delaySeconds?: number; contentType?: SendOptions['contentType'] }>) => Promise<void>;\n }\n | undefined;\n\n if (!binding || typeof binding.sendBatch !== 'function') {\n throw new Error(`Queue binding ${bindingName} not found in env.`);\n }\n\n const payload = messages.map((item) => ({\n body: item.body,\n ...toCloudflareSendOptions(item.options)\n }));\n await binding.sendBatch(payload);\n };\n\n const baseHandle: Record<string | symbol, unknown> = {\n async send(ctx: { env: E }, data: unknown, options?: SendOptions): Promise<void> {\n if (definition.kind === 'single') {\n await sendBase(ctx, data, options);\n return;\n }\n\n await sendBase(ctx, { _job: '__default', data }, options);\n },\n\n async sendBatch(\n ctx: { env: E },\n messages: SendBatchEntry<unknown>[],\n options?: SendBatchOptions\n ): Promise<void> {\n if (definition.kind === 'single') {\n await sendBatchBase(\n ctx,\n messages.map((message) => ({\n body: message.data,\n options: mergeSendOptions(message, options)\n }))\n );\n return;\n }\n\n await sendBatchBase(\n ctx,\n messages.map((message) => ({\n body: { _job: '__default', data: message.data },\n options: mergeSendOptions(message, options)\n }))\n );\n }\n };\n\n if (definition.kind === 'multi') {\n for (const jobName of Object.keys(definition.jobs)) {\n baseHandle[jobName] = {\n async send(ctx: { env: E }, data: unknown, options?: SendOptions) {\n await sendBase(ctx, { _job: jobName, data }, options);\n },\n async sendBatch(\n ctx: { env: E },\n messages: SendBatchEntry<unknown>[],\n options?: SendBatchOptions\n ) {\n await sendBatchBase(\n ctx,\n messages.map((message) => ({\n body: { _job: jobName, data: message.data },\n options: mergeSendOptions(message, options)\n }))\n );\n }\n };\n }\n }\n\n Object.defineProperty(baseHandle, kQueueInternals, {\n enumerable: false,\n configurable: false,\n writable: false,\n value: {\n setBinding(name: string) {\n bindingName = name;\n },\n getBinding() {\n return bindingName;\n },\n getDefinition() {\n return definition;\n },\n consume(batch: MessageBatch<unknown>, env: E, executionCtx: ExecutionContext) {\n return consumeQueueDefinition(definition, batch, env, executionCtx);\n }\n }\n });\n\n return baseHandle as unknown as QueueHandle<E, unknown>;\n}\n\n/**\n * Attaches the generated Cloudflare binding name to a queue handle.\n */\nexport function setQueueBinding<E>(handle: unknown, binding: string): void {\n getQueueInternals<E>(handle).setBinding(binding);\n}\n\n/**\n * Reads normalized queue metadata from a queue handle.\n */\nexport function readQueueDefinition<E>(handle: unknown): QueueDefinition<E> {\n return getQueueInternals<E>(handle).getDefinition();\n}\n\nfunction toSingleQueueDefinition<E>(config: QueueConfig<E, z.ZodTypeAny>): QueueDefinition<E> {\n if (isPullQueue(config)) {\n if ('handler' in config || 'batchHandler' in config) {\n throw new Error('Queue config with consumer.type=\"http_pull\" cannot define handler/batchHandler.');\n }\n return {\n kind: 'single',\n mode: 'pull',\n config: config as AnyPullQueueConfig<E>\n };\n }\n\n if (hasHandler(config) && hasBatchHandler(config)) {\n throw new Error('Queue config cannot define both handler and batchHandler.');\n }\n\n if (!hasHandler(config) && !hasBatchHandler(config)) {\n throw new Error('Queue config must define one of handler or batchHandler in worker consumer mode.');\n }\n\n return {\n kind: 'single',\n mode: 'push',\n config: config as AnyPushQueueConfig<E>\n };\n}\n\nfunction toMultiQueueDefinition<E>(config: AnyMultiJobQueueConfig<E>): QueueDefinition<E> {\n const shared = {\n retry: config.retry,\n retryDelay: config.retryDelay,\n deadLetter: config.deadLetter,\n deliveryDelay: config.deliveryDelay,\n visibilityTimeout: config.visibilityTimeout,\n batch: config.batch\n };\n\n const jobs: Record<string, JobConfig<E, z.ZodTypeAny>> = {};\n for (const [key, value] of Object.entries(config)) {\n if (RESERVED_MULTI_JOB_KEYS.has(key)) {\n continue;\n }\n\n if (hasLegacyKeys(value)) {\n throw new Error(\n `Multi-job queue \"${key}\" uses legacy keys. Rename message->args and process/processBatch->handler/batchHandler.`\n );\n }\n\n if (isPlainObject(value) && 'batchHandler' in value) {\n throw new Error(`Multi-job queue \"${key}\" cannot define batchHandler. Use handler per job.`);\n }\n\n if (isJobConfig(value)) {\n jobs[key] = value;\n }\n }\n\n if (Object.keys(jobs).length === 0) {\n throw new Error('Multi-job queue config must define at least one job.');\n }\n\n return {\n kind: 'multi',\n jobs,\n shared\n };\n}\n\nfunction isPullQueue<E>(config: QueueConfig<E, z.ZodTypeAny>): boolean {\n return 'consumer' in config && Boolean(config.consumer && config.consumer.type === 'http_pull');\n}\n\nfunction hasHandler<E>(config: QueueConfig<E, z.ZodTypeAny>): boolean {\n return 'handler' in config && typeof config.handler === 'function';\n}\n\nfunction hasBatchHandler<E>(config: QueueConfig<E, z.ZodTypeAny>): boolean {\n return 'batchHandler' in config && typeof config.batchHandler === 'function';\n}\n\nfunction isJobConfig<E>(value: unknown): value is JobConfig<E, z.ZodTypeAny> {\n if (!isPlainObject(value)) {\n return false;\n }\n\n return 'args' in value && 'handler' in value;\n}\n\nfunction assertNoLegacySingleQueueKeys(config: unknown): void {\n if (!isPlainObject(config)) {\n return;\n }\n\n const legacyKeys = [LEGACY_SCHEMA_KEY, ...LEGACY_SINGLE_HANDLER_KEYS].filter((key) => key in config);\n if (legacyKeys.length === 0) {\n return;\n }\n\n throw new Error(\n `Queue config uses legacy keys (${legacyKeys.join(', ')}). Rename message->args, process->handler, processBatch->batchHandler.`\n );\n}\n\nfunction assertNoLegacyMultiQueueKeys(config: AnyMultiJobQueueConfig<unknown>): void {\n const topLevelLegacyKeys = [LEGACY_SCHEMA_KEY, ...LEGACY_SINGLE_HANDLER_KEYS].filter((key) => key in config);\n if (topLevelLegacyKeys.length > 0) {\n throw new Error(\n `Multi-job queue config uses legacy keys (${topLevelLegacyKeys.join(', ')}). Use defineQueues({ job: { args, handler } }).`\n );\n }\n\n for (const [jobName, value] of Object.entries(config)) {\n if (RESERVED_MULTI_JOB_KEYS.has(jobName) || !isPlainObject(value)) {\n continue;\n }\n\n if (hasLegacyKeys(value)) {\n throw new Error(\n `Multi-job queue \"${jobName}\" uses legacy keys. Rename message->args and process/processBatch->handler/batchHandler.`\n );\n }\n }\n}\n\nfunction hasLegacyKeys(value: unknown): boolean {\n if (!isPlainObject(value)) {\n return false;\n }\n\n return LEGACY_SCHEMA_KEY in value || LEGACY_SINGLE_HANDLER_KEYS.some((key) => key in value);\n}\n","import type { DefineWorker, QueueEnv, WorkerConfig, WorkerEntrypoint } from './types.js';\n\n/**\n * Creates a typed `defineWorker` helper bound to the SDK env generic.\n */\nexport function defineWorkerFactory<E>(): DefineWorker<E> {\n return function defineWorker(config: WorkerConfig<E>): WorkerEntrypoint<E> {\n return {\n async fetch(request: Request, env: E, executionCtx: ExecutionContext): Promise<Response> {\n return config.fetch(request, {\n env: env as QueueEnv<E>,\n executionCtx\n });\n },\n ...(config.scheduled\n ? {\n async scheduled(event: ScheduledEvent, env: E, executionCtx: ExecutionContext): Promise<void> {\n await config.scheduled?.(event, {\n env: env as QueueEnv<E>,\n executionCtx\n });\n }\n }\n : {})\n };\n };\n}\n","import { defineQueueFactory, defineQueuesFactory } from './define-queue.js';\nimport { defineWorkerFactory } from './define-worker.js';\nimport type { BetterCfAutoEnv, BetterCfSDK } from './types.js';\n\n/**\n * Creates typed queue + worker helpers for your Cloudflare Worker app.\n *\n * @example\n * const { defineQueue, defineQueues, defineWorker } = createSDK<Env>();\n */\nexport function createSDK<E extends Record<string, unknown> = BetterCfAutoEnv>(): BetterCfSDK<E> {\n const defineQueue = defineQueueFactory<E>();\n const defineQueues = defineQueuesFactory<E>();\n\n return {\n defineQueue,\n defineQueues,\n defineWorker: defineWorkerFactory<E>()\n };\n}\n"]}
|
package/dist/queue/internal.d.ts
CHANGED
package/dist/testing/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Options for queue consumer tests.
|
|
3
3
|
*/
|
|
4
4
|
interface TestQueueBaseOptions<E> {
|
|
5
|
+
/** Worker env object passed into queue consume simulation. */
|
|
5
6
|
env: E;
|
|
6
7
|
/** Overrides message attempts metadata. */
|
|
7
8
|
attempts?: number;
|
|
@@ -29,6 +30,10 @@ interface TestQueueResult<TMessage> {
|
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
31
32
|
* Runs a queue declaration's consumer logic in-memory for tests.
|
|
33
|
+
*
|
|
34
|
+
* @param handle Queue handle returned by `defineQueue(...)` or `defineQueues(...)`.
|
|
35
|
+
* @param options Test input payloads and env.
|
|
36
|
+
* @returns Acked/retried payload collections captured from the simulated consume flow.
|
|
32
37
|
*/
|
|
33
38
|
declare function testQueue<E, TMessage>(handle: unknown, options: TestQueueOptions<E, TMessage>): Promise<TestQueueResult<TMessage>>;
|
|
34
39
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/queue/internal.ts","../../src/testing/index.ts"],"names":[],"mappings":";AAKO,IAAM,eAAA,mBAAkB,MAAA,CAAO,GAAA,CAAI,2BAA2B,CAAA;AAmB9D,SAAS,kBAAqB,KAAA,EAAqC;AACxE,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACvC,IAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,EAClD;AAEA,EAAA,MAAM,SAAA,GAAa,MAAgC,eAAe,CAAA;AAClE,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,MAAM,yCAAyC,CAAA;AAAA,EAC3D;AAEA,EAAA,OAAO,SAAA;AACT;;;
|
|
1
|
+
{"version":3,"sources":["../../src/queue/internal.ts","../../src/testing/index.ts"],"names":[],"mappings":";AAKO,IAAM,eAAA,mBAAkB,MAAA,CAAO,GAAA,CAAI,2BAA2B,CAAA;AAmB9D,SAAS,kBAAqB,KAAA,EAAqC;AACxE,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,QAAA,EAAU;AACvC,IAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,EAClD;AAEA,EAAA,MAAM,SAAA,GAAa,MAAgC,eAAe,CAAA;AAClE,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,MAAM,yCAAyC,CAAA;AAAA,EAC3D;AAEA,EAAA,OAAO,SAAA;AACT;;;ACSA,eAAsB,SAAA,CACpB,QACA,OAAA,EACoC;AACpC,EAAA,MAAM,SAAA,GAAY,kBAAqB,MAAM,CAAA;AAE7C,EAAA,IAAI,SAAA,IAAa,OAAA,IAAW,UAAA,IAAc,OAAA,EAAS;AACjD,IAAA,MAAM,IAAI,MAAM,yDAAyD,CAAA;AAAA,EAC3E;AAEA,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,QAAA,KAAa,OAAA,CAAQ,OAAA,KAAY,SAAY,CAAC,OAAA,CAAQ,OAAO,CAAA,GAAI,EAAC,CAAA;AAC9F,EAAA,IAAI,WAAA,CAAY,WAAW,CAAA,EAAG;AAC5B,IAAA,MAAM,IAAI,MAAM,yCAAyC,CAAA;AAAA,EAC3D;AAEA,EAAA,MAAM,MAAA,GAAoC;AAAA,IACxC,OAAO,EAAC;AAAA,IACR,SAAS;AAAC,GACZ;AAEA,EAAA,MAAM,KAAA,GAA+B;AAAA,IACnC,KAAA,EAAO,YAAA;AAAA,IACP,QAAA,EAAU,WAAA,CAAY,GAAA,CAAI,CAAC,MAAM,KAAA,MAAW;AAAA,MAC1C,EAAA,EAAI,OAAO,KAAK,CAAA,CAAA;AAAA,MAChB,SAAA,sBAAe,IAAA,EAAK;AAAA,MACpB,IAAA;AAAA,MACA,QAAA,EAAU,QAAQ,QAAA,IAAY,CAAA;AAAA,MAC9B,KAAK,MAAM;AACT,QAAA,MAAA,CAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,MACxB,CAAA;AAAA,MACA,OAAO,MAAM;AACX,QAAA,MAAA,CAAO,OAAA,CAAQ,KAAK,IAAI,CAAA;AAAA,MAC1B;AAAA,KACF,CAAE,CAAA;AAAA,IACF,QAAQ,MAAM;AACZ,MAAA,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,GAAG,WAAW,CAAA;AAAA,IAClC,CAAA;AAAA,IACA,UAAU,MAAM;AACd,MAAA,MAAA,CAAO,OAAA,CAAQ,IAAA,CAAK,GAAG,WAAW,CAAA;AAAA,IACpC;AAAA,GACF;AAEA,EAAA,MAAM,YAAA,GAAe;AAAA,IACnB,SAAA,GAAY;AACV,MAAA;AAAA,IACF,CAAA;AAAA,IACA,sBAAA,GAAyB;AACvB,MAAA;AAAA,IACF,CAAA;AAAA,IACA,OAAO;AAAC,GACV;AAEA,EAAA,MAAM,SAAA,CAAU,OAAA,CAAQ,KAAA,EAAO,OAAA,CAAQ,KAAK,YAAY,CAAA;AAExD,EAAA,OAAO,MAAA;AACT","file":"index.js","sourcesContent":["import type { QueueDefinition } from './types.js';\n\n/**\n * Symbol used to store non-enumerable queue internals on queue handles.\n */\nexport const kQueueInternals = Symbol.for('better-cf.queue.internals');\n\n/**\n * Internal queue API used by runtime/testing/CLI internals.\n */\nexport interface QueueInternalApi<E> {\n setBinding(name: string): void;\n getBinding(): string | null;\n getDefinition(): QueueDefinition<E>;\n consume(batch: MessageBatch<unknown>, env: E, executionCtx: ExecutionContext): Promise<void>;\n}\n\nexport type QueueWithInternals<E> = {\n [kQueueInternals]: QueueInternalApi<E>;\n};\n\n/**\n * Reads internal queue metadata from a queue handle.\n */\nexport function getQueueInternals<E>(value: unknown): QueueInternalApi<E> {\n if (!value || typeof value !== 'object') {\n throw new Error('Queue handle is not an object.');\n }\n\n const internals = (value as QueueWithInternals<E>)[kQueueInternals];\n if (!internals) {\n throw new Error('Object is not a better-cf queue handle.');\n }\n\n return internals;\n}\n\n/**\n * Input module shape accepted when resolving worker handlers.\n */\nexport interface WorkerModuleLike {\n default?: unknown;\n fetch?: (request: Request, env: unknown, ctx: ExecutionContext) => Promise<Response>;\n scheduled?: (\n event: ScheduledEvent,\n env: unknown,\n ctx: ExecutionContext\n ) => Promise<void>;\n}\n\n/**\n * Normalized handler pair resolved from a worker module export.\n */\nexport interface ResolvedWorkerHandlers {\n fetch: (request: Request, env: unknown, ctx: ExecutionContext) => Promise<Response>;\n scheduled?: (event: ScheduledEvent, env: unknown, ctx: ExecutionContext) => Promise<void>;\n}\n\n/**\n * Resolves `fetch`/`scheduled` handlers from various worker export styles.\n */\nexport function resolveWorkerHandlers(moduleLike: WorkerModuleLike): ResolvedWorkerHandlers {\n const root = moduleLike.default ?? moduleLike;\n\n let fetchHandler: ResolvedWorkerHandlers['fetch'] | undefined;\n if (typeof root === 'function') {\n fetchHandler = root as ResolvedWorkerHandlers['fetch'];\n } else if (root && typeof root === 'object' && 'fetch' in root) {\n const maybeFetch = (root as { fetch?: unknown }).fetch;\n if (typeof maybeFetch === 'function') {\n fetchHandler = maybeFetch.bind(root) as ResolvedWorkerHandlers['fetch'];\n }\n }\n\n if (!fetchHandler && typeof moduleLike.fetch === 'function') {\n fetchHandler = moduleLike.fetch;\n }\n\n if (!fetchHandler) {\n throw new Error(\n 'Could not resolve worker fetch handler. Export default app/object/function or named fetch.'\n );\n }\n\n let scheduledHandler: ResolvedWorkerHandlers['scheduled'] | undefined;\n if (root && typeof root === 'object' && 'scheduled' in root) {\n const maybeScheduled = (root as { scheduled?: unknown }).scheduled;\n if (typeof maybeScheduled === 'function') {\n scheduledHandler = maybeScheduled.bind(root) as ResolvedWorkerHandlers['scheduled'];\n }\n }\n\n if (!scheduledHandler && typeof moduleLike.scheduled === 'function') {\n scheduledHandler = moduleLike.scheduled;\n }\n\n return {\n fetch: fetchHandler,\n scheduled: scheduledHandler\n };\n}\n","import { getQueueInternals } from '../queue/internal.js';\n\n/**\n * Options for queue consumer tests.\n */\ninterface TestQueueBaseOptions<E> {\n /** Worker env object passed into queue consume simulation. */\n env: E;\n /** Overrides message attempts metadata. */\n attempts?: number;\n}\n\n/**\n * Options for queue consumer tests.\n */\nexport type TestQueueOptions<E, TMessage> =\n | (TestQueueBaseOptions<E> & {\n /** Test one message. */\n message: TMessage;\n messages?: never;\n })\n | (TestQueueBaseOptions<E> & {\n /** Test many messages in one batch. */\n messages: TMessage[];\n message?: never;\n });\n\n/**\n * Test execution result for queue consumers.\n */\nexport interface TestQueueResult<TMessage> {\n /** Messages acked by the consumer. */\n acked: TMessage[];\n /** Messages retried by the consumer. */\n retried: TMessage[];\n}\n\n/**\n * Runs a queue declaration's consumer logic in-memory for tests.\n *\n * @param handle Queue handle returned by `defineQueue(...)` or `defineQueues(...)`.\n * @param options Test input payloads and env.\n * @returns Acked/retried payload collections captured from the simulated consume flow.\n */\nexport async function testQueue<E, TMessage>(\n handle: unknown,\n options: TestQueueOptions<E, TMessage>\n): Promise<TestQueueResult<TMessage>> {\n const internals = getQueueInternals<E>(handle);\n\n if ('message' in options && 'messages' in options) {\n throw new Error('testQueue accepts either message or messages, not both.');\n }\n\n const allMessages = options.messages ?? (options.message !== undefined ? [options.message] : []);\n if (allMessages.length === 0) {\n throw new Error('testQueue requires message or messages.');\n }\n\n const result: TestQueueResult<TMessage> = {\n acked: [],\n retried: []\n };\n\n const batch: MessageBatch<unknown> = {\n queue: 'test-queue',\n messages: allMessages.map((body, index) => ({\n id: `msg-${index}`,\n timestamp: new Date(),\n body,\n attempts: options.attempts ?? 1,\n ack: () => {\n result.acked.push(body);\n },\n retry: () => {\n result.retried.push(body);\n }\n })),\n ackAll: () => {\n result.acked.push(...allMessages);\n },\n retryAll: () => {\n result.retried.push(...allMessages);\n }\n };\n\n const executionCtx = {\n waitUntil() {\n return;\n },\n passThroughOnException() {\n return;\n },\n props: {}\n } as unknown as ExecutionContext;\n\n await internals.consume(batch, options.env, executionCtx);\n\n return result;\n}\n"]}
|
|
@@ -40,20 +40,30 @@ type SendBatchOptions = SendOptions;
|
|
|
40
40
|
* Per-message input for `sendBatch`.
|
|
41
41
|
*/
|
|
42
42
|
interface SendBatchEntry<T> {
|
|
43
|
+
/** Payload to enqueue. */
|
|
43
44
|
data: T;
|
|
45
|
+
/** Per-message delay override (takes precedence over batch-level `options.delay`). */
|
|
44
46
|
delay?: Duration;
|
|
47
|
+
/** Per-message content type override (takes precedence over batch-level `options.contentType`). */
|
|
45
48
|
contentType?: ContentType;
|
|
46
49
|
}
|
|
47
50
|
/**
|
|
48
51
|
* Context passed to per-message queue consumers.
|
|
49
52
|
*/
|
|
50
53
|
interface QueueContext<E> {
|
|
54
|
+
/** Queue-aware runtime environment (`env` + generated bindings). */
|
|
51
55
|
env: QueueEnv<E>;
|
|
56
|
+
/** Cloudflare execution context. */
|
|
52
57
|
executionCtx: ExecutionContext;
|
|
58
|
+
/** Metadata for the currently processed message. */
|
|
53
59
|
message: {
|
|
60
|
+
/** Unique Cloudflare queue message id. */
|
|
54
61
|
id: string;
|
|
62
|
+
/** Message enqueue timestamp. */
|
|
55
63
|
timestamp: Date;
|
|
64
|
+
/** Delivery attempt count for this message. */
|
|
56
65
|
attempts: number;
|
|
66
|
+
/** Queue name currently being consumed. */
|
|
57
67
|
queue: string;
|
|
58
68
|
};
|
|
59
69
|
}
|
|
@@ -61,13 +71,21 @@ interface QueueContext<E> {
|
|
|
61
71
|
* Context passed to batch queue consumers.
|
|
62
72
|
*/
|
|
63
73
|
interface BatchContext<E> {
|
|
74
|
+
/** Queue-aware runtime environment (`env` + generated bindings). */
|
|
64
75
|
env: QueueEnv<E>;
|
|
76
|
+
/** Cloudflare execution context. */
|
|
65
77
|
executionCtx: ExecutionContext;
|
|
78
|
+
/** Batch metadata + helpers for explicit ack/retry control. */
|
|
66
79
|
batch: {
|
|
80
|
+
/** Queue name currently being consumed. */
|
|
67
81
|
queue: string;
|
|
82
|
+
/** When the batch was received by this worker invocation. */
|
|
68
83
|
receivedAt: Date;
|
|
84
|
+
/** Timestamp of first message in this batch (if present). */
|
|
69
85
|
firstMessageTimestamp?: Date;
|
|
86
|
+
/** Ack every message in the current batch. */
|
|
70
87
|
ackAll: () => void;
|
|
88
|
+
/** Retry every message in the current batch. */
|
|
71
89
|
retryAll: (options?: {
|
|
72
90
|
delaySeconds?: number;
|
|
73
91
|
}) => void;
|
|
@@ -77,16 +95,22 @@ interface BatchContext<E> {
|
|
|
77
95
|
* Context passed to worker handlers.
|
|
78
96
|
*/
|
|
79
97
|
interface WorkerContext<E> {
|
|
98
|
+
/** Queue-aware runtime environment (`env` + generated bindings). */
|
|
80
99
|
env: QueueEnv<E>;
|
|
100
|
+
/** Cloudflare execution context. */
|
|
81
101
|
executionCtx: ExecutionContext;
|
|
82
102
|
}
|
|
83
103
|
/**
|
|
84
104
|
* Message shape received by batch consumers.
|
|
85
105
|
*/
|
|
86
106
|
interface ConsumerBatchEntry<T> {
|
|
107
|
+
/** Validated payload data. */
|
|
87
108
|
data: T;
|
|
109
|
+
/** Unique Cloudflare queue message id. */
|
|
88
110
|
id: string;
|
|
111
|
+
/** Message enqueue timestamp. */
|
|
89
112
|
timestamp: Date;
|
|
113
|
+
/** Delivery attempt count for this message. */
|
|
90
114
|
attempts: number;
|
|
91
115
|
}
|
|
92
116
|
/**
|
|
@@ -105,8 +129,11 @@ interface QueueCommonConfig {
|
|
|
105
129
|
visibilityTimeout?: Duration;
|
|
106
130
|
/** Batch processing tuning (worker consumer mode only). */
|
|
107
131
|
batch?: {
|
|
132
|
+
/** Maximum number of messages per delivered batch. */
|
|
108
133
|
maxSize?: number;
|
|
134
|
+
/** Maximum time to wait before delivering a partial batch. */
|
|
109
135
|
timeout?: Duration;
|
|
136
|
+
/** Maximum concurrent batch invocations. */
|
|
110
137
|
maxConcurrency?: number;
|
|
111
138
|
};
|
|
112
139
|
}
|
|
@@ -116,55 +143,72 @@ interface QueueCommonConfig {
|
|
|
116
143
|
interface PullConsumerConfig {
|
|
117
144
|
/** Pull mode marker. */
|
|
118
145
|
type: 'http_pull';
|
|
119
|
-
/** Pull visibility timeout
|
|
146
|
+
/** Pull visibility timeout (seconds or duration shorthand). */
|
|
120
147
|
visibilityTimeout?: Duration;
|
|
121
148
|
}
|
|
122
149
|
/**
|
|
123
150
|
* Per-message queue handler.
|
|
124
151
|
*/
|
|
125
|
-
type
|
|
152
|
+
type QueueHandler<E, TSchema extends z.ZodTypeAny> = (ctx: QueueContext<E>, args: z.infer<TSchema>) => Promise<void>;
|
|
126
153
|
/**
|
|
127
154
|
* Batch queue handler.
|
|
128
155
|
*/
|
|
129
|
-
type
|
|
156
|
+
type QueueBatchHandler<E, TSchema extends z.ZodTypeAny> = (ctx: BatchContext<E>, args: ConsumerBatchEntry<z.infer<TSchema>>[]) => Promise<void>;
|
|
130
157
|
/**
|
|
131
158
|
* Optional failure handler for queue processing.
|
|
132
159
|
*/
|
|
133
|
-
type QueueFailureHandler<E, TSchema extends z.ZodTypeAny> = (ctx: QueueContext<E> | BatchContext<E>,
|
|
160
|
+
type QueueFailureHandler<E, TSchema extends z.ZodTypeAny> = (ctx: QueueContext<E> | BatchContext<E>, args: z.infer<TSchema> | null, error: Error) => Promise<void>;
|
|
134
161
|
/**
|
|
135
162
|
* Worker-consumer queue with per-message processing.
|
|
136
163
|
*/
|
|
137
164
|
type QueueProcessConfig<E, TSchema extends z.ZodTypeAny> = QueueCommonConfig & {
|
|
138
|
-
|
|
165
|
+
/** Zod schema used to validate each incoming payload. */
|
|
166
|
+
args: TSchema;
|
|
167
|
+
/** Optional explicit worker consumer marker. */
|
|
139
168
|
consumer?: {
|
|
140
169
|
type?: 'worker';
|
|
141
170
|
};
|
|
142
|
-
|
|
143
|
-
|
|
171
|
+
/** Per-message push handler. */
|
|
172
|
+
handler: QueueHandler<E, TSchema>;
|
|
173
|
+
/** Not allowed in single-message mode. */
|
|
174
|
+
batchHandler?: never;
|
|
175
|
+
/** Optional failure hook when `handler` throws or payload validation fails. */
|
|
144
176
|
onFailure?: QueueFailureHandler<E, TSchema>;
|
|
145
177
|
};
|
|
146
178
|
/**
|
|
147
179
|
* Worker-consumer queue with batch processing.
|
|
148
180
|
*/
|
|
149
181
|
type QueueBatchConfig<E, TSchema extends z.ZodTypeAny> = QueueCommonConfig & {
|
|
150
|
-
|
|
182
|
+
/** Zod schema used to validate each payload before `batchHandler` runs. */
|
|
183
|
+
args: TSchema;
|
|
184
|
+
/** Optional explicit worker consumer marker. */
|
|
151
185
|
consumer?: {
|
|
152
186
|
type?: 'worker';
|
|
153
187
|
};
|
|
154
|
-
|
|
155
|
-
|
|
188
|
+
/** Not allowed in batch mode. */
|
|
189
|
+
handler?: never;
|
|
190
|
+
/** Batch push handler. */
|
|
191
|
+
batchHandler: QueueBatchHandler<E, TSchema>;
|
|
192
|
+
/** Optional failure hook when `batchHandler` throws or batch validation fails. */
|
|
156
193
|
onFailure?: QueueFailureHandler<E, TSchema>;
|
|
157
194
|
};
|
|
158
195
|
/**
|
|
159
196
|
* HTTP pull consumer queue (producer-only declaration).
|
|
160
197
|
*/
|
|
161
198
|
type QueuePullConfig<E, TSchema extends z.ZodTypeAny> = Omit<QueueCommonConfig, 'visibilityTimeout' | 'batch'> & {
|
|
162
|
-
|
|
199
|
+
/** Zod schema for producer payload typing in pull mode. */
|
|
200
|
+
args: TSchema;
|
|
201
|
+
/** Required pull consumer configuration. */
|
|
163
202
|
consumer: PullConsumerConfig;
|
|
203
|
+
/** Not allowed in pull mode. */
|
|
164
204
|
batch?: never;
|
|
205
|
+
/** Not allowed in pull mode. */
|
|
165
206
|
visibilityTimeout?: never;
|
|
166
|
-
|
|
167
|
-
|
|
207
|
+
/** Not allowed in pull mode. */
|
|
208
|
+
handler?: never;
|
|
209
|
+
/** Not allowed in pull mode. */
|
|
210
|
+
batchHandler?: never;
|
|
211
|
+
/** Not allowed in pull mode. */
|
|
168
212
|
onFailure?: never;
|
|
169
213
|
};
|
|
170
214
|
/**
|
|
@@ -175,9 +219,12 @@ type QueueConfig<E, TSchema extends z.ZodTypeAny> = QueueProcessConfig<E, TSchem
|
|
|
175
219
|
* Per-job declaration inside a multi-job queue.
|
|
176
220
|
*/
|
|
177
221
|
interface JobConfig<E, TSchema extends z.ZodTypeAny> {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
222
|
+
/** Zod schema used to validate this job's payload. */
|
|
223
|
+
args: TSchema;
|
|
224
|
+
/** Job handler for this job key. */
|
|
225
|
+
handler: (ctx: QueueContext<E>, args: z.infer<TSchema>) => Promise<void>;
|
|
226
|
+
/** Optional failure hook for this job handler. */
|
|
227
|
+
onFailure?: (ctx: QueueContext<E>, args: z.infer<TSchema>, error: Error) => Promise<void>;
|
|
181
228
|
}
|
|
182
229
|
/**
|
|
183
230
|
* Internal helper alias for any job config.
|
|
@@ -193,10 +240,15 @@ type ExtractJobMap<E, TConfig extends Record<string, unknown>> = {
|
|
|
193
240
|
* Multi-job queue declaration object.
|
|
194
241
|
*/
|
|
195
242
|
type MultiJobQueueConfig<E, TConfig extends Record<string, unknown>> = QueueCommonConfig & {
|
|
243
|
+
/** Not allowed at top level in multi-job mode; define `args` per job key. */
|
|
196
244
|
consumer?: never;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
245
|
+
/** Not allowed at top level in multi-job mode; define `args` per job key. */
|
|
246
|
+
args?: never;
|
|
247
|
+
/** Not allowed at top level in multi-job mode; define `handler` per job key. */
|
|
248
|
+
handler?: never;
|
|
249
|
+
/** Not allowed in multi-job mode. */
|
|
250
|
+
batchHandler?: never;
|
|
251
|
+
/** Not allowed at top level in multi-job mode; define `onFailure` per job key. */
|
|
200
252
|
onFailure?: never;
|
|
201
253
|
} & TConfig;
|
|
202
254
|
/**
|
|
@@ -220,11 +272,11 @@ type MultiJobQueueHandle<E, TJobs extends Record<string, AnyJobConfig<E>>> = {
|
|
|
220
272
|
/** Sends one message to a named job. */
|
|
221
273
|
send(ctx: {
|
|
222
274
|
env: QueueEnv<E>;
|
|
223
|
-
}, data: z.infer<TJobs[K]['
|
|
275
|
+
}, data: z.infer<TJobs[K]['args']>, options?: SendOptions): Promise<void>;
|
|
224
276
|
/** Sends many messages to a named job. */
|
|
225
277
|
sendBatch(ctx: {
|
|
226
278
|
env: QueueEnv<E>;
|
|
227
|
-
}, messages: SendBatchEntry<z.infer<TJobs[K]['
|
|
279
|
+
}, messages: SendBatchEntry<z.infer<TJobs[K]['args']>>[], options?: SendBatchOptions): Promise<void>;
|
|
228
280
|
};
|
|
229
281
|
};
|
|
230
282
|
/**
|
|
@@ -240,7 +292,9 @@ interface WorkerConfig<E> {
|
|
|
240
292
|
* Worker module shape returned by `defineWorker`.
|
|
241
293
|
*/
|
|
242
294
|
interface WorkerEntrypoint<E> {
|
|
295
|
+
/** Cloudflare module `fetch` entrypoint. */
|
|
243
296
|
fetch(request: Request, env: E, executionCtx: ExecutionContext): Promise<Response>;
|
|
297
|
+
/** Optional Cloudflare module `scheduled` entrypoint. */
|
|
244
298
|
scheduled?: (event: ScheduledEvent, env: E, executionCtx: ExecutionContext) => Promise<void>;
|
|
245
299
|
}
|
|
246
300
|
/**
|
|
@@ -248,7 +302,7 @@ interface WorkerEntrypoint<E> {
|
|
|
248
302
|
*/
|
|
249
303
|
type DefineWorker<E> = (config: WorkerConfig<E>) => WorkerEntrypoint<E>;
|
|
250
304
|
/**
|
|
251
|
-
* Defines queue
|
|
305
|
+
* Defines a single queue contract and returns a typed producer handle.
|
|
252
306
|
*/
|
|
253
307
|
interface DefineQueue<E> {
|
|
254
308
|
/**
|
|
@@ -256,19 +310,30 @@ interface DefineQueue<E> {
|
|
|
256
310
|
*
|
|
257
311
|
* @example
|
|
258
312
|
* defineQueue({
|
|
259
|
-
*
|
|
260
|
-
*
|
|
313
|
+
* args: z.object({ id: z.string() }),
|
|
314
|
+
* handler: async (ctx, args) => {}
|
|
261
315
|
* })
|
|
316
|
+
*
|
|
317
|
+
* @remarks
|
|
318
|
+
* Use exactly one of `handler` or `batchHandler` for worker-consumer queues.
|
|
262
319
|
*/
|
|
263
320
|
<TSchema extends z.ZodTypeAny>(config: QueueConfig<E, TSchema>): QueueHandle<E, z.infer<TSchema>>;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Defines a multi-job queue contract and returns job-keyed producer handles.
|
|
324
|
+
*/
|
|
325
|
+
interface DefineQueues<E> {
|
|
264
326
|
/**
|
|
265
327
|
* Declare a multi-job queue where each top-level key is a job definition.
|
|
266
328
|
*
|
|
267
329
|
* @example
|
|
268
|
-
*
|
|
269
|
-
* email: {
|
|
270
|
-
* audit: {
|
|
330
|
+
* defineQueues({
|
|
331
|
+
* email: { args: z.object({ to: z.string() }), handler: async () => {} },
|
|
332
|
+
* audit: { args: z.object({ id: z.string() }), handler: async () => {} }
|
|
271
333
|
* })
|
|
334
|
+
*
|
|
335
|
+
* @remarks
|
|
336
|
+
* Shared queue settings (for example `retry`, `retryDelay`, `batch`) stay at the top level.
|
|
272
337
|
*/
|
|
273
338
|
<const TConfig extends Record<string, unknown>>(config: MultiJobQueueConfig<E, TConfig>): MultiJobQueueHandle<E, ExtractJobMap<E, TConfig>>;
|
|
274
339
|
}
|
|
@@ -276,8 +341,10 @@ interface DefineQueue<E> {
|
|
|
276
341
|
* SDK helpers returned by `createSDK`.
|
|
277
342
|
*/
|
|
278
343
|
interface BetterCfSDK<E> {
|
|
279
|
-
/**
|
|
344
|
+
/** Single-queue helper. */
|
|
280
345
|
defineQueue: DefineQueue<E>;
|
|
346
|
+
/** Multi-job helper where each top-level key is a job declaration. */
|
|
347
|
+
defineQueues: DefineQueues<E>;
|
|
281
348
|
/** Worker declaration helper that maps to Cloudflare module handlers. */
|
|
282
349
|
defineWorker: DefineWorker<E>;
|
|
283
350
|
}
|
|
@@ -306,4 +373,4 @@ type QueueDefinition<E> = {
|
|
|
306
373
|
shared: QueueCommonConfig;
|
|
307
374
|
};
|
|
308
375
|
|
|
309
|
-
export type { BetterCfAutoEnv as B, ConsumerBatchEntry as C, DefineQueue as D, JobConfig as J, MultiJobQueueConfig as M, PullConsumerConfig as P, QueueDefinition as Q, SendBatchEntry as S, WorkerConfig as W, BetterCfSDK as a, BatchContext as b, BetterCfGeneratedBindings as c, ContentType as d,
|
|
376
|
+
export type { BetterCfAutoEnv as B, ConsumerBatchEntry as C, DefineQueue as D, JobConfig as J, MultiJobQueueConfig as M, PullConsumerConfig as P, QueueDefinition as Q, SendBatchEntry as S, WorkerConfig as W, BetterCfSDK as a, BatchContext as b, BetterCfGeneratedBindings as c, ContentType as d, DefineQueues as e, DefineWorker as f, Duration as g, MultiJobQueueHandle as h, QueueCommonConfig as i, QueueConfig as j, QueueContext as k, QueueEnv as l, QueueHandle as m, SendBatchOptions as n, SendOptions as o, WorkerContext as p, WorkerEntrypoint as q };
|