alchemy 0.12.7 → 0.12.9

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 (51) hide show
  1. package/lib/cloudflare/bound.d.ts +1 -1
  2. package/lib/cloudflare/bound.d.ts.map +1 -1
  3. package/lib/cloudflare/bucket.d.ts +8 -2
  4. package/lib/cloudflare/bucket.d.ts.map +1 -1
  5. package/lib/cloudflare/bucket.js +1 -1
  6. package/lib/cloudflare/bucket.js.map +1 -1
  7. package/lib/cloudflare/d1-database.d.ts +8 -2
  8. package/lib/cloudflare/d1-database.d.ts.map +1 -1
  9. package/lib/cloudflare/d1-database.js +2 -2
  10. package/lib/cloudflare/d1-database.js.map +1 -1
  11. package/lib/cloudflare/event-source.d.ts +26 -0
  12. package/lib/cloudflare/event-source.d.ts.map +1 -0
  13. package/lib/cloudflare/event-source.js +9 -0
  14. package/lib/cloudflare/event-source.js.map +1 -0
  15. package/lib/cloudflare/index.d.ts +1 -0
  16. package/lib/cloudflare/index.d.ts.map +1 -1
  17. package/lib/cloudflare/index.js +1 -0
  18. package/lib/cloudflare/index.js.map +1 -1
  19. package/lib/cloudflare/queue-consumer.d.ts +162 -0
  20. package/lib/cloudflare/queue-consumer.d.ts.map +1 -0
  21. package/lib/cloudflare/queue-consumer.js +197 -0
  22. package/lib/cloudflare/queue-consumer.js.map +1 -0
  23. package/lib/cloudflare/queue.d.ts +15 -3
  24. package/lib/cloudflare/queue.d.ts.map +1 -1
  25. package/lib/cloudflare/queue.js +8 -2
  26. package/lib/cloudflare/queue.js.map +1 -1
  27. package/lib/cloudflare/r2-rest-state-store.js +1 -1
  28. package/lib/cloudflare/r2-rest-state-store.js.map +1 -1
  29. package/lib/cloudflare/website.d.ts.map +1 -1
  30. package/lib/cloudflare/website.js +8 -10
  31. package/lib/cloudflare/website.js.map +1 -1
  32. package/lib/cloudflare/worker.d.ts +13 -2
  33. package/lib/cloudflare/worker.d.ts.map +1 -1
  34. package/lib/cloudflare/worker.js +67 -3
  35. package/lib/cloudflare/worker.js.map +1 -1
  36. package/lib/cloudflare/wrangler.json.d.ts +13 -3
  37. package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
  38. package/lib/cloudflare/wrangler.json.js +27 -5
  39. package/lib/cloudflare/wrangler.json.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/cloudflare/bound.ts +2 -2
  42. package/src/cloudflare/bucket.ts +9 -2
  43. package/src/cloudflare/d1-database.ts +10 -3
  44. package/src/cloudflare/event-source.ts +33 -0
  45. package/src/cloudflare/index.ts +1 -0
  46. package/src/cloudflare/queue-consumer.ts +433 -0
  47. package/src/cloudflare/queue.ts +83 -63
  48. package/src/cloudflare/r2-rest-state-store.ts +1 -1
  49. package/src/cloudflare/website.ts +9 -13
  50. package/src/cloudflare/worker.ts +102 -5
  51. package/src/cloudflare/wrangler.json.ts +52 -8
