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,4 +1,5 @@
1
1
  import * as queues from "@distilled.cloud/cloudflare/queues";
2
+ import * as Console from "effect/Console";
2
3
  import * as Effect from "effect/Effect";
3
4
  import * as Option from "effect/Option";
4
5
  import * as Schedule from "effect/Schedule";
@@ -118,11 +119,11 @@ type ObservedConsumer = {
118
119
 
119
120
  const toObserved = (c: {
120
121
  consumerId?: string | null;
121
- script?: string | null;
122
+ scriptName?: string | null;
122
123
  type?: "worker" | "http_pull" | null;
123
124
  }): ObservedConsumer | undefined =>
124
125
  c.consumerId && c.type === "worker"
125
- ? { consumerId: c.consumerId, script: c.script ?? undefined }
126
+ ? { consumerId: c.consumerId, script: c.scriptName ?? undefined }
126
127
  : undefined;
127
128
 
128
129
  export const QueueConsumerProvider = () =>
@@ -139,10 +140,7 @@ export const QueueConsumerProvider = () =>
139
140
  // first match in the paginated stream is the only one. Using
140
141
  // `.items` defeats single-page lookups that would otherwise
141
142
  // miss late-arriving consumers under eventual consistency.
142
- const findWorkerConsumer = (
143
- acct: string,
144
- queueId: string,
145
- ): Effect.Effect<ObservedConsumer | undefined, any, any> =>
143
+ const findWorkerConsumer = (acct: string, queueId: string) =>
146
144
  queues.listConsumers.items({ accountId: acct, queueId }).pipe(
147
145
  Stream.map(toObserved),
148
146
  Stream.filter((c): c is ObservedConsumer => c !== undefined),
@@ -367,6 +365,22 @@ export const QueueConsumerProvider = () =>
367
365
  }),
368
366
  );
369
367
 
