@alchemy.run/modal 0.0.0-stage → 2.0.0-beta.86

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 (499) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +100 -2
  3. package/lib/App.d.ts +143 -0
  4. package/lib/App.d.ts.map +1 -0
  5. package/lib/App.js +198 -0
  6. package/lib/App.js.map +1 -0
  7. package/lib/AuthProvider.d.ts +53 -0
  8. package/lib/AuthProvider.d.ts.map +1 -0
  9. package/lib/AuthProvider.js +209 -0
  10. package/lib/AuthProvider.js.map +1 -0
  11. package/lib/BindingHttp.d.ts +56 -0
  12. package/lib/BindingHttp.d.ts.map +1 -0
  13. package/lib/BindingHttp.js +50 -0
  14. package/lib/BindingHttp.js.map +1 -0
  15. package/lib/Blob.d.ts +34 -0
  16. package/lib/Blob.d.ts.map +1 -0
  17. package/lib/Blob.js +59 -0
  18. package/lib/Blob.js.map +1 -0
  19. package/lib/Bootstrap.d.ts +8 -0
  20. package/lib/Bootstrap.d.ts.map +1 -0
  21. package/lib/Bootstrap.js +26 -0
  22. package/lib/Bootstrap.js.map +1 -0
  23. package/lib/Cbor.d.ts +10 -0
  24. package/lib/Cbor.d.ts.map +1 -0
  25. package/lib/Cbor.js +177 -0
  26. package/lib/Cbor.js.map +1 -0
  27. package/lib/ConnectSandbox.d.ts +64 -0
  28. package/lib/ConnectSandbox.d.ts.map +1 -0
  29. package/lib/ConnectSandbox.js +33 -0
  30. package/lib/ConnectSandbox.js.map +1 -0
  31. package/lib/Container.d.ts +124 -0
  32. package/lib/Container.d.ts.map +1 -0
  33. package/lib/Container.js +1 -0
  34. package/lib/Container.js.map +1 -0
  35. package/lib/Contributions.d.ts +7 -0
  36. package/lib/Contributions.d.ts.map +1 -0
  37. package/lib/Contributions.js +6 -0
  38. package/lib/Contributions.js.map +1 -0
  39. package/lib/CreateDict.d.ts +83 -0
  40. package/lib/CreateDict.d.ts.map +1 -0
  41. package/lib/CreateDict.js +3 -0
  42. package/lib/CreateDict.js.map +1 -0
  43. package/lib/CreateDictHttp.d.ts +33 -0
  44. package/lib/CreateDictHttp.d.ts.map +1 -0
  45. package/lib/CreateDictHttp.js +67 -0
  46. package/lib/CreateDictHttp.js.map +1 -0
  47. package/lib/CreateImage.d.ts +98 -0
  48. package/lib/CreateImage.d.ts.map +1 -0
  49. package/lib/CreateImage.js +3 -0
  50. package/lib/CreateImage.js.map +1 -0
  51. package/lib/CreateImageHttp.d.ts +51 -0
  52. package/lib/CreateImageHttp.d.ts.map +1 -0
  53. package/lib/CreateImageHttp.js +87 -0
  54. package/lib/CreateImageHttp.js.map +1 -0
  55. package/lib/CreateQueue.d.ts +83 -0
  56. package/lib/CreateQueue.d.ts.map +1 -0
  57. package/lib/CreateQueue.js +3 -0
  58. package/lib/CreateQueue.js.map +1 -0
  59. package/lib/CreateQueueHttp.d.ts +31 -0
  60. package/lib/CreateQueueHttp.d.ts.map +1 -0
  61. package/lib/CreateQueueHttp.js +67 -0
  62. package/lib/CreateQueueHttp.js.map +1 -0
  63. package/lib/CreateSandbox.d.ts +186 -0
  64. package/lib/CreateSandbox.d.ts.map +1 -0
  65. package/lib/CreateSandbox.js +3 -0
  66. package/lib/CreateSandbox.js.map +1 -0
  67. package/lib/CreateSandboxHttp.d.ts +17 -0
  68. package/lib/CreateSandboxHttp.d.ts.map +1 -0
  69. package/lib/CreateSandboxHttp.js +117 -0
  70. package/lib/CreateSandboxHttp.js.map +1 -0
  71. package/lib/CreateSecret.d.ts +95 -0
  72. package/lib/CreateSecret.d.ts.map +1 -0
  73. package/lib/CreateSecret.js +3 -0
  74. package/lib/CreateSecret.js.map +1 -0
  75. package/lib/CreateSecretHttp.d.ts +24 -0
  76. package/lib/CreateSecretHttp.d.ts.map +1 -0
  77. package/lib/CreateSecretHttp.js +60 -0
  78. package/lib/CreateSecretHttp.js.map +1 -0
  79. package/lib/CreateVolume.d.ts +84 -0
  80. package/lib/CreateVolume.d.ts.map +1 -0
  81. package/lib/CreateVolume.js +3 -0
  82. package/lib/CreateVolume.js.map +1 -0
  83. package/lib/CreateVolumeHttp.d.ts +32 -0
  84. package/lib/CreateVolumeHttp.d.ts.map +1 -0
  85. package/lib/CreateVolumeHttp.js +69 -0
  86. package/lib/CreateVolumeHttp.js.map +1 -0
  87. package/lib/Credentials.d.ts +32 -0
  88. package/lib/Credentials.d.ts.map +1 -0
  89. package/lib/Credentials.js +44 -0
  90. package/lib/Credentials.js.map +1 -0
  91. package/lib/Dict.d.ts +147 -0
  92. package/lib/Dict.d.ts.map +1 -0
  93. package/lib/Dict.js +175 -0
  94. package/lib/Dict.js.map +1 -0
  95. package/lib/DictClient.d.ts +55 -0
  96. package/lib/DictClient.d.ts.map +1 -0
  97. package/lib/DictClient.js +89 -0
  98. package/lib/DictClient.js.map +1 -0
  99. package/lib/Domain.d.ts +86 -0
  100. package/lib/Domain.d.ts.map +1 -0
  101. package/lib/Domain.js +113 -0
  102. package/lib/Domain.js.map +1 -0
  103. package/lib/Endpoint.d.ts +181 -0
  104. package/lib/Endpoint.d.ts.map +1 -0
  105. package/lib/Endpoint.js +283 -0
  106. package/lib/Endpoint.js.map +1 -0
  107. package/lib/Environment.d.ts +174 -0
  108. package/lib/Environment.d.ts.map +1 -0
  109. package/lib/Environment.js +244 -0
  110. package/lib/Environment.js.map +1 -0
  111. package/lib/FetchServer.d.ts +105 -0
  112. package/lib/FetchServer.d.ts.map +1 -0
  113. package/lib/FetchServer.js +3 -0
  114. package/lib/FetchServer.js.map +1 -0
  115. package/lib/FetchServerHttp.d.ts +21 -0
  116. package/lib/FetchServerHttp.d.ts.map +1 -0
  117. package/lib/FetchServerHttp.js +84 -0
  118. package/lib/FetchServerHttp.js.map +1 -0
  119. package/lib/Function.d.ts +236 -0
  120. package/lib/Function.d.ts.map +1 -0
  121. package/lib/Function.js +273 -0
  122. package/lib/Function.js.map +1 -0
  123. package/lib/FunctionAutoscaler.d.ts +99 -0
  124. package/lib/FunctionAutoscaler.d.ts.map +1 -0
  125. package/lib/FunctionAutoscaler.js +136 -0
  126. package/lib/FunctionAutoscaler.js.map +1 -0
  127. package/lib/FunctionTarget.d.ts +61 -0
  128. package/lib/FunctionTarget.d.ts.map +1 -0
  129. package/lib/FunctionTarget.js +136 -0
  130. package/lib/FunctionTarget.js.map +1 -0
  131. package/lib/Image.d.ts +159 -0
  132. package/lib/Image.d.ts.map +1 -0
  133. package/lib/Image.js +203 -0
  134. package/lib/Image.js.map +1 -0
  135. package/lib/ImageBuild.d.ts +108 -0
  136. package/lib/ImageBuild.d.ts.map +1 -0
  137. package/lib/ImageBuild.js +157 -0
  138. package/lib/ImageBuild.js.map +1 -0
  139. package/lib/ImagePlan.d.ts +31 -0
  140. package/lib/ImagePlan.d.ts.map +1 -0
  141. package/lib/ImagePlan.js +70 -0
  142. package/lib/ImagePlan.js.map +1 -0
  143. package/lib/InferEnv.d.ts +26 -0
  144. package/lib/InferEnv.d.ts.map +1 -0
  145. package/lib/InferEnv.js +1 -0
  146. package/lib/InferEnv.js.map +1 -0
  147. package/lib/InvokeFunction.d.ts +186 -0
  148. package/lib/InvokeFunction.d.ts.map +1 -0
  149. package/lib/InvokeFunction.js +10 -0
  150. package/lib/InvokeFunction.js.map +1 -0
  151. package/lib/InvokeFunctionHttp.d.ts +39 -0
  152. package/lib/InvokeFunctionHttp.d.ts.map +1 -0
  153. package/lib/InvokeFunctionHttp.js +210 -0
  154. package/lib/InvokeFunctionHttp.js.map +1 -0
  155. package/lib/ModalBindings.d.ts +138 -0
  156. package/lib/ModalBindings.d.ts.map +1 -0
  157. package/lib/ModalBindings.js +223 -0
  158. package/lib/ModalBindings.js.map +1 -0
  159. package/lib/MountBucket.d.ts +80 -0
  160. package/lib/MountBucket.d.ts.map +1 -0
  161. package/lib/MountBucket.js +44 -0
  162. package/lib/MountBucket.js.map +1 -0
  163. package/lib/MountVolume.d.ts +77 -0
  164. package/lib/MountVolume.d.ts.map +1 -0
  165. package/lib/MountVolume.js +41 -0
  166. package/lib/MountVolume.js.map +1 -0
  167. package/lib/Mounts.d.ts +134 -0
  168. package/lib/Mounts.d.ts.map +1 -0
  169. package/lib/Mounts.js +87 -0
  170. package/lib/Mounts.js.map +1 -0
  171. package/lib/PersistentSandbox.d.ts +75 -0
  172. package/lib/PersistentSandbox.d.ts.map +1 -0
  173. package/lib/PersistentSandbox.js +93 -0
  174. package/lib/PersistentSandbox.js.map +1 -0
  175. package/lib/Providers.d.ts +23 -0
  176. package/lib/Providers.d.ts.map +1 -0
  177. package/lib/Providers.js +64 -0
  178. package/lib/Providers.js.map +1 -0
  179. package/lib/Proxy.d.ts +94 -0
  180. package/lib/Proxy.d.ts.map +1 -0
  181. package/lib/Proxy.js +132 -0
  182. package/lib/Proxy.js.map +1 -0
  183. package/lib/Queue.d.ts +147 -0
  184. package/lib/Queue.d.ts.map +1 -0
  185. package/lib/Queue.js +177 -0
  186. package/lib/Queue.js.map +1 -0
  187. package/lib/QueueClient.d.ts +64 -0
  188. package/lib/QueueClient.d.ts.map +1 -0
  189. package/lib/QueueClient.js +73 -0
  190. package/lib/QueueClient.js.map +1 -0
  191. package/lib/ReadApp.d.ts +85 -0
  192. package/lib/ReadApp.d.ts.map +1 -0
  193. package/lib/ReadApp.js +3 -0
  194. package/lib/ReadApp.js.map +1 -0
  195. package/lib/ReadAppHttp.d.ts +26 -0
  196. package/lib/ReadAppHttp.d.ts.map +1 -0
  197. package/lib/ReadAppHttp.js +106 -0
  198. package/lib/ReadAppHttp.js.map +1 -0
  199. package/lib/ReadDict.d.ts +39 -0
  200. package/lib/ReadDict.d.ts.map +1 -0
  201. package/lib/ReadDict.js +3 -0
  202. package/lib/ReadDict.js.map +1 -0
  203. package/lib/ReadDictHttp.d.ts +12 -0
  204. package/lib/ReadDictHttp.d.ts.map +1 -0
  205. package/lib/ReadDictHttp.js +23 -0
  206. package/lib/ReadDictHttp.js.map +1 -0
  207. package/lib/ReadFunction.d.ts +73 -0
  208. package/lib/ReadFunction.d.ts.map +1 -0
  209. package/lib/ReadFunction.js +3 -0
  210. package/lib/ReadFunction.js.map +1 -0
  211. package/lib/ReadFunctionHttp.d.ts +25 -0
  212. package/lib/ReadFunctionHttp.d.ts.map +1 -0
  213. package/lib/ReadFunctionHttp.js +63 -0
  214. package/lib/ReadFunctionHttp.js.map +1 -0
  215. package/lib/ReadQueue.d.ts +39 -0
  216. package/lib/ReadQueue.d.ts.map +1 -0
  217. package/lib/ReadQueue.js +3 -0
  218. package/lib/ReadQueue.js.map +1 -0
  219. package/lib/ReadQueueHttp.d.ts +12 -0
  220. package/lib/ReadQueueHttp.d.ts.map +1 -0
  221. package/lib/ReadQueueHttp.js +23 -0
  222. package/lib/ReadQueueHttp.js.map +1 -0
  223. package/lib/ReadServer.d.ts +72 -0
  224. package/lib/ReadServer.d.ts.map +1 -0
  225. package/lib/ReadServer.js +3 -0
  226. package/lib/ReadServer.js.map +1 -0
  227. package/lib/ReadServerHttp.d.ts +25 -0
  228. package/lib/ReadServerHttp.d.ts.map +1 -0
  229. package/lib/ReadServerHttp.js +70 -0
  230. package/lib/ReadServerHttp.js.map +1 -0
  231. package/lib/ReadVolume.d.ts +40 -0
  232. package/lib/ReadVolume.d.ts.map +1 -0
  233. package/lib/ReadVolume.js +3 -0
  234. package/lib/ReadVolume.js.map +1 -0
  235. package/lib/ReadVolumeHttp.d.ts +12 -0
  236. package/lib/ReadVolumeHttp.d.ts.map +1 -0
  237. package/lib/ReadVolumeHttp.js +24 -0
  238. package/lib/ReadVolumeHttp.js.map +1 -0
  239. package/lib/ReadWriteDict.d.ts +39 -0
  240. package/lib/ReadWriteDict.d.ts.map +1 -0
  241. package/lib/ReadWriteDict.js +3 -0
  242. package/lib/ReadWriteDict.js.map +1 -0
  243. package/lib/ReadWriteDictHttp.d.ts +12 -0
  244. package/lib/ReadWriteDictHttp.d.ts.map +1 -0
  245. package/lib/ReadWriteDictHttp.js +23 -0
  246. package/lib/ReadWriteDictHttp.js.map +1 -0
  247. package/lib/ReadWriteQueue.d.ts +40 -0
  248. package/lib/ReadWriteQueue.d.ts.map +1 -0
  249. package/lib/ReadWriteQueue.js +3 -0
  250. package/lib/ReadWriteQueue.js.map +1 -0
  251. package/lib/ReadWriteQueueHttp.d.ts +12 -0
  252. package/lib/ReadWriteQueueHttp.d.ts.map +1 -0
  253. package/lib/ReadWriteQueueHttp.js +23 -0
  254. package/lib/ReadWriteQueueHttp.js.map +1 -0
  255. package/lib/ReadWriteVolume.d.ts +40 -0
  256. package/lib/ReadWriteVolume.d.ts.map +1 -0
  257. package/lib/ReadWriteVolume.js +3 -0
  258. package/lib/ReadWriteVolume.js.map +1 -0
  259. package/lib/ReadWriteVolumeHttp.d.ts +12 -0
  260. package/lib/ReadWriteVolumeHttp.d.ts.map +1 -0
  261. package/lib/ReadWriteVolumeHttp.js +24 -0
  262. package/lib/ReadWriteVolumeHttp.js.map +1 -0
  263. package/lib/RuntimeOwner.d.ts +39 -0
  264. package/lib/RuntimeOwner.d.ts.map +1 -0
  265. package/lib/RuntimeOwner.js +85 -0
  266. package/lib/RuntimeOwner.js.map +1 -0
  267. package/lib/Sandbox.d.ts +215 -0
  268. package/lib/Sandbox.d.ts.map +1 -0
  269. package/lib/Sandbox.js +278 -0
  270. package/lib/Sandbox.js.map +1 -0
  271. package/lib/SandboxClient.d.ts +748 -0
  272. package/lib/SandboxClient.d.ts.map +1 -0
  273. package/lib/SandboxClient.js +710 -0
  274. package/lib/SandboxClient.js.map +1 -0
  275. package/lib/ScaleFunction.d.ts +54 -0
  276. package/lib/ScaleFunction.d.ts.map +1 -0
  277. package/lib/ScaleFunction.js +3 -0
  278. package/lib/ScaleFunction.js.map +1 -0
  279. package/lib/ScaleFunctionHttp.d.ts +21 -0
  280. package/lib/ScaleFunctionHttp.d.ts.map +1 -0
  281. package/lib/ScaleFunctionHttp.js +39 -0
  282. package/lib/ScaleFunctionHttp.js.map +1 -0
  283. package/lib/Secret.d.ts +170 -0
  284. package/lib/Secret.d.ts.map +1 -0
  285. package/lib/Secret.js +196 -0
  286. package/lib/Secret.js.map +1 -0
  287. package/lib/Server.d.ts +155 -0
  288. package/lib/Server.d.ts.map +1 -0
  289. package/lib/Server.js +184 -0
  290. package/lib/Server.js.map +1 -0
  291. package/lib/ServiceUser.d.ts +139 -0
  292. package/lib/ServiceUser.d.ts.map +1 -0
  293. package/lib/ServiceUser.js +210 -0
  294. package/lib/ServiceUser.js.map +1 -0
  295. package/lib/Volume.d.ts +170 -0
  296. package/lib/Volume.d.ts.map +1 -0
  297. package/lib/Volume.js +220 -0
  298. package/lib/Volume.js.map +1 -0
  299. package/lib/VolumeClient.d.ts +53 -0
  300. package/lib/VolumeClient.d.ts.map +1 -0
  301. package/lib/VolumeClient.js +22 -0
  302. package/lib/VolumeClient.js.map +1 -0
  303. package/lib/VolumeFiles.d.ts +94 -0
  304. package/lib/VolumeFiles.d.ts.map +1 -0
  305. package/lib/VolumeFiles.js +139 -0
  306. package/lib/VolumeFiles.js.map +1 -0
  307. package/lib/WebhookToken.d.ts +102 -0
  308. package/lib/WebhookToken.d.ts.map +1 -0
  309. package/lib/WebhookToken.js +176 -0
  310. package/lib/WebhookToken.js.map +1 -0
  311. package/lib/WorkspaceSettings.d.ts +70 -0
  312. package/lib/WorkspaceSettings.d.ts.map +1 -0
  313. package/lib/WorkspaceSettings.js +105 -0
  314. package/lib/WorkspaceSettings.js.map +1 -0
  315. package/lib/WriteApp.d.ts +38 -0
  316. package/lib/WriteApp.d.ts.map +1 -0
  317. package/lib/WriteApp.js +3 -0
  318. package/lib/WriteApp.js.map +1 -0
  319. package/lib/WriteAppHttp.d.ts +23 -0
  320. package/lib/WriteAppHttp.d.ts.map +1 -0
  321. package/lib/WriteAppHttp.js +36 -0
  322. package/lib/WriteAppHttp.js.map +1 -0
  323. package/lib/WriteDict.d.ts +39 -0
  324. package/lib/WriteDict.d.ts.map +1 -0
  325. package/lib/WriteDict.js +3 -0
  326. package/lib/WriteDict.js.map +1 -0
  327. package/lib/WriteDictHttp.d.ts +12 -0
  328. package/lib/WriteDictHttp.d.ts.map +1 -0
  329. package/lib/WriteDictHttp.js +23 -0
  330. package/lib/WriteDictHttp.js.map +1 -0
  331. package/lib/WriteQueue.d.ts +39 -0
  332. package/lib/WriteQueue.d.ts.map +1 -0
  333. package/lib/WriteQueue.js +3 -0
  334. package/lib/WriteQueue.js.map +1 -0
  335. package/lib/WriteQueueHttp.d.ts +12 -0
  336. package/lib/WriteQueueHttp.d.ts.map +1 -0
  337. package/lib/WriteQueueHttp.js +23 -0
  338. package/lib/WriteQueueHttp.js.map +1 -0
  339. package/lib/WriteSecret.d.ts +53 -0
  340. package/lib/WriteSecret.d.ts.map +1 -0
  341. package/lib/WriteSecret.js +3 -0
  342. package/lib/WriteSecret.js.map +1 -0
  343. package/lib/WriteSecretHttp.d.ts +23 -0
  344. package/lib/WriteSecretHttp.d.ts.map +1 -0
  345. package/lib/WriteSecretHttp.js +44 -0
  346. package/lib/WriteSecretHttp.js.map +1 -0
  347. package/lib/WriteVolume.d.ts +39 -0
  348. package/lib/WriteVolume.d.ts.map +1 -0
  349. package/lib/WriteVolume.js +3 -0
  350. package/lib/WriteVolume.js.map +1 -0
  351. package/lib/WriteVolumeHttp.d.ts +12 -0
  352. package/lib/WriteVolumeHttp.d.ts.map +1 -0
  353. package/lib/WriteVolumeHttp.js +24 -0
  354. package/lib/WriteVolumeHttp.js.map +1 -0
  355. package/lib/index.d.ts +80 -0
  356. package/lib/index.d.ts.map +1 -0
  357. package/lib/index.js +78 -0
  358. package/lib/index.js.map +1 -0
  359. package/lib/internal/Declared.d.ts +29 -0
  360. package/lib/internal/Declared.d.ts.map +1 -0
  361. package/lib/internal/Declared.js +31 -0
  362. package/lib/internal/Declared.js.map +1 -0
  363. package/lib/internal/Deploy.d.ts +110 -0
  364. package/lib/internal/Deploy.d.ts.map +1 -0
  365. package/lib/internal/Deploy.js +230 -0
  366. package/lib/internal/Deploy.js.map +1 -0
  367. package/lib/internal/Entrypoint.d.ts +52 -0
  368. package/lib/internal/Entrypoint.d.ts.map +1 -0
  369. package/lib/internal/Entrypoint.js +193 -0
  370. package/lib/internal/Entrypoint.js.map +1 -0
  371. package/lib/internal/Rpc.d.ts +17 -0
  372. package/lib/internal/Rpc.d.ts.map +1 -0
  373. package/lib/internal/Rpc.js +49 -0
  374. package/lib/internal/Rpc.js.map +1 -0
  375. package/lib/internal/RpcAuth.d.ts +41 -0
  376. package/lib/internal/RpcAuth.d.ts.map +1 -0
  377. package/lib/internal/RpcAuth.js +100 -0
  378. package/lib/internal/RpcAuth.js.map +1 -0
  379. package/lib/internal/Runtime.d.ts +127 -0
  380. package/lib/internal/Runtime.d.ts.map +1 -0
  381. package/lib/internal/Runtime.js +246 -0
  382. package/lib/internal/Runtime.js.map +1 -0
  383. package/lib/internal/Tags.d.ts +19 -0
  384. package/lib/internal/Tags.d.ts.map +1 -0
  385. package/lib/internal/Tags.js +33 -0
  386. package/lib/internal/Tags.js.map +1 -0
  387. package/lib/internal/TcpConnect.d.ts +12 -0
  388. package/lib/internal/TcpConnect.d.ts.map +1 -0
  389. package/lib/internal/TcpConnect.js +46 -0
  390. package/lib/internal/TcpConnect.js.map +1 -0
  391. package/lib/internal/Transport.d.ts +13 -0
  392. package/lib/internal/Transport.d.ts.map +1 -0
  393. package/lib/internal/Transport.js +16 -0
  394. package/lib/internal/Transport.js.map +1 -0
  395. package/lib/internal.d.ts +71 -0
  396. package/lib/internal.d.ts.map +1 -0
  397. package/lib/internal.js +102 -0
  398. package/lib/internal.js.map +1 -0
  399. package/package.json +75 -3
  400. package/src/App.ts +262 -0
  401. package/src/AuthProvider.ts +295 -0
  402. package/src/BindingHttp.ts +112 -0
  403. package/src/Blob.ts +71 -0
  404. package/src/Bootstrap.ts +52 -0
  405. package/src/Cbor.ts +158 -0
  406. package/src/ConnectSandbox.ts +99 -0
  407. package/src/Container.ts +121 -0
  408. package/src/Contributions.ts +9 -0
  409. package/src/CreateDict.ts +95 -0
  410. package/src/CreateDictHttp.ts +91 -0
  411. package/src/CreateImage.ts +105 -0
  412. package/src/CreateImageHttp.ts +117 -0
  413. package/src/CreateQueue.ts +95 -0
  414. package/src/CreateQueueHttp.ts +91 -0
  415. package/src/CreateSandbox.ts +228 -0
  416. package/src/CreateSandboxHttp.ts +160 -0
  417. package/src/CreateSecret.ts +109 -0
  418. package/src/CreateSecretHttp.ts +83 -0
  419. package/src/CreateVolume.ts +96 -0
  420. package/src/CreateVolumeHttp.ts +93 -0
  421. package/src/Credentials.ts +74 -0
  422. package/src/Dict.ts +245 -0
  423. package/src/DictClient.ts +166 -0
  424. package/src/Domain.ts +147 -0
  425. package/src/Endpoint.ts +406 -0
  426. package/src/Environment.ts +373 -0
  427. package/src/FetchServer.ts +126 -0
  428. package/src/FetchServerHttp.ts +110 -0
  429. package/src/Function.ts +397 -0
  430. package/src/FunctionAutoscaler.ts +210 -0
  431. package/src/FunctionTarget.ts +181 -0
  432. package/src/Image.ts +281 -0
  433. package/src/ImageBuild.ts +228 -0
  434. package/src/ImagePlan.ts +78 -0
  435. package/src/InferEnv.ts +27 -0
  436. package/src/InvokeFunction.ts +211 -0
  437. package/src/InvokeFunctionHttp.ts +316 -0
  438. package/src/ModalBindings.ts +310 -0
  439. package/src/MountBucket.ts +137 -0
  440. package/src/MountVolume.ts +113 -0
  441. package/src/Mounts.ts +230 -0
  442. package/src/PersistentSandbox.ts +142 -0
  443. package/src/Providers.ts +100 -0
  444. package/src/Proxy.ts +191 -0
  445. package/src/Queue.ts +258 -0
  446. package/src/QueueClient.ts +149 -0
  447. package/src/ReadApp.ts +101 -0
  448. package/src/ReadAppHttp.ts +142 -0
  449. package/src/ReadDict.ts +44 -0
  450. package/src/ReadDictHttp.ts +27 -0
  451. package/src/ReadFunction.ts +107 -0
  452. package/src/ReadFunctionHttp.ts +91 -0
  453. package/src/ReadQueue.ts +44 -0
  454. package/src/ReadQueueHttp.ts +27 -0
  455. package/src/ReadServer.ts +98 -0
  456. package/src/ReadServerHttp.ts +101 -0
  457. package/src/ReadVolume.ts +45 -0
  458. package/src/ReadVolumeHttp.ts +28 -0
  459. package/src/ReadWriteDict.ts +44 -0
  460. package/src/ReadWriteDictHttp.ts +27 -0
  461. package/src/ReadWriteQueue.ts +45 -0
  462. package/src/ReadWriteQueueHttp.ts +27 -0
  463. package/src/ReadWriteVolume.ts +45 -0
  464. package/src/ReadWriteVolumeHttp.ts +28 -0
  465. package/src/RuntimeOwner.ts +111 -0
  466. package/src/Sandbox.ts +402 -0
  467. package/src/SandboxClient.ts +1404 -0
  468. package/src/ScaleFunction.ts +70 -0
  469. package/src/ScaleFunctionHttp.ts +54 -0
  470. package/src/Secret.ts +296 -0
  471. package/src/Server.ts +285 -0
  472. package/src/ServiceUser.ts +295 -0
  473. package/src/Volume.ts +320 -0
  474. package/src/VolumeClient.ts +108 -0
  475. package/src/VolumeFiles.ts +194 -0
  476. package/src/WebhookToken.ts +230 -0
  477. package/src/WorkspaceSettings.ts +160 -0
  478. package/src/WriteApp.ts +43 -0
  479. package/src/WriteAppHttp.ts +51 -0
  480. package/src/WriteDict.ts +44 -0
  481. package/src/WriteDictHttp.ts +27 -0
  482. package/src/WriteQueue.ts +44 -0
  483. package/src/WriteQueueHttp.ts +27 -0
  484. package/src/WriteSecret.ts +60 -0
  485. package/src/WriteSecretHttp.ts +56 -0
  486. package/src/WriteVolume.ts +44 -0
  487. package/src/WriteVolumeHttp.ts +28 -0
  488. package/src/globals.d.ts +2 -0
  489. package/src/index.ts +85 -0
  490. package/src/internal/Declared.ts +80 -0
  491. package/src/internal/Deploy.ts +309 -0
  492. package/src/internal/Entrypoint.ts +198 -0
  493. package/src/internal/Rpc.ts +59 -0
  494. package/src/internal/RpcAuth.ts +132 -0
  495. package/src/internal/Runtime.ts +386 -0
  496. package/src/internal/Tags.ts +44 -0
  497. package/src/internal/TcpConnect.ts +78 -0
  498. package/src/internal/Transport.ts +25 -0
  499. package/src/internal.ts +147 -0
