- Extract makeManagedRuntime() to src/effect/managed-runtime.ts so AppRuntime and BootstrapRuntime stop duplicating the lazy ManagedRuntime + dispose pattern, and document the shared-memoMap dispose ordering invariant. - Add lazy.resetIf(expected) and use it in 3 compare-and-reset call sites (db.close, AppRuntime.dispose, disposeWebHandler). - Drop dead `filename` option from EffectDrizzleSqlite MakeConfig. - Drop redundant `patched` IIFE flag (patchClass is already idempotent). - Add module-load assertion that Effect's protocol keys are present so a silent breakage on an Effect upgrade becomes a loud failure at import. - Collapse share-next test `live()` into the wider `wired()` factory. - Document lifecycle constraint in db-effect.ts and test/fixture/db.ts.
19 lines
908 B
TypeScript
19 lines
908 B
TypeScript
import { Database } from "@/storage/db"
|
|
import { Context, Effect, Layer } from "effect"
|
|
import type { EffectSQLiteDatabase } from "@opencode-ai/effect-drizzle-sqlite"
|
|
import * as StorageSchema from "@/storage/schema"
|
|
|
|
// Thin Effect Service over the module-global `Database.Client` lazy. The DB
|
|
// lifecycle is owned by `Database.open` / `Database.close`, not by this
|
|
// layer. Any runtime (see `effect/managed-runtime.ts`) that consumes this
|
|
// layer through the shared layer memoMap must be disposed before
|
|
// `Database.close()` so its memoized Service value does not outlive the
|
|
// underlying SQLite handle. See `test/fixture/db.ts:resetDatabase`.
|
|
export class Service extends Context.Service<Service, EffectSQLiteDatabase<typeof StorageSchema>>()(
|
|
"@opencode/DatabaseEffect",
|
|
) {}
|
|
|
|
export const layer = Layer.effect(Service, Effect.sync(Database.Client))
|
|
|
|
export * as DatabaseEffect from "./db-effect"
|