368
+ yield* getConsumer({ accountId: acct, queueId, consumerId }).pipe(
369
+ Effect.tap(Console.log),
370
+ Effect.flatMap((fetched) =>
371
+ toObserved(fetched)?.script === news.scriptName
372
+ ? Effect.void
373
+ : Effect.fail("ScriptUnbound" as const),
374
+ ),
375
+ Effect.catchTag("ConsumerNotFound", () =>
376
+ Effect.fail("ScriptUnbound" as const),
377
+ ),
378
+ Effect.retry({
379
+ while: (e) => e === "ScriptUnbound",
380
+ schedule: queueHandlerReadinessSchedule,
381
+ }),
382
+ );
383
+
370
384
  return {
371
385
  consumerId,
372
386
  queueId,
@@ -418,8 +432,9 @@ export const QueueConsumerProvider = () =>
418
432
  consumerId: fetched.consumerId!,
419
433
  queueId: output.queueId,
420
434
  scriptName:
421
- ("script" in fetched && typeof fetched.script === "string"
422
- ? fetched.script
435
+ ("scriptName" in fetched &&
436
+ typeof fetched.scriptName === "string"
437
+ ? fetched.scriptName
423
438
  : output.scriptName) ?? output.scriptName,
424
439
  accountId: output.accountId,
425
440
  };
@@ -1,6 +1,7 @@
1
1
  import type * as cf from "@cloudflare/workers-types";
2
2
  import * as Cause from "effect/Cause";
3
3
  import * as Context from "effect/Context";
4
+ import * as Duration from "effect/Duration";
4
5
  import * as Effect from "effect/Effect";
5
6
  import * as Layer from "effect/Layer";
6
7
  import * as Stream from "effect/Stream";
@@ -8,6 +9,7 @@ import * as Binding from "../../Binding.ts";
8
9
  import type { ResourceLike } from "../../Resource.ts";
9
10
  import { RuntimeContext } from "../../RuntimeContext.ts";
10
11
  import type { FunctionContext } from "../../Serverless/Function.ts";
12
+ import * as DurationUtil from "../../Util/Duration.ts";
11
13
  import { isWorker, isWorkerEvent } from "../Workers/Worker.ts";
12
14
  import type { Queue } from "./Queue.ts";
13
15
  import { QueueConsumer } from "./QueueConsumer.ts";
@@ -25,14 +27,37 @@ export interface MessagesProps {
25
27
  maxConcurrency?: number;
26
28
  /** Maximum delivery attempts before dead-lettering. */
27
29
  maxRetries?: number;
28
- /** Wait time, in ms, before flushing a partial batch. */
29
- maxWaitTimeMs?: number;
30
- /** Backoff, in seconds, applied to a retry. */
31
- retryDelay?: number;
30
+ /**
31
+ * Wait time before flushing a partial batch. Rounded up to whole
32
+ * milliseconds when forwarded to Cloudflare.
33
+ */
34
+ maxWaitTime?: Duration.Input;
35
+ /**
36
+ * Backoff applied to a retry. Rounded up to whole seconds when
37
+ * forwarded to Cloudflare.
38
+ */
39
+ retryDelay?: Duration.Input;
32
40
  /** Optional dead-letter queue name. */
33
41
  deadLetterQueue?: string;
34
42
  }
35
43
 
44
+ /**
45
+ * Convert a {@link MessagesProps} (with `Duration.Input` time fields)
46
+ * into the numeric settings shape Cloudflare's `QueueConsumer` API
47
+ * expects. `maxWaitTime` is rounded up to whole milliseconds and
48
+ * `retryDelay` to whole seconds.
49
+ *
50
+ * Exposed for testing and for callers that want to mirror the
51
+ * conversion when wiring `QueueConsumer` directly.
52
+ */
53
+ export const toConsumerSettings = (props: MessagesProps) => ({
54
+ batchSize: props.batchSize,
55
+ maxConcurrency: props.maxConcurrency,
56
+ maxRetries: props.maxRetries,
57
+ maxWaitTimeMs: DurationUtil.toMillis(props.maxWaitTime),
58
+ retryDelay: DurationUtil.toSeconds(props.retryDelay),
59
+ });
60
+
36
61
  /**
37
62
  * A single queue message handed to the subscribe handler. Mirrors
38
63
  * Cloudflare's runtime `Message<Body>` shape so per-message
@@ -63,12 +88,15 @@ export type QueueMessage<Body = unknown> = cf.Message<Body>;
63
88
  * @example
64
89
  * ```typescript
65
90
  * import * as Cloudflare from "alchemy/Cloudflare";
91
+ * import * as Duration from "effect/Duration";
66
92
  * import * as Effect from "effect/Effect";
67
93
  * import * as Stream from "effect/Stream";
68
94
  *
69
95
  * yield* Cloudflare.messages<MyEvent>(queueResource, {
70
96
  * batchSize: 25,
71
97
  * maxRetries: 3,
98
+ * maxWaitTime: "5 seconds",
99
+ * retryDelay: Duration.seconds(30),
72
100
  * }).subscribe((stream) =>
73
101
  * Stream.runForEach(stream, (msg) =>
74
102
  * Effect.log(`event ${msg.body.id}`),
@@ -148,7 +176,7 @@ export const QueueEventSourcePolicyLive = QueueEventSourcePolicy.layer.succeed(
148
176
  yield* QueueConsumer(`${queue.LogicalId}Consumer`, {
149
177
  queueId: queue.queueId,
150
178
  scriptName: host.workerName,
151
- settings: props,
179
+ settings: toConsumerSettings(props),
152
180
  deadLetterQueue: props.deadLetterQueue,
153
181
  });
154
182
  })) as unknown as (
@@ -12,6 +12,9 @@ import type * as Cloudflare from "../Providers.ts";
12
12
  import * as Zone from "../Zone.ts";
13
13
  import { R2BucketBinding } from "./R2BucketBinding.ts";
14
14
 
15
+ export const isR2Bucket = (value: unknown): value is R2Bucket =>
16
+ typeof value === "object" && (value as any)?.Type === "Cloudflare.R2Bucket";
17
+
15
18
  export type R2BucketName = string;
16
19
 
17
20
  export type R2BucketCustomDomainZone = Zone.ZoneReference;
@@ -520,6 +523,10 @@ export const R2BucketProvider = () =>
520
523
  while: isNoSuchBucket,
521
524
  schedule: r2BucketEndpointConsistencySchedule,
522
525
  }),
526
+ Effect.retry({
527
+ while: isDomainInUseConflict,
528
+ schedule: r2CustomDomainConflictSchedule,
529
+ }),
523
530
  );
524
531
  return toCustomDomainAttributes({ ...created, zoneId });
525
532
  }
@@ -842,3 +849,22 @@ const isNoSuchBucket = (error: unknown): boolean =>
842
849
  error !== null &&
843
850
  "_tag" in error &&
844
851
  (error as { _tag: unknown })._tag === "NoSuchBucket";
852
+
853
+ // Cloudflare keys a custom domain to a single bucket at the zone level. After a
854
+ // domain is deleted, re-attaching the same hostname can transiently 409 with
855
+ // "Domain already in use" until the prior association is fully released. Treat
856
+ // that narrow conflict as eventual consistency and retry it on create.
857
+ const isDomainInUseConflict = (error: unknown): boolean =>
858
+ typeof error === "object" &&
859
+ error !== null &&
860
+ "_tag" in error &&
861
+ (error as { _tag: unknown })._tag === "Conflict" &&
862
+ "message" in error &&
863
+ typeof (error as { message: unknown }).message === "string" &&
864
+ (error as { message: string }).message.toLowerCase().includes("in use");
865
+
866
+ // Releasing a custom domain after delete can lag a few seconds, so give the
867
+ // conflict a longer, bounded budget than the bucket-endpoint lag above.
868
+ const r2CustomDomainConflictSchedule = Schedule.spaced("2 seconds").pipe(
869
+ Schedule.both(Schedule.recurs(8)),
870
+ );
@@ -1,4 +1,5 @@
1
1
  import * as secretsStore from "@distilled.cloud/cloudflare/secrets-store";
2
+ import * as Console from "effect/Console";
2
3
  import * as Effect from "effect/Effect";
3
4
  import * as Option from "effect/Option";
4
5
  import * as Redacted from "effect/Redacted";
@@ -100,9 +101,6 @@ export const StoreSecretProvider = () =>
100
101
  const getStoreSecret = yield* secretsStore.getStoreSecret;
101
102
  const listStoreSecrets = secretsStore.listStoreSecrets;
102
103
 
103
- const arraysEqual = (a: string[], b: string[]) =>
104
- a.length === b.length && a.every((v, i) => v === b[i]);
105
-
106
104
  return {
107
105
  stables: ["secretId", "secretName", "storeId", "accountId"],
108
106
  diff: Effect.fn(function* ({ id, olds = {} as any, news, output }) {
@@ -117,7 +115,7 @@ export const StoreSecretProvider = () =>
117
115
  const oldValue = olds.value ? Redacted.value(olds.value) : undefined;
118
116
  const newValue = Redacted.value(news.value);
119
117
  if (oldValue !== newValue) {
120
- return { action: "replace" } as const;
118
+ return { action: "update" } as const;
121
119
  }
122
120
  }),
123
121
  reconcile: Effect.fn(function* ({ id, news, output }) {
@@ -212,49 +210,22 @@ export const StoreSecretProvider = () =>
212
210
  observed = existing;
213
211
  }
214
212
 
215
- // Sync — `listStoreSecrets` does not surface scopes, so we
216
- // can't reliably diff them. Issue PATCH only when we have a
217
- // record of prior props (`output`) and a difference is
218
- // visible; otherwise issue an unconditional PATCH on the
219
- // adoption / first-create path so scopes and comment converge.
220
- const oldScopes = output ? resolveScopes(output.scopes) : undefined;
221
- const scopesChanged = !oldScopes || !arraysEqual(scopes, oldScopes);
222
- const commentChanged =
223
- !output ||
224
- (output.comment ?? undefined) !== (news.comment ?? undefined);
225
- if (scopesChanged || commentChanged) {
226
- const patched = yield* patchStoreSecret({
227
- accountId,
228
- storeId,
229
- secretId: observed.id,
230
- scopes: scopesChanged ? scopes : undefined,
231
- comment: commentChanged ? news.comment : undefined,
232
- }).pipe(
233
- Effect.catchTag("SecretNotFound", () =>
234
- Effect.succeed(undefined),
235
- ),
236
- );
237
- if (patched) {
238
- return {
239
- secretId: observed.id,
240
- secretName: observed.name,
241
- storeId: observed.storeId,
242
- accountId,
243
- status: patched.status,
244
- scopes,
245
- comment: patched.comment ?? undefined,
246
- };
247
- }
248
- }
249
-
213
+ const patched = yield* patchStoreSecret({
214
+ accountId,
215
+ storeId,
216
+ secretId: observed.id,
217
+ scopes,
218
+ comment: news.comment,
219
+ value: Redacted.value(news.value),
220
+ });
250
221
  return {
251
222
  secretId: observed.id,
252
223
  secretName: observed.name,
253
224
  storeId: observed.storeId,
254
225
  accountId,
255
- status: observed.status,
226
+ status: patched.status,
256
227
  scopes,
257
- comment: news.comment ?? observed.comment ?? undefined,
228
+ comment: patched.comment ?? undefined,
258
229
  };
259
230
  }),
260
231
  delete: Effect.fn(function* ({ output }) {
@@ -263,6 +234,8 @@ export const StoreSecretProvider = () =>
263
234
  storeId: output.storeId,
264
235
  secretId: output.secretId,
265
236
  }).pipe(
237
+ Effect.tap(() => Effect.log(`deleted ${output.secretId}`)),
238
+ Effect.tapError(Console.log),
266
239
  Effect.catchTag("SecretNotFound", () => Effect.void),
267
240
  Effect.catchTag("StoreNotFound", () => Effect.void),
268
241
  Effect.catchTag("NotFound", () => Effect.void),
@@ -2,6 +2,7 @@ import type * as runtime from "@cloudflare/workers-types";
2
2
  import * as Data from "effect/Data";
3
3
  import * as Effect from "effect/Effect";
4
4
  import * as Layer from "effect/Layer";
5
+ import * as Redacted from "effect/Redacted";
5
6
  import * as Binding from "../../Binding.ts";
6
7
  import type { ResourceLike } from "../../Resource.ts";
7
8
  import type { RuntimeContext } from "../../RuntimeContext.ts";
@@ -20,7 +21,7 @@ export class SecretError extends Data.TaggedError("SecretError")<{
20
21
  * `SecretsStoreSecret` binding.
21
22
  */
22
23
  export interface SecretClient extends Effect.Effect<
23
- string,
24
+ Redacted.Redacted<string>,
24
25
  SecretError,
25
26
  RuntimeContext
26
27
  > {
@@ -31,7 +32,7 @@ export interface SecretClient extends Effect.Effect<
31
32
  /**
32
33
  * Read the current value of the secret.
33
34
  */
34
- get(): Effect.Effect<string, SecretError, RuntimeContext>;
35
+ get(): Effect.Effect<Redacted.Redacted<string>, SecretError, RuntimeContext>;
35
36
  }
36
37
 
37
38
  export class SecretBinding extends Binding.Service<
@@ -63,17 +64,16 @@ export const SecretBindingLive = Layer.effect(
63
64
  }),
