better-cf 1.0.0 → 2.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.
@@ -0,0 +1,427 @@
1
+ // src/queue/utils.ts
2
+ function parseDurationSeconds(value) {
3
+ if (typeof value === "number") {
4
+ if (!Number.isFinite(value) || value < 0) {
5
+ throw new Error(`Invalid duration number: ${value}`);
6
+ }
7
+ return value;
8
+ }
9
+ const match = value.match(/^(\d+)(s|m|h)$/);
10
+ if (!match) {
11
+ throw new Error(`Invalid duration string: ${value}`);
12
+ }
13
+ const numberValue = Number.parseInt(match[1], 10);
14
+ const unit = match[2];
15
+ if (unit === "s") {
16
+ return numberValue;
17
+ }
18
+ if (unit === "m") {
19
+ return numberValue * 60;
20
+ }
21
+ return numberValue * 3600;
22
+ }
23
+ function toCloudflareSendOptions(options) {
24
+ if (!options) {
25
+ return {};
26
+ }
27
+ const result = {};
28
+ if (options.delay !== void 0) {
29
+ result.delaySeconds = parseDurationSeconds(options.delay);
30
+ }
31
+ if (options.contentType !== void 0) {
32
+ result.contentType = options.contentType;
33
+ }
34
+ return result;
35
+ }
36
+
37
+ // src/durable-object/internal.ts
38
+ var kDurableObjectInternals = /* @__PURE__ */ Symbol.for("better-cf.durable-object.definition");
39
+ var kDurableRegistrationInternals = /* @__PURE__ */ Symbol.for("better-cf.durable-object.registration");
40
+ var kQueueDefinitionInternals = /* @__PURE__ */ Symbol.for("better-cf.durable-object.queue.definition");
41
+ var kQueueConsumerInternals = /* @__PURE__ */ Symbol.for("better-cf.durable-object.queue.consumer");
42
+ var kWorkerInternals = /* @__PURE__ */ Symbol.for("better-cf.durable-object.worker");
43
+ var apiFactory = null;
44
+ function setGeneratedApiFactory(factory) {
45
+ apiFactory = factory;
46
+ }
47
+ function createRuntimeContext(env, executionCtx) {
48
+ return {
49
+ env,
50
+ executionCtx,
51
+ api: apiFactory?.(env, executionCtx) ?? {}
52
+ };
53
+ }
54
+ function normalizeKey(value) {
55
+ if (typeof value === "string") {
56
+ return value;
57
+ }
58
+ if (typeof value === "number" || typeof value === "boolean" || value === null) {
59
+ return String(value);
60
+ }
61
+ return JSON.stringify(value);
62
+ }
63
+ function makeDurableBaseContext(env, executionCtx, state) {
64
+ const runtime = createRuntimeContext(env, executionCtx);
65
+ return {
66
+ ...runtime,
67
+ state,
68
+ storage: state.storage,
69
+ sql: state.storage.sql
70
+ };
71
+ }
72
+ function getDurableObjectInternals(value) {
73
+ if (!value || typeof value !== "object") {
74
+ throw new Error("Value is not a durable object definition.");
75
+ }
76
+ const internals = value[kDurableObjectInternals];
77
+ if (!internals) {
78
+ throw new Error("Object is not a better-cf durable object handle.");
79
+ }
80
+ return internals;
81
+ }
82
+ function getDurableRegistrationInternals(value) {
83
+ if (!value || typeof value !== "object") {
84
+ throw new Error("Value is not a durable object registration.");
85
+ }
86
+ const internals = value[kDurableRegistrationInternals];
87
+ if (!internals) {
88
+ throw new Error("Object is not a better-cf durable object registration.");
89
+ }
90
+ return internals;
91
+ }
92
+ function getQueueDefinitionInternals(value) {
93
+ if (!value || typeof value !== "object") {
94
+ throw new Error("Value is not a queue definition.");
95
+ }
96
+ const internals = value[kQueueDefinitionInternals];
97
+ if (!internals) {
98
+ throw new Error("Object is not a better-cf durable-object queue handle.");
99
+ }
100
+ return internals;
101
+ }
102
+ function getQueueConsumerInternals(value) {
103
+ if (!value || typeof value !== "object") {
104
+ throw new Error("Value is not a queue consumer registration.");
105
+ }
106
+ const internals = value[kQueueConsumerInternals];
107
+ if (!internals) {
108
+ throw new Error("Object is not a better-cf durable-object queue consumer registration.");
109
+ }
110
+ return internals;
111
+ }
112
+ function getWorkerInternals(value) {
113
+ if (!value || typeof value !== "object") {
114
+ return void 0;
115
+ }
116
+ const internals = value[kWorkerInternals];
117
+ return internals;
118
+ }
119
+ function createQueueProducerApi(binding, payload, options) {
120
+ const queueBinding = binding;
121
+ if (!queueBinding || typeof queueBinding.send !== "function") {
122
+ throw new Error("Queue binding is not available in env.");
123
+ }
124
+ return queueBinding.send(payload, options);
125
+ }
126
+ function createQueueProducerBatchApi(binding, payload) {
127
+ const queueBinding = binding;
128
+ if (!queueBinding || typeof queueBinding.sendBatch !== "function") {
129
+ throw new Error("Queue binding is not available in env.");
130
+ }
131
+ return queueBinding.sendBatch(payload);
132
+ }
133
+ async function consumeQueueRegistration(definitionHandle, consumerRegistration, batch, env, executionCtx) {
134
+ const definition = getQueueDefinitionInternals(definitionHandle);
135
+ const consumer = getQueueConsumerInternals(consumerRegistration);
136
+ const runtime = createRuntimeContext(env, executionCtx);
137
+ if (definition.config.consumer && definition.config.consumer.type === "http_pull") {
138
+ batch.ackAll();
139
+ return;
140
+ }
141
+ if (consumer.type === "batch") {
142
+ let ackOrRetryHandled = false;
143
+ const batchCtx = {
144
+ ...runtime,
145
+ batch: {
146
+ queue: batch.queue,
147
+ receivedAt: /* @__PURE__ */ new Date(),
148
+ firstMessageTimestamp: batch.messages[0]?.timestamp,
149
+ ackAll: () => {
150
+ ackOrRetryHandled = true;
151
+ batch.ackAll();
152
+ },
153
+ retryAll: (options) => {
154
+ ackOrRetryHandled = true;
155
+ batch.retryAll(options);
156
+ }
157
+ }
158
+ };
159
+ try {
160
+ const schema = definition.config.args;
161
+ const entries = batch.messages.map((message) => {
162
+ const parsed = schema.safeParse(message.body);
163
+ if (!parsed.success) {
164
+ throw new Error(`Queue batch validation failed for ${message.id}: ${parsed.error.message}`);
165
+ }
166
+ return {
167
+ data: parsed.data,
168
+ id: message.id,
169
+ timestamp: message.timestamp,
170
+ attempts: message.attempts
171
+ };
172
+ });
173
+ await consumer.config.handler(batchCtx, entries);
174
+ if (!ackOrRetryHandled) {
175
+ batch.ackAll();
176
+ }
177
+ } catch (error) {
178
+ const failure = consumer.config.failure;
179
+ if (failure) {
180
+ await failure(batchCtx, null, toError(error));
181
+ }
182
+ if (!ackOrRetryHandled) {
183
+ batch.retryAll(withRetryDelay(definition.config.retryDelay));
184
+ }
185
+ }
186
+ return;
187
+ }
188
+ if (consumer.type === "job-message") {
189
+ const jobConfig = definition.config[consumer.jobName];
190
+ for (const message of batch.messages) {
191
+ const envelope = message.body;
192
+ if (envelope?._job !== consumer.jobName) {
193
+ if (!envelope?._job) {
194
+ message.ack();
195
+ }
196
+ continue;
197
+ }
198
+ const messageCtx = {
199
+ ...runtime,
200
+ message: {
201
+ id: message.id,
202
+ timestamp: message.timestamp,
203
+ attempts: message.attempts,
204
+ queue: batch.queue
205
+ }
206
+ };
207
+ try {
208
+ const parsed = jobConfig.args.safeParse(envelope.data);
209
+ if (!parsed.success) {
210
+ throw new Error(`Queue job validation failed for ${consumer.jobName}: ${parsed.error.message}`);
211
+ }
212
+ await consumer.config.handler(messageCtx, parsed.data);
213
+ message.ack();
214
+ } catch (error) {
215
+ const failure = consumer.config.failure;
216
+ if (failure) {
217
+ await failure(messageCtx, envelope.data ?? null, toError(error));
218
+ }
219
+ message.retry(withRetryDelay(definition.config.retryDelay));
220
+ }
221
+ }
222
+ return;
223
+ }
224
+ for (const message of batch.messages) {
225
+ const messageCtx = {
226
+ ...runtime,
227
+ message: {
228
+ id: message.id,
229
+ timestamp: message.timestamp,
230
+ attempts: message.attempts,
231
+ queue: batch.queue
232
+ }
233
+ };
234
+ try {
235
+ const schema = definition.config.args;
236
+ const parsed = schema.safeParse(message.body);
237
+ if (!parsed.success) {
238
+ throw new Error(`Queue args validation failed: ${parsed.error.message}`);
239
+ }
240
+ await consumer.config.handler(messageCtx, parsed.data);
241
+ message.ack();
242
+ } catch (error) {
243
+ const failure = consumer.config.failure;
244
+ if (failure) {
245
+ await failure(messageCtx, message.body, toError(error));
246
+ }
247
+ message.retry(withRetryDelay(definition.config.retryDelay));
248
+ }
249
+ }
250
+ }
251
+ async function invokeDurableFunction(env, state, executionCtx, registration, args) {
252
+ const internals = getDurableRegistrationInternals(registration);
253
+ const parsed = internals.config.args.safeParse(args);
254
+ if (!parsed.success) {
255
+ throw new Error(parsed.error.message);
256
+ }
257
+ const ctx = makeDurableBaseContext(env, executionCtx, state);
258
+ const result = await internals.config.handler(ctx, parsed.data);
259
+ if (internals.config.returns) {
260
+ return internals.config.returns.parse(result);
261
+ }
262
+ return result;
263
+ }
264
+ async function invokeDurableFetch(env, state, executionCtx, registration, request) {
265
+ const internals = getDurableRegistrationInternals(registration);
266
+ const ctx = makeDurableBaseContext(env, executionCtx, state);
267
+ return internals.config.handler({
268
+ ...ctx,
269
+ request
270
+ });
271
+ }
272
+ async function invokeDurableAlarm(env, state, executionCtx, registration, alarmInfo) {
273
+ const internals = getDurableRegistrationInternals(registration);
274
+ const ctx = makeDurableBaseContext(env, executionCtx, state);
275
+ await internals.config.handler({
276
+ ...ctx,
277
+ alarmInfo
278
+ });
279
+ }
280
+ async function invokeDurableInit(env, state, executionCtx, registration) {
281
+ const internals = getDurableRegistrationInternals(registration);
282
+ const ctx = makeDurableBaseContext(env, executionCtx, state);
283
+ await internals.config.handler(ctx);
284
+ }
285
+ async function invokeDurableWebSocketConnect(env, state, executionCtx, registration, request) {
286
+ const internals = getDurableRegistrationInternals(registration);
287
+ const pair = new WebSocketPair();
288
+ const client = pair[0];
289
+ const server = pair[1];
290
+ let accepted = false;
291
+ const ctx = makeDurableBaseContext(env, executionCtx, state);
292
+ const response = await internals.config.connect?.({
293
+ ...ctx,
294
+ request,
295
+ client,
296
+ server,
297
+ accept(options) {
298
+ accepted = true;
299
+ state.acceptWebSocket(server, options?.tags);
300
+ if (options?.attachment !== void 0) {
301
+ const attachment = internals.config.serializeAttachment ? internals.config.serializeAttachment(options.attachment) : options.attachment;
302
+ server.serializeAttachment(attachment);
303
+ }
304
+ }
305
+ });
306
+ if (response) {
307
+ return response;
308
+ }
309
+ if (!accepted) {
310
+ state.acceptWebSocket(server);
311
+ }
312
+ return new Response(null, {
313
+ status: 101,
314
+ webSocket: client
315
+ });
316
+ }
317
+ async function invokeDurableWebSocketMessage(env, state, executionCtx, registration, socket, message) {
318
+ const internals = getDurableRegistrationInternals(registration);
319
+ if (!internals.config.message) {
320
+ return;
321
+ }
322
+ const ctx = makeDurableBaseContext(env, executionCtx, state);
323
+ await internals.config.message({
324
+ ...ctx,
325
+ socket,
326
+ attachment: hydrateAttachment(socket, internals)
327
+ }, message);
328
+ }
329
+ async function invokeDurableWebSocketClose(env, state, executionCtx, registration, socket, code, reason, wasClean) {
330
+ const internals = getDurableRegistrationInternals(registration);
331
+ if (!internals.config.close) {
332
+ return;
333
+ }
334
+ const ctx = makeDurableBaseContext(env, executionCtx, state);
335
+ await internals.config.close({
336
+ ...ctx,
337
+ socket,
338
+ attachment: hydrateAttachment(socket, internals)
339
+ }, code, reason, wasClean);
340
+ }
341
+ async function invokeDurableWebSocketError(env, state, executionCtx, registration, socket, error) {
342
+ const internals = getDurableRegistrationInternals(registration);
343
+ if (!internals.config.error) {
344
+ return;
345
+ }
346
+ const ctx = makeDurableBaseContext(env, executionCtx, state);
347
+ await internals.config.error({
348
+ ...ctx,
349
+ socket,
350
+ attachment: hydrateAttachment(socket, internals)
351
+ }, error);
352
+ }
353
+ function hydrateAttachment(socket, internals) {
354
+ const value = socket.deserializeAttachment();
355
+ if (value === void 0) {
356
+ return void 0;
357
+ }
358
+ return internals.config.hydrateAttachment ? internals.config.hydrateAttachment(value) : value;
359
+ }
360
+ function toError(error) {
361
+ return error instanceof Error ? error : new Error(String(error));
362
+ }
363
+ function withRetryDelay(value) {
364
+ if (value === void 0) {
365
+ return void 0;
366
+ }
367
+ return { delaySeconds: parseDurationSeconds(value) };
368
+ }
369
+ function createGeneratedQueueApi(binding, payload, options) {
370
+ return createQueueProducerApi(binding, payload, toCloudflareSendOptions(options));
371
+ }
372
+ function createGeneratedQueueBatchApi(binding, messages) {
373
+ return createQueueProducerBatchApi(
374
+ binding,
375
+ messages.map((message) => ({
376
+ body: message.data,
377
+ ...toCloudflareSendOptions(message)
378
+ }))
379
+ );
380
+ }
381
+ function resolveWorkerHandlers(moduleLike) {
382
+ const root = moduleLike.default ?? moduleLike;
383
+ const worker = getWorkerInternals(root);
384
+ if (worker) {
385
+ return {
386
+ async fetch(request, env, ctx) {
387
+ return worker.config.fetch(request, createRuntimeContext(env, ctx));
388
+ },
389
+ ...worker.config.scheduled ? {
390
+ async scheduled(event, env, ctx) {
391
+ await worker.config.scheduled?.(event, createRuntimeContext(env, ctx));
392
+ }
393
+ } : {}
394
+ };
395
+ }
396
+ let fetchHandler;
397
+ if (root && typeof root === "object" && "fetch" in root) {
398
+ const maybeFetch = root.fetch;
399
+ if (typeof maybeFetch === "function") {
400
+ fetchHandler = maybeFetch.bind(root);
401
+ }
402
+ }
403
+ if (!fetchHandler && typeof moduleLike.fetch === "function") {
404
+ fetchHandler = moduleLike.fetch;
405
+ }
406
+ if (!fetchHandler) {
407
+ throw new Error("Could not resolve worker fetch handler.");
408
+ }
409
+ let scheduledHandler;
410
+ if (root && typeof root === "object" && "scheduled" in root) {
411
+ const maybeScheduled = root.scheduled;
412
+ if (typeof maybeScheduled === "function") {
413
+ scheduledHandler = maybeScheduled.bind(root);
414
+ }
415
+ }
416
+ if (!scheduledHandler && typeof moduleLike.scheduled === "function") {
417
+ scheduledHandler = moduleLike.scheduled;
418
+ }
419
+ return {
420
+ fetch: fetchHandler,
421
+ scheduled: scheduledHandler
422
+ };
423
+ }
424
+
425
+ export { consumeQueueRegistration, createGeneratedQueueApi, createGeneratedQueueBatchApi, createQueueProducerApi, createQueueProducerBatchApi, createRuntimeContext, getDurableObjectInternals, getDurableRegistrationInternals, getQueueConsumerInternals, getQueueDefinitionInternals, getWorkerInternals, invokeDurableAlarm, invokeDurableFetch, invokeDurableFunction, invokeDurableInit, invokeDurableWebSocketClose, invokeDurableWebSocketConnect, invokeDurableWebSocketError, invokeDurableWebSocketMessage, kDurableObjectInternals, kDurableRegistrationInternals, kQueueConsumerInternals, kQueueDefinitionInternals, kWorkerInternals, makeDurableBaseContext, normalizeKey, resolveWorkerHandlers, setGeneratedApiFactory };
426
+ //# sourceMappingURL=internal.js.map
427
+ //# sourceMappingURL=internal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/queue/utils.ts","../../src/durable-object/internal.ts"],"names":[],"mappings":"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","file":"internal.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, toCloudflareSendOptions } from '../queue/utils.js';\nimport type {\n BetterCfGeneratedApi,\n BetterCfGeneratedBindings,\n BetterCfSDK,\n DurableAlarmConfig,\n DurableBaseContext,\n DurableFetchConfig,\n DurableFnConfig,\n DurableObjectConfig,\n DurableWebSocketConfig,\n MultiJobQueueConfig,\n PullConsumerConfig,\n QueueBatchConsumerConfig,\n QueueConfig,\n QueueJobConfig,\n QueueMessageConsumerConfig,\n RuntimeEnv,\n WorkerConfig,\n WorkerContext\n} from './types.js';\nimport type { z } from 'zod';\n\nexport const kDurableObjectInternals = Symbol.for('better-cf.durable-object.definition');\nexport const kDurableRegistrationInternals = Symbol.for('better-cf.durable-object.registration');\nexport const kQueueDefinitionInternals = Symbol.for('better-cf.durable-object.queue.definition');\nexport const kQueueConsumerInternals = Symbol.for('better-cf.durable-object.queue.consumer');\nexport const kWorkerInternals = Symbol.for('better-cf.durable-object.worker');\n\ntype ApiFactory = (env: unknown, executionCtx: ExecutionContext) => BetterCfGeneratedApi;\n\nlet apiFactory: ApiFactory | null = null;\n\nexport function setGeneratedApiFactory(factory: ApiFactory): void {\n apiFactory = factory;\n}\n\nexport function createRuntimeContext<E>(env: E, executionCtx: ExecutionContext): WorkerContext<E> {\n return {\n env: env as RuntimeEnv<E>,\n executionCtx,\n api: (apiFactory?.(env, executionCtx) ?? {}) as BetterCfGeneratedApi\n };\n}\n\nexport interface DurableObjectInternal<TKey> {\n config: DurableObjectConfig<z.ZodType<TKey>>;\n keySchema: z.ZodType<TKey>;\n serializeKey: (value: TKey) => string;\n}\n\nexport interface DurableFunctionInternal<E, TKey, TArgs, TReturn> {\n visibility: 'public' | 'internal';\n config: DurableFnConfig<E, z.ZodType<TArgs>, TReturn>;\n}\n\nexport interface DurableFetchInternal<E> {\n config: DurableFetchConfig<E>;\n}\n\nexport interface DurableAlarmInternal<E> {\n config: DurableAlarmConfig<E>;\n}\n\nexport interface DurableInitInternal<E> {\n config: { description?: string; handler: (ctx: DurableBaseContext<E>) => Promise<void> | void };\n}\n\nexport interface DurableWebSocketInternal<E, TAttachment> {\n config: DurableWebSocketConfig<E, TAttachment>;\n}\n\ntype PushQueueConsumerType = 'message' | 'batch' | 'job-message';\n\nexport interface QueueDefinitionInternal {\n kind: 'single' | 'multi';\n config: QueueConfig<z.ZodTypeAny> | MultiJobQueueConfig<Record<string, unknown>>;\n bindingName: string | null;\n setBinding: (bindingName: string) => void;\n getBinding: () => string | null;\n}\n\nexport interface QueueConsumerInternal<E> {\n type: PushQueueConsumerType;\n queue: unknown;\n jobName?: string;\n config: QueueMessageConsumerConfig<E, unknown> | QueueBatchConsumerConfig<E, unknown>;\n}\n\nexport interface WorkerInternal<E> {\n config: WorkerConfig<E>;\n}\n\nexport function normalizeKey(value: unknown): string {\n if (typeof value === 'string') {\n return value;\n }\n\n if (typeof value === 'number' || typeof value === 'boolean' || value === null) {\n return String(value);\n }\n\n return JSON.stringify(value);\n}\n\nexport function makeDurableBaseContext<E>(\n env: E,\n executionCtx: ExecutionContext,\n state: DurableObjectState\n): DurableBaseContext<E> {\n const runtime = createRuntimeContext(env, executionCtx);\n return {\n ...runtime,\n state,\n storage: state.storage,\n sql: state.storage.sql\n };\n}\n\nexport function getDurableObjectInternals<TKey>(value: unknown): DurableObjectInternal<TKey> {\n if (!value || typeof value !== 'object') {\n throw new Error('Value is not a durable object definition.');\n }\n\n const internals = (value as Record<PropertyKey, unknown>)[kDurableObjectInternals];\n if (!internals) {\n throw new Error('Object is not a better-cf durable object handle.');\n }\n\n return internals as DurableObjectInternal<TKey>;\n}\n\nexport function getDurableRegistrationInternals(value: unknown):\n | DurableFunctionInternal<unknown, unknown, unknown, unknown>\n | DurableFetchInternal<unknown>\n | DurableAlarmInternal<unknown>\n | DurableInitInternal<unknown>\n | DurableWebSocketInternal<unknown, unknown> {\n if (!value || typeof value !== 'object') {\n throw new Error('Value is not a durable object registration.');\n }\n\n const internals = (value as Record<PropertyKey, unknown>)[kDurableRegistrationInternals];\n if (!internals) {\n throw new Error('Object is not a better-cf durable object registration.');\n }\n\n return internals as\n | DurableFunctionInternal<unknown, unknown, unknown, unknown>\n | DurableFetchInternal<unknown>\n | DurableAlarmInternal<unknown>\n | DurableInitInternal<unknown>\n | DurableWebSocketInternal<unknown, unknown>;\n}\n\nexport function getQueueDefinitionInternals(value: unknown): QueueDefinitionInternal {\n if (!value || typeof value !== 'object') {\n throw new Error('Value is not a queue definition.');\n }\n\n const internals = (value as Record<PropertyKey, unknown>)[kQueueDefinitionInternals];\n if (!internals) {\n throw new Error('Object is not a better-cf durable-object queue handle.');\n }\n\n return internals as QueueDefinitionInternal;\n}\n\nexport function getQueueConsumerInternals<E>(value: unknown): QueueConsumerInternal<E> {\n if (!value || typeof value !== 'object') {\n throw new Error('Value is not a queue consumer registration.');\n }\n\n const internals = (value as Record<PropertyKey, unknown>)[kQueueConsumerInternals];\n if (!internals) {\n throw new Error('Object is not a better-cf durable-object queue consumer registration.');\n }\n\n return internals as QueueConsumerInternal<E>;\n}\n\nexport function getWorkerInternals<E>(value: unknown): WorkerInternal<E> | undefined {\n if (!value || typeof value !== 'object') {\n return undefined;\n }\n\n const internals = (value as Record<PropertyKey, unknown>)[kWorkerInternals];\n return internals as WorkerInternal<E> | undefined;\n}\n\nexport function createQueueProducerApi(\n binding: unknown,\n payload: unknown,\n options?: { delay?: number; contentType?: string }\n): Promise<void> {\n const queueBinding = binding as\n | {\n send: (value: unknown, opts?: { delaySeconds?: number; contentType?: string }) => Promise<void>;\n }\n | undefined;\n\n if (!queueBinding || typeof queueBinding.send !== 'function') {\n throw new Error('Queue binding is not available in env.');\n }\n\n return queueBinding.send(payload, options);\n}\n\nexport function createQueueProducerBatchApi(\n binding: unknown,\n payload: Array<{ body: unknown; delaySeconds?: number; contentType?: string }>\n): Promise<void> {\n const queueBinding = binding as\n | {\n sendBatch: (entries: Array<{ body: unknown; delaySeconds?: number; contentType?: string }>) => Promise<void>;\n }\n | undefined;\n\n if (!queueBinding || typeof queueBinding.sendBatch !== 'function') {\n throw new Error('Queue binding is not available in env.');\n }\n\n return queueBinding.sendBatch(payload);\n}\n\nexport async function consumeQueueRegistration<E>(\n definitionHandle: unknown,\n consumerRegistration: unknown,\n batch: MessageBatch<unknown>,\n env: E,\n executionCtx: ExecutionContext\n): Promise<void> {\n const definition = getQueueDefinitionInternals(definitionHandle);\n const consumer = getQueueConsumerInternals<E>(consumerRegistration);\n const runtime = createRuntimeContext(env, executionCtx);\n\n if (definition.config.consumer && (definition.config.consumer as PullConsumerConfig).type === 'http_pull') {\n batch.ackAll();\n return;\n }\n\n if (consumer.type === 'batch') {\n let ackOrRetryHandled = false;\n const batchCtx = {\n ...runtime,\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 schema = (definition.config as QueueConfig<z.ZodTypeAny>).args;\n const entries = batch.messages.map((message) => {\n const parsed = schema.safeParse(message.body);\n if (!parsed.success) {\n throw new Error(`Queue batch validation failed for ${message.id}: ${parsed.error.message}`);\n }\n\n return {\n data: parsed.data,\n id: message.id,\n timestamp: message.timestamp,\n attempts: message.attempts\n };\n });\n\n await (consumer.config as QueueBatchConsumerConfig<E, unknown>).handler(batchCtx, entries);\n if (!ackOrRetryHandled) {\n batch.ackAll();\n }\n } catch (error) {\n const failure = (consumer.config as QueueBatchConsumerConfig<E, unknown>).failure;\n if (failure) {\n await failure(batchCtx, null, toError(error));\n }\n if (!ackOrRetryHandled) {\n batch.retryAll(withRetryDelay(definition.config.retryDelay));\n }\n }\n return;\n }\n\n if (consumer.type === 'job-message') {\n const jobConfig = (definition.config as MultiJobQueueConfig<Record<string, unknown>>)[\n consumer.jobName as string\n ] as QueueJobConfig<z.ZodTypeAny>;\n\n for (const message of batch.messages) {\n const envelope = message.body as { _job?: string; data?: unknown };\n if (envelope?._job !== consumer.jobName) {\n if (!envelope?._job) {\n message.ack();\n }\n continue;\n }\n\n const messageCtx = {\n ...runtime,\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 = jobConfig.args.safeParse(envelope.data);\n if (!parsed.success) {\n throw new Error(`Queue job validation failed for ${consumer.jobName}: ${parsed.error.message}`);\n }\n\n await (consumer.config as QueueMessageConsumerConfig<E, unknown>).handler(messageCtx, parsed.data);\n message.ack();\n } catch (error) {\n const failure = (consumer.config as QueueMessageConsumerConfig<E, unknown>).failure;\n if (failure) {\n await failure(messageCtx, envelope.data ?? null, toError(error));\n }\n message.retry(withRetryDelay(definition.config.retryDelay));\n }\n }\n return;\n }\n\n for (const message of batch.messages) {\n const messageCtx = {\n ...runtime,\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 schema = (definition.config as QueueConfig<z.ZodTypeAny>).args;\n const parsed = schema.safeParse(message.body);\n if (!parsed.success) {\n throw new Error(`Queue args validation failed: ${parsed.error.message}`);\n }\n\n await (consumer.config as QueueMessageConsumerConfig<E, unknown>).handler(messageCtx, parsed.data);\n message.ack();\n } catch (error) {\n const failure = (consumer.config as QueueMessageConsumerConfig<E, unknown>).failure;\n if (failure) {\n await failure(messageCtx, message.body as unknown, toError(error));\n }\n message.retry(withRetryDelay(definition.config.retryDelay));\n }\n }\n}\n\nexport async function invokeDurableFunction<E, TArgs, TReturn>(\n env: E,\n state: DurableObjectState,\n executionCtx: ExecutionContext,\n registration: unknown,\n args: TArgs\n): Promise<TReturn> {\n const internals = getDurableRegistrationInternals(registration) as DurableFunctionInternal<E, unknown, TArgs, TReturn>;\n const parsed = internals.config.args.safeParse(args);\n if (!parsed.success) {\n throw new Error(parsed.error.message);\n }\n\n const ctx = makeDurableBaseContext(env, executionCtx, state);\n const result = await internals.config.handler(ctx, parsed.data);\n if (internals.config.returns) {\n return internals.config.returns.parse(result);\n }\n return result;\n}\n\nexport async function invokeDurableFetch<E>(\n env: E,\n state: DurableObjectState,\n executionCtx: ExecutionContext,\n registration: unknown,\n request: Request\n): Promise<Response> {\n const internals = getDurableRegistrationInternals(registration) as DurableFetchInternal<E>;\n const ctx = makeDurableBaseContext(env, executionCtx, state);\n return internals.config.handler({\n ...ctx,\n request\n });\n}\n\nexport async function invokeDurableAlarm<E>(\n env: E,\n state: DurableObjectState,\n executionCtx: ExecutionContext,\n registration: unknown,\n alarmInfo: AlarmInvocationInfo\n): Promise<void> {\n const internals = getDurableRegistrationInternals(registration) as DurableAlarmInternal<E>;\n const ctx = makeDurableBaseContext(env, executionCtx, state);\n await internals.config.handler({\n ...ctx,\n alarmInfo\n });\n}\n\nexport async function invokeDurableInit<E>(\n env: E,\n state: DurableObjectState,\n executionCtx: ExecutionContext,\n registration: unknown\n): Promise<void> {\n const internals = getDurableRegistrationInternals(registration) as DurableInitInternal<E>;\n const ctx = makeDurableBaseContext(env, executionCtx, state);\n await internals.config.handler(ctx);\n}\n\nexport async function invokeDurableWebSocketConnect<E, TAttachment>(\n env: E,\n state: DurableObjectState,\n executionCtx: ExecutionContext,\n registration: unknown,\n request: Request\n): Promise<Response> {\n const internals = getDurableRegistrationInternals(registration) as DurableWebSocketInternal<E, TAttachment>;\n const pair = new WebSocketPair();\n const client = pair[0];\n const server = pair[1];\n let accepted = false;\n\n const ctx = makeDurableBaseContext(env, executionCtx, state);\n const response = await internals.config.connect?.({\n ...ctx,\n request,\n client,\n server,\n accept(options) {\n accepted = true;\n state.acceptWebSocket(server, options?.tags);\n if (options?.attachment !== undefined) {\n const attachment = internals.config.serializeAttachment\n ? internals.config.serializeAttachment(options.attachment)\n : options.attachment;\n server.serializeAttachment(attachment);\n }\n }\n });\n\n if (response) {\n return response;\n }\n\n if (!accepted) {\n state.acceptWebSocket(server);\n }\n\n return new Response(null, {\n status: 101,\n webSocket: client\n });\n}\n\nexport async function invokeDurableWebSocketMessage<E, TAttachment>(\n env: E,\n state: DurableObjectState,\n executionCtx: ExecutionContext,\n registration: unknown,\n socket: WebSocket,\n message: string | ArrayBuffer\n): Promise<void> {\n const internals = getDurableRegistrationInternals(registration) as DurableWebSocketInternal<E, TAttachment>;\n if (!internals.config.message) {\n return;\n }\n\n const ctx = makeDurableBaseContext(env, executionCtx, state);\n await internals.config.message({\n ...ctx,\n socket,\n attachment: hydrateAttachment(socket, internals)\n }, message);\n}\n\nexport async function invokeDurableWebSocketClose<E, TAttachment>(\n env: E,\n state: DurableObjectState,\n executionCtx: ExecutionContext,\n registration: unknown,\n socket: WebSocket,\n code: number,\n reason: string,\n wasClean: boolean\n): Promise<void> {\n const internals = getDurableRegistrationInternals(registration) as DurableWebSocketInternal<E, TAttachment>;\n if (!internals.config.close) {\n return;\n }\n\n const ctx = makeDurableBaseContext(env, executionCtx, state);\n await internals.config.close({\n ...ctx,\n socket,\n attachment: hydrateAttachment(socket, internals)\n }, code, reason, wasClean);\n}\n\nexport async function invokeDurableWebSocketError<E, TAttachment>(\n env: E,\n state: DurableObjectState,\n executionCtx: ExecutionContext,\n registration: unknown,\n socket: WebSocket,\n error: unknown\n): Promise<void> {\n const internals = getDurableRegistrationInternals(registration) as DurableWebSocketInternal<E, TAttachment>;\n if (!internals.config.error) {\n return;\n }\n\n const ctx = makeDurableBaseContext(env, executionCtx, state);\n await internals.config.error({\n ...ctx,\n socket,\n attachment: hydrateAttachment(socket, internals)\n }, error);\n}\n\nfunction hydrateAttachment<E, TAttachment>(\n socket: WebSocket,\n internals: DurableWebSocketInternal<E, TAttachment>\n): TAttachment | undefined {\n const value = socket.deserializeAttachment();\n if (value === undefined) {\n return undefined;\n }\n return internals.config.hydrateAttachment ? internals.config.hydrateAttachment(value) : (value as TAttachment);\n}\n\nfunction toError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction withRetryDelay(value: unknown): { delaySeconds?: number } | undefined {\n if (value === undefined) {\n return undefined;\n }\n\n return { delaySeconds: parseDurationSeconds(value as never) };\n}\n\nexport function createGeneratedQueueApi(binding: unknown, payload: unknown, options?: { delay?: unknown; contentType?: unknown }) {\n return createQueueProducerApi(binding, payload, toCloudflareSendOptions(options as never));\n}\n\nexport function createGeneratedQueueBatchApi(\n binding: unknown,\n messages: Array<{ data: unknown; delay?: unknown; contentType?: unknown }>\n) {\n return createQueueProducerBatchApi(\n binding,\n messages.map((message) => ({\n body: message.data,\n ...toCloudflareSendOptions(message as never)\n }))\n );\n}\n\nexport function resolveWorkerHandlers(moduleLike: {\n default?: unknown;\n fetch?: (request: Request, env: unknown, ctx: ExecutionContext) => Promise<Response>;\n scheduled?: (event: ScheduledEvent, env: unknown, ctx: ExecutionContext) => Promise<void>;\n}) {\n const root = moduleLike.default ?? moduleLike;\n const worker = getWorkerInternals(root);\n if (worker) {\n return {\n async fetch(request: Request, env: unknown, ctx: ExecutionContext): Promise<Response> {\n return worker.config.fetch(request, createRuntimeContext(env, ctx));\n },\n ...(worker.config.scheduled\n ? {\n async scheduled(event: ScheduledEvent, env: unknown, ctx: ExecutionContext): Promise<void> {\n await worker.config.scheduled?.(event, createRuntimeContext(env, ctx));\n }\n }\n : {})\n };\n }\n\n let fetchHandler: ((request: Request, env: unknown, ctx: ExecutionContext) => Promise<Response>) | undefined;\n 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 (request: Request, env: unknown, ctx: ExecutionContext) => Promise<Response>;\n }\n }\n\n if (!fetchHandler && typeof moduleLike.fetch === 'function') {\n fetchHandler = moduleLike.fetch;\n }\n\n if (!fetchHandler) {\n throw new Error('Could not resolve worker fetch handler.');\n }\n\n let scheduledHandler: ((event: ScheduledEvent, env: unknown, ctx: ExecutionContext) => Promise<void>) | 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 (\n event: ScheduledEvent,\n env: unknown,\n ctx: ExecutionContext\n ) => Promise<void>;\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"]}
@@ -1,3 +1,6 @@
1
+ import { l as DurableFnArgs, p as DurableFnReturn } from '../types-C1mNTuC-.js';
2
+ import 'zod';
3
+
1
4
  /**
2
5
  * Options for queue consumer tests.
3
6
  */
