1import * as Cloudflare from "@/Cloudflare/index.ts";
2import * as Alchemy from "@/index.ts";
3import * as Neon from "@/Neon/index.ts";
4import * as SQL from "@/SQL/Postgres.ts";
5import * as Effect from "effect/Effect";
6import { HttpServerRequest } from "effect/http/HttpServerRequest";
7import * as HttpServerResponse from "effect/http/HttpServerResponse";
8
9/**
10 * `Alchemy.remote()` opts the Connection OUT of local emulation: even under
11 * `alchemy dev` the live provider creates a real Hyperdrive config on
12 * Cloudflare. The locally-served Worker's binding still passes through to
13 * the config's origin (no `dev` override here), so SQL round-trips against
14 * the real Neon database fronted by the real config.
15 */
16export const RemoteHyperdrive = Effect.gen(function* () {
17 const project = yield* Neon.Project("HyperdriveRemoteProject");
18 return yield* Cloudflare.Hyperdrive.Connection("HyperdriveRemoteConnection", {
19 origin: project.origin,
20 caching: { disabled: true },
21 }).pipe(Alchemy.remote());
22});
23
24/**
25 * Effect-native Worker binding the `Alchemy.remote()` Hyperdrive Connection.
26 * Same route surface as the local fixture so the test drives both legs the
27 * same way.
28 */
29export default class HyperdriveRemoteWorker extends Cloudflare.Worker<HyperdriveRemoteWorker>()(
30 "HyperdriveRemoteWorker",
31 { main: import.meta.url },
32 Effect.gen(function* () {
33 const hd = yield* Cloudflare.Hyperdrive.Connect(RemoteHyperdrive);
34 const sql = yield* SQL.Postgres({ url: hd.connectionString });
35
36 return {
37 fetch: Effect.gen(function* () {
38 const request = yield* HttpServerRequest;
39 const url = new URL(request.url, "http://x");
40 if (url.pathname === "/query") {
41 const rows = (yield* sql`
42 SELECT 1 + 1 AS sum, current_database() AS db
43 `) as ReadonlyArray<{ sum: number; db: string }>;
44 const host = yield* hd.host;
45 return yield* HttpServerResponse.json({ row: rows[0], host });
46 }
47 return HttpServerResponse.text("Not Found", { status: 404 });
48 }).pipe(
49 Effect.catchCause((cause) =>
50 HttpServerResponse.json({ error: String(cause) }, { status: 500 }),
51 ),
52 ),
53 };
54 }).pipe(Effect.provide(Cloudflare.Hyperdrive.ConnectBinding)),
55) {}