@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.
Files changed (184) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +57 -4
  3. package/lib/AWS/S3Disk.d.ts +68 -0
  4. package/lib/AWS/S3Disk.d.ts.map +1 -0
  5. package/lib/AWS/S3Disk.js +100 -0
  6. package/lib/AWS/S3Disk.js.map +1 -0
  7. package/lib/AWS/index.d.ts +2 -0
  8. package/lib/AWS/index.d.ts.map +1 -0
  9. package/lib/AWS/index.js +2 -0
  10. package/lib/AWS/index.js.map +1 -0
  11. package/lib/ApiToken.d.ts +63 -0
  12. package/lib/ApiToken.d.ts.map +1 -0
  13. package/lib/ApiToken.js +121 -0
  14. package/lib/ApiToken.js.map +1 -0
  15. package/lib/ArchilBindings.d.ts +65 -0
  16. package/lib/ArchilBindings.d.ts.map +1 -0
  17. package/lib/ArchilBindings.js +128 -0
  18. package/lib/ArchilBindings.js.map +1 -0
  19. package/lib/AuthProvider.d.ts +40 -0
  20. package/lib/AuthProvider.d.ts.map +1 -0
  21. package/lib/AuthProvider.js +87 -0
  22. package/lib/AuthProvider.js.map +1 -0
  23. package/lib/Bootstrap.d.ts +8 -0
  24. package/lib/Bootstrap.d.ts.map +1 -0
  25. package/lib/Bootstrap.js +27 -0
  26. package/lib/Bootstrap.js.map +1 -0
  27. package/lib/Branch.d.ts +101 -0
  28. package/lib/Branch.d.ts.map +1 -0
  29. package/lib/Branch.js +117 -0
  30. package/lib/Branch.js.map +1 -0
  31. package/lib/BranchDisk.d.ts +42 -0
  32. package/lib/BranchDisk.d.ts.map +1 -0
  33. package/lib/BranchDisk.js +14 -0
  34. package/lib/BranchDisk.js.map +1 -0
  35. package/lib/Checkpoint.d.ts +78 -0
  36. package/lib/Checkpoint.d.ts.map +1 -0
  37. package/lib/Checkpoint.js +95 -0
  38. package/lib/Checkpoint.js.map +1 -0
  39. package/lib/Clients.d.ts +369 -0
  40. package/lib/Clients.d.ts.map +1 -0
  41. package/lib/Clients.js +334 -0
  42. package/lib/Clients.js.map +1 -0
  43. package/lib/ConnectSandbox.d.ts +69 -0
  44. package/lib/ConnectSandbox.d.ts.map +1 -0
  45. package/lib/ConnectSandbox.js +21 -0
  46. package/lib/ConnectSandbox.js.map +1 -0
  47. package/lib/Contributions.d.ts +7 -0
  48. package/lib/Contributions.d.ts.map +1 -0
  49. package/lib/Contributions.js +6 -0
  50. package/lib/Contributions.js.map +1 -0
  51. package/lib/CreateDisk.d.ts +90 -0
  52. package/lib/CreateDisk.d.ts.map +1 -0
  53. package/lib/CreateDisk.js +47 -0
  54. package/lib/CreateDisk.js.map +1 -0
  55. package/lib/CreateImage.d.ts +42 -0
  56. package/lib/CreateImage.d.ts.map +1 -0
  57. package/lib/CreateImage.js +19 -0
  58. package/lib/CreateImage.js.map +1 -0
  59. package/lib/CreateSandbox.d.ts +104 -0
  60. package/lib/CreateSandbox.d.ts.map +1 -0
  61. package/lib/CreateSandbox.js +98 -0
  62. package/lib/CreateSandbox.js.map +1 -0
  63. package/lib/Credentials.d.ts +44 -0
  64. package/lib/Credentials.d.ts.map +1 -0
  65. package/lib/Credentials.js +57 -0
  66. package/lib/Credentials.js.map +1 -0
  67. package/lib/Disk.d.ts +283 -0
  68. package/lib/Disk.d.ts.map +1 -0
  69. package/lib/Disk.js +294 -0
  70. package/lib/Disk.js.map +1 -0
  71. package/lib/DiskObjectsHttp.d.ts +20 -0
  72. package/lib/DiskObjectsHttp.d.ts.map +1 -0
  73. package/lib/DiskObjectsHttp.js +51 -0
  74. package/lib/DiskObjectsHttp.js.map +1 -0
  75. package/lib/DiskUser.d.ts +189 -0
  76. package/lib/DiskUser.d.ts.map +1 -0
  77. package/lib/DiskUser.js +243 -0
  78. package/lib/DiskUser.js.map +1 -0
  79. package/lib/ExecDisk.d.ts +57 -0
  80. package/lib/ExecDisk.d.ts.map +1 -0
  81. package/lib/ExecDisk.js +3 -0
  82. package/lib/ExecDisk.js.map +1 -0
  83. package/lib/ExecDiskHttp.d.ts +5 -0
  84. package/lib/ExecDiskHttp.d.ts.map +1 -0
  85. package/lib/ExecDiskHttp.js +18 -0
  86. package/lib/ExecDiskHttp.js.map +1 -0
  87. package/lib/ExecDisks.d.ts +54 -0
  88. package/lib/ExecDisks.d.ts.map +1 -0
  89. package/lib/ExecDisks.js +37 -0
  90. package/lib/ExecDisks.js.map +1 -0
  91. package/lib/Image.d.ts +188 -0
  92. package/lib/Image.d.ts.map +1 -0
  93. package/lib/Image.js +191 -0
  94. package/lib/Image.js.map +1 -0
  95. package/lib/InferEnv.d.ts +26 -0
  96. package/lib/InferEnv.d.ts.map +1 -0
  97. package/lib/InferEnv.js +1 -0
  98. package/lib/InferEnv.js.map +1 -0
  99. package/lib/MountDisk.d.ts +190 -0
  100. package/lib/MountDisk.d.ts.map +1 -0
  101. package/lib/MountDisk.js +227 -0
  102. package/lib/MountDisk.js.map +1 -0
  103. package/lib/Providers.d.ts +25 -0
  104. package/lib/Providers.d.ts.map +1 -0
  105. package/lib/Providers.js +48 -0
  106. package/lib/Providers.js.map +1 -0
  107. package/lib/ReadDisk.d.ts +55 -0
  108. package/lib/ReadDisk.d.ts.map +1 -0
  109. package/lib/ReadDisk.js +3 -0
  110. package/lib/ReadDisk.js.map +1 -0
  111. package/lib/ReadWriteDisk.d.ts +26 -0
  112. package/lib/ReadWriteDisk.d.ts.map +1 -0
  113. package/lib/ReadWriteDisk.js +3 -0
  114. package/lib/ReadWriteDisk.js.map +1 -0
  115. package/lib/Sandbox.d.ts +507 -0
  116. package/lib/Sandbox.d.ts.map +1 -0
  117. package/lib/Sandbox.js +729 -0
  118. package/lib/Sandbox.js.map +1 -0
  119. package/lib/SandboxOptions.d.ts +185 -0
  120. package/lib/SandboxOptions.d.ts.map +1 -0
  121. package/lib/SandboxOptions.js +102 -0
  122. package/lib/SandboxOptions.js.map +1 -0
  123. package/lib/SandboxPortToken.d.ts +64 -0
  124. package/lib/SandboxPortToken.d.ts.map +1 -0
  125. package/lib/SandboxPortToken.js +77 -0
  126. package/lib/SandboxPortToken.js.map +1 -0
  127. package/lib/WriteDisk.d.ts +37 -0
  128. package/lib/WriteDisk.d.ts.map +1 -0
  129. package/lib/WriteDisk.js +3 -0
  130. package/lib/WriteDisk.js.map +1 -0
  131. package/lib/index.d.ts +29 -0
  132. package/lib/index.d.ts.map +1 -0
  133. package/lib/index.js +28 -0
  134. package/lib/index.js.map +1 -0
  135. package/lib/internal/DeployerKey.d.ts +21 -0
  136. package/lib/internal/DeployerKey.d.ts.map +1 -0
  137. package/lib/internal/DeployerKey.js +34 -0
  138. package/lib/internal/DeployerKey.js.map +1 -0
  139. package/lib/internal/archil.d.ts +87 -0
  140. package/lib/internal/archil.d.ts.map +1 -0
  141. package/lib/internal/archil.js +154 -0
  142. package/lib/internal/archil.js.map +1 -0
  143. package/lib/internal/hosted.d.ts +90 -0
  144. package/lib/internal/hosted.d.ts.map +1 -0
  145. package/lib/internal/hosted.js +291 -0
  146. package/lib/internal/hosted.js.map +1 -0
  147. package/package.json +79 -3
  148. package/src/AWS/S3Disk.ts +125 -0
  149. package/src/AWS/index.ts +1 -0
  150. package/src/ApiToken.ts +168 -0
  151. package/src/ArchilBindings.ts +179 -0
  152. package/src/AuthProvider.ts +122 -0
  153. package/src/Bootstrap.ts +54 -0
  154. package/src/Branch.ts +199 -0
  155. package/src/BranchDisk.ts +57 -0
  156. package/src/Checkpoint.ts +145 -0
  157. package/src/Clients.ts +954 -0
  158. package/src/ConnectSandbox.ts +91 -0
  159. package/src/Contributions.ts +9 -0
  160. package/src/CreateDisk.ts +165 -0
  161. package/src/CreateImage.ts +73 -0
  162. package/src/CreateSandbox.ts +258 -0
  163. package/src/Credentials.ts +101 -0
  164. package/src/Disk.ts +468 -0
  165. package/src/DiskObjectsHttp.ts +64 -0
  166. package/src/DiskUser.ts +369 -0
  167. package/src/ExecDisk.ts +62 -0
  168. package/src/ExecDiskHttp.ts +25 -0
  169. package/src/ExecDisks.ts +100 -0
  170. package/src/Image.ts +316 -0
  171. package/src/InferEnv.ts +27 -0
  172. package/src/MountDisk.ts +466 -0
  173. package/src/Providers.ts +75 -0
  174. package/src/ReadDisk.ts +61 -0
  175. package/src/ReadWriteDisk.ts +31 -0
  176. package/src/Sandbox.ts +1064 -0
  177. package/src/SandboxOptions.ts +230 -0
  178. package/src/SandboxPortToken.ts +125 -0
  179. package/src/WriteDisk.ts +42 -0
  180. package/src/globals.d.ts +2 -0
  181. package/src/index.ts +59 -0
  182. package/src/internal/DeployerKey.ts +63 -0
  183. package/src/internal/archil.ts +273 -0
  184. package/src/internal/hosted.ts +402 -0
