@jarenjs/db 0.46.5 → 0.56.0

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.
Files changed (72) hide show
  1. package/ARCHITECTURE.md +133 -17
  2. package/README.md +270 -36
  3. package/docs/JOBS-FORMAT.md +24 -8
  4. package/docs/LIVE-FORMAT.md +139 -7
  5. package/docs/MIGRATION-FORMAT.md +118 -36
  6. package/docs/MODEL-FORMAT.md +251 -30
  7. package/package.json +4 -5
  8. package/schemas/jaren-migration.draft-07.schema.json +73 -0
  9. package/schemas/jaren-migration.schema.json +73 -0
  10. package/src/algebra.js +22 -3
  11. package/src/capture.js +66 -28
  12. package/src/cli.js +225 -44
  13. package/src/ddl.js +23 -3
  14. package/src/dialect.js +13 -0
  15. package/src/dialects/sqlite.js +21 -1
  16. package/src/driver.js +63 -16
  17. package/src/drivers/wasm.js +1 -0
  18. package/src/emit-model.js +14 -0
  19. package/src/emit.js +42 -9
  20. package/src/entity.js +92 -47
  21. package/src/errors.js +28 -0
  22. package/src/index.js +2 -2
  23. package/src/jobs.js +40 -5
  24. package/src/live-time.js +605 -0
  25. package/src/live.js +52 -9
  26. package/src/migrate.js +397 -191
  27. package/src/model.js +173 -8
  28. package/src/plan.js +834 -47
  29. package/src/query.js +296 -22
  30. package/src/residual.js +15 -6
  31. package/src/series.js +349 -0
  32. package/src/store.js +243 -69
  33. package/src/tracker.js +173 -48
  34. package/types/index.d.ts +206 -12
  35. package/types/node.d.ts +3 -1
  36. package/types/typed.d.ts +58 -2
  37. package/types/wasm.d.ts +7 -0
  38. package/dist/types/algebra.d.ts +0 -199
  39. package/dist/types/app.d.ts +0 -49
  40. package/dist/types/capture.d.ts +0 -85
  41. package/dist/types/cli.d.ts +0 -2
  42. package/dist/types/dag-job.d.ts +0 -40
  43. package/dist/types/ddl.d.ts +0 -229
  44. package/dist/types/derive.d.ts +0 -250
  45. package/dist/types/dialect.d.ts +0 -149
  46. package/dist/types/dialects/sqlite.d.ts +0 -9
  47. package/dist/types/driver.d.ts +0 -110
  48. package/dist/types/drivers/bun.d.ts +0 -47
  49. package/dist/types/drivers/node.d.ts +0 -37
  50. package/dist/types/drivers/wasm.d.ts +0 -65
  51. package/dist/types/emit-model.d.ts +0 -44
  52. package/dist/types/emit.d.ts +0 -75
  53. package/dist/types/entity.d.ts +0 -23
  54. package/dist/types/errors.d.ts +0 -167
  55. package/dist/types/graph.d.ts +0 -28
  56. package/dist/types/index.d.ts +0 -37
  57. package/dist/types/jobs.d.ts +0 -140
  58. package/dist/types/knn.d.ts +0 -69
  59. package/dist/types/live.d.ts +0 -62
  60. package/dist/types/migrate.d.ts +0 -170
  61. package/dist/types/model.d.ts +0 -36
  62. package/dist/types/patch-sql.d.ts +0 -37
  63. package/dist/types/plan.d.ts +0 -140
  64. package/dist/types/profile.d.ts +0 -80
  65. package/dist/types/query.d.ts +0 -111
  66. package/dist/types/residual.d.ts +0 -61
  67. package/dist/types/store.d.ts +0 -53
  68. package/dist/types/tracker.d.ts +0 -43
  69. package/dist/types/typed.d.ts +0 -15
  70. package/dist/types/types.d.ts +0 -26
  71. package/dist/types/udf.d.ts +0 -75
  72. package/dist/types/window.d.ts +0 -52