64
65
  });
65
66
 
66
- const getEffect: Effect.Effect<string, SecretError> = raw.pipe(
67
- Effect.flatMap((raw) => tryPromise(() => raw.get())),
67
+ const getEffect = raw.pipe(
68
+ Effect.flatMap((raw) =>
69
+ tryPromise(() => raw.get().then(Redacted.make)),
70
+ ),
68
71
  );
69
72
 
70
- return Object.assign(
71
- Effect.suspend(() => getEffect),
72
- {
73
- raw,
74
- get: () => getEffect,
75
- },
76
- ) as SecretClient;
73
+ return Object.assign(getEffect, {
74
+ raw,
75
+ get: () => getEffect,
76
+ });
77
77
  });
78
78
  }),
79
79
  );
@@ -1,3 +1,4 @@
1
+ import { Redacted } from "effect";
1
2
  import * as Effect from "effect/Effect";
2
3
  import * as Layer from "effect/Layer";
3
4
  import * as Path from "effect/Path";
@@ -12,7 +13,7 @@ import {
12
13
  StateApi,
13
14
  StateAuthLive,
14
15
  } from "../../State/HttpStateApi.ts";
15
- import * as Secret from "../SecretsStore/Secret.ts";
16
+ import { Secret } from "../SecretsStore/Secret.ts";
16
17
  import { SecretBindingLive } from "../SecretsStore/SecretBinding.ts";
