1/**
2 * Process bootstrap for `AWS.ECS.Task` / `AWS.ECS.Service` containers. The
3 * generated entry imports this module and the user's `main`, nothing else —
4 * see {@link ./Process.ts} for why.
5 */
6import * as Credentials from "@distilled.cloud/aws/Credentials";
7import * as Endpoint from "@distilled.cloud/aws/Endpoint";
8import * as Region from "@distilled.cloud/aws/Region";
9import { BunServices } from "@effect/platform-bun";
10import * as ConfigProvider from "effect/ConfigProvider";
11import * as Effect from "effect/Effect";
12import * as Layer from "effect/Layer";
13import * as Logger from "effect/Logger";
14import * as FetchHttpClient from "effect/http/FetchHttpClient";
15import { BunHttpServer } from "../../Http.ts";
16import { reifyBoundConfigProvider } from "../../Runtime.ts";
17import {
18 entrypointLayer,
19 resolveProgram,
20 runProcess,
21 stackFromEnv,
22} from "./Process.ts";
23
24/**
25 * Resolve the bundled program (the runners registered via `host.run` /
26 * serve) and run it with a Bun HTTP server bound to `PORT`, so a returned
27 * `{ fetch }` handler is actually served and `host.run` loops stay alive. A
28 * pure one-shot `{ run }` program completes and the process exits 0.
29 */
30export const bootstrap = (entrypoint: unknown): Promise<void> => {
31 const platform = Layer.mergeAll(
32 BunServices.layer,
33 FetchHttpClient.layer,
34 Logger.layer([Logger.consolePretty()]),
35 );
36
37 const program = resolveProgram("program", { telemetry: true }).pipe(
38 Effect.provide(
39 entrypointLayer(entrypoint).pipe(
40 Layer.provideMerge(stackFromEnv),
41 // Full provider chain, not fromEnv: Fargate tasks receive credentials
42 // from the container-credentials endpoint
43 // (AWS_CONTAINER_CREDENTIALS_RELATIVE_URI), not environment variables.
44 Layer.provideMerge(Credentials.fromChain()),
45 Layer.provideMerge(Region.fromEnv()),
46 // AWS_ENDPOINT_URL is the LocalStack-standard override injected by
47 // local emulators (floci) into task containers — without it, runtime
48 // bindings in `alchemy dev` would call REAL AWS with dummy
49 // credentials. Resolves undefined when unset, so live deploys are
50 // unaffected.
51 Layer.provideMerge(Endpoint.fromEnv()),
52 Layer.provideMerge(BunHttpServer()),
53 Layer.provideMerge(platform),
54 Layer.provideMerge(
55 Layer.succeed(
56 ConfigProvider.ConfigProvider,
57 reifyBoundConfigProvider(ConfigProvider.fromEnv(), process.env),
58 ),
59 ),
60 ),
61 ),
62 Effect.scoped,
63 );
64
65 return runProcess("Task", program);
66};