@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.
Files changed (284) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +56 -4
  3. package/lib/ApiKey.d.ts +53 -0
  4. package/lib/ApiKey.d.ts.map +1 -0
  5. package/lib/ApiKey.js +107 -0
  6. package/lib/ApiKey.js.map +1 -0
  7. package/lib/AuthProvider.d.ts +60 -0
  8. package/lib/AuthProvider.d.ts.map +1 -0
  9. package/lib/AuthProvider.js +293 -0
  10. package/lib/AuthProvider.js.map +1 -0
  11. package/lib/Bootstrap.d.ts +7 -0
  12. package/lib/Bootstrap.d.ts.map +1 -0
  13. package/lib/Bootstrap.js +25 -0
  14. package/lib/Bootstrap.js.map +1 -0
  15. package/lib/ConnectSandbox.d.ts +67 -0
  16. package/lib/ConnectSandbox.d.ts.map +1 -0
  17. package/lib/ConnectSandbox.js +3 -0
  18. package/lib/ConnectSandbox.js.map +1 -0
  19. package/lib/ConnectSandboxHttp.d.ts +22 -0
  20. package/lib/ConnectSandboxHttp.d.ts.map +1 -0
  21. package/lib/ConnectSandboxHttp.js +30 -0
  22. package/lib/ConnectSandboxHttp.js.map +1 -0
  23. package/lib/Contributions.d.ts +7 -0
  24. package/lib/Contributions.d.ts.map +1 -0
  25. package/lib/Contributions.js +6 -0
  26. package/lib/Contributions.js.map +1 -0
  27. package/lib/CreateSandbox.d.ts +139 -0
  28. package/lib/CreateSandbox.d.ts.map +1 -0
  29. package/lib/CreateSandbox.js +3 -0
  30. package/lib/CreateSandbox.js.map +1 -0
  31. package/lib/CreateSandboxHttp.d.ts +22 -0
  32. package/lib/CreateSandboxHttp.d.ts.map +1 -0
  33. package/lib/CreateSandboxHttp.js +99 -0
  34. package/lib/CreateSandboxHttp.js.map +1 -0
  35. package/lib/CreateSecret.d.ts +57 -0
  36. package/lib/CreateSecret.d.ts.map +1 -0
  37. package/lib/CreateSecret.js +3 -0
  38. package/lib/CreateSecret.js.map +1 -0
  39. package/lib/CreateSecretHttp.d.ts +20 -0
  40. package/lib/CreateSecretHttp.d.ts.map +1 -0
  41. package/lib/CreateSecretHttp.js +64 -0
  42. package/lib/CreateSecretHttp.js.map +1 -0
  43. package/lib/CreateSnapshot.d.ts +53 -0
  44. package/lib/CreateSnapshot.d.ts.map +1 -0
  45. package/lib/CreateSnapshot.js +3 -0
  46. package/lib/CreateSnapshot.js.map +1 -0
  47. package/lib/CreateSnapshotHttp.d.ts +20 -0
  48. package/lib/CreateSnapshotHttp.d.ts.map +1 -0
  49. package/lib/CreateSnapshotHttp.js +41 -0
  50. package/lib/CreateSnapshotHttp.js.map +1 -0
  51. package/lib/CreateTemplate.d.ts +96 -0
  52. package/lib/CreateTemplate.d.ts.map +1 -0
  53. package/lib/CreateTemplate.js +3 -0
  54. package/lib/CreateTemplate.js.map +1 -0
  55. package/lib/CreateTemplateHttp.d.ts +20 -0
  56. package/lib/CreateTemplateHttp.d.ts.map +1 -0
  57. package/lib/CreateTemplateHttp.js +99 -0
  58. package/lib/CreateTemplateHttp.js.map +1 -0
  59. package/lib/CreateVolume.d.ts +58 -0
  60. package/lib/CreateVolume.d.ts.map +1 -0
  61. package/lib/CreateVolume.js +3 -0
  62. package/lib/CreateVolume.js.map +1 -0
  63. package/lib/CreateVolumeHttp.d.ts +20 -0
  64. package/lib/CreateVolumeHttp.d.ts.map +1 -0
  65. package/lib/CreateVolumeHttp.js +51 -0
  66. package/lib/CreateVolumeHttp.js.map +1 -0
  67. package/lib/Credentials.d.ts +18 -0
  68. package/lib/Credentials.d.ts.map +1 -0
  69. package/lib/Credentials.js +55 -0
  70. package/lib/Credentials.js.map +1 -0
  71. package/lib/E2BBindings.d.ts +35 -0
  72. package/lib/E2BBindings.d.ts.map +1 -0
  73. package/lib/E2BBindings.js +127 -0
  74. package/lib/E2BBindings.js.map +1 -0
  75. package/lib/Errors.d.ts +61 -0
  76. package/lib/Errors.d.ts.map +1 -0
  77. package/lib/Errors.js +23 -0
  78. package/lib/Errors.js.map +1 -0
  79. package/lib/InferEnv.d.ts +26 -0
  80. package/lib/InferEnv.d.ts.map +1 -0
  81. package/lib/InferEnv.js +1 -0
  82. package/lib/InferEnv.js.map +1 -0
  83. package/lib/MountVolume.d.ts +86 -0
  84. package/lib/MountVolume.d.ts.map +1 -0
  85. package/lib/MountVolume.js +3 -0
  86. package/lib/MountVolume.js.map +1 -0
  87. package/lib/MountVolumeLive.d.ts +23 -0
  88. package/lib/MountVolumeLive.d.ts.map +1 -0
  89. package/lib/MountVolumeLive.js +41 -0
  90. package/lib/MountVolumeLive.js.map +1 -0
  91. package/lib/Providers.d.ts +14 -0
  92. package/lib/Providers.d.ts.map +1 -0
  93. package/lib/Providers.js +23 -0
  94. package/lib/Providers.js.map +1 -0
  95. package/lib/ReadTeam.d.ts +41 -0
  96. package/lib/ReadTeam.d.ts.map +1 -0
  97. package/lib/ReadTeam.js +3 -0
  98. package/lib/ReadTeam.js.map +1 -0
  99. package/lib/ReadTeamHttp.d.ts +20 -0
  100. package/lib/ReadTeamHttp.d.ts.map +1 -0
  101. package/lib/ReadTeamHttp.js +40 -0
  102. package/lib/ReadTeamHttp.js.map +1 -0
  103. package/lib/ReadVolume.d.ts +25 -0
  104. package/lib/ReadVolume.d.ts.map +1 -0
  105. package/lib/ReadVolume.js +3 -0
  106. package/lib/ReadVolume.js.map +1 -0
  107. package/lib/ReadVolumeHttp.d.ts +20 -0
  108. package/lib/ReadVolumeHttp.d.ts.map +1 -0
  109. package/lib/ReadVolumeHttp.js +27 -0
  110. package/lib/ReadVolumeHttp.js.map +1 -0
  111. package/lib/ReadWebhook.d.ts +32 -0
  112. package/lib/ReadWebhook.d.ts.map +1 -0
  113. package/lib/ReadWebhook.js +3 -0
  114. package/lib/ReadWebhook.js.map +1 -0
  115. package/lib/ReadWebhookHttp.d.ts +20 -0
  116. package/lib/ReadWebhookHttp.d.ts.map +1 -0
  117. package/lib/ReadWebhookHttp.js +31 -0
  118. package/lib/ReadWebhookHttp.js.map +1 -0
  119. package/lib/ReadWriteVolume.d.ts +26 -0
  120. package/lib/ReadWriteVolume.d.ts.map +1 -0
  121. package/lib/ReadWriteVolume.js +3 -0
  122. package/lib/ReadWriteVolume.js.map +1 -0
  123. package/lib/ReadWriteVolumeHttp.d.ts +20 -0
  124. package/lib/ReadWriteVolumeHttp.d.ts.map +1 -0
  125. package/lib/ReadWriteVolumeHttp.js +27 -0
  126. package/lib/ReadWriteVolumeHttp.js.map +1 -0
  127. package/lib/Sandbox.d.ts +295 -0
  128. package/lib/Sandbox.d.ts.map +1 -0
  129. package/lib/Sandbox.js +351 -0
  130. package/lib/Sandbox.js.map +1 -0
  131. package/lib/SandboxClient.d.ts +226 -0
  132. package/lib/SandboxClient.d.ts.map +1 -0
  133. package/lib/SandboxClient.js +1 -0
  134. package/lib/SandboxClient.js.map +1 -0
  135. package/lib/SandboxEvents.d.ts +87 -0
  136. package/lib/SandboxEvents.d.ts.map +1 -0
  137. package/lib/SandboxEvents.js +39 -0
  138. package/lib/SandboxEvents.js.map +1 -0
  139. package/lib/SandboxEventsLive.d.ts +13 -0
  140. package/lib/SandboxEventsLive.d.ts.map +1 -0
  141. package/lib/SandboxEventsLive.js +80 -0
  142. package/lib/SandboxEventsLive.js.map +1 -0
  143. package/lib/Secret.d.ts +105 -0
  144. package/lib/Secret.d.ts.map +1 -0
  145. package/lib/Secret.js +161 -0
  146. package/lib/Secret.js.map +1 -0
  147. package/lib/Snapshot.d.ts +118 -0
  148. package/lib/Snapshot.d.ts.map +1 -0
  149. package/lib/Snapshot.js +158 -0
  150. package/lib/Snapshot.js.map +1 -0
  151. package/lib/Template.d.ts +313 -0
  152. package/lib/Template.d.ts.map +1 -0
  153. package/lib/Template.js +421 -0
  154. package/lib/Template.js.map +1 -0
  155. package/lib/Volume.d.ts +88 -0
  156. package/lib/Volume.d.ts.map +1 -0
  157. package/lib/Volume.js +136 -0
  158. package/lib/Volume.js.map +1 -0
  159. package/lib/VolumeFiles.d.ts +39 -0
  160. package/lib/VolumeFiles.d.ts.map +1 -0
  161. package/lib/VolumeFiles.js +1 -0
  162. package/lib/VolumeFiles.js.map +1 -0
  163. package/lib/Webhook.d.ts +83 -0
  164. package/lib/Webhook.d.ts.map +1 -0
  165. package/lib/Webhook.js +138 -0
  166. package/lib/Webhook.js.map +1 -0
  167. package/lib/WriteSecret.d.ts +34 -0
  168. package/lib/WriteSecret.d.ts.map +1 -0
  169. package/lib/WriteSecret.js +3 -0
  170. package/lib/WriteSecret.js.map +1 -0
  171. package/lib/WriteSecretHttp.d.ts +20 -0
  172. package/lib/WriteSecretHttp.d.ts.map +1 -0
  173. package/lib/WriteSecretHttp.js +37 -0
  174. package/lib/WriteSecretHttp.js.map +1 -0
  175. package/lib/WriteVolume.d.ts +25 -0
  176. package/lib/WriteVolume.d.ts.map +1 -0
  177. package/lib/WriteVolume.js +3 -0
  178. package/lib/WriteVolume.js.map +1 -0
  179. package/lib/WriteVolumeHttp.d.ts +20 -0
  180. package/lib/WriteVolumeHttp.d.ts.map +1 -0
  181. package/lib/WriteVolumeHttp.js +27 -0
  182. package/lib/WriteVolumeHttp.js.map +1 -0
  183. package/lib/index.d.ts +43 -0
  184. package/lib/index.d.ts.map +1 -0
  185. package/lib/index.js +43 -0
  186. package/lib/index.js.map +1 -0
  187. package/lib/internal/Declared.d.ts +29 -0
  188. package/lib/internal/Declared.d.ts.map +1 -0
  189. package/lib/internal/Declared.js +31 -0
  190. package/lib/internal/Declared.js.map +1 -0
  191. package/lib/internal/Login.d.ts +45 -0
  192. package/lib/internal/Login.d.ts.map +1 -0
  193. package/lib/internal/Login.js +157 -0
  194. package/lib/internal/Login.js.map +1 -0
  195. package/lib/internal/Ownership.d.ts +29 -0
  196. package/lib/internal/Ownership.d.ts.map +1 -0
  197. package/lib/internal/Ownership.js +49 -0
  198. package/lib/internal/Ownership.js.map +1 -0
  199. package/lib/internal/Program.d.ts +31 -0
  200. package/lib/internal/Program.d.ts.map +1 -0
  201. package/lib/internal/Program.js +60 -0
  202. package/lib/internal/Program.js.map +1 -0
  203. package/lib/internal/SandboxHandle.d.ts +25 -0
  204. package/lib/internal/SandboxHandle.d.ts.map +1 -0
  205. package/lib/internal/SandboxHandle.js +316 -0
  206. package/lib/internal/SandboxHandle.js.map +1 -0
  207. package/lib/internal/SnapshotBuild.d.ts +19 -0
  208. package/lib/internal/SnapshotBuild.d.ts.map +1 -0
  209. package/lib/internal/SnapshotBuild.js +49 -0
  210. package/lib/internal/SnapshotBuild.js.map +1 -0
  211. package/lib/internal/Tar.d.ts +10 -0
  212. package/lib/internal/Tar.d.ts.map +1 -0
  213. package/lib/internal/Tar.js +61 -0
  214. package/lib/internal/Tar.js.map +1 -0
  215. package/lib/internal/TemplateBuild.d.ts +142 -0
  216. package/lib/internal/TemplateBuild.d.ts.map +1 -0
  217. package/lib/internal/TemplateBuild.js +220 -0
  218. package/lib/internal/TemplateBuild.js.map +1 -0
  219. package/lib/internal/TemplatePlan.d.ts +57 -0
  220. package/lib/internal/TemplatePlan.d.ts.map +1 -0
  221. package/lib/internal/TemplatePlan.js +185 -0
  222. package/lib/internal/TemplatePlan.js.map +1 -0
  223. package/lib/internal/VolumeHttp.d.ts +5 -0
  224. package/lib/internal/VolumeHttp.d.ts.map +1 -0
  225. package/lib/internal/VolumeHttp.js +46 -0
  226. package/lib/internal/VolumeHttp.js.map +1 -0
  227. package/package.json +62 -3
  228. package/src/ApiKey.ts +148 -0
  229. package/src/AuthProvider.ts +437 -0
  230. package/src/Bootstrap.ts +51 -0
  231. package/src/ConnectSandbox.ts +71 -0
  232. package/src/ConnectSandboxHttp.ts +38 -0
  233. package/src/Contributions.ts +9 -0
  234. package/src/CreateSandbox.ts +157 -0
  235. package/src/CreateSandboxHttp.ts +131 -0
  236. package/src/CreateSecret.ts +65 -0
  237. package/src/CreateSecretHttp.ts +94 -0
  238. package/src/CreateSnapshot.ts +64 -0
  239. package/src/CreateSnapshotHttp.ts +55 -0
  240. package/src/CreateTemplate.ts +135 -0
  241. package/src/CreateTemplateHttp.ts +152 -0
  242. package/src/CreateVolume.ts +65 -0
  243. package/src/CreateVolumeHttp.ts +80 -0
  244. package/src/Credentials.ts +81 -0
  245. package/src/E2BBindings.ts +160 -0
  246. package/src/Errors.ts +47 -0
  247. package/src/InferEnv.ts +27 -0
  248. package/src/MountVolume.ts +92 -0
  249. package/src/MountVolumeLive.ts +49 -0
  250. package/src/Providers.ts +48 -0
  251. package/src/ReadTeam.ts +55 -0
  252. package/src/ReadTeamHttp.ts +44 -0
  253. package/src/ReadVolume.ts +29 -0
  254. package/src/ReadVolumeHttp.ts +32 -0
  255. package/src/ReadWebhook.ts +41 -0
  256. package/src/ReadWebhookHttp.ts +42 -0
  257. package/src/ReadWriteVolume.ts +30 -0
  258. package/src/ReadWriteVolumeHttp.ts +32 -0
  259. package/src/Sandbox.ts +581 -0
  260. package/src/SandboxClient.ts +268 -0
  261. package/src/SandboxEvents.ts +101 -0
  262. package/src/SandboxEventsLive.ts +118 -0
  263. package/src/Secret.ts +229 -0
  264. package/src/Snapshot.ts +234 -0
  265. package/src/Template.ts +636 -0
  266. package/src/Volume.ts +173 -0
  267. package/src/VolumeFiles.ts +53 -0
  268. package/src/Webhook.ts +215 -0
  269. package/src/WriteSecret.ts +39 -0
  270. package/src/WriteSecretHttp.ts +43 -0
  271. package/src/WriteVolume.ts +29 -0
  272. package/src/WriteVolumeHttp.ts +32 -0
  273. package/src/globals.d.ts +2 -0
  274. package/src/index.ts +42 -0
  275. package/src/internal/Declared.ts +80 -0
  276. package/src/internal/Login.ts +210 -0
  277. package/src/internal/Ownership.ts +67 -0
  278. package/src/internal/Program.ts +75 -0
  279. package/src/internal/SandboxHandle.ts +534 -0
  280. package/src/internal/SnapshotBuild.ts +74 -0
  281. package/src/internal/Tar.ts +74 -0
  282. package/src/internal/TemplateBuild.ts +383 -0
  283. package/src/internal/TemplatePlan.ts +230 -0
  284. package/src/internal/VolumeHttp.ts +88 -0
@@ -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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"}
@@ -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