@alchemy.run/e2b 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.
- package/LICENSE +201 -0
- package/README.md +56 -4
- package/lib/ApiKey.d.ts +53 -0
- package/lib/ApiKey.d.ts.map +1 -0
- package/lib/ApiKey.js +107 -0
- package/lib/ApiKey.js.map +1 -0
- package/lib/AuthProvider.d.ts +60 -0
- package/lib/AuthProvider.d.ts.map +1 -0
- package/lib/AuthProvider.js +293 -0
- package/lib/AuthProvider.js.map +1 -0
- package/lib/Bootstrap.d.ts +7 -0
- package/lib/Bootstrap.d.ts.map +1 -0
- package/lib/Bootstrap.js +25 -0
- package/lib/Bootstrap.js.map +1 -0
- package/lib/ConnectSandbox.d.ts +67 -0
- package/lib/ConnectSandbox.d.ts.map +1 -0
- package/lib/ConnectSandbox.js +3 -0
- package/lib/ConnectSandbox.js.map +1 -0
- package/lib/ConnectSandboxHttp.d.ts +22 -0
- package/lib/ConnectSandboxHttp.d.ts.map +1 -0
- package/lib/ConnectSandboxHttp.js +30 -0
- package/lib/ConnectSandboxHttp.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/CreateSandbox.d.ts +139 -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 +22 -0
- package/lib/CreateSandboxHttp.d.ts.map +1 -0
- package/lib/CreateSandboxHttp.js +99 -0
- package/lib/CreateSandboxHttp.js.map +1 -0
- package/lib/CreateSecret.d.ts +57 -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 +20 -0
- package/lib/CreateSecretHttp.d.ts.map +1 -0
- package/lib/CreateSecretHttp.js +64 -0
- package/lib/CreateSecretHttp.js.map +1 -0
- package/lib/CreateSnapshot.d.ts +53 -0
- package/lib/CreateSnapshot.d.ts.map +1 -0
- package/lib/CreateSnapshot.js +3 -0
- package/lib/CreateSnapshot.js.map +1 -0
- package/lib/CreateSnapshotHttp.d.ts +20 -0
- package/lib/CreateSnapshotHttp.d.ts.map +1 -0
- package/lib/CreateSnapshotHttp.js +41 -0
- package/lib/CreateSnapshotHttp.js.map +1 -0
- package/lib/CreateTemplate.d.ts +96 -0
- package/lib/CreateTemplate.d.ts.map +1 -0
- package/lib/CreateTemplate.js +3 -0
- package/lib/CreateTemplate.js.map +1 -0
- package/lib/CreateTemplateHttp.d.ts +20 -0
- package/lib/CreateTemplateHttp.d.ts.map +1 -0
- package/lib/CreateTemplateHttp.js +99 -0
- package/lib/CreateTemplateHttp.js.map +1 -0
- package/lib/CreateVolume.d.ts +58 -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 +20 -0
- package/lib/CreateVolumeHttp.d.ts.map +1 -0
- package/lib/CreateVolumeHttp.js +51 -0
- package/lib/CreateVolumeHttp.js.map +1 -0
- package/lib/Credentials.d.ts +18 -0
- package/lib/Credentials.d.ts.map +1 -0
- package/lib/Credentials.js +55 -0
- package/lib/Credentials.js.map +1 -0
- package/lib/E2BBindings.d.ts +35 -0
- package/lib/E2BBindings.d.ts.map +1 -0
- package/lib/E2BBindings.js +127 -0
- package/lib/E2BBindings.js.map +1 -0
- package/lib/Errors.d.ts +61 -0
- package/lib/Errors.d.ts.map +1 -0
- package/lib/Errors.js +23 -0
- package/lib/Errors.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/MountVolume.d.ts +86 -0
- package/lib/MountVolume.d.ts.map +1 -0
- package/lib/MountVolume.js +3 -0
- package/lib/MountVolume.js.map +1 -0
- package/lib/MountVolumeLive.d.ts +23 -0
- package/lib/MountVolumeLive.d.ts.map +1 -0
- package/lib/MountVolumeLive.js +41 -0
- package/lib/MountVolumeLive.js.map +1 -0
- package/lib/Providers.d.ts +14 -0
- package/lib/Providers.d.ts.map +1 -0
- package/lib/Providers.js +23 -0
- package/lib/Providers.js.map +1 -0
- package/lib/ReadTeam.d.ts +41 -0
- package/lib/ReadTeam.d.ts.map +1 -0
- package/lib/ReadTeam.js +3 -0
- package/lib/ReadTeam.js.map +1 -0
- package/lib/ReadTeamHttp.d.ts +20 -0
- package/lib/ReadTeamHttp.d.ts.map +1 -0
- package/lib/ReadTeamHttp.js +40 -0
- package/lib/ReadTeamHttp.js.map +1 -0
- package/lib/ReadVolume.d.ts +25 -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 +20 -0
- package/lib/ReadVolumeHttp.d.ts.map +1 -0
- package/lib/ReadVolumeHttp.js +27 -0
- package/lib/ReadVolumeHttp.js.map +1 -0
- package/lib/ReadWebhook.d.ts +32 -0
- package/lib/ReadWebhook.d.ts.map +1 -0
- package/lib/ReadWebhook.js +3 -0
- package/lib/ReadWebhook.js.map +1 -0
- package/lib/ReadWebhookHttp.d.ts +20 -0
- package/lib/ReadWebhookHttp.d.ts.map +1 -0
- package/lib/ReadWebhookHttp.js +31 -0
- package/lib/ReadWebhookHttp.js.map +1 -0
- package/lib/ReadWriteVolume.d.ts +26 -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 +20 -0
- package/lib/ReadWriteVolumeHttp.d.ts.map +1 -0
- package/lib/ReadWriteVolumeHttp.js +27 -0
- package/lib/ReadWriteVolumeHttp.js.map +1 -0
- package/lib/Sandbox.d.ts +295 -0
- package/lib/Sandbox.d.ts.map +1 -0
- package/lib/Sandbox.js +351 -0
- package/lib/Sandbox.js.map +1 -0
- package/lib/SandboxClient.d.ts +226 -0
- package/lib/SandboxClient.d.ts.map +1 -0
- package/lib/SandboxClient.js +1 -0
- package/lib/SandboxClient.js.map +1 -0
- package/lib/SandboxEvents.d.ts +87 -0
- package/lib/SandboxEvents.d.ts.map +1 -0
- package/lib/SandboxEvents.js +39 -0
- package/lib/SandboxEvents.js.map +1 -0
- package/lib/SandboxEventsLive.d.ts +13 -0
- package/lib/SandboxEventsLive.d.ts.map +1 -0
- package/lib/SandboxEventsLive.js +80 -0
- package/lib/SandboxEventsLive.js.map +1 -0
- package/lib/Secret.d.ts +105 -0
- package/lib/Secret.d.ts.map +1 -0
- package/lib/Secret.js +161 -0
- package/lib/Secret.js.map +1 -0
- package/lib/Snapshot.d.ts +118 -0
- package/lib/Snapshot.d.ts.map +1 -0
- package/lib/Snapshot.js +158 -0
- package/lib/Snapshot.js.map +1 -0
- package/lib/Template.d.ts +313 -0
- package/lib/Template.d.ts.map +1 -0
- package/lib/Template.js +421 -0
- package/lib/Template.js.map +1 -0
- package/lib/Volume.d.ts +88 -0
- package/lib/Volume.d.ts.map +1 -0
- package/lib/Volume.js +136 -0
- package/lib/Volume.js.map +1 -0
- package/lib/VolumeFiles.d.ts +39 -0
- package/lib/VolumeFiles.d.ts.map +1 -0
- package/lib/VolumeFiles.js +1 -0
- package/lib/VolumeFiles.js.map +1 -0
- package/lib/Webhook.d.ts +83 -0
- package/lib/Webhook.d.ts.map +1 -0
- package/lib/Webhook.js +138 -0
- package/lib/Webhook.js.map +1 -0
- package/lib/WriteSecret.d.ts +34 -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 +20 -0
- package/lib/WriteSecretHttp.d.ts.map +1 -0
- package/lib/WriteSecretHttp.js +37 -0
- package/lib/WriteSecretHttp.js.map +1 -0
- package/lib/WriteVolume.d.ts +25 -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 +20 -0
- package/lib/WriteVolumeHttp.d.ts.map +1 -0
- package/lib/WriteVolumeHttp.js +27 -0
- package/lib/WriteVolumeHttp.js.map +1 -0
- package/lib/index.d.ts +43 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +43 -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/Login.d.ts +45 -0
- package/lib/internal/Login.d.ts.map +1 -0
- package/lib/internal/Login.js +157 -0
- package/lib/internal/Login.js.map +1 -0
- package/lib/internal/Ownership.d.ts +29 -0
- package/lib/internal/Ownership.d.ts.map +1 -0
- package/lib/internal/Ownership.js +49 -0
- package/lib/internal/Ownership.js.map +1 -0
- package/lib/internal/Program.d.ts +31 -0
- package/lib/internal/Program.d.ts.map +1 -0
- package/lib/internal/Program.js +60 -0
- package/lib/internal/Program.js.map +1 -0
- package/lib/internal/SandboxHandle.d.ts +25 -0
- package/lib/internal/SandboxHandle.d.ts.map +1 -0
- package/lib/internal/SandboxHandle.js +316 -0
- package/lib/internal/SandboxHandle.js.map +1 -0
- package/lib/internal/SnapshotBuild.d.ts +19 -0
- package/lib/internal/SnapshotBuild.d.ts.map +1 -0
- package/lib/internal/SnapshotBuild.js +49 -0
- package/lib/internal/SnapshotBuild.js.map +1 -0
- package/lib/internal/Tar.d.ts +10 -0
- package/lib/internal/Tar.d.ts.map +1 -0
- package/lib/internal/Tar.js +61 -0
- package/lib/internal/Tar.js.map +1 -0
- package/lib/internal/TemplateBuild.d.ts +142 -0
- package/lib/internal/TemplateBuild.d.ts.map +1 -0
- package/lib/internal/TemplateBuild.js +220 -0
- package/lib/internal/TemplateBuild.js.map +1 -0
- package/lib/internal/TemplatePlan.d.ts +57 -0
- package/lib/internal/TemplatePlan.d.ts.map +1 -0
- package/lib/internal/TemplatePlan.js +185 -0
- package/lib/internal/TemplatePlan.js.map +1 -0
- package/lib/internal/VolumeHttp.d.ts +5 -0
- package/lib/internal/VolumeHttp.d.ts.map +1 -0
- package/lib/internal/VolumeHttp.js +46 -0
- package/lib/internal/VolumeHttp.js.map +1 -0
- package/package.json +62 -3
- package/src/ApiKey.ts +148 -0
- package/src/AuthProvider.ts +437 -0
- package/src/Bootstrap.ts +51 -0
- package/src/ConnectSandbox.ts +71 -0
- package/src/ConnectSandboxHttp.ts +38 -0
- package/src/Contributions.ts +9 -0
- package/src/CreateSandbox.ts +157 -0
- package/src/CreateSandboxHttp.ts +131 -0
- package/src/CreateSecret.ts +65 -0
- package/src/CreateSecretHttp.ts +94 -0
- package/src/CreateSnapshot.ts +64 -0
- package/src/CreateSnapshotHttp.ts +55 -0
- package/src/CreateTemplate.ts +135 -0
- package/src/CreateTemplateHttp.ts +152 -0
- package/src/CreateVolume.ts +65 -0
- package/src/CreateVolumeHttp.ts +80 -0
- package/src/Credentials.ts +81 -0
- package/src/E2BBindings.ts +160 -0
- package/src/Errors.ts +47 -0
- package/src/InferEnv.ts +27 -0
- package/src/MountVolume.ts +92 -0
- package/src/MountVolumeLive.ts +49 -0
- package/src/Providers.ts +48 -0
- package/src/ReadTeam.ts +55 -0
- package/src/ReadTeamHttp.ts +44 -0
- package/src/ReadVolume.ts +29 -0
- package/src/ReadVolumeHttp.ts +32 -0
- package/src/ReadWebhook.ts +41 -0
- package/src/ReadWebhookHttp.ts +42 -0
- package/src/ReadWriteVolume.ts +30 -0
- package/src/ReadWriteVolumeHttp.ts +32 -0
- package/src/Sandbox.ts +581 -0
- package/src/SandboxClient.ts +268 -0
- package/src/SandboxEvents.ts +101 -0
- package/src/SandboxEventsLive.ts +118 -0
- package/src/Secret.ts +229 -0
- package/src/Snapshot.ts +234 -0
- package/src/Template.ts +636 -0
- package/src/Volume.ts +173 -0
- package/src/VolumeFiles.ts +53 -0
- package/src/Webhook.ts +215 -0
- package/src/WriteSecret.ts +39 -0
- package/src/WriteSecretHttp.ts +43 -0
- package/src/WriteVolume.ts +29 -0
- package/src/WriteVolumeHttp.ts +32 -0
- package/src/globals.d.ts +2 -0
- package/src/index.ts +42 -0
- package/src/internal/Declared.ts +80 -0
- package/src/internal/Login.ts +210 -0
- package/src/internal/Ownership.ts +67 -0
- package/src/internal/Program.ts +75 -0
- package/src/internal/SandboxHandle.ts +534 -0
- package/src/internal/SnapshotBuild.ts +74 -0
- package/src/internal/Tar.ts +74 -0
- package/src/internal/TemplateBuild.ts +383 -0
- package/src/internal/TemplatePlan.ts +230 -0
- package/src/internal/VolumeHttp.ts +88 -0
package/lib/Template.js
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import * as templates from "@distilled.cloud/e2b/templates";
|
|
2
|
+
import { Unowned } from "alchemy/AdoptPolicy";
|
|
3
|
+
import { isResolved } from "alchemy/Diff";
|
|
4
|
+
import { checkMountSupport, collectMountCapabilities, mountEnv, mountInstallLines, } from "alchemy/Mount";
|
|
5
|
+
import { Platform } from "alchemy/Platform";
|
|
6
|
+
import * as Provider from "alchemy/Provider";
|
|
7
|
+
import { createContainerRuntimeContext, } from "alchemy/Runtime/Process";
|
|
8
|
+
import * as Effect from "effect/Effect";
|
|
9
|
+
import * as Redacted from "effect/Redacted";
|
|
10
|
+
import * as Schedule from "effect/Schedule";
|
|
11
|
+
import * as Stream from "effect/Stream";
|
|
12
|
+
import { E2BUnexpectedResponse } from "./Errors.js";
|
|
13
|
+
import { e2bName, isGeneratedName } from "./internal/Ownership.js";
|
|
14
|
+
import { DEFAULT_PORT, makeBootstrap, programEnv, programReadyCmd } from "./internal/Program.js";
|
|
15
|
+
import { planTemplateBuild, runTemplateBuild, } from "./internal/TemplateBuild.js";
|
|
16
|
+
import { planSource } from "./internal/TemplatePlan.js";
|
|
17
|
+
/**
|
|
18
|
+
* An E2B template: the image every sandbox boots from, built by E2B into a
|
|
19
|
+
* Firecracker snapshot.
|
|
20
|
+
*
|
|
21
|
+
* Build from a registry `image`, a `dockerfile` (a path or inline content),
|
|
22
|
+
* or another template (`fromTemplate`). E2B builds remotely, so a deploy
|
|
23
|
+
* needs no Docker daemon: Alchemy plans the Dockerfile with
|
|
24
|
+
* `@alchemy.run/docker`'s build plan, lowers it to E2B's build steps, and
|
|
25
|
+
* uploads only the `COPY` sources E2B has not seen, by content hash. A
|
|
26
|
+
* deploy starts a new build only when the inputs change.
|
|
27
|
+
*
|
|
28
|
+
* E2B's builder runs one stage for `linux/amd64`. A Dockerfile with several
|
|
29
|
+
* `FROM`s, `COPY --from`, `ADD <url>`, heredocs, `RUN --mount` or `SHELL`
|
|
30
|
+
* fails at plan time with `UnsupportedDockerfile`, listing the lines.
|
|
31
|
+
* `EXPOSE`, `LABEL`, `VOLUME`, `HEALTHCHECK` and `STOPSIGNAL` are ignored,
|
|
32
|
+
* as E2B ignores them. An `ARG` becomes an environment variable. `CMD` / `ENTRYPOINT`
|
|
33
|
+
* become the template's start command: it is captured running in the
|
|
34
|
+
* snapshot, so every sandbox starts with it already up.
|
|
35
|
+
*
|
|
36
|
+
* E2B templates carry no labels, so Alchemy recognises its templates by
|
|
37
|
+
* their generated name.
|
|
38
|
+
*
|
|
39
|
+
* ### Building a Template
|
|
40
|
+
* **Example:** From a registry image
|
|
41
|
+
* ```typescript
|
|
42
|
+
* export const Python = E2B.Template("Python", { image: "python:3.12-slim" });
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* **Example:** From an inline Dockerfile
|
|
46
|
+
* ```typescript
|
|
47
|
+
* import * as Dockerfile from "@alchemy.run/docker/Dockerfile";
|
|
48
|
+
*
|
|
49
|
+
* export const Agent = E2B.Template("Agent", {
|
|
50
|
+
* dockerfile: Dockerfile.inline`
|
|
51
|
+
* FROM node:22-bookworm
|
|
52
|
+
* RUN apt-get update && apt-get install -y git ripgrep
|
|
53
|
+
* WORKDIR /work
|
|
54
|
+
* `,
|
|
55
|
+
* cpuCount: 2,
|
|
56
|
+
* memoryMB: 4096,
|
|
57
|
+
* });
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* **Example:** From a Dockerfile and its build context
|
|
61
|
+
* ```typescript
|
|
62
|
+
* export const Repo = E2B.Template("Repo", {
|
|
63
|
+
* context: "./sandbox",
|
|
64
|
+
* dockerfile: "./sandbox/Dockerfile",
|
|
65
|
+
* build: { args: { NODE_VERSION: "22" } },
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* ### Starting a process in every sandbox
|
|
70
|
+
* **Example:** A dev server that is already running when a sandbox starts
|
|
71
|
+
* ```typescript
|
|
72
|
+
* export const Preview = E2B.Template("Preview", {
|
|
73
|
+
* image: "node:22-bookworm",
|
|
74
|
+
* run: ["npm create vite@latest app -- --template react", "cd app && npm install"],
|
|
75
|
+
* startCmd: "cd /home/user/app && npm run dev -- --host 0.0.0.0 --port 3000",
|
|
76
|
+
* readyCmd: "curl -sf http://localhost:3000",
|
|
77
|
+
* });
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* ### Private base images
|
|
81
|
+
* **Example:** A base image in GHCR
|
|
82
|
+
* ```typescript
|
|
83
|
+
* export const Private = E2B.Template("Private", {
|
|
84
|
+
* image: "ghcr.io/my-org/base:1",
|
|
85
|
+
* registry: { username: "my-org", password: Config.Redacted("GHCR_TOKEN") },
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* ### Effect program
|
|
90
|
+
* Give the template a `main` and an Effect, and every sandbox from it boots
|
|
91
|
+
* with the program already serving HTTP on `port`. Alchemy bundles `main`,
|
|
92
|
+
* copies it into the template, and E2B snapshots the template once the
|
|
93
|
+
* program answers. The program runs with Bun; the image defaults to
|
|
94
|
+
* `oven/bun:1`.
|
|
95
|
+
*
|
|
96
|
+
* **Example:** A program in every sandbox
|
|
97
|
+
* ```typescript
|
|
98
|
+
* export default class Program extends E2B.Template<Program>()(
|
|
99
|
+
* "Program",
|
|
100
|
+
* { main: import.meta.url, port: 3000 },
|
|
101
|
+
* Effect.gen(function* () {
|
|
102
|
+
* return {
|
|
103
|
+
* fetch: Effect.succeed(HttpServerResponse.text("hello from a sandbox")),
|
|
104
|
+
* };
|
|
105
|
+
* }),
|
|
106
|
+
* ) {}
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* **Example:** Call the program in a sandbox
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const sandboxes = yield* E2B.CreateSandbox(Program);
|
|
112
|
+
* const sandbox = yield* sandboxes.create({ timeout: 300 });
|
|
113
|
+
* const port = yield* sandbox.getTcpPort(3000);
|
|
114
|
+
* const res = yield* port.fetch(HttpClientRequest.get("/"));
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* ### Async program
|
|
118
|
+
* A `main` without an Effect is bundled and run with Bun as-is. It must
|
|
119
|
+
* listen on `PORT`. `E2B.InferEnv` types its `env`.
|
|
120
|
+
*
|
|
121
|
+
* **Example:** A plain server
|
|
122
|
+
* ```typescript
|
|
123
|
+
* export const Server = E2B.Template("Server", {
|
|
124
|
+
* main: "./src/server.mjs",
|
|
125
|
+
* env: { GREETING: "hi" },
|
|
126
|
+
* });
|
|
127
|
+
* export type ServerEnv = E2B.InferEnv<typeof Server>;
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* ### Bindings in the sandbox
|
|
131
|
+
* Bindings work inside a template program like in any other host.
|
|
132
|
+
*
|
|
133
|
+
* :::caution[Values are part of the template]
|
|
134
|
+
* Config and binding values are written into the template, so code in a
|
|
135
|
+
* sandbox can read them, `Redacted` ones included. Use egress secrets for
|
|
136
|
+
* credentials untrusted code must not see.
|
|
137
|
+
* :::
|
|
138
|
+
*
|
|
139
|
+
* **Example:** Read a volume from the program
|
|
140
|
+
* ```typescript
|
|
141
|
+
* export default class Program extends E2B.Template<Program>()(
|
|
142
|
+
* "Program",
|
|
143
|
+
* { main: import.meta.url },
|
|
144
|
+
* Effect.gen(function* () {
|
|
145
|
+
* const reports = yield* E2B.ReadVolume(Reports);
|
|
146
|
+
* return {
|
|
147
|
+
* fetch: Effect.gen(function* () {
|
|
148
|
+
* return HttpServerResponse.text(yield* reports.readText("/latest.json"));
|
|
149
|
+
* }).pipe(Effect.orDie),
|
|
150
|
+
* };
|
|
151
|
+
* }).pipe(Effect.provide(E2B.ReadVolumeHttp)),
|
|
152
|
+
* ) {}
|
|
153
|
+
* ```
|
|
154
|
+
*
|
|
155
|
+
* ### Configuration
|
|
156
|
+
* **Example:** Size, image and port
|
|
157
|
+
* ```typescript
|
|
158
|
+
* export default class Program extends E2B.Template<Program>()(
|
|
159
|
+
* "Program",
|
|
160
|
+
* { main: import.meta.url, image: "oven/bun:1-debian", cpuCount: 4, memoryMB: 8192, port: 8080 },
|
|
161
|
+
* Effect.gen(function* () {
|
|
162
|
+
* return { fetch: Effect.succeed(HttpServerResponse.text("ok")) };
|
|
163
|
+
* }),
|
|
164
|
+
* ) {}
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
167
|
+
* **Example:** Sandboxes from the template, in a Worker
|
|
168
|
+
* ```typescript
|
|
169
|
+
* const sandboxes = yield* E2B.CreateSandbox(Agent);
|
|
170
|
+
* const sandbox = yield* sandboxes.create({ timeout: 600 });
|
|
171
|
+
* ```
|
|
172
|
+
*
|
|
173
|
+
* ### Referencing a template the stack doesn't manage
|
|
174
|
+
* `E2B.Template.lookup` finds an existing template by name. Nothing is created,
|
|
175
|
+
* adopted or deleted.
|
|
176
|
+
*
|
|
177
|
+
* **Example:** Look one up by name
|
|
178
|
+
* ```typescript
|
|
179
|
+
* const base = E2B.Template.lookup({ name: "my-team/base-image" });
|
|
180
|
+
* const sandboxes = yield* E2B.CreateSandbox(base);
|
|
181
|
+
* ```
|
|
182
|
+
*
|
|
183
|
+
* @resource
|
|
184
|
+
* @product Template
|
|
185
|
+
*/
|
|
186
|
+
export const Template = Platform("E2B.Template", {
|
|
187
|
+
createRuntimeContext: createContainerRuntimeContext("E2B.Template"),
|
|
188
|
+
});
|
|
189
|
+
/** A template by id, or by name (alias). */
|
|
190
|
+
export const observeTemplate = (templateId, name) => (templateId !== undefined
|
|
191
|
+
? templates.getTemplate({ templateID: templateId })
|
|
192
|
+
: templates
|
|
193
|
+
.getTemplateByAlias({ alias: name })
|
|
194
|
+
.pipe(Effect.flatMap((alias) => templates.getTemplate({ templateID: alias.templateID })))).pipe(Effect.map((template) => template), Effect.catchTag("NotFound", () => Effect.undefined));
|
|
195
|
+
/** The mounts the template's bindings attach, by path (a later binding wins). */
|
|
196
|
+
const boundMounts = (bindings) => [
|
|
197
|
+
...new Map((bindings ?? [])
|
|
198
|
+
.filter((binding) => binding.action !== "delete")
|
|
199
|
+
.flatMap((binding) => binding.data?.volumes ?? [])
|
|
200
|
+
.map((mount) => [mount.path, { volume: { name: mount.volume.name }, path: mount.path }])).values(),
|
|
201
|
+
];
|
|
202
|
+
/** The mount clients the template's bindings need. */
|
|
203
|
+
const boundCapabilities = (bindings) => collectMountCapabilities((bindings ?? [])
|
|
204
|
+
.filter((binding) => binding.action !== "delete")
|
|
205
|
+
.map((binding) => ({ data: { mounts: binding.data?.mounts ?? [] } })));
|
|
206
|
+
/** What an E2B sandbox's kernel offers mount clients (checked live: `/dev/fuse`, nfs/nfs4, CAP_SYS_ADMIN). */
|
|
207
|
+
const E2B_MOUNT_SUPPORT = { fuse: true, nfs: true };
|
|
208
|
+
const boundEnv = (bindings) => (bindings ?? [])
|
|
209
|
+
.filter((binding) => binding.action !== "delete")
|
|
210
|
+
.reduce((env, binding) => ({ ...env, ...binding.data?.env }), {});
|
|
211
|
+
/**
|
|
212
|
+
* Plans a template's build: its Dockerfile or program lowered through
|
|
213
|
+
* `BuildPlan`, then its own E2B steps.
|
|
214
|
+
*/
|
|
215
|
+
const planOf = Effect.fn(function* (name, news, bindings) {
|
|
216
|
+
const { main, handler, port, build, env, dockerfile, context, image, ...steps } = news;
|
|
217
|
+
const programPort = port ?? DEFAULT_PORT;
|
|
218
|
+
const { args, ...bundle } = build ?? {};
|
|
219
|
+
let lowered;
|
|
220
|
+
const capabilities = boundCapabilities(bindings);
|
|
221
|
+
const unsupported = checkMountSupport("E2B.Template", capabilities, E2B_MOUNT_SUPPORT);
|
|
222
|
+
if (unsupported !== undefined)
|
|
223
|
+
return yield* unsupported;
|
|
224
|
+
if (main !== undefined) {
|
|
225
|
+
// The program, on `image` / `dockerfile` as its environment.
|
|
226
|
+
lowered = yield* planSource({
|
|
227
|
+
main,
|
|
228
|
+
...(handler !== undefined ? { handler } : {}),
|
|
229
|
+
...(image !== undefined ? { image } : {}),
|
|
230
|
+
...(dockerfile !== undefined ? { dockerfile } : {}),
|
|
231
|
+
...(context !== undefined ? { context } : {}),
|
|
232
|
+
build: bundle,
|
|
233
|
+
}, {
|
|
234
|
+
port: programPort,
|
|
235
|
+
...(args !== undefined ? { args } : {}),
|
|
236
|
+
install: mountInstallLines(capabilities),
|
|
237
|
+
...(news.isExternal
|
|
238
|
+
? {}
|
|
239
|
+
: { bootstrap: makeBootstrap(handler ?? "default") }),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
else if (dockerfile !== undefined || context !== undefined) {
|
|
243
|
+
if (image !== undefined) {
|
|
244
|
+
return yield* new E2BUnexpectedResponse({
|
|
245
|
+
message: `template ${name}: set one of image or dockerfile`,
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
lowered = yield* planSource({
|
|
249
|
+
...(dockerfile !== undefined ? { dockerfile } : {}),
|
|
250
|
+
...(context !== undefined ? { context } : {}),
|
|
251
|
+
...(args !== undefined ? { build: { args } } : {}),
|
|
252
|
+
}, args !== undefined ? { args } : {});
|
|
253
|
+
}
|
|
254
|
+
const spec = {
|
|
255
|
+
...steps,
|
|
256
|
+
...(lowered === undefined && image !== undefined ? { image } : {}),
|
|
257
|
+
name,
|
|
258
|
+
env: main === undefined
|
|
259
|
+
? yield* plainEnv(env)
|
|
260
|
+
: yield* programEnv(programPort, { ...mountEnv(capabilities), ...boundEnv(bindings) }, env),
|
|
261
|
+
...(main !== undefined ? { readyCmd: steps.readyCmd ?? programReadyCmd(programPort) } : {}),
|
|
262
|
+
};
|
|
263
|
+
return { spec, plan: yield* planTemplateBuild(spec, lowered) };
|
|
264
|
+
});
|
|
265
|
+
/** `env` for a template without a program: plain values only. */
|
|
266
|
+
const plainEnv = (env) => Effect.succeed(env === undefined
|
|
267
|
+
? undefined
|
|
268
|
+
: Object.fromEntries(Object.entries(env).flatMap(([key, value]) => Redacted.isRedacted(value)
|
|
269
|
+
? [[key, String(Redacted.value(value))]]
|
|
270
|
+
: typeof value === "string" || typeof value === "number" || typeof value === "boolean"
|
|
271
|
+
? [[key, String(value)]]
|
|
272
|
+
: [])));
|
|
273
|
+
export const TemplateProvider = () => Provider.effect(Template, Effect.gen(function* () {
|
|
274
|
+
return {
|
|
275
|
+
stables: ["templateId", "name"],
|
|
276
|
+
diff: Effect.fn(function* ({ id, olds, news, output }) {
|
|
277
|
+
if (!isResolved(news))
|
|
278
|
+
return undefined;
|
|
279
|
+
const name = output?.name ?? (yield* e2bName(id, olds?.name));
|
|
280
|
+
if (news.name !== undefined && news.name !== name)
|
|
281
|
+
return { action: "replace" };
|
|
282
|
+
if (output === undefined)
|
|
283
|
+
return undefined;
|
|
284
|
+
// The plan hash reads the build context, so a changed file under an
|
|
285
|
+
// unchanged `context` path still rebuilds.
|
|
286
|
+
// Bindings may be unresolved here; the engine reconciles when they
|
|
287
|
+
// change. Diff compares the hash of everything else.
|
|
288
|
+
const { plan } = yield* planOf(name, news, undefined);
|
|
289
|
+
if (plan.hash !== output.sourceHash || news.force)
|
|
290
|
+
return { action: "update" };
|
|
291
|
+
if ((news.public ?? false) !== output.public)
|
|
292
|
+
return { action: "update" };
|
|
293
|
+
return undefined;
|
|
294
|
+
}),
|
|
295
|
+
lookup: Effect.fn(function* ({ name }) {
|
|
296
|
+
// E2B's public defaults (`base`, `code-interpreter-v1`, …) can't be
|
|
297
|
+
// read by alias (403 "You don't have access to this template
|
|
298
|
+
// alias"); they are listed instead.
|
|
299
|
+
const defaults = yield* templates.listDefaultTemplates({});
|
|
300
|
+
const template = defaults.find((candidate) => candidate.aliases.includes(name) ||
|
|
301
|
+
candidate.names.some((full) => full === name || full.split(":")[0] === name)) ?? (yield* observeTemplate(undefined, name));
|
|
302
|
+
if (template === undefined)
|
|
303
|
+
return undefined;
|
|
304
|
+
return {
|
|
305
|
+
templateId: template.templateID,
|
|
306
|
+
name,
|
|
307
|
+
buildId: template.buildID,
|
|
308
|
+
buildHash: "",
|
|
309
|
+
sourceHash: "",
|
|
310
|
+
names: [...template.names],
|
|
311
|
+
public: template.public,
|
|
312
|
+
cpuCount: template.cpuCount,
|
|
313
|
+
memoryMB: template.memoryMB,
|
|
314
|
+
mounts: [],
|
|
315
|
+
};
|
|
316
|
+
}),
|
|
317
|
+
read: Effect.fn(function* ({ id, olds, output }) {
|
|
318
|
+
const name = output?.name ?? (yield* e2bName(id, olds?.name));
|
|
319
|
+
const template = yield* observeTemplate(output?.templateId, name);
|
|
320
|
+
if (template === undefined)
|
|
321
|
+
return undefined;
|
|
322
|
+
const attrs = {
|
|
323
|
+
templateId: template.templateID,
|
|
324
|
+
name,
|
|
325
|
+
buildId: template.buildID,
|
|
326
|
+
buildHash: output?.buildHash ?? "",
|
|
327
|
+
sourceHash: output?.sourceHash ?? "",
|
|
328
|
+
names: [...template.names],
|
|
329
|
+
public: template.public,
|
|
330
|
+
cpuCount: template.cpuCount,
|
|
331
|
+
memoryMB: template.memoryMB,
|
|
332
|
+
mounts: output?.mounts ?? [],
|
|
333
|
+
};
|
|
334
|
+
return output !== undefined || olds?.name === undefined ? attrs : Unowned(attrs);
|
|
335
|
+
}),
|
|
336
|
+
reconcile: Effect.fn(function* ({ id, news, output, bindings, session }) {
|
|
337
|
+
const name = output?.name ?? (yield* e2bName(id, news.name));
|
|
338
|
+
const { spec, plan } = yield* planOf(name, news, bindings);
|
|
339
|
+
// Observe
|
|
340
|
+
const observed = yield* observeTemplate(output?.templateId, name);
|
|
341
|
+
const sourceHash = bindings === undefined || bindings.length === 0
|
|
342
|
+
? plan.hash
|
|
343
|
+
: (yield* planOf(name, news, undefined)).plan.hash;
|
|
344
|
+
// Ensure — build when there is no ready build of these exact inputs.
|
|
345
|
+
let attrs;
|
|
346
|
+
const upToDate = observed !== undefined &&
|
|
347
|
+
observed.buildStatus === "ready" &&
|
|
348
|
+
output?.buildHash === plan.hash &&
|
|
349
|
+
!news.force;
|
|
350
|
+
if (upToDate) {
|
|
351
|
+
attrs = {
|
|
352
|
+
templateId: observed.templateID,
|
|
353
|
+
name,
|
|
354
|
+
buildId: observed.buildID,
|
|
355
|
+
buildHash: plan.hash,
|
|
356
|
+
sourceHash,
|
|
357
|
+
names: [...observed.names],
|
|
358
|
+
public: observed.public,
|
|
359
|
+
cpuCount: observed.cpuCount,
|
|
360
|
+
memoryMB: observed.memoryMB,
|
|
361
|
+
mounts: boundMounts(bindings),
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
yield* session.note(`Building template ${name}...`);
|
|
366
|
+
const built = yield* runTemplateBuild(spec, plan);
|
|
367
|
+
attrs = {
|
|
368
|
+
templateId: built.templateId,
|
|
369
|
+
name,
|
|
370
|
+
buildId: built.buildId,
|
|
371
|
+
buildHash: plan.hash,
|
|
372
|
+
sourceHash,
|
|
373
|
+
names: [...built.names],
|
|
374
|
+
public: built.public,
|
|
375
|
+
cpuCount: news.cpuCount,
|
|
376
|
+
memoryMB: news.memoryMB,
|
|
377
|
+
mounts: boundMounts(bindings),
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
// Sync — visibility.
|
|
381
|
+
const desiredPublic = news.public ?? false;
|
|
382
|
+
if (attrs.public !== desiredPublic) {
|
|
383
|
+
yield* templates.updateTemplate({
|
|
384
|
+
templateID: attrs.templateId,
|
|
385
|
+
public: desiredPublic,
|
|
386
|
+
});
|
|
387
|
+
attrs = { ...attrs, public: desiredPublic };
|
|
388
|
+
}
|
|
389
|
+
return attrs;
|
|
390
|
+
}),
|
|
391
|
+
delete: Effect.fn(function* ({ output }) {
|
|
392
|
+
// E2B refuses while sandboxes run on the template. A declared
|
|
393
|
+
// sandbox is deleted first, so retry a while; sandboxes created at
|
|
394
|
+
// run time are not deleted with the stack and keep failing it
|
|
395
|
+
// until they are killed or time out.
|
|
396
|
+
yield* templates.deleteTemplate({ templateID: output.templateId }).pipe(Effect.retry({
|
|
397
|
+
while: (error) => error._tag === "TemplateInUse",
|
|
398
|
+
schedule: Schedule.spaced("3 seconds"),
|
|
399
|
+
times: 10,
|
|
400
|
+
}), Effect.catchTag("NotFound", () => Effect.void));
|
|
401
|
+
}),
|
|
402
|
+
list: Effect.fn(function* () {
|
|
403
|
+
const all = Array.from(yield* Stream.runCollect(templates.listTemplates.items({ limit: 100 })));
|
|
404
|
+
return all
|
|
405
|
+
.filter((template) => template.aliases.some(isGeneratedName))
|
|
406
|
+
.map((template) => ({
|
|
407
|
+
templateId: template.templateID,
|
|
408
|
+
name: template.aliases.find(isGeneratedName) ?? template.templateID,
|
|
409
|
+
buildId: template.buildID,
|
|
410
|
+
buildHash: "",
|
|
411
|
+
sourceHash: "",
|
|
412
|
+
names: [...template.names],
|
|
413
|
+
public: template.public,
|
|
414
|
+
cpuCount: template.cpuCount,
|
|
415
|
+
memoryMB: template.memoryMB,
|
|
416
|
+
mounts: [],
|
|
417
|
+
}));
|
|
418
|
+
}),
|
|
419
|
+
};
|
|
420
|
+
}));
|
|
421
|
+
//# sourceMappingURL=Template.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Template.js","sources":["../src/Template.ts"],"names":[],"mappings":"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"}
|
package/lib/Volume.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import * as volumes from "@distilled.cloud/e2b/volumes";
|
|
2
|
+
import * as Provider from "alchemy/Provider";
|
|
3
|
+
import { Resource } from "alchemy/Resource";
|
|
4
|
+
import type { Providers } from "./Providers.ts";
|
|
5
|
+
export interface VolumeProps {
|
|
6
|
+
/**
|
|
7
|
+
* Volume name, unique within the team. Letters, digits, `-` and `_`. If
|
|
8
|
+
* omitted, a unique name is generated from the stack, stage and logical ID.
|
|
9
|
+
* Changing it replaces the volume, and its files are lost.
|
|
10
|
+
*/
|
|
11
|
+
name?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface VolumeAttributes {
|
|
14
|
+
/** E2B's volume id. */
|
|
15
|
+
volumeId: string;
|
|
16
|
+
/** The volume's name. Sandboxes mount a volume by name. */
|
|
17
|
+
name: string;
|
|
18
|
+
}
|
|
19
|
+
export interface Volume extends Resource<"E2B.Volume", VolumeProps, VolumeAttributes, never, Providers, {
|
|
20
|
+
name: string;
|
|
21
|
+
}> {
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A persistent E2B volume: a team-wide filesystem that sandboxes mount at a
|
|
25
|
+
* path and that outlives every sandbox using it.
|
|
26
|
+
*
|
|
27
|
+
* Declare a volume when every sandbox shares it (a package cache, a
|
|
28
|
+
* dataset). Per-user and per-session volumes are created at runtime by name
|
|
29
|
+
* with `E2B.CreateVolume()`, and both kinds mount the same way.
|
|
30
|
+
*
|
|
31
|
+
* E2B volumes carry no labels, so Alchemy recognises its volumes by their
|
|
32
|
+
* generated name. A volume found under an explicit name without prior state
|
|
33
|
+
* is reported as unowned and is only adopted with `--adopt`.
|
|
34
|
+
*
|
|
35
|
+
* E2B enables volumes per team; on a team without them, a deploy fails
|
|
36
|
+
* with `VolumesNotEnabled`.
|
|
37
|
+
*
|
|
38
|
+
* ### Creating a Volume
|
|
39
|
+
* **Example:** A shared cache volume
|
|
40
|
+
* ```typescript
|
|
41
|
+
* export const Cache = E2B.Volume("Cache", {});
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* **Example:** A volume with a fixed name
|
|
45
|
+
* ```typescript
|
|
46
|
+
* export const Datasets = E2B.Volume("Datasets", { name: "datasets" });
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* ### Mounting a Volume
|
|
50
|
+
* **Example:** Mount it into a declared sandbox
|
|
51
|
+
* ```typescript
|
|
52
|
+
* export const Builder = E2B.Sandbox("Builder", {
|
|
53
|
+
* template: Agent,
|
|
54
|
+
* mounts: [{ volume: Cache, path: "/cache" }],
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* **Example:** Mount it into the sandboxes a Worker creates
|
|
59
|
+
* ```typescript
|
|
60
|
+
* const cache = yield* E2B.MountVolume(Cache, { path: "/cache" });
|
|
61
|
+
* const sandboxes = yield* E2B.CreateSandbox(Agent);
|
|
62
|
+
* // in fetch:
|
|
63
|
+
* const sandbox = yield* sandboxes.create({ mounts: [cache] });
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* ### Reading files from outside a sandbox
|
|
67
|
+
* **Example:** Read a report the sandbox wrote
|
|
68
|
+
* ```typescript
|
|
69
|
+
* const reports = yield* E2B.ReadVolume(Reports);
|
|
70
|
+
* const report = yield* reports.readFile("/report.json");
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* ### Referencing a volume the stack doesn't manage
|
|
74
|
+
* `E2B.Volume.lookup` finds an existing volume by name. Nothing is created,
|
|
75
|
+
* adopted or deleted.
|
|
76
|
+
*
|
|
77
|
+
* **Example:** Look one up by name
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const datasets = E2B.Volume.lookup({ name: "datasets" });
|
|
80
|
+
* const files = yield* E2B.ReadVolume(datasets);
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @resource
|
|
84
|
+
* @product Volume
|
|
85
|
+
*/
|
|
86
|
+
export declare const Volume: import("alchemy/Resource").ResourceClass<Volume>;
|
|
87
|
+
export declare const VolumeProvider: () => import("effect/Layer").Layer<Provider.Provider<Volume>, never, import("alchemy/Stack").Stack | import("alchemy/Stage").Stage | volumes.E2BOpContext>;
|
|
88
|
+
//# sourceMappingURL=Volume.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Volume.d.ts","sources":["../src/Volume.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,8BAA8B,CAAC;AAGxD,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAI5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,MAAO,SAAQ,QAAQ,CACtC,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,KAAK,EACL,SAAS,EACT;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CACjB;CAAG;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,eAAO,MAAM,MAAM,kDAAiC,CAAC;AAmBrD,eAAO,MAAM,cAAc,4JAuDxB,CAAC"}
|
package/lib/Volume.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import * as volumes from "@distilled.cloud/e2b/volumes";
|
|
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 Effect from "effect/Effect";
|
|
7
|
+
import { E2BUnexpectedResponse } from "./Errors.js";
|
|
8
|
+
import { e2bName, isGeneratedName } from "./internal/Ownership.js";
|
|
9
|
+
/**
|
|
10
|
+
* A persistent E2B volume: a team-wide filesystem that sandboxes mount at a
|
|
11
|
+
* path and that outlives every sandbox using it.
|
|
12
|
+
*
|
|
13
|
+
* Declare a volume when every sandbox shares it (a package cache, a
|
|
14
|
+
* dataset). Per-user and per-session volumes are created at runtime by name
|
|
15
|
+
* with `E2B.CreateVolume()`, and both kinds mount the same way.
|
|
16
|
+
*
|
|
17
|
+
* E2B volumes carry no labels, so Alchemy recognises its volumes by their
|
|
18
|
+
* generated name. A volume found under an explicit name without prior state
|
|
19
|
+
* is reported as unowned and is only adopted with `--adopt`.
|
|
20
|
+
*
|
|
21
|
+
* E2B enables volumes per team; on a team without them, a deploy fails
|
|
22
|
+
* with `VolumesNotEnabled`.
|
|
23
|
+
*
|
|
24
|
+
* ### Creating a Volume
|
|
25
|
+
* **Example:** A shared cache volume
|
|
26
|
+
* ```typescript
|
|
27
|
+
* export const Cache = E2B.Volume("Cache", {});
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* **Example:** A volume with a fixed name
|
|
31
|
+
* ```typescript
|
|
32
|
+
* export const Datasets = E2B.Volume("Datasets", { name: "datasets" });
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* ### Mounting a Volume
|
|
36
|
+
* **Example:** Mount it into a declared sandbox
|
|
37
|
+
* ```typescript
|
|
38
|
+
* export const Builder = E2B.Sandbox("Builder", {
|
|
39
|
+
* template: Agent,
|
|
40
|
+
* mounts: [{ volume: Cache, path: "/cache" }],
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* **Example:** Mount it into the sandboxes a Worker creates
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const cache = yield* E2B.MountVolume(Cache, { path: "/cache" });
|
|
47
|
+
* const sandboxes = yield* E2B.CreateSandbox(Agent);
|
|
48
|
+
* // in fetch:
|
|
49
|
+
* const sandbox = yield* sandboxes.create({ mounts: [cache] });
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* ### Reading files from outside a sandbox
|
|
53
|
+
* **Example:** Read a report the sandbox wrote
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const reports = yield* E2B.ReadVolume(Reports);
|
|
56
|
+
* const report = yield* reports.readFile("/report.json");
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* ### Referencing a volume the stack doesn't manage
|
|
60
|
+
* `E2B.Volume.lookup` finds an existing volume by name. Nothing is created,
|
|
61
|
+
* adopted or deleted.
|
|
62
|
+
*
|
|
63
|
+
* **Example:** Look one up by name
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const datasets = E2B.Volume.lookup({ name: "datasets" });
|
|
66
|
+
* const files = yield* E2B.ReadVolume(datasets);
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @resource
|
|
70
|
+
* @product Volume
|
|
71
|
+
*/
|
|
72
|
+
export const Volume = Resource("E2B.Volume");
|
|
73
|
+
const toAttrs = (volume) => ({
|
|
74
|
+
volumeId: volume.volumeID,
|
|
75
|
+
name: volume.name,
|
|
76
|
+
});
|
|
77
|
+
/** The volume with this name, if any. E2B lists a team's volumes in one page. */
|
|
78
|
+
const findByName = (name) => volumes.listVolumes({}).pipe(Effect.map((all) => all.find((volume) => volume.name === name)));
|
|
79
|
+
const observe = (volumeId, name) => volumeId !== undefined
|
|
80
|
+
? volumes.getVolume({ volumeID: volumeId }).pipe(Effect.map((volume) => volume), Effect.catchTag("NotFound", () => findByName(name)))
|
|
81
|
+
: findByName(name);
|
|
82
|
+
export const VolumeProvider = () => Provider.effect(Volume, Effect.gen(function* () {
|
|
83
|
+
return {
|
|
84
|
+
stables: ["volumeId", "name"],
|
|
85
|
+
diff: Effect.fn(function* ({ id, olds, news, output }) {
|
|
86
|
+
if (!isResolved(news))
|
|
87
|
+
return undefined;
|
|
88
|
+
// Only an explicit name can force a rename; a generated name is
|
|
89
|
+
// engine-owned and never compared against a fresh computation.
|
|
90
|
+
if (news.name === undefined && olds?.name === undefined)
|
|
91
|
+
return undefined;
|
|
92
|
+
const name = output?.name ?? (yield* e2bName(id, olds?.name));
|
|
93
|
+
if (news.name !== name)
|
|
94
|
+
return { action: "replace" };
|
|
95
|
+
return undefined;
|
|
96
|
+
}),
|
|
97
|
+
lookup: Effect.fn(function* ({ name }) {
|
|
98
|
+
const volume = yield* observe(undefined, name);
|
|
99
|
+
return volume === undefined ? undefined : toAttrs(volume);
|
|
100
|
+
}),
|
|
101
|
+
read: Effect.fn(function* ({ id, olds, output }) {
|
|
102
|
+
const name = output?.name ?? (yield* e2bName(id, olds?.name));
|
|
103
|
+
const volume = yield* observe(output?.volumeId, name);
|
|
104
|
+
if (volume === undefined)
|
|
105
|
+
return undefined;
|
|
106
|
+
const attrs = toAttrs(volume);
|
|
107
|
+
return output !== undefined || olds?.name === undefined ? attrs : Unowned(attrs);
|
|
108
|
+
}),
|
|
109
|
+
reconcile: Effect.fn(function* ({ id, news, output, session }) {
|
|
110
|
+
const name = output?.name ?? (yield* e2bName(id, news.name));
|
|
111
|
+
// Observe
|
|
112
|
+
const observed = yield* observe(output?.volumeId, name);
|
|
113
|
+
if (observed !== undefined)
|
|
114
|
+
return toAttrs(observed);
|
|
115
|
+
// Ensure — a Conflict is a peer creating the same name: read it back.
|
|
116
|
+
yield* session.note(`Creating volume ${name}...`);
|
|
117
|
+
const created = yield* volumes.createVolume({ name }).pipe(Effect.map((volume) => volume), Effect.catchTag("Conflict", () => findByName(name)));
|
|
118
|
+
if (created === undefined) {
|
|
119
|
+
return yield* new E2BUnexpectedResponse({
|
|
120
|
+
message: `E2B volume ${name} vanished after create`,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return toAttrs(created);
|
|
124
|
+
}),
|
|
125
|
+
delete: Effect.fn(function* ({ output }) {
|
|
126
|
+
yield* volumes
|
|
127
|
+
.deleteVolume({ volumeID: output.volumeId })
|
|
128
|
+
.pipe(Effect.catchTag("NotFound", () => Effect.void));
|
|
129
|
+
}),
|
|
130
|
+
list: Effect.fn(function* () {
|
|
131
|
+
const all = yield* volumes.listVolumes({});
|
|
132
|
+
return all.filter((volume) => isGeneratedName(volume.name)).map(toAttrs);
|
|
133
|
+
}),
|
|
134
|
+
};
|
|
135
|
+
}));
|
|
136
|
+
//# sourceMappingURL=Volume.js.map
|