@jarenjs/db 0.49.2 → 0.66.1
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/ARCHITECTURE.md +420 -71
- package/README.md +711 -79
- package/docs/HOSTS.md +269 -0
- package/docs/JOBS-FORMAT.md +309 -45
- package/docs/LIVE-FORMAT.md +156 -19
- package/docs/MIGRATION-FORMAT.md +247 -40
- package/docs/MODEL-FORMAT.md +968 -86
- package/package.json +21 -8
- package/schemas/jaren-migration.draft-07.schema.json +73 -0
- package/schemas/jaren-migration.schema.json +73 -0
- package/schemas/jaren-model.draft-07.schema.json +224 -162
- package/schemas/jaren-model.schema.json +224 -162
- package/src/algebra.js +227 -9
- package/src/backup.js +161 -0
- package/src/cancellation.js +48 -0
- package/src/capture.js +255 -44
- package/src/cli.js +337 -50
- package/src/cursor.js +411 -0
- package/src/dag-job.js +154 -21
- package/src/ddl.js +125 -11
- package/src/dialect.js +267 -112
- package/src/dialects/expression-read.js +158 -0
- package/src/dialects/postgres.js +618 -0
- package/src/dialects/rtree-ddl.js +129 -0
- package/src/dialects/sqlite.js +245 -12
- package/src/document-files.js +311 -0
- package/src/document-steps.js +422 -0
- package/src/documents.js +335 -0
- package/src/driver.js +503 -69
- package/src/drivers/bun.js +37 -1
- package/src/drivers/indexeddb-snapshot.js +149 -0
- package/src/drivers/node-pool.js +11 -0
- package/src/drivers/node-worker-endpoint.js +105 -0
- package/src/drivers/node-worker.js +204 -0
- package/src/drivers/node.js +41 -7
- package/src/drivers/postgres.js +331 -0
- package/src/drivers/wasm-oo1.js +97 -0
- package/src/drivers/wasm-session.js +67 -0
- package/src/drivers/wasm.js +18 -83
- package/src/drivers/worker-pool.js +183 -0
- package/src/drivers/worker-protocol.js +79 -0
- package/src/drivers/worker-queue.js +60 -0
- package/src/emit-model.js +14 -0
- package/src/emit.js +349 -51
- package/src/entity.js +102 -59
- package/src/errors.js +430 -2
- package/src/expression.js +284 -0
- package/src/graph.js +64 -8
- package/src/index.js +48 -19
- package/src/introspect.js +583 -0
- package/src/jobs.js +870 -99
- package/src/json-bytes.js +58 -0
- package/src/live-time.js +12 -3
- package/src/live.js +11 -1
- package/src/maintenance.js +175 -0
- package/src/migrate.js +606 -333
- package/src/model.js +241 -8
- package/src/plan.js +1238 -160
- package/src/pragmas.js +314 -0
- package/src/profile.js +151 -3
- package/src/query.js +1748 -312
- package/src/residual.js +17 -0
- package/src/series.js +12 -4
- package/src/store.js +1672 -276
- package/src/tracker.js +367 -68
- package/src/udf.js +88 -7
- package/types/index.d.ts +1246 -32
- package/types/node-pool.d.ts +28 -0
- package/types/node-worker.d.ts +54 -0
- package/types/node.d.ts +72 -3
- package/types/postgres.d.ts +46 -0
- package/types/typed.d.ts +81 -3
- package/types/wasm.d.ts +21 -0
- package/dist/types/algebra.d.ts +0 -230
- package/dist/types/app.d.ts +0 -49
- package/dist/types/capture.d.ts +0 -85
- package/dist/types/cli.d.ts +0 -2
- package/dist/types/dag-job.d.ts +0 -40
- package/dist/types/ddl.d.ts +0 -229
- package/dist/types/derive.d.ts +0 -250
- package/dist/types/dialect.d.ts +0 -154
- package/dist/types/dialects/sqlite.d.ts +0 -9
- package/dist/types/driver.d.ts +0 -110
- package/dist/types/drivers/bun.d.ts +0 -47
- package/dist/types/drivers/node.d.ts +0 -37
- package/dist/types/drivers/wasm.d.ts +0 -65
- package/dist/types/emit-model.d.ts +0 -44
- package/dist/types/emit.d.ts +0 -75
- package/dist/types/entity.d.ts +0 -23
- package/dist/types/errors.d.ts +0 -170
- package/dist/types/graph.d.ts +0 -28
- package/dist/types/index.d.ts +0 -37
- package/dist/types/jobs.d.ts +0 -140
- package/dist/types/knn.d.ts +0 -69
- package/dist/types/live-time.d.ts +0 -141
- package/dist/types/live.d.ts +0 -64
- package/dist/types/migrate.d.ts +0 -170
- package/dist/types/model.d.ts +0 -36
- package/dist/types/patch-sql.d.ts +0 -37
- package/dist/types/plan.d.ts +0 -142
- package/dist/types/profile.d.ts +0 -80
- package/dist/types/query.d.ts +0 -112
- package/dist/types/residual.d.ts +0 -64
- package/dist/types/series.d.ts +0 -227
- package/dist/types/store.d.ts +0 -60
- package/dist/types/tracker.d.ts +0 -43
- package/dist/types/typed.d.ts +0 -15
- package/dist/types/types.d.ts +0 -26
- package/dist/types/udf.d.ts +0 -75
- package/dist/types/window.d.ts +0 -52
package/dist/types/capture.d.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Change capture (D13): committed writes become an observable,
|
|
3
|
-
* ordered stream of RFC 6902 patches — derived from SQLite's own
|
|
4
|
-
* session changesets where the binding has them, from a write-path
|
|
5
|
-
* journal where it does not (`bun:sqlite` has no `createSession`), or
|
|
6
|
-
* off entirely. One diff format then runs end to end: store → patch →
|
|
7
|
-
* live query → patch → O(k) render.
|
|
8
|
-
*
|
|
9
|
-
* The pointer contract (LIVE-FORMAT §2): `/<table>/<key>/<path…>`,
|
|
10
|
-
* every token escaped per RFC 6901. A single key renders as its
|
|
11
|
-
* scalar text (integers in decimal); a composite key renders as the
|
|
12
|
-
* JSON text of its parts array. Join-table rows are tiny documents
|
|
13
|
-
* under the join table's name — membership changes are part of the
|
|
14
|
-
* stream, not a blind spot.
|
|
15
|
-
*
|
|
16
|
-
* Session facts this file is built on (probed, 3.51.2):
|
|
17
|
-
* - a changeset carries ONE NET OP PER ROW (insert+update coalesce;
|
|
18
|
-
* insert+delete vanish; a no-op update is absent), and within-table
|
|
19
|
-
* order is NOT statement order — every row op targets a distinct
|
|
20
|
-
* pointer, so application order across rows cannot matter;
|
|
21
|
-
* - `ROLLBACK TO` a savepoint removes the undone rows from the
|
|
22
|
-
* session (pinned by test — the classic caveat does NOT hold here);
|
|
23
|
-
* - a rolled-back transaction yields an empty changeset;
|
|
24
|
-
* - virtual generated columns are invisible;
|
|
25
|
-
* - an UPDATE's old record carries the primary key and the CHANGED
|
|
26
|
-
* columns only — which is exactly enough for property-level ops,
|
|
27
|
-
* and why the doc column's old/new blobs make a minimal nested
|
|
28
|
-
* diff possible (`SELECT json(?)` turns JSONB back into text).
|
|
29
|
-
*/
|
|
30
|
-
/** The persisted change log (LIVE-FORMAT §5). */
|
|
31
|
-
export declare const CHANGES_TABLE = "_jaren_changes";
|
|
32
|
-
export declare const DEFAULT_RETENTION = 1000;
|
|
33
|
-
/**
|
|
34
|
-
* Decode a binary changeset into row operations.
|
|
35
|
-
* @param {Uint8Array} bytes
|
|
36
|
-
* @returns {{ table: string, pk: boolean[], op: 'insert'|'update'|'delete',
|
|
37
|
-
* indirect: boolean, oldValues: any[] | null, newValues: any[] | null }[]}
|
|
38
|
-
*/
|
|
39
|
-
export declare function parseChangeset(bytes: Uint8Array): {
|
|
40
|
-
table: string;
|
|
41
|
-
pk: boolean[];
|
|
42
|
-
op: 'insert' | 'update' | 'delete';
|
|
43
|
-
indirect: boolean;
|
|
44
|
-
oldValues: any[] | null;
|
|
45
|
-
newValues: any[] | null;
|
|
46
|
-
}[];
|
|
47
|
-
/**
|
|
48
|
-
* The key token (LIVE-FORMAT §2): a single key is its scalar text;
|
|
49
|
-
* a composite key is the JSON text of its parts array.
|
|
50
|
-
* @param {any[]} parts
|
|
51
|
-
* @returns {string}
|
|
52
|
-
*/
|
|
53
|
-
export declare function keyToken(parts: any[]): string;
|
|
54
|
-
export type TableShape = {
|
|
55
|
-
kind: 'collection' | 'entity' | 'join';
|
|
56
|
-
columns: {
|
|
57
|
-
name: string;
|
|
58
|
-
role: 'key' | 'doc' | 'scalar' | 'fk' | 'epoch';
|
|
59
|
-
storage?: string;
|
|
60
|
-
}[];
|
|
61
|
-
keyIndexes: number[];
|
|
62
|
-
docIndex: number;
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* Translate parsed row operations into RFC 6902 ops, resolving JSONB
|
|
66
|
-
* blobs through the connection (`SELECT json(?)`).
|
|
67
|
-
* @param {any} connection
|
|
68
|
-
* @param {Map<string, TableShape>} shapes
|
|
69
|
-
* @param {any[]} operations
|
|
70
|
-
* @returns {any} value-or-promise of RFC 6902 ops
|
|
71
|
-
*/
|
|
72
|
-
export declare function translateOperations(connection: any, shapes: Map<string, TableShape>, operations: any[]): any;
|
|
73
|
-
/**
|
|
74
|
-
* @param {{ connection: any, shapes: Map<string, TableShape>,
|
|
75
|
-
* mode: 'session' | 'journal',
|
|
76
|
-
* log: boolean, retention: number }} options
|
|
77
|
-
* @returns {any}
|
|
78
|
-
*/
|
|
79
|
-
export declare function createCaptureEngine(options: {
|
|
80
|
-
connection: any;
|
|
81
|
-
shapes: Map<string, TableShape>;
|
|
82
|
-
mode: 'session' | 'journal';
|
|
83
|
-
log: boolean;
|
|
84
|
-
retention: number;
|
|
85
|
-
}): any;
|
package/dist/types/cli.d.ts
DELETED
package/dist/types/dag-job.d.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file The composition (JOBS-FORMAT §7): a persisted `@jarenjs/flow`
|
|
3
|
-
* DAG run wired to a queue job. THE FLOW ENGINE IS INJECTED, NEVER
|
|
4
|
-
* IMPORTED — the shared invariant forbids `@jarenjs/db` importing
|
|
5
|
-
* `@jarenjs/flow`, so `compileDag` arrives as a capability (the D10
|
|
6
|
-
* shape applied to flow) and a test asserts the manifest and import
|
|
7
|
-
* graph name flow nowhere.
|
|
8
|
-
*
|
|
9
|
-
* Each kind's document compiles ONCE against a delegating checkpoint
|
|
10
|
-
* store; per claimed job, the delegate binds the engine's guarded
|
|
11
|
-
* per-job store (`checkpointsFor`) — `save` refuses once the lease is
|
|
12
|
-
* lost and `complete` records the DAG result, marks the job done and
|
|
13
|
-
* prunes the checkpoint rows in ONE transaction, so a failure leaves
|
|
14
|
-
* neither and a crash resumes instead of restarting.
|
|
15
|
-
*/
|
|
16
|
-
/**
|
|
17
|
-
* Build a worker whose handlers run checkpointed DAG documents.
|
|
18
|
-
* @param {any} store - an open store with `{ jobs: true }`
|
|
19
|
-
* @param {{ compileDag: Function,
|
|
20
|
-
* documents: Record<string, any>,
|
|
21
|
-
* tasks?: Record<string, Function>,
|
|
22
|
-
* concurrency?: number, pollInterval?: number, leaseMs?: number,
|
|
23
|
-
* owner?: string, backoffBase?: number, backoffCap?: number }} options
|
|
24
|
-
* @returns {{ start: () => any, stop: () => Promise<void>, stats: () => any }}
|
|
25
|
-
*/
|
|
26
|
-
export declare function createDagJobRunner(store: any, options: {
|
|
27
|
-
compileDag: Function;
|
|
28
|
-
documents: Record<string, any>;
|
|
29
|
-
tasks?: Record<string, Function>;
|
|
30
|
-
concurrency?: number;
|
|
31
|
-
pollInterval?: number;
|
|
32
|
-
leaseMs?: number;
|
|
33
|
-
owner?: string;
|
|
34
|
-
backoffBase?: number;
|
|
35
|
-
backoffCap?: number;
|
|
36
|
-
}): {
|
|
37
|
-
start: () => any;
|
|
38
|
-
stop: () => Promise<void>;
|
|
39
|
-
stats: () => any;
|
|
40
|
-
};
|
package/dist/types/ddl.d.ts
DELETED
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file DDL planning: a normalized collection becomes one physical
|
|
3
|
-
* table — a key column, a JSON document column, a virtual generated
|
|
4
|
-
* column per indexed path, and the declared indexes — with every byte
|
|
5
|
-
* of SQL rendered by the dialect.
|
|
6
|
-
*
|
|
7
|
-
* Index paths are JSONPath expressions analyzed through the engine's
|
|
8
|
-
* PUBLISHED AST (`analyzeQuery`): a path is indexable exactly when the
|
|
9
|
-
* analysis says it is singular and every segment is a plain member or
|
|
10
|
-
* index selection. That reuses the one grammar authority instead of
|
|
11
|
-
* re-parsing, and it fails loudly (`JD0004`) on everything else —
|
|
12
|
-
* wildcards, slices, filters, descendants, functions — rather than
|
|
13
|
-
* silently indexing the wrong thing.
|
|
14
|
-
*/
|
|
15
|
-
/** The fixed physical column names of the 0.1 mapping. */
|
|
16
|
-
export declare const KEY_COLUMN = "key";
|
|
17
|
-
export declare const DOC_COLUMN = "doc";
|
|
18
|
-
/**
|
|
19
|
-
* Analyze one index path expression down to typed segments.
|
|
20
|
-
* @param {string} expression - A JSONPath expression (`$.email`)
|
|
21
|
-
* @param {string} docPath - Model-document pointer for diagnostics
|
|
22
|
-
* @returns {{ segments: import('./dialect.js').JsonPathSegment[],
|
|
23
|
-
* canonical: string }}
|
|
24
|
-
*/
|
|
25
|
-
export declare function compileIndexPath(expression: string, docPath: string): {
|
|
26
|
-
segments: import('./dialect.js').JsonPathSegment[];
|
|
27
|
-
canonical: string;
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* The schema subschema at a segment path, walked structurally through
|
|
31
|
-
* `properties` / `items` / `prefixItems`. The collection's schema is
|
|
32
|
-
* the type source — that is why the physical mapping needs no
|
|
33
|
-
* engine-side inference. `undefined` where the walk leaves the schema.
|
|
34
|
-
* @param {any} schema
|
|
35
|
-
* @param {import('./dialect.js').JsonPathSegment[]} segments
|
|
36
|
-
* @returns {any}
|
|
37
|
-
*/
|
|
38
|
-
export declare function schemaNodeAt(schema: any, segments: import('./dialect.js').JsonPathSegment[]): any;
|
|
39
|
-
/**
|
|
40
|
-
* The declared schema type at a segment path: the first non-`null`
|
|
41
|
-
* member of a union, which is the type a COLUMN takes its storage
|
|
42
|
-
* from. A caller that must know the whole union (a promotion refusing
|
|
43
|
-
* a member that may also be `null`) reads {@link schemaNodeAt}.
|
|
44
|
-
* @param {any} schema
|
|
45
|
-
* @param {import('./dialect.js').JsonPathSegment[]} segments
|
|
46
|
-
* @returns {string | undefined}
|
|
47
|
-
*/
|
|
48
|
-
export declare function schemaTypeAt(schema: any, segments: import('./dialect.js').JsonPathSegment[]): string | undefined;
|
|
49
|
-
/**
|
|
50
|
-
* Plan one collection's physical shape: the DDL statements to create
|
|
51
|
-
* it and the structural facts an existing table must match (the
|
|
52
|
-
* `JD0002` comparison set).
|
|
53
|
-
* A derived index (`derive: 'geohash' | 'bbox'`) maps to the same
|
|
54
|
-
* shape through a registered deterministic function, EXCEPT where the
|
|
55
|
-
* driver cannot index one (`capabilities.deterministicIndexableFunctions`
|
|
56
|
-
* is false): there the columns are ordinary ones the store writes. The
|
|
57
|
-
* two mappings produce different declared text on purpose — a database
|
|
58
|
-
* built under one and opened under the other really does disagree, and
|
|
59
|
-
* `verifyShape` says so rather than papering over it. A
|
|
60
|
-
* `derive: 'vector'` column is the stored shape under BOTH mappings
|
|
61
|
-
* (`derivedMappingFor`), so for it the two agree.
|
|
62
|
-
* @param {string} name - The collection name (also the table name)
|
|
63
|
-
* @param {{ schema: any, keySegments: { name: string }[] | null,
|
|
64
|
-
* identity: string, indexes: { name: string, paths: string[],
|
|
65
|
-
* unique: boolean, derive?: string | null, precision?: number,
|
|
66
|
-
* dims?: number, docPath: string }[] }} collection - normalized
|
|
67
|
-
* @param {any} dialect
|
|
68
|
-
* @param {{ derived?: 'virtual' | 'stored', rtree?: boolean }} [options]
|
|
69
|
-
* - `derived` is the physical mapping for derived columns:
|
|
70
|
-
* `'virtual'` (a generated column over a registered function) unless
|
|
71
|
-
* the driver says it cannot index one. `rtree` is whether the driver
|
|
72
|
-
* carries the R\*Tree module; when it does not, a column set that
|
|
73
|
-
* declared `physical: 'rtree'` falls back to the B-tree over its
|
|
74
|
-
* columns and `explain().prefilters[].via` reports which shape ran
|
|
75
|
-
* (MODEL-FORMAT §4) — a report, not a silent degradation
|
|
76
|
-
* @returns {{
|
|
77
|
-
* table: string, keyColumn: string, docColumn: string,
|
|
78
|
-
* keyType: string,
|
|
79
|
-
* generated: { name: string, type: string, pathText: string,
|
|
80
|
-
* canonical: string }[],
|
|
81
|
-
* derived: { name: string, derive: string, precision?: number,
|
|
82
|
-
* component?: string, dims?: number, segments: any[] }[],
|
|
83
|
-
* columnByCanonical: Map<string, string>,
|
|
84
|
-
* createSql: string[],
|
|
85
|
-
* virtualTables: { stem: string, name: string, columns: string[],
|
|
86
|
-
* edges: string[], createSql: string, fillSql: string,
|
|
87
|
-
* triggers: { name: string, sql: string }[] }[],
|
|
88
|
-
* expected: { columns: { name: string, type: string,
|
|
89
|
-
* generated: boolean }[], indexes: { name: string, unique: boolean,
|
|
90
|
-
* columns: string[] }[] },
|
|
91
|
-
* }}
|
|
92
|
-
*/
|
|
93
|
-
export declare function planCollection(name: string, collection: {
|
|
94
|
-
schema: any;
|
|
95
|
-
keySegments: {
|
|
96
|
-
name: string;
|
|
97
|
-
}[] | null;
|
|
98
|
-
identity: string;
|
|
99
|
-
indexes: {
|
|
100
|
-
name: string;
|
|
101
|
-
paths: string[];
|
|
102
|
-
unique: boolean;
|
|
103
|
-
derive?: string | null;
|
|
104
|
-
precision?: number;
|
|
105
|
-
dims?: number;
|
|
106
|
-
docPath: string;
|
|
107
|
-
}[];
|
|
108
|
-
}, dialect: any, options?: {
|
|
109
|
-
derived?: 'virtual' | 'stored';
|
|
110
|
-
rtree?: boolean;
|
|
111
|
-
}): {
|
|
112
|
-
table: string;
|
|
113
|
-
keyColumn: string;
|
|
114
|
-
docColumn: string;
|
|
115
|
-
keyType: string;
|
|
116
|
-
generated: {
|
|
117
|
-
name: string;
|
|
118
|
-
type: string;
|
|
119
|
-
pathText: string;
|
|
120
|
-
canonical: string;
|
|
121
|
-
}[];
|
|
122
|
-
derived: {
|
|
123
|
-
name: string;
|
|
124
|
-
derive: string;
|
|
125
|
-
precision?: number;
|
|
126
|
-
component?: string;
|
|
127
|
-
dims?: number;
|
|
128
|
-
segments: any[];
|
|
129
|
-
}[];
|
|
130
|
-
columnByCanonical: Map<string, string>;
|
|
131
|
-
createSql: string[];
|
|
132
|
-
virtualTables: {
|
|
133
|
-
stem: string;
|
|
134
|
-
name: string;
|
|
135
|
-
columns: string[];
|
|
136
|
-
edges: string[];
|
|
137
|
-
createSql: string;
|
|
138
|
-
fillSql: string;
|
|
139
|
-
triggers: {
|
|
140
|
-
name: string;
|
|
141
|
-
sql: string;
|
|
142
|
-
}[];
|
|
143
|
-
}[];
|
|
144
|
-
expected: {
|
|
145
|
-
columns: {
|
|
146
|
-
name: string;
|
|
147
|
-
type: string;
|
|
148
|
-
generated: boolean;
|
|
149
|
-
}[];
|
|
150
|
-
indexes: {
|
|
151
|
-
name: string;
|
|
152
|
-
unique: boolean;
|
|
153
|
-
columns: string[];
|
|
154
|
-
}[];
|
|
155
|
-
};
|
|
156
|
-
};
|
|
157
|
-
/**
|
|
158
|
-
* Normalize a stored `CREATE` statement for comparison: collapse runs of
|
|
159
|
-
* whitespace, drop whitespace around punctuation, and strip the
|
|
160
|
-
* `IF NOT EXISTS` SQLite does not keep. What survives is every token that
|
|
161
|
-
* carries meaning, so two statements compare equal exactly when they
|
|
162
|
-
* declare the same physical object.
|
|
163
|
-
* @param {string} sql
|
|
164
|
-
* @returns {string}
|
|
165
|
-
*/
|
|
166
|
-
export declare function normalizeDeclaredSql(sql: string): string;
|
|
167
|
-
/**
|
|
168
|
-
* A comparable form of one `CREATE` statement.
|
|
169
|
-
*
|
|
170
|
-
* For a TABLE the column definitions compare as a SET, because
|
|
171
|
-
* `ALTER TABLE … ADD COLUMN` can only append — so a migrated table and a
|
|
172
|
-
* freshly built one legitimately differ in column order, and this store
|
|
173
|
-
* never reads a column positionally. Everything else is exact: each
|
|
174
|
-
* column's full definition (type, `PRIMARY KEY`, `NOT NULL`, `DEFAULT`,
|
|
175
|
-
* `CHECK`, `GENERATED … AS`, `REFERENCES … ON DELETE …`), the table
|
|
176
|
-
* constraints, and the trailing table options (`STRICT`,
|
|
177
|
-
* `WITHOUT ROWID`).
|
|
178
|
-
*
|
|
179
|
-
* For an INDEX the text compares whole, because an index IS its order —
|
|
180
|
-
* `(a,b)` and `(b,a)` serve different lookups — as are its partial
|
|
181
|
-
* predicate and each term's collation and direction.
|
|
182
|
-
* @param {string} sql
|
|
183
|
-
* @returns {string}
|
|
184
|
-
*/
|
|
185
|
-
export declare function comparableDeclaredSql(sql: string): string;
|
|
186
|
-
/**
|
|
187
|
-
* Verify an existing table against the planned shape; any difference
|
|
188
|
-
* is `JD0002` and nothing is altered. Shared by the store's open path
|
|
189
|
-
* and the migration engine's shadow validation.
|
|
190
|
-
* @param {any} connection
|
|
191
|
-
* @param {any} plan
|
|
192
|
-
* @param {string} collection
|
|
193
|
-
* @param {string} docPath
|
|
194
|
-
* @returns {any} value-or-promise
|
|
195
|
-
*/
|
|
196
|
-
export declare function verifyShape(connection: any, plan: any, collection: string, docPath: string): any;
|
|
197
|
-
/**
|
|
198
|
-
* Plan one ENTITY's physical shape from the mapping data
|
|
199
|
-
* `explainMapping` derived: the relational table (typed columns,
|
|
200
|
-
* checks, foreign keys, the JSONB document column), its indexes, and
|
|
201
|
-
* the structural facts an existing table must match. One verify path
|
|
202
|
-
* serves both document kinds.
|
|
203
|
-
* @param {string} name
|
|
204
|
-
* @param {any} entityMapping - `explainMapping(model).entities[name]`
|
|
205
|
-
* @param {any} entities - the full `explainMapping` result (key types
|
|
206
|
-
* come from the referenced entity's columns)
|
|
207
|
-
* @param {any} dialect
|
|
208
|
-
* @returns {{ table: string, createSql: string[], expected: any,
|
|
209
|
-
* columnNames: Set<string> }}
|
|
210
|
-
*/
|
|
211
|
-
export declare function planEntity(name: string, entityMapping: any, entities: any, dialect: any): {
|
|
212
|
-
table: string;
|
|
213
|
-
createSql: string[];
|
|
214
|
-
expected: any;
|
|
215
|
-
columnNames: Set<string>;
|
|
216
|
-
};
|
|
217
|
-
/**
|
|
218
|
-
* Plan a many-to-many join table.
|
|
219
|
-
* @param {string} tableName
|
|
220
|
-
* @param {any} join - `explainMapping(model).joinTables[tableName]`
|
|
221
|
-
* @param {any} entities - the full mapping
|
|
222
|
-
* @param {any} dialect
|
|
223
|
-
* @returns {{ table: string, createSql: string[], expected: any }}
|
|
224
|
-
*/
|
|
225
|
-
export declare function planJoinTable(tableName: string, join: any, entities: any, dialect: any): {
|
|
226
|
-
table: string;
|
|
227
|
-
createSql: string[];
|
|
228
|
-
expected: any;
|
|
229
|
-
};
|
package/dist/types/derive.d.ts
DELETED
|
@@ -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;
|