alchemy 2.0.0-beta.43 → 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 (561) hide show
  1. package/bin/cli.js +18 -5
  2. package/bin/exec.js +381 -240
  3. package/bin/exec.js.map +1 -1
  4. package/lib/AWS/Lambda/Function.d.ts +17 -0
  5. package/lib/AWS/Lambda/Function.d.ts.map +1 -1
  6. package/lib/AWS/Lambda/Function.js +61 -16
  7. package/lib/AWS/Lambda/Function.js.map +1 -1
  8. package/lib/AWS/Providers.d.ts +2 -1
  9. package/lib/AWS/Providers.d.ts.map +1 -1
  10. package/lib/AWS/Providers.js +3 -1
  11. package/lib/AWS/Providers.js.map +1 -1
  12. package/lib/Apply.js +17 -1
  13. package/lib/Apply.js.map +1 -1
  14. package/lib/Auth/AuthProvider.d.ts.map +1 -1
  15. package/lib/Auth/AuthProvider.js +24 -6
  16. package/lib/Auth/AuthProvider.js.map +1 -1
  17. package/lib/Auth/Credentials.d.ts.map +1 -1
  18. package/lib/Auth/Credentials.js +3 -3
  19. package/lib/Auth/Credentials.js.map +1 -1
  20. package/lib/Auth/Lock.js +2 -2
  21. package/lib/Auth/Lock.js.map +1 -1
  22. package/lib/Bundle/Bundle.d.ts +11 -0
  23. package/lib/Bundle/Bundle.d.ts.map +1 -1
  24. package/lib/Bundle/Bundle.js +19 -12
  25. package/lib/Bundle/Bundle.js.map +1 -1
  26. package/lib/Bundle/BundleAnalyzerPlugin.d.ts +25 -0
  27. package/lib/Bundle/BundleAnalyzerPlugin.d.ts.map +1 -0
  28. package/lib/Bundle/BundleAnalyzerPlugin.js +16 -0
  29. package/lib/Bundle/BundleAnalyzerPlugin.js.map +1 -0
  30. package/lib/Bundle/RawPlugin.d.ts +36 -0
  31. package/lib/Bundle/RawPlugin.d.ts.map +1 -0
  32. package/lib/Bundle/RawPlugin.js +80 -0
  33. package/lib/Bundle/RawPlugin.js.map +1 -0
  34. package/lib/Bundle/index.d.ts +2 -0
  35. package/lib/Bundle/index.d.ts.map +1 -1
  36. package/lib/Bundle/index.js +2 -0
  37. package/lib/Bundle/index.js.map +1 -1
  38. package/lib/Cli/commands/_shared.d.ts +13 -1
  39. package/lib/Cli/commands/_shared.d.ts.map +1 -1
  40. package/lib/Cli/commands/_shared.js +33 -2
  41. package/lib/Cli/commands/_shared.js.map +1 -1
  42. package/lib/Cli/commands/dev.d.ts +3 -2
  43. package/lib/Cli/commands/dev.d.ts.map +1 -1
  44. package/lib/Cli/commands/dev.js +19 -2
  45. package/lib/Cli/commands/dev.js.map +1 -1
  46. package/lib/Cli/commands/login.d.ts.map +1 -1
  47. package/lib/Cli/commands/login.js +19 -5
  48. package/lib/Cli/commands/login.js.map +1 -1
  49. package/lib/Cli/commands/profile.d.ts.map +1 -1
  50. package/lib/Cli/commands/profile.js +7 -27
  51. package/lib/Cli/commands/profile.js.map +1 -1
  52. package/lib/Cli/exec.d.ts.map +1 -1
  53. package/lib/Cli/exec.js +2 -1
  54. package/lib/Cli/exec.js.map +1 -1
  55. package/lib/Cli/main.d.ts.map +1 -1
  56. package/lib/Cli/main.js +0 -2
  57. package/lib/Cli/main.js.map +1 -1
  58. package/lib/Cloudflare/AiGateway/AiGateway.d.ts +0 -2
  59. package/lib/Cloudflare/AiGateway/AiGateway.d.ts.map +1 -1
  60. package/lib/Cloudflare/AiGateway/AiGateway.js +2 -4
  61. package/lib/Cloudflare/AiGateway/AiGateway.js.map +1 -1
  62. package/lib/Cloudflare/BrowserRendering/BrowserRendering.d.ts +116 -0
  63. package/lib/Cloudflare/BrowserRendering/BrowserRendering.d.ts.map +1 -0
  64. package/lib/Cloudflare/BrowserRendering/BrowserRendering.js +92 -0
  65. package/lib/Cloudflare/BrowserRendering/BrowserRendering.js.map +1 -0
  66. package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.d.ts +55 -0
  67. package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.d.ts.map +1 -0
  68. package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.js +55 -0
  69. package/lib/Cloudflare/BrowserRendering/BrowserRenderingBinding.js.map +1 -0
  70. package/lib/Cloudflare/BrowserRendering/index.d.ts +3 -0
  71. package/lib/Cloudflare/BrowserRendering/index.d.ts.map +1 -0
  72. package/lib/Cloudflare/BrowserRendering/index.js +3 -0
  73. package/lib/Cloudflare/BrowserRendering/index.js.map +1 -0
  74. package/lib/Cloudflare/Container/Container.d.ts +3 -3
  75. package/lib/Cloudflare/Container/Container.js +3 -3
  76. package/lib/Cloudflare/Container/StartContainer.d.ts.map +1 -1
  77. package/lib/Cloudflare/Container/StartContainer.js.map +1 -1
  78. package/lib/Cloudflare/D1/D1Database.d.ts +1 -0
  79. package/lib/Cloudflare/D1/D1Database.d.ts.map +1 -1
  80. package/lib/Cloudflare/D1/D1Database.js +2 -1
  81. package/lib/Cloudflare/D1/D1Database.js.map +1 -1
  82. package/lib/Cloudflare/D1/D1DatabaseBinding.js +1 -1
  83. package/lib/Cloudflare/D1/D1DatabaseBinding.js.map +1 -1
  84. package/lib/Cloudflare/Fetcher.d.ts.map +1 -1
  85. package/lib/Cloudflare/Fetcher.js +0 -2
  86. package/lib/Cloudflare/Fetcher.js.map +1 -1
  87. package/lib/Cloudflare/Hyperdrive/Hyperdrive.d.ts +1 -0
  88. package/lib/Cloudflare/Hyperdrive/Hyperdrive.d.ts.map +1 -1
  89. package/lib/Cloudflare/Hyperdrive/Hyperdrive.js +3 -0
  90. package/lib/Cloudflare/Hyperdrive/Hyperdrive.js.map +1 -1
  91. package/lib/Cloudflare/Hyperdrive/HyperdriveBinding.d.ts +3 -2
  92. package/lib/Cloudflare/Hyperdrive/HyperdriveBinding.d.ts.map +1 -1
  93. package/lib/Cloudflare/Hyperdrive/HyperdriveBinding.js +32 -33
  94. package/lib/Cloudflare/Hyperdrive/HyperdriveBinding.js.map +1 -1
  95. package/lib/Cloudflare/KV/KVNamespace.d.ts +1 -0
  96. package/lib/Cloudflare/KV/KVNamespace.d.ts.map +1 -1
  97. package/lib/Cloudflare/KV/KVNamespace.js +2 -0
  98. package/lib/Cloudflare/KV/KVNamespace.js.map +1 -1
  99. package/lib/Cloudflare/Local.d.ts +2 -0
  100. package/lib/Cloudflare/Local.d.ts.map +1 -0
  101. package/lib/Cloudflare/Local.js +9 -0
  102. package/lib/Cloudflare/Local.js.map +1 -0
  103. package/lib/Cloudflare/Providers.d.ts +2 -1
  104. package/lib/Cloudflare/Providers.d.ts.map +1 -1
  105. package/lib/Cloudflare/Providers.js +23 -17
  106. package/lib/Cloudflare/Providers.js.map +1 -1
  107. package/lib/Cloudflare/Queue/Queue.d.ts +1 -0
  108. package/lib/Cloudflare/Queue/Queue.d.ts.map +1 -1
  109. package/lib/Cloudflare/Queue/Queue.js +1 -0
  110. package/lib/Cloudflare/Queue/Queue.js.map +1 -1
  111. package/lib/Cloudflare/Queue/QueueConsumer.d.ts +2 -1
  112. package/lib/Cloudflare/Queue/QueueConsumer.d.ts.map +1 -1
  113. package/lib/Cloudflare/Queue/QueueConsumer.js +11 -3
  114. package/lib/Cloudflare/Queue/QueueConsumer.js.map +1 -1
  115. package/lib/Cloudflare/Queue/QueueEventSource.d.ts +30 -4
  116. package/lib/Cloudflare/Queue/QueueEventSource.d.ts.map +1 -1
  117. package/lib/Cloudflare/Queue/QueueEventSource.js +22 -1
  118. package/lib/Cloudflare/Queue/QueueEventSource.js.map +1 -1
  119. package/lib/Cloudflare/R2/R2Bucket.d.ts +1 -0
  120. package/lib/Cloudflare/R2/R2Bucket.d.ts.map +1 -1
  121. package/lib/Cloudflare/R2/R2Bucket.js +18 -0
  122. package/lib/Cloudflare/R2/R2Bucket.js.map +1 -1
  123. package/lib/Cloudflare/SecretsStore/Secret.d.ts.map +1 -1
  124. package/lib/Cloudflare/SecretsStore/Secret.js +13 -34
  125. package/lib/Cloudflare/SecretsStore/Secret.js.map +1 -1
  126. package/lib/Cloudflare/SecretsStore/SecretBinding.d.ts +3 -2
  127. package/lib/Cloudflare/SecretsStore/SecretBinding.d.ts.map +1 -1
  128. package/lib/Cloudflare/SecretsStore/SecretBinding.js +3 -2
  129. package/lib/Cloudflare/SecretsStore/SecretBinding.js.map +1 -1
  130. package/lib/Cloudflare/StateStore/Api.d.ts +5 -13
  131. package/lib/Cloudflare/StateStore/Api.d.ts.map +1 -1
  132. package/lib/Cloudflare/StateStore/Api.js +14 -8
  133. package/lib/Cloudflare/StateStore/Api.js.map +1 -1
  134. package/lib/Cloudflare/StateStore/State.d.ts.map +1 -1
  135. package/lib/Cloudflare/StateStore/State.js +45 -9
  136. package/lib/Cloudflare/StateStore/State.js.map +1 -1
  137. package/lib/Cloudflare/StateStore/Store.d.ts.map +1 -1
  138. package/lib/Cloudflare/StateStore/Store.js +5 -2
  139. package/lib/Cloudflare/StateStore/Store.js.map +1 -1
  140. package/lib/Cloudflare/VpcService/VpcService.d.ts +2 -2
  141. package/lib/Cloudflare/VpcService/VpcService.d.ts.map +1 -1
  142. package/lib/Cloudflare/Website/StaticSite.d.ts +5 -5
  143. package/lib/Cloudflare/Website/StaticSite.d.ts.map +1 -1
  144. package/lib/Cloudflare/Website/StaticSite.js +3 -0
  145. package/lib/Cloudflare/Website/StaticSite.js.map +1 -1
  146. package/lib/Cloudflare/Website/Vite.d.ts +5 -5
  147. package/lib/Cloudflare/Website/Vite.d.ts.map +1 -1
  148. package/lib/Cloudflare/Website/Vite.js.map +1 -1
  149. package/lib/Cloudflare/Workers/Assets.d.ts.map +1 -1
  150. package/lib/Cloudflare/Workers/Assets.js +1 -1
  151. package/lib/Cloudflare/Workers/Assets.js.map +1 -1
  152. package/lib/Cloudflare/Workers/DurableObjectBridge.d.ts.map +1 -1
  153. package/lib/Cloudflare/Workers/DurableObjectBridge.js +4 -3
  154. package/lib/Cloudflare/Workers/DurableObjectBridge.js.map +1 -1
  155. package/lib/Cloudflare/Workers/DurableObjectNamespace.d.ts +183 -6
  156. package/lib/Cloudflare/Workers/DurableObjectNamespace.d.ts.map +1 -1
  157. package/lib/Cloudflare/Workers/DurableObjectNamespace.js +279 -76
  158. package/lib/Cloudflare/Workers/DurableObjectNamespace.js.map +1 -1
  159. package/lib/Cloudflare/Workers/HttpServer.d.ts +6 -4
  160. package/lib/Cloudflare/Workers/HttpServer.d.ts.map +1 -1
  161. package/lib/Cloudflare/Workers/HttpServer.js +20 -15
  162. package/lib/Cloudflare/Workers/HttpServer.js.map +1 -1
  163. package/lib/Cloudflare/Workers/InferEnv.d.ts +3 -2
  164. package/lib/Cloudflare/Workers/InferEnv.d.ts.map +1 -1
  165. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts +19 -3
  166. package/lib/Cloudflare/Workers/LocalWorkerProvider.d.ts.map +1 -1
  167. package/lib/Cloudflare/Workers/LocalWorkerProvider.js +458 -21
  168. package/lib/Cloudflare/Workers/LocalWorkerProvider.js.map +1 -1
  169. package/lib/Cloudflare/Workers/Rpc.d.ts +16 -0
  170. package/lib/Cloudflare/Workers/Rpc.d.ts.map +1 -1
  171. package/lib/Cloudflare/Workers/Rpc.js +22 -0
  172. package/lib/Cloudflare/Workers/Rpc.js.map +1 -1
  173. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.d.ts +285 -0
  174. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.d.ts.map +1 -0
  175. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.js +288 -0
  176. package/lib/Cloudflare/Workers/RpcDurableObjectNamespace.js.map +1 -0
  177. package/lib/Cloudflare/Workers/RpcWorker.d.ts +305 -0
  178. package/lib/Cloudflare/Workers/RpcWorker.d.ts.map +1 -0
  179. package/lib/Cloudflare/Workers/RpcWorker.js +350 -0
  180. package/lib/Cloudflare/Workers/RpcWorker.js.map +1 -0
  181. package/lib/Cloudflare/Workers/Vite.d.ts +1 -1
  182. package/lib/Cloudflare/Workers/Vite.d.ts.map +1 -1
  183. package/lib/Cloudflare/Workers/Vite.js +2 -1
  184. package/lib/Cloudflare/Workers/Vite.js.map +1 -1
  185. package/lib/Cloudflare/Workers/Worker.d.ts +69 -37
  186. package/lib/Cloudflare/Workers/Worker.d.ts.map +1 -1
  187. package/lib/Cloudflare/Workers/Worker.js +171 -51
  188. package/lib/Cloudflare/Workers/Worker.js.map +1 -1
  189. package/lib/Cloudflare/Workers/WorkerAsyncBindings.d.ts +1 -1
  190. package/lib/Cloudflare/Workers/WorkerAsyncBindings.d.ts.map +1 -1
  191. package/lib/Cloudflare/Workers/WorkerAsyncBindings.js +158 -97
  192. package/lib/Cloudflare/Workers/WorkerAsyncBindings.js.map +1 -1
  193. package/lib/Cloudflare/Workers/WorkerBinding.d.ts +11 -23
  194. package/lib/Cloudflare/Workers/WorkerBinding.d.ts.map +1 -1
  195. package/lib/Cloudflare/Workers/WorkerBinding.js +3 -0
  196. package/lib/Cloudflare/Workers/WorkerBinding.js.map +1 -1
  197. package/lib/Cloudflare/Workers/WorkerBridge.d.ts.map +1 -1
  198. package/lib/Cloudflare/Workers/WorkerBridge.js +8 -7
  199. package/lib/Cloudflare/Workers/WorkerBridge.js.map +1 -1
  200. package/lib/Cloudflare/Workers/WorkerBundle.d.ts +1 -2
  201. package/lib/Cloudflare/Workers/WorkerBundle.d.ts.map +1 -1
  202. package/lib/Cloudflare/Workers/WorkerBundle.js +7 -7
  203. package/lib/Cloudflare/Workers/WorkerBundle.js.map +1 -1
  204. package/lib/Cloudflare/Workers/WorkerRuntimeContext.d.ts.map +1 -1
  205. package/lib/Cloudflare/Workers/WorkerRuntimeContext.js +9 -10
  206. package/lib/Cloudflare/Workers/WorkerRuntimeContext.js.map +1 -1
  207. package/lib/Cloudflare/Workers/Workflow.d.ts +5 -3
  208. package/lib/Cloudflare/Workers/Workflow.d.ts.map +1 -1
  209. package/lib/Cloudflare/Workers/Workflow.js +19 -1
  210. package/lib/Cloudflare/Workers/Workflow.js.map +1 -1
  211. package/lib/Cloudflare/Workers/index.d.ts +2 -0
  212. package/lib/Cloudflare/Workers/index.d.ts.map +1 -1
  213. package/lib/Cloudflare/Workers/index.js +2 -0
  214. package/lib/Cloudflare/Workers/index.js.map +1 -1
  215. package/lib/Cloudflare/Zaraz/ZarazConfig.d.ts +184 -0
  216. package/lib/Cloudflare/Zaraz/ZarazConfig.d.ts.map +1 -0
  217. package/lib/Cloudflare/Zaraz/ZarazConfig.js +216 -0
  218. package/lib/Cloudflare/Zaraz/ZarazConfig.js.map +1 -0
  219. package/lib/Cloudflare/Zaraz/ZarazEventTypes.d.ts +188 -0
  220. package/lib/Cloudflare/Zaraz/ZarazEventTypes.d.ts.map +1 -0
  221. package/lib/Cloudflare/Zaraz/ZarazEventTypes.js +4 -0
  222. package/lib/Cloudflare/Zaraz/ZarazEventTypes.js.map +1 -0
  223. package/lib/Cloudflare/Zaraz/index.d.ts +3 -0
  224. package/lib/Cloudflare/Zaraz/index.d.ts.map +1 -0
  225. package/lib/Cloudflare/Zaraz/index.js +2 -0
  226. package/lib/Cloudflare/Zaraz/index.js.map +1 -0
  227. package/lib/Cloudflare/index.d.ts +2 -0
  228. package/lib/Cloudflare/index.d.ts.map +1 -1
  229. package/lib/Cloudflare/index.js +2 -0
  230. package/lib/Cloudflare/index.js.map +1 -1
  231. package/lib/Dependencies.d.ts +10 -0
  232. package/lib/Dependencies.d.ts.map +1 -0
  233. package/lib/Dependencies.js +1 -0
  234. package/lib/Dependencies.js.map +1 -0
  235. package/lib/Deploy.d.ts +2 -1
  236. package/lib/Deploy.d.ts.map +1 -1
  237. package/lib/Deploy.js +2 -2
  238. package/lib/Deploy.js.map +1 -1
  239. package/lib/Diff.d.ts +11 -0
  240. package/lib/Diff.d.ts.map +1 -1
  241. package/lib/Diff.js +11 -0
  242. package/lib/Diff.js.map +1 -1
  243. package/lib/Input.d.ts +2 -1
  244. package/lib/Input.d.ts.map +1 -1
  245. package/lib/KeyPair.d.ts +77 -0
  246. package/lib/KeyPair.d.ts.map +1 -0
  247. package/lib/KeyPair.js +102 -0
  248. package/lib/KeyPair.js.map +1 -0
  249. package/lib/Local/RpcProvider.d.ts +56 -0
  250. package/lib/Local/RpcProvider.d.ts.map +1 -0
  251. package/lib/Local/RpcProvider.js +83 -0
  252. package/lib/Local/RpcProvider.js.map +1 -0
  253. package/lib/Local/RpcProviderProxy.d.ts +19 -0
  254. package/lib/Local/RpcProviderProxy.d.ts.map +1 -0
  255. package/lib/Local/RpcProviderProxy.js +48 -0
  256. package/lib/Local/RpcProviderProxy.js.map +1 -0
  257. package/lib/Local/RpcSerialization.d.ts +34 -0
  258. package/lib/Local/RpcSerialization.d.ts.map +1 -0
  259. package/lib/Local/RpcSerialization.js +120 -0
  260. package/lib/Local/RpcSerialization.js.map +1 -0
  261. package/lib/Local/RpcServer.d.ts +63 -0
  262. package/lib/Local/RpcServer.d.ts.map +1 -0
  263. package/lib/Local/RpcServer.js +72 -0
  264. package/lib/Local/RpcServer.js.map +1 -0
  265. package/lib/Local/RpcServerBun.d.ts +3 -0
  266. package/lib/Local/RpcServerBun.d.ts.map +1 -0
  267. package/lib/Local/RpcServerBun.js +47 -0
  268. package/lib/Local/RpcServerBun.js.map +1 -0
  269. package/lib/Local/RpcServerEnvironment.d.ts +20 -0
  270. package/lib/Local/RpcServerEnvironment.d.ts.map +1 -0
  271. package/lib/Local/RpcServerEnvironment.js +22 -0
  272. package/lib/Local/RpcServerEnvironment.js.map +1 -0
  273. package/lib/Local/RpcServerNode.d.ts +3 -0
  274. package/lib/Local/RpcServerNode.d.ts.map +1 -0
  275. package/lib/Local/RpcServerNode.js +43 -0
  276. package/lib/Local/RpcServerNode.js.map +1 -0
  277. package/lib/Local/RpcServerSession.d.ts +27 -0
  278. package/lib/Local/RpcServerSession.d.ts.map +1 -0
  279. package/lib/Local/RpcServerSession.js +68 -0
  280. package/lib/Local/RpcServerSession.js.map +1 -0
  281. package/lib/Local/RpcSpawner.d.ts +21 -0
  282. package/lib/Local/RpcSpawner.d.ts.map +1 -0
  283. package/lib/Local/RpcSpawner.js +132 -0
  284. package/lib/Local/RpcSpawner.js.map +1 -0
  285. package/lib/Neon/Project.d.ts.map +1 -1
  286. package/lib/Neon/Project.js +14 -3
  287. package/lib/Neon/Project.js.map +1 -1
  288. package/lib/Output.d.ts.map +1 -1
  289. package/lib/Output.js +9 -2
  290. package/lib/Output.js.map +1 -1
  291. package/lib/Phase.d.ts +2 -1
  292. package/lib/Phase.d.ts.map +1 -1
  293. package/lib/Phase.js +6 -1
  294. package/lib/Phase.js.map +1 -1
  295. package/lib/Plan.d.ts.map +1 -1
  296. package/lib/Plan.js +14 -3
  297. package/lib/Plan.js.map +1 -1
  298. package/lib/Platform.d.ts +8 -6
  299. package/lib/Platform.d.ts.map +1 -1
  300. package/lib/Platform.js +33 -3
  301. package/lib/Platform.js.map +1 -1
  302. package/lib/Random.d.ts.map +1 -1
  303. package/lib/Random.js +9 -14
  304. package/lib/Random.js.map +1 -1
  305. package/lib/RuntimeContext.d.ts +21 -1
  306. package/lib/RuntimeContext.d.ts.map +1 -1
  307. package/lib/RuntimeContext.js +12 -0
  308. package/lib/RuntimeContext.js.map +1 -1
  309. package/lib/Stack.d.ts +3 -3
  310. package/lib/Stack.d.ts.map +1 -1
  311. package/lib/Stack.js.map +1 -1
  312. package/lib/State/HttpStateApi.d.ts +2 -2
  313. package/lib/State/StateEncoding.d.ts +8 -0
  314. package/lib/State/StateEncoding.d.ts.map +1 -1
  315. package/lib/State/StateEncoding.js +55 -5
  316. package/lib/State/StateEncoding.js.map +1 -1
  317. package/lib/Test/Bun.d.ts.map +1 -1
  318. package/lib/Test/Bun.js +0 -2
  319. package/lib/Test/Bun.js.map +1 -1
  320. package/lib/Test/Vitest.d.ts.map +1 -1
  321. package/lib/Test/Vitest.js +0 -2
  322. package/lib/Test/Vitest.js.map +1 -1
  323. package/lib/Util/Duration.d.ts +14 -0
  324. package/lib/Util/Duration.d.ts.map +1 -0
  325. package/lib/Util/Duration.js +18 -0
  326. package/lib/Util/Duration.js.map +1 -0
  327. package/lib/Util/PlatformServices.d.ts +7 -0
  328. package/lib/Util/PlatformServices.d.ts.map +1 -1
  329. package/lib/Util/PlatformServices.js +22 -11
  330. package/lib/Util/PlatformServices.js.map +1 -1
  331. package/lib/Util/camel.d.ts.map +1 -1
  332. package/lib/Util/camel.js +2 -3
  333. package/lib/Util/camel.js.map +1 -1
  334. package/lib/Util/data.d.ts +5 -0
  335. package/lib/Util/data.d.ts.map +1 -1
  336. package/lib/Util/data.js +29 -0
  337. package/lib/Util/data.js.map +1 -1
  338. package/lib/Util/index.d.ts +0 -6
  339. package/lib/Util/index.d.ts.map +1 -1
  340. package/lib/Util/index.js +0 -6
  341. package/lib/Util/index.js.map +1 -1
  342. package/lib/Util/stable.d.ts.map +1 -1
  343. package/lib/Util/stable.js +3 -6
  344. package/lib/Util/stable.js.map +1 -1
  345. package/lib/Util/types.d.ts +3 -1
  346. package/lib/Util/types.d.ts.map +1 -1
  347. package/lib/Util/types.js +5 -1
  348. package/lib/Util/types.js.map +1 -1
  349. package/lib/index.d.ts +2 -3
  350. package/lib/index.d.ts.map +1 -1
  351. package/lib/index.js +1 -3
  352. package/lib/index.js.map +1 -1
  353. package/lib/tsconfig.test.tsbuildinfo +1 -1
  354. package/package.json +22 -23
  355. package/src/AWS/Lambda/Function.ts +87 -34
  356. package/src/AWS/Providers.ts +3 -0
  357. package/src/Apply.ts +18 -1
  358. package/src/Auth/AuthProvider.ts +25 -5
  359. package/src/Auth/Credentials.ts +8 -7
  360. package/src/Auth/Lock.ts +2 -2
  361. package/src/Bundle/Bundle.ts +35 -13
  362. package/src/Bundle/BundleAnalyzerPlugin.ts +33 -0
  363. package/src/Bundle/RawPlugin.ts +82 -0
  364. package/src/Bundle/index.ts +2 -0
  365. package/src/Cli/commands/_shared.ts +47 -4
  366. package/src/Cli/commands/dev.ts +63 -37
  367. package/src/Cli/commands/login.ts +20 -4
  368. package/src/Cli/commands/profile.ts +24 -34
  369. package/src/Cli/exec.ts +12 -7
  370. package/src/Cli/main.ts +0 -3
  371. package/src/Cloudflare/AiGateway/AiGateway.ts +2 -6
  372. package/src/Cloudflare/BrowserRendering/BrowserRendering.ts +132 -0
  373. package/src/Cloudflare/BrowserRendering/BrowserRenderingBinding.ts +137 -0
  374. package/src/Cloudflare/BrowserRendering/index.ts +11 -0
  375. package/src/Cloudflare/Container/Container.ts +3 -3
  376. package/src/Cloudflare/Container/StartContainer.ts +1 -2
  377. package/src/Cloudflare/D1/D1Database.ts +4 -1
  378. package/src/Cloudflare/D1/D1DatabaseBinding.ts +1 -1
  379. package/src/Cloudflare/Fetcher.ts +0 -2
  380. package/src/Cloudflare/Hyperdrive/Hyperdrive.ts +5 -0
  381. package/src/Cloudflare/Hyperdrive/HyperdriveBinding.ts +41 -43
  382. package/src/Cloudflare/KV/KVNamespace.ts +4 -0
  383. package/src/Cloudflare/Local.ts +23 -0
  384. package/src/Cloudflare/Providers.ts +28 -16
  385. package/src/Cloudflare/Queue/Queue.ts +3 -0
  386. package/src/Cloudflare/Queue/QueueConsumer.ts +23 -8
  387. package/src/Cloudflare/Queue/QueueEventSource.ts +33 -5
  388. package/src/Cloudflare/R2/R2Bucket.ts +26 -0
  389. package/src/Cloudflare/SecretsStore/Secret.ts +14 -41
  390. package/src/Cloudflare/SecretsStore/SecretBinding.ts +11 -11
  391. package/src/Cloudflare/StateStore/Api.ts +15 -15
  392. package/src/Cloudflare/StateStore/State.ts +68 -6
  393. package/src/Cloudflare/StateStore/Store.ts +5 -2
  394. package/src/Cloudflare/VpcService/VpcService.ts +2 -2
  395. package/src/Cloudflare/Website/StaticSite.ts +8 -10
  396. package/src/Cloudflare/Website/Vite.ts +4 -7
  397. package/src/Cloudflare/Workers/Assets.ts +1 -1
  398. package/src/Cloudflare/Workers/DurableObjectBridge.ts +7 -5
  399. package/src/Cloudflare/Workers/DurableObjectNamespace.ts +380 -121
  400. package/src/Cloudflare/Workers/HttpServer.ts +31 -25
  401. package/src/Cloudflare/Workers/InferEnv.ts +15 -8
  402. package/src/Cloudflare/Workers/LocalWorkerProvider.ts +609 -22
  403. package/src/Cloudflare/Workers/Rpc.ts +50 -0
  404. package/src/Cloudflare/Workers/RpcDurableObjectNamespace.ts +502 -0
  405. package/src/Cloudflare/Workers/RpcWorker.ts +562 -0
  406. package/src/Cloudflare/Workers/Vite.ts +2 -0
  407. package/src/Cloudflare/Workers/Worker.ts +280 -110
  408. package/src/Cloudflare/Workers/WorkerAsyncBindings.ts +158 -103
  409. package/src/Cloudflare/Workers/WorkerBinding.ts +10 -0
  410. package/src/Cloudflare/Workers/WorkerBridge.ts +10 -9
  411. package/src/Cloudflare/Workers/WorkerBundle.ts +8 -9
  412. package/src/Cloudflare/Workers/WorkerRuntimeContext.ts +8 -15
  413. package/src/Cloudflare/Workers/Workflow.ts +22 -3
  414. package/src/Cloudflare/Workers/index.ts +2 -0
  415. package/src/Cloudflare/Zaraz/ZarazConfig.ts +403 -0
  416. package/src/Cloudflare/Zaraz/ZarazEventTypes.ts +257 -0
  417. package/src/Cloudflare/Zaraz/index.ts +25 -0
  418. package/src/Cloudflare/index.ts +2 -0
  419. package/src/Dependencies.ts +10 -0
  420. package/src/Deploy.ts +3 -1
  421. package/src/Diff.ts +13 -0
  422. package/src/Input.ts +2 -0
  423. package/src/KeyPair.ts +146 -0
  424. package/src/Local/RpcProvider.ts +146 -0
  425. package/src/Local/RpcProviderProxy.ts +86 -0
  426. package/src/Local/RpcSerialization.ts +225 -0
  427. package/src/Local/RpcServer.ts +138 -0
  428. package/src/Local/RpcServerBun.ts +59 -0
  429. package/src/Local/RpcServerEnvironment.ts +55 -0
  430. package/src/Local/RpcServerNode.ts +58 -0
  431. package/src/Local/RpcServerSession.ts +87 -0
  432. package/src/Local/RpcSpawner.ts +196 -0
  433. package/src/Neon/Project.ts +16 -3
  434. package/src/Output.ts +8 -2
  435. package/src/Phase.ts +8 -0
  436. package/src/Plan.ts +16 -3
  437. package/src/Platform.ts +74 -27
  438. package/src/Random.ts +22 -27
  439. package/src/RuntimeContext.ts +23 -1
  440. package/src/Stack.ts +3 -3
  441. package/src/State/StateEncoding.ts +58 -7
  442. package/src/Test/Bun.ts +0 -3
  443. package/src/Test/Vitest.ts +0 -3
  444. package/src/Util/Duration.ts +21 -0
  445. package/src/Util/PlatformServices.ts +41 -27
  446. package/src/Util/camel.ts +3 -5
  447. package/src/Util/data.ts +38 -0
  448. package/src/Util/index.ts +0 -6
  449. package/src/Util/stable.ts +4 -10
  450. package/src/Util/types.ts +9 -2
  451. package/src/index.ts +2 -3
  452. package/lib/Cloudflare/Local/Sidecar.d.ts +0 -63
  453. package/lib/Cloudflare/Local/Sidecar.d.ts.map +0 -1
  454. package/lib/Cloudflare/Local/Sidecar.js +0 -50
  455. package/lib/Cloudflare/Local/Sidecar.js.map +0 -1
  456. package/lib/Cloudflare/Local/SidecarHandlers.d.ts +0 -8
  457. package/lib/Cloudflare/Local/SidecarHandlers.d.ts.map +0 -1
  458. package/lib/Cloudflare/Local/SidecarHandlers.js +0 -381
  459. package/lib/Cloudflare/Local/SidecarHandlers.js.map +0 -1
  460. package/lib/Cloudflare/Local/SidecarServer.d.ts +0 -2
  461. package/lib/Cloudflare/Local/SidecarServer.d.ts.map +0 -1
  462. package/lib/Cloudflare/Local/SidecarServer.js +0 -34
  463. package/lib/Cloudflare/Local/SidecarServer.js.map +0 -1
  464. package/lib/Secret.d.ts +0 -50
  465. package/lib/Secret.d.ts.map +0 -1
  466. package/lib/Secret.js +0 -23
  467. package/lib/Secret.js.map +0 -1
  468. package/lib/Sidecar/Lock.d.ts +0 -23
  469. package/lib/Sidecar/Lock.d.ts.map +0 -1
  470. package/lib/Sidecar/Lock.js +0 -39
  471. package/lib/Sidecar/Lock.js.map +0 -1
  472. package/lib/Sidecar/RpcClient.d.ts +0 -15
  473. package/lib/Sidecar/RpcClient.d.ts.map +0 -1
  474. package/lib/Sidecar/RpcClient.js +0 -78
  475. package/lib/Sidecar/RpcClient.js.map +0 -1
  476. package/lib/Sidecar/RpcHandler.d.ts +0 -51
  477. package/lib/Sidecar/RpcHandler.d.ts.map +0 -1
  478. package/lib/Sidecar/RpcHandler.js +0 -87
  479. package/lib/Sidecar/RpcHandler.js.map +0 -1
  480. package/lib/Sidecar/RpcPaths.d.ts +0 -19
  481. package/lib/Sidecar/RpcPaths.d.ts.map +0 -1
  482. package/lib/Sidecar/RpcPaths.js +0 -31
  483. package/lib/Sidecar/RpcPaths.js.map +0 -1
  484. package/lib/Sidecar/RpcServer.d.ts +0 -30
  485. package/lib/Sidecar/RpcServer.d.ts.map +0 -1
  486. package/lib/Sidecar/RpcServer.js +0 -105
  487. package/lib/Sidecar/RpcServer.js.map +0 -1
  488. package/lib/Sidecar/RpcServerBun.d.ts +0 -4
  489. package/lib/Sidecar/RpcServerBun.d.ts.map +0 -1
  490. package/lib/Sidecar/RpcServerBun.js +0 -28
  491. package/lib/Sidecar/RpcServerBun.js.map +0 -1
  492. package/lib/Sidecar/RpcServerNode.d.ts +0 -4
  493. package/lib/Sidecar/RpcServerNode.d.ts.map +0 -1
  494. package/lib/Sidecar/RpcServerNode.js +0 -39
  495. package/lib/Sidecar/RpcServerNode.js.map +0 -1
  496. package/lib/Sidecar/RpcServices.d.ts +0 -6
  497. package/lib/Sidecar/RpcServices.d.ts.map +0 -1
  498. package/lib/Sidecar/RpcServices.js +0 -29
  499. package/lib/Sidecar/RpcServices.js.map +0 -1
  500. package/lib/Trait.d.ts +0 -43
  501. package/lib/Trait.d.ts.map +0 -1
  502. package/lib/Trait.js +0 -17
  503. package/lib/Trait.js.map +0 -1
  504. package/lib/Util/LocalhostDns.d.ts +0 -23
  505. package/lib/Util/LocalhostDns.d.ts.map +0 -1
  506. package/lib/Util/LocalhostDns.js +0 -46
  507. package/lib/Util/LocalhostDns.js.map +0 -1
  508. package/lib/Util/assert-never.d.ts +0 -12
  509. package/lib/Util/assert-never.d.ts.map +0 -1
  510. package/lib/Util/assert-never.js +0 -11
  511. package/lib/Util/assert-never.js.map +0 -1
  512. package/lib/Util/class.d.ts +0 -3
  513. package/lib/Util/class.d.ts.map +0 -1
  514. package/lib/Util/class.js +0 -1
  515. package/lib/Util/class.js.map +0 -1
  516. package/lib/Util/ignore.d.ts +0 -40
  517. package/lib/Util/ignore.d.ts.map +0 -1
  518. package/lib/Util/ignore.js +0 -591
  519. package/lib/Util/ignore.js.map +0 -1
  520. package/lib/Util/instance.d.ts +0 -4
  521. package/lib/Util/instance.d.ts.map +0 -1
  522. package/lib/Util/instance.js +0 -1
  523. package/lib/Util/instance.js.map +0 -1
  524. package/lib/Util/pointer.d.ts +0 -5
  525. package/lib/Util/pointer.d.ts.map +0 -1
  526. package/lib/Util/pointer.js +0 -1
  527. package/lib/Util/pointer.js.map +0 -1
  528. package/lib/Util/schema-to-type.d.ts +0 -42
  529. package/lib/Util/schema-to-type.d.ts.map +0 -1
  530. package/lib/Util/schema-to-type.js +0 -364
  531. package/lib/Util/schema-to-type.js.map +0 -1
  532. package/lib/Util/todo.d.ts +0 -3
  533. package/lib/Util/todo.d.ts.map +0 -1
  534. package/lib/Util/todo.js +0 -3
  535. package/lib/Util/todo.js.map +0 -1
  536. package/lib/Variable.d.ts +0 -29
  537. package/lib/Variable.d.ts.map +0 -1
  538. package/lib/Variable.js +0 -9
  539. package/lib/Variable.js.map +0 -1
  540. package/src/Cloudflare/Local/Sidecar.ts +0 -81
  541. package/src/Cloudflare/Local/SidecarHandlers.ts +0 -491
  542. package/src/Cloudflare/Local/SidecarServer.ts +0 -70
  543. package/src/Secret.ts +0 -87
  544. package/src/Sidecar/Lock.ts +0 -66
  545. package/src/Sidecar/RpcClient.ts +0 -142
  546. package/src/Sidecar/RpcHandler.ts +0 -205
  547. package/src/Sidecar/RpcPaths.ts +0 -39
  548. package/src/Sidecar/RpcServer.ts +0 -153
  549. package/src/Sidecar/RpcServerBun.ts +0 -41
  550. package/src/Sidecar/RpcServerNode.ts +0 -51
  551. package/src/Sidecar/RpcServices.ts +0 -48
  552. package/src/Trait.ts +0 -105
  553. package/src/Util/LocalhostDns.ts +0 -52
  554. package/src/Util/assert-never.ts +0 -18
  555. package/src/Util/class.ts +0 -7
  556. package/src/Util/ignore.ts +0 -815
  557. package/src/Util/instance.ts +0 -9
  558. package/src/Util/pointer.ts +0 -5
  559. package/src/Util/schema-to-type.ts +0 -456
  560. package/src/Util/todo.ts +0 -4
  561. package/src/Variable.ts +0 -44
