@velajs/cloudflare 1.28.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.
Files changed (91) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/README.md +190 -69
  3. package/dist/_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js +9 -0
  4. package/dist/_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateMetadata.js +6 -0
  5. package/dist/_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorateParam.js +8 -0
  6. package/dist/cloudflare-application.js +309 -0
  7. package/dist/cloudflare-application.js.map +1 -0
  8. package/dist/cloudflare-factory.js +109 -0
  9. package/dist/cloudflare-factory.js.map +1 -0
  10. package/dist/decorators/queue-consumer.js +39 -0
  11. package/dist/decorators/queue-consumer.js.map +1 -0
  12. package/dist/durable-objects.d.ts +11 -11
  13. package/dist/durable-objects.js +2 -512
  14. package/dist/environment.js +19 -0
  15. package/dist/environment.js.map +1 -0
  16. package/dist/index.d.ts +146 -111
  17. package/dist/index.js +21 -1130
  18. package/dist/nonce/durable-object-nonce.store.js +33 -0
  19. package/dist/nonce/durable-object-nonce.store.js.map +1 -0
  20. package/dist/nonce/nonce-validation.js +18 -0
  21. package/dist/nonce/nonce-validation.js.map +1 -0
  22. package/dist/nonce/nonce.durable-object.js +54 -0
  23. package/dist/nonce/nonce.durable-object.js.map +1 -0
  24. package/dist/{nonce.durable-object-DffHMRnU.d.ts → nonce.durable-object-Ci9AGssY.d.ts} +9 -7
  25. package/dist/queue/cloudflare-queues.js +215 -0
  26. package/dist/queue/cloudflare-queues.js.map +1 -0
  27. package/dist/queues.d.ts +48 -0
  28. package/dist/queues.js +2 -0
  29. package/dist/rate-limit/cloudflare-rate-limit.store.js +40 -0
  30. package/dist/rate-limit/cloudflare-rate-limit.store.js.map +1 -0
  31. package/dist/schedule-diagnostics.js +51 -0
  32. package/dist/schedule-diagnostics.js.map +1 -0
  33. package/dist/scheduled-event.js +68 -0
  34. package/dist/scheduled-event.js.map +1 -0
  35. package/dist/services/flagship-flag.driver.js +52 -0
  36. package/dist/services/flagship-flag.driver.js.map +1 -0
  37. package/dist/services/kv-cache.store.js +82 -0
  38. package/dist/services/kv-cache.store.js.map +1 -0
  39. package/dist/services/kv-flag.driver.js +62 -0
  40. package/dist/services/kv-flag.driver.js.map +1 -0
  41. package/dist/storage/r2-storage.driver.js +67 -0
  42. package/dist/storage/r2-storage.driver.js.map +1 -0
  43. package/dist/storage/storage-key-claim.js +74 -0
  44. package/dist/storage/storage-key-claim.js.map +1 -0
  45. package/dist/storage/storage-manager.service.js +38 -0
  46. package/dist/storage/storage-manager.service.js.map +1 -0
  47. package/dist/storage/storage.controller.js +64 -0
  48. package/dist/storage/storage.controller.js.map +1 -0
  49. package/dist/storage/storage.module.js +25 -0
  50. package/dist/storage/storage.module.js.map +1 -0
  51. package/dist/storage/storage.service.js +64 -0
  52. package/dist/storage/storage.service.js.map +1 -0
  53. package/dist/storage/storage.tokens.js +7 -0
  54. package/dist/storage/storage.tokens.js.map +1 -0
  55. package/dist/vela-env-DFvyoNT3.d.ts +9 -0
  56. package/dist/websocket/broadcast.js +32 -0
  57. package/dist/websocket/broadcast.js.map +1 -0
  58. package/dist/websocket/cf-room-registry.js +137 -0
  59. package/dist/websocket/cf-room-registry.js.map +1 -0
  60. package/dist/websocket/cf-ws-client.js +94 -0
  61. package/dist/websocket/cf-ws-client.js.map +1 -0
  62. package/dist/websocket/cloudflare-websocket.module.js +25 -0
  63. package/dist/websocket/cloudflare-websocket.module.js.map +1 -0
  64. package/dist/websocket/do-bootstrap.js +56 -0
  65. package/dist/websocket/do-bootstrap.js.map +1 -0
  66. package/dist/websocket/do-live.js +184 -0
  67. package/dist/websocket/do-live.js.map +1 -0
  68. package/dist/websocket/do-pitr.js +81 -0
  69. package/dist/websocket/do-pitr.js.map +1 -0
  70. package/dist/websocket/do-state.js +7 -0
  71. package/dist/websocket/do-state.js.map +1 -0
  72. package/dist/websocket/do-websocket-host.js +169 -0
  73. package/dist/websocket/do-websocket-host.js.map +1 -0
  74. package/dist/websocket/room-id.js +27 -0
  75. package/dist/websocket/room-id.js.map +1 -0
  76. package/dist/websocket/websocket-routing.js +133 -0
  77. package/dist/websocket/websocket-routing.js.map +1 -0
  78. package/dist/websocket/websocket.durable-object.js +138 -0
  79. package/dist/websocket/websocket.durable-object.js.map +1 -0
  80. package/dist/websocket/ws-attachment.js +79 -0
  81. package/dist/websocket/ws-attachment.js.map +1 -0
  82. package/dist/websocket/ws-server-holder.js +38 -0
  83. package/dist/websocket/ws-server-holder.js.map +1 -0
  84. package/package.json +14 -11
  85. package/dist/durable-objects.js.map +0 -1
  86. package/dist/index.js.map +0 -1
  87. package/dist/nonce-validation-CeVihShV.js +0 -517
  88. package/dist/nonce-validation-CeVihShV.js.map +0 -1
  89. package/dist/queue.d.ts +0 -32
  90. package/dist/queue.js +0 -78
  91. package/dist/queue.js.map +0 -1
