@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.
Files changed (110) hide show
  1. package/ARCHITECTURE.md +420 -71
  2. package/README.md +711 -79
  3. package/docs/HOSTS.md +269 -0
  4. package/docs/JOBS-FORMAT.md +309 -45
  5. package/docs/LIVE-FORMAT.md +156 -19
  6. package/docs/MIGRATION-FORMAT.md +247 -40
  7. package/docs/MODEL-FORMAT.md +968 -86
  8. package/package.json +21 -8
  9. package/schemas/jaren-migration.draft-07.schema.json +73 -0
  10. package/schemas/jaren-migration.schema.json +73 -0
  11. package/schemas/jaren-model.draft-07.schema.json +224 -162
  12. package/schemas/jaren-model.schema.json +224 -162
  13. package/src/algebra.js +227 -9
  14. package/src/backup.js +161 -0
  15. package/src/cancellation.js +48 -0
  16. package/src/capture.js +255 -44
  17. package/src/cli.js +337 -50
  18. package/src/cursor.js +411 -0
  19. package/src/dag-job.js +154 -21
  20. package/src/ddl.js +125 -11
  21. package/src/dialect.js +267 -112
  22. package/src/dialects/expression-read.js +158 -0
  23. package/src/dialects/postgres.js +618 -0
  24. package/src/dialects/rtree-ddl.js +129 -0
  25. package/src/dialects/sqlite.js +245 -12
  26. package/src/document-files.js +311 -0
  27. package/src/document-steps.js +422 -0
  28. package/src/documents.js +335 -0
  29. package/src/driver.js +503 -69
  30. package/src/drivers/bun.js +37 -1
  31. package/src/drivers/indexeddb-snapshot.js +149 -0
  32. package/src/drivers/node-pool.js +11 -0
  33. package/src/drivers/node-worker-endpoint.js +105 -0
  34. package/src/drivers/node-worker.js +204 -0
  35. package/src/drivers/node.js +41 -7
  36. package/src/drivers/postgres.js +331 -0
  37. package/src/drivers/wasm-oo1.js +97 -0
  38. package/src/drivers/wasm-session.js +67 -0
  39. package/src/drivers/wasm.js +18 -83
  40. package/src/drivers/worker-pool.js +183 -0
  41. package/src/drivers/worker-protocol.js +79 -0
  42. package/src/drivers/worker-queue.js +60 -0
  43. package/src/emit-model.js +14 -0
  44. package/src/emit.js +349 -51
  45. package/src/entity.js +102 -59
  46. package/src/errors.js +430 -2
  47. package/src/expression.js +284 -0
  48. package/src/graph.js +64 -8
  49. package/src/index.js +48 -19
  50. package/src/introspect.js +583 -0
  51. package/src/jobs.js +870 -99
  52. package/src/json-bytes.js +58 -0
  53. package/src/live-time.js +12 -3
  54. package/src/live.js +11 -1
  55. package/src/maintenance.js +175 -0
  56. package/src/migrate.js +606 -333
  57. package/src/model.js +241 -8
  58. package/src/plan.js +1238 -160
  59. package/src/pragmas.js +314 -0
  60. package/src/profile.js +151 -3
  61. package/src/query.js +1748 -312
  62. package/src/residual.js +17 -0
  63. package/src/series.js +12 -4
  64. package/src/store.js +1672 -276
  65. package/src/tracker.js +367 -68
  66. package/src/udf.js +88 -7
  67. package/types/index.d.ts +1246 -32
  68. package/types/node-pool.d.ts +28 -0
  69. package/types/node-worker.d.ts +54 -0
  70. package/types/node.d.ts +72 -3
  71. package/types/postgres.d.ts +46 -0
  72. package/types/typed.d.ts +81 -3
  73. package/types/wasm.d.ts +21 -0
  74. package/dist/types/algebra.d.ts +0 -230
  75. package/dist/types/app.d.ts +0 -49
  76. package/dist/types/capture.d.ts +0 -85
  77. package/dist/types/cli.d.ts +0 -2
  78. package/dist/types/dag-job.d.ts +0 -40
  79. package/dist/types/ddl.d.ts +0 -229
  80. package/dist/types/derive.d.ts +0 -250
  81. package/dist/types/dialect.d.ts +0 -154
  82. package/dist/types/dialects/sqlite.d.ts +0 -9
  83. package/dist/types/driver.d.ts +0 -110
  84. package/dist/types/drivers/bun.d.ts +0 -47
  85. package/dist/types/drivers/node.d.ts +0 -37
  86. package/dist/types/drivers/wasm.d.ts +0 -65
  87. package/dist/types/emit-model.d.ts +0 -44
  88. package/dist/types/emit.d.ts +0 -75
  89. package/dist/types/entity.d.ts +0 -23
  90. package/dist/types/errors.d.ts +0 -170
  91. package/dist/types/graph.d.ts +0 -28
  92. package/dist/types/index.d.ts +0 -37
  93. package/dist/types/jobs.d.ts +0 -140
  94. package/dist/types/knn.d.ts +0 -69
  95. package/dist/types/live-time.d.ts +0 -141
  96. package/dist/types/live.d.ts +0 -64
  97. package/dist/types/migrate.d.ts +0 -170
  98. package/dist/types/model.d.ts +0 -36
  99. package/dist/types/patch-sql.d.ts +0 -37
  100. package/dist/types/plan.d.ts +0 -142
  101. package/dist/types/profile.d.ts +0 -80
  102. package/dist/types/query.d.ts +0 -112
  103. package/dist/types/residual.d.ts +0 -64
  104. package/dist/types/series.d.ts +0 -227
  105. package/dist/types/store.d.ts +0 -60
  106. package/dist/types/tracker.d.ts +0 -43
  107. package/dist/types/typed.d.ts +0 -15
  108. package/dist/types/types.d.ts +0 -26
  109. package/dist/types/udf.d.ts +0 -75
  110. package/dist/types/window.d.ts +0 -52
@@ -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
- }
@@ -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;
@@ -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';
@@ -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
- };
@@ -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
- };
@@ -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
- };