@orkestrel/database 0.0.12 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,48 @@
1
- import { ContractInterface } from '@orkestrel/contract';
2
- import { ContractShape } from '@orkestrel/contract';
3
- import { EmitterErrorHandler } from '@orkestrel/emitter';
4
- import { EmitterHooks } from '@orkestrel/emitter';
5
- import { EmitterInterface } from '@orkestrel/emitter';
6
- import { FieldPath } from '@orkestrel/contract';
7
- import { Infer } from '@orkestrel/contract';
8
- import { JSONSchema } from '@orkestrel/contract';
9
-
10
- /** An aggregate computed over a numeric column. */
1
+ import type { ContractInterface } from '@orkestrel/contract';
2
+ import type { ContractShape } from '@orkestrel/contract';
3
+ import type { EmitterErrorHandler } from '@orkestrel/emitter';
4
+ import type { EmitterHooks } from '@orkestrel/emitter';
5
+ import type { EmitterInterface } from '@orkestrel/emitter';
6
+ import type { FieldPath } from '@orkestrel/contract';
7
+ import type { Infer } from '@orkestrel/contract';
8
+ import type { JSONSchema } from '@orkestrel/contract';
9
+
10
+ /**
11
+ * Represents the admission boundary a scoped operation enters before it runs.
12
+ *
13
+ * @remarks
14
+ * The one contract the root database context and a transaction scope both
15
+ * expose: `accepting` reports whether the boundary still admits work, and
16
+ * `track` enters an operation into the boundary's ledger so whoever stops the
17
+ * boundary can contain everything already accepted. A streamed read enters each
18
+ * continuation independently through the same pair, so an idle iterator never
19
+ * pins the boundary open.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import type { AdmissionInterface } from '@orkestrel/database'
24
+ *
25
+ * const boundary: AdmissionInterface = {
26
+ * accepting: true,
27
+ * track: (operation) => operation(),
28
+ * }
29
+ * await boundary.track(async () => 42) // 42
30
+ * ```
31
+ */
32
+ export declare interface AdmissionInterface {
33
+ readonly accepting: boolean;
34
+ /**
35
+ * Enters one operation into the boundary's ledger so whoever stops the boundary
36
+ * contains everything already accepted.
37
+ */
38
+ track<R>(operation: () => Promise<R>): Promise<R>;
39
+ }
40
+
41
+ /** Names an aggregate computed over a numeric column. */
11
42
  export declare type AggregateOperation = 'count' | 'sum' | 'average' | 'minimum' | 'maximum';
12
43
 
13
44
  /**
14
- * Apply a {@link QueryInput} to rows — filter, then sort, then page.
45
+ * Applies a {@link QueryInput} to rows — filter, then sort, then page.
15
46
  *
16
47
  * @remarks
17
48
  * The whole portable read pipeline in one place: conditions filter, `order`
@@ -26,12 +57,12 @@ export declare type AggregateOperation = 'count' | 'sum' | 'average' | 'minimum'
26
57
  export declare function applyQuery(rows: readonly Row[], input?: QueryInput): readonly Row[];
27
58
 
28
59
  /**
29
- * Run the FULL driver-conformance battery and collect every violation — the
60
+ * Runs the full driver-conformance battery and collects every violation — the
30
61
  * audit entry point for a driver author who wants a complete report rather
31
62
  * than a single fail-fast throw.
32
63
  *
33
64
  * @remarks
34
- * Drains {@link driverFindings} to completion: every phase runs regardless
65
+ * Drains {@link scanDriver} to completion: every phase runs regardless
35
66
  * of earlier violations, so a driver breaking two independent invariants
36
67
  * reports both. An empty array means the driver is fully conformant.
37
68
  *
@@ -49,7 +80,7 @@ export declare function applyQuery(rows: readonly Row[], input?: QueryInput): re
49
80
  export declare function auditDriver(factory: () => DriverInterface): Promise<readonly ConformanceFinding[]>;
50
81
 
51
82
  /**
52
- * Return a fresh row whose primary column is authoritatively bound to its storage key.
83
+ * Returns a fresh row whose primary column is authoritatively bound to its storage key.
53
84
  *
54
85
  * @param row - The caller row
55
86
  * @param primary - The primary column
@@ -59,7 +90,7 @@ export declare function auditDriver(factory: () => DriverInterface): Promise<rea
59
90
  export declare function bindRowKey(row: Row, primary: string, key: Key): Row;
60
91
 
61
92
  /**
62
- * Throw when an {@link OperationOptions.signal | AbortSignal} has fired — the shared
93
+ * Throws when an {@link OperationOptions.signal | AbortSignal} has fired — the shared
63
94
  * abort gate checked at operation boundaries and between streamed rows.
64
95
  *
65
96
  * @remarks
@@ -86,7 +117,12 @@ export declare function bindRowKey(row: Row, primary: string, key: Key): Row;
86
117
  export declare function checkAbort(signal: AbortSignal | undefined): void;
87
118
 
88
119
  /**
89
- * Clone unknown driver metadata into a distinct deeply frozen snapshot.
120
+ * Clones unknown driver metadata into a distinct deeply frozen snapshot.
121
+ *
122
+ * @remarks
123
+ * The clone is validated as {@link DriverMetadata} before it is returned, so a
124
+ * malformed or hostile value throws a `VALIDATION` {@link DatabaseError} at
125
+ * `context.path === 'metadata'` rather than surfacing a raw Contract or caller error.
90
126
  *
91
127
  * @param value - Unknown metadata
92
128
  * @returns Owned driver metadata
@@ -94,7 +130,12 @@ export declare function checkAbort(signal: AbortSignal | undefined): void;
94
130
  export declare function cloneDriverMetadata(value: unknown): DriverMetadata;
95
131
 
96
132
  /**
97
- * Clone unknown driver schema into a distinct deeply frozen snapshot.
133
+ * Clones unknown driver schema into a distinct deeply frozen snapshot.
134
+ *
135
+ * @remarks
136
+ * The clone is validated as a table-schema collection before it is returned, so a
137
+ * malformed or hostile value throws a `VALIDATION` {@link DatabaseError} at
138
+ * `context.path === 'schema'` rather than surfacing a raw Contract or caller error.
98
139
  *
99
140
  * @param value - Unknown table schema collection
100
141
  * @returns Owned driver schema
@@ -102,7 +143,12 @@ export declare function cloneDriverMetadata(value: unknown): DriverMetadata;
102
143
  export declare function cloneDriverSchema(value: unknown): readonly TableSchema[];
103
144
 
104
145
  /**
105
- * Clone unknown migration input into a distinct deeply frozen snapshot.
146
+ * Clones unknown migration input into a distinct deeply frozen snapshot.
147
+ *
148
+ * @remarks
149
+ * The clone is validated as a {@link MigrationInput} before it is returned, so a
150
+ * malformed or hostile value throws a `VALIDATION` {@link DatabaseError} at
151
+ * `context.path === 'migration'` rather than surfacing a raw Contract or caller error.
106
152
  *
107
153
  * @param value - Unknown migration input
108
154
  * @returns Owned migration input
@@ -110,7 +156,7 @@ export declare function cloneDriverSchema(value: unknown): readonly TableSchema[
110
156
  export declare function cloneMigrationInput(value: unknown): MigrationInput;
111
157
 
112
158
  /**
113
- * One table's columns — a map of column name to its value {@link ContractShape}.
159
+ * Represents one table's columns — a map of column name to its value {@link ContractShape}.
114
160
  *
115
161
  * @remarks
116
162
  * This is exactly the property map an `objectShape` takes. A table row is always
@@ -122,7 +168,7 @@ export declare function cloneMigrationInput(value: unknown): MigrationInput;
122
168
  export declare type ColumnMap = Readonly<Record<string, ContractShape>>;
123
169
 
124
170
  /**
125
- * One column of a {@link TableSchema} — its name, portable {@link ColumnStorage}, and
171
+ * Represents one column of a {@link TableSchema} — its name, portable {@link ColumnStorage}, and
126
172
  * whether it independently accepts absence (`optional`) and explicit `null`
127
173
  * (`nullable`).
128
174
  */
@@ -134,7 +180,7 @@ export declare interface ColumnSchema {
134
180
  }
135
181
 
136
182
  /**
137
- * A portable storage type for a column — the backend maps it to its native type
183
+ * Names a portable storage type for a column — the backend maps it to its native type
138
184
  * (SQLite affinity, an IndexedDB value). Derived from a column's `ContractShape`
139
185
  * by `shapeToColumnStorage`; `json` covers object/array/union/raw values a backend stores
140
186
  * as JSON text and can `json_extract` for nested-field queries.
@@ -142,8 +188,8 @@ export declare interface ColumnSchema {
142
188
  export declare type ColumnStorage = 'text' | 'integer' | 'real' | 'boolean' | 'json' | 'blob';
143
189
 
144
190
  /**
145
- * A total ordering over arbitrary values — the comparator behind sorting and the
146
- * range operators.
191
+ * Compares two arbitrary values under one total order — the comparator behind
192
+ * sorting and the range operators.
147
193
  *
148
194
  * @remarks
149
195
  * Values of different types order by a fixed type rank (`undefined` < `null` <
@@ -158,7 +204,7 @@ export declare type ColumnStorage = 'text' | 'integer' | 'real' | 'boolean' | 'j
158
204
  export declare function compareValues(left: unknown, right: unknown): number;
159
205
 
160
206
  /**
161
- * Compute an aggregate over a column across rows.
207
+ * Computes an aggregate over a column across rows.
162
208
  *
163
209
  * @remarks
164
210
  * `count` returns the row count. The numeric aggregates coerce each cell with
@@ -174,14 +220,14 @@ export declare function compareValues(left: unknown, right: unknown): number;
174
220
  export declare function computeAggregate(rows: readonly unknown[], operation: AggregateOperation, column: FieldPath): number | undefined;
175
221
 
176
222
  /**
177
- * One compiled WHERE condition.
223
+ * Represents one compiled WHERE condition.
178
224
  *
179
225
  * @remarks
180
226
  * `values` carries the operands the operator needs — none for `absent` /
181
227
  * `present`, one for most, two for `between`, a list for `any` / `none`.
182
228
  * `connector` folds this condition into the accumulated result left-to-right;
183
229
  * the first condition's connector seeds the fold and is otherwise ignored.
184
- * `column` is a {@link FieldPath}: a single string is ONE column (never split on
230
+ * `column` is a {@link FieldPath}: a single string is one column (never split on
185
231
  * `.`), an array descends into a nested (object/`json`) value.
186
232
  */