17
18
  import { Worker } from "../Workers/Worker.ts";
18
19
  import Store from "./Store.ts";
@@ -29,7 +30,7 @@ export const STATE_STORE_SCRIPT_NAME = "alchemy-state-store" as const;
29
30
  * compare against this constant; a mismatch (or 404) triggers a
30
31
  * forced redeploy via the bootstrap flow.
31
32
  */
32
- export const STATE_STORE_VERSION = 5 as const;
33
+ export const STATE_STORE_VERSION = 6 as const;
33
34
 
34
35
  /**
35
36
  * Hard-coded OTLP/HTTP endpoints. Point at the public ingest relay
@@ -108,22 +109,21 @@ export default Worker(
108
109
  },
109
110
  },
110
111
  Effect.gen(function* () {
111
- const secret = yield* Secret.Secret.bind(AuthToken);
112
+ const remoteSecret = yield* Secret.bind(AuthToken);
112
113
  const store = yield* Store;
113
114
 
114
- const bearerTokenValidator = Layer.effect(
115
+ const bearerTokenValidator = Layer.succeed(
115
116
  BearerTokenValidator,
116
- secret.get().pipe(
117
- Effect.map((expected) =>
118
- BearerTokenValidator.of({
119
- validate: (token) =>
120
- !!expected && timingSafeEqual(token, expected)
121
- ? Effect.void
122
- : Effect.fail(new HttpApiError.Unauthorized()),
123
- }),
124
- ),
125
- Effect.orDie,
126
- ),
117
+ BearerTokenValidator.of({
118
+ // @ts-expect-error - TODO(sam): fix RuntimeContext color here
119
+ validate: Effect.fnUntraced(function* (token) {
120
+ const expected = yield* remoteSecret.get();
121
+ return !!expected &&
122
+ timingSafeEqual(token.trim(), Redacted.value(expected).trim())
123
+ ? yield* Effect.void
124
+ : yield* Effect.fail(new HttpApiError.Unauthorized());
125
+ }),
126
+ }),
127
127
  );
128
128
 
129
129
  const versionApi = HttpApiBuilder.group(StateApi, "version", (handlers) =>
@@ -41,7 +41,7 @@ import * as Access from "../Access.ts";
41
41
  import { CloudflareAuth } from "../Auth/AuthProvider.ts";
42
42
  import { EdgeSessionError, createEdgeSession } from "../EdgeSession.ts";
43
43
  import Api, { STATE_STORE_SCRIPT_NAME, STATE_STORE_VERSION } from "./Api.ts";
44
- import { AuthTokenSecretName, TokenValue } from "./Token.ts";
44
+ import { AuthToken, AuthTokenSecretName, TokenValue } from "./Token.ts";
45
45
 
46
46
  /** Filename used for stored credentials under the profile directory. */