@@ -0,0 +1,138 @@
1
+ import * as Console from "effect/Console";
2
+ import * as Context from "effect/Context";
3
+ import * as Deferred from "effect/Deferred";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Layer from "effect/Layer";
6
+ import type * as Scope from "effect/Scope";
7
+ import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
8
+ import type { HttpClient } from "effect/unstable/http/HttpClient";
9
+ import type { ProviderService } from "../Provider.ts";
10
+ import type { ResourceLike } from "../Resource.ts";
11
+ import {
12
+ platformLayer,
13
+ PlatformServices,
14
+ runMain,
15
+ } from "../Util/PlatformServices.ts";
16
+ import * as RpcSerialization from "./RpcSerialization.ts";
17
+ import * as RpcServerEnvironment from "./RpcServerEnvironment.ts";
18
+ import {
19
+ makeServerRpcSession,
20
+ type ServerRpcSession,
21
+ type ServerWebSocketLike,
22
+ } from "./RpcServerSession.ts";
23
+
24
+ /**
25
+ * A service that exposes one or more resource providers over RPC.
26
+ * This returns `never` because it is meant to be used with `Layer.launch` (see {@link launch}).
27
+ */
28
+ export class RpcServer extends Context.Service<RpcServer, never>()(
29
+ "alchemy/Local/RpcServer",
30
+ ) {}
31
+
32
+ /**
33
+ * The RPC API that is implemented by the server and consumed by {@link RpcProviderProxy}.
34
+ */
35
+ export interface RpcProxyApi {
36
+ /**
37
+ * Retrieves a provider from the RPC server context.
38
+ * The consumer must unwrap the provider using {@link RpcSerialization.unwrapRpcHandlers} before using it.
39
+ */
40
+ readonly getProvider: <R extends ResourceLike>(
41
+ type: R["Type"],
42
+ ) => Promise<RpcSerialization.RpcWrapped<ProviderService<R>>>;
43
+ }
44
+
45
+ const serverPlatformLayer = platformLayer({
46
+ bun: async () => {
47
+ const { RpcServerBun } = await import("./RpcServerBun.ts");
48
+ return RpcServerBun;
49
+ },
50
+ node: async () => {
51
+ const { RpcServerNode } = await import("./RpcServerNode.ts");
52
+ return RpcServerNode;
53
+ },
54
+ });
55
+
56
+ /**
57
+ * Launches an RPC server that serves the given providers.
58
+ * Alchemy globals such as `AlchemyContext`, `Profile`, and `Stack` are inherited from the parent via {@link RpcServerEnvironment.fromEnv} and should not be provided manually.
59
+ * `PlatformServices` and `HttpClient` are also included.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * RpcServer.launch(
64
+ * Layer.merge(
65
+ * FunctionProvider,
66
+ * QueueProvider,
67
+ * ),
68
+ * );
69
+ * ```
70
+ *
71
+ * @param providers - A layer containing the providers to serve.
72
+ */
73
+ export const launch = <ROut, E>(
74
+ providers: Layer.Layer<
75
+ ROut,
76
+ E,
77
+ | Scope.Scope
78
+ | RpcServerEnvironment.RpcEnvironmentServices
79
+ | PlatformServices
80
+ | HttpClient
81
+ >,
82
+ ) =>
83
+ serverPlatformLayer.pipe(
84
+ Layer.provide(providers),
85
+ Layer.provide(RpcServerEnvironment.fromEnv()),
86
+ Layer.provide(Layer.merge(PlatformServices, FetchHttpClient.layer)),
87
+ Layer.launch,
88
+ Effect.scoped,
89
+ runMain,
90
+ );
91
+
92
+ /**
93
+ * Constructs an `RpcServer` layer using the given server implementation.
94
+ * @param serve - A function that spawns a websocket server and returns its URL.
95
+ * @returns An `RpcServer` layer.
96
+ */
97
+ export const layerServer = (
98
+ serve: (handlers: {
99
+ /** Creates a new RPC session over the given websocket. */
100
+ createRpcSession: (
101
+ ws: ServerWebSocketLike,
102
+ ) => ServerRpcSession<RpcProxyApi>;
103
+ /** Called when the parent connection, indicated by the `/parent` path, is established. */
104
+ parentConnected: () => void;
105
+ /** Called when the parent disconnects. The server will shut down when this is called. */
106
+ parentDisconnected: () => void;
107
+ }) => Effect.Effect<{ readonly url: string }, never, Scope.Scope>,
108
+ ) =>
109
+ Layer.effect(
110
+ RpcServer,
111
+ Effect.gen(function* () {
112
+ const context = yield* Effect.context();
113
+ const connected = yield* Deferred.make<void>();
114
+ const disconnected = yield* Deferred.make<void>();
115
+ const { url } = yield* serve({
116
+ createRpcSession: (ws) =>
117
+ makeServerRpcSession<RpcProxyApi>(ws, {
118
+ getProvider: async <R extends ResourceLike>(type: R["Type"]) => {
119
+ const provider = context.mapUnsafe.get(type);
120
+ if (!provider) {
121
+ throw new Error(`Provider "${type}" not found`);
122
+ }
123
+ return RpcSerialization.wrapRpcHandlers(
124
+ provider as ProviderService<R>,
125
+ ["tail"],
126
+ );
127
+ },
128
+ }),
129
+ parentConnected: () => Deferred.doneUnsafe(connected, Effect.void),
130
+ parentDisconnected: () =>
131
+ Deferred.doneUnsafe(disconnected, Effect.void),
132
+ });
133
+ yield* Console.log(`<ALCHEMY_RPC_ADDRESS>${url}</ALCHEMY_RPC_ADDRESS>`);
134
+ yield* Deferred.await(connected).pipe(Effect.timeout("10 seconds")); // TODO(john): should the timeout be shorter?
135
+ yield* Deferred.await(disconnected);
136
+ return yield* Effect.interrupt;
137
+ }),
138
+ );
@@ -0,0 +1,59 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as RpcServer from "./RpcServer.ts";
3
+ import type { ServerRpcSession } from "./RpcServerSession.ts";
4
+
5
+ export const RpcServerBun = RpcServer.layerServer(
6
+ Effect.fnUntraced(function* ({
7
+ parentConnected,
8
+ parentDisconnected,
9
+ createRpcSession,
10
+ }) {
11
+ const server = yield* Effect.sync(() =>
12
+ Bun.serve<
13
+ { type: "session"; session: ServerRpcSession<any> } | { type: "parent" }
14
+ >({
15
+ port: 0,
16
+ fetch: (request, server) => {
17
+ const url = new URL(request.url);
18
+ if (
19
+ server.upgrade(request, {
20
+ data:
21
+ url.pathname === "/parent" ? { type: "parent" } : undefined!,
22
+ })
23
+ ) {
24
+ return;
25
+ }
26
+ return new Response("Upgrade failed", { status: 400 });
27
+ },
28
+ websocket: {
29
+ open: (ws) => {
30
+ if (ws.data && ws.data.type === "parent") {
31
+ parentConnected();
32
+ } else {
33
+ ws.data = {
34
+ type: "session",
35
+ session: createRpcSession(ws),
36
+ };
37
+ }
38
+ },
39
+ message: (ws, message) => {
40
+ if (ws.data.type === "session") {
41
+ ws.data.session.dispatch.message(message);
42
+ }
43
+ },
44
+ close: (ws, code, reason) => {
45
+ if (ws.data.type === "session") {
46
+ ws.data.session.dispatch.close(code, reason);
47
+ } else if (ws.data.type === "parent") {
48
+ parentDisconnected();
49
+ }
50
+ },
51
+ },
52
+ }),
53
+ );
54
+ yield* Effect.addFinalizer(() => Effect.sync(() => server.stop(true)));
55
+ return {
56
+ url: `ws://${server.hostname}:${server.port}`,
57
+ };
58
+ }),
59
+ );
@@ -0,0 +1,55 @@
1
+ import * as Config from "effect/Config";
2
+ import * as ConfigProvider from "effect/ConfigProvider";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import * as Option from "effect/Option";
6
+ import { AlchemyContext } from "../AlchemyContext.ts";
7
+ import { AuthProviders } from "../Auth/AuthProvider.ts";
8
+ import { CredentialsStoreLive } from "../Auth/Credentials.ts";
9
+ import { ProfileLive, withProfileOverride } from "../Auth/Profile.ts";
10
+ import { Stack } from "../Stack.ts";
11
+ import { Stage } from "../Stage.ts";
12
+ import { loadConfigProvider } from "../Util/ConfigProvider.ts";
13
+
14
+ export interface RpcServerEnvironment {
15
+ alchemyContext: AlchemyContext["Service"];
16
+ profile: string | undefined;
17
+ envFile: string | undefined;
18
+ stack: {
19
+ name: string;
20
+ stage: string;
21
+ };
22
+ }
23
+
24
+ export type RpcEnvironmentServices = Layer.Success<ReturnType<typeof layer>>;
25
+
26
+ export const layer = (environment: RpcServerEnvironment) =>
27
+ Layer.mergeAll(
28
+ ProfileLive,
29
+ CredentialsStoreLive,
30
+ Layer.succeed(AuthProviders, {}),
31
+ ConfigProvider.layer(
32
+ loadConfigProvider(Option.fromNullishOr(environment.envFile)).pipe(
33
+ Effect.map((base) => withProfileOverride(base, environment.profile)),
34
+ ),
35
+ ),
36
+ Layer.succeed(AlchemyContext, environment.alchemyContext),
37
+ Layer.succeed(Stack, {
38
+ name: environment.stack.name,
39
+ stage: environment.stack.stage,
40
+ resources: {},
41
+ bindings: {},
42
+ actions: {},
43
+ }),
44
+ Layer.succeed(Stage, environment.stack.stage),
45
+ );
46
+
47
+ export const RPC_SERVER_ENVIRONMENT_KEY =
48
+ "ALCHEMY_RPC_SERVER_ENVIRONMENT" as const;
49
+
50
+ export const fromEnv = () =>
51
+ Config.string(RPC_SERVER_ENVIRONMENT_KEY).pipe(
52
+ Config.map(JSON.parse),
53
+ Effect.map((environment) => layer(environment)),
54
+ Layer.unwrap,
55
+ );
@@ -0,0 +1,58 @@
1
+ import * as Effect from "effect/Effect";
2
+ import { WebSocketServer, type Server } from "ws";
3
+ import * as RpcServer from "./RpcServer.ts";
4
+
5
+ export const RpcServerNode = RpcServer.layerServer(
6
+ Effect.fnUntraced(function* ({
7
+ parentConnected,
8
+ parentDisconnected,
9
+ createRpcSession,
10
+ }) {
11
+ const server = new WebSocketServer({ host: "127.0.0.1", port: 0 });
12
+ const url = yield* Effect.callback<string>((resume) => {
13
+ server.on("connection", (ws, req) => {
14
+ if (req.url?.startsWith("/parent")) {
15
+ parentConnected();
16
+ ws.on("close", () => {
17
+ parentDisconnected();
18
+ });
19
+ return;
20
+ }
21
+ const session = createRpcSession(ws);
22
+ ws.on("message", (data) => {
23
+ session.dispatch.message(data.toString());
24
+ });
25
+ ws.on("close", (code, reason) => {
26
+ session.dispatch.close(code, reason.toString());
27
+ });
28
+ });
29
+ server.on("error", (error) => {
30
+ resume(Effect.die(error));
31
+ });
32
+ server.on("listening", () => {
33
+ resume(getServerAddress(server));
34
+ });
35
+ });
36
+ yield* Effect.addFinalizer(() => Effect.sync(() => server.close()));
37
+ return { url };
38
+ }),
39
+ );
40
+
41
+ function getServerAddress(server: Server): Effect.Effect<string> {
42
+ const address = server.address();
43
+ if (
44
+ typeof address === "object" &&
45
+ address !== null &&
46
+ "address" in address &&
47
+ "port" in address
48
+ ) {
49
+ return Effect.succeed(
50
+ `ws://${address.address === "::" ? "localhost" : address.address}:${address.port}`,
51
+ );
52
+ }
53
+ return Effect.die(
54
+ new Error(
55
+ `Server address is not an object with address and port properties: ${JSON.stringify(address)}`,
56
+ ),
57
+ );
58
+ }
@@ -0,0 +1,87 @@
1
+ import { RpcSession, type RpcCompatible, type RpcTransport } from "capnweb";
2
+
3
+ /**
4
+ * A platform-agnostic interface for a server-side WebSocket.
5
+ */
6
+ export interface ServerWebSocketLike {
7
+ send: (message: string) => any | Promise<any>;
8
+ close: (code?: number, reason?: string) => void;
9
+ }
10
+
11
+ /**
12
+ * Represents a websocket RPC session with capnweb.
13
+ * Use the `dispatch` object to handle messages that are received from the client.
14
+ */
15
+ export type ServerRpcSession<T extends RpcCompatible<T>> = ReturnType<
16
+ typeof makeServerRpcSession<T>
17
+ >;
18
+
19
+ /**
20
+ * Constructs a ServerRpcSession using capnweb.
21
+ * @param ws - The WebSocket to use for the session.
22
+ * @param main - The main object to use for the session.
23
+ * @returns A ServerRpcSession.
24
+ */
25
+ export function makeServerRpcSession<T extends RpcCompatible<T>>(
26
+ ws: ServerWebSocketLike,
27
+ main: T,
28
+ ) {
29
+ const { transport, dispatch } = makeWebSocketRpcTransport(ws);
30
+ const session = new RpcSession(transport, main);
31
+ return { session, dispatch };
32
+ }
33
+
34
+ function makeWebSocketRpcTransport(ws: ServerWebSocketLike) {
35
+ let receiveQueue: Array<string> = [];
36
+ let receiveResolver: ((value: string) => void) | undefined;
37
+ let receiveRejecter: ((reason: unknown) => void) | undefined;
38
+ let error: unknown | undefined;
39
+ return {
40
+ transport: {
41
+ send: async (message: string) => await ws.send(message),
42
+ receive: async () => {
43
+ const next = receiveQueue.shift();
44
+ if (next) {
45
+ return next;
46
+ } else if (error) {
47
+ throw error;
48
+ }
49
+ return new Promise<string>((resolve, reject) => {
50
+ receiveResolver = resolve;
51
+ receiveRejecter = reject;
52
+ });
53
+ },
54
+ abort: (reason: unknown) => {
55
+ const message =
56
+ reason instanceof Error ? reason.message : String(reason);
57
+ ws.close(3000, message);
58
+ error ??= reason;
59
+ },
60
+ } satisfies RpcTransport,
61
+ dispatch: {
62
+ message: (data: string | Buffer<ArrayBuffer>) => {
63
+ if (error) {
64
+ return;
65
+ }
66
+ data = typeof data === "string" ? data : data.toString("utf-8");
67
+ if (receiveResolver) {
68
+ receiveResolver(data);
69
+ receiveResolver = undefined;
70
+ receiveRejecter = undefined;
71
+ } else {
72
+ receiveQueue.push(data);
73
+ }
74
+ },
75
+ close: (code: number, reason: string) => {
76
+ if (!error) {
77
+ error = new Error(`WebSocket closed with code ${code}: ${reason}`);
78
+ if (receiveRejecter) {
79
+ receiveRejecter(error);
80
+ receiveRejecter = undefined;
81
+ receiveResolver = undefined;
82
+ }
83
+ }
84
+ },
85
+ },
86
+ };
87
+ }
@@ -0,0 +1,196 @@
1
+ import { exitHook } from "@alchemy.run/node-utils/exit-hook";
2
+ import * as Cache from "effect/Cache";
3
+ import * as Context from "effect/Context";
4
+ import * as Deferred from "effect/Deferred";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Layer from "effect/Layer";
7
+ import type { PlatformError } from "effect/PlatformError";
8
+ import * as Scope from "effect/Scope";
9
+ import * as Stream from "effect/Stream";
10
+ import * as HttpServer from "effect/unstable/http/HttpServer";
11
+ import { HttpServerRequest } from "effect/unstable/http/HttpServerRequest";
12
+ import * as HttpServerResponse from "effect/unstable/http/HttpServerResponse";
13
+ import * as ChildProcess from "effect/unstable/process/ChildProcess";
14
+ import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner";
15
+ import * as NodeChildProcess from "node:child_process";
16
+ import { fileURLToPath } from "node:url";
17
+ import { httpServer } from "../Util/PlatformServices.ts";
18
+ import {
19
+ RPC_SERVER_ENVIRONMENT_KEY,
20
+ type RpcServerEnvironment,
21
+ } from "./RpcServerEnvironment.ts";
22
+
23
+ export class RpcSpawner extends Context.Service<
24
+ RpcSpawner,
25
+ {
26
+ readonly url: string;
27
+ }
28
+ >()("alchemy/Local/RpcSpawner") {}
29
+
30
+ export interface RpcSpawnPayload extends Pick<
31
+ RpcServerEnvironment,
32
+ "alchemyContext" | "stack"
33
+ > {
34
+ serverEntryUrl: string;
35
+ }
36
+
37
+ export const make = Effect.fnUntraced(function* ({
38
+ profile,
39
+ envFile,
40
+ }: Pick<RpcServerEnvironment, "profile" | "envFile">) {
41
+ const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
42
+ const scope = yield* Effect.scope;
43
+ const cache = yield* Cache.make({
44
+ lookup: (payload: RpcSpawnPayload) =>
45
+ spawn(payload).pipe(Scope.provide(scope)),
46
+ capacity: Infinity,
47
+ });
48
+
49
+ const spawn = Effect.fnUntraced(function* ({
50
+ serverEntryUrl,
51
+ alchemyContext,
52
+ stack,
53
+ }: RpcSpawnPayload) {
54
+ const bin = typeof globalThis.Bun !== "undefined" ? "bun" : "node";
55
+ const main = fileURLToPath(serverEntryUrl);
56
+ const environment: RpcServerEnvironment = {
57
+ profile,
58
+ envFile,
59
+ alchemyContext,
60
+ stack,
61
+ };
62
+ const command = ChildProcess.make(
63
+ bin,
64
+ {
65
+ bun: ["run", main],
66
+ // Under Node, transparently strip TypeScript types so that `.ts`
67
+ // entry points work the same way they do under Bun. Mirrors what
68
+ // `dev.ts` already does for the outer process, so the dev experience
69
+ // is symmetric on both runtimes whether the entry came from `src/`
70
+ // (dev/tests) or `lib/` (published packages).
71
+ node: main.endsWith(".ts")
72
+ ? [
73
+ "--experimental-transform-types",
74
+ "--no-warnings=ExperimentalWarning",
75
+ main,
76
+ ]
77
+ : [main],
78
+ }[bin],
79
+ {
80
+ stdout: "pipe",
81
+ stderr: "inherit",
82
+ detached: false,
83
+ env: {
84
+ [RPC_SERVER_ENVIRONMENT_KEY]: JSON.stringify(environment),
85
+ },
86
+ extendEnv: true,
87
+ },
88
+ );
89
+ const handle = yield* spawner.spawn(command);
90
+ const unregister = exitHook(() => {
91
+ killProcessGroup(handle.pid, "SIGKILL");
92
+ });
93
+ const kill = handle
94
+ .kill({ forceKillAfter: "500 millis" })
95
+ .pipe(Effect.tap(() => Effect.sync(unregister)));
96
+ yield* Effect.addFinalizer(() => kill.pipe(Effect.ignore));
97
+ const url = yield* getRpcAddress(handle.stdout);
98
+ const ws = yield* Effect.acquireRelease(
99
+ Effect.sync(() => new WebSocket(new URL("/parent", url))),
100
+ (ws) => Effect.sync(() => ws.close()),
101
+ );
102
+ return {
103
+ url,
104
+ isRunning: Effect.zipWith(
105
+ handle.isRunning,
106
+ Effect.sync(
107
+ () =>
108
+ ws.readyState === WebSocket.CONNECTING ||
109
+ ws.readyState === WebSocket.OPEN,
110
+ ),
111
+ (a, b) => a && b,
112
+ { concurrent: true },
113
+ ),
114
+ kill,
115
+ };
116
+ });
117
+
118
+ const register = Effect.fnUntraced(function* (
119
+ payload: RpcSpawnPayload,
120
+ attempt = 0,
121
+ ): Effect.fn.Return<string, PlatformError> {
122
+ const child = yield* Cache.get(cache, payload);
123
+ if (yield* child.isRunning) {
124
+ return child.url;
125
+ }
126
+ if (attempt > 3) {
127
+ return yield* Effect.die(
128
+ new Error(
129
+ `Failed to spawn RPC server for "${payload.serverEntryUrl}" after ${attempt} attempts.`,
130
+ ),
131
+ );
132
+ }
133
+ yield* child.kill;
134
+ yield* Cache.invalidate(cache, payload);
135
+ return yield* register(payload, attempt + 1);
136
+ });
137
+
138
+ const server = yield* HttpServer.HttpServer;
139
+
140
+ yield* server.serve(
141
+ Effect.gen(function* () {
142
+ const request = yield* HttpServerRequest;
143
+ const payload = (yield* request.json) as unknown as RpcSpawnPayload;
144
+ const url = yield* register(payload);
145
+ return HttpServerResponse.text(url);
146
+ }),
147
+ );
148
+
149
+ return RpcSpawner.of({
150
+ url: HttpServer.formatAddress(server.address),
151
+ });
152
+ });
153
+
154
+ export const layerServer = (
155
+ environment: Pick<RpcServerEnvironment, "profile" | "envFile">,
156
+ ) =>
157
+ Layer.effect(RpcSpawner, make(environment)).pipe(Layer.provide(httpServer()));
158
+
159
+ const RPC_ADDRESS_REGEX =
160
+ /(<ALCHEMY_RPC_ADDRESS>)(.+)(<\/ALCHEMY_RPC_ADDRESS>)/;
161
+
162
+ const getRpcAddress = (stdout: Stream.Stream<Uint8Array, PlatformError>) =>
163
+ Effect.gen(function* () {
164
+ const address = yield* Deferred.make<string>();
165
+ let done = false;
166
+ yield* stdout.pipe(
167
+ Stream.decodeText,
168
+ Stream.splitLines,
169
+ Stream.runForEach((line) => {
170
+ 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
+ }
178
+ }
179
+ return Effect.void;
180
+ }),
181
+ Effect.forkScoped,
182
+ );
183
+ return yield* Deferred.await(address);
184
+ });
185
+
186
+ const killProcessGroup = (pid: number, signal: NodeJS.Signals) => {
187
+ try {
188
+ if (process.platform === "win32") {
189
+ NodeChildProcess.execSync(`taskkill /pid ${pid} /T /F`);
190
+ } else {
191
+ process.kill(-pid, signal);
192
+ }
193
+ } catch {
194
+ // ignore errors during best-effort cleanup
195
+ }
196
+ };
@@ -136,7 +136,7 @@ const findProjectByName = (name: string) =>
136
136
  Effect.gen(function* () {
137
137
  const matches: ListProjectsOutput["projects"][number][] = [];
138
138
  let cursor: string | undefined;
139
- do {
139
+ while (true) {
140
140
  const page = yield* listProjects({
141
141
  search: name,
142
142
  ...(cursor !== undefined ? { cursor } : {}),
@@ -144,8 +144,21 @@ const findProjectByName = (name: string) =>
144
144
  for (const p of page.projects) {
145
145
  if (p.name === name) matches.push(p);
146
146
  }
147
- cursor = page.pagination?.cursor;
148
- } while (cursor);
147
+ const nextCursor = page.pagination?.cursor;
148
+ // Neon returns a `pagination.cursor` on every response — it's the
149
+ // `created_at` of the last row, not a "has next page" flag — so we
150
+ // can't loop on cursor presence alone or we spin forever re-fetching
151
+ // empty/identical pages. Stop once a page comes back empty or the
152
+ // cursor stops advancing.
153
+ if (
154
+ page.projects.length === 0 ||
155
+ nextCursor === undefined ||
156
+ nextCursor === cursor
157
+ ) {
158
+ break;
159
+ }
160
+ cursor = nextCursor;
161
+ }
149
162
  return matches;
150
163
  });
151
164
 
package/src/Output.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as Data from "effect/Data";
2
+ import * as Duration from "effect/Duration";
2
3
  import * as Effect from "effect/Effect";
3
4
  import { pipe } from "effect/Function";
4
5
  import type { Pipeable } from "effect/Pipeable";
@@ -6,7 +7,7 @@ import * as Redacted from "effect/Redacted";
6
7
  import { SingleShotGen } from "effect/Utils";
7
8
  import { getRefMetadata, isRef, type Ref } from "./Ref.ts";
8
9
  import { isResource, type Resource, type ResourceLike } from "./Resource.ts";
9
- import { RuntimeContext } from "./RuntimeContext.ts";
10
+ import { RuntimeContext, sanitizeKey } from "./RuntimeContext.ts";
10
11
  import { Stack } from "./Stack.ts";
11
12
  import { Stage } from "./Stage.ts";
12
13
  import * as State from "./State/State.ts";
@@ -112,9 +113,11 @@ export abstract class BaseExpr<A = any, Req = any> implements Output<A, Req> {
112
113
  }
113
114
 
114
115
  public bind(id: string): any {
116
+ // `set`/`get` store keys verbatim, so canonicalize here (the caller's job).
117
+ const key = sanitizeKey(id);
115
118
  return RuntimeContext.pipe(
116
119
  Effect.flatMap((ctx) =>
117
- Effect.map(ctx.set(id, this), (key) => ctx.get<A>(key)),
120
+ Effect.map(ctx.set(key, this), (k) => ctx.get<A>(k)),
118
121
  ),
119
122
  );
120
123
  }
@@ -590,6 +593,9 @@ export const evaluate: <A, Req = never>(
590
593
  return yield* Effect.all(expr.map((item) => evaluate(item, upstream)));
591
594
  } else if (Redacted.isRedacted(expr)) {
592
595
  return expr;
596
+ } else if (Duration.isDuration(expr)) {
597
+ // Opaque value — see resolveInput in Plan.ts for rationale.
598
+ return expr;
593
599
  } else if (typeof expr === "object" && expr !== null) {
594
600
  return Object.fromEntries(
595
601
  yield* Effect.all(
package/src/Phase.ts CHANGED
@@ -1,7 +1,15 @@
1
1
  import * as Config from "effect/Config";
2
2
  import * as Effect from "effect/Effect";
3
3
 
4
+ export type AlchemyPhase = "plan" | "runtime";
5
+
4
6
  export const ALCHEMY_PHASE = Config.string("ALCHEMY_PHASE").pipe(
5
7
  Config.withDefault("plan"),
8
+ Config.mapOrFail((value) => {
9
+ if (value !== "plan" && value !== "runtime") {
10
+ return Effect.die(new Error(`Invalid ALCHEMY_PHASE: ${value}`));
11
+ }
12
+ return Effect.succeed(value as AlchemyPhase);
13
+ }),
6
14
  Effect.orDie,
7
15
  );