alchemy 2.0.0-beta.44 → 2.0.0-beta.45

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 (404) hide show
  1. package/bin/exec.js +67 -8
  2. package/bin/exec.js.map +1 -1
  3. package/lib/AWS/Lambda/Function.d.ts +17 -0
  4. package/lib/AWS/Lambda/Function.d.ts.map +1 -1
  5. package/lib/AWS/Lambda/Function.js +61 -16
  6. package/lib/AWS/Lambda/Function.js.map +1 -1
  7. package/lib/AWS/Providers.d.ts +2 -1
  8. package/lib/AWS/Providers.d.ts.map +1 -1
  9. package/lib/AWS/Providers.js +3 -1
  10. package/lib/AWS/Providers.js.map +1 -1
  11. package/lib/Apply.js +17 -1
  12. package/lib/Apply.js.map +1 -1
  13. package/lib/Auth/AuthProvider.d.ts.map +1 -1
  14. package/lib/Auth/AuthProvider.js +24 -6
  15. package/lib/Auth/AuthProvider.js.map +1 -1
  16. package/lib/Auth/Credentials.d.ts.map +1 -1
  17. package/lib/Auth/Credentials.js +3 -3
  18. package/lib/Auth/Credentials.js.map +1 -1
  19. package/lib/Cli/commands/_shared.d.ts +13 -1
  20. package/lib/Cli/commands/_shared.d.ts.map +1 -1
  21. package/lib/Cli/commands/_shared.js +33 -2
  22. package/lib/Cli/commands/_shared.js.map +1 -1
  23. package/lib/Cli/commands/dev.d.ts.map +1 -1
  24. package/lib/Cli/commands/dev.js +10 -1
  25. package/lib/Cli/commands/dev.js.map +1 -1
  26. package/lib/Cli/commands/login.d.ts.map +1 -1
  27. package/lib/Cli/commands/login.js +19 -5
  28. package/lib/Cli/commands/login.js.map +1 -1
  29. package/lib/Cli/commands/profile.d.ts.map +1 -1
  30. package/lib/Cli/commands/profile.js +7 -27
  31. package/lib/Cli/commands/profile.js.map +1 -1
  32. package/lib/Cli/main.d.ts.map +1 -1
  33. package/lib/Cli/main.js +0 -2
  34. package/lib/Cli/main.js.map +1 -1
  35. package/lib/Cloudflare/AiGateway/AiGateway.d.ts +0 -2
  36. package/lib/Cloudflare/AiGateway/AiGateway.d.ts.map +1 -1
  37. package/lib/Cloudflare/AiGateway/AiGateway.js +2 -4
  38. package/lib/Cloudflare/AiGateway/AiGateway.js.map +1 -1
  39. package/lib/Cloudflare/BrowserRendering/BrowserRendering.d.ts +116 -0
  40. package/lib/Cloudflare/BrowserRendering/BrowserRendering.d.ts.map +1 -0
  41. package/lib/Cloudflare/BrowserRendering/BrowserRendering.js +92 -0
  42. package/lib/Cloudflare/BrowserRendering/BrowserRendering.js.map +1 -0
  43. package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.d.ts +55 -0
  44. package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.d.ts.map +1 -0
  45. package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.js +55 -0
  46. package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.js.map +1 -0
  47. package/lib/Cloudflare/BrowserRendering/index.d.ts +3 -0
  48. package/lib/Cloudflare/BrowserRendering/index.d.ts.map +1 -0
  49. package/lib/Cloudflare/BrowserRendering/index.js +3 -0
  50. package/lib/Cloudflare/BrowserRendering/index.js.map +1 -0
  51. package/lib/Cloudflare/Container/Container.d.ts +3 -3
  52. package/lib/Cloudflare/Container/Container.js +3 -3
  53. package/lib/Cloudflare/Container/StartContainer.d.ts.map +1 -1
  54. package/lib/Cloudflare/Container/StartContainer.js.map +1 -1
  55. package/lib/Cloudflare/D1/D1Database.d.ts +1 -0
  56. package/lib/Cloudflare/D1/D1Database.d.ts.map +1 -1
  57. package/lib/Cloudflare/D1/D1Database.js +2 -1
  58. package/lib/Cloudflare/D1/D1Database.js.map +1 -1
  59. package/lib/Cloudflare/D1/D1DatabaseBinding.js +1 -1
  60. package/lib/Cloudflare/D1/D1DatabaseBinding.js.map +1 -1
  61. package/lib/Cloudflare/Fetcher.d.ts.map +1 -1
  62. package/lib/Cloudflare/Fetcher.js +0 -2
  63. package/lib/Cloudflare/Fetcher.js.map +1 -1
  64. package/lib/Cloudflare/Hyperdrive/Hyperdrive.d.ts +1 -0
  65. package/lib/Cloudflare/Hyperdrive/Hyperdrive.d.ts.map +1 -1
  66. package/lib/Cloudflare/Hyperdrive/Hyperdrive.js +3 -0
  67. package/lib/Cloudflare/Hyperdrive/Hyperdrive.js.map +1 -1
  68. package/lib/Cloudflare/Hyperdrive/HyperdriveBinding.d.ts +3 -2
  69. package/lib/Cloudflare/Hyperdrive/HyperdriveBinding.d.ts.map +1 -1
  70. package/lib/Cloudflare/Hyperdrive/HyperdriveBinding.js +32 -33
  71. package/lib/Cloudflare/Hyperdrive/HyperdriveBinding.js.map +1 -1
  72. package/lib/Cloudflare/KV/KVNamespace.d.ts +1 -0
  73. package/lib/Cloudflare/KV/KVNamespace.d.ts.map +1 -1
  74. package/lib/Cloudflare/KV/KVNamespace.js +2 -0
  75. package/lib/Cloudflare/KV/KVNamespace.js.map +1 -1
  76. package/lib/Cloudflare/Local.js +1 -1
  77. package/lib/Cloudflare/Local.js.map +1 -1
  78. package/lib/Cloudflare/Providers.d.ts +2 -1
  79. package/lib/Cloudflare/Providers.d.ts.map +1 -1
  80. package/lib/Cloudflare/Providers.js +21 -17
  81. package/lib/Cloudflare/Providers.js.map +1 -1
  82. package/lib/Cloudflare/Queue/Queue.d.ts +1 -0
  83. package/lib/Cloudflare/Queue/Queue.d.ts.map +1 -1
  84. package/lib/Cloudflare/Queue/Queue.js +1 -0
  85. package/lib/Cloudflare/Queue/Queue.js.map +1 -1
  86. package/lib/Cloudflare/Queue/QueueConsumer.d.ts +2 -1
  87. package/lib/Cloudflare/Queue/QueueConsumer.d.ts.map +1 -1
  88. package/lib/Cloudflare/Queue/QueueConsumer.js +11 -3
  89. package/lib/Cloudflare/Queue/QueueConsumer.js.map +1 -1
  90. package/lib/Cloudflare/Queue/QueueEventSource.d.ts +30 -4
  91. package/lib/Cloudflare/Queue/QueueEventSource.d.ts.map +1 -1
  92. package/lib/Cloudflare/Queue/QueueEventSource.js +22 -1
  93. package/lib/Cloudflare/Queue/QueueEventSource.js.map +1 -1
  94. package/lib/Cloudflare/R2/R2Bucket.d.ts +1 -0
  95. package/lib/Cloudflare/R2/R2Bucket.d.ts.map +1 -1
  96. package/lib/Cloudflare/R2/R2Bucket.js +18 -0
  97. package/lib/Cloudflare/R2/R2Bucket.js.map +1 -1
  98. package/lib/Cloudflare/SecretsStore/Secret.d.ts.map +1 -1
  99. package/lib/Cloudflare/SecretsStore/Secret.js +13 -34
  100. package/lib/Cloudflare/SecretsStore/Secret.js.map +1 -1
  101. package/lib/Cloudflare/SecretsStore/SecretBinding.d.ts +3 -2
  102. package/lib/Cloudflare/SecretsStore/SecretBinding.d.ts.map +1 -1
  103. package/lib/Cloudflare/SecretsStore/SecretBinding.js +3 -2
  104. package/lib/Cloudflare/SecretsStore/SecretBinding.js.map +1 -1
  105. package/lib/Cloudflare/StateStore/Api.d.ts +5 -13
  106. package/lib/Cloudflare/StateStore/Api.d.ts.map +1 -1
  107. package/lib/Cloudflare/StateStore/Api.js +14 -8
  108. package/lib/Cloudflare/StateStore/Api.js.map +1 -1
  109. package/lib/Cloudflare/StateStore/State.d.ts.map +1 -1
  110. package/lib/Cloudflare/StateStore/State.js +45 -9
  111. package/lib/Cloudflare/StateStore/State.js.map +1 -1
  112. package/lib/Cloudflare/StateStore/Store.d.ts.map +1 -1
  113. package/lib/Cloudflare/StateStore/Store.js +5 -2
  114. package/lib/Cloudflare/StateStore/Store.js.map +1 -1
  115. package/lib/Cloudflare/VpcService/VpcService.d.ts +2 -2
  116. package/lib/Cloudflare/VpcService/VpcService.d.ts.map +1 -1
  117. package/lib/Cloudflare/Website/StaticSite.d.ts +5 -5
  118. package/lib/Cloudflare/Website/StaticSite.d.ts.map +1 -1
  119. package/lib/Cloudflare/Website/StaticSite.js +3 -0
  120. package/lib/Cloudflare/Website/StaticSite.js.map +1 -1
  121. package/lib/Cloudflare/Website/Vite.d.ts +5 -5
  122. package/lib/Cloudflare/Website/Vite.d.ts.map +1 -1
  123. package/lib/Cloudflare/Website/Vite.js.map +1 -1
  124. package/lib/Cloudflare/Workers/Assets.d.ts.map +1 -1
  125. package/lib/Cloudflare/Workers/Assets.js +1 -1
  126. package/lib/Cloudflare/Workers/Assets.js.map +1 -1
  127. package/lib/Cloudflare/Workers/DurableObjectBridge.d.ts.map +1 -1
  128. package/lib/Cloudflare/Workers/DurableObjectBridge.js +4 -2
  129. package/lib/Cloudflare/Workers/DurableObjectBridge.js.map +1 -1
  130. package/lib/Cloudflare/Workers/DurableObjectNamespace.d.ts +183 -6
  131. package/lib/Cloudflare/Workers/DurableObjectNamespace.d.ts.map +1 -1
  132. package/lib/Cloudflare/Workers/DurableObjectNamespace.js +279 -76
  133. package/lib/Cloudflare/Workers/DurableObjectNamespace.js.map +1 -1
  134. package/lib/Cloudflare/Workers/HttpServer.d.ts +6 -4
  135. package/lib/Cloudflare/Workers/HttpServer.d.ts.map +1 -1
  136. package/lib/Cloudflare/Workers/HttpServer.js +20 -15
  137. package/lib/Cloudflare/Workers/HttpServer.js.map +1 -1
  138. package/lib/Cloudflare/Workers/InferEnv.d.ts +3 -2
  139. package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
  140. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts +4 -7
  141. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
  142. package/lib/Cloudflare/Workers/LocalWorkerProvider.js +111 -66
  143. package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
  144. package/lib/Cloudflare/Workers/Rpc.d.ts +16 -0
  145. package/lib/Cloudflare/Workers/Rpc.d.ts.map +1 -1
  146. package/lib/Cloudflare/Workers/Rpc.js +22 -0
  147. package/lib/Cloudflare/Workers/Rpc.js.map +1 -1
  148. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.d.ts +285 -0
  149. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.d.ts.map +1 -0
  150. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.js +288 -0
  151. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.js.map +1 -0
  152. package/lib/Cloudflare/Workers/RpcWorker.d.ts +305 -0
  153. package/lib/Cloudflare/Workers/RpcWorker.d.ts.map +1 -0
  154. package/lib/Cloudflare/Workers/RpcWorker.js +350 -0
  155. package/lib/Cloudflare/Workers/RpcWorker.js.map +1 -0
  156. package/lib/Cloudflare/Workers/Vite.d.ts +1 -1
  157. package/lib/Cloudflare/Workers/Vite.d.ts.map +1 -1
  158. package/lib/Cloudflare/Workers/Vite.js +2 -1
  159. package/lib/Cloudflare/Workers/Vite.js.map +1 -1
  160. package/lib/Cloudflare/Workers/Worker.d.ts +69 -24
  161. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  162. package/lib/Cloudflare/Workers/Worker.js +168 -47
  163. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  164. package/lib/Cloudflare/Workers/WorkerAsyncBindings.d.ts +1 -1
  165. package/lib/Cloudflare/Workers/WorkerAsyncBindings.d.ts.map +1 -1
  166. package/lib/Cloudflare/Workers/WorkerAsyncBindings.js +158 -97
  167. package/lib/Cloudflare/Workers/WorkerAsyncBindings.js.map +1 -1
  168. package/lib/Cloudflare/Workers/WorkerBinding.d.ts +11 -23
  169. package/lib/Cloudflare/Workers/WorkerBinding.d.ts.map +1 -1
  170. package/lib/Cloudflare/Workers/WorkerBinding.js +3 -0
  171. package/lib/Cloudflare/Workers/WorkerBinding.js.map +1 -1
  172. package/lib/Cloudflare/Workers/WorkerBridge.d.ts.map +1 -1
  173. package/lib/Cloudflare/Workers/WorkerBridge.js +5 -2
  174. package/lib/Cloudflare/Workers/WorkerBridge.js.map +1 -1
  175. package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
  176. package/lib/Cloudflare/Workers/WorkerBundle.js +4 -1
  177. package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
  178. package/lib/Cloudflare/Workers/WorkerRuntimeContext.d.ts.map +1 -1
  179. package/lib/Cloudflare/Workers/WorkerRuntimeContext.js +9 -10
  180. package/lib/Cloudflare/Workers/WorkerRuntimeContext.js.map +1 -1
  181. package/lib/Cloudflare/Workers/Workflow.d.ts +5 -3
  182. package/lib/Cloudflare/Workers/Workflow.d.ts.map +1 -1
  183. package/lib/Cloudflare/Workers/Workflow.js +19 -1
  184. package/lib/Cloudflare/Workers/Workflow.js.map +1 -1
  185. package/lib/Cloudflare/Workers/index.d.ts +2 -0
  186. package/lib/Cloudflare/Workers/index.d.ts.map +1 -1
  187. package/lib/Cloudflare/Workers/index.js +2 -0
  188. package/lib/Cloudflare/Workers/index.js.map +1 -1
  189. package/lib/Cloudflare/index.d.ts +1 -0
  190. package/lib/Cloudflare/index.d.ts.map +1 -1
  191. package/lib/Cloudflare/index.js +1 -0
  192. package/lib/Cloudflare/index.js.map +1 -1
  193. package/lib/Dependencies.d.ts +10 -0
  194. package/lib/Dependencies.d.ts.map +1 -0
  195. package/lib/Dependencies.js +1 -0
  196. package/lib/Dependencies.js.map +1 -0
  197. package/lib/Deploy.d.ts +2 -1
  198. package/lib/Deploy.d.ts.map +1 -1
  199. package/lib/Deploy.js +2 -2
  200. package/lib/Deploy.js.map +1 -1
  201. package/lib/Diff.d.ts +11 -0
  202. package/lib/Diff.d.ts.map +1 -1
  203. package/lib/Diff.js +11 -0
  204. package/lib/Diff.js.map +1 -1
  205. package/lib/Input.d.ts +2 -1
  206. package/lib/Input.d.ts.map +1 -1
  207. package/lib/KeyPair.d.ts +77 -0
  208. package/lib/KeyPair.d.ts.map +1 -0
  209. package/lib/KeyPair.js +102 -0
  210. package/lib/KeyPair.js.map +1 -0
  211. package/lib/Local/RpcProvider.d.ts +3 -1
  212. package/lib/Local/RpcProvider.d.ts.map +1 -1
  213. package/lib/Local/RpcProvider.js +28 -2
  214. package/lib/Local/RpcProvider.js.map +1 -1
  215. package/lib/Local/RpcServerEnvironment.js +1 -1
  216. package/lib/Local/RpcServerEnvironment.js.map +1 -1
  217. package/lib/Neon/Project.d.ts.map +1 -1
  218. package/lib/Neon/Project.js +14 -3
  219. package/lib/Neon/Project.js.map +1 -1
  220. package/lib/Output.d.ts.map +1 -1
  221. package/lib/Output.js +9 -2
  222. package/lib/Output.js.map +1 -1
  223. package/lib/Phase.d.ts +2 -1
  224. package/lib/Phase.d.ts.map +1 -1
  225. package/lib/Phase.js +6 -1
  226. package/lib/Phase.js.map +1 -1
  227. package/lib/Plan.d.ts.map +1 -1
  228. package/lib/Plan.js +14 -3
  229. package/lib/Plan.js.map +1 -1
  230. package/lib/Platform.d.ts +8 -6
  231. package/lib/Platform.d.ts.map +1 -1
  232. package/lib/Platform.js +33 -3
  233. package/lib/Platform.js.map +1 -1
  234. package/lib/Random.d.ts.map +1 -1
  235. package/lib/Random.js +9 -14
  236. package/lib/Random.js.map +1 -1
  237. package/lib/RuntimeContext.d.ts +21 -1
  238. package/lib/RuntimeContext.d.ts.map +1 -1
  239. package/lib/RuntimeContext.js +12 -0
  240. package/lib/RuntimeContext.js.map +1 -1
  241. package/lib/Stack.d.ts +3 -3
  242. package/lib/Stack.d.ts.map +1 -1
  243. package/lib/Stack.js.map +1 -1
  244. package/lib/State/HttpStateApi.d.ts +2 -2
  245. package/lib/State/StateEncoding.d.ts +8 -0
  246. package/lib/State/StateEncoding.d.ts.map +1 -1
  247. package/lib/State/StateEncoding.js +55 -5
  248. package/lib/State/StateEncoding.js.map +1 -1
  249. package/lib/Test/Bun.d.ts.map +1 -1
  250. package/lib/Test/Bun.js +0 -2
  251. package/lib/Test/Bun.js.map +1 -1
  252. package/lib/Test/Vitest.d.ts.map +1 -1
  253. package/lib/Test/Vitest.js +0 -2
  254. package/lib/Test/Vitest.js.map +1 -1
  255. package/lib/Util/Duration.d.ts +14 -0
  256. package/lib/Util/Duration.d.ts.map +1 -0
  257. package/lib/Util/Duration.js +18 -0
  258. package/lib/Util/Duration.js.map +1 -0
  259. package/lib/Util/index.d.ts +0 -6
  260. package/lib/Util/index.d.ts.map +1 -1
  261. package/lib/Util/index.js +0 -6
  262. package/lib/Util/index.js.map +1 -1
  263. package/lib/Util/types.d.ts +3 -1
  264. package/lib/Util/types.d.ts.map +1 -1
  265. package/lib/Util/types.js +5 -1
  266. package/lib/Util/types.js.map +1 -1
  267. package/lib/index.d.ts +2 -3
  268. package/lib/index.d.ts.map +1 -1
  269. package/lib/index.js +1 -3
  270. package/lib/index.js.map +1 -1
  271. package/lib/tsconfig.test.tsbuildinfo +1 -1
  272. package/package.json +20 -19
  273. package/src/AWS/Lambda/Function.ts +87 -34
  274. package/src/AWS/Providers.ts +3 -0
  275. package/src/Apply.ts +18 -1
  276. package/src/Auth/AuthProvider.ts +25 -5
  277. package/src/Auth/Credentials.ts +8 -7
  278. package/src/Cli/commands/_shared.ts +47 -4
  279. package/src/Cli/commands/dev.ts +13 -1
  280. package/src/Cli/commands/login.ts +20 -4
  281. package/src/Cli/commands/profile.ts +24 -34
  282. package/src/Cli/main.ts +0 -3
  283. package/src/Cloudflare/AiGateway/AiGateway.ts +2 -6
  284. package/src/Cloudflare/BrowserRendering/BrowserRendering.ts +132 -0
  285. package/src/Cloudflare/BrowserRendering/BrowserRenderingBinding.ts +137 -0
  286. package/src/Cloudflare/BrowserRendering/index.ts +11 -0
  287. package/src/Cloudflare/Container/Container.ts +3 -3
  288. package/src/Cloudflare/Container/StartContainer.ts +1 -2
  289. package/src/Cloudflare/D1/D1Database.ts +4 -1
  290. package/src/Cloudflare/D1/D1DatabaseBinding.ts +1 -1
  291. package/src/Cloudflare/Fetcher.ts +0 -2
  292. package/src/Cloudflare/Hyperdrive/Hyperdrive.ts +5 -0
  293. package/src/Cloudflare/Hyperdrive/HyperdriveBinding.ts +41 -43
  294. package/src/Cloudflare/KV/KVNamespace.ts +4 -0
  295. package/src/Cloudflare/Local.ts +1 -1
  296. package/src/Cloudflare/Providers.ts +25 -16
  297. package/src/Cloudflare/Queue/Queue.ts +3 -0
  298. package/src/Cloudflare/Queue/QueueConsumer.ts +23 -8
  299. package/src/Cloudflare/Queue/QueueEventSource.ts +33 -5
  300. package/src/Cloudflare/R2/R2Bucket.ts +26 -0
  301. package/src/Cloudflare/SecretsStore/Secret.ts +14 -41
  302. package/src/Cloudflare/SecretsStore/SecretBinding.ts +11 -11
  303. package/src/Cloudflare/StateStore/Api.ts +15 -15
  304. package/src/Cloudflare/StateStore/State.ts +68 -6
  305. package/src/Cloudflare/StateStore/Store.ts +5 -2
  306. package/src/Cloudflare/VpcService/VpcService.ts +2 -2
  307. package/src/Cloudflare/Website/StaticSite.ts +8 -10
  308. package/src/Cloudflare/Website/Vite.ts +4 -7
  309. package/src/Cloudflare/Workers/Assets.ts +1 -1
  310. package/src/Cloudflare/Workers/DurableObjectBridge.ts +7 -4
  311. package/src/Cloudflare/Workers/DurableObjectNamespace.ts +380 -121
  312. package/src/Cloudflare/Workers/HttpServer.ts +31 -25
  313. package/src/Cloudflare/Workers/InferEnv.ts +15 -8
  314. package/src/Cloudflare/Workers/LocalWorkerProvider.ts +139 -78
  315. package/src/Cloudflare/Workers/Rpc.ts +50 -0
  316. package/src/Cloudflare/Workers/RpcDurableObjectNamespace.ts +502 -0
  317. package/src/Cloudflare/Workers/RpcWorker.ts +562 -0
  318. package/src/Cloudflare/Workers/Vite.ts +2 -0
  319. package/src/Cloudflare/Workers/Worker.ts +274 -93
  320. package/src/Cloudflare/Workers/WorkerAsyncBindings.ts +158 -103
  321. package/src/Cloudflare/Workers/WorkerBinding.ts +10 -0
  322. package/src/Cloudflare/Workers/WorkerBridge.ts +7 -4
  323. package/src/Cloudflare/Workers/WorkerBundle.ts +4 -1
  324. package/src/Cloudflare/Workers/WorkerRuntimeContext.ts +8 -15
  325. package/src/Cloudflare/Workers/Workflow.ts +22 -3
  326. package/src/Cloudflare/Workers/index.ts +2 -0
  327. package/src/Cloudflare/index.ts +1 -0
  328. package/src/Dependencies.ts +10 -0
  329. package/src/Deploy.ts +3 -1
  330. package/src/Diff.ts +13 -0
  331. package/src/Input.ts +2 -0
  332. package/src/KeyPair.ts +146 -0
  333. package/src/Local/RpcProvider.ts +45 -1
  334. package/src/Local/RpcServerEnvironment.ts +1 -1
  335. package/src/Neon/Project.ts +16 -3
  336. package/src/Output.ts +8 -2
  337. package/src/Phase.ts +8 -0
  338. package/src/Plan.ts +16 -3
  339. package/src/Platform.ts +74 -27
  340. package/src/Random.ts +22 -27
  341. package/src/RuntimeContext.ts +23 -1
  342. package/src/Stack.ts +3 -3
  343. package/src/State/StateEncoding.ts +58 -7
  344. package/src/Test/Bun.ts +0 -3
  345. package/src/Test/Vitest.ts +0 -3
  346. package/src/Util/Duration.ts +21 -0
  347. package/src/Util/index.ts +0 -6
  348. package/src/Util/types.ts +9 -2
  349. package/src/index.ts +2 -3
  350. package/lib/Secret.d.ts +0 -50
  351. package/lib/Secret.d.ts.map +0 -1
  352. package/lib/Secret.js +0 -23
  353. package/lib/Secret.js.map +0 -1
  354. package/lib/Trait.d.ts +0 -43
  355. package/lib/Trait.d.ts.map +0 -1
  356. package/lib/Trait.js +0 -17
  357. package/lib/Trait.js.map +0 -1
  358. package/lib/Util/LocalhostDns.d.ts +0 -23
  359. package/lib/Util/LocalhostDns.d.ts.map +0 -1
  360. package/lib/Util/LocalhostDns.js +0 -46
  361. package/lib/Util/LocalhostDns.js.map +0 -1
  362. package/lib/Util/assert-never.d.ts +0 -12
  363. package/lib/Util/assert-never.d.ts.map +0 -1
  364. package/lib/Util/assert-never.js +0 -11
  365. package/lib/Util/assert-never.js.map +0 -1
  366. package/lib/Util/class.d.ts +0 -3
  367. package/lib/Util/class.d.ts.map +0 -1
  368. package/lib/Util/class.js +0 -1
  369. package/lib/Util/class.js.map +0 -1
  370. package/lib/Util/ignore.d.ts +0 -40
  371. package/lib/Util/ignore.d.ts.map +0 -1
  372. package/lib/Util/ignore.js +0 -591
  373. package/lib/Util/ignore.js.map +0 -1
  374. package/lib/Util/instance.d.ts +0 -4
  375. package/lib/Util/instance.d.ts.map +0 -1
  376. package/lib/Util/instance.js +0 -1
  377. package/lib/Util/instance.js.map +0 -1
  378. package/lib/Util/pointer.d.ts +0 -5
  379. package/lib/Util/pointer.d.ts.map +0 -1
  380. package/lib/Util/pointer.js +0 -1
  381. package/lib/Util/pointer.js.map +0 -1
  382. package/lib/Util/schema-to-type.d.ts +0 -42
  383. package/lib/Util/schema-to-type.d.ts.map +0 -1
  384. package/lib/Util/schema-to-type.js +0 -364
  385. package/lib/Util/schema-to-type.js.map +0 -1
  386. package/lib/Util/todo.d.ts +0 -3
  387. package/lib/Util/todo.d.ts.map +0 -1
  388. package/lib/Util/todo.js +0 -3
  389. package/lib/Util/todo.js.map +0 -1
  390. package/lib/Variable.d.ts +0 -29
  391. package/lib/Variable.d.ts.map +0 -1
  392. package/lib/Variable.js +0 -9
  393. package/lib/Variable.js.map +0 -1
  394. package/src/Secret.ts +0 -87
  395. package/src/Trait.ts +0 -105
  396. package/src/Util/LocalhostDns.ts +0 -52
  397. package/src/Util/assert-never.ts +0 -18
  398. package/src/Util/class.ts +0 -7
  399. package/src/Util/ignore.ts +0 -815
  400. package/src/Util/instance.ts +0 -9
  401. package/src/Util/pointer.ts +0 -5
  402. package/src/Util/schema-to-type.ts +0 -456
  403. package/src/Util/todo.ts +0 -4
  404. package/src/Variable.ts +0 -44
