@orkestrel/database 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["#path","#memory","#schema","#load","#deferring","#flush","#meta","#chain","#serialize","#flushCount","#path","#options","#guard","#database","#schema","#table","#require","#key","#transacting","#applyPlan"],"sources":["../../../src/server/helpers.ts","../../../src/server/compilers.ts","../../../src/server/constants.ts","../../../src/server/drivers/JSONDriver.ts","../../../src/server/drivers/SQLiteDriver.ts","../../../src/server/factories.ts"],"sourcesContent":["import type {\n\tAggregateFunction,\n\tColumnType,\n\tCondition,\n\tCriteria,\n\tMigrationStep,\n\tOrder,\n\tRow,\n\tTableSchema,\n} from '@src/core'\nimport type { FieldPath } from '@orkestrel/contract'\nimport type { SQLiteRow, SQLiteValue } from './types.js'\nimport { isBoolean, isFiniteNumber, isString } from '@orkestrel/contract'\nimport { randomUUID } from 'node:crypto'\n\n// The server's key-minting `KeyFunction` implementation — `core` mints no keys\n// itself (AGENTS §1: cross-environment code touches no `node:*`), so a server\n// consumer wires this in as `DatabaseOptions.key`.\n//\n// Below it: the SQLite ↔ JS bridge for the driver. Every helper is pure and\n// total — it narrows with `typeof` / `instanceof`, never `as` (AGENTS §1, §14):\n// a value that does not fit its column's storage type encodes to `null` rather\n// than throwing, and `decodeValue` is the exact inverse. `encodeRow` /\n// `decodeRow` lift the per-cell codecs across a whole schema; the SQL\n// identifier / type helpers (`quote`, `columnSQL`, `fieldColumn`) build the\n// static parts of a statement. `schemaToTable` / `schemaToIndexes` are pure\n// projections of the CREATE TABLE / CREATE INDEX DDL a SQLite driver's `open`\n// issues. This module speaks pure strings/values only — it imports no SQLite\n// package.\n\n/**\n * Generate a fresh unique key — a v4 UUID string, backed by `node:crypto`.\n *\n * @remarks\n * Supply this as {@link import('@orkestrel/database').DatabaseOptions.key} so a table mints\n * a key when a written row lacks its primary-key value. Strings work as keys on\n * every backend; supply your own key values directly to use numeric keys instead.\n *\n * @returns A new UUID string\n *\n * @example\n * ```ts\n * const db = createDatabase({ driver, tables, key: generateKey })\n * ```\n */\nexport function generateKey(): string {\n\treturn randomUUID()\n}\n\n// === Exactness (native ↔ engine parity gating)\n//\n// SQLiteDriver's `records` / `count` / `aggregate` / `stream` compile a\n// `Criteria` straight to SQL with NO engine re-filter — a huge perf win, but\n// only sound for a condition/order whose compiled SQL provably matches the\n// core engine's `matchesCondition` / `sortRows` semantics for every value a\n// contract-validated write can store (\"declared-type trust\"). These guards\n// decide, per condition/order/criteria, whether that proof holds; when it does\n// not, the driver falls back to a full scan refined through the same core\n// engine every scan-only driver (`MemoryDriver`, `JSONDriver`) already uses —\n// exact → native, otherwise → refine, never a silent semantics drift.\n\n/**\n * The declared {@link ColumnType}s whose SQL EQUALITY comparisons (`equals` /\n * `not` / `any` / `none`) and `starts` / `ends` compiles are provably\n * engine-exact under declared-type trust — `text` / `integer` / `real` /\n * `boolean`; a `json` or `blob` column always refines instead.\n *\n * @remarks\n * This set governs equality and prefix/suffix matching only. RANGE\n * comparisons (`above` / `below` / `from` / `to` / `between`) and `ORDER BY`\n * are exact for `integer` / `real` / `boolean` but NOT for `text`: compiled\n * SQL orders/ranges under SQLite's default BINARY collation, which compares\n * TEXT byte-for-byte as UTF-8 — equivalent to Unicode CODE-POINT order —\n * while the core engine's `compareValues` orders JS strings with `<`, which\n * compares UTF-16 CODE-UNIT order. The two orders diverge for supplementary-\n * plane characters (code points ≥ U+10000, e.g. many emoji): a lead surrogate\n * (`\\uD800`–`\\uDBFF`) sorts BELOW ``–`￿` in code-unit order, while\n * its code point sorts ABOVE them. So `isExactCondition`'s range family and\n * `isExactOrder` exclude `text`, refining through the core engine instead. A\n * future opt-in \"trusted collation\" mode (the caller vouches the column's\n * values are BMP-only, or a custom SQLite collation matching `compareValues`\n * is registered) could restore native text ranges/ordering.\n */\nexport const EXACT_COLUMN_TYPES: readonly ColumnType[] = ['text', 'integer', 'real', 'boolean']\n\n/**\n * The declared {@link ColumnType}s whose SQL RANGE comparisons\n * (`above` / `below` / `from` / `to` / `between`) and `ORDER BY` compiles are\n * provably engine-exact — `integer` / `real` / `boolean` only. `text` is\n * excluded: see {@link EXACT_COLUMN_TYPES}'s remarks for the BINARY-collation\n * (code-point) vs. JS `<` (code-unit) divergence on supplementary-plane\n * characters.\n */\nexport const EXACT_RANGE_COLUMN_TYPES: readonly ColumnType[] = ['integer', 'real', 'boolean']\n\n/**\n * Whether a value's runtime type matches a column's declared exact type —\n * the operand side of the declared-type-trust proof.\n *\n * @remarks\n * `text` ↔ string, `integer` / `real` ↔ FINITE number (`NaN` / `±Infinity`\n * fail), `boolean` ↔ boolean. Backs {@link isExactCondition}'s operand checks.\n *\n * @param value - The condition operand to test\n * @param type - The column's declared portable type\n * @returns `true` when the operand's runtime type matches the declared type\n *\n * @example\n * ```ts\n * matchesDeclaredType('Ada', 'text') // true\n * matchesDeclaredType(Number.NaN, 'integer') // false — only finite numbers\n * ```\n */\nexport function matchesDeclaredType(value: unknown, type: ColumnType): boolean {\n\tif (type === 'text') return isString(value)\n\tif (type === 'boolean') return isBoolean(value)\n\treturn isFiniteNumber(value)\n}\n\n/**\n * Whether one {@link Condition} compiles to SQL that is PROVABLY identical to\n * the core engine's `matchesCondition` for every value its column's declared\n * type can store.\n *\n * @remarks\n * `false` for a nested `FieldPath` (an array), a column absent from `schema`,\n * or a column whose declared type is not `text` / `integer` / `real` /\n * `boolean` (a `json` / `blob` column) — EXCEPT `absent` / `present`, which\n * compile to `IS NULL` / `IS NOT NULL` and match `decodeRow`'s \"a stored NULL\n * decodes to `undefined`\" rule for every column type, so they are exact\n * regardless of declared type. `equals` / `not` require a operand matching the\n * column's declared type (a `null` / `undefined` operand is never exact here —\n * `encodeRow` stores both an explicit `null` and an absent field as SQL NULL,\n * so native `IS NULL` semantics cannot match the engine's `deepEqual`-over-\n * decoded-rows truth). `above` / `below` / `from` / `to` / `between` are exact\n * ONLY for a declared type in {@link EXACT_RANGE_COLUMN_TYPES} (`integer` /\n * `real` / `boolean`) — a `text` column's range conditions REFINE, because\n * SQLite's default BINARY collation orders TEXT by Unicode CODE POINT while\n * the core engine's `compareValues` orders JS strings by UTF-16 CODE UNIT,\n * and the two diverge for supplementary-plane characters (see\n * {@link EXACT_COLUMN_TYPES}'s remarks for the full rationale).\n * `any` / `none` require a NON-EMPTY list where every element matches (an empty\n * list is exact under neither: the engine's `any([])` matches nothing while\n * `none([])` matches everything, and SQL `IN ()` is a syntax error) — these\n * stay exact on `text` (byte equality is collation-independent and engine-\n * identical). `starts` / `ends` are exact only on a `text` column with a\n * string operand (case-sensitive `substr` compile, see {@link fragment}) —\n * likewise collation-independent. `like` / `glob` are NEVER exact — SQLite\n * `LIKE` folds case ASCII-only against the engine's Unicode fold, and `GLOB`\n * has character classes the engine treats literally.\n *\n * @param condition - The condition to test\n * @param schema - The table's schema\n * @returns Whether `condition` is exact\n */\nexport function isExactCondition(condition: Condition, schema: TableSchema): boolean {\n\tif (!isString(condition.column)) return false\n\tconst column = schema.columns.find((candidate) => candidate.name === condition.column)\n\tif (column === undefined) return false\n\tif (condition.operator === 'absent' || condition.operator === 'present') return true\n\tif (!EXACT_COLUMN_TYPES.some((type) => type === column.type)) return false\n\tconst first = condition.values[0]\n\tconst second = condition.values[1]\n\tswitch (condition.operator) {\n\t\tcase 'equals':\n\t\tcase 'not':\n\t\t\treturn matchesDeclaredType(first, column.type)\n\t\tcase 'above':\n\t\tcase 'below':\n\t\tcase 'from':\n\t\tcase 'to':\n\t\t\treturn (\n\t\t\t\tEXACT_RANGE_COLUMN_TYPES.some((type) => type === column.type) &&\n\t\t\t\tmatchesDeclaredType(first, column.type)\n\t\t\t)\n\t\tcase 'between':\n\t\t\treturn (\n\t\t\t\tEXACT_RANGE_COLUMN_TYPES.some((type) => type === column.type) &&\n\t\t\t\tmatchesDeclaredType(first, column.type) &&\n\t\t\t\tmatchesDeclaredType(second, column.type)\n\t\t\t)\n\t\tcase 'any':\n\t\tcase 'none':\n\t\t\treturn (\n\t\t\t\tcondition.values.length > 0 &&\n\t\t\t\tcondition.values.every((value) => matchesDeclaredType(value, column.type))\n\t\t\t)\n\t\tcase 'starts':\n\t\tcase 'ends':\n\t\t\treturn column.type === 'text' && isString(first)\n\t\tcase 'like':\n\t\tcase 'glob':\n\t\t\treturn false\n\t}\n}\n\n/**\n * Whether one {@link Order} term's column compiles to an `ORDER BY` that\n * matches the engine's {@link import('@src/core').sortRows} exactly.\n *\n * @remarks\n * `false` for a nested `FieldPath`, a column absent from `schema`, or a\n * declared type outside {@link EXACT_RANGE_COLUMN_TYPES} (`integer` / `real` /\n * `boolean`). `text` is NOT exact here: SQLite's default BINARY collation\n * orders TEXT by Unicode code point while the core engine's `compareValues`\n * orders JS strings by UTF-16 code unit, and the two diverge for\n * supplementary-plane characters (see {@link EXACT_COLUMN_TYPES}'s remarks) —\n * a `text` order term REFINES through the core engine instead.\n *\n * @param order - The order term to test\n * @param schema - The table's schema\n * @returns Whether `order` is exact\n */\nexport function isExactOrder(order: Order, schema: TableSchema): boolean {\n\tif (!isString(order.column)) return false\n\tconst column = schema.columns.find((candidate) => candidate.name === order.column)\n\tif (column === undefined) return false\n\treturn EXACT_RANGE_COLUMN_TYPES.some((type) => type === column.type)\n}\n\n/**\n * Whether a whole {@link Criteria} is exact — every condition and every order\n * term is exact. `limit` / `offset` never affect exactness (SQL `LIMIT` /\n * `OFFSET` are always engine-identical).\n *\n * @param criteria - The criteria to test\n * @param schema - The table's schema\n * @returns Whether every part of `criteria` is exact\n */\nexport function isExactCriteria(criteria: Criteria, schema: TableSchema): boolean {\n\tconst conditions = criteria.conditions ?? []\n\tconst order = criteria.order ?? []\n\treturn (\n\t\tconditions.every((condition) => isExactCondition(condition, schema)) &&\n\t\torder.every((term) => isExactOrder(term, schema))\n\t)\n}\n\n// === SQL identifiers & types\n\n/**\n * Map a portable {@link ColumnType} to its SQLite column type.\n *\n * @remarks\n * `text` / `json` → `TEXT` (JSON is stored as text and read back with\n * `json_extract` for nested-field queries); `integer` / `boolean` → `INTEGER`\n * (a boolean stores `1` / `0`); `real` → `REAL`; `blob` → `BLOB`. No `NOT NULL`\n * is ever emitted — the contract validates required-ness; the database is just\n * storage (AGENTS §14, the typed layer above imposes the shape).\n *\n * @param type - The portable column type\n * @returns The SQLite column type keyword\n *\n * @example\n * ```ts\n * columnSQL('integer') // 'INTEGER'\n * columnSQL('json') // 'TEXT'\n * ```\n */\nexport function columnSQL(type: ColumnType): string {\n\tswitch (type) {\n\t\tcase 'text':\n\t\tcase 'json':\n\t\t\treturn 'TEXT'\n\t\tcase 'integer':\n\t\tcase 'boolean':\n\t\t\treturn 'INTEGER'\n\t\tcase 'real':\n\t\t\treturn 'REAL'\n\t\tcase 'blob':\n\t\t\treturn 'BLOB'\n\t}\n}\n\n/**\n * Quote a SQL identifier (a table or column name) so any characters are literal.\n *\n * @remarks\n * Wraps the name in double quotes and doubles any embedded quote — the standard\n * SQL identifier-quoting that lets a column named `order` or `from` be referenced\n * safely. Identifiers cannot be bound as parameters, so they are quoted instead.\n *\n * @param identifier - The raw identifier\n * @returns The double-quoted identifier\n *\n * @example\n * ```ts\n * quote('order') // '\"order\"'\n * ```\n */\nexport function quote(identifier: string): string {\n\treturn '\"' + identifier.replaceAll('\"', '\"\"') + '\"'\n}\n\n/**\n * Compile a {@link FieldPath} to the SQL expression that reads it.\n *\n * @remarks\n * A single string is ONE column — `quote(path)`. An array descends a JSON column:\n * the first element is the (quoted) column, the rest a `json_extract` path\n * (`json_extract(\"payload\", '$.user.id')`), matching the guide's nested-field\n * examples (simple identifier keys). The string's value is never split on `.`\n * (AGENTS — `FieldPath` semantics): a dotted string is one column literally.\n *\n * @param path - The field path (a column, or a column + nested keys)\n * @returns The SQL expression selecting the value\n *\n * @example\n * ```ts\n * fieldColumn('payload') // '\"payload\"'\n * fieldColumn(['payload', 'user', 'id']) // 'json_extract(\"payload\", \\'$.user.id\\')'\n * ```\n */\nexport function fieldColumn(path: FieldPath): string {\n\tif (isString(path)) return quote(path)\n\tconst rest = path\n\t\t.slice(1)\n\t\t.map((key) => '.' + key.replaceAll(\"'\", \"''\"))\n\t\t.join('')\n\treturn 'json_extract(' + quote(path[0]) + \", '$\" + rest + \"')\"\n}\n\n/**\n * Compile an {@link AggregateFunction} over a {@link FieldPath} to its SQL\n * aggregate expression — the SELECT body the SQLite driver's native `aggregate`\n * runs.\n *\n * @remarks\n * `count` → `COUNT(*)` (counting all matched ROWS, not non-null column values —\n * mirroring the engine's `computeAggregate('count')`, which is `rows.length`); the\n * numeric aggregates wrap the column's read expression (a flat column, or a nested\n * `json_extract` path) in `SUM` / `AVG` / `MIN` / `MAX`. Over zero matched rows\n * `COUNT(*)` is `0` and the numeric aggregates are SQL `NULL` (→ `undefined`),\n * matching the engine.\n *\n * @param operation - The aggregate to compute\n * @param column - The column (or nested path) to aggregate\n * @returns The SQL aggregate expression\n *\n * @example\n * ```ts\n * aggregateSQL('count', 'age') // 'COUNT(*)'\n * aggregateSQL('sum', 'age') // 'SUM(\"age\")'\n * aggregateSQL('average', ['payload', 'score']) // 'AVG(json_extract(\"payload\", \\'$.score\\'))'\n * ```\n */\nexport function aggregateSQL(operation: AggregateFunction, column: FieldPath): string {\n\tswitch (operation) {\n\t\tcase 'count':\n\t\t\treturn 'COUNT(*)'\n\t\tcase 'sum':\n\t\t\treturn 'SUM(' + fieldColumn(column) + ')'\n\t\tcase 'average':\n\t\t\treturn 'AVG(' + fieldColumn(column) + ')'\n\t\tcase 'minimum':\n\t\t\treturn 'MIN(' + fieldColumn(column) + ')'\n\t\tcase 'maximum':\n\t\t\treturn 'MAX(' + fieldColumn(column) + ')'\n\t}\n}\n\n// === Value codecs\n\n/**\n * Encode a JS value to its stored {@link SQLiteValue} for a column's type.\n *\n * @remarks\n * The forward half of the bridge, total (AGENTS §14): a value that does not fit\n * its column's storage type encodes to `null` rather than throwing. A `boolean`\n * column stores `1` / `0` (and `null` / `undefined` → `null`); a `json` column\n * stores `JSON.stringify` (or `null` for `null` / `undefined`); `integer` /\n * `real` keep a `number` / `bigint`, else `null`; `text` keeps a `string`, else\n * `null`; `blob` keeps a `Uint8Array`, else `null`. Narrowed with `typeof` /\n * `instanceof`, never `as`.\n *\n * @param value - The JS value to store\n * @param type - The column's portable storage type\n * @returns The value SQLite stores\n *\n * @example\n * ```ts\n * encodeValue(true, 'boolean') // 1\n * encodeValue({ a: 1 }, 'json') // '{\"a\":1}'\n * ```\n */\nexport function encodeValue(value: unknown, type: ColumnType): SQLiteValue {\n\tswitch (type) {\n\t\tcase 'boolean':\n\t\t\treturn value === undefined || value === null ? null : value === true ? 1 : 0\n\t\tcase 'json':\n\t\t\treturn value === undefined || value === null ? null : JSON.stringify(value)\n\t\tcase 'integer':\n\t\tcase 'real':\n\t\t\treturn typeof value === 'number' || typeof value === 'bigint' ? value : null\n\t\tcase 'text':\n\t\t\treturn typeof value === 'string' ? value : null\n\t\tcase 'blob':\n\t\t\treturn value instanceof Uint8Array ? value : null\n\t}\n}\n\n/**\n * Decode a stored {@link SQLiteValue} back to its JS value for a column's type —\n * the exact inverse of {@link encodeValue}.\n *\n * @remarks\n * A `boolean` column reads `1` / `0` back to `true` / `false` (a stored `null`\n * → `undefined`); a `json` column `JSON.parse`s a string (anything else →\n * `undefined`); every other type passes the value through, mapping a stored\n * `NULL` to `undefined`. NULL decodes to `undefined` so {@link decodeRow} can\n * omit absent columns.\n *\n * @param value - The stored SQLite value\n * @param type - The column's portable storage type\n * @returns The decoded JS value (`undefined` for a stored `NULL`)\n *\n * @example\n * ```ts\n * decodeValue(1, 'boolean') // true\n * decodeValue('{\"a\":1}', 'json') // { a: 1 }\n * ```\n */\nexport function decodeValue(value: SQLiteValue, type: ColumnType): unknown {\n\tswitch (type) {\n\t\tcase 'boolean':\n\t\t\treturn value === null ? undefined : value !== 0\n\t\tcase 'json':\n\t\t\treturn typeof value === 'string' ? JSON.parse(value) : undefined\n\t\tdefault:\n\t\t\treturn value === null ? undefined : value\n\t}\n}\n\n/**\n * Encode a whole {@link Row} to a {@link SQLiteRow} by its table's schema.\n *\n * @remarks\n * Encodes each declared column's value with {@link encodeValue}; columns the row\n * does not carry encode from `undefined` (so they store `null`). Only the\n * schema's columns appear in the result — an extra row key is dropped.\n *\n * @param row - The JS row to store\n * @param schema - The table's schema\n * @returns The storable SQLite row\n *\n * @example\n * ```ts\n * encodeRow({ id: 'u1', active: true }, schema) // { id: 'u1', active: 1, ... }\n * ```\n */\nexport function encodeRow(row: Row, schema: TableSchema): SQLiteRow {\n\tconst result: SQLiteRow = {}\n\tfor (const column of schema.columns) {\n\t\tresult[column.name] = encodeValue(row[column.name], column.type)\n\t}\n\treturn result\n}\n\n/**\n * Decode a stored {@link SQLiteRow} back to a {@link Row} by its table's schema.\n *\n * @remarks\n * Decodes each declared column with {@link decodeValue} and **omits** any column\n * whose decoded value is `undefined` — so an absent / `NULL` optional column does\n * not surface as `{ bio: undefined }`, matching how the contract's optional\n * columns expect absence. A known, documented edge: a non-optional `nullableShape`\n * column storing `null` round-trips to absent (a `null` cell decodes to\n * `undefined`, and an `undefined` value is omitted).\n *\n * @param row - The stored SQLite row\n * @param schema - The table's schema\n * @returns The decoded JS row (absent columns omitted)\n *\n * @example\n * ```ts\n * decodeRow({ id: 'u1', active: 1, bio: null }, schema) // { id: 'u1', active: true }\n * ```\n */\nexport function decodeRow(row: SQLiteRow, schema: TableSchema): Row {\n\tconst result: Row = {}\n\tfor (const column of schema.columns) {\n\t\tconst decoded = decodeValue(row[column.name], column.type)\n\t\tif (decoded !== undefined) result[column.name] = decoded\n\t}\n\treturn result\n}\n\n// === DDL projections\n\n/**\n * Project a {@link TableSchema} to the `CREATE TABLE IF NOT EXISTS` statement a\n * SQLite driver's `open` issues for it.\n *\n * @remarks\n * Each column compiles to `<quoted name> <columnSQL(type)>`; the statement ends\n * with `PRIMARY KEY (<quoted primary>)`. No `NOT NULL` is emitted — the contract\n * validates required-ness, the database is just storage (AGENTS §14).\n *\n * @param schema - The table's schema\n * @returns The `CREATE TABLE IF NOT EXISTS …` statement\n *\n * @example\n * ```ts\n * schemaToTable(schema)\n * // 'CREATE TABLE IF NOT EXISTS \"users\" (\"id\" TEXT, \"age\" INTEGER, PRIMARY KEY (\"id\"))'\n * ```\n */\nexport function schemaToTable(schema: TableSchema): string {\n\tconst columns = schema.columns.map((column) => quote(column.name) + ' ' + columnSQL(column.type))\n\treturn (\n\t\t'CREATE TABLE IF NOT EXISTS ' +\n\t\tquote(schema.name) +\n\t\t' (' +\n\t\tcolumns.join(', ') +\n\t\t', PRIMARY KEY (' +\n\t\tquote(schema.primary) +\n\t\t'))'\n\t)\n}\n\n/**\n * Build a collision-free SQL index name for a table + column-group index —\n * shared by {@link schemaToIndexes} (an `open`-time `CREATE INDEX`) and\n * {@link stepToSQL}'s `index.add` / `index.remove` (a migration-time DDL),\n * so a plan-built index name always matches one `open` would have created.\n *\n * @remarks\n * A naive `idx_<table>_<cols joined by _>` is AMBIGUOUS: table `'a_b'` with\n * column `'c'` and table `'a'` with columns `['b', 'c']` both produce\n * `idx_a_b_c`. This encodes each part (the table name, then each column name)\n * length-prefixed (`<len>_<part>`) so the boundary between parts is always\n * unambiguous, however the names themselves are punctuated.\n *\n * @param table - The table name\n * @param columns - The index's column names, in order\n * @returns The deterministic, collision-free index identifier (unquoted)\n *\n * @example\n * ```ts\n * indexName('users', ['name']) // 'idx_5_users_4_name'\n * indexName('a_b', ['c']) // 'idx_3_a_b_1_c'\n * indexName('a', ['b', 'c']) // 'idx_1_a_1_b_1_c'\n * ```\n */\nexport function indexName(table: string, columns: readonly string[]): string {\n\tconst parts = [table, ...columns].map((part) => String(part.length) + '_' + part)\n\treturn 'idx_' + parts.join('_')\n}\n\n/**\n * Project a {@link TableSchema} to the `CREATE INDEX IF NOT EXISTS` statements a\n * SQLite driver's `open` issues for its declared indexes.\n *\n * @remarks\n * One statement per index group; the index name is built by {@link indexName}\n * (collision-free and deterministic), matching the driver's naming so a\n * repeated `open` is idempotent.\n *\n * @param schema - The table's schema\n * @returns One `CREATE INDEX IF NOT EXISTS …` statement per declared index\n *\n * @example\n * ```ts\n * schemaToIndexes(schema)\n * // ['CREATE INDEX IF NOT EXISTS \"idx_5_users_4_name\" ON \"users\" (\"name\")']\n * ```\n */\nexport function schemaToIndexes(schema: TableSchema): readonly string[] {\n\treturn schema.indexes.map(\n\t\t(group) =>\n\t\t\t'CREATE INDEX IF NOT EXISTS ' +\n\t\t\tquote(indexName(schema.name, group)) +\n\t\t\t' ON ' +\n\t\t\tquote(schema.name) +\n\t\t\t' (' +\n\t\t\tgroup.map(quote).join(', ') +\n\t\t\t')',\n\t)\n}\n\n/**\n * Project one {@link MigrationStep} to the DDL statement(s) a SQLite driver's\n * `migrate` executes for it.\n *\n * @remarks\n * `table.add` emits the `CREATE TABLE` plus one `CREATE INDEX` per declared\n * index (via {@link schemaToTable} / {@link schemaToIndexes}); `table.remove`\n * emits `DROP TABLE IF EXISTS`; `column.add` / `column.remove` emit `ALTER\n * TABLE … ADD COLUMN` / `… DROP COLUMN`; `index.add` / `index.remove` emit\n * `CREATE INDEX IF NOT EXISTS` / `DROP INDEX IF EXISTS`, naming the index the\n * same way `schemaToIndexes` does (`idx_<table>_<columns joined by _>`) so a\n * plan-built index matches one `open` would have created. Whether the named\n * table actually exists is the caller's concern (a driver's `migrate` checks\n * its own declared schema before running these statements) — this projection\n * is pure and never inspects live state.\n *\n * @param step - The migration step to project\n * @returns The DDL statement(s) that apply the step\n *\n * @example\n * ```ts\n * stepToSQL({ operation: 'column.remove', table: 'users', column: 'legacy' })\n * // ['ALTER TABLE \"users\" DROP COLUMN \"legacy\"']\n * ```\n */\nexport function stepToSQL(step: MigrationStep): readonly string[] {\n\tswitch (step.operation) {\n\t\tcase 'table.add':\n\t\t\treturn [schemaToTable(step.table), ...schemaToIndexes(step.table)]\n\t\tcase 'table.remove':\n\t\t\treturn ['DROP TABLE IF EXISTS ' + quote(step.table)]\n\t\tcase 'column.add':\n\t\t\treturn [\n\t\t\t\t'ALTER TABLE ' +\n\t\t\t\t\tquote(step.table) +\n\t\t\t\t\t' ADD COLUMN ' +\n\t\t\t\t\tquote(step.column.name) +\n\t\t\t\t\t' ' +\n\t\t\t\t\tcolumnSQL(step.column.type),\n\t\t\t]\n\t\tcase 'column.remove':\n\t\t\treturn ['ALTER TABLE ' + quote(step.table) + ' DROP COLUMN ' + quote(step.column)]\n\t\tcase 'index.add':\n\t\t\treturn [\n\t\t\t\t'CREATE INDEX IF NOT EXISTS ' +\n\t\t\t\t\tquote(indexName(step.table, step.index)) +\n\t\t\t\t\t' ON ' +\n\t\t\t\t\tquote(step.table) +\n\t\t\t\t\t' (' +\n\t\t\t\t\tstep.index.map(quote).join(', ') +\n\t\t\t\t\t')',\n\t\t\t]\n\t\tcase 'index.remove':\n\t\t\treturn ['DROP INDEX IF EXISTS ' + quote(indexName(step.table, step.index))]\n\t}\n}\n\n/**\n * Project one {@link MigrationStep} onto its table's declared {@link TableSchema}\n * — the bookkeeping counterpart to {@link stepToSQL} (which projects the DDL a\n * driver's `migrate` runs against the live database).\n *\n * @remarks\n * `column.add` / `column.remove` add / filter the named column;\n * `index.add` / `index.remove` add / filter the matching index group (an exact\n * ordered match on `index`). `table.add` / `table.remove` act on a WHOLE\n * schema map rather than one table's shape, so they are the caller's concern\n * (a driver's `migrate` applies them directly against its table map) — passed\n * here, they return `schema` unchanged.\n *\n * @param schema - The table's current declared schema\n * @param step - The migration step to project onto it\n * @returns The table's schema after the step\n *\n * @example\n * ```ts\n * stepToSchema(schema, { operation: 'column.remove', table: 'users', column: 'legacy' })\n * // schema with the 'legacy' column dropped from `columns`\n * ```\n */\nexport function stepToSchema(schema: TableSchema, step: MigrationStep): TableSchema {\n\tswitch (step.operation) {\n\t\tcase 'column.add':\n\t\t\treturn { ...schema, columns: [...schema.columns, step.column] }\n\t\tcase 'column.remove':\n\t\t\treturn { ...schema, columns: schema.columns.filter((column) => column.name !== step.column) }\n\t\tcase 'index.add':\n\t\t\treturn { ...schema, indexes: [...schema.indexes, step.index] }\n\t\tcase 'index.remove':\n\t\t\treturn {\n\t\t\t\t...schema,\n\t\t\t\tindexes: schema.indexes.filter(\n\t\t\t\t\t(group) =>\n\t\t\t\t\t\t!(\n\t\t\t\t\t\t\tgroup.length === step.index.length &&\n\t\t\t\t\t\t\tgroup.every((name, position) => name === step.index[position])\n\t\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t}\n\t\tcase 'table.add':\n\t\tcase 'table.remove':\n\t\t\treturn schema\n\t}\n}\n","import type { ColumnType, Condition, Criteria, Order, TableSchema } from '@src/core'\nimport type { CompiledSQL, SQLiteValue } from './types.js'\nimport { isString } from '@orkestrel/contract'\nimport { encodeValue, fieldColumn, quote } from './helpers.js'\n\n/**\n * Compile a NESTED {@link FieldPath} to the `json_type(<col>, <path>)` SQL\n * expression — the {@link fieldColumn} `json_extract` sibling used to tell a\n * PRESENT JSON `null` apart from an ABSENT path (both read back as SQL `NULL`\n * through `json_extract`, but `json_type` reports `'null'` for the former and\n * SQL `NULL` for the latter).\n *\n * @param path - The nested field path (a column plus its JSON keys)\n * @returns The SQL expression reading the value's JSON type\n *\n * @example\n * ```ts\n * jsonTypeColumn(['payload', 'user', 'id']) // \"json_type(\\\"payload\\\", '$.user.id')\"\n * ```\n */\nexport function jsonTypeColumn(path: readonly string[]): string {\n\tconst rest = path\n\t\t.slice(1)\n\t\t.map((key) => '.' + key.replaceAll(\"'\", \"''\"))\n\t\t.join('')\n\treturn 'json_type(' + quote(path[0]) + \", '$\" + rest + \"')\"\n}\n\n// The `Criteria` → parameterized SQL compiler — the native-query payoff. It turns\n// a portable `Criteria` (the same one the core engine's `applyCriteria` folds)\n// into the `WHERE` / `ORDER BY` / `LIMIT` tail of a `SELECT`, with bound `?`\n// params in clause order. Its WHERE fold parenthesizes LEFT-TO-RIGHT to match the\n// engine's `matchesCriteria` exactly (NOT SQL's AND-over-OR precedence), so a\n// native read and an engine read agree on every query (the parity test). Branches\n// are centralized and public per AGENTS §5 — no operator logic buried in closures.\n// This module speaks pure strings/values only — it imports no SQLite package.\n\n/**\n * Escape `\\`, `%`, and `_` (each with a leading `\\`) so a `starts` / `ends`\n * operand is matched literally under the `LIKE … ESCAPE '\\'` clause.\n *\n * @param text - The raw operand text\n * @returns The text with LIKE metacharacters escaped\n *\n * @example\n * ```ts\n * escapeLike('50%_off') // '50\\\\%\\\\_off'\n * ```\n */\nexport function escapeLike(text: string): string {\n\treturn text.replaceAll('\\\\', '\\\\\\\\').replaceAll('%', '\\\\%').replaceAll('_', '\\\\_')\n}\n\n/**\n * The declared storage type of a flat (string) column, read from the schema.\n *\n * @param column - The column name\n * @param schema - The table's schema\n * @returns The column's {@link ColumnType}, or `undefined` if the schema does not carry it\n *\n * @example\n * ```ts\n * declaredType('age', schema) // 'integer'\n * ```\n */\nexport function declaredType(column: string, schema: TableSchema): ColumnType | undefined {\n\treturn schema.columns.find((candidate) => candidate.name === column)?.type\n}\n\n/**\n * The storage type a nested (`json_extract`) operand encodes as, derived from its\n * RUNTIME value — NOT `json`.\n *\n * @remarks\n * `json_extract` returns the unquoted, natively-typed scalar (a JSON boolean as\n * `1` / `0`, a number as-is, a string as-is), so the operand must encode to that\n * same scalar to compare. A boolean → `'boolean'` (→ `1` / `0`); a number →\n * `'integer'` / `'real'`; a bigint → `'integer'`; a string → `'text'`; `null` /\n * `undefined` → `'text'` (encodes to `null`); an object / array → `'json'` (the\n * edge of comparing against a json subtree).\n *\n * @param value - The runtime operand value\n * @returns The {@link ColumnType} to encode it as\n *\n * @example\n * ```ts\n * valueType(true) // 'boolean'\n * valueType(9) // 'integer'\n * ```\n */\nexport function valueType(value: unknown): ColumnType {\n\tif (typeof value === 'boolean') return 'boolean'\n\tif (typeof value === 'number') return Number.isInteger(value) ? 'integer' : 'real'\n\tif (typeof value === 'bigint') return 'integer'\n\tif (typeof value === 'object' && value !== null) return 'json'\n\treturn 'text'\n}\n\n/**\n * Compile one condition to its `<column> <operator>` SQL fragment and the params\n * it binds — engine-exact under SQL's three-valued NULL logic.\n *\n * @remarks\n * Every operand is run through `encodeValue`, so a bound value matches the SQL\n * the column side compiles to. A flat column encodes operands with its DECLARED\n * schema type (a flat `json` column → `JSON.stringify`); a nested `FieldPath`\n * encodes each operand as the NATIVE scalar `json_extract` returns, derived from\n * the operand's runtime type (per-operand, since `between` / `any` / `none` can\n * mix types). `any` / `none` collapse an empty list to a constant (`0` matches\n * nothing, `1` matches all) with no params.\n *\n * The core engine's total order ranks `undefined` (rank 0) BELOW `null`\n * (rank 1) (see `compareValues`), so a MISSING/`NULL` column MATCHES\n * `below` / `to` / a scalar `not` / `none` — the opposite of raw SQL, where a\n * comparison against `NULL` is `NULL` (excluded). This fragment replicates the\n * engine exactly. Truth table (`value` = the engine's decoded field read; a\n * FLAT column's stored `NULL` decodes to `undefined` per `decodeRow`, so a\n * flat `value` is NEVER a present `null` — only a NESTED path can be\n * present-but-`null`):\n *\n * ```text\n * operator | value=undefined (absent) | value=null (nested only) | value=scalar\n * --------------------|--------------------------------|---------------------------|-------------\n * equals, first=null | no match | MATCH | no match\n * equals, first=X | no match | no match | value===X\n * not, first=null | MATCH (flat: unconditionally; | no match | MATCH\n * | nested: absent still matches)| |\n * not, first=X | MATCH | MATCH | value!==X\n * below/to, first=X | MATCH (rank 0 < rank(X)) | MATCH (rank 1 < rank(X)) | rank compare\n * none, list=[…] | MATCH (no scalar rank-equal) | MATCH | not-in-list\n * any, list=[…] | no match | no match | in-list\n * above/from/between | no match | no match | rank compare\n * like/glob/starts/… | no match (not a string) | no match | string test\n * present | false | false | true\n * absent | true | true | false\n * ```\n *\n * Because a flat column's `NULL` always decodes to `undefined`, `equals`\n * against a `null` operand needs no special flat compilation (`col = ?`\n * binding a `NULL` param is already always-false in SQL, matching \"no match\"\n * above) — but flat `not` against `null` must match EVERY row (both the\n * absent and the scalar rows), which `col != ? OR col IS NULL` cannot express\n * (it only catches the `IS NULL` row), so a flat `not`-with-`null`-operand\n * compiles to the constant `1`.\n *\n * A NESTED path can be present-but-`null` (a stored JSON `null`), which\n * `json_extract` reads back as SQL `NULL` — indistinguishable from an ABSENT\n * path. `json_type(col, path)` disambiguates them (`'null'` for present-null,\n * SQL `NULL` for absent), so nested `equals` / `not` against a `null` operand\n * compile through `json_type` instead of `IS NULL` / `IS NOT NULL`.\n *\n * Every other MATCH-on-null-or-absent row is expressed uniformly (flat and\n * nested alike) as `(<column> <op> ? OR <column> IS NULL)` — for a nested\n * path, `json_extract` already collapses BOTH absent and present-null to SQL\n * `NULL`, so `IS NULL` catches both in one clause; for a flat column there is\n * only the absent case to catch.\n *\n * @param condition - The condition to compile\n * @param schema - The table's schema (for declared column types)\n * @returns The SQL fragment and its bound parameters\n *\n * @example\n * ```ts\n * fragment({ column: 'age', operator: 'above', values: [18], connector: 'and' }, schema)\n * // { sql: '\"age\" > ?', params: [18] }\n * fragment({ column: 'age', operator: 'below', values: [18], connector: 'and' }, schema)\n * // { sql: '(\"age\" < ? OR \"age\" IS NULL)', params: [18] }\n * ```\n */\nexport function fragment(condition: Condition, schema: TableSchema): CompiledSQL {\n\tconst column = fieldColumn(condition.column)\n\tconst nested = !isString(condition.column)\n\tconst declared = isString(condition.column) ? declaredType(condition.column, schema) : undefined\n\tconst encode = (value: unknown): SQLiteValue =>\n\t\tencodeValue(value, nested ? valueType(value) : (declared ?? 'json'))\n\tconst first = condition.values[0]\n\tconst second = condition.values[1]\n\tconst nullOperand = first === null || first === undefined\n\t// The nested `json_type` read — built only when `condition.column` is an\n\t// array (a nested path) — disambiguates a present JSON `null` from an\n\t// absent path under `equals` / `not` (see the truth table above).\n\tconst jsonType = !isString(condition.column) ? jsonTypeColumn(condition.column) : ''\n\tswitch (condition.operator) {\n\t\tcase 'equals':\n\t\t\tif (nullOperand && nested) return { sql: jsonType + \" = 'null'\", params: [] }\n\t\t\treturn { sql: column + ' = ?', params: [encode(first)] }\n\t\tcase 'not':\n\t\t\tif (nullOperand) {\n\t\t\t\tif (nested) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsql: '(' + jsonType + ' IS NULL OR ' + jsonType + \" != 'null')\",\n\t\t\t\t\t\tparams: [],\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// A flat column's decoded value is never a present null, so\n\t\t\t\t// `compareValues(value, null)` is nonzero for EVERY row (absent or\n\t\t\t\t// scalar) — the engine's `not null` matches unconditionally.\n\t\t\t\treturn { sql: '1', params: [] }\n\t\t\t}\n\t\t\treturn { sql: '(' + column + ' != ? OR ' + column + ' IS NULL)', params: [encode(first)] }\n\t\tcase 'above':\n\t\t\treturn { sql: column + ' > ?', params: [encode(first)] }\n\t\tcase 'below':\n\t\t\treturn { sql: '(' + column + ' < ? OR ' + column + ' IS NULL)', params: [encode(first)] }\n\t\tcase 'from':\n\t\t\treturn { sql: column + ' >= ?', params: [encode(first)] }\n\t\tcase 'to':\n\t\t\treturn { sql: '(' + column + ' <= ? OR ' + column + ' IS NULL)', params: [encode(first)] }\n\t\tcase 'between':\n\t\t\treturn { sql: column + ' BETWEEN ? AND ?', params: [encode(first), encode(second)] }\n\t\tcase 'like':\n\t\t\treturn { sql: column + ' LIKE ?', params: [encode(first)] }\n\t\tcase 'glob':\n\t\t\treturn { sql: column + ' GLOB ?', params: [encode(first)] }\n\t\tcase 'starts': {\n\t\t\t// Case-sensitive, exact compile (replaces the old LIKE-based one, which\n\t\t\t// was ASCII-only case-INsensitive — a mismatch with the engine's\n\t\t\t// case-sensitive `String.startsWith`). `substr` counts CODE POINTS, so\n\t\t\t// the length is a code-point count (`Array.from`), not `.length`. An\n\t\t\t// empty operand matches every text-column value (the engine: every\n\t\t\t// string starts with '').\n\t\t\tconst text = isString(first) ? first : ''\n\t\t\tif (text === '') return { sql: 'typeof(' + column + \") = 'text'\", params: [] }\n\t\t\tconst length = Array.from(text).length\n\t\t\treturn {\n\t\t\t\tsql: '(typeof(' + column + \") = 'text' AND substr(\" + column + ', 1, ' + length + ') = ?)',\n\t\t\t\tparams: [encode(first)],\n\t\t\t}\n\t\t}\n\t\tcase 'ends': {\n\t\t\t// Mirror of `starts`: `substr(<col>, -N)` (SQLite's 2-arg form counts\n\t\t\t// from the right when N is negative) reads the last N code points.\n\t\t\tconst text = isString(first) ? first : ''\n\t\t\tif (text === '') return { sql: 'typeof(' + column + \") = 'text'\", params: [] }\n\t\t\tconst length = Array.from(text).length\n\t\t\treturn {\n\t\t\t\tsql: '(typeof(' + column + \") = 'text' AND substr(\" + column + ', -' + length + ') = ?)',\n\t\t\t\tparams: [encode(first)],\n\t\t\t}\n\t\t}\n\t\tcase 'any':\n\t\t\tif (condition.values.length === 0) return { sql: '0', params: [] }\n\t\t\treturn {\n\t\t\t\tsql: column + ' IN (' + condition.values.map(() => '?').join(', ') + ')',\n\t\t\t\tparams: condition.values.map(encode),\n\t\t\t}\n\t\tcase 'none':\n\t\t\tif (condition.values.length === 0) return { sql: '1', params: [] }\n\t\t\treturn {\n\t\t\t\tsql:\n\t\t\t\t\t'(' +\n\t\t\t\t\tcolumn +\n\t\t\t\t\t' NOT IN (' +\n\t\t\t\t\tcondition.values.map(() => '?').join(', ') +\n\t\t\t\t\t') OR ' +\n\t\t\t\t\tcolumn +\n\t\t\t\t\t' IS NULL)',\n\t\t\t\tparams: condition.values.map(encode),\n\t\t\t}\n\t\tcase 'absent':\n\t\t\treturn { sql: column + ' IS NULL', params: [] }\n\t\tcase 'present':\n\t\t\treturn { sql: column + ' IS NOT NULL', params: [] }\n\t}\n}\n\n/**\n * Fold the conditions into one WHERE clause, parenthesizing progressively\n * left-to-right so the grouping matches the engine's `matchesCriteria` fold.\n *\n * @remarks\n * The first condition's connector is ignored, per the {@link Condition} types.\n * Every fragment (see {@link fragment}'s truth table) replicates the core\n * engine's total order EXACTLY under SQL's three-valued NULL logic, so this\n * clause matches `applyCriteria` row-for-row over the same table — a native\n * `records` / `count` read never disagrees with a scan-and-filter fallback.\n *\n * @param conditions - The conditions to fold\n * @param schema - The table's schema\n * @returns The `WHERE …` clause and its bound parameters, or an empty clause for zero conditions\n *\n * @example\n * ```ts\n * compileWhere([{ column: 'age', operator: 'from', values: [18], connector: 'and' }], schema)\n * // { sql: 'WHERE \"age\" >= ?', params: [18] }\n * ```\n */\nexport function compileWhere(conditions: readonly Condition[], schema: TableSchema): CompiledSQL {\n\tif (conditions.length === 0) return { sql: '', params: [] }\n\tconst head = fragment(conditions[0], schema)\n\tlet clause = head.sql\n\tconst params: SQLiteValue[] = [...head.params]\n\tfor (let index = 1; index < conditions.length; index += 1) {\n\t\tconst next = fragment(conditions[index], schema)\n\t\tconst operator = conditions[index].connector === 'or' ? 'OR' : 'AND'\n\t\tclause = '(' + clause + ' ' + operator + ' ' + next.sql + ')'\n\t\tparams.push(...next.params)\n\t}\n\treturn { sql: 'WHERE ' + clause, params }\n}\n\n/**\n * Compile the ORDER BY clause from the order terms, always ending with the\n * primary key as the final determinant.\n *\n * @remarks\n * The native `records` read then resolves ties in key order, matching a\n * primary-key-ordered `scan` and the core engine's stable `sortRows` over a\n * key-ordered scan (and IndexedDB's key-ordered reads), so a native read equals\n * the scan path (AGENTS §21 / §22 native ↔ engine parity). SQLite without an\n * `ORDER BY` returns rowid (insertion) order, and an explicit order alone breaks\n * ties by rowid too — both diverge from every key-ordered backend. The\n * tie-breaker is ASCENDING regardless of the explicit directions: the engine's\n * stable sort runs over key-ascending input, so equal rows stay in\n * ascending-key order whichever way the explicit terms point. Skipped when the\n * primary is already an explicit order term (no double-append).\n *\n * @param order - The explicit order terms, or `undefined`\n * @param schema - The table's schema (for the primary key)\n * @returns The `ORDER BY …` clause, or an empty string when there is nothing to order by\n *\n * @example\n * ```ts\n * compileOrder([{ column: 'age', direction: 'descending' }], schema)\n * // 'ORDER BY \"age\" DESC, \"id\"'\n * ```\n */\nexport function compileOrder(order: readonly Order[] | undefined, schema: TableSchema): string {\n\tconst terms = (order ?? []).map(\n\t\t(term) => fieldColumn(term.column) + (term.direction === 'descending' ? ' DESC' : ' ASC'),\n\t)\n\tconst ordersByPrimary = (order ?? []).some(\n\t\t(term) => isString(term.column) && term.column === schema.primary,\n\t)\n\tif (!ordersByPrimary) terms.push(quote(schema.primary))\n\treturn terms.length === 0 ? '' : 'ORDER BY ' + terms.join(', ')\n}\n\n/**\n * Compile the LIMIT / OFFSET clause.\n *\n * @remarks\n * An offset without a limit uses `LIMIT -1` (SQLite's \"no limit\") so OFFSET is\n * still honored.\n *\n * @param limit - The maximum row count, or `undefined`\n * @param offset - The row count to skip, or `undefined`\n * @returns The `LIMIT …` clause and its bound parameters, or an empty clause when neither is set\n *\n * @example\n * ```ts\n * compilePage(undefined, 5) // { sql: 'LIMIT -1 OFFSET ?', params: [5] }\n * ```\n */\nexport function compilePage(limit: number | undefined, offset: number | undefined): CompiledSQL {\n\tif (limit !== undefined && offset !== undefined) {\n\t\treturn { sql: 'LIMIT ? OFFSET ?', params: [limit, offset] }\n\t}\n\tif (limit !== undefined) return { sql: 'LIMIT ?', params: [limit] }\n\tif (offset !== undefined) return { sql: 'LIMIT -1 OFFSET ?', params: [offset] }\n\treturn { sql: '', params: [] }\n}\n\n/**\n * Compile a {@link Criteria} into the SQL clause that follows a table name, with\n * its bound parameters in clause order.\n *\n * @remarks\n * The driver's native `records` / `count` path: it assembles\n * `[where, orderBy, limitOffset]` (each possibly empty) into one clause so a\n * `SELECT * FROM <table> <clause>` runs the whole read in the engine instead of\n * over a JS `scan`. The WHERE fold is parenthesized **left-to-right** to mirror\n * the core engine's `matchesCriteria` (not SQL's native AND-over-OR precedence),\n * so a native and an engine read return identical rows. Each operand is encoded\n * via `encodeValue`: a flat column uses its declared schema type, while a nested\n * `FieldPath` (a `json_extract` read) encodes each operand as the native scalar\n * the extract returns — derived from the operand's runtime type — so it compares.\n * The 15 operators map per the databases guide's operator table, with\n * `starts` / `ends` using `LIKE … ESCAPE '\\'` and an empty `any` / `none` list\n * collapsing to a constant. A `undefined` criteria (or one with no parts)\n * compiles to an empty clause.\n *\n * @param criteria - The read specification, or `undefined` for all rows\n * @param schema - The table's schema (column types for operand encoding)\n * @returns The SQL tail and its bound parameters\n *\n * @example\n * ```ts\n * compileCriteria({ conditions: [{ column: 'age', operator: 'from', values: [18], connector: 'and' }] }, schema)\n * // { sql: 'WHERE \"age\" >= ? ORDER BY \"id\"', params: [18] }\n * ```\n */\nexport function compileCriteria(criteria: Criteria | undefined, schema: TableSchema): CompiledSQL {\n\tconst where = compileWhere(criteria?.conditions ?? [], schema)\n\tconst orderBy = compileOrder(criteria?.order, schema)\n\tconst page = compilePage(criteria?.limit, criteria?.offset)\n\tconst sql = [where.sql, orderBy, page.sql].filter((part) => part !== '').join(' ')\n\treturn { sql, params: [...where.params, ...page.params] }\n}\n","// The server surface's shared constants — reserved names its drivers claim.\n\n/**\n * The reserved metadata table the {@link SQLiteDriver} creates on `open` to\n * persist its stamped `DriverMeta` (`version` + declared schema JSON) — the\n * SQLite realization of the `meta` / `stamp` driver hooks.\n *\n * @remarks\n * A single-row table (`id = 1`). A user table named `_meta` collides with the\n * reservation — the caller's concern to avoid, documented on the driver class.\n */\nexport const META_TABLE = '_meta'\n","import type {\n\tCriteria,\n\tDriverInterface,\n\tDriverMeta,\n\tKey,\n\tMigration,\n\tRow,\n\tTableSchema,\n\tTransactionInterface,\n} from '@src/core'\nimport { DatabaseError, MemoryDriver, extractKey, isDriverMeta } from '@src/core'\nimport { isRecord } from '@orkestrel/contract'\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\n\n/**\n * A persistent {@link DriverInterface} backed by a single JSON file — the\n * reference {@link MemoryDriver} plus file load / flush.\n *\n * @remarks\n * A decorator, not a reimplementation: every primitive delegates to an inner\n * {@link MemoryDriver}, so querying, key-order `scan` / `keys`, and capture-replay\n * `snapshot` are inherited unchanged — this layer adds only persistence. `open`\n * loads the file into memory; every mutation (`write` / `delete` / `clear`) flushes\n * the whole store back. The file is one JSON object, `{ meta?: DriverMeta, tables: {\n * [name]: rows } }` — `meta` is present only once the store has been `stamp`ed\n * (an unstamped store serializes the old `{ tables }` shape, preserving\n * backward compatibility); a per-table array of rows, each row carrying its own\n * primary (the table contract), so the key is recovered on load with\n * {@link extractKey} and the file need not store it. The parsed JSON crosses the\n * boundary as `unknown` and is narrowed with {@link isRecord} / {@link extractKey},\n * never asserted (AGENTS §14): a missing, corrupt, or wrong-shaped file starts\n * empty rather than throwing, and a malformed row (or malformed `meta`) is\n * skipped/dropped rather than thrown on. It is scan-only — it implements none of\n * the optional native `records` / `count` / `aggregate` hooks, so the core engine\n * over `scan` answers every query. For development, small datasets, and portable /\n * inspectable data; for large or concurrent workloads reach for a SQLite-backed\n * driver.\n *\n * A failure in the write path ({@link JSONDriver.#serialize} — `mkdir` /\n * `writeFile` / `rename`) is wrapped and rethrown as `DatabaseError` `DRIVER`,\n * carrying the target `path` in its context; the read path ({@link\n * JSONDriver.#load}) tolerance above is a separate, deliberate contract and is\n * never touched by this wrapping.\n */\nexport class JSONDriver implements DriverInterface {\n\treadonly #path: string\n\treadonly #memory = new MemoryDriver()\n\t#schema: readonly TableSchema[] = []\n\t#meta: DriverMeta | undefined\n\t#flushCount = 0\n\t// Serializes #flush calls — each queued flush awaits the prior one before\n\t// serializing state, so the persisted snapshot always reflects the latest\n\t// memory state (see #flush @remarks).\n\t#chain: Promise<void> = Promise.resolve()\n\t// Set while a transaction() handle is active — suppresses #flush from\n\t// write/delete/clear so N mutations under the handle cost one file write\n\t// (on commit) instead of N (see transaction @remarks). Cleared by\n\t// commit/rollback, which is also how double-settle is detected.\n\t#deferring = false\n\n\tconstructor(path: string) {\n\t\tthis.#path = path\n\t}\n\n\tasync open(schema: readonly TableSchema[]): Promise<void> {\n\t\tthis.#schema = schema\n\t\tawait this.#memory.open(schema)\n\t\tawait this.#load()\n\t}\n\n\tasync close(): Promise<void> {\n\t\tawait this.#memory.close()\n\t}\n\n\tasync read(table: string, key: Key): Promise<Row | undefined> {\n\t\treturn this.#memory.read(table, key)\n\t}\n\n\tasync write(table: string, key: Key, row: Row): Promise<void> {\n\t\tawait this.#memory.write(table, key, row)\n\t\tif (!this.#deferring) await this.#flush()\n\t}\n\n\tasync delete(table: string, key: Key): Promise<boolean> {\n\t\tconst removed = await this.#memory.delete(table, key)\n\t\tif (!this.#deferring) await this.#flush()\n\t\treturn removed\n\t}\n\n\tkeys(table: string): Promise<readonly Key[]> {\n\t\treturn this.#memory.keys(table)\n\t}\n\n\tscan(table: string): AsyncIterable<Row> {\n\t\treturn this.#memory.scan(table)\n\t}\n\n\t/**\n\t * Natively filtered lazy iteration — delegates to the inner {@link MemoryDriver}.\n\t *\n\t * @remarks\n\t * Semantics are the memory driver's own: `criteria.conditions` filters, `offset`\n\t * / `limit` page lazily, and `criteria.order` is ignored (streaming yields key\n\t * order; sorted output is `records()`'s job).\n\t *\n\t * @param table - The table to stream\n\t * @param criteria - The filter / offset / limit to apply lazily\n\t */\n\tstream(table: string, criteria: Criteria): AsyncIterable<Row> {\n\t\treturn this.#memory.stream(table, criteria)\n\t}\n\n\tasync clear(table: string): Promise<void> {\n\t\tawait this.#memory.clear(table)\n\t\tif (!this.#deferring) await this.#flush()\n\t}\n\n\t/**\n\t * Begin a native transaction — flush-coalescing over the inner {@link MemoryDriver}.\n\t *\n\t * @remarks\n\t * Single-writer: throws `DatabaseError` `CONFLICT` if a transaction is already\n\t * active — this driver does not support nesting. On begin, captures the inner\n\t * memory rollback thunk via `#memory.snapshot()` and suppresses per-mutation\n\t * `#flush` — `write` / `delete` / `clear` still mutate memory but no longer\n\t * touch the file, so N mutations under the handle cost ONE file write instead\n\t * of N. `commit()` releases the suppression and performs that one atomic\n\t * `#flush()`, persisting the transaction's net state. `rollback()` restores\n\t * memory via the captured snapshot thunk, then `#flush()`s so the file reflects\n\t * the restored state. Outside a transaction, behavior is unchanged — every\n\t * mutation flushes on its own. Calling `commit` / `rollback` a second time (on\n\t * either method, in either order) throws `DatabaseError` `CONFLICT`.\n\t *\n\t * @returns A {@link TransactionInterface} handle to `commit` or `rollback`\n\t */\n\tasync transaction(): Promise<TransactionInterface> {\n\t\tif (this.#deferring) {\n\t\t\tthrow new DatabaseError('CONFLICT', 'A transaction is already active on this driver', {})\n\t\t}\n\t\tconst rollback = await this.#memory.snapshot()\n\t\tthis.#deferring = true\n\t\tlet settled = false\n\t\treturn {\n\t\t\tcommit: async () => {\n\t\t\t\tif (settled) {\n\t\t\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction already settled', {})\n\t\t\t\t}\n\t\t\t\tsettled = true\n\t\t\t\tthis.#deferring = false\n\t\t\t\tawait this.#flush()\n\t\t\t},\n\t\t\trollback: async () => {\n\t\t\t\tif (settled) {\n\t\t\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction already settled', {})\n\t\t\t\t}\n\t\t\t\tsettled = true\n\t\t\t\tawait rollback()\n\t\t\t\tthis.#deferring = false\n\t\t\t\tawait this.#flush()\n\t\t\t},\n\t\t}\n\t}\n\n\tasync snapshot(tables?: readonly string[]): Promise<() => Promise<void>> {\n\t\tconst rollback = await this.#memory.snapshot(tables)\n\t\t// Restore the in-memory state, then re-persist it — the file was rewritten\n\t\t// on each write during the scope, so a rollback must flush the restored state.\n\t\treturn async () => {\n\t\t\tawait rollback()\n\t\t\tawait this.#flush()\n\t\t}\n\t}\n\n\tasync meta(): Promise<DriverMeta | undefined> {\n\t\treturn this.#meta\n\t}\n\n\t/**\n\t * Persist `meta` verbatim for a later `meta()` to return.\n\t *\n\t * @remarks\n\t * Respects the same defer-flush suppression as `write` / `delete` / `clear`\n\t * (see {@link JSONDriver.transaction} @remarks) — stamping inside an active\n\t * transaction updates memory but does not flush until the transaction settles.\n\t *\n\t * @param meta - The {@link DriverMeta} to persist\n\t */\n\tasync stamp(meta: DriverMeta): Promise<void> {\n\t\tthis.#meta = meta\n\t\tif (!this.#deferring) await this.#flush()\n\t}\n\n\t/**\n\t * Apply a {@link Migration} plan by delegating to the inner {@link MemoryDriver},\n\t * then persist the migrated state.\n\t *\n\t * @remarks\n\t * The inner `MemoryDriver.migrate` applies each step (adding/removing tables,\n\t * adding/removing columns from stored rows, no-op index steps) and throws\n\t * `DatabaseError` `MIGRATION` for a step referencing an unknown table — that\n\t * error propagates untouched. `table.add` / `table.remove` steps also update\n\t * this driver's own declared `#schema`, mirroring the bookkeeping `open` does,\n\t * so a subsequent `#flush` / `#load` round-trip includes (or drops) the table.\n\t * A successful migration ends with one atomic `#flush()` so the new state\n\t * survives a close and reopen. A multi-step plan applies its steps\n\t * sequentially and is NOT atomic — a failure partway through a plan leaves\n\t * the earlier steps already applied.\n\t *\n\t * @param plan - The migration plan to apply\n\t */\n\tasync migrate(plan: Migration): Promise<void> {\n\t\tawait this.#memory.migrate?.(plan)\n\t\tlet schema = this.#schema\n\t\tfor (const step of plan.steps) {\n\t\t\tif (step.operation === 'table.add') {\n\t\t\t\tschema = schema.some((table) => table.name === step.table.name)\n\t\t\t\t\t? schema\n\t\t\t\t\t: [...schema, step.table]\n\t\t\t} else if (step.operation === 'table.remove') {\n\t\t\t\tschema = schema.filter((table) => table.name !== step.table)\n\t\t\t}\n\t\t}\n\t\tthis.#schema = schema\n\t\tawait this.#flush()\n\t}\n\n\t// === Private\n\n\t// Load the file into memory; a missing / corrupt / wrong-shaped file starts\n\t// empty (never throws). Each entry is narrowed via isRecord and its key recovered\n\t// with extractKey from the schema's primary column; bad entries are skipped. A\n\t// `meta` block is narrowed with the same tolerance — a malformed or absent\n\t// `meta` leaves #meta undefined (unstamped) rather than throwing, which is how\n\t// an old-format file (no `meta` key) is distinguished from a stamped one.\n\tasync #load(): Promise<void> {\n\t\tlet raw: string\n\t\ttry {\n\t\t\traw = await readFile(this.#path, 'utf-8')\n\t\t} catch {\n\t\t\treturn\n\t\t}\n\t\tlet parsed: unknown\n\t\ttry {\n\t\t\tparsed = JSON.parse(raw)\n\t\t} catch {\n\t\t\treturn\n\t\t}\n\t\tif (!isRecord(parsed) || !isRecord(parsed.tables)) return\n\t\tconst tables = parsed.tables\n\t\tfor (const table of this.#schema) {\n\t\t\tconst rows = tables[table.name]\n\t\t\tif (!Array.isArray(rows)) continue\n\t\t\tfor (const entry of rows) {\n\t\t\t\tif (!isRecord(entry)) continue\n\t\t\t\tconst key = extractKey(entry, table.primary)\n\t\t\t\tif (key === undefined) continue\n\t\t\t\tawait this.#memory.write(table.name, key, entry)\n\t\t\t}\n\t\t}\n\t\tif (isDriverMeta(parsed.meta)) this.#meta = parsed.meta\n\t}\n\n\t// Queue a flush behind #chain — see #flush @remarks for why.\n\tasync #flush(): Promise<void> {\n\t\tconst next = this.#chain.then(() => this.#serialize())\n\t\t// Swallow so a failed flush doesn't leave #chain permanently rejected and\n\t\t// block every later flush; the caller of THIS #flush still observes the\n\t\t// rejection via `next` below.\n\t\tthis.#chain = next.catch(() => {})\n\t\tawait next\n\t}\n\n\t// Drain every declared table's rows from memory (in key order) and write the\n\t// whole store back as one pretty-printed JSON object, creating the directory.\n\t//\n\t// @remarks\n\t// Written atomically: the payload lands in a sibling temp file (same directory,\n\t// so the platform rename is atomic) and is then renamed onto `#path`. A crash\n\t// mid-flush can no longer truncate or corrupt the previous good file — POSIX\n\t// `rename` replaces the destination in one indivisible step, so a reader always\n\t// sees either the old file or the fully-written new one, never a partial write.\n\t// `#flush` serializes calls to this method through `#chain` — each flush AWAITS\n\t// its predecessor before draining `#memory` and writing, so the payload always\n\t// reflects the latest memory state. Without this, overlapping flushes triggered\n\t// by non-awaited concurrent mutations could serialize out of order and persist a\n\t// stale snapshot as the \"latest\" file. `meta` is included in the payload only\n\t// once the store has been stamped, so an unstamped store keeps serializing the\n\t// old `{ tables }` shape (backward compat). Any failure in this write path\n\t// (`mkdir` / `writeFile` / `rename`) is wrapped as `DatabaseError` `DRIVER`\n\t// carrying `path` in its context, after the temp-file cleanup below runs.\n\tasync #serialize(): Promise<void> {\n\t\tconst tables: Record<string, readonly Row[]> = {}\n\t\tfor (const table of this.#schema) {\n\t\t\tconst rows: Row[] = []\n\t\t\tfor await (const row of this.#memory.scan(table.name)) rows.push(row)\n\t\t\ttables[table.name] = rows\n\t\t}\n\t\tthis.#flushCount += 1\n\t\tconst temp = `${this.#path}.${process.pid}.${this.#flushCount}.tmp`\n\t\tconst payload = this.#meta === undefined ? { tables } : { meta: this.#meta, tables }\n\t\ttry {\n\t\t\tawait mkdir(dirname(this.#path), { recursive: true })\n\t\t\tawait writeFile(temp, JSON.stringify(payload, null, 2), 'utf-8')\n\t\t\tawait rename(temp, this.#path)\n\t\t} catch (error) {\n\t\t\tawait rm(temp, { force: true }).catch(() => {})\n\t\t\tthrow new DatabaseError('DRIVER', 'Failed to persist the database file', {\n\t\t\t\tpath: this.#path,\n\t\t\t\tcause: error,\n\t\t\t})\n\t\t}\n\t}\n}\n","import type {\n\tAggregateFunction,\n\tCriteria,\n\tDriverInterface,\n\tDriverMeta,\n\tKey,\n\tMigration,\n\tRow,\n\tTableSchema,\n\tTransactionInterface,\n} from '@src/core'\nimport type { FieldPath } from '@orkestrel/contract'\nimport type { SQLiteDatabaseInterface, SQLiteRow, SQLiteValue } from '@orkestrel/sqlite'\nimport type { SQLiteDriverOptions } from '../types.js'\nimport {\n\tapplyCriteria,\n\tcomputeAggregate,\n\tDatabaseError,\n\tfilterRows,\n\tisDriverMeta,\n\tmatchesCriteria,\n} from '@src/core'\nimport { isString } from '@orkestrel/contract'\nimport { createSQLiteDatabase, isSQLiteError } from '@orkestrel/sqlite'\nimport { compileCriteria, compileWhere } from '../compilers.js'\nimport {\n\taggregateSQL,\n\tdecodeRow,\n\tencodeRow,\n\tencodeValue,\n\tisExactCondition,\n\tisExactCriteria,\n\tquote,\n\tschemaToIndexes,\n\tschemaToTable,\n\tstepToSchema,\n\tstepToSQL,\n} from '../helpers.js'\nimport { META_TABLE } from '../constants.js'\n\n/**\n * The SQLite {@link DriverInterface} — the server-native, trusted-mode backend\n * built on the published `@orkestrel/sqlite` synchronous wrapper.\n *\n * @remarks\n * A thin adapter: it implements the storage primitives the core database layer\n * needs by delegating to the wrapper's prepared statements — it never touches\n * raw `node:sqlite`. `open` issues `CREATE TABLE IF NOT EXISTS` with real typed\n * columns (mapped from each {@link TableSchema}'s portable column types) and a\n * `PRIMARY KEY`, plus a `CREATE INDEX IF NOT EXISTS` per declared index (both\n * reopen-safe), and readies a reserved `_meta` single-row table `meta()` /\n * `stamp()` read and write — **a user table named `_meta` collides with it**;\n * avoid the name. Rows cross the boundary through the codecs in `helpers.ts`\n * (`json` columns store / parse JSON text, a `boolean` stores `1` / `0`), so the\n * typed layer above imposes the exact shape (AGENTS §14). `write` is an\n * `INSERT OR REPLACE` upsert — the `Table` layer detects a `CONFLICT` via a\n * prior `has`, so this never translates a constraint error; a backend\n * `SQLiteError` otherwise propagates unchanged. Querying, ordering, paging, and\n * aggregation are native: `records` / `count` / `stream` compile a `Criteria`\n * to SQL with `compileCriteria`, and `aggregate` runs a SQL\n * `COUNT`/`SUM`/`AVG`/`MIN`/`MAX` (via `aggregateSQL`) over the same compiled\n * WHERE. `transaction` wraps native `BEGIN` / `COMMIT` / `ROLLBACK` with\n * double-settle guards. `migrate` runs the plan's projected DDL\n * ({@link import('../helpers.js').stepToSQL}) inside whichever native\n * transaction is active: joined into an already-open `transaction()` handle\n * when one exists (the core's versioned reconcile path wraps migrate + stamp\n * in one native `BEGIN`, and node:sqlite rejects a nested `BEGIN`), or inside\n * its own `database.transaction` otherwise — a mid-plan failure rolls back\n * atomically either way, an improvement over the non-atomic `MemoryDriver` /\n * `JSONDriver` migrate; a step referencing an undeclared table throws\n * `DatabaseError` `MIGRATION` before any DDL for that step runs. `snapshot` is\n * capture-replay (SELECT the\n * named tables' rows, replay via DELETE + INSERT OR REPLACE inside a native\n * transaction on rollback) rather than a SQL `SAVEPOINT`, since the core\n * `transaction` calls the rollback thunk only on failure with no commit-on-\n * success signal — a long-lived `SAVEPOINT` would leave the connection\n * uncommitted (lost on close). Every backend interaction runs through `#guard`,\n * which maps a thrown backend `SQLiteError` (or any unexpected non-`SQLiteError`\n * throw) to a typed {@link DatabaseError} — never a raw backend error escapes\n * `DriverInterface`: `CONSTRAINT` → `CONFLICT`, the wrapper's own `CLOSED` →\n * `CLOSED`, `BUSY` (a locked database that outlasted the configured `timeout`)\n * → a retryable `DRIVER` (`context.retryable` is `true`), and `UNKNOWN` / any\n * other throw → `DRIVER`. The original error is preserved as `context.cause`.\n * A `DatabaseError` this driver throws directly (`CLOSED` from the `#require`\n * gate, `NOT_FOUND` from `#table`, `MIGRATION` from a migration-plan fault)\n * passes through `#guard` unchanged, never re-wrapped.\n */\nexport class SQLiteDriver implements DriverInterface {\n\treadonly #path: string\n\treadonly #options: SQLiteDriverOptions\n\t#database: SQLiteDatabaseInterface | undefined\n\t#schema = new Map<string, TableSchema>()\n\t#transacting = false\n\n\tconstructor(path: string, options?: SQLiteDriverOptions) {\n\t\tthis.#path = path\n\t\tthis.#options = options ?? {}\n\t}\n\n\tasync open(schema: readonly TableSchema[]): Promise<void> {\n\t\tif (schema.some((table) => table.name === META_TABLE)) {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'VALIDATION',\n\t\t\t\t`A declared table cannot be named '${META_TABLE}' — it is reserved for driver metadata`,\n\t\t\t\t{ table: META_TABLE },\n\t\t\t)\n\t\t}\n\t\tthis.#guard(() => {\n\t\t\tthis.#database?.close()\n\t\t\tconst database = createSQLiteDatabase({\n\t\t\t\tpath: this.#path,\n\t\t\t\treadonly: this.#options.readonly,\n\t\t\t\ttimeout: this.#options.timeout,\n\t\t\t\tforeignKeys: this.#options.foreignKeys,\n\t\t\t})\n\t\t\tdatabase.connect()\n\t\t\tfor (const [name, value] of Object.entries(this.#options.pragmas ?? {})) {\n\t\t\t\tdatabase.pragma(name, value)\n\t\t\t}\n\t\t\tconst map = new Map<string, TableSchema>()\n\t\t\tfor (const table of schema) {\n\t\t\t\tmap.set(table.name, table)\n\t\t\t\tdatabase.exec(schemaToTable(table))\n\t\t\t\tfor (const sql of schemaToIndexes(table)) database.exec(sql)\n\t\t\t}\n\t\t\tdatabase.exec(\n\t\t\t\t'CREATE TABLE IF NOT EXISTS ' +\n\t\t\t\t\tquote(META_TABLE) +\n\t\t\t\t\t' (\"id\" INTEGER, \"version\" INTEGER, \"schema\" TEXT, PRIMARY KEY (\"id\"))',\n\t\t\t)\n\t\t\tthis.#schema = map\n\t\t\tthis.#database = database\n\t\t})\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.#database?.close()\n\t\tthis.#database = undefined\n\t}\n\n\tasync read(table: string, key: Key): Promise<Row | undefined> {\n\t\tconst schema = this.#table(table)\n\t\treturn this.#guard(() => {\n\t\t\tconst row = this.#require()\n\t\t\t\t.prepare('SELECT * FROM ' + quote(table) + ' WHERE ' + quote(schema.primary) + ' = ?')\n\t\t\t\t.get([this.#key(key, schema)])\n\t\t\treturn row === undefined ? undefined : decodeRow(row, schema)\n\t\t})\n\t}\n\n\tasync write(table: string, key: Key, row: Row): Promise<void> {\n\t\tconst schema = this.#table(table)\n\t\tthis.#guard(() => {\n\t\t\tconst encoded = encodeRow({ ...row, [schema.primary]: key }, schema)\n\t\t\tconst names = schema.columns.map((column) => column.name)\n\t\t\tconst values = names.map((name) => encoded[name])\n\t\t\tthis.#require()\n\t\t\t\t.prepare(\n\t\t\t\t\t'INSERT OR REPLACE INTO ' +\n\t\t\t\t\t\tquote(table) +\n\t\t\t\t\t\t' (' +\n\t\t\t\t\t\tnames.map(quote).join(', ') +\n\t\t\t\t\t\t') VALUES (' +\n\t\t\t\t\t\tnames.map(() => '?').join(', ') +\n\t\t\t\t\t\t')',\n\t\t\t\t)\n\t\t\t\t.run(values)\n\t\t})\n\t}\n\n\tasync delete(table: string, key: Key): Promise<boolean> {\n\t\tconst schema = this.#table(table)\n\t\treturn this.#guard(() => {\n\t\t\tconst result = this.#require()\n\t\t\t\t.prepare('DELETE FROM ' + quote(table) + ' WHERE ' + quote(schema.primary) + ' = ?')\n\t\t\t\t.run([this.#key(key, schema)])\n\t\t\treturn result.changes > 0\n\t\t})\n\t}\n\n\tasync keys(table: string): Promise<readonly Key[]> {\n\t\tconst schema = this.#table(table)\n\t\treturn this.#guard(() => {\n\t\t\tconst primary = quote(schema.primary)\n\t\t\t// ORDER BY the primary key: the contract lists keys in key order, and\n\t\t\t// SQLite returns rows in rowid (insertion) order without it.\n\t\t\tconst rows = this.#require()\n\t\t\t\t.prepare('SELECT ' + primary + ' FROM ' + quote(table) + ' ORDER BY ' + primary)\n\t\t\t\t.all()\n\t\t\tconst keys: Key[] = []\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst value = row[schema.primary]\n\t\t\t\tif (typeof value === 'string' || typeof value === 'number') keys.push(value)\n\t\t\t}\n\t\t\treturn keys\n\t\t})\n\t}\n\n\tasync *scan(table: string): AsyncIterable<Row> {\n\t\tconst schema = this.#table(table)\n\t\t// ORDER BY the primary key so the scan yields rows in key order (the engine\n\t\t// and cursors depend on it), not SQLite's default rowid order. Every step —\n\t\t// the iterator setup, each `next()` pull, and each row's decode — runs\n\t\t// through #guard, so a mid-iteration backend fault (not just the initial\n\t\t// call) surfaces as a mapped DatabaseError rather than leaking raw.\n\t\tconst iterator = this.#guard(() =>\n\t\t\tthis.#require()\n\t\t\t\t.prepare('SELECT * FROM ' + quote(table) + ' ORDER BY ' + quote(schema.primary))\n\t\t\t\t.iterate(),\n\t\t)[Symbol.iterator]()\n\t\twhile (true) {\n\t\t\tconst step = this.#guard(() => iterator.next())\n\t\t\tif (step.done === true) return\n\t\t\tyield this.#guard(() => decodeRow(step.value, schema))\n\t\t}\n\t}\n\n\tasync clear(table: string): Promise<void> {\n\t\tthis.#table(table)\n\t\tthis.#guard(() => {\n\t\t\tthis.#require()\n\t\t\t\t.prepare('DELETE FROM ' + quote(table))\n\t\t\t\t.run()\n\t\t})\n\t}\n\n\t// Doctrine (AGENTS §5, the audit's keystone fix): a Criteria whose compiled\n\t// SQL is PROVABLY identical to the core engine's semantics (see\n\t// `isExactCondition` / `isExactOrder` / `isExactCriteria`) runs the fast\n\t// native path; otherwise this driver fetches a full scan and refines it\n\t// through the SAME core engine every scan-only driver (`MemoryDriver`,\n\t// `JSONDriver`) already uses — exact → native, otherwise → refine, never a\n\t// silent semantics drift between backends. A native `WHERE` that is a\n\t// PROVABLE SUPERSET of the engine's match set (compile natively, then\n\t// engine-refine only the returned rows) is a possible future optimization,\n\t// not implemented here.\n\tasync records(table: string, criteria: Criteria): Promise<readonly Row[]> {\n\t\tconst schema = this.#table(table)\n\t\tif (isExactCriteria(criteria, schema)) {\n\t\t\treturn this.#guard(() => {\n\t\t\t\tconst { sql, params } = compileCriteria(criteria, schema)\n\t\t\t\tconst rows = this.#require()\n\t\t\t\t\t.prepare('SELECT * FROM ' + quote(table) + (sql === '' ? '' : ' ' + sql))\n\t\t\t\t\t.all(params)\n\t\t\t\treturn rows.map((row) => decodeRow(row, schema))\n\t\t\t})\n\t\t}\n\t\tconst rows: Row[] = []\n\t\tfor await (const row of this.scan(table)) rows.push(row)\n\t\treturn applyCriteria(rows, criteria)\n\t}\n\n\tasync count(table: string, criteria: Criteria): Promise<number> {\n\t\tconst schema = this.#table(table)\n\t\tconst conditions = criteria.conditions ?? []\n\t\tif (conditions.every((condition) => isExactCondition(condition, schema))) {\n\t\t\treturn this.#guard(() => {\n\t\t\t\t// Compile only the WHERE clause — no ORDER BY, no LIMIT/OFFSET — so a\n\t\t\t\t// direct call with `criteria.offset` set never skips the single\n\t\t\t\t// aggregate row (`compileCriteria`'s paging would otherwise apply\n\t\t\t\t// OFFSET/LIMIT to the one-row COUNT result).\n\t\t\t\tconst { sql, params } = compileWhere(conditions, schema)\n\t\t\t\tconst row = this.#require()\n\t\t\t\t\t.prepare('SELECT COUNT(*) AS count FROM ' + quote(table) + (sql === '' ? '' : ' ' + sql))\n\t\t\t\t\t.get(params)\n\t\t\t\tconst value = row?.count\n\t\t\t\treturn typeof value === 'number' || typeof value === 'bigint' ? Number(value) : 0\n\t\t\t})\n\t\t}\n\t\tconst rows: Row[] = []\n\t\tfor await (const row of this.scan(table)) rows.push(row)\n\t\treturn filterRows(rows, conditions).length\n\t}\n\n\tasync aggregate(\n\t\ttable: string,\n\t\toperation: AggregateFunction,\n\t\tcolumn: FieldPath,\n\t\tcriteria: Criteria,\n\t): Promise<number | undefined> {\n\t\tconst schema = this.#table(table)\n\t\tconst conditions = criteria.conditions ?? []\n\t\tconst conditionsExact = conditions.every((condition) => isExactCondition(condition, schema))\n\t\t// `count` ignores `column` entirely (COUNT(*) over rows), so only the\n\t\t// conditions need to be exact; every other aggregate coerces the column\n\t\t// numerically (parseNumber) — only a flat, declared integer/real column\n\t\t// is provably exact (a text/json/blob column may hold non-numeric cells\n\t\t// the engine skips via parseNumber, which SQL's numeric aggregates do not).\n\t\tconst columnExact =\n\t\t\toperation === 'count' ||\n\t\t\t(isString(column) &&\n\t\t\t\tschema.columns.some(\n\t\t\t\t\t(candidate) =>\n\t\t\t\t\t\tcandidate.name === column &&\n\t\t\t\t\t\t(candidate.type === 'integer' || candidate.type === 'real'),\n\t\t\t\t))\n\t\tif (conditionsExact && columnExact) {\n\t\t\treturn this.#guard(() => {\n\t\t\t\t// WHERE-only compile — same rationale as `count`: paging must never\n\t\t\t\t// apply to the single aggregate row.\n\t\t\t\tconst { sql, params } = compileWhere(conditions, schema)\n\t\t\t\tconst value = this.#require()\n\t\t\t\t\t.prepare(\n\t\t\t\t\t\t'SELECT ' +\n\t\t\t\t\t\t\taggregateSQL(operation, column) +\n\t\t\t\t\t\t\t' AS value FROM ' +\n\t\t\t\t\t\t\tquote(table) +\n\t\t\t\t\t\t\t(sql === '' ? '' : ' ' + sql),\n\t\t\t\t\t)\n\t\t\t\t\t.get(params)?.value\n\t\t\t\t// Over zero matched rows SUM/AVG/MIN/MAX are SQL NULL → undefined (the\n\t\t\t\t// engine agrees); COUNT(*) is 0. A clean numeric column coerces as the\n\t\t\t\t// engine does.\n\t\t\t\treturn value === null || value === undefined ? undefined : Number(value)\n\t\t\t})\n\t\t}\n\t\tconst rows: Row[] = []\n\t\tfor await (const row of this.scan(table)) rows.push(row)\n\t\treturn computeAggregate(filterRows(rows, conditions), operation, column)\n\t}\n\n\t// `order` is intentionally IGNORED (per DriverInterface.stream — streaming\n\t// yields unsorted), so the native gate checks only `conditions`; `offset` /\n\t// `limit` are always engine-identical under either path.\n\tasync *stream(table: string, criteria: Criteria): AsyncIterable<Row> {\n\t\tconst schema = this.#table(table)\n\t\tconst conditions = criteria.conditions ?? []\n\t\tif (conditions.every((condition) => isExactCondition(condition, schema))) {\n\t\t\tconst compiled = compileCriteria(\n\t\t\t\t{ conditions, limit: criteria.limit, offset: criteria.offset },\n\t\t\t\tschema,\n\t\t\t)\n\t\t\tfor (const row of this.#require()\n\t\t\t\t.prepare('SELECT * FROM ' + quote(table) + (compiled.sql === '' ? '' : ' ' + compiled.sql))\n\t\t\t\t.iterate(compiled.params)) {\n\t\t\t\tyield decodeRow(row, schema)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tconst offset = criteria.offset ?? 0\n\t\tconst limit = criteria.limit\n\t\tlet skipped = 0\n\t\tlet yielded = 0\n\t\tfor await (const row of this.scan(table)) {\n\t\t\tif (limit !== undefined && yielded >= limit) return\n\t\t\tif (conditions.length > 0 && !matchesCriteria(row, conditions)) continue\n\t\t\tif (skipped < offset) {\n\t\t\t\tskipped += 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tyield row\n\t\t\tyielded += 1\n\t\t}\n\t}\n\n\t/**\n\t * Begin a native transaction — real `BEGIN`, `COMMIT`, `ROLLBACK`.\n\t *\n\t * @remarks\n\t * Calling `commit` or `rollback` a second time (on either method, in either\n\t * order) throws `DatabaseError` `CONFLICT`.\n\t *\n\t * @returns A {@link TransactionInterface} handle to `commit` or `rollback`\n\t */\n\tasync transaction(): Promise<TransactionInterface> {\n\t\tconst database = this.#require()\n\t\tthis.#guard(() => database.exec('BEGIN'))\n\t\tlet settled = false\n\t\tthis.#transacting = true\n\t\treturn {\n\t\t\tcommit: async () => {\n\t\t\t\tif (settled) {\n\t\t\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction already settled', {})\n\t\t\t\t}\n\t\t\t\tsettled = true\n\t\t\t\tthis.#transacting = false\n\t\t\t\tthis.#guard(() => database.exec('COMMIT'))\n\t\t\t},\n\t\t\trollback: async () => {\n\t\t\t\tif (settled) {\n\t\t\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction already settled', {})\n\t\t\t\t}\n\t\t\t\tsettled = true\n\t\t\t\tthis.#transacting = false\n\t\t\t\tthis.#guard(() => database.exec('ROLLBACK'))\n\t\t\t},\n\t\t}\n\t}\n\n\t/**\n\t * Apply a {@link Migration} plan by executing each step's projected DDL\n\t * ({@link import('../helpers.js').stepToSQL}).\n\t *\n\t * @remarks\n\t * Atomicity is provided by whichever native transaction is active: when\n\t * this driver's own `transaction()` hook already has a handle open (the\n\t * core's versioned reconcile / migrate path joins migrate + stamp under\n\t * one native `BEGIN`), the plan's DDL runs directly inside that enclosing\n\t * transaction — a mid-plan failure propagates out and the CALLER's\n\t * `commit`/`rollback` provides atomicity. node:sqlite (and SQLite\n\t * generally) rejects a nested `BEGIN`, so this driver must never open a\n\t * second native transaction while one is already open. Otherwise (no\n\t * enclosing transaction), `migrate` wraps the plan in its own native\n\t * `database.transaction` — atomic on its own: a mid-plan failure rolls\n\t * back every DDL statement already applied by the plan. A step\n\t * referencing a table not in this driver's declared schema (and that is\n\t * not itself a `table.add`) throws `DatabaseError` `MIGRATION` before any\n\t * DDL for that step runs, propagating out of whichever transaction is\n\t * active (which rolls back on a throw).\n\t *\n\t * @param plan - The migration plan to apply\n\t */\n\tasync migrate(plan: Migration): Promise<void> {\n\t\tconst database = this.#require()\n\t\tconst schema = new Map(this.#schema)\n\t\tthis.#guard(() => {\n\t\t\tif (this.#transacting) {\n\t\t\t\tthis.#applyPlan(database, plan, schema)\n\t\t\t} else {\n\t\t\t\tdatabase.transaction(() => this.#applyPlan(database, plan, schema))\n\t\t\t}\n\t\t})\n\t\tthis.#schema = schema\n\t}\n\n\t/**\n\t * Read the persisted {@link DriverMeta} from the reserved `_meta` table.\n\t *\n\t * @returns The last-stamped `DriverMeta`, or `undefined` when never stamped\n\t * (or the stored row is malformed)\n\t */\n\tasync meta(): Promise<DriverMeta | undefined> {\n\t\tconst row = this.#guard(() =>\n\t\t\tthis.#require()\n\t\t\t\t.prepare('SELECT \"version\", \"schema\" FROM ' + quote(META_TABLE) + ' WHERE \"id\" = 1')\n\t\t\t\t.get(),\n\t\t)\n\t\tif (row === undefined) return undefined\n\t\tconst version = row.version\n\t\tconst text = row.schema\n\t\tif (typeof text !== 'string') return undefined\n\t\tif (typeof version !== 'number' && typeof version !== 'bigint') return undefined\n\t\tlet parsed: unknown\n\t\ttry {\n\t\t\tparsed = JSON.parse(text)\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t\tconst candidate = { version: Number(version), schema: parsed }\n\t\tif (!isDriverMeta(candidate)) return undefined\n\t\treturn candidate\n\t}\n\n\t/**\n\t * Persist `meta` verbatim (as JSON) into the reserved `_meta` table's single\n\t * row.\n\t *\n\t * @param meta - The {@link DriverMeta} to persist\n\t */\n\tasync stamp(meta: DriverMeta): Promise<void> {\n\t\tthis.#guard(() => {\n\t\t\tthis.#require()\n\t\t\t\t.prepare(\n\t\t\t\t\t'INSERT OR REPLACE INTO ' +\n\t\t\t\t\t\tquote(META_TABLE) +\n\t\t\t\t\t\t' (\"id\", \"version\", \"schema\") VALUES (1, ?, ?)',\n\t\t\t\t)\n\t\t\t\t.run([meta.version, JSON.stringify(meta.schema)])\n\t\t})\n\t}\n\n\tasync snapshot(tables?: readonly string[]): Promise<() => Promise<void>> {\n\t\tconst database = this.#require()\n\t\t// Capture-replay rather than a SQL SAVEPOINT: the core `transaction` calls\n\t\t// the rollback thunk only on failure, with no commit-on-success signal — a\n\t\t// long-lived SAVEPOINT would leave the connection in an uncommitted\n\t\t// transaction (lost on close). Captured rows are already encoded, so they\n\t\t// reinsert directly. `tables` omitted captures/restores the whole schema.\n\t\tconst names = tables ?? [...this.#schema.keys()]\n\t\tconst captured = new Map<\n\t\t\tstring,\n\t\t\t{ readonly names: readonly string[]; readonly rows: readonly SQLiteRow[] }\n\t\t>()\n\t\tfor (const name of names) {\n\t\t\tconst schema = this.#schema.get(name)\n\t\t\tif (schema === undefined) continue\n\t\t\tcaptured.set(name, {\n\t\t\t\tnames: schema.columns.map((column) => column.name),\n\t\t\t\trows: database.prepare('SELECT * FROM ' + quote(name)).all(),\n\t\t\t})\n\t\t}\n\t\treturn async () => {\n\t\t\tconst current = this.#require()\n\t\t\tcurrent.transaction(() => {\n\t\t\t\tfor (const [name, snapshot] of captured) {\n\t\t\t\t\tcurrent.exec('DELETE FROM ' + quote(name))\n\t\t\t\t\tconst statement = current.prepare(\n\t\t\t\t\t\t'INSERT OR REPLACE INTO ' +\n\t\t\t\t\t\t\tquote(name) +\n\t\t\t\t\t\t\t' (' +\n\t\t\t\t\t\t\tsnapshot.names.map(quote).join(', ') +\n\t\t\t\t\t\t\t') VALUES (' +\n\t\t\t\t\t\t\tsnapshot.names.map(() => '?').join(', ') +\n\t\t\t\t\t\t\t')',\n\t\t\t\t\t)\n\t\t\t\t\tfor (const row of snapshot.rows) {\n\t\t\t\t\t\tstatement.run(snapshot.names.map((column) => row[column]))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n\n\t// === Private\n\n\t// Run a synchronous backend interaction, mapping any `SQLiteError` (or\n\t// unexpected non-`SQLiteError` throw) to a typed `DatabaseError` so a\n\t// backend fault never leaks through `DriverInterface` unwrapped: a\n\t// `CONSTRAINT` violation becomes `CONFLICT`; the wrapper's own `CLOSED`\n\t// passes through as `CLOSED`; a `BUSY` (a locked database that outlasted\n\t// the configured `timeout`) becomes a `DRIVER` error whose context marks it\n\t// `retryable`; `UNKNOWN` and any non-`SQLiteError` throw become `DRIVER`.\n\t// A `DatabaseError` already thrown by this driver itself (the `#require`\n\t// `CLOSED` gate, `#table`'s `NOT_FOUND`, a `MIGRATION` step fault) passes\n\t// through unchanged — it is never re-wrapped. The original error is kept\n\t// as `context.cause` for diagnostics.\n\t#guard<T>(run: () => T): T {\n\t\ttry {\n\t\t\treturn run()\n\t\t} catch (error) {\n\t\t\tif (error instanceof DatabaseError) throw error\n\t\t\tif (isSQLiteError(error)) {\n\t\t\t\tif (error.code === 'CONSTRAINT') {\n\t\t\t\t\tthrow new DatabaseError('CONFLICT', error.message, { cause: error, code: error.code })\n\t\t\t\t}\n\t\t\t\tif (error.code === 'CLOSED') {\n\t\t\t\t\tthrow new DatabaseError('CLOSED', error.message, { cause: error, code: error.code })\n\t\t\t\t}\n\t\t\t\tif (error.code === 'BUSY') {\n\t\t\t\t\tthrow new DatabaseError('DRIVER', error.message, {\n\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\tcode: error.code,\n\t\t\t\t\t\tretryable: true,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tthrow new DatabaseError('DRIVER', error.message, { cause: error, code: error.code })\n\t\t\t}\n\t\t\tthrow new DatabaseError('DRIVER', error instanceof Error ? error.message : String(error), {\n\t\t\t\tcause: error,\n\t\t\t})\n\t\t}\n\t}\n\n\t#require(): SQLiteDatabaseInterface {\n\t\tif (this.#database === undefined) {\n\t\t\tthrow new DatabaseError('CLOSED', `SQLite database '${this.#path}' is not open`, {\n\t\t\t\tpath: this.#path,\n\t\t\t})\n\t\t}\n\t\treturn this.#database\n\t}\n\n\t// Require the database open and resolve a declared table's schema.\n\t#table(name: string): TableSchema {\n\t\tthis.#require()\n\t\tconst schema = this.#schema.get(name)\n\t\tif (schema === undefined) {\n\t\t\tthrow new DatabaseError('NOT_FOUND', `Table '${name}' is not in the schema`, { table: name })\n\t\t}\n\t\treturn schema\n\t}\n\n\t// Encode a primary key for binding against its column's stored type.\n\t#key(key: Key, schema: TableSchema): SQLiteValue {\n\t\tconst primary = schema.columns.find((column) => column.name === schema.primary)\n\t\treturn encodeValue(key, primary === undefined ? 'text' : primary.type)\n\t}\n\n\t// Walk a migration plan's steps, executing each one's projected DDL and updating\n\t// the working `schema` copy in place — shared by both `migrate`'s joined-transaction\n\t// (native handle already open) and self-wrapped (own `database.transaction`) paths.\n\t#applyPlan(\n\t\tdatabase: SQLiteDatabaseInterface,\n\t\tplan: Migration,\n\t\tschema: Map<string, TableSchema>,\n\t): void {\n\t\tfor (const step of plan.steps) {\n\t\t\tconst table = step.operation === 'table.add' ? step.table.name : step.table\n\t\t\tif (step.operation !== 'table.add' && !schema.has(table)) {\n\t\t\t\tthrow new DatabaseError('MIGRATION', `migrate: unknown table '${table}'`, { table })\n\t\t\t}\n\t\t\tfor (const sql of stepToSQL(step)) database.exec(sql)\n\t\t\tif (step.operation === 'table.add') {\n\t\t\t\tschema.set(step.table.name, step.table)\n\t\t\t} else if (step.operation === 'table.remove') {\n\t\t\t\tschema.delete(step.table)\n\t\t\t} else {\n\t\t\t\tconst existing = schema.get(table)\n\t\t\t\tif (existing !== undefined) schema.set(table, stepToSchema(existing, step))\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { DriverInterface } from '@src/core'\nimport type { SQLiteDriverOptions } from './types.js'\nimport { isString } from '@orkestrel/contract'\nimport { JSONDriver } from './drivers/JSONDriver.js'\nimport { SQLiteDriver } from './drivers/SQLiteDriver.js'\n\n/**\n * Create a persistent JSON-file {@link DriverInterface} for the core database layer.\n *\n * @remarks\n * Pass it to `createDatabase` from `@orkestrel/database` to run the whole typed database +\n * relations stack against a single JSON file instead of memory — the `Database` /\n * `Table` / `Query` / relations API is unchanged; only where the bytes live changes.\n * The driver is the reference `MemoryDriver` plus JSON-file persistence: `open` loads\n * the file, every mutation flushes the whole store back, and querying runs through\n * the core engine over `scan` (it is scan-only — no native `records` / `count` /\n * `aggregate`). A missing, corrupt, or wrong-shaped file starts empty rather than\n * throwing.\n *\n * @param path - The JSON file path data is loaded from and flushed to\n * @returns A {@link DriverInterface} backed by a JSON file\n *\n * @example\n * ```ts\n * import { createDatabase } from '@orkestrel/database'\n * import { stringShape } from '@orkestrel/contract'\n * import { createJSONDriver } from '@orkestrel/database/server'\n *\n * const db = createDatabase({\n * \tdriver: createJSONDriver('data/app.json'),\n * \ttables: { users: { id: stringShape(), name: stringShape() } },\n * })\n * await db.table('users').set({ id: 'u1', name: 'Ada' }) // persisted to app.json\n * ```\n */\nexport function createJSONDriver(path: string): DriverInterface {\n\treturn new JSONDriver(path)\n}\n\n/**\n * Create a trusted-mode SQLite {@link DriverInterface} for the core database layer.\n *\n * @remarks\n * Pass it to `createDatabase` from `@orkestrel/database` to run the whole typed database +\n * relations stack against a real SQLite database — the `Database` / `Table` /\n * `Query` / relations API is unchanged; only where the bytes live changes. Built\n * on the published `@orkestrel/sqlite` synchronous wrapper: `open` issues real\n * typed `CREATE TABLE` / `CREATE INDEX` statements (reopen-safe) plus a reserved\n * `_meta` table for `meta()` / `stamp()` — avoid naming a table `_meta`.\n * Querying, paging, and aggregation run natively (`records` / `count` /\n * `aggregate` / `stream`); `transaction` and `migrate` use real `BEGIN` /\n * `COMMIT` / `ROLLBACK`, so `migrate` is atomic even mid-plan.\n *\n * @param options - A bare database file path (`':memory:'` by default, for\n * back-compat), or a full {@link SQLiteDriverOptions} bag (`path`,\n * `readonly`, `timeout`, `foreignKeys`, `pragmas`)\n * @returns A {@link DriverInterface} backed by SQLite\n *\n * @example\n * ```ts\n * import { createDatabase } from '@orkestrel/database'\n * import { stringShape } from '@orkestrel/contract'\n * import { createSQLiteDriver } from '@orkestrel/database/server'\n *\n * const db = createDatabase({\n * \tdriver: createSQLiteDriver('data/app.sqlite'),\n * \ttables: { users: { id: stringShape(), name: stringShape() } },\n * })\n * await db.table('users').set({ id: 'u1', name: 'Ada' }) // persisted to app.sqlite\n *\n * // Or with options:\n * createSQLiteDriver({ path: 'data/app.sqlite', pragmas: { journal_mode: 'WAL' } })\n * ```\n */\nexport function createSQLiteDriver(\n\toptions: string | SQLiteDriverOptions = ':memory:',\n): DriverInterface {\n\tconst resolved: SQLiteDriverOptions = isString(options) ? { path: options } : options\n\treturn new SQLiteDriver(resolved.path ?? ':memory:', resolved)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["#source","#guard","#terminal","#cleaned","#discard","#path","#root","#enqueue","#open","#chain","#memory","#write","#insert","#delete","#scan","#stream","#clear","#transact","#capture","#restore","#metadata","#stamp","#migrate","#document","#hydrate","#schema","#identities","#alignIdentities","#clone","#projectIdentities","#apply","#serialize","#transaction","#candidate","#candidateIdentities","#candidateSchema","#capability","#readCandidate","#writeCandidate","#insertCandidate","#deleteCandidate","#keysCandidate","#scanCandidate","#clearCandidate","#migrateCandidate","#metadataCandidate","#stampCandidate","#requireCandidate","#flushCount","#path","#options","#root","#guard","#database","#identities","#schema","#ensureMetadataTable","#readMetadata","#validateTable","#read","#write","#insert","#delete","#keys","#scan","#clear","#table","#require","#stream","#transaction","#candidateSchema","#candidateIdentities","#capability","#projectIdentities","#applyPlan","#writeMetadata","#metadata","#stamp","#key","#iterate","#readTransaction","#writeTransaction","#insertTransaction","#deleteTransaction","#keysTransaction","#scanTransaction","#clearTransaction","#migrateTransaction","#metadataTransaction","#stampTransaction","#requireTransaction"],"sources":["../../../src/server/constants.ts","../../../src/server/helpers.ts","../../../src/server/compilers.ts","../../../src/core/DriverIterator.ts","../../../src/server/drivers/JSONDriver.ts","../../../src/server/drivers/SQLiteDriver.ts","../../../src/server/factories.ts"],"sourcesContent":["import type { ColumnStorage } from '@src/core'\n\n// The server surface's shared constants — reserved names its drivers claim and\n// the declared column groups that SQLite can query without engine refinement.\n\n/**\n * The declared {@link ColumnStorage}s whose SQL EQUALITY comparisons (`equals` /\n * `not` / `any` / `none`) and `starts` / `ends` compiles are provably\n * engine-exact under declared-type trust — `text` / `integer` / `real` /\n * `boolean`; a `json` or `blob` column always refines instead.\n *\n * @remarks\n * This set governs equality and prefix/suffix matching only. RANGE\n * comparisons (`above` / `below` / `from` / `to` / `between`) and `ORDER BY`\n * are exact for `integer` / `real` / `boolean` but NOT for `text`: compiled\n * SQL orders/ranges under SQLite's default BINARY collation, which compares\n * TEXT byte-for-byte as UTF-8 — equivalent to Unicode CODE-POINT order —\n * while the core engine's `compareValues` orders JS strings with `<`, which\n * compares UTF-16 CODE-UNIT order. The two orders diverge for supplementary-\n * plane characters (code points ≥ U+10000, e.g. many emoji): a lead surrogate\n * (`\\uD800`–`\\uDBFF`) sorts BELOW ``–`￿` in code-unit order, while\n * its code point sorts ABOVE them. So `matchesConditionExactly`'s range family and\n * `matchesOrderExactly` exclude `text`, refining through the core engine instead.\n */\nexport const EXACT_COLUMN_STORAGE: readonly ColumnStorage[] = Object.freeze([\n\t'text',\n\t'integer',\n\t'real',\n\t'boolean',\n])\n\n/**\n * The declared {@link ColumnStorage}s whose SQL RANGE comparisons\n * (`above` / `below` / `from` / `to` / `between`) and `ORDER BY` compiles are\n * provably engine-exact — `integer` / `real` / `boolean` only. `text` is\n * excluded: see {@link EXACT_COLUMN_STORAGE}'s remarks for the BINARY-collation\n * (code-point) vs. JS `<` (code-unit) divergence on supplementary-plane\n * characters.\n */\nexport const EXACT_RANGE_COLUMN_STORAGE: readonly ColumnStorage[] = Object.freeze([\n\t'integer',\n\t'real',\n\t'boolean',\n])\n\n/**\n * The reserved metadata table the {@link SQLiteDriver} creates on `open` to\n * persist its stamped `DriverMetadata` (`version` + declared schema JSON) — the\n * SQLite realization of the `metadata` / `stamp` driver hooks.\n *\n * @remarks\n * A single-row table (`id = 1`). A user table named `_metadata` collides with the\n * reservation — the caller's concern to avoid, documented on the driver class.\n */\nexport const METADATA_TABLE = '_metadata'\n","import type {\n\tAggregateOperation,\n\tColumnSchema,\n\tColumnStorage,\n\tCondition,\n\tQueryInput,\n\tOrder,\n\tRow,\n\tTableSchema,\n} from '@src/core'\nimport type { FieldPath } from '@orkestrel/contract'\nimport type { SQLiteRow, SQLiteValue } from '@orkestrel/sqlite'\nimport { DatabaseError } from '@src/core'\nimport { cloneJSONValue, isBoolean, isFiniteNumber, isString } from '@orkestrel/contract'\nimport { EXACT_COLUMN_STORAGE, EXACT_RANGE_COLUMN_STORAGE } from './constants.js'\n\n// The SQLite ↔ JS bridge for the driver. Every helper is pure and\n// total — it narrows with `typeof` / `instanceof`, never `as` (AGENTS §1, §14):\n// a value that does not fit its column's storage type encodes to `null` rather\n// than throwing, and `decodeValue` is the exact inverse. `encodeRow` /\n// `decodeRow` lift the per-cell codecs across a whole schema; the SQL\n// `quoteIdentifier` contains identifier input. The SQL emitters live together\n// in `compilers.ts`; this module owns exactness, codecs, value extraction, and\n// persisted-name derivation. Its SQLite import is type-only and cannot couple\n// the emitted JavaScript to the native package.\n\n// === Exactness (native ↔ engine parity gating)\n//\n// SQLiteDriver's `records` / `count` / `aggregate` / `stream` compile a\n// `QueryInput` straight to SQL with NO engine re-filter — a huge perf win, but\n// only sound for a condition/order whose compiled SQL provably matches the\n// core engine's `matchesCondition` / `sortRows` semantics for every value a\n// contract-validated write can store (\"declared-type trust\"). These guards\n// decide, per condition/order/input, whether that proof holds; when it does\n// not, the driver falls back to a full scan refined through the same core\n// engine every scan-only driver (`MemoryDriver`, `JSONDriver`) already uses —\n// exact → native, otherwise → refine, never a silent semantics drift.\n\n/**\n * Whether a value's runtime type matches a column's declared exact type —\n * the operand side of the declared-type-trust proof.\n *\n * @remarks\n * `text` ↔ string, `integer` / `real` ↔ FINITE number (`NaN` / `±Infinity`\n * fail), `boolean` ↔ boolean. Backs {@link matchesConditionExactly}'s operand checks.\n *\n * @param value - The condition operand to test\n * @param type - The column's declared portable type\n * @returns `true` when the operand's runtime type matches the declared type\n *\n * @example\n * ```ts\n * matchesDeclaredType('Ada', 'text') // true\n * matchesDeclaredType(Number.NaN, 'integer') // false — only finite numbers\n * ```\n */\nexport function matchesDeclaredStorage(value: unknown, storage: ColumnStorage): boolean {\n\tif (storage === 'text') return isString(value)\n\tif (storage === 'boolean') return isBoolean(value)\n\treturn isFiniteNumber(value)\n}\n\n/**\n * Whether one {@link Condition} compiles to SQL that is PROVABLY identical to\n * the core engine's `matchesCondition` for every value its column's declared\n * type can store.\n *\n * @remarks\n * `false` for a nested `FieldPath` (an array) or a column absent from `schema`.\n * `absent` / `present` are exact unless a column is both optional and nullable.\n * In that combined case the storage sentinel for explicit `null` is not SQL\n * `NULL`, while the core treats both absence and explicit `null` as absent.\n * Every scalar operator refines when the column is optional\n * OR nullable, because SQL null semantics and the core total order differ.\n * Required non-null `equals` / `not` require an operand matching the declared\n * storage and exclude `json` / `blob`. `above` / `below` / `from` / `to` /\n * `between` are exact only for {@link EXACT_RANGE_COLUMN_STORAGE} (`integer` /\n * `real` / `boolean`) — a `text` column's range conditions REFINE, because\n * SQLite's default BINARY collation orders TEXT by Unicode CODE POINT while\n * the core engine's `compareValues` orders JS strings by UTF-16 CODE UNIT,\n * and the two diverge for supplementary-plane characters (see\n * {@link EXACT_COLUMN_STORAGE}'s remarks for the full rationale).\n * `any` / `none` require a NON-EMPTY list where every element matches (an empty\n * list is exact under neither: the engine's `any([])` matches nothing while\n * `none([])` matches everything, and SQL `IN ()` is a syntax error) — these\n * stay exact on `text` (byte equality is collation-independent and engine-\n * identical). `starts` / `ends` are exact only on a `text` column with a\n * string operand (case-sensitive `substr` compile, see {@link compileConditionSQL}) —\n * likewise collation-independent. `like` / `glob` are NEVER exact — SQLite\n * `LIKE` folds case ASCII-only against the engine's Unicode fold, and `GLOB`\n * has character classes the engine treats literally.\n *\n * @param condition - The condition to test\n * @param schema - The table's schema\n * @returns Whether `condition` is exact\n */\nexport function matchesConditionExactly(condition: Condition, schema: TableSchema): boolean {\n\tif (!isString(condition.column)) return false\n\tconst column = schema.columns.find((candidate) => candidate.name === condition.column)\n\tif (column === undefined) return false\n\tif (condition.operator === 'absent' || condition.operator === 'present') {\n\t\treturn !(column.optional && column.nullable)\n\t}\n\tif (column.optional || column.nullable) return false\n\tif (!EXACT_COLUMN_STORAGE.some((storage) => storage === column.storage)) return false\n\tconst first = condition.values[0]\n\tconst second = condition.values[1]\n\tswitch (condition.operator) {\n\t\tcase 'equals':\n\t\tcase 'not':\n\t\t\treturn matchesDeclaredStorage(first, column.storage)\n\t\tcase 'above':\n\t\tcase 'below':\n\t\tcase 'from':\n\t\tcase 'to':\n\t\t\treturn (\n\t\t\t\tEXACT_RANGE_COLUMN_STORAGE.some((storage) => storage === column.storage) &&\n\t\t\t\tmatchesDeclaredStorage(first, column.storage)\n\t\t\t)\n\t\tcase 'between':\n\t\t\treturn (\n\t\t\t\tEXACT_RANGE_COLUMN_STORAGE.some((storage) => storage === column.storage) &&\n\t\t\t\tmatchesDeclaredStorage(first, column.storage) &&\n\t\t\t\tmatchesDeclaredStorage(second, column.storage)\n\t\t\t)\n\t\tcase 'any':\n\t\tcase 'none':\n\t\t\treturn (\n\t\t\t\tcondition.values.length > 0 &&\n\t\t\t\tcondition.values.every((value) => matchesDeclaredStorage(value, column.storage))\n\t\t\t)\n\t\tcase 'starts':\n\t\tcase 'ends':\n\t\t\treturn column.storage === 'text' && isString(first)\n\t\tcase 'like':\n\t\tcase 'glob':\n\t\t\treturn false\n\t}\n}\n\n/**\n * Whether one {@link Order} term's column compiles to an `ORDER BY` that\n * matches the engine's {@link import('@src/core').sortRows} exactly.\n *\n * @remarks\n * `false` for a nested `FieldPath`, a column absent from `schema`, or a\n * declared type outside {@link EXACT_RANGE_COLUMN_STORAGE} (`integer` / `real` /\n * `boolean`). `text` is NOT exact here: SQLite's default BINARY collation\n * orders TEXT by Unicode code point while the core engine's `compareValues`\n * orders JS strings by UTF-16 code unit, and the two diverge for\n * supplementary-plane characters (see {@link EXACT_COLUMN_STORAGE}'s remarks) —\n * a `text` order term REFINES through the core engine instead.\n *\n * @param order - The order term to test\n * @param schema - The table's schema\n * @returns Whether `order` is exact\n */\nexport function matchesOrderExactly(order: Order, schema: TableSchema): boolean {\n\tif (!isString(order.column)) return false\n\tconst column = schema.columns.find((candidate) => candidate.name === order.column)\n\tif (column === undefined) return false\n\treturn (\n\t\t!column.optional &&\n\t\t!column.nullable &&\n\t\tEXACT_RANGE_COLUMN_STORAGE.some((storage) => storage === column.storage)\n\t)\n}\n\n/**\n * Whether a whole {@link QueryInput} is exact — every condition and every order\n * term is exact. `limit` / `offset` never affect exactness (SQL `LIMIT` /\n * `OFFSET` are always engine-identical).\n *\n * @param input - The query input to test\n * @param schema - The table's schema\n * @returns Whether every part of `input` is exact\n */\nexport function matchesQueryExactly(input: QueryInput, schema: TableSchema): boolean {\n\tconst conditions = input.conditions ?? []\n\tconst order = input.order ?? []\n\treturn (\n\t\tconditions.every((condition) => matchesConditionExactly(condition, schema)) &&\n\t\torder.every((term) => matchesOrderExactly(term, schema))\n\t)\n}\n\n/**\n * Determine whether SQLite can execute an aggregate exactly like the core engine.\n *\n * @param operation - Aggregate operation\n * @param column - Aggregate field\n * @param schema - Current table schema\n * @returns Whether native aggregation is exact\n */\nexport function matchesAggregateExactly(\n\toperation: AggregateOperation,\n\tcolumn: FieldPath,\n\tschema: TableSchema,\n): boolean {\n\tif (operation === 'count') return true\n\tif (operation === 'sum' || operation === 'average' || !isString(column)) return false\n\tconst declared = schema.columns.find((candidate) => candidate.name === column)\n\treturn (\n\t\tdeclared !== undefined &&\n\t\t(declared.storage === 'integer' || declared.storage === 'real') &&\n\t\t!(declared.optional && declared.nullable)\n\t)\n}\n\n/**\n * Test a declared SQLite type against a portable storage affinity.\n *\n * @param declared - Native declared type\n * @param storage - Portable column storage\n * @returns Whether SQLite's official affinity rules yield the expected affinity\n */\nexport function matchesSQLiteAffinity(declared: unknown, storage: ColumnStorage): boolean {\n\tif (!isString(declared)) return false\n\tconst type = declared.toUpperCase()\n\tlet affinity: 'INTEGER' | 'TEXT' | 'BLOB' | 'REAL' | 'NUMERIC'\n\tif (type.includes('INT')) affinity = 'INTEGER'\n\telse if (type.includes('CHAR') || type.includes('CLOB') || type.includes('TEXT'))\n\t\taffinity = 'TEXT'\n\telse if (type === '' || type.includes('BLOB')) affinity = 'BLOB'\n\telse if (type.includes('REAL') || type.includes('FLOA') || type.includes('DOUB'))\n\t\taffinity = 'REAL'\n\telse affinity = 'NUMERIC'\n\tif (storage === 'integer' || storage === 'boolean') return affinity === 'INTEGER'\n\tif (storage === 'text' || storage === 'json') return affinity === 'TEXT'\n\tif (storage === 'blob') return affinity === 'BLOB'\n\treturn affinity === 'REAL'\n}\n\n// === SQL identifiers\n\n/**\n * Quote a SQL identifier (a table or column name) so any characters are literal.\n *\n * @remarks\n * Wraps the name in double quotes and doubles any embedded quote — the standard\n * SQL identifier-quoting that lets a column named `order` or `from` be referenced\n * safely. Identifiers cannot be bound as parameters, so they are quoted instead.\n *\n * @param identifier - The raw identifier\n * @returns The double-quoted identifier\n *\n * @example\n * ```ts\n * quoteIdentifier('order') // '\"order\"'\n * ```\n */\nexport function quoteIdentifier(identifier: string): string {\n\treturn '\"' + identifier.replaceAll('\"', '\"\"') + '\"'\n}\n\n// === Value codecs\n\n/**\n * Encode a JS value to its stored {@link SQLiteValue} for a declared column.\n *\n * @remarks\n * The codec is total: a malformed value encodes to SQL `NULL`. Absence always\n * uses SQL `NULL`. A nullable-only column also uses SQL `NULL` for explicit\n * `null`; an optional-and-nullable column uses a storage-class sentinel so\n * absence and explicit `null` remain distinct.\n *\n * @param value - The JS value to store\n * @param column - The declared storage and absence/null contract\n * @returns The value SQLite stores\n *\n * @example\n * ```ts\n * encodeValue(true, booleanColumn) // 1\n * encodeValue({ a: 1 }, jsonColumn) // '{\"a\":1}'\n * ```\n */\nexport function encodeValue(value: unknown, column: ColumnSchema): SQLiteValue {\n\tif (value === undefined) return null\n\tif (value === null) {\n\t\tif (!column.nullable) return null\n\t\tif (!column.optional) return null\n\t\treturn column.storage === 'text' || column.storage === 'json' ? new Uint8Array() : String(null)\n\t}\n\tswitch (column.storage) {\n\t\tcase 'boolean':\n\t\t\treturn typeof value === 'boolean' ? (value ? 1 : 0) : null\n\t\tcase 'json':\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(cloneJSONValue(value))\n\t\t\t} catch {\n\t\t\t\treturn null\n\t\t\t}\n\t\tcase 'integer':\n\t\t\treturn typeof value === 'bigint' ||\n\t\t\t\t(typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value))\n\t\t\t\t? value\n\t\t\t\t: null\n\t\tcase 'real':\n\t\t\treturn typeof value === 'bigint' || (typeof value === 'number' && Number.isFinite(value))\n\t\t\t\t? value\n\t\t\t\t: null\n\t\tcase 'text':\n\t\t\treturn typeof value === 'string' ? value : null\n\t\tcase 'blob':\n\t\t\treturn value instanceof Uint8Array ? value : null\n\t}\n}\n\n/**\n * Decode a stored {@link SQLiteValue} back to its JS value for a declared column —\n * the exact inverse of {@link encodeValue}.\n *\n * @remarks\n * Stored values must use the declared SQLite storage class. SQL `NULL` decodes\n * to explicit `null` only for nullable-only columns and otherwise to absence.\n * Optional-and-nullable sentinels decode to explicit `null`; malformed values\n * decode to `undefined` so {@link decodeRow} omits them.\n *\n * @param value - The stored SQLite value\n * @param column - The declared storage and absence/null contract\n * @returns The decoded JS value, or `undefined` for absence/malformed storage\n *\n * @example\n * ```ts\n * decodeValue(1, booleanColumn) // true\n * decodeValue('{\"a\":1}', jsonColumn) // { a: 1 }\n * ```\n */\nexport function decodeValue(value: SQLiteValue, column: ColumnSchema): unknown {\n\tif (value === null) return column.nullable && !column.optional ? null : undefined\n\tif (\n\t\tcolumn.optional &&\n\t\tcolumn.nullable &&\n\t\t(column.storage === 'text' || column.storage === 'json'\n\t\t\t? value instanceof Uint8Array && value.byteLength === 0\n\t\t\t: value === String(null))\n\t) {\n\t\treturn null\n\t}\n\tswitch (column.storage) {\n\t\tcase 'boolean':\n\t\t\tif (value === 0 || value === 0n) return false\n\t\t\tif (value === 1 || value === 1n) return true\n\t\t\treturn undefined\n\t\tcase 'json':\n\t\t\tif (typeof value !== 'string') return undefined\n\t\t\ttry {\n\t\t\t\treturn structuredClone(cloneJSONValue(JSON.parse(value)))\n\t\t\t} catch {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\tcase 'integer':\n\t\t\treturn typeof value === 'bigint' ||\n\t\t\t\t(typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value))\n\t\t\t\t? value\n\t\t\t\t: undefined\n\t\tcase 'real':\n\t\t\treturn typeof value === 'bigint' || (typeof value === 'number' && Number.isFinite(value))\n\t\t\t\t? value\n\t\t\t\t: undefined\n\t\tcase 'text':\n\t\t\treturn typeof value === 'string' ? value : undefined\n\t\tcase 'blob':\n\t\t\treturn value instanceof Uint8Array ? value : undefined\n\t}\n}\n\n/**\n * Encode a whole {@link Row} to a {@link SQLiteRow} by its table's schema.\n *\n * @remarks\n * Encodes each declared column's value with {@link encodeValue}; columns the row\n * does not carry encode from `undefined` (so they store `null`). Only the\n * schema's columns appear in the result — an extra row key is dropped.\n *\n * @param row - The JS row to store\n * @param schema - The table's schema\n * @returns The storable SQLite row\n *\n * @example\n * ```ts\n * encodeRow({ id: 'u1', active: true }, schema) // { id: 'u1', active: 1, ... }\n * ```\n */\nexport function encodeRow(row: Row, schema: TableSchema): SQLiteRow {\n\tconst result: SQLiteRow = {}\n\tfor (const column of schema.columns) {\n\t\tresult[column.name] = encodeValue(row[column.name], column)\n\t}\n\treturn result\n}\n\n/**\n * Extract a stored row's values in a declared positional order.\n *\n * @remarks\n * SQLite statements bind arrays positionally. Every requested column must be\n * present in `row`; an incomplete backend row is a typed `DRIVER` fault carrying\n * the table and missing column in its context.\n *\n * @param row - The stored SQLite row\n * @param names - The column names in binding order\n * @param table - The owning table name for fault context\n * @returns The row values in the same order as `names`\n * @throws A `DRIVER` {@link DatabaseError} when a requested column is missing\n *\n * @example\n * ```ts\n * extractValues({ id: 'u1', age: 36 }, ['age', 'id'], 'users') // [36, 'u1']\n * ```\n */\nexport function extractValues(\n\trow: SQLiteRow,\n\tnames: readonly string[],\n\ttable: string,\n): readonly SQLiteValue[] {\n\tconst values: SQLiteValue[] = []\n\tfor (const name of names) {\n\t\tconst value = row[name]\n\t\tif (value === undefined) {\n\t\t\tthrow new DatabaseError('DRIVER', 'SQLite row is missing a declared column', {\n\t\t\t\ttable,\n\t\t\t\tcolumn: name,\n\t\t\t})\n\t\t}\n\t\tvalues.push(value)\n\t}\n\treturn values\n}\n\n/**\n * Decode a stored {@link SQLiteRow} back to a {@link Row} by its table's schema.\n *\n * @remarks\n * Decodes each declared column with {@link decodeValue} and **omits** any column\n * whose decoded value is `undefined` — so an absent / `NULL` optional column does\n * not surface as `{ bio: undefined }`, matching how the contract's optional\n * columns expect absence. Nullable-only SQL `NULL` cells remain explicit\n * `null`; optional-and-nullable columns use their storage-class sentinel.\n *\n * @param row - The stored SQLite row\n * @param schema - The table's schema\n * @returns The decoded JS row (absent columns omitted)\n *\n * @example\n * ```ts\n * decodeRow({ id: 'u1', active: 1, bio: null }, schema) // { id: 'u1', active: true }\n * ```\n */\nexport function decodeRow(row: SQLiteRow, schema: TableSchema): Row {\n\tconst result: Row = {}\n\tfor (const column of schema.columns) {\n\t\tconst value = row[column.name]\n\t\tif (value === undefined) continue\n\t\tconst decoded = decodeValue(value, column)\n\t\tif (decoded !== undefined) result[column.name] = decoded\n\t}\n\treturn result\n}\n\n// === Persisted names\n\n/**\n * Build a collision-free SQL index name for a table + column-group index —\n * shared by the compiler module's `schemaToIndexes` and `stepToSQL`,\n * so a plan-built index name always matches one `open` would have created.\n *\n * @remarks\n * A naive `idx_<table>_<cols joined by _>` is AMBIGUOUS: table `'a_b'` with\n * column `'c'` and table `'a'` with columns `['b', 'c']` both produce\n * `idx_a_b_c`. This encodes each part (the table name, then each column name)\n * length-prefixed (`<len>_<part>`) so the boundary between parts is always\n * unambiguous, however the names themselves are punctuated.\n *\n * @param table - The table name\n * @param columns - The index's column names, in order\n * @returns The deterministic, collision-free index identifier (unquoted)\n *\n * @example\n * ```ts\n * deriveSQLiteIndexName('users', ['name']) // 'idx_5_users_4_name'\n * deriveSQLiteIndexName('a_b', ['c']) // 'idx_3_a_b_1_c'\n * deriveSQLiteIndexName('a', ['b', 'c']) // 'idx_1_a_1_b_1_c'\n * ```\n */\nexport function deriveSQLiteIndexName(table: string, columns: readonly string[]): string {\n\tconst parts = [table, ...columns].map((part) => String(part.length) + '_' + part)\n\treturn 'idx_' + parts.join('_')\n}\n","import type {\n\tAggregateOperation,\n\tColumnStorage,\n\tCondition,\n\tMigrationStep,\n\tOrder,\n\tQueryInput,\n\tTableSchema,\n} from '@src/core'\nimport type { FieldPath } from '@orkestrel/contract'\nimport type { SQLiteValue } from '@orkestrel/sqlite'\nimport type { CompiledSQL } from './types.js'\nimport { DatabaseError, validatePage } from '@src/core'\nimport { isString } from '@orkestrel/contract'\nimport { deriveSQLiteIndexName, encodeValue, quoteIdentifier } from './helpers.js'\n\n/**\n * Map a portable {@link ColumnStorage} to its SQLite column type.\n *\n * @param storage - The portable column type\n * @returns The SQLite column type keyword\n */\nexport function compileColumnSQL(storage: ColumnStorage): string {\n\tswitch (storage) {\n\t\tcase 'text':\n\t\tcase 'json':\n\t\t\treturn 'TEXT'\n\t\tcase 'integer':\n\t\tcase 'boolean':\n\t\t\treturn 'INTEGER'\n\t\tcase 'real':\n\t\t\treturn 'REAL'\n\t\tcase 'blob':\n\t\t\treturn 'BLOB'\n\t}\n}\n\n/**\n * Compile a {@link FieldPath} to the SQL expression that reads it.\n *\n * @param path - The field path\n * @returns The SQL expression selecting the value\n */\nexport function compileFieldSQL(path: FieldPath): string {\n\tif (isString(path)) return quoteIdentifier(path)\n\tconst [column, ...nested] = path\n\tif (column === undefined) {\n\t\tthrow new DatabaseError('VALIDATION', 'A field path must contain at least one column')\n\t}\n\tconst rest = nested.map((key) => '.' + key.replaceAll(\"'\", \"''\")).join('')\n\treturn 'json_extract(' + quoteIdentifier(column) + \", '$\" + rest + \"')\"\n}\n\n/**\n * Compile an {@link AggregateOperation} over a {@link FieldPath}.\n *\n * @param operation - The aggregate to compute\n * @param column - The column or nested path to aggregate\n * @returns The SQL aggregate expression\n */\nexport function compileAggregateSQL(operation: AggregateOperation, column: FieldPath): string {\n\tswitch (operation) {\n\t\tcase 'count':\n\t\t\treturn 'COUNT(*)'\n\t\tcase 'sum':\n\t\t\treturn 'SUM(' + compileFieldSQL(column) + ')'\n\t\tcase 'average':\n\t\t\treturn 'AVG(' + compileFieldSQL(column) + ')'\n\t\tcase 'minimum':\n\t\t\treturn 'MIN(' + compileFieldSQL(column) + ')'\n\t\tcase 'maximum':\n\t\t\treturn 'MAX(' + compileFieldSQL(column) + ')'\n\t}\n}\n\n/**\n * Compile a NESTED {@link FieldPath} to the `json_type(<col>, <path>)` SQL\n * expression — the {@link compileFieldSQL} `json_extract` sibling used to tell a\n * PRESENT JSON `null` apart from an ABSENT path (both read back as SQL `NULL`\n * through `json_extract`, but `json_type` reports `'null'` for the former and\n * SQL `NULL` for the latter).\n *\n * @param path - The nested field path (a column plus its JSON keys)\n * @returns The SQL expression reading the value's JSON type\n *\n * @example\n * ```ts\n * compileJSONTypeSQL(['payload', 'user', 'id']) // \"json_type(\\\"payload\\\", '$.user.id')\"\n * ```\n */\nexport function compileJSONTypeSQL(path: readonly string[]): string {\n\tconst [column, ...nested] = path\n\tif (column === undefined) {\n\t\tthrow new DatabaseError('VALIDATION', 'A field path must contain at least one column')\n\t}\n\tconst rest = nested.map((key) => '.' + key.replaceAll(\"'\", \"''\")).join('')\n\treturn 'json_type(' + quoteIdentifier(column) + \", '$\" + rest + \"')\"\n}\n\n// The `QueryInput` → parameterized SQL compiler — the native-query payoff. It turns\n// a portable `QueryInput` (the same one the core engine's `applyQuery` folds)\n// into the `WHERE` / `ORDER BY` / `LIMIT` tail of a `SELECT`, with bound `?`\n// parameters in clause order. Its WHERE fold parenthesizes LEFT-TO-RIGHT to match the\n// engine's `matchesQuery` exactly (NOT SQL's AND-over-OR precedence), so a\n// native read and an engine read agree on every query (the parity test). Branches\n// are centralized and public per AGENTS §5 — no operator logic buried in closures.\n// This module speaks pure strings/values only. Its SQLiteValue import is\n// type-only and cannot couple the emitted JavaScript to the native package.\n\n/**\n * Escape `\\`, `%`, and `_` (each with a leading `\\`) so a `starts` / `ends`\n * operand is matched literally under the `LIKE … ESCAPE '\\'` clause.\n *\n * @param text - The raw operand text\n * @returns The text with LIKE metacharacters escaped\n *\n * @example\n * ```ts\n * escapeLike('50%_off') // '50\\\\%\\\\_off'\n * ```\n */\nexport function escapeLike(text: string): string {\n\treturn text.replaceAll('\\\\', '\\\\\\\\').replaceAll('%', '\\\\%').replaceAll('_', '\\\\_')\n}\n\n/**\n * The declared storage type of a flat (string) column, read from the schema.\n *\n * @param column - The column name\n * @param schema - The table's schema\n * @returns The column's {@link ColumnStorage}, or `undefined` if the schema does not carry it\n *\n * @example\n * ```ts\n * findColumnStorage('age', schema) // 'integer'\n * ```\n */\nexport function findColumnStorage(column: string, schema: TableSchema): ColumnStorage | undefined {\n\treturn schema.columns.find((candidate) => candidate.name === column)?.storage\n}\n\n/**\n * The storage type a nested (`json_extract`) operand encodes as, derived from its\n * RUNTIME value — NOT `json`.\n *\n * @remarks\n * `json_extract` returns the unquoted, natively-typed scalar (a JSON boolean as\n * `1` / `0`, a number as-is, a string as-is), so the operand must encode to that\n * same scalar to compare. A boolean → `'boolean'` (→ `1` / `0`); a number →\n * `'integer'` / `'real'`; a bigint → `'integer'`; a string → `'text'`; `null` /\n * `undefined` → `'text'` (encodes to `null`); an object / array → `'json'` (the\n * edge of comparing against a json subtree).\n *\n * @param value - The runtime operand value\n * @returns The {@link ColumnStorage} to encode it as\n *\n * @example\n * ```ts\n * inferValueStorage(true) // 'boolean'\n * inferValueStorage(9) // 'integer'\n * ```\n */\nexport function inferValueStorage(value: unknown): ColumnStorage {\n\tif (typeof value === 'boolean') return 'boolean'\n\tif (typeof value === 'number') return Number.isInteger(value) ? 'integer' : 'real'\n\tif (typeof value === 'bigint') return 'integer'\n\tif (typeof value === 'object' && value !== null) return 'json'\n\treturn 'text'\n}\n\n/**\n * Compile one condition to its `<column> <operator>` SQL fragment and the parameters\n * it binds — engine-exact under SQL's three-valued NULL logic.\n *\n * @remarks\n * Every operand is run through `encodeValue`, so a bound value matches the SQL\n * the column side compiles to. A flat column encodes operands with its DECLARED\n * schema type (a flat `json` column → `JSON.stringify`); a nested `FieldPath`\n * encodes each operand as the NATIVE scalar `json_extract` returns, derived from\n * the operand's runtime type (per-operand, since `between` / `any` / `none` can\n * mix types). `any` / `none` collapse an empty list to a constant (`0` matches\n * nothing, `1` matches all) with no parameters.\n *\n * The core engine's total order ranks `undefined` (rank 0) BELOW `null`\n * (rank 1) (see `compareValues`), so a MISSING/`NULL` column MATCHES\n * `below` / `to` / a scalar `not` / `none` — the opposite of raw SQL, where a\n * comparison against `NULL` is `NULL` (excluded). This fragment replicates the\n * engine exactly. Truth table (`value` = the engine's decoded field read; a\n * FLAT column's stored `NULL` decodes to `undefined` per `decodeRow`, so a\n * flat `value` is NEVER a present `null` — only a NESTED path can be\n * present-but-`null`):\n *\n * ```text\n * operator | value=undefined (absent) | value=null (nested only) | value=scalar\n * --------------------|--------------------------------|---------------------------|-------------\n * equals, first=null | no match | MATCH | no match\n * equals, first=X | no match | no match | value===X\n * not, first=null | MATCH (flat: unconditionally; | no match | MATCH\n * | nested: absent still matches)| |\n * not, first=X | MATCH | MATCH | value!==X\n * below/to, first=X | MATCH (rank 0 < rank(X)) | MATCH (rank 1 < rank(X)) | rank compare\n * none, list=[…] | MATCH (no scalar rank-equal) | MATCH | not-in-list\n * any, list=[…] | no match | no match | in-list\n * above/from/between | no match | no match | rank compare\n * like/glob/starts/… | no match (not a string) | no match | string test\n * present | false | false | true\n * absent | true | true | false\n * ```\n *\n * A flat SQL `NULL` represents absence or explicit null according to its\n * {@link ColumnSchema}; optional-and-nullable columns use a storage-class\n * sentinel to distinguish the two. The native exactness gate therefore\n * refines every optional or nullable scalar comparison through the core engine.\n * This compiler still emits a total SQL fragment for direct consumers.\n *\n * A NESTED path can be present-but-`null` (a stored JSON `null`), which\n * `json_extract` reads back as SQL `NULL` — indistinguishable from an ABSENT\n * path. `json_type(col, path)` disambiguates them (`'null'` for present-null,\n * SQL `NULL` for absent), so nested `equals` / `not` against a `null` operand\n * compile through `json_type` instead of `IS NULL` / `IS NOT NULL`.\n *\n * Every other MATCH-on-null-or-absent row is expressed uniformly (flat and\n * nested alike) as `(<column> <op> ? OR <column> IS NULL)` — for a nested\n * path, `json_extract` already collapses BOTH absent and present-null to SQL\n * `NULL`, so `IS NULL` catches both in one clause; for a flat column there is\n * only the absent case to catch.\n *\n * @param condition - The condition to compile\n * @param schema - The table's schema (for declared column types)\n * @returns The SQL fragment and its bound parameters\n *\n * @example\n * ```ts\n * compileConditionSQL({ column: 'age', operator: 'above', values: [18], connector: 'and' }, schema)\n * // { sql: '\"age\" > ?', parameters: [18] }\n * compileConditionSQL({ column: 'age', operator: 'below', values: [18], connector: 'and' }, schema)\n * // { sql: '(\"age\" < ? OR \"age\" IS NULL)', parameters: [18] }\n * ```\n */\nexport function compileConditionSQL(condition: Condition, schema: TableSchema): CompiledSQL {\n\tconst column = compileFieldSQL(condition.column)\n\tconst nested = !isString(condition.column)\n\tconst declared = isString(condition.column)\n\t\t? schema.columns.find((candidate) => candidate.name === condition.column)\n\t\t: undefined\n\tconst first = condition.values[0]\n\tconst second = condition.values[1]\n\tconst nullOperand = first === null || first === undefined\n\t// The nested `json_type` read — built only when `condition.column` is an\n\t// array (a nested path) — disambiguates a present JSON `null` from an\n\t// absent path under `equals` / `not` (see the truth table above).\n\tconst jsonType = !isString(condition.column) ? compileJSONTypeSQL(condition.column) : ''\n\tlet sql: string\n\tlet values: readonly unknown[]\n\tswitch (condition.operator) {\n\t\tcase 'equals':\n\t\t\tif (nullOperand && nested) {\n\t\t\t\treturn { sql: jsonType + \" = 'null'\", parameters: [] }\n\t\t\t}\n\t\t\tsql = column + ' = ?'\n\t\t\tvalues = [first]\n\t\t\tbreak\n\t\tcase 'not':\n\t\t\tif (nullOperand) {\n\t\t\t\tif (nested) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tsql: '(' + jsonType + ' IS NULL OR ' + jsonType + \" != 'null')\",\n\t\t\t\t\t\tparameters: [],\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// A flat column's decoded value is never a present null, so\n\t\t\t\t// `compareValues(value, null)` is nonzero for EVERY row (absent or\n\t\t\t\t// scalar) — the engine's `not null` matches unconditionally.\n\t\t\t\treturn { sql: '1', parameters: [] }\n\t\t\t}\n\t\t\tsql = '(' + column + ' != ? OR ' + column + ' IS NULL)'\n\t\t\tvalues = [first]\n\t\t\tbreak\n\t\tcase 'above':\n\t\t\tsql = column + ' > ?'\n\t\t\tvalues = [first]\n\t\t\tbreak\n\t\tcase 'below':\n\t\t\tsql = '(' + column + ' < ? OR ' + column + ' IS NULL)'\n\t\t\tvalues = [first]\n\t\t\tbreak\n\t\tcase 'from':\n\t\t\tsql = column + ' >= ?'\n\t\t\tvalues = [first]\n\t\t\tbreak\n\t\tcase 'to':\n\t\t\tsql = '(' + column + ' <= ? OR ' + column + ' IS NULL)'\n\t\t\tvalues = [first]\n\t\t\tbreak\n\t\tcase 'between':\n\t\t\tsql = column + ' BETWEEN ? AND ?'\n\t\t\tvalues = [first, second]\n\t\t\tbreak\n\t\tcase 'like':\n\t\t\tsql = column + ' LIKE ?'\n\t\t\tvalues = [first]\n\t\t\tbreak\n\t\tcase 'glob':\n\t\t\tsql = column + ' GLOB ?'\n\t\t\tvalues = [first]\n\t\t\tbreak\n\t\tcase 'starts': {\n\t\t\t// Case-sensitive, exact compile (replaces the old LIKE-based one, which\n\t\t\t// was ASCII-only case-INsensitive — a mismatch with the engine's\n\t\t\t// case-sensitive `String.startsWith`). `substr` counts CODE POINTS, so\n\t\t\t// the length is a code-point count (`Array.from`), not `.length`. An\n\t\t\t// empty operand matches every text-column value (the engine: every\n\t\t\t// string starts with '').\n\t\t\tconst text = isString(first) ? first : ''\n\t\t\tif (text === '') {\n\t\t\t\treturn { sql: 'typeof(' + column + \") = 'text'\", parameters: [] }\n\t\t\t}\n\t\t\tconst length = Array.from(text).length\n\t\t\tsql = '(typeof(' + column + \") = 'text' AND substr(\" + column + ', 1, ' + length + ') = ?)'\n\t\t\tvalues = [first]\n\t\t\tbreak\n\t\t}\n\t\tcase 'ends': {\n\t\t\t// Mirror of `starts`: `substr(<col>, -N)` (SQLite's 2-arg form counts\n\t\t\t// from the right when N is negative) reads the last N code points.\n\t\t\tconst text = isString(first) ? first : ''\n\t\t\tif (text === '') {\n\t\t\t\treturn { sql: 'typeof(' + column + \") = 'text'\", parameters: [] }\n\t\t\t}\n\t\t\tconst length = Array.from(text).length\n\t\t\tsql = '(typeof(' + column + \") = 'text' AND substr(\" + column + ', -' + length + ') = ?)'\n\t\t\tvalues = [first]\n\t\t\tbreak\n\t\t}\n\t\tcase 'any':\n\t\t\tif (condition.values.length === 0) return { sql: '0', parameters: [] }\n\t\t\tsql = column + ' IN (' + condition.values.map(() => '?').join(', ') + ')'\n\t\t\tvalues = condition.values\n\t\t\tbreak\n\t\tcase 'none':\n\t\t\tif (condition.values.length === 0) return { sql: '1', parameters: [] }\n\t\t\tsql =\n\t\t\t\t'(' +\n\t\t\t\tcolumn +\n\t\t\t\t' NOT IN (' +\n\t\t\t\tcondition.values.map(() => '?').join(', ') +\n\t\t\t\t') OR ' +\n\t\t\t\tcolumn +\n\t\t\t\t' IS NULL)'\n\t\t\tvalues = condition.values\n\t\t\tbreak\n\t\tcase 'absent':\n\t\t\treturn { sql: column + ' IS NULL', parameters: [] }\n\t\tcase 'present':\n\t\t\treturn { sql: column + ' IS NOT NULL', parameters: [] }\n\t}\n\treturn {\n\t\tsql,\n\t\tparameters: values.map((value) => {\n\t\t\tconst storage = nested ? inferValueStorage(value) : (declared?.storage ?? 'json')\n\t\t\treturn encodeValue(value, declared ?? { name: '', storage, optional: false, nullable: false })\n\t\t}),\n\t}\n}\n\n/**\n * Fold the conditions into one WHERE clause, parenthesizing progressively\n * left-to-right so the grouping matches the engine's `matchesQuery` fold.\n *\n * @remarks\n * The first condition's connector is ignored, per the {@link Condition} types.\n * Every fragment (see {@link compileConditionSQL}'s truth table) replicates the core\n * engine's total order EXACTLY under SQL's three-valued NULL logic, so this\n * clause matches `applyQuery` row-for-row over the same table — a native\n * `records` / `count` read never disagrees with a scan-and-filter fallback.\n *\n * @param conditions - The conditions to fold\n * @param schema - The table's schema\n * @returns The `WHERE …` clause and its bound parameters, or an empty clause for zero conditions\n *\n * @example\n * ```ts\n * compileWhere([{ column: 'age', operator: 'from', values: [18], connector: 'and' }], schema)\n * // { sql: 'WHERE \"age\" >= ?', parameters: [18] }\n * ```\n */\nexport function compileWhere(conditions: readonly Condition[], schema: TableSchema): CompiledSQL {\n\tconst [first, ...remaining] = conditions\n\tif (first === undefined) return { sql: '', parameters: [] }\n\tconst head = compileConditionSQL(first, schema)\n\tlet clause = head.sql\n\tconst parameters: SQLiteValue[] = [...head.parameters]\n\tfor (const condition of remaining) {\n\t\tconst next = compileConditionSQL(condition, schema)\n\t\tconst operator = condition.connector === 'or' ? 'OR' : 'AND'\n\t\tclause = '(' + clause + ' ' + operator + ' ' + next.sql + ')'\n\t\tparameters.push(...next.parameters)\n\t}\n\treturn { sql: 'WHERE ' + clause, parameters }\n}\n\n/**\n * Compile the ORDER BY clause from the order terms, always ending with the\n * primary key as the final determinant.\n *\n * @remarks\n * The native `records` read then resolves ties in key order, matching a\n * primary-key-ordered `scan` and the core engine's stable `sortRows` over a\n * key-ordered scan (and IndexedDB's key-ordered reads), so a native read equals\n * the scan path (AGENTS §21 / §22 native ↔ engine parity). SQLite without an\n * `ORDER BY` returns rowid (insertion) order, and an explicit order alone breaks\n * ties by rowid too — both diverge from every key-ordered backend. The\n * tie-breaker is ASCENDING regardless of the explicit directions: the engine's\n * stable sort runs over key-ascending input, so equal rows stay in\n * ascending-key order whichever way the explicit terms point. Skipped when the\n * primary is already an explicit order term (no double-append).\n *\n * @param order - The explicit order terms, or `undefined`\n * @param schema - The table's schema (for the primary key)\n * @returns The `ORDER BY …` clause, or an empty string when there is nothing to order by\n *\n * @example\n * ```ts\n * compileOrder([{ column: 'age', direction: 'descending' }], schema)\n * // 'ORDER BY \"age\" DESC, \"id\"'\n * ```\n */\nexport function compileOrder(order: readonly Order[] | undefined, schema: TableSchema): string {\n\tconst terms = (order ?? []).map(\n\t\t(term) => compileFieldSQL(term.column) + (term.direction === 'descending' ? ' DESC' : ' ASC'),\n\t)\n\tconst ordersByPrimary = (order ?? []).some(\n\t\t(term) => isString(term.column) && term.column === schema.primary,\n\t)\n\tif (!ordersByPrimary) terms.push(quoteIdentifier(schema.primary))\n\treturn terms.length === 0 ? '' : 'ORDER BY ' + terms.join(', ')\n}\n\n/**\n * Compile the LIMIT / OFFSET clause.\n *\n * @remarks\n * An offset without a limit uses `LIMIT -1` (SQLite's \"no limit\") so OFFSET is\n * still honored.\n *\n * @param limit - The maximum row count, or `undefined`\n * @param offset - The row count to skip, or `undefined`\n * @returns The `LIMIT …` clause and its bound parameters, or an empty clause when neither is set\n *\n * @example\n * ```ts\n * compilePage(undefined, 5) // { sql: 'LIMIT -1 OFFSET ?', parameters: [5] }\n * ```\n */\nexport function compilePage(limit: number | undefined, offset: number | undefined): CompiledSQL {\n\tvalidatePage({\n\t\t...(limit === undefined ? {} : { limit }),\n\t\t...(offset === undefined ? {} : { offset }),\n\t})\n\tif (limit !== undefined && offset !== undefined) {\n\t\treturn { sql: 'LIMIT ? OFFSET ?', parameters: [limit, offset] }\n\t}\n\tif (limit !== undefined) return { sql: 'LIMIT ?', parameters: [limit] }\n\tif (offset !== undefined) return { sql: 'LIMIT -1 OFFSET ?', parameters: [offset] }\n\treturn { sql: '', parameters: [] }\n}\n\n/**\n * Compile a {@link QueryInput} into the SQL clause that follows a table name, with\n * its bound parameters in clause order.\n *\n * @remarks\n * The driver's native `records` / `count` path: it assembles\n * `[where, orderBy, limitOffset]` (each possibly empty) into one clause so a\n * `SELECT * FROM <table> <clause>` runs the whole read in the engine instead of\n * over a JS `scan`. The WHERE fold is parenthesized **left-to-right** to mirror\n * the core engine's `matchesQuery` (not SQL's native AND-over-OR precedence),\n * so a native and an engine read return identical rows. Each operand is encoded\n * via `encodeValue`: a flat column uses its declared schema type, while a nested\n * `FieldPath` (a `json_extract` read) encodes each operand as the native scalar\n * the extract returns — derived from the operand's runtime type — so it compares.\n * The 15 operators map per the databases guide's operator table, with\n * `starts` / `ends` using `LIKE … ESCAPE '\\'` and an empty `any` / `none` list\n * collapsing to a constant. An `undefined` input (or one with no parts)\n * compiles to an empty clause.\n *\n * @param input - The read specification, or `undefined` for all rows\n * @param schema - The table's schema (column types for operand encoding)\n * @returns The SQL tail and its bound parameters\n *\n * @example\n * ```ts\n * compileQuerySQL({ conditions: [{ column: 'age', operator: 'from', values: [18], connector: 'and' }] }, schema)\n * // { sql: 'WHERE \"age\" >= ? ORDER BY \"id\"', parameters: [18] }\n * ```\n */\nexport function compileQuerySQL(input: QueryInput | undefined, schema: TableSchema): CompiledSQL {\n\tvalidatePage(input)\n\tconst where = compileWhere(input?.conditions ?? [], schema)\n\tconst orderBy = compileOrder(input?.order, schema)\n\tconst page = compilePage(input?.limit, input?.offset)\n\tconst sql = [where.sql, orderBy, page.sql].filter((part) => part !== '').join(' ')\n\treturn {\n\t\tsql,\n\t\tparameters: [...where.parameters, ...page.parameters],\n\t}\n}\n\n/**\n * Project a {@link TableSchema} to its `CREATE TABLE IF NOT EXISTS` statement.\n *\n * @param schema - The table schema\n * @returns The complete table declaration\n */\nexport function schemaToTable(schema: TableSchema): string {\n\tconst columns = schema.columns.map(\n\t\t(column) =>\n\t\t\tquoteIdentifier(column.name) +\n\t\t\t' ' +\n\t\t\tcompileColumnSQL(column.storage) +\n\t\t\t(column.optional || column.nullable ? '' : ' NOT NULL'),\n\t)\n\treturn (\n\t\t'CREATE TABLE IF NOT EXISTS ' +\n\t\tquoteIdentifier(schema.name) +\n\t\t' (' +\n\t\tcolumns.join(', ') +\n\t\t', PRIMARY KEY (' +\n\t\tquoteIdentifier(schema.primary) +\n\t\t'))'\n\t)\n}\n\n/**\n * Project a {@link TableSchema} to its declared SQLite indexes.\n *\n * @param schema - The table schema\n * @returns One statement per declared index\n */\nexport function schemaToIndexes(schema: TableSchema): readonly string[] {\n\treturn schema.indexes.map(\n\t\t(group) =>\n\t\t\t'CREATE INDEX IF NOT EXISTS ' +\n\t\t\tquoteIdentifier(deriveSQLiteIndexName(schema.name, group)) +\n\t\t\t' ON ' +\n\t\t\tquoteIdentifier(schema.name) +\n\t\t\t' (' +\n\t\t\tgroup.map(quoteIdentifier).join(', ') +\n\t\t\t')',\n\t)\n}\n\n/**\n * Project one {@link MigrationStep} to SQLite DDL.\n *\n * @param step - The migration step\n * @returns The statements that apply the step\n */\nexport function stepToSQL(step: MigrationStep): readonly string[] {\n\tswitch (step.operation) {\n\t\tcase 'table.add':\n\t\t\treturn [schemaToTable(step.table), ...schemaToIndexes(step.table)]\n\t\tcase 'table.remove':\n\t\t\treturn ['DROP TABLE IF EXISTS ' + quoteIdentifier(step.table)]\n\t\tcase 'column.add':\n\t\t\treturn [\n\t\t\t\t'ALTER TABLE ' +\n\t\t\t\t\tquoteIdentifier(step.table) +\n\t\t\t\t\t' ADD COLUMN ' +\n\t\t\t\t\tquoteIdentifier(step.column.name) +\n\t\t\t\t\t' ' +\n\t\t\t\t\tcompileColumnSQL(step.column.storage) +\n\t\t\t\t\t(step.column.optional || step.column.nullable ? '' : ' NOT NULL'),\n\t\t\t]\n\t\tcase 'column.remove':\n\t\t\treturn [\n\t\t\t\t'ALTER TABLE ' +\n\t\t\t\t\tquoteIdentifier(step.table) +\n\t\t\t\t\t' DROP COLUMN ' +\n\t\t\t\t\tquoteIdentifier(step.column),\n\t\t\t]\n\t\tcase 'index.add':\n\t\t\treturn [\n\t\t\t\t'CREATE INDEX IF NOT EXISTS ' +\n\t\t\t\t\tquoteIdentifier(deriveSQLiteIndexName(step.table, step.index)) +\n\t\t\t\t\t' ON ' +\n\t\t\t\t\tquoteIdentifier(step.table) +\n\t\t\t\t\t' (' +\n\t\t\t\t\tstep.index.map(quoteIdentifier).join(', ') +\n\t\t\t\t\t')',\n\t\t\t]\n\t\tcase 'index.remove':\n\t\t\treturn [\n\t\t\t\t'DROP INDEX IF EXISTS ' + quoteIdentifier(deriveSQLiteIndexName(step.table, step.index)),\n\t\t\t]\n\t}\n}\n","/**\n * The internal continuation boundary for a root driver async iterator.\n *\n * @remarks\n * A driver transaction can begin while a caller holds an idle root iterator.\n * Every `next` therefore checks the driver's root-state guard immediately\n * before and after advancing the source. A failed continuation terminalizes the\n * iterator, discards any row produced before the post-advance guard failed, and\n * attempts source cleanup exactly once.\n */\nexport class DriverIterator<T> implements AsyncIterableIterator<T> {\n\treadonly #source: AsyncIterator<T>\n\treadonly #guard: () => void\n\t#terminal = false\n\t#cleaned = false\n\n\tconstructor(source: AsyncIterator<T>, guard: () => void) {\n\t\tthis.#source = source\n\t\tthis.#guard = guard\n\t}\n\n\t[Symbol.asyncIterator](): AsyncIterableIterator<T> {\n\t\treturn this\n\t}\n\n\tasync next(): Promise<IteratorResult<T>> {\n\t\tif (this.#terminal) return { done: true, value: undefined }\n\t\ttry {\n\t\t\tthis.#guard()\n\t\t\tconst result = await this.#source.next()\n\t\t\tthis.#guard()\n\t\t\tif (result.done === true) {\n\t\t\t\tthis.#terminal = true\n\t\t\t\tthis.#cleaned = true\n\t\t\t}\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tthis.#terminal = true\n\t\t\tawait this.#discard()\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync return(): Promise<IteratorResult<T>> {\n\t\tif (this.#terminal) return { done: true, value: undefined }\n\t\tthis.#terminal = true\n\t\tif (this.#cleaned || this.#source.return === undefined) {\n\t\t\tthis.#cleaned = true\n\t\t\treturn { done: true, value: undefined }\n\t\t}\n\t\tthis.#cleaned = true\n\t\treturn this.#source.return()\n\t}\n\n\tasync throw(error?: unknown): Promise<IteratorResult<T>> {\n\t\tif (this.#terminal) throw error\n\t\tif (this.#source.throw === undefined) {\n\t\t\tthis.#terminal = true\n\t\t\tawait this.#discard()\n\t\t\tthrow error\n\t\t}\n\t\ttry {\n\t\t\tconst result = await this.#source.throw(error)\n\t\t\tif (result.done === true) {\n\t\t\t\tthis.#terminal = true\n\t\t\t\tthis.#cleaned = true\n\t\t\t}\n\t\t\treturn result\n\t\t} catch (cause) {\n\t\t\tthis.#terminal = true\n\t\t\tawait this.#discard()\n\t\t\tthrow cause\n\t\t}\n\t}\n\n\tasync #discard(): Promise<void> {\n\t\tif (this.#cleaned) return\n\t\tthis.#cleaned = true\n\t\ttry {\n\t\t\tawait this.#source.return?.()\n\t\t} catch {}\n\t}\n}\n","import type {\n\tQueryInput,\n\tDriverInterface,\n\tDriverMetadata,\n\tKey,\n\tMigrationInput,\n\tMigrationStep,\n\tOperationOptions,\n\tRow,\n\tTableSchema,\n\tStorageInterface,\n} from '@src/core'\nimport {\n\tbindRowKey,\n\tDatabaseError,\n\tMemoryDriver,\n\tcheckAbort,\n\tcloneDriverMetadata,\n\tcloneMigrationInput,\n\tequalsValue,\n\textractKey,\n\tisDatabaseError,\n\tmigrateRows,\n\tnormalizeDriverSchema,\n\tplanMigration,\n\tprojectMigrationSchema,\n\tvalidatePage,\n} from '@src/core'\nimport { isRecord } from '@orkestrel/contract'\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { DriverIterator } from '../../core/DriverIterator.js'\n\n/**\n * A persistent {@link DriverInterface} backed by a single JSON file — the\n * reference {@link MemoryDriver} plus file load / flush.\n *\n * @remarks\n * A decorator, not a reimplementation: storage primitives delegate to an inner\n * {@link MemoryDriver}, while this layer owns persistence, writer ordering,\n * isolated transactions, and queued row-snapshot restoration. `open`\n * loads the file into memory; every mutation (`write` / `delete` / `clear`) flushes\n * the whole store back. The file is one JSON object, `{ metadata?: DriverMetadata, tables: {\n * [name]: rows } }` — `metadata` is present only once the store has been `stamp`ed\n * (an unstamped store omits `metadata`); a per-table array of rows, each row carrying its own\n * primary (the table contract), so the key is recovered on load with\n * {@link extractKey} and the file need not store it. The parsed JSON crosses the\n * boundary as `unknown` and is narrowed with {@link isRecord} / {@link extractKey},\n * never asserted (AGENTS §14). Only an `ENOENT` read starts empty; every other\n * read failure or invalid existing document fails closed without publication,\n * mutation, or automatic repair. It is scan-only — it implements none of\n * the optional native `records` / `aggregate` hooks, so the core engine\n * over `scan` answers every query. For development, small datasets, and portable /\n * inspectable data; for large or concurrent workloads reach for a SQLite-backed\n * driver.\n *\n * Metadata crosses {@link cloneDriverMetadata} at parsed-file ingress, public and\n * scoped write ingress, candidate/root publication, serialization, and copy-out.\n * Callers therefore cannot mutate queued metadata, and `metadata()` always returns a\n * distinct deeply frozen snapshot. A failure in the write path ({@link\n * JSONDriver.#serialize} — `mkdir` / `writeFile` / `rename`) is wrapped and\n * rethrown as `DatabaseError` `DRIVER`, carrying the target `path` and native\n * `cause` in its context. If temporary-file cleanup also fails, the top-level\n * `DRIVER` context additionally carries `temp` and `cleanup`; a precommit abort\n * remains an `ABORTED` `DatabaseError` in `context.cause`. The fail-closed read path\n * ({@link JSONDriver.#document}) remains separate from this write-error contract.\n */\nexport class JSONDriver implements DriverInterface {\n\treadonly #path: string\n\t#memory = new MemoryDriver()\n\t#identities = new Map<string, object>()\n\t#schema: readonly TableSchema[] = []\n\t#metadata: DriverMetadata | undefined\n\t#flushCount = 0\n\t// Serializes point mutations and whole transaction callbacks. Reads await\n\t// the same chain and cannot observe a half-published file/memory transition.\n\t#chain: Promise<void> = Promise.resolve()\n\t// The token and candidate are present only while one isolated transaction\n\t// callback owns the writer. Root operations conflict instead of reaching\n\t// speculative state; the scoped capability checks the token on every call.\n\t#transaction: object | undefined\n\t#candidate: MemoryDriver | undefined\n\t#candidateIdentities: Map<string, object> | undefined\n\t#candidateSchema: readonly TableSchema[] | undefined\n\n\tconstructor(path: string) {\n\t\tthis.#path = path\n\t}\n\n\tasync open(schema: readonly TableSchema[]): Promise<void> {\n\t\tthis.#root()\n\t\tconst owned = normalizeDriverSchema(schema)\n\t\tawait this.#enqueue(() => this.#open(owned))\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.#root()\n\t\tawait this.#chain\n\t\tawait this.#memory.close()\n\t}\n\n\tasync read(table: string, key: Key): Promise<Row | undefined> {\n\t\tthis.#root()\n\t\tawait this.#chain\n\t\treturn this.#memory.read(table, key)\n\t}\n\n\tasync write(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void> {\n\t\tthis.#root()\n\t\tawait this.#enqueue(() => this.#write(table, key, row, options), options?.signal)\n\t}\n\n\tasync insert(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void> {\n\t\tthis.#root()\n\t\tawait this.#enqueue(() => this.#insert(table, key, row, options), options?.signal)\n\t}\n\n\tasync delete(table: string, key: Key, options?: OperationOptions): Promise<boolean> {\n\t\tthis.#root()\n\t\treturn this.#enqueue(() => this.#delete(table, key, options), options?.signal)\n\t}\n\n\tasync keys(table: string): Promise<readonly Key[]> {\n\t\tthis.#root()\n\t\tawait this.#chain\n\t\treturn this.#memory.keys(table)\n\t}\n\n\tscan(table: string): AsyncIterable<Row> {\n\t\treturn new DriverIterator(this.#scan(table)[Symbol.asyncIterator](), () => this.#root())\n\t}\n\n\t/**\n\t * Natively filtered lazy iteration — delegates to the inner {@link MemoryDriver}.\n\t *\n\t * @remarks\n\t * Semantics are the memory driver's own: `input.conditions` filters, `offset`\n\t * / `limit` page lazily, and `input.order` is ignored (streaming yields key\n\t * order; sorted output is `records()`'s job).\n\t *\n\t * @param table - The table to stream\n\t * @param input - The filter / offset / limit to apply lazily\n\t */\n\tstream(table: string, input: QueryInput): AsyncIterable<Row> {\n\t\tvalidatePage(input)\n\t\treturn new DriverIterator(this.#stream(table, input)[Symbol.asyncIterator](), () =>\n\t\t\tthis.#root(),\n\t\t)\n\t}\n\n\tasync clear(table: string): Promise<void> {\n\t\tthis.#root()\n\t\tawait this.#enqueue(() => this.#clear(table))\n\t}\n\n\t/**\n\t * Run an isolated native transaction callback over a candidate memory store.\n\t *\n\t * @remarks\n\t * Single-writer: nesting and root operations while active throw `CONFLICT`.\n\t * The callback receives a capability over cloned rows, schema, and metadata.\n\t * Fulfillment atomically serializes that candidate and publishes it to root\n\t * memory only after file replacement succeeds. Rejection or persistence\n\t * failure discards the candidate, and every captured capability call after\n\t * settlement throws `CONFLICT`.\n\t *\n\t * @returns The callback's resolved value\n\t */\n\tasync transaction<R>(scope: (storage: StorageInterface) => Promise<R>): Promise<R> {\n\t\tthis.#root()\n\t\treturn this.#enqueue(() => this.#transact(scope))\n\t}\n\n\t/**\n\t * Capture an owned row snapshot at an exact writer-queue position.\n\t *\n\t * @remarks\n\t * Capture owns table names, schemas, rows, and one session-local identity per\n\t * table. Rollback is repeatable: it clones the then-current root into a\n\t * candidate, adapts captured rows to each surviving same-identity table\n\t * through the portable migration engine, persists the candidate with current\n\t * metadata, and publishes memory only after file replacement succeeds.\n\t * Removed, replaced, uncaptured, and later-added tables remain untouched.\n\t *\n\t * @param tables - Existing tables to capture; omitted captures every current table\n\t * @returns A repeatable rollback operation\n\t */\n\tasync snapshot(tables?: readonly string[]): Promise<() => Promise<void>> {\n\t\tthis.#root()\n\t\tconst names = tables === undefined ? undefined : [...tables]\n\t\tconst captured = await this.#enqueue(() => this.#capture(names))\n\t\treturn async () => {\n\t\t\tthis.#root()\n\t\t\tawait this.#enqueue(() => this.#restore(captured))\n\t\t}\n\t}\n\n\tasync metadata(): Promise<DriverMetadata | undefined> {\n\t\tthis.#root()\n\t\tawait this.#chain\n\t\treturn this.#metadata === undefined ? undefined : cloneDriverMetadata(this.#metadata)\n\t}\n\n\t/**\n\t * Persist an owned metadata snapshot for a later `metadata()` to copy out.\n\t *\n\t * @remarks\n\t * Root stamping conflicts while a transaction is active. The scoped\n\t * {@link StorageInterface.stamp} updates candidate metadata and publishes\n\t * with the candidate rows on callback fulfillment.\n\t *\n\t * @param metadata - The {@link DriverMetadata} to persist\n\t */\n\tasync stamp(metadata: DriverMetadata): Promise<void> {\n\t\tthis.#root()\n\t\tconst owned = cloneDriverMetadata(metadata)\n\t\tawait this.#enqueue(() => this.#stamp(owned))\n\t}\n\n\t/**\n\t * Apply one atomic {@link MigrationInput} through an isolated candidate.\n\t *\n\t * @remarks\n\t * The candidate receives every plan step plus optional metadata. Its complete\n\t * rows, derived schema, and metadata serialize through one atomic file\n\t * replacement before root memory changes. Any migration or persistence failure\n\t * therefore leaves root state and the prior file exact.\n\t *\n\t * @param input - The plan and optional metadata to settle together\n\t */\n\tasync migrate(input: MigrationInput): Promise<void> {\n\t\tthis.#root()\n\t\tconst owned = cloneMigrationInput(input)\n\t\tawait this.#enqueue(() => this.#migrate(owned))\n\t}\n\n\t// === Private\n\n\tasync *#scan(table: string): AsyncIterable<Row> {\n\t\tawait this.#chain\n\t\tfor await (const row of this.#memory.scan(table)) yield row\n\t}\n\n\tasync *#stream(table: string, input: QueryInput): AsyncIterable<Row> {\n\t\tawait this.#chain\n\t\tfor await (const row of this.#memory.stream(table, input)) yield row\n\t}\n\n\tasync #open(declared: readonly TableSchema[]): Promise<void> {\n\t\tconst parsed = await this.#document()\n\t\tlet stored: DriverMetadata | undefined\n\t\tlet tables: Readonly<Record<string, unknown>>\n\t\tif (parsed === undefined) {\n\t\t\tconst fresh: Record<string, unknown> = {}\n\t\t\tfor (const table of declared) fresh[table.name] = []\n\t\t\ttables = fresh\n\t\t} else {\n\t\t\tif (\n\t\t\t\t!isRecord(parsed) ||\n\t\t\t\t!Object.hasOwn(parsed, 'tables') ||\n\t\t\t\tObject.keys(parsed).some((key) => key !== 'tables' && key !== 'metadata')\n\t\t\t) {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'Stored JSON database document is invalid', {\n\t\t\t\t\tpath: this.#path,\n\t\t\t\t\taspect: 'document',\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (!isRecord(parsed.tables)) {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'Stored JSON tables are invalid', {\n\t\t\t\t\tpath: this.#path,\n\t\t\t\t\taspect: 'tables',\n\t\t\t\t})\n\t\t\t}\n\t\t\ttables = parsed.tables\n\t\t\tif (Object.hasOwn(parsed, 'metadata')) {\n\t\t\t\ttry {\n\t\t\t\t\tstored = cloneDriverMetadata(parsed.metadata)\n\t\t\t\t} catch {\n\t\t\t\t\tconst cause = new DatabaseError('VALIDATION', 'Stored JSON metadata failed validation', {\n\t\t\t\t\t\tpath: 'metadata',\n\t\t\t\t\t})\n\t\t\t\t\tthrow new DatabaseError('DRIVER', 'Stored JSON metadata is invalid', {\n\t\t\t\t\t\tpath: this.#path,\n\t\t\t\t\t\taspect: 'metadata',\n\t\t\t\t\t\tcause,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst schema = normalizeDriverSchema(stored?.schema ?? declared)\n\t\tconst names = new Set(schema.map((table) => table.name))\n\t\tfor (const table of schema) {\n\t\t\tif (!Object.hasOwn(tables, table.name)) {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'Stored JSON table set is invalid', {\n\t\t\t\t\tpath: this.#path,\n\t\t\t\t\ttable: table.name,\n\t\t\t\t\taspect: 'missing',\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tconst unknown = Object.keys(tables).filter((name) => !names.has(name)).length\n\t\tif (unknown > 0) {\n\t\t\tthrow new DatabaseError('DRIVER', 'Stored JSON table set is invalid', {\n\t\t\t\tpath: this.#path,\n\t\t\t\taspect: 'unknown',\n\t\t\t\tcount: unknown,\n\t\t\t})\n\t\t}\n\t\tconst memory = new MemoryDriver()\n\t\tawait memory.open(schema)\n\t\tawait this.#hydrate(memory, schema, tables)\n\t\tif (stored !== undefined) await memory.stamp(stored)\n\t\tthis.#memory = memory\n\t\tthis.#schema = schema\n\t\tthis.#identities = this.#alignIdentities(schema)\n\t\tconst metadata = await memory.metadata()\n\t\tthis.#metadata = metadata === undefined ? undefined : cloneDriverMetadata(metadata)\n\t}\n\n\tasync #migrate(input: MigrationInput): Promise<void> {\n\t\tconst candidate = await this.#clone()\n\t\tconst identities = this.#projectIdentities(this.#identities, input.plan.steps)\n\t\tconst schema = await this.#apply(candidate, this.#schema, input)\n\t\tconst metadata = await candidate.metadata()\n\t\tawait this.#serialize(undefined, candidate, schema, metadata)\n\t\tthis.#memory = candidate\n\t\tthis.#identities = identities\n\t\tthis.#schema = schema\n\t\tthis.#metadata = metadata === undefined ? undefined : cloneDriverMetadata(metadata)\n\t}\n\n\tasync #apply(\n\t\tmemory: MemoryDriver,\n\t\tcurrent: readonly TableSchema[],\n\t\tinput: MigrationInput,\n\t): Promise<readonly TableSchema[]> {\n\t\tconst schema = projectMigrationSchema(current, input.plan.steps)\n\t\tif (\n\t\t\tinput.metadata !== undefined &&\n\t\t\t!equalsValue(normalizeDriverSchema(input.metadata.schema), schema)\n\t\t) {\n\t\t\tthrow new DatabaseError('MIGRATION', 'Migration metadata schema does not match the plan', {\n\t\t\t\tprojected: schema,\n\t\t\t\tmetadata: input.metadata.schema,\n\t\t\t})\n\t\t}\n\t\tawait memory.migrate(input)\n\t\treturn schema\n\t}\n\n\tasync #transact<R>(scope: (storage: StorageInterface) => Promise<R>): Promise<R> {\n\t\tthis.#root()\n\t\tconst candidate = await this.#clone()\n\t\tconst token = {}\n\t\tthis.#transaction = token\n\t\tthis.#candidate = candidate\n\t\tthis.#candidateIdentities = new Map(this.#identities)\n\t\tthis.#candidateSchema = this.#schema\n\t\ttry {\n\t\t\tconst value = await scope(this.#capability(token))\n\t\t\tconst schema = this.#candidateSchema\n\t\t\tconst identities = this.#candidateIdentities\n\t\t\tif (schema === undefined || identities === undefined) {\n\t\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction scope has settled')\n\t\t\t}\n\t\t\tthis.#candidate = undefined\n\t\t\tthis.#candidateIdentities = undefined\n\t\t\tthis.#candidateSchema = undefined\n\t\t\tconst metadata = await candidate.metadata()\n\t\t\tawait this.#serialize(undefined, candidate, schema, metadata)\n\t\t\tthis.#memory = candidate\n\t\t\tthis.#identities = identities\n\t\t\tthis.#schema = schema\n\t\t\tthis.#metadata = metadata === undefined ? undefined : cloneDriverMetadata(metadata)\n\t\t\treturn value\n\t\t} finally {\n\t\t\tif (this.#transaction === token) {\n\t\t\t\tthis.#transaction = undefined\n\t\t\t\tthis.#candidate = undefined\n\t\t\t\tthis.#candidateIdentities = undefined\n\t\t\t\tthis.#candidateSchema = undefined\n\t\t\t}\n\t\t}\n\t}\n\n\tasync #clone(): Promise<MemoryDriver> {\n\t\tconst candidate = new MemoryDriver()\n\t\tawait candidate.open(this.#schema)\n\t\tfor (const table of this.#schema) {\n\t\t\tfor await (const row of this.#memory.scan(table.name)) {\n\t\t\t\tconst key = extractKey(row, table.primary)\n\t\t\t\tif (key !== undefined) await candidate.write(table.name, key, row)\n\t\t\t}\n\t\t}\n\t\tif (this.#metadata !== undefined) {\n\t\t\tawait candidate.stamp(cloneDriverMetadata(this.#metadata))\n\t\t}\n\t\treturn candidate\n\t}\n\n\tasync #capture(names: readonly string[] | undefined) {\n\t\tconst selected = names === undefined ? undefined : new Set(names)\n\t\tconst captured = new Map<\n\t\t\tstring,\n\t\t\t{ readonly identity: object; readonly schema: TableSchema; readonly rows: readonly Row[] }\n\t\t>()\n\t\tfor (const table of this.#schema) {\n\t\t\tif (selected !== undefined && !selected.has(table.name)) continue\n\t\t\tconst identity = this.#identities.get(table.name)\n\t\t\tif (identity === undefined) continue\n\t\t\tconst rows: Row[] = []\n\t\t\tfor await (const row of this.#memory.scan(table.name)) rows.push(row)\n\t\t\tcaptured.set(table.name, { identity, schema: table, rows })\n\t\t}\n\t\treturn captured\n\t}\n\n\tasync #restore(\n\t\tcaptured: ReadonlyMap<\n\t\t\tstring,\n\t\t\t{ readonly identity: object; readonly schema: TableSchema; readonly rows: readonly Row[] }\n\t\t>,\n\t): Promise<void> {\n\t\tconst replacements = new Map<string, ReadonlyMap<Key, Row>>()\n\t\tfor (const [name, capture] of captured) {\n\t\t\tconst current = this.#schema.find((table) => table.name === name)\n\t\t\tif (current === undefined || this.#identities.get(name) !== capture.identity) continue\n\t\t\tconst plan = planMigration([capture.schema], [current])\n\t\t\tconst migrated = migrateRows(capture.rows, plan.steps)\n\t\t\tif (migrated.length !== capture.rows.length) {\n\t\t\t\tthrow new DatabaseError('MIGRATION', 'Snapshot row count changed during migration', {\n\t\t\t\t\ttable: name,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst rows = new Map<Key, Row>()\n\t\t\tfor (const [index, row] of migrated.entries()) {\n\t\t\t\tconst key = extractKey(row, current.primary)\n\t\t\t\tif (key === undefined) {\n\t\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t\t'MIGRATION',\n\t\t\t\t\t\t`migrate: captured row is missing primary column '${current.primary}'`,\n\t\t\t\t\t\t{ table: name, column: current.primary, index },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\trows.set(key, bindRowKey(row, current.primary, key))\n\t\t\t}\n\t\t\treplacements.set(name, rows)\n\t\t}\n\t\tconst candidate = await this.#clone()\n\t\tfor (const [name, rows] of replacements) {\n\t\t\tawait candidate.clear(name)\n\t\t\tfor (const [key, row] of rows) await candidate.write(name, key, row)\n\t\t}\n\t\tconst metadata = await candidate.metadata()\n\t\tawait this.#serialize(undefined, candidate, this.#schema, metadata)\n\t\tthis.#memory = candidate\n\t\tthis.#metadata = metadata === undefined ? undefined : cloneDriverMetadata(metadata)\n\t}\n\n\t#capability(token: object): StorageInterface {\n\t\treturn {\n\t\t\tread: this.#readCandidate.bind(this, token),\n\t\t\twrite: this.#writeCandidate.bind(this, token),\n\t\t\tinsert: this.#insertCandidate.bind(this, token),\n\t\t\tdelete: this.#deleteCandidate.bind(this, token),\n\t\t\tkeys: this.#keysCandidate.bind(this, token),\n\t\t\tscan: this.#scanCandidate.bind(this, token),\n\t\t\tclear: this.#clearCandidate.bind(this, token),\n\t\t\tmigrate: this.#migrateCandidate.bind(this, token),\n\t\t\tmetadata: this.#metadataCandidate.bind(this, token),\n\t\t\tstamp: this.#stampCandidate.bind(this, token),\n\t\t}\n\t}\n\n\tasync #readCandidate(token: object, table: string, key: Key): Promise<Row | undefined> {\n\t\treturn this.#requireCandidate(token).read(table, key)\n\t}\n\n\tasync #writeCandidate(\n\t\ttoken: object,\n\t\ttable: string,\n\t\tkey: Key,\n\t\trow: Row,\n\t\toptions?: OperationOptions,\n\t): Promise<void> {\n\t\tawait this.#requireCandidate(token).write(table, key, row, options)\n\t}\n\n\tasync #insertCandidate(\n\t\ttoken: object,\n\t\ttable: string,\n\t\tkey: Key,\n\t\trow: Row,\n\t\toptions?: OperationOptions,\n\t): Promise<void> {\n\t\tawait this.#requireCandidate(token).insert(table, key, row, options)\n\t}\n\n\tasync #deleteCandidate(\n\t\ttoken: object,\n\t\ttable: string,\n\t\tkey: Key,\n\t\toptions?: OperationOptions,\n\t): Promise<boolean> {\n\t\treturn this.#requireCandidate(token).delete(table, key, options)\n\t}\n\n\tasync #keysCandidate(token: object, table: string): Promise<readonly Key[]> {\n\t\treturn this.#requireCandidate(token).keys(table)\n\t}\n\n\t#scanCandidate(token: object, table: string): AsyncIterable<Row> {\n\t\tconst source = this.#requireCandidate(token).scan(table)\n\t\treturn new DriverIterator(source[Symbol.asyncIterator](), () => {\n\t\t\tthis.#requireCandidate(token)\n\t\t})\n\t}\n\n\tasync #clearCandidate(token: object, table: string): Promise<void> {\n\t\tawait this.#requireCandidate(token).clear(table)\n\t}\n\n\tasync #migrateCandidate(token: object, input: MigrationInput): Promise<void> {\n\t\tconst memory = this.#requireCandidate(token)\n\t\tconst schema = this.#candidateSchema\n\t\tconst identities = this.#candidateIdentities\n\t\tif (schema === undefined || identities === undefined) {\n\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction scope has settled')\n\t\t}\n\t\tconst owned = cloneMigrationInput(input)\n\t\tconst projected = this.#projectIdentities(identities, owned.plan.steps)\n\t\tthis.#candidateSchema = await this.#apply(memory, schema, owned)\n\t\tthis.#candidateIdentities = projected\n\t}\n\n\tasync #metadataCandidate(token: object): Promise<DriverMetadata | undefined> {\n\t\tconst metadata = await this.#requireCandidate(token).metadata()\n\t\treturn metadata === undefined ? undefined : cloneDriverMetadata(metadata)\n\t}\n\n\tasync #stampCandidate(token: object, metadata: DriverMetadata): Promise<void> {\n\t\tconst memory = this.#requireCandidate(token)\n\t\tconst owned = cloneDriverMetadata(metadata)\n\t\tawait memory.stamp(owned)\n\t}\n\n\t#requireCandidate(token: object): MemoryDriver {\n\t\tif (this.#transaction !== token || this.#candidate === undefined) {\n\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction scope has settled')\n\t\t}\n\t\treturn this.#candidate\n\t}\n\n\t#alignIdentities(schema: readonly TableSchema[]): Map<string, object> {\n\t\tconst aligned = new Map<string, object>()\n\t\tfor (const table of schema) {\n\t\t\taligned.set(table.name, this.#identities.get(table.name) ?? {})\n\t\t}\n\t\treturn aligned\n\t}\n\n\t#projectIdentities(\n\t\tidentities: ReadonlyMap<string, object>,\n\t\tsteps: readonly MigrationStep[],\n\t): Map<string, object> {\n\t\tconst projected = new Map(identities)\n\t\tfor (const step of steps) {\n\t\t\tif (step.operation === 'table.add') projected.set(step.table.name, {})\n\t\t\tif (step.operation === 'table.remove') projected.delete(step.table)\n\t\t}\n\t\treturn projected\n\t}\n\n\t#root(): void {\n\t\tif (this.#transaction !== undefined) {\n\t\t\tthrow new DatabaseError('CONFLICT', 'A transaction is active on this driver')\n\t\t}\n\t}\n\n\t// Read and parse without publishing state. Only native ENOENT is absence;\n\t// every existing unreadable or syntactically invalid file fails closed.\n\tasync #document(): Promise<unknown> {\n\t\tlet raw: string\n\t\ttry {\n\t\t\traw = await readFile(this.#path, 'utf-8')\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\ttypeof error === 'object' &&\n\t\t\t\terror !== null &&\n\t\t\t\t'code' in error &&\n\t\t\t\terror.code === 'ENOENT'\n\t\t\t) {\n\t\t\t\treturn undefined\n\t\t\t}\n\t\t\tthrow new DatabaseError('DRIVER', 'Failed to read the JSON database file', {\n\t\t\t\tpath: this.#path,\n\t\t\t\tcause: error,\n\t\t\t})\n\t\t}\n\t\ttry {\n\t\t\treturn JSON.parse(raw)\n\t\t} catch {\n\t\t\tthrow new DatabaseError('DRIVER', 'Stored JSON database is invalid JSON', {\n\t\t\t\tpath: this.#path,\n\t\t\t\taspect: 'syntax',\n\t\t\t})\n\t\t}\n\t}\n\n\t// Validate and hydrate only into the local candidate memory. The caller\n\t// publishes that candidate after every selected table and row succeeds.\n\tasync #hydrate(\n\t\tmemory: MemoryDriver,\n\t\tschema: readonly TableSchema[],\n\t\ttables: Readonly<Record<string, unknown>>,\n\t): Promise<void> {\n\t\tfor (const table of schema) {\n\t\t\tconst rows = tables[table.name]\n\t\t\tif (!Array.isArray(rows)) {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'Stored JSON table is invalid', {\n\t\t\t\t\tpath: this.#path,\n\t\t\t\t\ttable: table.name,\n\t\t\t\t\taspect: 'container',\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst keys = new Set<Key>()\n\t\t\tfor (const [index, entry] of rows.entries()) {\n\t\t\t\tif (!isRecord(entry)) {\n\t\t\t\t\tthrow new DatabaseError('DRIVER', 'Stored JSON row is invalid', {\n\t\t\t\t\t\tpath: this.#path,\n\t\t\t\t\t\ttable: table.name,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\taspect: 'record',\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconst key = extractKey(entry, table.primary)\n\t\t\t\tif (key === undefined) {\n\t\t\t\t\tthrow new DatabaseError('DRIVER', 'Stored JSON row is invalid', {\n\t\t\t\t\t\tpath: this.#path,\n\t\t\t\t\t\ttable: table.name,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\taspect: 'primary',\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (keys.has(key)) {\n\t\t\t\t\tthrow new DatabaseError('DRIVER', 'Stored JSON row is invalid', {\n\t\t\t\t\t\tpath: this.#path,\n\t\t\t\t\t\ttable: table.name,\n\t\t\t\t\t\tindex,\n\t\t\t\t\t\taspect: 'duplicate',\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tkeys.add(key)\n\t\t\t\tawait memory.write(table.name, key, entry)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Queue a nontransactional operation behind #chain.\n\tasync #enqueue<R>(operation: () => Promise<R>, signal?: AbortSignal): Promise<R> {\n\t\tcheckAbort(signal)\n\t\tlet started = false\n\t\tconst next = this.#chain.then(async () => {\n\t\t\tstarted = true\n\t\t\tcheckAbort(signal)\n\t\t\treturn operation()\n\t\t})\n\t\tthis.#chain = next.then(\n\t\t\t() => {},\n\t\t\t() => {},\n\t\t)\n\t\tif (signal === undefined) return next\n\t\tconst cleanup = new AbortController()\n\t\treturn new Promise<R>((resolve, reject) => {\n\t\t\tsignal.addEventListener(\n\t\t\t\t'abort',\n\t\t\t\t() => {\n\t\t\t\t\tif (started) return\n\t\t\t\t\ttry {\n\t\t\t\t\t\tcheckAbort(signal)\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\treject(error)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ once: true, signal: cleanup.signal },\n\t\t\t)\n\t\t\tnext.then(\n\t\t\t\t(result) => {\n\t\t\t\t\tcleanup.abort()\n\t\t\t\t\tresolve(result)\n\t\t\t\t},\n\t\t\t\t(error) => {\n\t\t\t\t\tcleanup.abort()\n\t\t\t\t\treject(error)\n\t\t\t\t},\n\t\t\t)\n\t\t})\n\t}\n\n\tasync #write(\n\t\ttable: string,\n\t\tkey: Key,\n\t\trow: Row,\n\t\toptions: OperationOptions | undefined,\n\t): Promise<void> {\n\t\tconst previous = await this.#memory.read(table, key)\n\t\tawait this.#memory.write(table, key, row, options)\n\t\ttry {\n\t\t\tawait this.#serialize(options?.signal)\n\t\t} catch (error) {\n\t\t\tif (previous === undefined) await this.#memory.delete(table, key)\n\t\t\telse await this.#memory.write(table, key, previous)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync #insert(\n\t\ttable: string,\n\t\tkey: Key,\n\t\trow: Row,\n\t\toptions: OperationOptions | undefined,\n\t): Promise<void> {\n\t\tawait this.#memory.insert(table, key, row, options)\n\t\ttry {\n\t\t\tawait this.#serialize(options?.signal)\n\t\t} catch (error) {\n\t\t\tawait this.#memory.delete(table, key)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync #delete(table: string, key: Key, options: OperationOptions | undefined): Promise<boolean> {\n\t\tconst previous = await this.#memory.read(table, key)\n\t\tif (previous === undefined) {\n\t\t\tcheckAbort(options?.signal)\n\t\t\treturn false\n\t\t}\n\t\tawait this.#memory.delete(table, key, options)\n\t\ttry {\n\t\t\tawait this.#serialize(options?.signal)\n\t\t} catch (error) {\n\t\t\tawait this.#memory.write(table, key, previous)\n\t\t\tthrow error\n\t\t}\n\t\treturn true\n\t}\n\n\tasync #clear(table: string): Promise<void> {\n\t\tconst rollback = await this.#memory.snapshot([table])\n\t\tawait this.#memory.clear(table)\n\t\ttry {\n\t\t\tawait this.#serialize()\n\t\t} catch (error) {\n\t\t\tawait rollback()\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync #stamp(metadata: DriverMetadata): Promise<void> {\n\t\tconst previous = this.#metadata\n\t\tthis.#metadata = cloneDriverMetadata(metadata)\n\t\ttry {\n\t\t\tawait this.#serialize()\n\t\t} catch (error) {\n\t\t\tthis.#metadata = previous\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t// Drain every declared table's rows from memory (in key order) and write the\n\t// whole store back as one pretty-printed JSON object, creating the directory.\n\t//\n\t// @remarks\n\t// Written atomically: the payload lands in a sibling temp file (same directory,\n\t// so the platform rename is atomic) and is then renamed onto `#path`. A crash\n\t// mid-flush can no longer truncate or corrupt the previous good file — POSIX\n\t// `rename` replaces the destination in one indivisible step, so a reader always\n\t// sees either the old file or the fully-written new one, never a partial write.\n\t// `#enqueue` serializes calls to this method through `#chain` — each job AWAITS\n\t// its predecessor before draining `#memory` and writing, so the payload always\n\t// reflects the latest memory state. Without this, overlapping flushes triggered\n\t// by non-awaited concurrent mutations could serialize out of order and persist a\n\t// stale snapshot as the \"latest\" file. `metadata` is included in the payload only\n\t// once the store has been stamped; an unstamped store omits it. Metadata is cloned before the\n\t// first scan so this serialization owns one validated immutable snapshot.\n\t// A lone write-path failure becomes `DRIVER` after cleanup succeeds, while a\n\t// precommit abort retains `ABORTED`. If cleanup also fails, the top-level\n\t// `DRIVER` context carries `path`, `temp`, the mapped/original `cause`, and\n\t// `cleanup`.\n\tasync #serialize(\n\t\tsignal?: AbortSignal,\n\t\tmemory = this.#memory,\n\t\tschema = this.#schema,\n\t\tmetadata = this.#metadata,\n\t): Promise<void> {\n\t\tconst owned = metadata === undefined ? undefined : cloneDriverMetadata(metadata)\n\t\tconst tables: Record<string, readonly Row[]> = {}\n\t\tcheckAbort(signal)\n\t\tfor (const table of schema) {\n\t\t\tconst rows: Row[] = []\n\t\t\tfor await (const row of memory.scan(table.name)) {\n\t\t\t\tcheckAbort(signal)\n\t\t\t\trows.push(row)\n\t\t\t}\n\t\t\ttables[table.name] = rows\n\t\t}\n\t\tcheckAbort(signal)\n\t\tthis.#flushCount += 1\n\t\tconst temp = `${this.#path}.${process.pid}.${this.#flushCount}.tmp`\n\t\tconst payload = owned === undefined ? { tables } : { metadata: owned, tables }\n\t\tlet dispatched = false\n\t\ttry {\n\t\t\tawait mkdir(dirname(this.#path), { recursive: true })\n\t\t\tconst serialized = JSON.stringify(payload, null, 2)\n\t\t\tcheckAbort(signal)\n\t\t\tawait writeFile(temp, serialized, {\n\t\t\t\tencoding: 'utf-8',\n\t\t\t\tflush: true,\n\t\t\t\tsignal,\n\t\t\t})\n\t\t\tcheckAbort(signal)\n\t\t\tdispatched = true\n\t\t\tawait rename(temp, this.#path)\n\t\t} catch (error) {\n\t\t\tlet cause: unknown = error\n\t\t\tif (!dispatched) {\n\t\t\t\ttry {\n\t\t\t\t\tcheckAbort(signal)\n\t\t\t\t} catch (abort) {\n\t\t\t\t\tcause = abort\n\t\t\t\t}\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait rm(temp, { force: true })\n\t\t\t} catch (cleanup) {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'Failed to persist and clean the database file', {\n\t\t\t\t\tpath: this.#path,\n\t\t\t\t\ttemp,\n\t\t\t\t\tcause,\n\t\t\t\t\tcleanup,\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (isDatabaseError(cause) && cause.code === 'ABORTED') throw cause\n\t\t\tthrow new DatabaseError('DRIVER', 'Failed to persist the database file', {\n\t\t\t\tpath: this.#path,\n\t\t\t\tcause,\n\t\t\t})\n\t\t}\n\t}\n}\n","import type {\n\tAggregateOperation,\n\tQueryInput,\n\tDriverInterface,\n\tDriverMetadata,\n\tKey,\n\tMigrationInput,\n\tOperationOptions,\n\tRow,\n\tTableSchema,\n\tStorageInterface,\n} from '@src/core'\nimport type { FieldPath } from '@orkestrel/contract'\nimport type { SQLiteDatabaseInterface, SQLiteValue } from '@orkestrel/sqlite'\nimport type { SQLiteDriverOptions } from '../types.js'\nimport {\n\tapplyQuery,\n\tbindRowKey,\n\tcloneDriverMetadata,\n\tcloneMigrationInput,\n\tcomputeAggregate,\n\tcheckAbort,\n\tDatabaseError,\n\tfilterRows,\n\tequalsValue,\n\textractKey,\n\tisDatabaseError,\n\tisKey,\n\tmatchesQuery,\n\tmigrateRows,\n\tnormalizeDriverSchema,\n\tplanMigration,\n\tprojectMigrationSchema,\n\tvalidatePage,\n} from '@src/core'\nimport { createSQLiteDatabase, isSQLiteError } from '@orkestrel/sqlite'\nimport {\n\tcompileAggregateSQL,\n\tcompileQuerySQL,\n\tcompileWhere,\n\tschemaToIndexes,\n\tschemaToTable,\n\tstepToSQL,\n} from '../compilers.js'\nimport {\n\tdecodeRow,\n\tencodeRow,\n\tencodeValue,\n\textractValues,\n\tderiveSQLiteIndexName,\n\tmatchesAggregateExactly,\n\tmatchesConditionExactly,\n\tmatchesQueryExactly,\n\tmatchesSQLiteAffinity,\n\tquoteIdentifier,\n} from '../helpers.js'\nimport { METADATA_TABLE } from '../constants.js'\nimport { DriverIterator } from '../../core/DriverIterator.js'\n\n/**\n * The SQLite {@link DriverInterface} — the server-native, trusted-mode backend\n * built on the published `@orkestrel/sqlite` synchronous wrapper.\n *\n * @remarks\n * A thin adapter: it implements the storage primitives the core database layer\n * needs by delegating to the wrapper's prepared statements — it never touches\n * raw `node:sqlite`. `open` issues `CREATE TABLE IF NOT EXISTS` with real typed\n * columns (mapped from each {@link TableSchema}'s portable column types) and a\n * `PRIMARY KEY`, plus a `CREATE INDEX IF NOT EXISTS` per declared index (both\n * reopen-safe), and readies a reserved `_metadata` single-row table `metadata()` /\n * `stamp()` read and write — **a user table named `_metadata` collides with it**;\n * avoid the name. Rows cross the boundary through the codecs in `helpers.ts`\n * (`json` columns store / parse JSON text, a `boolean` stores `1` / `0`), so the\n * typed layer above imposes the exact shape (AGENTS §14). `write` is an\n * `INSERT OR REPLACE` upsert, while `insert` uses a plain `INSERT` and maps its\n * atomic primary-key constraint failure to `CONFLICT`; every other backend\n * `SQLiteError` is contained by the same `DatabaseError` boundary described\n * below. Querying, ordering, paging, and\n * aggregation is native: `records` / `stream` compile a `QueryInput`\n * to SQL with `compileQuerySQL`, and `aggregate` runs a SQL\n * `COUNT`/`SUM`/`AVG`/`MIN`/`MAX` (via `compileAggregateSQL`) over the same compiled\n * WHERE. `transaction` runs a callback inside native `BEGIN` / `COMMIT` /\n * `ROLLBACK`, passing a scoped storage capability that becomes invalid after\n * settlement. `migrate` runs the plan's projected DDL\n * ({@link import('../compilers.js').stepToSQL}) inside whichever native\n * transaction is active: joined into the active transaction callback\n * when one exists (the core's versioned reconcile path wraps migrate + stamp\n * in one native `BEGIN`, and node:sqlite rejects a nested `BEGIN`), or inside\n * its own `database.transaction` otherwise — a mid-plan failure rolls back\n * atomically either way, an improvement over the non-atomic `MemoryDriver` /\n * `JSONDriver` migrate; a step referencing an undeclared table throws\n * `DatabaseError` `MIGRATION` before any DDL for that step runs. `snapshot` is\n * capture-replay (SELECT the\n * named tables' rows, replay via DELETE + INSERT OR REPLACE inside a native\n * transaction on rollback) rather than a SQL `SAVEPOINT`, since the core\n * `transaction` calls the rollback thunk only on failure with no commit-on-\n * success signal — a long-lived `SAVEPOINT` would leave the connection\n * uncommitted (lost on close). Every backend interaction runs through `#guard`,\n * which maps a thrown backend `SQLiteError` (or any unexpected non-`SQLiteError`\n * throw) to a typed {@link DatabaseError} — never a raw backend error escapes\n * `DriverInterface`: `CONSTRAINT` → `CONFLICT`, the wrapper's own `CLOSED` →\n * `CLOSED`, `BUSY` (a locked database that outlasted the configured `timeout`)\n * → a retryable `DRIVER` (`context.retryable` is `true`), and `UNKNOWN` / any\n * other throw → `DRIVER`. The original error is preserved as `context.cause`.\n * A `DatabaseError` this driver throws directly (`CLOSED` from the `#require`\n * gate, `NOT_FOUND` from `#table`, `MIGRATION` from a migration-plan fault)\n * passes through `#guard` unchanged, never re-wrapped.\n */\nexport class SQLiteDriver implements DriverInterface {\n\treadonly #path: string\n\treadonly #options: SQLiteDriverOptions\n\t#database: SQLiteDatabaseInterface | undefined\n\t#schema = new Map<string, TableSchema>()\n\t#identities = new Map<string, object>()\n\t#transaction: object | undefined\n\t#candidateSchema: Map<string, TableSchema> | undefined\n\t#candidateIdentities: Map<string, object> | undefined\n\n\tconstructor(options: SQLiteDriverOptions = {}) {\n\t\tthis.#path = options.path ?? ':memory:'\n\t\tthis.#options = options\n\t}\n\n\tasync open(schema: readonly TableSchema[]): Promise<void> {\n\t\tthis.#root()\n\t\tconst owned = normalizeDriverSchema(schema)\n\t\tif (owned.some((table) => table.name === METADATA_TABLE)) {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'VALIDATION',\n\t\t\t\t`A declared table cannot be named '${METADATA_TABLE}' — it is reserved for driver metadata`,\n\t\t\t\t{ table: METADATA_TABLE },\n\t\t\t)\n\t\t}\n\t\tthis.#guard(() => {\n\t\t\tconst current = this.#database\n\t\t\tconst previousIdentities = this.#identities\n\t\t\tthis.#database = undefined\n\t\t\tthis.#schema = new Map()\n\t\t\tthis.#identities = new Map()\n\t\t\tcurrent?.close()\n\t\t\tconst database = createSQLiteDatabase({\n\t\t\t\tpath: this.#path,\n\t\t\t\t...(this.#options.readonly !== undefined ? { readonly: this.#options.readonly } : {}),\n\t\t\t\t...(this.#options.timeout !== undefined ? { timeout: this.#options.timeout } : {}),\n\t\t\t\t...(this.#options.references !== undefined\n\t\t\t\t\t? { foreignKeys: this.#options.references }\n\t\t\t\t\t: {}),\n\t\t\t})\n\t\t\ttry {\n\t\t\t\tdatabase.connect()\n\t\t\t\tfor (const [name, value] of Object.entries(this.#options.pragmas ?? {})) {\n\t\t\t\t\tdatabase.pragma(name, value)\n\t\t\t\t}\n\t\t\t\tconst map = new Map<string, TableSchema>()\n\t\t\t\tconst identities = new Map<string, object>()\n\t\t\t\tdatabase.transaction(() => {\n\t\t\t\t\tthis.#ensureMetadataTable(database)\n\t\t\t\t\tconst stored = this.#readMetadata(database)\n\t\t\t\t\tconst deployed = normalizeDriverSchema(stored?.schema ?? owned)\n\t\t\t\t\tconst missing = new Map<string, readonly string[] | undefined>()\n\t\t\t\t\tfor (const table of deployed) {\n\t\t\t\t\t\tmap.set(table.name, table)\n\t\t\t\t\t\tmissing.set(table.name, this.#validateTable(database, table))\n\t\t\t\t\t}\n\t\t\t\t\tif (stored !== undefined) {\n\t\t\t\t\t\tfor (const table of stored.schema) {\n\t\t\t\t\t\t\tif (missing.get(table.name) === undefined) {\n\t\t\t\t\t\t\t\tthrow new DatabaseError('DRIVER', 'Stored SQLite table is missing', {\n\t\t\t\t\t\t\t\t\ttable: table.name,\n\t\t\t\t\t\t\t\t\taspect: 'missing',\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (const table of deployed) {\n\t\t\t\t\t\tconst absent = missing.get(table.name)\n\t\t\t\t\t\tif (absent === undefined) {\n\t\t\t\t\t\t\tdatabase.exec(schemaToTable(table))\n\t\t\t\t\t\t\tfor (const sql of schemaToIndexes(table)) database.exec(sql)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfor (const [index, group] of table.indexes.entries()) {\n\t\t\t\t\t\t\t\tif (absent.includes(deriveSQLiteIndexName(table.name, group))) {\n\t\t\t\t\t\t\t\t\tconst sql = schemaToIndexes(table)[index]\n\t\t\t\t\t\t\t\t\tif (sql !== undefined) database.exec(sql)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tidentities.set(table.name, previousIdentities.get(table.name) ?? {})\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\tthis.#schema = map\n\t\t\t\tthis.#identities = identities\n\t\t\t\tthis.#database = database\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tdatabase.close()\n\t\t\t\t} catch {}\n\t\t\t\tthis.#schema = new Map()\n\t\t\t\tthis.#identities = new Map()\n\t\t\t\tthrow error\n\t\t\t}\n\t\t})\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.#root()\n\t\tthis.#guard(() => {\n\t\t\tthis.#database?.close()\n\t\t\tthis.#database = undefined\n\t\t})\n\t}\n\n\tasync read(table: string, key: Key): Promise<Row | undefined> {\n\t\tthis.#root()\n\t\treturn this.#read(table, key)\n\t}\n\n\tasync write(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void> {\n\t\tthis.#root()\n\t\tawait this.#write(table, key, row, options)\n\t}\n\n\tasync insert(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void> {\n\t\tthis.#root()\n\t\tawait this.#insert(table, key, row, options)\n\t}\n\n\tasync delete(table: string, key: Key, options?: OperationOptions): Promise<boolean> {\n\t\tthis.#root()\n\t\treturn this.#delete(table, key, options)\n\t}\n\n\tasync keys(table: string): Promise<readonly Key[]> {\n\t\tthis.#root()\n\t\treturn this.#keys(table)\n\t}\n\n\tscan(table: string): AsyncIterable<Row> {\n\t\treturn new DriverIterator(this.#scan(table)[Symbol.asyncIterator](), () => this.#root())\n\t}\n\n\tasync clear(table: string): Promise<void> {\n\t\tthis.#root()\n\t\tawait this.#clear(table)\n\t}\n\n\t// Doctrine (AGENTS §5, the audit's keystone fix): a QueryInput whose compiled\n\t// SQL is PROVABLY identical to the core engine's semantics (see\n\t// `matchesConditionExactly` / `matchesOrderExactly` / `matchesQueryExactly`) runs the fast\n\t// native path; otherwise this driver fetches a full scan and refines it\n\t// through the SAME core engine every scan-only driver (`MemoryDriver`,\n\t// `JSONDriver`) already uses — exact → native, otherwise → refine, never a\n\t// silent semantics drift between backends.\n\tasync records(table: string, input: QueryInput): Promise<readonly Row[]> {\n\t\tvalidatePage(input)\n\t\tthis.#root()\n\t\tconst schema = this.#table(table)\n\t\tif (matchesQueryExactly(input, schema)) {\n\t\t\treturn this.#guard(() => {\n\t\t\t\tconst { sql, parameters } = compileQuerySQL(input, schema)\n\t\t\t\tconst rows = this.#require()\n\t\t\t\t\t.prepare('SELECT * FROM ' + quoteIdentifier(table) + (sql === '' ? '' : ' ' + sql))\n\t\t\t\t\t.all(parameters)\n\t\t\t\treturn rows.map((row) => decodeRow(row, schema))\n\t\t\t})\n\t\t}\n\t\tconst rows: Row[] = []\n\t\tfor await (const row of this.#scan(table)) rows.push(row)\n\t\treturn applyQuery(rows, input)\n\t}\n\n\tasync aggregate(\n\t\ttable: string,\n\t\toperation: AggregateOperation,\n\t\tcolumn: FieldPath,\n\t\tinput: QueryInput,\n\t): Promise<number | undefined> {\n\t\tvalidatePage(input)\n\t\tthis.#root()\n\t\tconst schema = this.#table(table)\n\t\tconst conditions = input.conditions ?? []\n\t\tconst conditionsExact = conditions.every((condition) =>\n\t\t\tmatchesConditionExactly(condition, schema),\n\t\t)\n\t\t// `count` ignores `column` entirely (COUNT(*) over rows), so only the\n\t\t// conditions need to be exact; every other aggregate coerces the column\n\t\t// numerically (parseNumber) — only a flat, declared integer/real column\n\t\t// is provably exact (a text/json/blob column may hold non-numeric cells\n\t\t// the engine skips via parseNumber, which SQL's numeric aggregates do not).\n\t\tconst columnExact = matchesAggregateExactly(operation, column, schema)\n\t\tif (conditionsExact && columnExact) {\n\t\t\treturn this.#guard(() => {\n\t\t\t\t// WHERE-only compile — same rationale as `count`: paging must never\n\t\t\t\t// apply to the single aggregate row.\n\t\t\t\tconst { sql, parameters } = compileWhere(conditions, schema)\n\t\t\t\tconst value = this.#require()\n\t\t\t\t\t.prepare(\n\t\t\t\t\t\t'SELECT ' +\n\t\t\t\t\t\t\tcompileAggregateSQL(operation, column) +\n\t\t\t\t\t\t\t' AS value FROM ' +\n\t\t\t\t\t\t\tquoteIdentifier(table) +\n\t\t\t\t\t\t\t(sql === '' ? '' : ' ' + sql),\n\t\t\t\t\t)\n\t\t\t\t\t.get(parameters)?.value\n\t\t\t\t// Over zero matched rows SUM/AVG/MIN/MAX are SQL NULL → undefined (the\n\t\t\t\t// engine agrees); COUNT(*) is 0. A clean numeric column coerces as the\n\t\t\t\t// engine does.\n\t\t\t\treturn value === null || value === undefined ? undefined : Number(value)\n\t\t\t})\n\t\t}\n\t\tconst rows: Row[] = []\n\t\tfor await (const row of this.#scan(table)) rows.push(row)\n\t\treturn computeAggregate(filterRows(rows, conditions), operation, column)\n\t}\n\n\t// `order` is intentionally IGNORED (per DriverInterface.stream — streaming\n\t// yields unsorted), so the native gate checks only `conditions`; `offset` /\n\t// `limit` are always engine-identical under either path.\n\tstream(table: string, input: QueryInput): AsyncIterable<Row> {\n\t\tvalidatePage(input)\n\t\treturn new DriverIterator(this.#stream(table, input)[Symbol.asyncIterator](), () =>\n\t\t\tthis.#root(),\n\t\t)\n\t}\n\n\t/**\n\t * Begin a native transaction — real `BEGIN`, `COMMIT`, `ROLLBACK`.\n\t *\n\t * @remarks\n\t * The callback receives a scoped {@link StorageInterface}. Fulfillment\n\t * commits and returns its value; rejection rolls back and preserves the\n\t * original error. Root operations and nesting conflict while active, and a\n\t * captured capability conflicts after settlement.\n\t *\n\t * @returns The callback's resolved value\n\t */\n\tasync transaction<R>(scope: (storage: StorageInterface) => Promise<R>): Promise<R> {\n\t\tthis.#root()\n\t\tconst database = this.#require()\n\t\tthis.#guard(() => database.begin())\n\t\tconst token = {}\n\t\tthis.#transaction = token\n\t\tthis.#candidateSchema = new Map(this.#schema)\n\t\tthis.#candidateIdentities = new Map(this.#identities)\n\t\ttry {\n\t\t\tlet value: R\n\t\t\ttry {\n\t\t\t\tvalue = await scope(this.#capability(token))\n\t\t\t} catch (error) {\n\t\t\t\tthis.#guard(() => database.rollback())\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tthis.#guard(() => database.commit())\n\t\t\t} catch (error) {\n\t\t\t\tif (database.transacting) this.#guard(() => database.rollback())\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\tconst schema = this.#candidateSchema\n\t\t\tconst identities = this.#candidateIdentities\n\t\t\tif (schema === undefined || identities === undefined) {\n\t\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction scope has settled')\n\t\t\t}\n\t\t\tthis.#schema = schema\n\t\t\tthis.#identities = identities\n\t\t\treturn value\n\t\t} finally {\n\t\t\tif (this.#transaction === token) {\n\t\t\t\tthis.#transaction = undefined\n\t\t\t\tthis.#candidateSchema = undefined\n\t\t\t\tthis.#candidateIdentities = undefined\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Apply a {@link Migration} plan by executing each step's projected DDL\n\t * ({@link import('../compilers.js').stepToSQL}).\n\t *\n\t * @remarks\n\t * Atomicity is provided by whichever native transaction is active: when\n\t * this driver's own `transaction()` callback is active (the\n\t * core's versioned reconcile / migrate path joins migrate + stamp under\n\t * one native `BEGIN`), the plan's DDL runs directly inside that enclosing\n\t * transaction — a mid-plan failure rejects the callback and the driver\n\t * rolls it back. node:sqlite (and SQLite\n\t * generally) rejects a nested `BEGIN`, so this driver must never open a\n\t * second native transaction while one is already open. Otherwise (no\n\t * enclosing transaction), `migrate` wraps the plan in its own native\n\t * `database.transaction` — atomic on its own: a mid-plan failure rolls\n\t * back every DDL statement already applied by the plan. A scoped migration\n\t * uses one fixed internal savepoint literal because the published SQLite\n\t * wrapper intentionally exposes raw `exec` but no savepoint manager. That\n\t * savepoint contains a caught inner migration so the outer callback\n\t * transaction remains active and may continue safely. A step referencing a\n\t * table not in this driver's declared schema (and that is not itself a\n\t * `table.add`) throws `DatabaseError` `MIGRATION` before any DDL for that\n\t * step runs.\n\t *\n\t * @param input - The migration plan and optional metadata stamp to apply atomically\n\t */\n\tasync migrate(input: MigrationInput): Promise<void> {\n\t\tthis.#root()\n\t\tconst database = this.#require()\n\t\tconst owned = cloneMigrationInput(input)\n\t\tconst projected = projectMigrationSchema([...this.#schema.values()], owned.plan.steps)\n\t\tconst identities = this.#projectIdentities(this.#identities, owned.plan.steps)\n\t\tif (\n\t\t\towned.metadata !== undefined &&\n\t\t\t!equalsValue(normalizeDriverSchema(owned.metadata.schema), projected)\n\t\t) {\n\t\t\tthrow new DatabaseError('MIGRATION', 'Migration metadata schema does not match the plan', {\n\t\t\t\tprojected,\n\t\t\t\tmetadata: owned.metadata.schema,\n\t\t\t})\n\t\t}\n\t\tthis.#guard(() => {\n\t\t\tdatabase.transaction(() => {\n\t\t\t\tthis.#applyPlan(database, owned)\n\t\t\t\tif (owned.metadata !== undefined) {\n\t\t\t\t\tthis.#writeMetadata(database, owned.metadata)\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t\tthis.#schema = new Map(projected.map((table) => [table.name, table]))\n\t\tthis.#identities = identities\n\t}\n\n\t/**\n\t * Read the persisted {@link DriverMetadata} from the reserved `_metadata` table.\n\t *\n\t * @returns The last-stamped `DriverMetadata`, or `undefined` when never stamped\n\t * (or the stored row is malformed)\n\t */\n\tasync metadata(): Promise<DriverMetadata | undefined> {\n\t\tthis.#root()\n\t\treturn this.#metadata()\n\t}\n\n\t/**\n\t * Persist an owned metadata snapshot into the reserved `_metadata` table's\n\t * single row.\n\t *\n\t * @param metadata - The {@link DriverMetadata} to persist\n\t */\n\tasync stamp(metadata: DriverMetadata): Promise<void> {\n\t\tthis.#root()\n\t\tawait this.#stamp(metadata)\n\t}\n\n\tasync snapshot(tables?: readonly string[]): Promise<() => Promise<void>> {\n\t\tthis.#root()\n\t\t// Capture-replay rather than a SQL SAVEPOINT: the core `transaction` calls\n\t\t// the rollback thunk only on failure, with no commit-on-success signal — a\n\t\t// long-lived SAVEPOINT would leave the connection in an uncommitted\n\t\t// transaction (lost on close). Captured logical rows are adapted to each\n\t\t// surviving same-identity table before replay.\n\t\tconst captured = this.#guard(() => {\n\t\t\tconst database = this.#require()\n\t\t\tconst names = tables === undefined ? [...this.#schema.keys()] : [...new Set(tables)]\n\t\t\tconst snapshots = new Map<\n\t\t\t\tstring,\n\t\t\t\t{\n\t\t\t\t\treadonly identity: object\n\t\t\t\t\treadonly rows: readonly Row[]\n\t\t\t\t\treadonly schema: TableSchema\n\t\t\t\t}\n\t\t\t>()\n\t\t\tfor (const name of names) {\n\t\t\t\tconst schema = this.#schema.get(name)\n\t\t\t\tconst identity = this.#identities.get(name)\n\t\t\t\tif (schema === undefined || identity === undefined) continue\n\t\t\t\tsnapshots.set(name, {\n\t\t\t\t\tidentity,\n\t\t\t\t\trows: database\n\t\t\t\t\t\t.prepare('SELECT * FROM ' + quoteIdentifier(name))\n\t\t\t\t\t\t.all()\n\t\t\t\t\t\t.map((row) => decodeRow(row, schema)),\n\t\t\t\t\tschema,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn snapshots\n\t\t})\n\t\treturn async () => {\n\t\t\tthis.#root()\n\t\t\tconst replacements = new Map<\n\t\t\t\tstring,\n\t\t\t\t{ readonly names: readonly string[]; readonly values: readonly (readonly SQLiteValue[])[] }\n\t\t\t>()\n\t\t\tfor (const [name, capture] of captured) {\n\t\t\t\tconst schema = this.#schema.get(name)\n\t\t\t\tif (schema === undefined || this.#identities.get(name) !== capture.identity) continue\n\t\t\t\tconst plan = planMigration([capture.schema], [schema])\n\t\t\t\tconst rows = migrateRows(capture.rows, plan.steps)\n\t\t\t\tif (rows.length !== capture.rows.length) {\n\t\t\t\t\tthrow new DatabaseError('MIGRATION', 'Snapshot row count changed during migration', {\n\t\t\t\t\t\ttable: name,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconst names = schema.columns.map((column) => column.name)\n\t\t\t\tconst values: (readonly SQLiteValue[])[] = []\n\t\t\t\tfor (const [index, row] of rows.entries()) {\n\t\t\t\t\tconst key = extractKey(row, schema.primary)\n\t\t\t\t\tif (!isKey(key)) {\n\t\t\t\t\t\tthrow new DatabaseError('MIGRATION', 'Snapshot row has no usable primary key', {\n\t\t\t\t\t\t\ttable: name,\n\t\t\t\t\t\t\tcolumn: schema.primary,\n\t\t\t\t\t\t\tindex,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\tconst encoded = encodeRow(bindRowKey(row, schema.primary, key), schema)\n\t\t\t\t\tvalues.push(extractValues(encoded, names, name))\n\t\t\t\t}\n\t\t\t\treplacements.set(name, { names, values })\n\t\t\t}\n\t\t\tthis.#guard(() => {\n\t\t\t\tconst current = this.#require()\n\t\t\t\tcurrent.transaction(() => {\n\t\t\t\t\tfor (const [name, replacement] of replacements) {\n\t\t\t\t\t\tcurrent.exec('DELETE FROM ' + quoteIdentifier(name))\n\t\t\t\t\t\tconst statement = current.prepare(\n\t\t\t\t\t\t\t'INSERT OR REPLACE INTO ' +\n\t\t\t\t\t\t\t\tquoteIdentifier(name) +\n\t\t\t\t\t\t\t\t' (' +\n\t\t\t\t\t\t\t\treplacement.names.map(quoteIdentifier).join(', ') +\n\t\t\t\t\t\t\t\t') VALUES (' +\n\t\t\t\t\t\t\t\treplacement.names.map(() => '?').join(', ') +\n\t\t\t\t\t\t\t\t')',\n\t\t\t\t\t\t)\n\t\t\t\t\t\tfor (const values of replacement.values) statement.run(values)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\t\t}\n\t}\n\n\t// === Private\n\n\tasync #read(table: string, key: Key): Promise<Row | undefined> {\n\t\tconst schema = this.#table(table)\n\t\treturn this.#guard(() => {\n\t\t\tconst row = this.#require()\n\t\t\t\t.prepare(\n\t\t\t\t\t'SELECT * FROM ' +\n\t\t\t\t\t\tquoteIdentifier(table) +\n\t\t\t\t\t\t' WHERE ' +\n\t\t\t\t\t\tquoteIdentifier(schema.primary) +\n\t\t\t\t\t\t' = ?',\n\t\t\t\t)\n\t\t\t\t.get([this.#key(key, schema)])\n\t\t\treturn row === undefined ? undefined : decodeRow(row, schema)\n\t\t})\n\t}\n\n\tasync #write(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void> {\n\t\tconst schema = this.#table(table)\n\t\tthis.#guard(() => {\n\t\t\tconst encoded = encodeRow(bindRowKey(row, schema.primary, key), schema)\n\t\t\tconst names = schema.columns.map((column) => column.name)\n\t\t\tconst values = extractValues(encoded, names, table)\n\t\t\tconst statement = this.#require().prepare(\n\t\t\t\t'INSERT OR REPLACE INTO ' +\n\t\t\t\t\tquoteIdentifier(table) +\n\t\t\t\t\t' (' +\n\t\t\t\t\tnames.map(quoteIdentifier).join(', ') +\n\t\t\t\t\t') VALUES (' +\n\t\t\t\t\tnames.map(() => '?').join(', ') +\n\t\t\t\t\t')',\n\t\t\t)\n\t\t\tcheckAbort(options?.signal)\n\t\t\tstatement.run(values)\n\t\t})\n\t}\n\n\tasync #insert(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void> {\n\t\tconst schema = this.#table(table)\n\t\tthis.#guard(() => {\n\t\t\tconst encoded = encodeRow(bindRowKey(row, schema.primary, key), schema)\n\t\t\tconst names = schema.columns.map((column) => column.name)\n\t\t\tconst values = extractValues(encoded, names, table)\n\t\t\tconst statement = this.#require().prepare(\n\t\t\t\t'INSERT INTO ' +\n\t\t\t\t\tquoteIdentifier(table) +\n\t\t\t\t\t' (' +\n\t\t\t\t\tnames.map(quoteIdentifier).join(', ') +\n\t\t\t\t\t') VALUES (' +\n\t\t\t\t\tnames.map(() => '?').join(', ') +\n\t\t\t\t\t')',\n\t\t\t)\n\t\t\tcheckAbort(options?.signal)\n\t\t\tstatement.run(values)\n\t\t})\n\t}\n\n\tasync #delete(table: string, key: Key, options?: OperationOptions): Promise<boolean> {\n\t\tconst schema = this.#table(table)\n\t\treturn this.#guard(() => {\n\t\t\tconst statement = this.#require().prepare(\n\t\t\t\t'DELETE FROM ' +\n\t\t\t\t\tquoteIdentifier(table) +\n\t\t\t\t\t' WHERE ' +\n\t\t\t\t\tquoteIdentifier(schema.primary) +\n\t\t\t\t\t' = ?',\n\t\t\t)\n\t\t\tcheckAbort(options?.signal)\n\t\t\tconst result = statement.run([this.#key(key, schema)])\n\t\t\treturn result.changes > 0\n\t\t})\n\t}\n\n\tasync #keys(table: string): Promise<readonly Key[]> {\n\t\tconst schema = this.#table(table)\n\t\treturn this.#guard(() => {\n\t\t\tconst primary = quoteIdentifier(schema.primary)\n\t\t\tconst rows = this.#require()\n\t\t\t\t.prepare('SELECT ' + primary + ' FROM ' + quoteIdentifier(table) + ' ORDER BY ' + primary)\n\t\t\t\t.all()\n\t\t\tconst keys: Key[] = []\n\t\t\tfor (const row of rows) {\n\t\t\t\tconst value = row[schema.primary]\n\t\t\t\tif (typeof value === 'string' || typeof value === 'number') keys.push(value)\n\t\t\t}\n\t\t\treturn keys\n\t\t})\n\t}\n\n\tasync *#scan(table: string): AsyncIterable<Row> {\n\t\tconst schema = this.#table(table)\n\t\tfor await (const row of this.#iterate(\n\t\t\tschema,\n\t\t\t'SELECT * FROM ' + quoteIdentifier(table) + ' ORDER BY ' + quoteIdentifier(schema.primary),\n\t\t)) {\n\t\t\tyield row\n\t\t}\n\t}\n\n\tasync *#stream(table: string, input: QueryInput): AsyncIterable<Row> {\n\t\tconst schema = this.#table(table)\n\t\tconst conditions = input.conditions ?? []\n\t\tif (conditions.every((condition) => matchesConditionExactly(condition, schema))) {\n\t\t\tconst compiled = compileQuerySQL(\n\t\t\t\t{\n\t\t\t\t\tconditions,\n\t\t\t\t\t...(input.limit !== undefined ? { limit: input.limit } : {}),\n\t\t\t\t\t...(input.offset !== undefined ? { offset: input.offset } : {}),\n\t\t\t\t},\n\t\t\t\tschema,\n\t\t\t)\n\t\t\tfor await (const row of this.#iterate(\n\t\t\t\tschema,\n\t\t\t\t'SELECT * FROM ' + quoteIdentifier(table) + (compiled.sql === '' ? '' : ' ' + compiled.sql),\n\t\t\t\tcompiled.parameters,\n\t\t\t)) {\n\t\t\t\tyield row\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tconst offset = input.offset ?? 0\n\t\tconst limit = input.limit\n\t\tlet skipped = 0\n\t\tlet yielded = 0\n\t\tfor await (const row of this.#scan(table)) {\n\t\t\tif (limit !== undefined && yielded >= limit) return\n\t\t\tif (conditions.length > 0 && !matchesQuery(row, conditions)) continue\n\t\t\tif (skipped < offset) {\n\t\t\t\tskipped += 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tyield row\n\t\t\tyielded += 1\n\t\t}\n\t}\n\n\tasync *#iterate(\n\t\tschema: TableSchema,\n\t\tsql: string,\n\t\tparameters: readonly SQLiteValue[] = [],\n\t): AsyncIterable<Row> {\n\t\tconst iterator = this.#guard(() =>\n\t\t\tthis.#require().prepare(sql).iterate(parameters)[Symbol.iterator](),\n\t\t)\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tconst step = this.#guard(() => iterator.next())\n\t\t\t\tif (step.done === true) return\n\t\t\t\tyield this.#guard(() => decodeRow(step.value, schema))\n\t\t\t}\n\t\t} finally {\n\t\t\tif (iterator.return !== undefined) {\n\t\t\t\tthis.#guard(() => iterator.return?.())\n\t\t\t}\n\t\t}\n\t}\n\n\tasync #clear(table: string): Promise<void> {\n\t\tthis.#table(table)\n\t\tthis.#guard(() => {\n\t\t\tthis.#require()\n\t\t\t\t.prepare('DELETE FROM ' + quoteIdentifier(table))\n\t\t\t\t.run()\n\t\t})\n\t}\n\n\tasync #metadata(): Promise<DriverMetadata | undefined> {\n\t\treturn this.#guard(() => this.#readMetadata(this.#require()))\n\t}\n\n\t#ensureMetadataTable(database: SQLiteDatabaseInterface): void {\n\t\tdatabase.exec(\n\t\t\t'CREATE TABLE IF NOT EXISTS ' +\n\t\t\t\tquoteIdentifier(METADATA_TABLE) +\n\t\t\t\t' (\"id\" INTEGER, \"version\" INTEGER, \"schema\" TEXT, PRIMARY KEY (\"id\"))',\n\t\t)\n\t}\n\n\t#validateTable(\n\t\tdatabase: SQLiteDatabaseInterface,\n\t\tschema: TableSchema,\n\t): readonly string[] | undefined {\n\t\tconst object = database\n\t\t\t.prepare('SELECT \"type\" AS \"category\" FROM \"sqlite_schema\" WHERE \"name\" = ?')\n\t\t\t.get([schema.name])\n\t\tif (object === undefined) return undefined\n\t\tif (object.category !== 'table') {\n\t\t\tthrow new DatabaseError('DRIVER', 'SQLite object is not a table', {\n\t\t\t\ttable: schema.name,\n\t\t\t\taspect: 'object',\n\t\t\t\tactual: object.category,\n\t\t\t})\n\t\t}\n\t\tconst trigger = database\n\t\t\t.prepare('SELECT \"name\" FROM \"sqlite_schema\" WHERE \"type\" = ? AND \"tbl_name\" = ? LIMIT 1')\n\t\t\t.get(['trigger', schema.name])\n\t\tif (trigger !== undefined) {\n\t\t\tthrow new DatabaseError('DRIVER', 'SQLite table has an undeclared trigger', {\n\t\t\t\ttable: schema.name,\n\t\t\t\taspect: 'trigger',\n\t\t\t\tactual: trigger.name,\n\t\t\t})\n\t\t}\n\n\t\tconst columns = database.prepare('SELECT * FROM pragma_table_xinfo(?)').all([schema.name])\n\t\tif (columns.length !== schema.columns.length) {\n\t\t\tthrow new DatabaseError('DRIVER', 'SQLite table has different columns', {\n\t\t\t\ttable: schema.name,\n\t\t\t\taspect: 'columns',\n\t\t\t\texpected: schema.columns.map((column) => column.name),\n\t\t\t\tactual: columns.map((column) => column.name),\n\t\t\t})\n\t\t}\n\t\tfor (const declared of schema.columns) {\n\t\t\tconst column = columns.find((candidate) => candidate.name === declared.name)\n\t\t\tif (column === undefined) {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'SQLite table is missing a declared column', {\n\t\t\t\t\ttable: schema.name,\n\t\t\t\t\taspect: 'column',\n\t\t\t\t\tcolumn: declared.name,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst expectedRequired = !declared.optional && !declared.nullable\n\t\t\tconst required = column.notnull === 1 || column.notnull === 1n\n\t\t\tconst expectedPrimary = declared.name === schema.primary ? 1 : 0\n\t\t\tconst primary = column.pk === expectedPrimary || column.pk === BigInt(expectedPrimary)\n\t\t\tconst hidden = column.hidden === 0 || column.hidden === 0n\n\t\t\tif (\n\t\t\t\t!matchesSQLiteAffinity(column.type, declared.storage) ||\n\t\t\t\trequired !== expectedRequired ||\n\t\t\t\t!primary ||\n\t\t\t\t!hidden\n\t\t\t) {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'SQLite column does not match its declaration', {\n\t\t\t\t\ttable: schema.name,\n\t\t\t\t\taspect: 'column',\n\t\t\t\t\tcolumn: declared.name,\n\t\t\t\t\texpected: declared,\n\t\t\t\t\tactual: column,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\n\t\tconst indexes = database.prepare('SELECT * FROM pragma_index_list(?)').all([schema.name])\n\t\tfor (const index of indexes) {\n\t\t\tconst unique = index.unique === 1 || index.unique === 1n\n\t\t\tif (unique && index.origin !== 'pk') {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'SQLite table has an undeclared unique constraint', {\n\t\t\t\t\ttable: schema.name,\n\t\t\t\t\taspect: 'index',\n\t\t\t\t\tactual: index.name,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tconst missing: string[] = []\n\t\tfor (const group of schema.indexes) {\n\t\t\tconst name = deriveSQLiteIndexName(schema.name, group)\n\t\t\tconst index = indexes.find((candidate) => candidate.name === name)\n\t\t\tif (index === undefined) {\n\t\t\t\tmissing.push(name)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst ordinary = index.unique === 0 || index.unique === 0n\n\t\t\tconst complete = index.partial === 0 || index.partial === 0n\n\t\t\tif (!ordinary || !complete || index.origin !== 'c') {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'SQLite index does not match its declaration', {\n\t\t\t\t\ttable: schema.name,\n\t\t\t\t\taspect: 'index',\n\t\t\t\t\tindex: name,\n\t\t\t\t\tactual: index,\n\t\t\t\t})\n\t\t\t}\n\t\t\tconst entries = database\n\t\t\t\t.prepare('SELECT * FROM pragma_index_xinfo(?)')\n\t\t\t\t.all([name])\n\t\t\t\t.filter((entry) => entry.key === 1 || entry.key === 1n)\n\t\t\tif (entries.length !== group.length) {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'SQLite index has different columns', {\n\t\t\t\t\ttable: schema.name,\n\t\t\t\t\taspect: 'index',\n\t\t\t\t\tindex: name,\n\t\t\t\t\texpected: group,\n\t\t\t\t\tactual: entries.map((entry) => entry.name),\n\t\t\t\t})\n\t\t\t}\n\t\t\tfor (const [position, column] of group.entries()) {\n\t\t\t\tconst entry = entries.find(\n\t\t\t\t\t(candidate) => candidate.seqno === position || candidate.seqno === BigInt(position),\n\t\t\t\t)\n\t\t\t\tconst stored =\n\t\t\t\t\tentry !== undefined &&\n\t\t\t\t\t((typeof entry.cid === 'number' && Number.isInteger(entry.cid) && entry.cid >= 0) ||\n\t\t\t\t\t\t(typeof entry.cid === 'bigint' && entry.cid >= 0n))\n\t\t\t\tif (\n\t\t\t\t\tentry === undefined ||\n\t\t\t\t\tentry.name !== column ||\n\t\t\t\t\t!stored ||\n\t\t\t\t\t(entry.desc !== 0 && entry.desc !== 0n) ||\n\t\t\t\t\tentry.coll !== 'BINARY'\n\t\t\t\t) {\n\t\t\t\t\tthrow new DatabaseError('DRIVER', 'SQLite index column does not match its declaration', {\n\t\t\t\t\t\ttable: schema.name,\n\t\t\t\t\t\taspect: 'index',\n\t\t\t\t\t\tindex: name,\n\t\t\t\t\t\tcolumn,\n\t\t\t\t\t\tactual: entry,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn missing\n\t}\n\n\t#readMetadata(database: SQLiteDatabaseInterface): DriverMetadata | undefined {\n\t\tconst row = database\n\t\t\t.prepare(\n\t\t\t\t'SELECT \"version\", \"schema\" FROM ' + quoteIdentifier(METADATA_TABLE) + ' WHERE \"id\" = 1',\n\t\t\t)\n\t\t\t.get()\n\t\tif (row === undefined) return undefined\n\t\tconst version = row.version\n\t\tconst text = row.schema\n\t\tif (typeof text !== 'string') {\n\t\t\tthrow new DatabaseError('DRIVER', 'Stored SQLite metadata schema is invalid', {\n\t\t\t\ttable: METADATA_TABLE,\n\t\t\t\taspect: 'metadata',\n\t\t\t})\n\t\t}\n\t\tif (typeof version !== 'number' && typeof version !== 'bigint') {\n\t\t\tthrow new DatabaseError('DRIVER', 'Stored SQLite metadata version is invalid', {\n\t\t\t\ttable: METADATA_TABLE,\n\t\t\t\taspect: 'metadata',\n\t\t\t})\n\t\t}\n\t\tlet parsed: unknown\n\t\ttry {\n\t\t\tparsed = JSON.parse(text)\n\t\t} catch (error) {\n\t\t\tthrow new DatabaseError('DRIVER', 'Stored SQLite metadata JSON is invalid', {\n\t\t\t\ttable: METADATA_TABLE,\n\t\t\t\taspect: 'metadata',\n\t\t\t\tcause: error,\n\t\t\t})\n\t\t}\n\t\tif (!Array.isArray(parsed)) {\n\t\t\tthrow new DatabaseError('DRIVER', 'Stored SQLite metadata schema is invalid', {\n\t\t\t\ttable: METADATA_TABLE,\n\t\t\t\taspect: 'metadata',\n\t\t\t})\n\t\t}\n\t\tconst candidate = { version: Number(version), schema: parsed }\n\t\ttry {\n\t\t\treturn cloneDriverMetadata(candidate)\n\t\t} catch (error) {\n\t\t\tif (isDatabaseError(error) && error.code === 'VALIDATION') {\n\t\t\t\tthrow new DatabaseError('DRIVER', 'Stored SQLite metadata is invalid', {\n\t\t\t\t\ttable: METADATA_TABLE,\n\t\t\t\t\taspect: 'metadata',\n\t\t\t\t\tcause: error,\n\t\t\t\t})\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync #stamp(metadata: DriverMetadata): Promise<void> {\n\t\tconst database = this.#require()\n\t\tconst owned = cloneDriverMetadata(metadata)\n\t\tthis.#guard(() => this.#writeMetadata(database, owned))\n\t}\n\n\t#writeMetadata(database: SQLiteDatabaseInterface, metadata: DriverMetadata): void {\n\t\tdatabase\n\t\t\t.prepare(\n\t\t\t\t'INSERT OR REPLACE INTO ' +\n\t\t\t\t\tquoteIdentifier(METADATA_TABLE) +\n\t\t\t\t\t' (\"id\", \"version\", \"schema\") VALUES (1, ?, ?)',\n\t\t\t)\n\t\t\t.run([metadata.version, JSON.stringify(metadata.schema)])\n\t}\n\n\t#capability(token: object): StorageInterface {\n\t\treturn {\n\t\t\tread: this.#readTransaction.bind(this, token),\n\t\t\twrite: this.#writeTransaction.bind(this, token),\n\t\t\tinsert: this.#insertTransaction.bind(this, token),\n\t\t\tdelete: this.#deleteTransaction.bind(this, token),\n\t\t\tkeys: this.#keysTransaction.bind(this, token),\n\t\t\tscan: this.#scanTransaction.bind(this, token),\n\t\t\tclear: this.#clearTransaction.bind(this, token),\n\t\t\tmigrate: this.#migrateTransaction.bind(this, token),\n\t\t\tmetadata: this.#metadataTransaction.bind(this, token),\n\t\t\tstamp: this.#stampTransaction.bind(this, token),\n\t\t}\n\t}\n\n\tasync #readTransaction(token: object, table: string, key: Key): Promise<Row | undefined> {\n\t\tthis.#requireTransaction(token)\n\t\treturn this.#read(table, key)\n\t}\n\n\tasync #writeTransaction(\n\t\ttoken: object,\n\t\ttable: string,\n\t\tkey: Key,\n\t\trow: Row,\n\t\toptions?: OperationOptions,\n\t): Promise<void> {\n\t\tthis.#requireTransaction(token)\n\t\tawait this.#write(table, key, row, options)\n\t}\n\n\tasync #insertTransaction(\n\t\ttoken: object,\n\t\ttable: string,\n\t\tkey: Key,\n\t\trow: Row,\n\t\toptions?: OperationOptions,\n\t): Promise<void> {\n\t\tthis.#requireTransaction(token)\n\t\tawait this.#insert(table, key, row, options)\n\t}\n\n\tasync #deleteTransaction(\n\t\ttoken: object,\n\t\ttable: string,\n\t\tkey: Key,\n\t\toptions?: OperationOptions,\n\t): Promise<boolean> {\n\t\tthis.#requireTransaction(token)\n\t\treturn this.#delete(table, key, options)\n\t}\n\n\tasync #keysTransaction(token: object, table: string): Promise<readonly Key[]> {\n\t\tthis.#requireTransaction(token)\n\t\treturn this.#keys(table)\n\t}\n\n\t#scanTransaction(token: object, table: string): AsyncIterable<Row> {\n\t\treturn new DriverIterator(this.#scan(table)[Symbol.asyncIterator](), () => {\n\t\t\tthis.#requireTransaction(token)\n\t\t})\n\t}\n\n\tasync #clearTransaction(token: object, table: string): Promise<void> {\n\t\tthis.#requireTransaction(token)\n\t\tawait this.#clear(table)\n\t}\n\n\tasync #migrateTransaction(token: object, input: MigrationInput): Promise<void> {\n\t\tthis.#requireTransaction(token)\n\t\tconst database = this.#require()\n\t\tconst owned = cloneMigrationInput(input)\n\t\tconst candidate = this.#candidateSchema\n\t\tconst identities = this.#candidateIdentities\n\t\tif (candidate === undefined || identities === undefined) {\n\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction scope has settled')\n\t\t}\n\t\tconst projected = projectMigrationSchema([...candidate.values()], owned.plan.steps)\n\t\tconst projectedIdentities = this.#projectIdentities(identities, owned.plan.steps)\n\t\tif (\n\t\t\towned.metadata !== undefined &&\n\t\t\t!equalsValue(normalizeDriverSchema(owned.metadata.schema), projected)\n\t\t) {\n\t\t\tthrow new DatabaseError('MIGRATION', 'Migration metadata schema does not match the plan', {\n\t\t\t\tprojected,\n\t\t\t\tmetadata: owned.metadata.schema,\n\t\t\t})\n\t\t}\n\t\tthis.#guard(() => {\n\t\t\tdatabase.exec('SAVEPOINT \"_orkestrel_migration\"')\n\t\t\ttry {\n\t\t\t\tthis.#applyPlan(database, owned)\n\t\t\t\tif (owned.metadata !== undefined) {\n\t\t\t\t\tthis.#writeMetadata(database, owned.metadata)\n\t\t\t\t}\n\t\t\t\tdatabase.exec('RELEASE SAVEPOINT \"_orkestrel_migration\"')\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tdatabase.exec('ROLLBACK TO SAVEPOINT \"_orkestrel_migration\"')\n\t\t\t\t} finally {\n\t\t\t\t\tdatabase.exec('RELEASE SAVEPOINT \"_orkestrel_migration\"')\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t})\n\t\tthis.#candidateSchema = new Map(projected.map((table) => [table.name, table]))\n\t\tthis.#candidateIdentities = projectedIdentities\n\t}\n\n\tasync #metadataTransaction(token: object): Promise<DriverMetadata | undefined> {\n\t\tthis.#requireTransaction(token)\n\t\treturn this.#metadata()\n\t}\n\n\tasync #stampTransaction(token: object, metadata: DriverMetadata): Promise<void> {\n\t\tthis.#requireTransaction(token)\n\t\tawait this.#stamp(metadata)\n\t}\n\n\t#requireTransaction(token: object): void {\n\t\tif (this.#transaction !== token) {\n\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction scope has settled')\n\t\t}\n\t}\n\n\t#root(): void {\n\t\tif (this.#transaction !== undefined) {\n\t\t\tthrow new DatabaseError('CONFLICT', 'A transaction is active on this driver')\n\t\t}\n\t}\n\n\t// Run a synchronous backend interaction, mapping any `SQLiteError` (or\n\t// unexpected non-`SQLiteError` throw) to a typed `DatabaseError` so a\n\t// backend fault never leaks through `DriverInterface` unwrapped: a\n\t// `CONSTRAINT` violation becomes `CONFLICT`; the wrapper's own `CLOSED`\n\t// passes through as `CLOSED`; a `BUSY` (a locked database that outlasted\n\t// the configured `timeout`) becomes a `DRIVER` error whose context marks it\n\t// `retryable`; `UNKNOWN` and any non-`SQLiteError` throw become `DRIVER`.\n\t// A `DatabaseError` already thrown by this driver itself (the `#require`\n\t// `CLOSED` gate, `#table`'s `NOT_FOUND`, a `MIGRATION` step fault) passes\n\t// through unchanged — it is never re-wrapped. The original error is kept\n\t// as `context.cause` for diagnostics.\n\t#guard<T>(operation: () => T): T {\n\t\ttry {\n\t\t\treturn operation()\n\t\t} catch (error) {\n\t\t\tif (error instanceof DatabaseError) throw error\n\t\t\tif (isSQLiteError(error)) {\n\t\t\t\tif (error.code === 'CONSTRAINT') {\n\t\t\t\t\tthrow new DatabaseError('CONFLICT', error.message, { cause: error, code: error.code })\n\t\t\t\t}\n\t\t\t\tif (error.code === 'CLOSED') {\n\t\t\t\t\tthrow new DatabaseError('CLOSED', error.message, { cause: error, code: error.code })\n\t\t\t\t}\n\t\t\t\tif (error.code === 'BUSY') {\n\t\t\t\t\tthrow new DatabaseError('DRIVER', error.message, {\n\t\t\t\t\t\tcause: error,\n\t\t\t\t\t\tcode: error.code,\n\t\t\t\t\t\tretryable: true,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tthrow new DatabaseError('DRIVER', error.message, { cause: error, code: error.code })\n\t\t\t}\n\t\t\tthrow new DatabaseError('DRIVER', error instanceof Error ? error.message : String(error), {\n\t\t\t\tcause: error,\n\t\t\t})\n\t\t}\n\t}\n\n\t#require(): SQLiteDatabaseInterface {\n\t\tif (this.#database === undefined) {\n\t\t\tthrow new DatabaseError('CLOSED', `SQLite database '${this.#path}' is not open`, {\n\t\t\t\tpath: this.#path,\n\t\t\t})\n\t\t}\n\t\treturn this.#database\n\t}\n\n\t#projectIdentities(\n\t\tidentities: ReadonlyMap<string, object>,\n\t\tsteps: MigrationInput['plan']['steps'],\n\t): Map<string, object> {\n\t\tconst projected = new Map(identities)\n\t\tfor (const step of steps) {\n\t\t\tif (step.operation === 'table.add') projected.set(step.table.name, {})\n\t\t\tif (step.operation === 'table.remove') projected.delete(step.table)\n\t\t}\n\t\treturn projected\n\t}\n\n\t// Require the database open and resolve a declared table's schema.\n\t#table(name: string): TableSchema {\n\t\tthis.#require()\n\t\tconst schema = (this.#candidateSchema ?? this.#schema).get(name)\n\t\tif (schema === undefined) {\n\t\t\tthrow new DatabaseError('NOT_FOUND', `Table '${name}' is not in the schema`, { table: name })\n\t\t}\n\t\treturn schema\n\t}\n\n\t// Encode a primary key for binding against its column's stored type.\n\t#key(key: Key, schema: TableSchema): SQLiteValue {\n\t\tconst primary = schema.columns.find((column) => column.name === schema.primary)\n\t\treturn encodeValue(\n\t\t\tkey,\n\t\t\tprimary ?? {\n\t\t\t\tname: schema.primary,\n\t\t\t\tstorage: 'text',\n\t\t\t\toptional: false,\n\t\t\t\tnullable: false,\n\t\t\t},\n\t\t)\n\t}\n\n\t// Walk a migration plan's steps, executing each one's projected DDL and updating\n\t// the working `schema` copy in place — shared by both `migrate`'s joined-transaction\n\t// (native callback active) and self-wrapped (own `database.transaction`) paths.\n\t#applyPlan(database: SQLiteDatabaseInterface, input: MigrationInput): void {\n\t\tfor (const step of input.plan.steps) {\n\t\t\tfor (const sql of stepToSQL(step)) database.exec(sql)\n\t\t}\n\t}\n}\n","import type { DriverInterface } from '@src/core'\nimport type { SQLiteDriverOptions } from './types.js'\nimport { JSONDriver } from './drivers/JSONDriver.js'\nimport { SQLiteDriver } from './drivers/SQLiteDriver.js'\n\n/**\n * Create a persistent JSON-file {@link DriverInterface} for the core database layer.\n *\n * @remarks\n * Pass it to `createDatabase` from `@orkestrel/database` to run the typed\n * database against a single JSON file instead of memory — the `Database` /\n * `Table` / `Query` API is unchanged; only where the bytes live changes.\n * The driver is the reference `MemoryDriver` plus JSON-file persistence: `open` loads\n * the file, every mutation flushes the whole store back, and querying runs through\n * the core engine over `scan` (it is scan-only — no native `records` / `count` /\n * `aggregate`). A missing, corrupt, or wrong-shaped file starts empty rather than\n * throwing.\n *\n * @param path - The JSON file path data is loaded from and flushed to\n * @returns A {@link DriverInterface} backed by a JSON file\n *\n * @example\n * ```ts\n * import { createDatabase } from '@orkestrel/database'\n * import { stringShape } from '@orkestrel/contract'\n * import { createJSONDriver } from '@orkestrel/database/server'\n *\n * const db = createDatabase({\n * \tdriver: createJSONDriver('data/app.json'),\n * \ttables: { users: { id: stringShape(), name: stringShape() } },\n * })\n * await db.table('users').set({ id: 'u1', name: 'Ada' }) // persisted to app.json\n * ```\n */\nexport function createJSONDriver(path: string): DriverInterface {\n\treturn new JSONDriver(path)\n}\n\n/**\n * Create a trusted-mode SQLite {@link DriverInterface} for the core database layer.\n *\n * @remarks\n * Pass it to `createDatabase` from `@orkestrel/database` to run the typed\n * database against a real SQLite database — the `Database` / `Table` /\n * `Query` API is unchanged; only where the bytes live changes. Built\n * on the published `@orkestrel/sqlite` synchronous wrapper: `open` issues real\n * typed `CREATE TABLE` / `CREATE INDEX` statements (reopen-safe) plus a reserved\n * `_metadata` table for `metadata()` / `stamp()` — avoid naming a table `_metadata`.\n * Querying, paging, and aggregation run natively (`records` / `count` /\n * `aggregate` / `stream`); `transaction` and `migrate` use real `BEGIN` /\n * `COMMIT` / `ROLLBACK`, so `migrate` is atomic even mid-plan.\n *\n * @param options - The {@link SQLiteDriverOptions} bag (`path`, `readonly`,\n * `timeout`, `references`, `pragmas`); `references` directly enables or\n * disables foreign-key enforcement, and omission retains the upstream\n * default; omit the whole bag for an in-memory database\n * @returns A {@link DriverInterface} backed by SQLite\n *\n * @example\n * ```ts\n * import { createDatabase } from '@orkestrel/database'\n * import { stringShape } from '@orkestrel/contract'\n * import { createSQLiteDriver } from '@orkestrel/database/server'\n *\n * const db = createDatabase({\n * \tdriver: createSQLiteDriver({ path: 'data/app.sqlite' }),\n * \ttables: { users: { id: stringShape(), name: stringShape() } },\n * })\n * await db.table('users').set({ id: 'u1', name: 'Ada' }) // persisted to app.sqlite\n *\n * // Or with additional options:\n * createSQLiteDriver({ path: 'data/app.sqlite', pragmas: { journal_mode: 'WAL' } })\n * ```\n */\nexport function createSQLiteDriver(options?: SQLiteDriverOptions): DriverInterface {\n\treturn new SQLiteDriver(options)\n}\n"],"mappings":"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"}