@orkestrel/database 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -10
- package/dist/src/browser/index.d.ts +342 -0
- package/dist/src/browser/index.js +686 -0
- package/dist/src/browser/index.js.map +1 -0
- package/dist/src/core/index.cjs +2453 -0
- package/dist/src/core/index.cjs.map +1 -0
- package/dist/src/core/index.d.cts +1730 -0
- package/dist/src/core/index.d.ts +1730 -11
- package/dist/src/core/index.js +209 -1152
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +836 -153
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +1054 -0
- package/dist/src/server/index.d.ts +1054 -5
- package/dist/src/server/index.js +1663 -0
- package/dist/src/server/index.js.map +1 -0
- package/package.json +40 -16
- package/dist/src/core/Clause.d.ts +0 -30
- package/dist/src/core/Cursor.d.ts +0 -21
- package/dist/src/core/Database.d.ts +0 -80
- package/dist/src/core/Query.d.ts +0 -47
- package/dist/src/core/Table.d.ts +0 -69
- package/dist/src/core/constants.d.ts +0 -22
- package/dist/src/core/drivers/MemoryDriver.d.ts +0 -94
- package/dist/src/core/errors.d.ts +0 -38
- package/dist/src/core/factories.d.ts +0 -43
- package/dist/src/core/helpers.d.ts +0 -383
- package/dist/src/core/types.d.ts +0 -739
- package/dist/src/server/compilers.d.ts +0 -169
- package/dist/src/server/drivers/JSONDriver.d.ts +0 -106
- package/dist/src/server/factories.d.ts +0 -31
- package/dist/src/server/helpers.d.ts +0 -222
- package/dist/src/server/types.d.ts +0 -36
package/dist/src/core/types.d.ts
DELETED
|
@@ -1,739 +0,0 @@
|
|
|
1
|
-
import type { ContractInterface, ContractShape, FieldPath, Infer, JSONSchema } from '@orkestrel/contract';
|
|
2
|
-
import type { EmitterErrorHandler, EmitterHooks, EmitterInterface } from '@orkestrel/emitter';
|
|
3
|
-
/**
|
|
4
|
-
* A primary key — the value identifying a row within its table.
|
|
5
|
-
*
|
|
6
|
-
* @remarks
|
|
7
|
-
* `string | number` is the intersection of what IndexedDB key ranges and SQL
|
|
8
|
-
* primary keys both express without coercion. Auto-generated keys are UUID
|
|
9
|
-
* strings; supply your own to use numeric keys.
|
|
10
|
-
*/
|
|
11
|
-
export type Key = string | number;
|
|
12
|
-
/**
|
|
13
|
-
* A caller-supplied key minting function.
|
|
14
|
-
*
|
|
15
|
-
* @remarks
|
|
16
|
-
* Environment surfaces provide implementations (the server's `node:crypto`-backed
|
|
17
|
-
* `generateKey`); the core mints no keys itself. Supplied via
|
|
18
|
-
* {@link DatabaseOptions.key} and used by a table when a written row lacks its
|
|
19
|
-
* primary key. Without one, writing a keyless row is a `VALIDATION` error.
|
|
20
|
-
*/
|
|
21
|
-
export type KeyFunction = () => Key;
|
|
22
|
-
/** A table row — a plain record of column values keyed by column name. */
|
|
23
|
-
export type Row = Record<string, unknown>;
|
|
24
|
-
/**
|
|
25
|
-
* A WHERE operator — the comparison a single {@link Condition} applies.
|
|
26
|
-
*
|
|
27
|
-
* @remarks
|
|
28
|
-
* Each maps to a SQL operator and an IndexedDB read strategy (a key range where
|
|
29
|
-
* the bounds allow it, a scanned predicate otherwise). The set is closed to
|
|
30
|
-
* comparisons expressible on both backends.
|
|
31
|
-
*/
|
|
32
|
-
export type ConditionOperator = 'equals' | 'not' | 'above' | 'below' | 'from' | 'to' | 'between' | 'like' | 'glob' | 'starts' | 'ends' | 'any' | 'none' | 'absent' | 'present';
|
|
33
|
-
/** How a {@link Condition} joins to the running result of the conditions before it. */
|
|
34
|
-
export type Connector = 'and' | 'or';
|
|
35
|
-
/**
|
|
36
|
-
* One compiled WHERE condition.
|
|
37
|
-
*
|
|
38
|
-
* @remarks
|
|
39
|
-
* `values` carries the operands the operator needs — none for `absent` /
|
|
40
|
-
* `present`, one for most, two for `between`, a list for `any` / `none`.
|
|
41
|
-
* `connector` folds this condition into the accumulated result left-to-right;
|
|
42
|
-
* the first condition's connector seeds the fold and is otherwise ignored.
|
|
43
|
-
* `column` is a {@link FieldPath}: a single string is ONE column (never split on
|
|
44
|
-
* `.`), an array descends into a nested (object/`json`) value.
|
|
45
|
-
*/
|
|
46
|
-
export interface Condition {
|
|
47
|
-
readonly column: FieldPath;
|
|
48
|
-
readonly operator: ConditionOperator;
|
|
49
|
-
readonly values: readonly unknown[];
|
|
50
|
-
readonly connector: Connector;
|
|
51
|
-
}
|
|
52
|
-
/** A sort direction. */
|
|
53
|
-
export type Direction = 'ascending' | 'descending';
|
|
54
|
-
/** One ordering term — a column ({@link FieldPath}, flat or nested) and its direction. */
|
|
55
|
-
export interface Order {
|
|
56
|
-
readonly column: FieldPath;
|
|
57
|
-
readonly direction: Direction;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* A serializable read specification — everything a backend needs to compile one
|
|
61
|
-
* read, free of JS callbacks so any backend can honor it.
|
|
62
|
-
*
|
|
63
|
-
* @remarks
|
|
64
|
-
* The post-fetch `filter` predicate lives on {@link QueryInterface}, never here,
|
|
65
|
-
* so `Criteria` stays portable across backends.
|
|
66
|
-
*/
|
|
67
|
-
export interface Criteria {
|
|
68
|
-
readonly conditions?: readonly Condition[];
|
|
69
|
-
readonly order?: readonly Order[];
|
|
70
|
-
readonly limit?: number;
|
|
71
|
-
readonly offset?: number;
|
|
72
|
-
}
|
|
73
|
-
/** An aggregate computed over a numeric column. */
|
|
74
|
-
export type AggregateFunction = 'count' | 'sum' | 'average' | 'minimum' | 'maximum';
|
|
75
|
-
/**
|
|
76
|
-
* Options for a cancellable read / iteration operation.
|
|
77
|
-
*
|
|
78
|
-
* @remarks
|
|
79
|
-
* When `signal` aborts, the operation throws a {@link DatabaseError} with code
|
|
80
|
-
* `ABORTED` carrying `signal.reason` in `context`. `TableInterface.scan` and
|
|
81
|
-
* `QueryInterface.stream` check the signal before each yield; other read
|
|
82
|
-
* methods check it at entry.
|
|
83
|
-
*/
|
|
84
|
-
export interface ReadOptions {
|
|
85
|
-
readonly signal?: AbortSignal;
|
|
86
|
-
}
|
|
87
|
-
/** The lifecycle state of a {@link DatabaseInterface}. */
|
|
88
|
-
export type DatabaseStatus = 'idle' | 'open' | 'closed';
|
|
89
|
-
/** A machine-readable {@link DatabaseError} code. */
|
|
90
|
-
export type DatabaseErrorCode = 'CLOSED' | 'NOT_FOUND' | 'CONFLICT' | 'VALIDATION' | 'ABORTED' | 'MIGRATION' | 'CONFORMANCE' | 'DRIVER';
|
|
91
|
-
/**
|
|
92
|
-
* One violated invariant from the driver-conformance battery.
|
|
93
|
-
*
|
|
94
|
-
* @remarks
|
|
95
|
-
* Mirrors the payload shape of a `DatabaseError` `CONFORMANCE` `context` —
|
|
96
|
-
* `check` names the invariant, `message` describes the violation, and
|
|
97
|
-
* `context` carries the offending table / key / value that failed it.
|
|
98
|
-
*/
|
|
99
|
-
export interface ConformanceFinding {
|
|
100
|
-
readonly check: string;
|
|
101
|
-
readonly message: string;
|
|
102
|
-
readonly context: Readonly<Record<string, unknown>>;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* The push observation surface of a {@link DatabaseInterface} (AGENTS §13) — the
|
|
106
|
-
* connection + transaction lifecycle a fire-and-forget observer (logging, metrics,
|
|
107
|
-
* tracing, cache invalidation) subscribes to.
|
|
108
|
-
*
|
|
109
|
-
* @remarks
|
|
110
|
-
* Pure signals carrying no row data — these are the database-level (not per-row)
|
|
111
|
-
* moments, so a non-generic map stays lean (per-row writes are {@link TableEventMap}).
|
|
112
|
-
* Listener isolation is the emitter's (AGENTS §13): every event is emitted directly and a
|
|
113
|
-
* listener throw is routed to the emitter's OWN `error` handler (the `error` option), never
|
|
114
|
-
* onto this domain map and never into the snapshot / commit / rollback flow — so a buggy
|
|
115
|
-
* observer can never reorder, throw into, or corrupt a transaction. Every emit sits AFTER the
|
|
116
|
-
* relevant transition: `commit` only after the scope succeeds, `rollback` only after every
|
|
117
|
-
* table has been restored (it OBSERVES the propagated error; the original throw still
|
|
118
|
-
* propagates exactly as before). Subscribe via `database.emitter.on(...)`.
|
|
119
|
-
*
|
|
120
|
-
* Declared as a `type` alias (not `interface extends EventMap`, §4.5 — `EventMap` is a
|
|
121
|
-
* `type` kind): a type-literal satisfies the `EventMap` constraint
|
|
122
|
-
* (`Record<string, readonly unknown[]>`) structurally, whereas an interface lacks the
|
|
123
|
-
* required index signature.
|
|
124
|
-
*/
|
|
125
|
-
export type DatabaseEventMap = {
|
|
126
|
-
/** The driver connected (`open`, or the lazy first-use connect completed). */
|
|
127
|
-
readonly open: readonly [];
|
|
128
|
-
/** The database was closed (the driver released). */
|
|
129
|
-
readonly close: readonly [];
|
|
130
|
-
/** A transaction scope began — the store was snapshotted, the scope is about to run. */
|
|
131
|
-
readonly transaction: readonly [];
|
|
132
|
-
/** A transaction scope completed successfully (no rollback). */
|
|
133
|
-
readonly commit: readonly [];
|
|
134
|
-
/** A transaction scope threw and every table was rolled back — the propagated error. */
|
|
135
|
-
readonly rollback: readonly [error: unknown];
|
|
136
|
-
/** A {@link Migration} plan was applied via `migrate` — the applied plan. */
|
|
137
|
-
readonly migrate: readonly [migration: Migration];
|
|
138
|
-
};
|
|
139
|
-
/**
|
|
140
|
-
* The push observation surface of a {@link TableInterface} (AGENTS §13) — the per-row
|
|
141
|
-
* mutation moments a fire-and-forget observer (cache invalidation, sync, an audit log)
|
|
142
|
-
* subscribes to, ALONGSIDE the database-level {@link DatabaseEventMap}.
|
|
143
|
-
*
|
|
144
|
-
* @typeParam TKey - The table's primary-key type (a {@link Key}); the events carry the
|
|
145
|
-
* affected key so the map is `TableEventMap<TKey>`.
|
|
146
|
-
*
|
|
147
|
-
* @remarks
|
|
148
|
-
* Events carry the affected KEY only — never the row value — to keep fan-out lean and
|
|
149
|
-
* avoid leaking row data through the observation channel; a consumer that needs the
|
|
150
|
-
* value re-reads it by key. Any row put — `set`, `add`, or `update` — emits a single
|
|
151
|
-
* `write` (the consumer re-reads if it needs to know what changed); a delete emits
|
|
152
|
-
* `remove`; emptying the table emits `clear`. Reads / queries / counts are NOT emitted
|
|
153
|
-
* (too hot, and a reader does not mutate). Listener isolation is the emitter's (AGENTS §13):
|
|
154
|
-
* every event is emitted directly and a listener throw is routed to the emitter's `error`
|
|
155
|
-
* handler (the `error` option), never onto this map, and sits AFTER the driver write / delete
|
|
156
|
-
* / clear has completed — so a throwing observer can never corrupt a write or perturb a
|
|
157
|
-
* transaction. Subscribe via `table.emitter.on(...)`. Declared as a `type` alias (§4.5 —
|
|
158
|
-
* `EventMap` is a `type` kind).
|
|
159
|
-
*/
|
|
160
|
-
export type TableEventMap<TKey extends Key = Key> = {
|
|
161
|
-
/** A row was written (set / added / updated) — the affected key (no value payload). */
|
|
162
|
-
readonly write: readonly [key: TKey];
|
|
163
|
-
/** A row was removed — the affected key. */
|
|
164
|
-
readonly remove: readonly [key: TKey];
|
|
165
|
-
/** The table was cleared (every row removed). */
|
|
166
|
-
readonly clear: readonly [];
|
|
167
|
-
};
|
|
168
|
-
/**
|
|
169
|
-
* A portable storage type for a column — the backend maps it to its native type
|
|
170
|
-
* (SQLite affinity, an IndexedDB value). Derived from a column's `ContractShape`
|
|
171
|
-
* by `shapeToColumnType`; `json` covers object/array/union/raw values a backend stores
|
|
172
|
-
* as JSON text and can `json_extract` for nested-field queries.
|
|
173
|
-
*/
|
|
174
|
-
export type ColumnType = 'text' | 'integer' | 'real' | 'boolean' | 'json' | 'blob';
|
|
175
|
-
/**
|
|
176
|
-
* One column of a {@link TableSchema} — its name, portable {@link ColumnType}, and
|
|
177
|
-
* whether it is nullable (its shape is `optionalShape` / `nullableShape`).
|
|
178
|
-
*/
|
|
179
|
-
export interface ColumnSchema {
|
|
180
|
-
readonly name: string;
|
|
181
|
-
readonly type: ColumnType;
|
|
182
|
-
readonly nullable: boolean;
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Persisted schema metadata a versioning driver stores verbatim and returns on
|
|
186
|
-
* demand.
|
|
187
|
-
*
|
|
188
|
-
* @remarks
|
|
189
|
-
* The driver never introspects this payload — it hands back exactly what was
|
|
190
|
-
* last stamped via {@link DriverInterface.stamp}. `meta()` returning `undefined`
|
|
191
|
-
* is how a fresh store is distinguished from an upgradable one: it means the
|
|
192
|
-
* store has never been stamped, not that it is at version zero.
|
|
193
|
-
*/
|
|
194
|
-
export interface DriverMeta {
|
|
195
|
-
readonly version: number;
|
|
196
|
-
readonly schema: readonly TableSchema[];
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* A backend-agnostic description of one table — what `open` hands each driver so a
|
|
200
|
-
* native backend can create real tables and indexes.
|
|
201
|
-
*
|
|
202
|
-
* @remarks
|
|
203
|
-
* Derived by the database from its `tables` contract shapes ({@link ColumnSchema}
|
|
204
|
-
* per column, via `shapeToColumnType`), its `keys` (`primary`), and its `indexes` option
|
|
205
|
-
* (`indexes`, each entry one possibly-compound index of column names). A scan-only
|
|
206
|
-
* backend (the reference `MemoryDriver`) ignores everything but `name`.
|
|
207
|
-
*/
|
|
208
|
-
export interface TableSchema {
|
|
209
|
-
readonly name: string;
|
|
210
|
-
readonly primary: string;
|
|
211
|
-
readonly columns: readonly ColumnSchema[];
|
|
212
|
-
readonly indexes: readonly (readonly string[])[];
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* One step of a {@link Migration} plan — a single schema change applied to one
|
|
216
|
-
* table.
|
|
217
|
-
*
|
|
218
|
-
* @remarks
|
|
219
|
-
* `operation` names the axis it splits on (AGENTS §4.4): adding / removing a
|
|
220
|
-
* whole table, a column, or an index. A driver's optional `migrate` applies each
|
|
221
|
-
* step natively; a step referencing an unknown table throws `DatabaseError`
|
|
222
|
-
* `MIGRATION`.
|
|
223
|
-
*/
|
|
224
|
-
export type MigrationStep = {
|
|
225
|
-
readonly operation: 'table.add';
|
|
226
|
-
readonly table: TableSchema;
|
|
227
|
-
} | {
|
|
228
|
-
readonly operation: 'table.remove';
|
|
229
|
-
readonly table: string;
|
|
230
|
-
} | {
|
|
231
|
-
readonly operation: 'column.add';
|
|
232
|
-
readonly table: string;
|
|
233
|
-
readonly column: ColumnSchema;
|
|
234
|
-
} | {
|
|
235
|
-
readonly operation: 'column.remove';
|
|
236
|
-
readonly table: string;
|
|
237
|
-
readonly column: string;
|
|
238
|
-
} | {
|
|
239
|
-
readonly operation: 'index.add';
|
|
240
|
-
readonly table: string;
|
|
241
|
-
readonly index: readonly string[];
|
|
242
|
-
} | {
|
|
243
|
-
readonly operation: 'index.remove';
|
|
244
|
-
readonly table: string;
|
|
245
|
-
readonly index: readonly string[];
|
|
246
|
-
};
|
|
247
|
-
/**
|
|
248
|
-
* A schema migration plan — an ordered set of {@link MigrationStep}s moving a
|
|
249
|
-
* database from one schema version to another.
|
|
250
|
-
*
|
|
251
|
-
* @remarks
|
|
252
|
-
* `from` / `to` are the source and target schema versions; `steps` runs in
|
|
253
|
-
* order. Applied natively via {@link DriverInterface.migrate} when a driver
|
|
254
|
-
* implements it.
|
|
255
|
-
*/
|
|
256
|
-
export interface Migration {
|
|
257
|
-
readonly from: number;
|
|
258
|
-
readonly to: number;
|
|
259
|
-
readonly steps: readonly MigrationStep[];
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* The handle a driver's native `transaction` hook returns.
|
|
263
|
-
*
|
|
264
|
-
* @remarks
|
|
265
|
-
* `commit` finalizes the native BEGIN; `rollback` undoes it. When a driver
|
|
266
|
-
* implements {@link DriverInterface.transaction}, the engine uses this handle
|
|
267
|
-
* instead of the snapshot-based rollback floor.
|
|
268
|
-
*/
|
|
269
|
-
export interface TransactionInterface {
|
|
270
|
-
commit(): Promise<void>;
|
|
271
|
-
rollback(): Promise<void>;
|
|
272
|
-
}
|
|
273
|
-
/**
|
|
274
|
-
* The storage primitive every backend implements — the whole of the bridge.
|
|
275
|
-
*
|
|
276
|
-
* @remarks
|
|
277
|
-
* The REQUIRED surface is deliberately minimal: keyed read / write / delete, an
|
|
278
|
-
* ordered `scan`, a key listing, and a `snapshot` that backs transactions — the
|
|
279
|
-
* irreducible primitive. There is **no** required query, count, or aggregate
|
|
280
|
-
* here: all of that is one query engine in the core (`helpers.ts`) running over
|
|
281
|
-
* `scan`, so a new backend implements a handful of tiny methods rather than
|
|
282
|
-
* re-deriving WHERE compilation. `open` now receives a derived
|
|
283
|
-
* {@link TableSchema}`[]` (columns, types, primary, indexes) so a native backend
|
|
284
|
-
* can build real tables and indexes; a scan-only backend reads only `name`. The
|
|
285
|
-
* optional `records?` / `count?` / `aggregate?` are native overrides the engine
|
|
286
|
-
* falls back from (AGENTS §21). The API is async (Promises) because IndexedDB is; synchronous
|
|
287
|
-
* backends resolve immediately. Lookups that may miss return `undefined` /
|
|
288
|
-
* `false` rather than throwing (AGENTS §12).
|
|
289
|
-
*/
|
|
290
|
-
export interface DriverInterface {
|
|
291
|
-
open(schema: readonly TableSchema[]): Promise<void>;
|
|
292
|
-
close(): Promise<void>;
|
|
293
|
-
read(table: string, key: Key): Promise<Row | undefined>;
|
|
294
|
-
write(table: string, key: Key, row: Row): Promise<void>;
|
|
295
|
-
delete(table: string, key: Key): Promise<boolean>;
|
|
296
|
-
keys(table: string): Promise<readonly Key[]>;
|
|
297
|
-
scan(table: string): AsyncIterable<Row>;
|
|
298
|
-
clear(table: string): Promise<void>;
|
|
299
|
-
/**
|
|
300
|
-
* Capture the current state and return a thunk that rolls every table back to
|
|
301
|
-
* it — the primitive transactions are built on (SQL `SAVEPOINT`, an IndexedDB
|
|
302
|
-
* key buffer, a cloned map).
|
|
303
|
-
*
|
|
304
|
-
* @remarks
|
|
305
|
-
* `tables` omitted captures/rolls back the WHOLE store (existing behavior).
|
|
306
|
-
* `tables` provided captures/restores ONLY the named tables — the returned
|
|
307
|
-
* rollback thunk leaves every other table untouched.
|
|
308
|
-
*/
|
|
309
|
-
snapshot(tables?: readonly string[]): Promise<() => Promise<void>>;
|
|
310
|
-
/**
|
|
311
|
-
* Optional native filtered read (AGENTS §21). A backend that can evaluate a
|
|
312
|
-
* {@link Criteria} natively (SQL `WHERE` + `ORDER`/`LIMIT`, an index range)
|
|
313
|
-
* implements this; `Table` prefers it and falls back to `applyCriteria` over
|
|
314
|
-
* `scan` when it is absent. Must honor the full criteria (filter, order, page).
|
|
315
|
-
*/
|
|
316
|
-
records?(table: string, criteria: Criteria): Promise<readonly Row[]>;
|
|
317
|
-
/**
|
|
318
|
-
* Optional native count (AGENTS §21). Counts rows matching the criteria's
|
|
319
|
-
* conditions (paging is irrelevant to a count); `Table` falls back to counting
|
|
320
|
-
* the engine-filtered `scan` when absent.
|
|
321
|
-
*/
|
|
322
|
-
count?(table: string, criteria: Criteria): Promise<number>;
|
|
323
|
-
/**
|
|
324
|
-
* Optional native aggregate (AGENTS §21). A backend that can compute an
|
|
325
|
-
* aggregate natively (SQL `COUNT`/`SUM`/`AVG`/`MIN`/`MAX`, an indexed count)
|
|
326
|
-
* implements this; `Table.aggregate` prefers it and otherwise falls back to
|
|
327
|
-
* `computeAggregate` over the native-filtered (or scanned) rows. Aggregates
|
|
328
|
-
* ignore paging, so `criteria` carries only conditions.
|
|
329
|
-
*/
|
|
330
|
-
aggregate?(table: string, operation: AggregateFunction, column: FieldPath, criteria: Criteria): Promise<number | undefined>;
|
|
331
|
-
/**
|
|
332
|
-
* Optional native transaction (BEGIN). When present, the engine uses the
|
|
333
|
-
* returned {@link TransactionInterface}'s `commit` / `rollback` instead of
|
|
334
|
-
* the snapshot-based rollback floor.
|
|
335
|
-
*/
|
|
336
|
-
transaction?(): Promise<TransactionInterface>;
|
|
337
|
-
/**
|
|
338
|
-
* Optional natively filtered lazy iteration — a {@link Criteria}-aware
|
|
339
|
-
* streaming read. Drivers without it are served by the core scan fallback
|
|
340
|
-
* (filtering `scan` lazily).
|
|
341
|
-
*/
|
|
342
|
-
stream?(table: string, criteria: Criteria): AsyncIterable<Row>;
|
|
343
|
-
/**
|
|
344
|
-
* Optional native migration — applies a {@link Migration} plan directly.
|
|
345
|
-
* Throws `DatabaseError` `MIGRATION` when a step references an unknown
|
|
346
|
-
* table.
|
|
347
|
-
*/
|
|
348
|
-
migrate?(plan: Migration): Promise<void>;
|
|
349
|
-
/**
|
|
350
|
-
* Optional persisted-metadata read (PAIRED with {@link stamp} — a driver
|
|
351
|
-
* implements both or neither). Returns the {@link DriverMeta} last stamped,
|
|
352
|
-
* or `undefined` when the store has never been stamped.
|
|
353
|
-
*/
|
|
354
|
-
meta?(): Promise<DriverMeta | undefined>;
|
|
355
|
-
/**
|
|
356
|
-
* Optional persisted-metadata write (PAIRED with {@link meta} — a driver
|
|
357
|
-
* implements both or neither). Persists `meta` verbatim for a later `meta()`
|
|
358
|
-
* to return.
|
|
359
|
-
*/
|
|
360
|
-
stamp?(meta: DriverMeta): Promise<void>;
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* One table's columns — a map of column name to its value {@link ContractShape}.
|
|
364
|
-
*
|
|
365
|
-
* @remarks
|
|
366
|
-
* This is exactly the property map an `objectShape` takes. A table row is always
|
|
367
|
-
* an object, so you write the columns directly (`{ id: stringShape(), … }`) and
|
|
368
|
-
* the database wraps them in an `objectShape` for you — no redundant `objectShape`
|
|
369
|
-
* at the table level. (Nested object *columns* still use `objectShape`, since a
|
|
370
|
-
* column is not always an object.)
|
|
371
|
-
*/
|
|
372
|
-
export type Columns = Readonly<Record<string, ContractShape>>;
|
|
373
|
-
/**
|
|
374
|
-
* A database's table schema — a map of table name to its {@link Columns}.
|
|
375
|
-
*
|
|
376
|
-
* @remarks
|
|
377
|
-
* Each table's row type is `Infer` of its columns (see {@link RowOf}); primary-key
|
|
378
|
-
* columns are named separately via {@link TableKeys}.
|
|
379
|
-
*/
|
|
380
|
-
export type TablesShape = Readonly<Record<string, Columns>>;
|
|
381
|
-
/**
|
|
382
|
-
* The row type a table's {@link Columns} describe — `Infer` of its `objectShape`.
|
|
383
|
-
*
|
|
384
|
-
* @remarks
|
|
385
|
-
* The broad `Columns` (an open `column → shape` map, e.g. when a database is held
|
|
386
|
-
* at its default type) short-circuits to {@link Row}: there is nothing concrete to
|
|
387
|
-
* infer, and expanding `Infer` over the open shape would trip TS's
|
|
388
|
-
* instantiation-depth guard. Concrete column maps infer their exact row.
|
|
389
|
-
*/
|
|
390
|
-
export type RowOf<C extends Columns> = [Columns] extends [C] ? Row : Infer<{
|
|
391
|
-
readonly type: 'object';
|
|
392
|
-
readonly properties: C;
|
|
393
|
-
}>;
|
|
394
|
-
/**
|
|
395
|
-
* Per-table primary-key column overrides — `{ [table]: column }`.
|
|
396
|
-
*
|
|
397
|
-
* @remarks
|
|
398
|
-
* A table absent from this map keys its rows by {@link DEFAULT_PRIMARY} (`id`).
|
|
399
|
-
* Kept separate from {@link TablesShape} so the table map stays purely columns.
|
|
400
|
-
*/
|
|
401
|
-
export type TableKeys = Readonly<Record<string, string>>;
|
|
402
|
-
/**
|
|
403
|
-
* Per-table secondary indexes — `{ [table]: groups }`, each group one
|
|
404
|
-
* (possibly compound) index of column names.
|
|
405
|
-
*
|
|
406
|
-
* @remarks
|
|
407
|
-
* Contracts don't express indexes, so they're declared here on `createDatabase`
|
|
408
|
-
* and flow into each {@link TableSchema}'s `indexes` (SQLite `CREATE INDEX`,
|
|
409
|
-
* IndexedDB `createIndex`). Mirrors {@link TableKeys}.
|
|
410
|
-
*/
|
|
411
|
-
export type TableIndexes = Readonly<Record<string, readonly (readonly string[])[]>>;
|
|
412
|
-
/**
|
|
413
|
-
* Options for `createDatabase`.
|
|
414
|
-
*
|
|
415
|
-
* @remarks
|
|
416
|
-
* `driver` is the storage backend; `tables` declares each table's columns;
|
|
417
|
-
* `keys` overrides the primary-key column per table ({@link DEFAULT_PRIMARY}
|
|
418
|
-
* otherwise); `indexes` declares secondary indexes per table (contracts don't
|
|
419
|
-
* express them) that flow into each derived {@link TableSchema}; `name` labels
|
|
420
|
-
* the database; `on` wires initial {@link DatabaseEventMap} listeners (§8); `error`
|
|
421
|
-
* is the emitter's listener-error handler (§13 — a listener throw routes here);
|
|
422
|
-
* `key` is the key factory a table uses when a written row lacks its primary
|
|
423
|
-
* key — without one, writing a keyless row is a `VALIDATION` error (the core
|
|
424
|
-
* mints no keys itself).
|
|
425
|
-
*/
|
|
426
|
-
export interface DatabaseOptions<T extends TablesShape = TablesShape> {
|
|
427
|
-
readonly on?: EmitterHooks<DatabaseEventMap>;
|
|
428
|
-
/** The emitter's listener-error handler (AGENTS §13) — a listener throw routes here, not to a domain event. */
|
|
429
|
-
readonly error?: EmitterErrorHandler;
|
|
430
|
-
readonly driver: DriverInterface;
|
|
431
|
-
readonly tables: T;
|
|
432
|
-
readonly keys?: TableKeys;
|
|
433
|
-
readonly indexes?: TableIndexes;
|
|
434
|
-
readonly name?: string;
|
|
435
|
-
readonly key?: KeyFunction;
|
|
436
|
-
/**
|
|
437
|
-
* The declared schema version.
|
|
438
|
-
*
|
|
439
|
-
* @remarks
|
|
440
|
-
* Only meaningful when the driver implements BOTH {@link DriverInterface.meta}
|
|
441
|
-
* and {@link DriverInterface.stamp} (a versioning driver); unset, or a
|
|
442
|
-
* non-versioning driver, leaves `open()` unchanged from today's behavior.
|
|
443
|
-
* When set and the driver versions, `open()` reconciles against the
|
|
444
|
-
* driver's persisted {@link DriverMeta}:
|
|
445
|
-
* - **Fresh store** (`meta()` returns `undefined`) — no migration is
|
|
446
|
-
* possible (there is nothing deployed to diff against), so `open()`
|
|
447
|
-
* simply `stamp`s `{ version, schema }` for next time.
|
|
448
|
-
* - **Stored version < `version`** — `planMigration(stored.schema, declared
|
|
449
|
-
* schema)` computes the upgrade plan, applied via the driver's optional
|
|
450
|
-
* `migrate` hook. If `migrate` is absent and the plan is non-empty,
|
|
451
|
-
* `open()` throws `DatabaseError` `MIGRATION`. On success, `open()`
|
|
452
|
-
* `stamp`s the new `{ version, schema }` and emits the `migrate` event.
|
|
453
|
-
* - **Stored version > `version`** — the store is newer than the declared
|
|
454
|
-
* schema; `open()` throws `DatabaseError` `MIGRATION`.
|
|
455
|
-
* - **Stored version === `version`** — no-op.
|
|
456
|
-
*
|
|
457
|
-
* When the driver ALSO implements {@link DriverInterface.transaction}, the
|
|
458
|
-
* `migrate` + `stamp` pair applies atomically through that native handle
|
|
459
|
-
* (all-or-nothing, rolled back cleanly on a mid-plan failure); otherwise the
|
|
460
|
-
* pair applies sequentially, with a small documented window in which a `stamp`
|
|
461
|
-
* failure after a successful `migrate` can leave new data under old meta.
|
|
462
|
-
*/
|
|
463
|
-
readonly version?: number;
|
|
464
|
-
}
|
|
465
|
-
/**
|
|
466
|
-
* One table's portable definition, produced by `export` — the unit of schema /
|
|
467
|
-
* migration exchange across environments.
|
|
468
|
-
*
|
|
469
|
-
* @remarks
|
|
470
|
-
* `schema` is the JSON Schema (universally portable, serializable); `columns` is
|
|
471
|
-
* the source column map, which re-imports losslessly via `import` within a
|
|
472
|
-
* TypeScript environment. `key` is the primary-key column.
|
|
473
|
-
*/
|
|
474
|
-
export interface TableExport {
|
|
475
|
-
readonly key: string;
|
|
476
|
-
readonly columns: Columns;
|
|
477
|
-
readonly schema: JSONSchema;
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* A database — the ergonomic entry point that owns the driver and its tables.
|
|
481
|
-
*
|
|
482
|
-
* @remarks
|
|
483
|
-
* A database is a typed view over a set of tables on one driver. Tables are
|
|
484
|
-
* declared up front in `createDatabase({ tables })` and reached, fully typed,
|
|
485
|
-
* with `table(name)`. The driver connects lazily on first use, so a freshly
|
|
486
|
-
* created database is immediately usable. `import` defines more than one table
|
|
487
|
-
* from a shape map and returns a new typed view of **those** tables over the
|
|
488
|
-
* same driver and storage (so views can be split by concern and still share
|
|
489
|
-
* data); `export` produces a portable {@link TableExport} per table for moving a
|
|
490
|
-
* schema between databases or environments. `transaction` snapshots the store,
|
|
491
|
-
* runs the scope, and rolls every table back if it throws — an optimistic model
|
|
492
|
-
* that works uniformly across backends rather than reconciling SQL's and
|
|
493
|
-
* IndexedDB's incompatible native transactions.
|
|
494
|
-
*/
|
|
495
|
-
export interface DatabaseInterface<T extends TablesShape = TablesShape> {
|
|
496
|
-
readonly emitter: EmitterInterface<DatabaseEventMap>;
|
|
497
|
-
readonly name: string;
|
|
498
|
-
readonly status: DatabaseStatus;
|
|
499
|
-
table<K extends keyof T & string>(name: K): TableInterface<RowOf<T[K]>>;
|
|
500
|
-
import<U extends TablesShape>(tables: U, keys?: TableKeys): DatabaseInterface<U>;
|
|
501
|
-
export(): Readonly<Record<string, TableExport>>;
|
|
502
|
-
open(): Promise<void>;
|
|
503
|
-
close(): Promise<void>;
|
|
504
|
-
transaction<R>(scope: () => Promise<R>, options?: ReadOptions): Promise<R>;
|
|
505
|
-
/**
|
|
506
|
-
* Diff a caller-supplied deployed schema against this database's declared
|
|
507
|
-
* schema (its `tables`, as configured) via `planMigration`, apply the
|
|
508
|
-
* resulting plan through the driver's optional `migrate` hook, and return
|
|
509
|
-
* the applied plan.
|
|
510
|
-
*
|
|
511
|
-
* @param deployed - The schema currently deployed, as {@link TableSchema}s
|
|
512
|
-
* @param options - Optional abort signal, checked at entry
|
|
513
|
-
* @returns The applied {@link Migration} plan
|
|
514
|
-
*
|
|
515
|
-
* @remarks
|
|
516
|
-
* Throws `DatabaseError` `MIGRATION` when the driver does not implement
|
|
517
|
-
* `migrate`, or when a step references an unknown table (propagated from
|
|
518
|
-
* the driver). Throws `ABORTED` when `options.signal` has already fired at
|
|
519
|
-
* entry. Emits the `migrate` event after a successful apply. Version
|
|
520
|
-
* TRACKING (persisting `from` / `to`) remains deferred to persistent
|
|
521
|
-
* backends — the caller owns knowing what was deployed.
|
|
522
|
-
*/
|
|
523
|
-
migrate(deployed: readonly TableSchema[], options?: ReadOptions): Promise<Migration>;
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* A table — typed keyed CRUD plus fluent query and cursor access.
|
|
527
|
-
*
|
|
528
|
-
* @remarks
|
|
529
|
-
* Writes are coerced through the table's contract: a string input to a numeric
|
|
530
|
-
* column is normalized, and a row that cannot be coerced throws `VALIDATION`. A
|
|
531
|
-
* row missing its key is assigned a generated UUID. `get` returns `undefined`
|
|
532
|
-
* when a key is absent; `resolve` throws `NOT_FOUND`. `set` upserts; `add`
|
|
533
|
-
* inserts and throws `CONFLICT` on a duplicate key. `contract` exposes the
|
|
534
|
-
* compiled contract for introspection (`schema`) and fixtures (`generate`).
|
|
535
|
-
*
|
|
536
|
-
* The keyed methods batch by overload (AGENTS §9.2): pass one key/row for one
|
|
537
|
-
* result, or an array for an array of results in the same order — a single verb,
|
|
538
|
-
* never `getMany` / `setAll`. Batches run as independent sequential operations;
|
|
539
|
-
* wrap them in `transaction` for atomicity.
|
|
540
|
-
*/
|
|
541
|
-
export interface TableInterface<T = Row> {
|
|
542
|
-
readonly emitter: EmitterInterface<TableEventMap>;
|
|
543
|
-
readonly name: string;
|
|
544
|
-
readonly primary: string;
|
|
545
|
-
readonly contract: ContractInterface<T>;
|
|
546
|
-
get(key: Key): Promise<T | undefined>;
|
|
547
|
-
get(keys: readonly Key[]): Promise<readonly (T | undefined)[]>;
|
|
548
|
-
resolve(key: Key): Promise<T>;
|
|
549
|
-
resolve(keys: readonly Key[]): Promise<readonly T[]>;
|
|
550
|
-
has(key: Key): Promise<boolean>;
|
|
551
|
-
has(keys: readonly Key[]): Promise<readonly boolean[]>;
|
|
552
|
-
keys(): Promise<readonly Key[]>;
|
|
553
|
-
records(criteria?: Criteria, options?: ReadOptions): Promise<readonly T[]>;
|
|
554
|
-
count(criteria?: Criteria, options?: ReadOptions): Promise<number>;
|
|
555
|
-
aggregate(operation: AggregateFunction, column: FieldPath, criteria?: Criteria, options?: ReadOptions): Promise<number | undefined>;
|
|
556
|
-
/**
|
|
557
|
-
* Lazy filtered iteration over the table's rows.
|
|
558
|
-
*
|
|
559
|
-
* @remarks
|
|
560
|
-
* `criteria`'s `conditions` / `offset` / `limit` are honored lazily as rows
|
|
561
|
-
* stream; `order` is intentionally IGNORED — streaming yields driver
|
|
562
|
-
* key-order, sorted output is `records()`'s job. Breaking out of the
|
|
563
|
-
* iteration early closes the underlying source. The signal (if any) is
|
|
564
|
-
* checked before each yield.
|
|
565
|
-
*/
|
|
566
|
-
scan(criteria?: Criteria, options?: ReadOptions): AsyncIterable<T>;
|
|
567
|
-
/**
|
|
568
|
-
* Upsert one or more rows.
|
|
569
|
-
*
|
|
570
|
-
* @param row - The row to upsert
|
|
571
|
-
* @param options - Optional abort signal
|
|
572
|
-
* @returns The row's key
|
|
573
|
-
*/
|
|
574
|
-
set(row: T, options?: ReadOptions): Promise<Key>;
|
|
575
|
-
/**
|
|
576
|
-
* Upsert one or more rows.
|
|
577
|
-
*
|
|
578
|
-
* @param rows - The rows to upsert
|
|
579
|
-
* @param options - Optional abort signal, checked at entry and between items
|
|
580
|
-
* @returns Each row's key, in order
|
|
581
|
-
*
|
|
582
|
-
* @remarks
|
|
583
|
-
* The signal (if any) is checked at entry and between items; an abort
|
|
584
|
-
* surfaces as `DatabaseError` `ABORTED`. Already-applied items stay
|
|
585
|
-
* applied — there is no rollback. Wrap in `transaction()` for atomicity.
|
|
586
|
-
*/
|
|
587
|
-
set(rows: readonly T[], options?: ReadOptions): Promise<readonly Key[]>;
|
|
588
|
-
/**
|
|
589
|
-
* Insert one or more rows, throwing `CONFLICT` on a duplicate key.
|
|
590
|
-
*
|
|
591
|
-
* @param row - The row to insert
|
|
592
|
-
* @param options - Optional abort signal
|
|
593
|
-
* @returns The row's key
|
|
594
|
-
*/
|
|
595
|
-
add(row: T, options?: ReadOptions): Promise<Key>;
|
|
596
|
-
/**
|
|
597
|
-
* Insert one or more rows, throwing `CONFLICT` on a duplicate key.
|
|
598
|
-
*
|
|
599
|
-
* @param rows - The rows to insert
|
|
600
|
-
* @param options - Optional abort signal, checked at entry and between items
|
|
601
|
-
* @returns Each row's key, in order
|
|
602
|
-
*
|
|
603
|
-
* @remarks
|
|
604
|
-
* The signal (if any) is checked at entry and between items; an abort
|
|
605
|
-
* surfaces as `DatabaseError` `ABORTED`. Already-applied items stay
|
|
606
|
-
* applied — there is no rollback. Wrap in `transaction()` for atomicity.
|
|
607
|
-
*/
|
|
608
|
-
add(rows: readonly T[], options?: ReadOptions): Promise<readonly Key[]>;
|
|
609
|
-
/**
|
|
610
|
-
* Apply a partial change to one or more rows.
|
|
611
|
-
*
|
|
612
|
-
* @param key - The key of the row to update
|
|
613
|
-
* @param changes - The partial changes to apply
|
|
614
|
-
* @param options - Optional abort signal
|
|
615
|
-
* @returns `true` when the row existed and was updated
|
|
616
|
-
*/
|
|
617
|
-
update(key: Key, changes: Partial<T>, options?: ReadOptions): Promise<boolean>;
|
|
618
|
-
/**
|
|
619
|
-
* Apply a partial change to one or more rows.
|
|
620
|
-
*
|
|
621
|
-
* @param keys - The keys of the rows to update
|
|
622
|
-
* @param changes - The partial changes to apply to each row
|
|
623
|
-
* @param options - Optional abort signal, checked at entry and between items
|
|
624
|
-
* @returns Each row's update result, in order
|
|
625
|
-
*
|
|
626
|
-
* @remarks
|
|
627
|
-
* The signal (if any) is checked at entry and between items; an abort
|
|
628
|
-
* surfaces as `DatabaseError` `ABORTED`. Already-applied items stay
|
|
629
|
-
* applied — there is no rollback. Wrap in `transaction()` for atomicity.
|
|
630
|
-
*/
|
|
631
|
-
update(keys: readonly Key[], changes: Partial<T>, options?: ReadOptions): Promise<readonly boolean[]>;
|
|
632
|
-
/**
|
|
633
|
-
* Delete one or more rows.
|
|
634
|
-
*
|
|
635
|
-
* @param key - The key of the row to remove
|
|
636
|
-
* @param options - Optional abort signal
|
|
637
|
-
* @returns `true` when the row existed and was removed
|
|
638
|
-
*/
|
|
639
|
-
remove(key: Key, options?: ReadOptions): Promise<boolean>;
|
|
640
|
-
/**
|
|
641
|
-
* Delete one or more rows.
|
|
642
|
-
*
|
|
643
|
-
* @param keys - The keys of the rows to remove
|
|
644
|
-
* @param options - Optional abort signal, checked at entry and between items
|
|
645
|
-
* @returns Each row's removal result, in order
|
|
646
|
-
*
|
|
647
|
-
* @remarks
|
|
648
|
-
* The signal (if any) is checked at entry and between items; an abort
|
|
649
|
-
* surfaces as `DatabaseError` `ABORTED`. Already-applied items stay
|
|
650
|
-
* applied — there is no rollback. Wrap in `transaction()` for atomicity.
|
|
651
|
-
*/
|
|
652
|
-
remove(keys: readonly Key[], options?: ReadOptions): Promise<readonly boolean[]>;
|
|
653
|
-
clear(): Promise<void>;
|
|
654
|
-
query(): QueryInterface<T>;
|
|
655
|
-
cursor(): Promise<CursorInterface<T>>;
|
|
656
|
-
}
|
|
657
|
-
/**
|
|
658
|
-
* A fluent query builder.
|
|
659
|
-
*
|
|
660
|
-
* @remarks
|
|
661
|
-
* `where` / `and` / `or` open a {@link ClauseInterface} whose operator
|
|
662
|
-
* closes the condition and returns the query. `filter` adds a post-fetch JS
|
|
663
|
-
* predicate (applied after the backend read, before paging). The terminals
|
|
664
|
-
* (`all` / `first` / `count` / the aggregates) execute against the table; each
|
|
665
|
-
* call mutates and returns the same builder, so a chain reads as one statement.
|
|
666
|
-
* Every `column` is a {@link FieldPath} — a string is one column, an array
|
|
667
|
-
* descends a nested value.
|
|
668
|
-
*/
|
|
669
|
-
export interface QueryInterface<T = Row> {
|
|
670
|
-
where(column: FieldPath): ClauseInterface<T>;
|
|
671
|
-
and(column: FieldPath): ClauseInterface<T>;
|
|
672
|
-
or(column: FieldPath): ClauseInterface<T>;
|
|
673
|
-
filter(predicate: (row: T) => boolean): QueryInterface<T>;
|
|
674
|
-
ascending(column: FieldPath): QueryInterface<T>;
|
|
675
|
-
descending(column: FieldPath): QueryInterface<T>;
|
|
676
|
-
limit(count: number): QueryInterface<T>;
|
|
677
|
-
offset(count: number): QueryInterface<T>;
|
|
678
|
-
all(): Promise<readonly T[]>;
|
|
679
|
-
first(): Promise<T | undefined>;
|
|
680
|
-
count(): Promise<number>;
|
|
681
|
-
/**
|
|
682
|
-
* Lazy per-row evaluation of this query's conditions / filters / offset /
|
|
683
|
-
* limit.
|
|
684
|
-
*
|
|
685
|
-
* @remarks
|
|
686
|
-
* `order` and its comparators are IGNORED (streaming yields unsorted, as
|
|
687
|
-
* rows are evaluated one at a time). Same abort semantics as
|
|
688
|
-
* {@link TableInterface.scan}: the signal (if any) is checked before each
|
|
689
|
-
* yield, and breaking out early closes the underlying source.
|
|
690
|
-
*/
|
|
691
|
-
stream(options?: ReadOptions): AsyncIterable<T>;
|
|
692
|
-
sum(column: FieldPath): Promise<number | undefined>;
|
|
693
|
-
average(column: FieldPath): Promise<number | undefined>;
|
|
694
|
-
minimum(column: FieldPath): Promise<number | undefined>;
|
|
695
|
-
maximum(column: FieldPath): Promise<number | undefined>;
|
|
696
|
-
aggregate(operation: AggregateFunction, column: FieldPath): Promise<number | undefined>;
|
|
697
|
-
}
|
|
698
|
-
/**
|
|
699
|
-
* A pending condition opened by `where` / `and` / `or`.
|
|
700
|
-
*
|
|
701
|
-
* @remarks
|
|
702
|
-
* Each operator records its condition against the query and returns the query,
|
|
703
|
-
* so the chain continues fluently. `absent` / `present` take no operand;
|
|
704
|
-
* `between` takes two; `any` / `none` take a list.
|
|
705
|
-
*/
|
|
706
|
-
export interface ClauseInterface<T = Row> {
|
|
707
|
-
equals(value: unknown): QueryInterface<T>;
|
|
708
|
-
not(value: unknown): QueryInterface<T>;
|
|
709
|
-
above(value: unknown): QueryInterface<T>;
|
|
710
|
-
below(value: unknown): QueryInterface<T>;
|
|
711
|
-
from(value: unknown): QueryInterface<T>;
|
|
712
|
-
to(value: unknown): QueryInterface<T>;
|
|
713
|
-
between(lower: unknown, upper: unknown): QueryInterface<T>;
|
|
714
|
-
like(pattern: string): QueryInterface<T>;
|
|
715
|
-
glob(pattern: string): QueryInterface<T>;
|
|
716
|
-
starts(prefix: string): QueryInterface<T>;
|
|
717
|
-
ends(suffix: string): QueryInterface<T>;
|
|
718
|
-
any(values: readonly unknown[]): QueryInterface<T>;
|
|
719
|
-
none(values: readonly unknown[]): QueryInterface<T>;
|
|
720
|
-
absent(): QueryInterface<T>;
|
|
721
|
-
present(): QueryInterface<T>;
|
|
722
|
-
}
|
|
723
|
-
/**
|
|
724
|
-
* A forward row cursor for bulk in-place mutation.
|
|
725
|
-
*
|
|
726
|
-
* @remarks
|
|
727
|
-
* Iterates a snapshot of the table's keys taken at creation; `update` and
|
|
728
|
-
* `remove` act on the row at the current position through the owning table.
|
|
729
|
-
* `done` is `true` once iteration has advanced past the last key.
|
|
730
|
-
*/
|
|
731
|
-
export interface CursorInterface<T = Row> {
|
|
732
|
-
readonly value: T | undefined;
|
|
733
|
-
readonly index: number;
|
|
734
|
-
readonly done: boolean;
|
|
735
|
-
next(): Promise<void>;
|
|
736
|
-
update(changes: Partial<T>): Promise<void>;
|
|
737
|
-
remove(): Promise<void>;
|
|
738
|
-
close(): void;
|
|
739
|
-
}
|