@@ -1,6 +1,7 @@
1
1
  import type * as cf from "@cloudflare/workers-types";
2
2
  import * as workers from "@distilled.cloud/cloudflare/workers";
3
3
  import * as zones from "@distilled.cloud/cloudflare/zones";
4
+ import * as Config from "effect/Config";
4
5
  import * as Context from "effect/Context";
5
6
  import * as Data from "effect/Data";
6
7
  import * as Effect from "effect/Effect";
@@ -8,6 +9,7 @@ import * as Layer from "effect/Layer";
8
9
  import * as Path from "effect/Path";
9
10
  import * as Redacted from "effect/Redacted";
10
11
  import * as Schedule from "effect/Schedule";
12
+ import * as crypto from "node:crypto";
11
13
  import { Unowned } from "../../AdoptPolicy.ts";
12
14
  import { AlchemyContext } from "../../AlchemyContext.ts";
13
15
  import * as Artifacts from "../../Artifacts.ts";
@@ -172,7 +174,9 @@ type NormalizedBindings<
172
174
  any,
173
175
  any
174
176
  >
175
- ? T
177
+ ? T extends Redacted.Redacted<infer T> | Config.Config<infer T>
178
+ ? T
179
+ : T
176
180
  : Extract<Bindings[B], WorkerBindingResource>;