47
47
  const CREDENTIALS_FILE = "cloudflare-state-store";
@@ -145,7 +145,13 @@ export const bootstrap = (options: BootstrapOptions = {}) =>
145
145
  yield* Clank.info(
146
146
  `Resuming Cloudflare State Store '${scriptName}' deployment...`,
147
147
  );
148
- yield* finishBootstrap({ scriptName, profileName, localState, isCI });
148
+ yield* finishBootstrap({
149
+ scriptName,
150
+ profileName,
151
+ localState,
152
+ isCI,
153
+ force,
154
+ });
149
155
  yield* Clank.success(`Cloudflare State Store '${scriptName}' is ready.`);
150
156
  return;
151
157
  }
@@ -178,6 +184,7 @@ export const bootstrap = (options: BootstrapOptions = {}) =>
178
184
  localState,
179
185
  isCI,
180
186
  url: credentials.url,
187
+ force,
181
188
  });
182
189
  yield* Clank.success(`Cloudflare State Store '${scriptName}' is ready.`);
183
190
  return;
@@ -191,7 +198,13 @@ export const bootstrap = (options: BootstrapOptions = {}) =>
191
198
  yield* Clank.info(`Deploying Cloudflare State Store '${scriptName}'...`);
192
199
  }
193
200
 
194
- yield* finishBootstrap({ scriptName, profileName, localState, isCI });
201
+ yield* finishBootstrap({
202
+ scriptName,
203
+ profileName,
204
+ localState,
205
+ isCI,
206
+ force,
207
+ });
195
208
  yield* Clank.success(`Cloudflare State Store '${scriptName}' is ready.`);
196
209
  }).pipe(
197
210
  Effect.withSpan("state_store.bootstrap", {
@@ -221,6 +234,7 @@ export const state = () =>
221
234
  "alchemy.state_store.script_name": scriptName,
222
235
  "alchemy.state_store.profile": profileName,
223
236
  "alchemy.state_store.ci": isCI,
237
+ "alchemy.state_store.force": false,
224
238
  });
225
239
  yield* annotateAccountHash(
226
240
  yield* Config.boolean("NO_TRACK").pipe(Config.withDefault(false)),
@@ -255,6 +269,7 @@ export const state = () =>
255
269
  profileName,
256
270
  localState,
257
271
  isCI,
272
+ force: false,
258
273
  });
