@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.
- package/README.md +13 -35
- package/dist/src/browser/index.d.ts +100 -87
- package/dist/src/browser/index.js +369 -219
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/core/index.cjs +2389 -1244
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +545 -706
- package/dist/src/core/index.d.ts +545 -706
- package/dist/src/core/index.js +2368 -1231
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +1620 -827
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +466 -571
- package/dist/src/server/index.d.ts +466 -571
- package/dist/src/server/index.js +1603 -811
- package/dist/src/server/index.js.map +1 -1
- package/package.json +21 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#table","#keys","#value","#index","#closed","#record","#column","#connector","#apply","#table","#conditions","#orders","#filters","#clause","#limit","#offset","#page","#filtered","#ready","#driver","#name","#key","#contract","#guard","#generate","#emitter","#each","#read","#resolveOne","#collect","#cast","#put","#updateOne","#delete","#validate","#prepare","#resolveKey","#driver","#tables","#keys","#indexes","#name","#generate","#version","#emitter","#status","#build","#key","#spawn","#connect","#ready","#schema","#apply","#reconcile","#stamp","#tables","#store","#ordered","#meta","#require"],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/helpers.ts","../../../src/core/Cursor.ts","../../../src/core/Clause.ts","../../../src/core/Query.ts","../../../src/core/Table.ts","../../../src/core/Database.ts","../../../src/core/drivers/MemoryDriver.ts","../../../src/core/factories.ts"],"sourcesContent":["// Database constants — frozen plain data (AGENTS §5).\n\n/**\n * The primary-key column assumed when {@link TableKeys} does not name one.\n *\n * @remarks\n * `id` is the convention IndexedDB (`keyPath: 'id'`) and SQL (`id` / rowid) both\n * lean on, so a table that omits `key` keys its rows by `id`.\n */\nexport const DEFAULT_PRIMARY = 'id'\n\n/**\n * The longest `LIKE` / `GLOB` pattern the wildcard matcher accepts before rejecting it.\n *\n * @remarks\n * A ReDoS bound (AGENTS §6.5): the SA1–SA4 migration lets a model supply `list`\n * criteria over the wire, so `likeMatch` / `globMatch` run attacker-controlled\n * patterns. The matcher is the LINEAR greedy two-pointer wildcard match — never a\n * backtracking regex (`.*`-segments-separated-by-literals against a long input is the\n * catastrophic shape JS cannot bound without atomic groups), so it is O(value ×\n * pattern). Capping the pattern length bounds that pattern factor, leaving a match\n * linear in the value length whatever the pattern. A longer pattern throws a\n * `VALIDATION` {@link DatabaseError}; the cap is generous for any legitimate search.\n */\nexport const MAX_PATTERN_LENGTH = 1024\n\n/** The number of bytes encoded by an RFC 4122 UUID. */\nexport const UUID_BYTE_COUNT = 16\n\n/** The number of distinct values one UUID byte may hold. */\nexport const UUID_BYTE_RANGE = 256\n","import type { DatabaseErrorCode } from './types.js'\n\n// AGENTS §12: invalid operations and programmer errors `throw`, always a\n// `DatabaseError` carrying a machine-readable `code` so a `catch` branches on\n// `error.code` instead of parsing the message. Lookups that may simply miss\n// (`get`, `has`, `remove`) return `undefined` / `false` — they never throw.\n\n/**\n * An error thrown by the database layer.\n *\n * @remarks\n * Carries a {@link DatabaseErrorCode} and an optional `context` bag naming the\n * offending table / key. Thrown for: operating on a closed database (`CLOSED`), a\n * `resolve` miss (`NOT_FOUND`), an `add` onto an existing key (`CONFLICT`), a\n * row that fails its table's contract (`VALIDATION`), a cancelled operation whose\n * {@link ReadOptions.signal} aborted (`ABORTED`, carrying `signal.reason` in\n * `context`), an inapplicable {@link Migration} plan (`MIGRATION`), a\n * driver that violates a {@link DriverInterface} invariant, thrown by the\n * `conformDriver` helper (`CONFORMANCE`), and an unexpected infrastructure\n * fault surfaced by a driver seam — e.g. a filesystem failure while\n * persisting (`DRIVER`) — as opposed to expected domain conditions, which\n * keep their specific codes.\n */\nexport class DatabaseError extends Error {\n\treadonly code: DatabaseErrorCode\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\tconstructor(\n\t\tcode: DatabaseErrorCode,\n\t\tmessage: string,\n\t\tcontext?: Readonly<Record<string, unknown>>,\n\t) {\n\t\tsuper(message)\n\t\tthis.name = 'DatabaseError'\n\t\tthis.code = code\n\t\tthis.context = context\n\t}\n}\n\n/**\n * Narrow an unknown caught value to a {@link DatabaseError}.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns `true` when `value` is a {@link DatabaseError}\n *\n * @example\n * ```ts\n * try {\n * \tawait users.add(row)\n * } catch (error) {\n * \tif (isDatabaseError(error) && error.code === 'CONFLICT') await users.set(row)\n * }\n * ```\n */\nexport function isDatabaseError(value: unknown): value is DatabaseError {\n\treturn value instanceof DatabaseError\n}\n","import type { ContractShape, FieldPath, RandomFunction } from '@orkestrel/contract'\nimport type {\n\tAggregateFunction,\n\tColumnType,\n\tConformanceFinding,\n\tCondition,\n\tCriteria,\n\tDriverInterface,\n\tDriverMeta,\n\tKey,\n\tMigration,\n\tMigrationStep,\n\tOrder,\n\tRow,\n\tTableSchema,\n} from './types.js'\nimport {\n\tisArray,\n\tisBoolean,\n\tisFiniteNumber,\n\tisRecord,\n\tisString,\n\tparseNumber,\n\tresolveField,\n} from '@orkestrel/contract'\nimport { MAX_PATTERN_LENGTH, UUID_BYTE_COUNT, UUID_BYTE_RANGE } from './constants.js'\nimport { DatabaseError, isDatabaseError } from './errors.js'\n\n// The query engine. Every backend's `scan` yields rows; these pure helpers do\n// the filtering, ordering, paging, and aggregation once, so a driver never\n// re-implements WHERE compilation. They are total — like the contracts guards\n// they lean on, hostile input yields a `false` / a skipped value, never a throw.\n\n// === Comparison\n\n/**\n * A total ordering over arbitrary values — the comparator behind sorting and the\n * range operators.\n *\n * @remarks\n * Values of different types order by a fixed type rank (`undefined` < `null` <\n * boolean < number < string < other); same-typed values compare naturally.\n * `NaN` sorts after every other number and equal to itself, so the comparator\n * is total and never returns `NaN`.\n *\n * @param left - The left value\n * @param right - The right value\n * @returns `-1`, `0`, or `1`\n */\nexport function compareValues(left: unknown, right: unknown): number {\n\t// Rank unlike types so a mixed column still sorts deterministically:\n\t// undefined < null < boolean < number < string < other.\n\tconst rankOf = (value: unknown): number => {\n\t\tif (value === undefined) return 0\n\t\tif (value === null) return 1\n\t\tif (typeof value === 'boolean') return 2\n\t\tif (typeof value === 'number') return 3\n\t\tif (typeof value === 'string') return 4\n\t\treturn 5\n\t}\n\tconst leftRank = rankOf(left)\n\tconst rightRank = rankOf(right)\n\tif (leftRank !== rightRank) return leftRank < rightRank ? -1 : 1\n\tif (typeof left === 'number' && typeof right === 'number') {\n\t\tif (Number.isNaN(left) || Number.isNaN(right)) {\n\t\t\treturn Number.isNaN(left) ? (Number.isNaN(right) ? 0 : 1) : -1\n\t\t}\n\t\treturn left < right ? -1 : left > right ? 1 : 0\n\t}\n\tif (typeof left === 'string' && typeof right === 'string') {\n\t\treturn left < right ? -1 : left > right ? 1 : 0\n\t}\n\tif (typeof left === 'boolean' && typeof right === 'boolean') {\n\t\treturn left === right ? 0 : left ? 1 : -1\n\t}\n\treturn 0\n}\n\n/**\n * Structural equality by SameValueZero leaves — the comparator behind conformance\n * checks and any test/fixture that needs \"same data\", not \"same reference\".\n *\n * @remarks\n * Primitives compare by SameValueZero (`NaN` equals itself; `+0` equals `-0`).\n * Arrays compare by index (same length, every element `deepEqual`). Plain\n * records (via `isRecord`) compare by their OWN enumerable keys: same key\n * COUNT and, for every key in `left`, `right` has that key (`Object.hasOwn`)\n * with a `deepEqual` value — so a key present with value `undefined` is NOT\n * equal to that key being absent (both differ in `Object.keys` membership).\n * Anything else (functions, class instances, mismatched shapes) falls through\n * to `false`. There is no cycle detection — a cyclic input recurses forever;\n * callers pass acyclic data (rows, plans, config).\n *\n * @param left - The left value\n * @param right - The right value\n * @returns Whether `left` and `right` are structurally equal\n *\n * @example\n * ```ts\n * deepEqual(Number.NaN, Number.NaN) // true\n * deepEqual({ a: [1, { b: 2 }] }, { a: [1, { b: 2 }] }) // true\n * deepEqual({ a: undefined }, {}) // false — present-undefined ≠ absent\n * ```\n */\nexport function deepEqual(left: unknown, right: unknown): boolean {\n\tif (typeof left === 'number' && typeof right === 'number') {\n\t\treturn (Number.isNaN(left) && Number.isNaN(right)) || left === right\n\t}\n\tif (left === right) return true\n\tif (Array.isArray(left) && Array.isArray(right)) {\n\t\treturn (\n\t\t\tleft.length === right.length && left.every((item, index) => deepEqual(item, right[index]))\n\t\t)\n\t}\n\tif (isRecord(left) && isRecord(right)) {\n\t\tconst leftKeys = Object.keys(left)\n\t\tconst rightKeys = Object.keys(right)\n\t\tif (leftKeys.length !== rightKeys.length) return false\n\t\treturn leftKeys.every((key) => Object.hasOwn(right, key) && deepEqual(left[key], right[key]))\n\t}\n\treturn false\n}\n\n// === Pattern matching\n\n/**\n * Match a value against a wildcard pattern in LINEAR time — the shared, ReDoS-SAFE\n * engine behind {@link likeMatch} and {@link globMatch}.\n *\n * @remarks\n * A backtracking RegExp (`a%b%c` → `^a.*b.*c$`) is CATASTROPHIC on a hostile pattern:\n * `.*` segments separated by literals, matched against a long non-matching input, blow\n * up super-linearly — and JS has no atomic groups / possessive quantifiers to bound it\n * (AGENTS §6.5, now that the authed server runs model-supplied `list` criteria over the\n * wire). So this builds NO regex. It runs the classic GREEDY TWO-POINTER wildcard match:\n * the `any` wildcard records its position and, on a later mismatch, backtracks ONLY to\n * that last `any` (letting it absorb one more char) — so the work is O(value × pattern),\n * never the exponential / polynomial backtracking a regex would do. The pattern length\n * is capped at {@link MAX_PATTERN_LENGTH} (a `VALIDATION` {@link DatabaseError} over it),\n * bounding the pattern factor so a match stays linear in the value length whatever the\n * pattern.\n *\n * The `any` wildcard matches any run (including empty); `single` matches exactly one\n * char; every other pattern char matches itself LITERALLY (a pattern `.` / `(` / `\\` is\n * a literal — the regex-metacharacter hazard is gone with the regex). `any` is tested\n * BEFORE a literal match, so a value that literally contains the wildcard char never\n * shadows the wildcard. Case folding is applied to BOTH sides when `fold` is set.\n *\n * @param value - The value to test\n * @param pattern - The wildcard pattern\n * @param any - The any-run wildcard char (`%` for `LIKE`, `*` for `GLOB`)\n * @param single - The single-char wildcard char (`_` for `LIKE`, `?` for `GLOB`)\n * @param fold - Whether to match case-INSENSITIVELY (`LIKE` folds; `GLOB` does not)\n * @returns Whether `value` matches `pattern`\n * @throws A `VALIDATION` {@link DatabaseError} when `pattern` exceeds {@link MAX_PATTERN_LENGTH}\n */\nexport function wildcardMatch(\n\tvalue: string,\n\tpattern: string,\n\tany: string,\n\tsingle: string,\n\tfold: boolean,\n): boolean {\n\tif (pattern.length > MAX_PATTERN_LENGTH) {\n\t\tthrow new DatabaseError(\n\t\t\t'VALIDATION',\n\t\t\t`Pattern exceeds the maximum length of ${MAX_PATTERN_LENGTH}`,\n\t\t\t{ length: pattern.length, limit: MAX_PATTERN_LENGTH },\n\t\t)\n\t}\n\tconst haystack = fold ? value.toLowerCase() : value\n\tconst needle = fold ? pattern.toLowerCase() : pattern\n\tlet vi = 0\n\tlet pi = 0\n\t// The greedy backtrack point: the pattern index of the LAST `any` wildcard + the value\n\t// index it was taken at. On a mismatch we resume just past it and let it absorb one more\n\t// char (`mark += 1`) — O(value × pattern), never a regex's exponential backtracking.\n\tlet star = -1\n\tlet mark = 0\n\twhile (vi < haystack.length) {\n\t\tconst pc = pi < needle.length ? needle[pi] : undefined\n\t\tif (pc === any) {\n\t\t\t// Record the wildcard (it absorbs zero chars for now) and advance the pattern.\n\t\t\tstar = pi\n\t\t\tmark = vi\n\t\t\tpi += 1\n\t\t} else if (pc !== undefined && (pc === single || pc === haystack[vi])) {\n\t\t\tvi += 1\n\t\t\tpi += 1\n\t\t} else if (star !== -1) {\n\t\t\t// Mismatch under an open `any`: let it swallow one more value char and retry.\n\t\t\tpi = star + 1\n\t\t\tmark += 1\n\t\t\tvi = mark\n\t\t} else {\n\t\t\treturn false\n\t\t}\n\t}\n\t// The value is consumed — the leftover pattern matches iff it is all `any` wildcards.\n\twhile (pi < needle.length && needle[pi] === any) pi += 1\n\treturn pi === needle.length\n}\n\n// SQL `LIKE` → case-INSENSITIVE wildcard match (`%` any run, `_` any char).\nexport function likeMatch(value: string, pattern: string): boolean {\n\treturn wildcardMatch(value, pattern, '%', '_', true)\n}\n\n// `GLOB` → case-SENSITIVE wildcard match (`*` any run, `?` any char).\nexport function globMatch(value: string, pattern: string): boolean {\n\treturn wildcardMatch(value, pattern, '*', '?', false)\n}\n\n// === Condition matching\n\n/**\n * Evaluate one {@link Condition} against a row — the per-operator predicate.\n *\n * @remarks\n * Reads the condition's column — a `FieldPath`, resolved with `resolveField` (a\n * string is one column; an array descends a nested value) — and applies the\n * operator. Range operators (`above` / `below` / `from` / `to` / `between`) use\n * {@link compareValues}, the total order; the equality family (`equals` / `not`\n * / `any` / `none`) uses {@link deepEqual} — STRUCTURAL equality, not the total\n * order's rank-5-collapses-all-objects behavior, so `equals` on an object/array\n * operand only matches a structurally-equal value, never every row holding any\n * object. This is a semantics change from ranking: `deepEqual` is SameValueZero\n * on leaves, so `NaN` now equals `NaN` under `equals` / `any` (it never matched\n * anything under the old rank-based comparison). `like` / `glob` / `starts` /\n * `ends` match only strings; `absent` / `present` test nullishness. Total — a\n * type mismatch is simply a non-match.\n *\n * @param row - The row to test\n * @param condition - The condition to apply\n * @returns Whether the row satisfies the condition\n */\nexport function matchesCondition(row: Row, condition: Condition): boolean {\n\tconst value = resolveField(row, condition.column)\n\tconst first = condition.values[0]\n\tconst second = condition.values[1]\n\tswitch (condition.operator) {\n\t\tcase 'equals':\n\t\t\treturn deepEqual(value, first)\n\t\tcase 'not':\n\t\t\treturn !deepEqual(value, first)\n\t\tcase 'above':\n\t\t\treturn compareValues(value, first) > 0\n\t\tcase 'below':\n\t\t\treturn compareValues(value, first) < 0\n\t\tcase 'from':\n\t\t\treturn compareValues(value, first) >= 0\n\t\tcase 'to':\n\t\t\treturn compareValues(value, first) <= 0\n\t\tcase 'between':\n\t\t\treturn compareValues(value, first) >= 0 && compareValues(value, second) <= 0\n\t\tcase 'like':\n\t\t\treturn isString(value) && isString(first) && likeMatch(value, first)\n\t\tcase 'glob':\n\t\t\treturn isString(value) && isString(first) && globMatch(value, first)\n\t\tcase 'starts':\n\t\t\treturn isString(value) && isString(first) && value.startsWith(first)\n\t\tcase 'ends':\n\t\t\treturn isString(value) && isString(first) && value.endsWith(first)\n\t\tcase 'any':\n\t\t\treturn condition.values.some((candidate) => deepEqual(value, candidate))\n\t\tcase 'none':\n\t\t\treturn !condition.values.some((candidate) => deepEqual(value, candidate))\n\t\tcase 'absent':\n\t\t\treturn value === undefined || value === null\n\t\tcase 'present':\n\t\t\treturn value !== undefined && value !== null\n\t}\n}\n\n/**\n * Fold a row through a list of conditions, joining each by its connector.\n *\n * @remarks\n * Evaluated left-to-right: the first condition seeds the result, and each later\n * condition combines with `&&` (`and`) or `||` (`or`). An empty list matches\n * every row. There is no operator precedence — conditions combine in the order\n * the query builder recorded them.\n *\n * @param row - The row to test\n * @param conditions - The conditions to fold\n * @returns Whether the row satisfies the combined conditions\n */\nexport function matchesCriteria(row: Row, conditions: readonly Condition[]): boolean {\n\tlet result = true\n\tlet seeded = false\n\tfor (const condition of conditions) {\n\t\tconst match = matchesCondition(row, condition)\n\t\tif (!seeded) {\n\t\t\tresult = match\n\t\t\tseeded = true\n\t\t} else {\n\t\t\tresult = condition.connector === 'or' ? result || match : result && match\n\t\t}\n\t}\n\treturn result\n}\n\n/**\n * Filter rows by a list of conditions — the shared basis for a table's count\n * and aggregate paths (no sort/page, unlike {@link applyCriteria}).\n *\n * @remarks\n * An empty condition list matches every row (returned as-is, no copy). Folds\n * each row through {@link matchesCriteria}.\n *\n * @param rows - The rows to filter\n * @param conditions - The conditions to apply (empty matches everything)\n * @returns The matching rows\n *\n * @example\n * ```ts\n * filterRows(\n * \t[{ age: 30 }, { age: 12 }],\n * \t[{ column: 'age', operator: 'above', values: [18], connector: 'and' }],\n * ) // => [{ age: 30 }]\n * ```\n */\nexport function filterRows(rows: readonly Row[], conditions: readonly Condition[]): readonly Row[] {\n\tif (conditions.length === 0) return rows\n\treturn rows.filter((row) => matchesCriteria(row, conditions))\n}\n\n// === Ordering & paging\n\n/**\n * Sort rows by an ordering specification, leaving the input untouched.\n *\n * @remarks\n * Applies the terms in priority order — the first term that distinguishes two\n * rows decides — using {@link compareValues}, reversing for `descending`.\n *\n * @param rows - The rows to sort\n * @param order - The ordering terms in priority order\n * @returns A new, sorted array\n */\nexport function sortRows(rows: readonly Row[], order: readonly Order[]): readonly Row[] {\n\tconst sorted = [...rows]\n\tsorted.sort((left, right) => {\n\t\tfor (const term of order) {\n\t\t\tconst comparison = compareValues(\n\t\t\t\tresolveField(left, term.column),\n\t\t\t\tresolveField(right, term.column),\n\t\t\t)\n\t\t\tif (comparison !== 0) return term.direction === 'descending' ? -comparison : comparison\n\t\t}\n\t\treturn 0\n\t})\n\treturn sorted\n}\n\n/**\n * Apply a {@link Criteria} to rows — filter, then sort, then page.\n *\n * @remarks\n * The whole portable read pipeline in one place: conditions filter, `order`\n * sorts, and `offset` / `limit` window the result. Each step is skipped when its\n * part of the criteria is absent. The reference {@link DriverInterface} backends\n * lean on this rather than each re-deriving it.\n *\n * @param rows - The rows to process (typically a table's full `scan`)\n * @param criteria - The read specification, or `undefined` for all rows as-is\n * @returns The filtered, sorted, paged rows\n */\nexport function applyCriteria(rows: readonly Row[], criteria?: Criteria): readonly Row[] {\n\tlet result = rows\n\tconst conditions = criteria?.conditions\n\tif (conditions !== undefined && conditions.length > 0) {\n\t\tresult = result.filter((row) => matchesCriteria(row, conditions))\n\t}\n\tconst order = criteria?.order\n\tif (order !== undefined && order.length > 0) {\n\t\tresult = sortRows(result, order)\n\t}\n\tconst offset = criteria?.offset ?? 0\n\tconst limit = criteria?.limit\n\tif (offset > 0 || limit !== undefined) {\n\t\tresult = result.slice(offset, limit !== undefined ? offset + limit : undefined)\n\t}\n\treturn result\n}\n\n// === Aggregation\n\n/**\n * Compute an aggregate over a column across rows.\n *\n * @remarks\n * `count` returns the row count. The numeric aggregates coerce each cell with\n * the contracts `parseNumber` (so `'42'` counts) and ignore non-numeric cells;\n * over zero numeric values they return `undefined` — the SQL `NULL` of an empty\n * aggregate.\n *\n * @param rows - The rows to aggregate (non-record entries are ignored)\n * @param operation - The aggregate to compute\n * @param column - The column to aggregate\n * @returns The aggregate value, or `undefined` when undefined for the inputs\n */\nexport function computeAggregate(\n\trows: readonly unknown[],\n\toperation: AggregateFunction,\n\tcolumn: FieldPath,\n): number | undefined {\n\tif (operation === 'count') return rows.length\n\tconst numbers: number[] = []\n\tfor (const row of rows) {\n\t\tif (!isRecord(row)) continue\n\t\tconst value = parseNumber(resolveField(row, column))\n\t\tif (value !== undefined) numbers.push(value)\n\t}\n\tif (numbers.length === 0) return undefined\n\tif (operation === 'sum' || operation === 'average') {\n\t\tconst total = numbers.reduce((sum, value) => sum + value, 0)\n\t\treturn operation === 'average' ? total / numbers.length : total\n\t}\n\treturn operation === 'minimum' ? Math.min(...numbers) : Math.max(...numbers)\n}\n\n// === Keys\n\n/**\n * Read a row's primary key from a column, when it is a usable {@link Key}.\n *\n * @param row - The row to read\n * @param column - The primary-key column name\n * @returns The key (a string or finite number), or `undefined`\n */\nexport function extractKey(row: Row, column: string): Key | undefined {\n\tconst value = row[column]\n\tif (isString(value)) return value\n\tif (isFiniteNumber(value)) return value\n\treturn undefined\n}\n\n// === Schema\n\n/**\n * Map a column's {@link ContractShape} to its portable {@link ColumnType} — the\n * value a `TableSchema` carries so a native backend can declare a real column.\n *\n * @remarks\n * `string` → `text`; `number` → `integer` when the shape is integer-only, else\n * `real`; `boolean` → `boolean`. A `literal` takes the type of its values\n * (all-boolean → `boolean`, all-integer → `integer`, mixed/fractional numbers →\n * `real`, anything else → `text`). `optional` / `nullable` unwrap to their inner\n * type (nullability is tracked separately). `null` / `object` / `array` / `union` /\n * `json` / `raw` → `json`: a backend stores them as JSON text and can `json_extract`\n * for nested `FieldPath` queries. A scan-only backend ignores the result.\n *\n * @param shape - The column's contract shape\n * @returns The portable column type\n *\n * @example\n * ```ts\n * shapeToColumnType(stringShape()) // 'text'\n * shapeToColumnType(integerShape()) // 'integer'\n * shapeToColumnType(optionalShape(integerShape())) // 'integer'\n * shapeToColumnType(objectShape({ a: stringShape() })) // 'json'\n * ```\n */\nexport function shapeToColumnType(shape: ContractShape): ColumnType {\n\tswitch (shape.type) {\n\t\tcase 'string':\n\t\t\treturn 'text'\n\t\tcase 'number':\n\t\t\treturn shape.integer === true ? 'integer' : 'real'\n\t\tcase 'boolean':\n\t\t\treturn 'boolean'\n\t\tcase 'literal': {\n\t\t\tif (shape.values.every((value) => typeof value === 'boolean')) return 'boolean'\n\t\t\tif (shape.values.every((value) => typeof value === 'number')) {\n\t\t\t\treturn shape.values.every((value) => Number.isInteger(value)) ? 'integer' : 'real'\n\t\t\t}\n\t\t\treturn 'text'\n\t\t}\n\t\tcase 'optional':\n\t\tcase 'nullable':\n\t\t\treturn shapeToColumnType(shape.inner)\n\t\tcase 'null':\n\t\tcase 'object':\n\t\tcase 'array':\n\t\tcase 'union':\n\t\tcase 'json':\n\t\tcase 'raw':\n\t\t\treturn 'json'\n\t}\n}\n\n/**\n * Whether a value is a well-formed {@link DriverMeta} — the boundary guard a\n * versioning driver's `meta()` narrows a stored (structured-clone or\n * `JSON.parse`d) value through before trusting it, replacing the per-driver\n * duplicated narrowing every backend used to hand-roll (AGENTS §14: never `as`).\n *\n * @remarks\n * Total and total-recursive over the whole shape: a finite `version`, and a\n * `schema` array of well-formed {@link TableSchema} entries — each a `name` /\n * `primary` string pair, a `columns` array of well-formed {@link ColumnSchema}\n * entries (a `name` string, a {@link ColumnType} literal, a `nullable`\n * boolean), and an `indexes` array of string arrays. Anything off-shape\n * (including a non-record) returns `false` rather than throwing.\n *\n * @param value - The value to test\n * @returns `true` when `value` is a well-formed `DriverMeta`\n *\n * @example\n * ```ts\n * isDriverMeta({ version: 1, schema: [] }) // true\n * isDriverMeta({ version: 1, schema: [{ name: 'users' }] }) // false\n * ```\n */\nexport function isDriverMeta(value: unknown): value is DriverMeta {\n\tconst COLUMN_TYPES: readonly ColumnType[] = ['text', 'integer', 'real', 'boolean', 'json', 'blob']\n\tconst isColumnType = (candidate: unknown): candidate is ColumnType =>\n\t\tisString(candidate) && COLUMN_TYPES.some((type) => type === candidate)\n\tconst isColumnSchema = (candidate: unknown): boolean =>\n\t\tisRecord(candidate) &&\n\t\tisString(candidate.name) &&\n\t\tisColumnType(candidate.type) &&\n\t\tisBoolean(candidate.nullable)\n\tconst isIndexGroup = (candidate: unknown): boolean =>\n\t\tisArray(candidate) && candidate.every((entry) => isString(entry))\n\tconst isTableSchema = (candidate: unknown): candidate is TableSchema =>\n\t\tisRecord(candidate) &&\n\t\tisString(candidate.name) &&\n\t\tisString(candidate.primary) &&\n\t\tisArray(candidate.columns) &&\n\t\tcandidate.columns.every(isColumnSchema) &&\n\t\tisArray(candidate.indexes) &&\n\t\tcandidate.indexes.every(isIndexGroup)\n\treturn (\n\t\tisRecord(value) &&\n\t\tisFiniteNumber(value.version) &&\n\t\tisArray(value.schema) &&\n\t\tvalue.schema.every(isTableSchema)\n\t)\n}\n\n// === Cancellation\n\n/**\n * Throw when an {@link ReadOptions.signal | AbortSignal} has fired — the shared\n * cancellation gate checked at operation boundaries and between streamed rows.\n *\n * @remarks\n * A no-op for `undefined` or a live signal, so callers thread `options?.signal`\n * straight through. When the signal has aborted, throws an `ABORTED`\n * {@link DatabaseError} carrying the signal's `reason` in its context — callers\n * mint signals with whatever tool they like (`AbortSignal.timeout(ms)`,\n * `new AbortController()`, `@orkestrel/abort`).\n *\n * @param signal - The signal to check, if any\n * @returns Nothing — returns normally while the signal is live\n * @throws An `ABORTED` {@link DatabaseError} when the signal has aborted\n *\n * @example\n * ```ts\n * import { checkAbort } from '@orkestrel/database'\n *\n * const controller = new AbortController()\n * checkAbort(controller.signal) // returns\n * controller.abort('too slow')\n * checkAbort(controller.signal) // throws DatabaseError('ABORTED', …)\n * ```\n */\nexport function checkAbort(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) {\n\t\tthrow new DatabaseError('ABORTED', 'Operation aborted', { reason: signal.reason })\n\t}\n}\n\n// === Migrations\n\n/**\n * Structurally diff a deployed and a declared table set into a {@link Migration}\n * plan.\n *\n * @remarks\n * Tables present in `declared` but not `deployed` become `table.add` steps\n * (carrying the full declared {@link TableSchema}); tables present in\n * `deployed` but not `declared` become `table.remove` steps. Tables present in\n * both are diffed column-by-column (by name) and index-group-by-index-group\n * (by deep equality of the column-name array), each producing `column.add` /\n * `column.remove` / `index.add` / `index.remove` steps. Step order is\n * deterministic: every `table.remove`, then every `table.add`, then each\n * shared table's column/index changes in `declared` order. `from` / `to` are\n * plan labels only — version tracking itself is deferred to persistent\n * backends.\n *\n * A column present in BOTH schemas under the same name but with a different\n * `type` or `nullable` throws a `MIGRATION` {@link DatabaseError} naming the\n * table, the column, and the from→to difference — a name-only diff would\n * otherwise silently produce NO step for the drift, and versioned\n * reconciliation would stamp over it. There is no automatic in-place\n * type-change step: the manual path is to add a new column, copy/convert the\n * data at the application layer, then remove the old column — two separate\n * plans, never a single implicit \"alter\" step.\n *\n * @param deployed - The table schemas currently applied\n * @param declared - The table schemas the caller wants applied\n * @param from - The plan's source version label (defaults to `0`)\n * @param to - The plan's target version label (defaults to `1`)\n * @returns The migration plan moving `deployed` toward `declared`\n * @throws A `MIGRATION` {@link DatabaseError} when a shared column's `type` or\n * `nullable` differs between `deployed` and `declared`\n *\n * @example\n * ```ts\n * const plan = planMigration(\n * \t[{ name: 'users', primary: 'id', columns: [], indexes: [] }],\n * \t[{ name: 'users', primary: 'id', columns: [{ name: 'age', type: 'integer', nullable: false }], indexes: [] }],\n * )\n * // plan.steps === [{ operation: 'column.add', table: 'users', column: { name: 'age', ... } }]\n * ```\n */\nexport function planMigration(\n\tdeployed: readonly TableSchema[],\n\tdeclared: readonly TableSchema[],\n\tfrom = 0,\n\tto = 1,\n): Migration {\n\tconst deployedByName = new Map(deployed.map((table) => [table.name, table]))\n\tconst declaredByName = new Map(declared.map((table) => [table.name, table]))\n\n\tconst steps: MigrationStep[] = []\n\n\tfor (const table of deployed) {\n\t\tif (!declaredByName.has(table.name))\n\t\t\tsteps.push({ operation: 'table.remove', table: table.name })\n\t}\n\tfor (const table of declared) {\n\t\tif (!deployedByName.has(table.name)) steps.push({ operation: 'table.add', table })\n\t}\n\n\tfor (const table of declared) {\n\t\tconst before = deployedByName.get(table.name)\n\t\tif (before === undefined) continue\n\n\t\tconst beforeColumns = new Map(before.columns.map((column) => [column.name, column]))\n\t\tconst afterColumns = new Map(table.columns.map((column) => [column.name, column]))\n\n\t\tfor (const column of before.columns) {\n\t\t\tif (!afterColumns.has(column.name)) {\n\t\t\t\tsteps.push({ operation: 'column.remove', table: table.name, column: column.name })\n\t\t\t}\n\t\t}\n\t\tfor (const column of table.columns) {\n\t\t\tconst previous = beforeColumns.get(column.name)\n\t\t\tif (previous === undefined) {\n\t\t\t\tsteps.push({ operation: 'column.add', table: table.name, column })\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (previous.type !== column.type || previous.nullable !== column.nullable) {\n\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t'MIGRATION',\n\t\t\t\t\t`planMigration: column '${column.name}' on table '${table.name}' changed shape ` +\n\t\t\t\t\t\t`(type ${previous.type}→${column.type}, nullable ${previous.nullable}→${column.nullable}) — ` +\n\t\t\t\t\t\t`in-place type/nullability changes are not auto-migrated; add a new column, copy/convert ` +\n\t\t\t\t\t\t`the data, then remove the old column`,\n\t\t\t\t\t{\n\t\t\t\t\t\ttable: table.name,\n\t\t\t\t\t\tcolumn: column.name,\n\t\t\t\t\t\tfrom: { type: previous.type, nullable: previous.nullable },\n\t\t\t\t\t\tto: { type: column.type, nullable: column.nullable },\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\t// Deep-equal two column-name index groups (order-sensitive: an index over\n\t\t// `[a, b]` is not the same index as `[b, a]`).\n\t\tconst sameIndex = (left: readonly string[], right: readonly string[]): boolean =>\n\t\t\tleft.length === right.length && left.every((column, position) => column === right[position])\n\t\tfor (const index of before.indexes) {\n\t\t\tif (!table.indexes.some((candidate) => sameIndex(candidate, index))) {\n\t\t\t\tsteps.push({ operation: 'index.remove', table: table.name, index })\n\t\t\t}\n\t\t}\n\t\tfor (const index of table.indexes) {\n\t\t\tif (!before.indexes.some((candidate) => sameIndex(candidate, index))) {\n\t\t\t\tsteps.push({ operation: 'index.add', table: table.name, index })\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { from, to, steps }\n}\n\n/**\n * Apply one table's {@link MigrationStep}s to its rows — a pure row transform.\n *\n * @remarks\n * `column.remove` drops that field from every row (a fresh copy — inputs are\n * never mutated, AGENTS §11); `column.add` leaves rows as-is (an absent field\n * reads as `undefined`, backfill is application policy). `table.add` /\n * `table.remove` / `index.add` / `index.remove` are no-ops here (they operate\n * on storage shape, not row shape). Steps for tables other than the one\n * `rows` belongs to are ignored — pass only the steps relevant to this table.\n *\n * @param rows - The table's current rows\n * @param steps - The migration steps to apply (typically one table's slice of a {@link Migration})\n * @returns A new array of transformed rows; `rows` is never mutated\n *\n * @example\n * ```ts\n * const rows = [{ id: 'a', name: 'Ada', legacy: true }]\n * migrateRows(rows, [{ operation: 'column.remove', table: 'users', column: 'legacy' }])\n * // => [{ id: 'a', name: 'Ada' }]\n * ```\n */\nexport function migrateRows(rows: readonly Row[], steps: readonly MigrationStep[]): readonly Row[] {\n\tconst removed = steps\n\t\t.filter(\n\t\t\t(step): step is Extract<MigrationStep, { operation: 'column.remove' }> =>\n\t\t\t\tstep.operation === 'column.remove',\n\t\t)\n\t\t.map((step) => step.column)\n\n\tif (removed.length === 0) return rows.map((row) => ({ ...row }))\n\n\treturn rows.map((row) => {\n\t\tconst next: Row = {}\n\t\tfor (const key of Object.keys(row)) {\n\t\t\tif (!removed.includes(key)) next[key] = row[key]\n\t\t}\n\t\treturn next\n\t})\n}\n\n// === Conformance\n\n/**\n * Run the driver-conformance battery against a fresh {@link DriverInterface}\n * per phase, yielding one {@link ConformanceFinding} per violated invariant —\n * the shared invariant suite every backend (in-memory, SQLite, IndexedDB)\n * must uphold to be a drop-in {@link DriverInterface}.\n *\n * @remarks\n * Framework-agnostic: no test-runner or Node imports, only sibling core\n * modules — so it runs equally from a unit test, a smoke script, or a new\n * driver's own README. Opens a fixed two-table schema (`users` keyed by the\n * default `id`, `posts` keyed by a non-id `slug`) and, calling `factory()`\n * fresh for each phase so failures stay isolated, verifies: `open`/`close`;\n * `read` of a missing key returns `undefined`; `write`/`read` round-trip with\n * DEEP copy-in/copy-out isolation (mutating the caller's row — including a\n * NESTED field — after `write`, or a row `read` returns, never perturbs\n * stored state) and upsert-overwrite; `delete` returns `true` then `false`;\n * `keys`/`scan` yield in ascending key order; `clear` empties only its target\n * table; `snapshot`'s rollback thunk restores pre-snapshot state, including a\n * NESTED field mutated in place on a read-back row between capture and\n * restore; a scoped `snapshot(['users'])` rolls back only the named table,\n * leaving a concurrent mutation to another table intact; a\n * non-`id` primary key (`posts.slug`) round-trips; a nested-object row\n * round-trips structurally (via {@link deepEqual}). The optional surface is\n * presence-gated: when `migrate` exists, a `column.remove` plan strips the\n * column from stored rows and a plan referencing an unknown table throws\n * `DatabaseError` `MIGRATION`; when `stream` exists, it yields only\n * condition-matching rows and honors `offset`/`limit`; when `transaction`\n * exists, `commit` persists and `rollback` restores; when both `meta` and\n * `stamp` exist, a fresh store's `meta()` is `undefined`, and after\n * `stamp({ version, schema })`, `meta()` returns the exact stamped value.\n *\n * Each phase runs within a `try`/`catch`: an EXPECTED mismatch yields a\n * finding built from the assertion, while an UNEXPECTED throw (a driver\n * crash mid-phase) is caught and yielded as a finding too, naming the phase\n * as `check` and carrying the caught error in `context.error` — a broken\n * driver can never escape the battery as an unhandled rejection. Within a\n * phase, the FIRST violated assertion yields and the phase stops (matching\n * the historical fail-fast shape at phase granularity); the generator then\n * moves on to the next phase regardless. Because this is a **generator**,\n * consuming only the first yielded value reproduces true fail-fast (later\n * phases never run) — that is exactly what {@link conformDriver} does.\n *\n * @param factory - Mints a fresh, unopened driver instance (called once per phase)\n * @yields One {@link ConformanceFinding} per violated invariant, in phase order\n *\n * @example\n * ```ts\n * import { createMemoryDriver, driverFindings } from '@orkestrel/database'\n *\n * for await (const finding of driverFindings(() => createMemoryDriver())) {\n * \tconsole.log(finding.check, finding.message)\n * }\n * ```\n */\nexport async function* driverFindings(\n\tfactory: () => DriverInterface,\n): AsyncIterable<ConformanceFinding> {\n\t// Fixed two-table schema every phase opens: `users` keyed by `id` (the\n\t// default primary), `posts` keyed by a non-id `slug` — exercising both\n\t// primary-key shapes in one battery.\n\tconst CONFORMANCE_USERS_SCHEMA: TableSchema = {\n\t\tname: 'users',\n\t\tprimary: 'id',\n\t\tcolumns: [\n\t\t\t{ name: 'id', type: 'text', nullable: false },\n\t\t\t{ name: 'name', type: 'text', nullable: false },\n\t\t\t{ name: 'age', type: 'integer', nullable: true },\n\t\t\t// Declared so the nested-roundtrip phase is fair to typed-column\n\t\t\t// backends (a SQL driver persists only declared columns; schemaless\n\t\t\t// backends ignore declarations entirely).\n\t\t\t{ name: 'meta', type: 'json', nullable: true },\n\t\t],\n\t\tindexes: [],\n\t}\n\tconst CONFORMANCE_POSTS_SCHEMA: TableSchema = {\n\t\tname: 'posts',\n\t\tprimary: 'slug',\n\t\tcolumns: [\n\t\t\t{ name: 'slug', type: 'text', nullable: false },\n\t\t\t{ name: 'title', type: 'text', nullable: false },\n\t\t],\n\t\tindexes: [],\n\t}\n\tconst CONFORMANCE_SCHEMA: readonly TableSchema[] = [\n\t\tCONFORMANCE_USERS_SCHEMA,\n\t\tCONFORMANCE_POSTS_SCHEMA,\n\t]\n\t// Build a ConformanceFinding naming which check failed plus the\n\t// expected/actual summary — the single failure-reporting shape every\n\t// phase below funnels through (returned, never thrown).\n\tconst findingOf = (\n\t\tcheck: string,\n\t\tmessage: string,\n\t\tcontext: Readonly<Record<string, unknown>>,\n\t): ConformanceFinding => ({ check, message, context })\n\n\ttype Phase = {\n\t\treadonly check: string\n\t\treadonly run: () => Promise<ConformanceFinding | undefined>\n\t}\n\n\tconst phases: readonly Phase[] = [\n\t\t// a. open with the inline two-table schema, then close cleanly.\n\t\t{\n\t\t\tcheck: 'open-close',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tawait driver.close()\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// b. read of a missing key -> undefined.\n\t\t{\n\t\t\tcheck: 'read-missing',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tconst missing = await driver.read('users', 'nope')\n\t\t\t\tawait driver.close()\n\t\t\t\tif (missing !== undefined) {\n\t\t\t\t\treturn findingOf('read-missing', 'read of a missing key must return undefined', {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected: undefined,\n\t\t\t\t\t\tactual: missing,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// c. write/read round-trip, copy-in/copy-out isolation (including NESTED\n\t\t// fields, not just top-level ones), upsert-overwrite.\n\t\t{\n\t\t\tcheck: 'write-read',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tconst input: Row = { id: 'u1', name: 'Ada', age: 30, meta: { tags: ['a'] } }\n\t\t\t\tawait driver.write('users', 'u1', input)\n\t\t\t\tinput.name = 'Mutated after write'\n\t\t\t\t// Mutate a NESTED field of the input after write — a shallow copy-in\n\t\t\t\t// would still share the nested object by reference.\n\t\t\t\tif (isRecord(input.meta) && Array.isArray(input.meta.tags)) input.meta.tags.push('mutated')\n\t\t\t\tconst stored = await driver.read('users', 'u1')\n\t\t\t\tconst original = { id: 'u1', name: 'Ada', age: 30, meta: { tags: ['a'] } }\n\t\t\t\tif (stored === undefined || !deepEqual(stored, original)) {\n\t\t\t\t\tawait driver.close()\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'copy-in',\n\t\t\t\t\t\t'write must deep-copy the input row (including nested fields) rather than store it by reference',\n\t\t\t\t\t\t{ table: 'users', expected: original, actual: stored },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tstored.name = 'Mutated after read'\n\t\t\t\t// Mutate a NESTED field of the read result — a shallow copy-out would\n\t\t\t\t// still share the nested object with stored state.\n\t\t\t\tif (isRecord(stored.meta) && Array.isArray(stored.meta.tags))\n\t\t\t\t\tstored.meta.tags.push('mutated')\n\t\t\t\tconst reread = await driver.read('users', 'u1')\n\t\t\t\tif (reread === undefined || !deepEqual(reread, original)) {\n\t\t\t\t\tawait driver.close()\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'copy-out',\n\t\t\t\t\t\t'read must deep-copy the stored row (including nested fields) rather than return it by reference',\n\t\t\t\t\t\t{ table: 'users', expected: original, actual: reread },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tconst overwrite = { id: 'u1', name: 'Ada Overwritten', age: 31 }\n\t\t\t\tawait driver.write('users', 'u1', overwrite)\n\t\t\t\tconst overwritten = await driver.read('users', 'u1')\n\t\t\t\tawait driver.close()\n\t\t\t\tif (overwritten === undefined || !deepEqual(overwritten, overwrite)) {\n\t\t\t\t\treturn findingOf('upsert', 'write must upsert-overwrite an existing key', {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected: overwrite,\n\t\t\t\t\t\tactual: overwritten,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// d. delete -> true then false.\n\t\t{\n\t\t\tcheck: 'delete',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tawait driver.write('users', 'u1', { id: 'u1', name: 'Ada', age: 30 })\n\t\t\t\tconst first = await driver.delete('users', 'u1')\n\t\t\t\tif (first !== true) {\n\t\t\t\t\tawait driver.close()\n\t\t\t\t\treturn findingOf('delete-true', 'delete of an existing key must return true', {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected: true,\n\t\t\t\t\t\tactual: first,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconst second = await driver.delete('users', 'u1')\n\t\t\t\tawait driver.close()\n\t\t\t\tif (second !== false) {\n\t\t\t\t\treturn findingOf('delete-false', 'delete of an already-removed key must return false', {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected: false,\n\t\t\t\t\t\tactual: second,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// e. keys and scan in ascending key order.\n\t\t{\n\t\t\tcheck: 'order',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tconst rows = [\n\t\t\t\t\t{ id: 'c', name: 'C', age: 3 },\n\t\t\t\t\t{ id: 'a', name: 'A', age: 1 },\n\t\t\t\t\t{ id: 'b', name: 'B', age: 2 },\n\t\t\t\t]\n\t\t\t\tfor (const row of rows) await driver.write('users', row.id, row)\n\t\t\t\tconst expected = ['a', 'b', 'c']\n\t\t\t\tconst keys = [...(await driver.keys('users'))]\n\t\t\t\tif (!deepEqual(keys, expected)) {\n\t\t\t\t\tawait driver.close()\n\t\t\t\t\treturn findingOf('keys-order', 'keys must be returned in ascending key order', {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected,\n\t\t\t\t\t\tactual: keys,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconst scanned: Row[] = []\n\t\t\t\tfor await (const row of driver.scan('users')) scanned.push(row)\n\t\t\t\tconst scannedIds = scanned.map((row) => row.id)\n\t\t\t\tawait driver.close()\n\t\t\t\tif (!deepEqual(scannedIds, expected)) {\n\t\t\t\t\treturn findingOf('scan-order', 'scan must yield rows in ascending key order', {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected,\n\t\t\t\t\t\tactual: scannedIds,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// f. clear empties only the targeted table.\n\t\t{\n\t\t\tcheck: 'clear',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tawait driver.write('users', 'u1', { id: 'u1', name: 'Ada', age: 30 })\n\t\t\t\tawait driver.write('posts', 'p1', { slug: 'p1', title: 'Post' })\n\t\t\t\tawait driver.clear('users')\n\t\t\t\tconst usersKeys = await driver.keys('users')\n\t\t\t\tconst postsKeys = await driver.keys('posts')\n\t\t\t\tawait driver.close()\n\t\t\t\tif (usersKeys.length !== 0) {\n\t\t\t\t\treturn findingOf('clear-target', 'clear must empty the targeted table', {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected: [],\n\t\t\t\t\t\tactual: usersKeys,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif (postsKeys.length !== 1) {\n\t\t\t\t\treturn findingOf('clear-other', 'clear must not affect other tables', {\n\t\t\t\t\t\ttable: 'posts',\n\t\t\t\t\t\texpected: 1,\n\t\t\t\t\t\tactual: postsKeys.length,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// g. snapshot rollback restores pre-snapshot state.\n\t\t{\n\t\t\tcheck: 'snapshot',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tconst original = { id: 'u1', name: 'Ada', age: 30 }\n\t\t\t\tawait driver.write('users', 'u1', original)\n\t\t\t\tconst rollback = await driver.snapshot()\n\t\t\t\tawait driver.write('users', 'u2', { id: 'u2', name: 'Grace', age: 40 })\n\t\t\t\tawait driver.delete('users', 'u1')\n\t\t\t\tawait rollback()\n\t\t\t\tconst keys = [...(await driver.keys('users'))]\n\t\t\t\tif (!deepEqual(keys, ['u1'])) {\n\t\t\t\t\tawait driver.close()\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'snapshot-rollback',\n\t\t\t\t\t\t'snapshot rollback must restore the pre-snapshot key set',\n\t\t\t\t\t\t{ table: 'users', expected: ['u1'], actual: keys },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tconst restored = await driver.read('users', 'u1')\n\t\t\t\tawait driver.close()\n\t\t\t\tif (restored === undefined || !deepEqual(restored, original)) {\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'snapshot-rollback-value',\n\t\t\t\t\t\t'snapshot rollback must restore pre-snapshot row values',\n\t\t\t\t\t\t{ table: 'users', expected: original, actual: restored },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// g2. snapshot rollback survives a NESTED field mutated in place, on a\n\t\t// row already read back, BETWEEN capture and restore — a snapshot that\n\t\t// only clones top-level fields (or shares nested references) would\n\t\t// restore a mutated nested value instead of the pre-snapshot one.\n\t\t{\n\t\t\tcheck: 'snapshot-nested',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tconst original = { id: 'u3', name: 'Nested', age: 20, meta: { tags: ['a'] } }\n\t\t\t\tawait driver.write('users', 'u3', original)\n\t\t\t\tconst rollback = await driver.snapshot()\n\t\t\t\tconst before = await driver.read('users', 'u3')\n\t\t\t\tif (isRecord(before) && isRecord(before.meta) && Array.isArray(before.meta.tags)) {\n\t\t\t\t\tbefore.meta.tags.push('mutated-before-restore')\n\t\t\t\t}\n\t\t\t\tawait driver.write('users', 'u3', {\n\t\t\t\t\tid: 'u3',\n\t\t\t\t\tname: 'Nested',\n\t\t\t\t\tage: 20,\n\t\t\t\t\tmeta: { tags: ['a', 'mutated-after-write'] },\n\t\t\t\t})\n\t\t\t\tawait rollback()\n\t\t\t\tconst restored = await driver.read('users', 'u3')\n\t\t\t\tawait driver.close()\n\t\t\t\tif (restored === undefined || !deepEqual(restored, original)) {\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'snapshot-nested',\n\t\t\t\t\t\t'snapshot rollback must restore pre-snapshot nested field values, unaffected by a later in-place mutation of a read-back row',\n\t\t\t\t\t\t{ table: 'users', expected: original, actual: restored },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// h. non-id primary extraction (posts keyed by slug).\n\t\t{\n\t\t\tcheck: 'non-id-primary',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tawait driver.write('posts', 'hello-world', { slug: 'hello-world', title: 'Hello' })\n\t\t\t\tconst post = await driver.read('posts', 'hello-world')\n\t\t\t\tconst key = post === undefined ? undefined : extractKey(post, 'slug')\n\t\t\t\tawait driver.close()\n\t\t\t\tif (key !== 'hello-world') {\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'non-id-primary',\n\t\t\t\t\t\t'a non-id primary key column must round-trip through the store',\n\t\t\t\t\t\t{ table: 'posts', expected: 'hello-world', actual: key },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// i. nested-object row round-trip (structural, via deepEqual).\n\t\t{\n\t\t\tcheck: 'nested-roundtrip',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tconst nested = {\n\t\t\t\t\tid: 'u3',\n\t\t\t\t\tname: 'Nested',\n\t\t\t\t\tage: 20,\n\t\t\t\t\tmeta: { tags: ['a', 'b'], deep: { flag: true } },\n\t\t\t\t}\n\t\t\t\tawait driver.write('users', 'u3', nested)\n\t\t\t\tconst readBack = await driver.read('users', 'u3')\n\t\t\t\tawait driver.close()\n\t\t\t\tif (readBack === undefined || !deepEqual(readBack, nested)) {\n\t\t\t\t\treturn findingOf('nested-roundtrip', 'a nested-object row must round-trip structurally', {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected: nested,\n\t\t\t\t\t\tactual: readBack,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// j. migrate (presence-gated): a planMigration-built column.remove plan strips\n\t\t// stored rows; an unknown-table plan throws a MIGRATION DatabaseError.\n\t\t{\n\t\t\tcheck: 'migrate',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tif (driver.migrate === undefined) return undefined\n\t\t\t\t// Open with the DEPLOYED schema so `legacy` is a declared column —\n\t\t\t\t// a typed-column backend persists only declared columns and can only\n\t\t\t\t// drop a column that really exists; schemaless backends are unaffected.\n\t\t\t\tconst deployedUsers: TableSchema = {\n\t\t\t\t\t...CONFORMANCE_USERS_SCHEMA,\n\t\t\t\t\tcolumns: [\n\t\t\t\t\t\t...CONFORMANCE_USERS_SCHEMA.columns,\n\t\t\t\t\t\t{ name: 'legacy', type: 'boolean', nullable: true },\n\t\t\t\t\t],\n\t\t\t\t}\n\t\t\t\tawait driver.open([deployedUsers, CONFORMANCE_POSTS_SCHEMA])\n\t\t\t\tawait driver.write('users', 'u1', { id: 'u1', name: 'Ada', age: 30, legacy: true })\n\t\t\t\tconst removePlan = planMigration([deployedUsers], [CONFORMANCE_USERS_SCHEMA])\n\t\t\t\tawait driver.migrate(removePlan)\n\t\t\t\tconst migrated = await driver.read('users', 'u1')\n\t\t\t\tif (migrated === undefined || 'legacy' in migrated) {\n\t\t\t\t\tawait driver.close()\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'migrate-column-remove',\n\t\t\t\t\t\t'a column.remove migration must strip the column from stored rows',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\t\texpected: undefined,\n\t\t\t\t\t\t\tactual: migrated === undefined ? undefined : migrated.legacy,\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tlet caught: unknown\n\t\t\t\ttry {\n\t\t\t\t\tawait driver.migrate({\n\t\t\t\t\t\tfrom: 0,\n\t\t\t\t\t\tto: 1,\n\t\t\t\t\t\tsteps: [{ operation: 'table.remove', table: 'ghost' }],\n\t\t\t\t\t})\n\t\t\t\t} catch (error) {\n\t\t\t\t\tcaught = error\n\t\t\t\t}\n\t\t\t\tawait driver.close()\n\t\t\t\tif (!isDatabaseError(caught) || caught.code !== 'MIGRATION') {\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'migrate-unknown-table',\n\t\t\t\t\t\t'a migration step referencing an unknown table must throw a MIGRATION DatabaseError',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttable: 'ghost',\n\t\t\t\t\t\t\texpected: 'MIGRATION',\n\t\t\t\t\t\t\tactual: isDatabaseError(caught) ? caught.code : caught,\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// k. stream (presence-gated): yields only condition-matching rows, honors offset/limit.\n\t\t{\n\t\t\tcheck: 'stream',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tif (driver.stream === undefined) return undefined\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tconst rows = [\n\t\t\t\t\t{ id: 'a', name: 'A', age: 10 },\n\t\t\t\t\t{ id: 'b', name: 'B', age: 20 },\n\t\t\t\t\t{ id: 'c', name: 'C', age: 30 },\n\t\t\t\t]\n\t\t\t\tfor (const row of rows) await driver.write('users', row.id, row)\n\t\t\t\tconst criteria: Criteria = {\n\t\t\t\t\tconditions: [{ column: 'age', operator: 'above', values: [10], connector: 'and' }],\n\t\t\t\t}\n\t\t\t\tconst matched: Row[] = []\n\t\t\t\tfor await (const row of driver.stream('users', criteria)) matched.push(row)\n\t\t\t\tconst matchedIds = matched.map((row) => row.id).sort()\n\t\t\t\tif (!deepEqual(matchedIds, ['b', 'c'])) {\n\t\t\t\t\tawait driver.close()\n\t\t\t\t\treturn findingOf('stream-match', 'stream must yield only condition-matching rows', {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected: ['b', 'c'],\n\t\t\t\t\t\tactual: matchedIds,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconst paged: Row[] = []\n\t\t\t\tfor await (const row of driver.stream('users', { offset: 1, limit: 1 })) paged.push(row)\n\t\t\t\tawait driver.close()\n\t\t\t\tif (paged.length !== 1) {\n\t\t\t\t\treturn findingOf('stream-page', 'stream must honor offset and limit', {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected: 1,\n\t\t\t\t\t\tactual: paged.length,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// l. transaction (presence-gated): commit persists, rollback restores.\n\t\t{\n\t\t\tcheck: 'transaction',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tif (driver.transaction === undefined) return undefined\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tawait driver.write('users', 'u1', { id: 'u1', name: 'Ada', age: 30 })\n\t\t\t\tconst committing = await driver.transaction()\n\t\t\t\tawait driver.write('users', 'u2', { id: 'u2', name: 'Grace', age: 40 })\n\t\t\t\tawait committing.commit()\n\t\t\t\tconst afterCommit = [...(await driver.keys('users'))].sort()\n\t\t\t\tif (!deepEqual(afterCommit, ['u1', 'u2'])) {\n\t\t\t\t\tawait driver.close()\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'transaction-commit',\n\t\t\t\t\t\t'transaction commit must persist writes made during the scope',\n\t\t\t\t\t\t{ table: 'users', expected: ['u1', 'u2'], actual: afterCommit },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tconst rollingBack = await driver.transaction()\n\t\t\t\tawait driver.write('users', 'u3', { id: 'u3', name: 'Marie', age: 50 })\n\t\t\t\tawait rollingBack.rollback()\n\t\t\t\tconst afterRollback = [...(await driver.keys('users'))].sort()\n\t\t\t\tawait driver.close()\n\t\t\t\tif (!deepEqual(afterRollback, ['u1', 'u2'])) {\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'transaction-rollback',\n\t\t\t\t\t\t'transaction rollback must restore pre-transaction state',\n\t\t\t\t\t\t{ table: 'users', expected: ['u1', 'u2'], actual: afterRollback },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// m. meta/stamp (presence-gated: a driver implements both or neither). A\n\t\t// fresh store's meta() is undefined; after stamp({ version, schema }),\n\t\t// meta() returns exactly the stamped value.\n\t\t{\n\t\t\tcheck: 'meta-stamp',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tif (driver.meta === undefined || driver.stamp === undefined) return undefined\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tconst fresh = await driver.meta()\n\t\t\t\tif (fresh !== undefined) {\n\t\t\t\t\tawait driver.close()\n\t\t\t\t\treturn findingOf('meta-fresh', 'a fresh store must report undefined meta', {\n\t\t\t\t\t\texpected: undefined,\n\t\t\t\t\t\tactual: fresh,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tconst stamped = { version: 1, schema: CONFORMANCE_SCHEMA }\n\t\t\t\tawait driver.stamp(stamped)\n\t\t\t\tconst read = await driver.meta()\n\t\t\t\tawait driver.close()\n\t\t\t\tif (read === undefined || !deepEqual(read, stamped)) {\n\t\t\t\t\treturn findingOf('meta-stamp', 'meta() must return exactly the last-stamped value', {\n\t\t\t\t\t\texpected: stamped,\n\t\t\t\t\t\tactual: read,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\n\t\t// n. scoped snapshot: snapshot(['users']) rolls back only the named\n\t\t// table — a concurrent mutation to another table survives the rollback.\n\t\t{\n\t\t\tcheck: 'snapshot-scoped',\n\t\t\trun: async () => {\n\t\t\t\tconst driver = factory()\n\t\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\t\tconst original = { id: 'u1', name: 'Ada', age: 30 }\n\t\t\t\tawait driver.write('users', 'u1', original)\n\t\t\t\tawait driver.write('posts', 'p1', { slug: 'p1', title: 'Post' })\n\t\t\t\tconst rollback = await driver.snapshot(['users'])\n\t\t\t\tawait driver.write('users', 'u2', { id: 'u2', name: 'Grace', age: 40 })\n\t\t\t\tawait driver.write('posts', 'p2', { slug: 'p2', title: 'Another post' })\n\t\t\t\tawait rollback()\n\t\t\t\tconst usersKeys = [...(await driver.keys('users'))]\n\t\t\t\tif (!deepEqual(usersKeys, ['u1'])) {\n\t\t\t\t\tawait driver.close()\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'snapshot-scoped-users',\n\t\t\t\t\t\t'a scoped snapshot must roll back only the named table',\n\t\t\t\t\t\t{ table: 'users', expected: ['u1'], actual: usersKeys },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tconst postsKeys = [...(await driver.keys('posts'))].sort()\n\t\t\t\tawait driver.close()\n\t\t\t\tif (!deepEqual(postsKeys, ['p1', 'p2'])) {\n\t\t\t\t\treturn findingOf(\n\t\t\t\t\t\t'snapshot-scoped-posts',\n\t\t\t\t\t\t\"a scoped snapshot must leave an unnamed table's mutations intact\",\n\t\t\t\t\t\t{ table: 'posts', expected: ['p1', 'p2'], actual: postsKeys },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\treturn undefined\n\t\t\t},\n\t\t},\n\t]\n\n\tfor (const phase of phases) {\n\t\ttry {\n\t\t\tconst finding = await phase.run()\n\t\t\tif (finding !== undefined) yield finding\n\t\t} catch (error) {\n\t\t\tyield findingOf(phase.check, error instanceof Error ? error.message : String(error), {\n\t\t\t\terror,\n\t\t\t})\n\t\t}\n\t}\n}\n\n/**\n * Run the driver-conformance battery, throwing on the first violated\n * invariant — the fail-fast entry point most callers (test setup, CI smoke\n * checks) want.\n *\n * @remarks\n * A thin driver over {@link driverFindings}: because that generator is\n * lazy, consuming only its first yielded value means every LATER phase\n * never runs — true fail-fast, not merely \"report only the first\". The\n * thrown error is byte-compatible with the historical shape: a\n * `CONFORMANCE` {@link DatabaseError} whose `message` is the finding's\n * `message` and whose `context` is `{ check, ...finding.context }`.\n *\n * @param factory - Mints a fresh, unopened driver instance (called once per phase)\n * @returns Nothing — resolves once every phase has passed\n * @throws A `CONFORMANCE` {@link DatabaseError} on the first violated invariant\n *\n * @example\n * ```ts\n * import { conformDriver, createMemoryDriver } from '@orkestrel/database'\n *\n * await conformDriver(() => createMemoryDriver()) // resolves when every invariant holds\n * ```\n */\nexport async function conformDriver(factory: () => DriverInterface): Promise<void> {\n\tfor await (const finding of driverFindings(factory)) {\n\t\tthrow new DatabaseError('CONFORMANCE', finding.message, {\n\t\t\tcheck: finding.check,\n\t\t\t...finding.context,\n\t\t})\n\t}\n}\n\n/**\n * Run the FULL driver-conformance battery and collect every violation — the\n * audit entry point for a driver author who wants a complete report rather\n * than a single fail-fast throw.\n *\n * @remarks\n * Drains {@link driverFindings} to completion: every phase runs regardless\n * of earlier violations, so a driver breaking two independent invariants\n * reports both. An empty array means the driver is fully conformant.\n *\n * @param factory - Mints a fresh, unopened driver instance (called once per phase)\n * @returns Every violated invariant found, in phase order (empty when fully conformant)\n *\n * @example\n * ```ts\n * import { auditDriver, createMemoryDriver } from '@orkestrel/database'\n *\n * const findings = await auditDriver(() => createMemoryDriver())\n * for (const finding of findings) console.log(`${finding.check}: ${finding.message}`)\n * ```\n */\nexport async function auditDriver(\n\tfactory: () => DriverInterface,\n): Promise<readonly ConformanceFinding[]> {\n\tconst findings: ConformanceFinding[] = []\n\tfor await (const finding of driverFindings(factory)) findings.push(finding)\n\treturn findings\n}\n\n// === Identifiers\n\n/**\n * Generate an RFC 4122 version 4 UUID from a number source — no host crypto global.\n *\n * @remarks\n * Draws exactly {@link UUID_BYTE_COUNT} values from `random`, one per byte, then\n * forces the version (`4`) and variant (`10xx`) bits. The default source is\n * `Math.random` — a pure-ECMAScript intrinsic, so generation works on every host;\n * pass a seeded source (`seededRandom` from `@orkestrel/contract`) and reuse it\n * across calls for reproducible sequences in tests and fixtures — production\n * identifiers should keep the default source, whose engine entropy is far larger\n * than a 32-bit seed. Each byte is floored and masked, so a source straying\n * outside `[0, 1)` (negative, `>= 1`, `NaN`, `Infinity`) can never yield a\n * malformed UUID. Suitable as a collision-resistant record identifier — not a\n * cryptographic token; never use one as a secret.\n *\n * @param random - A number source returning values in the half-open range `[0, 1)` (defaults to `Math.random`)\n * @returns A lowercase RFC 4122 version 4 UUID\n *\n * @example\n * ```ts\n * import { generateUUID } from '@orkestrel/database'\n * import { seededRandom } from '@orkestrel/contract'\n *\n * generateUUID() // e.g. '9b2f7c1e-3d4a-4f6b-8e2d-5a1c0b9f8e7d'\n * generateUUID(seededRandom(42)) // the same UUID on every run\n * ```\n */\nexport function generateUUID(random: RandomFunction = Math.random): string {\n\tconst bytes = Array.from(\n\t\t{ length: UUID_BYTE_COUNT },\n\t\t() => Math.floor(random() * UUID_BYTE_RANGE) & 0xff,\n\t)\n\tbytes[6] = (bytes[6] & 0x0f) | 0x40\n\tbytes[8] = (bytes[8] & 0x3f) | 0x80\n\tconst hex = bytes.map((byte) => byte.toString(16).padStart(2, '0'))\n\treturn `${hex.slice(0, 4).join('')}-${hex.slice(4, 6).join('')}-${hex.slice(6, 8).join('')}-${hex.slice(8, 10).join('')}-${hex.slice(10).join('')}`\n}\n","import type { CursorInterface, Key, TableInterface } from './types.js'\n\n/**\n * A forward row cursor for bulk in-place mutation.\n *\n * @remarks\n * Iterates a snapshot of the table's keys captured when the cursor was opened,\n * reading each row lazily through the owning table — so a mutation made during\n * iteration cannot corrupt the walk, and a key removed mid-iteration is simply\n * skipped. `update` and `remove` act on the row at the current position.\n */\nexport class Cursor<T = Record<string, unknown>> implements CursorInterface<T> {\n\treadonly #table: TableInterface<T>\n\treadonly #keys: readonly Key[]\n\t#index = -1\n\t#value: T | undefined\n\t#closed = false\n\n\tconstructor(table: TableInterface<T>, keys: readonly Key[]) {\n\t\tthis.#table = table\n\t\tthis.#keys = keys\n\t}\n\n\tget value(): T | undefined {\n\t\treturn this.#value\n\t}\n\n\tget index(): number {\n\t\treturn this.#index\n\t}\n\n\tget done(): boolean {\n\t\treturn this.#closed || this.#index >= this.#keys.length\n\t}\n\n\tasync next(): Promise<void> {\n\t\tif (this.#closed) return\n\t\tthis.#index += 1\n\t\twhile (this.#index < this.#keys.length) {\n\t\t\tconst row = await this.#table.get(this.#keys[this.#index])\n\t\t\tif (row !== undefined) {\n\t\t\t\tthis.#value = row\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.#index += 1\n\t\t}\n\t\tthis.#value = undefined\n\t}\n\n\tasync update(changes: Partial<T>): Promise<void> {\n\t\tif (this.#closed || this.#value === undefined) return\n\t\tconst key = this.#keys[this.#index]\n\t\tawait this.#table.update(key, changes)\n\t\tthis.#value = await this.#table.get(key)\n\t}\n\n\tasync remove(): Promise<void> {\n\t\tif (this.#closed || this.#value === undefined) return\n\t\tawait this.#table.remove(this.#keys[this.#index])\n\t\tthis.#value = undefined\n\t}\n\n\tclose(): void {\n\t\tthis.#closed = true\n\t\tthis.#value = undefined\n\t}\n}\n","import type { FieldPath } from '@orkestrel/contract'\nimport type {\n\tCondition,\n\tConditionOperator,\n\tConnector,\n\tQueryInterface,\n\tClauseInterface,\n} from './types.js'\n\n/**\n * A pending condition opened by a query's `where` / `and` / `or`.\n *\n * @remarks\n * Holds the column, the connector that will join this condition to the ones\n * before it, and a recorder the owning query supplies. Each operator builds the\n * {@link Condition}, hands it to the recorder, and returns the query — so the\n * fluent chain flows straight back into the builder without exposing a mutator.\n */\nexport class Clause<T = Record<string, unknown>> implements ClauseInterface<T> {\n\treadonly #record: (condition: Condition) => QueryInterface<T>\n\treadonly #column: FieldPath\n\treadonly #connector: Connector\n\n\tconstructor(\n\t\trecord: (condition: Condition) => QueryInterface<T>,\n\t\tcolumn: FieldPath,\n\t\tconnector: Connector,\n\t) {\n\t\tthis.#record = record\n\t\tthis.#column = column\n\t\tthis.#connector = connector\n\t}\n\n\tequals(value: unknown): QueryInterface<T> {\n\t\treturn this.#apply('equals', [value])\n\t}\n\n\tnot(value: unknown): QueryInterface<T> {\n\t\treturn this.#apply('not', [value])\n\t}\n\n\tabove(value: unknown): QueryInterface<T> {\n\t\treturn this.#apply('above', [value])\n\t}\n\n\tbelow(value: unknown): QueryInterface<T> {\n\t\treturn this.#apply('below', [value])\n\t}\n\n\tfrom(value: unknown): QueryInterface<T> {\n\t\treturn this.#apply('from', [value])\n\t}\n\n\tto(value: unknown): QueryInterface<T> {\n\t\treturn this.#apply('to', [value])\n\t}\n\n\tbetween(lower: unknown, upper: unknown): QueryInterface<T> {\n\t\treturn this.#apply('between', [lower, upper])\n\t}\n\n\tlike(pattern: string): QueryInterface<T> {\n\t\treturn this.#apply('like', [pattern])\n\t}\n\n\tglob(pattern: string): QueryInterface<T> {\n\t\treturn this.#apply('glob', [pattern])\n\t}\n\n\tstarts(prefix: string): QueryInterface<T> {\n\t\treturn this.#apply('starts', [prefix])\n\t}\n\n\tends(suffix: string): QueryInterface<T> {\n\t\treturn this.#apply('ends', [suffix])\n\t}\n\n\tany(values: readonly unknown[]): QueryInterface<T> {\n\t\treturn this.#apply('any', values)\n\t}\n\n\tnone(values: readonly unknown[]): QueryInterface<T> {\n\t\treturn this.#apply('none', values)\n\t}\n\n\tabsent(): QueryInterface<T> {\n\t\treturn this.#apply('absent', [])\n\t}\n\n\tpresent(): QueryInterface<T> {\n\t\treturn this.#apply('present', [])\n\t}\n\n\t#apply(operator: ConditionOperator, values: readonly unknown[]): QueryInterface<T> {\n\t\treturn this.#record({ column: this.#column, operator, values, connector: this.#connector })\n\t}\n}\n","import type { FieldPath } from '@orkestrel/contract'\nimport type {\n\tAggregateFunction,\n\tClauseInterface,\n\tCondition,\n\tConnector,\n\tOrder,\n\tQueryInterface,\n\tReadOptions,\n\tTableInterface,\n} from './types.js'\nimport { computeAggregate } from './helpers.js'\nimport { Clause } from './Clause.js'\n\n/**\n * A fluent query builder bound to one table.\n *\n * @remarks\n * Accumulates conditions, ordering, JS filters, and a page; each builder method\n * mutates and returns the same instance, so a chain reads as one statement. The\n * portable parts (conditions, order, page) compile into a {@link Criteria} the\n * table resolves; a `filter` predicate is applied in memory after the read and\n * before paging, so it composes with the rest without a backend ever seeing a\n * JS callback.\n */\nexport class Query<T = Record<string, unknown>> implements QueryInterface<T> {\n\treadonly #table: TableInterface<T>\n\treadonly #conditions: Condition[] = []\n\treadonly #orders: Order[] = []\n\treadonly #filters: ((row: T) => boolean)[] = []\n\t#limit: number | undefined\n\t#offset: number | undefined\n\n\tconstructor(table: TableInterface<T>) {\n\t\tthis.#table = table\n\t}\n\n\twhere(column: FieldPath): ClauseInterface<T> {\n\t\treturn this.#clause(column, 'and')\n\t}\n\n\tand(column: FieldPath): ClauseInterface<T> {\n\t\treturn this.#clause(column, 'and')\n\t}\n\n\tor(column: FieldPath): ClauseInterface<T> {\n\t\treturn this.#clause(column, 'or')\n\t}\n\n\tfilter(predicate: (row: T) => boolean): QueryInterface<T> {\n\t\tthis.#filters.push(predicate)\n\t\treturn this\n\t}\n\n\tascending(column: FieldPath): QueryInterface<T> {\n\t\tthis.#orders.push({ column, direction: 'ascending' })\n\t\treturn this\n\t}\n\n\tdescending(column: FieldPath): QueryInterface<T> {\n\t\tthis.#orders.push({ column, direction: 'descending' })\n\t\treturn this\n\t}\n\n\tlimit(count: number): QueryInterface<T> {\n\t\tthis.#limit = count\n\t\treturn this\n\t}\n\n\toffset(count: number): QueryInterface<T> {\n\t\tthis.#offset = count\n\t\treturn this\n\t}\n\n\tasync all(): Promise<readonly T[]> {\n\t\t// No JS filters → push the whole criteria (including paging) to the table.\n\t\tif (this.#filters.length === 0) {\n\t\t\treturn this.#table.records({\n\t\t\t\tconditions: this.#conditions,\n\t\t\t\torder: this.#orders,\n\t\t\t\tlimit: this.#limit,\n\t\t\t\toffset: this.#offset,\n\t\t\t})\n\t\t}\n\t\t// With filters → fetch conditions + order, filter in memory, then page.\n\t\tconst fetched = await this.#table.records({ conditions: this.#conditions, order: this.#orders })\n\t\treturn this.#page(this.#filtered(fetched))\n\t}\n\n\tasync first(): Promise<T | undefined> {\n\t\tconst rows = await this.all()\n\t\treturn rows[0]\n\t}\n\n\tasync count(): Promise<number> {\n\t\tif (this.#filters.length === 0) {\n\t\t\treturn this.#table.count({ conditions: this.#conditions })\n\t\t}\n\t\tconst fetched = await this.#table.records({ conditions: this.#conditions })\n\t\treturn this.#filtered(fetched).length\n\t}\n\n\t/**\n\t * Lazy per-row evaluation of this query's conditions / filters / offset /\n\t * limit.\n\t *\n\t * @remarks\n\t * `order` and its comparators are IGNORED (streaming yields unsorted, as rows\n\t * are evaluated one at a time). Same abort semantics as\n\t * `TableInterface.scan`: the signal (if any) is checked before each yield,\n\t * and breaking out early closes the underlying source.\n\t *\n\t * @param options - `signal` to cancel the iteration; checked before each yield\n\t * @returns An async iterable of matching rows\n\t */\n\tasync *stream(options?: ReadOptions): AsyncIterable<T> {\n\t\t// No JS filters → the table's own offset/limit apply directly against the\n\t\t// condition-matched rows (matching `all()`'s no-filter fast path).\n\t\tif (this.#filters.length === 0) {\n\t\t\tyield* this.#table.scan(\n\t\t\t\t{ conditions: this.#conditions, limit: this.#limit, offset: this.#offset },\n\t\t\t\toptions,\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\t// With filters → offset/limit must apply AFTER filtering, so the table is\n\t\t// asked for conditions only and paging is counted here (matching `all()`'s\n\t\t// filtered path: fetch, filter in memory, then page).\n\t\tconst offset = this.#offset ?? 0\n\t\tlet matched = 0\n\t\tlet yielded = 0\n\t\tfor await (const row of this.#table.scan({ conditions: this.#conditions }, options)) {\n\t\t\tif (this.#limit !== undefined && yielded >= this.#limit) break\n\t\t\tlet matches = true\n\t\t\tfor (const predicate of this.#filters) {\n\t\t\t\tif (!predicate(row)) {\n\t\t\t\t\tmatches = false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!matches) continue\n\t\t\tif (matched < offset) {\n\t\t\t\tmatched += 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmatched += 1\n\t\t\tyielded += 1\n\t\t\tyield row\n\t\t}\n\t}\n\n\taggregate(operation: AggregateFunction, column: FieldPath): Promise<number | undefined> {\n\t\tif (this.#filters.length === 0) {\n\t\t\treturn this.#table.aggregate(operation, column, { conditions: this.#conditions })\n\t\t}\n\t\treturn this.#table\n\t\t\t.records({ conditions: this.#conditions })\n\t\t\t.then((fetched) => computeAggregate(this.#filtered(fetched), operation, column))\n\t}\n\n\tsum(column: FieldPath): Promise<number | undefined> {\n\t\treturn this.aggregate('sum', column)\n\t}\n\n\taverage(column: FieldPath): Promise<number | undefined> {\n\t\treturn this.aggregate('average', column)\n\t}\n\n\tminimum(column: FieldPath): Promise<number | undefined> {\n\t\treturn this.aggregate('minimum', column)\n\t}\n\n\tmaximum(column: FieldPath): Promise<number | undefined> {\n\t\treturn this.aggregate('maximum', column)\n\t}\n\n\t#clause(column: FieldPath, connector: Connector): ClauseInterface<T> {\n\t\treturn new Clause<T>(\n\t\t\t(condition) => {\n\t\t\t\tthis.#conditions.push(condition)\n\t\t\t\treturn this\n\t\t\t},\n\t\t\tcolumn,\n\t\t\tconnector,\n\t\t)\n\t}\n\n\t#filtered(rows: readonly T[]): readonly T[] {\n\t\tlet result = rows\n\t\tfor (const predicate of this.#filters) result = result.filter(predicate)\n\t\treturn result\n\t}\n\n\t#page(rows: readonly T[]): readonly T[] {\n\t\tconst offset = this.#offset ?? 0\n\t\tif (offset === 0 && this.#limit === undefined) return rows\n\t\treturn rows.slice(offset, this.#limit === undefined ? undefined : offset + this.#limit)\n\t}\n}\n","import type { ContractInterface, FieldPath, Guard } from '@orkestrel/contract'\nimport type { EmitterErrorHandler, EmitterHooks, EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tAggregateFunction,\n\tCriteria,\n\tCursorInterface,\n\tDriverInterface,\n\tKey,\n\tKeyFunction,\n\tQueryInterface,\n\tReadOptions,\n\tRow,\n\tTableEventMap,\n\tTableInterface,\n} from './types.js'\nimport { isArray, isRecord } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { DatabaseError } from './errors.js'\nimport {\n\tapplyCriteria,\n\tcheckAbort,\n\tcomputeAggregate,\n\textractKey,\n\tfilterRows,\n\tmatchesCriteria,\n} from './helpers.js'\nimport { Cursor } from './Cursor.js'\nimport { Query } from './Query.js'\n\n/**\n * A table — typed keyed CRUD plus fluent query and cursor access over a driver.\n *\n * @remarks\n * The table's contract is the load-bearing piece: writes go through `parse`\n * (coercing inputs and rejecting rows that don't fit with a `VALIDATION` throw),\n * reads come back through the contract guard (narrowing a stored {@link Row} to\n * the table's type — no assertion, AGENTS §1), and `contract` is exposed for\n * introspection and seeding. The driver only stores and scans; all querying is\n * the shared core engine in `helpers.ts`.\n *\n * @remarks\n * - **Observable (§13).** The owned {@link emitter} ({@link TableEventMap}) carries the\n * per-row mutation moments — `write` (set / add / update), `remove`, `clear` — for\n * fire-and-forget observers (cache invalidation, sync, an audit log), ALONGSIDE the\n * database-level lifecycle. Events carry the affected KEY only (no value payload, to\n * keep fan-out lean); reads / queries / counts are not emitted. Every event is emitted\n * directly, strictly AFTER the driver write / delete / clear completes; the emitter\n * isolates a listener throw and routes it to its `error` handler (the `error` option),\n * so a buggy observer can never corrupt a write or perturb a transaction.\n */\nexport class Table<T = Row> implements TableInterface<T> {\n\treadonly #ready: () => Promise<void>\n\treadonly #driver: DriverInterface\n\treadonly #name: string\n\treadonly #key: string\n\treadonly #contract: ContractInterface<T>\n\treadonly #guard: Guard<T>\n\treadonly #generate: KeyFunction | undefined\n\t// The PUSH observation surface (§13) — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into a write\n\t// or a transaction.\n\treadonly #emitter: Emitter<TableEventMap>\n\n\tconstructor(\n\t\tready: () => Promise<void>,\n\t\tdriver: DriverInterface,\n\t\tname: string,\n\t\tkey: string,\n\t\tcontract: ContractInterface<T>,\n\t\tgenerate?: KeyFunction,\n\t\ton?: EmitterHooks<TableEventMap>,\n\t\terror?: EmitterErrorHandler,\n\t) {\n\t\tthis.#ready = ready\n\t\tthis.#driver = driver\n\t\tthis.#name = name\n\t\tthis.#key = key\n\t\tthis.#contract = contract\n\t\tthis.#guard = contract.is\n\t\tthis.#generate = generate\n\t\tthis.#emitter = new Emitter<TableEventMap>({ on, error })\n\t}\n\n\tget emitter(): EmitterInterface<TableEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget name(): string {\n\t\treturn this.#name\n\t}\n\n\tget primary(): string {\n\t\treturn this.#key\n\t}\n\n\tget contract(): ContractInterface<T> {\n\t\treturn this.#contract\n\t}\n\n\tget(key: Key): Promise<T | undefined>\n\tget(keys: readonly Key[]): Promise<readonly (T | undefined)[]>\n\tasync get(keys: Key | readonly Key[]): Promise<(T | undefined) | readonly (T | undefined)[]> {\n\t\tawait this.#ready()\n\t\tif (isArray(keys)) return this.#each(keys, (key) => this.#read(key))\n\t\treturn this.#read(keys)\n\t}\n\n\tresolve(key: Key): Promise<T>\n\tresolve(keys: readonly Key[]): Promise<readonly T[]>\n\tasync resolve(keys: Key | readonly Key[]): Promise<T | readonly T[]> {\n\t\tawait this.#ready()\n\t\tif (isArray(keys)) return this.#each(keys, (key) => this.#resolveOne(key))\n\t\treturn this.#resolveOne(keys)\n\t}\n\n\thas(key: Key): Promise<boolean>\n\thas(keys: readonly Key[]): Promise<readonly boolean[]>\n\tasync has(keys: Key | readonly Key[]): Promise<boolean | readonly boolean[]> {\n\t\tawait this.#ready()\n\t\tif (isArray(keys)) return this.#each(keys, async (key) => (await this.#read(key)) !== undefined)\n\t\treturn (await this.#read(keys)) !== undefined\n\t}\n\n\tasync keys(): Promise<readonly Key[]> {\n\t\tawait this.#ready()\n\t\treturn this.#driver.keys(this.#name)\n\t}\n\n\tasync records(criteria?: Criteria, options?: ReadOptions): Promise<readonly T[]> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#ready()\n\t\t// Native filtered read when the backend offers one; else the engine over scan.\n\t\tconst native = await this.#driver.records?.(this.#name, criteria ?? {})\n\t\tconst source = native ?? applyCriteria(await this.#collect(), criteria)\n\t\tconst rows: T[] = []\n\t\tfor (const row of source) {\n\t\t\tif (this.#guard(row)) rows.push(row)\n\t\t}\n\t\treturn rows\n\t}\n\n\t/**\n\t * Count rows matching `criteria`'s conditions.\n\t *\n\t * @remarks\n\t * Unlike {@link records}, which narrows every row through the table's\n\t * contract guard before returning it, `count` operates on STORED rows\n\t * WITHOUT that guard (both the native `driver.count` hook and the\n\t * `filterRows`-over-`#collect()` fallback count raw storage) — so it can\n\t * exceed `(await records(criteria)).length` when storage holds rows that\n\t * no longer conform to the table's contract (legacy or migrated data).\n\t *\n\t * @param criteria - Optional conditions to filter by (paging is ignored)\n\t * @param options - `{ signal }` to abort\n\t * @returns The count of matching stored rows\n\t */\n\tasync count(criteria?: Criteria, options?: ReadOptions): Promise<number> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#ready()\n\t\t// Counts ignore paging — pass conditions only, so native and scan agree.\n\t\tconst conditions = criteria?.conditions\n\t\tconst native = await this.#driver.count?.(this.#name, conditions ? { conditions } : {})\n\t\tif (native !== undefined) return native\n\t\treturn filterRows(await this.#collect(), criteria?.conditions ?? []).length\n\t}\n\n\t/**\n\t * Compute an aggregate over `column` across rows matching `criteria`'s\n\t * conditions.\n\t *\n\t * @remarks\n\t * Like {@link count}, `aggregate` operates on STORED rows WITHOUT the\n\t * contract guard {@link records} / {@link scan} apply — a non-conforming\n\t * stored row still contributes to the computed aggregate when it matches\n\t * the conditions, even though it would never appear in `records()`'s\n\t * output.\n\t *\n\t * @param operation - The aggregate to compute\n\t * @param column - The column to aggregate\n\t * @param criteria - Optional conditions to filter by (paging is ignored)\n\t * @param options - `{ signal }` to abort\n\t * @returns The aggregate value, or `undefined` when undefined for the inputs\n\t */\n\tasync aggregate(\n\t\toperation: AggregateFunction,\n\t\tcolumn: FieldPath,\n\t\tcriteria?: Criteria,\n\t\toptions?: ReadOptions,\n\t): Promise<number | undefined> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#ready()\n\t\t// Aggregate over filtered (not paged) rows — native hook, native records, or scan.\n\t\tconst conditions = criteria?.conditions\n\t\tconst filter: Criteria = conditions ? { conditions } : {}\n\t\t// `?.()` is `undefined` only when the driver lacks the method; a present\n\t\t// hook returns a Promise (whose resolved value may itself be `undefined`).\n\t\tconst native = this.#driver.aggregate?.(this.#name, operation, column, filter)\n\t\tif (native !== undefined) return native\n\t\tconst rows = await this.#driver.records?.(this.#name, filter)\n\t\tconst matched = rows ?? filterRows(await this.#collect(), criteria?.conditions ?? [])\n\t\treturn computeAggregate(matched, operation, column)\n\t}\n\n\t/**\n\t * Stream the table's rows matching `criteria`, applying offset/limit paging.\n\t *\n\t * @remarks\n\t * `criteria.limit` counts rows that pass BOTH the criteria conditions AND the\n\t * table's contract guard (a stored row that fails the guard is skipped and\n\t * does not count toward `limit`) — this can differ from {@link records}'s\n\t * `limit`, which a driver's optional native `records` hook applies BEFORE\n\t * the contract guard runs, when storage holds rows that no longer conform\n\t * to the table's contract.\n\t *\n\t * @param criteria - Optional conditions plus offset/limit paging\n\t * @param options - `{ signal }` to abort mid-stream\n\t * @returns An async iterable of matching, guard-conforming rows\n\t */\n\tasync *scan(criteria?: Criteria, options?: ReadOptions): AsyncIterable<T> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#ready()\n\t\tif (this.#driver.stream !== undefined) {\n\t\t\tfor await (const row of this.#driver.stream(this.#name, criteria ?? {})) {\n\t\t\t\tcheckAbort(options?.signal)\n\t\t\t\tconst narrowed = this.#cast(row)\n\t\t\t\tif (narrowed !== undefined) yield narrowed\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tconst conditions = criteria?.conditions\n\t\tconst offset = criteria?.offset ?? 0\n\t\tconst limit = criteria?.limit\n\t\tlet matched = 0\n\t\tlet yielded = 0\n\t\tfor await (const row of this.#driver.scan(this.#name)) {\n\t\t\tcheckAbort(options?.signal)\n\t\t\tif (limit !== undefined && yielded >= limit) break\n\t\t\tif (conditions !== undefined && conditions.length > 0 && !matchesCriteria(row, conditions)) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (matched < offset) {\n\t\t\t\tmatched += 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmatched += 1\n\t\t\tconst narrowed = this.#cast(row)\n\t\t\tif (narrowed !== undefined) {\n\t\t\t\tyielded += 1\n\t\t\t\tyield narrowed\n\t\t\t}\n\t\t}\n\t}\n\n\tset(row: T, options?: ReadOptions): Promise<Key>\n\tset(rows: readonly T[], options?: ReadOptions): Promise<readonly Key[]>\n\tasync set(rows: T | readonly T[], options?: ReadOptions): Promise<Key | readonly Key[]> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#ready()\n\t\tif (isArray(rows)) return this.#each(rows, (row) => this.#put(row, false), options?.signal)\n\t\treturn this.#put(rows, false)\n\t}\n\n\tadd(row: T, options?: ReadOptions): Promise<Key>\n\tadd(rows: readonly T[], options?: ReadOptions): Promise<readonly Key[]>\n\tasync add(rows: T | readonly T[], options?: ReadOptions): Promise<Key | readonly Key[]> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#ready()\n\t\tif (isArray(rows)) return this.#each(rows, (row) => this.#put(row, true), options?.signal)\n\t\treturn this.#put(rows, true)\n\t}\n\n\tupdate(key: Key, changes: Partial<T>, options?: ReadOptions): Promise<boolean>\n\tupdate(\n\t\tkeys: readonly Key[],\n\t\tchanges: Partial<T>,\n\t\toptions?: ReadOptions,\n\t): Promise<readonly boolean[]>\n\tasync update(\n\t\tkeys: Key | readonly Key[],\n\t\tchanges: Partial<T>,\n\t\toptions?: ReadOptions,\n\t): Promise<boolean | readonly boolean[]> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#ready()\n\t\tif (isArray(keys)) {\n\t\t\treturn this.#each(keys, (key) => this.#updateOne(key, changes), options?.signal)\n\t\t}\n\t\treturn this.#updateOne(keys, changes)\n\t}\n\n\tremove(key: Key, options?: ReadOptions): Promise<boolean>\n\tremove(keys: readonly Key[], options?: ReadOptions): Promise<readonly boolean[]>\n\tasync remove(\n\t\tkeys: Key | readonly Key[],\n\t\toptions?: ReadOptions,\n\t): Promise<boolean | readonly boolean[]> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#ready()\n\t\tif (isArray(keys)) return this.#each(keys, (key) => this.#delete(key), options?.signal)\n\t\treturn this.#delete(keys)\n\t}\n\n\tasync clear(): Promise<void> {\n\t\tawait this.#ready()\n\t\tawait this.#driver.clear(this.#name)\n\t\t// Observe the cleared table — AFTER the driver emptied it, so a swallowed listener\n\t\t// throw can never alter the clear (no value payload — `clear` is a pure signal).\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\tquery(): QueryInterface<T> {\n\t\treturn new Query<T>(this)\n\t}\n\n\tasync cursor(): Promise<CursorInterface<T>> {\n\t\tawait this.#ready()\n\t\tconst cursor = new Cursor<T>(this, await this.#driver.keys(this.#name))\n\t\tawait cursor.next()\n\t\treturn cursor\n\t}\n\n\t// Run a single-item operation across each item in order — the batch overloads\n\t// loop one item at a time (sequential, so writes never race) rather than\n\t// pushing batch logic into the thin driver. `signal` (write batches only) is\n\t// checked before EVERY item, so an abort mid-batch stops before the next\n\t// item runs — already-applied items stay applied (no rollback).\n\tasync #each<I, R>(\n\t\titems: readonly I[],\n\t\toperation: (item: I) => Promise<R>,\n\t\tsignal?: AbortSignal,\n\t): Promise<readonly R[]> {\n\t\tconst results: R[] = []\n\t\tfor (const item of items) {\n\t\t\tcheckAbort(signal)\n\t\t\tresults.push(await operation(item))\n\t\t}\n\t\treturn results\n\t}\n\n\t// Read and narrow one row (assumes the driver is connected).\n\tasync #read(key: Key): Promise<T | undefined> {\n\t\treturn this.#cast(await this.#driver.read(this.#name, key))\n\t}\n\n\t// Read one row or throw NOT_FOUND.\n\tasync #resolveOne(key: Key): Promise<T> {\n\t\tconst row = await this.#read(key)\n\t\tif (row === undefined) {\n\t\t\tthrow new DatabaseError('NOT_FOUND', `No row '${key}' in table '${this.#name}'`, {\n\t\t\t\ttable: this.#name,\n\t\t\t\tkey,\n\t\t\t})\n\t\t}\n\t\treturn row\n\t}\n\n\t// Coerce/validate and write one row; `exclusive` makes it an insert (CONFLICT on a dup).\n\tasync #put(row: T, exclusive: boolean): Promise<Key> {\n\t\tconst validated = this.#validate(this.#prepare(row))\n\t\tconst key = this.#resolveKey(validated)\n\t\tif (exclusive && (await this.#driver.read(this.#name, key)) !== undefined) {\n\t\t\tthrow new DatabaseError('CONFLICT', `Row '${key}' already exists in table '${this.#name}'`, {\n\t\t\t\ttable: this.#name,\n\t\t\t\tkey,\n\t\t\t})\n\t\t}\n\t\tawait this.#driver.write(this.#name, key, validated)\n\t\t// Observe the written row — AFTER the driver write succeeded; carries the KEY only\n\t\t// (set / add / update all emit one `write`, the consumer re-reads if it needs the\n\t\t// value). A swallowed listener throw can't perturb the write (or its transaction).\n\t\tthis.#emitter.emit('write', key)\n\t\treturn key\n\t}\n\n\t// Merge changes into one existing row and re-validate; `false` when it is absent.\n\tasync #updateOne(key: Key, changes: Partial<T>): Promise<boolean> {\n\t\tconst existing = await this.#driver.read(this.#name, key)\n\t\tif (existing === undefined) return false\n\t\tawait this.#driver.write(this.#name, key, this.#validate(Object.assign({}, existing, changes)))\n\t\t// Observe the updated row — AFTER the driver write, and only on the path that wrote\n\t\t// (an absent key returned `false` above, emitting nothing).\n\t\tthis.#emitter.emit('write', key)\n\t\treturn true\n\t}\n\n\t// Delete one row, emitting `remove` only when a row was actually removed (a delete of\n\t// an absent key returns `false` and emits nothing) — AFTER the driver delete completes.\n\tasync #delete(key: Key): Promise<boolean> {\n\t\tconst removed = await this.#driver.delete(this.#name, key)\n\t\tif (removed) this.#emitter.emit('remove', key)\n\t\treturn removed\n\t}\n\n\t// Gather the table's full contents from the driver's ordered scan.\n\tasync #collect(): Promise<readonly Row[]> {\n\t\tconst rows: Row[] = []\n\t\tfor await (const row of this.#driver.scan(this.#name)) rows.push(row)\n\t\treturn rows\n\t}\n\n\t// Copy the input and assign a generated key when the key column is empty.\n\t#prepare(row: T): Row {\n\t\tif (!isRecord(row)) {\n\t\t\tthrow new DatabaseError('VALIDATION', `Row for table '${this.#name}' is not a record`, {\n\t\t\t\ttable: this.#name,\n\t\t\t})\n\t\t}\n\t\tconst prepared: Row = { ...row }\n\t\tif (prepared[this.#key] === undefined) {\n\t\t\tif (this.#generate === undefined) {\n\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t'VALIDATION',\n\t\t\t\t\t`Row for table '${this.#name}' is missing its key column '${this.#key}' and no key factory was provided`,\n\t\t\t\t\t{ table: this.#name, column: this.#key },\n\t\t\t\t)\n\t\t\t}\n\t\t\tprepared[this.#key] = this.#generate()\n\t\t}\n\t\treturn prepared\n\t}\n\n\t// Coerce *and* validate through the contract in one step: the contract's `parse`\n\t// now coerces types (`'36'` → `36`) AND enforces every leaf refinement (`min` /\n\t// `max` / `pattern`), so a non-`undefined` result already satisfies the guard\n\t// (AGENTS §14 parse↔guard soundness) — no separate `is` re-check is needed.\n\t// `isRecord` is kept solely to narrow the parsed `T` back to a storable `Row`\n\t// without an assertion (AGENTS §1); a table contract is always an object shape,\n\t// so it never rejects a genuinely-parsed row.\n\t#validate(row: Row): Row {\n\t\tconst parsed = this.#contract.parse(row)\n\t\tif (parsed === undefined || !isRecord(parsed)) {\n\t\t\tthrow new DatabaseError('VALIDATION', `Row failed the '${this.#name}' contract`, {\n\t\t\t\ttable: this.#name,\n\t\t\t\trow,\n\t\t\t})\n\t\t}\n\t\treturn parsed\n\t}\n\n\t#resolveKey(row: Row): Key {\n\t\tconst key = extractKey(row, this.#key)\n\t\tif (key === undefined) {\n\t\t\tthrow new DatabaseError('VALIDATION', `Row has no usable key in column '${this.#key}'`, {\n\t\t\t\ttable: this.#name,\n\t\t\t\tcolumn: this.#key,\n\t\t\t})\n\t\t}\n\t\treturn key\n\t}\n\n\t// Narrow a stored row to the table's type through the contract guard.\n\t#cast(row: Row | undefined): T | undefined {\n\t\treturn row !== undefined && this.#guard(row) ? row : undefined\n\t}\n}\n","import type { ContractInterface } from '@orkestrel/contract'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tDatabaseEventMap,\n\tDatabaseInterface,\n\tDatabaseOptions,\n\tDatabaseStatus,\n\tDriverInterface,\n\tDriverMeta,\n\tKeyFunction,\n\tMigration,\n\tReadOptions,\n\tRowOf,\n\tTableExport,\n\tTableIndexes,\n\tTableInterface,\n\tTableKeys,\n\tTableSchema,\n\tTablesShape,\n} from './types.js'\nimport { compileSchema, createContract, objectShape } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { DEFAULT_PRIMARY } from './constants.js'\nimport { DatabaseError } from './errors.js'\nimport { checkAbort, planMigration, shapeToColumnType } from './helpers.js'\nimport { Table } from './Table.js'\n\n/**\n * A database — the ergonomic entry point over a {@link DriverInterface}.\n *\n * @remarks\n * Owns the driver and a `tables` shape map, connecting the driver lazily on first\n * use so a freshly created database is immediately usable. `table(name)` returns\n * a table typed by that table's shape `Infer`. `import` registers more tables and\n * returns a database re-typed with them over the **same** driver and storage;\n * `export` emits a portable {@link TableExport} per table. `transaction` snapshots\n * the driver, runs the scope, and rolls every table back if it throws — an\n * optimistic model that works uniformly across backends rather than reconciling\n * SQL's and IndexedDB's incompatible native transactions.\n *\n * @remarks\n * - **Versioned (optional).** When {@link DatabaseOptions.version} is set and the driver\n * implements both {@link DriverInterface.meta} and {@link DriverInterface.stamp},\n * `open()` reconciles the driver's persisted {@link DriverMeta} against the declared\n * version INSIDE the same lazy-connect chain, AFTER the `open` event fires — see\n * {@link DatabaseOptions.version} for the full reconciliation contract.\n * - **Observable (§13).** The owned {@link emitter} ({@link DatabaseEventMap}) carries the\n * connection + transaction lifecycle — `open` / `close` / `transaction` / `commit` /\n * `rollback` — for fire-and-forget observers, ALONGSIDE each table's per-row events. Every\n * event is emitted directly, strictly AFTER the relevant transition: `commit` only after\n * the scope succeeds, `rollback` only after every table is restored. The `rollback` emit\n * OBSERVES the propagated error — it never swallows it (the original throw propagates\n * exactly as before). The emitter isolates a listener throw and routes it to its `error`\n * handler (the `error` option), so observation can never reorder, throw into, or corrupt\n * the snapshot / commit / rollback flow.\n */\nexport class Database<T extends TablesShape = TablesShape> implements DatabaseInterface<T> {\n\treadonly #driver: DriverInterface\n\treadonly #tables: T\n\treadonly #keys: TableKeys\n\treadonly #indexes: TableIndexes\n\treadonly #name: string\n\treadonly #generate: KeyFunction | undefined\n\treadonly #version: number | undefined\n\t// The PUSH observation surface (§13) — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into the\n\t// transaction flow.\n\treadonly #emitter: Emitter<DatabaseEventMap>\n\t#status: DatabaseStatus = 'idle'\n\t#ready: Promise<void> | undefined\n\n\tconstructor(options: DatabaseOptions<T>) {\n\t\tthis.#driver = options.driver\n\t\tthis.#tables = options.tables\n\t\tthis.#keys = options.keys ?? {}\n\t\tthis.#indexes = options.indexes ?? {}\n\t\tthis.#name = options.name ?? 'database'\n\t\tthis.#generate = options.key\n\t\tthis.#version = options.version\n\t\tthis.#emitter = new Emitter<DatabaseEventMap>({ on: options.on, error: options.error })\n\t}\n\n\tget emitter(): EmitterInterface<DatabaseEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget name(): string {\n\t\treturn this.#name\n\t}\n\n\tget status(): DatabaseStatus {\n\t\treturn this.#status\n\t}\n\n\ttable<K extends keyof T & string>(name: K): TableInterface<RowOf<T[K]>> {\n\t\tif (this.#status === 'closed') {\n\t\t\tthrow new DatabaseError('CLOSED', `Database '${this.#name}' is closed`, { name: this.#name })\n\t\t}\n\t\t// A table row is always an object, so compile its columns into a typed contract.\n\t\t// Contract 0.0.4's non-distributive inference resolves the open columns union\n\t\t// directly, so no seam is needed to relate the compiled contract to RowOf.\n\t\treturn this.#build(name, this.#key(name), createContract(objectShape(this.#tables[name])))\n\t}\n\n\timport<U extends TablesShape>(tables: U, keys?: TableKeys): DatabaseInterface<U> {\n\t\treturn this.#spawn(tables, { ...this.#keys, ...keys })\n\t}\n\n\texport(): Readonly<Record<string, TableExport>> {\n\t\tconst result: Record<string, TableExport> = {}\n\t\tfor (const name of Object.keys(this.#tables)) {\n\t\t\tconst columns = this.#tables[name]\n\t\t\t// `compileSchema` (not `createContract`) emits the JSON Schema without\n\t\t\t// instantiating `Infer` over the broad shape — which would trip TS's\n\t\t\t// instantiation-depth guard here, where the columns are the open union.\n\t\t\tresult[name] = { key: this.#key(name), columns, schema: compileSchema(objectShape(columns)) }\n\t\t}\n\t\treturn result\n\t}\n\n\tasync open(): Promise<void> {\n\t\tawait this.#connect()\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.#status = 'closed'\n\t\tthis.#ready = undefined\n\t\tawait this.#driver.close()\n\t\t// Observe the close — AFTER the driver released, so a swallowed listener throw can't\n\t\t// perturb the teardown (a pure signal — no payload).\n\t\tthis.#emitter.emit('close')\n\t}\n\n\t/**\n\t * Run `scope` transactionally: commit its writes on success, roll every table\n\t * back if it throws.\n\t *\n\t * @remarks\n\t * When the driver implements the optional native {@link DriverInterface.transaction}\n\t * hook, that native `commit` / `rollback` handle drives the transaction; otherwise\n\t * the universal snapshot floor (`driver.snapshot()`) runs unchanged. Either path\n\t * emits the same `transaction` / `commit` / `rollback` lifecycle (AGENTS §13).\n\t * `options.signal` is checked ONCE at entry, before connecting or starting any\n\t * transactional work — an already-aborted signal throws `ABORTED` and neither the\n\t * native hook nor the snapshot floor is invoked. Nesting is unguarded and\n\t * unsupported exactly as before: this is a single-writer model, not reentrant.\n\t * On the native path, a `scope` throw rolls back via the native handle; a\n\t * native `commit` failure propagates as-is with no rollback attempt — the\n\t * engine owns transaction state after a failed COMMIT.\n\t *\n\t * @param scope - The transactional work to run\n\t * @param options - `{ signal }` to abort before the transaction starts\n\t * @returns The scope's resolved value\n\t * @throws An `ABORTED` {@link DatabaseError} when `options.signal` has already fired\n\t */\n\tasync transaction<R>(scope: () => Promise<R>, options?: ReadOptions): Promise<R> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#connect()\n\t\tconst native = await this.#driver.transaction?.()\n\t\tif (native !== undefined) {\n\t\t\t// Observe the scope beginning — AFTER the native BEGIN, mirroring the snapshot\n\t\t\t// path's `transaction` emit placement (after the floor is laid, before the scope runs).\n\t\t\tthis.#emitter.emit('transaction')\n\t\t\tlet value: R\n\t\t\ttry {\n\t\t\t\tvalue = await scope()\n\t\t\t} catch (error) {\n\t\t\t\t// The scope threw: roll back via the native handle FIRST, then observe —\n\t\t\t\t// mirrors the snapshot path exactly. A rollback throw is NOT caught here (the\n\t\t\t\t// snapshot path likewise lets a failing restore propagate uncaught), so it\n\t\t\t\t// would replace the original error as the rejection.\n\t\t\t\tawait native.rollback()\n\t\t\t\tthis.#emitter.emit('rollback', error)\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\t// The scope succeeded: commit OUTSIDE the try — a failed commit propagates\n\t\t\t// as-is, with no rollback attempt. The engine owns transaction state after a\n\t\t\t// failed COMMIT; invoking rollback here could mask the commit error with a\n\t\t\t// rollback error, or roll back a commit the engine actually applied.\n\t\t\tawait native.commit()\n\t\t\t// Observe the successful commit — AFTER the native commit resolved, mirroring\n\t\t\t// the snapshot path's emit-after-transition contract.\n\t\t\tthis.#emitter.emit('commit')\n\t\t\treturn value\n\t\t}\n\t\tconst rollback = await this.#driver.snapshot()\n\t\t// Observe the scope beginning — AFTER the store was snapshotted and BEFORE the scope\n\t\t// runs, so a swallowed listener throw can't perturb the snapshot the scope builds on.\n\t\tthis.#emitter.emit('transaction')\n\t\ttry {\n\t\t\tconst value = await scope()\n\t\t\t// Observe the successful commit — AFTER the scope resolved with no throw, so the\n\t\t\t// transaction has already committed (there is nothing to roll back); the emit only\n\t\t\t// OBSERVES it. NEVER emitted on the throw path below.\n\t\t\tthis.#emitter.emit('commit')\n\t\t\treturn value\n\t\t} catch (error) {\n\t\t\t// The scope threw: roll every table back FIRST, then observe — the `rollback` emit\n\t\t\t// fires strictly AFTER the restore completes, and OBSERVES the propagated error (it\n\t\t\t// carries the error but never swallows it; the original throw still propagates,\n\t\t\t// exactly as before — a swallowed listener throw can't suppress or reorder it).\n\t\t\tawait rollback()\n\t\t\tthis.#emitter.emit('rollback', error)\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Diff `deployed` against this database's declared schema and apply the\n\t * resulting plan through the driver's optional `migrate` hook.\n\t *\n\t * @param deployed - The schema currently deployed, as {@link TableSchema}s\n\t * @param options - `{ signal }` to abort before the migration starts\n\t * @returns The applied {@link Migration} plan\n\t * @throws A `MIGRATION` {@link DatabaseError} when the driver does not\n\t * implement `migrate`, or when a step references an unknown table\n\t * (propagated from the driver)\n\t * @throws An `ABORTED` {@link DatabaseError} when `options.signal` has\n\t * already fired at entry\n\t */\n\tasync migrate(deployed: readonly TableSchema[], options?: ReadOptions): Promise<Migration> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#connect()\n\t\tconst plan = planMigration(deployed, this.#schema())\n\t\tif (this.#driver.migrate === undefined) {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'MIGRATION',\n\t\t\t\t`Database '${this.#name}' driver does not support migration`,\n\t\t\t\t{\n\t\t\t\t\tname: this.#name,\n\t\t\t\t},\n\t\t\t)\n\t\t}\n\t\tawait this.#apply(plan)\n\t\treturn plan\n\t}\n\n\t// Construct a table over an opaque row type `R`, so the deep `Infer<T[K]>` of\n\t// `table` is never expanded structurally here (it would trip TS's\n\t// instantiation-depth guard — the reason `createContract` keeps its impl untyped).\n\t#build<R>(name: string, key: string, contract: ContractInterface<R>): TableInterface<R> {\n\t\treturn new Table(() => this.#connect(), this.#driver, name, key, contract, this.#generate)\n\t}\n\n\t// Construct a sibling view over an opaque table map `X` (sharing the driver),\n\t// so the deep `Infer<X[K]>` of the result's `table` is not expanded\n\t// structurally here — the same instantiation-depth guard `#build` sidesteps.\n\t#spawn<X extends TablesShape>(tables: X, keys: TableKeys): DatabaseInterface<X> {\n\t\treturn new Database({\n\t\t\tdriver: this.#driver,\n\t\t\ttables,\n\t\t\tkeys,\n\t\t\tname: this.#name,\n\t\t\t...(this.#generate === undefined ? {} : { key: this.#generate }),\n\t\t})\n\t}\n\n\t#key(name: string): string {\n\t\treturn this.#keys[name] ?? DEFAULT_PRIMARY\n\t}\n\n\t// Derive each table's backend-agnostic TableSchema from its contract columns,\n\t// primary key, and declared indexes — what every driver's `open` receives.\n\t#schema(): readonly TableSchema[] {\n\t\treturn Object.keys(this.#tables).map((name) => {\n\t\t\tconst columns = this.#tables[name]\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\tprimary: this.#key(name),\n\t\t\t\tcolumns: Object.keys(columns).map((column) => {\n\t\t\t\t\tconst shape = columns[column]\n\t\t\t\t\treturn {\n\t\t\t\t\t\tname: column,\n\t\t\t\t\t\ttype: shapeToColumnType(shape),\n\t\t\t\t\t\tnullable: shape.type === 'optional' || shape.type === 'nullable',\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t\tindexes: this.#indexes[name] ?? [],\n\t\t\t}\n\t\t})\n\t}\n\n\t// Open the driver once, lazily; every table operation awaits the same promise. The\n\t// `open` event fires from the one-time `.then` (so it observes the actual connect, not\n\t// each cached re-await) — AFTER the driver opened and the status flipped. Version\n\t// reconciliation (`#reconcile`) runs INSIDE this same one-time chain, AFTER the `open`\n\t// emit, so `await db.open()` (and every cached re-await) resolves only once\n\t// reconciliation has settled. A reconnect after `close()` (which clears `#ready`)\n\t// re-runs this and emits `open` again.\n\t#connect(): Promise<void> {\n\t\tif (this.#status === 'closed') {\n\t\t\tthrow new DatabaseError('CLOSED', `Database '${this.#name}' is closed`, { name: this.#name })\n\t\t}\n\t\tif (this.#ready === undefined) {\n\t\t\tthis.#ready = this.#driver.open(this.#schema()).then(async () => {\n\t\t\t\tif (this.#status === 'idle') this.#status = 'open'\n\t\t\t\tthis.#emitter.emit('open')\n\t\t\t\tawait this.#reconcile()\n\t\t\t})\n\t\t}\n\t\treturn this.#ready\n\t}\n\n\t// Reconcile the driver's persisted DriverMeta against the declared `#version` (AGENTS\n\t// §13 emits AFTER the transition). Skips silently when versioning is not configured\n\t// (no `#version`, or the driver implements neither `meta` nor `stamp`). A fresh store\n\t// (`meta()` undefined) has nothing to diff against, so it just stamps for next time. A\n\t// stored version newer than declared is unrecoverable here — throws MIGRATION. A stored\n\t// version older than declared computes and applies the upgrade plan (throwing MIGRATION\n\t// when the plan is non-empty and the driver lacks `migrate`), then stamps and emits.\n\tasync #reconcile(): Promise<void> {\n\t\tif (this.#version === undefined || this.#driver.meta === undefined) return\n\t\tconst declared = this.#schema()\n\t\tconst meta = await this.#driver.meta()\n\t\tif (meta === undefined) {\n\t\t\tawait this.#stamp()\n\t\t\treturn\n\t\t}\n\t\tif (meta.version > this.#version) {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'MIGRATION',\n\t\t\t\t`Database '${this.#name}' store version ${meta.version} is newer than declared version ${this.#version}`,\n\t\t\t\t{ name: this.#name, stored: meta.version, declared: this.#version },\n\t\t\t)\n\t\t}\n\t\tif (meta.version < this.#version) {\n\t\t\tconst plan = planMigration(meta.schema, declared, meta.version, this.#version)\n\t\t\tif (plan.steps.length > 0 && this.#driver.migrate === undefined) {\n\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t'MIGRATION',\n\t\t\t\t\t`Database '${this.#name}' driver does not support migration`,\n\t\t\t\t\t{ name: this.#name, stored: meta.version, declared: this.#version },\n\t\t\t\t)\n\t\t\t}\n\t\t\tawait this.#apply(plan)\n\t\t}\n\t}\n\n\t// Apply `plan` through the driver's optional `migrate` hook and persist the new meta\n\t// as one unit — the shared orchestration behind both `#reconcile`'s upgrade branch and\n\t// the public `migrate()`. WHEN the driver implements the optional native `transaction`\n\t// hook, the migrate + stamp pair commits or rolls back atomically through that handle:\n\t// a mid-plan `migrate` failure, or a failing `stamp`, rolls back cleanly, so the store\n\t// never ends up with the new data under the OLD meta (which would otherwise re-trigger\n\t// the same non-idempotent plan on the next `open()`). WITHOUT the hook, `migrate` then\n\t// `stamp` run sequentially with a small window between them (documented on\n\t// {@link DatabaseOptions.version}). Either path applies, stamps, then emits `migrate`\n\t// strictly AFTER the full transition (AGENTS §13).\n\tasync #apply(plan: Migration): Promise<void> {\n\t\tconst native = await this.#driver.transaction?.()\n\t\tif (native !== undefined) {\n\t\t\ttry {\n\t\t\t\tawait this.#driver.migrate?.(plan)\n\t\t\t\tawait this.#stamp()\n\t\t\t} catch (error) {\n\t\t\t\tawait native.rollback()\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\tawait native.commit()\n\t\t\tthis.#emitter.emit('migrate', plan)\n\t\t\treturn\n\t\t}\n\t\tawait this.#driver.migrate?.(plan)\n\t\tawait this.#stamp()\n\t\tthis.#emitter.emit('migrate', plan)\n\t}\n\n\t// Persist the current declared { version, schema } via the driver's optional `stamp` —\n\t// a no-op when versioning is not configured (no `#version`, or no `stamp` hook).\n\tasync #stamp(): Promise<void> {\n\t\tif (this.#version === undefined || this.#driver.stamp === undefined) return\n\t\tconst meta: DriverMeta = { version: this.#version, schema: this.#schema() }\n\t\tawait this.#driver.stamp(meta)\n\t}\n}\n","import type {\n\tCriteria,\n\tDriverInterface,\n\tDriverMeta,\n\tKey,\n\tMigration,\n\tRow,\n\tTableSchema,\n} from '../types.js'\nimport { DatabaseError } from '../errors.js'\nimport { compareValues, matchesCriteria, migrateRows } from '../helpers.js'\n\n/**\n * The reference {@link DriverInterface} — nested maps, no I/O.\n *\n * @remarks\n * The in-between made concrete: it runs identically in a browser or on a server,\n * so it is the storage behind tests, ephemeral caches, and any code that wants\n * the database API without a persistent backend. Rows are DEEP-copied (via\n * `structuredClone`) in and out — at `write`, `read`, `scan`, `stream`, and both\n * snapshot capture and restore — so a caller mutating a nested field of an input\n * row, a returned row, or a row mutated in place between snapshot and rollback\n * can never perturb stored state (AGENTS §11); a shallow `{ ...row }` spread\n * would still share nested object/array references. `snapshot`\n * clones every table to give transactions an exact rollback point. `scan` and\n * `keys` yield in key order — sorted by the core {@link compareValues} total\n * order, the same contract the SQLite (`ORDER BY`) and IndexedDB (key-ordered\n * reads) backends honor, so an unordered read agrees across every backend rather\n * than leaking Map insertion order. A persistent backend (IndexedDB, SQLite)\n * implements the same nine methods over real storage.\n */\nexport class MemoryDriver implements DriverInterface {\n\treadonly #tables = new Map<string, Map<Key, Row>>()\n\t#meta: DriverMeta | undefined\n\n\tasync open(schema: readonly TableSchema[]): Promise<void> {\n\t\tfor (const table of schema) {\n\t\t\tif (!this.#tables.has(table.name)) this.#tables.set(table.name, new Map())\n\t\t}\n\t}\n\n\tasync close(): Promise<void> {}\n\n\tasync read(table: string, key: Key): Promise<Row | undefined> {\n\t\tconst row = this.#store(table).get(key)\n\t\treturn row === undefined ? undefined : structuredClone(row)\n\t}\n\n\tasync write(table: string, key: Key, row: Row): Promise<void> {\n\t\tthis.#store(table).set(key, structuredClone(row))\n\t}\n\n\tasync delete(table: string, key: Key): Promise<boolean> {\n\t\treturn this.#store(table).delete(key)\n\t}\n\n\tasync keys(table: string): Promise<readonly Key[]> {\n\t\treturn this.#ordered(table)\n\t}\n\n\tasync *scan(table: string): AsyncIterable<Row> {\n\t\tconst store = this.#store(table)\n\t\tfor (const key of this.#ordered(table)) {\n\t\t\tconst row = store.get(key)\n\t\t\tif (row !== undefined) yield structuredClone(row)\n\t\t}\n\t}\n\n\t/**\n\t * Natively filtered lazy iteration — the {@link DriverInterface.stream} hook.\n\t *\n\t * @remarks\n\t * Iterates the table's keys in the same key order `scan` and `keys` yield\n\t * (sorted by {@link compareValues}), testing each row against\n\t * `criteria.conditions` (via {@link matchesCriteria}) before counting it\n\t * toward `offset` / `limit`. Both are applied lazily as matches are found —\n\t * `offset` matches are skipped without being yielded, and iteration stops the\n\t * instant `limit` yields have been produced, so a large table is never fully\n\t * walked for a small page. `criteria.order` is IGNORED (the same contract as\n\t * `TableInterface.scan` and `QueryInterface.stream`): streaming yields key\n\t * order, sorted output is `records()`'s job. Rows yield copy-out (AGENTS\n\t * §11), and an unknown table mirrors `scan`'s empty-yield behavior.\n\t *\n\t * @param table - The table to stream\n\t * @param criteria - The filter / offset / limit to apply lazily\n\t *\n\t * @example\n\t * ```ts\n\t * for await (const row of driver.stream('users', { conditions, limit: 10 })) {\n\t * // one matched row at a time, in key order\n\t * }\n\t * ```\n\t */\n\tasync *stream(table: string, criteria: Criteria): AsyncIterable<Row> {\n\t\tconst store = this.#store(table)\n\t\tconst conditions = criteria.conditions\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 (const key of this.#ordered(table)) {\n\t\t\tif (limit !== undefined && yielded >= limit) return\n\t\t\tconst row = store.get(key)\n\t\t\tif (row === undefined) continue\n\t\t\tif (conditions !== undefined && conditions.length > 0 && !matchesCriteria(row, conditions)) {\n\t\t\t\tcontinue\n\t\t\t}\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 structuredClone(row)\n\t\t\tyielded += 1\n\t\t}\n\t}\n\n\tasync clear(table: string): Promise<void> {\n\t\tthis.#store(table).clear()\n\t}\n\n\t/**\n\t * Capture the current state and return a thunk that rolls back to it.\n\t *\n\t * @remarks\n\t * `tables` omitted clones and restores the WHOLE store, byte-identical to the\n\t * prior whole-store behavior. `tables` provided clones ONLY the named tables,\n\t * and the returned thunk restores ONLY those — every other table keeps\n\t * whatever it was mutated to after the snapshot was taken.\n\t *\n\t * @param tables - The table names to scope the snapshot to; omitted captures every table\n\t * @returns A thunk that restores the captured tables\n\t */\n\tasync snapshot(tables?: readonly string[]): Promise<() => Promise<void>> {\n\t\tif (tables === undefined) {\n\t\t\tconst copy = new Map<string, Map<Key, Row>>()\n\t\t\tfor (const [name, store] of this.#tables) {\n\t\t\t\tconst cloned = new Map<Key, Row>()\n\t\t\t\tfor (const [key, row] of store) cloned.set(key, structuredClone(row))\n\t\t\t\tcopy.set(name, cloned)\n\t\t\t}\n\t\t\treturn async () => {\n\t\t\t\tthis.#tables.clear()\n\t\t\t\tfor (const [name, store] of copy) {\n\t\t\t\t\tconst restored = new Map<Key, Row>()\n\t\t\t\t\tfor (const [key, row] of store) restored.set(key, structuredClone(row))\n\t\t\t\t\tthis.#tables.set(name, restored)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst copy = new Map<string, Map<Key, Row>>()\n\t\tfor (const name of tables) {\n\t\t\tconst store = this.#tables.get(name)\n\t\t\tif (store === undefined) continue\n\t\t\tconst cloned = new Map<Key, Row>()\n\t\t\tfor (const [key, row] of store) cloned.set(key, structuredClone(row))\n\t\t\tcopy.set(name, cloned)\n\t\t}\n\t\treturn async () => {\n\t\t\tfor (const [name, store] of copy) {\n\t\t\t\tconst restored = new Map<Key, Row>()\n\t\t\t\tfor (const [key, row] of store) restored.set(key, structuredClone(row))\n\t\t\t\tthis.#tables.set(name, restored)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Return the persisted {@link DriverMeta}, or `undefined` when the store has\n\t * never been stamped.\n\t *\n\t * @remarks\n\t * In-process only — the metadata lives in this instance's memory, exactly\n\t * like the rest of this driver's storage. A driver-conformance-valid\n\t * implementation of the optional `meta` / `stamp` pair.\n\t *\n\t * @returns The last-stamped {@link DriverMeta}, or `undefined`\n\t */\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 * @param meta - The {@link DriverMeta} to persist\n\t */\n\tasync stamp(meta: DriverMeta): Promise<void> {\n\t\tthis.#meta = meta\n\t}\n\n\t/**\n\t * Apply a {@link Migration} plan's steps against the in-memory store.\n\t *\n\t * @remarks\n\t * A multi-step plan applies its steps sequentially and is NOT atomic — a\n\t * failure partway through a plan leaves 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\tfor (const step of plan.steps) {\n\t\t\tswitch (step.operation) {\n\t\t\t\tcase 'table.add':\n\t\t\t\t\tif (!this.#tables.has(step.table.name)) this.#tables.set(step.table.name, new Map())\n\t\t\t\t\tbreak\n\t\t\t\tcase 'table.remove':\n\t\t\t\t\tthis.#require(step.table)\n\t\t\t\t\tthis.#tables.delete(step.table)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'column.add':\n\t\t\t\tcase 'column.remove': {\n\t\t\t\t\tconst store = this.#require(step.table)\n\t\t\t\t\tconst rows = [...store.entries()]\n\t\t\t\t\tconst migrated = migrateRows(\n\t\t\t\t\t\trows.map(([, row]) => row),\n\t\t\t\t\t\t[step],\n\t\t\t\t\t)\n\t\t\t\t\trows.forEach(([key], index) => store.set(key, migrated[index]))\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tcase 'index.add':\n\t\t\t\tcase 'index.remove':\n\t\t\t\t\tthis.#require(step.table)\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\t// A table's keys in key order — the contract `scan` and `keys` yield in.\n\t// `compareValues` is the core total order (number < string, natural within),\n\t// matching the SQLite `ORDER BY` and IndexedDB key-range orderings.\n\t#ordered(table: string): readonly Key[] {\n\t\treturn [...this.#store(table).keys()].sort(compareValues)\n\t}\n\n\t// A migration step's table must already exist — unlike `#store`, a missing\n\t// table here is a MIGRATION error rather than an as-yet-untouched table.\n\t#require(table: string): Map<Key, Row> {\n\t\tconst store = this.#tables.get(table)\n\t\tif (store === undefined) {\n\t\t\tthrow new DatabaseError('MIGRATION', `migrate: unknown table '${table}'`, { table })\n\t\t}\n\t\treturn store\n\t}\n\n\t// Lazily create a table's backing map — a write to an as-yet-untouched (but\n\t// declared) table just works, and reads of an empty table return nothing.\n\t#store(table: string): Map<Key, Row> {\n\t\tlet store = this.#tables.get(table)\n\t\tif (store === undefined) {\n\t\t\tstore = new Map()\n\t\t\tthis.#tables.set(table, store)\n\t\t}\n\t\treturn store\n\t}\n}\n","import type { DatabaseInterface, DatabaseOptions, DriverInterface, TablesShape } from './types.js'\nimport { Database } from './Database.js'\nimport { MemoryDriver } from './drivers/MemoryDriver.js'\n\n/**\n * Create a database over a driver and a declared `tables` schema.\n *\n * @remarks\n * `tables` maps each name to its columns (a `column → shape` map); the database\n * wraps each in an `objectShape`, so you never write `objectShape` at the table\n * level. The `const` type parameter captures the literal names and columns, so\n * `db.table('users')` is checked against the schema and typed by `Infer` of its\n * columns — no annotations. Name a non-`id` primary-key column per table via the\n * optional `keys` map.\n *\n * @param options - The driver, the `tables` column map, optional `keys`, and an\n * optional `name`\n * @returns A typed {@link DatabaseInterface}\n *\n * @example\n * ```ts\n * import { createDatabase, createMemoryDriver } from '@orkestrel/database'\n * import { integerShape, stringShape } from '@orkestrel/contract'\n *\n * const db = createDatabase({\n * \tdriver: createMemoryDriver(),\n * \ttables: {\n * \t\tusers: { id: stringShape(), age: integerShape() },\n * \t\tposts: { slug: stringShape(), title: stringShape() },\n * \t},\n * \tkeys: { posts: 'slug' },\n * })\n * await db.table('users').set({ id: 'u1', age: 36 }) // typed; coerced + validated\n * ```\n */\nexport function createDatabase<const T extends TablesShape>(\n\toptions: DatabaseOptions<T>,\n): DatabaseInterface<T> {\n\treturn new Database(options)\n}\n\n/**\n * Create the in-memory reference {@link DriverInterface}.\n *\n * @remarks\n * Backed by nested maps with no I/O — the same driver runs in a browser or on a\n * server, making it the natural choice for tests and ephemeral storage.\n *\n * @returns A fresh in-memory driver\n */\nexport function createMemoryDriver(): DriverInterface {\n\treturn new MemoryDriver()\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["#source","#scope","#continue","#next","#return","#throw","#cleaned","#cleanup","#operations","#accepting","#failed","#error","#driver","#name","#version","#error","#emitter","#operations","#status","#transaction","#ready","#schema","#outside","#drain","#connect","#admit","#rollbackError","#transition","#failure","#reconcile","#stamp","#apply","#migration","#keys","#read","#update","#remove","#track","#value","#index","#closed","#queue","#advance","#revise","#delete","#tail","#source","#context","#continue","#next","#return","#throw","#cleaned","#cleanup","#table","#conditions","#orders","#filters","#limit","#offset","#page","#filtered","#ready","#driver","#name","#key","#contract","#guard","#generate","#context","#scope","#emitter","#track","#each","#read","#resolveOne","#collect","#scan","#wait","#put","#updateOne","#delete","#readCursor","#updateCursor","#deleteCursor","#cast","#validate","#prepare","#resolveKey","#driver","#tables","#primary","#generate","#error","#scope","#columns","#build","#key","#tables","#primary","#indexes","#generate","#context","#schema","#columns","#build","#key","#spawn","#settle","#attach","#tables","#metadata","#identities","#schema","#store","#table","#ordered","#stream","#copy","#projectIdentities","#migrate","#require"],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/validators.ts","../../../src/core/cloners.ts","../../../src/core/helpers.ts","../../../src/core/TransactionIterator.ts","../../../src/core/TransactionScope.ts","../../../src/core/DatabaseContext.ts","../../../src/core/Cursor.ts","../../../src/core/DatabaseIterator.ts","../../../src/core/Query.ts","../../../src/core/Table.ts","../../../src/core/DatabaseTransaction.ts","../../../src/core/Database.ts","../../../src/core/drivers/MemoryDriver.ts","../../../src/core/factories.ts"],"sourcesContent":["// Database constants — frozen plain data (AGENTS §5).\n\n/**\n * The primary-key column assumed when {@link PrimaryMap} does not name one.\n *\n * @remarks\n * `id` is the convention IndexedDB (`keyPath: 'id'`) and SQL (`id` / rowid) both\n * lean on, so a table without a `primary` override keys its rows by `id`.\n */\nexport const DEFAULT_PRIMARY = 'id'\n\n/**\n * The longest `LIKE` / `GLOB` pattern the wildcard matcher accepts before rejecting it.\n *\n * @remarks\n * A ReDoS bound (AGENTS §6.5): the SA1–SA4 migration lets a model supply `list`\n * input over the wire, so `matchesLikePattern` / `matchesGlobPattern` run attacker-controlled\n * patterns. The matcher is the LINEAR greedy two-pointer wildcard match — never a\n * backtracking regex (`.*`-segments-separated-by-literals against a long input is the\n * catastrophic shape JS cannot bound without atomic groups), so it is O(value ×\n * pattern). Capping the pattern length bounds that pattern factor, leaving a match\n * linear in the value length whatever the pattern. A longer pattern throws a\n * `VALIDATION` {@link DatabaseError}; the cap is generous for any legitimate search.\n */\nexport const MAX_PATTERN_LENGTH = 1024\n","import type { DatabaseErrorCode } from './types.js'\n\n// AGENTS §12: invalid operations and programmer errors `throw`, always a\n// `DatabaseError` carrying a machine-readable `code` so a `catch` branches on\n// `error.code` instead of parsing the message. Lookups that may simply miss\n// (`get`, `has`, `remove`) return `undefined` / `false` — they never throw.\n\n/**\n * An error thrown by the database layer.\n *\n * @remarks\n * Carries a {@link DatabaseErrorCode} and an optional `context` bag naming the\n * offending table / key. Thrown for: operating on a closed database (`CLOSED`), a\n * `resolve` miss (`NOT_FOUND`), an `add` onto an existing key (`CONFLICT`), a\n * row that fails its table's contract (`VALIDATION`), an aborted operation whose\n * {@link OperationOptions.signal} aborted (`ABORTED`, carrying `signal.reason` in\n * `context`), an inapplicable {@link Migration} plan (`MIGRATION`), a\n * driver that violates a {@link DriverInterface} invariant, thrown by the\n * `conformDriver` helper (`CONFORMANCE`), and an unexpected infrastructure\n * fault surfaced by a driver seam — e.g. a filesystem failure while\n * persisting (`DRIVER`) — as opposed to expected domain conditions, which\n * keep their specific codes.\n */\nexport class DatabaseError extends Error {\n\treadonly code: DatabaseErrorCode\n\treadonly context?: Readonly<Record<string, unknown>>\n\n\tconstructor(\n\t\tcode: DatabaseErrorCode,\n\t\tmessage: string,\n\t\tcontext?: Readonly<Record<string, unknown>>,\n\t) {\n\t\tsuper(message)\n\t\tthis.name = 'DatabaseError'\n\t\tthis.code = code\n\t\tif (context !== undefined) this.context = context\n\t}\n}\n\n/**\n * Narrow an unknown caught value to a {@link DatabaseError}.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns `true` when `value` is a {@link DatabaseError}\n *\n * @example\n * ```ts\n * try {\n * \tawait users.add(row)\n * } catch (error) {\n * \tif (isDatabaseError(error) && error.code === 'CONFLICT') await users.set(row)\n * }\n * ```\n */\nexport function isDatabaseError(value: unknown): value is DatabaseError {\n\treturn value instanceof DatabaseError\n}\n","import type {\n\tColumnSchema,\n\tDriverMetadata,\n\tKey,\n\tMigration,\n\tMigrationInput,\n\tMigrationStep,\n\tQueryInput,\n\tTableSchema,\n} from './types.js'\nimport { cloneJSONRecord, cloneJSONValue } from '@orkestrel/contract'\nimport { DatabaseError } from './errors.js'\n\n/**\n * Validate the paging fields of a portable query.\n *\n * @remarks\n * A present `limit` or `offset` must be a finite nonnegative integer; zero is\n * valid. Validation is deterministic (`limit` before `offset`). Non-finite\n * values are rendered as strings in error context so JSON serialization cannot\n * collapse `NaN` or infinity to `null`.\n *\n * @param input - The portable query whose paging fields to validate\n * @throws {@link DatabaseError} `VALIDATION` when a paging field is invalid\n */\nexport function validatePage(input?: QueryInput): void {\n\tconst limit = input?.limit\n\tif (limit !== undefined && (!Number.isInteger(limit) || limit < 0)) {\n\t\tthrow new DatabaseError('VALIDATION', 'Query limit must be a nonnegative integer', {\n\t\t\tfield: 'limit',\n\t\t\tvalue: Number.isFinite(limit) ? limit : String(limit),\n\t\t})\n\t}\n\tconst offset = input?.offset\n\tif (offset !== undefined && (!Number.isInteger(offset) || offset < 0)) {\n\t\tthrow new DatabaseError('VALIDATION', 'Query offset must be a nonnegative integer', {\n\t\t\tfield: 'offset',\n\t\t\tvalue: Number.isFinite(offset) ? offset : String(offset),\n\t\t})\n\t}\n}\n\n/**\n * Test whether a value is a usable database key.\n *\n * @param value - The value to test\n * @returns Whether `value` is a string or finite number\n */\nexport function isKey(value: unknown): value is Key {\n\treturn typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value))\n}\n\n/**\n * Test whether a value is a portable column schema.\n *\n * @param value - The value to test\n * @returns Whether `value` is a complete {@link ColumnSchema}\n */\nexport function isColumnSchema(value: unknown): value is ColumnSchema {\n\ttry {\n\t\tconst column = cloneJSONRecord(value)\n\t\tconst keys = Object.keys(column)\n\t\treturn (\n\t\t\tkeys.length === 4 &&\n\t\t\tkeys.includes('name') &&\n\t\t\tkeys.includes('storage') &&\n\t\t\tkeys.includes('optional') &&\n\t\t\tkeys.includes('nullable') &&\n\t\t\ttypeof column.name === 'string' &&\n\t\t\tcolumn.name.length > 0 &&\n\t\t\t(column.storage === 'text' ||\n\t\t\t\tcolumn.storage === 'integer' ||\n\t\t\t\tcolumn.storage === 'real' ||\n\t\t\t\tcolumn.storage === 'boolean' ||\n\t\t\t\tcolumn.storage === 'json' ||\n\t\t\t\tcolumn.storage === 'blob') &&\n\t\t\ttypeof column.optional === 'boolean' &&\n\t\t\ttypeof column.nullable === 'boolean'\n\t\t)\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Test whether a value is a portable table schema.\n *\n * @param value - The value to test\n * @returns Whether `value` is a complete {@link TableSchema}\n */\nexport function isTableSchema(value: unknown): value is TableSchema {\n\ttry {\n\t\tconst table = cloneJSONRecord(value)\n\t\tconst keys = Object.keys(table)\n\t\tif (\n\t\t\tkeys.length !== 4 ||\n\t\t\t!keys.includes('name') ||\n\t\t\t!keys.includes('primary') ||\n\t\t\t!keys.includes('columns') ||\n\t\t\t!keys.includes('indexes') ||\n\t\t\ttypeof table.name !== 'string' ||\n\t\t\ttable.name.length === 0 ||\n\t\t\ttypeof table.primary !== 'string' ||\n\t\t\ttable.primary.length === 0 ||\n\t\t\t!Array.isArray(table.columns) ||\n\t\t\t!Array.isArray(table.indexes) ||\n\t\t\t!table.columns.every(isColumnSchema)\n\t\t) {\n\t\t\treturn false\n\t\t}\n\t\tconst names = table.columns.map((column) => column.name)\n\t\tif (\n\t\t\tnew Set(names).size !== names.length ||\n\t\t\t!names.includes(table.primary) ||\n\t\t\t!table.indexes.every(\n\t\t\t\t(index) =>\n\t\t\t\t\tArray.isArray(index) &&\n\t\t\t\t\tindex.length > 0 &&\n\t\t\t\t\tindex.every((column) => typeof column === 'string' && names.includes(column)),\n\t\t\t)\n\t\t) {\n\t\t\treturn false\n\t\t}\n\t\tconst indexes = table.indexes.map((index) => JSON.stringify(index))\n\t\treturn new Set(indexes).size === indexes.length\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Test whether a value is a complete portable driver schema.\n *\n * @param value - The value to test\n * @returns Whether `value` is a table-schema collection with unique table names\n */\nexport function isDriverSchema(value: unknown): value is readonly TableSchema[] {\n\ttry {\n\t\tconst schema = cloneJSONValue(value)\n\t\tif (!Array.isArray(schema) || !schema.every(isTableSchema)) return false\n\t\tconst names = schema.map((table) => table.name)\n\t\treturn new Set(names).size === names.length\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Test whether a value is one ordered migration step.\n *\n * @param value - The value to test\n * @returns Whether `value` is a complete {@link MigrationStep}\n */\nexport function isMigrationStep(value: unknown): value is MigrationStep {\n\ttry {\n\t\tconst step = cloneJSONRecord(value)\n\t\tif (typeof step.operation !== 'string') return false\n\t\tconst keys = Object.keys(step)\n\t\tswitch (step.operation) {\n\t\t\tcase 'table.add':\n\t\t\t\treturn (\n\t\t\t\t\tkeys.length === 2 &&\n\t\t\t\t\tkeys.includes('operation') &&\n\t\t\t\t\tkeys.includes('table') &&\n\t\t\t\t\tisTableSchema(step.table)\n\t\t\t\t)\n\t\t\tcase 'table.remove':\n\t\t\t\treturn (\n\t\t\t\t\tkeys.length === 2 &&\n\t\t\t\t\tkeys.includes('operation') &&\n\t\t\t\t\tkeys.includes('table') &&\n\t\t\t\t\ttypeof step.table === 'string' &&\n\t\t\t\t\tstep.table.length > 0\n\t\t\t\t)\n\t\t\tcase 'column.add':\n\t\t\t\treturn (\n\t\t\t\t\tkeys.length === 3 &&\n\t\t\t\t\tkeys.includes('operation') &&\n\t\t\t\t\tkeys.includes('table') &&\n\t\t\t\t\tkeys.includes('column') &&\n\t\t\t\t\ttypeof step.table === 'string' &&\n\t\t\t\t\tstep.table.length > 0 &&\n\t\t\t\t\tisColumnSchema(step.column)\n\t\t\t\t)\n\t\t\tcase 'column.remove':\n\t\t\t\treturn (\n\t\t\t\t\tkeys.length === 3 &&\n\t\t\t\t\tkeys.includes('operation') &&\n\t\t\t\t\tkeys.includes('table') &&\n\t\t\t\t\tkeys.includes('column') &&\n\t\t\t\t\ttypeof step.table === 'string' &&\n\t\t\t\t\tstep.table.length > 0 &&\n\t\t\t\t\ttypeof step.column === 'string' &&\n\t\t\t\t\tstep.column.length > 0\n\t\t\t\t)\n\t\t\tcase 'index.add':\n\t\t\tcase 'index.remove':\n\t\t\t\treturn (\n\t\t\t\t\tkeys.length === 3 &&\n\t\t\t\t\tkeys.includes('operation') &&\n\t\t\t\t\tkeys.includes('table') &&\n\t\t\t\t\tkeys.includes('index') &&\n\t\t\t\t\ttypeof step.table === 'string' &&\n\t\t\t\t\tstep.table.length > 0 &&\n\t\t\t\t\tArray.isArray(step.index) &&\n\t\t\t\t\tstep.index.length > 0 &&\n\t\t\t\t\tstep.index.every((column) => typeof column === 'string' && column.length > 0)\n\t\t\t\t)\n\t\t\tdefault:\n\t\t\t\treturn false\n\t\t}\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Test whether a value is an ordered migration plan.\n *\n * @param value - The value to test\n * @returns Whether `value` is a complete {@link Migration}\n */\nexport function isMigration(value: unknown): value is Migration {\n\ttry {\n\t\tconst migration = cloneJSONRecord(value)\n\t\tconst keys = Object.keys(migration)\n\t\treturn (\n\t\t\tkeys.length === 3 &&\n\t\t\tkeys.includes('from') &&\n\t\t\tkeys.includes('to') &&\n\t\t\tkeys.includes('steps') &&\n\t\t\ttypeof migration.from === 'number' &&\n\t\t\tNumber.isFinite(migration.from) &&\n\t\t\ttypeof migration.to === 'number' &&\n\t\t\tNumber.isFinite(migration.to) &&\n\t\t\tArray.isArray(migration.steps) &&\n\t\t\tmigration.steps.every(isMigrationStep)\n\t\t)\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Test whether a value is persisted driver metadata.\n *\n * @param value - The value to test\n * @returns Whether `value` is complete {@link DriverMetadata}\n */\nexport function isDriverMetadata(value: unknown): value is DriverMetadata {\n\ttry {\n\t\tconst metadata = cloneJSONRecord(value)\n\t\tconst keys = Object.keys(metadata)\n\t\treturn (\n\t\t\tkeys.length === 2 &&\n\t\t\tkeys.includes('version') &&\n\t\t\tkeys.includes('schema') &&\n\t\t\ttypeof metadata.version === 'number' &&\n\t\t\tNumber.isFinite(metadata.version) &&\n\t\t\tisDriverSchema(metadata.schema)\n\t\t)\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Test whether a value is one atomic migration request.\n *\n * @param value - The value to test\n * @returns Whether `value` is a complete {@link MigrationInput}\n */\nexport function isMigrationInput(value: unknown): value is MigrationInput {\n\ttry {\n\t\tconst input = cloneJSONRecord(value)\n\t\tconst keys = Object.keys(input)\n\t\treturn (\n\t\t\t(keys.length === 1 || keys.length === 2) &&\n\t\t\tkeys.includes('plan') &&\n\t\t\t(keys.length === 1 || keys.includes('metadata')) &&\n\t\t\tisMigration(input.plan) &&\n\t\t\t(input.metadata === undefined || isDriverMetadata(input.metadata))\n\t\t)\n\t} catch {\n\t\treturn false\n\t}\n}\n","import type { DriverMetadata, MigrationInput, TableSchema } from './types.js'\nimport { cloneJSONRecord, cloneJSONValue } from '@orkestrel/contract'\nimport { DatabaseError } from './errors.js'\nimport { isDriverMetadata, isDriverSchema, isMigrationInput } from './validators.js'\n\n/**\n * Clone unknown driver metadata into a distinct deeply frozen snapshot.\n *\n * @param value - Unknown metadata\n * @returns Owned driver metadata\n */\nexport function cloneDriverMetadata(value: unknown): DriverMetadata {\n\ttry {\n\t\tconst metadata = cloneJSONRecord(value)\n\t\tif (isDriverMetadata(metadata)) return metadata\n\t\tthrow new DatabaseError('VALIDATION', 'Driver metadata is invalid', {\n\t\t\tpath: 'metadata',\n\t\t})\n\t} catch (error) {\n\t\tif (error instanceof DatabaseError) throw error\n\t\tthrow new DatabaseError('VALIDATION', 'Driver metadata is invalid', {\n\t\t\tpath: 'metadata',\n\t\t\tcause: error,\n\t\t})\n\t}\n}\n\n/**\n * Clone unknown driver schema into a distinct deeply frozen snapshot.\n *\n * @param value - Unknown table schema collection\n * @returns Owned driver schema\n */\nexport function cloneDriverSchema(value: unknown): readonly TableSchema[] {\n\ttry {\n\t\tconst schema = cloneJSONValue(value)\n\t\tif (isDriverSchema(schema)) return schema\n\t\tthrow new DatabaseError('VALIDATION', 'Driver schema is invalid', {\n\t\t\tpath: 'schema',\n\t\t})\n\t} catch (error) {\n\t\tif (error instanceof DatabaseError) throw error\n\t\tthrow new DatabaseError('VALIDATION', 'Driver schema is invalid', {\n\t\t\tpath: 'schema',\n\t\t\tcause: error,\n\t\t})\n\t}\n}\n\n/**\n * Clone unknown migration input into a distinct deeply frozen snapshot.\n *\n * @param value - Unknown migration input\n * @returns Owned migration input\n */\nexport function cloneMigrationInput(value: unknown): MigrationInput {\n\ttry {\n\t\tconst input = cloneJSONRecord(value)\n\t\tif (isMigrationInput(input)) return input\n\t\tthrow new DatabaseError('VALIDATION', 'Migration input is invalid', {\n\t\t\tpath: 'migration',\n\t\t})\n\t} catch (error) {\n\t\tif (error instanceof DatabaseError) throw error\n\t\tthrow new DatabaseError('VALIDATION', 'Migration input is invalid', {\n\t\t\tpath: 'migration',\n\t\t\tcause: error,\n\t\t})\n\t}\n}\n","import type { ContractShape, FieldPath } from '@orkestrel/contract'\nimport type {\n\tAggregateOperation,\n\tColumnSchema,\n\tColumnStorage,\n\tConformanceFinding,\n\tCondition,\n\tQueryInput,\n\tDriverInterface,\n\tKey,\n\tMigration,\n\tMigrationStep,\n\tOrder,\n\tRow,\n\tTableSchema,\n} from './types.js'\nimport {\n\tcompileGuard,\n\tisRecord,\n\tisString,\n\tobjectShape,\n\tparseNumber,\n\tresolveField,\n} from '@orkestrel/contract'\nimport { MAX_PATTERN_LENGTH } from './constants.js'\nimport { cloneDriverSchema, cloneMigrationInput } from './cloners.js'\nimport { DatabaseError, isDatabaseError } from './errors.js'\nimport { isKey, validatePage } from './validators.js'\n\n// The query engine. Every backend's `scan` yields rows; these pure helpers do\n// the filtering, ordering, paging, and aggregation once, so a driver never\n// re-implements WHERE compilation. They are total — like the contracts guards\n// they lean on, hostile input yields a `false` / a skipped value, never a throw.\n\n// === Comparison\n\n/**\n * A total ordering over arbitrary values — the comparator behind sorting and the\n * range operators.\n *\n * @remarks\n * Values of different types order by a fixed type rank (`undefined` < `null` <\n * boolean < number < string < other); same-typed values compare naturally.\n * `NaN` sorts after every other number and equal to itself, so the comparator\n * is total and never returns `NaN`.\n *\n * @param left - The left value\n * @param right - The right value\n * @returns `-1`, `0`, or `1`\n */\nexport function compareValues(left: unknown, right: unknown): number {\n\t// Rank unlike types so a mixed column still sorts deterministically:\n\t// undefined < null < boolean < number < string < other.\n\t// Mapping two inputs always produces two ranks; the defaults only satisfy\n\t// unchecked indexed destructuring and are semantically unreachable.\n\tconst [leftRank = 5, rightRank = 5] = [left, right].map((value) =>\n\t\tvalue === undefined\n\t\t\t? 0\n\t\t\t: value === null\n\t\t\t\t? 1\n\t\t\t\t: typeof value === 'boolean'\n\t\t\t\t\t? 2\n\t\t\t\t\t: typeof value === 'number'\n\t\t\t\t\t\t? 3\n\t\t\t\t\t\t: typeof value === 'string'\n\t\t\t\t\t\t\t? 4\n\t\t\t\t\t\t\t: 5,\n\t)\n\tif (leftRank !== rightRank) return leftRank < rightRank ? -1 : 1\n\tif (typeof left === 'number' && typeof right === 'number') {\n\t\tif (Number.isNaN(left) || Number.isNaN(right)) {\n\t\t\treturn Number.isNaN(left) ? (Number.isNaN(right) ? 0 : 1) : -1\n\t\t}\n\t\treturn left < right ? -1 : left > right ? 1 : 0\n\t}\n\tif (typeof left === 'string' && typeof right === 'string') {\n\t\treturn left < right ? -1 : left > right ? 1 : 0\n\t}\n\tif (typeof left === 'boolean' && typeof right === 'boolean') {\n\t\treturn left === right ? 0 : left ? 1 : -1\n\t}\n\treturn 0\n}\n\n/**\n * Structural equality by SameValueZero leaves — the comparator behind conformance\n * checks and any test/fixture that needs \"same data\", not \"same reference\".\n *\n * @remarks\n * Primitives compare by SameValueZero (`NaN` equals itself; `+0` equals `-0`).\n * Arrays compare by index (same length, every element `equalsValue`). Plain\n * records (via `isRecord`) compare by their OWN enumerable keys: same key\n * COUNT and, for every key in `left`, `right` has that key (`Object.hasOwn`)\n * with a `equalsValue` value — so a key present with value `undefined` is NOT\n * equal to that key being absent (both differ in `Object.keys` membership).\n * Anything else (functions, class instances, mismatched shapes) falls through\n * to `false`. Container pairs are tracked iteratively, so self-referential and\n * mutually cyclic arrays/records terminate without consuming the call stack.\n * Hostile proxy traps and accessors are contained as a non-match.\n *\n * @param left - The left value\n * @param right - The right value\n * @returns Whether `left` and `right` are structurally equal\n *\n * @example\n * ```ts\n * equalsValue(Number.NaN, Number.NaN) // true\n * equalsValue({ a: [1, { b: 2 }] }, { a: [1, { b: 2 }] }) // true\n * equalsValue({ a: undefined }, {}) // false — present-undefined ≠ absent\n * ```\n */\nexport function equalsValue(left: unknown, right: unknown): boolean {\n\tconst pending: Array<readonly [unknown, unknown]> = [[left, right]]\n\tconst compared = new WeakMap<object, WeakSet<object>>()\n\ttry {\n\t\twhile (pending.length > 0) {\n\t\t\tconst pair = pending.pop()\n\t\t\tif (pair === undefined) continue\n\t\t\tconst [currentLeft, currentRight] = pair\n\t\t\tif (typeof currentLeft === 'number' && typeof currentRight === 'number') {\n\t\t\t\tif (\n\t\t\t\t\t(Number.isNaN(currentLeft) && Number.isNaN(currentRight)) ||\n\t\t\t\t\tcurrentLeft === currentRight\n\t\t\t\t) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif (currentLeft === currentRight) continue\n\n\t\t\tconst leftArray = Array.isArray(currentLeft)\n\t\t\tconst rightArray = Array.isArray(currentRight)\n\t\t\tconst leftRecord = isRecord(currentLeft)\n\t\t\tconst rightRecord = isRecord(currentRight)\n\t\t\tif (leftArray !== rightArray || leftRecord !== rightRecord) return false\n\t\t\tif ((!leftArray && !leftRecord) || (!rightArray && !rightRecord)) return false\n\n\t\t\tconst prior = compared.get(currentLeft)\n\t\t\tif (prior?.has(currentRight)) continue\n\t\t\tif (prior === undefined) {\n\t\t\t\tcompared.set(currentLeft, new WeakSet([currentRight]))\n\t\t\t} else {\n\t\t\t\tprior.add(currentRight)\n\t\t\t}\n\n\t\t\tif (leftArray && rightArray) {\n\t\t\t\tif (currentLeft.length !== currentRight.length) return false\n\t\t\t\tfor (let index = 0; index < currentLeft.length; index += 1) {\n\t\t\t\t\tconst leftOwn = Object.hasOwn(currentLeft, index)\n\t\t\t\t\tconst rightOwn = Object.hasOwn(currentRight, index)\n\t\t\t\t\tif (leftOwn !== rightOwn) return false\n\t\t\t\t\tif (leftOwn) pending.push([currentLeft[index], currentRight[index]])\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (leftRecord && rightRecord) {\n\t\t\t\tconst leftKeys = Object.keys(currentLeft)\n\t\t\t\tconst rightKeys = Object.keys(currentRight)\n\t\t\t\tif (leftKeys.length !== rightKeys.length) return false\n\t\t\t\tfor (const key of leftKeys) {\n\t\t\t\t\tif (!Object.hasOwn(currentRight, key)) return false\n\t\t\t\t\tpending.push([currentLeft[key], currentRight[key]])\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n// === Pattern matching\n\n/**\n * Match a value against a wildcard pattern in LINEAR time — the shared, ReDoS-SAFE\n * engine behind {@link matchesLikePattern} and {@link matchesGlobPattern}.\n *\n * @remarks\n * A backtracking RegExp (`a%b%c` → `^a.*b.*c$`) is CATASTROPHIC on a hostile pattern:\n * `.*` segments separated by literals, matched against a long non-matching input, blow\n * up super-linearly — and JS has no atomic groups / possessive quantifiers to bound it\n * (AGENTS §6.5, now that the authed server runs model-supplied `list` input over the\n * wire). So this builds NO regex. It runs the classic GREEDY TWO-POINTER wildcard match:\n * the `any` wildcard records its position and, on a later mismatch, backtracks ONLY to\n * that last `any` (letting it absorb one more char) — so the work is O(value × pattern),\n * never the exponential / polynomial backtracking a regex would do. The pattern length\n * is capped at {@link MAX_PATTERN_LENGTH} (a `VALIDATION` {@link DatabaseError} over it),\n * bounding the pattern factor so a match stays linear in the value length whatever the\n * pattern.\n *\n * The `any` wildcard matches any run (including empty); `single` matches exactly one\n * char; every other pattern char matches itself LITERALLY (a pattern `.` / `(` / `\\` is\n * a literal — the regex-metacharacter hazard is gone with the regex). `any` is tested\n * BEFORE a literal match, so a value that literally contains the wildcard char never\n * shadows the wildcard. Case folding is applied to BOTH sides when `fold` is set.\n *\n * @param value - The value to test\n * @param pattern - The wildcard pattern\n * @param any - The any-run wildcard char (`%` for `LIKE`, `*` for `GLOB`)\n * @param single - The single-char wildcard char (`_` for `LIKE`, `?` for `GLOB`)\n * @param fold - Whether to match case-INSENSITIVELY (`LIKE` folds; `GLOB` does not)\n * @returns Whether `value` matches `pattern`\n * @throws A `VALIDATION` {@link DatabaseError} when `pattern` exceeds {@link MAX_PATTERN_LENGTH}\n */\nexport function matchesWildcardPattern(\n\tvalue: string,\n\tpattern: string,\n\tany: string,\n\tsingle: string,\n\tfold: boolean,\n): boolean {\n\tif (pattern.length > MAX_PATTERN_LENGTH) {\n\t\tthrow new DatabaseError(\n\t\t\t'VALIDATION',\n\t\t\t`Pattern exceeds the maximum length of ${MAX_PATTERN_LENGTH}`,\n\t\t\t{ length: pattern.length, limit: MAX_PATTERN_LENGTH },\n\t\t)\n\t}\n\tconst haystack = fold ? value.toLowerCase() : value\n\tconst needle = fold ? pattern.toLowerCase() : pattern\n\tlet vi = 0\n\tlet pi = 0\n\t// The greedy backtrack point: the pattern index of the LAST `any` wildcard + the value\n\t// index it was taken at. On a mismatch we resume just past it and let it absorb one more\n\t// char (`mark += 1`) — O(value × pattern), never a regex's exponential backtracking.\n\tlet star = -1\n\tlet mark = 0\n\twhile (vi < haystack.length) {\n\t\tconst pc = pi < needle.length ? needle[pi] : undefined\n\t\tif (pc === any) {\n\t\t\t// Record the wildcard (it absorbs zero chars for now) and advance the pattern.\n\t\t\tstar = pi\n\t\t\tmark = vi\n\t\t\tpi += 1\n\t\t} else if (pc !== undefined && (pc === single || pc === haystack[vi])) {\n\t\t\tvi += 1\n\t\t\tpi += 1\n\t\t} else if (star !== -1) {\n\t\t\t// Mismatch under an open `any`: let it swallow one more value char and retry.\n\t\t\tpi = star + 1\n\t\t\tmark += 1\n\t\t\tvi = mark\n\t\t} else {\n\t\t\treturn false\n\t\t}\n\t}\n\t// The value is consumed — the leftover pattern matches iff it is all `any` wildcards.\n\twhile (pi < needle.length && needle[pi] === any) pi += 1\n\treturn pi === needle.length\n}\n\n// SQL `LIKE` → case-INSENSITIVE wildcard match (`%` any run, `_` any char).\nexport function matchesLikePattern(value: string, pattern: string): boolean {\n\treturn matchesWildcardPattern(value, pattern, '%', '_', true)\n}\n\n// `GLOB` → case-SENSITIVE wildcard match (`*` any run, `?` any char).\nexport function matchesGlobPattern(value: string, pattern: string): boolean {\n\treturn matchesWildcardPattern(value, pattern, '*', '?', false)\n}\n\n// === Condition matching\n\n/**\n * Evaluate one {@link Condition} against a row — the per-operator predicate.\n *\n * @remarks\n * Reads the condition's column — a `FieldPath`, resolved with `resolveField` (a\n * string is one column; an array descends a nested value) — and applies the\n * operator. Range operators (`above` / `below` / `from` / `to` / `between`) use\n * {@link compareValues}, the total order; the equality family (`equals` / `not`\n * / `any` / `none`) uses {@link equalsValue} — STRUCTURAL equality, not the total\n * order's rank-5-collapses-all-objects behavior, so `equals` on an object/array\n * operand only matches a structurally-equal value, never every row holding any\n * object. This is a semantics change from ranking: `equalsValue` is SameValueZero\n * on leaves, so `NaN` now equals `NaN` under `equals` / `any` (it never matched\n * anything under the old rank-based comparison). `like` / `glob` / `starts` /\n * `ends` match only strings; `absent` / `present` test nullishness. Total — a\n * type mismatch is simply a non-match.\n *\n * @param row - The row to test\n * @param condition - The condition to apply\n * @returns Whether the row satisfies the condition\n */\nexport function matchesCondition(row: Row, condition: Condition): boolean {\n\tconst value = resolveField(row, condition.column)\n\tconst first = condition.values[0]\n\tconst second = condition.values[1]\n\tswitch (condition.operator) {\n\t\tcase 'equals':\n\t\t\treturn equalsValue(value, first)\n\t\tcase 'not':\n\t\t\treturn !equalsValue(value, first)\n\t\tcase 'above':\n\t\t\treturn compareValues(value, first) > 0\n\t\tcase 'below':\n\t\t\treturn compareValues(value, first) < 0\n\t\tcase 'from':\n\t\t\treturn compareValues(value, first) >= 0\n\t\tcase 'to':\n\t\t\treturn compareValues(value, first) <= 0\n\t\tcase 'between':\n\t\t\treturn compareValues(value, first) >= 0 && compareValues(value, second) <= 0\n\t\tcase 'like':\n\t\t\treturn isString(value) && isString(first) && matchesLikePattern(value, first)\n\t\tcase 'glob':\n\t\t\treturn isString(value) && isString(first) && matchesGlobPattern(value, first)\n\t\tcase 'starts':\n\t\t\treturn isString(value) && isString(first) && value.startsWith(first)\n\t\tcase 'ends':\n\t\t\treturn isString(value) && isString(first) && value.endsWith(first)\n\t\tcase 'any':\n\t\t\treturn condition.values.some((candidate) => equalsValue(value, candidate))\n\t\tcase 'none':\n\t\t\treturn !condition.values.some((candidate) => equalsValue(value, candidate))\n\t\tcase 'absent':\n\t\t\treturn value === undefined || value === null\n\t\tcase 'present':\n\t\t\treturn value !== undefined && value !== null\n\t}\n}\n\n/**\n * Fold a row through a list of conditions, joining each by its connector.\n *\n * @remarks\n * Evaluated left-to-right: the first condition seeds the result, and each later\n * condition combines with `&&` (`and`) or `||` (`or`). An empty list matches\n * every row. There is no operator precedence — conditions combine in the order\n * the query builder recorded them.\n *\n * @param row - The row to test\n * @param conditions - The conditions to fold\n * @returns Whether the row satisfies the combined conditions\n */\nexport function matchesQuery(row: Row, conditions: readonly Condition[]): boolean {\n\tlet result = true\n\tlet seeded = false\n\tfor (const condition of conditions) {\n\t\tconst match = matchesCondition(row, condition)\n\t\tif (!seeded) {\n\t\t\tresult = match\n\t\t\tseeded = true\n\t\t} else {\n\t\t\tresult = condition.connector === 'or' ? result || match : result && match\n\t\t}\n\t}\n\treturn result\n}\n\n/**\n * Filter rows by a list of conditions — the shared basis for a table's count\n * and aggregate paths (no sort/page, unlike {@link applyQuery}).\n *\n * @remarks\n * An empty condition list matches every row (returned as-is, no copy). Folds\n * each row through {@link matchesQuery}.\n *\n * @param rows - The rows to filter\n * @param conditions - The conditions to apply (empty matches everything)\n * @returns The matching rows\n *\n * @example\n * ```ts\n * filterRows(\n * \t[{ age: 30 }, { age: 12 }],\n * \t[{ column: 'age', operator: 'above', values: [18], connector: 'and' }],\n * ) // => [{ age: 30 }]\n * ```\n */\nexport function filterRows(rows: readonly Row[], conditions: readonly Condition[]): readonly Row[] {\n\tif (conditions.length === 0) return rows\n\treturn rows.filter((row) => matchesQuery(row, conditions))\n}\n\n// === Ordering & paging\n\n/**\n * Sort rows by an ordering specification, leaving the input untouched.\n *\n * @remarks\n * Applies the terms in priority order — the first term that distinguishes two\n * rows decides — using {@link compareValues}, reversing for `descending`.\n *\n * @param rows - The rows to sort\n * @param order - The ordering terms in priority order\n * @returns A new, sorted array\n */\nexport function sortRows(rows: readonly Row[], order: readonly Order[]): readonly Row[] {\n\tconst sorted = [...rows]\n\tsorted.sort((left, right) => {\n\t\tfor (const term of order) {\n\t\t\tconst comparison = compareValues(\n\t\t\t\tresolveField(left, term.column),\n\t\t\t\tresolveField(right, term.column),\n\t\t\t)\n\t\t\tif (comparison !== 0) return term.direction === 'descending' ? -comparison : comparison\n\t\t}\n\t\treturn 0\n\t})\n\treturn sorted\n}\n\n/**\n * Apply a {@link QueryInput} to rows — filter, then sort, then page.\n *\n * @remarks\n * The whole portable read pipeline in one place: conditions filter, `order`\n * sorts, and `offset` / `limit` window the result. Each step is skipped when its\n * part of the input is absent. The reference {@link DriverInterface} backends\n * lean on this rather than each re-deriving it.\n *\n * @param rows - The rows to process (typically a table's full `scan`)\n * @param input - The read specification, or `undefined` for all rows as-is\n * @returns The filtered, sorted, paged rows\n */\nexport function applyQuery(rows: readonly Row[], input?: QueryInput): readonly Row[] {\n\tvalidatePage(input)\n\tlet result = rows\n\tconst conditions = input?.conditions\n\tif (conditions !== undefined && conditions.length > 0) {\n\t\tresult = result.filter((row) => matchesQuery(row, conditions))\n\t}\n\tconst order = input?.order\n\tif (order !== undefined && order.length > 0) {\n\t\tresult = sortRows(result, order)\n\t}\n\tconst offset = input?.offset ?? 0\n\tconst limit = input?.limit\n\tif (offset > 0 || limit !== undefined) {\n\t\tresult = result.slice(offset, limit !== undefined ? offset + limit : undefined)\n\t}\n\treturn result\n}\n\n// === Aggregation\n\n/**\n * Compute an aggregate over a column across rows.\n *\n * @remarks\n * `count` returns the row count. The numeric aggregates coerce each cell with\n * the contracts `parseNumber` (so `'42'` counts) and ignore non-numeric cells;\n * over zero numeric values they return `undefined` — the SQL `NULL` of an empty\n * aggregate.\n *\n * @param rows - The rows to aggregate (non-record entries are ignored)\n * @param operation - The aggregate to compute\n * @param column - The column to aggregate\n * @returns The aggregate value, or `undefined` when undefined for the inputs\n */\nexport function computeAggregate(\n\trows: readonly unknown[],\n\toperation: AggregateOperation,\n\tcolumn: FieldPath,\n): number | undefined {\n\tif (operation === 'count') return rows.length\n\tconst numbers: number[] = []\n\tfor (const row of rows) {\n\t\tif (!isRecord(row)) continue\n\t\tconst value = parseNumber(resolveField(row, column))\n\t\tif (value !== undefined) numbers.push(value)\n\t}\n\tif (numbers.length === 0) return undefined\n\tif (operation === 'sum' || operation === 'average') {\n\t\tconst total = numbers.reduce((sum, value) => sum + value, 0)\n\t\treturn operation === 'average' ? total / numbers.length : total\n\t}\n\treturn operation === 'minimum' ? Math.min(...numbers) : Math.max(...numbers)\n}\n\n// === Keys\n\n/**\n * Read a row's primary key from a column, when it is a usable {@link Key}.\n *\n * @param row - The row to read\n * @param column - The primary-key column name\n * @returns The key (a string or finite number), or `undefined`\n */\nexport function extractKey(row: Row, column: string): Key | undefined {\n\tconst value = row[column]\n\treturn isKey(value) ? value : undefined\n}\n\n/**\n * Return a fresh row whose primary column is authoritatively bound to its storage key.\n *\n * @param row - The caller row\n * @param primary - The primary column\n * @param key - The authoritative storage key\n * @returns A fresh row with the bound primary\n */\nexport function bindRowKey(row: Row, primary: string, key: Key): Row {\n\treturn { ...row, [primary]: key }\n}\n\n// === Schema\n\n/**\n * Map a column's {@link ContractShape} to its portable {@link ColumnStorage} — the\n * value a `TableSchema` carries so a native backend can declare a real column.\n *\n * @remarks\n * `string` → `text`; `number` → `integer` when the shape is integer-only, else\n * `real`; `boolean` → `boolean`. A `literal` takes the type of its values\n * (all-boolean → `boolean`, all-integer → `integer`, mixed/fractional numbers →\n * `real`, anything else → `text`). `optional` / `nullable` unwrap to their inner\n * type (nullability is tracked separately). `null` / `object` / `array` / `union` /\n * `json` / `raw` → `json`: a backend stores them as JSON text and can `json_extract`\n * for nested `FieldPath` queries. A scan-only backend ignores the result.\n *\n * @param shape - The column's contract shape\n * @returns The portable column type\n *\n * @example\n * ```ts\n * shapeToColumnStorage(stringShape()) // 'text'\n * shapeToColumnStorage(integerShape()) // 'integer'\n * shapeToColumnStorage(optionalShape(integerShape())) // 'integer'\n * shapeToColumnStorage(objectShape({ a: stringShape() })) // 'json'\n * ```\n */\nexport function shapeToColumnStorage(shape: ContractShape): ColumnStorage {\n\tswitch (shape.type) {\n\t\tcase 'string':\n\t\t\treturn 'text'\n\t\tcase 'number':\n\t\t\treturn shape.integer === true ? 'integer' : 'real'\n\t\tcase 'boolean':\n\t\t\treturn 'boolean'\n\t\tcase 'literal': {\n\t\t\tif (shape.values.every((value) => typeof value === 'boolean')) return 'boolean'\n\t\t\tif (shape.values.every((value) => typeof value === 'number')) {\n\t\t\t\treturn shape.values.every((value) => Number.isInteger(value)) ? 'integer' : 'real'\n\t\t\t}\n\t\t\treturn 'text'\n\t\t}\n\t\tcase 'optional':\n\t\tcase 'nullable':\n\t\t\treturn shapeToColumnStorage(shape.inner)\n\t\tcase 'null':\n\t\tcase 'object':\n\t\tcase 'array':\n\t\tcase 'union':\n\t\tcase 'json':\n\t\tcase 'raw':\n\t\t\treturn 'json'\n\t}\n}\n\n/**\n * Project one contract shape into a portable column schema.\n *\n * @param name - The column name\n * @param shape - The column contract shape\n * @returns The portable storage and independent absence/null acceptance\n */\nexport function shapeToColumnSchema(name: string, shape: ContractShape): ColumnSchema {\n\tconst isColumn = compileGuard(objectShape({ value: shape }))\n\treturn {\n\t\tname,\n\t\tstorage: shapeToColumnStorage(shape),\n\t\toptional: isColumn({}),\n\t\tnullable: isColumn({ value: null }),\n\t}\n}\n\n// === Abort\n\n/**\n * Throw when an {@link OperationOptions.signal | AbortSignal} has fired — the shared\n * abort gate checked at operation boundaries and between streamed rows.\n *\n * @remarks\n * A no-op for `undefined` or a live signal, so callers thread `options?.signal`\n * straight through. When the signal has aborted, throws an `ABORTED`\n * {@link DatabaseError} carrying the signal's `reason` in its context — callers\n * mint signals with native APIs such as `AbortSignal.timeout(ms)` or\n * `new AbortController()`.\n *\n * @param signal - The signal to check, if any\n * @returns Nothing — returns normally while the signal is live\n * @throws An `ABORTED` {@link DatabaseError} when the signal has aborted\n *\n * @example\n * ```ts\n * import { checkAbort } from '@orkestrel/database'\n *\n * const controller = new AbortController()\n * checkAbort(controller.signal) // returns\n * controller.abort('too slow')\n * checkAbort(controller.signal) // throws DatabaseError('ABORTED', …)\n * ```\n */\nexport function checkAbort(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) {\n\t\tthrow new DatabaseError('ABORTED', 'Operation aborted', { reason: signal.reason })\n\t}\n}\n\n// === Migrations\n\n/**\n * Structurally diff a deployed and a declared table set into a {@link Migration}\n * plan.\n *\n * @remarks\n * Tables present in `declared` but not `deployed` become `table.add` steps\n * (carrying the full declared {@link TableSchema}); tables present in\n * `deployed` but not `declared` become `table.remove` steps. Tables present in\n * both are diffed column-by-column (by name) and index-group-by-index-group\n * (by deep equality of the column-name array), each producing `column.add` /\n * `column.remove` / `index.add` / `index.remove` steps. Step order is\n * deterministic: every `table.remove`, then every `table.add`, then each\n * shared table's column/index changes in `declared` order. `from` / `to` are\n * plan labels only; versioning drivers persist and reconcile them through\n * {@link DriverMetadata}.\n *\n * A column present in BOTH schemas under the same name but with a different\n * `storage`, `optional`, or `nullable` value throws a `MIGRATION`\n * {@link DatabaseError} naming the\n * table, the column, and the from→to difference — a name-only diff would\n * otherwise silently produce NO step for the drift, and versioned\n * reconciliation would stamp over it. There is no automatic in-place\n * type-change step: the manual path is to add a new column, copy/convert the\n * data at the application layer, then remove the old column — two separate\n * plans, never a single implicit \"alter\" step.\n *\n * @param deployed - The table schemas currently applied\n * @param declared - The table schemas the caller wants applied\n * @param from - The plan's source version label (defaults to `0`)\n * @param to - The plan's target version label (defaults to `1`)\n * @returns The migration plan moving `deployed` toward `declared`\n * @throws A `MIGRATION` {@link DatabaseError} when a shared table's primary or\n * a shared column's `storage`, `optional`, or `nullable` differs, or when a\n * required non-null column would be added to an existing table without a\n * portable backfill\n *\n * @example\n * ```ts\n * const plan = planMigration(\n * \t[{ name: 'users', primary: 'id', columns: [{ name: 'id', storage: 'text', optional: false, nullable: false }], indexes: [] }],\n * \t[{ name: 'users', primary: 'id', columns: [{ name: 'id', storage: 'text', optional: false, nullable: false }, { name: 'age', storage: 'integer', optional: true, nullable: false }], indexes: [] }],\n * )\n * // plan.steps === [{ operation: 'column.add', table: 'users', column: { name: 'age', ... } }]\n * ```\n */\nexport function planMigration(\n\tdeployed: readonly TableSchema[],\n\tdeclared: readonly TableSchema[],\n\tfrom = 0,\n\tto = 1,\n): Migration {\n\tif (!Number.isFinite(from) || !Number.isFinite(to)) {\n\t\tthrow new DatabaseError('MIGRATION', 'Migration versions must be finite', { from, to })\n\t}\n\tlet beforeSchema: readonly TableSchema[]\n\tlet targetSchema: readonly TableSchema[]\n\ttry {\n\t\tbeforeSchema = normalizeDriverSchema(deployed)\n\t\ttargetSchema = normalizeDriverSchema(declared)\n\t} catch (error) {\n\t\tthrow new DatabaseError('MIGRATION', 'Migration schema is invalid', { cause: error })\n\t}\n\tconst deployedByName = new Map(beforeSchema.map((table) => [table.name, table]))\n\tconst declaredByName = new Map(targetSchema.map((table) => [table.name, table]))\n\n\tconst steps: MigrationStep[] = []\n\n\tfor (const table of beforeSchema) {\n\t\tif (!declaredByName.has(table.name))\n\t\t\tsteps.push({ operation: 'table.remove', table: table.name })\n\t}\n\tfor (const table of targetSchema) {\n\t\tif (!deployedByName.has(table.name)) steps.push({ operation: 'table.add', table })\n\t}\n\n\tfor (const table of targetSchema) {\n\t\tconst before = deployedByName.get(table.name)\n\t\tif (before === undefined) continue\n\t\tif (before.primary !== table.primary) {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'MIGRATION',\n\t\t\t\t`planMigration: primary column on table '${table.name}' changed from '${before.primary}' to '${table.primary}'`,\n\t\t\t\t{ table: table.name, from: before.primary, to: table.primary },\n\t\t\t)\n\t\t}\n\n\t\tconst beforeColumnMap = new Map(before.columns.map((column) => [column.name, column]))\n\t\tconst afterColumnMap = new Map(table.columns.map((column) => [column.name, column]))\n\n\t\tfor (const index of before.indexes) {\n\t\t\tif (!table.indexes.some((candidate) => equalsValue(candidate, index))) {\n\t\t\t\tsteps.push({ operation: 'index.remove', table: table.name, index })\n\t\t\t}\n\t\t}\n\t\tfor (const column of before.columns) {\n\t\t\tif (!afterColumnMap.has(column.name)) {\n\t\t\t\tsteps.push({ operation: 'column.remove', table: table.name, column: column.name })\n\t\t\t}\n\t\t}\n\t\tfor (const column of table.columns) {\n\t\t\tconst previous = beforeColumnMap.get(column.name)\n\t\t\tif (previous === undefined) {\n\t\t\t\tsteps.push({ operation: 'column.add', table: table.name, column })\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (\n\t\t\t\tprevious.storage !== column.storage ||\n\t\t\t\tprevious.optional !== column.optional ||\n\t\t\t\tprevious.nullable !== column.nullable\n\t\t\t) {\n\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t'MIGRATION',\n\t\t\t\t\t`planMigration: column '${column.name}' on table '${table.name}' changed shape ` +\n\t\t\t\t\t\t`(storage ${previous.storage}→${column.storage}, optional ${previous.optional}→${column.optional}, nullable ${previous.nullable}→${column.nullable}) — ` +\n\t\t\t\t\t\t`in-place storage/optionality/nullability changes are not auto-migrated; add a new column, copy/convert ` +\n\t\t\t\t\t\t`the data, then remove the old column`,\n\t\t\t\t\t{\n\t\t\t\t\t\ttable: table.name,\n\t\t\t\t\t\tcolumn: column.name,\n\t\t\t\t\t\tfrom: {\n\t\t\t\t\t\t\tstorage: previous.storage,\n\t\t\t\t\t\t\toptional: previous.optional,\n\t\t\t\t\t\t\tnullable: previous.nullable,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tto: {\n\t\t\t\t\t\t\tstorage: column.storage,\n\t\t\t\t\t\t\toptional: column.optional,\n\t\t\t\t\t\t\tnullable: column.nullable,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tfor (const index of table.indexes) {\n\t\t\tif (!before.indexes.some((candidate) => equalsValue(candidate, index))) {\n\t\t\t\tsteps.push({ operation: 'index.add', table: table.name, index })\n\t\t\t}\n\t\t}\n\t}\n\n\tconst projected = projectMigrationSchema(beforeSchema, steps)\n\tif (!equalsValue(projected, targetSchema)) {\n\t\tthrow new DatabaseError('MIGRATION', 'Migration plan does not project to the declared schema', {\n\t\t\tprojected,\n\t\t\tdeclared: targetSchema,\n\t\t})\n\t}\n\treturn cloneMigrationInput({ plan: { from, to, steps } }).plan\n}\n\n/**\n * Sequentially project migration steps over a canonical validated owned schema.\n * Adding a required non-null column to an existing table rejects with\n * `MIGRATION`; optional-only and nullable-only additions remain portable.\n *\n * @param schema - The initial deployed schema\n * @param steps - The ordered migration steps\n * @returns A fresh owned final schema\n */\nexport function projectMigrationSchema(\n\tschema: readonly TableSchema[],\n\tsteps: readonly MigrationStep[],\n): readonly TableSchema[] {\n\tlet owned: readonly TableSchema[]\n\tlet projectedSteps: readonly MigrationStep[]\n\ttry {\n\t\towned = normalizeDriverSchema(schema)\n\t\tprojectedSteps = cloneMigrationInput({ plan: { from: 0, to: 1, steps } }).plan.steps\n\t} catch (error) {\n\t\tthrow new DatabaseError('MIGRATION', 'Migration input is invalid', { cause: error })\n\t}\n\tconst tables = new Map(owned.map((table) => [table.name, table]))\n\tfor (const step of projectedSteps) {\n\t\tif (step.operation === 'table.add') {\n\t\t\tif (tables.has(step.table.name)) {\n\t\t\t\tthrow new DatabaseError('MIGRATION', `migrate: table '${step.table.name}' already exists`, {\n\t\t\t\t\ttable: step.table.name,\n\t\t\t\t})\n\t\t\t}\n\t\t\ttables.set(step.table.name, step.table)\n\t\t\tcontinue\n\t\t}\n\t\tconst table = tables.get(step.table)\n\t\tif (table === undefined) {\n\t\t\tthrow new DatabaseError('MIGRATION', `migrate: table '${step.table}' does not exist`, {\n\t\t\t\ttable: step.table,\n\t\t\t})\n\t\t}\n\t\tif (step.operation === 'table.remove') {\n\t\t\ttables.delete(step.table)\n\t\t\tcontinue\n\t\t}\n\t\tif (step.operation === 'column.add') {\n\t\t\tif (table.columns.some((column) => column.name === step.column.name)) {\n\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t'MIGRATION',\n\t\t\t\t\t`migrate: column '${step.column.name}' already exists`,\n\t\t\t\t\t{ table: step.table, column: step.column.name },\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (!step.column.optional && !step.column.nullable) {\n\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t'MIGRATION',\n\t\t\t\t\t`migrate: required non-null column '${step.column.name}' cannot be added automatically to existing table '${step.table}'`,\n\t\t\t\t\t{ table: step.table, column: step.column.name },\n\t\t\t\t)\n\t\t\t}\n\t\t\ttables.set(step.table, { ...table, columns: [...table.columns, step.column] })\n\t\t\tcontinue\n\t\t}\n\t\tif (step.operation === 'column.remove') {\n\t\t\tif (!table.columns.some((column) => column.name === step.column)) {\n\t\t\t\tthrow new DatabaseError('MIGRATION', `migrate: column '${step.column}' does not exist`, {\n\t\t\t\t\ttable: step.table,\n\t\t\t\t\tcolumn: step.column,\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (table.primary === step.column) {\n\t\t\t\tthrow new DatabaseError('MIGRATION', 'migrate: cannot remove the primary column', {\n\t\t\t\t\ttable: step.table,\n\t\t\t\t\tcolumn: step.column,\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (table.indexes.some((index) => index.includes(step.column))) {\n\t\t\t\tthrow new DatabaseError('MIGRATION', 'migrate: cannot remove an indexed column', {\n\t\t\t\t\ttable: step.table,\n\t\t\t\t\tcolumn: step.column,\n\t\t\t\t})\n\t\t\t}\n\t\t\ttables.set(step.table, {\n\t\t\t\t...table,\n\t\t\t\tcolumns: table.columns.filter((column) => column.name !== step.column),\n\t\t\t})\n\t\t\tcontinue\n\t\t}\n\t\tif (step.operation === 'index.add') {\n\t\t\tif (\n\t\t\t\tstep.index.length === 0 ||\n\t\t\t\tstep.index.some((name) => !table.columns.some((column) => column.name === name))\n\t\t\t) {\n\t\t\t\tthrow new DatabaseError('MIGRATION', 'migrate: index references a missing column', {\n\t\t\t\t\ttable: step.table,\n\t\t\t\t\tindex: step.index,\n\t\t\t\t})\n\t\t\t}\n\t\t\tif (table.indexes.some((index) => equalsValue(index, step.index))) {\n\t\t\t\tthrow new DatabaseError('MIGRATION', 'migrate: index already exists', {\n\t\t\t\t\ttable: step.table,\n\t\t\t\t\tindex: step.index,\n\t\t\t\t})\n\t\t\t}\n\t\t\ttables.set(step.table, { ...table, indexes: [...table.indexes, step.index] })\n\t\t\tcontinue\n\t\t}\n\t\tif (!table.indexes.some((index) => equalsValue(index, step.index))) {\n\t\t\tthrow new DatabaseError('MIGRATION', 'migrate: index does not exist', {\n\t\t\t\ttable: step.table,\n\t\t\t\tindex: step.index,\n\t\t\t})\n\t\t}\n\t\ttables.set(step.table, {\n\t\t\t...table,\n\t\t\tindexes: table.indexes.filter((index) => !equalsValue(index, step.index)),\n\t\t})\n\t}\n\ttry {\n\t\treturn normalizeDriverSchema([...tables.values()])\n\t} catch (error) {\n\t\tthrow new DatabaseError('MIGRATION', 'Projected migration schema is invalid', { cause: error })\n\t}\n}\n\n/**\n * Canonicalize an unknown driver schema into a distinct deeply frozen snapshot.\n *\n * @remarks\n * Table and column lists are sorted by name. The index list is sorted by the\n * complete serialized tuple while column order inside each compound index is\n * preserved because it carries index semantics. Validation and ownership flow\n * through {@link cloneDriverSchema} before and after projection.\n *\n * @param value - Unknown driver schema\n * @returns A validated, owned canonical schema\n */\nexport function normalizeDriverSchema(value: unknown): readonly TableSchema[] {\n\tconst owned = cloneDriverSchema(value)\n\tconst tables = owned.map((table) => ({\n\t\tname: table.name,\n\t\tprimary: table.primary,\n\t\tcolumns: [...table.columns].sort((left, right) => compareValues(left.name, right.name)),\n\t\tindexes: [...table.indexes].sort((left, right) =>\n\t\t\tcompareValues(JSON.stringify(left), JSON.stringify(right)),\n\t\t),\n\t}))\n\ttables.sort((left, right) => compareValues(left.name, right.name))\n\treturn cloneDriverSchema(tables)\n}\n\n/**\n * Apply one table's {@link MigrationStep}s to its rows — a pure row transform.\n *\n * @remarks\n * `column.remove` drops that field from every row (a fresh copy — inputs are\n * never mutated, AGENTS §11); `column.add` leaves rows as-is (an absent field\n * reads as `undefined`, backfill is application policy). `table.add` /\n * `table.remove` / `index.add` / `index.remove` are no-ops here (they operate\n * on storage shape, not row shape). Steps for tables other than the one\n * `rows` belongs to are ignored — pass only the steps relevant to this table.\n *\n * @param rows - The table's current rows\n * @param steps - The migration steps to apply (typically one table's slice of a {@link Migration})\n * @returns A new array of transformed rows; `rows` is never mutated\n *\n * @example\n * ```ts\n * const rows = [{ id: 'a', name: 'Ada', legacy: true }]\n * migrateRows(rows, [{ operation: 'column.remove', table: 'users', column: 'legacy' }])\n * // => [{ id: 'a', name: 'Ada' }]\n * ```\n */\nexport function migrateRows(rows: readonly Row[], steps: readonly MigrationStep[]): readonly Row[] {\n\tconst removed = steps\n\t\t.filter(\n\t\t\t(step): step is Extract<MigrationStep, { operation: 'column.remove' }> =>\n\t\t\t\tstep.operation === 'column.remove',\n\t\t)\n\t\t.map((step) => step.column)\n\n\tif (removed.length === 0) return rows.map((row) => ({ ...row }))\n\n\treturn rows.map((row) => {\n\t\tconst next: Row = {}\n\t\tfor (const key of Object.keys(row)) {\n\t\t\tif (!removed.includes(key)) next[key] = row[key]\n\t\t}\n\t\treturn next\n\t})\n}\n\n// === Conformance\n\n/**\n * Run the driver-conformance battery against a fresh {@link DriverInterface}\n * per phase, yielding one {@link ConformanceFinding} per violated invariant —\n * the shared invariant suite every backend (in-memory, SQLite, IndexedDB)\n * must uphold to be a drop-in {@link DriverInterface}.\n *\n * @remarks\n * Framework-agnostic: no test-runner or Node imports, only sibling core\n * modules — so it runs equally from a unit test, a smoke script, or a new\n * driver's own README. Opens a fixed two-table schema (`users` keyed by the\n * default `id`, `posts` keyed by a non-id `slug`) and, calling `factory()`\n * fresh for each phase so failures stay isolated, verifies: `open`/`close`;\n * `read` of a missing key returns `undefined`; `write`/`read` round-trip with\n * DEEP copy-in/copy-out isolation (mutating the caller's row — including a\n * NESTED field — after `write`, or a row `read` returns, never perturbs\n * stored state) and upsert-overwrite; simultaneous same-key `insert` calls\n * produce exactly one commit and one `CONFLICT`; pre-aborted `write`,\n * `insert`, and `delete` calls leave storage unchanged; `delete` returns\n * `true` then `false`;\n * `keys`/`scan` yield in ascending key order; `clear` empties only its target\n * table; `snapshot`'s rollback thunk restores pre-snapshot state, including a\n * NESTED field mutated in place on a read-back row between capture and\n * restore; a scoped `snapshot(['users'])` rolls back only the named table,\n * leaving a concurrent mutation to another table intact; a\n * non-`id` primary key (`posts.slug`) round-trips; a nested-object row\n * round-trips structurally (via {@link equalsValue}). The optional surface is\n * presence-gated: when `migrate` exists, a `column.remove` plan strips the\n * column from stored rows and a plan referencing an unknown table throws\n * `DatabaseError` `MIGRATION`; when `stream` exists, it yields only\n * condition-matching rows and honors `offset`/`limit`; when `transaction`\n * exists, `commit` persists and `rollback` restores; when both `metadata` and\n * `stamp` exist, a fresh store's `metadata()` is `undefined`, and after\n * `stamp({ version, schema })`, `metadata()` returns the exact stamped value.\n *\n * Each phase runs within a `try`/`catch`: an EXPECTED mismatch yields a\n * finding built from the assertion, while an UNEXPECTED throw (a driver\n * crash mid-phase) is caught and yielded as a finding too, naming the phase\n * as `check` and carrying the caught error in `context.error` — a broken\n * driver can never escape the battery as an unhandled rejection. Within a\n * phase, the FIRST violated assertion yields and the phase stops (matching\n * the historical fail-fast shape at phase granularity); the generator then\n * moves on to the next phase regardless. Because this is a **generator**,\n * consuming only the first yielded value reproduces true fail-fast (later\n * phases never run) — that is exactly what {@link conformDriver} does.\n *\n * @param factory - Mints a fresh, unopened driver instance (called once per phase)\n * @yields One {@link ConformanceFinding} per violated invariant, in phase order\n *\n * @example\n * ```ts\n * import { createMemoryDriver, driverFindings } from '@orkestrel/database'\n *\n * for await (const finding of driverFindings(() => createMemoryDriver())) {\n * \tconsole.log(finding.check, finding.message)\n * }\n * ```\n */\nexport async function* driverFindings(\n\tfactory: () => DriverInterface,\n): AsyncIterable<ConformanceFinding> {\n\t// Fixed two-table schema every phase opens: `users` keyed by `id` (the\n\t// default primary), `posts` keyed by a non-id `slug` — exercising both\n\t// primary-key shapes in one battery.\n\tconst CONFORMANCE_USERS_SCHEMA: TableSchema = {\n\t\tname: 'users',\n\t\tprimary: 'id',\n\t\tcolumns: [\n\t\t\t{ name: 'id', storage: 'text', optional: false, nullable: false },\n\t\t\t{ name: 'name', storage: 'text', optional: false, nullable: false },\n\t\t\t{ name: 'age', storage: 'integer', optional: true, nullable: false },\n\t\t\t// Declared so the nested-roundtrip phase is fair to typed-column\n\t\t\t// backends (a SQL driver persists only declared columns; schemaless\n\t\t\t// backends ignore declarations entirely).\n\t\t\t{ name: 'meta', storage: 'json', optional: true, nullable: false },\n\t\t],\n\t\tindexes: [],\n\t}\n\tconst CONFORMANCE_POSTS_SCHEMA: TableSchema = {\n\t\tname: 'posts',\n\t\tprimary: 'slug',\n\t\tcolumns: [\n\t\t\t{ name: 'slug', storage: 'text', optional: false, nullable: false },\n\t\t\t{ name: 'title', storage: 'text', optional: false, nullable: false },\n\t\t],\n\t\tindexes: [],\n\t}\n\tconst CONFORMANCE_SCHEMA: readonly TableSchema[] = [\n\t\tCONFORMANCE_USERS_SCHEMA,\n\t\tCONFORMANCE_POSTS_SCHEMA,\n\t]\n\t// a. open with the inline two-table schema, then close cleanly.\n\ttry {\n\t\tconst driver = factory()\n\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\tawait driver.close()\n\t} catch (error) {\n\t\tyield {\n\t\t\tcheck: 'open-close',\n\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\tcontext: { error },\n\t\t}\n\t}\n\n\t// b. read of a missing key -> undefined.\n\ttry {\n\t\tconst driver = factory()\n\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\tconst missing = await driver.read('users', 'nope')\n\t\tawait driver.close()\n\t\tif (missing !== undefined) {\n\t\t\tyield {\n\t\t\t\tcheck: 'read-missing',\n\t\t\t\tmessage: 'read of a missing key must return undefined',\n\t\t\t\tcontext: { table: 'users', expected: undefined, actual: missing },\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tyield {\n\t\t\tcheck: 'read-missing',\n\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\tcontext: { error },\n\t\t}\n\t}\n\n\t// c. write/read round-trip, copy-in/copy-out isolation (including NESTED\n\t// fields, not just top-level ones), upsert-overwrite.\n\twriteRead: {\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\tconst input: Row = { id: 'caller', name: 'Ada', age: 30, meta: { tags: ['a'] } }\n\t\t\tawait driver.write('users', 'u1', input)\n\t\t\tinput.name = 'Mutated after write'\n\t\t\tif (isRecord(input.meta) && Array.isArray(input.meta.tags)) input.meta.tags.push('mutated')\n\t\t\tconst stored = await driver.read('users', 'u1')\n\t\t\tconst original = { id: 'u1', name: 'Ada', age: 30, meta: { tags: ['a'] } }\n\t\t\tif (stored === undefined || !equalsValue(stored, original)) {\n\t\t\t\tawait driver.close()\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'copy-in',\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t'write must deep-copy the input row (including nested fields) rather than store it by reference',\n\t\t\t\t\tcontext: { table: 'users', expected: original, actual: stored },\n\t\t\t\t}\n\t\t\t\tbreak writeRead\n\t\t\t}\n\t\t\tstored.name = 'Mutated after read'\n\t\t\tif (isRecord(stored.meta) && Array.isArray(stored.meta.tags)) stored.meta.tags.push('mutated')\n\t\t\tconst reread = await driver.read('users', 'u1')\n\t\t\tif (reread === undefined || !equalsValue(reread, original)) {\n\t\t\t\tawait driver.close()\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'copy-out',\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t'read must deep-copy the stored row (including nested fields) rather than return it by reference',\n\t\t\t\t\tcontext: { table: 'users', expected: original, actual: reread },\n\t\t\t\t}\n\t\t\t\tbreak writeRead\n\t\t\t}\n\t\t\tconst overwrite = { id: 'caller', name: 'Ada Overwritten', age: 31 }\n\t\t\tawait driver.write('users', 'u1', overwrite)\n\t\t\tconst overwritten = await driver.read('users', 'u1')\n\t\t\tawait driver.close()\n\t\t\tconst expectedOverwrite = { ...overwrite, id: 'u1' }\n\t\t\tif (overwritten === undefined || !equalsValue(overwritten, expectedOverwrite)) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'upsert',\n\t\t\t\t\tmessage: 'write must upsert-overwrite an existing key',\n\t\t\t\t\tcontext: { table: 'users', expected: expectedOverwrite, actual: overwritten },\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'write-read',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n\n\t// c2. insert is atomic: concurrent duplicates produce one commit and one CONFLICT.\n\t{\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\tconst outcomes = await Promise.allSettled([\n\t\t\t\tdriver.insert('users', 'u1', { id: 'u1', name: 'Ada', age: 30 }),\n\t\t\t\tdriver.insert('users', 'u1', { id: 'u1', name: 'Grace', age: 40 }),\n\t\t\t])\n\t\t\tlet fulfilled = 0\n\t\t\tlet conflicted = 0\n\t\t\tfor (const outcome of outcomes) {\n\t\t\t\tif (outcome.status === 'fulfilled') fulfilled += 1\n\t\t\t\telse if (isDatabaseError(outcome.reason) && outcome.reason.code === 'CONFLICT') {\n\t\t\t\t\tconflicted += 1\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst keys = await driver.keys('users')\n\t\t\tawait driver.close()\n\t\t\tif (fulfilled !== 1 || conflicted !== 1 || !equalsValue(keys, ['u1'])) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'insert-atomic',\n\t\t\t\t\tmessage: 'concurrent same-key inserts must produce one commit and one CONFLICT',\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\texpected: { fulfilled: 1, conflicted: 1, keys: ['u1'] },\n\t\t\t\t\t\tactual: { fulfilled, conflicted, keys },\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'insert-atomic',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n\n\t// d. delete -> true then false.\n\tdeletePhase: {\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\tawait driver.write('users', 'u1', { id: 'u1', name: 'Ada', age: 30 })\n\t\t\tconst first = await driver.delete('users', 'u1')\n\t\t\tif (first !== true) {\n\t\t\t\tawait driver.close()\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'delete-true',\n\t\t\t\t\tmessage: 'delete of an existing key must return true',\n\t\t\t\t\tcontext: { table: 'users', expected: true, actual: first },\n\t\t\t\t}\n\t\t\t\tbreak deletePhase\n\t\t\t}\n\t\t\tconst second = await driver.delete('users', 'u1')\n\t\t\tawait driver.close()\n\t\t\tif (second !== false) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'delete-false',\n\t\t\t\t\tmessage: 'delete of an already-removed key must return false',\n\t\t\t\t\tcontext: { table: 'users', expected: false, actual: second },\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'delete',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n\n\t// d2. pre-aborted point mutations reject as ABORTED without changing rows.\n\ttry {\n\t\tconst driver = factory()\n\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\tawait driver.write('users', 'u1', { id: 'u1', name: 'Ada', age: 30 })\n\t\tconst controller = new AbortController()\n\t\tcontroller.abort('conformance abort')\n\t\tlet writeError: unknown\n\t\tlet insertError: unknown\n\t\tlet deleteError: unknown\n\t\ttry {\n\t\t\tawait driver.write(\n\t\t\t\t'users',\n\t\t\t\t'u2',\n\t\t\t\t{ id: 'u2', name: 'Grace', age: 40 },\n\t\t\t\t{ signal: controller.signal },\n\t\t\t)\n\t\t} catch (error) {\n\t\t\twriteError = error\n\t\t}\n\t\ttry {\n\t\t\tawait driver.insert(\n\t\t\t\t'users',\n\t\t\t\t'u2',\n\t\t\t\t{ id: 'u2', name: 'Grace', age: 40 },\n\t\t\t\t{ signal: controller.signal },\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tinsertError = error\n\t\t}\n\t\ttry {\n\t\t\tawait driver.delete('users', 'u1', { signal: controller.signal })\n\t\t} catch (error) {\n\t\t\tdeleteError = error\n\t\t}\n\t\tconst keys = await driver.keys('users')\n\t\tawait driver.close()\n\t\tif (\n\t\t\t!isDatabaseError(writeError) ||\n\t\t\twriteError.code !== 'ABORTED' ||\n\t\t\t!isDatabaseError(insertError) ||\n\t\t\tinsertError.code !== 'ABORTED' ||\n\t\t\t!isDatabaseError(deleteError) ||\n\t\t\tdeleteError.code !== 'ABORTED' ||\n\t\t\t!equalsValue(keys, ['u1'])\n\t\t) {\n\t\t\tyield {\n\t\t\t\tcheck: 'mutation-abort',\n\t\t\t\tmessage: 'pre-aborted write/insert/delete must reject ABORTED without changing rows',\n\t\t\t\tcontext: {\n\t\t\t\t\texpected: { write: 'ABORTED', insert: 'ABORTED', delete: 'ABORTED', keys: ['u1'] },\n\t\t\t\t\tactual: {\n\t\t\t\t\t\twrite: isDatabaseError(writeError) ? writeError.code : writeError,\n\t\t\t\t\t\tinsert: isDatabaseError(insertError) ? insertError.code : insertError,\n\t\t\t\t\t\tdelete: isDatabaseError(deleteError) ? deleteError.code : deleteError,\n\t\t\t\t\t\tkeys,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tyield {\n\t\t\tcheck: 'mutation-abort',\n\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\tcontext: { error },\n\t\t}\n\t}\n\n\t// e. keys and scan in ascending key order.\n\torderPhase: {\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\tconst rows = [\n\t\t\t\t{ id: 'c', name: 'C', age: 3 },\n\t\t\t\t{ id: 'a', name: 'A', age: 1 },\n\t\t\t\t{ id: 'b', name: 'B', age: 2 },\n\t\t\t]\n\t\t\tfor (const row of rows) await driver.write('users', row.id, row)\n\t\t\tconst expected = ['a', 'b', 'c']\n\t\t\tconst keys = [...(await driver.keys('users'))]\n\t\t\tif (!equalsValue(keys, expected)) {\n\t\t\t\tawait driver.close()\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'keys-order',\n\t\t\t\t\tmessage: 'keys must be returned in ascending key order',\n\t\t\t\t\tcontext: { table: 'users', expected, actual: keys },\n\t\t\t\t}\n\t\t\t\tbreak orderPhase\n\t\t\t}\n\t\t\tconst scanned: Row[] = []\n\t\t\tfor await (const row of driver.scan('users')) scanned.push(row)\n\t\t\tconst scannedIds = scanned.map((row) => row.id)\n\t\t\tawait driver.close()\n\t\t\tif (!equalsValue(scannedIds, expected)) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'scan-order',\n\t\t\t\t\tmessage: 'scan must yield rows in ascending key order',\n\t\t\t\t\tcontext: { table: 'users', expected, actual: scannedIds },\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'order',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n\n\t// f. clear empties only the targeted table.\n\tclearPhase: {\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\tawait driver.write('users', 'u1', { id: 'u1', name: 'Ada', age: 30 })\n\t\t\tawait driver.write('posts', 'p1', { slug: 'p1', title: 'Post' })\n\t\t\tawait driver.clear('users')\n\t\t\tconst usersKeys = await driver.keys('users')\n\t\t\tconst postsKeys = await driver.keys('posts')\n\t\t\tawait driver.close()\n\t\t\tif (usersKeys.length !== 0) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'clear-target',\n\t\t\t\t\tmessage: 'clear must empty the targeted table',\n\t\t\t\t\tcontext: { table: 'users', expected: [], actual: usersKeys },\n\t\t\t\t}\n\t\t\t\tbreak clearPhase\n\t\t\t}\n\t\t\tif (postsKeys.length !== 1) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'clear-other',\n\t\t\t\t\tmessage: 'clear must not affect other tables',\n\t\t\t\t\tcontext: { table: 'posts', expected: 1, actual: postsKeys.length },\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'clear',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n\n\t// g. snapshot rollback restores pre-snapshot state.\n\tsnapshotPhase: {\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\tconst original = { id: 'u1', name: 'Ada', age: 30 }\n\t\t\tawait driver.write('users', 'u1', original)\n\t\t\tconst rollback = await driver.snapshot()\n\t\t\tawait driver.write('users', 'u2', { id: 'u2', name: 'Grace', age: 40 })\n\t\t\tawait driver.delete('users', 'u1')\n\t\t\tawait rollback()\n\t\t\tconst keys = [...(await driver.keys('users'))]\n\t\t\tif (!equalsValue(keys, ['u1'])) {\n\t\t\t\tawait driver.close()\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'snapshot-rollback',\n\t\t\t\t\tmessage: 'snapshot rollback must restore the pre-snapshot key set',\n\t\t\t\t\tcontext: { table: 'users', expected: ['u1'], actual: keys },\n\t\t\t\t}\n\t\t\t\tbreak snapshotPhase\n\t\t\t}\n\t\t\tconst restored = await driver.read('users', 'u1')\n\t\t\tawait driver.close()\n\t\t\tif (restored === undefined || !equalsValue(restored, original)) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'snapshot-rollback-value',\n\t\t\t\t\tmessage: 'snapshot rollback must restore pre-snapshot row values',\n\t\t\t\t\tcontext: { table: 'users', expected: original, actual: restored },\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'snapshot',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n\n\t// g2. snapshot rollback survives a nested field mutated between capture and restore.\n\ttry {\n\t\tconst driver = factory()\n\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\tconst original = { id: 'u3', name: 'Nested', age: 20, meta: { tags: ['a'] } }\n\t\tawait driver.write('users', 'u3', original)\n\t\tconst rollback = await driver.snapshot()\n\t\tconst before = await driver.read('users', 'u3')\n\t\tif (isRecord(before) && isRecord(before.meta) && Array.isArray(before.meta.tags)) {\n\t\t\tbefore.meta.tags.push('mutated-before-restore')\n\t\t}\n\t\tawait driver.write('users', 'u3', {\n\t\t\tid: 'u3',\n\t\t\tname: 'Nested',\n\t\t\tage: 20,\n\t\t\tmeta: { tags: ['a', 'mutated-after-write'] },\n\t\t})\n\t\tawait rollback()\n\t\tconst restored = await driver.read('users', 'u3')\n\t\tawait driver.close()\n\t\tif (restored === undefined || !equalsValue(restored, original)) {\n\t\t\tyield {\n\t\t\t\tcheck: 'snapshot-nested',\n\t\t\t\tmessage:\n\t\t\t\t\t'snapshot rollback must restore pre-snapshot nested field values, unaffected by a later in-place mutation of a read-back row',\n\t\t\t\tcontext: { table: 'users', expected: original, actual: restored },\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tyield {\n\t\t\tcheck: 'snapshot-nested',\n\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\tcontext: { error },\n\t\t}\n\t}\n\n\t// h. non-id primary extraction (posts keyed by slug).\n\ttry {\n\t\tconst driver = factory()\n\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\tawait driver.write('posts', 'hello-world', { slug: 'caller', title: 'Hello' })\n\t\tconst post = await driver.read('posts', 'hello-world')\n\t\tconst key = post === undefined ? undefined : extractKey(post, 'slug')\n\t\tawait driver.close()\n\t\tif (key !== 'hello-world') {\n\t\t\tyield {\n\t\t\t\tcheck: 'non-id-primary',\n\t\t\t\tmessage: 'a non-id primary key column must round-trip through the store',\n\t\t\t\tcontext: { table: 'posts', expected: 'hello-world', actual: key },\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tyield {\n\t\t\tcheck: 'non-id-primary',\n\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\tcontext: { error },\n\t\t}\n\t}\n\n\t// i. nested-object row round-trip (structural, via equalsValue).\n\ttry {\n\t\tconst driver = factory()\n\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\tconst nested = {\n\t\t\tid: 'u3',\n\t\t\tname: 'Nested',\n\t\t\tage: 20,\n\t\t\tmeta: { tags: ['a', 'b'], deep: { flag: true } },\n\t\t}\n\t\tawait driver.write('users', 'u3', nested)\n\t\tconst readBack = await driver.read('users', 'u3')\n\t\tawait driver.close()\n\t\tif (readBack === undefined || !equalsValue(readBack, nested)) {\n\t\t\tyield {\n\t\t\t\tcheck: 'nested-roundtrip',\n\t\t\t\tmessage: 'a nested-object row must round-trip structurally',\n\t\t\t\tcontext: { table: 'users', expected: nested, actual: readBack },\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tyield {\n\t\t\tcheck: 'nested-roundtrip',\n\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\tcontext: { error },\n\t\t}\n\t}\n\n\t// j. migrate (presence-gated): column.remove strips rows; unknown tables fail.\n\tmigratePhase: {\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tif (driver.migrate === undefined) break migratePhase\n\t\t\tconst deployedUsers: TableSchema = {\n\t\t\t\t...CONFORMANCE_USERS_SCHEMA,\n\t\t\t\tcolumns: [\n\t\t\t\t\t...CONFORMANCE_USERS_SCHEMA.columns,\n\t\t\t\t\t{ name: 'legacy', storage: 'boolean', optional: true, nullable: false },\n\t\t\t\t],\n\t\t\t}\n\t\t\tawait driver.open([deployedUsers, CONFORMANCE_POSTS_SCHEMA])\n\t\t\tawait driver.write('users', 'u1', { id: 'u1', name: 'Ada', age: 30, legacy: true })\n\t\t\tconst removePlan = planMigration([deployedUsers], [CONFORMANCE_USERS_SCHEMA])\n\t\t\tawait driver.migrate({ plan: removePlan })\n\t\t\tconst migrated = await driver.read('users', 'u1')\n\t\t\tif (migrated === undefined || 'legacy' in migrated) {\n\t\t\t\tawait driver.close()\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'migrate-column-remove',\n\t\t\t\t\tmessage: 'a column.remove migration must strip the column from stored rows',\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\ttable: 'users',\n\t\t\t\t\t\texpected: undefined,\n\t\t\t\t\t\tactual: migrated === undefined ? undefined : migrated.legacy,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tbreak migratePhase\n\t\t\t}\n\t\t\tlet caught: unknown\n\t\t\ttry {\n\t\t\t\tawait driver.migrate({\n\t\t\t\t\tplan: {\n\t\t\t\t\t\tfrom: 0,\n\t\t\t\t\t\tto: 1,\n\t\t\t\t\t\tsteps: [{ operation: 'table.remove', table: 'ghost' }],\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tcaught = error\n\t\t\t}\n\t\t\tawait driver.close()\n\t\t\tif (!isDatabaseError(caught) || caught.code !== 'MIGRATION') {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'migrate-unknown-table',\n\t\t\t\t\tmessage:\n\t\t\t\t\t\t'a migration step referencing an unknown table must throw a MIGRATION DatabaseError',\n\t\t\t\t\tcontext: {\n\t\t\t\t\t\ttable: 'ghost',\n\t\t\t\t\t\texpected: 'MIGRATION',\n\t\t\t\t\t\tactual: isDatabaseError(caught) ? caught.code : caught,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'migrate',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n\n\t// k. stream (presence-gated): condition matching and paging.\n\tstreamPhase: {\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tif (driver.stream === undefined) break streamPhase\n\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\tconst rows = [\n\t\t\t\t{ id: 'a', name: 'A', age: 10 },\n\t\t\t\t{ id: 'b', name: 'B', age: 20 },\n\t\t\t\t{ id: 'c', name: 'C', age: 30 },\n\t\t\t]\n\t\t\tfor (const row of rows) await driver.write('users', row.id, row)\n\t\t\tconst input: QueryInput = {\n\t\t\t\tconditions: [{ column: 'age', operator: 'above', values: [10], connector: 'and' }],\n\t\t\t}\n\t\t\tconst matched: Row[] = []\n\t\t\tfor await (const row of driver.stream('users', input)) matched.push(row)\n\t\t\tconst matchedIds = matched.map((row) => row.id).sort()\n\t\t\tif (!equalsValue(matchedIds, ['b', 'c'])) {\n\t\t\t\tawait driver.close()\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'stream-match',\n\t\t\t\t\tmessage: 'stream must yield only condition-matching rows',\n\t\t\t\t\tcontext: { table: 'users', expected: ['b', 'c'], actual: matchedIds },\n\t\t\t\t}\n\t\t\t\tbreak streamPhase\n\t\t\t}\n\t\t\tconst paged: Row[] = []\n\t\t\tfor await (const row of driver.stream('users', { offset: 1, limit: 1 })) paged.push(row)\n\t\t\tawait driver.close()\n\t\t\tif (paged.length !== 1) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'stream-page',\n\t\t\t\t\tmessage: 'stream must honor offset and limit',\n\t\t\t\t\tcontext: { table: 'users', expected: 1, actual: paged.length },\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'stream',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n\n\t// l. transaction (presence-gated): commit persists, rollback restores.\n\ttransactionPhase: {\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tif (driver.transaction === undefined) break transactionPhase\n\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\tawait driver.write('users', 'u1', { id: 'u1', name: 'Ada', age: 30 })\n\t\t\tawait driver.transaction(async (transaction) => {\n\t\t\t\tawait transaction.write('users', 'u2', { id: 'u2', name: 'Grace', age: 40 })\n\t\t\t})\n\t\t\tconst afterCommit = [...(await driver.keys('users'))].sort()\n\t\t\tif (!equalsValue(afterCommit, ['u1', 'u2'])) {\n\t\t\t\tawait driver.close()\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'transaction-commit',\n\t\t\t\t\tmessage: 'transaction commit must persist writes made during the scope',\n\t\t\t\t\tcontext: { table: 'users', expected: ['u1', 'u2'], actual: afterCommit },\n\t\t\t\t}\n\t\t\t\tbreak transactionPhase\n\t\t\t}\n\t\t\tconst reason = {}\n\t\t\ttry {\n\t\t\t\tawait driver.transaction(async (transaction) => {\n\t\t\t\t\tawait transaction.write('users', 'u3', { id: 'u3', name: 'Marie', age: 50 })\n\t\t\t\t\tthrow reason\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tif (error !== reason) throw error\n\t\t\t}\n\t\t\tconst afterRollback = [...(await driver.keys('users'))].sort()\n\t\t\tawait driver.close()\n\t\t\tif (!equalsValue(afterRollback, ['u1', 'u2'])) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'transaction-rollback',\n\t\t\t\t\tmessage: 'transaction rollback must restore pre-transaction state',\n\t\t\t\t\tcontext: { table: 'users', expected: ['u1', 'u2'], actual: afterRollback },\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'transaction',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n\n\t// m. metadata/stamp (presence-gated): fresh is undefined; stamp round-trips.\n\tmetadataPhase: {\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tif (driver.metadata === undefined || driver.stamp === undefined) break metadataPhase\n\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\tconst fresh = await driver.metadata()\n\t\t\tif (fresh !== undefined) {\n\t\t\t\tawait driver.close()\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'metadata-fresh',\n\t\t\t\t\tmessage: 'a fresh store must report undefined metadata',\n\t\t\t\t\tcontext: { expected: undefined, actual: fresh },\n\t\t\t\t}\n\t\t\t\tbreak metadataPhase\n\t\t\t}\n\t\t\tconst stamped = { version: 1, schema: CONFORMANCE_SCHEMA }\n\t\t\tawait driver.stamp(stamped)\n\t\t\tconst read = await driver.metadata()\n\t\t\tawait driver.close()\n\t\t\tif (read === undefined || !equalsValue(read, stamped)) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'metadata-stamp',\n\t\t\t\t\tmessage: 'metadata() must return exactly the last-stamped value',\n\t\t\t\t\tcontext: { expected: stamped, actual: read },\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'metadata-stamp',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n\n\t// n. scoped snapshot rolls back only the named table.\n\tscopedPhase: {\n\t\ttry {\n\t\t\tconst driver = factory()\n\t\t\tawait driver.open(CONFORMANCE_SCHEMA)\n\t\t\tconst original = { id: 'u1', name: 'Ada', age: 30 }\n\t\t\tawait driver.write('users', 'u1', original)\n\t\t\tawait driver.write('posts', 'p1', { slug: 'p1', title: 'Post' })\n\t\t\tconst rollback = await driver.snapshot(['users'])\n\t\t\tawait driver.write('users', 'u2', { id: 'u2', name: 'Grace', age: 40 })\n\t\t\tawait driver.write('posts', 'p2', { slug: 'p2', title: 'Another post' })\n\t\t\tawait rollback()\n\t\t\tconst usersKeys = [...(await driver.keys('users'))]\n\t\t\tif (!equalsValue(usersKeys, ['u1'])) {\n\t\t\t\tawait driver.close()\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'snapshot-scoped-users',\n\t\t\t\t\tmessage: 'a scoped snapshot must roll back only the named table',\n\t\t\t\t\tcontext: { table: 'users', expected: ['u1'], actual: usersKeys },\n\t\t\t\t}\n\t\t\t\tbreak scopedPhase\n\t\t\t}\n\t\t\tconst postsKeys = [...(await driver.keys('posts'))].sort()\n\t\t\tawait driver.close()\n\t\t\tif (!equalsValue(postsKeys, ['p1', 'p2'])) {\n\t\t\t\tyield {\n\t\t\t\t\tcheck: 'snapshot-scoped-posts',\n\t\t\t\t\tmessage: \"a scoped snapshot must leave an unnamed table's mutations intact\",\n\t\t\t\t\tcontext: { table: 'posts', expected: ['p1', 'p2'], actual: postsKeys },\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tyield {\n\t\t\t\tcheck: 'snapshot-scoped',\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcontext: { error },\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Run the driver-conformance battery, throwing on the first violated\n * invariant — the fail-fast entry point most callers (test setup, CI smoke\n * checks) want.\n *\n * @remarks\n * A thin driver over {@link driverFindings}: because that generator is\n * lazy, consuming only its first yielded value means every LATER phase\n * never runs — true fail-fast, not merely \"report only the first\". The\n * thrown error is byte-compatible with the historical shape: a\n * `CONFORMANCE` {@link DatabaseError} whose `message` is the finding's\n * `message` and whose `context` is `{ check, ...finding.context }`.\n *\n * @param factory - Mints a fresh, unopened driver instance (called once per phase)\n * @returns Nothing — resolves once every phase has passed\n * @throws A `CONFORMANCE` {@link DatabaseError} on the first violated invariant\n *\n * @example\n * ```ts\n * import { conformDriver, createMemoryDriver } from '@orkestrel/database'\n *\n * await conformDriver(() => createMemoryDriver()) // resolves when every invariant holds\n * ```\n */\nexport async function conformDriver(factory: () => DriverInterface): Promise<void> {\n\tfor await (const finding of driverFindings(factory)) {\n\t\tthrow new DatabaseError('CONFORMANCE', finding.message, {\n\t\t\tcheck: finding.check,\n\t\t\t...finding.context,\n\t\t})\n\t}\n}\n\n/**\n * Run the FULL driver-conformance battery and collect every violation — the\n * audit entry point for a driver author who wants a complete report rather\n * than a single fail-fast throw.\n *\n * @remarks\n * Drains {@link driverFindings} to completion: every phase runs regardless\n * of earlier violations, so a driver breaking two independent invariants\n * reports both. An empty array means the driver is fully conformant.\n *\n * @param factory - Mints a fresh, unopened driver instance (called once per phase)\n * @returns Every violated invariant found, in phase order (empty when fully conformant)\n *\n * @example\n * ```ts\n * import { auditDriver, createMemoryDriver } from '@orkestrel/database'\n *\n * const findings = await auditDriver(() => createMemoryDriver())\n * for (const finding of findings) console.log(`${finding.check}: ${finding.message}`)\n * ```\n */\nexport async function auditDriver(\n\tfactory: () => DriverInterface,\n): Promise<readonly ConformanceFinding[]> {\n\tconst findings: ConformanceFinding[] = []\n\tfor await (const finding of driverFindings(factory)) findings.push(finding)\n\treturn findings\n}\n","import type { TransactionScope } from './TransactionScope.js'\n\n/**\n * The internal continuation boundary for one transaction-scoped async iterable.\n *\n * @remarks\n * Each active continuation enters the owning transaction ledger independently,\n * so an idle iterator never pins settlement. A continuation requested after\n * admission closes rejects while still attempting source cleanup exactly once.\n */\nexport class TransactionIterator<T> implements AsyncIterableIterator<T> {\n\treadonly #source: AsyncIterator<T>\n\treadonly #scope: TransactionScope\n\t#cleaned = false\n\n\tconstructor(source: AsyncIterable<T>, scope: TransactionScope) {\n\t\tthis.#source = source[Symbol.asyncIterator]()\n\t\tthis.#scope = scope\n\t}\n\n\t[Symbol.asyncIterator](): AsyncIterableIterator<T> {\n\t\treturn this\n\t}\n\n\tnext(): Promise<IteratorResult<T>> {\n\t\treturn this.#continue(() => this.#next())\n\t}\n\n\treturn(): Promise<IteratorResult<T>> {\n\t\treturn this.#continue(() => this.#return())\n\t}\n\n\tthrow(error?: unknown): Promise<IteratorResult<T>> {\n\t\treturn this.#continue(() => this.#throw(error))\n\t}\n\n\tasync #next(): Promise<IteratorResult<T>> {\n\t\tif (this.#cleaned) return { done: true, value: undefined }\n\t\tconst result = await this.#source.next()\n\t\tif (result.done === true) this.#cleaned = true\n\t\treturn result\n\t}\n\n\tasync #return(): Promise<IteratorResult<T>> {\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.#source.throw !== undefined) {\n\t\t\tconst result = await this.#source.throw(error)\n\t\t\tif (result.done === true) this.#cleaned = true\n\t\t\treturn result\n\t\t}\n\t\ttry {\n\t\t\tawait this.#return()\n\t\t} catch {}\n\t\tthrow error\n\t}\n\n\t#continue<R>(operation: () => Promise<R>): Promise<R> {\n\t\tif (!this.#scope.accepting) this.#cleanup()\n\t\treturn this.#scope.track(operation)\n\t}\n\n\t#cleanup(): void {\n\t\tif (this.#cleaned) return\n\t\tthis.#cleaned = true\n\t\ttry {\n\t\t\tconst cleanup = this.#source.return?.()\n\t\t\tcleanup?.catch(() => {})\n\t\t} catch {}\n\t}\n}\n","import { DatabaseError } from './errors.js'\nimport { TransactionIterator } from './TransactionIterator.js'\n\n/**\n * The internal lifetime boundary for one database transaction callback.\n *\n * @remarks\n * Promise operations enter synchronously through {@link track}. Closing stops new\n * work while {@link drain} contains every operation already accepted, including\n * work the callback started without awaiting. {@link stream} applies the same\n * boundary to each iterator continuation without retaining an idle iterator.\n */\nexport class TransactionScope {\n\treadonly #operations = new Set<Promise<unknown>>()\n\t#accepting = true\n\t#failed = false\n\t#error: unknown\n\n\tget accepting(): boolean {\n\t\treturn this.#accepting\n\t}\n\n\tcheck(): void {\n\t\tif (!this.#accepting) {\n\t\t\tthrow new DatabaseError('CONFLICT', 'Transaction scope has settled')\n\t\t}\n\t}\n\n\ttrack<R>(operation: () => Promise<R>): Promise<R> {\n\t\ttry {\n\t\t\tthis.check()\n\t\t} catch (error) {\n\t\t\treturn Promise.reject(error)\n\t\t}\n\t\tlet promise: Promise<R>\n\t\ttry {\n\t\t\tpromise = operation()\n\t\t} catch (error) {\n\t\t\tpromise = Promise.reject(error)\n\t\t}\n\t\tthis.#operations.add(promise)\n\t\tpromise.then(\n\t\t\t() => {\n\t\t\t\tthis.#operations.delete(promise)\n\t\t\t},\n\t\t\t(error: unknown) => {\n\t\t\t\tthis.#operations.delete(promise)\n\t\t\t\tif (!this.#failed) {\n\t\t\t\t\tthis.#failed = true\n\t\t\t\t\tthis.#error = error\n\t\t\t\t}\n\t\t\t},\n\t\t)\n\t\treturn promise\n\t}\n\n\tstream<T>(source: AsyncIterable<T>): AsyncIterable<T> {\n\t\treturn new TransactionIterator(source, this)\n\t}\n\n\tstop(): void {\n\t\tthis.#accepting = false\n\t}\n\n\tasync drain(): Promise<void> {\n\t\twhile (this.#operations.size > 0) {\n\t\t\tawait Promise.allSettled(this.#operations)\n\t\t}\n\t\tif (this.#failed) throw this.#error\n\t}\n}\n","import type { Result } from '@orkestrel/contract'\nimport type { EmitterErrorHandler, EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tDatabaseEventMap,\n\tDatabaseOptions,\n\tDatabaseStatus,\n\tDriverInterface,\n\tDriverMetadata,\n\tMigration,\n\tMigrationInput,\n\tOperationOptions,\n\tStorageInterface,\n\tTableSchema,\n} from './types.js'\nimport { Emitter } from '@orkestrel/emitter'\nimport { DatabaseError } from './errors.js'\nimport { checkAbort, equalsValue, normalizeDriverSchema, planMigration } from './helpers.js'\nimport { TransactionScope } from './TransactionScope.js'\n\n/**\n * The internal shared owner behind every typed view of one database.\n *\n * @remarks\n * A context owns the driver, merged physical schema, lifecycle, observation,\n * migration, and single transaction admission. It is deliberately omitted from\n * the public barrel; {@link Database} is the consumer-facing typed view.\n */\nexport class DatabaseContext {\n\treadonly #driver: DriverInterface\n\treadonly #name: string\n\treadonly #version: number | undefined\n\treadonly #error: EmitterErrorHandler | undefined\n\treadonly #emitter: Emitter<DatabaseEventMap>\n\treadonly #operations = new Set<Promise<unknown>>()\n\t#schema: readonly TableSchema[] = []\n\t#transaction: object | undefined\n\t#status: DatabaseStatus = 'idle'\n\t#ready: Promise<void> | undefined\n\t#failure: { readonly error: unknown } | undefined\n\n\tconstructor(options: DatabaseOptions) {\n\t\tthis.#driver = options.driver\n\t\tthis.#name = options.name ?? 'database'\n\t\tthis.#version = options.version\n\t\tthis.#error = options.error\n\t\tthis.#emitter = new Emitter<DatabaseEventMap>({\n\t\t\t...(options.on === undefined ? {} : { on: options.on }),\n\t\t\t...(options.error === undefined ? {} : { error: options.error }),\n\t\t})\n\t}\n\n\tget driver(): DriverInterface {\n\t\treturn this.#driver\n\t}\n\n\tget emitter(): EmitterInterface<DatabaseEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget error(): EmitterErrorHandler | undefined {\n\t\treturn this.#error\n\t}\n\n\tget name(): string {\n\t\treturn this.#name\n\t}\n\n\tget accepting(): boolean {\n\t\treturn this.#status !== 'closed' && this.#transaction === undefined\n\t}\n\n\tget status(): DatabaseStatus {\n\t\treturn this.#status\n\t}\n\n\tget version(): number | undefined {\n\t\treturn this.#version\n\t}\n\n\tregister(schema: readonly TableSchema[]): void {\n\t\tif (this.#status === 'closed') {\n\t\t\tthrow new DatabaseError('CLOSED', `Database '${this.#name}' is closed`, {\n\t\t\t\tname: this.#name,\n\t\t\t})\n\t\t}\n\t\tif (this.#ready !== undefined || this.#transaction !== undefined) {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'CONFLICT',\n\t\t\t\t`Database '${this.#name}' cannot import tables after opening has started`,\n\t\t\t\t{ name: this.#name, status: this.#status },\n\t\t\t)\n\t\t}\n\t\tconst registered = normalizeDriverSchema(schema)\n\t\tconst merged = [...this.#schema]\n\t\tfor (const table of registered) {\n\t\t\tconst existing = merged.find((candidate) => candidate.name === table.name)\n\t\t\tif (existing === undefined) {\n\t\t\t\tmerged.push(table)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!equalsValue(existing, table)) {\n\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t'VALIDATION',\n\t\t\t\t\t`Table '${table.name}' conflicts with its registered schema`,\n\t\t\t\t\t{ table: table.name },\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tthis.#schema = normalizeDriverSchema(merged)\n\t}\n\n\tasync open(): Promise<void> {\n\t\tthis.#outside()\n\t\tawait this.connect()\n\t}\n\n\tasync close(): Promise<void> {\n\t\tthis.#outside()\n\t\tif (this.#status === 'closed') return\n\t\tthis.#status = 'closed'\n\t\tawait this.#drain()\n\t\tconst ready = this.#ready\n\t\tif (ready !== undefined) await ready.catch(() => {})\n\t\tthis.#ready = undefined\n\t\tawait this.#driver.close()\n\t\tthis.#emitter.emit('close')\n\t}\n\n\tconnect(): Promise<void> {\n\t\treturn this.#connect()\n\t}\n\n\ttrack<R>(operation: () => Promise<R>): Promise<R> {\n\t\ttry {\n\t\t\tthis.#admit()\n\t\t} catch (error) {\n\t\t\treturn Promise.reject(error)\n\t\t}\n\t\tlet promise: Promise<R>\n\t\ttry {\n\t\t\tpromise = operation()\n\t\t} catch (error) {\n\t\t\tpromise = Promise.reject(error)\n\t\t}\n\t\tthis.#operations.add(promise)\n\t\tpromise.then(\n\t\t\t() => {\n\t\t\t\tthis.#operations.delete(promise)\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tthis.#operations.delete(promise)\n\t\t\t},\n\t\t)\n\t\treturn promise\n\t}\n\n\tasync transaction<R>(\n\t\tscope: (storage: StorageInterface, lifetime: TransactionScope) => Promise<Result<R, unknown>>,\n\t\toptions?: OperationOptions,\n\t): Promise<R> {\n\t\tcheckAbort(options?.signal)\n\t\tthis.#admit()\n\t\tconst token = {}\n\t\tthis.#transaction = token\n\t\ttry {\n\t\t\tawait this.#drain()\n\t\t\tawait this.#connect()\n\t\t\tif (this.#driver.transaction !== undefined) {\n\t\t\t\tconst rejection: { rejected: boolean; error: unknown; marker: object } = {\n\t\t\t\t\trejected: false,\n\t\t\t\t\terror: undefined,\n\t\t\t\t\tmarker: {},\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tconst value = await this.#driver.transaction(async (storage) => {\n\t\t\t\t\t\tthis.#emitter.emit('transaction')\n\t\t\t\t\t\tconst outcome = await scope(storage, new TransactionScope())\n\t\t\t\t\t\tif (!outcome.success) {\n\t\t\t\t\t\t\trejection.rejected = true\n\t\t\t\t\t\t\trejection.error = outcome.error\n\t\t\t\t\t\t\tthrow rejection.marker\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn outcome.value\n\t\t\t\t\t})\n\t\t\t\t\tthis.#emitter.emit('commit')\n\t\t\t\t\treturn value\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (rejection.rejected) {\n\t\t\t\t\t\tif (Object.is(error, rejection.marker)) {\n\t\t\t\t\t\t\tthis.#emitter.emit('rollback', rejection.error)\n\t\t\t\t\t\t\tthrow rejection.error\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow this.#rollbackError(rejection.error, error)\n\t\t\t\t\t}\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst rollback = await this.#driver.snapshot()\n\t\t\tthis.#emitter.emit('transaction')\n\t\t\tconst outcome = await scope(this.#driver, new TransactionScope())\n\t\t\tif (outcome.success) {\n\t\t\t\tthis.#emitter.emit('commit')\n\t\t\t\treturn outcome.value\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait rollback()\n\t\t\t} catch (cause) {\n\t\t\t\tthrow this.#rollbackError(outcome.error, cause)\n\t\t\t}\n\t\t\tthis.#emitter.emit('rollback', outcome.error)\n\t\t\tthrow outcome.error\n\t\t} finally {\n\t\t\tif (this.#transaction === token) this.#transaction = undefined\n\t\t}\n\t}\n\n\tasync migrate(deployed: readonly TableSchema[], options?: OperationOptions): Promise<Migration> {\n\t\tcheckAbort(options?.signal)\n\t\tthis.#outside()\n\t\tif (this.#ready !== undefined || this.#status !== 'idle') {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'CONFLICT',\n\t\t\t\t`Database '${this.#name}' cannot apply an explicit deployed schema after opening`,\n\t\t\t\t{ name: this.#name, status: this.#status },\n\t\t\t)\n\t\t}\n\t\tif (this.#driver.migrate === undefined) {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'MIGRATION',\n\t\t\t\t`Database '${this.#name}' driver does not support migration`,\n\t\t\t\t{ name: this.#name },\n\t\t\t)\n\t\t}\n\t\tconst plan = planMigration(deployed, this.#schema)\n\t\tconst readiness = this.#transition(deployed, plan).catch((error: unknown) => {\n\t\t\tif (this.#ready === readiness) this.#ready = undefined\n\t\t\tthis.#failure = { error }\n\t\t\tthrow error\n\t\t})\n\t\tthis.#failure = undefined\n\t\tthis.#ready = readiness\n\t\tawait readiness\n\t\treturn plan\n\t}\n\n\t#admit(): void {\n\t\tif (this.#status === 'closed') {\n\t\t\tthrow new DatabaseError('CLOSED', `Database '${this.#name}' is closed`, {\n\t\t\t\tname: this.#name,\n\t\t\t})\n\t\t}\n\t\tif (this.#transaction !== undefined) {\n\t\t\tthrow new DatabaseError('CONFLICT', `Database '${this.#name}' has an active transaction`, {\n\t\t\t\tname: this.#name,\n\t\t\t})\n\t\t}\n\t\tif (this.#failure !== undefined) throw this.#failure.error\n\t}\n\n\t#outside(): void {\n\t\tif (this.#transaction !== undefined) {\n\t\t\tthrow new DatabaseError('CONFLICT', `Database '${this.#name}' has an active transaction`, {\n\t\t\t\tname: this.#name,\n\t\t\t})\n\t\t}\n\t}\n\n\t#connect(): Promise<void> {\n\t\tif (this.#ready !== undefined) return this.#ready\n\t\tif (this.#failure !== undefined) throw this.#failure.error\n\t\tif (this.#status === 'closed') {\n\t\t\tthrow new DatabaseError('CLOSED', `Database '${this.#name}' is closed`, {\n\t\t\t\tname: this.#name,\n\t\t\t})\n\t\t}\n\t\tconst readiness = this.#driver\n\t\t\t.open(this.#schema)\n\t\t\t.then(async () => {\n\t\t\t\tif (this.#status === 'idle') {\n\t\t\t\t\tthis.#status = 'open'\n\t\t\t\t\tthis.#emitter.emit('open')\n\t\t\t\t}\n\t\t\t\tawait this.#reconcile()\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tif (this.#ready === readiness) this.#ready = undefined\n\t\t\t\tthrow error\n\t\t\t})\n\t\tthis.#ready = readiness\n\t\treturn readiness\n\t}\n\n\tasync #drain(): Promise<void> {\n\t\tif (this.#operations.size === 0) return\n\t\tawait Promise.allSettled(this.#operations)\n\t}\n\n\tasync #reconcile(): Promise<void> {\n\t\tif (\n\t\t\tthis.#version === undefined ||\n\t\t\tthis.#driver.metadata === undefined ||\n\t\t\tthis.#driver.stamp === undefined\n\t\t) {\n\t\t\treturn\n\t\t}\n\t\tconst metadata = await this.#driver.metadata()\n\t\tif (metadata === undefined) {\n\t\t\tawait this.#stamp()\n\t\t\treturn\n\t\t}\n\t\tif (metadata.version > this.#version) {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'MIGRATION',\n\t\t\t\t`Database '${this.#name}' store version ${metadata.version} is newer than declared version ${this.#version}`,\n\t\t\t\t{ name: this.#name, stored: metadata.version, declared: this.#version },\n\t\t\t)\n\t\t}\n\t\tif (metadata.version === this.#version) {\n\t\t\tif (!equalsValue(normalizeDriverSchema(metadata.schema), this.#schema)) {\n\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t'MIGRATION',\n\t\t\t\t\t`Database '${this.#name}' stored schema differs at version ${this.#version}`,\n\t\t\t\t\t{ name: this.#name, version: this.#version },\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tconst plan = planMigration(metadata.schema, this.#schema, metadata.version, this.#version)\n\t\tif (plan.steps.length > 0 && this.#driver.migrate === undefined) {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'MIGRATION',\n\t\t\t\t`Database '${this.#name}' driver does not support migration`,\n\t\t\t\t{ name: this.#name, stored: metadata.version, declared: this.#version },\n\t\t\t)\n\t\t}\n\t\tawait this.#apply(plan)\n\t}\n\n\tasync #apply(plan: Migration): Promise<void> {\n\t\tif (this.#driver.transaction !== undefined) {\n\t\t\tawait this.#driver.transaction(async (storage) => {\n\t\t\t\tif (plan.steps.length > 0 && storage.migrate === undefined) {\n\t\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t\t'MIGRATION',\n\t\t\t\t\t\t`Database '${this.#name}' transaction does not support migration`,\n\t\t\t\t\t\t{ name: this.#name },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tif (storage.migrate === undefined) await this.#stamp(storage)\n\t\t\t\telse await storage.migrate(this.#migration(plan))\n\t\t\t})\n\t\t\tthis.#emitter.emit('migrate', plan)\n\t\t\treturn\n\t\t}\n\t\tif (this.#driver.migrate === undefined) await this.#stamp()\n\t\telse await this.#driver.migrate(this.#migration(plan))\n\t\tthis.#emitter.emit('migrate', plan)\n\t}\n\n\tasync #transition(deployed: readonly TableSchema[], plan: Migration): Promise<void> {\n\t\tawait this.#driver.open(deployed)\n\t\tawait this.#apply(plan)\n\t\tif (this.#status === 'idle') {\n\t\t\tthis.#status = 'open'\n\t\t\tthis.#emitter.emit('open')\n\t\t}\n\t}\n\n\tasync #stamp(storage?: StorageInterface): Promise<void> {\n\t\tconst target = storage ?? this.#driver\n\t\tif (this.#version === undefined || target.stamp === undefined) return\n\t\tconst metadata: DriverMetadata = {\n\t\t\tversion: this.#version,\n\t\t\tschema: this.#schema,\n\t\t}\n\t\tawait target.stamp(metadata)\n\t}\n\n\t#migration(plan: Migration): MigrationInput {\n\t\tif (this.#version === undefined) return { plan }\n\t\treturn {\n\t\t\tplan,\n\t\t\tmetadata: { version: this.#version, schema: this.#schema },\n\t\t}\n\t}\n\n\t#rollbackError(transaction: unknown, cause: unknown): DatabaseError {\n\t\treturn new DatabaseError('DRIVER', `Database '${this.#name}' rollback failed`, {\n\t\t\tcause,\n\t\t\ttransaction,\n\t\t})\n\t}\n}\n","import type { CursorInterface, Key } from './types.js'\n\n/**\n * A forward row cursor for bulk in-place mutation.\n *\n * @remarks\n * Iterates a snapshot of the table's keys captured when the cursor was opened,\n * reading each row lazily through the owning table — so a mutation made during\n * iteration cannot corrupt the walk, and a key removed mid-iteration is simply\n * skipped. `update` and `remove` act on the row at the current position.\n */\nexport class Cursor<T = Record<string, unknown>> implements CursorInterface<T> {\n\treadonly #keys: readonly Key[]\n\treadonly #read: (key: Key) => Promise<T | undefined>\n\treadonly #update: (key: Key, changes: Partial<T>) => Promise<boolean>\n\treadonly #remove: (key: Key) => Promise<boolean>\n\treadonly #track: <R>(operation: () => Promise<R>) => Promise<R>\n\t#tail = Promise.resolve()\n\t#index = -1\n\t#value: T | undefined\n\t#closed = false\n\n\tconstructor(\n\t\tkeys: readonly Key[],\n\t\tread: (key: Key) => Promise<T | undefined>,\n\t\tupdate: (key: Key, changes: Partial<T>) => Promise<boolean>,\n\t\tremove: (key: Key) => Promise<boolean>,\n\t\ttrack: <R>(operation: () => Promise<R>) => Promise<R>,\n\t) {\n\t\tthis.#keys = keys\n\t\tthis.#read = read\n\t\tthis.#update = update\n\t\tthis.#remove = remove\n\t\tthis.#track = track\n\t}\n\n\tget value(): T | undefined {\n\t\treturn this.#value\n\t}\n\n\tget index(): number {\n\t\treturn this.#index\n\t}\n\n\tget done(): boolean {\n\t\treturn this.#closed || this.#index >= this.#keys.length\n\t}\n\n\tnext(): Promise<void> {\n\t\treturn this.#track(() => this.#queue(() => this.#advance()))\n\t}\n\n\tupdate(changes: Partial<T>): Promise<void> {\n\t\treturn this.#track(() => this.#queue(() => this.#revise(changes)))\n\t}\n\n\tremove(): Promise<void> {\n\t\treturn this.#track(() => this.#queue(() => this.#delete()))\n\t}\n\n\tclose(): void {\n\t\tthis.#closed = true\n\t\tthis.#value = undefined\n\t}\n\n\tasync #advance(): Promise<void> {\n\t\tif (this.#closed) return\n\t\tthis.#index += 1\n\t\twhile (this.#index < this.#keys.length) {\n\t\t\tif (this.#closed) return\n\t\t\tconst key = this.#keys[this.#index]\n\t\t\tif (key === undefined) {\n\t\t\t\tthis.#index += 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst row = await this.#read(key)\n\t\t\tif (this.#closed) return\n\t\t\tif (row !== undefined) {\n\t\t\t\tthis.#value = row\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.#index += 1\n\t\t}\n\t\tthis.#value = undefined\n\t}\n\n\tasync #revise(changes: Partial<T>): Promise<void> {\n\t\tif (this.#closed || this.#value === undefined) return\n\t\tconst key = this.#keys[this.#index]\n\t\tif (key === undefined) return\n\t\tawait this.#update(key, changes)\n\t\tif (this.#closed) return\n\t\tconst row = await this.#read(key)\n\t\tif (this.#closed) return\n\t\tthis.#value = row\n\t}\n\n\tasync #delete(): Promise<void> {\n\t\tif (this.#closed || this.#value === undefined) return\n\t\tconst key = this.#keys[this.#index]\n\t\tif (key === undefined) return\n\t\tawait this.#remove(key)\n\t\tif (this.#closed) return\n\t\tthis.#value = undefined\n\t}\n\n\t#queue(operation: () => Promise<void>): Promise<void> {\n\t\tconst result = this.#tail.then(operation)\n\t\tthis.#tail = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t)\n\t\treturn result\n\t}\n}\n","import type { DatabaseContext } from './DatabaseContext.js'\n\n/**\n * The internal continuation admission boundary for a root database stream.\n *\n * @remarks\n * Each continuation enters the shared root operation ledger independently, so\n * an idle iterator never delays a transaction or close. A continuation rejected\n * after transaction or close admission closes attempts source cleanup exactly\n * once and leaves the iterator terminal.\n */\nexport class DatabaseIterator<T> implements AsyncIterableIterator<T> {\n\treadonly #source: AsyncIterator<T>\n\treadonly #context: DatabaseContext\n\t#cleaned = false\n\n\tconstructor(source: AsyncIterable<T>, context: DatabaseContext) {\n\t\tthis.#source = source[Symbol.asyncIterator]()\n\t\tthis.#context = context\n\t}\n\n\t[Symbol.asyncIterator](): AsyncIterableIterator<T> {\n\t\treturn this\n\t}\n\n\tnext(): Promise<IteratorResult<T>> {\n\t\treturn this.#continue(() => this.#next())\n\t}\n\n\treturn(): Promise<IteratorResult<T>> {\n\t\treturn this.#continue(() => this.#return())\n\t}\n\n\tthrow(error?: unknown): Promise<IteratorResult<T>> {\n\t\treturn this.#continue(() => this.#throw(error))\n\t}\n\n\tasync #next(): Promise<IteratorResult<T>> {\n\t\tif (this.#cleaned) return { done: true, value: undefined }\n\t\tawait this.#context.connect()\n\t\tconst result = await this.#source.next()\n\t\tif (result.done === true) this.#cleaned = true\n\t\treturn result\n\t}\n\n\tasync #return(): Promise<IteratorResult<T>> {\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.#source.throw !== undefined) {\n\t\t\tconst result = await this.#source.throw(error)\n\t\t\tif (result.done === true) this.#cleaned = true\n\t\t\treturn result\n\t\t}\n\t\ttry {\n\t\t\tawait this.#return()\n\t\t} catch {}\n\t\tthrow error\n\t}\n\n\t#continue<R>(operation: () => Promise<R>): Promise<R> {\n\t\tif (!this.#context.accepting) this.#cleanup()\n\t\treturn this.#context.track(operation)\n\t}\n\n\t#cleanup(): void {\n\t\tif (this.#cleaned) return\n\t\tthis.#cleaned = true\n\t\ttry {\n\t\t\tconst cleanup = this.#source.return?.()\n\t\t\tcleanup?.catch(() => {})\n\t\t} catch {}\n\t}\n}\n","import type { FieldPath } from '@orkestrel/contract'\nimport type {\n\tAggregateOperation,\n\tCondition,\n\tOperationOptions,\n\tOrder,\n\tQueryInterface,\n\tTableInterface,\n} from './types.js'\nimport { computeAggregate } from './helpers.js'\nimport { validatePage } from './validators.js'\n\n/**\n * A fluent query builder bound to one table.\n *\n * @remarks\n * Accumulates typed conditions, ordering, JS filters, and a page. Each builder\n * method mutates and returns the same instance. Portable inputs flow to the\n * table, while predicates remain an in-memory refinement.\n */\nexport class Query<T = Record<string, unknown>> implements QueryInterface<T> {\n\treadonly #table: TableInterface<T>\n\treadonly #conditions: Condition[] = []\n\treadonly #orders: Order[] = []\n\treadonly #filters: ((row: T) => boolean)[] = []\n\t#limit: number | undefined\n\t#offset: number | undefined\n\n\tconstructor(table: TableInterface<T>) {\n\t\tthis.#table = table\n\t}\n\n\tcondition(input: Condition): QueryInterface<T> {\n\t\tthis.#conditions.push(input)\n\t\treturn this\n\t}\n\n\torder(input: Order): QueryInterface<T> {\n\t\tthis.#orders.push(input)\n\t\treturn this\n\t}\n\n\tfilter(predicate: (row: T) => boolean): QueryInterface<T> {\n\t\tthis.#filters.push(predicate)\n\t\treturn this\n\t}\n\n\tlimit(count: number): QueryInterface<T> {\n\t\tvalidatePage({ limit: count })\n\t\tthis.#limit = count\n\t\treturn this\n\t}\n\n\toffset(count: number): QueryInterface<T> {\n\t\tvalidatePage({ offset: count })\n\t\tthis.#offset = count\n\t\treturn this\n\t}\n\n\tasync collect(): Promise<readonly T[]> {\n\t\tif (this.#filters.length === 0) {\n\t\t\treturn this.#table.records({\n\t\t\t\tconditions: this.#conditions,\n\t\t\t\torder: this.#orders,\n\t\t\t\t...(this.#limit !== undefined ? { limit: this.#limit } : {}),\n\t\t\t\t...(this.#offset !== undefined ? { offset: this.#offset } : {}),\n\t\t\t})\n\t\t}\n\t\tconst fetched = await this.#table.records({\n\t\t\tconditions: this.#conditions,\n\t\t\torder: this.#orders,\n\t\t})\n\t\treturn this.#page(this.#filtered(fetched))\n\t}\n\n\tasync find(): Promise<T | undefined> {\n\t\tconst rows = await this.collect()\n\t\treturn rows[0]\n\t}\n\n\tasync count(): Promise<number> {\n\t\tif (this.#filters.length === 0) {\n\t\t\treturn this.#table.count({ conditions: this.#conditions })\n\t\t}\n\t\tconst fetched = await this.#table.records({ conditions: this.#conditions })\n\t\treturn this.#filtered(fetched).length\n\t}\n\n\t/**\n\t * Lazily evaluate conditions, filters, offset, and limit.\n\t *\n\t * @param options - Optional abort options\n\t * @returns Matching rows in storage order\n\t */\n\tasync *stream(options?: OperationOptions): AsyncIterable<T> {\n\t\tif (this.#filters.length === 0) {\n\t\t\tyield* this.#table.scan(\n\t\t\t\t{\n\t\t\t\t\tconditions: this.#conditions,\n\t\t\t\t\t...(this.#limit !== undefined ? { limit: this.#limit } : {}),\n\t\t\t\t\t...(this.#offset !== undefined ? { offset: this.#offset } : {}),\n\t\t\t\t},\n\t\t\t\toptions,\n\t\t\t)\n\t\t\treturn\n\t\t}\n\t\tconst offset = this.#offset ?? 0\n\t\tlet matched = 0\n\t\tlet yielded = 0\n\t\tfor await (const row of this.#table.scan({ conditions: this.#conditions }, options)) {\n\t\t\tif (this.#limit !== undefined && yielded >= this.#limit) break\n\t\t\tlet matches = true\n\t\t\tfor (const predicate of this.#filters) {\n\t\t\t\tif (!predicate(row)) {\n\t\t\t\t\tmatches = false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!matches) continue\n\t\t\tif (matched < offset) {\n\t\t\t\tmatched += 1\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmatched += 1\n\t\t\tyielded += 1\n\t\t\tyield row\n\t\t}\n\t}\n\n\taggregate(operation: AggregateOperation, column: FieldPath): Promise<number | undefined> {\n\t\tif (this.#filters.length === 0) {\n\t\t\treturn this.#table.aggregate(operation, column, {\n\t\t\t\tconditions: this.#conditions,\n\t\t\t})\n\t\t}\n\t\treturn this.#table\n\t\t\t.records({ conditions: this.#conditions })\n\t\t\t.then((fetched) => computeAggregate(this.#filtered(fetched), operation, column))\n\t}\n\n\t#filtered(rows: readonly T[]): readonly T[] {\n\t\tlet result = rows\n\t\tfor (const predicate of this.#filters) result = result.filter(predicate)\n\t\treturn result\n\t}\n\n\t#page(rows: readonly T[]): readonly T[] {\n\t\tconst offset = this.#offset ?? 0\n\t\tif (offset === 0 && this.#limit === undefined) return rows\n\t\treturn rows.slice(offset, this.#limit === undefined ? undefined : offset + this.#limit)\n\t}\n}\n","import type { ContractInterface, FieldPath, Guard } from '@orkestrel/contract'\nimport type { EmitterErrorHandler, EmitterInterface } from '@orkestrel/emitter'\nimport type { DatabaseContext } from './DatabaseContext.js'\nimport type {\n\tAggregateOperation,\n\tQueryInput,\n\tCursorInterface,\n\tKey,\n\tKeyFunction,\n\tQueryInterface,\n\tOperationOptions,\n\tRow,\n\tTableEventMap,\n\tTableInterface,\n\tStorageInterface,\n} from './types.js'\nimport { isArray, isRecord } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { DatabaseError } from './errors.js'\nimport {\n\tapplyQuery,\n\tcheckAbort,\n\tcomputeAggregate,\n\tequalsValue,\n\textractKey,\n\tfilterRows,\n\tmatchesQuery,\n} from './helpers.js'\nimport { Cursor } from './Cursor.js'\nimport { DatabaseIterator } from './DatabaseIterator.js'\nimport { Query } from './Query.js'\nimport { TransactionScope } from './TransactionScope.js'\nimport { validatePage } from './validators.js'\n\n/**\n * A table — typed keyed CRUD plus fluent query and cursor access over a driver.\n *\n * @remarks\n * The table's contract is the load-bearing piece: writes go through `parse`\n * (coercing inputs and rejecting rows that don't fit with a `VALIDATION` throw),\n * reads come back through the contract guard (narrowing a stored {@link Row} to\n * the table's type — no assertion, AGENTS §1), and `contract` is exposed for\n * introspection and seeding. The driver only stores and scans; all querying is\n * the shared core engine in `helpers.ts`.\n *\n * @remarks\n * - **Observable (§13).** The owned {@link emitter} ({@link TableEventMap}) carries the\n * per-row mutation moments — `write` (set / add / update), `remove`, `clear` — for\n * fire-and-forget observers (cache invalidation, sync, an audit log), ALONGSIDE the\n * database-level lifecycle. Events carry the affected KEY only (no value payload, to\n * keep fan-out lean); reads / queries / counts are not emitted. Every event is emitted\n * directly, strictly AFTER the driver write / delete / clear completes; the emitter\n * isolates a listener throw and routes it to its `error` handler (the `error` option),\n * so a buggy observer can never corrupt a write or perturb a transaction.\n */\nexport class Table<T = Row> implements TableInterface<T> {\n\treadonly #ready: () => Promise<void>\n\treadonly #driver: StorageInterface\n\treadonly #name: string\n\treadonly #key: string\n\treadonly #contract: ContractInterface<T>\n\treadonly #guard: Guard<T>\n\treadonly #generate: KeyFunction | undefined\n\treadonly #context: DatabaseContext | undefined\n\treadonly #scope: TransactionScope | undefined\n\t// The PUSH observation surface (§13) — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into a write\n\t// or a transaction.\n\treadonly #emitter: Emitter<TableEventMap>\n\n\tconstructor(\n\t\tready: () => Promise<void>,\n\t\tdriver: StorageInterface,\n\t\tname: string,\n\t\tkey: string,\n\t\tcontract: ContractInterface<T>,\n\t\tgenerate?: KeyFunction,\n\t\terror?: EmitterErrorHandler,\n\t\tcontext?: DatabaseContext,\n\t\tscope?: TransactionScope,\n\t) {\n\t\tthis.#ready = ready\n\t\tthis.#driver = driver\n\t\tthis.#name = name\n\t\tthis.#key = key\n\t\tthis.#contract = contract\n\t\tthis.#guard = contract.is\n\t\tthis.#generate = generate\n\t\tthis.#context = context\n\t\tthis.#scope = scope\n\t\tthis.#emitter = new Emitter<TableEventMap>({\n\t\t\t...(error !== undefined ? { error } : {}),\n\t\t})\n\t}\n\n\tget emitter(): EmitterInterface<TableEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget name(): string {\n\t\treturn this.#name\n\t}\n\n\tget primary(): string {\n\t\treturn this.#key\n\t}\n\n\tget contract(): ContractInterface<T> {\n\t\treturn this.#contract\n\t}\n\n\tget(key: Key): Promise<T | undefined>\n\tget(keys: readonly Key[]): Promise<readonly (T | undefined)[]>\n\tget(keys: Key | readonly Key[]): Promise<(T | undefined) | readonly (T | undefined)[]> {\n\t\treturn this.#track(async () => {\n\t\t\tawait this.#ready()\n\t\t\tif (isArray(keys)) return this.#each(keys, (key) => this.#read(key))\n\t\t\treturn this.#read(keys)\n\t\t})\n\t}\n\n\tresolve(key: Key): Promise<T>\n\tresolve(keys: readonly Key[]): Promise<readonly T[]>\n\tresolve(keys: Key | readonly Key[]): Promise<T | readonly T[]> {\n\t\treturn this.#track(async () => {\n\t\t\tawait this.#ready()\n\t\t\tif (isArray(keys)) return this.#each(keys, (key) => this.#resolveOne(key))\n\t\t\treturn this.#resolveOne(keys)\n\t\t})\n\t}\n\n\thas(key: Key): Promise<boolean>\n\thas(keys: readonly Key[]): Promise<readonly boolean[]>\n\thas(keys: Key | readonly Key[]): Promise<boolean | readonly boolean[]> {\n\t\treturn this.#track(async () => {\n\t\t\tawait this.#ready()\n\t\t\tif (isArray(keys)) {\n\t\t\t\treturn this.#each(keys, async (key) => (await this.#read(key)) !== undefined)\n\t\t\t}\n\t\t\treturn (await this.#read(keys)) !== undefined\n\t\t})\n\t}\n\n\tkeys(): Promise<readonly Key[]> {\n\t\treturn this.#track(async () => {\n\t\t\tawait this.#ready()\n\t\t\treturn this.#driver.keys(this.#name)\n\t\t})\n\t}\n\n\tasync records(input?: QueryInput, options?: OperationOptions): Promise<readonly T[]> {\n\t\tvalidatePage(input)\n\t\treturn this.#track(async () => {\n\t\t\tcheckAbort(options?.signal)\n\t\t\tawait this.#ready()\n\t\t\tconst candidate: QueryInput = {\n\t\t\t\t...(input?.conditions === undefined ? {} : { conditions: input.conditions }),\n\t\t\t\t...(input?.order === undefined ? {} : { order: input.order }),\n\t\t\t}\n\t\t\tconst native = await this.#driver.records?.(this.#name, candidate)\n\t\t\tconst source = native ?? applyQuery(await this.#collect(), candidate)\n\t\t\tconst rows: T[] = []\n\t\t\tfor (const row of source) {\n\t\t\t\tif (this.#guard(row)) rows.push(row)\n\t\t\t}\n\t\t\tconst offset = input?.offset ?? 0\n\t\t\tconst limit = input?.limit\n\t\t\treturn rows.slice(offset, limit === undefined ? undefined : offset + limit)\n\t\t})\n\t}\n\n\t/**\n\t * Count contract-valid rows matching `input`'s conditions.\n\t *\n\t * @remarks\n\t * Paging is ignored. Candidate rows use the driver's native `records` hook\n\t * when present, then the table contract guard determines the count so legacy\n\t * invalid rows cannot make `count()` disagree with `records()`.\n\t *\n\t * @param input - Optional conditions to filter by (paging is ignored)\n\t * @param options - `{ signal }` to abort\n\t * @returns The count of matching contract-valid rows\n\t */\n\tasync count(input?: QueryInput, options?: OperationOptions): Promise<number> {\n\t\tvalidatePage(input)\n\t\treturn this.#track(async () => {\n\t\t\tcheckAbort(options?.signal)\n\t\t\tawait this.#ready()\n\t\t\tconst conditions = input?.conditions\n\t\t\tconst candidate: QueryInput = conditions === undefined ? {} : { conditions }\n\t\t\tconst native = await this.#driver.records?.(this.#name, candidate)\n\t\t\tconst rows = native ?? filterRows(await this.#collect(), conditions ?? [])\n\t\t\tlet count = 0\n\t\t\tfor (const row of rows) {\n\t\t\t\tif (this.#guard(row)) count += 1\n\t\t\t}\n\t\t\treturn count\n\t\t})\n\t}\n\n\t/**\n\t * Compute an aggregate over `column` across rows matching `input`'s\n\t * conditions.\n\t *\n\t * @remarks\n\t * Like {@link count}, `aggregate` operates on STORED rows WITHOUT the\n\t * contract guard {@link records} / {@link scan} apply — a non-conforming\n\t * stored row still contributes to the computed aggregate when it matches\n\t * the conditions, even though it would never appear in `records()`'s\n\t * output.\n\t *\n\t * @param operation - The aggregate to compute\n\t * @param column - The column to aggregate\n\t * @param input - Optional conditions to filter by (paging is ignored)\n\t * @param options - `{ signal }` to abort\n\t * @returns The aggregate value, or `undefined` when undefined for the inputs\n\t */\n\tasync aggregate(\n\t\toperation: AggregateOperation,\n\t\tcolumn: FieldPath,\n\t\tinput?: QueryInput,\n\t\toptions?: OperationOptions,\n\t): Promise<number | undefined> {\n\t\tvalidatePage(input)\n\t\treturn this.#track(async () => {\n\t\t\tcheckAbort(options?.signal)\n\t\t\tawait this.#ready()\n\t\t\t// Aggregate over filtered (not paged) rows — native hook, native records, or scan.\n\t\t\tconst conditions = input?.conditions\n\t\t\tconst filter: QueryInput = conditions ? { conditions } : {}\n\t\t\t// `?.()` is `undefined` only when the driver lacks the method; a present\n\t\t\t// hook returns a Promise (whose resolved value may itself be `undefined`).\n\t\t\tconst native = this.#driver.aggregate?.(this.#name, operation, column, filter)\n\t\t\tif (native !== undefined) return native\n\t\t\tconst rows = await this.#driver.records?.(this.#name, filter)\n\t\t\tconst matched = rows ?? filterRows(await this.#collect(), input?.conditions ?? [])\n\t\t\treturn computeAggregate(matched, operation, column)\n\t\t})\n\t}\n\n\t/**\n\t * Stream the table's rows matching `input`, applying offset/limit paging.\n\t *\n\t * @remarks\n\t * `input.limit` counts rows that pass both the input conditions and the\n\t * table's contract guard. Native streams receive only the conditions; this\n\t * table rechecks them, narrows each candidate, and applies offset/limit last,\n\t * matching {@link records} when storage contains legacy invalid rows.\n\t *\n\t * @param input - Optional conditions plus offset/limit paging\n\t * @param options - `{ signal }` to abort mid-stream\n\t * @returns An async iterable of matching, guard-conforming rows\n\t */\n\tscan(input?: QueryInput, options?: OperationOptions): AsyncIterable<T> {\n\t\tvalidatePage(input)\n\t\tconst source = this.#scan(input, options)\n\t\tif (this.#context !== undefined) return new DatabaseIterator(source, this.#context)\n\t\treturn this.#scope === undefined ? source : this.#scope.stream(source)\n\t}\n\n\tset(row: T, options?: OperationOptions): Promise<Key>\n\tset(rows: readonly T[], options?: OperationOptions): Promise<readonly Key[]>\n\tset(rows: T | readonly T[], options?: OperationOptions): Promise<Key | readonly Key[]> {\n\t\treturn this.#track(async () => {\n\t\t\tawait this.#wait(options?.signal)\n\t\t\tif (isArray(rows)) {\n\t\t\t\treturn this.#each(rows, (row) => this.#put(row, false, options), options?.signal)\n\t\t\t}\n\t\t\treturn this.#put(rows, false, options)\n\t\t})\n\t}\n\n\tadd(row: T, options?: OperationOptions): Promise<Key>\n\tadd(rows: readonly T[], options?: OperationOptions): Promise<readonly Key[]>\n\tadd(rows: T | readonly T[], options?: OperationOptions): Promise<Key | readonly Key[]> {\n\t\treturn this.#track(async () => {\n\t\t\tawait this.#wait(options?.signal)\n\t\t\tif (isArray(rows)) {\n\t\t\t\treturn this.#each(rows, (row) => this.#put(row, true, options), options?.signal)\n\t\t\t}\n\t\t\treturn this.#put(rows, true, options)\n\t\t})\n\t}\n\n\tupdate(key: Key, changes: Partial<T>, options?: OperationOptions): Promise<boolean>\n\tupdate(\n\t\tkeys: readonly Key[],\n\t\tchanges: Partial<T>,\n\t\toptions?: OperationOptions,\n\t): Promise<readonly boolean[]>\n\tupdate(\n\t\tkeys: Key | readonly Key[],\n\t\tchanges: Partial<T>,\n\t\toptions?: OperationOptions,\n\t): Promise<boolean | readonly boolean[]> {\n\t\treturn this.#track(async () => {\n\t\t\tawait this.#wait(options?.signal)\n\t\t\tif (isArray(keys)) {\n\t\t\t\treturn this.#each(keys, (key) => this.#updateOne(key, changes, options), options?.signal)\n\t\t\t}\n\t\t\treturn this.#updateOne(keys, changes, options)\n\t\t})\n\t}\n\n\tremove(key: Key, options?: OperationOptions): Promise<boolean>\n\tremove(keys: readonly Key[], options?: OperationOptions): Promise<readonly boolean[]>\n\tremove(\n\t\tkeys: Key | readonly Key[],\n\t\toptions?: OperationOptions,\n\t): Promise<boolean | readonly boolean[]> {\n\t\treturn this.#track(async () => {\n\t\t\tawait this.#wait(options?.signal)\n\t\t\tif (isArray(keys)) {\n\t\t\t\treturn this.#each(keys, (key) => this.#delete(key, options), options?.signal)\n\t\t\t}\n\t\t\treturn this.#delete(keys, options)\n\t\t})\n\t}\n\n\tclear(): Promise<void> {\n\t\treturn this.#track(async () => {\n\t\t\tawait this.#ready()\n\t\t\tawait this.#driver.clear(this.#name)\n\t\t\t// Observe the cleared table — AFTER the driver emptied it, so a swallowed listener\n\t\t\t// throw can never alter the clear (no value payload — `clear` is a pure signal).\n\t\t\tthis.#emitter.emit('clear')\n\t\t})\n\t}\n\n\tquery(): QueryInterface<T> {\n\t\treturn new Query<T>(this)\n\t}\n\n\tcursor(): Promise<CursorInterface<T>> {\n\t\treturn this.#track(async () => {\n\t\t\tawait this.#ready()\n\t\t\tlet initializing = true\n\t\t\tconst cursor = new Cursor<T>(\n\t\t\t\tawait this.#driver.keys(this.#name),\n\t\t\t\t(key) => this.#readCursor(key),\n\t\t\t\t(key, changes) => this.#updateCursor(key, changes),\n\t\t\t\t(key) => this.#deleteCursor(key),\n\t\t\t\t(operation) => (initializing ? operation() : this.#track(operation)),\n\t\t\t)\n\t\t\tawait cursor.next()\n\t\t\tinitializing = false\n\t\t\treturn cursor\n\t\t})\n\t}\n\n\tasync *#scan(input?: QueryInput, options?: OperationOptions): AsyncIterable<T> {\n\t\tcheckAbort(options?.signal)\n\t\tawait this.#ready()\n\t\tconst conditions = input?.conditions\n\t\tconst offset = input?.offset ?? 0\n\t\tconst limit = input?.limit\n\t\tlet matched = 0\n\t\tlet yielded = 0\n\t\tconst source =\n\t\t\tthis.#driver.stream === undefined\n\t\t\t\t? this.#driver.scan(this.#name)\n\t\t\t\t: this.#driver.stream(this.#name, conditions === undefined ? {} : { conditions })\n\t\tconst iterator = source[Symbol.asyncIterator]()\n\t\ttry {\n\t\t\twhile (true) {\n\t\t\t\tawait this.#ready()\n\t\t\t\tcheckAbort(options?.signal)\n\t\t\t\tif (limit !== undefined && yielded >= limit) return\n\t\t\t\tconst step = await iterator.next()\n\t\t\t\tawait this.#ready()\n\t\t\t\tcheckAbort(options?.signal)\n\t\t\t\tif (step.done === true) return\n\t\t\t\tconst row = step.value\n\t\t\t\tif (conditions !== undefined && conditions.length > 0 && !matchesQuery(row, conditions)) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst narrowed = this.#cast(row)\n\t\t\t\tif (narrowed === undefined) continue\n\t\t\t\tif (matched < offset) {\n\t\t\t\t\tmatched += 1\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tmatched += 1\n\t\t\t\tyielded += 1\n\t\t\t\tyield narrowed\n\t\t\t}\n\t\t} finally {\n\t\t\tawait iterator.return?.()\n\t\t}\n\t}\n\n\t// Run a single-item operation across each item in order — the batch overloads\n\t// loop one item at a time (sequential, so writes never race) rather than\n\t// pushing batch logic into the thin driver. `signal` (write batches only) is\n\t// checked before EVERY item, so an abort mid-batch stops before the next\n\t// item runs — already-applied items stay applied (no rollback).\n\tasync #each<I, R>(\n\t\telements: readonly I[],\n\t\toperation: (element: I) => Promise<R>,\n\t\tsignal?: AbortSignal,\n\t): Promise<readonly R[]> {\n\t\tconst results: R[] = []\n\t\tfor (const element of elements) {\n\t\t\tcheckAbort(signal)\n\t\t\tresults.push(await operation(element))\n\t\t}\n\t\treturn results\n\t}\n\n\t// Read and narrow one row (assumes the driver is connected).\n\tasync #read(key: Key): Promise<T | undefined> {\n\t\treturn this.#cast(await this.#driver.read(this.#name, key))\n\t}\n\n\tasync #readCursor(key: Key): Promise<T | undefined> {\n\t\tawait this.#ready()\n\t\treturn this.#read(key)\n\t}\n\n\t// Read one row or throw NOT_FOUND.\n\tasync #resolveOne(key: Key): Promise<T> {\n\t\tconst row = await this.#read(key)\n\t\tif (row === undefined) {\n\t\t\tthrow new DatabaseError('NOT_FOUND', `No row '${key}' in table '${this.#name}'`, {\n\t\t\t\ttable: this.#name,\n\t\t\t\tkey,\n\t\t\t})\n\t\t}\n\t\treturn row\n\t}\n\n\t// Coerce/validate and write one row; `insert` selects the atomic insert primitive.\n\tasync #put(row: T, insert: boolean, options?: OperationOptions): Promise<Key> {\n\t\tconst validated = this.#validate(this.#prepare(row))\n\t\tconst key = this.#resolveKey(validated)\n\t\tif (insert) await this.#driver.insert(this.#name, key, validated, options)\n\t\telse await this.#driver.write(this.#name, key, validated, options)\n\t\t// Observe the written row — AFTER the driver write succeeded; carries the KEY only\n\t\t// (set / add / update all emit one `write`, the consumer re-reads if it needs the\n\t\t// value). A swallowed listener throw can't perturb the write (or its transaction).\n\t\tthis.#emitter.emit('write', key)\n\t\treturn key\n\t}\n\n\t// Merge changes into one existing row and re-validate; `false` when it is absent.\n\tasync #updateOne(key: Key, changes: Partial<T>, options?: OperationOptions): Promise<boolean> {\n\t\tconst existing = await this.#driver.read(this.#name, key)\n\t\tif (existing === undefined) {\n\t\t\tcheckAbort(options?.signal)\n\t\t\treturn false\n\t\t}\n\t\tconst input: unknown = changes\n\t\tif (isRecord(input) && Object.hasOwn(input, this.#key) && !equalsValue(input[this.#key], key)) {\n\t\t\tthrow new DatabaseError(\n\t\t\t\t'VALIDATION',\n\t\t\t\t`Update cannot change primary column '${this.#key}' on table '${this.#name}'`,\n\t\t\t\t{ table: this.#name, column: this.#key, key },\n\t\t\t)\n\t\t}\n\t\tawait this.#driver.write(\n\t\t\tthis.#name,\n\t\t\tkey,\n\t\t\tthis.#validate(Object.assign({}, existing, changes)),\n\t\t\toptions,\n\t\t)\n\t\t// Observe the updated row — AFTER the driver write, and only on the path that wrote\n\t\t// (an absent key returned `false` above, emitting nothing).\n\t\tthis.#emitter.emit('write', key)\n\t\treturn true\n\t}\n\n\tasync #updateCursor(key: Key, changes: Partial<T>): Promise<boolean> {\n\t\tawait this.#wait(undefined)\n\t\treturn this.#updateOne(key, changes)\n\t}\n\n\t// Delete one row, emitting `remove` only when a row was actually removed (a delete of\n\t// an absent key returns `false` and emits nothing) — AFTER the driver delete completes.\n\tasync #delete(key: Key, options?: OperationOptions): Promise<boolean> {\n\t\tconst removed = await this.#driver.delete(this.#name, key, options)\n\t\tif (removed) this.#emitter.emit('remove', key)\n\t\treturn removed\n\t}\n\n\tasync #deleteCursor(key: Key): Promise<boolean> {\n\t\tawait this.#wait(undefined)\n\t\treturn this.#delete(key)\n\t}\n\n\t// Await the shared lazy-open promise without tying its lifetime to this\n\t// mutation. An abort rejects this waiter promptly and consumes the open\n\t// promise's later settlement; the driver still checks the same signal at its\n\t// commit point, so a readiness completion after abort can never dispatch a\n\t// row mutation.\n\tasync #wait(signal: AbortSignal | undefined): Promise<void> {\n\t\tcheckAbort(signal)\n\t\tconst ready = this.#ready()\n\t\tif (signal === undefined) {\n\t\t\tawait ready\n\t\t\treturn\n\t\t}\n\t\tconst cleanup = new AbortController()\n\t\ttry {\n\t\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\t\tsignal.addEventListener(\n\t\t\t\t\t'abort',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tready.catch(() => {})\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tcheckAbort(signal)\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\treject(error)\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t{ once: true, signal: cleanup.signal },\n\t\t\t\t)\n\t\t\t\tready.then(resolve, reject)\n\t\t\t\tif (signal.aborted) {\n\t\t\t\t\tready.catch(() => {})\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})\n\t\t} finally {\n\t\t\tcleanup.abort()\n\t\t}\n\t\tcheckAbort(signal)\n\t}\n\n\t// Gather the table's full contents from the driver's ordered scan.\n\tasync #collect(): Promise<readonly Row[]> {\n\t\tconst rows: Row[] = []\n\t\tfor await (const row of this.#driver.scan(this.#name)) rows.push(row)\n\t\treturn rows\n\t}\n\n\t// Copy the input and assign a generated key when the key column is empty.\n\t#prepare(row: T): Row {\n\t\tif (!isRecord(row)) {\n\t\t\tthrow new DatabaseError('VALIDATION', `Row for table '${this.#name}' is not a record`, {\n\t\t\t\ttable: this.#name,\n\t\t\t})\n\t\t}\n\t\tconst prepared: Row = { ...row }\n\t\tif (prepared[this.#key] === undefined) {\n\t\t\tif (this.#generate !== undefined) {\n\t\t\t\ttry {\n\t\t\t\t\tprepared[this.#key] = this.#generate()\n\t\t\t\t} catch (cause) {\n\t\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t\t'VALIDATION',\n\t\t\t\t\t\t`Failed to generate primary column '${this.#key}' for table '${this.#name}'`,\n\t\t\t\t\t\t{ table: this.#name, column: this.#key, cause },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttry {\n\t\t\t\t\tprepared[this.#key] = crypto.randomUUID()\n\t\t\t\t} catch (cause) {\n\t\t\t\t\tthrow new DatabaseError(\n\t\t\t\t\t\t'DRIVER',\n\t\t\t\t\t\t`Host failed to generate primary column '${this.#key}' for table '${this.#name}'`,\n\t\t\t\t\t\t{ table: this.#name, column: this.#key, cause },\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn prepared\n\t}\n\n\t// Coerce *and* validate through the contract in one step: the contract's `parse`\n\t// now coerces types (`'36'` → `36`) AND enforces every leaf refinement (`min` /\n\t// `max` / `pattern`), so a non-`undefined` result already satisfies the guard\n\t// (AGENTS §14 parse↔guard soundness) — no separate `is` re-check is needed.\n\t// `isRecord` is kept solely to narrow the parsed `T` back to a storable `Row`\n\t// without an assertion (AGENTS §1); a table contract is always an object shape,\n\t// so it never rejects a genuinely-parsed row.\n\t#validate(row: Row): Row {\n\t\tconst parsed = this.#contract.parse(row)\n\t\tif (parsed === undefined || !isRecord(parsed)) {\n\t\t\tconst [fault] = this.#contract.explain(row)\n\t\t\tthrow new DatabaseError('VALIDATION', `Row failed the '${this.#name}' contract`, {\n\t\t\t\ttable: this.#name,\n\t\t\t\t...(fault === undefined ? {} : { field: fault.path, reason: fault.reason }),\n\t\t\t})\n\t\t}\n\t\treturn parsed\n\t}\n\n\t#resolveKey(row: Row): Key {\n\t\tconst key = extractKey(row, this.#key)\n\t\tif (key === undefined) {\n\t\t\tthrow new DatabaseError('VALIDATION', `Row has no usable key in column '${this.#key}'`, {\n\t\t\t\ttable: this.#name,\n\t\t\t\tcolumn: this.#key,\n\t\t\t})\n\t\t}\n\t\treturn key\n\t}\n\n\t// Narrow a stored row to the table's type through the contract guard.\n\t#cast(row: Row | undefined): T | undefined {\n\t\treturn row !== undefined && this.#guard(row) ? row : undefined\n\t}\n\n\t#track<R>(operation: () => Promise<R>): Promise<R> {\n\t\tif (this.#context !== undefined) return this.#context.track(operation)\n\t\treturn this.#scope === undefined ? operation() : this.#scope.track(operation)\n\t}\n}\n","import type { ContractInterface } from '@orkestrel/contract'\nimport type { EmitterErrorHandler } from '@orkestrel/emitter'\nimport type {\n\tColumnMap,\n\tDatabaseStorageInterface,\n\tKeyFunction,\n\tRowOf,\n\tTableInterface,\n\tPrimaryMap,\n\tTableMap,\n\tStorageInterface,\n} from './types.js'\nimport { createContract, objectShape } from '@orkestrel/contract'\nimport { DEFAULT_PRIMARY } from './constants.js'\nimport { DatabaseError } from './errors.js'\nimport { Table } from './Table.js'\nimport { TransactionScope } from './TransactionScope.js'\n\n/**\n * A table-only database view bound to one driver transaction scope.\n *\n * @typeParam T - The declared table shape map\n *\n * @remarks\n * The view gives transaction work the same typed tables as its owning database\n * while enforcing a materially narrower contract and lifetime. `table` and\n * every table operation call the owning scope check, so a captured capability\n * cannot escape its transaction.\n */\nexport class DatabaseTransaction<\n\tT extends TableMap = TableMap,\n> implements DatabaseStorageInterface<T> {\n\treadonly #driver: StorageInterface\n\treadonly #tables: T\n\treadonly #primary: PrimaryMap\n\treadonly #generate: KeyFunction | undefined\n\treadonly #error: EmitterErrorHandler | undefined\n\treadonly #scope: TransactionScope\n\n\tconstructor(\n\t\tdriver: StorageInterface,\n\t\ttables: T,\n\t\tprimary: PrimaryMap,\n\t\tgenerate: KeyFunction | undefined,\n\t\terror: EmitterErrorHandler | undefined,\n\t\tscope: TransactionScope,\n\t) {\n\t\tthis.#driver = driver\n\t\tthis.#tables = tables\n\t\tthis.#primary = primary\n\t\tthis.#generate = generate\n\t\tthis.#error = error\n\t\tthis.#scope = scope\n\t}\n\n\ttable<K extends keyof T & string>(name: K): TableInterface<RowOf<T[K]>> {\n\t\tthis.#scope.check()\n\t\tconst columns = this.#columns(name)\n\t\treturn this.#build(name, this.#key(name), createContract(objectShape(columns)))\n\t}\n\n\t#build<R>(name: string, key: string, contract: ContractInterface<R>): TableInterface<R> {\n\t\treturn new Table(\n\t\t\t() => Promise.resolve(),\n\t\t\tthis.#driver,\n\t\t\tname,\n\t\t\tkey,\n\t\t\tcontract,\n\t\t\tthis.#generate,\n\t\t\tthis.#error,\n\t\t\tundefined,\n\t\t\tthis.#scope,\n\t\t)\n\t}\n\n\t#key(name: string): string {\n\t\treturn this.#primary[name] ?? DEFAULT_PRIMARY\n\t}\n\n\t#columns<K extends keyof T & string>(name: K): T[K]\n\t#columns(name: string): ColumnMap\n\t#columns(name: string): ColumnMap {\n\t\tconst columns = this.#tables[name]\n\t\tif (columns === undefined) {\n\t\t\tthrow new DatabaseError('NOT_FOUND', `Table '${name}' is not declared`, { table: name })\n\t\t}\n\t\treturn columns\n\t}\n}\n","import type { ContractInterface, Result } from '@orkestrel/contract'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport type {\n\tColumnMap,\n\tDatabaseEventMap,\n\tDatabaseInterface,\n\tDatabaseOptions,\n\tDatabaseStatus,\n\tDatabaseStorageInterface,\n\tIndexMap,\n\tKeyFunction,\n\tMigration,\n\tOperationOptions,\n\tPrimaryMap,\n\tRowOf,\n\tTableDefinition,\n\tTableInterface,\n\tTableMap,\n\tTableSchema,\n} from './types.js'\nimport { compileSchema, createContract, objectShape } from '@orkestrel/contract'\nimport { DEFAULT_PRIMARY } from './constants.js'\nimport { DatabaseError } from './errors.js'\nimport { shapeToColumnSchema } from './helpers.js'\nimport { DatabaseContext } from './DatabaseContext.js'\nimport { DatabaseTransaction } from './DatabaseTransaction.js'\nimport { Table } from './Table.js'\nimport { TransactionScope } from './TransactionScope.js'\n\n/**\n * A typed database view over one shared internal lifecycle and storage context.\n *\n * @remarks\n * Each view owns only its table contracts, primary columns, indexes, and key\n * generator. Imported views register their physical schemas with the same\n * internal context before opening begins, so every view observes one driver,\n * merged schema, emitter, status, transaction boundary, and terminal close.\n */\nexport class Database<T extends TableMap = TableMap> implements DatabaseInterface<T> {\n\t#context: DatabaseContext\n\treadonly #tables: T\n\treadonly #primary: PrimaryMap\n\treadonly #indexes: IndexMap\n\treadonly #generate: KeyFunction | undefined\n\n\tconstructor(options: DatabaseOptions<T>) {\n\t\tthis.#tables = options.tables\n\t\tthis.#primary = options.primary ?? {}\n\t\tthis.#indexes = options.indexes ?? {}\n\t\tthis.#generate = options.generator\n\t\tthis.#context = new DatabaseContext(options)\n\t\tthis.#context.register(this.#schema())\n\t}\n\n\tget emitter(): EmitterInterface<DatabaseEventMap> {\n\t\treturn this.#context.emitter\n\t}\n\n\tget name(): string {\n\t\treturn this.#context.name\n\t}\n\n\tget status(): DatabaseStatus {\n\t\treturn this.#context.status\n\t}\n\n\ttable<K extends keyof T & string>(name: K): TableInterface<RowOf<T[K]>> {\n\t\tif (this.#context.status === 'closed') {\n\t\t\tthrow new DatabaseError('CLOSED', `Database '${this.#context.name}' is closed`, {\n\t\t\t\tname: this.#context.name,\n\t\t\t})\n\t\t}\n\t\tconst columns = this.#columns(name)\n\t\treturn this.#build(name, this.#key(name), createContract(objectShape(columns)))\n\t}\n\n\timport<U extends TableMap>(tables: U, primary?: PrimaryMap): DatabaseInterface<U> {\n\t\treturn this.#spawn(tables, { ...this.#primary, ...primary })\n\t}\n\n\texport(): Readonly<Record<string, TableDefinition>> {\n\t\tconst result: Record<string, TableDefinition> = {}\n\t\tfor (const name of Object.keys(this.#tables)) {\n\t\t\tconst columns = this.#columns(name)\n\t\t\tresult[name] = {\n\t\t\t\tprimary: this.#key(name),\n\t\t\t\tcolumns,\n\t\t\t\tschema: compileSchema(objectShape(columns)),\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\n\topen(): Promise<void> {\n\t\treturn this.#context.open()\n\t}\n\n\tclose(): Promise<void> {\n\t\treturn this.#context.close()\n\t}\n\n\ttransaction<R>(\n\t\tscope: (transaction: DatabaseStorageInterface<T>) => Promise<R>,\n\t\toptions?: OperationOptions,\n\t): Promise<R> {\n\t\treturn this.#context.transaction(async (storage, lifetime) => {\n\t\t\tconst transaction = new DatabaseTransaction(\n\t\t\t\tstorage,\n\t\t\t\tthis.#tables,\n\t\t\t\tthis.#primary,\n\t\t\t\tthis.#generate,\n\t\t\t\tthis.#context.error,\n\t\t\t\tlifetime,\n\t\t\t)\n\t\t\treturn this.#settle(scope, transaction, lifetime)\n\t\t}, options)\n\t}\n\n\tmigrate(deployed: readonly TableSchema[], options?: OperationOptions): Promise<Migration> {\n\t\treturn this.#context.migrate(deployed, options)\n\t}\n\n\t#build<R>(name: string, key: string, contract: ContractInterface<R>): TableInterface<R> {\n\t\treturn new Table(\n\t\t\t() => this.#context.connect(),\n\t\t\tthis.#context.driver,\n\t\t\tname,\n\t\t\tkey,\n\t\t\tcontract,\n\t\t\tthis.#generate,\n\t\t\tthis.#context.error,\n\t\t\tthis.#context,\n\t\t)\n\t}\n\n\t#spawn<X extends TableMap>(tables: X, primary: PrimaryMap): DatabaseInterface<X> {\n\t\treturn Database.#attach(\n\t\t\t{\n\t\t\t\tdriver: this.#context.driver,\n\t\t\t\ttables,\n\t\t\t\tprimary,\n\t\t\t\tname: this.#context.name,\n\t\t\t\t...(this.#context.error === undefined ? {} : { error: this.#context.error }),\n\t\t\t\t...(this.#generate === undefined ? {} : { generator: this.#generate }),\n\t\t\t\t...(this.#context.version === undefined ? {} : { version: this.#context.version }),\n\t\t\t},\n\t\t\tthis.#context,\n\t\t)\n\t}\n\n\t#key(name: string): string {\n\t\treturn this.#primary[name] ?? DEFAULT_PRIMARY\n\t}\n\n\t#columns<K extends keyof T & string>(name: K): T[K]\n\t#columns(name: string): ColumnMap\n\t#columns(name: string): ColumnMap {\n\t\tconst columns = this.#tables[name]\n\t\tif (columns === undefined) {\n\t\t\tthrow new DatabaseError('NOT_FOUND', `Table '${name}' is not declared`, { table: name })\n\t\t}\n\t\treturn columns\n\t}\n\n\t#schema(): readonly TableSchema[] {\n\t\treturn Object.keys(this.#tables).map((name) => {\n\t\t\tconst columns = this.#columns(name)\n\t\t\treturn {\n\t\t\t\tname,\n\t\t\t\tprimary: this.#key(name),\n\t\t\t\tcolumns: Object.entries(columns).map(([column, shape]) =>\n\t\t\t\t\tshapeToColumnSchema(column, shape),\n\t\t\t\t),\n\t\t\t\tindexes: this.#indexes[name] ?? [],\n\t\t\t}\n\t\t})\n\t}\n\n\tasync #settle<R>(\n\t\tscope: (transaction: DatabaseStorageInterface<T>) => Promise<R>,\n\t\ttransaction: DatabaseStorageInterface<T>,\n\t\tlifetime: TransactionScope,\n\t): Promise<Result<R, unknown>> {\n\t\tconst outcome: Result<R, unknown> = await Promise.resolve()\n\t\t\t.then(() => scope(transaction))\n\t\t\t.then(\n\t\t\t\t(value) => ({ success: true, value }),\n\t\t\t\t(error: unknown) => ({ success: false, error }),\n\t\t\t)\n\t\tlifetime.stop()\n\t\tconst drained: Result<void, unknown> = await lifetime.drain().then(\n\t\t\t() => ({ success: true, value: undefined }),\n\t\t\t(error: unknown) => ({ success: false, error }),\n\t\t)\n\t\tif (!outcome.success) return outcome\n\t\tif (!drained.success) return drained\n\t\treturn outcome\n\t}\n\n\tstatic #attach<X extends TableMap>(\n\t\toptions: DatabaseOptions<X>,\n\t\tcontext: DatabaseContext,\n\t): Database<X> {\n\t\tconst database = new Database(options)\n\t\tdatabase.#context = context\n\t\tcontext.register(database.#schema())\n\t\treturn database\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} from '../types.js'\nimport { cloneDriverMetadata, cloneMigrationInput } from '../cloners.js'\nimport { DatabaseError } from '../errors.js'\nimport {\n\tbindRowKey,\n\tcheckAbort,\n\tcompareValues,\n\tequalsValue,\n\tmatchesQuery,\n\tmigrateRows,\n\tnormalizeDriverSchema,\n\tplanMigration,\n\tprojectMigrationSchema,\n} from '../helpers.js'\nimport { isKey, validatePage } from '../validators.js'\n\n/**\n * The reference {@link DriverInterface} — nested maps, no I/O.\n *\n * @remarks\n * The in-between made concrete: it runs identically in a browser or on a server,\n * so it is the storage behind tests, ephemeral caches, and any code that wants\n * the database API without a persistent backend. Rows are DEEP-copied (via\n * `structuredClone`) in and out — at `write`, `read`, `scan`, `stream`, and both\n * snapshot capture and restore — so a caller mutating a nested field of an input\n * row, a returned row, or a row mutated in place between snapshot and rollback\n * can never perturb stored state (AGENTS §11); a shallow `{ ...row }` spread\n * would still share nested object/array references. Metadata instead routes\n * through `cloneDriverMetadata`: `stamp` and migration snapshot exact JSON at\n * ingress, and `metadata` returns a distinct deeply frozen owned copy. `snapshot`\n * clones every table to give transactions an exact rollback point. `scan` and\n * `keys` yield in key order — sorted by the core {@link compareValues} total\n * order, the same contract the SQLite (`ORDER BY`) and IndexedDB (key-ordered\n * reads) backends honor, so an unordered read agrees across every backend rather\n * than leaking Map insertion order. A persistent backend (IndexedDB, SQLite)\n * implements the same required methods over real storage.\n */\nexport class MemoryDriver implements DriverInterface {\n\treadonly #tables = new Map<string, Map<Key, Row>>()\n\t#identities = new Map<string, object>()\n\t#schema: readonly TableSchema[] = []\n\t#metadata: DriverMetadata | undefined\n\n\tasync open(schema: readonly TableSchema[]): Promise<void> {\n\t\tconst owned = normalizeDriverSchema(schema)\n\t\tconst deployed = normalizeDriverSchema(this.#metadata?.schema ?? owned)\n\t\tconst names = new Set(deployed.map((table) => table.name))\n\t\tfor (const name of this.#identities.keys()) {\n\t\t\tif (!names.has(name)) this.#identities.delete(name)\n\t\t}\n\t\tfor (const table of deployed) {\n\t\t\tif (!this.#tables.has(table.name)) this.#tables.set(table.name, new Map())\n\t\t\tif (!this.#identities.has(table.name)) this.#identities.set(table.name, {})\n\t\t}\n\t\tthis.#schema = deployed\n\t}\n\n\tasync close(): Promise<void> {}\n\n\tasync read(table: string, key: Key): Promise<Row | undefined> {\n\t\tconst row = this.#store(table).get(key)\n\t\treturn row === undefined ? undefined : structuredClone(row)\n\t}\n\n\tasync write(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void> {\n\t\tcheckAbort(options?.signal)\n\t\tconst primary = this.#table(table).primary\n\t\tthis.#store(table).set(key, structuredClone(bindRowKey(row, primary, key)))\n\t}\n\n\tasync insert(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void> {\n\t\tcheckAbort(options?.signal)\n\t\tconst store = this.#store(table)\n\t\tif (store.has(key)) {\n\t\t\tthrow new DatabaseError('CONFLICT', `Row '${key}' already exists in table '${table}'`, {\n\t\t\t\ttable,\n\t\t\t\tkey,\n\t\t\t})\n\t\t}\n\t\tconst primary = this.#table(table).primary\n\t\tstore.set(key, structuredClone(bindRowKey(row, primary, key)))\n\t}\n\n\tasync delete(table: string, key: Key, options?: OperationOptions): Promise<boolean> {\n\t\tcheckAbort(options?.signal)\n\t\treturn this.#store(table).delete(key)\n\t}\n\n\tasync keys(table: string): Promise<readonly Key[]> {\n\t\treturn this.#ordered(table)\n\t}\n\n\tasync *scan(table: string): AsyncIterable<Row> {\n\t\tconst store = this.#store(table)\n\t\tfor (const key of this.#ordered(table)) {\n\t\t\tconst row = store.get(key)\n\t\t\tif (row !== undefined) yield structuredClone(row)\n\t\t}\n\t}\n\n\t/**\n\t * Natively filtered lazy iteration — the {@link DriverInterface.stream} hook.\n\t *\n\t * @remarks\n\t * Iterates the table's keys in the same key order `scan` and `keys` yield\n\t * (sorted by {@link compareValues}), testing each row against\n\t * `input.conditions` (via {@link matchesQuery}) before counting it\n\t * toward `offset` / `limit`. Both are applied lazily as matches are found —\n\t * `offset` matches are skipped without being yielded, and iteration stops the\n\t * instant `limit` yields have been produced, so a large table is never fully\n\t * walked for a small page. `input.order` is IGNORED (the same contract as\n\t * `TableInterface.scan` and `QueryInterface.stream`): streaming yields key\n\t * order, sorted output is `records()`'s job. Rows yield copy-out (AGENTS\n\t * §11), and an unknown table mirrors `scan`'s empty-yield behavior.\n\t *\n\t * @param table - The table to stream\n\t * @param input - The filter / offset / limit to apply lazily\n\t *\n\t * @example\n\t * ```ts\n\t * for await (const row of driver.stream('users', { conditions, limit: 10 })) {\n\t * // one matched row at a time, in key order\n\t * }\n\t * ```\n\t */\n\tstream(table: string, input: QueryInput): AsyncIterable<Row> {\n\t\tvalidatePage(input)\n\t\treturn this.#stream(table, input)\n\t}\n\n\tasync *#stream(table: string, input: QueryInput): AsyncIterable<Row> {\n\t\tconst store = this.#store(table)\n\t\tconst conditions = input.conditions\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 (const key of this.#ordered(table)) {\n\t\t\tif (limit !== undefined && yielded >= limit) return\n\t\t\tconst row = store.get(key)\n\t\t\tif (row === undefined) continue\n\t\t\tif (conditions !== undefined && conditions.length > 0 && !matchesQuery(row, conditions)) {\n\t\t\t\tcontinue\n\t\t\t}\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 structuredClone(row)\n\t\t\tyielded += 1\n\t\t}\n\t}\n\n\tasync clear(table: string): Promise<void> {\n\t\tthis.#store(table).clear()\n\t}\n\n\t/**\n\t * Capture the current state and return a thunk that rolls back to it.\n\t *\n\t * @remarks\n\t * Capture owns rows, schema, and one session-local table identity. Replay\n\t * adapts rows to each surviving same-identity table's current schema before\n\t * changing storage. Removed or replaced tables are skipped; uncaptured and\n\t * later-added tables retain their current rows. Schema and metadata are never\n\t * restored.\n\t *\n\t * @param tables - The table names to scope the snapshot to; omitted captures every table\n\t * @returns A thunk that restores the captured tables\n\t */\n\tasync snapshot(tables?: readonly string[]): Promise<() => Promise<void>> {\n\t\tconst names =\n\t\t\ttables === undefined\n\t\t\t\t? this.#schema.map((table) => table.name)\n\t\t\t\t: [...new Set(tables)].filter((name) => this.#schema.some((table) => table.name === name))\n\t\tconst captured = new Map<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\treadonly identity: object\n\t\t\t\treadonly rows: ReadonlyMap<Key, Row>\n\t\t\t\treadonly schema: TableSchema\n\t\t\t}\n\t\t>()\n\t\tfor (const name of names) {\n\t\t\tconst schema = this.#schema.find((table) => table.name === name)\n\t\t\tconst store = this.#tables.get(name)\n\t\t\tconst identity = this.#identities.get(name)\n\t\t\tif (schema === undefined || store === undefined || identity === undefined) continue\n\t\t\tconst rows = new Map<Key, Row>()\n\t\t\tfor (const [key, row] of store) rows.set(key, structuredClone(row))\n\t\t\tcaptured.set(name, { identity, rows, schema })\n\t\t}\n\t\treturn async () => {\n\t\t\tconst replacements = new Map<Map<Key, Row>, ReadonlyMap<Key, Row>>()\n\t\t\tfor (const [name, capture] of captured) {\n\t\t\t\tconst schema = this.#schema.find((table) => table.name === name)\n\t\t\t\tconst store = this.#tables.get(name)\n\t\t\t\tif (\n\t\t\t\t\tschema === undefined ||\n\t\t\t\t\tstore === undefined ||\n\t\t\t\t\tthis.#identities.get(name) !== capture.identity\n\t\t\t\t) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst plan = planMigration([capture.schema], [schema])\n\t\t\t\tconst entries = [...capture.rows.entries()]\n\t\t\t\tconst migrated = migrateRows(\n\t\t\t\t\tentries.map(([, row]) => row),\n\t\t\t\t\tplan.steps,\n\t\t\t\t)\n\t\t\t\tif (migrated.length !== entries.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 rows = new Map<Key, Row>()\n\t\t\t\tfor (const [index, [key]] of entries.entries()) {\n\t\t\t\t\tconst row = migrated[index]\n\t\t\t\t\tif (!isKey(key) || row === undefined) {\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\trows.set(key, structuredClone(bindRowKey(row, schema.primary, key)))\n\t\t\t\t}\n\t\t\t\treplacements.set(store, rows)\n\t\t\t}\n\t\t\tfor (const [store, rows] of replacements) {\n\t\t\t\tstore.clear()\n\t\t\t\tfor (const [key, row] of rows) store.set(key, row)\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Return the persisted {@link DriverMetadata}, or `undefined` when the store has\n\t * never been stamped.\n\t *\n\t * @remarks\n\t * In-process only — the metadata lives in this instance's memory, exactly\n\t * like the rest of this driver's storage. The returned value is a distinct\n\t * deeply frozen owned snapshot. A driver-conformance-valid implementation of\n\t * the optional `metadata` / `stamp` pair.\n\t *\n\t * @returns The last-stamped {@link DriverMetadata}, or `undefined`\n\t */\n\tasync metadata(): Promise<DriverMetadata | undefined> {\n\t\treturn this.#metadata === undefined ? undefined : cloneDriverMetadata(this.#metadata)\n\t}\n\n\t/**\n\t * Persist an owned snapshot for a later `metadata()` to return.\n\t *\n\t * @param metadata - The {@link DriverMetadata} to persist\n\t */\n\tasync stamp(metadata: DriverMetadata): Promise<void> {\n\t\tthis.#metadata = cloneDriverMetadata(metadata)\n\t}\n\n\t/**\n\t * Apply a {@link Migration} plan's steps against the in-memory store.\n\t *\n\t * @remarks\n\t * Steps apply against an isolated candidate. Rows, schema changes, and\n\t * optional metadata publish together only after the whole request succeeds.\n\t *\n\t * @param input - The migration plan and optional metadata to settle atomically\n\t */\n\tasync migrate(input: MigrationInput): Promise<void> {\n\t\tconst owned = cloneMigrationInput(input)\n\t\tconst schema = projectMigrationSchema(this.#schema, owned.plan.steps)\n\t\tif (\n\t\t\towned.metadata !== undefined &&\n\t\t\t!equalsValue(normalizeDriverSchema(owned.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: owned.metadata.schema,\n\t\t\t})\n\t\t}\n\t\tconst candidate = this.#copy(this.#tables)\n\t\tconst identities = this.#projectIdentities(this.#identities, owned.plan.steps)\n\t\tfor (const step of owned.plan.steps) this.#migrate(candidate, step)\n\t\tthis.#tables.clear()\n\t\tfor (const [name, store] of candidate) this.#tables.set(name, store)\n\t\tthis.#identities = identities\n\t\tthis.#schema = schema\n\t\tif (owned.metadata !== undefined) this.#metadata = owned.metadata\n\t}\n\n\t// A table's keys in key order — the contract `scan` and `keys` yield in.\n\t// `compareValues` is the core total order (number < string, natural within),\n\t// matching the SQLite `ORDER BY` and IndexedDB key-range orderings.\n\t#ordered(table: string): readonly Key[] {\n\t\treturn [...this.#store(table).keys()].sort(compareValues)\n\t}\n\n\t// A migration step's table must already exist — unlike `#store`, a missing\n\t// table here is a MIGRATION error rather than an as-yet-untouched table.\n\t#require(tables: Map<string, Map<Key, Row>>, table: string): Map<Key, Row> {\n\t\tconst store = tables.get(table)\n\t\tif (store === undefined) {\n\t\t\tthrow new DatabaseError('MIGRATION', `migrate: unknown table '${table}'`, { table })\n\t\t}\n\t\treturn store\n\t}\n\n\t#copy(tables: Map<string, Map<Key, Row>>): Map<string, Map<Key, Row>> {\n\t\tconst copy = new Map<string, Map<Key, Row>>()\n\t\tfor (const [name, store] of tables) {\n\t\t\tconst cloned = new Map<Key, Row>()\n\t\t\tfor (const [key, row] of store) cloned.set(key, structuredClone(row))\n\t\t\tcopy.set(name, cloned)\n\t\t}\n\t\treturn copy\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#table(name: string): TableSchema {\n\t\tconst schema = this.#schema.find((table) => table.name === name)\n\t\tif (schema === undefined) {\n\t\t\tthrow new DatabaseError('NOT_FOUND', `Unknown table '${name}'`, { table: name })\n\t\t}\n\t\treturn schema\n\t}\n\n\t#migrate(tables: Map<string, Map<Key, Row>>, step: MigrationStep): void {\n\t\tswitch (step.operation) {\n\t\t\tcase 'table.add':\n\t\t\t\tif (!tables.has(step.table.name)) tables.set(step.table.name, new Map())\n\t\t\t\tbreak\n\t\t\tcase 'table.remove':\n\t\t\t\tthis.#require(tables, step.table)\n\t\t\t\ttables.delete(step.table)\n\t\t\t\tbreak\n\t\t\tcase 'column.add':\n\t\t\tcase 'column.remove': {\n\t\t\t\tconst store = this.#require(tables, step.table)\n\t\t\t\tconst rows = [...store.entries()]\n\t\t\t\tconst migrated = migrateRows(\n\t\t\t\t\trows.map(([, row]) => row),\n\t\t\t\t\t[step],\n\t\t\t\t)\n\t\t\t\tfor (const [index, [key]] of rows.entries()) {\n\t\t\t\t\tconst row = migrated[index]\n\t\t\t\t\tif (row === undefined) {\n\t\t\t\t\t\tthrow new DatabaseError('MIGRATION', 'migrate: transformed row is missing', {\n\t\t\t\t\t\t\ttable: step.table,\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\tstore.set(key, row)\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'index.add':\n\t\t\tcase 'index.remove':\n\t\t\t\tthis.#require(tables, step.table)\n\t\t\t\tbreak\n\t\t}\n\t}\n\n\t// Resolve only a currently declared table. `open` creates every backing map,\n\t// so a missing map is a lookup failure rather than an implicit declaration.\n\t#store(table: string): Map<Key, Row> {\n\t\tthis.#table(table)\n\t\tconst store = this.#tables.get(table)\n\t\tif (store === undefined) {\n\t\t\tthrow new DatabaseError('NOT_FOUND', `Table '${table}' has no backing store`, { table })\n\t\t}\n\t\treturn store\n\t}\n}\n","import type { DatabaseInterface, DatabaseOptions, DriverInterface, TableMap } from './types.js'\nimport { Database } from './Database.js'\nimport { MemoryDriver } from './drivers/MemoryDriver.js'\n\n/**\n * Create a database over a driver and a declared `tables` schema.\n *\n * @remarks\n * `tables` maps each name to its columns (a `column → shape` map); the database\n * wraps each in an `objectShape`, so you never write `objectShape` at the table\n * level. The `const` type parameter captures the literal names and columns, so\n * `db.table('users')` is checked against the schema and typed by `Infer` of its\n * columns — no annotations. Name a non-`id` primary-key column per table via the\n * optional `primary` and `indexes` maps.\n *\n * @param options - The driver, `tables`, and optional `primary`, `indexes`,\n * `name`, `generator`, `version`, and emitter hooks\n * @returns A typed {@link DatabaseInterface}\n *\n * @example\n * ```ts\n * import { createDatabase, createMemoryDriver } from '@orkestrel/database'\n * import { integerShape, stringShape } from '@orkestrel/contract'\n *\n * const db = createDatabase({\n * \tdriver: createMemoryDriver(),\n * \ttables: {\n * \t\tusers: { id: stringShape(), age: integerShape() },\n * \t\tposts: { slug: stringShape(), title: stringShape() },\n * \t},\n * \tprimary: { posts: 'slug' },\n * })\n * await db.table('users').set({ id: 'u1', age: 36 }) // typed; coerced + validated\n * ```\n */\nexport function createDatabase<const T extends TableMap>(\n\toptions: DatabaseOptions<T>,\n): DatabaseInterface<T> {\n\treturn new Database(options)\n}\n\n/**\n * Create the in-memory reference {@link DriverInterface}.\n *\n * @remarks\n * Backed by nested maps with no I/O — the same driver runs in a browser or on a\n * server, making it the natural choice for tests and ephemeral storage.\n *\n * @returns A fresh in-memory driver\n */\nexport function createMemoryDriver(): DriverInterface {\n\treturn new MemoryDriver()\n}\n"],"mappings":"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"}
|