177
181
  } & (undefined extends AssetsConfig ? {} : { ASSETS: Assets });
178
182
 
@@ -180,7 +184,6 @@ export type WorkerAssetsConfig = string | AssetsProps | AssetsWithHash;
180
184
 
181
185
  export interface WorkerProps<
182
186
  Bindings extends WorkerBindingProps = any,
183
- Env extends WorkerEnv = WorkerEnv,
184
187
  Assets extends WorkerAssetsConfig | undefined =
185
188
  | WorkerAssetsConfig
186
189
  | undefined,
@@ -223,16 +226,46 @@ export interface WorkerProps<
223
226
  */
224
227
  observability?: WorkerObservability;
225
228
  tags?: string[];
226
- main: string;
229
+ /**
230
+ * Path to the Worker's entry module. Bundled with rolldown before
231
+ * upload. Mutually exclusive with {@link script} — provide exactly one.
232
+ */
233
+ main?: string;
234
+ /**
235
+ * Raw module source for the Worker. When provided, bundling is bypassed
236
+ * entirely and this string is uploaded as a single ESM module
237
+ * (`main.js`). Useful for tiny inline workers (tests, fixtures,
238
+ * one-offs) and any case where you've already produced the final
239
+ * bundle elsewhere. Mutually exclusive with {@link main}.
240
+ */
241
+ script?: string;
227
242
  compatibility?: {
228
243
  date?: string;
229
244
  flags?: ("nodejs_compat" | "nodejs_als" | (string & {}))[];
230
245
  };
