db

10 modules

  • db/assert_row.ts

    Assertion helper for INSERT RETURNING results.

  • db/create_db.ts

    Database initialization with driver auto-detection.

    Selects the appropriate database driver based on database_url: - postgres:// or postgresql:// — uses pg (PostgreSQL) - file:// — uses @electric-sql/pglite (file-based) - memory:// — uses @electric-sql/pglite (in-memory)

    Both pg and @electric-sql/pglite are optional peer dependencies, dynamically imported only when needed. For direct driver construction without auto-detection, use db/db_pg.ts or db/db_pglite.ts.

  • db/db_pg.ts

    PostgreSQL driver adapter for Db.

    Provides create_pg_db() to construct a Db backed by a pg.Pool. Only imports pg types — the actual pg package is dynamically imported by callers (e.g., create_db) that construct the Pool.

  • db/db_pglite.ts

    PGlite driver adapter for Db.

    Provides create_pglite_db() to construct a Db backed by @electric-sql/pglite. Only imports PGlite types — the actual package is dynamically imported by callers (e.g., create_db) that construct the PGlite instance.

  • db/db.ts

    Database wrapper with duck-typed interface.

    Accepts any client with a query(text, values) method. Both pg.Pool and @electric-sql/pglite satisfy this interface.

    Transaction safety is provided by an injected transaction callback — the driver adapters (db/db_pg.ts, db/db_pglite.ts) supply the driver-appropriate implementation. Close is handled externally (returned alongside the Db as DbDriverResult), not as a method on this class.

  • db/migrate.ts

    Identity-tracked database migration runner.

    Migrations are named {name, up} objects in ordered arrays, grouped by namespace. A schema_version table records one row per applied migration — (namespace, name, sequence, applied_at) — and the runner verifies the applied list is a name-prefix of the code's migration array at boot.

    Schema is not stabilized yet — append-only is NOT the rule. While fuz_app is pre-stable, migration bodies, names, and positions can change freely between versions; consumers upgrading across a schema change are expected to drop and re-bootstrap their dev/test databases (production deployments are not yet a supported use case). Once the schema is declared stable a hard append-only-after-publish rule will apply and the cliff will be called out in that release's notes; until then, body edits to a published migration slip past the runner (no content hashing) by design — they're the recommended way to evolve the schema.

    Chain-level transactions: All pending migrations in a namespace run in a single transaction. Any failure rolls back every migration in that run — no partial-state recovery. This rules out non-transactional DDL (e.g., CREATE INDEX CONCURRENTLY); run those out of band.

    Chain idempotency, not migration idempotency: the chain-tx wraps every migration replayed in a single boot, so an individual migration may temporarily produce intermediate state that a later migration reverses (e.g. v0's ROLE_GRANT_INDEXES recreates an index that v1 drops; chain-tx hides this from observers). What matters is that the *committed end state* matches; the in-tx steps may not be individually idempotent against an arbitrary mid-chain target.

    Forward-only: No down-migrations. Schema changes are additive.

    Advisory locking: Per-namespace pg_advisory_lock reduces contention in multi-instance deployments — best-effort, not load-bearing. The locks are session-scoped, but Db.query runs against a pool that may check out a different backend per call, so two concurrent boots can both "hold" the lock on different sessions. The real serialization comes from chain- tx atomicity + the (namespace, name) PK on schema_version: the loser's INSERT hits a PK violation, the chain-tx rolls back, and the next boot reads the committed state and proceeds cleanly. Environments without pg_advisory_lock (some PGlite versions) silently fall through.

  • db/pg_error.ts

    PostgreSQL error utilities.

    Works with both pg and @electric-sql/pglite — both set .code on error objects using standard PostgreSQL error codes.

  • db/query_deps.ts

    Shared query dependency type.

    All query_* functions take deps: QueryDeps as their first argument. Widened per-function when additional capabilities are needed (e.g., log for token validation).

  • db/sql_identifier.ts

    SQL identifier validation for dynamic DDL queries.

    PostgreSQL DDL operations (DROP TABLE, TRUNCATE, ALTER) do not support parameterized table/column names — only values can be parameterized. This validator ensures identifiers are safe for string interpolation in those specific cases.

  • db/status.ts

    Database status utility for CLI and dev workflows.

    Queries migration state and table info without a running server. Returns structured data that consumer scripts can print however they like.