1import * as Railway from "alchemy/Railway";
2import { ServerHost } from "alchemy/Server";
3import * as Effect from "effect/Effect";
4import * as FileSystem from "effect/FileSystem";
5import * as HttpServerResponse from "effect/http/HttpServerResponse";
6import { Disk, MARKER, MARKER_FILE, Site, VOLUME_PATH } from "./shared.ts";
7
8/**
9 * Background Service: mounts {@link Disk} at `/data` and writes a
10 * marker file. Hosted Services default to a `/health` probe, so this
11 * still answers HTTP there — {@link Api} is the public surface.
12 */
13export default class Worker extends Railway.Service<Worker>()(
14 "Worker",
15 {
16 project: Site,
17 main: import.meta.url,
18 port: 3000,
19 healthcheck: "/health",
20 },
21 Effect.gen(function* () {
22 const mount = yield* Railway.MountVolume(Disk, { path: VOLUME_PATH });
23 const host = yield* ServerHost;
24 const fs = yield* FileSystem.FileSystem;
25
26 yield* host.run(
27 Effect.gen(function* () {
28 yield* fs.makeDirectory(mount.path, { recursive: true });
29 yield* fs.writeFileString(MARKER_FILE, MARKER);
30 return yield* Effect.never;
31 }).pipe(Effect.orDie),
32 );
33 return {
34 fetch: HttpServerResponse.json({ ok: true }),
35 };
36 }).pipe(Effect.provide(Railway.MountVolumeLive)),
37) {}