231
246
  limits?: WorkerLimits;
232
247
  placement?: WorkerPlacement;
233
- env?: Env;
234
248
  exports?: string[];
235
- bindings?: Bindings;
249
+ /**
250
+ * Environment variables and native Cloudflare Bindings to bind to
251
+ * the Worker. Accepts:
252
+ *
253
+ * - Resource references (R2 bucket, KV namespace, D1 database,
254
+ * another Worker, Durable Object, etc.) — emitted as the
255
+ * corresponding native binding.
256
+ * - `effect/Config` values (`Config.redacted`, `Config.string`,
257
+ * `Config.number`, …) — resolved at deploy time and bound as
258
+ * `secret_text` on Cloudflare regardless of the `Config`
259
+ * constructor used. See
260
+ * {@link https://v2.alchemy.run/concepts/secrets | Concepts › Secrets and Variables}.
261
+ * - Literal values — routed by shape: `Redacted<string>` →
262
+ * `secret_text`, `string` → `plain_text`, anything else → `json`.
263
+ *
264
+ * In Effect-native Workers you can alternatively `yield*` a
265
+ * `Config` in the Init phase to register the binding implicitly;
266
+ * `env` is the only option for async (non-Effect) Workers.
267
+ */
268
+ env?: Bindings;
236
269
  /**
237
270
  * Cron expressions that trigger the Worker's scheduled handler.
238
271
  *
@@ -250,6 +283,29 @@ export interface WorkerProps<
250
283
  * options used to build this Worker. See {@link Bundle.BundleExtraOptions}.
251
284
  */
