@velajs/cloudflare 1.29.0 → 1.30.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/CHANGELOG.md +24 -0
- package/README.md +2 -1
- package/dist/_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js +9 -0
- package/dist/_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js +6 -0
- package/dist/_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateParam.js +8 -0
- package/dist/cloudflare-application.js +309 -0
- package/dist/cloudflare-application.js.map +1 -0
- package/dist/cloudflare-factory.js +109 -0
- package/dist/cloudflare-factory.js.map +1 -0
- package/dist/decorators/queue-consumer.js +39 -0
- package/dist/decorators/queue-consumer.js.map +1 -0
- package/dist/durable-objects.d.ts +3 -4
- package/dist/durable-objects.js +2 -524
- package/dist/environment.js +19 -0
- package/dist/environment.js.map +1 -0
- package/dist/index.d.ts +11 -9
- package/dist/index.js +21 -1276
- package/dist/nonce/durable-object-nonce.store.js +33 -0
- package/dist/nonce/durable-object-nonce.store.js.map +1 -0
- package/dist/nonce/nonce-validation.js +18 -0
- package/dist/nonce/nonce-validation.js.map +1 -0
- package/dist/nonce/nonce.durable-object.js +54 -0
- package/dist/nonce/nonce.durable-object.js.map +1 -0
- package/dist/{nonce.durable-object-Df4CZi-0.d.ts → nonce.durable-object-Ci9AGssY.d.ts} +2 -3
- package/dist/queue/cloudflare-queues.js +215 -0
- package/dist/queue/cloudflare-queues.js.map +1 -0
- package/dist/queues.d.ts +1 -2
- package/dist/queues.js +1 -214
- package/dist/rate-limit/cloudflare-rate-limit.store.js +40 -0
- package/dist/rate-limit/cloudflare-rate-limit.store.js.map +1 -0
- package/dist/schedule-diagnostics.js +51 -0
- package/dist/schedule-diagnostics.js.map +1 -0
- package/dist/scheduled-event.js +68 -0
- package/dist/scheduled-event.js.map +1 -0
- package/dist/services/flagship-flag.driver.js +52 -0
- package/dist/services/flagship-flag.driver.js.map +1 -0
- package/dist/services/kv-cache.store.js +82 -0
- package/dist/services/kv-cache.store.js.map +1 -0
- package/dist/services/kv-flag.driver.js +62 -0
- package/dist/services/kv-flag.driver.js.map +1 -0
- package/dist/storage/r2-storage.driver.js +67 -0
- package/dist/storage/r2-storage.driver.js.map +1 -0
- package/dist/storage/storage-key-claim.js +74 -0
- package/dist/storage/storage-key-claim.js.map +1 -0
- package/dist/storage/storage-manager.service.js +38 -0
- package/dist/storage/storage-manager.service.js.map +1 -0
- package/dist/storage/storage.controller.js +64 -0
- package/dist/storage/storage.controller.js.map +1 -0
- package/dist/storage/storage.module.js +25 -0
- package/dist/storage/storage.module.js.map +1 -0
- package/dist/storage/storage.service.js +64 -0
- package/dist/storage/storage.service.js.map +1 -0
- package/dist/storage/storage.tokens.js +7 -0
- package/dist/storage/storage.tokens.js.map +1 -0
- package/dist/vela-env-DFvyoNT3.d.ts +1 -2
- package/dist/websocket/broadcast.js +32 -0
- package/dist/websocket/broadcast.js.map +1 -0
- package/dist/websocket/cf-room-registry.js +137 -0
- package/dist/websocket/cf-room-registry.js.map +1 -0
- package/dist/websocket/cf-ws-client.js +94 -0
- package/dist/websocket/cf-ws-client.js.map +1 -0
- package/dist/websocket/cloudflare-websocket.module.js +25 -0
- package/dist/websocket/cloudflare-websocket.module.js.map +1 -0
- package/dist/websocket/do-bootstrap.js +56 -0
- package/dist/websocket/do-bootstrap.js.map +1 -0
- package/dist/websocket/do-live.js +184 -0
- package/dist/websocket/do-live.js.map +1 -0
- package/dist/websocket/do-pitr.js +81 -0
- package/dist/websocket/do-pitr.js.map +1 -0
- package/dist/websocket/do-state.js +7 -0
- package/dist/websocket/do-state.js.map +1 -0
- package/dist/websocket/do-websocket-host.js +169 -0
- package/dist/websocket/do-websocket-host.js.map +1 -0
- package/dist/websocket/room-id.js +27 -0
- package/dist/websocket/room-id.js.map +1 -0
- package/dist/websocket/websocket-routing.js +133 -0
- package/dist/websocket/websocket-routing.js.map +1 -0
- package/dist/websocket/websocket.durable-object.js +138 -0
- package/dist/websocket/websocket.durable-object.js.map +1 -0
- package/dist/websocket/ws-attachment.js +79 -0
- package/dist/websocket/ws-attachment.js.map +1 -0
- package/dist/websocket/ws-server-holder.js +38 -0
- package/dist/websocket/ws-server-holder.js.map +1 -0
- package/package.json +9 -7
- package/dist/durable-objects.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/nonce-validation-Dy8z05A9.js +0 -522
- package/dist/nonce-validation-Dy8z05A9.js.map +0 -1
- package/dist/queues.js.map +0 -1
package/dist/queues.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queues.js","names":[],"sources":["../src/queue/cloudflare-queues.ts"],"sourcesContent":["import { observeMessage, parseQueueJob, QueueBatchError } from '@velajs/vela/queue';\nimport type {\n AddJobOptions,\n QueueDispatchFn,\n QueueDispatchResult,\n QueueDriver,\n QueueDriverContext,\n QueueDriverFactory,\n QueueEnqueueRequest,\n QueueJob,\n QueueMessageLike,\n} from '@velajs/vela/queue';\n\n/** The native producer surface the driver uses: a Wrangler `queues.producers` binding. */\nexport interface CloudflareQueueProducer {\n // Both older void-returning bindings and current metric-returning bindings work.\n send(message: QueueJob, options?: QueueSendOptions): Promise<unknown>;\n sendBatch?(messages: Iterable<MessageSendRequest<QueueJob>>): Promise<unknown>;\n}\n\n/** The Cloudflare Queues send limits `addBulk` is chunked to (bytes are decimal kilobytes). */\nexport const QUEUE_SEND_LIMITS = Object.freeze({\n /** Messages per `sendBatch` call. */\n messages: 100,\n /** Estimated bytes per `sendBatch` call. */\n batchBytes: 256_000,\n /** Estimated bytes per message. */\n messageBytes: 128_000,\n});\n\n/** Allowance for the platform's per-message framing on top of the body estimate. */\nconst MESSAGE_MARGIN_BYTES = 256;\nconst MAX_DELAY_MS = 86_400_000;\n\n/**\n * A string's size as JSON (UTF-8, quoted, escaped) or as V8 serializes it\n * (one byte per character, two for a string holding any character above\n * U+00FF), whichever is larger.\n */\nfunction stringBytes(text: string): number {\n let json = 2;\n let wide = false;\n for (let index = 0; index < text.length; index++) {\n const code = text.charCodeAt(index);\n if (code > 0xff) wide = true;\n if (code < 0x20) json += 6;\n else if (code === 0x22 || code === 0x5c) json += 2;\n else if (code < 0x80) json += 1;\n else if (code < 0x800) json += 2;\n else if (code >= 0xd800 && code <= 0xdfff) json += 2;\n else json += 3;\n }\n return Math.max(json, (wide ? text.length * 2 : text.length) + 5);\n}\n\nfunction measure(value: unknown, seen: Set<object>): number {\n switch (typeof value) {\n case 'string':\n return stringBytes(value);\n case 'number':\n return Math.max(String(value).length, 9);\n case 'bigint':\n return String(value).length + 9;\n case 'boolean':\n return 5;\n case 'object':\n break;\n default:\n return 9;\n }\n if (value === null) return 4;\n // V8 serializes a repeated reference as a back-reference.\n if (seen.has(value)) return 9;\n seen.add(value);\n let bytes = 2;\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer) {\n bytes += value.byteLength + 9;\n } else if (value instanceof Date) {\n bytes += 26;\n } else if (value instanceof Map) {\n for (const [key, item] of value) bytes += measure(key, seen) + measure(item, seen) + 2;\n } else if (value instanceof Set) {\n for (const item of value) bytes += measure(item, seen) + 1;\n } else if (Array.isArray(value)) {\n for (const item of value) bytes += measure(item, seen) + 1;\n } else {\n for (const key of Object.keys(value)) {\n bytes += stringBytes(key) + measure(Reflect.get(value, key), seen) + 2;\n }\n }\n return bytes;\n}\n\n/**\n * A conservative size estimate of one native queue message: the larger of the\n * body's JSON and V8 sizes, plus a per-message margin.\n */\nexport function estimateQueueMessageBytes(body: unknown): number {\n return measure(body, new Set()) + MESSAGE_MARGIN_BYTES;\n}\n\nfunction delaySeconds(options: AddJobOptions | undefined): number | undefined {\n const delayMs = options?.delayMs;\n if (delayMs === undefined) return undefined;\n if (!Number.isFinite(delayMs) || delayMs < 0 || delayMs > MAX_DELAY_MS) {\n throw new RangeError('Queue delayMs must be between 0 and 86400000.');\n }\n return Math.ceil(delayMs / 1000);\n}\n\nfunction isProducer(value: unknown): value is CloudflareQueueProducer {\n return (\n typeof value === 'object' && value !== null && typeof Reflect.get(value, 'send') === 'function'\n );\n}\n\nfunction nativeBatch(payload: unknown): { queue: string; messages: QueueMessageLike[] } {\n if (\n typeof payload !== 'object' ||\n payload === null ||\n !('queue' in payload) ||\n typeof payload.queue !== 'string' ||\n !('messages' in payload) ||\n !Array.isArray(payload.messages)\n )\n throw new TypeError('Invalid native queue batch.');\n const messages: QueueMessageLike[] = [];\n for (const message of payload.messages as unknown[]) {\n if (\n typeof message !== 'object' ||\n message === null ||\n !('body' in message) ||\n !('ack' in message) ||\n typeof message.ack !== 'function' ||\n !('retry' in message) ||\n typeof message.retry !== 'function' ||\n !('id' in message) ||\n typeof message.id !== 'string' ||\n !('timestamp' in message) ||\n !(message.timestamp instanceof Date) ||\n !('attempts' in message) ||\n typeof message.attempts !== 'number'\n )\n throw new TypeError('Invalid native queue message.');\n messages.push(message as QueueMessageLike);\n }\n return { queue: payload.queue, messages };\n}\n\ninterface PreparedMessage {\n readonly id: string;\n readonly queue: string;\n readonly bytes: number;\n readonly request: MessageSendRequest<QueueJob>;\n}\n\n/** Split in order: a new call starts at 100 messages, at the byte budget, or at another queue. */\nfunction chunk(messages: readonly PreparedMessage[]): PreparedMessage[][] {\n const chunks: PreparedMessage[][] = [];\n let current: PreparedMessage[] = [];\n let bytes = 0;\n for (const message of messages) {\n if (\n current.length > 0 &&\n (current.length === QUEUE_SEND_LIMITS.messages ||\n bytes + message.bytes > QUEUE_SEND_LIMITS.batchBytes ||\n current[0]!.queue !== message.queue)\n ) {\n chunks.push(current);\n current = [];\n bytes = 0;\n }\n current.push(message);\n bytes += message.bytes;\n }\n if (current.length > 0) chunks.push(current);\n return chunks;\n}\n\nfunction createDriver({ env, queues }: QueueDriverContext): QueueDriver {\n // Physical queue -> the logical queues registrations pin to it.\n const pins = new Map<string, string[]>();\n for (const queue of queues.all()) {\n for (const physical of queue.consumers) {\n pins.set(physical, [...(pins.get(physical) ?? []), queue.name]);\n }\n }\n\n // Resolved on every send from this application's ENV, never cached.\n const producerFor = (name: string): CloudflareQueueProducer => {\n const registration = queues.get(name);\n if (!registration) {\n throw new Error(\n `Queue '${name}' is not registered. Add QueueModule.registerQueue({ name: '${name}', ` +\n `binding }) to the module that produces it.`,\n );\n }\n if (registration.binding === undefined) {\n throw new Error(\n `Queue '${name}' has no producer binding. Register it with ` +\n `QueueModule.registerQueue({ name: '${name}', binding: 'YOUR_QUEUE' }), where the ` +\n `binding is a queues.producers[].binding of this Worker.`,\n );\n }\n if (env === undefined) {\n throw new Error(\n `cloudflareQueues() needs the Workers ENV to send '${name}' jobs. Build the application ` +\n `with createCloudflareWorker, createCloudflareApp or cloudflareAdapter.`,\n );\n }\n const producer: unknown = Reflect.get(env, registration.binding);\n if (!isProducer(producer)) {\n throw new TypeError(\n `ENV.${registration.binding} is not a Cloudflare queue producer binding (queue ` +\n `'${name}'). Declare it under queues.producers in this Worker's Wrangler configuration.`,\n );\n }\n return producer;\n };\n\n return {\n kind: 'cloudflare',\n entrypoints: [{ kind: 'cf:queue:module', meta: { consumers: [...pins.keys()] } }],\n\n async consume(payload: unknown, dispatch: QueueDispatchFn): Promise<void> {\n const batch = nativeBatch(payload);\n const pinned = pins.get(batch.queue);\n await consumeQueueBatch(\n batch,\n (job) => {\n // A pinned queue is consumed only from the physical queues it names.\n const expected = queues.get(job.queue)?.consumers ?? [];\n if (expected.length > 0 && !expected.includes(batch.queue)) {\n throw new Error(\n `Queue '${job.queue}' is consumed from ` +\n `${expected.map((queue) => `'${queue}'`).join(', ')}, not '${batch.queue}'.`,\n );\n }\n return dispatch(job);\n },\n pinned ? { queues: pinned } : {},\n );\n },\n\n async enqueue(job: QueueJob, options?: AddJobOptions): Promise<void> {\n const delay = delaySeconds(options);\n await producerFor(job.queue).send(\n parseQueueJob(job),\n delay === undefined ? undefined : { delaySeconds: delay },\n );\n },\n\n async enqueueBatch(requests: readonly QueueEnqueueRequest[]): Promise<void> {\n // Validate every job and resolve every binding before the first send.\n const messages = requests.map(({ job, options }): PreparedMessage => {\n const body = parseQueueJob(job);\n const bytes = estimateQueueMessageBytes(body);\n if (bytes > QUEUE_SEND_LIMITS.messageBytes) {\n throw new RangeError(\n `Queue job '${job.id}' is an estimated ${bytes} bytes, over the ` +\n `${QUEUE_SEND_LIMITS.messageBytes}-byte Cloudflare message limit. Store large ` +\n `payloads elsewhere (for example in R2) and enqueue a reference.`,\n );\n }\n const delay = delaySeconds(options);\n return {\n id: job.id,\n queue: job.queue,\n bytes,\n request: delay === undefined ? { body } : { body, delaySeconds: delay },\n };\n });\n const producers = new Map<string, CloudflareQueueProducer>();\n for (const { queue } of messages) {\n if (!producers.has(queue)) producers.set(queue, producerFor(queue));\n }\n const accepted: string[] = [];\n for (const part of chunk(messages)) {\n const producer = producers.get(part[0]!.queue)!;\n try {\n if (typeof producer.sendBatch === 'function') {\n // eslint-disable-next-line no-await-in-loop\n await producer.sendBatch(part.map(({ request }) => request));\n accepted.push(...part.map(({ id }) => id));\n } else {\n for (const { id, request } of part) {\n const delay = request.delaySeconds;\n // eslint-disable-next-line no-await-in-loop\n await producer.send(\n request.body,\n delay === undefined ? undefined : { delaySeconds: delay },\n );\n accepted.push(id);\n }\n }\n } catch (error) {\n throw new QueueBatchError(\n accepted,\n messages.slice(accepted.length).map(({ id }) => id),\n error,\n );\n }\n }\n },\n };\n}\n\n/**\n * The Cloudflare Queues driver for `QueueModule`:\n *\n * ```ts\n * QueueModule.forRoot({ driver: cloudflareQueues() })\n * QueueModule.registerQueue({ name: 'email', binding: 'EMAIL_QUEUE' })\n * ```\n *\n * Each application gets its own driver. Producing reads the registered binding\n * from that application's `ENV` when a job is added and awaits the native\n * send; `addBulk` uses `sendBatch`, chunked to {@link QUEUE_SEND_LIMITS}.\n * Consuming is native too: the Worker's `queue()` handler routes every batch\n * that no `@QueueConsumer` claims through `QueueModule`, one message at a time,\n * by each job's logical `queue`, with the module's dispatch policy (signed\n * dispatch included). A registration's `consumer` pins its queue to that\n * physical queue: the queue's jobs are accepted only from it, and it only\n * carries the queues pinned to it. A message that is not a job envelope,\n * belongs to an unregistered queue, or fails stays unacknowledged, so\n * Cloudflare retries it and then dead-letters it.\n */\nexport function cloudflareQueues(): QueueDriverFactory {\n return (context) => createDriver(context);\n}\n\nexport interface ConsumeQueueBatchOptions {\n /**\n * Accept only jobs of these logical queues; any other message fails and is\n * retried. By default every job envelope is accepted.\n */\n readonly queues?: readonly string[];\n}\n\n/**\n * Settle native messages one job at a time. Attempts come from the host.\n * Process every message; ack successful/unsettled deliveries, then rethrow any\n * failures so the host retries the unsettled remainder. Explicit settlement wins.\n * The callback must await all work that should determine delivery success.\n */\nexport async function consumeQueueBatch(\n batch: { readonly queue: string; readonly messages: readonly QueueMessageLike[] },\n dispatch: (job: QueueJob, message: QueueMessageLike) => Promise<QueueDispatchResult | void>,\n options: ConsumeQueueBatchOptions = {},\n): Promise<void> {\n const errors: unknown[] = [];\n for (const message of batch.messages) {\n try {\n const job = parseQueueJob(message.body, message.attempts);\n if (options.queues && !options.queues.includes(job.queue)) {\n throw new Error(\n `Queue '${job.queue}' is not consumed from '${batch.queue}', which accepts ` +\n `${options.queues.map((queue) => `'${queue}'`).join(', ')}.`,\n );\n }\n const observed = observeMessage(message);\n // eslint-disable-next-line no-await-in-loop\n const result = await dispatch(job, observed.message);\n if (result?.handled === 0) throw new Error(`Queue job '${job.name}' has no handler.`);\n if (observed.disposition().outcome === 'unsettled') observed.message.ack();\n } catch (error) {\n errors.push(error);\n }\n }\n if (errors.length === 1) throw errors[0];\n if (errors.length > 1) throw new AggregateError(errors, 'Queue batch deliveries failed.');\n}\n"],"mappings":"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"}
|