alchemy 2.0.0-beta.50 → 2.0.0-beta.52

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 (254) hide show
  1. package/bin/exec.js +133 -135
  2. package/bin/exec.js.map +1 -1
  3. package/lib/AWS/Lambda/BucketEventSource.d.ts.map +1 -1
  4. package/lib/AWS/Lambda/BucketEventSource.js +13 -2
  5. package/lib/AWS/Lambda/BucketEventSource.js.map +1 -1
  6. package/lib/AWS/S3/Bucket.d.ts.map +1 -1
  7. package/lib/AWS/S3/Bucket.js +49 -0
  8. package/lib/AWS/S3/Bucket.js.map +1 -1
  9. package/lib/AWS/S3/BucketNotifications.d.ts +10 -0
  10. package/lib/AWS/S3/BucketNotifications.d.ts.map +1 -1
  11. package/lib/AWS/S3/BucketNotifications.js.map +1 -1
  12. package/lib/Apply.js +15 -3
  13. package/lib/Apply.js.map +1 -1
  14. package/lib/Auth/AuthProvider.js +1 -1
  15. package/lib/Auth/AuthProvider.js.map +1 -1
  16. package/lib/Binding.d.ts.map +1 -1
  17. package/lib/Binding.js +12 -8
  18. package/lib/Binding.js.map +1 -1
  19. package/lib/Build/DevServer.d.ts +113 -0
  20. package/lib/Build/DevServer.d.ts.map +1 -0
  21. package/lib/Build/DevServer.js +212 -0
  22. package/lib/Build/DevServer.js.map +1 -0
  23. package/lib/Build/Local.d.ts +2 -0
  24. package/lib/Build/Local.d.ts.map +1 -0
  25. package/lib/Build/Local.js +4 -0
  26. package/lib/Build/Local.js.map +1 -0
  27. package/lib/Bundle/Bundle.js +1 -1
  28. package/lib/Bundle/Bundle.js.map +1 -1
  29. package/lib/Cli/commands/cloudflare.d.ts +1 -1
  30. package/lib/Cloudflare/Access.js +1 -1
  31. package/lib/Cloudflare/Access.js.map +1 -1
  32. package/lib/Cloudflare/AiGateway/AiGateway.d.ts +1 -1
  33. package/lib/Cloudflare/AiGateway/AiGateway.js +1 -1
  34. package/lib/Cloudflare/AiGateway/AiGatewayBinding.d.ts +1 -1
  35. package/lib/Cloudflare/AiGateway/AiGatewayBinding.d.ts.map +1 -1
  36. package/lib/Cloudflare/AiGateway/AiGatewayBinding.js +6 -2
  37. package/lib/Cloudflare/AiGateway/AiGatewayBinding.js.map +1 -1
  38. package/lib/Cloudflare/Browser/Browser.d.ts +84 -12
  39. package/lib/Cloudflare/Browser/Browser.d.ts.map +1 -1
  40. package/lib/Cloudflare/Browser/Browser.js +80 -9
  41. package/lib/Cloudflare/Browser/Browser.js.map +1 -1
  42. package/lib/Cloudflare/Browser/BrowserBinding.d.ts +90 -16
  43. package/lib/Cloudflare/Browser/BrowserBinding.d.ts.map +1 -1
  44. package/lib/Cloudflare/Browser/BrowserBinding.js +41 -6
  45. package/lib/Cloudflare/Browser/BrowserBinding.js.map +1 -1
  46. package/lib/Cloudflare/Browser/index.d.ts +1 -1
  47. package/lib/Cloudflare/Browser/index.d.ts.map +1 -1
  48. package/lib/Cloudflare/Browser/index.js.map +1 -1
  49. package/lib/Cloudflare/Container/ContainerBinding.d.ts.map +1 -1
  50. package/lib/Cloudflare/Container/ContainerBinding.js +2 -4
  51. package/lib/Cloudflare/Container/ContainerBinding.js.map +1 -1
  52. package/lib/Cloudflare/Images/Images.d.ts +4 -3
  53. package/lib/Cloudflare/Images/Images.d.ts.map +1 -1
  54. package/lib/Cloudflare/Images/Images.js.map +1 -1
  55. package/lib/Cloudflare/Providers.d.ts +1 -1
  56. package/lib/Cloudflare/Providers.d.ts.map +1 -1
  57. package/lib/Cloudflare/Providers.js +6 -1
  58. package/lib/Cloudflare/Providers.js.map +1 -1
  59. package/lib/Cloudflare/RateLimit/RateLimit.d.ts +4 -3
  60. package/lib/Cloudflare/RateLimit/RateLimit.d.ts.map +1 -1
  61. package/lib/Cloudflare/RateLimit/RateLimit.js.map +1 -1
  62. package/lib/Cloudflare/Ruleset/Ruleset.d.ts +82 -0
  63. package/lib/Cloudflare/Ruleset/Ruleset.d.ts.map +1 -0
  64. package/lib/Cloudflare/Ruleset/Ruleset.js +126 -0
  65. package/lib/Cloudflare/Ruleset/Ruleset.js.map +1 -0
  66. package/lib/Cloudflare/Ruleset/index.d.ts +2 -0
  67. package/lib/Cloudflare/Ruleset/index.d.ts.map +1 -0
  68. package/lib/Cloudflare/Ruleset/index.js +2 -0
  69. package/lib/Cloudflare/Ruleset/index.js.map +1 -0
  70. package/lib/Cloudflare/SecretsStore/Secret.d.ts +1 -0
  71. package/lib/Cloudflare/SecretsStore/Secret.d.ts.map +1 -1
  72. package/lib/Cloudflare/SecretsStore/Secret.js +2 -0
  73. package/lib/Cloudflare/SecretsStore/Secret.js.map +1 -1
  74. package/lib/Cloudflare/StateStore/State.d.ts +1 -1
  75. package/lib/Cloudflare/StateStore/State.d.ts.map +1 -1
  76. package/lib/Cloudflare/Website/StaticSite.d.ts +64 -12
  77. package/lib/Cloudflare/Website/StaticSite.d.ts.map +1 -1
  78. package/lib/Cloudflare/Website/StaticSite.js +80 -30
  79. package/lib/Cloudflare/Website/StaticSite.js.map +1 -1
  80. package/lib/Cloudflare/Website/Vite.d.ts +36 -7
  81. package/lib/Cloudflare/Website/Vite.d.ts.map +1 -1
  82. package/lib/Cloudflare/Website/Vite.js +26 -8
  83. package/lib/Cloudflare/Website/Vite.js.map +1 -1
  84. package/lib/Cloudflare/Workers/Assets.d.ts +10 -4
  85. package/lib/Cloudflare/Workers/Assets.d.ts.map +1 -1
  86. package/lib/Cloudflare/Workers/Assets.js +6 -6
  87. package/lib/Cloudflare/Workers/Assets.js.map +1 -1
  88. package/lib/Cloudflare/Workers/DurableObjectChatPersistence.d.ts +69 -0
  89. package/lib/Cloudflare/Workers/DurableObjectChatPersistence.d.ts.map +1 -0
  90. package/lib/Cloudflare/Workers/DurableObjectChatPersistence.js +104 -0
  91. package/lib/Cloudflare/Workers/DurableObjectChatPersistence.js.map +1 -0
  92. package/lib/Cloudflare/Workers/DynamicWorkerLoader.d.ts +4 -4
  93. package/lib/Cloudflare/Workers/InferEnv.d.ts +1 -1
  94. package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
  95. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
  96. package/lib/Cloudflare/Workers/LocalWorkerProvider.js +45 -11
  97. package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
  98. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.d.ts +5 -4
  99. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.d.ts.map +1 -1
  100. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.js +4 -2
  101. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.js.map +1 -1
  102. package/lib/Cloudflare/Workers/RpcWorker.d.ts +3 -2
  103. package/lib/Cloudflare/Workers/RpcWorker.d.ts.map +1 -1
  104. package/lib/Cloudflare/Workers/RpcWorker.js +5 -3
  105. package/lib/Cloudflare/Workers/RpcWorker.js.map +1 -1
  106. package/lib/Cloudflare/Workers/VersionMetadata.d.ts +99 -0
  107. package/lib/Cloudflare/Workers/VersionMetadata.d.ts.map +1 -0
  108. package/lib/Cloudflare/Workers/VersionMetadata.js +65 -0
  109. package/lib/Cloudflare/Workers/VersionMetadata.js.map +1 -0
  110. package/lib/Cloudflare/Workers/VersionMetadataBinding.d.ts +35 -0
  111. package/lib/Cloudflare/Workers/VersionMetadataBinding.d.ts.map +1 -0
  112. package/lib/Cloudflare/Workers/VersionMetadataBinding.js +31 -0
  113. package/lib/Cloudflare/Workers/VersionMetadataBinding.js.map +1 -0
  114. package/lib/Cloudflare/Workers/Worker.d.ts +20 -19
  115. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  116. package/lib/Cloudflare/Workers/Worker.js +23 -37
  117. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  118. package/lib/Cloudflare/Workers/WorkerAsyncBindings.d.ts.map +1 -1
  119. package/lib/Cloudflare/Workers/WorkerAsyncBindings.js +16 -0
  120. package/lib/Cloudflare/Workers/WorkerAsyncBindings.js.map +1 -1
  121. package/lib/Cloudflare/Workers/WorkerBinding.d.ts +3 -1
  122. package/lib/Cloudflare/Workers/WorkerBinding.d.ts.map +1 -1
  123. package/lib/Cloudflare/Workers/WorkerBinding.js.map +1 -1
  124. package/lib/Cloudflare/Workers/Workflow.d.ts +8 -1
  125. package/lib/Cloudflare/Workers/Workflow.d.ts.map +1 -1
  126. package/lib/Cloudflare/Workers/Workflow.js +1 -0
  127. package/lib/Cloudflare/Workers/Workflow.js.map +1 -1
  128. package/lib/Cloudflare/Workers/WorkflowBridge.d.ts.map +1 -1
  129. package/lib/Cloudflare/Workers/WorkflowBridge.js +31 -2
  130. package/lib/Cloudflare/Workers/WorkflowBridge.js.map +1 -1
  131. package/lib/Cloudflare/Workers/index.d.ts +3 -0
  132. package/lib/Cloudflare/Workers/index.d.ts.map +1 -1
  133. package/lib/Cloudflare/Workers/index.js +3 -0
  134. package/lib/Cloudflare/Workers/index.js.map +1 -1
  135. package/lib/Cloudflare/Zaraz/ZarazConfig.d.ts.map +1 -1
  136. package/lib/Cloudflare/index.d.ts +1 -0
  137. package/lib/Cloudflare/index.d.ts.map +1 -1
  138. package/lib/Cloudflare/index.js +1 -0
  139. package/lib/Cloudflare/index.js.map +1 -1
  140. package/lib/Deploy.d.ts +3 -2
  141. package/lib/Deploy.d.ts.map +1 -1
  142. package/lib/Deploy.js.map +1 -1
  143. package/lib/Destroy.d.ts +3 -2
  144. package/lib/Destroy.d.ts.map +1 -1
  145. package/lib/Destroy.js.map +1 -1
  146. package/lib/Diff.d.ts.map +1 -1
  147. package/lib/Diff.js +7 -0
  148. package/lib/Diff.js.map +1 -1
  149. package/lib/Drizzle/Postgres.d.ts +13 -12
  150. package/lib/Drizzle/Postgres.d.ts.map +1 -1
  151. package/lib/Drizzle/Postgres.js +13 -12
  152. package/lib/Drizzle/Postgres.js.map +1 -1
  153. package/lib/Drizzle/Schema.d.ts +1 -1
  154. package/lib/Drizzle/Schema.d.ts.map +1 -1
  155. package/lib/Drizzle/Schema.js +20 -9
  156. package/lib/Drizzle/Schema.js.map +1 -1
  157. package/lib/Local/RpcSerialization.js +5 -2
  158. package/lib/Local/RpcSerialization.js.map +1 -1
  159. package/lib/Output.d.ts.map +1 -1
  160. package/lib/Output.js +11 -10
  161. package/lib/Output.js.map +1 -1
  162. package/lib/Plan.d.ts.map +1 -1
  163. package/lib/Plan.js +5 -1
  164. package/lib/Plan.js.map +1 -1
  165. package/lib/Planetscale/MySQL/MySQLDatabase.d.ts +0 -2
  166. package/lib/Planetscale/MySQL/MySQLDatabase.d.ts.map +1 -1
  167. package/lib/Planetscale/MySQL/MySQLDatabase.js +1 -3
  168. package/lib/Planetscale/MySQL/MySQLDatabase.js.map +1 -1
  169. package/lib/Planetscale/Postgres/PostgresDatabase.d.ts +0 -2
  170. package/lib/Planetscale/Postgres/PostgresDatabase.d.ts.map +1 -1
  171. package/lib/Planetscale/Postgres/PostgresDatabase.js +1 -3
  172. package/lib/Planetscale/Postgres/PostgresDatabase.js.map +1 -1
  173. package/lib/Platform.d.ts +4 -4
  174. package/lib/Platform.d.ts.map +1 -1
  175. package/lib/Platform.js +27 -25
  176. package/lib/Platform.js.map +1 -1
  177. package/lib/Resource.d.ts +7 -1
  178. package/lib/Resource.d.ts.map +1 -1
  179. package/lib/Resource.js +11 -12
  180. package/lib/Resource.js.map +1 -1
  181. package/lib/Runtime.d.ts +1 -1
  182. package/lib/Runtime.d.ts.map +1 -1
  183. package/lib/Runtime.js +3 -4
  184. package/lib/Runtime.js.map +1 -1
  185. package/lib/Stack.d.ts +5 -4
  186. package/lib/Stack.d.ts.map +1 -1
  187. package/lib/Stack.js.map +1 -1
  188. package/lib/Test/Core.d.ts +2 -2
  189. package/lib/Test/Core.d.ts.map +1 -1
  190. package/lib/Util/effect.d.ts.map +1 -1
  191. package/lib/Util/effect.js +13 -15
  192. package/lib/Util/effect.js.map +1 -1
  193. package/lib/Util/poll.d.ts +0 -1
  194. package/lib/Util/poll.d.ts.map +1 -1
  195. package/lib/Util/poll.js +2 -2
  196. package/lib/Util/poll.js.map +1 -1
  197. package/lib/tsconfig.test.tsbuildinfo +1 -1
  198. package/package.json +20 -20
  199. package/src/AWS/Lambda/BucketEventSource.ts +16 -1
  200. package/src/AWS/S3/Bucket.ts +78 -0
  201. package/src/AWS/S3/BucketNotifications.ts +10 -0
  202. package/src/Apply.ts +22 -3
  203. package/src/Auth/AuthProvider.ts +1 -1
  204. package/src/Binding.ts +45 -38
  205. package/src/Build/DevServer.ts +330 -0
  206. package/src/Build/Local.ts +4 -0
  207. package/src/Bundle/Bundle.ts +1 -1
  208. package/src/Cloudflare/Access.ts +1 -1
  209. package/src/Cloudflare/AiGateway/AiGateway.ts +1 -1
  210. package/src/Cloudflare/AiGateway/AiGatewayBinding.ts +8 -3
  211. package/src/Cloudflare/Browser/Browser.ts +84 -12
  212. package/src/Cloudflare/Browser/BrowserBinding.ts +205 -33
  213. package/src/Cloudflare/Browser/index.ts +15 -2
  214. package/src/Cloudflare/Container/ContainerBinding.ts +5 -10
  215. package/src/Cloudflare/Images/Images.ts +4 -3
  216. package/src/Cloudflare/Providers.ts +8 -0
  217. package/src/Cloudflare/RateLimit/RateLimit.ts +4 -3
  218. package/src/Cloudflare/Ruleset/Ruleset.ts +223 -0
  219. package/src/Cloudflare/Ruleset/index.ts +1 -0
  220. package/src/Cloudflare/SecretsStore/Secret.ts +4 -0
  221. package/src/Cloudflare/Website/StaticSite.ts +154 -41
  222. package/src/Cloudflare/Website/Vite.ts +73 -25
  223. package/src/Cloudflare/Workers/Assets.ts +10 -8
  224. package/src/Cloudflare/Workers/DurableObjectChatPersistence.ts +131 -0
  225. package/src/Cloudflare/Workers/DynamicWorkerLoader.ts +4 -4
  226. package/src/Cloudflare/Workers/InferEnv.ts +14 -12
  227. package/src/Cloudflare/Workers/LocalWorkerProvider.ts +54 -13
  228. package/src/Cloudflare/Workers/RpcDurableObjectNamespace.ts +11 -8
  229. package/src/Cloudflare/Workers/RpcWorker.ts +8 -7
  230. package/src/Cloudflare/Workers/VersionMetadata.ts +129 -0
  231. package/src/Cloudflare/Workers/VersionMetadataBinding.ts +82 -0
  232. package/src/Cloudflare/Workers/Worker.ts +66 -82
  233. package/src/Cloudflare/Workers/WorkerAsyncBindings.ts +14 -0
  234. package/src/Cloudflare/Workers/WorkerBinding.ts +4 -0
  235. package/src/Cloudflare/Workers/Workflow.ts +12 -1
  236. package/src/Cloudflare/Workers/WorkflowBridge.ts +47 -6
  237. package/src/Cloudflare/Workers/index.ts +3 -0
  238. package/src/Cloudflare/index.ts +1 -0
  239. package/src/Deploy.ts +2 -1
  240. package/src/Destroy.ts +2 -1
  241. package/src/Diff.ts +7 -0
  242. package/src/Drizzle/Postgres.ts +13 -12
  243. package/src/Drizzle/Schema.ts +27 -9
  244. package/src/Local/RpcSerialization.ts +5 -2
  245. package/src/Output.ts +12 -10
  246. package/src/Plan.ts +5 -1
  247. package/src/Planetscale/MySQL/MySQLDatabase.ts +1 -6
  248. package/src/Planetscale/Postgres/PostgresDatabase.ts +1 -5
  249. package/src/Platform.ts +48 -36
  250. package/src/Resource.ts +22 -13
  251. package/src/Runtime.ts +3 -7
  252. package/src/Stack.ts +11 -10
  253. package/src/Util/effect.ts +13 -17
  254. package/src/Util/poll.ts +3 -3