252
285
  build?: Bundle.BundleExtraOptions;
286
+ /**
287
+ * Options for the local dev server that runs this Worker under `alchemy dev`.
288
+ * Each Worker is served on its own port.
289
+ */
290
+ dev?: {
291
+ /**
292
+ * Host the local dev server binds to.
293
+ * @default "localhost"
294
+ */
295
+ host?: string;
296
+ /**
297
+ * Port the local dev server listens on. If the port is unavailable, the
298
+ * next free port is used unless {@link strictPort} is `true`.
299
+ * @default 1337
300
+ */
301
+ port?: number;
302
+ /**
303
+ * When `true`, fail instead of falling back to another port if {@link port}
304
+ * is already in use.
305
+ * @default false
306
+ */
307
+ strictPort?: boolean;
308
+ };
253
309
  }
254
310
 
255
311
  export type Worker<Bindings extends WorkerBindings = any> = Resource<
@@ -263,7 +319,7 @@ export type Worker<Bindings extends WorkerBindings = any> = Resource<
263
319
  tags: string[] | undefined;
264
320
  durableObjectNamespaces: Record<string, string>;
265
321
  accountId: string;
266
- domains: { hostname: string; id: string; zoneId: string }[];
322
+ domains: string[];
267
323
  crons: string[];
