VA.2026.004 · Floor 0 · service · hall 03
“persistence should be a sentence you write once, not a binary you ship.”
VA-ORM began as a refusal: no query-engine binary, no heavy codegen daemon, no second language to learn. A single va.schema file — Prisma-like, readable at a glance — is the only source of truth. From it, tables are pushed, clients are generated, and migrations are written as plain SQL files a human can audit.
Its runtime is deliberately thin. VaClient.create takes a driver, a DSN, and a model map — then exposes repositories with findUnique, findMany, create, update, delete, aggregations, raw SQL, transactions, and cursor/keyset pagination. @updatedAt fields refresh themselves on write. Relations resolve without an ORM priesthood.
This is the load-bearing layer of the museum. Exnest taught the collection how to route intelligence; VA-ORM teaches it how to remember. Every exhibit that needs to persist — users, wallets, tickets, memories — rests on this drawing. By beta.9 it also learned to travel: an HTTP transport lets a serverless consumer persist through a gateway instead of opening a socket of its own.
VA.2026.004
VA-ORM
TypeScript ORM · PostgreSQL · MySQL · SQLite · Schema-First
First va.schema drafted: datasource, model User, @id @unique @default(now()) @updatedAt. One file that describes both the database and the intent.
PostgreSQL via pg, MySQL via mysql2, SQLite via bun:sqlite built-in. One repository API, three SQL emitters — no engine binary shipped.
VaClient with repository pattern goes live: findUnique, findMany with where/limit, create, aggregations, raw SQL, transactions, cursor and keyset pagination.
va validate, generate, migrate up/down/status, db push with drift alter, db pull introspection. File migrations as auditable SQL.
0.1.0-beta.4. NestJS VaModule.forRoot and Elysia createVaSingleton adapters published. API stabilising — version pinned, issues tracked in the open.
A connection leak is closed, and expression, filter, and relation handling are hardened — the thin client stops being thin in the places that matter.
Driver options pass through untouched, max-uses tracking arrives, and an idle pool rebuilds itself at a minimum health check — released as beta.7.
SSL and DSN options are honoured, drivers are exposed, and Postgres plus MySQL are provisioned in CI for live tests; an idle-connection error that could crash the process is fixed.
beta.9: the migrator's DSN splits from the runtime, an HTTP transport serves serverless consumers, and a test sandbox ships alongside — the foundation learns to travel.
concepts — kept & discarded
kept — one va.schema as the single source of truth, human-readable
rejected — shipping a query-engine binary; the runtime stays thin
held — bring-your-own-driver; install only the dialect you serve
archive ref — VA.2026.004/CON
cross ref — timeline fig. 01
curator annotations
if the ORM needs a binary to think, the schema was never the source of truth.
three databases, one sentence. the emitter translates; the intent stays still.
@updatedAt is a small mercy — the record keeps its own time so you don't have to.
| materials | schema-first DSL · zero-engine runtime · repository pattern · multi-dialect SQL · file migration CLI · connection pool · HTTP transport · NestJS adapter · Elysia adapter | dimensions | dialects — 3 · CLI commands — 6 · adapters — 2 · relations — 1-N · N-N · engine binary — 0 · version — 0.1.0-beta.9 · commits — 49 |
|---|---|---|---|
| condition | beta · 3 dialects · 2 framework adapters · HTTP transport · pool hardened | acquired | 2026 |
| revision | Rev. B | archive location | DWG-004 · floor Floor 0 · service |
| internal reference | VA.2026.004/M | origin | drawn from the Exnest engine room, 2026 |
failed experiments
early sketch bundled a query compiler. deleted — it doubled install size and taught nothing the emitter couldn't.
autoincrement meant three different things across pg, mysql, sqlite. normalized behind @default(autoincrement()) before it leaked into user code.
@updatedAt first fired on read instead of write. every record rewrote its own history — fixed to write-path only.
draft concepts
research notes
— schema-first beats code-first when the database outlives the framework — and it always does.
— bring-your-own-driver keeps the install honest: pg and mysql2 as optional peers, SQLite free on Bun.
— file migrations are a curatorial choice: SQL you can read, diff, and hang on a wall.
The schema is a sentence, not a build step. Declare the model a single time and let push, pull, and generate derive everything else — tables, clients, migrations — from that one utterance.
No engine binary, no daemon, no second toolchain. The runtime is TypeScript and the driver you already chose. Lightness is not minimalism for its own sake — it is how a foundation stays load-bearing.
Migrations as SQL files, introspection as a first-class command. A database is a museum of its own past; every alteration should be legible to the curator who comes after you.
within the collection
future vision
VA-ORM is still beta, deliberately. The grammar will freeze, the emitters will harden, and the adapters will multiply — but the promise will not change: one schema, zero engine, every dialect you need. When the museum finally needs to remember everything, this is the room it will remember in.