@@ -66,6 +66,10 @@ import type { WorkerBinding } from "./WorkerBinding.ts";
66
66
  import { WorkerBundle, type WorkerBundleOptions } from "./WorkerBundle.ts";
67
67
  import { createWorkerName } from "./WorkerName.ts";
68
68
 
69
+ type WorkerPropsWithDev = Omit<WorkerProps, "dev"> & {
70
+ dev: Exclude<WorkerProps["dev"], false | string>;
71
+ };
72
+
69
73
  export class WorkerValidationError extends Schema.TaggedErrorClass<WorkerValidationError>()(
70
74
  "WorkerValidationError",
71
75
  {
@@ -227,7 +231,7 @@ export const LocalWorkerProvider = () =>
227
231
  bindings,
228
232
  }: {
229
233
  id: string;
230
- props: WorkerProps;
234
+ props: WorkerPropsWithDev;
231
235
  bindings: ResourceBinding<Worker["Binding"]>[];
232
236
  }) {
233
237
  const name = yield* createWorkerName(id, props.name);
@@ -244,6 +248,7 @@ export const LocalWorkerProvider = () =>
244
248
  ? Text.local(key, unredacted)
245
249
  : Json.local(key, unredacted);
246
250
  }),
251
+ ...(props.assets || props.vite ? [Assets.local("ASSETS")] : []),
247
252
  ];
