| 1 | import type { D1Database } from "@cloudflare/workers-types" |
| 2 | import { D1Client } from "@effect/sql-d1" |
| 3 | import { Context, Data, Effect, Layer } from "effect" |
| 4 | import { Miniflare } from "miniflare" |
| 5 | |
| 6 | export class MiniflareError extends Data.TaggedError("MiniflareError")<{ |
| 7 | cause: unknown |
| 8 | }> {} |
| 9 | |
| 10 | export class D1Miniflare extends Context.Service< |
| 11 | D1Miniflare, |
| 12 | Miniflare |
| 13 | >()("test/D1Miniflare") { |
| 14 | static readonly layer = Layer.effect(this)( |
| 15 | Effect.acquireRelease( |
| 16 | Effect.try({ |
| 17 | try: () => |
| 18 | new Miniflare({ |
| 19 | workers: [{ |
| 20 | config: { |
| 21 | name: "test", |
| 22 | compatibilityDate: "2026-08-30", |
| 23 | manifest: { |
| 24 | mainModule: "index.mjs", |
| 25 | modules: { |
| 26 | "index.mjs": { |
| 27 | type: "esm", |
| 28 | contents: "export default {}" |
| 29 | } |
| 30 | } |
| 31 | }, |
| 32 | env: { |
| 33 | DB: { |
| 34 | type: "d1", |
| 35 | id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" |
| 36 | } |
| 37 | } |
| 38 | } |
| 39 | }] |
| 40 | }), |
| 41 | catch: (cause) => new MiniflareError({ cause }) |
| 42 | }), |
| 43 | (miniflare) => Effect.promise(() => miniflare.dispose()) |
| 44 | ) |
| 45 | ) |
| 46 | |
| 47 | static layerClient = Layer.unwrap( |
| 48 | Effect.gen(function*() { |
| 49 | const miniflare = yield* D1Miniflare |
| 50 | const db: D1Database = yield* Effect.tryPromise(() => miniflare.getD1Database("DB")) |
| 51 | return D1Client.layer({ db }) |
| 52 | }) |
| 53 | ).pipe(Layer.provide(this.layer)) |
| 54 | } |