alchemy 2.0.0-beta.62 → 2.0.0-beta.63

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 (489) hide show
  1. package/README.md +12 -12
  2. package/bin/exec.js +1959 -70
  3. package/bin/exec.js.map +1 -1
  4. package/lib/AWS/AuthProvider.js +1 -1
  5. package/lib/AWS/AuthProvider.js.map +1 -1
  6. package/lib/AWS/EC2/hosted.d.ts.map +1 -1
  7. package/lib/AWS/EC2/hosted.js +2 -1
  8. package/lib/AWS/EC2/hosted.js.map +1 -1
  9. package/lib/AWS/ECS/Task.d.ts.map +1 -1
  10. package/lib/AWS/ECS/Task.js +2 -1
  11. package/lib/AWS/ECS/Task.js.map +1 -1
  12. package/lib/AWS/Lambda/Function.d.ts.map +1 -1
  13. package/lib/AWS/Lambda/Function.js +13 -40
  14. package/lib/AWS/Lambda/Function.js.map +1 -1
  15. package/lib/AWS/Lambda/MicrovmRuntimeContext.d.ts.map +1 -1
  16. package/lib/AWS/Lambda/MicrovmRuntimeContext.js +9 -21
  17. package/lib/AWS/Lambda/MicrovmRuntimeContext.js.map +1 -1
  18. package/lib/Action.d.ts +8 -0
  19. package/lib/Action.d.ts.map +1 -1
  20. package/lib/Action.js +16 -5
  21. package/lib/Action.js.map +1 -1
  22. package/lib/ActionRuntimeContext.d.ts +14 -0
  23. package/lib/ActionRuntimeContext.d.ts.map +1 -0
  24. package/lib/ActionRuntimeContext.js +56 -0
  25. package/lib/ActionRuntimeContext.js.map +1 -0
  26. package/lib/Apply.d.ts.map +1 -1
  27. package/lib/Apply.js +40 -6
  28. package/lib/Apply.js.map +1 -1
  29. package/lib/Auth/AuthProvider.d.ts +3 -3
  30. package/lib/Auth/AuthProvider.d.ts.map +1 -1
  31. package/lib/Auth/AuthProvider.js +1 -1
  32. package/lib/Auth/AuthProvider.js.map +1 -1
  33. package/lib/Auth/Lock.d.ts.map +1 -1
  34. package/lib/Auth/Lock.js +5 -2
  35. package/lib/Auth/Lock.js.map +1 -1
  36. package/lib/Bundle/PurePlugin.d.ts.map +1 -1
  37. package/lib/Bundle/PurePlugin.js +26 -1
  38. package/lib/Bundle/PurePlugin.js.map +1 -1
  39. package/lib/Bundle/Vite.d.ts +2 -0
  40. package/lib/Bundle/Vite.d.ts.map +1 -1
  41. package/lib/Bundle/Vite.js +24 -1
  42. package/lib/Bundle/Vite.js.map +1 -1
  43. package/lib/Cli/LoggingCli.d.ts.map +1 -1
  44. package/lib/Cli/LoggingCli.js +7 -4
  45. package/lib/Cli/LoggingCli.js.map +1 -1
  46. package/lib/Cli/commands/_shared.d.ts +19 -0
  47. package/lib/Cli/commands/_shared.d.ts.map +1 -1
  48. package/lib/Cli/commands/_shared.js +22 -0
  49. package/lib/Cli/commands/_shared.js.map +1 -1
  50. package/lib/Cli/commands/login.d.ts +7 -3
  51. package/lib/Cli/commands/login.d.ts.map +1 -1
  52. package/lib/Cli/commands/login.js +70 -12
  53. package/lib/Cli/commands/login.js.map +1 -1
  54. package/lib/Cli/commands/profile.d.ts.map +1 -1
  55. package/lib/Cli/commands/profile.js +7 -20
  56. package/lib/Cli/commands/profile.js.map +1 -1
  57. package/lib/Cloudflare/AI/LanguageModel.js +21 -4
  58. package/lib/Cloudflare/AI/LanguageModel.js.map +1 -1
  59. package/lib/Cloudflare/AI/QuerySearchLocal.d.ts +37 -0
  60. package/lib/Cloudflare/AI/QuerySearchLocal.d.ts.map +1 -0
  61. package/lib/Cloudflare/AI/QuerySearchLocal.js +53 -0
  62. package/lib/Cloudflare/AI/QuerySearchLocal.js.map +1 -0
  63. package/lib/Cloudflare/AI/QuerySearchNamespaceLocal.d.ts +35 -0
  64. package/lib/Cloudflare/AI/QuerySearchNamespaceLocal.d.ts.map +1 -0
  65. package/lib/Cloudflare/AI/QuerySearchNamespaceLocal.js +47 -0
  66. package/lib/Cloudflare/AI/QuerySearchNamespaceLocal.js.map +1 -0
  67. package/lib/Cloudflare/AI/SearchHttpClient.d.ts +34 -0
  68. package/lib/Cloudflare/AI/SearchHttpClient.d.ts.map +1 -0
  69. package/lib/Cloudflare/AI/SearchHttpClient.js +262 -0
  70. package/lib/Cloudflare/AI/SearchHttpClient.js.map +1 -0
  71. package/lib/Cloudflare/AI/index.d.ts +2 -0
  72. package/lib/Cloudflare/AI/index.d.ts.map +1 -1
  73. package/lib/Cloudflare/AI/index.js +2 -0
  74. package/lib/Cloudflare/AI/index.js.map +1 -1
  75. package/lib/Cloudflare/Auth/AuthProvider.js +1 -1
  76. package/lib/Cloudflare/Auth/AuthProvider.js.map +1 -1
  77. package/lib/Cloudflare/Containers/ContainerBundle.d.ts.map +1 -1
  78. package/lib/Cloudflare/Containers/ContainerBundle.js +11 -1
  79. package/lib/Cloudflare/Containers/ContainerBundle.js.map +1 -1
  80. package/lib/Cloudflare/Containers/ContainerPlatform.d.ts.map +1 -1
  81. package/lib/Cloudflare/Containers/ContainerPlatform.js +12 -33
  82. package/lib/Cloudflare/Containers/ContainerPlatform.js.map +1 -1
  83. package/lib/Cloudflare/D1/QueryDatabaseHttpClient.d.ts +24 -0
  84. package/lib/Cloudflare/D1/QueryDatabaseHttpClient.d.ts.map +1 -0
  85. package/lib/Cloudflare/D1/QueryDatabaseHttpClient.js +106 -0
  86. package/lib/Cloudflare/D1/QueryDatabaseHttpClient.js.map +1 -0
  87. package/lib/Cloudflare/D1/QueryDatabaseLocal.d.ts +38 -0
  88. package/lib/Cloudflare/D1/QueryDatabaseLocal.d.ts.map +1 -0
  89. package/lib/Cloudflare/D1/QueryDatabaseLocal.js +54 -0
  90. package/lib/Cloudflare/D1/QueryDatabaseLocal.js.map +1 -0
  91. package/lib/Cloudflare/D1/index.d.ts +1 -0
  92. package/lib/Cloudflare/D1/index.d.ts.map +1 -1
  93. package/lib/Cloudflare/D1/index.js +1 -0
  94. package/lib/Cloudflare/D1/index.js.map +1 -1
  95. package/lib/Cloudflare/DNS/DnsHttp.d.ts +16 -1
  96. package/lib/Cloudflare/DNS/DnsHttp.d.ts.map +1 -1
  97. package/lib/Cloudflare/DNS/DnsHttp.js +6 -1
  98. package/lib/Cloudflare/DNS/DnsHttp.js.map +1 -1
  99. package/lib/Cloudflare/DNS/DnsLocal.d.ts +22 -0
  100. package/lib/Cloudflare/DNS/DnsLocal.d.ts.map +1 -0
  101. package/lib/Cloudflare/DNS/DnsLocal.js +31 -0
  102. package/lib/Cloudflare/DNS/DnsLocal.js.map +1 -0
  103. package/lib/Cloudflare/DNS/ReadDnsHttp.d.ts +3 -3
  104. package/lib/Cloudflare/DNS/ReadDnsHttp.d.ts.map +1 -1
  105. package/lib/Cloudflare/DNS/ReadDnsHttp.js +3 -4
  106. package/lib/Cloudflare/DNS/ReadDnsHttp.js.map +1 -1
  107. package/lib/Cloudflare/DNS/ReadDnsLocal.d.ts +32 -0
  108. package/lib/Cloudflare/DNS/ReadDnsLocal.d.ts.map +1 -0
  109. package/lib/Cloudflare/DNS/ReadDnsLocal.js +35 -0
  110. package/lib/Cloudflare/DNS/ReadDnsLocal.js.map +1 -0
  111. package/lib/Cloudflare/DNS/ReadWriteDnsHttp.d.ts +3 -3
  112. package/lib/Cloudflare/DNS/ReadWriteDnsHttp.d.ts.map +1 -1
  113. package/lib/Cloudflare/DNS/ReadWriteDnsHttp.js +4 -4
  114. package/lib/Cloudflare/DNS/ReadWriteDnsHttp.js.map +1 -1
  115. package/lib/Cloudflare/DNS/ReadWriteDnsLocal.d.ts +40 -0
  116. package/lib/Cloudflare/DNS/ReadWriteDnsLocal.d.ts.map +1 -0
  117. package/lib/Cloudflare/DNS/ReadWriteDnsLocal.js +43 -0
  118. package/lib/Cloudflare/DNS/ReadWriteDnsLocal.js.map +1 -0
  119. package/lib/Cloudflare/DNS/WriteDnsHttp.d.ts +3 -3
  120. package/lib/Cloudflare/DNS/WriteDnsHttp.d.ts.map +1 -1
  121. package/lib/Cloudflare/DNS/WriteDnsHttp.js +3 -4
  122. package/lib/Cloudflare/DNS/WriteDnsHttp.js.map +1 -1
  123. package/lib/Cloudflare/DNS/WriteDnsLocal.d.ts +38 -0
  124. package/lib/Cloudflare/DNS/WriteDnsLocal.d.ts.map +1 -0
  125. package/lib/Cloudflare/DNS/WriteDnsLocal.js +41 -0
  126. package/lib/Cloudflare/DNS/WriteDnsLocal.js.map +1 -0
  127. package/lib/Cloudflare/DNS/index.d.ts +3 -0
  128. package/lib/Cloudflare/DNS/index.d.ts.map +1 -1
  129. package/lib/Cloudflare/DNS/index.js +3 -0
  130. package/lib/Cloudflare/DNS/index.js.map +1 -1
  131. package/lib/Cloudflare/Flagship/ReadFlagsHttpClient.d.ts +27 -0
  132. package/lib/Cloudflare/Flagship/ReadFlagsHttpClient.d.ts.map +1 -0
  133. package/lib/Cloudflare/Flagship/ReadFlagsHttpClient.js +86 -0
  134. package/lib/Cloudflare/Flagship/ReadFlagsHttpClient.js.map +1 -0
  135. package/lib/Cloudflare/Flagship/ReadFlagsLocal.d.ts +41 -0
  136. package/lib/Cloudflare/Flagship/ReadFlagsLocal.d.ts.map +1 -0
  137. package/lib/Cloudflare/Flagship/ReadFlagsLocal.js +57 -0
  138. package/lib/Cloudflare/Flagship/ReadFlagsLocal.js.map +1 -0
  139. package/lib/Cloudflare/Flagship/index.d.ts +1 -0
  140. package/lib/Cloudflare/Flagship/index.d.ts.map +1 -1
  141. package/lib/Cloudflare/Flagship/index.js +1 -0
  142. package/lib/Cloudflare/Flagship/index.js.map +1 -1
  143. package/lib/Cloudflare/KV/NamespaceHttp.d.ts +16 -1
  144. package/lib/Cloudflare/KV/NamespaceHttp.d.ts.map +1 -1
  145. package/lib/Cloudflare/KV/NamespaceHttp.js +8 -2
  146. package/lib/Cloudflare/KV/NamespaceHttp.js.map +1 -1
  147. package/lib/Cloudflare/KV/NamespaceLocal.d.ts +22 -0
  148. package/lib/Cloudflare/KV/NamespaceLocal.d.ts.map +1 -0
  149. package/lib/Cloudflare/KV/NamespaceLocal.js +32 -0
  150. package/lib/Cloudflare/KV/NamespaceLocal.js.map +1 -0
  151. package/lib/Cloudflare/KV/ReadNamespaceHttp.d.ts +2 -2
  152. package/lib/Cloudflare/KV/ReadNamespaceHttp.d.ts.map +1 -1
  153. package/lib/Cloudflare/KV/ReadNamespaceHttp.js +5 -6
  154. package/lib/Cloudflare/KV/ReadNamespaceHttp.js.map +1 -1
  155. package/lib/Cloudflare/KV/ReadNamespaceLocal.d.ts +27 -0
  156. package/lib/Cloudflare/KV/ReadNamespaceLocal.d.ts.map +1 -0
  157. package/lib/Cloudflare/KV/ReadNamespaceLocal.js +30 -0
  158. package/lib/Cloudflare/KV/ReadNamespaceLocal.js.map +1 -0
  159. package/lib/Cloudflare/KV/ReadWriteNamespaceHttp.d.ts +3 -3
  160. package/lib/Cloudflare/KV/ReadWriteNamespaceHttp.d.ts.map +1 -1
  161. package/lib/Cloudflare/KV/ReadWriteNamespaceHttp.js +6 -6
  162. package/lib/Cloudflare/KV/ReadWriteNamespaceHttp.js.map +1 -1
  163. package/lib/Cloudflare/KV/ReadWriteNamespaceLocal.d.ts +34 -0
  164. package/lib/Cloudflare/KV/ReadWriteNamespaceLocal.d.ts.map +1 -0
  165. package/lib/Cloudflare/KV/ReadWriteNamespaceLocal.js +37 -0
  166. package/lib/Cloudflare/KV/ReadWriteNamespaceLocal.js.map +1 -0
  167. package/lib/Cloudflare/KV/WriteNamespaceHttp.d.ts +2 -2
  168. package/lib/Cloudflare/KV/WriteNamespaceHttp.d.ts.map +1 -1
  169. package/lib/Cloudflare/KV/WriteNamespaceHttp.js +5 -6
  170. package/lib/Cloudflare/KV/WriteNamespaceHttp.js.map +1 -1
  171. package/lib/Cloudflare/KV/WriteNamespaceLocal.d.ts +27 -0
  172. package/lib/Cloudflare/KV/WriteNamespaceLocal.d.ts.map +1 -0
  173. package/lib/Cloudflare/KV/WriteNamespaceLocal.js +30 -0
  174. package/lib/Cloudflare/KV/WriteNamespaceLocal.js.map +1 -0
  175. package/lib/Cloudflare/KV/index.d.ts +3 -0
  176. package/lib/Cloudflare/KV/index.d.ts.map +1 -1
  177. package/lib/Cloudflare/KV/index.js +3 -0
  178. package/lib/Cloudflare/KV/index.js.map +1 -1
  179. package/lib/Cloudflare/Queues/QueueHttp.d.ts +20 -1
  180. package/lib/Cloudflare/Queues/QueueHttp.d.ts.map +1 -1
  181. package/lib/Cloudflare/Queues/QueueHttp.js +2 -2
  182. package/lib/Cloudflare/Queues/QueueHttp.js.map +1 -1
  183. package/lib/Cloudflare/Queues/WriteQueueHttp.d.ts +9 -3
  184. package/lib/Cloudflare/Queues/WriteQueueHttp.d.ts.map +1 -1
  185. package/lib/Cloudflare/Queues/WriteQueueHttp.js +11 -6
  186. package/lib/Cloudflare/Queues/WriteQueueHttp.js.map +1 -1
  187. package/lib/Cloudflare/Queues/WriteQueueLocal.d.ts +36 -0
  188. package/lib/Cloudflare/Queues/WriteQueueLocal.d.ts.map +1 -0
  189. package/lib/Cloudflare/Queues/WriteQueueLocal.js +51 -0
  190. package/lib/Cloudflare/Queues/WriteQueueLocal.js.map +1 -0
  191. package/lib/Cloudflare/Queues/index.d.ts +1 -0
  192. package/lib/Cloudflare/Queues/index.d.ts.map +1 -1
  193. package/lib/Cloudflare/Queues/index.js +1 -0
  194. package/lib/Cloudflare/Queues/index.js.map +1 -1
  195. package/lib/Cloudflare/R2/BucketHttp.d.ts +15 -1
  196. package/lib/Cloudflare/R2/BucketHttp.d.ts.map +1 -1
  197. package/lib/Cloudflare/R2/BucketHttp.js +3 -3
  198. package/lib/Cloudflare/R2/BucketHttp.js.map +1 -1
  199. package/lib/Cloudflare/R2/BucketLocal.d.ts +21 -0
  200. package/lib/Cloudflare/R2/BucketLocal.d.ts.map +1 -0
  201. package/lib/Cloudflare/R2/BucketLocal.js +32 -0
  202. package/lib/Cloudflare/R2/BucketLocal.js.map +1 -0
  203. package/lib/Cloudflare/R2/ReadBucketHttp.d.ts +2 -2
  204. package/lib/Cloudflare/R2/ReadBucketHttp.d.ts.map +1 -1
  205. package/lib/Cloudflare/R2/ReadBucketHttp.js +4 -4
  206. package/lib/Cloudflare/R2/ReadBucketHttp.js.map +1 -1
  207. package/lib/Cloudflare/R2/ReadBucketLocal.d.ts +27 -0
  208. package/lib/Cloudflare/R2/ReadBucketLocal.d.ts.map +1 -0
  209. package/lib/Cloudflare/R2/ReadBucketLocal.js +30 -0
  210. package/lib/Cloudflare/R2/ReadBucketLocal.js.map +1 -0
  211. package/lib/Cloudflare/R2/ReadWriteBucketHttp.d.ts +2 -2
  212. package/lib/Cloudflare/R2/ReadWriteBucketHttp.d.ts.map +1 -1
  213. package/lib/Cloudflare/R2/ReadWriteBucketHttp.js +5 -4
  214. package/lib/Cloudflare/R2/ReadWriteBucketHttp.js.map +1 -1
  215. package/lib/Cloudflare/R2/ReadWriteBucketLocal.d.ts +30 -0
  216. package/lib/Cloudflare/R2/ReadWriteBucketLocal.d.ts.map +1 -0
  217. package/lib/Cloudflare/R2/ReadWriteBucketLocal.js +33 -0
  218. package/lib/Cloudflare/R2/ReadWriteBucketLocal.js.map +1 -0
  219. package/lib/Cloudflare/R2/WriteBucketHttp.d.ts +2 -2
  220. package/lib/Cloudflare/R2/WriteBucketHttp.d.ts.map +1 -1
  221. package/lib/Cloudflare/R2/WriteBucketHttp.js +4 -4
  222. package/lib/Cloudflare/R2/WriteBucketHttp.js.map +1 -1
  223. package/lib/Cloudflare/R2/WriteBucketLocal.d.ts +27 -0
  224. package/lib/Cloudflare/R2/WriteBucketLocal.d.ts.map +1 -0
  225. package/lib/Cloudflare/R2/WriteBucketLocal.js +30 -0
  226. package/lib/Cloudflare/R2/WriteBucketLocal.js.map +1 -0
  227. package/lib/Cloudflare/R2/index.d.ts +3 -0
  228. package/lib/Cloudflare/R2/index.d.ts.map +1 -1
  229. package/lib/Cloudflare/R2/index.js +3 -0
  230. package/lib/Cloudflare/R2/index.js.map +1 -1
  231. package/lib/Cloudflare/StateStore/Api.d.ts +2 -0
  232. package/lib/Cloudflare/Tunnel/ReadTunnel.d.ts +3 -3
  233. package/lib/Cloudflare/Tunnel/ReadTunnel.d.ts.map +1 -1
  234. package/lib/Cloudflare/Tunnel/ReadTunnel.js +7 -8
  235. package/lib/Cloudflare/Tunnel/ReadTunnel.js.map +1 -1
  236. package/lib/Cloudflare/Tunnel/ReadTunnelLocal.d.ts +29 -0
  237. package/lib/Cloudflare/Tunnel/ReadTunnelLocal.d.ts.map +1 -0
  238. package/lib/Cloudflare/Tunnel/ReadTunnelLocal.js +30 -0
  239. package/lib/Cloudflare/Tunnel/ReadTunnelLocal.js.map +1 -0
  240. package/lib/Cloudflare/Tunnel/ReadWriteTunnel.d.ts +3 -3
  241. package/lib/Cloudflare/Tunnel/ReadWriteTunnel.d.ts.map +1 -1
  242. package/lib/Cloudflare/Tunnel/ReadWriteTunnel.js +4 -4
  243. package/lib/Cloudflare/Tunnel/ReadWriteTunnel.js.map +1 -1
  244. package/lib/Cloudflare/Tunnel/ReadWriteTunnelLocal.d.ts +35 -0
  245. package/lib/Cloudflare/Tunnel/ReadWriteTunnelLocal.d.ts.map +1 -0
  246. package/lib/Cloudflare/Tunnel/ReadWriteTunnelLocal.js +36 -0
  247. package/lib/Cloudflare/Tunnel/ReadWriteTunnelLocal.js.map +1 -0
  248. package/lib/Cloudflare/Tunnel/TunnelBinding.d.ts +17 -1
  249. package/lib/Cloudflare/Tunnel/TunnelBinding.d.ts.map +1 -1
  250. package/lib/Cloudflare/Tunnel/TunnelBinding.js +7 -1
  251. package/lib/Cloudflare/Tunnel/TunnelBinding.js.map +1 -1
  252. package/lib/Cloudflare/Tunnel/TunnelLocalBinding.d.ts +19 -0
  253. package/lib/Cloudflare/Tunnel/TunnelLocalBinding.d.ts.map +1 -0
  254. package/lib/Cloudflare/Tunnel/TunnelLocalBinding.js +29 -0
  255. package/lib/Cloudflare/Tunnel/TunnelLocalBinding.js.map +1 -0
  256. package/lib/Cloudflare/Tunnel/WarpConnector.d.ts +3 -3
  257. package/lib/Cloudflare/Tunnel/WarpConnector.d.ts.map +1 -1
  258. package/lib/Cloudflare/Tunnel/WarpConnector.js +7 -4
  259. package/lib/Cloudflare/Tunnel/WarpConnector.js.map +1 -1
  260. package/lib/Cloudflare/Tunnel/WriteTunnel.d.ts +3 -3
  261. package/lib/Cloudflare/Tunnel/WriteTunnel.d.ts.map +1 -1
  262. package/lib/Cloudflare/Tunnel/WriteTunnel.js +7 -8
  263. package/lib/Cloudflare/Tunnel/WriteTunnel.js.map +1 -1
  264. package/lib/Cloudflare/Tunnel/WriteTunnelLocal.d.ts +29 -0
  265. package/lib/Cloudflare/Tunnel/WriteTunnelLocal.d.ts.map +1 -0
  266. package/lib/Cloudflare/Tunnel/WriteTunnelLocal.js +30 -0
  267. package/lib/Cloudflare/Tunnel/WriteTunnelLocal.js.map +1 -0
  268. package/lib/Cloudflare/Tunnel/index.d.ts +3 -0
  269. package/lib/Cloudflare/Tunnel/index.d.ts.map +1 -1
  270. package/lib/Cloudflare/Tunnel/index.js +3 -0
  271. package/lib/Cloudflare/Tunnel/index.js.map +1 -1
  272. package/lib/Cloudflare/Vectorize/SearchIndexHttpClient.d.ts +30 -0
  273. package/lib/Cloudflare/Vectorize/SearchIndexHttpClient.d.ts.map +1 -0
  274. package/lib/Cloudflare/Vectorize/SearchIndexHttpClient.js +100 -0
  275. package/lib/Cloudflare/Vectorize/SearchIndexHttpClient.js.map +1 -0
  276. package/lib/Cloudflare/Vectorize/SearchIndexLocal.d.ts +42 -0
  277. package/lib/Cloudflare/Vectorize/SearchIndexLocal.d.ts.map +1 -0
  278. package/lib/Cloudflare/Vectorize/SearchIndexLocal.js +58 -0
  279. package/lib/Cloudflare/Vectorize/SearchIndexLocal.js.map +1 -0
  280. package/lib/Cloudflare/Vectorize/index.d.ts +1 -0
  281. package/lib/Cloudflare/Vectorize/index.d.ts.map +1 -1
  282. package/lib/Cloudflare/Vectorize/index.js +1 -0
  283. package/lib/Cloudflare/Vectorize/index.js.map +1 -1
  284. package/lib/Cloudflare/Workers/BrowserHttpClient.d.ts +32 -0
  285. package/lib/Cloudflare/Workers/BrowserHttpClient.d.ts.map +1 -0
  286. package/lib/Cloudflare/Workers/BrowserHttpClient.js +100 -0
  287. package/lib/Cloudflare/Workers/BrowserHttpClient.js.map +1 -0
  288. package/lib/Cloudflare/Workers/BrowserLocal.d.ts +37 -0
  289. package/lib/Cloudflare/Workers/BrowserLocal.d.ts.map +1 -0
  290. package/lib/Cloudflare/Workers/BrowserLocal.js +53 -0
  291. package/lib/Cloudflare/Workers/BrowserLocal.js.map +1 -0
  292. package/lib/Cloudflare/Workers/ConfigProvider.d.ts +8 -0
  293. package/lib/Cloudflare/Workers/ConfigProvider.d.ts.map +1 -1
  294. package/lib/Cloudflare/Workers/ConfigProvider.js +10 -1
  295. package/lib/Cloudflare/Workers/ConfigProvider.js.map +1 -1
  296. package/lib/Cloudflare/Workers/DurableObject.d.ts +137 -3
  297. package/lib/Cloudflare/Workers/DurableObject.d.ts.map +1 -1
  298. package/lib/Cloudflare/Workers/DurableObject.js +141 -6
  299. package/lib/Cloudflare/Workers/DurableObject.js.map +1 -1
  300. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts +2 -185
  301. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
  302. package/lib/Cloudflare/Workers/Vite.d.ts.map +1 -1
  303. package/lib/Cloudflare/Workers/Vite.js +81 -2
  304. package/lib/Cloudflare/Workers/Vite.js.map +1 -1
  305. package/lib/Cloudflare/Workers/Worker.d.ts +15 -1
  306. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  307. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  308. package/lib/Cloudflare/Workers/WorkerAsyncBindings.d.ts.map +1 -1
  309. package/lib/Cloudflare/Workers/WorkerAsyncBindings.js +2 -1
  310. package/lib/Cloudflare/Workers/WorkerAsyncBindings.js.map +1 -1
  311. package/lib/Cloudflare/Workers/WorkerBinding.d.ts +22 -1
  312. package/lib/Cloudflare/Workers/WorkerBinding.d.ts.map +1 -1
  313. package/lib/Cloudflare/Workers/WorkerBinding.js.map +1 -1
  314. package/lib/Cloudflare/Workers/WorkerBridge.d.ts.map +1 -1
  315. package/lib/Cloudflare/Workers/WorkerBridge.js +7 -2
  316. package/lib/Cloudflare/Workers/WorkerBridge.js.map +1 -1
  317. package/lib/Cloudflare/Workers/WorkerProvider.d.ts +81 -0
  318. package/lib/Cloudflare/Workers/WorkerProvider.d.ts.map +1 -1
  319. package/lib/Cloudflare/Workers/WorkerProvider.js +450 -61
  320. package/lib/Cloudflare/Workers/WorkerProvider.js.map +1 -1
  321. package/lib/Cloudflare/Workers/WorkerRuntimeContext.d.ts.map +1 -1
  322. package/lib/Cloudflare/Workers/WorkerRuntimeContext.js +11 -37
  323. package/lib/Cloudflare/Workers/WorkerRuntimeContext.js.map +1 -1
  324. package/lib/Cloudflare/Workers/index.d.ts +1 -0
  325. package/lib/Cloudflare/Workers/index.d.ts.map +1 -1
  326. package/lib/Cloudflare/Workers/index.js +1 -0
  327. package/lib/Cloudflare/Workers/index.js.map +1 -1
  328. package/lib/Diff.d.ts +16 -0
  329. package/lib/Diff.d.ts.map +1 -1
  330. package/lib/Diff.js +33 -0
  331. package/lib/Diff.js.map +1 -1
  332. package/lib/GitHub/Secrets.d.ts +1 -1
  333. package/lib/GitHub/Secrets.js +1 -1
  334. package/lib/GitHub/Variables.d.ts +1 -1
  335. package/lib/GitHub/Variables.js +1 -1
  336. package/lib/Local/RpcSerialization.d.ts.map +1 -1
  337. package/lib/Local/RpcSerialization.js +6 -2
  338. package/lib/Local/RpcSerialization.js.map +1 -1
  339. package/lib/Local/RpcSpawner.d.ts.map +1 -1
  340. package/lib/Local/RpcSpawner.js +14 -8
  341. package/lib/Local/RpcSpawner.js.map +1 -1
  342. package/lib/Neon/AuthProvider.js +1 -1
  343. package/lib/Neon/AuthProvider.js.map +1 -1
  344. package/lib/Plan.d.ts.map +1 -1
  345. package/lib/Plan.js +11 -4
  346. package/lib/Plan.js.map +1 -1
  347. package/lib/Planetscale/Database.d.ts +2 -1
  348. package/lib/Planetscale/Database.d.ts.map +1 -1
  349. package/lib/Planetscale/MySQL/MySQLClusterSize.d.ts +41 -3
  350. package/lib/Planetscale/MySQL/MySQLClusterSize.d.ts.map +1 -1
  351. package/lib/Planetscale/MySQL/MySQLClusterSize.js +88 -11
  352. package/lib/Planetscale/MySQL/MySQLClusterSize.js.map +1 -1
  353. package/lib/Planetscale/MySQL/MySQLDatabase.d.ts +14 -0
  354. package/lib/Planetscale/MySQL/MySQLDatabase.d.ts.map +1 -1
  355. package/lib/Planetscale/MySQL/MySQLDatabase.js +24 -11
  356. package/lib/Planetscale/MySQL/MySQLDatabase.js.map +1 -1
  357. package/lib/Platform.d.ts.map +1 -1
  358. package/lib/Platform.js +11 -1
  359. package/lib/Platform.js.map +1 -1
  360. package/lib/Runtime.d.ts +23 -0
  361. package/lib/Runtime.d.ts.map +1 -1
  362. package/lib/Runtime.js +83 -0
  363. package/lib/Runtime.js.map +1 -1
  364. package/lib/RuntimeContext.d.ts +46 -0
  365. package/lib/RuntimeContext.d.ts.map +1 -1
  366. package/lib/RuntimeContext.js +60 -0
  367. package/lib/RuntimeContext.js.map +1 -1
  368. package/lib/Server/Process.d.ts +1 -1
  369. package/lib/Server/Process.d.ts.map +1 -1
  370. package/lib/Server/Process.js +8 -8
  371. package/lib/Server/Process.js.map +1 -1
  372. package/lib/Stack.js +1 -1
  373. package/lib/Stack.js.map +1 -1
  374. package/lib/State/HttpStateApi.d.ts +10 -10
  375. package/lib/Test/Alchemy.d.ts +74 -0
  376. package/lib/Test/Alchemy.d.ts.map +1 -0
  377. package/lib/Test/Alchemy.js +143 -0
  378. package/lib/Test/Alchemy.js.map +1 -0
  379. package/lib/Util/cached-function.d.ts +1 -1
  380. package/lib/Util/cached-function.d.ts.map +1 -1
  381. package/lib/Util/cached-function.js +2 -2
  382. package/lib/Util/cached-function.js.map +1 -1
  383. package/lib/Util/proxy-chain.js +3 -0
  384. package/lib/Util/proxy-chain.js.map +1 -1
  385. package/package.json +10 -10
  386. package/src/AWS/AuthProvider.ts +1 -1
  387. package/src/AWS/EC2/hosted.ts +2 -1
  388. package/src/AWS/ECS/Task.ts +2 -1
  389. package/src/AWS/Lambda/Function.ts +13 -47
  390. package/src/AWS/Lambda/MicrovmRuntimeContext.ts +11 -38
  391. package/src/Action.ts +39 -6
  392. package/src/ActionRuntimeContext.ts +68 -0
  393. package/src/Apply.ts +46 -8
  394. package/src/Auth/AuthProvider.ts +1 -1
  395. package/src/Auth/Lock.ts +5 -2
  396. package/src/Bundle/PurePlugin.ts +34 -1
  397. package/src/Bundle/Vite.ts +51 -1
  398. package/src/Cli/LoggingCli.ts +7 -4
  399. package/src/Cli/commands/_shared.ts +52 -0
  400. package/src/Cli/commands/login.ts +90 -14
  401. package/src/Cli/commands/profile.ts +7 -41
  402. package/src/Cloudflare/AI/LanguageModel.ts +25 -5
  403. package/src/Cloudflare/AI/QuerySearchLocal.ts +66 -0
  404. package/src/Cloudflare/AI/QuerySearchNamespaceLocal.ts +60 -0
  405. package/src/Cloudflare/AI/SearchHttpClient.ts +423 -0
  406. package/src/Cloudflare/AI/index.ts +2 -0
  407. package/src/Cloudflare/Auth/AuthProvider.ts +1 -1
  408. package/src/Cloudflare/Containers/ContainerBundle.ts +11 -1
  409. package/src/Cloudflare/Containers/ContainerPlatform.ts +14 -52
  410. package/src/Cloudflare/D1/QueryDatabaseHttpClient.ts +176 -0
  411. package/src/Cloudflare/D1/QueryDatabaseLocal.ts +66 -0
  412. package/src/Cloudflare/D1/index.ts +1 -0
  413. package/src/Cloudflare/DNS/DnsHttp.ts +24 -2
  414. package/src/Cloudflare/DNS/DnsLocal.ts +41 -0
  415. package/src/Cloudflare/DNS/ReadDnsHttp.ts +4 -5
  416. package/src/Cloudflare/DNS/ReadDnsLocal.ts +38 -0
  417. package/src/Cloudflare/DNS/ReadWriteDnsHttp.ts +5 -5
  418. package/src/Cloudflare/DNS/ReadWriteDnsLocal.ts +46 -0
  419. package/src/Cloudflare/DNS/WriteDnsHttp.ts +4 -5
  420. package/src/Cloudflare/DNS/WriteDnsLocal.ts +44 -0
  421. package/src/Cloudflare/DNS/index.ts +3 -0
  422. package/src/Cloudflare/Flagship/ReadFlagsHttpClient.ts +183 -0
  423. package/src/Cloudflare/Flagship/ReadFlagsLocal.ts +69 -0
  424. package/src/Cloudflare/Flagship/index.ts +1 -0
  425. package/src/Cloudflare/KV/NamespaceHttp.ts +25 -2
  426. package/src/Cloudflare/KV/NamespaceLocal.ts +42 -0
  427. package/src/Cloudflare/KV/ReadNamespaceHttp.ts +7 -6
  428. package/src/Cloudflare/KV/ReadNamespaceLocal.ts +35 -0
  429. package/src/Cloudflare/KV/ReadWriteNamespaceHttp.ts +11 -6
  430. package/src/Cloudflare/KV/ReadWriteNamespaceLocal.ts +42 -0
  431. package/src/Cloudflare/KV/WriteNamespaceHttp.ts +7 -6
  432. package/src/Cloudflare/KV/WriteNamespaceLocal.ts +35 -0
  433. package/src/Cloudflare/KV/index.ts +3 -0
  434. package/src/Cloudflare/Queues/QueueHttp.ts +24 -2
  435. package/src/Cloudflare/Queues/WriteQueueHttp.ts +16 -7
  436. package/src/Cloudflare/Queues/WriteQueueLocal.ts +64 -0
  437. package/src/Cloudflare/Queues/index.ts +1 -0
  438. package/src/Cloudflare/R2/BucketHttp.ts +20 -3
  439. package/src/Cloudflare/R2/BucketLocal.ts +47 -0
  440. package/src/Cloudflare/R2/ReadBucketHttp.ts +10 -5
  441. package/src/Cloudflare/R2/ReadBucketLocal.ts +33 -0
  442. package/src/Cloudflare/R2/ReadWriteBucketHttp.ts +11 -5
  443. package/src/Cloudflare/R2/ReadWriteBucketLocal.ts +36 -0
  444. package/src/Cloudflare/R2/WriteBucketHttp.ts +10 -5
  445. package/src/Cloudflare/R2/WriteBucketLocal.ts +33 -0
  446. package/src/Cloudflare/R2/index.ts +3 -0
  447. package/src/Cloudflare/Tunnel/ReadTunnel.ts +8 -9
  448. package/src/Cloudflare/Tunnel/ReadTunnelLocal.ts +33 -0
  449. package/src/Cloudflare/Tunnel/ReadWriteTunnel.ts +5 -5
  450. package/src/Cloudflare/Tunnel/ReadWriteTunnelLocal.ts +39 -0
  451. package/src/Cloudflare/Tunnel/TunnelBinding.ts +26 -2
  452. package/src/Cloudflare/Tunnel/TunnelLocalBinding.ts +38 -0
  453. package/src/Cloudflare/Tunnel/WarpConnector.ts +8 -5
  454. package/src/Cloudflare/Tunnel/WriteTunnel.ts +8 -9
  455. package/src/Cloudflare/Tunnel/WriteTunnelLocal.ts +33 -0
  456. package/src/Cloudflare/Tunnel/index.ts +3 -0
  457. package/src/Cloudflare/Vectorize/SearchIndexHttpClient.ts +183 -0
  458. package/src/Cloudflare/Vectorize/SearchIndexLocal.ts +70 -0
  459. package/src/Cloudflare/Vectorize/index.ts +1 -0
  460. package/src/Cloudflare/Workers/BrowserHttpClient.ts +201 -0
  461. package/src/Cloudflare/Workers/BrowserLocal.ts +65 -0
  462. package/src/Cloudflare/Workers/ConfigProvider.ts +15 -1
  463. package/src/Cloudflare/Workers/DurableObject.ts +227 -6
  464. package/src/Cloudflare/Workers/Vite.ts +93 -11
  465. package/src/Cloudflare/Workers/Worker.ts +19 -1
  466. package/src/Cloudflare/Workers/WorkerAsyncBindings.ts +6 -5
  467. package/src/Cloudflare/Workers/WorkerBinding.ts +20 -1
  468. package/src/Cloudflare/Workers/WorkerBridge.ts +12 -2
  469. package/src/Cloudflare/Workers/WorkerProvider.ts +664 -117
  470. package/src/Cloudflare/Workers/WorkerRuntimeContext.ts +14 -45
  471. package/src/Cloudflare/Workers/index.ts +1 -0
  472. package/src/Diff.ts +33 -0
  473. package/src/GitHub/Secrets.ts +1 -1
  474. package/src/GitHub/Variables.ts +1 -1
  475. package/src/Local/RpcSerialization.ts +6 -2
  476. package/src/Local/RpcSpawner.ts +21 -8
  477. package/src/Neon/AuthProvider.ts +1 -1
  478. package/src/Plan.ts +17 -4
  479. package/src/Planetscale/Database.ts +2 -1
  480. package/src/Planetscale/MySQL/MySQLClusterSize.ts +120 -21
  481. package/src/Planetscale/MySQL/MySQLDatabase.ts +84 -44
  482. package/src/Platform.ts +12 -3
  483. package/src/Runtime.ts +92 -0
  484. package/src/RuntimeContext.ts +79 -0
  485. package/src/Server/Process.ts +11 -18
  486. package/src/Stack.ts +1 -1
  487. package/src/Test/Alchemy.ts +282 -0
  488. package/src/Util/cached-function.ts +5 -5
  489. package/src/Util/proxy-chain.ts +3 -0
