@alchemy.run/modal 0.0.0 → 2.0.0-beta.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +96 -4
- package/lib/App.d.ts +143 -0
- package/lib/App.d.ts.map +1 -0
- package/lib/App.js +198 -0
- package/lib/App.js.map +1 -0
- package/lib/AuthProvider.d.ts +53 -0
- package/lib/AuthProvider.d.ts.map +1 -0
- package/lib/AuthProvider.js +209 -0
- package/lib/AuthProvider.js.map +1 -0
- package/lib/BindingHttp.d.ts +56 -0
- package/lib/BindingHttp.d.ts.map +1 -0
- package/lib/BindingHttp.js +50 -0
- package/lib/BindingHttp.js.map +1 -0
- package/lib/Blob.d.ts +34 -0
- package/lib/Blob.d.ts.map +1 -0
- package/lib/Blob.js +59 -0
- package/lib/Blob.js.map +1 -0
- package/lib/Bootstrap.d.ts +8 -0
- package/lib/Bootstrap.d.ts.map +1 -0
- package/lib/Bootstrap.js +26 -0
- package/lib/Bootstrap.js.map +1 -0
- package/lib/Cbor.d.ts +10 -0
- package/lib/Cbor.d.ts.map +1 -0
- package/lib/Cbor.js +177 -0
- package/lib/Cbor.js.map +1 -0
- package/lib/ConnectSandbox.d.ts +64 -0
- package/lib/ConnectSandbox.d.ts.map +1 -0
- package/lib/ConnectSandbox.js +33 -0
- package/lib/ConnectSandbox.js.map +1 -0
- package/lib/Container.d.ts +124 -0
- package/lib/Container.d.ts.map +1 -0
- package/lib/Container.js +1 -0
- package/lib/Container.js.map +1 -0
- package/lib/Contributions.d.ts +7 -0
- package/lib/Contributions.d.ts.map +1 -0
- package/lib/Contributions.js +6 -0
- package/lib/Contributions.js.map +1 -0
- package/lib/CreateDict.d.ts +83 -0
- package/lib/CreateDict.d.ts.map +1 -0
- package/lib/CreateDict.js +3 -0
- package/lib/CreateDict.js.map +1 -0
- package/lib/CreateDictHttp.d.ts +33 -0
- package/lib/CreateDictHttp.d.ts.map +1 -0
- package/lib/CreateDictHttp.js +67 -0
- package/lib/CreateDictHttp.js.map +1 -0
- package/lib/CreateImage.d.ts +98 -0
- package/lib/CreateImage.d.ts.map +1 -0
- package/lib/CreateImage.js +3 -0
- package/lib/CreateImage.js.map +1 -0
- package/lib/CreateImageHttp.d.ts +51 -0
- package/lib/CreateImageHttp.d.ts.map +1 -0
- package/lib/CreateImageHttp.js +87 -0
- package/lib/CreateImageHttp.js.map +1 -0
- package/lib/CreateQueue.d.ts +83 -0
- package/lib/CreateQueue.d.ts.map +1 -0
- package/lib/CreateQueue.js +3 -0
- package/lib/CreateQueue.js.map +1 -0
- package/lib/CreateQueueHttp.d.ts +31 -0
- package/lib/CreateQueueHttp.d.ts.map +1 -0
- package/lib/CreateQueueHttp.js +67 -0
- package/lib/CreateQueueHttp.js.map +1 -0
- package/lib/CreateSandbox.d.ts +186 -0
- package/lib/CreateSandbox.d.ts.map +1 -0
- package/lib/CreateSandbox.js +3 -0
- package/lib/CreateSandbox.js.map +1 -0
- package/lib/CreateSandboxHttp.d.ts +17 -0
- package/lib/CreateSandboxHttp.d.ts.map +1 -0
- package/lib/CreateSandboxHttp.js +117 -0
- package/lib/CreateSandboxHttp.js.map +1 -0
- package/lib/CreateSecret.d.ts +95 -0
- package/lib/CreateSecret.d.ts.map +1 -0
- package/lib/CreateSecret.js +3 -0
- package/lib/CreateSecret.js.map +1 -0
- package/lib/CreateSecretHttp.d.ts +24 -0
- package/lib/CreateSecretHttp.d.ts.map +1 -0
- package/lib/CreateSecretHttp.js +60 -0
- package/lib/CreateSecretHttp.js.map +1 -0
- package/lib/CreateVolume.d.ts +84 -0
- package/lib/CreateVolume.d.ts.map +1 -0
- package/lib/CreateVolume.js +3 -0
- package/lib/CreateVolume.js.map +1 -0
- package/lib/CreateVolumeHttp.d.ts +32 -0
- package/lib/CreateVolumeHttp.d.ts.map +1 -0
- package/lib/CreateVolumeHttp.js +69 -0
- package/lib/CreateVolumeHttp.js.map +1 -0
- package/lib/Credentials.d.ts +32 -0
- package/lib/Credentials.d.ts.map +1 -0
- package/lib/Credentials.js +44 -0
- package/lib/Credentials.js.map +1 -0
- package/lib/Dict.d.ts +147 -0
- package/lib/Dict.d.ts.map +1 -0
- package/lib/Dict.js +175 -0
- package/lib/Dict.js.map +1 -0
- package/lib/DictClient.d.ts +55 -0
- package/lib/DictClient.d.ts.map +1 -0
- package/lib/DictClient.js +89 -0
- package/lib/DictClient.js.map +1 -0
- package/lib/Domain.d.ts +86 -0
- package/lib/Domain.d.ts.map +1 -0
- package/lib/Domain.js +113 -0
- package/lib/Domain.js.map +1 -0
- package/lib/Endpoint.d.ts +181 -0
- package/lib/Endpoint.d.ts.map +1 -0
- package/lib/Endpoint.js +283 -0
- package/lib/Endpoint.js.map +1 -0
- package/lib/Environment.d.ts +174 -0
- package/lib/Environment.d.ts.map +1 -0
- package/lib/Environment.js +244 -0
- package/lib/Environment.js.map +1 -0
- package/lib/FetchServer.d.ts +105 -0
- package/lib/FetchServer.d.ts.map +1 -0
- package/lib/FetchServer.js +3 -0
- package/lib/FetchServer.js.map +1 -0
- package/lib/FetchServerHttp.d.ts +21 -0
- package/lib/FetchServerHttp.d.ts.map +1 -0
- package/lib/FetchServerHttp.js +84 -0
- package/lib/FetchServerHttp.js.map +1 -0
- package/lib/Function.d.ts +236 -0
- package/lib/Function.d.ts.map +1 -0
- package/lib/Function.js +273 -0
- package/lib/Function.js.map +1 -0
- package/lib/FunctionAutoscaler.d.ts +99 -0
- package/lib/FunctionAutoscaler.d.ts.map +1 -0
- package/lib/FunctionAutoscaler.js +136 -0
- package/lib/FunctionAutoscaler.js.map +1 -0
- package/lib/FunctionTarget.d.ts +61 -0
- package/lib/FunctionTarget.d.ts.map +1 -0
- package/lib/FunctionTarget.js +136 -0
- package/lib/FunctionTarget.js.map +1 -0
- package/lib/Image.d.ts +159 -0
- package/lib/Image.d.ts.map +1 -0
- package/lib/Image.js +203 -0
- package/lib/Image.js.map +1 -0
- package/lib/ImageBuild.d.ts +108 -0
- package/lib/ImageBuild.d.ts.map +1 -0
- package/lib/ImageBuild.js +157 -0
- package/lib/ImageBuild.js.map +1 -0
- package/lib/ImagePlan.d.ts +31 -0
- package/lib/ImagePlan.d.ts.map +1 -0
- package/lib/ImagePlan.js +70 -0
- package/lib/ImagePlan.js.map +1 -0
- package/lib/InferEnv.d.ts +26 -0
- package/lib/InferEnv.d.ts.map +1 -0
- package/lib/InferEnv.js +1 -0
- package/lib/InferEnv.js.map +1 -0
- package/lib/InvokeFunction.d.ts +186 -0
- package/lib/InvokeFunction.d.ts.map +1 -0
- package/lib/InvokeFunction.js +10 -0
- package/lib/InvokeFunction.js.map +1 -0
- package/lib/InvokeFunctionHttp.d.ts +39 -0
- package/lib/InvokeFunctionHttp.d.ts.map +1 -0
- package/lib/InvokeFunctionHttp.js +210 -0
- package/lib/InvokeFunctionHttp.js.map +1 -0
- package/lib/ModalBindings.d.ts +138 -0
- package/lib/ModalBindings.d.ts.map +1 -0
- package/lib/ModalBindings.js +223 -0
- package/lib/ModalBindings.js.map +1 -0
- package/lib/MountBucket.d.ts +80 -0
- package/lib/MountBucket.d.ts.map +1 -0
- package/lib/MountBucket.js +44 -0
- package/lib/MountBucket.js.map +1 -0
- package/lib/MountVolume.d.ts +77 -0
- package/lib/MountVolume.d.ts.map +1 -0
- package/lib/MountVolume.js +41 -0
- package/lib/MountVolume.js.map +1 -0
- package/lib/Mounts.d.ts +134 -0
- package/lib/Mounts.d.ts.map +1 -0
- package/lib/Mounts.js +87 -0
- package/lib/Mounts.js.map +1 -0
- package/lib/PersistentSandbox.d.ts +75 -0
- package/lib/PersistentSandbox.d.ts.map +1 -0
- package/lib/PersistentSandbox.js +93 -0
- package/lib/PersistentSandbox.js.map +1 -0
- package/lib/Providers.d.ts +23 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +64 -0
- package/lib/Providers.js.map +1 -0
- package/lib/Proxy.d.ts +94 -0
- package/lib/Proxy.d.ts.map +1 -0
- package/lib/Proxy.js +132 -0
- package/lib/Proxy.js.map +1 -0
- package/lib/Queue.d.ts +147 -0
- package/lib/Queue.d.ts.map +1 -0
- package/lib/Queue.js +177 -0
- package/lib/Queue.js.map +1 -0
- package/lib/QueueClient.d.ts +64 -0
- package/lib/QueueClient.d.ts.map +1 -0
- package/lib/QueueClient.js +73 -0
- package/lib/QueueClient.js.map +1 -0
- package/lib/ReadApp.d.ts +85 -0
- package/lib/ReadApp.d.ts.map +1 -0
- package/lib/ReadApp.js +3 -0
- package/lib/ReadApp.js.map +1 -0
- package/lib/ReadAppHttp.d.ts +26 -0
- package/lib/ReadAppHttp.d.ts.map +1 -0
- package/lib/ReadAppHttp.js +106 -0
- package/lib/ReadAppHttp.js.map +1 -0
- package/lib/ReadDict.d.ts +39 -0
- package/lib/ReadDict.d.ts.map +1 -0
- package/lib/ReadDict.js +3 -0
- package/lib/ReadDict.js.map +1 -0
- package/lib/ReadDictHttp.d.ts +12 -0
- package/lib/ReadDictHttp.d.ts.map +1 -0
- package/lib/ReadDictHttp.js +23 -0
- package/lib/ReadDictHttp.js.map +1 -0
- package/lib/ReadFunction.d.ts +73 -0
- package/lib/ReadFunction.d.ts.map +1 -0
- package/lib/ReadFunction.js +3 -0
- package/lib/ReadFunction.js.map +1 -0
- package/lib/ReadFunctionHttp.d.ts +25 -0
- package/lib/ReadFunctionHttp.d.ts.map +1 -0
- package/lib/ReadFunctionHttp.js +63 -0
- package/lib/ReadFunctionHttp.js.map +1 -0
- package/lib/ReadQueue.d.ts +39 -0
- package/lib/ReadQueue.d.ts.map +1 -0
- package/lib/ReadQueue.js +3 -0
- package/lib/ReadQueue.js.map +1 -0
- package/lib/ReadQueueHttp.d.ts +12 -0
- package/lib/ReadQueueHttp.d.ts.map +1 -0
- package/lib/ReadQueueHttp.js +23 -0
- package/lib/ReadQueueHttp.js.map +1 -0
- package/lib/ReadServer.d.ts +72 -0
- package/lib/ReadServer.d.ts.map +1 -0
- package/lib/ReadServer.js +3 -0
- package/lib/ReadServer.js.map +1 -0
- package/lib/ReadServerHttp.d.ts +25 -0
- package/lib/ReadServerHttp.d.ts.map +1 -0
- package/lib/ReadServerHttp.js +70 -0
- package/lib/ReadServerHttp.js.map +1 -0
- package/lib/ReadVolume.d.ts +40 -0
- package/lib/ReadVolume.d.ts.map +1 -0
- package/lib/ReadVolume.js +3 -0
- package/lib/ReadVolume.js.map +1 -0
- package/lib/ReadVolumeHttp.d.ts +12 -0
- package/lib/ReadVolumeHttp.d.ts.map +1 -0
- package/lib/ReadVolumeHttp.js +24 -0
- package/lib/ReadVolumeHttp.js.map +1 -0
- package/lib/ReadWriteDict.d.ts +39 -0
- package/lib/ReadWriteDict.d.ts.map +1 -0
- package/lib/ReadWriteDict.js +3 -0
- package/lib/ReadWriteDict.js.map +1 -0
- package/lib/ReadWriteDictHttp.d.ts +12 -0
- package/lib/ReadWriteDictHttp.d.ts.map +1 -0
- package/lib/ReadWriteDictHttp.js +23 -0
- package/lib/ReadWriteDictHttp.js.map +1 -0
- package/lib/ReadWriteQueue.d.ts +40 -0
- package/lib/ReadWriteQueue.d.ts.map +1 -0
- package/lib/ReadWriteQueue.js +3 -0
- package/lib/ReadWriteQueue.js.map +1 -0
- package/lib/ReadWriteQueueHttp.d.ts +12 -0
- package/lib/ReadWriteQueueHttp.d.ts.map +1 -0
- package/lib/ReadWriteQueueHttp.js +23 -0
- package/lib/ReadWriteQueueHttp.js.map +1 -0
- package/lib/ReadWriteVolume.d.ts +40 -0
- package/lib/ReadWriteVolume.d.ts.map +1 -0
- package/lib/ReadWriteVolume.js +3 -0
- package/lib/ReadWriteVolume.js.map +1 -0
- package/lib/ReadWriteVolumeHttp.d.ts +12 -0
- package/lib/ReadWriteVolumeHttp.d.ts.map +1 -0
- package/lib/ReadWriteVolumeHttp.js +24 -0
- package/lib/ReadWriteVolumeHttp.js.map +1 -0
- package/lib/RuntimeOwner.d.ts +39 -0
- package/lib/RuntimeOwner.d.ts.map +1 -0
- package/lib/RuntimeOwner.js +85 -0
- package/lib/RuntimeOwner.js.map +1 -0
- package/lib/Sandbox.d.ts +215 -0
- package/lib/Sandbox.d.ts.map +1 -0
- package/lib/Sandbox.js +278 -0
- package/lib/Sandbox.js.map +1 -0
- package/lib/SandboxClient.d.ts +748 -0
- package/lib/SandboxClient.d.ts.map +1 -0
- package/lib/SandboxClient.js +710 -0
- package/lib/SandboxClient.js.map +1 -0
- package/lib/ScaleFunction.d.ts +54 -0
- package/lib/ScaleFunction.d.ts.map +1 -0
- package/lib/ScaleFunction.js +3 -0
- package/lib/ScaleFunction.js.map +1 -0
- package/lib/ScaleFunctionHttp.d.ts +21 -0
- package/lib/ScaleFunctionHttp.d.ts.map +1 -0
- package/lib/ScaleFunctionHttp.js +39 -0
- package/lib/ScaleFunctionHttp.js.map +1 -0
- package/lib/Secret.d.ts +170 -0
- package/lib/Secret.d.ts.map +1 -0
- package/lib/Secret.js +196 -0
- package/lib/Secret.js.map +1 -0
- package/lib/Server.d.ts +155 -0
- package/lib/Server.d.ts.map +1 -0
- package/lib/Server.js +184 -0
- package/lib/Server.js.map +1 -0
- package/lib/ServiceUser.d.ts +139 -0
- package/lib/ServiceUser.d.ts.map +1 -0
- package/lib/ServiceUser.js +210 -0
- package/lib/ServiceUser.js.map +1 -0
- package/lib/Volume.d.ts +170 -0
- package/lib/Volume.d.ts.map +1 -0
- package/lib/Volume.js +220 -0
- package/lib/Volume.js.map +1 -0
- package/lib/VolumeClient.d.ts +53 -0
- package/lib/VolumeClient.d.ts.map +1 -0
- package/lib/VolumeClient.js +22 -0
- package/lib/VolumeClient.js.map +1 -0
- package/lib/VolumeFiles.d.ts +94 -0
- package/lib/VolumeFiles.d.ts.map +1 -0
- package/lib/VolumeFiles.js +139 -0
- package/lib/VolumeFiles.js.map +1 -0
- package/lib/WebhookToken.d.ts +102 -0
- package/lib/WebhookToken.d.ts.map +1 -0
- package/lib/WebhookToken.js +176 -0
- package/lib/WebhookToken.js.map +1 -0
- package/lib/WorkspaceSettings.d.ts +70 -0
- package/lib/WorkspaceSettings.d.ts.map +1 -0
- package/lib/WorkspaceSettings.js +105 -0
- package/lib/WorkspaceSettings.js.map +1 -0
- package/lib/WriteApp.d.ts +38 -0
- package/lib/WriteApp.d.ts.map +1 -0
- package/lib/WriteApp.js +3 -0
- package/lib/WriteApp.js.map +1 -0
- package/lib/WriteAppHttp.d.ts +23 -0
- package/lib/WriteAppHttp.d.ts.map +1 -0
- package/lib/WriteAppHttp.js +36 -0
- package/lib/WriteAppHttp.js.map +1 -0
- package/lib/WriteDict.d.ts +39 -0
- package/lib/WriteDict.d.ts.map +1 -0
- package/lib/WriteDict.js +3 -0
- package/lib/WriteDict.js.map +1 -0
- package/lib/WriteDictHttp.d.ts +12 -0
- package/lib/WriteDictHttp.d.ts.map +1 -0
- package/lib/WriteDictHttp.js +23 -0
- package/lib/WriteDictHttp.js.map +1 -0
- package/lib/WriteQueue.d.ts +39 -0
- package/lib/WriteQueue.d.ts.map +1 -0
- package/lib/WriteQueue.js +3 -0
- package/lib/WriteQueue.js.map +1 -0
- package/lib/WriteQueueHttp.d.ts +12 -0
- package/lib/WriteQueueHttp.d.ts.map +1 -0
- package/lib/WriteQueueHttp.js +23 -0
- package/lib/WriteQueueHttp.js.map +1 -0
- package/lib/WriteSecret.d.ts +53 -0
- package/lib/WriteSecret.d.ts.map +1 -0
- package/lib/WriteSecret.js +3 -0
- package/lib/WriteSecret.js.map +1 -0
- package/lib/WriteSecretHttp.d.ts +23 -0
- package/lib/WriteSecretHttp.d.ts.map +1 -0
- package/lib/WriteSecretHttp.js +44 -0
- package/lib/WriteSecretHttp.js.map +1 -0
- package/lib/WriteVolume.d.ts +39 -0
- package/lib/WriteVolume.d.ts.map +1 -0
- package/lib/WriteVolume.js +3 -0
- package/lib/WriteVolume.js.map +1 -0
- package/lib/WriteVolumeHttp.d.ts +12 -0
- package/lib/WriteVolumeHttp.d.ts.map +1 -0
- package/lib/WriteVolumeHttp.js +24 -0
- package/lib/WriteVolumeHttp.js.map +1 -0
- package/lib/index.d.ts +80 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +78 -0
- package/lib/index.js.map +1 -0
- package/lib/internal/Declared.d.ts +29 -0
- package/lib/internal/Declared.d.ts.map +1 -0
- package/lib/internal/Declared.js +31 -0
- package/lib/internal/Declared.js.map +1 -0
- package/lib/internal/Deploy.d.ts +110 -0
- package/lib/internal/Deploy.d.ts.map +1 -0
- package/lib/internal/Deploy.js +230 -0
- package/lib/internal/Deploy.js.map +1 -0
- package/lib/internal/Entrypoint.d.ts +52 -0
- package/lib/internal/Entrypoint.d.ts.map +1 -0
- package/lib/internal/Entrypoint.js +193 -0
- package/lib/internal/Entrypoint.js.map +1 -0
- package/lib/internal/Rpc.d.ts +17 -0
- package/lib/internal/Rpc.d.ts.map +1 -0
- package/lib/internal/Rpc.js +49 -0
- package/lib/internal/Rpc.js.map +1 -0
- package/lib/internal/RpcAuth.d.ts +41 -0
- package/lib/internal/RpcAuth.d.ts.map +1 -0
- package/lib/internal/RpcAuth.js +100 -0
- package/lib/internal/RpcAuth.js.map +1 -0
- package/lib/internal/Runtime.d.ts +127 -0
- package/lib/internal/Runtime.d.ts.map +1 -0
- package/lib/internal/Runtime.js +246 -0
- package/lib/internal/Runtime.js.map +1 -0
- package/lib/internal/Tags.d.ts +19 -0
- package/lib/internal/Tags.d.ts.map +1 -0
- package/lib/internal/Tags.js +33 -0
- package/lib/internal/Tags.js.map +1 -0
- package/lib/internal/TcpConnect.d.ts +12 -0
- package/lib/internal/TcpConnect.d.ts.map +1 -0
- package/lib/internal/TcpConnect.js +46 -0
- package/lib/internal/TcpConnect.js.map +1 -0
- package/lib/internal/Transport.d.ts +13 -0
- package/lib/internal/Transport.d.ts.map +1 -0
- package/lib/internal/Transport.js +16 -0
- package/lib/internal/Transport.js.map +1 -0
- package/lib/internal.d.ts +71 -0
- package/lib/internal.d.ts.map +1 -0
- package/lib/internal.js +102 -0
- package/lib/internal.js.map +1 -0
- package/package.json +59 -3
- package/src/App.ts +262 -0
- package/src/AuthProvider.ts +295 -0
- package/src/BindingHttp.ts +112 -0
- package/src/Blob.ts +71 -0
- package/src/Bootstrap.ts +52 -0
- package/src/Cbor.ts +158 -0
- package/src/ConnectSandbox.ts +99 -0
- package/src/Container.ts +121 -0
- package/src/Contributions.ts +9 -0
- package/src/CreateDict.ts +95 -0
- package/src/CreateDictHttp.ts +91 -0
- package/src/CreateImage.ts +105 -0
- package/src/CreateImageHttp.ts +117 -0
- package/src/CreateQueue.ts +95 -0
- package/src/CreateQueueHttp.ts +91 -0
- package/src/CreateSandbox.ts +228 -0
- package/src/CreateSandboxHttp.ts +160 -0
- package/src/CreateSecret.ts +109 -0
- package/src/CreateSecretHttp.ts +83 -0
- package/src/CreateVolume.ts +96 -0
- package/src/CreateVolumeHttp.ts +93 -0
- package/src/Credentials.ts +74 -0
- package/src/Dict.ts +245 -0
- package/src/DictClient.ts +166 -0
- package/src/Domain.ts +147 -0
- package/src/Endpoint.ts +406 -0
- package/src/Environment.ts +373 -0
- package/src/FetchServer.ts +126 -0
- package/src/FetchServerHttp.ts +110 -0
- package/src/Function.ts +397 -0
- package/src/FunctionAutoscaler.ts +210 -0
- package/src/FunctionTarget.ts +181 -0
- package/src/Image.ts +281 -0
- package/src/ImageBuild.ts +228 -0
- package/src/ImagePlan.ts +78 -0
- package/src/InferEnv.ts +27 -0
- package/src/InvokeFunction.ts +211 -0
- package/src/InvokeFunctionHttp.ts +316 -0
- package/src/ModalBindings.ts +310 -0
- package/src/MountBucket.ts +137 -0
- package/src/MountVolume.ts +113 -0
- package/src/Mounts.ts +230 -0
- package/src/PersistentSandbox.ts +142 -0
- package/src/Providers.ts +100 -0
- package/src/Proxy.ts +191 -0
- package/src/Queue.ts +258 -0
- package/src/QueueClient.ts +149 -0
- package/src/ReadApp.ts +101 -0
- package/src/ReadAppHttp.ts +142 -0
- package/src/ReadDict.ts +44 -0
- package/src/ReadDictHttp.ts +27 -0
- package/src/ReadFunction.ts +107 -0
- package/src/ReadFunctionHttp.ts +91 -0
- package/src/ReadQueue.ts +44 -0
- package/src/ReadQueueHttp.ts +27 -0
- package/src/ReadServer.ts +98 -0
- package/src/ReadServerHttp.ts +101 -0
- package/src/ReadVolume.ts +45 -0
- package/src/ReadVolumeHttp.ts +28 -0
- package/src/ReadWriteDict.ts +44 -0
- package/src/ReadWriteDictHttp.ts +27 -0
- package/src/ReadWriteQueue.ts +45 -0
- package/src/ReadWriteQueueHttp.ts +27 -0
- package/src/ReadWriteVolume.ts +45 -0
- package/src/ReadWriteVolumeHttp.ts +28 -0
- package/src/RuntimeOwner.ts +111 -0
- package/src/Sandbox.ts +402 -0
- package/src/SandboxClient.ts +1404 -0
- package/src/ScaleFunction.ts +70 -0
- package/src/ScaleFunctionHttp.ts +54 -0
- package/src/Secret.ts +296 -0
- package/src/Server.ts +285 -0
- package/src/ServiceUser.ts +295 -0
- package/src/Volume.ts +320 -0
- package/src/VolumeClient.ts +108 -0
- package/src/VolumeFiles.ts +194 -0
- package/src/WebhookToken.ts +230 -0
- package/src/WorkspaceSettings.ts +160 -0
- package/src/WriteApp.ts +43 -0
- package/src/WriteAppHttp.ts +51 -0
- package/src/WriteDict.ts +44 -0
- package/src/WriteDictHttp.ts +27 -0
- package/src/WriteQueue.ts +44 -0
- package/src/WriteQueueHttp.ts +27 -0
- package/src/WriteSecret.ts +60 -0
- package/src/WriteSecretHttp.ts +56 -0
- package/src/WriteVolume.ts +44 -0
- package/src/WriteVolumeHttp.ts +28 -0
- package/src/globals.d.ts +2 -0
- package/src/index.ts +85 -0
- package/src/internal/Declared.ts +80 -0
- package/src/internal/Deploy.ts +309 -0
- package/src/internal/Entrypoint.ts +198 -0
- package/src/internal/Rpc.ts +59 -0
- package/src/internal/RpcAuth.ts +132 -0
- package/src/internal/Runtime.ts +386 -0
- package/src/internal/Tags.ts +44 -0
- package/src/internal/TcpConnect.ts +78 -0
- package/src/internal/Transport.ts +25 -0
- 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
|
+
);
|