baa-conductor


baa-conductor / apps / conductor-daemon / src
im_wower  ·  2026-03-22

local-control-plane.ts

 1import { readFileSync } from "node:fs";
 2import { resolve } from "node:path";
 3import { fileURLToPath } from "node:url";
 4
 5import { D1ControlPlaneRepository, SqliteD1Database } from "../../../packages/db/dist/index.js";
 6
 7const REPO_ROOT = resolve(fileURLToPath(new URL("../../..", import.meta.url)));
 8
 9export const DEFAULT_CONTROL_PLANE_DB_FILENAME = "control-plane.sqlite";
10
11export interface ConductorLocalControlPlaneOptions {
12  databasePath?: string | null;
13  schemaPath?: string | null;
14  stateDir?: string | null;
15}
16
17export function resolveConductorRepoRoot(): string {
18  return REPO_ROOT;
19}
20
21export function resolveDefaultConductorStateDir(): string {
22  return resolve(REPO_ROOT, "state");
23}
24
25export function resolveConductorControlPlaneSchemaPath(schemaPath?: string | null): string {
26  return resolve(schemaPath ?? resolve(REPO_ROOT, "ops/sql/schema.sql"));
27}
28
29export function resolveConductorControlPlaneDatabasePath(
30  options: Pick<ConductorLocalControlPlaneOptions, "databasePath" | "stateDir"> = {}
31): string {
32  const explicitDatabasePath = options.databasePath?.trim();
33
34  if (explicitDatabasePath) {
35    return explicitDatabasePath === ":memory:" ? ":memory:" : resolve(explicitDatabasePath);
36  }
37
38  return resolve(options.stateDir ?? resolveDefaultConductorStateDir(), DEFAULT_CONTROL_PLANE_DB_FILENAME);
39}
40
41export class ConductorLocalControlPlane {
42  readonly databasePath: string;
43  readonly repository: D1ControlPlaneRepository;
44  readonly schemaPath: string;
45
46  private readonly database: SqliteD1Database;
47
48  constructor(options: ConductorLocalControlPlaneOptions = {}) {
49    this.databasePath = resolveConductorControlPlaneDatabasePath(options);
50    this.schemaPath = resolveConductorControlPlaneSchemaPath(options.schemaPath);
51    this.database = new SqliteD1Database(this.databasePath, {
52      schemaSql: readFileSync(this.schemaPath, "utf8")
53    });
54    this.repository = new D1ControlPlaneRepository(this.database);
55  }
56
57  async initialize(): Promise<void> {
58    await this.repository.ensureAutomationState();
59  }
60
61  close(): void {
62    this.database.close();
63  }
64}