1import * as AWS from "@/AWS";
2import * as Effect from "effect/Effect";
3import { HttpServerRequest } from "effect/http/HttpServerRequest";
4import * as HttpServerResponse from "effect/http/HttpServerResponse";
5import { isolatedProject } from "../../../../../IsolatedProject.ts";
6
7/**
8 * The isolated consumer project this image is bundled from (see
9 * `test/IsolatedProject.ts`): `main` lives outside the repository, so the
10 * bundle `cwd` resolves none of alchemy's dependencies and the MicroVM
11 * bootstrap's own imports (`alchemy/*`, `effect/*`, …) must be anchored by
12 * the bundler.
13 */
14export const project = isolatedProject("lambda-microvm", import.meta.filename);
15
16export const IsolatedSandboxBuildRole = AWS.IAM.Role(
17 "IsolatedProjectMicrovmBuildRole",
18);
19
20/**
21 * Minimal effectful MicroVM image bundled from an isolated project: a typed
22 * RPC method (`hello`) plus a raw `fetch` route (`/echo`). Either answering
23 * from inside a running MicroVM proves the generated bootstrap booted — with
24 * its imports left external the in-VM server dies at module load and the
25 * orchestrator's calls never get a reply.
26 */
27export class IsolatedSandbox extends AWS.Lambda.MicrovmImage<
28 IsolatedSandbox,
29 {
30 hello: (message: string) => Effect.Effect<string>;
31 }
32>()("IsolatedProjectMicrovmSandbox") {}
33
34export default IsolatedSandbox.make(
35 IsolatedSandboxBuildRole.pipe(
36 Effect.map((buildRole) => ({
37 main: project.main,
38 buildRole,
39 resources: [{ minimumMemoryInMiB: 512 }],
40 cpuConfigurations: [{ architecture: "ARM_64" }],
41 })),
42 ),
43 Effect.gen(function* () {
44 return {
45 fetch: Effect.gen(function* () {
46 const request = yield* HttpServerRequest;
47 const url = new URL(request.url, "http://microvm");
48 if (url.pathname === "/echo") {
49 return yield* HttpServerResponse.json({
50 message: url.searchParams.get("message") ?? "",
51 });
52 }
53 return HttpServerResponse.text("hello from isolated project");
54 }),
55 hello: (message: string) => Effect.succeed(`hello, ${message}!`),
56 };
57 }),
58);