@@ -0,0 +1,54 @@
1
+ import * as archil from "@distilled.cloud/archil";
2
+ import * as Binding from "alchemy/Binding";
3
+ import type { RuntimeContext } from "alchemy/RuntimeContext";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Layer from "effect/Layer";
6
+ import type { ExecResult } from "./Clients.ts";
7
+ /** One disk in a multi-disk exec. */
8
+ export interface ExecDisksMount {
9
+ /** Disk id (`dsk-…`). */
10
+ disk: string;
11
+ /** Mount this subdirectory of the disk instead of its root. */
12
+ subdirectory?: string;
13
+ /** Mount without write access. */
14
+ readOnly?: boolean;
15
+ /** Write without the disk's root delegation, so other writers can mount it too. */
16
+ conditional?: boolean;
17
+ }
18
+ export interface ExecDisksClient {
19
+ /**
20
+ * Run a shell command in a fresh microVM with several disks mounted.
21
+ * Keys are paths under `/mnt/archil`; values are disk ids or mounts.
22
+ */
23
+ exec(request: {
24
+ readonly disks: Record<string, string | ExecDisksMount>;
25
+ readonly command: string;
26
+ }): Effect.Effect<ExecResult, archil.ExecError, RuntimeContext>;
27
+ }
28
+ /**
29
+ * Run one serverless command against several disks at once, e.g. read a
30
+ * shared dataset and write into a user's own disk in the same call. Disks
31
+ * are named at run time, so it works with disks created per user.
32
+ *
33
+ * ### Running Across Disks
34
+ * **Example:** Copy a dataset into a user's disk
35
+ * ```typescript
36
+ * const exec = yield* Archil.ExecDisks();
37
+ * const result = yield* exec.exec({
38
+ * disks: {
39
+ * data: { disk: datasetId, readOnly: true },
40
+ * home: userDisk.diskId,
41
+ * },
42
+ * command: "cp -r /mnt/archil/data/samples /mnt/archil/home/",
43
+ * });
44
+ * ```
45
+ *
46
+ * @binding
47
+ * @product Disk
48
+ */
49
+ export interface ExecDisks extends Binding.Service<ExecDisks, "Archil.ExecDisks", () => Effect.Effect<ExecDisksClient>> {
50
+ }
51
+ export declare const ExecDisks: ExecDisks;
52
+ /** {@link ExecDisks} over Archil's HTTP API, usable from any host. */
53
+ export declare const ExecDisksHttp: Layer.Layer<ExecDisks, never, never>;
54
+ //# sourceMappingURL=ExecDisks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExecDisks.d.ts","sources":["../src/ExecDisks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,yBAAyB,CAAC;AAClD,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAEtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC7B,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mFAAmF;IACnF,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,IAAI,CAAC,OAAO,EAAE;QACZ,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC;QACxD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;CACjE;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,SAAU,SAAQ,OAAO,CAAC,OAAO,CAChD,SAAS,EACT,kBAAkB,EAClB,MAAM,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CACrC;CAAG;AAEJ,eAAO,MAAM,SAAS,WAAiD,CAAC;AAExE,sEAAsE;AACtE,eAAO,MAAM,aAAa,sCAsCzB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import * as archil from "@distilled.cloud/archil";
2
+ import * as Binding from "alchemy/Binding";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import { ApiAccess } from "./ArchilBindings.js";
6
+ export const ExecDisks = Binding.Service("Archil.ExecDisks");
7
+ /** {@link ExecDisks} over Archil's HTTP API, usable from any host. */
8
+ export const ExecDisksHttp = Layer.effect(ExecDisks, Effect.gen(function* () {
9
+ const access = yield* ApiAccess;
10
+ return Effect.fn(function* () {
11
+ const authorize = yield* access();
12
+ return {
13
+ exec: (request) => authorize(archil
14
+ .exec({
15
+ command: request.command,
16
+ disks: Object.fromEntries(Object.entries(request.disks).map(([path, mount]) => [
17
+ path,
18
+ typeof mount === "string"
19
+ ? mount
20
+ : {
21
+ disk: mount.disk,
22
+ subdirectory: mount.subdirectory,
23
+ readOnly: mount.readOnly,
24
+ conditional: mount.conditional,
25
+ },
26
+ ])),
27
+ })
28
+ .pipe(Effect.map(({ data }) => ({
29
+ exitCode: data.exitCode,
30
+ stdout: data.stdout,
31
+ stderr: data.stderr,
32
+ timing: data.timing,
33
+ })))),
34
+ };
35
+ });
36
+ }));
37
+ //# sourceMappingURL=ExecDisks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExecDisks.js","sources":["../src/ExecDisks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,yBAAyB,CAAC;AAClD,OAAO,KAAK,OAAO,MAAM,iBAAiB,CAAC;AAE3C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAqDhD,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAY,kBAAkB,CAAC,CAAC;AAExE,sEAAsE;AACtE,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CACvC,SAAS,EACT,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC;IAChC,OAAO,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC;QACxB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO;YACL,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAChB,SAAS,CACP,MAAM;iBACH,IAAI,CAAC;gBACJ,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,KAAK,EAAE,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;oBACnD,IAAI;oBACJ,OAAO,KAAK,KAAK,QAAQ;wBACvB,CAAC,CAAC,KAAK;wBACP,CAAC,CAAC;4BACE,IAAI,EAAE,KAAK,CAAC,IAAI;4BAChB,YAAY,EAAE,KAAK,CAAC,YAAY;4BAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ;4BACxB,WAAW,EAAE,KAAK,CAAC,WAAW;yBAC/B;iBACN,CAAC,CACH;aACF,CAAC;iBACD,IAAI,CACH,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;gBACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAC,CAAC,CACJ,CACJ;SACsB,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CACH,CAAC"}
package/lib/Image.d.ts ADDED
@@ -0,0 +1,188 @@
1
+ import * as BuildPlan from "@alchemy.run/docker/BuildPlan";
2
+ import type { InlineDockerfile } from "@alchemy.run/docker/Dockerfile";
3
+ import type { DockerfileBuild } from "@alchemy.run/docker/ImageSource";
4
+ import type { ImageRegistry } from "@alchemy.run/docker/Registry";
5
+ import * as archil from "@distilled.cloud/archil";
6
+ import * as Provider from "alchemy/Provider";
7
+ import { Resource } from "alchemy/Resource";
8
+ import * as Effect from "effect/Effect";
9
+ import type { Providers } from "./Providers.ts";
10
+ export interface ImageProps {
11
+ /**
12
+ * Linux OCI image reference with a `linux/amd64` manifest, e.g.
13
+ * `ghcr.io/acme/agent:1`. Docker shorthand and tags are accepted.
14
+ * Exclusive with `dockerfile` and `context`. Changing it builds a new
15
+ * image.
16
+ */
17
+ image?: string;
18
+ /**
19
+ * A Dockerfile path (relative to the cwd) or `Dockerfile.inline` content.
20
+ * Archil has no builder of its own: Alchemy builds it with your local
21
+ * Docker and pushes it to `push.repository`, and Archil pulls it from
22
+ * there.
23
+ */
24
+ dockerfile?: string | InlineDockerfile;
25
+ /** Build context for a `dockerfile` path. */
26
+ context?: string;
27
+ /** Docker build args and BuildKit secrets for a `dockerfile` image. */
28
+ build?: DockerfileBuild;
29
+ /**
30
+ * Credentials for a private registry. Archil uses them to pull this
31
+ * image only and doesn't store them.
32
+ */
33
+ registry?: ImageRegistry;
34
+ /**
35
+ * Where a Dockerfile image is pushed for Archil to pull: a repository
36
+ * (no tag; the build's hash is the tag) and credentials that can push to
37
+ * it and pull from it. Required for `dockerfile` images.
38
+ */
39
+ push?: ImagePush;
40
+ }
41
+ /** A registry repository Alchemy pushes built images to, for Archil to pull. */
42
+ export interface ImagePush {
43
+ /** Repository without a tag, e.g. `ghcr.io/acme/agent`. */
44
+ repository: string;
45
+ /** Credentials that can push to and pull from the repository. */
46
+ credentials: ImageRegistry;
47
+ }
48
+ export interface ImageAttributes {
49
+ /** Image id (64 hex characters); pass it as a sandbox's `image`. */
50
+ imageId: string;
51
+ /** The reference the image was built from. */
52
+ source: string;
53
+ /** The fully qualified reference Archil resolved, e.g. `docker.io/library/node:24`. */
54
+ canonicalSource: string | undefined;
55
+ /** Digest of the image sandboxes boot. */
56
+ digest: string | undefined;
57
+ /** Whether the image came from a private registry. */
58
+ private: boolean;
59
+ /** Hash of the build plan the image came from. */
60
+ hash: string;
61
+ }
62
+ export type Image = Resource<"Archil.Image", ImageProps, ImageAttributes, never, Providers, ImageLookup>;
63
+ /**
64
+ * Props for {@link Image.lookup}: find an image this stack
65
+ * doesn't manage by its id.
66
+ */
67
+ export interface ImageLookup {
68
+ /** Archil image id. */
69
+ imageId: string;
70
+ }
71
+ declare const ImageRequiresBuild_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 & {
72
+ readonly _tag: "Archil.ImageRequiresBuild";
73
+ } & Readonly<A>;
74
+ /**
75
+ * The image needs instructions run on top of its base, and Archil only
76
+ * pulls finished images.
77
+ */
78
+ export declare class ImageRequiresBuild extends ImageRequiresBuild_base<{
79
+ readonly message: string;
80
+ }> {
81
+ }
82
+ /**
83
+ * A sandbox image. Archil pulls it from a public or private registry and
84
+ * sandboxes boot its current digest. Public images can also be used
85
+ * directly as a sandbox's `baseImage`; build an `Image` for a private one,
86
+ * or to pin the digest every sandbox boots.
87
+ *
88
+ * Props follow `@alchemy.run/docker`'s image source, like every Alchemy
89
+ * image resource. Archil has no builder, so a Dockerfile is built with
90
+ * your local Docker and pushed to `push.repository`, and Archil pulls it
91
+ * from there.
92
+ *
93
+ * Archil has no API to delete an image, so destroying the resource only
94
+ * removes it from Alchemy's state.
95
+ * @see https://docs.archil.com/api-reference/images/build-image
96
+ *
97
+ * ### Building an Image
98
+ * **Example:** From a public image
99
+ * ```typescript
100
+ * export const Base = Archil.Image("Base", { image: "node:24-bookworm" });
101
+ * ```
102
+ *
103
+ * **Example:** From a private registry
104
+ * ```typescript
105
+ * export const Agent = Archil.Image("Agent", {
106
+ * image: "ghcr.io/acme/agent:1",
107
+ * registry: {
108
+ * server: "ghcr.io",
109
+ * username: "acme-bot",
110
+ * password: Alchemy.Secret("GHCR_TOKEN"),
111
+ * },
112
+ * });
113
+ * ```
114
+ *
115
+ * **Example:** Build a Dockerfile and push it for Archil to pull
116
+ * ```typescript
117
+ * export const Agent = Archil.Image("Agent", {
118
+ * dockerfile: "./agent/Dockerfile",
119
+ * context: "./agent",
120
+ * push: {
121
+ * repository: "ghcr.io/acme/agent",
122
+ * credentials: { server: "ghcr.io", username: "acme-bot", password: Alchemy.Secret("GHCR_TOKEN") },
123
+ * },
124
+ * });
125
+ * ```
126
+ *
127
+ * ### Booting Sandboxes from an Image
128
+ * **Example:** Sandboxes created at run time
129
+ * ```typescript
130
+ * const sandboxes = yield* Archil.CreateSandbox(Agent);
131
+ * const sandbox = yield* sandboxes.create({ name: "task-1" });
132
+ * ```
133
+ *
134
+ * ### Looking up an existing image
135
+ * `Image.lookup` references an image Alchemy doesn't manage (created in
136
+ * the Archil console or by another stack). It is read during plan/deploy,
137
+ * never created, updated or deleted.
138
+ * `hash` is empty: the image wasn't built by this stack.
139
+ *
140
+ * **Example:** Reference an existing image
141
+ * ```typescript
142
+ * const base = Archil.Image.lookup({ imageId: "img_123" });
143
+ * ```
144
+ *
145
+ * @resource
146
+ * @product Image
147
+ */
148
+ export declare const Image: import("alchemy").ResourceClass<Image>;
149
+ /** What Archil's image service can build: nothing beyond pulling a reference. */
150
+ export declare const capabilities: BuildPlan.Capabilities;
151
+ /** Map an image response to attributes. */
152
+ export declare const toImageAttributes: (image: archil.Image, hash: string, source?: string) => ImageAttributes;
153
+ /** Plan an image source for Archil. */
154
+ export declare const planImage: (props: ImageProps) => Effect.Effect<{
155
+ hash: string;
156
+ platform: string;
157
+ dockerfile: import("@alchemy.run/docker/DockerfileParser").ParsedDockerfile;
158
+ base: string;
159
+ pull: ImageRegistry | undefined;
160
+ instructions: readonly import("@alchemy.run/docker/DockerfileParser").Instruction[];
161
+ files: BuildPlan.ContextFile[];
162
+ args: Record<string, string>;
163
+ secrets: Record<string, import("effect/Redacted").Redacted<string>>;
164
+ warnings: string[];
165
+ }, import("@alchemy.run/docker/BuildHash").BuildHashInvalidProps | BuildPlan.BuildPlanError | import("alchemy/Bundle/Bundle").BundleError | import("@alchemy.run/docker/DockerfileParser").DockerfileSyntaxError | import("effect/PlatformError").PlatformError | BuildPlan.UnsupportedDockerfile, import("effect/FileSystem").FileSystem | import("effect/Path").Path>;
166
+ /**
167
+ * The reference Archil can pull for a plan: its base, when the plan adds
168
+ * nothing on top of it.
169
+ */
170
+ export declare const pullableSource: (plan: BuildPlan.BuildPlan) => Effect.Effect<string, never, never> | Effect.Effect<never, ImageRequiresBuild, never>;
171
+ /** Ask Archil to pull a reference and wait until the image is ready. */
172
+ export declare const pullImage: (source: string, registry: ImageRegistry | undefined, hash: string) => Effect.Effect<ImageAttributes, 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.NoCapacity | archil.NotEnabled | import("@distilled.cloud/core/errors").NotFound | archil.NotFound | import("@distilled.cloud/core/sdk-error").SdkError | archil.ServiceUnavailable | archil.TooManyRequests | archil.Unauthorized | archil.UnknownArchilError | archil.UnprocessableEntity, archil.ArchilOpContext>;
173
+ /**
174
+ * The reference Archil pulls for a plan: its base when the plan adds
175
+ * nothing, else the plan built locally and pushed to `push`.
176
+ */
177
+ export declare const publishPlan: (plan: BuildPlan.BuildPlan, push: ImagePush | undefined) => Effect.Effect<{
178
+ source: string;
179
+ credentials: undefined;
180
+ } | {
181
+ source: string;
182
+ credentials: ImageRegistry;
183
+ }, ImageRequiresBuild | import("@alchemy.run/docker/RegistryError").DockerImagePublicationError, import("@alchemy.run/docker/Docker").Docker | import("effect/FileSystem").FileSystem | import("effect/Path").Path>;
184
+ /** Plan, publish, then pull, an image. */
185
+ export declare const buildImage: (props: ImageProps) => Effect.Effect<ImageAttributes, import("./index.ts").ArchilFailed | import("./index.ts").ArchilNotReady | archil.ArchilParseError | archil.BadGateway | import("@distilled.cloud/core/errors").BadRequest | archil.BadRequest | import("@alchemy.run/docker/BuildHash").BuildHashInvalidProps | BuildPlan.BuildPlanError | import("alchemy/Bundle/Bundle").BundleError | archil.ConfigError | import("@distilled.cloud/core/errors").Conflict | import("@alchemy.run/docker/DockerfileParser").DockerfileSyntaxError | import("@distilled.cloud/core/errors").Forbidden | archil.GatewayTimeout | import("effect/http/HttpClientError").HttpClientError | ImageRequiresBuild | archil.InternalServerError | import("@distilled.cloud/core/protocol-http").InvalidInput | archil.Locked | archil.NoCapacity | archil.NotEnabled | import("@distilled.cloud/core/errors").NotFound | archil.NotFound | import("@distilled.cloud/core/sdk-error").SdkError | archil.ServiceUnavailable | archil.TooManyRequests | archil.Unauthorized | archil.UnknownArchilError | archil.UnprocessableEntity | BuildPlan.UnsupportedDockerfile | import("@alchemy.run/docker/RegistryError").DockerImagePublicationError, import("@alchemy.run/docker/Docker").Docker | import("effect/FileSystem").FileSystem | import("effect/Path").Path | archil.ArchilOpContext>;
186
+ export declare const ImageProvider: () => import("effect/Layer").Layer<Provider.Provider<Image>, never, import("@alchemy.run/docker/Docker").Docker | import("effect/FileSystem").FileSystem | import("effect/Path").Path | archil.ArchilOpContext>;
187
+ export {};
188
+ //# sourceMappingURL=Image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Image.d.ts","sources":["../src/Image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,MAAM,MAAM,yBAAyB,CAAC;AAElD,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACvC,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED,gFAAgF;AAChF,MAAM,WAAW,SAAS;IACxB,2DAA2D;IAC3D,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,WAAW,EAAE,aAAa,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,uFAAuF;IACvF,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,0CAA0C;IAC1C,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,KAAK,GAAG,QAAQ,CAC1B,cAAc,EACd,UAAU,EACV,eAAe,EACf,KAAK,EACL,SAAS,EACT,WAAW,CACZ,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;CACjB;;;;AAED;;;GAGG;AACH,qBAAa,kBAAmB,SAAQ,wBAA8C;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;CAAG;AAEL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,eAAO,MAAM,KAAK,wCAAkC,CAAC;AAErD,iFAAiF;AACjF,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,YAGpC,CAAC;AAEF,2CAA2C;AAC3C,eAAO,MAAM,iBAAiB,UACrB,MAAM,CAAC,KAAK,QACb,MAAM,WACJ,MAAM,KACb,eASD,CAAC;AAEH,uCAAuC;AACvC,eAAO,MAAM,SAAS,UAAW,UAAU;;;;;;;;;;;uWAMxC,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,cAAc,SAAU,SAAS,CAAC,SAAS,0FAOjD,CAAC;AAER,wEAAwE;AACxE,eAAO,MAAM,SAAS,u5BAYpB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,WAAW;;;;;;mNAgBtB,CAAC;AAEH,0CAA0C;AAC1C,eAAO,MAAM,UAAU,4yCAIrB,CAAC;AAEH,eAAO,MAAM,aAAa,iNAiEvB,CAAC"}
package/lib/Image.js ADDED
@@ -0,0 +1,191 @@
1
+ import * as BuildPlan from "@alchemy.run/docker/BuildPlan";
2
+ import * as archil from "@distilled.cloud/archil";
3
+ import { isResolved } from "alchemy/Diff";
4
+ import * as Provider from "alchemy/Provider";
5
+ import { Resource } from "alchemy/Resource";
6
+ import * as Data from "effect/Data";
7
+ import * as Effect from "effect/Effect";
8
+ import { waitForImage } from "./internal/archil.js";
9
+ /**
10
+ * The image needs instructions run on top of its base, and Archil only
11
+ * pulls finished images.
12
+ */
13
+ export class ImageRequiresBuild extends Data.TaggedError("Archil.ImageRequiresBuild") {
14
+ }
15
+ /**
16
+ * A sandbox image. Archil pulls it from a public or private registry and
17
+ * sandboxes boot its current digest. Public images can also be used
18
+ * directly as a sandbox's `baseImage`; build an `Image` for a private one,
19
+ * or to pin the digest every sandbox boots.
20
+ *
21
+ * Props follow `@alchemy.run/docker`'s image source, like every Alchemy
22
+ * image resource. Archil has no builder, so a Dockerfile is built with
23
+ * your local Docker and pushed to `push.repository`, and Archil pulls it
24
+ * from there.
25
+ *
26
+ * Archil has no API to delete an image, so destroying the resource only
27
+ * removes it from Alchemy's state.
28
+ * @see https://docs.archil.com/api-reference/images/build-image
29
+ *
30
+ * ### Building an Image
31
+ * **Example:** From a public image
32
+ * ```typescript
33
+ * export const Base = Archil.Image("Base", { image: "node:24-bookworm" });
34
+ * ```
35
+ *
36
+ * **Example:** From a private registry
37
+ * ```typescript
38
+ * export const Agent = Archil.Image("Agent", {
39
+ * image: "ghcr.io/acme/agent:1",
40
+ * registry: {
41
+ * server: "ghcr.io",
42
+ * username: "acme-bot",
43
+ * password: Alchemy.Secret("GHCR_TOKEN"),
44
+ * },
45
+ * });
46
+ * ```
47
+ *
48
+ * **Example:** Build a Dockerfile and push it for Archil to pull
49
+ * ```typescript
50
+ * export const Agent = Archil.Image("Agent", {
51
+ * dockerfile: "./agent/Dockerfile",
52
+ * context: "./agent",
53
+ * push: {
54
+ * repository: "ghcr.io/acme/agent",
55
+ * credentials: { server: "ghcr.io", username: "acme-bot", password: Alchemy.Secret("GHCR_TOKEN") },
56
+ * },
57
+ * });
58
+ * ```
59
+ *
60
+ * ### Booting Sandboxes from an Image
61
+ * **Example:** Sandboxes created at run time
62
+ * ```typescript
63
+ * const sandboxes = yield* Archil.CreateSandbox(Agent);
64
+ * const sandbox = yield* sandboxes.create({ name: "task-1" });
65
+ * ```
66
+ *
67
+ * ### Looking up an existing image
68
+ * `Image.lookup` references an image Alchemy doesn't manage (created in
69
+ * the Archil console or by another stack). It is read during plan/deploy,
70
+ * never created, updated or deleted.
71
+ * `hash` is empty: the image wasn't built by this stack.
72
+ *
73
+ * **Example:** Reference an existing image
74
+ * ```typescript
75
+ * const base = Archil.Image.lookup({ imageId: "img_123" });
76
+ * ```
77
+ *
78
+ * @resource
79
+ * @product Image
80
+ */
81
+ export const Image = Resource("Archil.Image");
82
+ /** What Archil's image service can build: nothing beyond pulling a reference. */
83
+ export const capabilities = {
84
+ target: "Archil.Image",
85
+ platforms: ["linux/amd64"],
86
+ };
87
+ /** Map an image response to attributes. */
88
+ export const toImageAttributes = (image, hash, source = image.source) => ({
89
+ imageId: image.image_id,
90
+ // Archil may answer with a reference it normalized (or one an earlier
91
+ // build of the same image used), so keep the one that was asked for.
92
+ source,
93
+ canonicalSource: image.canonical_source,
94
+ digest: image.digest,
95
+ private: image.private,
96
+ hash,
97
+ });
98
+ /** Plan an image source for Archil. */
99
+ export const planImage = (props) => BuildPlan.plan(props.image !== undefined
100
+ ? { image: props.image }
101
+ : { dockerfile: props.dockerfile, context: props.context, build: props.build }, { capabilities, pull: props.registry });
102
+ /**
103
+ * The reference Archil can pull for a plan: its base, when the plan adds
104
+ * nothing on top of it.
105
+ */
106
+ export const pullableSource = (plan) => plan.instructions.length === 0 && plan.files.length === 0
107
+ ? Effect.succeed(plan.base)
108
+ : Effect.fail(new ImageRequiresBuild({
109
+ message: `Archil.Image pulls finished images; this Dockerfile adds ${plan.instructions.length} instruction(s) on top of ${plan.base}. Set \`push: { repository, credentials }\` so Alchemy can build it and push it there.`,
110
+ }));
111
+ /** Ask Archil to pull a reference and wait until the image is ready. */
112
+ export const pullImage = Effect.fn(function* (source, registry, hash) {
113
+ const { data } = yield* archil.createImage({
114
+ source,
115
+ registry_auth: registry
116
+ ? { username: registry.username, password: registry.password }
117
+ : undefined,
118
+ });
119
+ return toImageAttributes(yield* waitForImage(data.image_id), hash, source);
120
+ });
121
+ /**
122
+ * The reference Archil pulls for a plan: its base when the plan adds
123
+ * nothing, else the plan built locally and pushed to `push`.
124
+ */
125
+ export const publishPlan = Effect.fn(function* (plan, push) {
126
+ if (plan.instructions.length === 0 && plan.files.length === 0) {
127
+ return { source: plan.base, credentials: undefined };
128
+ }
129
+ if (push === undefined) {
130
+ return yield* new ImageRequiresBuild({
131
+ message: `Archil.Image pulls finished images; this Dockerfile adds ${plan.instructions.length} instruction(s) on top of ${plan.base}. Set \`push: { repository, credentials }\` so Alchemy can build it and push it there.`,
132
+ });
133
+ }
134
+ const { imageRef } = yield* Effect.scoped(BuildPlan.push(plan, { repository: push.repository, push: push.credentials }));
135
+ return { source: imageRef, credentials: push.credentials };
136
+ });
137
+ /** Plan, publish, then pull, an image. */
138
+ export const buildImage = Effect.fn(function* (props) {
139
+ const plan = yield* planImage(props);
140
+ const published = yield* publishPlan(plan, props.push);
141
+ return yield* pullImage(published.source, published.credentials ?? props.registry, plan.hash);
142
+ });
143
+ export const ImageProvider = () => Provider.effect(Image, Effect.gen(function* () {
144
+ return {
145
+ stables: ["imageId"],
146
+ // No delete or list API: nuke can't remove images.
147
+ nuke: { skip: true },
148
+ diff: Effect.fn(function* ({ news, output }) {
149
+ if (!isResolved(news) || output === undefined)
150
+ return undefined;
151
+ // The plan hash covers the reference, the Dockerfile and its context.
152
+ const plan = yield* planImage(news);
153
+ if (plan.hash !== output.hash)
154
+ return { action: "replace" };
155
+ return undefined;
156
+ }),
157
+ lookup: Effect.fn(function* ({ imageId }) {
158
+ return yield* archil.getImage({ image_id: imageId }).pipe(Effect.map(({ data }) => toImageAttributes(data, "")), Effect.catchTag("NotFound", () => Effect.undefined));
159
+ }),
160
+ read: Effect.fn(function* ({ output }) {
161
+ if (!output)
162
+ return undefined;
163
+ return yield* archil.getImage({ image_id: output.imageId }).pipe(Effect.map(({ data }) => toImageAttributes(data, output.hash, output.source)), Effect.catchTag("NotFound", () => Effect.undefined));
164
+ }),
165
+ reconcile: Effect.fn(function* ({ news, output, session }) {
166
+ const plan = yield* planImage(news);
167
+ for (const warning of plan.warnings)
168
+ yield* session.note(warning);
169
+ // Observe — a ready image from the same plan is kept; anything
170
+ // else (missing, failed, interrupted) is requested again.
171
+ if (output && output.hash === plan.hash) {
172
+ const observed = yield* archil.getImage({ image_id: output.imageId }).pipe(Effect.map(({ data }) => data), Effect.catchTag("NotFound", () => Effect.undefined));
173
+ if (observed?.status === "ready")
174
+ return toImageAttributes(observed, plan.hash, output.source);
175
+ if (observed?.status === "building") {
176
+ return toImageAttributes(yield* waitForImage(observed.image_id), plan.hash, output.source);
177
+ }
178
+ }
179
+ // Ensure
180
+ if (plan.instructions.length > 0 || plan.files.length > 0) {
181
+ yield* session.note(`Building and pushing image to ${news.push?.repository}...`);
182
+ }
183
+ const published = yield* publishPlan(plan, news.push);
184
+ yield* session.note(`Pulling image ${published.source}...`);
185
+ return yield* pullImage(published.source, published.credentials ?? news.registry, plan.hash);
186
+ }),
187
+ // Archil has no image delete API.
188
+ delete: () => Effect.void,
189
+ };
190
+ }));
191
+ //# sourceMappingURL=Image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Image.js","sources":["../src/Image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,+BAA+B,CAAC;AAI3D,OAAO,KAAK,MAAM,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA4EpD;;;GAGG;AACH,MAAM,OAAO,kBAAmB,SAAQ,IAAI,CAAC,WAAW,CAAC,2BAA2B,CAElF;CAAG;AAEL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiEG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAQ,cAAc,CAAC,CAAC;AAErD,iFAAiF;AACjF,MAAM,CAAC,MAAM,YAAY,GAA2B;IAClD,MAAM,EAAE,cAAc;IACtB,SAAS,EAAE,CAAC,aAAa,CAAC;CAC3B,CAAC;AAEF,2CAA2C;AAC3C,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,KAAmB,EACnB,IAAY,EACZ,MAAM,GAAW,KAAK,CAAC,MAAM,EACZ,EAAE,CAAC,CAAC;IACrB,OAAO,EAAE,KAAK,CAAC,QAAQ;IACvB,sEAAsE;IACtE,qEAAqE;IACrE,MAAM;IACN,eAAe,EAAE,KAAK,CAAC,gBAAgB;IACvC,MAAM,EAAE,KAAK,CAAC,MAAM;IACpB,OAAO,EAAE,KAAK,CAAC,OAAO;IACtB,IAAI;CACL,CAAC,CAAC;AAEH,uCAAuC;AACvC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAiB,EAAE,EAAE,CAC7C,SAAS,CAAC,IAAI,CACZ,KAAK,CAAC,KAAK,KAAK,SAAS;IACvB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;IACxB,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAChF,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,CACvC,CAAC;AAEJ;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAyB,EAAE,EAAE,CAC1D,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;IACvD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;IAC3B,CAAC,CAAC,MAAM,CAAC,IAAI,CACT,IAAI,kBAAkB,CAAC;QACrB,OAAO,EAAE,4DAA4D,IAAI,CAAC,YAAY,CAAC,MAAM,6BAA6B,IAAI,CAAC,IAAI,wFAAwF;KAC5N,CAAC,CACH,CAAC;AAER,wEAAwE;AACxE,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAC1C,MAAc,EACd,QAAmC,EACnC,IAAY;IAEZ,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;QACzC,MAAM;QACN,aAAa,EAAE,QAAQ;YACrB,CAAC,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE;YAC9D,CAAC,CAAC,SAAS;KACd,CAAC,CAAC;IACH,OAAO,iBAAiB,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC7E,CAAC,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAC5C,IAAyB,EACzB,IAA2B;IAE3B,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9D,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;IACvD,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC,CAAC,IAAI,kBAAkB,CAAC;YACnC,OAAO,EAAE,4DAA4D,IAAI,CAAC,YAAY,CAAC,MAAM,6BAA6B,IAAI,CAAC,IAAI,wFAAwF;SAC5N,CAAC,CAAC;IACL,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CACvC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAC9E,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;AAC7D,CAAC,CAAC,CAAC;AAEH,0CAA0C;AAC1C,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAiB;IAC9D,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,WAAW,IAAI,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;AAChG,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAG,EAAE,CAChC,QAAQ,CAAC,MAAM,CACb,KAAK,EACL,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,OAAO;QACL,OAAO,EAAE,CAAC,SAAS,CAAC;QACpB,mDAAmD;QACnD,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;QACpB,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;YACzC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAChE,sEAAsE;YACtE,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI;gBAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAW,CAAC;YACrE,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QACF,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE;YACtC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CACvD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EACrD,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CACpD,CAAC;QACJ,CAAC,CAAC;QAEF,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE;YACnC,IAAI,CAAC,MAAM;gBAAE,OAAO,SAAS,CAAC;YAC9B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAC9D,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAC7E,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CACpD,CAAC;QACJ,CAAC,CAAC;QACF,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;YACvD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACpC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ;gBAAE,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAClE,+DAA+D;YAC/D,0DAA0D;YAC1D,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;gBACxC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CACxE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,EAC9B,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CACpD,CAAC;gBACF,IAAI,QAAQ,EAAE,MAAM,KAAK,OAAO;oBAC9B,OAAO,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC/D,IAAI,QAAQ,EAAE,MAAM,KAAK,UAAU,EAAE,CAAC;oBACpC,OAAO,iBAAiB,CACtB,KAAK,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACtC,IAAI,CAAC,IAAI,EACT,MAAM,CAAC,MAAM,CACd,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,SAAS;YACT,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1D,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,iCAAiC,IAAI,CAAC,IAAI,EAAE,UAAU,KAAK,CAAC,CAAC;YACnF,CAAC;YACD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YACtD,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;YAC5D,OAAO,KAAK,CAAC,CAAC,SAAS,CACrB,SAAS,CAAC,MAAM,EAChB,SAAS,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ,EACtC,IAAI,CAAC,IAAI,CACV,CAAC;QACJ,CAAC,CAAC;QACF,kCAAkC;QAClC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI;KAC1B,CAAC;AACJ,CAAC,CAAC,CACH,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type * as Effect from "effect/Effect";
2
+ /**
3
+ * Typed `env` for the async (non-Effect) program of an `Archil.Sandbox`.
4
+ * A program's environment is process environment variables, so every
5
+ * entry is a `string`: the object the handler receives as its second
6
+ * argument.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * export const Hello = Archil.Sandbox("Hello", {
11
+ * main: "./src/hello.ts",
12
+ * env: { GREETING: "hello" },
13
+ * });
14
+ * export type HelloEnv = Archil.InferEnv<typeof Hello>;
15
+ * ```
16
+ */
17
+ export type InferEnv<F> = F extends Effect.Effect<infer A, infer _E, infer _R> ? InferEnv<A> : F extends {
18
+ readonly Props: {
19
+ readonly env?: infer E;
20
+ };
21
+ } ? InferEnvRecord<Exclude<E, undefined>> : InferEnvRecord<F>;
22
+ type InferEnvRecord<E> = {
23
+ readonly [K in keyof E]: string;
24
+ };
25
+ export {};
26
+ //# sourceMappingURL=InferEnv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InferEnv.d.ts","sources":["../src/InferEnv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,MAAM,eAAe,CAAC;AAE7C;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,IACpB,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,GAChD,QAAQ,CAAC,CAAC,CAAC,GACX,CAAC,SAAS;IAAE,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAA;KAAE,CAAA;CAAE,GACtD,cAAc,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GACrC,cAAc,CAAC,CAAC,CAAC,CAAC;AAE1B,KAAK,cAAc,CAAC,CAAC,IAAI;IACvB,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM;CAChC,CAAC"}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=InferEnv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InferEnv.js","sources":["../src/InferEnv.ts"],"names":[],"mappings":""}