@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,83 @@
1
+ import * as secret from "@distilled.cloud/modal/secret";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import { makeOpenModalBinding } from "./BindingHttp.ts";
5
+ import { CreateSecret, type SecretsClientOf } from "./CreateSecret.ts";
6
+ import type { Environment } from "./Environment.ts";
7
+ import { environmentOf, listAll, operations } from "./internal.ts";
8
+ import { ownedName, type RuntimeOwner, RuntimeOwnerOf, unownedName } from "./RuntimeOwner.ts";
9
+ import { lookupSecret, putSecret } from "./Secret.ts";
10
+
11
+ /** The operations the client calls, resolved by `ModalBindings.withCredentials`. */
12
+ export const SecretsOps = operations({
13
+ getOrCreate: secret.secretGetOrCreate,
14
+ delete: secret.deleteSecret,
15
+ list: secret.listSecret,
16
+ });
17
+
18
+ export type SecretsOps = Effect.Success<typeof SecretsOps>;
19
+
20
+ /** A secrets client over an environment name resolved per call. */
21
+ export const makeSecretsClient = (
22
+ environment: Effect.Effect<string | undefined>,
23
+ ops: SecretsOps,
24
+ owner: Effect.Effect<RuntimeOwner | undefined> = Effect.undefined,
25
+ ): SecretsClientOf<never> => ({
26
+ put: (name, env) =>
27
+ Effect.flatMap(Effect.all([environment, owner]), ([e, stamp]) =>
28
+ putSecret(ops.getOrCreate, ownedName(stamp, name), e, env),
29
+ ),
30
+ get: (name) =>
31
+ Effect.flatMap(Effect.all([environment, owner]), ([e, stamp]) =>
32
+ lookupSecret(ops.getOrCreate, ownedName(stamp, name), e),
33
+ ),
34
+ delete: (name) =>
35
+ Effect.gen(function* () {
36
+ const env = yield* environment;
37
+ const found = yield* lookupSecret(ops.getOrCreate, ownedName(yield* owner, name), env);
38
+ if (!found) return;
39
+ yield* ops
40
+ .delete({ secretId: found.secretId })
41
+ .pipe(Effect.catchTag("SecretNotFound", () => Effect.void));
42
+ }),
43
+ list: () =>
44
+ Effect.gen(function* () {
45
+ const env = yield* environment;
46
+ const stamp = yield* owner;
47
+ const items = yield* listAll(
48
+ (pagination) =>
49
+ ops
50
+ .list({ environmentName: environmentOf(env), pagination })
51
+ .pipe(Effect.map((response) => response.items ?? [])),
52
+ (item) => item.createdAt,
53
+ );
54
+ return items.flatMap((item) => {
55
+ const name = item.label ?? item.metadata?.name;
56
+ const own = name ? unownedName(stamp, name) : undefined;
57
+ return own ? [own] : [];
58
+ });
59
+ }),
60
+ });
61
+
62
+ /**
63
+ * {@link CreateSecret} over Modal's API. Grants the host's identity (a scoped
64
+ * `Modal.ServiceUser`) the `contributor` role on the environment.
65
+ *
66
+ * @layer
67
+ * @product Secret
68
+ * @provides Modal.CreateSecret
69
+ */
70
+ export const CreateSecretHttp = Layer.effect(
71
+ CreateSecret,
72
+ makeOpenModalBinding({
73
+ tag: "Modal.CreateSecret",
74
+ operations: SecretsOps,
75
+ role: "contributor",
76
+ environmentOf: (environment?: Environment) => environment?.name,
77
+ make: Effect.fn(function* (ops, environment?: Environment) {
78
+ const name = environment ? yield* environment.name : Effect.undefined;
79
+ const owner = yield* RuntimeOwnerOf();
80
+ return makeSecretsClient(name, ops, owner);
81
+ }),
82
+ }),
83
+ );
@@ -0,0 +1,96 @@
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 { VolumesOps } from "./CreateVolumeHttp.ts";
5
+ import type { Environment } from "./Environment.ts";
6
+ import type { ErrorOf, OpError } from "./internal.ts";
7
+ import type { ensureVolume, lookupVolume } from "./Volume.ts";
8
+ import type { VolumeAttributes } from "./Volume.ts";
9
+ import type { ReadWriteVolumeClient } from "./VolumeClient.ts";
10
+
11
+ /** A volume created or found at runtime: its attributes plus a read-write client. */
12
+ export interface VolumeHandle extends ReadWriteVolumeClient {
13
+ readonly volumeId: Effect.Effect<string>;
14
+ readonly name: string;
15
+ /** The attributes, to pass where a `Modal.Volume` is accepted (e.g. sandbox mounts). */
16
+ readonly attributes: VolumeAttributes;
17
+ }
18
+
19
+ /** Get, create, list and delete volumes by name in one environment. */
20
+ export interface VolumesClientOf<R> {
21
+ /** The volume named `name`, created when missing (Modal's own get-or-create). */
22
+ getOrCreate(name: string): Effect.Effect<VolumeHandle, ErrorOf<typeof ensureVolume>, R>;
23
+ /** The volume named `name`, or `undefined`. */
24
+ get(name: string): Effect.Effect<VolumeHandle | undefined, ErrorOf<typeof lookupVolume>, R>;
25
+ /** Delete the volume named `name` (no-op when missing). */
26
+ delete(
27
+ name: string,
28
+ ): Effect.Effect<
29
+ void,
30
+ | ErrorOf<typeof lookupVolume>
31
+ | Exclude<OpError<VolumesOps, "delete">, { readonly _tag: "VolumeNotFound" }>,
32
+ R
33
+ >;
34
+ /** Names of every volume in the environment. */
35
+ list(): Effect.Effect<ReadonlyArray<string>, OpError<VolumesOps, "list">, R>;
36
+ }
37
+
38
+ /** A VolumesClient whose calls run inside a deployed runtime. */
39
+ export type VolumesClient = VolumesClientOf<RuntimeContext>;
40
+
41
+ /**
42
+ * Create volumes 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 volume has only a name, so the tags become
53
+ * its name prefix, `Modal.runtimePrefix({ stack, stage, id })`: list them
54
+ * with `modal volume list` and delete the ones whose name starts with it.
55
+ *
56
+ * ### One volume 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 volumes = yield* Modal.CreateVolume(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 home = yield* volumes.getOrCreate(`user-${user}`);
78
+ * yield* home.writeFile("/notes.md", "hello");
79
+ * const sandbox = yield* sandboxes.create({ mounts: [{ volume: home, path: "/home/user" }] });
80
+ * return HttpServerResponse.text("ok");
81
+ * }).pipe(Effect.orDie),
82
+ * };
83
+ * }).pipe(Effect.provide(Layer.mergeAll(Modal.CreateVolumeHttp, Modal.CreateSandboxHttp))),
84
+ * ) {}
85
+ * ```
86
+ *
87
+ * @binding
88
+ * @product Volume
89
+ */
90
+ export interface CreateVolume extends Binding.Service<
91
+ CreateVolume,
92
+ "Modal.CreateVolume",
93
+ (environment?: Environment) => Effect.Effect<VolumesClient>
94
+ > {}
95
+
96
+ export const CreateVolume = Binding.Service<CreateVolume>("Modal.CreateVolume");
@@ -0,0 +1,93 @@
1
+ import * as volume from "@distilled.cloud/modal/volume";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import { makeOpenModalBinding } from "./BindingHttp.ts";
5
+ import { CreateVolume, type VolumeHandle, type VolumesClientOf } from "./CreateVolume.ts";
6
+ import type { Environment } from "./Environment.ts";
7
+ import { environmentOf, listAll, operations } from "./internal.ts";
8
+ import { ownedName, type RuntimeOwner, RuntimeOwnerOf, unownedName } from "./RuntimeOwner.ts";
9
+ import { ensureVolume, lookupVolume, type VolumeAttributes } from "./Volume.ts";
10
+ import { makeReadWriteVolumeClient } from "./VolumeClient.ts";
11
+ import { VolumeFileOps } from "./VolumeFiles.ts";
12
+
13
+ /** The operations the client calls, resolved by `ModalBindings.withCredentials`. */
14
+ export const VolumesOps = operations({
15
+ getOrCreate: volume.volumeGetOrCreate,
16
+ delete: volume.deleteVolume,
17
+ list: volume.listVolume,
18
+ client: VolumeFileOps,
19
+ });
20
+
21
+ export type VolumesOps = Effect.Success<typeof VolumesOps>;
22
+
23
+ const handleOf = (attributes: VolumeAttributes, ops: VolumesOps, name: string): VolumeHandle => ({
24
+ ...makeReadWriteVolumeClient(Effect.succeed(attributes.volumeId), ops.client),
25
+ volumeId: Effect.succeed(attributes.volumeId),
26
+ name,
27
+ attributes,
28
+ });
29
+
30
+ /** A volumes client over an environment name resolved per call. */
31
+ export const makeVolumesClient = (
32
+ environment: Effect.Effect<string | undefined>,
33
+ ops: VolumesOps,
34
+ owner: Effect.Effect<RuntimeOwner | undefined> = Effect.undefined,
35
+ ): VolumesClientOf<never> => ({
36
+ getOrCreate: (name) =>
37
+ Effect.flatMap(Effect.all([environment, owner]), ([env, stamp]) =>
38
+ ensureVolume(ops.getOrCreate, ownedName(stamp, name), env),
39
+ ).pipe(Effect.map((attributes) => handleOf(attributes, ops, name))),
40
+ get: (name) =>
41
+ Effect.flatMap(Effect.all([environment, owner]), ([env, stamp]) =>
42
+ lookupVolume(ops.getOrCreate, ownedName(stamp, name), env),
43
+ ).pipe(Effect.map((attributes) => (attributes ? handleOf(attributes, ops, name) : undefined))),
44
+ delete: (name) =>
45
+ Effect.gen(function* () {
46
+ const env = yield* environment;
47
+ const found = yield* lookupVolume(ops.getOrCreate, ownedName(yield* owner, name), env);
48
+ if (!found) return;
49
+ yield* ops
50
+ .delete({ volumeId: found.volumeId, environmentName: environmentOf(env) })
51
+ .pipe(Effect.catchTag("VolumeNotFound", () => Effect.void));
52
+ }),
53
+ list: () =>
54
+ Effect.gen(function* () {
55
+ const env = yield* environment;
56
+ const stamp = yield* owner;
57
+ const items = yield* listAll(
58
+ (pagination) =>
59
+ ops
60
+ .list({ environmentName: environmentOf(env), pagination })
61
+ .pipe(Effect.map((response) => response.items ?? [])),
62
+ (item) => item.createdAt,
63
+ );
64
+ return items.flatMap((item) => {
65
+ const name = item.label ?? item.metadata?.name;
66
+ const own = name ? unownedName(stamp, name) : undefined;
67
+ return own ? [own] : [];
68
+ });
69
+ }),
70
+ });
71
+
72
+ /**
73
+ * {@link CreateVolume} over Modal's API. Grants the host's identity (a scoped
74
+ * `Modal.ServiceUser`) the `contributor` role on the environment.
75
+ *
76
+ * @layer
77
+ * @product Volume
78
+ * @provides Modal.CreateVolume
79
+ */
80
+ export const CreateVolumeHttp = Layer.effect(
81
+ CreateVolume,
82
+ makeOpenModalBinding({
83
+ tag: "Modal.CreateVolume",
84
+ operations: VolumesOps,
85
+ role: "contributor",
86
+ environmentOf: (environment?: Environment) => environment?.name,
87
+ make: Effect.fn(function* (ops, environment?: Environment) {
88
+ const name = environment ? yield* environment.name : Effect.undefined;
89
+ const owner = yield* RuntimeOwnerOf();
90
+ return makeVolumesClient(name, ops, owner);
91
+ }),
92
+ }),
93
+ );
@@ -0,0 +1,74 @@
1
+ import { ConfigError } from "@distilled.cloud/core/errors";
2
+ import { withAuthToken } from "@distilled.cloud/modal/AuthToken";
3
+ import { Credentials, DEFAULT_API_BASE_URL } from "@distilled.cloud/modal/Credentials";
4
+ import { lazyCredentials } from "alchemy/Auth/Resolve";
5
+ import * as Effect from "effect/Effect";
6
+ import * as Layer from "effect/Layer";
7
+ import * as Redacted from "effect/Redacted";
8
+ import { MODAL_AUTH_PROVIDER_NAME, type ModalResolvedCredentials } from "./AuthProvider.ts";
9
+ import { ModalTransport } from "./internal/Transport.ts";
10
+
11
+ export { withAuthToken } from "@distilled.cloud/modal/AuthToken";
12
+ export {
13
+ Credentials,
14
+ CredentialsFromEnv,
15
+ DEFAULT_API_BASE_URL,
16
+ } from "@distilled.cloud/modal/Credentials";
17
+
18
+ /**
19
+ * Build Modal `Credentials` that resolve through the Alchemy AuthProvider:
20
+ * `MODAL_TOKEN_ID` / `MODAL_TOKEN_SECRET` when set, otherwise the selected
21
+ * profile. Resolution is deferred until the first API call, so building the
22
+ * provider layers never needs a profile.
23
+ */
24
+ export const fromAuthProvider = () =>
25
+ withAuthTokens(
26
+ Layer.effect(
27
+ Credentials,
28
+ lazyCredentials<ModalResolvedCredentials, ConfigError>()(
29
+ MODAL_AUTH_PROVIDER_NAME,
30
+ (creds) => ({
31
+ tokenId: creds.tokenId,
32
+ tokenSecret: creds.tokenSecret,
33
+ apiBaseUrl: creds.apiBaseUrl,
34
+ }),
35
+ ),
36
+ ),
37
+ );
38
+
39
+ /**
40
+ * Add Modal's short-lived auth token (the `x-modal-auth-token` JWT its V2
41
+ * sandbox RPCs and input plane need) to a token pair's `Credentials`.
42
+ */
43
+ export const withAuthTokens = <E, R>(
44
+ credentials: Layer.Layer<Credentials, E, R>,
45
+ ): Layer.Layer<Credentials, E, R> =>
46
+ withAuthToken.pipe(Layer.provide(Layer.mergeAll(credentials, ModalTransport)));
47
+
48
+ /**
49
+ * Build Modal `Credentials` from an explicit token pair, e.g. in a test or a
50
+ * script that already holds one.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * Effect.provide(Modal.fromToken({ tokenId: "ak-…", tokenSecret: "as-…" }))
55
+ * ```
56
+ */
57
+ export const fromToken = (input: {
58
+ tokenId: string | Redacted.Redacted<string>;
59
+ tokenSecret: string | Redacted.Redacted<string>;
60
+ apiBaseUrl?: string;
61
+ }): Layer.Layer<Credentials> =>
62
+ withAuthTokens(
63
+ Layer.succeed(
64
+ Credentials,
65
+ Effect.succeed({
66
+ tokenId: typeof input.tokenId === "string" ? Redacted.make(input.tokenId) : input.tokenId,
67
+ tokenSecret:
68
+ typeof input.tokenSecret === "string"
69
+ ? Redacted.make(input.tokenSecret)
70
+ : input.tokenSecret,
71
+ apiBaseUrl: input.apiBaseUrl ?? DEFAULT_API_BASE_URL,
72
+ }),
73
+ ),
74
+ );
package/src/Dict.ts ADDED
@@ -0,0 +1,245 @@
1
+ import * as dict from "@distilled.cloud/modal/dict";
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 {
9
+ type EnvironmentInput,
10
+ envNameOf,
11
+ environmentNames,
12
+ environmentOf,
13
+ isGeneratedName,
14
+ listAll,
15
+ objectName,
16
+ } from "./internal.ts";
17
+ import { declarable } from "./internal/Declared.ts";
18
+ import type { Providers } from "./Providers.ts";
19
+ import { isRuntimeName } from "./RuntimeOwner.ts";
20
+
21
+ export class DictUnexpectedResponse extends Data.TaggedError("Modal.DictUnexpectedResponse")<{
22
+ readonly message: string;
23
+ }> {}
24
+
25
+ export interface DictProps {
26
+ /**
27
+ * Dict name, unique per environment. If omitted, a unique name is
28
+ * generated from the stack, stage and logical ID. Changing it replaces the
29
+ * dict (Modal can't rename dicts).
30
+ */
31
+ name?: string;
32
+ /**
33
+ * Environment the dict lives in. Changing it replaces the dict.
34
+ * @default the workspace's default environment
35
+ */
36
+ environment?: EnvironmentInput;
37
+ }
38
+
39
+ export interface DictAttributes {
40
+ /** Dict ID (`di-…`). */
41
+ dictId: string;
42
+ /** Dict name. */
43
+ name: string;
44
+ /** Environment name, or `undefined` for the workspace default. */
45
+ environment: string | undefined;
46
+ }
47
+
48
+ /**
49
+ * A Modal Dict: a distributed key-value store shared by every container,
50
+ * Sandbox and client in the workspace. Entries expire 7 days after their
51
+ * last write.
52
+ *
53
+ * Bind it with {@link ReadDict}, {@link WriteDict} or {@link ReadWriteDict}
54
+ * to use it from a Worker, Lambda or any other runtime. Values travel as
55
+ * bytes: the bindings encode them as JSON by default.
56
+ *
57
+ * Modal dicts have no tags. Ownership is inferred from Alchemy state: a
58
+ * dict found under an explicit `name` without prior state is reported as
59
+ * unowned.
60
+ *
61
+ * ### Creating a Dict
62
+ * **Example:** A dict with a generated name
63
+ * ```typescript
64
+ * import * as Modal from "@alchemy.run/modal";
65
+ *
66
+ * export const Results = Modal.Dict("Results", {});
67
+ * ```
68
+ *
69
+ * **Example:** A named dict in an environment
70
+ * ```typescript
71
+ * import * as Modal from "@alchemy.run/modal";
72
+ *
73
+ * export const Agents = Modal.Environment("Agents", {});
74
+ * export const Sessions = Modal.Dict("Sessions", { name: "sessions", environment: Agents });
75
+ * ```
76
+ *
77
+ * ### Reading and writing from a Worker
78
+ * **Example:** Bind read and write access
79
+ * ```typescript
80
+ * import * as Cloudflare from "@alchemy.run/cloudflare";
81
+ * import * as Modal from "@alchemy.run/modal";
82
+ * import * as Effect from "effect/Effect";
83
+ * import * as HttpServerResponse from "effect/http/HttpServerResponse";
84
+ * import { Results } from "./Storage.ts";
85
+ *
86
+ * export default class Api extends Cloudflare.Worker<Api>()(
87
+ * "Api",
88
+ * { main: import.meta.url },
89
+ * Effect.gen(function* () {
90
+ * const results = yield* Modal.ReadWriteDict(Results);
91
+ * return {
92
+ * fetch: Effect.gen(function* () {
93
+ * yield* results.put("last-run", { ok: true });
94
+ * const last = yield* results.get("last-run");
95
+ * return yield* HttpServerResponse.json(last ?? null);
96
+ * }).pipe(Effect.orDie),
97
+ * };
98
+ * }).pipe(Effect.provide(Modal.ReadWriteDictHttp)),
99
+ * ) {}
100
+ * ```
101
+ *
102
+ * ### Looking up an existing dict
103
+ * `Dict.lookup` references a dict Alchemy doesn't manage (created with
104
+ * the Modal CLI or by another stack). It is read during plan/deploy, never
105
+ * created, updated or deleted.
106
+ *
107
+ * **Example:** Reference an existing dict
108
+ * ```typescript
109
+ * const cache = Modal.Dict.lookup({ name: "cache" });
110
+ * ```
111
+ *
112
+ * @resource
113
+ * @product Dict
114
+ */
115
+ export const Dict = declarable<Dict>()(Resource<Dict>("Modal.Dict"));
116
+
117
+ export type Dict = Resource<"Modal.Dict", DictProps, DictAttributes, never, Providers, DictLookup>;
118
+
119
+ /**
120
+ * Props for {@link Dict.lookup}: find a dict this stack
121
+ * doesn't manage by its name.
122
+ */
123
+ export interface DictLookup {
124
+ /** Dict name. */
125
+ name: string;
126
+ /**
127
+ * Modal environment the object lives in.
128
+ * @default the workspace's default environment
129
+ */
130
+ environment?: string;
131
+ }
132
+
133
+ /** A dict by name, or `undefined` when missing. */
134
+ export const lookupDict = Effect.fn(function* (
135
+ getOrCreate: Effect.Success<typeof dict.dictGetOrCreate>,
136
+ name: string,
137
+ env: string | undefined,
138
+ ) {
139
+ const found = yield* getOrCreate({
140
+ deploymentName: name,
141
+ environmentName: environmentOf(env),
142
+ objectCreationType: "OBJECT_CREATION_TYPE_UNSPECIFIED",
143
+ }).pipe(Effect.catchTag("DictNotFound", () => Effect.undefined));
144
+ if (!found?.dictId) return undefined;
145
+ return { dictId: found.dictId, name, environment: env } satisfies DictAttributes;
146
+ });
147
+
148
+ /**
149
+ * Get a dict by name, creating it when missing: the one implementation behind
150
+ * {@link Dict}'s reconcile and the runtime {@link CreateDict} client.
151
+ */
152
+ export const ensureDict = Effect.fn(function* (
153
+ getOrCreate: Effect.Success<typeof dict.dictGetOrCreate>,
154
+ name: string,
155
+ env: string | undefined,
156
+ ) {
157
+ const created = yield* getOrCreate({
158
+ deploymentName: name,
159
+ environmentName: environmentOf(env),
160
+ objectCreationType: "OBJECT_CREATION_TYPE_CREATE_IF_MISSING",
161
+ });
162
+ if (!created.dictId) {
163
+ return yield* new DictUnexpectedResponse({ message: `Modal returned no id for dict ${name}` });
164
+ }
165
+ return { dictId: created.dictId, name, environment: env } satisfies DictAttributes;
166
+ });
167
+
168
+ export const DictProvider = () =>
169
+ Provider.effect(
170
+ Dict,
171
+ Effect.gen(function* () {
172
+ const observe = Effect.fn(function* (
173
+ dictId: string | undefined,
174
+ name: string,
175
+ env: string | undefined,
176
+ ) {
177
+ if (dictId !== undefined) {
178
+ const byId = yield* dict
179
+ .dictGetById({ dictId })
180
+ .pipe(Effect.catchTag("DictNotFound", () => Effect.undefined));
181
+ if (byId?.dictId) {
182
+ return {
183
+ dictId: byId.dictId,
184
+ name: byId.metadata?.name ?? name,
185
+ environment: env,
186
+ } satisfies DictAttributes;
187
+ }
188
+ }
189
+ return yield* lookupDict(yield* dict.dictGetOrCreate, name, env);
190
+ });
191
+
192
+ return {
193
+ stables: ["dictId", "name", "environment"],
194
+ diff: Effect.fn(function* ({ id, news, olds, output }) {
195
+ if (!isResolved(news)) return undefined;
196
+ if (envNameOf(news.environment) !== envNameOf(olds?.environment))
197
+ return { action: "replace" } as const;
198
+ const name = yield* objectName(id, news.name);
199
+ if (output !== undefined && name !== output.name) return { action: "replace" } as const;
200
+ return undefined;
201
+ }),
202
+ lookup: Effect.fn(function* ({ name, environment }) {
203
+ return yield* observe(undefined, name, environment);
204
+ }),
205
+
206
+ read: Effect.fn(function* ({ id, olds, output }) {
207
+ const name = output?.name ?? (yield* objectName(id, olds?.name));
208
+ const observed = yield* observe(output?.dictId, name, envNameOf(olds?.environment));
209
+ if (!observed) return undefined;
210
+ return output !== undefined || olds?.name === undefined ? observed : Unowned(observed);
211
+ }),
212
+ reconcile: Effect.fn(function* ({ id, news, output, session }) {
213
+ const name = output?.name ?? (yield* objectName(id, news.name));
214
+ const current = yield* observe(output?.dictId, name, envNameOf(news.environment));
215
+ if (current) return current;
216
+ yield* session.note(`Creating dict ${name}...`);
217
+ return yield* ensureDict(yield* dict.dictGetOrCreate, name, envNameOf(news.environment));
218
+ }),
219
+ delete: Effect.fn(function* ({ output }) {
220
+ yield* dict
221
+ .deleteDict({ dictId: output.dictId })
222
+ .pipe(Effect.catchTag("DictNotFound", () => Effect.void));
223
+ }),
224
+ list: Effect.fn(function* () {
225
+ const envs = yield* environmentNames;
226
+ const all: DictAttributes[] = [];
227
+ for (const env of envs) {
228
+ const items = yield* listAll(
229
+ (pagination) =>
230
+ dict
231
+ .listDict({ environmentName: env, pagination })
232
+ .pipe(Effect.map((response) => response.dicts ?? [])),
233
+ (item) => item.createdAt,
234
+ );
235
+ for (const item of items) {
236
+ if (!item.dictId || !(isGeneratedName(item.name) || isRuntimeName(item.name)))
237
+ continue;
238
+ all.push({ dictId: item.dictId, name: item.name ?? "", environment: env });
239
+ }
240
+ }
241
+ return all;
242
+ }),
243
+ };
244
+ }),
245
+ );