@alchemy.run/modal 0.0.0 → 2.0.0-beta.87

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 +96 -4
  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 +59 -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,70 @@
1
+ import type * as functions from "@distilled.cloud/modal/functions";
2
+ import * as Binding from "alchemy/Binding";
3
+ import type { RuntimeContext } from "alchemy/RuntimeContext";
4
+ import type * as Effect from "effect/Effect";
5
+ import type { FunctionLookupError } from "./FunctionTarget.ts";
6
+ import type { OpError } from "./internal.ts";
7
+ import type { FunctionTarget } from "./InvokeFunction.ts";
8
+ import type { ScaleFunctionOps } from "./ScaleFunctionHttp.ts";
9
+ import type { Server } from "./Server.ts";
10
+
11
+ /** Autoscaler settings to override; unset fields keep their value. */
12
+ export interface AutoscalerOverride {
13
+ /** Containers kept running regardless of demand. */
14
+ readonly minContainers?: number;
15
+ /** Most containers running at once. */
16
+ readonly maxContainers?: number;
17
+ /** Idle containers kept on top of demand while busy. */
18
+ readonly bufferContainers?: number;
19
+ /** Seconds of sustained demand before scaling up. */
20
+ readonly scaleupWindow?: number;
21
+ /** Seconds a container may stay idle before it scales down. */
22
+ readonly scaledownWindow?: number;
23
+ /** A Server's target concurrent requests per container (fractional allowed). */
24
+ readonly targetConcurrency?: number;
25
+ }
26
+
27
+ /** Change a function's autoscaler at runtime. */
28
+ export interface FunctionScaler {
29
+ /** The settings in effect. */
30
+ autoscaler(): Effect.Effect<
31
+ functions.AutoscalerSettings | undefined,
32
+ FunctionLookupError | OpError<ScaleFunctionOps, "schedulingParams">,
33
+ RuntimeContext
34
+ >;
35
+ /**
36
+ * Override settings until the next deploy, which restores the declared
37
+ * ones. Returns the settings now in effect.
38
+ */
39
+ update(
40
+ settings: AutoscalerOverride,
41
+ ): Effect.Effect<
42
+ functions.AutoscalerSettings | undefined,
43
+ FunctionLookupError | OpError<ScaleFunctionOps, "schedulingParams" | "updateSchedulingParams">,
44
+ RuntimeContext
45
+ >;
46
+ }
47
+
48
+ /**
49
+ * Scale a Modal Function or Server from a running program: keep containers
50
+ * warm ahead of a launch, or cap them at night. Overrides last until the
51
+ * next deploy; use the resource's own props (or `Modal.FunctionAutoscaler`
52
+ * for a function deployed outside the Stack) for the steady state.
53
+ *
54
+ * ### Warm up ahead of traffic
55
+ * **Example:** From a scheduled Worker
56
+ * ```typescript
57
+ * const generate = yield* Modal.ScaleFunction(Generate);
58
+ * yield* generate.update({ minContainers: 4, bufferContainers: 2 });
59
+ * ```
60
+ *
61
+ * @binding
62
+ * @product Function
63
+ */
64
+ export interface ScaleFunction extends Binding.Service<
65
+ ScaleFunction,
66
+ "Modal.ScaleFunction",
67
+ (target: FunctionTarget | Server) => Effect.Effect<FunctionScaler>
68
+ > {}
69
+
70
+ export const ScaleFunction = Binding.Service<ScaleFunction>("Modal.ScaleFunction");
@@ -0,0 +1,54 @@
1
+ import * as functions from "@distilled.cloud/modal/functions";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import { makeFunctionBinding } from "./FunctionTarget.ts";
5
+ import { operations } from "./internal.ts";
6
+ import type { FunctionTarget } from "./InvokeFunction.ts";
7
+ import { ScaleFunction, type FunctionScaler } from "./ScaleFunction.ts";
8
+ import type { Server } from "./Server.ts";
9
+
10
+ /** The operations the client calls, resolved by `ModalBindings.withCredentials`. */
11
+ const ScaleFunctionOps = operations({
12
+ schedulingParams: functions.functionGetSchedulingParams,
13
+ updateSchedulingParams: functions.functionUpdateSchedulingParams,
14
+ });
15
+
16
+ export type ScaleFunctionOps = Effect.Success<typeof ScaleFunctionOps>;
17
+
18
+ /**
19
+ * {@link ScaleFunction} over Modal's API. Grants the host's identity (a scoped
20
+ * `Modal.ServiceUser`) the `contributor` role on the function's environment.
21
+ *
22
+ * @layer
23
+ * @product Function
24
+ * @provides Modal.ScaleFunction
25
+ */
26
+ export const ScaleFunctionHttp = Layer.effect(
27
+ ScaleFunction,
28
+ makeFunctionBinding({
29
+ tag: "Modal.ScaleFunction",
30
+ operations: ScaleFunctionOps,
31
+ role: "contributor",
32
+ make: ({ functionId }, ops, _target: FunctionTarget | Server) =>
33
+ Effect.succeed({
34
+ autoscaler: () =>
35
+ Effect.flatMap(functionId, (id) => ops.schedulingParams({ functionId: id })).pipe(
36
+ Effect.map((response) => response.autoscalerConfiguration?.settings),
37
+ ),
38
+ update: (settings) =>
39
+ Effect.flatMap(functionId, (id) =>
40
+ ops.updateSchedulingParams({
41
+ functionId: id,
42
+ settings: {
43
+ minContainers: settings.minContainers,
44
+ maxContainers: settings.maxContainers,
45
+ bufferContainers: settings.bufferContainers,
46
+ scaleupWindow: settings.scaleupWindow,
47
+ scaledownWindow: settings.scaledownWindow,
48
+ targetConcurrencyFloat: settings.targetConcurrency,
49
+ },
50
+ }),
51
+ ).pipe(Effect.map((response) => response.currentSettings)),
52
+ } satisfies FunctionScaler),
53
+ }),
54
+ );
package/src/Secret.ts ADDED
@@ -0,0 +1,296 @@
1
+ import * as secret from "@distilled.cloud/modal/secret";
2
+ import { Unowned } from "alchemy/AdoptPolicy";
3
+ import { isResolved } from "alchemy/Diff";
4
+ import * as Provider from "alchemy/Provider";
5
+ import { Resource } from "alchemy/Resource";
6
+ import * as Data from "effect/Data";
7
+ import * as Effect from "effect/Effect";
8
+ import * as Redacted from "effect/Redacted";
9
+ import {
10
+ type EnvironmentInput,
11
+ envNameOf,
12
+ environmentNames,
13
+ environmentOf,
14
+ isGeneratedName,
15
+ listAll,
16
+ objectName,
17
+ } from "./internal.ts";
18
+ import { declarable } from "./internal/Declared.ts";
19
+ import type { Providers } from "./Providers.ts";
20
+ import { isRuntimeName } from "./RuntimeOwner.ts";
21
+
22
+ export class SecretUnexpectedResponse extends Data.TaggedError("Modal.SecretUnexpectedResponse")<{
23
+ readonly message: string;
24
+ }> {}
25
+
26
+ export interface SecretProps {
27
+ /**
28
+ * Secret name, unique per environment. If omitted, a unique name is
29
+ * generated from the stack, stage and logical ID. Changing it replaces the
30
+ * secret.
31
+ */
32
+ name?: string;
33
+ /**
34
+ * Environment the secret lives in. Changing it replaces the secret.
35
+ * @default the workspace's default environment
36
+ */
37
+ environment?: EnvironmentInput;
38
+ /**
39
+ * The secret's environment variables. Containers that attach the secret
40
+ * see each entry as an environment variable; an outbound header
41
+ * replacement can inject one into requests instead, so the container never
42
+ * sees it. Every deploy writes the full set.
43
+ */
44
+ env: Record<string, string | Redacted.Redacted<string>>;
45
+ }
46
+
47
+ export interface SecretAttributes {
48
+ /** Secret ID (`st-…`). */
49
+ secretId: string;
50
+ /** Secret name. */
51
+ name: string;
52
+ /** Environment name, or `undefined` for the workspace default. */
53
+ environment: string | undefined;
54
+ /** The secret's variable names (values are never returned by Modal). */
55
+ keys: string[];
56
+ }
57
+
58
+ /**
59
+ * A Modal Secret: a named set of environment variables stored by Modal and
60
+ * attached to Sandboxes and Functions by reference.
61
+ *
62
+ * A Sandbox can see a secret two ways: as environment variables
63
+ * (`secrets: [OpenAI]`), or through an outbound header replacement
64
+ * (`outboundPolicy`), where Modal adds the value to matching HTTPS requests
65
+ * on their way out and the sandbox never holds it. Prefer the second for
66
+ * credentials an agent's code shouldn't be able to read.
67
+ *
68
+ * Modal never returns secret values, so every deploy overwrites the full
69
+ * `env` map. Modal secrets have no tags; ownership is inferred from Alchemy
70
+ * state.
71
+ *
72
+ * ### Creating a Secret
73
+ * **Example:** An API key from your Alchemy secrets
74
+ * ```typescript
75
+ * import * as Alchemy from "alchemy";
76
+ * import * as Modal from "@alchemy.run/modal";
77
+ *
78
+ * export const OpenAI = Modal.Secret("OpenAI", {
79
+ * env: { OPENAI_API_KEY: Alchemy.Secret("OPENAI_API_KEY") },
80
+ * });
81
+ * ```
82
+ *
83
+ * ### Using a Secret in a Sandbox
84
+ * **Example:** As environment variables
85
+ * ```typescript
86
+ * // construction phase: read the Secret's id
87
+ * const openaiId = yield* (yield* OpenAI).secretId;
88
+ * // in a handler
89
+ * const openai = { secretId: yield* openaiId };
90
+ * const sandbox = yield* sandboxes.create({ secrets: [openai] });
91
+ * ```
92
+ *
93
+ * **Example:** Injected into outbound requests only
94
+ * ```typescript
95
+ * // construction phase: read the Secret's id
96
+ * const openaiId = yield* (yield* OpenAI).secretId;
97
+ * // in a handler
98
+ * const openai = { secretId: yield* openaiId };
99
+ * const sandbox = yield* sandboxes.create({
100
+ * outboundPolicy: {
101
+ * routes: [
102
+ * {
103
+ * https: {
104
+ * domains: ["api.openai.com"],
105
+ * headerReplacements: [{ secret: openai, headers: { Authorization: "Bearer $OPENAI_API_KEY" } }],
106
+ * },
107
+ * },
108
+ * { any: {} },
109
+ * ],
110
+ * },
111
+ * });
112
+ * ```
113
+ *
114
+ * ### Rotating a Secret at runtime
115
+ * **Example:** Bind write access
116
+ * ```typescript
117
+ * const openai = yield* Modal.WriteSecret(OpenAI);
118
+ * yield* openai.put({ OPENAI_API_KEY: newKey });
119
+ * ```
120
+ *
121
+ * ### Looking up an existing secret
122
+ * `Secret.lookup` references a secret Alchemy doesn't manage (created with
123
+ * the Modal CLI or by another stack). It is read during plan/deploy, never
124
+ * created, updated or deleted. Its values are never read; `keys` lists their
125
+ * names.
126
+ *
127
+ * **Example:** Reference an existing secret
128
+ * ```typescript
129
+ * const openai = Modal.Secret.lookup({ name: "openai" });
130
+ * ```
131
+ *
132
+ * @resource
133
+ * @product Secret
134
+ */
135
+ export const Secret = declarable<Secret>()(Resource<Secret>("Modal.Secret"));
136
+
137
+ export type Secret = Resource<
138
+ "Modal.Secret",
139
+ SecretProps,
140
+ SecretAttributes,
141
+ never,
142
+ Providers,
143
+ SecretLookup
144
+ >;
145
+
146
+ /**
147
+ * Props for {@link Secret.lookup}: find a secret this stack
148
+ * doesn't manage by its name.
149
+ */
150
+ export interface SecretLookup {
151
+ /** Secret name. */
152
+ name: string;
153
+ /**
154
+ * Modal environment the object lives in.
155
+ * @default the workspace's default environment
156
+ */
157
+ environment?: string;
158
+ }
159
+
160
+ const plainEnv = (env: Record<string, string | Redacted.Redacted<string>>) =>
161
+ Object.fromEntries(
162
+ Object.entries(env).map(([key, value]) => [
163
+ key,
164
+ Redacted.isRedacted(value) ? Redacted.value(value) : value,
165
+ ]),
166
+ );
167
+
168
+ /** A secret by name, or `undefined` when missing. */
169
+ export const lookupSecret = Effect.fn(function* (
170
+ getOrCreate: Effect.Success<typeof secret.secretGetOrCreate>,
171
+ name: string,
172
+ env: string | undefined,
173
+ ) {
174
+ const found = yield* getOrCreate({
175
+ deploymentName: name,
176
+ environmentName: environmentOf(env),
177
+ objectCreationType: "OBJECT_CREATION_TYPE_UNSPECIFIED",
178
+ }).pipe(Effect.catchTag("SecretNotFound", () => Effect.undefined));
179
+ if (!found?.secretId) return undefined;
180
+ return {
181
+ secretId: found.secretId,
182
+ name,
183
+ environment: env,
184
+ keys: found.metadata?.keys ?? [],
185
+ } satisfies SecretAttributes;
186
+ });
187
+
188
+ /**
189
+ * Create or overwrite a secret by name: the one implementation behind
190
+ * {@link Secret}'s reconcile and the runtime {@link CreateSecret} and
191
+ * {@link WriteSecret} clients.
192
+ */
193
+ export const putSecret = Effect.fn(function* (
194
+ getOrCreate: Effect.Success<typeof secret.secretGetOrCreate>,
195
+ name: string,
196
+ env: string | undefined,
197
+ values: Record<string, string | Redacted.Redacted<string>>,
198
+ ) {
199
+ const written = yield* getOrCreate({
200
+ deploymentName: name,
201
+ environmentName: environmentOf(env),
202
+ objectCreationType: "OBJECT_CREATION_TYPE_CREATE_OVERWRITE_IF_EXISTS",
203
+ envDict: plainEnv(values),
204
+ });
205
+ if (!written.secretId) {
206
+ return yield* new SecretUnexpectedResponse({
207
+ message: `Modal returned no id for secret ${name}`,
208
+ });
209
+ }
210
+ return {
211
+ secretId: written.secretId,
212
+ name,
213
+ environment: env,
214
+ keys: written.metadata?.keys ?? Object.keys(values).sort(),
215
+ } satisfies SecretAttributes;
216
+ });
217
+
218
+ export const SecretProvider = () =>
219
+ Provider.effect(
220
+ Secret,
221
+ Effect.gen(function* () {
222
+ return {
223
+ // An overwrite gives the secret a new id, so only its name is stable.
224
+ stables: ["name", "environment"],
225
+ diff: Effect.fn(function* ({ id, news, olds, output }) {
226
+ if (!isResolved(news)) return undefined;
227
+ if (envNameOf(news.environment) !== envNameOf(olds?.environment))
228
+ return { action: "replace" } as const;
229
+ const name = yield* objectName(id, news.name);
230
+ if (output !== undefined && name !== output.name) return { action: "replace" } as const;
231
+ return undefined;
232
+ }),
233
+ lookup: Effect.fn(function* ({ name, environment }) {
234
+ return yield* lookupSecret(yield* secret.secretGetOrCreate, name, environment);
235
+ }),
236
+
237
+ read: Effect.fn(function* ({ id, olds, output }) {
238
+ const name = output?.name ?? (yield* objectName(id, olds?.name));
239
+ const observed = yield* lookupSecret(
240
+ yield* secret.secretGetOrCreate,
241
+ name,
242
+ output?.environment ?? envNameOf(olds?.environment),
243
+ );
244
+ if (!observed) return undefined;
245
+ return output !== undefined || olds?.name === undefined ? observed : Unowned(observed);
246
+ }),
247
+ reconcile: Effect.fn(function* ({ id, news, output, session }) {
248
+ const name = output?.name ?? (yield* objectName(id, news.name));
249
+ // Values can't be observed, so overwriting is the sync: Modal
250
+ // replaces the secret atomically, under a new secret id.
251
+ yield* session.note(`Writing secret ${name}...`);
252
+ return yield* putSecret(
253
+ yield* secret.secretGetOrCreate,
254
+ name,
255
+ envNameOf(news.environment),
256
+ news.env,
257
+ );
258
+ }),
259
+ delete: Effect.fn(function* ({ output }) {
260
+ yield* secret
261
+ .deleteSecret({ secretId: output.secretId })
262
+ .pipe(Effect.catchTag("SecretNotFound", () => Effect.void));
263
+ }),
264
+ list: Effect.fn(function* () {
265
+ const envs = yield* environmentNames;
266
+ const all: SecretAttributes[] = [];
267
+ for (const env of envs) {
268
+ const items = yield* listAll(
269
+ (pagination) =>
270
+ secret
271
+ .listSecret({ environmentName: env, pagination })
272
+ .pipe(Effect.map((response) => response.items ?? [])),
273
+ (item) => item.createdAt,
274
+ );
275
+ for (const item of items) {
276
+ if (
277
+ !item.secretId ||
278
+ !(
279
+ isGeneratedName(item.label ?? item.metadata?.name) ||
280
+ isRuntimeName(item.label ?? item.metadata?.name)
281
+ )
282
+ )
283
+ continue;
284
+ all.push({
285
+ secretId: item.secretId,
286
+ name: item.label ?? item.metadata?.name ?? "",
287
+ environment: env,
288
+ keys: item.metadata?.keys ?? [],
289
+ });
290
+ }
291
+ }
292
+ return all;
293
+ }),
294
+ };
295
+ }),
296
+ );
package/src/Server.ts ADDED
@@ -0,0 +1,285 @@
1
+ import * as functions from "@distilled.cloud/modal/functions";
2
+ import { Platform, type Main, type MainRpc } from "alchemy/Platform";
3
+ import * as Provider from "alchemy/Provider";
4
+ import type { Resource } from "alchemy/Resource";
5
+ import type { HostRuntimeContext, ServerHost } from "alchemy/Runtime/Process";
6
+ import * as Effect from "effect/Effect";
7
+ import * as Schedule from "effect/Schedule";
8
+ import type { ContainerProps } from "./Container.ts";
9
+ import { environmentOf, seconds } from "./internal.ts";
10
+ import { ENTRYPOINT, RPC_SERVE_ENV } from "./internal/Entrypoint.ts";
11
+ import { createModalRuntimeContext } from "./internal/Rpc.ts";
12
+ import {
13
+ resolveContainerProps,
14
+ runtimeLifecycle,
15
+ type RuntimeAttributes,
16
+ } from "./internal/Runtime.ts";
17
+ import type { MountContract } from "./Mounts.ts";
18
+ import type { Providers } from "./Providers.ts";
19
+ import type { DurationInput } from "./SandboxClient.ts";
20
+
21
+ export interface ServerProps extends ContainerProps {
22
+ /**
23
+ * Region requests are routed through (`"us-east"`, `"us-west"`, `"eu-west"`,
24
+ * `"ap-south"`, ...). Containers run near it.
25
+ * @default "us-east"
26
+ */
27
+ routingRegion?: string;
28
+ /**
29
+ * Serve without Modal's proxy auth. By default every request needs the
30
+ * `Modal-Key` / `Modal-Secret` headers of a `Modal.WebhookToken`.
31
+ * @default false
32
+ */
33
+ unauthenticated?: boolean;
34
+ /** Serve HTTP/2 to the program. */
35
+ h2?: boolean;
36
+ /**
37
+ * Time in-flight requests get to finish when a container shuts down, at
38
+ * most an hour.
39
+ * @default 0
40
+ */
41
+ exitGracePeriod?: DurationInput;
42
+ /**
43
+ * Concurrent requests per container the autoscaler aims for; may be
44
+ * fractional (`1.5`). `0` turns autoscaling off.
45
+ */
46
+ targetConcurrency?: number;
47
+ /**
48
+ * Most concurrent requests per container; more get `429`.
49
+ * @default unlimited
50
+ */
51
+ maxConcurrency?: number;
52
+ /**
53
+ * Sticky sessions: each session is pinned to one container
54
+ * (`server.sessions.start()` in Modal's clients).
55
+ * @default false
56
+ */
57
+ sessioned?: boolean;
58
+ }
59
+
60
+ export interface ServerAttributes extends RuntimeAttributes {
61
+ /** The Server's URL. */
62
+ url: string | undefined;
63
+ /** Region requests are routed through. */
64
+ routingRegion: string;
65
+ /** Whether requests skip Modal's proxy auth. */
66
+ unauthenticated: boolean;
67
+ }
68
+
69
+ export type Server = Resource<
70
+ "Modal.Server",
71
+ ServerProps,
72
+ ServerAttributes,
73
+ { env?: Record<string, any>; mounts?: MountContract; rpcCallers?: string[] },
74
+ Providers
75
+ >;
76
+
77
+ export type ServerServices = ServerHost;
78
+ /**
79
+ * What the program returns: `fetch` for HTTP, and any other functions,
80
+ * its RPC methods.
81
+ */
82
+ export type ServerShape =
83
+ | Main<ServerServices>
84
+ | (Exclude<Main<ServerServices>, void> & MainRpc<ServerServices>);
85
+ export type ServerRuntimeContext = HostRuntimeContext;
86
+
87
+ /**
88
+ * A Modal Server: your program as a long-running HTTP server on Modal, with
89
+ * low-latency routing through one region and autoscaling on concurrent
90
+ * requests. Use it for APIs, model servers and anything that keeps
91
+ * connections open; use `Modal.Function` with `web` for simple endpoints.
92
+ *
93
+ * Alchemy bundles `main`, builds it into an image on Modal's builder (no
94
+ * Docker) and deploys the Server into its `Modal.App`. Each container starts
95
+ * the program, and Modal routes the Server's URL to its `fetch` handler.
96
+ * Requests need Modal's proxy auth headers unless `unauthenticated` is set:
97
+ * bind `Modal.FetchServer(server)` to call it from another runtime.
98
+ *
99
+ * ### Effect program
100
+ * **Example:** An API server
101
+ * ```typescript
102
+ * // src/Api.ts
103
+ * import * as Modal from "@alchemy.run/modal";
104
+ * import * as Effect from "effect/Effect";
105
+ * import * as HttpServerResponse from "effect/http/HttpServerResponse";
106
+ * import { Backend } from "./Backend.ts";
107
+ *
108
+ * export default class Api extends Modal.Server<Api>()(
109
+ * "Api",
110
+ * { main: import.meta.url, app: Backend, routingRegion: "us-east" },
111
+ * Effect.gen(function* () {
112
+ * return {
113
+ * fetch: Effect.succeed(HttpServerResponse.text("ok")),
114
+ * };
115
+ * }),
116
+ * ) {}
117
+ * ```
118
+ *
119
+ * ### Async program
120
+ * **Example:** A plain HTTP server, no Effect (it runs on Bun)
121
+ * ```typescript
122
+ * // src/Api.ts
123
+ * import * as Modal from "@alchemy.run/modal";
124
+ * import { Backend } from "./Backend.ts";
125
+ *
126
+ * export const Api = Modal.Server("Api", {
127
+ * main: "./src/api-server.ts",
128
+ * app: Backend,
129
+ * unauthenticated: true,
130
+ * env: { GREETING: "hello" },
131
+ * });
132
+ * export type ApiEnv = Modal.InferEnv<typeof Api>;
133
+ * ```
134
+ *
135
+ * ```typescript
136
+ * // src/api-server.ts
137
+ * import type { ApiEnv } from "./Api.ts";
138
+ *
139
+ * const env = process.env as unknown as ApiEnv;
140
+ *
141
+ * Bun.serve({ port: Number(process.env.PORT), fetch: () => new Response(env.GREETING) });
142
+ * ```
143
+ *
144
+ * ### Calling it
145
+ * **Example:** From a Cloudflare Worker, with proxy auth
146
+ * ```typescript
147
+ * const api = yield* Modal.FetchServer(Api);
148
+ * const response = yield* api.fetch(HttpClientRequest.get("/"));
149
+ * ```
150
+ *
151
+ * ### Scaling
152
+ * **Example:** Two warm containers, 20 requests each
153
+ * ```typescript
154
+ * export default class Api extends Modal.Server<Api>()(
155
+ * "Api",
156
+ * {
157
+ * main: import.meta.url,
158
+ * app: Backend,
159
+ * minContainers: 2,
160
+ * targetConcurrency: 20,
161
+ * maxConcurrency: 50,
162
+ * exitGracePeriod: "30 seconds",
163
+ * },
164
+ * program,
165
+ * ) {}
166
+ * ```
167
+ *
168
+ * @resource
169
+ * @product Server
170
+ */
171
+ export const Server: Platform<Server, ServerServices, ServerShape, ServerRuntimeContext> = Platform(
172
+ "Modal.Server",
173
+ {
174
+ createRuntimeContext: createModalRuntimeContext("Modal.Server"),
175
+ transformProps: resolveContainerProps,
176
+ },
177
+ );
178
+
179
+ const bootstrapEntry =
180
+ (handler: string) =>
181
+ (importPath: string): string =>
182
+ `
183
+ import { bootstrap } from "@alchemy.run/modal/Bootstrap";
184
+ import { ${handler} as entrypoint } from ${JSON.stringify(importPath)};
185
+
186
+ await bootstrap(entrypoint);
187
+ `;
188
+
189
+ const DEFAULT_REGION = "us-east";
190
+
191
+ const definitionOf = (
192
+ props: ServerProps,
193
+ context: { readonly port: number; readonly startupTimeout: number },
194
+ ): functions.Function => {
195
+ const region = props.routingRegion ?? DEFAULT_REGION;
196
+ return {
197
+ implementationName: ENTRYPOINT.server,
198
+ isServer: true,
199
+ isSessioned: props.sessioned ?? false,
200
+ routingRegion: region,
201
+ httpConfig: {
202
+ port: context.port,
203
+ proxyRegions: [region],
204
+ startupTimeout: Math.round(context.startupTimeout),
205
+ exitGracePeriod: Math.round(seconds(props.exitGracePeriod) ?? 0),
206
+ h2Enabled: props.h2 ?? false,
207
+ unauthenticated: props.unauthenticated ?? false,
208
+ },
209
+ maxConcurrentInputs: props.maxConcurrency ?? 0,
210
+ supportedInputFormats: [],
211
+ supportedOutputFormats: [],
212
+ };
213
+ };
214
+
215
+ export const ServerProvider = () =>
216
+ Provider.effect(
217
+ Server,
218
+ Effect.gen(function* () {
219
+ const lifecycle = yield* runtimeLifecycle<ServerProps>({
220
+ type: "Modal.Server",
221
+ definition: (props, context) => {
222
+ const definition = definitionOf(props, context);
223
+ return props.targetConcurrency === undefined
224
+ ? definition
225
+ : {
226
+ ...definition,
227
+ autoscalerSettings: { targetConcurrencyFloat: props.targetConcurrency },
228
+ };
229
+ },
230
+ bootstrap: bootstrapEntry,
231
+ // Behind proxy auth Modal authenticates every request, so the
232
+ // program serves RPC; an unauthenticated Server never does.
233
+ env: (props): Record<string, string> =>
234
+ props.unauthenticated ? {} : { [RPC_SERVE_ENV]: "1" },
235
+ });
236
+
237
+ /** The Server's URL: Modal assigns it once the App is published. */
238
+ const urlOf = Effect.fn(function* (
239
+ attributes: RuntimeAttributes,
240
+ published: ReadonlyArray<string> | undefined,
241
+ ) {
242
+ if (published?.[0]) return published[0];
243
+ const found = yield* functions
244
+ .getFunction({
245
+ appName: attributes.appName ?? "",
246
+ objectTag: attributes.name,
247
+ environmentName: environmentOf(attributes.environment),
248
+ })
249
+ .pipe(
250
+ Effect.map((response) => response.handleMetadata?.ExperimentalFlashUrls?.[0]),
251
+ Effect.repeat({
252
+ schedule: Schedule.spaced("2 seconds"),
253
+ until: (url) => url !== undefined,
254
+ times: 10,
255
+ }),
256
+ );
257
+ return found;
258
+ });
259
+
260
+ return {
261
+ stables: lifecycle.stables,
262
+ diff: lifecycle.diff,
263
+ read: Effect.fn(function* ({ output }) {
264
+ const found = yield* lifecycle.read({ output });
265
+ return found === undefined ? undefined : (output as ServerAttributes);
266
+ }),
267
+ reconcile: Effect.fn(function* ({ id, news, output, session, bindings }) {
268
+ const { attributes, metadata } = yield* lifecycle.reconcile({
269
+ id,
270
+ news,
271
+ output,
272
+ session,
273
+ bindings,
274
+ });
275
+ return {
276
+ ...attributes,
277
+ url: yield* urlOf(attributes, metadata?.ExperimentalFlashUrls),
278
+ routingRegion: news.routingRegion ?? DEFAULT_REGION,
279
+ unauthenticated: news.unauthenticated ?? false,
280
+ };
281
+ }),
282
+ delete: lifecycle.delete,
283
+ };
284
+ }),
285
+ );