248
253
  const durableObjectNamespaces: Record<string, string> = {};
249
254
  const hyperdrives: Record<string, Required<HyperdriveOrigin>> = {};
@@ -257,11 +262,19 @@ export const LocalWorkerProvider = () =>
257
262
  ) {
258
263
  // Reuse the existing namespace id if it was provided, otherwise generate a new one.
259
264
  // `workerd` uses this for the object's storage path, so it must be safe to use as a file name.
260
- durableObjectNamespaces[binding.className] =
265
+ const namespaceId =
261
266
  binding.namespaceId ??
262
- encodeURIComponent(`${id}-${binding.className}`);
267
+ encodeURIComponent(`${name}-${binding.className}`);
268
+ durableObjectNamespaces[binding.className] = namespaceId;
269
+ workerBindings.push(
270
+ yield* toRuntimeBinding({
271
+ ...binding,
272
+ namespaceId,
273
+ }),
274
+ );
275
+ } else {
276
+ workerBindings.push(yield* toRuntimeBinding(binding));
263
277
  }
264
- workerBindings.push(yield* toRuntimeBinding(binding));
265
278
  }
266
279
  if (data.hyperdrives) {
267
280
  for (const [id, origin] of Object.entries(data.hyperdrives)) {
@@ -408,7 +421,7 @@ export const LocalWorkerProvider = () =>
408
421
 
409
422
  const runInstance = Effect.fn(function* (options: {
410
423
  id: string;
411
- props: WorkerProps;
424
+ props: WorkerPropsWithDev;
412
425
  bindings: ResourceBinding<Worker["Binding"]>[];
413
426
  }) {
414
427
  const { props, bindings } = options;
@@ -450,7 +463,32 @@ export const LocalWorkerProvider = () =>
450
463
  };
451
464
  }),
452
465
  reconcile: Effect.fn(function* ({ id, news, bindings }) {
453
- const options = { id, props: news, bindings };
466
+ // `dev: false` opts out of running a local Worker entirely —
467
+ // typically because an external dev process (DevCommand) is
468
+ // serving requests. Tear down any prior instance and return a
469
+ // stub Attributes; the resource exists in state but has no
470
+ // running workerd / proxy behind it.
471
+ if (news.dev === false || typeof news.dev === "string") {
472
+ const existing = instances.get(id);
473
+ if (existing) {
474
+ yield* Fiber.interrupt(existing.fiber);
475
+ yield* Scope.close(existing.scope, Exit.void);
476
+ instances.delete(id);
477
+ }
478
+ const name = yield* createWorkerName(id, news.name);
479
+ return {
480
+ workerId: name,
481
+ workerName: name,
482
+ logpush: undefined,
483
+ url: news.dev || undefined,
484
+ tags: [],
485
+ durableObjectNamespaces: {},
486
+ accountId,
487
+ domains: [],
488
+ crons: news.crons ?? [],
489
+ } satisfies Worker["Attributes"];
490
+ }
491
+ const options = { id, props: news as WorkerPropsWithDev, bindings };
454
492
  const hash = Hash.structure(options);
455
493
  const existing = instances.get(options.id);
456
494
  if (existing) {
@@ -526,6 +564,9 @@ const toRuntimeBinding = Effect.fnUntraced(function* (b: WorkerBinding) {
526
564
  binding: b.name,
527
565
  className: b.className,
528
566
  scriptName: b.scriptName,
567
+ uniqueKey:
568
+ b.namespaceId ??
569
+ encodeURIComponent(`${b.scriptName!}-${b.className}`),
529
570
  });
530
571
  case "hyperdrive":
531
572
  return Hyperdrive.local(b.name, b.id);
@@ -600,24 +641,24 @@ const toRuntimeAssets = (
600
641
  };
601
642
  }
602
643
  return {
603
- directory: "directory" in assets ? assets.directory : assets.path,
604
- headers: assets.config?.headers,
605
- redirects: assets.config?.redirects,
644
+ directory: assets.directory,
645
+ headers: assets.headers,
646
+ redirects: assets.redirects,
606
647
  // Distilled widened generated string enums to open unions (`string & {}`);
607
648
  // the API only ever returns the known variants here.
608
- htmlHandling: assets.config?.htmlHandling as
649
+ htmlHandling: assets.htmlHandling as
609
650
  | "none"
610
651
  | "auto-trailing-slash"
611
652
  | "force-trailing-slash"
612
653
  | "drop-trailing-slash"
613
654
  | undefined,
614
- notFoundHandling: assets.config?.notFoundHandling as
655
+ notFoundHandling: assets.notFoundHandling as
615
656
  | "none"
616
657
  | "404-page"
617
658
  | "single-page-application"
618
659
  | undefined,
619
- runWorkerFirst: assets.config?.runWorkerFirst,
620
- serveDirectly: assets.config?.serveDirectly,
660
+ runWorkerFirst: assets.runWorkerFirst,
661
+ serveDirectly: assets.serveDirectly,
621
662
  };
622
663
  };
623
664
 
@@ -1,3 +1,4 @@
1
+ import type { ConfigError } from "effect/Config";
1
2
  import * as Context from "effect/Context";
2
3
  import * as Effect from "effect/Effect";
3
4
  import type * as Layer from "effect/Layer";
@@ -100,7 +101,7 @@ export interface RpcDurableObjectNamespaceClass extends Effect.Effect<
100
101
  from<Req = never>(
101
102
  worker:
102
103
  | Dependencies<Self>
103
- | Effect.Effect<Dependencies<Self>, never, Req>,
104
+ | Effect.Effect<Dependencies<Self>, ConfigError, Req>,
104
105
  ): Effect.Effect<
105
106
  RpcDurableObjectNamespace<Self, Rpcs>,
106
107
  never,
@@ -113,7 +114,7 @@ export interface RpcDurableObjectNamespaceClass extends Effect.Effect<
113
114
  never,
114
115
  DurableObjectServices
115
116
  >,
116
- never,
117
+ ConfigError,
117
118
  InitReq
118
119
  >,
119
120
  ): Layer.Layer<
@@ -132,7 +133,7 @@ export interface RpcDurableObjectNamespaceClass extends Effect.Effect<
132
133
  never,
133
134
  DurableObjectServices
134
135
  >,
135
- never,
136
+ ConfigError,
136
137
  InitReq
137
138
  >,
138
139
  ): Effect.Effect<