268
324
  hash?: {
269
325
  assets: string | undefined;
@@ -319,9 +375,10 @@ export type Worker<Bindings extends WorkerBindings = any> = Resource<
319
375
  * as-is. Your handler is a plain `async fetch` — no Effect runtime
320
376
  * is included in the bundle.
321
377
  *
322
- * Use the `bindings` prop to declare which resources are available
323
- * at runtime, and `Cloudflare.InferEnv` to extract a fully typed
324
- * `env` object from those bindings.
378
+ * Use the `env` prop to declare which resources, `Config` values,
379
+ * and literal env vars are available at runtime, and
380
+ * `Cloudflare.InferEnv` to extract a fully typed `env` object from
381
+ * them.
325
382
  *
326
383
  * See the {@link https://alchemy.run/guides/async-worker | Async Workers Guide}
327
384
  * for a comprehensive walkthrough of all binding types (R2, D1,
@@ -337,7 +394,7 @@ export type Worker<Bindings extends WorkerBindings = any> = Resource<
337
394
  *
338
395
  * export const Worker = Cloudflare.Worker("Worker", {
339
396
  * main: "./src/worker.ts",
340
- * bindings: { db, bucket },
397
+ * env: { db, bucket },
341
398
  * });
342
399
  * ```
343
400
  *
@@ -594,7 +651,7 @@ export type Worker<Bindings extends WorkerBindings = any> = Resource<
594
651
  * const sandbox = yield* Cloudflare.Container.bind(Sandbox);
595
652
  *
596
653
  * return Effect.gen(function* () {
597
- * const container = yield* Cloudflare.start(sandbox);
654
+ * const container = yield* Cloudflare.start(sandbox, { enableInternet: true });
598
655
  *
599
656
  * return {
600
657
  * exec: (cmd: string) => container.exec(cmd),
@@ -645,31 +702,20 @@ export const Worker: Platform<
645
702
  > & {
646
703
  <
647
704
  const Bindings extends WorkerBindingProps = {},
648
- const Env extends WorkerEnv = {},
649
705
  const Assets extends WorkerAssetsConfig | undefined = undefined,
650
706
  Req = never,
651
707
  >(
652
708
  id: string,
653
709
  props:
654
- | InputProps<WorkerProps<Bindings, Env, Assets>>
655
- | Effect.Effect<
656
- InputProps<WorkerProps<Bindings, Env, Assets>>,
657
- never,
658
- Req
659
- >,
710
+ | InputProps<WorkerProps<Bindings, Assets>>
711
+ | Effect.Effect<InputProps<WorkerProps<Bindings, Assets>>, never, Req>,
660
712
  ): Effect.Effect<
661
- Worker<
662
- {
663
- [binding in keyof NormalizedBindings<
664
- Bindings,
665
- Assets
666
- >]: NormalizedBindings<Bindings, Assets>[binding];
667
- } & {
668
- [K in keyof Env]: Env[K] extends Redacted.Redacted<infer T>
669
- ? T
670
- : Env[K];
671
- }
672
- >,
713
+ Worker<{
714
+ [binding in keyof NormalizedBindings<
715
+ Bindings,
716
+ Assets
717
+ >]: NormalizedBindings<Bindings, Assets>[binding];
718
+ }>,
673
719
  never,
674
720
  Req | Providers
675
721
  >;
@@ -870,11 +916,7 @@ export const LiveWorkerProvider = () =>
870
916
  );
871
917
  });
872
918
 
873
- const reconcileDomains = (
874
- scriptName: string,
875
- desired: string[],
876
- _previous: Worker["Attributes"]["domains"],
877
- ) =>
919
+ const reconcileDomains = (scriptName: string, desired: string[]) =>
878
920
  Effect.gen(function* () {
879
921
  // Always query the live state of domains attached to *this*
880
922
  // Worker rather than trusting `_previous` from local state.
@@ -1024,11 +1066,15 @@ export const LiveWorkerProvider = () =>
1024
1066
 
1025
1067
  const getExpectedDurableObjectClassNames = (
1026
1068
  bindings: readonly WorkerBinding[] | undefined,
1069
+ workerName: string,
1027
1070
  ) =>
1028
1071
  Array.from(
1029
1072
  new Set(
1030
1073
  bindings?.flatMap((binding) =>
1031
- binding.type === "durable_object_namespace" && binding.className
1074
+ binding.type === "durable_object_namespace" &&
1075
+ binding.className &&
1076
+ (binding.scriptName === undefined ||
1077
+ binding.scriptName === workerName)
1032
1078
  ? [binding.className]
1033
1079
  : [],
1034
1080
  ) ?? [],
@@ -1099,7 +1145,7 @@ export const LiveWorkerProvider = () =>
1099
1145
  bundler
1100
1146
  .build({
1101
1147
  id,
1102
- main: props.main,
1148
+ main: props.main!,
1103
1149
  compatibility: getCompatibility(props),
1104
1150
  entry: props.isExternal
1105
1151
  ? {
@@ -1114,11 +1160,34 @@ export const LiveWorkerProvider = () =>
1114
1160
  })
1115
1161
  .pipe(Artifacts.cached("build"));
1116
1162
 
1163
+ const hashScript = (script: string) =>
1164
+ Effect.sync(() =>
1165
+ crypto.createHash("sha256").update(script).digest("hex"),
1166
+ );
1167
+
1117
1168
  const viteBuild = Effect.fnUntraced(function* (props: WorkerProps) {
1118
1169
  const compatibility = getCompatibility(props);
1119
1170
  const { assetsDirectory, serverBundle } = yield* Vite.viteBuild(
1120
1171
  props.vite?.rootDir,
1121
- props.env ?? {},
1172
+ Object.fromEntries(
1173
+ (yield* Effect.all(
1174
+ Object.entries(props.env ?? {}).map(
1175
+ Effect.fnUntraced(function* ([key, value]) {
1176
+ return [
1177
+ key,
1178
+ typeof value === "string"
1179
+ ? value
1180
+ : Redacted.isRedacted(value) &&
1181
+ typeof Redacted.value(value) === "string"
1182
+ ? Redacted.value(value)
1183
+ : Config.isConfig(value) || Effect.isEffect(value)
1184
+ ? yield* value
1185
+ : undefined,
1186
+ ];
1187
+ }),
1188
+ ),
1189
+ )).filter(([_, value]) => value !== undefined),
1190
+ ),
1122
1191
  {
1123
1192
  compatibilityDate: compatibility.date,
1124
1193
  compatibilityFlags: compatibility.flags,
@@ -1156,6 +1225,24 @@ export const LiveWorkerProvider = () =>
1156
1225
  opts: { skipAssetsRead?: boolean } = {},
1157
1226
  ) =>
1158
1227
  Effect.gen(function* () {
1228
+ if (props.script !== undefined) {
1229
+ const [assets, bundleHash] = yield* Effect.all(
1230
+ [
1231
+ opts.skipAssetsRead
1232
+ ? Effect.succeed(undefined)
1233
+ : prepareAssets(props.assets),
1234
+ hashScript(props.script),
1235
+ ],
1236
+ { concurrency: "unbounded" },
1237
+ );
1238
+ return {
1239
+ assets,
1240
+ bundle: {
1241
+ files: [{ path: "main.js", content: props.script }],
1242
+ hash: bundleHash,
1243
+ },
1244
+ };
1245
+ }
1159
1246
  if (props.vite) {
1160
1247
  const [{ assets, bundle }, input] = yield* Effect.all(
1161
1248
  [
@@ -1258,7 +1345,7 @@ export const LiveWorkerProvider = () =>
1258
1345
  } satisfies Worker["Attributes"]["hash"];
1259
1346
  const metadataBindings = bindings.flatMap((b) => b.data.bindings ?? []);
1260
1347
  const expectedDurableObjectClassNames =
1261
- getExpectedDurableObjectClassNames(metadataBindings);
1348
+ getExpectedDurableObjectClassNames(metadataBindings, name);
1262
1349
  let metadataAssets:
1263
1350
  | workers.PutScriptRequest["metadata"]["assets"]
1264
1351
  | undefined;
@@ -1312,6 +1399,11 @@ export const LiveWorkerProvider = () =>
1312
1399
  });
1313
1400
  }
1314
1401
  metadataBindings.push(
1402
+ {
1403
+ type: "plain_text",
1404
+ name: "ALCHEMY_PHASE",
1405
+ text: "runtime",
1406
+ },
1315
1407
  {
1316
1408
  type: "plain_text",
1317
1409
  name: "ALCHEMY_STACK_NAME",
@@ -1327,11 +1419,16 @@ export const LiveWorkerProvider = () =>
1327
1419
  if (news.env) {
1328
1420
  for (const [key, value] of Object.entries(news.env)) {
1329
1421
  if (value === undefined) continue;
1422
+ if (metadataBindings.some((b) => b.name === key)) continue;
1330
1423
  if (Redacted.isRedacted(value)) {
1424
+ const unredacted = Redacted.value(value);
1331
1425
  metadataBindings.push({
1332
1426
  type: "secret_text",
1333
1427
  name: key,
1334
- text: Redacted.value(value),
1428
+ text:
1429
+ typeof unredacted === "string"
1430
+ ? unredacted
1431
+ : JSON.stringify(unredacted),
1335
1432
  });
1336
1433
  } else if (typeof value === "string") {
1337
1434
  metadataBindings.push({
@@ -1403,16 +1500,19 @@ export const LiveWorkerProvider = () =>
1403
1500
  }
1404
1501
 
1405
1502
  // Backward compatibility for old workers that have DO bindings but no
1406
- // alchemy:do tags yet.
1503
+ // alchemy:do tags yet. Cross-script bindings (`scriptName` set to
1504
+ // anything other than this worker) are NEVER candidates for
1505
+ // delete-class migrations — the class lives on the foreign script
1506
+ // and we don't own its lifecycle.
1407
1507
  if (Object.keys(oldDoClassNameByLogicalId).length === 0) {
1408
1508
  for (const oldBinding of oldBindings) {
1509
+ const ownedLocally =
1510
+ !("scriptName" in oldBinding) || oldBinding.scriptName === name;
1409
1511
  if (
1410
1512
  oldBinding.type === "durable_object_namespace" &&
1411
1513
  "className" in oldBinding &&
1412
1514
  oldBinding.className &&
1413
- (!("scriptName" in oldBinding) ||
1414
- !oldBinding.scriptName ||
1415
- oldBinding.scriptName === name) &&
1515
+ ownedLocally &&
1416
1516
  !currentDoBindings.some(
1417
1517
  (binding) => binding.bindingName === oldBinding.name,
1418
1518
  )
@@ -1574,27 +1674,36 @@ export const LiveWorkerProvider = () =>
1574
1674
  // Cloudflare currently has it (disabled by default, or whatever
1575
1675
  // a previous failed/external action left it as).
1576
1676
  const desiredSubdomainEnabled = news.url !== false;
1577
- const observedSubdomainEnabled = yield* getScriptSubdomain({
1677
+ const observedSubdomain = yield* getScriptSubdomain({
1578
1678
  accountId,
1579
1679
  scriptName: name,
1580
1680
  }).pipe(
1581
- Effect.map((s) => s.enabled === true),
1582
- Effect.catch(() => Effect.succeed(false)),
1681
+ Effect.orElseSucceed<workers.GetScriptSubdomainResponse>(() => ({
1682
+ enabled: false,
1683
+ previewsEnabled: false,
1684
+ })),
1583
1685
  );
1584
- if (desiredSubdomainEnabled !== observedSubdomainEnabled) {
1686
+ if (
1687
+ desiredSubdomainEnabled !== observedSubdomain.enabled ||
1688
+ desiredSubdomainEnabled !== observedSubdomain.previewsEnabled
1689
+ ) {
1585
1690
  yield* session.note(
1586
1691
  `${desiredSubdomainEnabled ? "Enabling" : "Disabling"} workers.dev subdomain...`,
1587
1692
  );
1588
1693
  // Cloudflare's script registry is eventually consistent — for the
1589
1694
  // first few hundred ms after `putScript` returns, POST /subdomain
1590
1695
  // can still get back `WorkerNotFound` (a generic "unknown error"
1591
- // body). Bigger uploads race harder. Retry the subdomain toggle on
1592
- // that specific tag with a short exponential backoff; same pattern
1593
- // we use elsewhere in this provider for DO-namespace propagation.
1696
+ // body), or a bare 500 surfaced as `InternalServerError` /
1697
+ // `UnknownCloudflareError` (code 10013). Bigger uploads race harder.
1698
+ // Retry the subdomain toggle on those transient tags with a short
1699
+ // exponential backoff; same pattern we use elsewhere in this
1700
+ // provider for DO-namespace propagation and for `putScript` itself.
1594
1701
  yield* setWorkerSubdomain(name, desiredSubdomainEnabled).pipe(
1595
1702
  Effect.retry({
1596
1703
  while: (error: { _tag?: string }) =>
1597
- error?._tag === "WorkerNotFound",
1704
+ error?._tag === "WorkerNotFound" ||
1705
+ error?._tag === "InternalServerError" ||
1706
+ error?._tag === "UnknownCloudflareError",
1598
1707
  schedule: Schedule.exponential(200).pipe(
1599
1708
  Schedule.both(Schedule.recurs(15)),
1600
1709
  ),
@@ -1608,11 +1717,15 @@ export const LiveWorkerProvider = () =>
1608
1717
  `Reconciling custom domains (${desiredDomains.length}) ...`,
1609
1718
  );
1610
1719
  }
1611
- const domains = yield* reconcileDomains(
1612
- name,
1613
- desiredDomains,
1614
- previousDomains,
1615
- );
1720
+ const reconciled = yield* reconcileDomains(name, desiredDomains);
1721
+ const workersDevUrl =
1722
+ news.url !== false
1723
+ ? `https://${name}.${yield* getAccountSubdomain(accountId)}.workers.dev`
1724
+ : undefined;
1725
+ const domains = [
1726
+ ...reconciled.map((d) => `https://${d.hostname}`),
1727
+ ...(workersDevUrl ? [workersDevUrl] : []),
1728
+ ];
1616
1729
  const crons = yield* reconcileCrons(
1617
1730
  name,
1618
1731
  normalizeCrons([...getCronBindings(bindings), ...(news.crons ?? [])]),
@@ -1623,10 +1736,7 @@ export const LiveWorkerProvider = () =>
1623
1736
  workerId: worker.id ?? name,
1624
1737
  workerName: name,
1625
1738
  logpush: worker.logpush ?? undefined,
1626
- url:
1627
- news.url !== false
1628
- ? `https://${name}.${yield* getAccountSubdomain(accountId)}.workers.dev`
1629
- : undefined,
1739
+ url: domains[0],
1630
1740
  tags: settings.tags ?? metadata.tags,
1631
1741
  durableObjectNamespaces,
1632
1742
  accountId,
@@ -1641,6 +1751,25 @@ export const LiveWorkerProvider = () =>
1641
1751
  props: WorkerProps,
1642
1752
  output: Worker["Attributes"],
1643
1753
  ) {
1754
+ if (props.script !== undefined) {
1755
+ const scriptHash = yield* hashScript(props.script);
1756
+ if (scriptHash !== output.hash?.bundle) {
1757
+ return true;
1758
+ }
1759
+ if (!props.assets) {
1760
+ return false;
1761
+ }
1762
+ const assetsHash =
1763
+ typeof props.assets === "object" &&
1764
+ "path" in props.assets &&
1765
+ "hash" in props.assets
1766
+ ? (props.assets.hash as string)
1767
+ : undefined;
1768
+ if (assetsHash === undefined) {
1769
+ return true;
1770
+ }
1771
+ return assetsHash !== output.hash?.assets;
1772
+ }
1644
1773
  if (props.vite) {
1645
1774
  const input = yield* hashDirectory({
1646
1775
  cwd: props.vite.rootDir,
@@ -1708,9 +1837,11 @@ export const LiveWorkerProvider = () =>
1708
1837
  if (!output) {
1709
1838
  return;
1710
1839
  }
1711
- const newDomains = normalizeDomains(news.domain).sort();
1840
+ const newDomains = normalizeDomains(news.domain)
1841
+ .map((h) => `https://${h}`)
1842
+ .sort();
1712
1843
  const oldDomains = (output?.domains ?? [])
1713
- .map((d) => d.hostname)
1844
+ .filter((u) => !u.endsWith(".workers.dev"))
1714
1845
  .sort();
1715
1846
  const domainsChanged =
1716
1847
  newDomains.length !== oldDomains.length ||
@@ -1905,6 +2036,30 @@ export const LiveWorkerProvider = () =>
1905
2036
  service: workerName,
1906
2037
  }).pipe(Effect.map((r) => r.result ?? [])),
1907
2038
  ]);
2039
+ // Preserve the order the user provided in `olds.domain`. The
2040
+ // Cloudflare API returns domains in non-deterministic order,
2041
+ // which would cause downstream `worker.domains[0]` reads to flip
2042
+ // between deploys. Drift (domains we don't know about) is
2043
+ // appended after the user-ordered ones.
2044
+ const userOrder = normalizeDomains(olds?.domain);
2045
+ const orderedHostnames = [
2046
+ ...userOrder.flatMap(
2047
+ (h) =>
2048
+ domainsList.find((d) => d.hostname === h)?.hostname ?? [],
2049
+ ),
2050
+ ...domainsList.flatMap((d) =>
2051
+ d.hostname && !userOrder.includes(d.hostname)
2052
+ ? [d.hostname]
2053
+ : [],
2054
+ ),
2055
+ ];
2056
+ const workersDevUrl = subdomain.enabled
2057
+ ? `https://${workerName}.${yield* getAccountSubdomain(accountId)}.workers.dev`
2058
+ : undefined;
2059
+ const domains = [
2060
+ ...orderedHostnames.map((h) => `https://${h}`),
2061
+ ...(workersDevUrl ? [workersDevUrl] : []),
2062
+ ];
1908
2063
  const crons = yield* getWorkerCrons(workerName);
1909
2064
  yield* Effect.logInfo(
1910
2065
  `Cloudflare Worker read: found ${workerName}`,
@@ -1914,18 +2069,12 @@ export const LiveWorkerProvider = () =>
1914
2069
  workerId: workerName,
1915
2070
  workerName,
1916
2071
  logpush: settings.logpush ?? undefined,
1917
- url: subdomain.enabled
1918
- ? `https://${workerName}.${yield* getAccountSubdomain(accountId)}.workers.dev`
1919
- : undefined,
2072
+ url: domains[0],
1920
2073
  tags: settings.tags ?? undefined,
1921
2074
  durableObjectNamespaces: getDurableObjectNamespaces(
1922
2075
  settings.bindings,
1923
2076
  ),
1924
- domains: domainsList.flatMap((d) =>
1925
- d.id && d.hostname && d.zoneId
1926
- ? [{ id: d.id, hostname: d.hostname, zoneId: d.zoneId }]
1927
- : [],
1928
- ),
2077
+ domains,
1929
2078
  crons,
1930
2079
  } satisfies Worker["Attributes"];
1931
2080
 
@@ -2010,13 +2159,30 @@ export const LiveWorkerProvider = () =>
2010
2159
  yield* Effect.logInfo(
2011
2160
  `Cloudflare Worker delete: deleting ${output.workerName}`,
2012
2161
  );
2013
- if (output.domains?.length) {
2162
+ // Look up live domain IDs rather than trusting persisted state.
2163
+ // We no longer track `{ id, zoneId }` on the output; fetching
2164
+ // straight from Cloudflare handles both the normal case and
2165
+ // adopted workers whose domains we never recorded.
2166
+ const liveDomains = yield* listDomains({
2167
+ accountId: output.accountId,
2168
+ service: output.workerName,
2169
+ }).pipe(
2170
+ Effect.map((r) => r.result ?? []),
2171
+ Effect.catch(() => Effect.succeed([])),
2172
+ );
2173
+ if (liveDomains.length) {
2014
2174
  yield* Effect.all(
2015
- output.domains.map((d) =>
2016
- deleteDomain({
2017
- accountId: output.accountId,
2018
- domainId: d.id,
2019
- }).pipe(Effect.catchTag("DomainNotFound", () => Effect.void)),
2175
+ liveDomains.flatMap((d) =>
2176
+ d.id
2177
+ ? [
2178
+ deleteDomain({
2179
+ accountId: output.accountId,
2180
+ domainId: d.id,
2181
+ }).pipe(
2182
+ Effect.catchTag("DomainNotFound", () => Effect.void),
2183
+ ),
2184
+ ]
2185
+ : [],
2020
2186
  ),
2021
2187
  { concurrency: "unbounded" },
2022
2188
  );
@@ -2090,23 +2256,38 @@ function getDurableObjectBindings(
2090
2256
  bindings: ReadonlyArray<ResourceBinding>,
2091
2257
  workerName: string,
2092
2258
  ) {
2259
+ // Resource authors (and the `make`/`yield* Tag`/plan-vs-apply machinery)
2260
+ // can register the same DO binding multiple times under the same logical
2261
+ // id — `binding()` is a plain `worker.bind` and intentionally has no
2262
+ // dedup. Collapse duplicates here so each `(logicalId, bindingName,
2263
+ // className)` tuple appears at most once. We also exclude cross-script
2264
+ // references: a `scriptName` pointing to *another* worker means this
2265
+ // worker just references a foreign class — ship the binding to
2266
+ // Cloudflare, but don't drive class migrations for it.
2267
+ const seen = new Set<string>();
2093
2268
  return bindings.flatMap((binding) =>
2094
- (binding.data.bindings ?? []).flatMap((item: WorkerBinding) =>
2095
- item.type === "durable_object_namespace" &&
2096
- "className" in item &&
2097
- item.className &&
2098
- (!("scriptName" in item) ||
2099
- !item.scriptName ||
2100
- item.scriptName === workerName)
2101
- ? [
2102
- {
2103
- logicalId: binding.sid,
2104
- bindingName: item.name,
2105
- className: item.className,
2106
- },
2107
- ]
2108
- : [],
2109
- ),
2269
+ (binding.data.bindings ?? []).flatMap((item: WorkerBinding) => {
2270
+ if (
2271
+ item.type !== "durable_object_namespace" ||
2272
+ !("className" in item) ||
2273
+ !item.className
2274
+ ) {
2275
+ return [];
2276
+ }
2277
+ if (item.scriptName !== undefined && item.scriptName !== workerName) {
2278
+ return [];
2279
+ }
2280
+ const dedupKey = `${binding.sid}::${item.name}::${item.className}`;
2281
+ if (seen.has(dedupKey)) return [];
2282
+ seen.add(dedupKey);
2283
+ return [
2284
+ {
2285
+ logicalId: binding.sid,
2286
+ bindingName: item.name,
2287
+ className: item.className,
2288
+ },
2289
+ ];
2290
+ }),
2110
2291
  );
2111
2292
  }
2112
2293