package/dist/queue.js DELETED
@@ -1,78 +0,0 @@
1
- import { observeMessage, parseQueueJob } from "@velajs/vela/queue";
2
- //#region src/queue/cloudflare-queue.ts
3
- function nativeBatch(payload) {
4
- if (typeof payload !== "object" || payload === null || !("queue" in payload) || typeof payload.queue !== "string" || !("messages" in payload) || !Array.isArray(payload.messages)) throw new TypeError("Invalid native queue batch.");
5
- const messages = [];
6
- for (const message of payload.messages) {
7
- if (typeof message !== "object" || message === null || !("body" in message) || !("ack" in message) || typeof message.ack !== "function" || !("retry" in message) || typeof message.retry !== "function" || !("id" in message) || typeof message.id !== "string" || !("timestamp" in message) || !(message.timestamp instanceof Date) || !("attempts" in message) || typeof message.attempts !== "number") throw new TypeError("Invalid native queue message.");
8
- messages.push(message);
9
- }
10
- return {
11
- queue: payload.queue,
12
- messages
13
- };
14
- }
15
- /** Native sends are awaited. No buffering, implicit retry, or deferred error handling. */
16
- function cloudflareQueueDriver(bindings, options = {}) {
17
- const queues = new Map(Object.entries(bindings));
18
- const consumers = new Map(Object.entries(options.consumers ?? {}));
19
- for (const [physical, logical] of consumers) if (!physical.trim() || !logical.trim()) throw new TypeError("Queue mapping names must not be empty.");
20
- const producerBindings = Object.entries(options.producerBindings ?? {});
21
- for (const [logical, binding] of producerBindings) if (!queues.has(logical) || !binding.trim()) throw new TypeError("Invalid queue producer binding declaration.");
22
- return {
23
- kind: "cloudflare",
24
- entrypoints: [...[...consumers].map(([queueName, queue]) => ({
25
- kind: "cf:queue:module",
26
- queue,
27
- meta: {
28
- queueName,
29
- logicalQueue: queue
30
- }
31
- })), ...producerBindings.map(([queue, binding]) => ({
32
- kind: "cf:queue:producer",
33
- queue,
34
- meta: {
35
- logicalQueue: queue,
36
- binding
37
- }
38
- }))],
39
- async consume(payload, dispatch) {
40
- const batch = nativeBatch(payload);
41
- const queue = consumers.get(batch.queue);
42
- if (!queue) throw new Error(`No consumer mapping for queue '${batch.queue}'.`);
43
- await consumeQueueBatch(batch, (job) => dispatch(job), { queue });
44
- },
45
- async enqueue(job, options) {
46
- const queue = queues.get(job.queue);
47
- if (!queue) throw new Error(`No Cloudflare producer binding for queue '${job.queue}'.`);
48
- const delayMs = options?.delayMs;
49
- if (delayMs !== void 0 && (!Number.isFinite(delayMs) || delayMs < 0 || delayMs > 864e5)) throw new RangeError("Queue delayMs must be between 0 and 86400000.");
50
- await queue.send(parseQueueJob(job), delayMs === void 0 ? void 0 : { delaySeconds: Math.ceil(delayMs / 1e3) });
51
- }
52
- };
53
- }
54
- /**
55
- * Bridge native messages to portable dispatch. Attempts come from the host.
56
- * Process every message; ack successful/unsettled deliveries, then rethrow any
57
- * failures so the host retries the unsettled remainder. Explicit settlement wins.
58
- * The callback must await all work that should determine delivery success.
59
- */
60
- async function consumeQueueBatch(batch, dispatch, options = {}) {
61
- const errors = [];
62
- const queue = options.queue ?? batch.queue;
63
- for (const message of batch.messages) try {
64
- const job = parseQueueJob(message.body, message.attempts);
65
- if (job.queue !== queue) throw new Error(`Queue envelope '${job.queue}' does not match '${queue}'.`);
66
- const observed = observeMessage(message);
67
- if ((await dispatch(job, observed.message))?.handled === 0) throw new Error(`Queue job '${job.name}' has no handler.`);
68
- if (observed.disposition().outcome === "unsettled") observed.message.ack();
69
- } catch (error) {
70
- errors.push(error);
71
- }
72
- if (errors.length === 1) throw errors[0];
73
- if (errors.length > 1) throw new AggregateError(errors, "Queue batch deliveries failed.");
74
- }
75
- //#endregion
76
- export { cloudflareQueueDriver, consumeQueueBatch };
77
-
78
- //# sourceMappingURL=queue.js.map
package/dist/queue.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"queue.js","names":[],"sources":["../src/queue/cloudflare-queue.ts"],"sourcesContent":["import { observeMessage, parseQueueJob } from '@velajs/vela/queue';\nimport type {\n QueueDispatchResult,\n QueueDriver,\n QueueJob,\n QueueMessageLike,\n} from '@velajs/vela/queue';\n\n/** Logical queue names mapped to native producer bindings from this application's environment. */\nexport interface CloudflareQueueProducer {\n // Both older void-returning bindings and current metric-returning bindings work.\n send(message: QueueJob, options?: QueueSendOptions): Promise<unknown>;\n}\nexport type CloudflareQueueBindings = Readonly<Record<string, CloudflareQueueProducer>>;\n\nexport interface CloudflareQueueDriverOptions {\n /** Physical delivery queue name -> logical QueueModule name. */\n consumers?: Readonly<Record<string, string>>;\n /** Logical queue -> Wrangler producer binding name, for deployment inspection. */\n producerBindings?: Readonly<Record<string, string>>;\n}\n\nfunction nativeBatch(payload: unknown): {\n queue: string;\n messages: QueueMessageLike[];\n} {\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\n/** Native sends are awaited. No buffering, implicit retry, or deferred error handling. */\nexport function cloudflareQueueDriver(\n bindings: CloudflareQueueBindings,\n options: CloudflareQueueDriverOptions = {},\n): QueueDriver {\n const queues = new Map(Object.entries(bindings));\n const consumers = new Map(Object.entries(options.consumers ?? {}));\n for (const [physical, logical] of consumers) {\n if (!physical.trim() || !logical.trim())\n throw new TypeError('Queue mapping names must not be empty.');\n }\n const producerBindings = Object.entries(options.producerBindings ?? {});\n for (const [logical, binding] of producerBindings) {\n if (!queues.has(logical) || !binding.trim())\n throw new TypeError('Invalid queue producer binding declaration.');\n }\n return {\n kind: 'cloudflare',\n entrypoints: [\n ...[...consumers].map(([queueName, queue]) => ({\n kind: 'cf:queue:module',\n queue,\n meta: { queueName, logicalQueue: queue },\n })),\n ...producerBindings.map(([queue, binding]) => ({\n kind: 'cf:queue:producer',\n queue,\n meta: { logicalQueue: queue, binding },\n })),\n ],\n async consume(payload, dispatch) {\n const batch = nativeBatch(payload);\n const queue = consumers.get(batch.queue);\n if (!queue) throw new Error(`No consumer mapping for queue '${batch.queue}'.`);\n await consumeQueueBatch(batch, (job) => dispatch(job), { queue });\n },\n async enqueue(job, options) {\n const queue = queues.get(job.queue);\n if (!queue) throw new Error(`No Cloudflare producer binding for queue '${job.queue}'.`);\n const delayMs = options?.delayMs;\n if (\n delayMs !== undefined &&\n (!Number.isFinite(delayMs) || delayMs < 0 || delayMs > 86_400_000)\n ) {\n throw new RangeError('Queue delayMs must be between 0 and 86400000.');\n }\n await queue.send(\n parseQueueJob(job),\n delayMs === undefined ? undefined : { delaySeconds: Math.ceil(delayMs / 1000) },\n );\n },\n };\n}\n\nexport interface ConsumeQueueBatchOptions {\n /** Logical queue name. Defaults to the native batch queue name. */\n queue?: string;\n}\n\n/**\n * Bridge native messages to portable dispatch. 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 const queue = options.queue ?? batch.queue;\n for (const message of batch.messages) {\n try {\n const job = parseQueueJob(message.body, message.attempts);\n if (job.queue !== queue)\n throw new Error(`Queue envelope '${job.queue}' does not match '${queue}'.`);\n const observed = observeMessage(message);\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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"}