@@ -160,7 +161,7 @@ export interface RpcDurableObjectNamespaceClass extends Effect.Effect<
160
161
  never,
161
162
  DurableObjectServices
162
163
  >,
163
- never,
164
+ ConfigError,
164
165
  InitReq
165
166
  >,
166
167
  ): Effect.Effect<
@@ -456,11 +457,12 @@ const build = (
456
457
  // eagerly here (consumers wanting cross-script binding use the
457
458
  // modular form below).
458
459
  const underlying = (DurableObjectNamespace as any)()(name, wrapImpl(impl));
459
- const underlyingEff: Effect.Effect<
460
+ // `underlying` is itself an Effect now, no `.asEffect()` hop required.
461
+ const underlyingEff = underlying as Effect.Effect<
460
462
  DurableObjectNamespaceType<any>,
461
463
  never,
462
464
  any
463
- > = (underlying as { asEffect(): Effect.Effect<any, never, any> }).asEffect();
465
+ >;
464
466
  const rpcBound = underlyingEff.pipe(
465
467
  Effect.map((rawNs) => rpcWrap(rawNs, props.schema)),
466
468
  ) as unknown as Effect.Effect<RpcDurableObjectNamespace<any>>;
@@ -476,11 +478,12 @@ const buildModular = (name: string, schema: RpcGroup.RpcGroup<any>) => {
476
478
  // binding on the surrounding worker and yields a fresh handle
477
479
  // We just rpc-wrap each output so consumers see a typed `getByName`.
478
480
  const Underlying: any = (DurableObjectNamespace as any)()(name);
479
- const underlyingEff: Effect.Effect<
481
+ // `Underlying` is itself an Effect now, no `.asEffect()` hop required.
482
+ const underlyingEff = Underlying as Effect.Effect<
480
483
  DurableObjectNamespaceType<any>,
481
484
  never,
482
485
  any
483
- > = (Underlying as { asEffect(): Effect.Effect<any, never, any> }).asEffect();
486
+ >;
484
487
 
485
488
  return class extends effectClass(
486
489
  underlyingEff.pipe(
@@ -1,3 +1,4 @@
1
+ import type { ConfigError } from "effect/Config";
1
2
  import * as Context from "effect/Context";
2
3
  import * as Effect from "effect/Effect";
3
4
  import * as Layer from "effect/Layer";
@@ -107,7 +108,7 @@ export interface RpcWorkerClass extends Effect.Effect<
107
108
  make<InnerR = never, InitReq = never>(
108
109
  impl: Effect.Effect<
109
110
  Effect.Effect<HttpEffect<InnerR>, never, InnerR>,
110
- never,
111
+ ConfigError,
111
112
  InitReq
112
113
  >,
113
114
  ): Layer.Layer<Self, never, Exclude<InitReq | InnerR, never>>;
@@ -118,7 +119,7 @@ export interface RpcWorkerClass extends Effect.Effect<
118
119
  props: RpcWorkerProps<Rpcs>,
119
120
  impl: Effect.Effect<
120
121
  Effect.Effect<HttpEffect<InnerR>, never, InnerR>,
121
- never,
122
+ ConfigError,
122
123
  InitReq
123
124
  >,
124
125
  ): RpcWorkerYieldable<Self, Rpcs, Deps> & {
@@ -519,9 +520,9 @@ const buildModular = (id: string, props: RpcWorkerProps<any>) => {
519
520
  // shape `Cloudflare.Worker` expects, and stash the rpc schema on
520
521
  // the class so `RpcWorker.bind(WorkerClass)` can recover it.
521
522
  const Underlying: any = (WorkerCtor as any)()(id, workerProps);
522
- const klass = class extends effectClass(
523
- (Underlying as { asEffect(): Effect.Effect<Worker> }).asEffect(),
524
- ) {
523
+ // `Underlying` is itself an Effect (the no-impl Worker class), so hand it
524
+ // straight to `effectClass` rather than reaching for a removed `.asEffect()`.
525
+ const klass = class extends effectClass(Underlying as Effect.Effect<Worker>) {
525
526
  static make = (
526
527
  impl: Effect.Effect<Effect.Effect<HttpEffect<any>>>,
527
528
  ): Layer.Layer<any, never, any> => Underlying.make(wrapImpl(impl));
@@ -553,9 +554,9 @@ const build = (
553
554
  // Re-wrap as our own `effectClass` so we can stash the rpc schema
554
555
  // on the class for `RpcWorker.bind` to recover later. (Re-using
555
556
  // `effectClass` here means `class X extends RpcWorker<X>()(...)`
556
- // still works.)
557
+ // still works.) `underlying` is already an Effect, so pass it directly.
557
558
  const klass = effectClass(
558
- (underlying as { asEffect(): Effect.Effect<Worker> }).asEffect(),
559
+ underlying as Effect.Effect<Worker>,
559
560
  ) as unknown as Record<symbol, unknown>;
560
561
  klass[SchemaSymbol] = schema;
561
562
  return klass;
@@ -0,0 +1,129 @@
1
+ import type * as Effect from "effect/Effect";
2
+ import { SingleShotGen } from "effect/Utils";
3
+ import {
4
+ VersionMetadataBinding,
5
+ type VersionMetadataAccessor,
6
+ } from "./VersionMetadataBinding.ts";
7
+
8
+ type VersionMetadataTypeId = typeof VersionMetadataTypeId;
9
+ const VersionMetadataTypeId = "Cloudflare.VersionMetadata" as const;
10
+
11
+ export type VersionMetadataProps = {
12
+ /**
13
+ * Binding name used when `VersionMetadata` is bound from inside a Worker init
14
+ * phase (`yield* Cloudflare.VersionMetadata(...)`). When passed through
15
+ * `Worker({ env: { ... } })`, the object key remains the binding name.
16
+ *
17
+ * @default "CF_VERSION_METADATA"
18
+ */
19
+ name?: string;
20
+ };
21
+
22
+ /**
23
+ * The Effect yielded when a `VersionMetadata` marker is used inside a Worker
24
+ * init phase: it attaches the `version_metadata` binding to the surrounding
25
+ * Worker and resolves to a deferred {@link VersionMetadataAccessor}.
26
+ */
27
+ type BindEffect = Effect.Effect<
28
+ VersionMetadataAccessor,
29
+ never,
30
+ VersionMetadataBinding
31
+ >;
32
+
33
+ /**
34
+ * Marker for a Cloudflare Workers Version Metadata binding.
35
+ *
36
+ * It is a plain data structure (so it can be declared directly on a Worker's
37
+ * `env`) that is **also** yieldable inside an Effect-native Worker. Yielding it
38
+ * (`yield* Cloudflare.VersionMetadata(...)`) attaches the binding to the
39
+ * surrounding Worker and returns a deferred accessor for the runtime
40
+ * {@link import("./VersionMetadataBinding.ts").WorkerVersionMetadata}.
41
+ *
42
+ * The divergence is achieved via `[Symbol.iterator]`: the object is
43
+ * deliberately not an `Effect` (so `InferEnv` and the Worker `env` resolver
44
+ * keep it as the native version metadata rather than `yield*`-ing it), but it
45
+ * is iterable as one when `yield*`-ed.
46
+ */
47
+ export type VersionMetadata = {
48
+ kind: VersionMetadataTypeId;
49
+ name: string;
50
+ asEffect(): BindEffect;
51
+ [Symbol.iterator](): SingleShotGen<BindEffect, VersionMetadataAccessor>;
52
+ };
53
+
54
+ export const isVersionMetadata = (value: unknown): value is VersionMetadata =>
55
+ typeof value === "object" &&
56
+ value !== null &&
57
+ "kind" in value &&
58
+ (value as VersionMetadata).kind === VersionMetadataTypeId;
59
+
60
+ /**
61
+ * A Cloudflare Workers Version Metadata binding.
62
+ *
63
+ * Cloudflare provides the deployed Worker version at runtime (`id`, `tag`,
64
+ * `timestamp`).
65
+ *
66
+ * @binding
67
+ *
68
+ * @section Effect-style Worker (recommended)
69
+ * @example Read the deployed version from inside a handler
70
+ * ```typescript
71
+ * import * as Effect from "effect/Effect";
72
+ *
73
+ * Cloudflare.Worker(
74
+ * "VersionWorker",
75
+ * { main: import.meta.filename },
76
+ * Effect.gen(function* () {
77
+ * // Attaches the binding to this Worker AND returns a deferred accessor.
78
+ * const versionMetadata = yield* Cloudflare.VersionMetadata();
79
+ *
80
+ * return {
81
+ * fetch: Effect.gen(function* () {
82
+ * const { id, tag, timestamp } = yield* versionMetadata;
83
+ * return Response.json({ id, tag, timestamp });
84
+ * }),
85
+ * };
86
+ * }).pipe(Effect.provide(Cloudflare.VersionMetadataBindingLive)),
87
+ * );
88
+ * ```
89
+ *
90
+ * @section Worker binding metadata
91
+ * @example
92
+ * ```typescript
93
+ * export const Worker = Cloudflare.Worker("Worker", {
94
+ * main: "./src/worker.ts",
95
+ * env: {
96
+ * CF_VERSION_METADATA: Cloudflare.VersionMetadata(),
97
+ * },
98
+ * });
99
+ *
100
+ * export type WorkerEnv = Cloudflare.InferEnv<typeof Worker>;
101
+ * // { CF_VERSION_METADATA: WorkerVersionMetadata }
102
+ * ```
103
+ *
104
+ * @see https://developers.cloudflare.com/workers/runtime-apis/bindings/version-metadata/
105
+ */
106
+ export const VersionMetadata: {
107
+ (props?: VersionMetadataProps): VersionMetadata;
108
+ /**
109
+ * Bind an existing `VersionMetadata` marker to the surrounding Worker,
110
+ * returning the deferred accessor. Equivalent to `yield* versionMetadata` —
111
+ * prefer yielding the marker directly.
112
+ */
113
+ bind: typeof VersionMetadataBinding.bind;
114
+ } = Object.assign(
115
+ (props?: VersionMetadataProps): VersionMetadata => {
116
+ const self: VersionMetadata = {
117
+ kind: VersionMetadataTypeId,
118
+ name: props?.name ?? "CF_VERSION_METADATA",
119
+ asEffect: () => VersionMetadataBinding.bind(self),
120
+ [Symbol.iterator]: () =>
121
+ new SingleShotGen(VersionMetadataBinding.bind(self)),
122
+ };
123
+ return self;
124
+ },
125
+ {
126
+ bind: (...args: Parameters<typeof VersionMetadataBinding.bind>) =>
127
+ VersionMetadataBinding.bind(...args),
128
+ },
129
+ );
@@ -0,0 +1,82 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Layer from "effect/Layer";
3
+ import * as Binding from "../../Binding.ts";
4
+ import type { ResourceLike } from "../../Resource.ts";
5
+ import type { VersionMetadata as VersionMetadataLike } from "./VersionMetadata.ts";
6
+ import { isWorker, WorkerEnvironment } from "./Worker.ts";
7
+
8
+ /**
9
+ * Runtime value Cloudflare exposes for a `version_metadata` binding — the
10
+ * deployed Worker version's `id`, `tag`, and `timestamp`.
11
+ */
12
+ export interface WorkerVersionMetadata {
13
+ readonly id: string;
14
+ readonly tag: string;
15
+ readonly timestamp: string;
16
+ }
17
+
18
+ /**
19
+ * Effect-native accessor for a Cloudflare Workers Version Metadata binding.
20
+ *
21
+ * The Worker env binding only exists at the *exec* phase on the deployed
22
+ * Worker, so reading it is deferred behind an Effect that requires
23
+ * {@link WorkerEnvironment}. Yield it inside a handler to obtain the
24
+ * {@link WorkerVersionMetadata}.
25
+ */
26
+ export type VersionMetadataAccessor = Effect.Effect<
27
+ WorkerVersionMetadata,
28
+ never,
29
+ WorkerEnvironment
30
+ >;
31
+
32
+ export class VersionMetadataBinding extends Binding.Service<
33
+ VersionMetadataBinding,
34
+ (
35
+ versionMetadata: VersionMetadataLike,
36
+ ) => Effect.Effect<VersionMetadataAccessor>
37
+ >()("Cloudflare.VersionMetadata") {}
38
+
39
+ export const VersionMetadataBindingLive = Layer.effect(
40
+ VersionMetadataBinding,
41
+ Effect.gen(function* () {
42
+ const Policy = yield* VersionMetadataBindingPolicy;
43
+
44
+ return Effect.fn(function* (versionMetadata: VersionMetadataLike) {
45
+ yield* Policy(versionMetadata);
46
+ return WorkerEnvironment.useSync(
47
+ (env) =>
48
+ (env as Record<string, WorkerVersionMetadata>)[versionMetadata.name]!,
49
+ );
50
+ });
51
+ }),
52
+ );
53
+
54
+ export class VersionMetadataBindingPolicy extends Binding.Policy<
55
+ VersionMetadataBindingPolicy,
56
+ (versionMetadata: VersionMetadataLike) => Effect.Effect<void>
57
+ >()("Cloudflare.VersionMetadata") {}
58
+
59
+ export const VersionMetadataBindingPolicyLive =
60
+ VersionMetadataBindingPolicy.layer.succeed(
61
+ Effect.fn(function* (
62
+ host: ResourceLike,
63
+ versionMetadata: VersionMetadataLike,
64
+ ) {
65
+ if (isWorker(host)) {
66
+ yield* host.bind(versionMetadata.name, {
67
+ bindings: [
68
+ {
69
+ type: "version_metadata",
70
+ name: versionMetadata.name,
71
+ },
72
+ ],
73
+ });
74
+ } else {
75
+ return yield* Effect.die(
76
+ new Error(
77
+ `VersionMetadataBinding does not support runtime '${host.Type}'`,
78
+ ),
79
+ );
80
+ }
81
+ }),
82
+ );