@@ -2,9 +2,12 @@ import type * as cf from "@cloudflare/workers-types";
2
2
  import * as Effect from "effect/Effect";
3
3
  import * as Layer from "effect/Layer";
4
4
  import * as Option from "effect/Option";
5
- import * as Redacted from "effect/Redacted";
6
5
  import type { HttpEffect } from "../../Http.ts";
7
6
  import * as Output from "../../Output.ts";
7
+ import {
8
+ packEnvValueKeepRedacted,
9
+ unpackEnvValue,
10
+ } from "../../RuntimeContext.ts";
8
11
  import type * as Serverless from "../../Serverless/index.ts";
9
12
  import type { DurableObjectExport } from "./DurableObject.ts";
10
13
  import { makeRequestHandler } from "./HttpServer.ts";
@@ -37,53 +40,19 @@ export const makeWorkerRuntimeContext = (id: string): WorkerRuntimeContext => {
37
40
  get: (key: string) =>
38
41
  Effect.serviceOption(WorkerEnvironment).pipe(
39
42
  Effect.map(Option.getOrUndefined),
40
- // Key is already canonical (see RuntimeContext.sanitizeKey).
41
- Effect.map((env) => env?.[key]),
42
- Effect.map((json) => {
43
- if (json === undefined) {
44
- return undefined;
45
- }
46
- try {
47
- const value = JSON.parse(json);
48
- // The `set` path serializes Redacted values as
49
- // `{_tag: "Redacted", value: ...}`. After JSON.parse the
50
- // result is a plain object — `Redacted.isRedacted` would
51
- // always return `false` on it — so detect the marker shape
52
- // and rebuild the Redacted wrapper. Plain values pass
53
- // through unchanged.
54
- if (
55
- typeof value === "object" &&
56
- value?._tag === "Redacted" &&
57
- "value" in value
58
- ) {
59
- return Redacted.make((value as { value: unknown }).value);
60
- }
61
- return value;
62
- } catch {
63
- return json;
64
- }
65
- }),
43
+ // Key is already canonical (see RuntimeContext.sanitizeKey). Read
44
+ // straight from `WorkerEnvironment` — see `unpackEnvValue` for why
45
+ // this must never resolve through `Config.string`.
46
+ Effect.map((env) => unpackEnvValue(env?.[key])),
66
47
  ) as any,
67
48
  set: (key: string, output: Output.Output) =>
68
49
  Effect.sync(() => {
69
- // Preserve `Redacted`-ness across the Output → env → Cloudflare
70
- // binding boundary so the put-worker loop can deploy secrets via
71
- // `secret_text` instead of leaking them as `plain_text`. The JSON
72
- // payload still carries the `{_tag: "Redacted", …}` marker so the
73
- // runtime `get` accessor can rebuild the wrapper after Cloudflare
74
- // hands the binding back as a plain string.
75
- env[key] = output.pipe(
76
- Output.map((value) =>
77
- Redacted.isRedacted(value)
78
- ? Redacted.make(
79
- JSON.stringify({
80
- _tag: "Redacted",
81
- value: Redacted.value(value),
82
- }),
83
- )
84
- : JSON.stringify(value),
85
- ),
86
- );
50
+ // `packEnvValueKeepRedacted` keeps the Redacted wrapper on the
51
+ // outside so the put-worker loop can deploy secrets via
52
+ // `secret_text` instead of leaking them as `plain_text`, while the
53
+ // inner marker lets the runtime `get` accessor rebuild the wrapper
54
+ // after Cloudflare hands the binding back as a plain string.
55
+ env[key] = output.pipe(Output.map(packEnvValueKeepRedacted));
87
56
  return key;
88
57
  }),
89
58
  serve: <Req = never>(
@@ -2,6 +2,7 @@ export * from "./AccountSetting.ts";
2
2
  export * from "./Assets.ts";
3
3
  export * from "./Browser.ts";
4
4
  export * from "./BrowserBinding.ts";
5
+ export * from "./BrowserLocal.ts";
5
6
  export * from "./Cache.ts";
6
7
  export * from "./ConfigProvider.ts";
7
8
  export * from "./CronEventSource.ts";
package/src/Diff.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as Duration from "effect/Duration";
1
2
  import * as Effect from "effect/Effect";
2
3
  import * as Redacted from "effect/Redacted";
3
4
  import type { Input } from "./Input.ts";
@@ -53,6 +54,38 @@ const _hasUnresolved = (value: unknown): boolean => {
53
54
  return false;
54
55
  };
55
56
 
57
+ /**
58
+ * Deeply replace every unresolved plan-time expression (an `Output`/`Expr`
59
+ * or an un-evaluated `Effect`) with `undefined`, leaving resolved values
60
+ * (including opaque `Redacted`/`Duration` instances) intact.
61
+ *
62
+ * Persisted resource state must only ever hold plain data. Durable (JSON)
63
+ * state stores already enforce this implicitly — Output proxies are
64
+ * function-typed, so `JSON.stringify` silently drops them — but the
65
+ * in-memory store used by tests retains live proxies, which would later be
66
+ * fed back into provider lifecycle operations as `olds` after an
67
+ * interrupted apply (e.g. `read` during a destroy plan) and blow up on
68
+ * first string coercion. Sanitizing at the commit boundary keeps both
69
+ * store kinds consistent with the provider contract that `olds` is
70
+ * resolved `Props`.
71
+ */
72
+ export const stripUnresolved = <T>(value: T): T => _stripUnresolved(value) as T;
73
+
74
+ const _stripUnresolved = (value: unknown): unknown => {
75
+ if (value == null || isPrimitive(value)) return value;
76
+ if (Output.isExpr(value) || Effect.isEffect(value)) return undefined;
77
+ // Opaque resolved values — rebuilding them structurally would strip
78
+ // their prototype (see resolveInput in Plan.ts for the same rule).
79
+ if (Redacted.isRedacted(value) || Duration.isDuration(value)) return value;
80
+ if (Array.isArray(value)) return value.map(_stripUnresolved);
81
+ if (typeof value === "object") {
82
+ return Object.fromEntries(
83
+ Object.entries(value).map(([key, item]) => [key, _stripUnresolved(item)]),
84
+ );
85
+ }
86
+ return value;
87
+ };
88
+
56
89
  export const somePropsAreDifferent = <Props extends Record<string, any>>(
57
90
  olds: Props,
58
91
  news: Props,
@@ -41,7 +41,7 @@ export interface SecretsProps {
41
41
  * ```ts
42
42
  * yield* GitHub.Secrets({
43
43
  * owner: "alchemy-run",
44
- * repository: "alchemy-effect",
44
+ * repository: "alchemy",
45
45
  * secrets: {
46
46
  * AXIOM_INGEST_TOKEN: tokenValue,
47
47
  * AXIOM_DATASET_TRACES: traces.name,
@@ -33,7 +33,7 @@ export interface VariablesProps {
33
33
  * ```ts
34
34
  * yield* GitHub.Variables({
35
35
  * owner: "alchemy-run",
36
- * repository: "alchemy-effect",
36
+ * repository: "alchemy",
37
37
  * variables: {
38
38
  * AWS_ROLE_ARN: role.roleArn,
39
39
  * AWS_REGION: region,
@@ -7,6 +7,7 @@ import * as Schema from "effect/Schema";
7
7
  import * as Stream from "effect/Stream";
8
8
  import * as NodeUtil from "node:util";
9
9
  import * as Output from "../Output.ts";
10
+ import { isRedactedMarker, type RedactedMarker } from "../RuntimeContext.ts";
10
11
 
11
12
  type RpcEffectHandler<Args extends Array<any>, Success, Error> = (
12
13
  ...args: Args
@@ -173,7 +174,10 @@ const unwrapRpcStreamHandler = <Args extends Array<any>, Success, Error>(
173
174
 
174
175
  const serializeRpcArgs = (value: unknown): unknown => {
175
176
  if (Redacted.isRedacted(value)) {
176
- return { _tag: "Redacted", value: Redacted.value(value) };
177
+ return {
178
+ _tag: "Redacted",
179
+ value: Redacted.value(value),
180
+ } satisfies RedactedMarker;
177
181
  }
178
182
  if (Output.isOutput(value)) {
179
183
  return {
@@ -204,7 +208,7 @@ const deserializeRpcArgs = (value: unknown): unknown => {
204
208
  } else if (typeof value === "object" && value !== null) {
205
209
  // These values are serialized as `{_tag: "Redacted", value: ...}` and `{_tag: "Output", description: ...}`,
206
210
  // so we need to detect them manually - Redacted.isRedacted and Output.isOutput do not work.
207
- if ("_tag" in value && value._tag === "Redacted" && "value" in value) {
211
+ if (isRedactedMarker(value)) {
208
212
  return Redacted.make(value.value);
209
213
  } else if (
210
214
  "_tag" in value &&
@@ -1,5 +1,6 @@
1
1
  import { exitHook } from "@alchemy.run/node-utils/exit-hook";
2
2
  import * as Cache from "effect/Cache";
3
+ import * as Console from "effect/Console";
3
4
  import * as Context from "effect/Context";
4
5
  import * as Deferred from "effect/Deferred";
5
6
  import * as Effect from "effect/Effect";
@@ -78,7 +79,11 @@ export const make = Effect.fn(function* ({
78
79
  }[bin],
79
80
  {
80
81
  stdout: "pipe",
81
- stderr: "inherit",
82
+ // Piped (NOT inherited) so the child's output routes through the
83
+ // Effect Console service: raw writes to the parent's fd corrupt the
84
+ // test runner's reporter/TUI. The drain below is mandatory — an
85
+ // unread pipe eventually fills and blocks the child.
86
+ stderr: "pipe",
82
87
  detached: false,
83
88
  env: {
84
89
  [RPC_SERVER_ENVIRONMENT_KEY]: JSON.stringify(environment),
@@ -87,6 +92,13 @@ export const make = Effect.fn(function* ({
87
92
  },
88
93
  );
89
94
  const handle = yield* spawner.spawn(command);
95
+ yield* handle.stderr.pipe(
96
+ Stream.decodeText,
97
+ Stream.splitLines,
98
+ Stream.runForEach((line) => Console.error(line)),
99
+ Effect.ignore,
100
+ Effect.forkScoped,
101
+ );
90
102
  const unregister = exitHook(() => {
91
103
  killProcessGroup(handle.pid, "SIGKILL");
92
104
  });
@@ -168,13 +180,14 @@ const getRpcAddress = (stdout: Stream.Stream<Uint8Array, PlatformError>) =>
168
180
  Stream.splitLines,
169
181
  Stream.runForEach((line) => {
170
182
  if (done) {
171
- console.log(line);
172
- } else {
173
- const match = line.match(RPC_ADDRESS_REGEX);
174
- if (match) {
175
- done = true;
176
- return Deferred.succeed(address, match[2]);
177
- }
183
+ // Through the Console SERVICE so runners that override it (e.g.
184
+ // alchemy-test's per-test buffer) capture the sidecar's output.
185
+ return Console.log(line);
186
+ }
187
+ const match = line.match(RPC_ADDRESS_REGEX);
188
+ if (match) {
189
+ done = true;
190
+ return Deferred.succeed(address, match[2]);
178
191
  }
179
192
  return Effect.void;
180
193
  }),
@@ -129,7 +129,7 @@ export const NeonAuth = AuthProviderLayer<
129
129
  ? Effect.fail(
130
130
  new AuthError({
131
131
  message:
132
- "Neon stored credentials not found. Run: alchemy-effect login --configure",
132
+ "Neon stored credentials not found. Run: alchemy login --configure",
133
133
  }),
134
134
  )
135
135
  : Effect.succeed({
package/src/Plan.ts CHANGED
@@ -543,7 +543,18 @@ export const make = <A>(
543
543
  (action) =>
544
544
  [
545
545
  action.FQN,
546
- Object.values(Output.upstreamAny(action.Input)).map((r) => r.FQN),
546
+ // An Action depends on the resources referenced by its Input *and*
547
+ // any Output captured via `yield* output` inside its init Effect.
548
+ Array.from(
549
+ new Set([
550
+ ...Object.values(Output.upstreamAny(action.Input)).map(
551
+ (r) => r.FQN,
552
+ ),
553
+ ...Object.values(Output.upstreamAny(action.Captures)).map(
554
+ (r) => r.FQN,
555
+ ),
556
+ ]),
557
+ ),
547
558
  ] as const,
548
559
  ),
549
560
  ]);
@@ -572,7 +583,8 @@ export const make = <A>(
572
583
  const bindDeps = bindingUpstreamDependencies[fqn] ?? [];
573
584
  return [fqn, [...new Set([...propDeps, ...bindDeps])]];
574
585
  }),
575
- // Actions have no bindings — their upstream is purely their input.
586
+ // Actions have no bindings — their upstream is input + init captures,
587
+ // both already folded into newUpstreamDependencies above.
576
588
  ...actions.map((action): [string, string[]] => {
577
589
  const fqn = action.FQN;
578
590
  return [fqn, newUpstreamDependencies[fqn] ?? []];
@@ -717,7 +729,7 @@ export const make = <A>(
717
729
  // If planning persisted here, a mere `alchemy plan` / `--dry-run`
718
730
  // would claim ownership of an unowned cloud resource, arming a
719
731
  // later unrelated deploy to orphan-delete it. See
720
- // https://github.com/alchemy-run/alchemy-effect/issues/793.
732
+ // https://github.com/alchemy-run/alchemy/issues/793.
721
733
  //
722
734
  // After a cold-start adoption (engine just discovered an
723
735
  // existing cloud resource via `read`), force the engine's
@@ -784,7 +796,7 @@ export const make = <A>(
784
796
  // The adopted state rides onto the plan node via `oldState`
785
797
  // (→ `node.state`) and is persisted at APPLY time by the
786
798
  // update lifecycle's `updating` / `updated` commits. See
787
- // https://github.com/alchemy-run/alchemy-effect/issues/793.
799
+ // https://github.com/alchemy-run/alchemy/issues/793.
788
800
  oldState = adoptedState;
789
801
  forceUpdateAfterAdoption = true;
790
802
  }
@@ -1212,6 +1224,7 @@ export const make = <A>(
1212
1224
  LogicalId: logicalId,
1213
1225
  Type: persisted.actionType,
1214
1226
  Input: persisted.input,
1227
+ Captures: {},
1215
1228
  Run: () => undefined as any,
1216
1229
  Output: undefined as any,
1217
1230
  } satisfies ActionLike,
@@ -29,7 +29,8 @@ export interface BaseDatabaseProps {
29
29
 
30
30
  /**
31
31
  * Number of replicas for the database. `0` for non-HA, `2+` for HA.
32
- * Create-only.
32
+ * Create-only for PostgreSQL databases; MySQL databases reconcile
33
+ * changes in place ({@link MySQLDatabaseProps.replicas}).
33
34
  */
34
35
  replicas?: number;
35
36
 
@@ -1,6 +1,7 @@
1
1
  import * as ops from "@distilled.cloud/planetscale/Operations";
2
2
  import * as Effect from "effect/Effect";
3
- import { pollUntil } from "../Util.ts";
3
+ import * as Schedule from "effect/Schedule";
4
+ import { PlanetscaleConflict, pollUntil } from "../Util.ts";
4
5
 
5
6
  /**
6
7
  * Available PlanetScale MySQL (Vitess) cluster sizes.
@@ -55,15 +56,15 @@ export const waitForKeyspaceReady = Effect.fn(function* (
55
56
  });
56
57
 
57
58
  /**
58
- * Ensures the default keyspace of a MySQL production branch has the
59
- * expected cluster size, triggering a resize if it doesn't. Cluster sizes
60
- * can only be configured on production branches.
59
+ * Observes the default keyspace of a branch. The default keyspace usually
60
+ * shares the database's name, but a renamed database keeps its original
61
+ * keyspace name, so prefer the `default` flag and fall back to name
62
+ * matching.
61
63
  */
62
- export const ensureMySQLProductionBranchClusterSize = Effect.fn(function* (
64
+ const observeDefaultKeyspace = Effect.fn(function* (
63
65
  organization: string,
64
66
  database: string,
65
67
  branch: string,
66
- expectedClusterSize: MySQLClusterSize,
67
68
  ) {
68
69
  const keyspaces = yield* ops.listKeyspaces({
69
70
  organization,
@@ -72,31 +73,129 @@ export const ensureMySQLProductionBranchClusterSize = Effect.fn(function* (
72
73
  page: 1,
73
74
  per_page: 100,
74
75
  });
75
- // Default keyspace is always the same name as the database.
76
- const defaultKeyspace = keyspaces.data.find((x) => x.name === database);
77
- if (!defaultKeyspace) {
76
+ return (
77
+ keyspaces.data.find((x) => x.default) ??
78
+ keyspaces.data.find((x) => x.name === database)
79
+ );
80
+ });
81
+
82
+ /**
83
+ * Observes the total replica count of a branch's default keyspace, or
84
+ * `undefined` when the branch or keyspace does not exist (yet).
85
+ */
86
+ export const observeDefaultKeyspaceReplicas = Effect.fn(function* (
87
+ organization: string,
88
+ database: string,
89
+ branch: string,
90
+ ) {
91
+ return yield* observeDefaultKeyspace(organization, database, branch).pipe(
92
+ Effect.map((keyspace) => keyspace?.replicas),
93
+ Effect.catchTag("NotFound", () => Effect.succeed(undefined)),
94
+ );
95
+ });
96
+
97
+ /**
98
+ * Ensures the default keyspace of a MySQL production branch has the
99
+ * expected cluster size and (optionally) total replica count, driving
100
+ * PlanetScale's in-place keyspace resize lifecycle when it doesn't.
101
+ * Cluster sizes can only be configured on production branches. Returns
102
+ * the final observed keyspace.
103
+ */
104
+ export const ensureMySQLProductionBranchClusterSize = Effect.fn(function* (
105
+ organization: string,
106
+ database: string,
107
+ branch: string,
108
+ expectedClusterSize: MySQLClusterSize,
109
+ expectedReplicas?: number,
110
+ ) {
111
+ let keyspace = yield* observeDefaultKeyspace(organization, database, branch);
112
+ if (!keyspace) {
78
113
  return yield* Effect.die(`No default keyspace found for branch ${branch}`);
79
114
  }
80
115
 
81
- yield* waitForKeyspaceReady(
82
- organization,
83
- database,
84
- branch,
85
- defaultKeyspace.name,
86
- );
116
+ yield* waitForKeyspaceReady(organization, database, branch, keyspace.name);
87
117
 
88
- if (defaultKeyspace.cluster_name !== expectedClusterSize) {
118
+ if (keyspace.cluster_name !== expectedClusterSize) {
89
119
  yield* ops.updateBranchClusterConfig({
90
120
  organization,
91
121
  database,
92
122
  branch,
93
123
  cluster_size: expectedClusterSize,
94
124
  });
95
- yield* waitForKeyspaceReady(
96
- organization,
97
- database,
98
- branch,
99
- defaultKeyspace.name,
125
+ yield* waitForKeyspaceReady(organization, database, branch, keyspace.name);
126
+ // Re-observe so the replica sync below diffs against the post-resize
127
+ // keyspace state.
128
+ keyspace =
129
+ (yield* observeDefaultKeyspace(organization, database, branch)) ??
130
+ keyspace;
131
+ }
132
+
133
+ // Sync replicas — MySQL databases cannot configure replicas at
134
+ // creation time (the API rejects the `replicas` param for mysql), so
135
+ // the desired total replica count is converged in place via a keyspace
136
+ // resize request.
137
+ if (
138
+ expectedReplicas !== undefined &&
139
+ keyspace.replicas !== expectedReplicas
140
+ ) {
141
+ // Each cluster size includes a fixed number of replicas (2 for
142
+ // production PS_* sizes); the resize API only accepts the count of
143
+ // additional replicas beyond that.
144
+ const includedReplicas = keyspace.replicas - keyspace.extra_replicas;
145
+ const extraReplicas = expectedReplicas - includedReplicas;
146
+ if (extraReplicas < 0) {
147
+ return yield* Effect.fail(
148
+ new PlanetscaleConflict({
149
+ message:
150
+ `Cannot set replicas to ${expectedReplicas} on keyspace "${keyspace.name}": ` +
151
+ `cluster size ${keyspace.cluster_name} always includes ${includedReplicas} replicas. ` +
152
+ `Set replicas to ${includedReplicas} or more (or omit it).`,
153
+ }),
154
+ );
155
+ }
156
+
157
+ const resize = yield* ops
158
+ .createKeyspaceResizeRequest({
159
+ organization,
160
+ database,
161
+ branch,
162
+ keyspace: keyspace.name,
163
+ extra_replicas: extraReplicas,
164
+ })
165
+ .pipe(
166
+ // A prior resize (e.g. the cluster-size change above) can still
167
+ // be finalizing after the keyspace reports `resizing: false`;
168
+ // PlanetScale rejects new resize requests during that window.
169
+ Effect.retry({
170
+ while: (e): boolean =>
171
+ e._tag === "UnprocessableEntity" &&
172
+ e.message.includes("resize in progress"),
173
+ schedule: Schedule.max([
174
+ Schedule.spaced("5 seconds"),
175
+ Schedule.recurs(120),
176
+ ]),
177
+ }),
178
+ );
179
+
180
+ yield* pollUntil(
181
+ `keyspace "${keyspace.name}" resize completed`,
182
+ ops.listKeyspaceResizeRequests({
183
+ organization,
184
+ database,
185
+ branch,
186
+ keyspace: keyspace.name,
187
+ }),
188
+ (page) => {
189
+ const request = page.data.find((r) => r.id === resize.id);
190
+ // If the request is missing, treat as settled (caller re-observes).
191
+ return request ? request.state === "completed" : true;
192
+ },
100
193
  );
194
+
195
+ keyspace =
196
+ (yield* observeDefaultKeyspace(organization, database, branch)) ??
197
+ keyspace;
101
198
  }
199
+
200
+ return keyspace;
102
201
  });