259
274
  }
260
275
 
@@ -270,6 +285,7 @@ export const state = () =>
270
285
  localState,
271
286
  isCI,
272
287
  url: credentials.url,
288
+ force: false,
273
289
  });
274
290
  if (fresh) return fresh;
275
291
 
@@ -311,6 +327,7 @@ export const state = () =>
311
327
  localState,
312
328
  isCI,
313
329
  url: credentials.url,
330
+ force: false,
314
331
  });
315
332
  if (fresh) return fresh;
316
333
 
@@ -346,6 +363,7 @@ export const state = () =>
346
363
  profileName,
347
364
  localState,
348
365
  isCI,
366
+ force: false,
349
367
  });
350
368
  }).pipe(recordStateStoreInit, Effect.orDie),
351
369
  ).pipe(
@@ -423,14 +441,20 @@ const finishBootstrap = ({
423
441
  profileName,
424
442
  localState,
425
443
  isCI,
444
+ force,
426
445
  }: {
427
446
  scriptName: string;
428
447
  profileName: string;
429
448
  localState: StateService;
430
449
  isCI: boolean;
450
+ force: boolean;
431
451
  }) =>
432
452
  Effect.gen(function* () {
433
- yield* deployStateStore(scriptName, localState);
453
+ const { authToken } = yield* deployStateStore(
454
+ scriptName,
455
+ localState,
456
+ force,
457
+ );
434
458
 
435
459
  // Don't trust the `authToken` returned by `deploy(...)`: when
436
460
  // adoption kicks in (the Secrets Store secret already existed),
@@ -442,7 +466,7 @@ const finishBootstrap = ({
442
466
  // actually deployed. `loginWithCloudflare` also persists the
443
467
  // credentials file (skipping the write in CI), so we don't need
444
468
  // to do that explicitly here.
445
- const { url, authToken } = yield* loginWithCloudflare();
469
+ const { url } = yield* loginWithCloudflare();
446
470
  const httpState = yield* makeCloudflareStateStore({ url, authToken });
447
471
  // `profileName` is intentionally unused here — `loginWithCloudflare`
448
472
  // resolves it itself. Reference it to keep the surrounding API
@@ -476,7 +500,11 @@ const finishBootstrap = ({
476
500
  }),
477
501
  );
478
502
 
479
- const deployStateStore = (scriptName: string, state?: StateService) =>
503
+ const deployStateStore = (
504
+ scriptName: string,
505
+ state?: StateService,
506
+ force?: boolean,
507
+ ) =>
480
508
  Effect.gen(function* () {
481
509
  yield* annotateAccountHash();
482
510
  const localState = state ?? (yield* makeLocalState());
@@ -485,6 +513,7 @@ const deployStateStore = (scriptName: string, state?: StateService) =>
485
513
  const { url, authToken } = yield* deploy({
486
514
  // use the script name as the stage name (so the user can have multiple state stores)
487
515
  stage: scriptName,
516
+ force,
488
517
  stack: Alchemy.Stack(
489
518
  "CloudflareStateStore",
490
519
  {
@@ -494,6 +523,7 @@ const deployStateStore = (scriptName: string, state?: StateService) =>
494
523
  Effect.gen(function* () {
495
524
  const token = yield* TokenValue;
496
525
  const api = yield* Api;
526
+ yield* AuthToken; // make sure it's in the Secrets Store
497
527
 
498
528
  // Surface the bearer token so tests and clients can authenticate
499
529
  // after deploy. The underlying value lives in the Cloudflare
@@ -514,6 +544,9 @@ const deployStateStore = (scriptName: string, state?: StateService) =>
514
544
  // TODO(sam): we should not need to do this, but types do complain. fix deploy
515
545
  Effect.provide(stateLayer),
516
546
  );
547
+
548
+ yield* writeCredentials(url, authToken);
549
+
517
550
  // Cloudflare's worker upload is eventually consistent: the deploy
518
551
  // call returns as soon as the script upload is accepted, but the
519
552
  // edge can keep serving the previous version for several seconds
@@ -582,6 +615,13 @@ export const loginWithCloudflare = () =>
582
615
  STATE_STORE_SCRIPT_NAME,
583
616
  store.id,
584
617
  AuthTokenSecretName,
618
+ ).pipe(
619
+ Effect.retry({
620
+ while: isWorkersPreviewConfigurationError,
621
+ schedule: Schedule.exponential(200).pipe(
622
+ Schedule.both(Schedule.recurs(15)),
623
+ ),
624
+ }),
585
625
  );
586
626
 
587
627
  // 3. Derive the deployed worker URL.
@@ -634,6 +674,25 @@ export const loginWithCloudflare = () =>
634
674
  }),
635
675
  );
636
676
 
677
+ const writeCredentials = (url: string, authToken: string) =>
678
+ Effect.gen(function* () {
679
+ const profileName = yield* ALCHEMY_PROFILE;
680
+ const credStore = yield* CredentialsStore;
681
+ yield* credStore.write<HttpStateStoreCredentials>(
682
+ profileName,
683
+ CREDENTIALS_FILE,
684
+ {
685
+ url,
686
+ authToken,
687
+ },
688
+ );
689
+ });
690
+
691
+ const isWorkersPreviewConfigurationError = (error: unknown) =>
692
+ error instanceof EdgeSessionError &&
693
+ (error.message.includes("Invalid Workers Preview configuration") ||
694
+ error.message.includes("Error 1031"));
695
+
637
696
  /**
638
697
  * Run {@link finishBootstrap} iff the worker at `url` fails the
639
698
  * version probe; otherwise resolve to `undefined`. Centralises the
@@ -646,12 +705,14 @@ const redeployIfStale = ({
646
705
  profileName,
647
706
  localState,
648
707
  isCI,
708
+ force,
649
709
  }: {
650
710
  url: string;
651
711
  scriptName: string;
652
712
  profileName: string;
653
713
  localState: StateService;
654
714
  isCI: boolean;
715
+ force: boolean;
655
716
  }) =>
656
717
  Effect.gen(function* () {
657
718
  const { matches, expected, observed } = yield* checkStateStoreVersion(url);
@@ -665,6 +726,7 @@ const redeployIfStale = ({
665
726
  profileName,
666
727
  localState,
667
728
  isCI,
729
+ force,
668
730
  });
669
731
  }).pipe(
670
732
  Effect.withSpan("state_store.redeploy_if_stale", {
@@ -1,11 +1,12 @@
1
1
  import * as Effect from "effect/Effect";
2
+ import * as Redacted from "effect/Redacted";
2
3
 
4
+ import { pipe } from "effect/Function";
3
5
  import type {
4
6
  ReplacedResourceState,
5
7
  ResourceState,
6
8
  } from "../../State/ResourceState.ts";
7
9
  import { encodeState } from "../../State/StateEncoding.ts";
8
- import { pipe } from "effect/Function";
9
10
  import * as Secret from "../SecretsStore/Secret.ts";
10
11
  import { DurableObjectNamespace } from "../Workers/DurableObjectNamespace.ts";
11
12
  import { DurableObjectState } from "../Workers/DurableObjectState.ts";
@@ -25,7 +26,9 @@ export default class Store extends DurableObjectNamespace<Store>()(
25
26
  const doState = yield* DurableObjectState;
26
27
  const storage = doState.storage;
27
28
 
28
- const keyHex = yield* encryptionSecret.get().pipe(Effect.orDie);
29
+ const keyHex = yield* encryptionSecret
30
+ .get()
31
+ .pipe(Effect.map(Redacted.value), Effect.orDie);
29
32
  const cryptoKey = yield* Effect.tryPromise(() =>
30
33
  crypto.subtle.importKey(
31
34
  "raw",
@@ -77,7 +77,7 @@ export declare namespace VpcService {
77
77
  export type VpcServiceAttributes = {
78
78
  serviceId: string;
79
79
  serviceName: string;
80
- serviceType: "http";
80
+ serviceType: "http" | "tcp";
81
81
  httpPort: number | undefined;
82
82
  httpsPort: number | undefined;
83
83
  host: VpcService.Host;
@@ -262,7 +262,7 @@ export const formatVpcService = (
262
262
  service: {
263
263
  serviceId?: string | null;
264
264
  name: string;
265
- type: "http";
265
+ type: "http" | "tcp";
266
266
  createdAt?: string | null;
267
267
  updatedAt?: string | null;
268
268
  httpPort?: number | null;