@@ -0,0 +1,433 @@
1
+ import type { Context } from "../context.js";
2
+ import { Resource } from "../resource.js";
3
+ import { CloudflareApiError, handleApiError } from "./api-error.js";
4
+ import {
5
+ CloudflareApi,
6
+ createCloudflareApi,
7
+ type CloudflareApiOptions,
8
+ } from "./api.js";
9
+ import type { Queue } from "./queue.js";
10
+
11
+ /**
12
+ * Settings for configuring a Queue Consumer
13
+ */
14
+ export interface QueueConsumerSettings {
15
+ /**
16
+ * Number of messages to deliver in a batch
17
+ * @default 10
18
+ */
19
+ batchSize?: number;
20
+
21
+ /**
22
+ * Maximum number of concurrent consumer worker invocations
23
+ * @default 2
24
+ */
25
+ maxConcurrency?: number;
26
+
27
+ /**
28
+ * Maximum number of retries for each message
29
+ * @default 3
30
+ */
31
+ maxRetries?: number;
32
+
33
+ /**
34
+ * Maximum time in milliseconds to wait for batch to fill
35
+ * @default 500
36
+ */
37
+ maxWaitTimeMs?: number;
38
+
39
+ /**
40
+ * Time in seconds to delay retry after a failure
41
+ * @default 30
42
+ */
43
+ retryDelay?: number;
44
+ }
45
+
46
+ /**
47
+ * Properties for creating or updating a Queue Consumer
48
+ */
49
+ export interface QueueConsumerProps extends CloudflareApiOptions {
50
+ /**
51
+ * The queue to consume
52
+ * Either queue or queueId must be provided
53
+ */
54
+ queue?: Queue;
55
+
56
+ /**
57
+ * The queue ID to consume (alternative to providing a queue)
58
+ * Either queue or queueId must be provided
59
+ */
60
+ queueId?: string;
61
+
62
+ /**
63
+ * Name of the worker script that will consume the queue
64
+ */
65
+ scriptName: string;
66
+
67
+ /**
68
+ * Settings for the consumer
69
+ */
70
+ settings?: QueueConsumerSettings;
71
+
72
+ /**
73
+ * Whether to delete the consumer.
74
+ * If set to false, the consumer will remain but the resource will be removed from state
75
+ * @default true
76
+ */
77
+ delete?: boolean;
78
+ }
79
+
80
+ /**
81
+ * Output returned after Queue Consumer creation/update
82
+ */
83
+ export interface QueueConsumer
84
+ extends Resource<"cloudflare::QueueConsumer">,
85
+ QueueConsumerProps {
86
+ /**
87
+ * Unique ID for the consumer
88
+ */
89
+ id: string;
90
+
91
+ /**
92
+ * Type identifier for Cloudflare Queue Consumer
93
+ */
94
+ type: "worker";
95
+
96
+ /**
97
+ * ID of the queue being consumed
98
+ */
99
+ queueId: string;
100
+
101
+ /**
102
+ * Time when the consumer was created
103
+ */
104
+ createdOn?: string;
105
+ }
106
+
107
+ /**
108
+ * Creates a consumer for a Cloudflare Queue that processes messages using a Worker.
109
+ *
110
+ * @example
111
+ * // Create a queue consumer with default settings
112
+ * const queue = await Queue("notifications", {
113
+ * name: "notifications"
114
+ * });
115
+ *
116
+ * const consumer = await QueueConsumer("notification-processor", {
117
+ * queue,
118
+ * scriptName: "notification-worker"
119
+ * });
120
+ *
121
+ * @example
122
+ * // Create a consumer with custom settings
123
+ * const batchConsumer = await QueueConsumer("batch-processor", {
124
+ * queue,
125
+ * scriptName: "batch-worker",
126
+ * settings: {
127
+ * batchSize: 50, // Process 50 messages at once
128
+ * maxConcurrency: 10, // Allow 10 concurrent invocations
129
+ * maxRetries: 5, // Retry failed messages up to 5 times
130
+ * maxWaitTimeMs: 2000, // Wait up to 2 seconds to fill a batch
131
+ * retryDelay: 60 // Wait 60 seconds before retrying failed messages
132
+ * }
133
+ * });
134
+ *
135
+ * @see https://developers.cloudflare.com/queues/platform/consumers/
136
+ */
137
+ export const QueueConsumer = Resource(
138
+ "cloudflare::QueueConsumer",
139
+ async function (
140
+ this: Context<QueueConsumer>,
141
+ id: string,
142
+ props: QueueConsumerProps
143
+ ): Promise<QueueConsumer> {
144
+ const api = await createCloudflareApi(props);
145
+
146
+ // Get queueId from either props.queue or props.queueId
147
+ const queueId = props.queue?.id || props.queueId;
148
+
149
+ if (!queueId) {
150
+ throw new Error("Either queue or queueId must be provided");
151
+ }
152
+
153
+ if (this.phase === "delete") {
154
+ console.log(`Deleting Queue Consumer for queue ${queueId}`);
155
+ if (props.delete !== false && this.output?.id) {
156
+ // Delete the consumer
157
+ await deleteQueueConsumer(api, queueId, this.output.id);
158
+ }
159
+
160
+ // Return void (a deleted consumer has no content)
161
+ return this.destroy();
162
+ } else {
163
+ let consumerData: CloudflareQueueConsumerResponse;
164
+
165
+ if (this.phase === "create") {
166
+ console.log(`Creating Queue Consumer for queue ${queueId}`);
167
+ consumerData = await createQueueConsumer(api, queueId, props);
168
+ } else if (this.output?.id) {
169
+ console.log(`Updating Queue Consumer ${this.output.id}`);
170
+ consumerData = await updateQueueConsumer(
171
+ api,
172
+ queueId,
173
+ this.output.id,
174
+ props
175
+ );
176
+ } else {
177
+ // If no ID exists, fall back to creating a new consumer
178
+ console.log(
179
+ `No existing Consumer ID found, creating new Queue Consumer for queue ${queueId}`
180
+ );
181
+ consumerData = await createQueueConsumer(api, queueId, props);
182
+ }
183
+
184
+ return this({
185
+ id: consumerData.result.consumer_id,
186
+ queueId,
187
+ queue: props.queue,
188
+ type: "worker",
189
+ scriptName: props.scriptName,
190
+ settings: consumerData.result.settings
191
+ ? {
192
+ batchSize: consumerData.result.settings.batch_size,
193
+ maxConcurrency: consumerData.result.settings.max_concurrency,
194
+ maxRetries: consumerData.result.settings.max_retries,
195
+ maxWaitTimeMs: consumerData.result.settings.max_wait_time_ms,
196
+ retryDelay: consumerData.result.settings.retry_delay,
197
+ }
198
+ : undefined,
199
+ createdOn: consumerData.result.created_on,
200
+ accountId: api.accountId,
201
+ });
202
+ }
203
+ }
204
+ );
205
+
206
+ /**
207
+ * Response from Cloudflare API for Queue Consumer operations
208
+ */
209
+ interface CloudflareQueueConsumerResponse {
210
+ result: {
211
+ consumer_id: string;
212
+ script_name: string;
213
+ settings?: {
214
+ batch_size?: number;
215
+ max_concurrency?: number;
216
+ max_retries?: number;
217
+ max_wait_time_ms?: number;
218
+ retry_delay?: number;
219
+ };
220
+ type: "worker";
221
+ queue_id?: string;
222
+ created_on?: string;
223
+ };
224
+ success: boolean;
225
+ errors: Array<{ code: number; message: string }>;
226
+ messages: string[];
227
+ }
228
+
229
+ /**
230
+ * Create a new Queue Consumer
231
+ */
232
+ export async function createQueueConsumer(
233
+ api: CloudflareApi,
234
+ queueId: string,
235
+ props: QueueConsumerProps
236
+ ): Promise<CloudflareQueueConsumerResponse> {
237
+ // Prepare the create payload
238
+ const createPayload: any = {
239
+ script_name: props.scriptName,
240
+ type: "worker",
241
+ };
242
+
243
+ // Add settings if provided
244
+ if (props.settings) {
245
+ createPayload.settings = {};
246
+
247
+ if (props.settings.batchSize !== undefined) {
248
+ createPayload.settings.batch_size = props.settings.batchSize;
249
+ }
250
+
251
+ if (props.settings.maxConcurrency !== undefined) {
252
+ createPayload.settings.max_concurrency = props.settings.maxConcurrency;
253
+ }
254
+
255
+ if (props.settings.maxRetries !== undefined) {
256
+ createPayload.settings.max_retries = props.settings.maxRetries;
257
+ }
258
+
259
+ if (props.settings.maxWaitTimeMs !== undefined) {
260
+ createPayload.settings.max_wait_time_ms = props.settings.maxWaitTimeMs;
261
+ }
262
+
263
+ if (props.settings.retryDelay !== undefined) {
264
+ createPayload.settings.retry_delay = props.settings.retryDelay;
265
+ }
266
+ }
267
+
268
+ const createResponse = await api.post(
269
+ `/accounts/${api.accountId}/queues/${queueId}/consumers`,
270
+ createPayload
271
+ );
272
+
273
+ if (!createResponse.ok) {
274
+ return await handleApiError(
275
+ createResponse,
276
+ "creating",
277
+ "Queue Consumer",
278
+ `for queue ${queueId}`
279
+ );
280
+ }
281
+
282
+ return (await createResponse.json()) as CloudflareQueueConsumerResponse;
283
+ }
284
+
285
+ /**
286
+ * Delete a Queue Consumer
287
+ */
288
+ export async function deleteQueueConsumer(
289
+ api: CloudflareApi,
290
+ queueId: string,
291
+ consumerId: string
292
+ ): Promise<void> {
293
+ const deleteResponse = await api.delete(
294
+ `/accounts/${api.accountId}/queues/${queueId}/consumers/${consumerId}`
295
+ );
296
+
297
+ if (!deleteResponse.ok && deleteResponse.status !== 404) {
298
+ const errorData: any = await deleteResponse.json().catch(() => ({
299
+ errors: [{ message: deleteResponse.statusText }],
300
+ }));
301
+ throw new CloudflareApiError(
302
+ `Error deleting Queue Consumer '${consumerId}': ${errorData.errors?.[0]?.message || deleteResponse.statusText}`,
303
+ deleteResponse
304
+ );
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Update a Queue Consumer
310
+ */
311
+ async function updateQueueConsumer(
312
+ api: CloudflareApi,
313
+ queueId: string,
314
+ consumerId: string,
315
+ props: QueueConsumerProps
316
+ ): Promise<CloudflareQueueConsumerResponse> {
317
+ // Prepare the update payload
318
+ const updatePayload: any = {
319
+ script_name: props.scriptName,
320
+ type: "worker",
321
+ };
322
+
323
+ // Add settings if provided
324
+ if (props.settings) {
325
+ updatePayload.settings = {};
326
+
327
+ if (props.settings.batchSize !== undefined) {
328
+ updatePayload.settings.batch_size = props.settings.batchSize;
329
+ }
330
+
331
+ if (props.settings.maxConcurrency !== undefined) {
332
+ updatePayload.settings.max_concurrency = props.settings.maxConcurrency;
333
+ }
334
+
335
+ if (props.settings.maxRetries !== undefined) {
336
+ updatePayload.settings.max_retries = props.settings.maxRetries;
337
+ }
338
+
339
+ if (props.settings.maxWaitTimeMs !== undefined) {
340
+ updatePayload.settings.max_wait_time_ms = props.settings.maxWaitTimeMs;
341
+ }
342
+
343
+ if (props.settings.retryDelay !== undefined) {
344
+ updatePayload.settings.retry_delay = props.settings.retryDelay;
345
+ }
346
+ }
347
+
348
+ // Use PUT to update the consumer
349
+ const updateResponse = await api.put(
350
+ `/accounts/${api.accountId}/queues/${queueId}/consumers/${consumerId}`,
351
+ updatePayload
352
+ );
353
+
354
+ if (!updateResponse.ok) {
355
+ return await handleApiError(
356
+ updateResponse,
357
+ "updating",
358
+ "Queue Consumer",
359
+ consumerId
360
+ );
361
+ }
362
+
363
+ return (await updateResponse.json()) as CloudflareQueueConsumerResponse;
364
+ }
365
+
366
+ export interface ListQueueConsumersResponse {
367
+ id: string;
368
+ scriptName: string;
369
+ queueId: string;
370
+ queueName: string;
371
+ createdOn: string;
372
+ settings?: QueueConsumerSettings;
373
+ }
374
+ /**
375
+ * List all consumers for a queue
376
+ */
377
+ export async function listQueueConsumers(
378
+ api: CloudflareApi,
379
+ queueId: string
380
+ ): Promise<ListQueueConsumersResponse[]> {
381
+ const response = await api.get(
382
+ `/accounts/${api.accountId}/queues/${queueId}/consumers`
383
+ );
384
+
385
+ if (!response.ok) {
386
+ throw new CloudflareApiError(
387
+ `Failed to list queue consumers: ${response.statusText}`,
388
+ response
389
+ );
390
+ }
391
+
392
+ const data = (await response.json()) as {
393
+ success: boolean;
394
+ errors?: Array<{ code: number; message: string }>;
395
+ result?: Array<{
396
+ consumer_id: string;
397
+ script: string;
398
+ queue_id: string;
399
+ queue_name: string;
400
+ created_on: string;
401
+ settings?: {
402
+ batch_size?: number;
403
+ max_concurrency?: number;
404
+ max_retries?: number;
405
+ max_wait_time_ms?: number;
406
+ retry_delay?: number;
407
+ };
408
+ }>;
409
+ };
410
+
411
+ if (!data.success) {
412
+ const errorMessage = data.errors?.[0]?.message || "Unknown error";
413
+ throw new Error(`Failed to list queue consumers: ${errorMessage}`);
414
+ }
415
+
416
+ // Transform API response
417
+ return (data.result || []).map((consumer) => ({
418
+ id: consumer.consumer_id,
419
+ scriptName: consumer.script,
420
+ queueId: consumer.queue_id,
421
+ queueName: consumer.queue_name,
422
+ createdOn: consumer.created_on,
423
+ settings: consumer.settings
424
+ ? {
425
+ batchSize: consumer.settings.batch_size,
426
+ maxConcurrency: consumer.settings.max_concurrency,
427
+ maxRetries: consumer.settings.max_retries,
428
+ maxWaitTimeMs: consumer.settings.max_wait_time_ms,
429
+ retryDelay: consumer.settings.retry_delay,
430
+ }
431
+ : undefined,
432
+ }));
433
+ }
@@ -38,8 +38,10 @@ export interface QueueProps extends CloudflareApiOptions {
38
38
  * Name of the queue
39
39
  * Required during creation
40
40
  * Cannot be changed after creation
41
+ *
42
+ * @default id
41
43
  */
42
- name: string;
44
+ name?: string;
43
45
 
44
46
  /**
45
47
  * Settings for the queue
@@ -56,10 +58,16 @@ export interface QueueProps extends CloudflareApiOptions {
56
58
  delete?: boolean;
57
59
  }
58
60
 
61
+ export function isQueue(eventSource: any): eventSource is Queue {
62
+ return "Kind" in eventSource && eventSource.Kind === "cloudflare::Queue";
63
+ }
64
+
59
65
  /**
60
66
  * Output returned after Cloudflare Queue creation/update
61
67
  */
62
- export interface Queue extends Resource<"cloudflare::Queue">, QueueProps {
68
+ export interface Queue<Body = unknown>
69
+ extends Resource<"cloudflare::Queue">,
70
+ QueueProps {
63
71
  /**
64
72
  * Type identifier for Cloudflare Queue
65
73
  */
@@ -70,6 +78,11 @@ export interface Queue extends Resource<"cloudflare::Queue">, QueueProps {
70
78
  */
71
79
  id: string;
72
80
 
81
+ /**
82
+ * The name of the queue
83
+ */
84
+ name: string;
85
+
73
86
  /**
74
87
  * Time when the queue was created
75
88
  */
@@ -79,6 +92,13 @@ export interface Queue extends Resource<"cloudflare::Queue">, QueueProps {
79
92
  * Modified timestamp
80
93
  */
81
94
  modifiedOn: string;
95
+
96
+ /**
97
+ * Phantom property to allow type inference
98
+ */
99
+ Body: Body;
100
+
101
+ Batch: MessageBatch<Body>;
82
102
  }
83
103
 
84
104
  interface CloudflareQueueResponse {
@@ -131,74 +151,74 @@ interface CloudflareQueueResponse {
131
151
  *
132
152
  * @see https://developers.cloudflare.com/queues/
133
153
  */
134
- export const Queue = Resource(
135
- "cloudflare::Queue",
136
- async function (
137
- this: Context<Queue>,
138
- id: string,
139
- props: QueueProps
140
- ): Promise<Queue> {
141
- const api = await createCloudflareApi(props);
142
- const queueName = props.name || id;
143
-
144
- if (this.phase === "delete") {
145
- console.log("Deleting Cloudflare Queue:", queueName);
146
- if (props.delete !== false) {
147
- // Delete Queue
148
- await deleteQueue(api, this.output?.id);
149
- }
154
+ export const Queue = Resource("cloudflare::Queue", async function <
155
+ T = unknown,
156
+ >(this: Context<Queue<T>>, id: string, props: QueueProps = {}): Promise<
157
+ Queue<T>
158
+ > {
159
+ const api = await createCloudflareApi(props);
160
+ const queueName = props.name ?? id;
161
+
162
+ if (this.phase === "delete") {
163
+ console.log("Deleting Cloudflare Queue:", queueName);
164
+ if (props.delete !== false) {
165
+ // Delete Queue
166
+ await deleteQueue(api, this.output?.id);
167
+ }
150
168
 
151
- // Return void (a deleted queue has no content)
152
- return this.destroy();
153
- } else {
154
- let queueData: CloudflareQueueResponse;
169
+ // Return void (a deleted queue has no content)
170
+ return this.destroy();
171
+ } else {
172
+ let queueData: CloudflareQueueResponse;
155
173
 
156
- if (this.phase === "create") {
157
- console.log("Creating Cloudflare Queue:", queueName);
158
- queueData = await createQueue(api, queueName, props);
159
- } else {
160
- // Update operation
161
- if (this.output?.id) {
162
- console.log("Updating Cloudflare Queue:", queueName);
163
-
164
- // Check if name is being changed, which is not allowed
165
- if (props.name !== this.output.name) {
166
- throw new Error(
167
- "Cannot update Queue name after creation. Queue name is immutable."
168
- );
169
- }
170
-
171
- // Update the queue with new settings
172
- queueData = await updateQueue(api, this.output.id, props);
173
- } else {
174
- // If no ID exists, fall back to creating a new queue
175
- console.log(
176
- "No existing Queue ID found, creating new Cloudflare Queue:",
177
- queueName
174
+ if (this.phase === "create") {
175
+ console.log("Creating Cloudflare Queue:", queueName);
176
+ queueData = await createQueue(api, queueName, props);
177
+ } else {
178
+ // Update operation
179
+ if (this.output?.id) {
180
+ console.log("Updating Cloudflare Queue:", queueName);
181
+
182
+ // Check if name is being changed, which is not allowed
183
+ if (props.name !== this.output.name) {
184
+ throw new Error(
185
+ "Cannot update Queue name after creation. Queue name is immutable."
178
186
  );
179
- queueData = await createQueue(api, queueName, props);
180
187
  }
181
- }
182
188
 
183
- return this({
184
- type: "queue",
185
- id: queueData.result.queue_id || "",
186
- name: queueName,
187
- settings: queueData.result.settings
188
- ? {
189
- deliveryDelay: queueData.result.settings.delivery_delay,
190
- deliveryPaused: queueData.result.settings.delivery_paused,
191
- messageRetentionPeriod:
192
- queueData.result.settings.message_retention_period,
193
- }
194
- : undefined,
195
- createdOn: queueData.result.created_on || new Date().toISOString(),
196
- modifiedOn: queueData.result.modified_on || new Date().toISOString(),
197
- accountId: api.accountId,
198
- });
189
+ // Update the queue with new settings
190
+ queueData = await updateQueue(api, this.output.id, props);
191
+ } else {
192
+ // If no ID exists, fall back to creating a new queue
193
+ console.log(
194
+ "No existing Queue ID found, creating new Cloudflare Queue:",
195
+ queueName
196
+ );
197
+ queueData = await createQueue(api, queueName, props);
198
+ }
199
199
  }
200
+
201
+ return this({
202
+ type: "queue",
203
+ id: queueData.result.queue_id || "",
204
+ name: queueName,
205
+ settings: queueData.result.settings
206
+ ? {
207
+ deliveryDelay: queueData.result.settings.delivery_delay,
208
+ deliveryPaused: queueData.result.settings.delivery_paused,
209
+ messageRetentionPeriod:
210
+ queueData.result.settings.message_retention_period,
211
+ }
212
+ : undefined,
213
+ createdOn: queueData.result.created_on || new Date().toISOString(),
214
+ modifiedOn: queueData.result.modified_on || new Date().toISOString(),
215
+ accountId: api.accountId,
216
+ // phantom properties
217
+ Body: undefined as T,
218
+ Batch: undefined! as MessageBatch<T>,
219
+ });
200
220
  }
201
- );
221
+ });
202
222
 
203
223
  /**
204
224
  * Create a new Cloudflare Queue
@@ -122,7 +122,7 @@ export class R2RestStateStore implements StateStore {
122
122
 
123
123
  // The result structure may be under "result" key in Cloudflare's API
124
124
  const result = data.result || data;
125
- const objects = result.objects || [];
125
+ const objects = result.objects || result;
126
126
 
127
127
  // Add keys to our list, removing the prefix and converting from storage format
128
128
  keys = keys.concat(
@@ -93,15 +93,6 @@ export async function Website<B extends Bindings>(
93
93
  command: props.command,
94
94
  });
95
95
 
96
- const dist =
97
- typeof props.assets === "string"
98
- ? props.assets
99
- : (props.assets?.dist ?? "dist");
100
-
101
- const staticAssets = await Assets("assets", {
102
- path: dist,
103
- });
104
-
105
96
  const worker = await Worker("worker", {
106
97
  ...props,
107
98
  name: props.name ?? id,
@@ -116,15 +107,20 @@ export async function Website<B extends Bindings>(
116
107
  ? undefined
117
108
  : `
118
109
  export default {
119
- async fetch(request, env) {
120
- return new Response("Not Found", { status: 404 });
121
- },
110
+ async fetch(request, env) {
111
+ return new Response("Not Found", { status: 404 });
112
+ },
122
113
  };`,
123
114
  url: true,
124
115
  adopt: true,
125
116
  bindings: {
126
117
  ...props.bindings,
127
- ASSETS: staticAssets,
118
+ ASSETS: await Assets("assets", {
119
+ path:
120
+ typeof props.assets === "string"
121
+ ? props.assets
122
+ : (props.assets?.dist ?? "dist"),
123
+ }),
128
124
  },
129
125
  });
130
126