@@ -28,6 +31,16 @@ interface TestQueueResult<TMessage> {
28
31
  /** Messages retried by the consumer. */
29
32
  retried: TMessage[];
30
33
  }
34
+ type TestQueueConsumerOptions<E, TMessage> = TestQueueOptions<E, TMessage> & {
35
+ /** Optional generated API object to inject into `ctx.api` for tests. */
36
+ api?: Record<string, unknown>;
37
+ };
38
+ interface TestDurableFunctionOptions<E, TArgs> {
39
+ env: E;
40
+ args: TArgs;
41
+ storage?: Map<string, unknown>;
42
+ api?: Record<string, unknown>;
43
+ }
31
44
  /**
32
45
  * Runs a queue declaration's consumer logic in-memory for tests.
33
46
  *
@@ -36,5 +49,7 @@ interface TestQueueResult<TMessage> {
36
49
  * @returns Acked/retried payload collections captured from the simulated consume flow.
37
50
  */
38
51
  declare function testQueue<E, TMessage>(handle: unknown, options: TestQueueOptions<E, TMessage>): Promise<TestQueueResult<TMessage>>;
52
+ declare function testQueueConsumer<E, TMessage>(queue: unknown, consumer: unknown, options: TestQueueConsumerOptions<E, TMessage>): Promise<TestQueueResult<TMessage>>;
53
+ declare function testDurableFunction<E, TFunction>(fn: TFunction, options: TestDurableFunctionOptions<E, DurableFnArgs<TFunction>>): Promise<DurableFnReturn<TFunction>>;
39
54
 
40
- export { type TestQueueOptions, type TestQueueResult, testQueue };
55
+ export { type TestDurableFunctionOptions, type TestQueueConsumerOptions, type TestQueueOptions, type TestQueueResult, testDurableFunction, testQueue, testQueueConsumer };