187
233
  export declare interface Condition {
@@ -191,11 +237,11 @@ export declare interface Condition {
191
237
  readonly connector: ConditionConnector;
192
238
  }
193
239
 
194
- /** How a {@link Condition} joins to the running result of the conditions before it. */
240
+ /** Names how a {@link Condition} joins to the running result of the conditions before it. */
195
241
  export declare type ConditionConnector = 'and' | 'or';
196
242
 
197
243
  /**
198
- * A WHERE operator — the comparison a single {@link Condition} applies.
244
+ * Represents a WHERE operator — the comparison a single {@link Condition} applies.
199
245
  *
200
246
  * @remarks
201
247
  * Each maps to a SQL operator and an IndexedDB read strategy (a key range where
@@ -205,12 +251,46 @@ export declare type ConditionConnector = 'and' | 'or';
205
251
  export declare type ConditionOperator = 'equals' | 'not' | 'above' | 'below' | 'from' | 'to' | 'between' | 'like' | 'glob' | 'starts' | 'ends' | 'any' | 'none' | 'absent' | 'present';
206
252
 
207
253
  /**
208
- * One violated invariant from the driver-conformance battery.
254
+ * Describes the `posts` table the driver-conformance battery opens — keyed by a non-`id`
255
+ * `slug` primary column.
256
+ *
257
+ * @remarks
258
+ * Pairs with {@link CONFORMANCE_USERS_SCHEMA} so one battery exercises both
259
+ * primary-key shapes: the default `id` and an explicit override.
260
+ */
261
+ export declare const CONFORMANCE_POSTS_SCHEMA: TableSchema;
262
+
263
+ /**
264
+ * Holds the fixed `users` and `posts` schema every driver-conformance phase opens.
265
+ *
266
+ * @remarks
267
+ * Each phase mints a fresh driver and opens this exact schema, so a finding
268
+ * names a violated invariant rather than a setup difference between phases. The
269
+ * array and each schema in it are frozen, so a consumer holding it cannot change
270
+ * what a later phase opens.
271
+ */
272
+ export declare const CONFORMANCE_SCHEMA: readonly TableSchema[];
273
+
274
+ /**
275
+ * Describes the `users` table the driver-conformance battery opens — keyed by the default
276
+ * `id` primary column.
277
+ *
278
+ * @remarks
279
+ * `age` is optional and `meta` is a declared `json` column, so the battery's
280
+ * nested-round-trip phase is fair to a typed-column backend: a SQL driver
281
+ * persists only declared columns, while a schemaless backend ignores the
282
+ * declarations entirely.
283
+ */
284
+ export declare const CONFORMANCE_USERS_SCHEMA: TableSchema;
285
+
286
+ /**
287
+ * Represents one violated invariant from the driver-conformance battery.
209
288
  *
210
289
  * @remarks
211
290
  * Mirrors the payload shape of a `DatabaseError` `CONFORMANCE` `context` —
212
291
  * `check` names the invariant, `message` describes the violation, and
213
- * `context` carries the offending table / key / value that failed it.
292
+ * `context` carries the offending table / key / value that failed it. Yielded one at a
293
+ * time by {@link scanDriver} and collected whole by {@link auditDriver}.
214
294
  */
215
295
  export declare interface ConformanceFinding {
216
296
  readonly check: string;
@@ -219,17 +299,19 @@ export declare interface ConformanceFinding {
219
299
  }
220
300
 
221
301
  /**
222
- * Run the driver-conformance battery, throwing on the first violated
302
+ * Runs the driver-conformance battery, throwing on the first violated
223
303
  * invariant — the fail-fast entry point most callers (test setup, CI smoke
224
304
  * checks) want.
225
305
  *
226
306
  * @remarks
227
- * A thin driver over {@link driverFindings}: because that generator is
228
- * lazy, consuming only its first yielded value means every LATER phase
229
- * never runs — true fail-fast, not merely "report only the first". The
307
+ * Consumes only the first value {@link scanDriver} yields: because that
308
+ * generator is lazy, every later phase never runs true fail-fast, not
309
+ * merely "report only the first". The
230
310
  * thrown error is byte-compatible with the historical shape: a
231
311
  * `CONFORMANCE` {@link DatabaseError} whose `message` is the finding's
232
- * `message` and whose `context` is `{ check, ...finding.context }`.
312
+ * `message` and whose `context` is `{ check, ...finding.context }`. The battery
313
+ * takes a driver factory and reports through a throw, so it binds no test
314
+ * framework and runs from any runner.
233
315
  *
234
316
  * @param factory - Mints a fresh, unopened driver instance (called once per phase)
235
317
  * @returns Nothing — resolves once every phase has passed
@@ -245,40 +327,49 @@ export declare interface ConformanceFinding {
245
327
  export declare function conformDriver(factory: () => DriverInterface): Promise<void>;
246
328
 
247
329
  /**
248
- * Create a database over a driver and a declared `tables` schema.
330
+ * Creates a database over a driver and a declared `tables` schema.
249
331
  *
250
332
  * @remarks
251
333
  * `tables` maps each name to its columns (a `column → shape` map); the database
252
334
  * wraps each in an `objectShape`, so you never write `objectShape` at the table
253
335
  * level. The `const` type parameter captures the literal names and columns, so
254
336
  * `db.table('users')` is checked against the schema and typed by `Infer` of its
255
- * columns — no annotations. Name a non-`id` primary-key column per table via the
256
- * optional `primary` and `indexes` maps.
337
+ * columns — no annotations. Name a non-`id` primary-key column per table through
338
+ * the optional `primary` and `indexes` maps.
257
339
  *
258
340
  * @param options - The driver, `tables`, and optional `primary`, `indexes`,
259
341
  * `name`, `generator`, `version`, and emitter hooks
260
342
  * @returns A typed {@link DatabaseInterface}
261
343
  *
262
- * @example
344
+ * @example Create a database
263
345
  * ```ts
264
346
  * import { createDatabase, createMemoryDriver } from '@orkestrel/database'
265
347
  * import { integerShape, stringShape } from '@orkestrel/contract'
266
348
  *
267
349
  * const db = createDatabase({
268
- * driver: createMemoryDriver(),
350
+ * driver: createMemoryDriver(), // any DriverInterface — a persistent backend swaps in, same API
269
351
  * tables: {
270
- * users: { id: stringShape(), age: integerShape() },
352
+ * users: { id: stringShape(), name: stringShape(), age: integerShape() },
271
353
  * posts: { slug: stringShape(), title: stringShape() },
272
354
  * },
273
- * primary: { posts: 'slug' },
355
+ * primary: { posts: 'slug' }, // non-`id` primary-key columns, per table
274
356
  * })
275
- * await db.table('users').set({ id: 'u1', age: 36 }) // typed; coerced + validated
357
+ *
358
+ * const users = db.table('users') // hold the handle; TableInterface<{ id; name; age }>
359
+ *
360
+ * await users.set({ id: 'u1', name: 'Ada', age: 36 }) // coerced + validated through the contract
361
+ * await users.get('u1') // typed { id; name; age } | undefined — narrowed, never `as`
362
+ * await users
363
+ * .query()
364
+ * .condition({ column: 'age', operator: 'from', values: [18], connector: 'and' })
365
+ * .order({ column: 'age', direction: 'descending' })
366
+ * .collect() // typed rows
276
367
  * ```
277
368
  */
278
369
  export declare function createDatabase<const T extends TableMap>(options: DatabaseOptions<T>): DatabaseInterface<T>;
279
370
 
280
371
  /**
281
- * Create the in-memory reference {@link DriverInterface}.
372
+ * Creates the in-memory reference {@link DriverInterface}.
282
373
  *
283
374
  * @remarks
284
375
  * Backed by nested maps with no I/O — the same driver runs in a browser or on a
@@ -289,7 +380,7 @@ export declare function createDatabase<const T extends TableMap>(options: Databa
289
380
  export declare function createMemoryDriver(): DriverInterface;
290
381
 
291
382
  /**
292
- * A forward row cursor for bulk in-place mutation.
383
+ * Walks a table's rows forward for bulk in-place mutation.
293
384
  *
294
385
  * @remarks
295
386
  * Iterates a snapshot of the table's keys taken at creation; `update` and
@@ -304,20 +395,36 @@ export declare interface CursorInterface<T = Row> {
304
395
  readonly value: T | undefined;
305
396
  readonly index: number;
306
397
  readonly done: boolean;
398
+ /**
399
+ * Advances to the next present row.
400
+ */
307
401
  next(): Promise<void>;
402
+ /**
403
+ * Merges changes into the row at the current position.
404
+ */
308
405
  update(changes: Partial<T>): Promise<void>;
406
+ /**
407
+ * Deletes the row at the current position.
408
+ */
309
409
  remove(): Promise<void>;
410
+ /**
411
+ * Closes the cursor terminally, so every later operation is a no-op.
412
+ */
310
413
  close(): void;
311
414
  }
312
415
 
313
416
  /**
314
- * A typed database view over one shared internal lifecycle and storage context.
417
+ * Exposes a typed view over one shared internal lifecycle and storage context.
315
418
  *
316
419
  * @remarks
317
420
  * Each view owns only its table contracts, primary columns, indexes, and key
318
421
  * generator. Imported views register their physical schemas with the same
319
422
  * internal context before opening begins, so every view observes one driver,
320
423
  * merged schema, emitter, status, transaction boundary, and terminal close.
424
+ *
425
+ * The view owns the driver and its declared `tables`, connects that driver lazily on
426
+ * first use, `import`s further tables and `export`s their portable definitions, and
427
+ * runs `transaction` scopes over the shared context.
321
428
  */
322
429
  export declare class Database<T extends TableMap = TableMap> implements DatabaseInterface<T> {
323
430
  #private;
@@ -335,7 +442,7 @@ export declare class Database<T extends TableMap = TableMap> implements Database
335
442
  }
336
443
 
337
444
  /**
338
- * An error thrown by the database layer.
445
+ * Represents an error thrown by the database layer.
339
446
  *
340
447
  * @remarks
341
448
  * Carries a {@link DatabaseErrorCode} and an optional `context` bag naming the
@@ -346,7 +453,7 @@ export declare class Database<T extends TableMap = TableMap> implements Database
346
453
  * `context`), an inapplicable {@link Migration} plan (`MIGRATION`), a
347
454
  * driver that violates a {@link DriverInterface} invariant, thrown by the
348
455
  * `conformDriver` helper (`CONFORMANCE`), and an unexpected infrastructure
349
- * fault surfaced by a driver seam — e.g. a filesystem failure while
456
+ * fault surfaced by a driver seam — for example a filesystem failure while
350
457
  * persisting (`DRIVER`) — as opposed to expected domain conditions, which
351
458
  * keep their specific codes.
352
459
  */
@@ -356,48 +463,48 @@ export declare class DatabaseError extends Error {
356
463
  constructor(code: DatabaseErrorCode, message: string, context?: Readonly<Record<string, unknown>>);
357
464
  }
358
465
 
359
- /** A machine-readable {@link DatabaseError} code. */
466
+ /** Names a machine-readable {@link DatabaseError} code. */
360
467
  export declare type DatabaseErrorCode = 'CLOSED' | 'NOT_FOUND' | 'CONFLICT' | 'VALIDATION' | 'ABORTED' | 'MIGRATION' | 'CONFORMANCE' | 'DRIVER';
361
468
 
362
469
  /**
363
- * The push observation surface of a {@link DatabaseInterface} (AGENTS §13) — the
470
+ * Describes the push observation surface of a {@link DatabaseInterface} — the
364
471
  * connection + transaction lifecycle a fire-and-forget observer (logging, metrics,
365
472
  * tracing, cache invalidation) subscribes to.
366
473
  *
367
474
  * @remarks
368
475
  * Pure signals carrying no row data — these are the database-level (not per-row)
369
476
  * moments, so a non-generic map stays lean (per-row writes are {@link TableEventMap}).
370
- * Listener isolation is the emitter's (AGENTS §13): every event is emitted directly and a
371
- * listener throw is routed to the emitter's OWN `error` handler (the `error` option), never
477
+ * Listener isolation is the emitter's: every event is emitted directly and a
478
+ * listener throw is routed to the emitter's own `error` handler (the `error` option), never
372
479
  * onto this domain map and never into the snapshot / commit / rollback flow — so a buggy
373
- * observer can never reorder, throw into, or corrupt a transaction. Every emit sits AFTER the
480
+ * observer can never reorder, throw into, or corrupt a transaction. Every emit sits after the
374
481
  * relevant transition: `commit` only after the scope succeeds, `rollback` only after the
375
- * rollback operation completes (it OBSERVES the propagated scope error; that exact reason
482
+ * rollback operation completes (it observes the propagated scope error; that exact reason
376
483
  * still propagates). A rollback failure propagates instead and emits no misleading
377
- * `rollback` event. Subscribe via `database.emitter.on(...)`.
484
+ * `rollback` event. Subscribe through `database.emitter.on(...)`.
378
485
  *
379
- * Declared as a `type` alias (not `interface extends EventMap`, §4.5 — `EventMap` is a
486
+ * Declared as a `type` alias (not `interface extends EventMap` — `EventMap` is a
380
487
  * `type` kind): a type-literal satisfies the `EventMap` constraint
381
488
  * (`Record<string, readonly unknown[]>`) structurally, whereas an interface lacks the
382
489
  * required index signature.
383
490
  */
384
491
  export declare type DatabaseEventMap = {
385
- /** The driver connected (`open`, or the lazy first-use connect completed). */
492
+ /** Signals that the driver connected (`open`, or the lazy first-use connect completed). */
386
493
  readonly open: readonly [];
387
- /** The database was closed (the driver released). */
494
+ /** Signals that the database was closed (the driver released). */
388
495
  readonly close: readonly [];
389
- /** A transaction scope began after its native boundary or fallback snapshot was acquired. */
496
+ /** Signals that a transaction scope began after its native boundary or fallback snapshot was acquired. */
390
497
  readonly transaction: readonly [];
391
- /** A transaction scope completed successfully (no rollback). */
498
+ /** Signals that a transaction scope completed successfully (no rollback). */
392
499
  readonly commit: readonly [];
393
- /** A transaction scope failed and rollback completed — the exact propagated scope error. */
500
+ /** Signals that a transaction scope failed and rollback completed — the exact propagated scope error. */
394
501
  readonly rollback: readonly [error: unknown];
395
- /** A {@link Migration} plan was applied via `migrate` — the applied plan. */
502
+ /** Signals that a {@link Migration} plan was applied through `migrate` — the applied plan. */
396
503
  readonly migrate: readonly [migration: Migration];
397
504
  };
398
505
 
399
506
  /**
400
- * A database — the ergonomic entry point that owns the driver and its tables.
507
+ * Represents a database — the ergonomic entry point that owns the driver and its tables.
401
508
  *
402
509
  * @remarks
403
510
  * A database is a typed view over a set of tables on one driver. Tables are
@@ -415,19 +522,43 @@ export declare interface DatabaseInterface<T extends TableMap = TableMap> {
415
522
  readonly emitter: EmitterInterface<DatabaseEventMap>;
416
523
  readonly name: string;
417
524
  readonly status: DatabaseStatus;
525
+ /**
526
+ * Returns the typed handle for a declared table.
527
+ */
418
528
  table<K extends keyof T & string>(name: K): TableInterface<RowOf<T[K]>>;
529
+ /**
530
+ * Defines a further shape map of tables as a typed view over the same driver and storage.
531
+ */
419
532
  import<U extends TableMap>(tables: U, primary?: PrimaryMap): DatabaseInterface<U>;
533
+ /**
534
+ * Returns one portable {@link TableDefinition} per declared table.
535
+ */
420
536
  export(): Readonly<Record<string, TableDefinition>>;
537
+ /**
538
+ * Connects the driver eagerly, ahead of the lazy connect on first use.
539
+ */
421
540
  open(): Promise<void>;
541
+ /**
542
+ * Closes the database and releases its driver.
543
+ */
422
544
  close(): Promise<void>;
545
+ /**
546
+ * Runs a scope over a {@link DatabaseStorageInterface}, committing when the callback
547
+ * fulfills and rolling back when it rejects.
548
+ *
549
+ * @remarks
550
+ * A native driver transaction carries the scope where the driver offers one;
551
+ * otherwise the universal whole-store snapshot floor does. `options.signal` is
552
+ * checked once, at entry.
553
+ */
423
554
  transaction<R>(scope: (transaction: DatabaseStorageInterface<T>) => Promise<R>, options?: OperationOptions): Promise<R>;
424
555
  /**
425
- * Diff a caller-supplied deployed schema against this database's declared
426
- * schema (its `tables`, as configured) via `planMigration`, apply the
427
- * resulting plan through the driver's optional `migrate` hook, and return
556
+ * Diffs a caller-supplied deployed schema against this database's declared
557
+ * schema (its `tables`, as configured) through `planMigration`, applies the
558
+ * resulting plan through the driver's optional `migrate` hook, and returns
428
559
  * the applied plan.
429
560
  *
430
- * @param deployed - The schema currently deployed, as {@link TableSchema}s
561
+ * @param deployed - The deployed schema, as {@link TableSchema}s
431
562
  * @param options - Optional abort signal, checked at entry
432
563
  * @returns The applied {@link Migration} plan
433
564
  *
@@ -459,8 +590,8 @@ export declare interface DatabaseInterface<T extends TableMap = TableMap> {
459
590
  * `primary` overrides the primary-key column per table ({@link DEFAULT_PRIMARY}
460
591
  * otherwise); `indexes` declares secondary indexes per table (contracts don't
461
592
  * express them) that flow into each derived {@link TableSchema}; `name` labels
462
- * the database; `on` wires initial {@link DatabaseEventMap} listeners (§8); `error`
463
- * is the emitter's listener-error handler (§13 — a listener throw routes here);
593
+ * the database; `on` wires initial {@link DatabaseEventMap} listeners; `error`
594
+ * is the emitter's listener-error handler (a listener throw routes here);
464
595
  * `generator` is the authoritative key-generation override a table uses when a
465
596
  * written row's primary is exactly `undefined`. When omitted, the table uses
466
597
  * global `crypto.randomUUID()`; numeric primary keys require a custom generator.
@@ -468,7 +599,7 @@ export declare interface DatabaseInterface<T extends TableMap = TableMap> {
468
599
  export declare interface DatabaseOptions<T extends TableMap = TableMap> {
469
600
  readonly on?: EmitterHooks<DatabaseEventMap>;
470
601
  /**
471
- * The listener-error handler shared by the database and every table emitter.
602
+ * Holds the listener-error handler shared by the database and every table emitter.
472
603
  *
473
604
  * @remarks
474
605
  * Listener throws from root, imported, and transaction-scoped handles route
@@ -482,31 +613,31 @@ export declare interface DatabaseOptions<T extends TableMap = TableMap> {
482
613
  readonly indexes?: IndexMap;
483
614
  readonly name?: string;
484
615
  /**
485
- * The authoritative key-generation override for a keyless write.
616
+ * Holds the authoritative key-generation override for a keyless write.
486
617
  *
487
618
  * @remarks
488
619
  * Omit it to use global `crypto.randomUUID()`. A numeric primary requires a
489
620
  * custom generator. Explicit primary values never invoke this function. A
490
- * custom generator throw is `VALIDATION`; a host
491
- * `crypto.randomUUID()` failure is `DRIVER`. An invalid returned key is
492
- * `VALIDATION`; neither branch falls back or retries.
621
+ * custom generator throw is `VALIDATION`; a host `crypto.randomUUID()` failure
622
+ * is `DRIVER`. An invalid returned key is `VALIDATION`; neither branch falls
623
+ * back or retries.
493
624
  */
494
625
  readonly generator?: KeyFunction;
495
626
  /**
496
- * The declared schema version.
627
+ * Holds the declared schema version.
497
628
  *
498
629
  * @remarks
499
- * Only meaningful when the driver implements BOTH {@link DriverInterface.metadata}
630
+ * Only meaningful when the driver implements both {@link DriverInterface.metadata}
500
631
  * and {@link DriverInterface.stamp} (a versioning driver); unset, or a
501
632
  * non-versioning driver, leaves `open()` unchanged from today's behavior.
502
- * When set and the driver versions, `open()` reconciles against the
503
- * driver's persisted {@link DriverMetadata}:
633
+ * When set and the driver versions, `open()` reconciles against the driver's
634
+ * persisted {@link DriverMetadata}:
504
635
  * - **Fresh store** (`metadata()` returns `undefined` after the durable
505
636
  * driver proves absence) — no migration is possible (there is nothing
506
- * deployed to diff against), so `open()` simply `stamp`s
507
- * `{ version, schema }` for next time.
637
+ * deployed to diff against), so `open()` stamps `{ version, schema }` for
638
+ * next time.
508
639
  * - **Stored version < `version`** — `planMigration(stored.schema, declared
509
- * schema)` computes the upgrade plan, applied via the driver's optional
640
+ * schema)` computes the upgrade plan, applied through the driver's optional
510
641
  * `migrate` hook. If `migrate` is absent and the plan is non-empty,
511
642
  * `open()` throws `DatabaseError` `MIGRATION`. On success, `open()`
512
643
  * `stamp`s the new `{ version, schema }` and emits the `migrate` event.
@@ -524,11 +655,11 @@ export declare interface DatabaseOptions<T extends TableMap = TableMap> {
524
655
  readonly version?: number;
525
656
  }
526
657
 
527
- /** The lifecycle state of a {@link DatabaseInterface}. */
658
+ /** Names the lifecycle state of a {@link DatabaseInterface}. */
528
659
  export declare type DatabaseStatus = 'idle' | 'open' | 'closed';
529
660
 
530
661
  /**
531
- * A database view valid only inside one {@link DatabaseInterface.transaction}
662
+ * Represents a database view valid only inside one {@link DatabaseInterface.transaction}
532
663
  * scope.
533
664
  *
534
665
  * @remarks
@@ -538,11 +669,17 @@ export declare type DatabaseStatus = 'idle' | 'open' | 'closed';
538
669
  * after the scope settles.
539
670
  */
540
671
  export declare interface DatabaseStorageInterface<T extends TableMap = TableMap> {
672
+ /**
673
+ * Returns a table bound to the active transaction scope.
674
+ *
675
+ * @remarks
676
+ * The returned table throws `CONFLICT` for work started after the scope settles.
677
+ */
541
678
  table<K extends keyof T & string>(name: K): TableInterface<RowOf<T[K]>>;
542
679
  }
543
680
 
544
681
  /**
545
- * The primary-key column assumed when {@link PrimaryMap} does not name one.
682
+ * Supplies the primary-key column, `'id'`, assumed when {@link PrimaryMap} does not name one.
546
683
  *
547
684
  * @remarks
548
685
  * `id` is the convention IndexedDB (`keyPath: 'id'`) and SQL (`id` / rowid) both
@@ -551,93 +688,43 @@ export declare interface DatabaseStorageInterface<T extends TableMap = TableMap>
551
688
  export declare const DEFAULT_PRIMARY = "id";
552
689
 
553
690
  /**
554
- * Run the driver-conformance battery against a fresh {@link DriverInterface}
555
- * per phase, yielding one {@link ConformanceFinding} per violated invariant —
556
- * the shared invariant suite every backend (in-memory, SQLite, IndexedDB)
557
- * must uphold to be a drop-in {@link DriverInterface}.
691
+ * Declares the storage primitive every backend implements the whole of the bridge.
558
692
  *
559
693
  * @remarks
560
- * Framework-agnostic: no test-runner or Node imports, only sibling core
561
- * modules so it runs equally from a unit test, a smoke script, or a new
562
- * driver's own README. Opens a fixed two-table schema (`users` keyed by the
563
- * default `id`, `posts` keyed by a non-id `slug`) and, calling `factory()`
564
- * fresh for each phase so failures stay isolated, verifies: `open`/`close`;
565
- * `read` of a missing key returns `undefined`; `write`/`read` round-trip with
566
- * DEEP copy-in/copy-out isolation (mutating the caller's row including a
567
- * NESTED field after `write`, or a row `read` returns, never perturbs
568
- * stored state) and upsert-overwrite; simultaneous same-key `insert` calls
569
- * produce exactly one commit and one `CONFLICT`; pre-aborted `write`,
570
- * `insert`, and `delete` calls leave storage unchanged; `delete` returns
571
- * `true` then `false`;
572
- * `keys`/`scan` yield in ascending key order; `clear` empties only its target
573
- * table; `snapshot`'s rollback thunk restores pre-snapshot state, including a
574
- * NESTED field mutated in place on a read-back row between capture and
575
- * restore; a scoped `snapshot(['users'])` rolls back only the named table,
576
- * leaving a concurrent mutation to another table intact; a
577
- * non-`id` primary key (`posts.slug`) round-trips; a nested-object row
578
- * round-trips structurally (via {@link equalsValue}). The optional surface is
579
- * presence-gated: when `migrate` exists, a `column.remove` plan strips the
580
- * column from stored rows and a plan referencing an unknown table throws
581
- * `DatabaseError` `MIGRATION`; when `stream` exists, it yields only
582
- * condition-matching rows and honors `offset`/`limit`; when `transaction`
583
- * exists, `commit` persists and `rollback` restores; when both `metadata` and
584
- * `stamp` exist, a fresh store's `metadata()` is `undefined`, and after
585
- * `stamp({ version, schema })`, `metadata()` returns the exact stamped value.
586
- *
587
- * Each phase runs within a `try`/`catch`: an EXPECTED mismatch yields a
588
- * finding built from the assertion, while an UNEXPECTED throw (a driver
589
- * crash mid-phase) is caught and yielded as a finding too, naming the phase
590
- * as `check` and carrying the caught error in `context.error` — a broken
591
- * driver can never escape the battery as an unhandled rejection. Within a
592
- * phase, the FIRST violated assertion yields and the phase stops (matching
593
- * the historical fail-fast shape at phase granularity); the generator then
594
- * moves on to the next phase regardless. Because this is a **generator**,
595
- * consuming only the first yielded value reproduces true fail-fast (later
596
- * phases never run) — that is exactly what {@link conformDriver} does.
597
- *
598
- * @param factory - Mints a fresh, unopened driver instance (called once per phase)
599
- * @yields One {@link ConformanceFinding} per violated invariant, in phase order
600
- *
601
- * @example
602
- * ```ts
603
- * import { createMemoryDriver, driverFindings } from '@orkestrel/database'
604
- *
605
- * for await (const finding of driverFindings(() => createMemoryDriver())) {
606
- * console.log(finding.check, finding.message)
607
- * }
608
- * ```
609
- */
610
- export declare function driverFindings(factory: () => DriverInterface): AsyncIterable<ConformanceFinding>;
611
-
612
- /**
613
- * The storage primitive every backend implements — the whole of the bridge.
614
- *
615
- * @remarks
616
- * The REQUIRED surface is deliberately minimal: keyed read / write / atomic
617
- * insert / delete, an ordered `scan`, a key listing, and a `snapshot` that backs
618
- * transactions — the irreducible primitive. There is **no** required query,
619
- * count, or aggregate
620
- * here: all of that is one query engine in the core (`helpers.ts`) running over
621
- * `scan`, so a new backend implements a handful of tiny methods rather than
622
- * re-deriving WHERE compilation. `open` now receives a derived
623
- * {@link TableSchema}`[]` (columns, types, primary, indexes) so a native backend
624
- * can build real tables and indexes; a scan-only backend reads only `name`. The
625
- * optional `records?` / `aggregate?` are native overrides the engine
626
- * falls back from (AGENTS §21). The API is async (Promises) because IndexedDB is; synchronous
627
- * backends resolve immediately. Lookups that may miss return `undefined` /
628
- * `false` rather than throwing (AGENTS §12). Metadata has the same ownership
694
+ * The required surface is deliberately minimal: keyed read / write / atomic
695
+ * insert / delete, an ordered `scan`, a key listing, and a `snapshot` that
696
+ * backs transactions the irreducible primitive. There is **no** required
697
+ * query, count, or aggregate here: all of that is one query engine in the core
698
+ * (`helpers.ts`) running over `scan`, so a new backend implements a handful of
699
+ * tiny methods rather than re-deriving WHERE compilation. `open` receives a
700
+ * derived {@link TableSchema}`[]` (columns, types, primary, indexes) so a
701
+ * native backend can build real tables and indexes; a scan-only backend reads
702
+ * only `name`. The optional `records?` / `aggregate?` are native overrides the
703
+ * engine falls back from. The API is async (Promises) because IndexedDB is;
704
+ * synchronous backends resolve immediately. Lookups that may miss return
705
+ * `undefined` / `false` rather than throwing. Metadata has the same ownership
629
706
  * boundary across every implementation: `stamp` and `migrate` snapshot
630
- * {@link DriverMetadata} at entry, while `metadata` returns a distinct deeply frozen
631
- * snapshot. A durable driver returns `undefined` only when it proves the
707
+ * {@link DriverMetadata} at entry, while `metadata` returns a distinct deeply
708
+ * frozen snapshot. A durable driver returns `undefined` only when it proves the
632
709
  * metadata record or durable store is absent. Existing unreadable or malformed
633
710
  * durable state fails `open` / `metadata` closed; it is never treated as fresh,
634
711
  * rewritten, or repaired automatically.
635
712
  */
636
713
  export declare interface DriverInterface extends StorageInterface {
714
+ /**
715
+ * Readies the tables from a derived {@link TableSchema} list.
716
+ *
717
+ * @remarks
718
+ * A native backend builds real tables and indexes from the derived columns,
719
+ * types, primary, and index groups; a scan-only backend reads `name` alone.
720
+ */
637
721
  open(schema: readonly TableSchema[]): Promise<void>;
722
+ /**
723
+ * Releases the backend.
724
+ */
638
725
  close(): Promise<void>;
639
726
  /**
640
- * Capture table rows and return a repeatable thunk that restores those rows —
727
+ * Captures table rows and returns a repeatable thunk that restores those rows —
641
728
  * the primitive transactions are built on.
642
729
  *
643
730
  * @remarks
@@ -648,14 +735,61 @@ export declare interface DriverInterface extends StorageInterface {
648
735
  */
649
736
  snapshot(tables?: readonly string[]): Promise<() => Promise<void>>;
650
737
  /**
651
- * Optional native transaction scope. The driver owns acquisition, commit or
652
- * rollback, release, and invalidation of the scoped capability.
738
+ * Opens a native transaction scope — an optional driver hook. The driver owns acquisition,
739
+ * commit or rollback, release, and invalidation of the scoped capability.
653
740
  */
654
741
  transaction?<R>(scope: (storage: StorageInterface) => Promise<R>): Promise<R>;
655
742
  }
656
743
 
657
744
  /**
658
- * Persisted schema metadata a versioning driver owns as an immutable snapshot.
745
+ * Forms the internal continuation boundary for a root driver async iterator.
746
+ *
747
+ * @remarks
748
+ * A driver transaction can begin while a caller holds an idle root iterator.
749
+ * Every `next` therefore checks the driver's root-state guard immediately
750
+ * before and after advancing the source. A failed continuation terminalizes the
751
+ * iterator, discards any row produced before the post-advance guard failed, and
752
+ * attempts source cleanup exactly once.
753
+ *
754
+ * A driver implementing the published `DriverInterface` extension seam wraps its
755
+ * own source iterator in one so a root `scan` / `stream` cannot outlive the
756
+ * driver state it was opened against.
757
+ *
758
+ * @typeParam T - The value the wrapped source yields
759
+ *
760
+ * @example
761
+ * ```ts
762
+ * import type { Row } from '@orkestrel/database'
763
+ * import { DatabaseError, DriverIterator } from '@orkestrel/database'
764
+ *
765
+ * // Inside a driver's `scan`, over its own row source and root-state guard.
766
+ * declare const rows: AsyncIterator<Row>
767
+ * declare const transacting: () => boolean
768
+ * const scan = new DriverIterator(rows, () => {
769
+ * if (transacting()) {
770
+ * throw new DatabaseError('CONFLICT', 'scan: a transaction is active')
771
+ * }
772
+ * })
773
+ * for await (const row of scan) row // one row at a time, guarded around each advance
774
+ * ```
775
+ */
776
+ export declare class DriverIterator<T> implements AsyncIterableIterator<T> {
777
+ #private;
778
+ /**
779
+ * Wraps one source iterator in the continuation boundary.
780
+ *
781
+ * @param source - The driver's own row iterator, advanced once per `next`
782
+ * @param guard - The root-state check, run immediately before and after each advance; it throws to terminalize the iteration
783
+ */
784
+ constructor(source: AsyncIterator<T>, guard: () => void);
785
+ [Symbol.asyncIterator](): AsyncIterableIterator<T>;
786
+ next(): Promise<IteratorResult<T>>;
787
+ return(): Promise<IteratorResult<T>>;
788
+ throw(error?: unknown): Promise<IteratorResult<T>>;
789
+ }
790
+
791
+ /**
792
+ * Represents persisted schema metadata a versioning driver owns as an immutable snapshot.
659
793
  *
660
794
  * @remarks
661
795
  * A driver snapshots metadata when it enters through `stamp` or a
@@ -671,15 +805,16 @@ export declare interface DriverMetadata {
671
805
  }
672
806
 
673
807
  /**
674
- * Structural equality by SameValueZero leaves — the comparator behind conformance
675
- * checks and any test/fixture that needs "same data", not "same reference".
808
+ * Compares two values structurally by SameValueZero leaves — the comparator
809
+ * behind conformance checks and any test/fixture that needs "same data", not
810
+ * "same reference".
676
811
  *
677
812
  * @remarks
678
813
  * Primitives compare by SameValueZero (`NaN` equals itself; `+0` equals `-0`).
679
814
  * Arrays compare by index (same length, every element `equalsValue`). Plain
680
- * records (via `isRecord`) compare by their OWN enumerable keys: same key
681
- * COUNT and, for every key in `left`, `right` has that key (`Object.hasOwn`)
682
- * with a `equalsValue` value — so a key present with value `undefined` is NOT
815
+ * records (through `isRecord`) compare by their own enumerable keys: same key
816
+ * count and, for every key in `left`, `right` has that key (`Object.hasOwn`)
817
+ * with a `equalsValue` value — so a key present with value `undefined` is not
683
818
  * equal to that key being absent (both differ in `Object.keys` membership).
684
819
  * Anything else (functions, class instances, mismatched shapes) falls through
685
820
  * to `false`. Container pairs are tracked iteratively, so self-referential and
@@ -688,7 +823,7 @@ export declare interface DriverMetadata {
688
823
  *
689
824
  * @param left - The left value
690
825
  * @param right - The right value
691
- * @returns Whether `left` and `right` are structurally equal
826
+ * @returns True if `left` and `right` are structurally equal; false otherwise
692
827
  *
693
828
  * @example
694
829
  * ```ts
@@ -700,7 +835,7 @@ export declare interface DriverMetadata {
700
835
  export declare function equalsValue(left: unknown, right: unknown): boolean;
701
836
 
702
837
  /**
703
- * Read a row's primary key from a column, when it is a usable {@link Key}.
838
+ * Reads a row's primary key from a column, when it is a usable {@link Key}.
704
839
  *
705
840
  * @param row - The row to read
706
841
  * @param column - The primary-key column name
@@ -709,7 +844,7 @@ export declare function equalsValue(left: unknown, right: unknown): boolean;
709
844
  export declare function extractKey(row: Row, column: string): Key | undefined;
710
845
 
711
846
  /**
712
- * Filter rows by a list of conditions — the shared basis for a table's count
847
+ * Filters rows by a list of conditions — the shared basis for a table's count
713
848
  * and aggregate paths (no sort/page, unlike {@link applyQuery}).
714
849
  *
715
850
  * @remarks
@@ -731,7 +866,29 @@ export declare function extractKey(row: Row, column: string): Key | undefined;
731
866
  export declare function filterRows(rows: readonly Row[], conditions: readonly Condition[]): readonly Row[];
732
867
 
733
868
  /**
734
- * Per-table secondary indexes `{ [table]: groups }`, each group one
869
+ * Reads one flat column's declaration out of a table schema.
870
+ *
871
+ * @remarks
872
+ * The single lookup behind every declared-column question — storage type,
873
+ * optionality, and nullability all come off the returned {@link ColumnSchema},
874
+ * so a caller that needs more than one of them reads them from one result. A
875
+ * nested {@link FieldPath} names no declared column, so resolve the path's head
876
+ * before calling. A schema that does not declare the column returns `undefined`.
877
+ *
878
+ * @param name - The flat column name
879
+ * @param schema - The table's schema
880
+ * @returns The column's {@link ColumnSchema}, or `undefined` when the schema does not declare it
881
+ *
882
+ * @example
883
+ * ```ts
884
+ * findColumn('age', schema)?.storage // 'integer'
885
+ * findColumn('absent', schema) // undefined
886
+ * ```
887
+ */
888
+ export declare function findColumn(name: string, schema: TableSchema): ColumnSchema | undefined;
889
+
890
+ /**
891
+ * Holds per-table secondary indexes — `{ [table]: groups }`, each group one
735
892
  * (possibly compound) index of column names.
736
893
  *
737
894
  * @remarks
@@ -742,18 +899,22 @@ export declare function filterRows(rows: readonly Row[], conditions: readonly Co
742
899
  export declare type IndexMap = Readonly<Record<string, ReadonlyArray<readonly string[]>>>;
743
900
 
744
901
  /**
745
- * Test whether a value is a portable column schema.
902
+ * Checks whether a value is a portable column schema.
903
+ *
904
+ * @remarks
905
+ * Total over any input: a hostile getter, a revoked proxy, or a cyclic value is
906
+ * contained as a non-match rather than a throw.
746
907
  *
747
908
  * @param value - The value to test
748
- * @returns Whether `value` is a complete {@link ColumnSchema}
909
+ * @returns True if `value` is a complete {@link ColumnSchema}; false otherwise
749
910
  */
750
911
  export declare function isColumnSchema(value: unknown): value is ColumnSchema;
751
912
 
752
913
  /**
753
- * Narrow an unknown caught value to a {@link DatabaseError}.
914
+ * Narrows an unknown caught value to a {@link DatabaseError}.
754
915
  *
755
916
  * @param value - The value to test (typically a `catch` binding)
756
- * @returns `true` when `value` is a {@link DatabaseError}
917
+ * @returns True if `value` is a {@link DatabaseError}; false otherwise
757
918
  *
758
919
  * @example
759
920
  * ```ts
@@ -767,63 +928,89 @@ export declare function isColumnSchema(value: unknown): value is ColumnSchema;
767
928
  export declare function isDatabaseError(value: unknown): value is DatabaseError;
768
929
 
769
930
  /**
770
- * Test whether a value is persisted driver metadata.
931
+ * Checks whether a value is persisted driver metadata.
932
+ *
933
+ * @remarks
934
+ * The boundary check a versioning driver's `metadata()` narrows a stored or
935
+ * deserialized record through, so no call site needs an assertion. Total over any
936
+ * input: a hostile getter, a revoked proxy, or a cyclic value is contained as a
937
+ * non-match rather than a throw.
771
938
  *
772
939
  * @param value - The value to test
773
- * @returns Whether `value` is complete {@link DriverMetadata}
940
+ * @returns True if `value` is complete {@link DriverMetadata}; false otherwise
774
941
  */
775
942
  export declare function isDriverMetadata(value: unknown): value is DriverMetadata;
776
943
 
777
944
  /**
778
- * Test whether a value is a complete portable driver schema.
945
+ * Checks whether a value is a complete portable driver schema.
946
+ *
947
+ * @remarks
948
+ * Total over any input: a hostile getter, a revoked proxy, or a cyclic value is
949
+ * contained as a non-match rather than a throw.
779
950
  *
780
951
  * @param value - The value to test
781
- * @returns Whether `value` is a table-schema collection with unique table names
952
+ * @returns True if `value` is a table-schema collection with unique table names; false otherwise
782
953
  */
783
954
  export declare function isDriverSchema(value: unknown): value is readonly TableSchema[];
784
955
 
785
956
  /**
786
- * Test whether a value is a usable database key.
957
+ * Checks whether a value is a usable database key.
787
958
  *
788
959
  * @param value - The value to test
789
- * @returns Whether `value` is a string or finite number
960
+ * @returns True if `value` is a string or a finite number; false otherwise
790
961
  */
791
962
  export declare function isKey(value: unknown): value is Key;
792
963
 
793
964
  /**
794
- * Test whether a value is an ordered migration plan.
965
+ * Checks whether a value is an ordered migration plan.
966
+ *
967
+ * @remarks
968
+ * Total over any input: a hostile getter, a revoked proxy, or a cyclic value is
969
+ * contained as a non-match rather than a throw.
795
970
  *
796
971
  * @param value - The value to test
797
- * @returns Whether `value` is a complete {@link Migration}
972
+ * @returns True if `value` is a complete {@link Migration}; false otherwise
798
973
  */
799
974
  export declare function isMigration(value: unknown): value is Migration;
800
975
 
801
976
  /**
802
- * Test whether a value is one atomic migration request.
977
+ * Checks whether a value is one atomic migration request.
978
+ *
979
+ * @remarks
980
+ * Total over any input: a hostile getter, a revoked proxy, or a cyclic value is
981
+ * contained as a non-match rather than a throw.
803
982
  *
804
983
  * @param value - The value to test
805
- * @returns Whether `value` is a complete {@link MigrationInput}
984
+ * @returns True if `value` is a complete {@link MigrationInput}; false otherwise
806
985
  */
807
986
  export declare function isMigrationInput(value: unknown): value is MigrationInput;
808
987
 
809
988
  /**
810
- * Test whether a value is one ordered migration step.
989
+ * Checks whether a value is one ordered migration step.
990
+ *
991
+ * @remarks
992
+ * Total over any input: a hostile getter, a revoked proxy, or a cyclic value is
993
+ * contained as a non-match rather than a throw.
811
994
  *
812
995
  * @param value - The value to test
813
- * @returns Whether `value` is a complete {@link MigrationStep}
996
+ * @returns True if `value` is a complete {@link MigrationStep}; false otherwise
814
997
  */
815
998
  export declare function isMigrationStep(value: unknown): value is MigrationStep;
816
999
 
817
1000
  /**
818
- * Test whether a value is a portable table schema.
1001
+ * Checks whether a value is a portable table schema.
1002
+ *
1003
+ * @remarks
1004
+ * Total over any input: a hostile getter, a revoked proxy, or a cyclic value is
1005
+ * contained as a non-match rather than a throw.
819
1006
  *
820
1007
  * @param value - The value to test
821
- * @returns Whether `value` is a complete {@link TableSchema}
1008
+ * @returns True if `value` is a complete {@link TableSchema}; false otherwise
822
1009
  */
823
1010
  export declare function isTableSchema(value: unknown): value is TableSchema;
824
1011
 
825
1012
  /**
826
- * A primary key — the value identifying a row within its table.
1013
+ * Represents a primary key — the value identifying a row within its table.
827
1014
  *
828
1015
  * @remarks
829
1016
  * `string | number` is the intersection of what IndexedDB key ranges and SQL
@@ -833,7 +1020,7 @@ export declare function isTableSchema(value: unknown): value is TableSchema;
833
1020
  export declare type Key = string | number;
834
1021
 
835
1022
  /**
836
- * A key-generating function.
1023
+ * Represents a key-generating function.
837
1024
  *
838
1025
  * @remarks
839
1026
  * Supplied through {@link DatabaseOptions.generator} as an authoritative
@@ -844,56 +1031,75 @@ export declare type Key = string | number;
844
1031
  export declare type KeyFunction = () => Key;
845
1032
 
846
1033
  /**
847
- * Evaluate one {@link Condition} against a row — the per-operator predicate.
1034
+ * Evaluates one {@link Condition} against a row — the per-operator predicate.
848
1035
  *
849
1036
  * @remarks
850
1037
  * Reads the condition's column — a `FieldPath`, resolved with `resolveField` (a
851
1038
  * string is one column; an array descends a nested value) — and applies the
852
1039
  * operator. Range operators (`above` / `below` / `from` / `to` / `between`) use
853
1040
  * {@link compareValues}, the total order; the equality family (`equals` / `not`
854
- * / `any` / `none`) uses {@link equalsValue} — STRUCTURAL equality, not the total
1041
+ * / `any` / `none`) uses {@link equalsValue} — structural equality, not the total
855
1042
  * order's rank-5-collapses-all-objects behavior, so `equals` on an object/array
856
1043
  * operand only matches a structurally-equal value, never every row holding any
857
1044
  * object. This is a semantics change from ranking: `equalsValue` is SameValueZero
858
1045
  * on leaves, so `NaN` now equals `NaN` under `equals` / `any` (it never matched
859
1046
  * anything under the old rank-based comparison). `like` / `glob` / `starts` /
860
1047
  * `ends` match only strings; `absent` / `present` test nullishness. Total — a
861
- * type mismatch is simply a non-match.
1048
+ * type mismatch is a non-match.
862
1049
  *
863
1050
  * @param row - The row to test
864
1051
  * @param condition - The condition to apply
865
- * @returns Whether the row satisfies the condition
1052
+ * @returns True if the row satisfies the condition; false otherwise
866
1053
  */
867
1054
  export declare function matchesCondition(row: Row, condition: Condition): boolean;
868
1055
 
869
1056
  /**
870
- * Match a query against a value as a case-insensitive ordered subsequence.
1057
+ * Matches a value against a `GLOB` pattern, preserving case.
871
1058
  *
872
1059
  * @remarks
873
- * Every query character must appear in order in the value, but the characters
874
- * do not need to be contiguous. Query characters are literal, including
875
- * whitespace. Matching applies JavaScript `toLowerCase()` to both inputs
876
- * without locale-specific folding or Unicode normalization. An empty query
877
- * matches every value.
1060
+ * `*` matches any run of characters (including none) and `?` matches exactly one
1061
+ * character; every other pattern character matches itself literally, so a
1062
+ * character class such as `[a-z]` is not interpreted. Runs on
1063
+ * {@link matchesWildcardPattern}, so the match is linear in the value length and
1064
+ * the pattern is capped at {@link MAX_PATTERN_LENGTH}.
878
1065
  *
879
- * @param value - The text searched for the query's characters
880
- * @param query - The characters that must all appear in order
881
- * @returns Whether the case-folded query is a subsequence of the case-folded value
1066
+ * @param value - The value to test
1067
+ * @param pattern - The `GLOB` pattern
1068
+ * @returns True if `value` matches `pattern` case-sensitively; false otherwise
1069
+ * @throws A `VALIDATION` {@link DatabaseError} when `pattern` exceeds {@link MAX_PATTERN_LENGTH}
882
1070
  *
883
1071
  * @example
884
1072
  * ```ts
885
- * matchesFuzzy('Database', 'dbe') // true
886
- * matchesFuzzy('Database', 'abd') // false
1073
+ * matchesGlobPattern('hello', 'h*o') // true — `*` spans any run
1074
+ * matchesGlobPattern('Hello', 'h*o') // false — `GLOB` is case-sensitive
887
1075
  * ```
888
1076
  */
889
- export declare function matchesFuzzy(value: string, query: string): boolean;
890
-
891
1077
  export declare function matchesGlobPattern(value: string, pattern: string): boolean;
892
1078
 
1079
+ /**
1080
+ * Matches a value against a SQL `LIKE` pattern, folding case.
1081
+ *
1082
+ * @remarks
1083
+ * `%` matches any run of characters (including none) and `_` matches exactly one
1084
+ * character; every other pattern character matches itself literally. Runs on
1085
+ * {@link matchesWildcardPattern}, so the match is linear in the value length and
1086
+ * the pattern is capped at {@link MAX_PATTERN_LENGTH}.
1087
+ *
1088
+ * @param value - The value to test
1089
+ * @param pattern - The `LIKE` pattern
1090
+ * @returns True if `value` matches `pattern` under case folding; false otherwise
1091
+ * @throws A `VALIDATION` {@link DatabaseError} when `pattern` exceeds {@link MAX_PATTERN_LENGTH}
1092
+ *
1093
+ * @example
1094
+ * ```ts
1095
+ * matchesLikePattern('Hello', 'h%o') // true — `%` spans any run, and case folds
1096
+ * matchesLikePattern('Hello', 'h_llo') // true — `_` matches exactly one character
1097
+ * ```
1098
+ */
893
1099
  export declare function matchesLikePattern(value: string, pattern: string): boolean;
894
1100
 
895
1101
  /**
896
- * Fold a row through a list of conditions, joining each by its connector.
1102
+ * Folds a row through a list of conditions, joining each by its connector.
897
1103
  *
898
1104
  * @remarks
899
1105
  * Evaluated left-to-right: the first condition seeds the result, and each later
@@ -903,21 +1109,21 @@ export declare function matchesLikePattern(value: string, pattern: string): bool
903
1109
  *
904
1110
  * @param row - The row to test
905
1111
  * @param conditions - The conditions to fold
906
- * @returns Whether the row satisfies the combined conditions
1112
+ * @returns True if the row satisfies the combined conditions; false otherwise
907
1113
  */
908
1114
  export declare function matchesQuery(row: Row, conditions: readonly Condition[]): boolean;
909
1115
 
910
1116
  /**
911
- * Match a value against a wildcard pattern in LINEAR time — the shared, ReDoS-SAFE
1117
+ * Matches a value against a wildcard pattern in linear time — the shared, ReDoS-safe
912
1118
  * engine behind {@link matchesLikePattern} and {@link matchesGlobPattern}.
913
1119
  *
914
1120
  * @remarks
915
- * A backtracking RegExp (`a%b%c` → `^a.*b.*c$`) is CATASTROPHIC on a hostile pattern:
1121
+ * A backtracking RegExp (`a%b%c` → `^a.*b.*c$`) is catastrophic on a hostile pattern:
916
1122
  * `.*` segments separated by literals, matched against a long non-matching input, blow
917
- * up super-linearly — and JS has no atomic groups / possessive quantifiers to bound it
918
- * (AGENTS §6.5, now that the authed server runs model-supplied `list` input over the
919
- * wire). So this builds NO regex. It runs the classic GREEDY TWO-POINTER wildcard match:
920
- * the `any` wildcard records its position and, on a later mismatch, backtracks ONLY to
1123
+ * up super-linearly — and JS has no atomic groups / possessive quantifiers to bound it,
1124
+ * while a `LIKE` / `GLOB` pattern is a caller-supplied operand this package cannot
1125
+ * trust. So this builds no regex. It runs the classic greedy two-pointer wildcard match:
1126
+ * the `any` wildcard records its position and, on a later mismatch, backtracks only to
921
1127
  * that last `any` (letting it absorb one more char) — so the work is O(value × pattern),
922
1128
  * never the exponential / polynomial backtracking a regex would do. The pattern length
923
1129
  * is capped at {@link MAX_PATTERN_LENGTH} (a `VALIDATION` {@link DatabaseError} over it),
@@ -925,28 +1131,29 @@ export declare function matchesQuery(row: Row, conditions: readonly Condition[])
925
1131
  * pattern.
926
1132
  *
927
1133
  * The `any` wildcard matches any run (including empty); `single` matches exactly one
928
- * char; every other pattern char matches itself LITERALLY (a pattern `.` / `(` / `\` is
1134
+ * char; every other pattern char matches itself literally (a pattern `.` / `(` / `\` is
929
1135
  * a literal — the regex-metacharacter hazard is gone with the regex). `any` is tested
930
- * BEFORE a literal match, so a value that literally contains the wildcard char never
931
- * shadows the wildcard. Case folding is applied to BOTH sides when `fold` is set.
1136
+ * before a literal match, so a value that literally contains the wildcard char never
1137
+ * shadows the wildcard. Case folding is applied to both sides when `fold` is set.
932
1138
  *
933
1139
  * @param value - The value to test
934
1140
  * @param pattern - The wildcard pattern
935
1141
  * @param any - The any-run wildcard char (`%` for `LIKE`, `*` for `GLOB`)
936
1142
  * @param single - The single-char wildcard char (`_` for `LIKE`, `?` for `GLOB`)
937
- * @param fold - Whether to match case-INSENSITIVELY (`LIKE` folds; `GLOB` does not)
938
- * @returns Whether `value` matches `pattern`
1143
+ * @param fold - Whether to match case-insensitively (`LIKE` folds; `GLOB` does not)
1144
+ * @returns True if `value` matches `pattern`; false otherwise
939
1145
  * @throws A `VALIDATION` {@link DatabaseError} when `pattern` exceeds {@link MAX_PATTERN_LENGTH}
940
1146
  */
941
1147
  export declare function matchesWildcardPattern(value: string, pattern: string, any: string, single: string, fold: boolean): boolean;
942
1148
 
943
1149
  /**
944
- * The longest `LIKE` / `GLOB` pattern the wildcard matcher accepts before rejecting it.
1150
+ * Sets the longest `LIKE` / `GLOB` pattern the wildcard matcher accepts, 1024 characters, before
1151
+ * rejecting it.
945
1152
  *
946
1153
  * @remarks
947
- * A ReDoS bound (AGENTS §6.5): the SA1–SA4 migration lets a model supply `list`
948
- * input over the wire, so `matchesLikePattern` / `matchesGlobPattern` run attacker-controlled
949
- * patterns. The matcher is the LINEAR greedy two-pointer wildcard match — never a
1154
+ * A `LIKE` / `GLOB` pattern is a caller-supplied operand, so
1155
+ * `matchesLikePattern` / `matchesGlobPattern` run patterns this package cannot
1156
+ * trust. The matcher is the linear greedy two-pointer wildcard match — never a
950
1157
  * backtracking regex (`.*`-segments-separated-by-literals against a long input is the
951
1158
  * catastrophic shape JS cannot bound without atomic groups), so it is O(value ×
952
1159
  * pattern). Capping the pattern length bounds that pattern factor, leaving a match
@@ -956,16 +1163,16 @@ export declare function matchesWildcardPattern(value: string, pattern: string, a
956
1163
  export declare const MAX_PATTERN_LENGTH = 1024;
957
1164
 
958
1165
  /**
959
- * The reference {@link DriverInterface} — nested maps, no I/O.
1166
+ * Implements the reference {@link DriverInterface} — nested maps, no I/O.
960
1167
  *
961
1168
  * @remarks
962
1169
  * The in-between made concrete: it runs identically in a browser or on a server,
963
1170
  * so it is the storage behind tests, ephemeral caches, and any code that wants
964
- * the database API without a persistent backend. Rows are DEEP-copied (via
1171
+ * the database API without a persistent backend. Rows are deep-copied (through
965
1172
  * `structuredClone`) in and out — at `write`, `read`, `scan`, `stream`, and both
966
1173
  * snapshot capture and restore — so a caller mutating a nested field of an input
967
1174
  * row, a returned row, or a row mutated in place between snapshot and rollback
968
- * can never perturb stored state (AGENTS §11); a shallow `{ ...row }` spread
1175
+ * can never perturb stored state; a shallow `{ ...row }` spread
969
1176
  * would still share nested object/array references. Metadata instead routes
970
1177
  * through `cloneDriverMetadata`: `stamp` and migration snapshot exact JSON at
971
1178
  * ingress, and `metadata` returns a distinct deeply frozen owned copy. `snapshot`
@@ -987,19 +1194,19 @@ export declare class MemoryDriver implements DriverInterface {
987
1194
  keys(table: string): Promise<readonly Key[]>;
988
1195
  scan(table: string): AsyncIterable<Row>;
989
1196
  /**
990
- * Natively filtered lazy iteration — the {@link DriverInterface.stream} hook.
1197
+ * Iterates rows lazily with native filtering — the {@link DriverInterface.stream} hook.
991
1198
  *
992
1199
  * @remarks
993
1200
  * Iterates the table's keys in the same key order `scan` and `keys` yield
994
1201
  * (sorted by {@link compareValues}), testing each row against
995
- * `input.conditions` (via {@link matchesQuery}) before counting it
1202
+ * `input.conditions` (through {@link matchesQuery}) before counting it
996
1203
  * toward `offset` / `limit`. Both are applied lazily as matches are found —
997
1204
  * `offset` matches are skipped without being yielded, and iteration stops the
998
1205
  * instant `limit` yields have been produced, so a large table is never fully
999
- * walked for a small page. `input.order` is IGNORED (the same contract as
1206
+ * walked for a small page. `input.order` is ignored (the same contract as
1000
1207
  * `TableInterface.scan` and `QueryInterface.stream`): streaming yields key
1001
- * order, sorted output is `records()`'s job. Rows yield copy-out (AGENTS
1002
- * §11), and an unknown table mirrors `scan`'s empty-yield behavior.
1208
+ * order, sorted output is `records()`'s job. Rows yield copy-out, and an
1209
+ * unknown table mirrors `scan`'s empty-yield behavior.
1003
1210
  *
1004
1211
  * @param table - The table to stream
1005
1212
  * @param input - The filter / offset / limit to apply lazily
@@ -1014,7 +1221,7 @@ export declare class MemoryDriver implements DriverInterface {
1014
1221
  stream(table: string, input: QueryInput): AsyncIterable<Row>;
1015
1222
  clear(table: string): Promise<void>;
1016
1223
  /**
1017
- * Capture the current state and return a thunk that rolls back to it.
1224
+ * Captures the current state and returns a thunk that rolls back to it.
1018
1225
  *
1019
1226
  * @remarks
1020
1227
  * Capture owns rows, schema, and one session-local table identity. Replay
@@ -1028,7 +1235,7 @@ export declare class MemoryDriver implements DriverInterface {
1028
1235
  */
1029
1236
  snapshot(tables?: readonly string[]): Promise<() => Promise<void>>;
1030
1237
  /**
1031
- * Return the persisted {@link DriverMetadata}, or `undefined` when the store has
1238
+ * Returns the persisted {@link DriverMetadata}, or `undefined` when the store has
1032
1239
  * never been stamped.
1033
1240
  *
1034
1241
  * @remarks
@@ -1041,13 +1248,13 @@ export declare class MemoryDriver implements DriverInterface {
1041
1248
  */
1042
1249
  metadata(): Promise<DriverMetadata | undefined>;
1043
1250
  /**
1044
- * Persist an owned snapshot for a later `metadata()` to return.
1251
+ * Persists an owned snapshot for a later `metadata()` to return.
1045
1252
  *
1046
1253
  * @param metadata - The {@link DriverMetadata} to persist
1047
1254
  */
1048
1255
  stamp(metadata: DriverMetadata): Promise<void>;
1049
1256
  /**
1050
- * Apply a {@link Migration} plan's steps against the in-memory store.
1257
+ * Applies a {@link Migration} plan's steps against the in-memory store.
1051
1258
  *
1052
1259
  * @remarks
1053
1260
  * Steps apply against an isolated candidate. Rows, schema changes, and
@@ -1059,11 +1266,11 @@ export declare class MemoryDriver implements DriverInterface {
1059
1266
  }
1060
1267
 
1061
1268
  /**
1062
- * Apply one table's {@link MigrationStep}s to its rows — a pure row transform.
1269
+ * Applies one table's {@link MigrationStep}s to its rows — a pure row transform.
1063
1270
  *
1064
1271
  * @remarks
1065
1272
  * `column.remove` drops that field from every row (a fresh copy — inputs are
1066
- * never mutated, AGENTS §11); `column.add` leaves rows as-is (an absent field
1273
+ * never mutated); `column.add` leaves rows as-is (an absent field
1067
1274
  * reads as `undefined`, backfill is application policy). `table.add` /
1068
1275
  * `table.remove` / `index.add` / `index.remove` are no-ops here (they operate
1069
1276
  * on storage shape, not row shape). Steps for tables other than the one
@@ -1083,12 +1290,12 @@ export declare class MemoryDriver implements DriverInterface {
1083
1290
  export declare function migrateRows(rows: readonly Row[], steps: readonly MigrationStep[]): readonly Row[];
1084
1291
 
1085
1292
  /**
1086
- * A schema migration plan — an ordered set of {@link MigrationStep}s moving a
1293
+ * Represents a schema migration plan — an ordered set of {@link MigrationStep}s moving a
1087
1294
  * database from one schema version to another.
1088
1295
  *
1089
1296
  * @remarks
1090
1297
  * `from` / `to` are the source and target schema versions; `steps` runs in
1091
- * order. Applied natively via {@link DriverInterface.migrate} when a driver
1298
+ * order. Applied natively through {@link DriverInterface.migrate} when a driver
1092
1299
  * implements it.
1093
1300
  */
1094
1301
  export declare interface Migration {
@@ -1098,7 +1305,7 @@ export declare interface Migration {
1098
1305
  }
1099
1306
 
1100
1307
  /**
1101
- * One atomic migration request.
1308
+ * Represents one atomic migration request.
1102
1309
  *
1103
1310
  * @remarks
1104
1311
  * `plan` carries the schema changes. `metadata`, when present, is the snapshot that
@@ -1111,11 +1318,11 @@ export declare interface MigrationInput {
1111
1318
  }
1112
1319
 
1113
1320
  /**
1114
- * One step of a {@link Migration} plan — a single schema change applied to one
1321
+ * Represents one step of a {@link Migration} plan — a single schema change applied to one
1115
1322
  * table.
1116
1323
  *
1117
1324
  * @remarks
1118
- * `operation` names the axis it splits on (AGENTS §4.4): adding / removing a
1325
+ * `operation` names the axis it splits on: adding / removing a
1119
1326
  * whole table, a column, or an index. A driver's optional `migrate` applies each
1120
1327
  * step natively; a step referencing an unknown table throws `DatabaseError`
1121
1328
  * `MIGRATION`.
@@ -1145,7 +1352,7 @@ export declare type MigrationStep = {
1145
1352
  };
1146
1353
 
1147
1354
  /**
1148
- * Canonicalize an unknown driver schema into a distinct deeply frozen snapshot.
1355
+ * Canonicalizes an unknown driver schema into a distinct deeply frozen snapshot.
1149
1356
  *
1150
1357
  * @remarks
1151
1358
  * Table and column lists are sorted by name. The index list is sorted by the
@@ -1165,23 +1372,24 @@ export declare function normalizeDriverSchema(value: unknown): readonly TableSch
1165
1372
  * When `signal` aborts, the operation throws a {@link DatabaseError} with code
1166
1373
  * `ABORTED` carrying `signal.reason` in `context`. Reads check at their
1167
1374
  * documented boundaries; point mutations propagate the signal through the
1168
- * driver to the backend commit point.
1375
+ * driver to the backend commit point. A streamed read — {@link TableInterface.scan}
1376
+ * or {@link QueryInterface.stream} — checks the signal before each yield.
1169
1377
  */
1170
1378
  export declare interface OperationOptions {
1171
1379
  readonly signal?: AbortSignal;
1172
1380
  }
1173
1381
 
1174
- /** One ordering term — a column ({@link FieldPath}, flat or nested) and its direction. */
1382
+ /** Represents one ordering term — a column ({@link FieldPath}, flat or nested) and its direction. */
1175
1383
  export declare interface Order {
1176
1384
  readonly column: FieldPath;
1177
1385
  readonly direction: OrderDirection;
1178
1386
  }
1179
1387
 
1180
- /** A sort direction. */
1388
+ /** Names a sort direction. */
1181
1389
  export declare type OrderDirection = 'ascending' | 'descending';
1182
1390
 
1183
1391
  /**
1184
- * Structurally diff a deployed and a declared table set into a {@link Migration}
1392
+ * Diffs a deployed and a declared table set structurally into a {@link Migration}
1185
1393
  * plan.
1186
1394
  *
1187
1395
  * @remarks
@@ -1196,17 +1404,16 @@ export declare type OrderDirection = 'ascending' | 'descending';
1196
1404
  * plan labels only; versioning drivers persist and reconcile them through
1197
1405
  * {@link DriverMetadata}.
1198
1406
  *
1199
- * A column present in BOTH schemas under the same name but with a different
1407
+ * A column present in both schemas under the same name but with a different
1200
1408
  * `storage`, `optional`, or `nullable` value throws a `MIGRATION`
1201
- * {@link DatabaseError} naming the
1202
- * table, the column, and the from→to difference — a name-only diff would
1203
- * otherwise silently produce NO step for the drift, and versioned
1204
- * reconciliation would stamp over it. There is no automatic in-place
1205
- * type-change step: the manual path is to add a new column, copy/convert the
1206
- * data at the application layer, then remove the old column — two separate
1207
- * plans, never a single implicit "alter" step.
1208
- *
1209
- * @param deployed - The table schemas currently applied
1409
+ * {@link DatabaseError} naming the table, the column, and the from→to
1410
+ * difference — a name-only diff would otherwise silently produce no step for
1411
+ * the drift, and versioned reconciliation would stamp over it. There is no
1412
+ * automatic in-place type-change step: the manual path is to add a new column,
1413
+ * copy/convert the data at the application layer, then remove the old column
1414
+ * two separate plans, never a single implicit "alter" step.
1415
+ *
1416
+ * @param deployed - The already-applied table schemas
1210
1417
  * @param declared - The table schemas the caller wants applied
1211
1418
  * @param from - The plan's source version label (defaults to `0`)
1212
1419
  * @param to - The plan's target version label (defaults to `1`)
@@ -1228,7 +1435,7 @@ export declare type OrderDirection = 'ascending' | 'descending';
1228
1435
  export declare function planMigration(deployed: readonly TableSchema[], declared: readonly TableSchema[], from?: number, to?: number): Migration;
1229
1436
 
1230
1437
  /**
1231
- * Per-table primary-key column overrides — `{ [table]: column }`.
1438
+ * Holds per-table primary-key column overrides — `{ [table]: column }`.
1232
1439
  *
1233
1440
  * @remarks
1234
1441
  * A table absent from this map keys its rows by {@link DEFAULT_PRIMARY} (`id`).
@@ -1237,7 +1444,9 @@ export declare function planMigration(deployed: readonly TableSchema[], declared
1237
1444
  export declare type PrimaryMap = Readonly<Record<string, string>>;
1238
1445
 
1239
1446
  /**
1240
- * Sequentially project migration steps over a canonical validated owned schema.
1447
+ * Projects migration steps sequentially over a canonical validated owned schema.
1448
+ *
1449
+ * @remarks
1241
1450
  * Adding a required non-null column to an existing table rejects with
1242
1451
  * `MIGRATION`; optional-only and nullable-only additions remain portable.
1243
1452
  *
@@ -1248,7 +1457,7 @@ export declare type PrimaryMap = Readonly<Record<string, string>>;
1248
1457
  export declare function projectMigrationSchema(schema: readonly TableSchema[], steps: readonly MigrationStep[]): readonly TableSchema[];
1249
1458
 
1250
1459
  /**
1251
- * A serializable read specification — everything a backend needs to compile one
1460
+ * Represents a serializable read specification — everything a backend needs to compile one
1252
1461
  * read, free of JS callbacks so any backend can honor it.
1253
1462
  *
1254
1463
  * @remarks
@@ -1265,50 +1474,118 @@ export declare interface QueryInput {
1265
1474
  }
1266
1475
 
1267
1476
  /**
1268
- * A fluent query builder.
1477
+ * Builds a read through a fluent chain.
1269
1478
  *
1270
1479
  * @remarks
1271
1480
  * `condition` appends one portable condition and `order` appends one portable
1272
1481
  * ordering term. `filter` adds a post-fetch JavaScript predicate (applied after
1273
1482
  * the backend read, before paging). The terminals (`collect` / `find` / `count`
1274
- * / `aggregate`) execute against the table; each
1275
- * call mutates and returns the same builder, so a chain reads as one statement.
1276
- * Every `column` is a {@link FieldPath} — a string is one column, an array
1277
- * descends a nested value.
1483
+ * / `aggregate`) execute against the table; each call mutates and returns the
1484
+ * same builder, so a chain reads as one statement. Every `column` is a
1485
+ * {@link FieldPath} — a string is one column, an array descends a nested value.
1278
1486
  */
1279
1487
  export declare interface QueryInterface<T = Row> {
1488
+ /**
1489
+ * Adds one portable condition, including its explicit connector.
1490
+ */
1280
1491
  condition(input: Condition): QueryInterface<T>;
1492
+ /**
1493
+ * Adds one portable ordering term — a column and a direction.
1494
+ */
1281
1495
  order(input: Order): QueryInterface<T>;
1496
+ /**
1497
+ * Adds a post-fetch JavaScript predicate.
1498
+ */
1282
1499
  filter(predicate: (row: T) => boolean): QueryInterface<T>;
1500
+ /**
1501
+ * Caps the result count.
1502
+ */
1283
1503
  limit(count: number): QueryInterface<T>;
1504
+ /**
1505
+ * Skips the leading rows.
1506
+ */
1284
1507
  offset(count: number): QueryInterface<T>;
1508
+ /**
1509
+ * Executes the accumulated read and collects every matching row.
1510
+ */
1285
1511
  collect(): Promise<readonly T[]>;
1512
+ /**
1513
+ * Executes the accumulated read and returns the first match, or `undefined`.
1514
+ */
1286
1515
  find(): Promise<T | undefined>;
1516
+ /**
1517
+ * Executes the accumulated read and returns the match count.
1518
+ */
1287
1519
  count(): Promise<number>;
1288
1520
  /**
1289
- * Lazy per-row evaluation of this query's conditions / filters / offset /
1290
- * limit.
1521
+ * Evaluates this query's conditions / filters / offset / limit lazily, row
1522
+ * by row.
1291
1523
  *
1292
1524
  * @remarks
1293
- * `order` and its comparators are IGNORED (streaming yields unsorted, as
1525
+ * `order` and its comparators are ignored (streaming yields unsorted, as
1294
1526
  * rows are evaluated one at a time). Same abort semantics as
1295
1527
  * {@link TableInterface.scan}: the signal (if any) is checked before each
1296
1528
  * yield, and breaking out early closes the underlying source.
1297
1529
  */
1298
1530
  stream(options?: OperationOptions): AsyncIterable<T>;
1531
+ /**
1532
+ * Executes a named aggregate over one column.
1533
+ */
1299
1534
  aggregate(operation: AggregateOperation, column: FieldPath): Promise<number | undefined>;
1300
1535
  }
1301
1536
 
1302
- /** A table row — a plain record of column values keyed by column name. */
1537
+ /**
1538
+ * Requires one declared table's columns out of a table map.
1539
+ *
1540
+ * @remarks
1541
+ * The overload preserves the map's own value type for a statically known table
1542
+ * name, so a typed view keeps its row type without an assertion. An undeclared
1543
+ * table is a caller error rather than an absence, so it throws instead of
1544
+ * returning `undefined`.
1545
+ *
1546
+ * @param tables - The declared table map
1547
+ * @param name - The table name
1548
+ * @returns The table's {@link ColumnMap}
1549
+ * @throws A `NOT_FOUND` {@link DatabaseError} when `tables` does not declare `name`
1550
+ *
1551
+ * @example
1552
+ * ```ts
1553
+ * requireColumns({ users: { id: stringShape() } }, 'users') // { id: … }
1554
+ * ```
1555
+ */
1556
+ export declare function requireColumns<T extends TableMap, K extends keyof T & string>(tables: T, name: K): T[K];
1557
+
1558
+ export declare function requireColumns(tables: TableMap, name: string): ColumnMap;
1559
+
1560
+ /**
1561
+ * Resolves the primary-key column one table keys its rows by.
1562
+ *
1563
+ * @remarks
1564
+ * A table absent from the {@link PrimaryMap} keys its rows by
1565
+ * {@link DEFAULT_PRIMARY}, so this is total over any table name.
1566
+ *
1567
+ * @param primary - The per-table primary-key overrides
1568
+ * @param name - The table name
1569
+ * @returns The table's primary-key column
1570
+ *
1571
+ * @example
1572
+ * ```ts
1573
+ * resolvePrimary({ posts: 'slug' }, 'posts') // 'slug'
1574
+ * resolvePrimary({ posts: 'slug' }, 'users') // 'id' — the default primary
1575
+ * ```
1576
+ */
1577
+ export declare function resolvePrimary(primary: PrimaryMap, name: string): string;
1578
+
1579
+ /** Represents a table row — a plain record of column values keyed by column name. */
1303
1580
  export declare type Row = Record<string, unknown>;
1304
1581
 
1305
1582
  /**
1306
- * The row type a table's {@link ColumnMap} describe — `Infer` of the `objectShape`
1583
+ * Represents the row type a table's {@link ColumnMap} describe — `Infer` of the `objectShape`
1307
1584
  * the database wraps them in.
1308
1585
  *
1309
1586
  * @remarks
1310
1587
  * Contract 0.0.4's non-distributive `Infer` resolves the OPEN case (the broad
1311
- * `ColumnMap` — e.g. when a database is held at its default type) directly:
1588
+ * `ColumnMap` — for example when a database is held at its default type) directly:
1312
1589
  * `RowOf<ColumnMap>` and {@link Row} are mutually assignable, so no short-circuit
1313
1590
  * to `Row` and no `additionalProperties: false` pin are needed — `Infer` no
1314
1591
  * longer trips TS's instantiation-depth guard over the open shape, and the
@@ -1317,12 +1594,71 @@ export declare type Row = Record<string, unknown>;
1317
1594
  * concrete column map.
1318
1595
  */
1319
1596
  export declare type RowOf<C extends ColumnMap> = Infer<{
1320
- readonly type: 'object';
1597
+ readonly category: 'object';
1321
1598
  readonly properties: C;
1322
1599
  }>;
1323
1600
 
1324
1601
  /**
1325
- * Project one contract shape into a portable column schema.
1602
+ * Walks the driver-conformance battery against a fresh {@link DriverInterface}
1603
+ * per phase, yielding one {@link ConformanceFinding} per violated invariant —
1604
+ * the shared invariant suite every backend (in-memory, SQLite, IndexedDB)
1605
+ * must uphold to be a drop-in {@link DriverInterface}.
1606
+ *
1607
+ * @remarks
1608
+ * Framework-agnostic: no test-runner or Node imports, only sibling core
1609
+ * modules — so it runs equally from a unit test, a smoke script, or a new
1610
+ * driver's own README. Opens a fixed two-table schema (`users` keyed by the
1611
+ * default `id`, `posts` keyed by a non-id `slug`) and, calling `factory()`
1612
+ * fresh for each phase so failures stay isolated, verifies: `open`/`close`;
1613
+ * `read` of a missing key returns `undefined`; `write`/`read` round-trip
1614
+ * with deep copy-in/copy-out isolation (mutating the caller's row —
1615
+ * including a nested field — after `write`, or a row `read` returns, never
1616
+ * perturbs stored state) and upsert-overwrite; simultaneous same-key
1617
+ * `insert` calls produce exactly one commit and one `CONFLICT`; pre-aborted
1618
+ * `write`, `insert`, and `delete` calls leave storage unchanged; `delete`
1619
+ * returns `true` then `false`; `keys`/`scan` yield in ascending key order;
1620
+ * `clear` empties only its target table; `snapshot`'s rollback thunk
1621
+ * restores pre-snapshot state, including a nested field mutated in place on
1622
+ * a read-back row between capture and restore; a scoped
1623
+ * `snapshot(['users'])` rolls back only the named table, leaving a
1624
+ * concurrent mutation to another table intact; a non-`id` primary key
1625
+ * (`posts.slug`) round-trips; a nested-object row round-trips structurally
1626
+ * (through {@link equalsValue}). The optional surface is presence-gated: when
1627
+ * `migrate` exists, a `column.remove` plan strips the column from stored
1628
+ * rows and a plan referencing an unknown table throws `DatabaseError`
1629
+ * `MIGRATION`; when `stream` exists, it yields only condition-matching rows
1630
+ * and honors `offset`/`limit`; when `transaction` exists, `commit` persists
1631
+ * and `rollback` restores; when both `metadata` and `stamp` exist, a fresh
1632
+ * store's `metadata()` is `undefined`, and after
1633
+ * `stamp({ version, schema })`, `metadata()` returns the exact stamped value.
1634
+ *
1635
+ * Each phase runs within a `try`/`catch`: an expected mismatch yields a
1636
+ * finding built from the assertion, while an unexpected throw (a driver
1637
+ * crash mid-phase) is caught and yielded as a finding too, naming the phase
1638
+ * as `check` and carrying the caught error in `context.error` — a broken
1639
+ * driver can never escape the battery as an unhandled rejection. Within a
1640
+ * phase, the first violated assertion yields and the phase stops (matching
1641
+ * the historical fail-fast shape at phase granularity); the generator then
1642
+ * moves on to the next phase regardless. Because this is a **generator**,
1643
+ * consuming only the first yielded value reproduces true fail-fast (later
1644
+ * phases never run) — that is exactly what {@link conformDriver} does.
1645
+ *
1646
+ * @param factory - Mints a fresh, unopened driver instance (called once per phase)
1647
+ * @yields One {@link ConformanceFinding} per violated invariant, in phase order
1648
+ *
1649
+ * @example
1650
+ * ```ts
1651
+ * import { createMemoryDriver, scanDriver } from '@orkestrel/database'
1652
+ *
1653
+ * for await (const finding of scanDriver(() => createMemoryDriver())) {
1654
+ * console.log(finding.check, finding.message)
1655
+ * }
1656
+ * ```
1657
+ */
1658
+ export declare function scanDriver(factory: () => DriverInterface): AsyncIterable<ConformanceFinding>;
1659
+
1660
+ /**
1661
+ * Projects one contract shape into a portable column schema.
1326
1662
  *
1327
1663
  * @param name - The column name
1328
1664
  * @param shape - The column contract shape
@@ -1331,7 +1667,7 @@ export declare type RowOf<C extends ColumnMap> = Infer<{
1331
1667
  export declare function shapeToColumnSchema(name: string, shape: ContractShape): ColumnSchema;
1332
1668
 
1333
1669
  /**
1334
- * Map a column's {@link ContractShape} to its portable {@link ColumnStorage} — the
1670
+ * Maps a column's {@link ContractShape} to its portable {@link ColumnStorage} — the
1335
1671
  * value a `TableSchema` carries so a native backend can declare a real column.
1336
1672
  *
1337
1673
  * @remarks
@@ -1357,7 +1693,7 @@ export declare function shapeToColumnSchema(name: string, shape: ContractShape):
1357
1693
  export declare function shapeToColumnStorage(shape: ContractShape): ColumnStorage;
1358
1694
 
1359
1695
  /**
1360
- * Sort rows by an ordering specification, leaving the input untouched.
1696
+ * Sorts rows by an ordering specification, leaving the input untouched.
1361
1697
  *
1362
1698
  * @remarks
1363
1699
  * Applies the terms in priority order — the first term that distinguishes two
@@ -1370,7 +1706,7 @@ export declare function shapeToColumnStorage(shape: ContractShape): ColumnStorag
1370
1706
  export declare function sortRows(rows: readonly Row[], order: readonly Order[]): readonly Row[];
1371
1707
 
1372
1708
  /**
1373
- * The storage operations available only inside a driver's transaction scope.
1709
+ * Declares the storage operations available only inside a driver's transaction scope.
1374
1710
  *
1375
1711
  * @remarks
1376
1712
  * A driver owns acquisition, commit or rollback, release, and lifetime. This
@@ -1380,28 +1716,67 @@ export declare function sortRows(rows: readonly Row[], order: readonly Order[]):
1380
1716
  * callers fall back to `scan` when a native read hook is absent.
1381
1717
  */
1382
1718
  export declare interface StorageInterface {
1719
+ /**
1720
+ * Reads one row by key.
1721
+ */
1383
1722
  read(table: string, key: Key): Promise<Row | undefined>;
1723
+ /**
1724
+ * Writes one row at a key.
1725
+ */
1384
1726
  write(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void>;
1727
+ /**
1728
+ * Inserts one row atomically, rejecting `CONFLICT` when its key already exists.
1729
+ */
1385
1730
  insert(table: string, key: Key, row: Row, options?: OperationOptions): Promise<void>;
1731
+ /**
1732
+ * Deletes one row by key.
1733
+ */
1386
1734
  delete(table: string, key: Key, options?: OperationOptions): Promise<boolean>;
1735
+ /**
1736
+ * Lists a table's keys.
1737
+ */
1387
1738
  keys(table: string): Promise<readonly Key[]>;
1739
+ /**
1740
+ * Iterates a table's rows in ascending key order.
1741
+ */
1388
1742
  scan(table: string): AsyncIterable<Row>;
1743
+ /**
1744
+ * Empties a table.
1745
+ */
1389
1746
  clear(table: string): Promise<void>;
1747
+ /**
1748
+ * Reads the rows matching a {@link QueryInput} natively — an optional hook.
1749
+ */
1390
1750
  records?(table: string, input: QueryInput): Promise<readonly Row[]>;
1751
+ /**
1752
+ * Computes an aggregate over a column natively — an optional hook.
1753
+ */
1391
1754
  aggregate?(table: string, operation: AggregateOperation, column: FieldPath, input: QueryInput): Promise<number | undefined>;
1755
+ /**
1756
+ * Iterates the natively filtered rows lazily — an optional hook.
1757
+ */
1392
1758
  stream?(table: string, input: QueryInput): AsyncIterable<Row>;
1759
+ /**
1760
+ * Applies one atomic {@link MigrationInput} — an optional hook.
1761
+ */
1393
1762
  migrate?(input: MigrationInput): Promise<void>;
1763
+ /**
1764
+ * Reads the persisted {@link DriverMetadata} as a deeply frozen copy — an optional hook.
1765
+ */
1394
1766
  metadata?(): Promise<DriverMetadata | undefined>;
1767
+ /**
1768
+ * Writes the persisted {@link DriverMetadata}, snapshot at entry — an optional hook.
1769
+ */
1395
1770
  stamp?(metadata: DriverMetadata): Promise<void>;
1396
1771
  }
1397
1772
 
1398
1773
  /**
1399
- * One table's portable definition, produced by `export` — the unit of schema /
1774
+ * Represents one table's portable definition, produced by `export` — the unit of schema /
1400
1775
  * migration exchange across environments.
1401
1776
  *
1402
1777
  * @remarks
1403
1778
  * `schema` is the JSON Schema (universally portable, serializable); `columns` is
1404
- * the source column map, which re-imports losslessly via `import` within a
1779
+ * the source column map, which re-imports losslessly through `import` within a
1405
1780
  * TypeScript environment. `primary` is the primary-key column.
1406
1781
  */
1407
1782
  export declare interface TableDefinition {
@@ -1411,34 +1786,34 @@ export declare interface TableDefinition {
1411
1786
  }
1412
1787
 
1413
1788
  /**
1414
- * The push observation surface of a {@link TableInterface} (AGENTS §13) — the per-row
1789
+ * Describes the push observation surface of a {@link TableInterface} — the per-row
1415
1790
  * mutation moments a fire-and-forget observer (cache invalidation, sync, an audit log)
1416
- * subscribes to, ALONGSIDE the database-level {@link DatabaseEventMap}.
1791
+ * subscribes to, alongside the database-level {@link DatabaseEventMap}.
1417
1792
  *
1418
1793
  * @remarks
1419
- * Events carry the affected KEY only — never the row value — to keep fan-out lean and
1794
+ * Events carry the affected key only — never the row value — to keep fan-out lean and
1420
1795
  * avoid leaking row data through the observation channel; a consumer that needs the
1421
1796
  * value re-reads it by key. Any row put — `set`, `add`, or `update` — emits a single
1422
1797
  * `write` (the consumer re-reads if it needs to know what changed); a delete emits
1423
- * `remove`; emptying the table emits `clear`. Reads / queries / counts are NOT emitted
1424
- * (too hot, and a reader does not mutate). Listener isolation is the emitter's (AGENTS §13):
1798
+ * `remove`; emptying the table emits `clear`. Reads / queries / counts are not emitted
1799
+ * (too hot, and a reader does not mutate). Listener isolation is the emitter's:
1425
1800
  * every event is emitted directly and a listener throw is routed to the emitter's `error`
1426
- * handler (the `error` option), never onto this map, and sits AFTER the driver write / delete
1801
+ * handler (the `error` option), never onto this map, and sits after the driver write / delete
1427
1802
  * / clear has completed — so a throwing observer can never corrupt a write or perturb a
1428
- * transaction. Subscribe via `table.emitter.on(...)`. Declared as a `type` alias (§4.5 —
1803
+ * transaction. Subscribe through `table.emitter.on(...)`. Declared as a `type` alias (
1429
1804
  * `EventMap` is a `type` kind).
1430
1805
  */
1431
1806
  export declare type TableEventMap = {
1432
- /** A row was written (set / added / updated) — the affected key (no value payload). */
1807
+ /** Signals that a row was written (set / added / updated) — the affected key (no value payload). */
1433
1808
  readonly write: readonly [key: Key];
1434
- /** A row was removed — the affected key. */
1809
+ /** Signals that a row was removed — the affected key. */
1435
1810
  readonly remove: readonly [key: Key];
1436
- /** The table was cleared (every row removed). */
1811
+ /** Signals that the table was cleared (every row removed). */
1437
1812
  readonly clear: readonly [];
1438
1813
  };
1439
1814
 
1440
1815
  /**
1441
- * A table — typed keyed CRUD plus fluent query and cursor access.
1816
+ * Exposes typed keyed CRUD plus fluent query and cursor access.
1442
1817
  *
1443
1818
  * @remarks
1444
1819
  * Writes are coerced through the table's contract: a string input to a numeric
@@ -1448,7 +1823,7 @@ export declare type TableEventMap = {
1448
1823
  * inserts and throws `CONFLICT` on a duplicate key. `contract` exposes the
1449
1824
  * compiled contract for introspection (`schema`) and fixtures (`generate`).
1450
1825
  *
1451
- * The keyed methods batch by overload (AGENTS §9.2): pass one key/row for one
1826
+ * The keyed methods batch by overload: pass one key/row for one
1452
1827
  * result, or an array for an array of results in the same order — a single verb,
1453
1828
  * never `getMany` / `setAll`. Batches run as independent sequential operations;
1454
1829
  * wrap them in `transaction` for atomicity.
@@ -1458,16 +1833,31 @@ export declare interface TableInterface<T = Row> {
1458
1833
  readonly name: string;
1459
1834
  readonly primary: string;
1460
1835
  readonly contract: ContractInterface<T>;
1836
+ /**
1837
+ * Reads one row by key, or one row per key for a list — `undefined` for each miss.
1838
+ */
1461
1839
  get(key: Key): Promise<T | undefined>;
1462
1840
  get(keys: readonly Key[]): Promise<ReadonlyArray<T | undefined>>;
1841
+ /**
1842
+ * Reads one row by key, or one row per key for a list, throwing `NOT_FOUND` on a miss.
1843
+ */
1463
1844
  resolve(key: Key): Promise<T>;
1464
1845
  resolve(keys: readonly Key[]): Promise<readonly T[]>;
1846
+ /**
1847
+ * Reports whether one key exists, or one result per key for a list.
1848
+ */
1465
1849
  has(key: Key): Promise<boolean>;
1466
1850
  has(keys: readonly Key[]): Promise<readonly boolean[]>;
1851
+ /**
1852
+ * Lists every primary key in order.
1853
+ */
1467
1854
  keys(): Promise<readonly Key[]>;
1855
+ /**
1856
+ * Reads the contract-valid rows matching an optional {@link QueryInput}.
1857
+ */
1468
1858
  records(input?: QueryInput, options?: OperationOptions): Promise<readonly T[]>;
1469
1859
  /**
1470
- * Count contract-valid rows matching `input`'s conditions.
1860
+ * Counts contract-valid rows matching `input`'s conditions.
1471
1861
  *
1472
1862
  * @remarks
1473
1863
  * Paging is ignored. Like `records()` / `scan()`, `count()` narrows every
@@ -1476,11 +1866,11 @@ export declare interface TableInterface<T = Row> {
1476
1866
  */
1477
1867
  count(input?: QueryInput, options?: OperationOptions): Promise<number>;
1478
1868
  /**
1479
- * Compute an aggregate over `column` across rows matching `input`'s
1869
+ * Computes an aggregate over `column` across rows matching `input`'s
1480
1870
  * conditions.
1481
1871
  *
1482
1872
  * @remarks
1483
- * Unlike {@link TableInterface.count}, `aggregate` operates on STORED rows
1873
+ * Unlike {@link TableInterface.count}, `aggregate` operates on stored rows
1484
1874
  * without the contract guard that `records()` / `scan()` apply — a
1485
1875
  * non-conforming stored row still contributes to the aggregate (or to the
1486
1876
  * `count` operation's tally) when it matches the conditions, even though
@@ -1488,18 +1878,18 @@ export declare interface TableInterface<T = Row> {
1488
1878
  */
1489
1879
  aggregate(operation: AggregateOperation, column: FieldPath, input?: QueryInput, options?: OperationOptions): Promise<number | undefined>;
1490
1880
  /**
1491
- * Lazy filtered iteration over the table's rows.
1881
+ * Iterates the table's rows lazily with filtering.
1492
1882
  *
1493
1883
  * @remarks
1494
1884
  * `input`'s `conditions` / `offset` / `limit` are honored lazily as rows
1495
- * stream; `order` is intentionally IGNORED — streaming yields driver
1885
+ * stream; `order` is intentionally ignored — streaming yields driver
1496
1886
  * key-order, sorted output is `records()`'s job. Breaking out of the
1497
1887
  * iteration early closes the underlying source. The signal (if any) is
1498
1888
  * checked before each yield.
1499
1889
  */
1500
1890
  scan(input?: QueryInput, options?: OperationOptions): AsyncIterable<T>;
1501
1891
  /**
1502
- * Upsert one or more rows.
1892
+ * Upserts one or more rows.
1503
1893
  *
1504
1894
  * @param row - The row to upsert
1505
1895
  * @param options - Optional abort signal
@@ -1507,7 +1897,7 @@ export declare interface TableInterface<T = Row> {
1507
1897
  */
1508
1898
  set(row: T, options?: OperationOptions): Promise<Key>;
1509
1899
  /**
1510
- * Upsert one or more rows.
1900
+ * Upserts one or more rows.
1511
1901
  *
1512
1902
  * @param rows - The rows to upsert
1513
1903
  * @param options - Optional abort signal, checked at entry and between items
@@ -1520,7 +1910,7 @@ export declare interface TableInterface<T = Row> {
1520
1910
  */
1521
1911
  set(rows: readonly T[], options?: OperationOptions): Promise<readonly Key[]>;
1522
1912
  /**
1523
- * Insert one or more rows, throwing `CONFLICT` on a duplicate key.
1913
+ * Inserts one or more rows, throwing `CONFLICT` on a duplicate key.
1524
1914
  *
1525
1915
  * @param row - The row to insert
1526
1916
  * @param options - Optional abort signal
@@ -1528,7 +1918,7 @@ export declare interface TableInterface<T = Row> {
1528
1918
  */
1529
1919
  add(row: T, options?: OperationOptions): Promise<Key>;
1530
1920
  /**
1531
- * Insert one or more rows, throwing `CONFLICT` on a duplicate key.
1921
+ * Inserts one or more rows, throwing `CONFLICT` on a duplicate key.
1532
1922
  *
1533
1923
  * @param rows - The rows to insert
1534
1924
  * @param options - Optional abort signal, checked at entry and between items
@@ -1541,16 +1931,16 @@ export declare interface TableInterface<T = Row> {
1541
1931
  */
1542
1932
  add(rows: readonly T[], options?: OperationOptions): Promise<readonly Key[]>;
1543
1933
  /**
1544
- * Apply a partial change to one or more rows.
1934
+ * Applies a partial change to one or more rows.
1545
1935
  *
1546
1936
  * @param key - The key of the row to update
1547
1937
  * @param changes - The partial changes to apply
1548
1938
  * @param options - Optional abort signal
1549
- * @returns `true` when the row existed and was updated
1939
+ * @returns True if the row existed and was updated; false otherwise
1550
1940
  */
1551
1941
  update(key: Key, changes: Partial<T>, options?: OperationOptions): Promise<boolean>;
1552
1942
  /**
1553
- * Apply a partial change to one or more rows.
1943
+ * Applies a partial change to one or more rows.
1554
1944
  *
1555
1945
  * @param keys - The keys of the rows to update
1556
1946
  * @param changes - The partial changes to apply to each row
@@ -1564,15 +1954,15 @@ export declare interface TableInterface<T = Row> {
1564
1954
  */
1565
1955
  update(keys: readonly Key[], changes: Partial<T>, options?: OperationOptions): Promise<readonly boolean[]>;
1566
1956
  /**
1567
- * Delete one or more rows.
1957
+ * Deletes one or more rows.
1568
1958
  *
1569
1959
  * @param key - The key of the row to remove
1570
1960
  * @param options - Optional abort signal
1571
- * @returns `true` when the row existed and was removed
1961
+ * @returns True if the row existed and was removed; false otherwise
1572
1962
  */
1573
1963
  remove(key: Key, options?: OperationOptions): Promise<boolean>;
1574
1964
  /**
1575
- * Delete one or more rows.
1965
+ * Deletes one or more rows.
1576
1966
  *
1577
1967
  * @param keys - The keys of the rows to remove
1578
1968
  * @param options - Optional abort signal, checked at entry and between items
@@ -1584,27 +1974,36 @@ export declare interface TableInterface<T = Row> {
1584
1974
  * applied — there is no rollback. Wrap in `transaction()` for atomicity.
1585
1975
  */
1586
1976
  remove(keys: readonly Key[], options?: OperationOptions): Promise<readonly boolean[]>;
1977
+ /**
1978
+ * Empties the table.
1979
+ */
1587
1980
  clear(): Promise<void>;
1981
+ /**
1982
+ * Opens a fluent query builder over the table.
1983
+ */
1588
1984
  query(): QueryInterface<T>;
1985
+ /**
1986
+ * Opens a forward row cursor for bulk mutation.
1987
+ */
1589
1988
  cursor(): Promise<CursorInterface<T>>;
1590
1989
  }
1591
1990
 
1592
1991
  /**
1593
- * A database's table schema — a map of table name to its {@link ColumnMap}.
1992
+ * Represents a database's table schema — a map of table name to its {@link ColumnMap}.
1594
1993
  *
1595
1994
  * @remarks
1596
1995
  * Each table's row type is `Infer` of its columns (see {@link RowOf}); primary-key
1597
- * columns are named separately via {@link PrimaryMap}.
1996
+ * columns are named separately through {@link PrimaryMap}.
1598
1997
  */
1599
1998
  export declare type TableMap = Readonly<Record<string, ColumnMap>>;
1600
1999
 
1601
2000
  /**
1602
- * A backend-agnostic description of one table — what `open` hands each driver so a
2001
+ * Represents a backend-agnostic description of one table — what `open` hands each driver so a
1603
2002
  * native backend can create real tables and indexes.
1604
2003
  *
1605
2004
  * @remarks
1606
2005
  * Derived by the database from its `tables` contract shapes ({@link ColumnSchema}
1607
- * per column, via `shapeToColumnStorage`), its `primary`, and its `indexes` option
2006
+ * per column, through `shapeToColumnStorage`), its `primary`, and its `indexes` option
1608
2007
  * (`indexes`, each entry one possibly-compound index of column names). A scan-only
1609
2008
  * backend (the reference `MemoryDriver`) ignores everything but `name`.
1610
2009
  */
@@ -1616,7 +2015,7 @@ export declare interface TableSchema {
1616
2015
  }
1617
2016
 
1618
2017
  /**
1619
- * Validate the paging fields of a portable query.
2018
+ * Validates the paging fields of a portable query.
1620
2019
  *
1621
2020
  * @remarks
1622
2021
  * A present `limit` or `offset` must be a finite nonnegative integer; zero is