@@ -0,0 +1,99 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import type { RuntimeContext } from "alchemy/RuntimeContext";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import { makeModalBinding } from "./BindingHttp.ts";
6
+ import type { PersistentSandbox } from "./PersistentSandbox.ts";
7
+ import {
8
+ persistentSandboxHandle,
9
+ type PersistentSandboxHandleOf,
10
+ SandboxOps,
11
+ } from "./SandboxClient.ts";
12
+
13
+ /**
14
+ * A declared `Modal.PersistentSandbox`, reached from a runtime: its id, and
15
+ * the box's session API.
16
+ */
17
+ export interface ConnectedPersistentSandbox extends Omit<
18
+ PersistentSandboxHandleOf<RuntimeContext>,
19
+ "persistentSandboxId"
20
+ > {
21
+ /** The box's id (`ps-…`). */
22
+ readonly persistentSandboxId: Effect.Effect<string>;
23
+ }
24
+
25
+ /**
26
+ * Connect to a declared `Modal.PersistentSandbox` from any runtime. The
27
+ * handle follows Modal's session API: `session()` returns the running
28
+ * session, resuming the box from its last session's filesystem when it's
29
+ * paused, and every session is a full sandbox handle (`exec`, `files`,
30
+ * snapshots).
31
+ *
32
+ * ### Use a persistent box
33
+ * **Example:** From a Cloudflare Worker
34
+ * ```typescript
35
+ * import * as Cloudflare from "@alchemy.run/cloudflare";
36
+ * import * as Modal from "@alchemy.run/modal";
37
+ * import * as Effect from "effect/Effect";
38
+ * import * as HttpServerResponse from "effect/http/HttpServerResponse";
39
+ * import { DevBox } from "./DevBox.ts";
40
+ *
41
+ * export default class Shell extends Cloudflare.Worker<Shell>()(
42
+ * "Shell",
43
+ * { main: import.meta.url, compatibility: { flags: ["nodejs_compat"] } },
44
+ * Effect.gen(function* () {
45
+ * const box = yield* Modal.ConnectSandbox(DevBox);
46
+ * return {
47
+ * fetch: Effect.gen(function* () {
48
+ * const session = yield* box.session();
49
+ * const status = yield* session.exec("git status");
50
+ * return HttpServerResponse.text(status.stdout);
51
+ * }).pipe(Effect.orDie),
52
+ * };
53
+ * }).pipe(Effect.provide(Modal.ConnectSandboxHttp)),
54
+ * ) {}
55
+ * ```
56
+ *
57
+ * @binding
58
+ * @product Sandbox
59
+ */
60
+ export interface ConnectSandbox extends Binding.Service<
61
+ ConnectSandbox,
62
+ "Modal.ConnectSandbox",
63
+ (box: PersistentSandbox) => Effect.Effect<ConnectedPersistentSandbox>
64
+ > {}
65
+
66
+ export const ConnectSandbox = Binding.Service<ConnectSandbox>("Modal.ConnectSandbox");
67
+
68
+ /**
69
+ * {@link ConnectSandbox} over Modal's API. Grants the runtime's identity the
70
+ * `contributor` role on the box's environment.
71
+ *
72
+ * @layer
73
+ * @product Sandbox
74
+ * @provides Modal.ConnectSandbox
75
+ */
76
+ export const ConnectSandboxHttp = Layer.effect(
77
+ ConnectSandbox,
78
+ makeModalBinding({
79
+ tag: "Modal.ConnectSandbox",
80
+ operations: SandboxOps,
81
+ role: "contributor",
82
+ make: Effect.fn(function* (box: PersistentSandbox, ops) {
83
+ const persistentSandboxId = yield* box.persistentSandboxId;
84
+ const environment = yield* box.environment;
85
+ // The box's identity resolves at runtime, on each call.
86
+ const handle = Effect.map(Effect.all([persistentSandboxId, environment]), ([id, env]) =>
87
+ persistentSandboxHandle(ops, id, { environment: env }),
88
+ );
89
+ return {
90
+ persistentSandboxId,
91
+ session: () => Effect.flatMap(handle, (h) => h.session()),
92
+ terminate: () => Effect.flatMap(handle, (h) => h.terminate()),
93
+ } satisfies ConnectedPersistentSandbox;
94
+ }),
95
+ }),
96
+ );
97
+
98
+ /** {@link ConnectSandboxHttp}: Modal has one transport, so both names provide it. */
99
+ export const ConnectSandboxLive = ConnectSandboxHttp;
@@ -0,0 +1,121 @@
1
+ import type * as Bundle from "alchemy/Bundle/Bundle";
2
+ import type { PlatformProps } from "alchemy/Platform";
3
+ import type * as Effect from "effect/Effect";
4
+ import type { App } from "./App.ts";
5
+ import type { Mount } from "./Mounts.ts";
6
+ import type { Providers } from "./Providers.ts";
7
+ import type { DurationInput } from "./SandboxClient.ts";
8
+
9
+ /** A resource, or the module-scope Effect that declares it. */
10
+ export type Ref<T> = T | Effect.Effect<T, never, Providers>;
11
+
12
+ /**
13
+ * Container settings shared by `Modal.Function` and `Modal.Server`: the
14
+ * program, the image it runs on, and Modal's resource, scaling and
15
+ * placement options.
16
+ */
17
+ export interface ContainerProps extends PlatformProps {
18
+ /**
19
+ * Module entrypoint, bundled into the image. Typically `import.meta.url`.
20
+ * A change to the bundle builds a new image.
21
+ */
22
+ main: string;
23
+ /** The App the function is deployed in. Changing it replaces the function. */
24
+ app: Ref<App>;
25
+ /**
26
+ * Name of the function in its App, unique per App. Changing it replaces
27
+ * the function.
28
+ * @default the logical ID
29
+ */
30
+ name?: string;
31
+ /**
32
+ * Base image the bundle runs on. It needs Bun on the `PATH`; Alchemy adds
33
+ * Python (see {@link python}).
34
+ * @default "oven/bun:1"
35
+ */
36
+ image?: string;
37
+ /** Dockerfile lines run on the base before the bundle is added. */
38
+ commands?: string[];
39
+ /**
40
+ * Standalone Python added to the image. Modal starts every Function
41
+ * container with its Python entrypoint, which then starts the program.
42
+ * Set `false` when the base image already has Python 3.10+ on the `PATH`.
43
+ * @default "3.12"
44
+ */
45
+ python?: string | false;
46
+ /**
47
+ * Port the program listens on.
48
+ * @default 8000
49
+ */
50
+ port?: number;
51
+ /**
52
+ * Named export to load from `main`.
53
+ * @default "default"
54
+ */
55
+ handler?: string;
56
+ /**
57
+ * Extra environment variables for the program. Stored, with the bindings'
58
+ * env, in a Modal Secret attached to the function.
59
+ */
60
+ env?: Record<string, any>;
61
+ /** Bundler options. */
62
+ build?: Bundle.BundleConfig;
63
+ /** Secrets whose variables the program sees as environment variables. */
64
+ secrets?: Array<Ref<{ readonly secretId: string }>>;
65
+ /**
66
+ * Volumes and cloud buckets mounted into every container:
67
+ * `{ volume: Data, path: "/data" }`, `{ bucket: Uploads, path: "/uploads", secret: R2Keys }`.
68
+ * `Modal.MountVolume` and `Modal.MountBucket` add more from the program.
69
+ */
70
+ mounts?: Mount[];
71
+ /** CPU cores to reserve (fractional allowed). */
72
+ cpu?: number;
73
+ /** Most CPU cores a container may use. */
74
+ cpuLimit?: number;
75
+ /** Memory in MiB to reserve. */
76
+ memory?: number;
77
+ /** Most memory in MiB a container may use. */
78
+ memoryLimit?: number;
79
+ /** GPU: `"T4"`, `"L4"`, `"A10G"`, `"A100-80GB"`, `"H100"`, ..., with an optional `":<count>"`. */
80
+ gpu?: string;
81
+ /** Ephemeral disk in MiB. */
82
+ ephemeralDisk?: number;
83
+ /**
84
+ * Most time one input (a call, a request) may run.
85
+ * @default 300 seconds
86
+ */
87
+ timeout?: DurationInput;
88
+ /**
89
+ * Most time a container may take to start.
90
+ * @default the timeout
91
+ */
92
+ startupTimeout?: DurationInput;
93
+ /** Containers kept running even with no traffic. @default 0 */
94
+ minContainers?: number;
95
+ /** Most containers running at once. */
96
+ maxContainers?: number;
97
+ /** Idle containers kept on top of demand while the function is busy. */
98
+ bufferContainers?: number;
99
+ /** Seconds of sustained demand before scaling up. */
100
+ scaleupWindow?: number;
101
+ /** Seconds a container may stay idle before it scales down. */
102
+ scaledownWindow?: number;
103
+ /** Regions containers may run in (`"us-east"`, `"eu"`, ...). */
104
+ regions?: string[];
105
+ /** Cloud provider containers run on. */
106
+ cloud?: "aws" | "gcp" | "oci" | "auto";
107
+ /** Run on non-preemptible capacity (costs more). */
108
+ nonpreemptible?: boolean;
109
+ /** A `Modal.Proxy` outbound traffic goes through (static egress IPs). */
110
+ proxy?: Ref<{ readonly proxyId: string }>;
111
+ /** Block all outbound network access. */
112
+ blockNetwork?: boolean;
113
+ /** Stop the program from calling Modal's API with the container's identity. */
114
+ restrictModalAccess?: boolean;
115
+ /** Snapshot the container's memory after startup, so cold starts restore it. */
116
+ enableMemorySnapshot?: boolean;
117
+ /** Enable IPv6 networking between the function's containers. */
118
+ i6pn?: boolean;
119
+ /** Pin Modal's image builder version (`"2025.06"`). */
120
+ builderVersion?: string;
121
+ }
@@ -0,0 +1,9 @@
1
+ import * as Contributions from "alchemy/Contributions";
2
+
3
+ export default Contributions.make({
4
+ name: "modal",
5
+ auth: Contributions.lazy(
6
+ () => import("./AuthProvider.ts"),
7
+ (module) => module.ModalAuth,
8
+ ),
9
+ });
@@ -0,0 +1,95 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import type { RuntimeContext } from "alchemy/RuntimeContext";
3
+ import type * as Effect from "effect/Effect";
4
+ import type { DictsOps } from "./CreateDictHttp.ts";
5
+ import type { ensureDict, lookupDict } from "./Dict.ts";
6
+ import type { DictAttributes } from "./Dict.ts";
7
+ import type { ReadWriteDictClient } from "./DictClient.ts";
8
+ import type { Environment } from "./Environment.ts";
9
+ import type { ErrorOf, OpError } from "./internal.ts";
10
+
11
+ /** A dict created or found at runtime: its attributes plus a read-write client. */
12
+ export interface DictHandle extends ReadWriteDictClient {
13
+ readonly dictId: Effect.Effect<string>;
14
+ readonly name: string;
15
+ /** The attributes, to pass where a `Modal.Dict` is accepted (e.g. sandbox mounts). */
16
+ readonly attributes: DictAttributes;
17
+ }
18
+
19
+ /** Get, create, list and delete dicts by name in one environment. */
20
+ export interface DictsClientOf<R> {
21
+ /** The dict named `name`, created when missing (Modal's own get-or-create). */
22
+ getOrCreate(name: string): Effect.Effect<DictHandle, ErrorOf<typeof ensureDict>, R>;
23
+ /** The dict named `name`, or `undefined`. */
24
+ get(name: string): Effect.Effect<DictHandle | undefined, ErrorOf<typeof lookupDict>, R>;
25
+ /** Delete the dict named `name` (no-op when missing). */
26
+ delete(
27
+ name: string,
28
+ ): Effect.Effect<
29
+ void,
30
+ | ErrorOf<typeof lookupDict>
31
+ | Exclude<OpError<DictsOps, "delete">, { readonly _tag: "DictNotFound" }>,
32
+ R
33
+ >;
34
+ /** Names of every dict in the environment. */
35
+ list(): Effect.Effect<ReadonlyArray<string>, OpError<DictsOps, "list">, R>;
36
+ }
37
+
38
+ /** A DictsClient whose calls run inside a deployed runtime. */
39
+ export type DictsClient = DictsClientOf<RuntimeContext>;
40
+
41
+ /**
42
+ * Create dicts by name at runtime: one per user, session or task.
43
+ * Modal's native shape is get-or-create by name, so `getOrCreate` is
44
+ * idempotent and safe to call on every request.
45
+ *
46
+ * Bind it to a `Modal.Environment` to keep these runtime objects in their
47
+ * own namespace (or to nothing, for the workspace's default environment).
48
+ * They aren't in Alchemy state: deleting the environment removes them.
49
+ *
50
+ * Objects created at run time are tagged with the stack, stage and binding
51
+ * (`alchemy::stack`, `alchemy::stage`, `alchemy::id`) and are not deleted when
52
+ * the stack is destroyed. A Modal dict has only a name, so the tags become
53
+ * its name prefix, `Modal.runtimePrefix({ stack, stage, id })`: list them
54
+ * with `modal dict list` and delete the ones whose name starts with it.
55
+ *
56
+ * ### One dict per user
57
+ * **Example:** From a Cloudflare Worker
58
+ * ```typescript
59
+ * import * as Cloudflare from "@alchemy.run/cloudflare";
60
+ * import * as Modal from "@alchemy.run/modal";
61
+ * import * as Effect from "effect/Effect";
62
+ * import * as Layer from "effect/Layer";
63
+ * import { HttpServerRequest } from "effect/http/HttpServerRequest";
64
+ * import * as HttpServerResponse from "effect/http/HttpServerResponse";
65
+ * import { Agents, Coder } from "./Coder.ts";
66
+ *
67
+ * export default class Api extends Cloudflare.Worker<Api>()(
68
+ * "Api",
69
+ * { main: import.meta.url },
70
+ * Effect.gen(function* () {
71
+ * const dicts = yield* Modal.CreateDict(Agents);
72
+ * const sandboxes = yield* Modal.CreateSandbox(Coder);
73
+ * return {
74
+ * fetch: Effect.gen(function* () {
75
+ * const request = yield* HttpServerRequest;
76
+ * const user = request.headers["x-user"] ?? "anonymous";
77
+ * const state = yield* dicts.getOrCreate(`state-${user}`);
78
+ * yield* state.put("lastSeen", Date.now());
79
+ * return HttpServerResponse.text("ok");
80
+ * }).pipe(Effect.orDie),
81
+ * };
82
+ * }).pipe(Effect.provide(Layer.mergeAll(Modal.CreateDictHttp, Modal.CreateSandboxHttp))),
83
+ * ) {}
84
+ * ```
85
+ *
86
+ * @binding
87
+ * @product Dict
88
+ */
89
+ export interface CreateDict extends Binding.Service<
90
+ CreateDict,
91
+ "Modal.CreateDict",
92
+ (environment?: Environment) => Effect.Effect<DictsClient>
93
+ > {}
94
+
95
+ export const CreateDict = Binding.Service<CreateDict>("Modal.CreateDict");
@@ -0,0 +1,91 @@
1
+ import * as dict from "@distilled.cloud/modal/dict";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import { makeOpenModalBinding } from "./BindingHttp.ts";
5
+ import { CreateDict, type DictHandle, type DictsClientOf } from "./CreateDict.ts";
6
+ import { ensureDict, lookupDict, type DictAttributes } from "./Dict.ts";
7
+ import { DictOps, makeReadWriteDictClient } from "./DictClient.ts";
8
+ import type { Environment } from "./Environment.ts";
9
+ import { environmentOf, listAll, operations } from "./internal.ts";
10
+ import { ownedName, type RuntimeOwner, RuntimeOwnerOf, unownedName } from "./RuntimeOwner.ts";
11
+
12
+ /** The operations the client calls, resolved by `ModalBindings.withCredentials`. */
13
+ export const DictsOps = operations({
14
+ getOrCreate: dict.dictGetOrCreate,
15
+ delete: dict.deleteDict,
16
+ list: dict.listDict,
17
+ client: DictOps,
18
+ });
19
+
20
+ export type DictsOps = Effect.Success<typeof DictsOps>;
21
+
22
+ const handleOf = (attributes: DictAttributes, ops: DictsOps, name: string): DictHandle => ({
23
+ ...makeReadWriteDictClient(Effect.succeed(attributes.dictId), ops.client),
24
+ dictId: Effect.succeed(attributes.dictId),
25
+ name,
26
+ attributes,
27
+ });
28
+
29
+ /** A dicts client over an environment name resolved per call. */
30
+ export const makeDictsClient = (
31
+ environment: Effect.Effect<string | undefined>,
32
+ ops: DictsOps,
33
+ owner: Effect.Effect<RuntimeOwner | undefined> = Effect.undefined,
34
+ ): DictsClientOf<never> => ({
35
+ getOrCreate: (name) =>
36
+ Effect.flatMap(Effect.all([environment, owner]), ([env, stamp]) =>
37
+ ensureDict(ops.getOrCreate, ownedName(stamp, name), env),
38
+ ).pipe(Effect.map((attributes) => handleOf(attributes, ops, name))),
39
+ get: (name) =>
40
+ Effect.flatMap(Effect.all([environment, owner]), ([env, stamp]) =>
41
+ lookupDict(ops.getOrCreate, ownedName(stamp, name), env),
42
+ ).pipe(Effect.map((attributes) => (attributes ? handleOf(attributes, ops, name) : undefined))),
43
+ delete: (name) =>
44
+ Effect.gen(function* () {
45
+ const env = yield* environment;
46
+ const found = yield* lookupDict(ops.getOrCreate, ownedName(yield* owner, name), env);
47
+ if (!found) return;
48
+ yield* ops
49
+ .delete({ dictId: found.dictId })
50
+ .pipe(Effect.catchTag("DictNotFound", () => Effect.void));
51
+ }),
52
+ list: () =>
53
+ Effect.gen(function* () {
54
+ const env = yield* environment;
55
+ const stamp = yield* owner;
56
+ const items = yield* listAll(
57
+ (pagination) =>
58
+ ops
59
+ .list({ environmentName: environmentOf(env), pagination })
60
+ .pipe(Effect.map((response) => response.dicts ?? [])),
61
+ (item) => item.createdAt,
62
+ );
63
+ return items.flatMap((item) => {
64
+ const own = item.name ? unownedName(stamp, item.name) : undefined;
65
+ return own ? [own] : [];
66
+ });
67
+ }),
68
+ });
69
+
70
+ /**
71
+ * {@link CreateDict} over Modal's API. Grants the host's identity (a scoped
72
+ * `Modal.ServiceUser`) the `contributor` role on the environment.
73
+ *
74
+ * @layer
75
+ * @product Dict
76
+ * @provides Modal.CreateDict
77
+ */
78
+ export const CreateDictHttp = Layer.effect(
79
+ CreateDict,
80
+ makeOpenModalBinding({
81
+ tag: "Modal.CreateDict",
82
+ operations: DictsOps,
83
+ role: "contributor",
84
+ environmentOf: (environment?: Environment) => environment?.name,
85
+ make: Effect.fn(function* (ops, environment?: Environment) {
86
+ const name = environment ? yield* environment.name : Effect.undefined;
87
+ const owner = yield* RuntimeOwnerOf();
88
+ return makeDictsClient(name, ops, owner);
89
+ }),
90
+ }),
91
+ );
@@ -0,0 +1,105 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import type { RuntimeContext } from "alchemy/RuntimeContext";
3
+ import type * as Effect from "effect/Effect";
4
+ import type { App } from "./App.ts";
5
+ import type { buildFromOptions, ImagesOps } from "./CreateImageHttp.ts";
6
+ import type { ErrorOf, OpError } from "./internal.ts";
7
+
8
+ /** What to build: Modal's image inputs, in memory (no build context directory). */
9
+ export interface ImageBuildOptions {
10
+ /** Start from a registry image. */
11
+ readonly image?: string;
12
+ /** Start from a Modal image (a deploy-time `Modal.Image`, or a snapshot). */
13
+ readonly from?: { readonly imageId: string };
14
+ /** A whole Dockerfile as text (`FROM` included). Exclusive with `image`/`from`. */
15
+ readonly dockerfile?: string;
16
+ /** Dockerfile lines appended to the build. */
17
+ readonly commands?: ReadonlyArray<string>;
18
+ /** Files the commands `COPY`, by path relative to the build context. */
19
+ readonly files?: Record<string, string | Uint8Array>;
20
+ /** Secrets the build steps see as environment variables. */
21
+ readonly secrets?: ReadonlyArray<{ readonly secretId: string }>;
22
+ /** Run the build on a GPU. */
23
+ readonly gpu?: string;
24
+ /** Rebuild even when Modal has the same image cached. */
25
+ readonly force?: boolean;
26
+ }
27
+
28
+ /** Build images in one App at runtime. */
29
+ export interface ImagesClient {
30
+ /**
31
+ * Build an image (or return the cached one: Modal content-addresses
32
+ * builds) and wait until it's ready. Fails with `Modal.ImageBuildFailed`.
33
+ */
34
+ build(
35
+ options: ImageBuildOptions,
36
+ ): Effect.Effect<{ readonly imageId: string }, ErrorOf<typeof buildFromOptions>, RuntimeContext>;
37
+ /** The image published under `tag`, or `undefined`. */
38
+ fromTag(
39
+ tag: string,
40
+ ): Effect.Effect<
41
+ { readonly imageId: string } | undefined,
42
+ OpError<ImagesOps, "getByTag">,
43
+ RuntimeContext
44
+ >;
45
+ /** Publish an image under `tag` (moving the tag if it points elsewhere). */
46
+ publish(
47
+ image: { readonly imageId: string },
48
+ tag: string,
49
+ ): Effect.Effect<void, OpError<ImagesOps, "publish">, RuntimeContext>;
50
+ /** Remove a published tag (`name` or `name:tag`); the image itself stays. */
51
+ unpublish(tag: string): Effect.Effect<void, OpError<ImagesOps, "deleteName">, RuntimeContext>;
52
+ /** Delete an image. */
53
+ delete(image: {
54
+ readonly imageId: string;
55
+ }): Effect.Effect<void, OpError<ImagesOps, "delete">, RuntimeContext>;
56
+ }
57
+
58
+ /**
59
+ * Build Modal Images at runtime, e.g. one per repository a user connects,
60
+ * from the same inputs a `Modal.Image` takes. Modal builds remotely; the
61
+ * runtime needs no Docker.
62
+ *
63
+ * ### An image per repository
64
+ * **Example:** From a Cloudflare Worker
65
+ * ```typescript
66
+ * import * as Cloudflare from "@alchemy.run/cloudflare";
67
+ * import * as Modal from "@alchemy.run/modal";
68
+ * import * as Effect from "effect/Effect";
69
+ * import * as Layer from "effect/Layer";
70
+ * import { HttpServerRequest } from "effect/http/HttpServerRequest";
71
+ * import * as HttpServerResponse from "effect/http/HttpServerResponse";
72
+ * import { Coder } from "./Coder.ts";
73
+ *
74
+ * export default class Api extends Cloudflare.Worker<Api>()(
75
+ * "Api",
76
+ * { main: import.meta.url },
77
+ * Effect.gen(function* () {
78
+ * const images = yield* Modal.CreateImage(Coder);
79
+ * const sandboxes = yield* Modal.CreateSandbox(Coder);
80
+ * return {
81
+ * fetch: Effect.gen(function* () {
82
+ * const request = yield* HttpServerRequest;
83
+ * const repo = request.headers["x-repo"] ?? "alchemy-run/alchemy";
84
+ * const image = yield* images.build({
85
+ * image: "node:22-bookworm",
86
+ * commands: [`RUN git clone https://github.com/${repo} /work`],
87
+ * });
88
+ * const sandbox = yield* sandboxes.create({ image });
89
+ * return HttpServerResponse.text(sandbox.sandboxId);
90
+ * }).pipe(Effect.orDie),
91
+ * };
92
+ * }).pipe(Effect.provide(Layer.mergeAll(Modal.CreateImageHttp, Modal.CreateSandboxHttp))),
93
+ * ) {}
94
+ * ```
95
+ *
96
+ * @binding
97
+ * @product Image
98
+ */
99
+ export interface CreateImage extends Binding.Service<
100
+ CreateImage,
101
+ "Modal.CreateImage",
102
+ (app: App) => Effect.Effect<ImagesClient>
103
+ > {}
104
+
105
+ export const CreateImage = Binding.Service<CreateImage>("Modal.CreateImage");
@@ -0,0 +1,117 @@
1
+ import * as DockerfileParser from "@alchemy.run/docker/DockerfileParser";
2
+ import * as image from "@distilled.cloud/modal/image";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import type { App } from "./App.ts";
6
+ import { makeModalBinding } from "./BindingHttp.ts";
7
+ import { CreateImage, type ImageBuildOptions, type ImagesClient } from "./CreateImage.ts";
8
+ import { buildImage, ImageBuildOps } from "./ImageBuild.ts";
9
+ import { operations } from "./internal.ts";
10
+
11
+ /** The operations the client calls, resolved by `ModalBindings.withCredentials`. */
12
+ const ImagesOps = operations({
13
+ build: ImageBuildOps,
14
+ getByTag: image.imageGetByTag,
15
+ publish: image.publishImage,
16
+ deleteName: image.deleteImageName,
17
+ delete: image.deleteImage,
18
+ });
19
+
20
+ export type ImagesOps = Effect.Success<typeof ImagesOps>;
21
+
22
+ const toBytes = (data: string | Uint8Array) =>
23
+ Effect.sync(() => (typeof data === "string" ? new TextEncoder().encode(data) : data));
24
+
25
+ /** Build one image from runtime options in `appId`. */
26
+ export const buildFromOptions = Effect.fn(function* (
27
+ ops: ImageBuildOps,
28
+ appId: string,
29
+ options: ImageBuildOptions,
30
+ ) {
31
+ // Parsed to normalize it; Modal's builder rejects what it can't run.
32
+ // (The plan-time capability check lives with BuildPlan, which imports the
33
+ // bundler and so stays out of runtime bundles.)
34
+ const parsed =
35
+ options.dockerfile !== undefined
36
+ ? yield* DockerfileParser.parse(options.dockerfile)
37
+ : undefined;
38
+ const dockerfile = parsed ? DockerfileParser.renderLines(parsed) : [];
39
+ const extra = options.commands ?? [];
40
+ const commands = [...dockerfile, ...extra];
41
+ const contextFiles = yield* Effect.forEach(
42
+ Object.entries(options.files ?? {}),
43
+ ([filename, data]) => Effect.map(toBytes(data), (bytes) => ({ filename, data: bytes })),
44
+ );
45
+ const imageId = yield* buildImage(ops, appId, {
46
+ dockerTag: options.dockerfile
47
+ ? undefined
48
+ : options.from
49
+ ? undefined
50
+ : (options.image ?? "debian:bookworm-slim"),
51
+ baseImageId: options.dockerfile ? undefined : options.from?.imageId,
52
+ commands,
53
+ contextFiles,
54
+ secretIds: options.secrets?.map((s) => s.secretId),
55
+ gpu: options.gpu,
56
+ forceBuild: options.force,
57
+ });
58
+ return { imageId };
59
+ });
60
+
61
+ /** An images client over an app id resolved per call. */
62
+ export const makeImagesClient = (
63
+ appId: Effect.Effect<string>,
64
+ ops: ImagesOps,
65
+ environment: Effect.Effect<string | undefined> = Effect.undefined,
66
+ ): ImagesClient => ({
67
+ fromTag: (tag) =>
68
+ Effect.gen(function* () {
69
+ const env = yield* environment;
70
+ const found = yield* ops
71
+ .getByTag({ tag, environmentName: env ?? "" })
72
+ .pipe(Effect.catchTag("ImageNotFound", () => Effect.undefined));
73
+ return found?.imageId ? { imageId: found.imageId } : undefined;
74
+ }),
75
+ publish: (target, tag) =>
76
+ Effect.gen(function* () {
77
+ const env = yield* environment;
78
+ yield* ops.publish({ imageId: target.imageId, tag, environmentName: env ?? "" });
79
+ }),
80
+ unpublish: (tag) =>
81
+ Effect.gen(function* () {
82
+ const env = yield* environment;
83
+ // Modal deletes only an explicit `name:tag`; a bare name is `name:latest`.
84
+ const named = /:[^/]*$/.test(tag) ? tag : `${tag}:latest`;
85
+ yield* ops
86
+ .deleteName({ tag: env ? `${env}/${named}` : named })
87
+ .pipe(Effect.catchTag("ImageNotFound", () => Effect.void));
88
+ }),
89
+ build: (options) => Effect.flatMap(appId, (id) => buildFromOptions(ops.build, id, options)),
90
+ delete: (target) =>
91
+ ops.delete({ imageId: target.imageId }).pipe(
92
+ Effect.catchTag("ImageNotFound", () => Effect.void),
93
+ Effect.asVoid,
94
+ ),
95
+ });
96
+
97
+ /**
98
+ * {@link CreateImage} over Modal's API. Grants the host's identity (a scoped
99
+ * `Modal.ServiceUser`) the `contributor` role on the App's environment.
100
+ *
101
+ * @layer
102
+ * @product Image
103
+ * @provides Modal.CreateImage
104
+ */
105
+ export const CreateImageHttp = Layer.effect(
106
+ CreateImage,
107
+ makeModalBinding({
108
+ tag: "Modal.CreateImage",
109
+ operations: ImagesOps,
110
+ role: "contributor",
111
+ make: Effect.fn(function* (app: App, ops) {
112
+ const appId = yield* app.appId;
113
+ const environment = yield* app.environment;
114
+ return makeImagesClient(appId, ops, environment);
115
+ }),
116
+ }),
117
+ );