@alchemy.run/archil 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 +57 -4
- package/lib/AWS/S3Disk.d.ts +68 -0
- package/lib/AWS/S3Disk.d.ts.map +1 -0
- package/lib/AWS/S3Disk.js +100 -0
- package/lib/AWS/S3Disk.js.map +1 -0
- package/lib/AWS/index.d.ts +2 -0
- package/lib/AWS/index.d.ts.map +1 -0
- package/lib/AWS/index.js +2 -0
- package/lib/AWS/index.js.map +1 -0
- package/lib/ApiToken.d.ts +63 -0
- package/lib/ApiToken.d.ts.map +1 -0
- package/lib/ApiToken.js +121 -0
- package/lib/ApiToken.js.map +1 -0
- package/lib/ArchilBindings.d.ts +65 -0
- package/lib/ArchilBindings.d.ts.map +1 -0
- package/lib/ArchilBindings.js +128 -0
- package/lib/ArchilBindings.js.map +1 -0
- package/lib/AuthProvider.d.ts +40 -0
- package/lib/AuthProvider.d.ts.map +1 -0
- package/lib/AuthProvider.js +87 -0
- package/lib/AuthProvider.js.map +1 -0
- package/lib/Bootstrap.d.ts +8 -0
- package/lib/Bootstrap.d.ts.map +1 -0
- package/lib/Bootstrap.js +27 -0
- package/lib/Bootstrap.js.map +1 -0
- package/lib/Branch.d.ts +101 -0
- package/lib/Branch.d.ts.map +1 -0
- package/lib/Branch.js +117 -0
- package/lib/Branch.js.map +1 -0
- package/lib/BranchDisk.d.ts +42 -0
- package/lib/BranchDisk.d.ts.map +1 -0
- package/lib/BranchDisk.js +14 -0
- package/lib/BranchDisk.js.map +1 -0
- package/lib/Checkpoint.d.ts +78 -0
- package/lib/Checkpoint.d.ts.map +1 -0
- package/lib/Checkpoint.js +95 -0
- package/lib/Checkpoint.js.map +1 -0
- package/lib/Clients.d.ts +369 -0
- package/lib/Clients.d.ts.map +1 -0
- package/lib/Clients.js +334 -0
- package/lib/Clients.js.map +1 -0
- package/lib/ConnectSandbox.d.ts +69 -0
- package/lib/ConnectSandbox.d.ts.map +1 -0
- package/lib/ConnectSandbox.js +21 -0
- package/lib/ConnectSandbox.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/CreateDisk.d.ts +90 -0
- package/lib/CreateDisk.d.ts.map +1 -0
- package/lib/CreateDisk.js +47 -0
- package/lib/CreateDisk.js.map +1 -0
- package/lib/CreateImage.d.ts +42 -0
- package/lib/CreateImage.d.ts.map +1 -0
- package/lib/CreateImage.js +19 -0
- package/lib/CreateImage.js.map +1 -0
- package/lib/CreateSandbox.d.ts +104 -0
- package/lib/CreateSandbox.d.ts.map +1 -0
- package/lib/CreateSandbox.js +98 -0
- package/lib/CreateSandbox.js.map +1 -0
- package/lib/Credentials.d.ts +44 -0
- package/lib/Credentials.d.ts.map +1 -0
- package/lib/Credentials.js +57 -0
- package/lib/Credentials.js.map +1 -0
- package/lib/Disk.d.ts +283 -0
- package/lib/Disk.d.ts.map +1 -0
- package/lib/Disk.js +294 -0
- package/lib/Disk.js.map +1 -0
- package/lib/DiskObjectsHttp.d.ts +20 -0
- package/lib/DiskObjectsHttp.d.ts.map +1 -0
- package/lib/DiskObjectsHttp.js +51 -0
- package/lib/DiskObjectsHttp.js.map +1 -0
- package/lib/DiskUser.d.ts +189 -0
- package/lib/DiskUser.d.ts.map +1 -0
- package/lib/DiskUser.js +243 -0
- package/lib/DiskUser.js.map +1 -0
- package/lib/ExecDisk.d.ts +57 -0
- package/lib/ExecDisk.d.ts.map +1 -0
- package/lib/ExecDisk.js +3 -0
- package/lib/ExecDisk.js.map +1 -0
- package/lib/ExecDiskHttp.d.ts +5 -0
- package/lib/ExecDiskHttp.d.ts.map +1 -0
- package/lib/ExecDiskHttp.js +18 -0
- package/lib/ExecDiskHttp.js.map +1 -0
- package/lib/ExecDisks.d.ts +54 -0
- package/lib/ExecDisks.d.ts.map +1 -0
- package/lib/ExecDisks.js +37 -0
- package/lib/ExecDisks.js.map +1 -0
- package/lib/Image.d.ts +188 -0
- package/lib/Image.d.ts.map +1 -0
- package/lib/Image.js +191 -0
- package/lib/Image.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/MountDisk.d.ts +190 -0
- package/lib/MountDisk.d.ts.map +1 -0
- package/lib/MountDisk.js +227 -0
- package/lib/MountDisk.js.map +1 -0
- package/lib/Providers.d.ts +25 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +48 -0
- package/lib/Providers.js.map +1 -0
- package/lib/ReadDisk.d.ts +55 -0
- package/lib/ReadDisk.d.ts.map +1 -0
- package/lib/ReadDisk.js +3 -0
- package/lib/ReadDisk.js.map +1 -0
- package/lib/ReadWriteDisk.d.ts +26 -0
- package/lib/ReadWriteDisk.d.ts.map +1 -0
- package/lib/ReadWriteDisk.js +3 -0
- package/lib/ReadWriteDisk.js.map +1 -0
- package/lib/Sandbox.d.ts +507 -0
- package/lib/Sandbox.d.ts.map +1 -0
- package/lib/Sandbox.js +729 -0
- package/lib/Sandbox.js.map +1 -0
- package/lib/SandboxOptions.d.ts +185 -0
- package/lib/SandboxOptions.d.ts.map +1 -0
- package/lib/SandboxOptions.js +102 -0
- package/lib/SandboxOptions.js.map +1 -0
- package/lib/SandboxPortToken.d.ts +64 -0
- package/lib/SandboxPortToken.d.ts.map +1 -0
- package/lib/SandboxPortToken.js +77 -0
- package/lib/SandboxPortToken.js.map +1 -0
- package/lib/WriteDisk.d.ts +37 -0
- package/lib/WriteDisk.d.ts.map +1 -0
- package/lib/WriteDisk.js +3 -0
- package/lib/WriteDisk.js.map +1 -0
- package/lib/index.d.ts +29 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +28 -0
- package/lib/index.js.map +1 -0
- package/lib/internal/DeployerKey.d.ts +21 -0
- package/lib/internal/DeployerKey.d.ts.map +1 -0
- package/lib/internal/DeployerKey.js +34 -0
- package/lib/internal/DeployerKey.js.map +1 -0
- package/lib/internal/archil.d.ts +87 -0
- package/lib/internal/archil.d.ts.map +1 -0
- package/lib/internal/archil.js +154 -0
- package/lib/internal/archil.js.map +1 -0
- package/lib/internal/hosted.d.ts +90 -0
- package/lib/internal/hosted.d.ts.map +1 -0
- package/lib/internal/hosted.js +291 -0
- package/lib/internal/hosted.js.map +1 -0
- package/package.json +79 -3
- package/src/AWS/S3Disk.ts +125 -0
- package/src/AWS/index.ts +1 -0
- package/src/ApiToken.ts +168 -0
- package/src/ArchilBindings.ts +179 -0
- package/src/AuthProvider.ts +122 -0
- package/src/Bootstrap.ts +54 -0
- package/src/Branch.ts +199 -0
- package/src/BranchDisk.ts +57 -0
- package/src/Checkpoint.ts +145 -0
- package/src/Clients.ts +954 -0
- package/src/ConnectSandbox.ts +91 -0
- package/src/Contributions.ts +9 -0
- package/src/CreateDisk.ts +165 -0
- package/src/CreateImage.ts +73 -0
- package/src/CreateSandbox.ts +258 -0
- package/src/Credentials.ts +101 -0
- package/src/Disk.ts +468 -0
- package/src/DiskObjectsHttp.ts +64 -0
- package/src/DiskUser.ts +369 -0
- package/src/ExecDisk.ts +62 -0
- package/src/ExecDiskHttp.ts +25 -0
- package/src/ExecDisks.ts +100 -0
- package/src/Image.ts +316 -0
- package/src/InferEnv.ts +27 -0
- package/src/MountDisk.ts +466 -0
- package/src/Providers.ts +75 -0
- package/src/ReadDisk.ts +61 -0
- package/src/ReadWriteDisk.ts +31 -0
- package/src/Sandbox.ts +1064 -0
- package/src/SandboxOptions.ts +230 -0
- package/src/SandboxPortToken.ts +125 -0
- package/src/WriteDisk.ts +42 -0
- package/src/globals.d.ts +2 -0
- package/src/index.ts +59 -0
- package/src/internal/DeployerKey.ts +63 -0
- package/src/internal/archil.ts +273 -0
- package/src/internal/hosted.ts +402 -0
package/lib/Sandbox.d.ts
ADDED
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import * as archil from "@distilled.cloud/archil";
|
|
2
|
+
import { type MountCapability } from "alchemy/Mount";
|
|
3
|
+
import { Platform, type Main, type PlatformProps } from "alchemy/Platform";
|
|
4
|
+
import * as Provider from "alchemy/Provider";
|
|
5
|
+
import type { LookupMethod, Resource } from "alchemy/Resource";
|
|
6
|
+
import { type HostRuntimeContext, type ServerHost } from "alchemy/Runtime/Process";
|
|
7
|
+
import { Stack } from "alchemy/Stack";
|
|
8
|
+
import * as Effect from "effect/Effect";
|
|
9
|
+
import type * as Redacted from "effect/Redacted";
|
|
10
|
+
import { type ImagePush } from "./Image.ts";
|
|
11
|
+
import { type ProgramBuildOptions, type ProgramExtraFile } from "./internal/hosted.ts";
|
|
12
|
+
import type { Providers } from "./Providers.ts";
|
|
13
|
+
import { MountDiskUnresolved, type DiskMount, type DiskMountOptions, type SandboxEgress, type SandboxEndpoint } from "./SandboxOptions.ts";
|
|
14
|
+
declare const SandboxSetupFailed_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
15
|
+
readonly _tag: "Archil.SandboxSetupFailed";
|
|
16
|
+
} & Readonly<A>;
|
|
17
|
+
/** A disk a binding mounts into a program sandbox (`MountDisk` inside one). */
|
|
18
|
+
/** A sandbox's `run` command exited non-zero. */
|
|
19
|
+
export declare class SandboxSetupFailed extends SandboxSetupFailed_base<{
|
|
20
|
+
readonly sandbox: string;
|
|
21
|
+
readonly command: string;
|
|
22
|
+
readonly exitCode: number;
|
|
23
|
+
readonly stderr: string;
|
|
24
|
+
}> {
|
|
25
|
+
get message(): string;
|
|
26
|
+
}
|
|
27
|
+
export interface SandboxMountBinding extends DiskMountOptions {
|
|
28
|
+
readonly diskId: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* What bindings attach to a sandbox: its program's environment, disks it
|
|
32
|
+
* mounts natively (`SandboxMountBinding`), and filesystem clients other
|
|
33
|
+
* mount bindings install into its image (`MountCapability`, from
|
|
34
|
+
* `alchemy/Mount`).
|
|
35
|
+
*/
|
|
36
|
+
export interface SandboxBinding {
|
|
37
|
+
env?: Record<string, any>;
|
|
38
|
+
mounts?: ReadonlyArray<SandboxMountBinding | MountCapability>;
|
|
39
|
+
}
|
|
40
|
+
export interface SandboxProps extends PlatformProps {
|
|
41
|
+
/**
|
|
42
|
+
* Sandbox name, unique within your account: lowercase letters, digits
|
|
43
|
+
* and `-`, at most 63 characters. If omitted, a unique name is generated
|
|
44
|
+
* from the stack, stage, and logical ID. Changing it replaces the sandbox.
|
|
45
|
+
*/
|
|
46
|
+
name?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Image id from an {@link Image} (e.g. `image.imageId`), for a private
|
|
49
|
+
* image or a pinned digest. Exclusive with `baseImage`. Changing it
|
|
50
|
+
* replaces the sandbox.
|
|
51
|
+
*/
|
|
52
|
+
image?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Public OCI image reference with a `linux/amd64` manifest. Exclusive
|
|
55
|
+
* with `image`. Changing it replaces the sandbox.
|
|
56
|
+
* @default "node:24-bookworm"
|
|
57
|
+
*/
|
|
58
|
+
baseImage?: string;
|
|
59
|
+
/** vCPUs, 1–32. Changing it replaces the sandbox. @default 1 */
|
|
60
|
+
vcpuCount?: number;
|
|
61
|
+
/** Memory in MiB, 256–65536. Changing it replaces the sandbox. @default 2048 */
|
|
62
|
+
memSizeMiB?: number;
|
|
63
|
+
/**
|
|
64
|
+
* TCP ports to serve publicly. Updated in place. When set, it is the
|
|
65
|
+
* whole list (plus the program's `port`): ports not in it are unexposed.
|
|
66
|
+
*/
|
|
67
|
+
ports?: number[];
|
|
68
|
+
/**
|
|
69
|
+
* Let services inside the sandbox publish their own ingress.
|
|
70
|
+
* Changing it replaces the sandbox. @default false
|
|
71
|
+
*/
|
|
72
|
+
enableServiceIngress?: boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Environment variables. With `main`, they are the program's environment
|
|
75
|
+
* and a change restarts it. Without `main`, every process in the sandbox
|
|
76
|
+
* gets them, and a change replaces the sandbox.
|
|
77
|
+
*/
|
|
78
|
+
env?: Record<string, string | Redacted.Redacted<string>>;
|
|
79
|
+
/** Outbound network policy. Updated in place. */
|
|
80
|
+
network?: {
|
|
81
|
+
egress?: SandboxEgress;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Disks to mount: a declared `Archil.Disk` (or the Effect that declares
|
|
85
|
+
* it) at a `path`. Updated in place: the sandbox stops, then starts with
|
|
86
|
+
* the new mounts, keeping its root filesystem.
|
|
87
|
+
*/
|
|
88
|
+
mounts?: DiskMount[];
|
|
89
|
+
/**
|
|
90
|
+
* Seconds a powered-on session may run before the sandbox pauses
|
|
91
|
+
* (at most 24 hours). Changing it replaces the sandbox.
|
|
92
|
+
*/
|
|
93
|
+
maxTtlSeconds?: number;
|
|
94
|
+
/**
|
|
95
|
+
* Seconds without a process connection before the sandbox pauses.
|
|
96
|
+
* `0` disables idle expiry. Updated in place.
|
|
97
|
+
*/
|
|
98
|
+
idleTtlSeconds?: number;
|
|
99
|
+
/** Concurrent processes allowed. Changing it replaces the sandbox. */
|
|
100
|
+
maxConcurrentExecs?: number;
|
|
101
|
+
/**
|
|
102
|
+
* Shell commands run in the sandbox, in order, once it is created: clone
|
|
103
|
+
* a repository, install packages, warm a cache. A non-zero exit fails the
|
|
104
|
+
* deploy with `SandboxSetupFailed`. Changing them replaces the sandbox,
|
|
105
|
+
* so it starts again from its image and runs the new commands. Fork the
|
|
106
|
+
* result at run time with `Archil.CreateSandbox(sandbox)`.
|
|
107
|
+
*/
|
|
108
|
+
run?: string[];
|
|
109
|
+
/**
|
|
110
|
+
* A program to run in the sandbox. In the Effect form, `import.meta.url`
|
|
111
|
+
* (the file is both the bundle entry and the program). In the async form,
|
|
112
|
+
* a path to a module whose default export has `fetch(request, env)`.
|
|
113
|
+
* A code change uploads it and restarts the program in place.
|
|
114
|
+
*/
|
|
115
|
+
main?: string;
|
|
116
|
+
/** Named export to load from `main`. @default "default" */
|
|
117
|
+
handler?: string;
|
|
118
|
+
/**
|
|
119
|
+
* TCP port the program listens on, passed to it as `PORT`. Alchemy
|
|
120
|
+
* exposes it publicly and returns its URL as `url`.
|
|
121
|
+
* @default 3000
|
|
122
|
+
*/
|
|
123
|
+
port?: number;
|
|
124
|
+
/**
|
|
125
|
+
* Bundler options for `main` (rolldown `input` / `output`), and
|
|
126
|
+
* `install`: packages to `npm install` next to the program instead of
|
|
127
|
+
* bundling them.
|
|
128
|
+
*/
|
|
129
|
+
build?: ProgramBuildOptions;
|
|
130
|
+
/**
|
|
131
|
+
* Host files or directories uploaded with the program, e.g. a site's
|
|
132
|
+
* built assets. With `extraFiles`, an async `main` is treated as a
|
|
133
|
+
* complete Node program and uploaded as built instead of bundled.
|
|
134
|
+
* Their content is part of `code.hash`, so a change redeploys.
|
|
135
|
+
*/
|
|
136
|
+
extraFiles?: ReadonlyArray<ProgramExtraFile>;
|
|
137
|
+
/**
|
|
138
|
+
* Where Alchemy pushes the sandbox's derived image, for Archil to pull.
|
|
139
|
+
* Only needed when a binding installs a filesystem client (an
|
|
140
|
+
* `alchemy/Mount` capability) into the program's image: Alchemy builds
|
|
141
|
+
* the base image plus those install lines with your local Docker.
|
|
142
|
+
*/
|
|
143
|
+
push?: ImagePush;
|
|
144
|
+
}
|
|
145
|
+
export interface SandboxAttributes {
|
|
146
|
+
/** Sandbox id. */
|
|
147
|
+
sandboxId: string;
|
|
148
|
+
/** Sandbox name. */
|
|
149
|
+
name: string;
|
|
150
|
+
/** Lifecycle state when last observed, e.g. `running` or `paused`. */
|
|
151
|
+
status: string;
|
|
152
|
+
/** The image reference the sandbox boots. */
|
|
153
|
+
baseImage: string;
|
|
154
|
+
/** Digest of the booted image. */
|
|
155
|
+
imageDigest: string | undefined;
|
|
156
|
+
vcpuCount: number;
|
|
157
|
+
memSizeMiB: number;
|
|
158
|
+
/** Public hostnames of the exposed ports. */
|
|
159
|
+
endpoints: SandboxEndpoint[];
|
|
160
|
+
/** `https://` URL of the program's port, or of the first exposed port. */
|
|
161
|
+
url: string | undefined;
|
|
162
|
+
/** The port the program listens on, when the sandbox runs one. */
|
|
163
|
+
port: number | undefined;
|
|
164
|
+
/** Content hash of the deployed program, when the sandbox runs one. */
|
|
165
|
+
code: {
|
|
166
|
+
hash: string;
|
|
167
|
+
} | undefined;
|
|
168
|
+
/**
|
|
169
|
+
* The image Alchemy built for the sandbox (its base plus the install
|
|
170
|
+
* lines its bindings contribute), when it needed one.
|
|
171
|
+
*/
|
|
172
|
+
derivedImage: {
|
|
173
|
+
imageId: string;
|
|
174
|
+
hash: string;
|
|
175
|
+
} | undefined;
|
|
176
|
+
/** Hash of the `run` commands the sandbox was set up with. */
|
|
177
|
+
setupHash: string | undefined;
|
|
178
|
+
}
|
|
179
|
+
export type Sandbox = Resource<"Archil.Sandbox", SandboxProps, SandboxAttributes, SandboxBinding, Providers, SandboxLookup>;
|
|
180
|
+
/**
|
|
181
|
+
* Props for {@link Sandbox.lookup}: find a sandbox this stack
|
|
182
|
+
* doesn't manage by its name.
|
|
183
|
+
*/
|
|
184
|
+
export interface SandboxLookup {
|
|
185
|
+
/** Sandbox name. */
|
|
186
|
+
name: string;
|
|
187
|
+
}
|
|
188
|
+
export type SandboxShape = Main<ServerHost>;
|
|
189
|
+
/**
|
|
190
|
+
* An Archil sandbox: a Firecracker microVM with disks mounted, public
|
|
191
|
+
* ports, and an outbound network policy that can inject credentials at the
|
|
192
|
+
* boundary. It pauses when idle and resumes on the next connection,
|
|
193
|
+
* keeping its memory.
|
|
194
|
+
*
|
|
195
|
+
* Declare one as a box (a dev box or a preview environment that outlives
|
|
196
|
+
* deploys), or give it a `main` and it runs your program: Alchemy bundles
|
|
197
|
+
* it, uploads it, and registers it with Archil's service manager, which
|
|
198
|
+
* restarts it when it crashes and starts it whenever the sandbox boots. Its
|
|
199
|
+
* port gets a public `https://` URL, and a request to a stopped sandbox
|
|
200
|
+
* starts it again, typically in a few seconds. A code change uploads the
|
|
201
|
+
* program and restarts it in place.
|
|
202
|
+
*
|
|
203
|
+
* Short-lived sandboxes for one user or task are created at run time with
|
|
204
|
+
* {@link CreateSandbox}; act on a declared one with {@link ConnectSandbox}.
|
|
205
|
+
*
|
|
206
|
+
* :::caution
|
|
207
|
+
* Changing the image, size, timeouts, or the `env` of a sandbox without
|
|
208
|
+
* `main` replaces the sandbox, and a new one starts with an empty root
|
|
209
|
+
* filesystem. Keep data on a mounted disk. `mounts`, `ports`, `network`
|
|
210
|
+
* and the program update in place.
|
|
211
|
+
* :::
|
|
212
|
+
*
|
|
213
|
+
* :::caution
|
|
214
|
+
* An exposed port is public: anyone with the URL can call it. Check
|
|
215
|
+
* requests yourself, or hand clients an `Archil.SandboxPortToken`.
|
|
216
|
+
* :::
|
|
217
|
+
* @see https://docs.archil.com/compute/sandboxes/introduction
|
|
218
|
+
*
|
|
219
|
+
* ### Creating a Sandbox
|
|
220
|
+
* **Example:** A dev box with a disk mounted
|
|
221
|
+
* ```typescript
|
|
222
|
+
* export const Workspace = Archil.Disk("Workspace", {});
|
|
223
|
+
* export const DevBox = Archil.Sandbox("DevBox", {
|
|
224
|
+
* baseImage: "node:24-bookworm",
|
|
225
|
+
* vcpuCount: 2,
|
|
226
|
+
* memSizeMiB: 4096,
|
|
227
|
+
* mounts: [{ disk: Workspace, path: "/workspace" }],
|
|
228
|
+
* ports: [3000],
|
|
229
|
+
* idleTtlSeconds: 600,
|
|
230
|
+
* });
|
|
231
|
+
* ```
|
|
232
|
+
*
|
|
233
|
+
* **Example:** A bigger sandbox that never pauses while idle
|
|
234
|
+
* ```typescript
|
|
235
|
+
* export const Box = Archil.Sandbox("Box", {
|
|
236
|
+
* vcpuCount: 4,
|
|
237
|
+
* memSizeMiB: 8192,
|
|
238
|
+
* idleTtlSeconds: 0,
|
|
239
|
+
* });
|
|
240
|
+
* ```
|
|
241
|
+
*
|
|
242
|
+
* **Example:** Boot a private image
|
|
243
|
+
* ```typescript
|
|
244
|
+
* export const AgentImage = Archil.Image("AgentImage", {
|
|
245
|
+
* image: "ghcr.io/acme/agent:1",
|
|
246
|
+
* registry: { server: "ghcr.io", username: "acme", password: Config.Redacted("GHCR_TOKEN") },
|
|
247
|
+
* });
|
|
248
|
+
* export const Agent = Effect.gen(function* () {
|
|
249
|
+
* const image = yield* AgentImage;
|
|
250
|
+
* return yield* Archil.Sandbox("Agent", { image: image.imageId });
|
|
251
|
+
* });
|
|
252
|
+
* ```
|
|
253
|
+
*
|
|
254
|
+
* ### Setting Up at Deploy and Forking at Run Time
|
|
255
|
+
* **Example:** Clone a repository once, then fork the sandbox per task
|
|
256
|
+
* ```typescript
|
|
257
|
+
* export const Golden = Archil.Sandbox("Golden", {
|
|
258
|
+
* run: ["git clone --depth 1 https://github.com/sindresorhus/is /work/is"],
|
|
259
|
+
* });
|
|
260
|
+
*
|
|
261
|
+
* // in a Worker or program:
|
|
262
|
+
* const sandboxes = yield* Archil.CreateSandbox(Golden);
|
|
263
|
+
* const task = yield* sandboxes.create({ name: "task-1" });
|
|
264
|
+
* const result = yield* task.exec("git log -1", { cwd: "/work/is" });
|
|
265
|
+
* ```
|
|
266
|
+
*
|
|
267
|
+
* ### Running a Program
|
|
268
|
+
* **Example:** An Effect program that reads a mounted disk
|
|
269
|
+
* ```typescript
|
|
270
|
+
* // src/Api.ts
|
|
271
|
+
* import * as Archil from "@alchemy.run/archil";
|
|
272
|
+
* import * as Effect from "effect/Effect";
|
|
273
|
+
* import * as FileSystem from "effect/FileSystem";
|
|
274
|
+
* import * as HttpServerResponse from "effect/http/HttpServerResponse";
|
|
275
|
+
*
|
|
276
|
+
* export const Dataset = Archil.Disk("Dataset", {});
|
|
277
|
+
*
|
|
278
|
+
* export default class Api extends Archil.Sandbox<Api>()(
|
|
279
|
+
* "Api",
|
|
280
|
+
* { main: import.meta.url, port: 3000 },
|
|
281
|
+
* Effect.gen(function* () {
|
|
282
|
+
* const dataset = yield* Archil.MountDisk(Dataset, { path: "/data", mode: "read-only" });
|
|
283
|
+
* const fs = yield* FileSystem.FileSystem;
|
|
284
|
+
* return {
|
|
285
|
+
* fetch: Effect.gen(function* () {
|
|
286
|
+
* return yield* HttpServerResponse.json(yield* fs.readDirectory(dataset.path));
|
|
287
|
+
* }).pipe(Effect.orDie),
|
|
288
|
+
* };
|
|
289
|
+
* }).pipe(Effect.provide(Archil.MountDiskLive)),
|
|
290
|
+
* ) {}
|
|
291
|
+
* ```
|
|
292
|
+
*
|
|
293
|
+
* **Example:** A plain async handler with typed `env`
|
|
294
|
+
* ```typescript
|
|
295
|
+
* // src/infra.ts
|
|
296
|
+
* export const Hello = Archil.Sandbox("Hello", {
|
|
297
|
+
* main: "./src/hello.ts",
|
|
298
|
+
* env: { GREETING: "hello" },
|
|
299
|
+
* });
|
|
300
|
+
* export type HelloEnv = Archil.InferEnv<typeof Hello>;
|
|
301
|
+
* ```
|
|
302
|
+
*
|
|
303
|
+
* ```typescript
|
|
304
|
+
* // src/hello.ts
|
|
305
|
+
* import type { HelloEnv } from "./infra.ts";
|
|
306
|
+
*
|
|
307
|
+
* export default {
|
|
308
|
+
* async fetch(request: Request, env: HelloEnv) {
|
|
309
|
+
* return new Response(`${env.GREETING} from ${new URL(request.url).pathname}`);
|
|
310
|
+
* },
|
|
311
|
+
* };
|
|
312
|
+
* ```
|
|
313
|
+
*
|
|
314
|
+
* **Example:** Secrets in the program's environment
|
|
315
|
+
* ```typescript
|
|
316
|
+
* export const Billing = Archil.Sandbox("Billing", {
|
|
317
|
+
* main: "./src/billing.ts",
|
|
318
|
+
* env: { STRIPE_KEY: Config.Redacted("STRIPE_KEY") },
|
|
319
|
+
* });
|
|
320
|
+
* ```
|
|
321
|
+
*
|
|
322
|
+
* ### Mounting Disks
|
|
323
|
+
* Archil sandboxes mount disks natively. Each entry names the disk and a
|
|
324
|
+
* `path`, with Archil's own options: `mode` (`exclusive`, `conditional`
|
|
325
|
+
* or `read-only`), `subdirectory`, and `queueMs`.
|
|
326
|
+
*
|
|
327
|
+
* **Example:** Mount two disks, one read-only
|
|
328
|
+
* ```typescript
|
|
329
|
+
* export const Box = Archil.Sandbox("Box", {
|
|
330
|
+
* mounts: [
|
|
331
|
+
* { disk: Workspace, path: "/workspace" },
|
|
332
|
+
* { disk: Dataset, path: "/data", mode: "read-only" },
|
|
333
|
+
* ],
|
|
334
|
+
* });
|
|
335
|
+
* ```
|
|
336
|
+
*
|
|
337
|
+
* **Example:** Mount from the program with `MountDisk`
|
|
338
|
+
* ```typescript
|
|
339
|
+
* const uploads = yield* Archil.MountDisk(Uploads, { path: "/uploads", mode: "conditional" });
|
|
340
|
+
* // runtime: the disk is already mounted at uploads.path
|
|
341
|
+
* yield* fs.writeFileString(`${uploads.path}/${id}.txt`, body);
|
|
342
|
+
* ```
|
|
343
|
+
*
|
|
344
|
+
* ### Mount Clients From Other Bindings
|
|
345
|
+
* A binding that installs a filesystem client (an `alchemy/Mount`
|
|
346
|
+
* capability) into a program's image makes Alchemy build one: the
|
|
347
|
+
* sandbox's base plus the client's install lines, built with your local
|
|
348
|
+
* Docker and pushed to `push.repository` for Archil to pull. A different
|
|
349
|
+
* set of clients replaces the sandbox.
|
|
350
|
+
*
|
|
351
|
+
* **Example:** Give a program sandbox a repository for its derived image
|
|
352
|
+
* ```typescript
|
|
353
|
+
* export default class Indexer extends Archil.Sandbox<Indexer>()(
|
|
354
|
+
* "Indexer",
|
|
355
|
+
* {
|
|
356
|
+
* main: import.meta.url,
|
|
357
|
+
* push: {
|
|
358
|
+
* repository: "ghcr.io/acme/indexer",
|
|
359
|
+
* credentials: { server: "ghcr.io", username: "acme-bot", password: Alchemy.Secret("GHCR_TOKEN") },
|
|
360
|
+
* },
|
|
361
|
+
* },
|
|
362
|
+
* Effect.gen(function* () {
|
|
363
|
+
* const media = yield* Cloud.MountBucket(Media, { path: "/media" }); // installs a FUSE client
|
|
364
|
+
* return { fetch: Effect.succeed(HttpServerResponse.text(media.path)) };
|
|
365
|
+
* }),
|
|
366
|
+
* ) {}
|
|
367
|
+
* ```
|
|
368
|
+
*
|
|
369
|
+
* ### Packaging
|
|
370
|
+
* Alchemy bundles `main` with rolldown into one Node program. Packages
|
|
371
|
+
* that can't be bundled (native modules, or ones that read their own files
|
|
372
|
+
* at run time) go in `build.install` and are installed next to it with
|
|
373
|
+
* `npm install`.
|
|
374
|
+
*
|
|
375
|
+
* **Example:** Install a native package
|
|
376
|
+
* ```typescript
|
|
377
|
+
* export const Thumbs = Archil.Sandbox("Thumbs", {
|
|
378
|
+
* main: "./src/thumbs.ts",
|
|
379
|
+
* build: { install: ["sharp"] },
|
|
380
|
+
* });
|
|
381
|
+
* ```
|
|
382
|
+
*
|
|
383
|
+
* **Example:** Upload static files next to the program
|
|
384
|
+
* ```typescript
|
|
385
|
+
* export const Site = Archil.Sandbox("Site", {
|
|
386
|
+
* main: "./dist/server.mjs",
|
|
387
|
+
* extraFiles: [{ source: "./dist/client", destination: "client" }],
|
|
388
|
+
* });
|
|
389
|
+
* ```
|
|
390
|
+
*
|
|
391
|
+
* ### Ports
|
|
392
|
+
* **Example:** Serve a port and hand out a token for it
|
|
393
|
+
* ```typescript
|
|
394
|
+
* export const Preview = Archil.Sandbox("Preview", { ports: [8080] });
|
|
395
|
+
* export const PreviewToken = Effect.gen(function* () {
|
|
396
|
+
* const preview = yield* Preview;
|
|
397
|
+
* return yield* Archil.SandboxPortToken("PreviewToken", {
|
|
398
|
+
* sandbox: preview.sandboxId,
|
|
399
|
+
* port: 8080,
|
|
400
|
+
* ttl: "24h",
|
|
401
|
+
* });
|
|
402
|
+
* });
|
|
403
|
+
* ```
|
|
404
|
+
*
|
|
405
|
+
* ### Network Policy
|
|
406
|
+
* **Example:** Deny by default, inject a token for one API
|
|
407
|
+
* ```typescript
|
|
408
|
+
* export const Agent = Archil.Sandbox("Agent", {
|
|
409
|
+
* network: {
|
|
410
|
+
* egress: {
|
|
411
|
+
* default: "deny",
|
|
412
|
+
* allow: [
|
|
413
|
+
* "registry.npmjs.org",
|
|
414
|
+
* { target: "api.github.com", headers: { Authorization: Alchemy.Secret("GITHUB_AUTH") } },
|
|
415
|
+
* ],
|
|
416
|
+
* },
|
|
417
|
+
* },
|
|
418
|
+
* });
|
|
419
|
+
* ```
|
|
420
|
+
*
|
|
421
|
+
* **Example:** Forward an API's requests to a Worker gateway that adds the key
|
|
422
|
+
* ```typescript
|
|
423
|
+
* const gateway = yield* MyGateway;
|
|
424
|
+
* const sandbox = yield* Archil.Sandbox("MySandbox", {
|
|
425
|
+
* network: {
|
|
426
|
+
* egress: {
|
|
427
|
+
* default: "deny",
|
|
428
|
+
* allow: [
|
|
429
|
+
* {
|
|
430
|
+
* target: "api.example.com",
|
|
431
|
+
* // proves to the gateway that the request came through this policy
|
|
432
|
+
* headers: { "X-Gateway-Token": Config.Redacted("GATEWAY_TOKEN") },
|
|
433
|
+
* forwardUrl: gateway.url.as<string>(),
|
|
434
|
+
* },
|
|
435
|
+
* ],
|
|
436
|
+
* },
|
|
437
|
+
* },
|
|
438
|
+
* });
|
|
439
|
+
* ```
|
|
440
|
+
*
|
|
441
|
+
* ### Using a Sandbox at Run Time
|
|
442
|
+
* **Example:** Run a command and fork a preview from a Worker
|
|
443
|
+
* ```typescript
|
|
444
|
+
* const preview = yield* Archil.ConnectSandbox(Preview);
|
|
445
|
+
* const result = yield* preview.exec("pnpm build", { cwd: "/workspace" });
|
|
446
|
+
* const fork = yield* preview.fork({ name: "pr-42" });
|
|
447
|
+
* ```
|
|
448
|
+
*
|
|
449
|
+
* ### Looking up an existing sandbox
|
|
450
|
+
* `Sandbox.lookup` references a sandbox Alchemy doesn't manage (created in
|
|
451
|
+
* the Archil console or by another stack). It is read during plan/deploy,
|
|
452
|
+
* never created, updated or deleted.
|
|
453
|
+
* Its program fields are `undefined`: they come from the deploy that started
|
|
454
|
+
* the sandbox's program.
|
|
455
|
+
*
|
|
456
|
+
* **Example:** Reference an existing sandbox
|
|
457
|
+
* ```typescript
|
|
458
|
+
* const box = Archil.Sandbox.lookup({ name: "research" });
|
|
459
|
+
* ```
|
|
460
|
+
*
|
|
461
|
+
* @resource
|
|
462
|
+
* @product Sandbox
|
|
463
|
+
*/
|
|
464
|
+
export declare const Sandbox: Platform<Sandbox, ServerHost, SandboxShape, HostRuntimeContext> & LookupMethod<Sandbox>;
|
|
465
|
+
/**
|
|
466
|
+
* Map a sandbox and its exposed ports to attributes. Archil lists port
|
|
467
|
+
* hostnames separately; sandbox responses don't carry them. `program` is
|
|
468
|
+
* the port and code of the program the sandbox runs, if any.
|
|
469
|
+
*/
|
|
470
|
+
export declare const toSandboxAttributes: (sandbox: archil.Sandbox, ports: ReadonlyArray<{
|
|
471
|
+
port: number;
|
|
472
|
+
hostname: string;
|
|
473
|
+
}>, program?: {
|
|
474
|
+
readonly port: number;
|
|
475
|
+
readonly code: {
|
|
476
|
+
hash: string;
|
|
477
|
+
};
|
|
478
|
+
}, derivedImage?: {
|
|
479
|
+
readonly imageId: string;
|
|
480
|
+
readonly hash: string;
|
|
481
|
+
}) => SandboxAttributes;
|
|
482
|
+
/** Read a sandbox's exposed ports and map it to attributes. */
|
|
483
|
+
export declare const observeSandbox: (sandbox: archil.Sandbox, program?: {
|
|
484
|
+
readonly port: number;
|
|
485
|
+
readonly code: {
|
|
486
|
+
hash: string;
|
|
487
|
+
};
|
|
488
|
+
} | undefined, derivedImage?: {
|
|
489
|
+
readonly imageId: string;
|
|
490
|
+
readonly hash: string;
|
|
491
|
+
} | undefined) => Effect.Effect<SandboxAttributes, archil.ArchilParseError | archil.BadGateway | import("@distilled.cloud/core/errors").BadRequest | archil.ConfigError | import("@distilled.cloud/core/errors").Conflict | import("@distilled.cloud/core/errors").Forbidden | archil.GatewayTimeout | import("effect/http/HttpClientError").HttpClientError | archil.InternalServerError | import("@distilled.cloud/core/protocol-http").InvalidInput | archil.Locked | import("@distilled.cloud/core/sdk-error").SdkError | archil.ServiceUnavailable | archil.TooManyRequests | archil.Unauthorized | archil.UnknownArchilError | archil.UnprocessableEntity, archil.ArchilOpContext>;
|
|
492
|
+
/** The create request for sandbox props, with mounts already on the wire. */
|
|
493
|
+
export declare const toCreateSandboxRequest: (name: string | undefined, props: Omit<SandboxProps, "name" | "mounts">, mounts: ReadonlyArray<archil.SandboxMount> | undefined) => archil.CreateSandboxRequest;
|
|
494
|
+
/**
|
|
495
|
+
* Delete a sandbox and wait until it is gone. Archil only deletes stopped,
|
|
496
|
+
* exited or failed sandboxes, so a live one is stopped first. Deleting a
|
|
497
|
+
* missing sandbox succeeds.
|
|
498
|
+
*/
|
|
499
|
+
export declare const deleteSandbox: (sid: string) => Effect.Effect<void, import("./index.ts").ArchilFailed | import("./index.ts").ArchilNotReady | archil.ArchilParseError | archil.BadGateway | import("@distilled.cloud/core/errors").BadRequest | archil.BadRequest | archil.ConfigError | import("@distilled.cloud/core/errors").Conflict | import("@distilled.cloud/core/errors").Forbidden | archil.GatewayTimeout | import("effect/http/HttpClientError").HttpClientError | archil.InternalServerError | import("@distilled.cloud/core/protocol-http").InvalidInput | archil.Locked | archil.SandboxHasForks | archil.SandboxNotDeletable | archil.SandboxStopConflict | import("@distilled.cloud/core/sdk-error").SdkError | archil.ServiceUnavailable | archil.TooManyRequests | archil.Unauthorized | archil.UnknownArchilError | archil.UnprocessableEntity, archil.ArchilOpContext>;
|
|
500
|
+
/**
|
|
501
|
+
* Wire mounts for a list of entries whose disks resolved to attributes or
|
|
502
|
+
* handles. Fails when a disk has no id yet.
|
|
503
|
+
*/
|
|
504
|
+
export declare const toSandboxMounts: (owner: string, mounts: readonly DiskMount[]) => Effect.Effect<archil.SandboxMount[], MountDiskUnresolved | import("./SandboxOptions.ts").MountOptionUnsupported, never>;
|
|
505
|
+
export declare const SandboxProvider: () => import("effect/Layer").Layer<Provider.Provider<Sandbox>, never, import("effect/process/ChildProcessSpawner").ChildProcessSpawner | import("@alchemy.run/docker/Docker").Docker | import("effect/FileSystem").FileSystem | import("effect/Path").Path | Stack | import("alchemy").Stage | archil.ArchilOpContext>;
|
|
506
|
+
export {};
|
|
507
|
+
//# sourceMappingURL=Sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Sandbox.d.ts","sources":["../src/Sandbox.ts"],"names":[],"mappings":"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"}
|