1import * as Cloudflare from "@/Cloudflare";
2import * as Effect from "effect/Effect";
3import * as HttpClientRequest from "effect/http/HttpClientRequest";
4import { PrismaHostConnection } from "./db.ts";
5
6class PrismaHostContainer extends Cloudflare.Container<PrismaHostContainer>()(
7 "PrismaHostContainer",
8 Effect.gen(function* () {
9 const connection = yield* PrismaHostConnection;
10 return {
11 // Template string, not `path.join(import.meta.dirname, …)`: this module is
12 // bundled into the Worker and `import.meta.dirname` is undefined there.
13 context: `${import.meta.dirname}/../sqlreach/context`,
14 env: {
15 DATABASE_URL: connection.directConnectionString,
16 },
17 observability: { logs: { enabled: true } },
18 };
19 }),
20) {}
21
22/**
23 * Durable Object that binds the {@link PrismaHostContainer} and exposes the
24 * probe server's routes to the Worker.
25 */
26export class PrismaHostContainerObject extends Cloudflare.DurableObject<PrismaHostContainerObject>()(
27 "PrismaHostContainerObject",
28 Effect.gen(function* () {
29 const container = yield* PrismaHostContainer;
30
31 return Effect.gen(function* () {
32 const { fetch } = yield* container.getTcpPort(8080);
33
34 const get = (path: string) =>
35 Effect.gen(function* () {
36 const response = yield* fetch(
37 HttpClientRequest.get(`http://container${path}`),
38 );
39 return yield* response.text;
40 });
41
42 return {
43 getEnv: () => get("/env"),
44 getProbe: () => get("/probe"),
45 };
46 });
47 }).pipe(
48 Effect.provide(
49 Cloudflare.Containers.layer(PrismaHostContainer, {
50 enableInternet: true,
51 }),
52 ),
53 ),
54) {}