@@ -1,250 +0,0 @@
1
- /**
2
- * @file Derived index columns: the one place a declared
3
- * `indexes[].derive` becomes a value. A spatial member is an array of
4
- * numbers or an object, and a generated column must be a scalar, so a
5
- * geohash cell or a bounding-box edge is what actually gets indexed;
6
- * an embedding is an array of hundreds of numbers, and what gets
7
- * stored is its packed, l2-normalized Float32 form.
8
- *
9
- * Every cell and every box comes from `@jarenjs/core/geo`, and every
10
- * normalization and packing from `@jarenjs/core/vector`; nothing here
11
- * computes arithmetic of its own. The spatial functions serve BOTH
12
- * physical mappings — registered as deterministic SQL functions inside
13
- * a virtual generated column's expression where the driver can index
14
- * them, and called directly on the write path where it cannot — so
15
- * the two branches cannot drift into different answers. The vector
16
- * kind has ONE mapping, stored everywhere (`DERIVE_MAPPING`), and
17
- * registers no function at all: a whole array re-derived per row as a
18
- * host call is the cost the spatial work measured at 150×, a stored
19
- * column is readable without any registration, and bun has no
20
- * function API — one mapping is the only way every driver agrees.
21
- *
22
- * It is also this package's ONLY seam onto `@jarenjs/core/geo` (D1 —
23
- * one home for spatial arithmetic, grep-proven by test) and onto
24
- * `@jarenjs/core/vector` (the same rule, one home for vector
25
- * arithmetic): the planner's probe geometry — the box of a literal or
26
- * bound region, the box of a bounded-distance circle, a cell's
27
- * neighbourhood — and the k-nearest plan's probe vector and column
28
- * score are computed by the helpers below rather than by an import of
29
- * their own.
30
- *
31
- * The switches over the kind are EXHAUSTIVE: a kind with no rule
32
- * throws, here and in the dialect, so that adding a kind without
33
- * teaching both is a failure at the first call rather than a bbox
34
- * edge of the first two floats and `jaren_bbox_undefined(...)` SQL.
35
- *
36
- * Determinism is the contract, not a convenience: a value here is a
37
- * pure function of the document bytes. Nothing reads the clock, a
38
- * random source or store state, because an INDEX over a function that
39
- * did would make the database unreadable from a connection whose
40
- * function answered differently — and unreadable, not merely wrong:
41
- * a connection that has not registered the function at all cannot even
42
- * SELECT the table (probed). That hazard is why the mapping is
43
- * capability-gated rather than always-on.
44
- */
45
- /** The closed set of derive kinds. */
46
- export declare const DERIVE_KINDS: Set<string>;
47
- /**
48
- * The per-kind PHYSICAL MAPPING override. A spatial kind takes the
49
- * mapping the driver's capability selects (`null` here); the vector
50
- * kind is `'stored'` on every driver, for the three reasons in the
51
- * file header, and never joins `registerDeriveFunctions`.
52
- * @type {Readonly<Record<string, 'stored' | null>>}
53
- */
54
- export declare const DERIVE_MAPPING: Readonly<Record<string, 'stored' | null>>;
55
- /**
56
- * The physical mapping one derived column takes: the kind's override
57
- * where it has one, the driver's mapping otherwise.
58
- * @param {string} kind
59
- * @param {'virtual' | 'stored'} driverMapping
60
- * @returns {'virtual' | 'stored'}
61
- */
62
- export declare function derivedMappingFor(kind: string, driverMapping: 'virtual' | 'stored'): 'virtual' | 'stored';
63
- /**
64
- * The closed set of PHYSICAL realizations a `derive: 'bbox'` index may
65
- * ask for. `'columns'` is the default and what an absent member means:
66
- * four generated columns under one B-tree. `'rtree'` is the same four
67
- * columns (they stay the box's one definition) beside a SQLite R\*Tree
68
- * virtual table kept in sync by declared triggers, with no B-tree over
69
- * them. The LOGICAL meaning of `derive: 'bbox'` is identical either
70
- * way — same rows, same answers — which is the whole point of naming
71
- * the shape separately from the derivation.
72
- */
73
- export declare const PHYSICAL_KINDS: Set<string>;
74
- /** A bbox index's four columns, in the order they are declared —
75
- * `[west, south, east, north]`, the order the kernel's boxes carry. */
76
- export declare const BBOX_COMPONENTS: readonly string[];
77
- /**
78
- * The order a bbox index COVERS its four columns, which is not the
79
- * order they are declared in: an intersection test reads
80
- * `w <= ? AND e >= ? AND s <= ? AND n >= ?`, so the two longitude
81
- * bounds sit together at the front of the index where a leading-column
82
- * range can use them. `(a,b)` and `(b,a)` are different indexes.
83
- */
84
- export declare const BBOX_INDEX_ORDER: readonly string[];
85
- /** The declared geohash precision range (characters). */
86
- export declare const PRECISION_MIN = 1;
87
- export declare const PRECISION_MAX = 12;
88
- /** The declared vector width range (components). */
89
- export declare const DIMS_MIN = 1;
90
- export declare const DIMS_MAX = 8192;
91
- /**
92
- * The geohash cell of a value at a precision, or null when the value
93
- * carries no bounded position.
94
- * @param {any} value
95
- * @param {number} precision
96
- * @returns {string | null}
97
- */
98
- export declare function deriveGeohash(value: any, precision: number): string | null;
99
- /**
100
- * One edge of a value's bounding box, or null when it has none —
101
- * including the D6 case where a non-finite coordinate refuses the box
102
- * rather than producing one that does not bound its input.
103
- * @param {any} value
104
- * @param {string} component - `'w'`, `'s'`, `'e'` or `'n'`
105
- * @returns {number | null}
106
- */
107
- export declare function deriveBboxEdge(value: any, component: string): number | null;
108
- /**
109
- * The value of a `derive: 'vector'` column for a document member — the
110
- * ONE seam from this package onto `@jarenjs/core/vector`. The member
111
- * round-trips through its stored form first, exactly as the spatial
112
- * kinds do: a `Float32Array` in the document is held as an object and
113
- * a `NaN` as `null`, and the column must be a function of what is
114
- * held, so that a write, a migration backfill and a second open can
115
- * never disagree about one row.
116
- * @param {any} member - the value at the index path, or `undefined`
117
- * @param {number} dims - the declared width
118
- * @returns {Uint8Array | null} `4·dims` bytes, or `null` when the
119
- * member is not a vector of that width
120
- */
121
- export declare function deriveVector(member: any, dims: number): Uint8Array | null;
122
- /**
123
- * A member as the database will hold it. A derived value must be a
124
- * function of the STORED document, not of the object handed to the
125
- * write: JSON has no `NaN` and no `Infinity`, so a non-finite
126
- * coordinate becomes `null` on the way in and is no longer a position
127
- * at all. Computing from the in-memory value would make the two
128
- * physical mappings answer differently for the same document, which is
129
- * the one thing they may never do.
130
- *
131
- * Only the indexed MEMBER round-trips, not the whole document — it is
132
- * the only part a derived column reads.
133
- * @param {any} member
134
- * @returns {any} the member as stored, or `undefined` when there is none
135
- */
136
- export declare function storedMemberForm(member: any): any;
137
- /**
138
- * The value of one derived column for a document member, which the
139
- * caller hands over in its STORED form (`storedMemberForm`): the write
140
- * path round-trips it, and a migration backfill reads it from the row.
141
- * Exhaustive over the kind — see the file header.
142
- * @param {{ derive: string, precision?: number, component?: string,
143
- * dims?: number }} column
144
- * @param {any} member - the stored value at the index path, or `undefined`
145
- * @returns {string | number | Uint8Array | null}
146
- */
147
- export declare function derivedValue(column: {
148
- derive: string;
149
- precision?: number;
150
- component?: string;
151
- dims?: number;
152
- }, member: any): string | number | Uint8Array | null;
153
- /**
154
- * Read the member one derived column is computed from, walking the
155
- * same typed segments the physical mapping was planned over.
156
- * @param {any} doc
157
- * @param {import('./dialect.js').JsonPathSegment[]} segments
158
- * @returns {any} the member, or `undefined`
159
- */
160
- export declare function memberAt(doc: any, segments: import('./dialect.js').JsonPathSegment[]): any;
161
- /**
162
- * Register the deterministic functions the virtual generated columns
163
- * call. Idempotent per connection by SQLite's own semantics (a second
164
- * registration replaces the first with the identical implementation),
165
- * and a no-op where the driver cannot index a registered function —
166
- * that branch stores the columns instead.
167
- *
168
- * The four bbox edges share a one-entry memo of the last text they
169
- * were asked about, because they are called back to back with the same
170
- * argument for one row and the box costs a full walk of the geometry.
171
- * The memo is keyed on the argument itself, so it changes no answer.
172
- * @param {any} connection
173
- * @returns {any} value-or-promise
174
- */
175
- export declare function registerDeriveFunctions(connection: any): any;
176
- /**
177
- * The bounding box of a probe value, or `null` when it has none — the
178
- * D6 refusal included, which is what makes an unbounded probe divert to
179
- * the full scan instead of narrowing with a box that does not bound it.
180
- * @param {any} value - a GeoJSON value or a `[lon, lat]` position
181
- * @returns {number[] | null} `[west, south, east, north]`
182
- */
183
- export declare function probeBox(value: any): number[] | null;
184
- /**
185
- * The representative position §8.14 measures a probe value by — the
186
- * same rule the derived columns use, so the pushed filter and the
187
- * engine cannot disagree about where a value IS. `null` when it has no
188
- * bounded position.
189
- * @param {any} value
190
- * @returns {number[] | null}
191
- */
192
- export declare function probePosition(value: any): number[] | null;
193
- /**
194
- * The bounding box of the circle of `metres` around a position — the
195
- * box a `$distance <= r` predicate narrows with, on the same sphere and
196
- * the same radius constant the engine measures with. `null` when the
197
- * radius is not a finite non-negative number, or when the circle
198
- * reaches a pole, where there is no longitude bound to give.
199
- * @param {number[]} position
200
- * @param {number} metres
201
- * @returns {number[] | null} `[west, south, east, north]`, NOT wrapped
202
- * into `[-180, 180]`: a circle spanning the antimeridian answers a
203
- * west below -180, which is how the planner detects it
204
- */
205
- export declare function probeCircleBox(position: number[], metres: number): number[] | null;
206
- /**
207
- * A cell and its neighbours, the nine-cell probe D7 requires — a single
208
- * prefix is bucketing, never proximity.
209
- * @param {string} cell
210
- * @returns {string[]} up to nine cells (fewer past a pole)
211
- */
212
- export declare function cellNeighbourhood(cell: string): string[];
213
- /**
214
- * The value one DERIVED parameter slot binds: an axis of a bound
215
- * external's bounding box, computed at bind time because a GeoJSON
216
- * object is not a value any database can bind. `null` when the value
217
- * has no box, which is what tells the caller to divert.
218
- * @param {{ kind: string, external: string, axis: string }} derived
219
- * @param {any} value - the bound external
220
- * @returns {number | null}
221
- */
222
- export declare function derivedSlotValue(derived: {
223
- kind: string;
224
- external: string;
225
- axis: string;
226
- }, value: any): number | null;
227
- /**
228
- * The probe a k-nearest plan scores the column against: a literal or
229
- * bound vector, l2-normalized once, so that its dot product with the
230
- * column's normalized form IS the cosine of the raw vectors. `null`
231
- * when the value is not a vector of exactly `dims` finite numbers —
232
- * the binder's signal to divert the call to the residual, where the
233
- * engine answers what it answers everywhere for such a probe (empty
234
- * keys for another width, its own refusal for a non-array).
235
- * @param {unknown} value
236
- * @param {number} dims - the column's declared width
237
- * @returns {Float32Array | null}
238
- */
239
- export declare function probeVector(value: unknown, dims: number): Float32Array | null;
240
- /**
241
- * One row's column score against a prepared probe: the packed column
242
- * unpacked at the declared width and dotted with the probe. `null` for
243
- * a row whose column holds no vector — SQL `NULL`, or bytes of another
244
- * length — because such a row is unrankable and 0 is a real score.
245
- * @param {unknown} bytes - the column value as the driver returns it
246
- * @param {number} dims
247
- * @param {Float32Array} probe - from {@link probeVector}
248
- * @returns {number | null}
249
- */
250
- export declare function columnScore(bytes: unknown, dims: number, probe: Float32Array): number | null;
@@ -1,149 +0,0 @@
1
- /**
2
- * @file The dialect seam: the ONLY place SQL text is produced. A
3
- * dialect is data plus a small emitter — a spelling spec (how to quote
4
- * an identifier, reference a parameter, extract a JSON member, open a
5
- * savepoint) composed by {@link createDialect} into the DDL and DML
6
- * statement builders the store consumes. Nothing outside a dialect
7
- * concatenates SQL; that costs one indirection now, and without it a
8
- * second backend is a rewrite.
9
- *
10
- * Deliberately NOT in the dialect, because they are behavioural rather
11
- * than syntactic: whether functions can be registered per connection,
12
- * whether change capture exists and in what form, and whether tables
13
- * can be restructured in place. Those are capabilities on the
14
- * connection.
15
- */
16
- export type JsonPathSegment = {
17
- name: string;
18
- } | {
19
- index: number;
20
- };
21
- /**
22
- * A typed member path into the JSON document column: name segments for
23
- * object members, index segments for array positions. Produced by the
24
- * DDL planner (from analyzed index paths) and the patch translator
25
- * (from pointers discriminated against the live document).
26
- * @typedef {{ name: string } | { index: number }} JsonPathSegment
27
- */
28
- /**
29
- * Compose a dialect from its spelling spec. Every statement the store
30
- * ever runs is built here from the spec's primitives, so a spec with
31
- * different quoting or parameter style produces correspondingly
32
- * different SQL from the same model — the property the test-double
33
- * dialect pins.
34
- * @param {{
35
- * name: string,
36
- * capabilities: Record<string, any>,
37
- * tableSuffix: string,
38
- * docColumnType: string,
39
- * packedVectorType: string,
40
- * quoteIdentifier: (s: string) => string,
41
- * parameterRef: (i: number, name: string) => string,
42
- * stringLiteral: (s: string) => string,
43
- * booleanLiteral: (b: boolean) => string,
44
- * typeFor: (schemaType: string | undefined, hint: string) => string,
45
- * limitClause: (limit: number, offset?: number) => string,
46
- * jsonPathText: (segments: JsonPathSegment[]) => string | null,
47
- * jsonExtract: (columnSql: string, pathText: string) => string,
48
- * derivedExpression?: (memberSql: string, column: { derive: string,
49
- * precision?: number, component?: string, dims?: number }) => string,
50
- * jsonSet: (exprSql: string, pathText: string, valueSql: string) => string,
51
- * jsonRemove: (exprSql: string, pathText: string) => string,
52
- * jsonAppend: (exprSql: string, arrayPathText: string, valueSql: string) => string,
53
- * jsonEncode: (paramSql: string) => string,
54
- * jsonText: (columnSql: string) => string,
55
- * jsonAgg: (exprSql: string) => string,
56
- * jsonTypeOf: (columnSql: string, pathText: string) => string,
57
- * valueTypeOf: (paramSql: string) => string,
58
- * strStartsWith: (valueSql: string, lowerParamSql: string, upperParamSql: string) => string,
59
- * strStartsWithExact: (valueSql: string, patternA: string, patternB: string) => string,
60
- * strEndsWith: (valueSql: string, patternA: string, patternB: string, patternC: string) => string,
61
- * strContains: (valueSql: string, patternSql: string) => string,
62
- * orderNulls: (nullsFirst: boolean) => string,
63
- * rowIdentity: () => string,
64
- * identityIn: (identitySql: string, paramSqls: string[]) => string,
65
- * rtree?: { module: string, columns: readonly string[] },
66
- * explainQuery: (sql: string) => string,
67
- * excludedRef: (columnSql: string) => string,
68
- * tx: { begin: string, beginImmediate: string, commit: string,
69
- * rollback: string,
70
- * savepoint: (n: string) => string, release: (n: string) => string,
71
- * rollbackTo: (n: string) => string },
72
- * pragma: { busyTimeout: (ms: number) => string,
73
- * journalMode: (mode: string) => string,
74
- * foreignKeys: (on: boolean) => string },
75
- * introspect: { version: () => string, compileOptions: () => string,
76
- * tableExists: () => string, columns: (table: string) => string,
77
- * indexes: (table: string) => string,
78
- * indexColumns: (index: string) => string,
79
- * foreignKeysOn: () => string,
80
- * foreignKeyList: (table: string) => string },
81
- * }} spec
82
- * @returns {any} the frozen dialect
83
- */
84
- export declare function createDialect(spec: {
85
- name: string;
86
- capabilities: Record<string, any>;
87
- tableSuffix: string;
88
- docColumnType: string;
89
- packedVectorType: string;
90
- quoteIdentifier: (s: string) => string;
91
- parameterRef: (i: number, name: string) => string;
92
- stringLiteral: (s: string) => string;
93
- booleanLiteral: (b: boolean) => string;
94
- typeFor: (schemaType: string | undefined, hint: string) => string;
95
- limitClause: (limit: number, offset?: number) => string;
96
- jsonPathText: (segments: JsonPathSegment[]) => string | null;
97
- jsonExtract: (columnSql: string, pathText: string) => string;
98
- derivedExpression?: (memberSql: string, column: {
99
- derive: string;
100
- precision?: number;
101
- component?: string;
102
- dims?: number;
103
- }) => string;
104
- jsonSet: (exprSql: string, pathText: string, valueSql: string) => string;
105
- jsonRemove: (exprSql: string, pathText: string) => string;
106
- jsonAppend: (exprSql: string, arrayPathText: string, valueSql: string) => string;
107
- jsonEncode: (paramSql: string) => string;
108
- jsonText: (columnSql: string) => string;
109
- jsonAgg: (exprSql: string) => string;
110
- jsonTypeOf: (columnSql: string, pathText: string) => string;
111
- valueTypeOf: (paramSql: string) => string;
112
- strStartsWith: (valueSql: string, lowerParamSql: string, upperParamSql: string) => string;
113
- strStartsWithExact: (valueSql: string, patternA: string, patternB: string) => string;
114
- strEndsWith: (valueSql: string, patternA: string, patternB: string, patternC: string) => string;
115
- strContains: (valueSql: string, patternSql: string) => string;
116
- orderNulls: (nullsFirst: boolean) => string;
117
- rowIdentity: () => string;
118
- identityIn: (identitySql: string, paramSqls: string[]) => string;
119
- rtree?: {
120
- module: string;
121
- columns: readonly string[];
122
- };
123
- explainQuery: (sql: string) => string;
124
- excludedRef: (columnSql: string) => string;
125
- tx: {
126
- begin: string;
127
- beginImmediate: string;
128
- commit: string;
129
- rollback: string;
130
- savepoint: (n: string) => string;
131
- release: (n: string) => string;
132
- rollbackTo: (n: string) => string;
133
- };
134
- pragma: {
135
- busyTimeout: (ms: number) => string;
136
- journalMode: (mode: string) => string;
137
- foreignKeys: (on: boolean) => string;
138
- };
139
- introspect: {
140
- version: () => string;
141
- compileOptions: () => string;
142
- tableExists: () => string;
143
- columns: (table: string) => string;
144
- indexes: (table: string) => string;
145
- indexColumns: (index: string) => string;
146
- foreignKeysOn: () => string;
147
- foreignKeyList: (table: string) => string;
148
- };
149
- }): any;
@@ -1,9 +0,0 @@
1
- /**
2
- * @file The SQLite dialect — the first spelling of the dialect
3
- * contract, not the only conceivable one. Documents are stored JSONB
4
- * in a BLOB column of a STRICT table; indexed paths become virtual
5
- * generated columns over `jsonb_extract`; reads render back to text
6
- * through `json()`. Parameters are positional (`?`) because every
7
- * binding this package ships binds arrays.
8
- */
9
- export declare const sqliteDialect: any;
@@ -1,110 +0,0 @@
1
- /**
2
- * @file The driver seam: the contract every binding satisfies, the
3
- * capability probe that runs once at open, and the sync-capable-async
4
- * helpers the store composes with.
5
- *
6
- * A driver is `{ name, dialect, open(path, options) }`; `open` returns
7
- * a `Connection` or a promise of one. Every connection method may
8
- * return a value or a promise — the store never assumes either, and
9
- * composes through {@link chain}, which does not allocate a promise
10
- * when the driver answered with a value. That is what keeps the public
11
- * asynchronous surface from paying twice while the synchronous fast
12
- * path stays exact.
13
- *
14
- * The runtime builtin behind a binding is imported LAZILY inside
15
- * `open()` via {@link lazyOpen} — never at module scope — because the
16
- * packed-consumer gate imports every export subpath under Node *and*
17
- * Bun, Bun ships no `node:sqlite`, and Node cannot resolve `bun:`
18
- * specifiers. `open()` is where "this driver does not exist here"
19
- * becomes the coded `JD0003` instead of a module-load crash.
20
- *
21
- * `capabilities` is read once at open — from the library's version
22
- * report, its compile options and the binding's declaration — and is
23
- * the single source of truth for feature gating; never a `typeof`
24
- * sniff at a call site. Two slots are deliberately EMPTY on every
25
- * SQLite driver: `statementTimeout` (no interrupt or progress handler
26
- * exists to build one on) and `rowEstimates` (the query plan is prose,
27
- * not numbers). They exist so a driver that has the facts can fill
28
- * them without a contract change; pretending SQLite has them is the
29
- * silent degradation this suite refuses.
30
- */
31
- import { isThenable, chain, toPromise } from '@jarenjs/core/function';
32
- /** The minimum SQLite the store accepts, asserted at open. */
33
- export declare const SQLITE_FLOOR = "3.45.0";
34
- /**
35
- * How long work may wait for an open transaction to settle before it is
36
- * rejected with `JD0012`. Matches the store's default busy timeout: the
37
- * question "has this waited unreasonably long?" has one answer per
38
- * connection whether the contention is another process (SQLite's own
39
- * busy timeout) or another transaction on this one.
40
- */
41
- export declare const DEFAULT_QUEUE_TIMEOUT = 5000;
42
- export { isThenable, chain, toPromise };
43
- /**
44
- * Compare two dotted version strings numerically.
45
- * @param {string} a
46
- * @param {string} b
47
- * @returns {number} negative when a < b, zero when equal
48
- */
49
- export declare function compareVersions(a: string, b: string): number;
50
- /**
51
- * Load a runtime builtin lazily and hand it to the binding's adapter.
52
- * A failed import — the specifier does not exist on this runtime —
53
- * becomes `JD0003` carrying the loader's error as `cause`.
54
- * @param {string} specifier - The builtin module specifier
55
- * @param {string} reason - The `JD0003` reason for this binding
56
- * @param {(mod: any, ...args: any[]) => any} use - The binding's
57
- * module-to-connection adapter (a named export so the suite can
58
- * exercise it with a substitute module on any runtime)
59
- * @param {any[]} args - Extra arguments forwarded to `use`
60
- * @returns {Promise<any>}
61
- */
62
- export declare function lazyOpen(specifier: string, reason: string, use: (mod: any, ...args: any[]) => any, args: any[]): Promise<any>;
63
- /**
64
- * Normalize a raw statement to the contract shape. A binding without a
65
- * native `iterate` gets one composed over `all` — eager, but the same
66
- * rows in the same order.
67
- * @param {{ run: Function, get: Function, all: Function,
68
- * iterate?: Function }} statement
69
- * @returns {{ run: Function, get: Function, all: Function,
70
- * iterate: Function }}
71
- */
72
- export declare function wrapStatement(statement: {
73
- run: Function;
74
- get: Function;
75
- all: Function;
76
- iterate?: Function;
77
- }): {
78
- run: Function;
79
- get: Function;
80
- all: Function;
81
- iterate: Function;
82
- };
83
- /**
84
- * Finish a raw binding into the connection contract: probe the library
85
- * once, assert the version floor, freeze the capability table, and
86
- * attach the savepoint-nested `transaction`.
87
- *
88
- * The raw shape a binding supplies:
89
- * `{ exec(sql), prepare(sql) -> { run, get, all, iterate? }, close(),
90
- * registerFunction?, registerAggregate?, session? }` — every method
91
- * value-or-promise.
92
- *
93
- * @param {any} raw
94
- * @param {{ dialect: any, synchronous?: boolean, queueTimeout?: number,
95
- * declared?: { sessions?: boolean, userFunctions?: boolean,
96
- * deterministicIndexableFunctions?: boolean,
97
- * aggregateFunctions?: boolean } }} options
98
- * @returns {any} a Connection, or a promise of one
99
- */
100
- export declare function openConnection(raw: any, options: {
101
- dialect: any;
102
- synchronous?: boolean;
103
- queueTimeout?: number;
104
- declared?: {
105
- sessions?: boolean;
106
- userFunctions?: boolean;
107
- deterministicIndexableFunctions?: boolean;
108
- aggregateFunctions?: boolean;
109
- };
110
- }): any;
@@ -1,47 +0,0 @@
1
- /**
2
- * @file The Bun binding: `bun:sqlite` behind the driver contract. The
3
- * builtin is imported lazily inside `open()` — never at module scope —
4
- * so this module itself loads under any runtime; on a runtime that
5
- * cannot resolve `bun:` specifiers the open fails with the coded
6
- * `JD0003`.
7
- *
8
- * Probed reality this binding declares rather than papers over:
9
- * `bun:sqlite`'s `Database` exposes no `function`, no `aggregate` and
10
- * no `createSession` — on Bun the UDF hatch does not exist and there
11
- * is no session-based change capture. The capability table says so.
12
- *
13
- * What it DOES expose is a native lazy row iterator, forwarded below.
14
- * Without it the driver's generic fallback composes a cursor over
15
- * `all()`, which materialises every row first — so a query that streams
16
- * on Node would spike memory in a compiled Bun binary, on the same code
17
- * and the same data. A cursor that is not lazy is not a cursor.
18
- */
19
- /**
20
- * Adapt an already-constructed `bun:sqlite` `Database` (or any object
21
- * with its shape) into a probed connection. Exported so the adapter is
22
- * exercisable without the builtin.
23
- * @param {any} db - A Bun `Database`-shaped database
24
- * @param {{ queueTimeout?: number }} [options]
25
- * @returns {any} a Connection, or a promise of one
26
- */
27
- export declare function adaptBunDatabase(db: any, options?: {
28
- queueTimeout?: number;
29
- }): any;
30
- /**
31
- * Construct and adapt the database from a loaded `bun:sqlite` module.
32
- * Exported so the whole open path runs under any runtime with a
33
- * substitute module.
34
- * @param {any} mod - The `bun:sqlite` module (or a substitute)
35
- * @param {string} path
36
- * @param {{ readOnly?: boolean, queueTimeout?: number }} [options]
37
- * @returns {any}
38
- */
39
- export declare function fromBunModule(mod: any, path: string, options?: {
40
- readOnly?: boolean;
41
- queueTimeout?: number;
42
- }): any;
43
- /**
44
- * The Bun driver: `{ name, dialect, open }` over `bun:sqlite`.
45
- * @returns {any}
46
- */
47
- export declare function bunDriver(): any;
@@ -1,37 +0,0 @@
1
- /**
2
- * @file The Node binding: `node:sqlite` behind the driver contract.
3
- * The builtin is imported lazily inside `open()` — never at module
4
- * scope — so this module itself loads under any runtime; on a runtime
5
- * without `node:sqlite` the open fails with the coded `JD0003`.
6
- */
7
- /**
8
- * Adapt an already-constructed `node:sqlite` `DatabaseSync` (or any
9
- * object with its shape) into a probed connection. Exported so the
10
- * adapter is exercisable without the builtin.
11
- * @param {any} db - A `DatabaseSync`-shaped database
12
- * @param {{ queueTimeout?: number }} [options]
13
- * @returns {any} a Connection, or a promise of one
14
- */
15
- export declare function adaptNodeDatabase(db: any, options?: {
16
- queueTimeout?: number;
17
- }): any;
18
- /**
19
- * Construct and adapt the database from a loaded `node:sqlite` module.
20
- * The seam {@link nodeDriver} feeds through `lazyOpen`; exported so the
21
- * whole open path runs under any runtime with a substitute module.
22
- * @param {any} mod - The `node:sqlite` module (or a substitute)
23
- * @param {string} path
24
- * @param {{ timeout?: number, readOnly?: boolean,
25
- * queueTimeout?: number }} [options]
26
- * @returns {any}
27
- */
28
- export declare function fromNodeModule(mod: any, path: string, options?: {
29
- timeout?: number;
30
- readOnly?: boolean;
31
- queueTimeout?: number;
32
- }): any;
33
- /**
34
- * The Node driver: `{ name, dialect, open }` over `node:sqlite`.
35
- * @returns {any}
36
- */
37
- export declare function nodeDriver(): any;
@@ -1,65 +0,0 @@
1
- /**
2
- * @file The wasm binding: an INJECTED handle behind the driver
3
- * contract. This module imports no runtime builtin at all — the host
4
- * (a browser, a worker) supplies the SQLite build, and this driver
5
- * only adapts it. Every handle method may return a value or a promise;
6
- * a main-thread OPFS-backed build is asynchronous and that is exactly
7
- * why the public store surface is.
8
- *
9
- * The injected contract:
10
- *
11
- * handle = {
12
- * open(path, options) -> raw | Promise<raw>,
13
- * synchronous?: boolean, // default false
14
- * declares?: { userFunctions?, deterministicIndexableFunctions?,
15
- * sessions? } // default all false
16
- * }
17
- * raw = { exec(sql), prepare(sql) -> { run, get, all, iterate? },
18
- * close(), registerFunction?, registerAggregate?, session? }
19
- *
20
- * Capability truth still comes from the probe: whatever the handle
21
- * declares is intersected with what the loaded library actually
22
- * compiled in.
23
- */
24
- /**
25
- * Adapt an already-constructed `sqlite3.oo1` database (the official
26
- * SQLite wasm build's object API) into the raw contract. The oo1 API
27
- * is SYNCHRONOUS — wasm SQLite computes in place and the SAH-pool
28
- * OPFS VFS does synchronous I/O inside a dedicated worker — which is
29
- * exactly what keeps journal capture, live queries and the job queue
30
- * working unchanged in a browser.
31
- *
32
- * Statements are REUSED by the store's prepared caches: every
33
- * operation ends in `reset()`, never `finalize()`. oo1 user functions
34
- * receive a context pointer first — stripped here — and register
35
- * variadic (`arity: -1`), matching the engine's fragment shapes.
36
- * @param {any} sqlite3 - the loaded sqlite3 module (for `capi`)
37
- * @param {any} db - an `sqlite3.oo1.DB`-shaped database
38
- * @returns {any} the raw binding for {@link openConnection}
39
- */
40
- export declare function adaptOo1Database(sqlite3: any, db: any): any;
41
- /**
42
- * Build the injected HANDLE from a loaded sqlite3 module — the D6
43
- * recipe: the host loads the wasm build and picks the database class
44
- * (`sqlite3.oo1.DB` for `:memory:`, the SAH-pool util's `OpfsSAHPoolDb`
45
- * for OPFS persistence), and this package only adapts it.
46
- *
47
- * `sessions` is deliberately NOT declared even though the canonical
48
- * wasm build compiles `ENABLE_SESSION`: this adapter does not yet map
49
- * the session C API, so capture runs in the journal mode — stated in
50
- * the capability matrix, adapting it is a roadmap item.
51
- * @param {any} sqlite3 - the loaded sqlite3 module
52
- * @param {{ DbClass?: any }} [handleOptions] - the database class to
53
- * construct (default `sqlite3.oo1.DB`)
54
- * @returns {any} a handle for {@link wasmDriver}
55
- */
56
- export declare function sqlite3Handle(sqlite3: any, handleOptions?: {
57
- DbClass?: any;
58
- }): any;
59
- /**
60
- * The wasm driver over an injected handle.
61
- * @param {any} handle - The host-supplied SQLite handle (see the file
62
- * header for the contract)
63
- * @returns {any}
64
- */
65
- export declare function wasmDriver(handle: any): any;