1import type * as runtime from "@cloudflare/workers-types";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import { Worker, WorkerEnvironment } from "../Workers/Worker.ts";
5import type { Database } from "./Database.ts";
6import {
7 type QueryDatabaseClient,
8 PreparedStatement,
9 QueryDatabase,
10} from "./QueryDatabase.ts";
11
12export const QueryDatabaseBinding = Layer.effect(
13 QueryDatabase,
14 Effect.gen(function* () {
15 const env = yield* WorkerEnvironment;
16 const host = yield* Worker;
17
18 return Effect.fn(function* (database: Database) {
19 if (!globalThis.__ALCHEMY_RUNTIME__) {
20 yield* host.bind`${database}`({
21 bindings: [
22 {
23 type: "d1",
24 name: database.LogicalId,
25 databaseId: database.databaseId,
26 },
27 ],
28 });
29 }
30
31 const rawEff = Effect.sync(
32 () => (env as Record<string, runtime.D1Database>)[database.LogicalId]!,
33 );
34
35 return {
36 raw: rawEff,
37 prepare: (query: string) => new PreparedStatement(query, [], rawEff),
38 exec: (query: string) =>
39 Effect.flatMap(rawEff, (raw) =>
40 Effect.promise(() => raw.exec(query)),
41 ),
42 batch: <T = unknown>(statements: PreparedStatement[]) =>
43 Effect.flatMap(rawEff, (raw) =>
44 Effect.promise(() =>
45 raw.batch<T>(statements.map((s) => s._build(raw))),
46 ),
47 ),
48 } satisfies QueryDatabaseClient;
49 });
50 }),
51);