@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/errors.d.ts
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Error types for @jarenjs/db, built on `@jarenjs/core`'s coded
|
|
3
|
-
* contract: every failure carries a stable `code` (JD0xxx compile-time,
|
|
4
|
-
* JD2xxx runtime), a bare `reason`, a composed `message`, and — where a
|
|
5
|
-
* position in the model document exists — a `docPath`. Runtime errors
|
|
6
|
-
* additionally carry the `collection` and, where one exists, the `key`
|
|
7
|
-
* as own properties. Database errors are wrapped, never leaked raw: the
|
|
8
|
-
* reason keeps the original text, `cause` keeps the original error. The
|
|
9
|
-
* normative table lives in docs/MODEL-FORMAT.md §7, proven in sync with
|
|
10
|
-
* `DB_CODES` below by a test.
|
|
11
|
-
*/
|
|
12
|
-
import { CodedError } from '@jarenjs/core/errors';
|
|
13
|
-
/**
|
|
14
|
-
* The runtime code table (the `CSV_CODES` shape): one entry per code
|
|
15
|
-
* this package can raise, proven in sync with MODEL-FORMAT.md §7's
|
|
16
|
-
* normative table by a test.
|
|
17
|
-
*/
|
|
18
|
-
export declare const DB_CODES: Readonly<{
|
|
19
|
-
JD0001: "the SQLite library is below the supported floor";
|
|
20
|
-
JD0002: "the declared model disagrees with the existing database";
|
|
21
|
-
JD0003: "the driver binding is unavailable on this runtime";
|
|
22
|
-
JD0004: "a declared index cannot be mapped to a column";
|
|
23
|
-
JD0005: "the model document is invalid";
|
|
24
|
-
JD0010: "strict mode refused a residual";
|
|
25
|
-
JD0011: "the profile refused the document";
|
|
26
|
-
JD0012: "work waited too long for the open transaction to settle";
|
|
27
|
-
JD0030: "an unknown x-entity member was declared";
|
|
28
|
-
JD0031: "relation declarations contradict each other";
|
|
29
|
-
JD0032: "the include specification is invalid";
|
|
30
|
-
JD0040: "the save spans a relation cycle";
|
|
31
|
-
JD0050: "live queries require change capture";
|
|
32
|
-
JD0051: "the demanded live mode is unavailable";
|
|
33
|
-
JD0052: "the live-query bound was reached";
|
|
34
|
-
JD0053: "the live event-time declaration is invalid";
|
|
35
|
-
JD0020: "the migration's from-shape does not match the database";
|
|
36
|
-
JD0021: "the migration is missing a required data transform";
|
|
37
|
-
JD0022: "an applied migration disagrees with the history record";
|
|
38
|
-
JD0023: "a migration step failed";
|
|
39
|
-
JD2001: "insert found the key already present";
|
|
40
|
-
JD2002: "a usable key could not be resolved for the write";
|
|
41
|
-
JD2003: "the write failed schema validation";
|
|
42
|
-
JD2004: "an undeclared collection was requested";
|
|
43
|
-
JD2005: "a database operation failed";
|
|
44
|
-
JD2006: "patch found no document at the key";
|
|
45
|
-
JD2007: "the result exceeded the profile row bound";
|
|
46
|
-
JD2040: "the row changed under an optimistic update";
|
|
47
|
-
JD2050: "a changeset could not be decoded";
|
|
48
|
-
JD2051: "the change log is not enabled";
|
|
49
|
-
JD2060: "the maintained live state exceeded its bound";
|
|
50
|
-
JD2061: "another context owns the database";
|
|
51
|
-
JD2062: "the store closed with job handlers still in flight";
|
|
52
|
-
}>;
|
|
53
|
-
/**
|
|
54
|
-
* A defect found while opening a store — in the model document, the
|
|
55
|
-
* declared indexes, the driver binding, or the database's agreement
|
|
56
|
-
* with the declaration. Codes:
|
|
57
|
-
*
|
|
58
|
-
* - `JD0001` — the SQLite library reported a version below the
|
|
59
|
-
* supported floor; the reason names the version found
|
|
60
|
-
* - `JD0002` — a declared collection already exists in the database
|
|
61
|
-
* with a different shape; nothing was altered — changing shape is
|
|
62
|
-
* the migration story, a later capability
|
|
63
|
-
* - `JD0003` — the runtime builtin behind a driver could not be
|
|
64
|
-
* loaded here (Node cannot resolve `bun:`; Bun ships no
|
|
65
|
-
* `node:sqlite`), or an injected handle is missing
|
|
66
|
-
* - `JD0004` — a declared index cannot be mapped to a column: its
|
|
67
|
-
* path does not select exactly one member (wildcards, slices,
|
|
68
|
-
* filters and descendants are not indexable), or its `derive`
|
|
69
|
-
* declaration is not one the storage vocabulary carries; the reason
|
|
70
|
-
* names the expression or the member and `docPath` points at it
|
|
71
|
-
* - `JD0005` — the model document is invalid; `docPath` points at
|
|
72
|
-
* the offending member
|
|
73
|
-
* - `JD0010` — `strict: true` and part of the query would have run
|
|
74
|
-
* outside the database; the reason names the forcing construct
|
|
75
|
-
* - `JD0011` — the active profile refused the document before any
|
|
76
|
-
* execution: an undeclared external, host function, collation or
|
|
77
|
-
* collection, or a refused full-table scan; the reason names it
|
|
78
|
-
* - `JD0030` — an unknown member inside an `x-entity` block; a
|
|
79
|
-
* silently ignored mapping directive is a data-loss bug waiting
|
|
80
|
-
* - `JD0031` — two relation declarations whose inverses contradict
|
|
81
|
-
* (different `via`, impossible `many` pairings)
|
|
82
|
-
* - `JD0032` — a graph-load include specification is invalid: an
|
|
83
|
-
* unknown relation, a cycle, an untranslatable filter, or the
|
|
84
|
-
* depth bound exceeded (the bound is printed, never silent)
|
|
85
|
-
* - `JD0040` — `saveChanges()` cannot order its statements: the
|
|
86
|
-
* entities being inserted or deleted form a foreign-key cycle
|
|
87
|
-
* (self-references included); break the save in two
|
|
88
|
-
* - `JD0050` — a live query was registered on a store opened without
|
|
89
|
-
* `capture`; the patch stream is the invalidation source
|
|
90
|
-
* - `JD0051` — `mode: 'incremental'` was demanded but the document
|
|
91
|
-
* classifies as re-run; the reason names the forcing construct
|
|
92
|
-
* - `JD0052` — registering would exceed the store's `live.maxQueries`
|
|
93
|
-
* bound; the bound is printed, never silent
|
|
94
|
-
* - `JD0053` — a live query's `eventTime` names a member it does not
|
|
95
|
-
* admit, or a watermark/retention that is not a finite span
|
|
96
|
-
* - `JD0020` — a migration's `from` hash does not match the
|
|
97
|
-
* database's recorded shape; running it would corrupt
|
|
98
|
-
* - `JD0021` — a draft transform was not filled in, or a document no
|
|
99
|
-
* longer validates after the migration (a narrowing without an
|
|
100
|
-
* adequate transform)
|
|
101
|
-
* - `JD0022` — the migration list disagrees with the applied history
|
|
102
|
-
* (an edited file, a missing file, a reordered sequence)
|
|
103
|
-
* - `JD0023` — a step failed: an assertion returned rows, DDL was
|
|
104
|
-
* rejected, or a transform produced an unstorable value
|
|
105
|
-
*/
|
|
106
|
-
export declare class DbCompileError extends CodedError {
|
|
107
|
-
/**
|
|
108
|
-
* @param {string} code
|
|
109
|
-
* @param {string} reason - The bare reason; `message` is composed per
|
|
110
|
-
* the coded contract.
|
|
111
|
-
* @param {string} [docPath] - JSON Pointer into the model document,
|
|
112
|
-
* where one exists.
|
|
113
|
-
* @param {Error} [cause]
|
|
114
|
-
*/
|
|
115
|
-
constructor(code: string, reason: string, docPath?: string, cause?: Error);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* A failure while reading or writing an open store. Codes:
|
|
119
|
-
*
|
|
120
|
-
* - `JD2001` — `insert` hit a document already stored under the key
|
|
121
|
-
* - `JD2002` — the declared key pointer resolved to nothing or to a
|
|
122
|
-
* non-scalar, or an explicit key argument is not a string or number
|
|
123
|
-
* - `JD2003` — the injected validation hook rejected the document
|
|
124
|
-
* that a write would have stored; `errors` carries the hook's
|
|
125
|
-
* findings when it produced any
|
|
126
|
-
* - `JD2004` — `collection()` named a collection the model does not
|
|
127
|
-
* declare
|
|
128
|
-
* - `JD2005` — the database rejected an operation for a reason that
|
|
129
|
-
* is not a duplicate key; the original error is the `cause`
|
|
130
|
-
* - `JD2006` — `patch` addressed a key with no stored document
|
|
131
|
-
* - `JD2007` — a fetch crossed the profile's `maxRows` bound; the
|
|
132
|
-
* result is refused whole, never silently truncated
|
|
133
|
-
* - `JD2040` — an optimistic update or delete matched no row: the
|
|
134
|
-
* declared version changed under the save (or the row is gone);
|
|
135
|
-
* the error names the entity and key, and the whole save rolled
|
|
136
|
-
* back
|
|
137
|
-
* - `JD2050` — a session changeset carried bytes this decoder does
|
|
138
|
-
* not recognise (a future SQLite format change would land here)
|
|
139
|
-
* - `JD2051` — `changesSince` was called on a store whose capture
|
|
140
|
-
* has no persisted log
|
|
141
|
-
* - `JD2060` — maintenance crossed the live query's `maxMaintained`
|
|
142
|
-
* bound; the query delivered this error and closed rather than
|
|
143
|
-
* degrade
|
|
144
|
-
* - `JD2061` — a second context tried to open a database whose
|
|
145
|
-
* storage grants one context exclusive access (the owner topology
|
|
146
|
-
* of LIVE-FORMAT §11); connect to the owner instead
|
|
147
|
-
*/
|
|
148
|
-
export declare class DbRuntimeError extends CodedError {
|
|
149
|
-
collection: string | undefined;
|
|
150
|
-
key: string | number | undefined;
|
|
151
|
-
errors: unknown[] | undefined;
|
|
152
|
-
/**
|
|
153
|
-
* @param {string} code
|
|
154
|
-
* @param {string} reason - The bare reason; `message` is composed per
|
|
155
|
-
* the coded contract.
|
|
156
|
-
* @param {{ docPath?: string, collection?: string,
|
|
157
|
-
* key?: string | number, errors?: unknown[], cause?: unknown }} [details]
|
|
158
|
-
* - `docPath` points into the model document (the collection the
|
|
159
|
-
* failure belongs to); `collection`/`key` are installed as own
|
|
160
|
-
* properties; `errors` carries validation findings; `cause` follows
|
|
161
|
-
* the coded contract's `hasOwn` form.
|
|
162
|
-
*/
|
|
163
|
-
constructor(code: string, reason: string, details?: {
|
|
164
|
-
docPath?: string;
|
|
165
|
-
collection?: string;
|
|
166
|
-
key?: string | number;
|
|
167
|
-
errors?: unknown[];
|
|
168
|
-
cause?: unknown;
|
|
169
|
-
});
|
|
170
|
-
}
|
package/dist/types/graph.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Row → entity-graph reconstruction. One place owns the merge
|
|
3
|
-
* discipline (§9.3): mapped scalar columns fold back into the JSONB
|
|
4
|
-
* document's parse (booleans un-integer, SQL NULL reads back ABSENT,
|
|
5
|
-
* derived epoch columns are skipped because the string never left the
|
|
6
|
-
* document), foreign-key columns fold in the same way, and — for the
|
|
7
|
-
* one-statement graph loads — projected relation JSON parses
|
|
8
|
-
* recursively into child arrays or single children.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Merge one database row back into its entity document.
|
|
12
|
-
* @param {any} entityMapping - `explainMapping(...).entities[name]`
|
|
13
|
-
* @param {any} row - a row carrying the entity's columns plus the
|
|
14
|
-
* rendered document text
|
|
15
|
-
* @param {string} [docField] - the column the document text rides in
|
|
16
|
-
* @returns {any}
|
|
17
|
-
*/
|
|
18
|
-
export declare function mergeEntityRow(entityMapping: any, row: any, docField?: string): any;
|
|
19
|
-
/**
|
|
20
|
-
* Parse one graph-load row: the root entity's merge plus every
|
|
21
|
-
* included relation's projected JSON, recursively.
|
|
22
|
-
* @param {any} node - the include-plan node
|
|
23
|
-
* `{ entityMapping, includes: { name, field, many, count, child }[] }`
|
|
24
|
-
* @param {any} row
|
|
25
|
-
* @param {string} docField
|
|
26
|
-
* @returns {any}
|
|
27
|
-
*/
|
|
28
|
-
export declare function parseGraphRow(node: any, row: any, docField?: string): any;
|
package/dist/types/index.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file @jarenjs/db — document storage over SQLite through two seams:
|
|
3
|
-
* a driver (how a connection is made: `@jarenjs/db/node`, `/bun`, or
|
|
4
|
-
* `/wasm` with an injected handle) and a dialect (how SQL is spelled).
|
|
5
|
-
* This root subpath never touches a runtime builtin — a browser
|
|
6
|
-
* bundler resolves it clean; the bindings live behind their own
|
|
7
|
-
* subpaths and load their builtin lazily inside `open()`.
|
|
8
|
-
*/
|
|
9
|
-
export { openStore, normalizeModel, MODEL_VERSION } from './store.js';
|
|
10
|
-
export { createDialect } from './dialect.js';
|
|
11
|
-
export { sqliteDialect } from './dialects/sqlite.js';
|
|
12
|
-
export { SQLITE_FLOOR, chain, toPromise, isThenable, compareVersions, openConnection, wrapStatement, lazyOpen, } from './driver.js';
|
|
13
|
-
export { planCollection, compileIndexPath, schemaTypeAt, KEY_COLUMN, DOC_COLUMN, normalizeDeclaredSql, comparableDeclaredSql, } from './ddl.js';
|
|
14
|
-
export { planQuery, assertDecidedKind, entityShape, entityPathRef, planEntityPredicate, planEntityQuery, } from './plan.js';
|
|
15
|
-
export { emitPlan, createEntityPredicateEmitters, emitEntityPlan } from './emit.js';
|
|
16
|
-
export { mergeEntityRow, parseGraphRow } from './graph.js';
|
|
17
|
-
export { selectPlan, conjoin, assertNoSqlText, PLAN_VERSION } from './algebra.js';
|
|
18
|
-
export { typeOfPath, isNumericType } from './types.js';
|
|
19
|
-
export { compileSetResidual, compileRowResidual, sequenceResult } from './residual.js';
|
|
20
|
-
export { deterministicFragment, registerFragment } from './udf.js';
|
|
21
|
-
export { DERIVE_KINDS, DERIVE_MAPPING, PHYSICAL_KINDS, BBOX_COMPONENTS, BBOX_INDEX_ORDER, PRECISION_MIN, PRECISION_MAX, DIMS_MIN, DIMS_MAX, deriveGeohash, deriveBboxEdge, deriveVector, derivedValue, derivedMappingFor, memberAt, storedMemberForm, registerDeriveFunctions, probeVector, columnScore, } from './derive.js';
|
|
22
|
-
export { KNN_MARGIN, IDENTITY_CHUNK, cutCandidates, identityBatches } from './knn.js';
|
|
23
|
-
export { createQueryEngine, createQueryState, createEntityQueryEngine, createLoadEngine, INCLUDE_DEPTH_DEFAULT, } from './query.js';
|
|
24
|
-
export { normalizeProfile, SAFE_PROFILE, translateProfilePredicate, applyMandatoryPredicate, applyRowBound, } from './profile.js';
|
|
25
|
-
export { translatePatch } from './patch-sql.js';
|
|
26
|
-
export { normalizeEntities, explainMapping } from './model.js';
|
|
27
|
-
export { planEntity, planJoinTable } from './ddl.js';
|
|
28
|
-
export { entityCore } from './entity.js';
|
|
29
|
-
export { entityEmitModel } from './emit-model.js';
|
|
30
|
-
export { parseChangeset, translateOperations, keyToken, createCaptureEngine, CHANGES_TABLE, DEFAULT_RETENTION, } from './capture.js';
|
|
31
|
-
export { createTracker, deepFreeze, BATCH_PARAM_BUDGET, BATCH_ROW_BOUND, } from './tracker.js';
|
|
32
|
-
export { planMigration, planModelMigration, migrate, migrationStatus, shapeHash, migrationChecksum, createModelShape, schemaShapeOf, compareShapeToModel, MIGRATION_VERSION, HISTORY_TABLE, } from './migrate.js';
|
|
33
|
-
export { DbCompileError, DbRuntimeError, DB_CODES } from './errors.js';
|
|
34
|
-
export { classifyLiveQuery, createLiveRegistry, diffRows, LIVE_DEFAULTS } from './live.js';
|
|
35
|
-
export { createSortedWindow, compareCodepoint } from './window.js';
|
|
36
|
-
export { createJobEngine, JOBS_TABLE, JOB_CHECKPOINTS_TABLE, JOB_DEFAULTS, describeValue, serializeResult, } from './jobs.js';
|
|
37
|
-
export { createDagJobRunner } from './dag-job.js';
|
package/dist/types/jobs.d.ts
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file The durable job queue (JOBS-FORMAT): enqueue, the
|
|
3
|
-
* single-statement guarded claim (§3 — one statement is one
|
|
4
|
-
* transaction, so no double-claim without any distributed lock),
|
|
5
|
-
* retry with exponential backoff and jitter (§4), recovery as
|
|
6
|
-
* re-claim of expired leases (§5), polling workers with same-process
|
|
7
|
-
* wake-on-enqueue (§6), and the per-job flow checkpoint store the DAG
|
|
8
|
-
* composition binds (§7) — completion marks the job done and records
|
|
9
|
-
* the result in ONE guarded transaction.
|
|
10
|
-
*
|
|
11
|
-
* Every worker transition is guarded by `state='leased' AND
|
|
12
|
-
* lease_owner=?`: execution is at-least-once, completion is
|
|
13
|
-
* exactly-once. `now` and `random` are injectable — the runtime
|
|
14
|
-
* defaults are the clock and `Math.random`; every test injects.
|
|
15
|
-
*
|
|
16
|
-
* The worker LIFECYCLE holds two invariants that a long-running process
|
|
17
|
-
* depends on, and neither is a detail:
|
|
18
|
-
*
|
|
19
|
-
* - **No handler value can break the loop.** A handler is host code and
|
|
20
|
-
* may resolve with something JSON cannot express, or reject with a
|
|
21
|
-
* value whose own `message` throws when read. Both are normalized
|
|
22
|
-
* totally, and `runOne` is isolated inside the loop, so the worst a
|
|
23
|
-
* single job can do is fail its own attempt. A rejected claim-execute
|
|
24
|
-
* loop would stop draining the queue silently.
|
|
25
|
-
* - **Shutdown is bounded.** Handlers receive an `AbortSignal` and
|
|
26
|
-
* `stop()` takes a deadline, so a handler that never settles cannot
|
|
27
|
-
* hold `stop()` — and therefore `store.close()`, and therefore the
|
|
28
|
-
* database file — open forever. A loop the deadline could not drain
|
|
29
|
-
* is CANCELLED, not merely left behind: when its handler finally
|
|
30
|
-
* settles it exits without another claim, store write or poll
|
|
31
|
-
* timer, and its abandoned job recovers by lease expiry (§5).
|
|
32
|
-
*/
|
|
33
|
-
export declare const JOBS_TABLE = "_jaren_jobs";
|
|
34
|
-
export declare const JOB_CHECKPOINTS_TABLE = "_jaren_job_checkpoints";
|
|
35
|
-
/** §4 defaults, all overridable per worker. */
|
|
36
|
-
export declare const JOB_DEFAULTS: Readonly<{
|
|
37
|
-
maxAttempts: 5;
|
|
38
|
-
leaseMs: 30000;
|
|
39
|
-
pollInterval: 500;
|
|
40
|
-
backoffBase: 1000;
|
|
41
|
-
backoffCap: 60000;
|
|
42
|
-
/** How long `stop()` waits for in-flight handlers after signalling
|
|
43
|
-
* abort, before it stops waiting and reports what is still running.
|
|
44
|
-
* Bounded on purpose: an unbounded wait makes one stuck handler
|
|
45
|
-
* indistinguishable from a hung process. */
|
|
46
|
-
stopGraceMs: 5000;
|
|
47
|
-
}>;
|
|
48
|
-
/**
|
|
49
|
-
* A diagnostic string for ANY value, including ones that fight back — a
|
|
50
|
-
* getter that throws, a null-prototype object, a revoked proxy, a
|
|
51
|
-
* symbol. Total by construction: an error report is never the thing that
|
|
52
|
-
* fails.
|
|
53
|
-
* @param {any} value
|
|
54
|
-
* @returns {string}
|
|
55
|
-
*/
|
|
56
|
-
export declare function describeValue(value: any): string;
|
|
57
|
-
/**
|
|
58
|
-
* JSON text for a job result, or `null` when the value cannot be
|
|
59
|
-
* expressed — a BigInt, a cycle, a `toJSON` that throws. The caller
|
|
60
|
-
* treats that as a failed attempt, never as a broken worker.
|
|
61
|
-
* @param {any} value
|
|
62
|
-
* @returns {{ text: string | null } | { reason: string }}
|
|
63
|
-
*/
|
|
64
|
-
export declare function serializeResult(value: any): {
|
|
65
|
-
text: string | null;
|
|
66
|
-
} | {
|
|
67
|
-
reason: string;
|
|
68
|
-
};
|
|
69
|
-
/**
|
|
70
|
-
* The queue engine over one open connection.
|
|
71
|
-
* @param {{ connection: any, now?: () => number,
|
|
72
|
-
* random?: () => number,
|
|
73
|
-
* defaults?: Partial<typeof JOB_DEFAULTS> }} options
|
|
74
|
-
*/
|
|
75
|
-
export declare function createJobEngine(options: {
|
|
76
|
-
connection: any;
|
|
77
|
-
now?: () => number;
|
|
78
|
-
random?: () => number;
|
|
79
|
-
defaults?: Partial<typeof JOB_DEFAULTS>;
|
|
80
|
-
}): {
|
|
81
|
-
ready: any;
|
|
82
|
-
enqueue: (kind: any, payload: any, enqueueOptions: any) => any;
|
|
83
|
-
get: (id: any) => any;
|
|
84
|
-
counts: () => any;
|
|
85
|
-
claim: (claimOptions: {
|
|
86
|
-
kinds: string[];
|
|
87
|
-
owner: string;
|
|
88
|
-
leaseMs?: number;
|
|
89
|
-
}) => any;
|
|
90
|
-
complete: (id: any, owner: any, result: any) => any;
|
|
91
|
-
fail: (id: any, owner: any, error: any, workerDefaults: any) => any;
|
|
92
|
-
checkpointsFor: (job: {
|
|
93
|
-
id: string;
|
|
94
|
-
leaseOwner: string | null;
|
|
95
|
-
}) => {
|
|
96
|
-
load: (runId: any) => any;
|
|
97
|
-
save: (runId: any, nodeId: any, value: any) => any;
|
|
98
|
-
complete: (runId: any, result: any) => any;
|
|
99
|
-
};
|
|
100
|
-
createWorker: (workerOptions: {
|
|
101
|
-
handlers: Record<string, Function>;
|
|
102
|
-
concurrency?: number;
|
|
103
|
-
pollInterval?: number;
|
|
104
|
-
leaseMs?: number;
|
|
105
|
-
owner?: string;
|
|
106
|
-
backoffBase?: number;
|
|
107
|
-
backoffCap?: number;
|
|
108
|
-
}) => {
|
|
109
|
-
stats: () => {
|
|
110
|
-
claims: number;
|
|
111
|
-
completions: number;
|
|
112
|
-
failures: number;
|
|
113
|
-
polls: number;
|
|
114
|
-
wakes: number;
|
|
115
|
-
inFlight: number;
|
|
116
|
-
};
|
|
117
|
-
start(): /*elided*/ any;
|
|
118
|
-
/**
|
|
119
|
-
* Stop claiming, signal in-flight handlers to abort, and wait for
|
|
120
|
-
* the loops — but only up to `graceMs`. A handler that ignores its
|
|
121
|
-
* signal cannot hold the process open; the resolved record says so
|
|
122
|
-
* instead, and the lease expiry (§5) lets another worker re-claim.
|
|
123
|
-
* A loop the grace period could not drain is cancelled outright:
|
|
124
|
-
* when its handler finally settles it exits without another
|
|
125
|
-
* claim, store write or poll timer.
|
|
126
|
-
* @param {{ graceMs?: number }} [stopOptions]
|
|
127
|
-
* @returns {Promise<{ drained: boolean, inFlight: number }>}
|
|
128
|
-
*/
|
|
129
|
-
stop(stopOptions?: {
|
|
130
|
-
graceMs?: number;
|
|
131
|
-
}): Promise<{
|
|
132
|
-
drained: boolean;
|
|
133
|
-
inFlight: number;
|
|
134
|
-
}>;
|
|
135
|
-
};
|
|
136
|
-
/** Stop every worker, bounded. Resolves to the per-worker outcome so
|
|
137
|
-
* `close()` can report a handler it could not wait out rather than
|
|
138
|
-
* hanging on it. */
|
|
139
|
-
stopAll: (stopOptions: any) => Promise<any[]>;
|
|
140
|
-
};
|
package/dist/types/knn.d.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file The candidate cut of a k-nearest plan: the arithmetic between
|
|
3
|
-
* the scores a statement fetched and the row identities the engine
|
|
4
|
-
* will decide over. No vector arithmetic lives here — a score is
|
|
5
|
-
* `derive.js`'s, through `@jarenjs/core/vector` — and no SQL: the
|
|
6
|
-
* fetch of the winners is the dialect's. This is the one place the
|
|
7
|
-
* margin is applied and the one place candidate identities are
|
|
8
|
-
* batched for it.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* The inclusive score margin of the cut. The column's score is a dot
|
|
12
|
-
* product over binary32-normalized forms; the engine's key is the
|
|
13
|
-
* cosine of the raw doubles; measured, the two differ by at most
|
|
14
|
-
* ~1e-8. Any margin of at least twice that makes the engine's top
|
|
15
|
-
* `offset + limit` a SUBSET of the candidates: were a row the engine
|
|
16
|
-
* ranks inside the window cut, some candidate the engine ranks outside
|
|
17
|
-
* it would have to score higher by the column and lower by the engine,
|
|
18
|
-
* which two scores within half the margin of each other cannot do.
|
|
19
|
-
* This is a hundred times that bound — it admits, in practice, only
|
|
20
|
-
* true ties, and those the engine breaks by the document's own keys.
|
|
21
|
-
*/
|
|
22
|
-
export declare const KNN_MARGIN = 0.000001;
|
|
23
|
-
/**
|
|
24
|
-
* The most identities one fetch statement binds: under the parameter
|
|
25
|
-
* cap of every SQLite build the store runs on. A guard, not a design —
|
|
26
|
-
* a k-nearest window is a handful of rows, and this only matters for a
|
|
27
|
-
* collection of many exact duplicates.
|
|
28
|
-
*/
|
|
29
|
-
export declare const IDENTITY_CHUNK = 512;
|
|
30
|
-
/**
|
|
31
|
-
* The rows a k-nearest window can contain, from the scored fetch.
|
|
32
|
-
*
|
|
33
|
-
* `m = offset + limit` rows are needed. When at least `m` rows scored,
|
|
34
|
-
* the candidates are every scored row within `margin` of the m-th best
|
|
35
|
-
* score — ties at the boundary included by construction. When fewer
|
|
36
|
-
* did, the window reaches the unrankable tail (NULL columns, or a
|
|
37
|
-
* collection smaller than the window), which only the documents can
|
|
38
|
-
* order: every row is then a candidate, and the collection is no
|
|
39
|
-
* larger than the window.
|
|
40
|
-
* @param {{ identity: any, score: number | null }[]} rows - one per
|
|
41
|
-
* fetched row; `score` is `null` where the column held no vector
|
|
42
|
-
* @param {number} m - `offset + limit`
|
|
43
|
-
* @param {number} margin
|
|
44
|
-
* @returns {{ identities: any[], scored: number, full: boolean }} the
|
|
45
|
-
* candidate identities in ascending identity order — the
|
|
46
|
-
* collection's own order, which a stable sort over the candidates
|
|
47
|
-
* must see — with how many rows scored and whether every row was
|
|
48
|
-
* taken
|
|
49
|
-
*/
|
|
50
|
-
export declare function cutCandidates(rows: {
|
|
51
|
-
identity: any;
|
|
52
|
-
score: number | null;
|
|
53
|
-
}[], m: number, margin: number): {
|
|
54
|
-
identities: any[];
|
|
55
|
-
scored: number;
|
|
56
|
-
full: boolean;
|
|
57
|
-
};
|
|
58
|
-
/**
|
|
59
|
-
* The identities sliced into fetch batches: at most `IDENTITY_CHUNK`
|
|
60
|
-
* each, and each padded with `null` to the next power of two — a NULL
|
|
61
|
-
* in an IN list matches no row — so a handful of prepared statements
|
|
62
|
-
* serve every candidate count instead of one per count seen.
|
|
63
|
-
* @param {any[]} identities - in the order they should be fetched
|
|
64
|
-
* @returns {{ size: number, params: any[] }[]}
|
|
65
|
-
*/
|
|
66
|
-
export declare function identityBatches(identities: any[]): {
|
|
67
|
-
size: number;
|
|
68
|
-
params: any[];
|
|
69
|
-
}[];
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Event-time live views (LIVE-FORMAT §13): a `$resample` or
|
|
3
|
-
* `$rolling` document over a collection, maintained against an
|
|
4
|
-
* explicit watermark.
|
|
5
|
-
*
|
|
6
|
-
* There is no clock in this file, and there is none anywhere under it.
|
|
7
|
-
* A live view over time needs to know what "now" is — which bucket is
|
|
8
|
-
* still open, which reading counts as late — and the only honest
|
|
9
|
-
* source of that is the host, because the machine's clock is a
|
|
10
|
-
* different quantity from the instant a reading carries. So the
|
|
11
|
-
* watermark ARRIVES: it is a finite epoch supplied at registration and
|
|
12
|
-
* moved forward by `advance()`, it never goes backwards, and a test can
|
|
13
|
-
* put it wherever the story needs it without waiting for a timer.
|
|
14
|
-
*
|
|
15
|
-
* What the maintenance actually does:
|
|
16
|
-
*
|
|
17
|
-
* - **A bucket view keeps its rows by bucket.** A write touches one
|
|
18
|
-
* bucket (two, when it moves a reading across a boundary), and only
|
|
19
|
-
* those are folded again — through `resampleSeries` itself, over that
|
|
20
|
-
* bucket's own rows, so the aggregate is the kernel's and cannot
|
|
21
|
-
* drift from what a fresh query would answer.
|
|
22
|
-
* - **A rolling view keeps its rows in instant order.** A write at `t`
|
|
23
|
-
* can only change the windows ending in `[t, t + width)`, so exactly
|
|
24
|
-
* that stretch is recomputed — again by the kernel, over the slice
|
|
25
|
-
* that stretch can see.
|
|
26
|
-
*
|
|
27
|
-
* And what it refuses. A calendar ladder walks a wall clock, a named
|
|
28
|
-
* zone needs host code, `locf`/`linear` couple every bucket to its
|
|
29
|
-
* neighbours, and `first`/`last` name a row by a position a maintained
|
|
30
|
-
* map does not preserve. Each of those re-runs with its own reason
|
|
31
|
-
* rather than being approximated. So does a reading older than the
|
|
32
|
-
* declared lateness: the view re-runs, the emission carries a
|
|
33
|
-
* `lateData` record naming the instant and the boundary, and the row is
|
|
34
|
-
* never quietly folded into a bucket its reader already believed
|
|
35
|
-
* closed.
|
|
36
|
-
*
|
|
37
|
-
* `retention` is the horizon this view claims to work over. It is
|
|
38
|
-
* checked, not assumed: it must cover a whole window plus the lateness
|
|
39
|
-
* the caller allows, which is the span a single repair can read. It is
|
|
40
|
-
* NOT a compaction policy — the maintained state is bounded by
|
|
41
|
-
* `live.maxMaintained` exactly as every other strategy's is, and this
|
|
42
|
-
* file drops nothing that an answer still depends on.
|
|
43
|
-
*/
|
|
44
|
-
/**
|
|
45
|
-
* Validate the `eventTime` option into the record the classifier and
|
|
46
|
-
* the strategies read, or `null` when the caller declared none.
|
|
47
|
-
* @param {any} options - the live options
|
|
48
|
-
* @param {string} collection - for the error's `collection` property
|
|
49
|
-
* @returns {null | { member: string, watermark: number,
|
|
50
|
-
* allowedLateness: number, retention: number }}
|
|
51
|
-
* @throws {DbCompileError} `JD0053` for any member this does not admit
|
|
52
|
-
*/
|
|
53
|
-
export declare function normalizeEventTime(options: any, collection: string): null | {
|
|
54
|
-
member: string;
|
|
55
|
-
watermark: number;
|
|
56
|
-
allowedLateness: number;
|
|
57
|
-
retention: number;
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* Classify a document as an event-time view, or say why it is not one.
|
|
61
|
-
*
|
|
62
|
-
* Returns `null` when the document does not name `$resample` or
|
|
63
|
-
* `$rolling` over this collection at all — the caller then goes on to
|
|
64
|
-
* §7's ordinary table. Every other outcome is a decision: a maintained
|
|
65
|
-
* description, or `{ strategy: 'rerun', reason }`.
|
|
66
|
-
* @param {any} inner - the unwrapped document
|
|
67
|
-
* @param {boolean} windowed - whether a `$subsequence` wrapped it
|
|
68
|
-
* @param {boolean} keyed
|
|
69
|
-
* @param {null | { member: string, watermark: number,
|
|
70
|
-
* allowedLateness: number, retention: number }} eventTime
|
|
71
|
-
* @returns {any}
|
|
72
|
-
*/
|
|
73
|
-
export declare function classifyEventTime(inner: any, windowed: boolean, keyed: boolean, eventTime: null | {
|
|
74
|
-
member: string;
|
|
75
|
-
watermark: number;
|
|
76
|
-
allowedLateness: number;
|
|
77
|
-
retention: number;
|
|
78
|
-
}): any;
|
|
79
|
-
/**
|
|
80
|
-
* `$resample` over a fixed ladder: one maintained fold per bucket.
|
|
81
|
-
* @param {any} description
|
|
82
|
-
* @param {any} context
|
|
83
|
-
*/
|
|
84
|
-
export declare function bucketStrategy(description: any, context: any): {
|
|
85
|
-
advance: (next: any) => void;
|
|
86
|
-
stats: () => {
|
|
87
|
-
lateData: number;
|
|
88
|
-
reruns: number;
|
|
89
|
-
recomputes: number;
|
|
90
|
-
watermark: any;
|
|
91
|
-
};
|
|
92
|
-
entries: () => number;
|
|
93
|
-
init: () => any;
|
|
94
|
-
apply(record: any): {
|
|
95
|
-
rebuild: boolean;
|
|
96
|
-
late: any;
|
|
97
|
-
rows?: undefined;
|
|
98
|
-
} | {
|
|
99
|
-
rebuild?: undefined;
|
|
100
|
-
late?: undefined;
|
|
101
|
-
rows: {
|
|
102
|
-
at: any;
|
|
103
|
-
value: number | null;
|
|
104
|
-
count: number;
|
|
105
|
-
}[] | ({
|
|
106
|
-
at: number;
|
|
107
|
-
value: number | null;
|
|
108
|
-
count: number;
|
|
109
|
-
} | undefined)[];
|
|
110
|
-
} | null;
|
|
111
|
-
/** A re-run rebuilds the whole state from the store — the only
|
|
112
|
-
* answer to a reading the maintained state cannot place. */
|
|
113
|
-
rebuild(): any;
|
|
114
|
-
};
|
|
115
|
-
/**
|
|
116
|
-
* `$rolling` over a fixed width: one output per input instant, with
|
|
117
|
-
* only the stretch a write can reach recomputed.
|
|
118
|
-
* @param {any} description
|
|
119
|
-
* @param {any} context
|
|
120
|
-
*/
|
|
121
|
-
export declare function rollingStrategy(description: any, context: any): {
|
|
122
|
-
advance: (next: any) => void;
|
|
123
|
-
stats: () => {
|
|
124
|
-
lateData: number;
|
|
125
|
-
reruns: number;
|
|
126
|
-
recomputes: number;
|
|
127
|
-
watermark: any;
|
|
128
|
-
};
|
|
129
|
-
entries: () => number;
|
|
130
|
-
init: () => any;
|
|
131
|
-
apply(record: any): {
|
|
132
|
-
rows?: undefined;
|
|
133
|
-
rebuild: boolean;
|
|
134
|
-
late: any;
|
|
135
|
-
} | {
|
|
136
|
-
rebuild?: undefined;
|
|
137
|
-
late?: undefined;
|
|
138
|
-
rows: any[];
|
|
139
|
-
} | null;
|
|
140
|
-
rebuild(): any;
|
|
141
|
-
};
|
package/dist/types/live.d.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Live queries (LIVE-FORMAT §§7–12): a registered query document
|
|
3
|
-
* whose result is maintained as capture records arrive, emitting
|
|
4
|
-
* RFC 6902 patches against its own `{ rows }` result document.
|
|
5
|
-
*
|
|
6
|
-
* The CLASSIFIER implements §7's normative table and nothing more —
|
|
7
|
-
* it unwraps the one-element array pack and literal `$subsequence`
|
|
8
|
-
* windows the same way the planner does, then reads the compiled
|
|
9
|
-
* plan: translated filters, order terms and aggregates are exactly
|
|
10
|
-
* the planner's, never a re-implementation. Everything outside the
|
|
11
|
-
* table re-runs on invalidation with the reason named (`live.mode`).
|
|
12
|
-
*
|
|
13
|
-
* Maintenance is synchronous inside capture delivery (§8): inserts
|
|
14
|
-
* carry their document in the patch, updates point-read the touched
|
|
15
|
-
* row, deletes are answered from maintained state. Per-row semantics
|
|
16
|
-
* reuse the ENGINE via packed one-row compilation (the residual
|
|
17
|
-
* discipline) — a live row evaluates exactly as the query would.
|
|
18
|
-
*/
|
|
19
|
-
/** The store-level live bounds and their defaults (§12: printed,
|
|
20
|
-
* never silent). */
|
|
21
|
-
export declare const LIVE_DEFAULTS: Readonly<{
|
|
22
|
-
maxQueries: 64;
|
|
23
|
-
maxMaintained: 10000;
|
|
24
|
-
}>;
|
|
25
|
-
/**
|
|
26
|
-
* Classify a collection query document against §7's table. Pure —
|
|
27
|
-
* given the document and the collection's planner shape, returns the
|
|
28
|
-
* strategy description, or a re-run description with the reason.
|
|
29
|
-
* @param {any} document
|
|
30
|
-
* @param {any} queryShape - the planner shape (collection, schema,
|
|
31
|
-
* columnByCanonical)
|
|
32
|
-
* @param {boolean} keyed - whether documents carry their key (a
|
|
33
|
-
* declared key pointer); unkeyed rows cannot be tracked by key
|
|
34
|
-
* @param {any} [eventTime] - the normalized `eventTime` option
|
|
35
|
-
* (`live-time.js`), or null when the caller declared none
|
|
36
|
-
* @returns {any}
|
|
37
|
-
*/
|
|
38
|
-
export declare function classifyLiveQuery(document: any, queryShape: any, keyed: boolean, eventTime?: any): any;
|
|
39
|
-
/**
|
|
40
|
-
* Diff two row arrays into sequential add/remove/replace ops under
|
|
41
|
-
* `/rows`, relying on REFERENCE identity for unchanged rows (the §9
|
|
42
|
-
* sharing contract makes identity the equality that matters). A
|
|
43
|
-
* working copy is replayed op by op, so the emitted patch transforms
|
|
44
|
-
* the old array into the new one BY CONSTRUCTION; a remove re-filled
|
|
45
|
-
* at the same index merges into a replace.
|
|
46
|
-
* @param {any[]} oldRows
|
|
47
|
-
* @param {any[]} newRows
|
|
48
|
-
* @returns {any[]} ops
|
|
49
|
-
*/
|
|
50
|
-
export declare function diffRows(oldRows: any[], newRows: any[]): any[];
|
|
51
|
-
/**
|
|
52
|
-
* The store-level live-query registry: registration against the §12
|
|
53
|
-
* bounds, capture-record delivery in commit order, lifecycle.
|
|
54
|
-
* @param {{ maxQueries: number, maxMaintained: number }} bounds
|
|
55
|
-
*/
|
|
56
|
-
export declare function createLiveRegistry(bounds: {
|
|
57
|
-
maxQueries: number;
|
|
58
|
-
maxMaintained: number;
|
|
59
|
-
}): {
|
|
60
|
-
register: (definition: any) => any;
|
|
61
|
-
count: () => number;
|
|
62
|
-
deliver(record: any): void;
|
|
63
|
-
closeAll(): void;
|
|
64
|
-
};
|