@minnowdb/core 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -32
- package/dist/block-format/block.d.ts +32 -13
- package/dist/block-format/block.js +179 -55
- package/dist/block-format/checksum.d.ts +2 -1
- package/dist/block-format/checksum.js +5 -2
- package/dist/block-format/codecs.d.ts +7 -2
- package/dist/block-format/codecs.js +53 -12
- package/dist/block-format/column.d.ts +3 -2
- package/dist/block-format/column.js +96 -30
- package/dist/block-format/index.d.ts +2 -2
- package/dist/block-format/index.js +2 -2
- package/dist/block-format/physical.d.ts +8 -2
- package/dist/block-format/physical.js +14 -6
- package/dist/block-format/types.d.ts +7 -3
- package/dist/block-format/types.js +0 -1
- package/dist/block-format/unicode.d.ts +11 -0
- package/dist/block-format/unicode.js +46 -0
- package/dist/date-value.d.ts +15 -0
- package/dist/date-value.js +64 -0
- package/dist/engine/artifact-cache.d.ts +2 -1
- package/dist/engine/artifact-cache.js +5 -1
- package/dist/engine/batch.d.ts +11 -3
- package/dist/engine/batch.js +17 -7
- package/dist/engine/buffered-writer.d.ts +2 -1
- package/dist/engine/buffered-writer.js +34 -9
- package/dist/engine/cache-limits.d.ts +25 -0
- package/dist/engine/cache-limits.js +25 -0
- package/dist/engine/catalog.d.ts +24 -5
- package/dist/engine/catalog.js +34 -7
- package/dist/engine/client.d.ts +29 -7
- package/dist/engine/client.js +216 -40
- package/dist/engine/database.d.ts +224 -39
- package/dist/engine/database.js +7475 -1539
- package/dist/engine/defaults.d.ts +4 -8
- package/dist/engine/defaults.js +46 -22
- package/dist/engine/errors.d.ts +19 -1
- package/dist/engine/errors.js +32 -2
- package/dist/engine/fts.d.ts +0 -6
- package/dist/engine/fts.js +41 -14
- package/dist/engine/group-index.d.ts +0 -1
- package/dist/engine/group-index.js +6 -11
- package/dist/engine/index.d.ts +16 -10
- package/dist/engine/index.js +12 -9
- package/dist/engine/join-index.d.ts +0 -1
- package/dist/engine/join-index.js +2 -2
- package/dist/engine/keyed-live.d.ts +57 -0
- package/dist/engine/keyed-live.js +226 -0
- package/dist/engine/live-api.d.ts +4 -0
- package/dist/engine/live-api.js +4 -0
- package/dist/engine/live.d.ts +43 -26
- package/dist/engine/live.js +504 -126
- package/dist/engine/memory.d.ts +2 -1
- package/dist/engine/memory.js +3 -2
- package/dist/engine/optimizer.d.ts +0 -1
- package/dist/engine/optimizer.js +262 -27
- package/dist/engine/query-api.d.ts +3 -0
- package/dist/engine/query-api.js +3 -0
- package/dist/engine/query-cache.d.ts +1 -2
- package/dist/engine/query-cache.js +7 -5
- package/dist/engine/query.d.ts +134 -29
- package/dist/engine/query.js +1668 -372
- package/dist/engine/result-wire.d.ts +0 -1
- package/dist/engine/result-wire.js +2 -2
- package/dist/engine/schema-wire.d.ts +6 -3
- package/dist/engine/schema-wire.js +40 -34
- package/dist/engine/schema.d.ts +156 -80
- package/dist/engine/schema.js +570 -108
- package/dist/engine/sort-keys.d.ts +4 -4
- package/dist/engine/sort-keys.js +44 -29
- package/dist/engine/sql-domains.d.ts +31 -0
- package/dist/engine/sql-domains.js +585 -0
- package/dist/engine/sql-driver.d.ts +19 -0
- package/dist/engine/sql-driver.js +1 -0
- package/dist/engine/sql-json.d.ts +7 -9
- package/dist/engine/sql-json.js +75 -15
- package/dist/engine/sql-semantics.d.ts +8 -3
- package/dist/engine/sql-semantics.js +458 -30
- package/dist/engine/typed-live.d.ts +67 -0
- package/dist/engine/typed-live.js +349 -0
- package/dist/engine/vector.d.ts +12 -2
- package/dist/engine/vector.js +635 -119
- package/dist/engine/worker-host.d.ts +9 -2
- package/dist/engine/worker-host.js +620 -152
- package/dist/engine/worker.d.ts +0 -1
- package/dist/engine/worker.js +3 -3
- package/dist/engine/write-block-planner.d.ts +18 -0
- package/dist/engine/write-block-planner.js +112 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/dist/plan/index.d.ts +3 -4
- package/dist/plan/index.js +3 -4
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.js +1 -1
- package/dist/storage/indexeddb.d.ts +99 -51
- package/dist/storage/indexeddb.js +13448 -2660
- package/dist/storage/memory.d.ts +64 -57
- package/dist/storage/memory.js +1042 -128
- package/dist/storage/opfs/files.d.ts +18 -7
- package/dist/storage/opfs/files.js +115 -28
- package/dist/storage/opfs/index.d.ts +1 -1
- package/dist/storage/opfs/index.js +1 -1
- package/dist/storage/opfs/leader.d.ts +409 -75
- package/dist/storage/opfs/leader.js +4621 -650
- package/dist/storage/opfs/rpc.d.ts +15 -3
- package/dist/storage/opfs/rpc.js +224 -2
- package/dist/storage/opfs/snapshot-ledger.d.ts +40 -0
- package/dist/storage/opfs/snapshot-ledger.js +281 -0
- package/dist/storage/opfs/store.d.ts +33 -99
- package/dist/storage/opfs/store.js +453 -364
- package/dist/storage/persistence.d.ts +37 -0
- package/dist/storage/persistence.js +78 -0
- package/dist/storage/snapshot-stream.d.ts +24 -0
- package/dist/storage/snapshot-stream.js +897 -0
- package/dist/storage/snapshot.d.ts +9 -85
- package/dist/storage/snapshot.js +33 -265
- package/dist/storage/toolkit/extents.d.ts +41 -7
- package/dist/storage/toolkit/extents.js +402 -39
- package/dist/storage/toolkit/index.d.ts +4 -5
- package/dist/storage/toolkit/index.js +28 -4
- package/dist/storage/toolkit/record-core.d.ts +182 -55
- package/dist/storage/toolkit/record-core.js +6158 -1331
- package/dist/storage/toolkit/sync-file.d.ts +10 -1
- package/dist/storage/toolkit/sync-file.js +50 -2
- package/dist/storage/toolkit/wal.d.ts +23 -5
- package/dist/storage/toolkit/wal.js +89 -27
- package/dist/storage/toolkit/wire.d.ts +15 -2
- package/dist/storage/toolkit/wire.js +199 -10
- package/dist/storage/types.d.ts +1439 -204
- package/dist/storage/types.js +1745 -141
- package/dist/testing/block-store-conformance.d.ts +0 -1
- package/dist/testing/block-store-conformance.js +1009 -119
- package/dist/testing/index.d.ts +46 -26
- package/dist/testing/index.js +112 -57
- package/dist/testing/opfs-shim.d.ts +13 -3
- package/dist/testing/opfs-shim.js +40 -6
- package/dist/testing/simulator.d.ts +97 -0
- package/dist/testing/simulator.js +591 -0
- package/dist/testing/sqllogictest.d.ts +89 -0
- package/dist/testing/sqllogictest.js +434 -0
- package/dist/transactions/index.d.ts +92 -16
- package/dist/transactions/index.js +1074 -236
- package/dist/worker-protocol/index.d.ts +3 -2
- package/dist/worker-protocol/index.js +2 -5
- package/package.json +53 -3
- package/postgres-feature-profile.json +223 -0
- package/sql-feature-matrix.json +172 -252
- package/dist/block-format/block.d.ts.map +0 -1
- package/dist/block-format/block.js.map +0 -1
- package/dist/block-format/checksum.d.ts.map +0 -1
- package/dist/block-format/checksum.js.map +0 -1
- package/dist/block-format/codecs.d.ts.map +0 -1
- package/dist/block-format/codecs.js.map +0 -1
- package/dist/block-format/column.d.ts.map +0 -1
- package/dist/block-format/column.js.map +0 -1
- package/dist/block-format/index.d.ts.map +0 -1
- package/dist/block-format/index.js.map +0 -1
- package/dist/block-format/physical.d.ts.map +0 -1
- package/dist/block-format/physical.js.map +0 -1
- package/dist/block-format/types.d.ts.map +0 -1
- package/dist/block-format/types.js.map +0 -1
- package/dist/engine/artifact-cache.d.ts.map +0 -1
- package/dist/engine/artifact-cache.js.map +0 -1
- package/dist/engine/batch.d.ts.map +0 -1
- package/dist/engine/batch.js.map +0 -1
- package/dist/engine/buffered-writer.d.ts.map +0 -1
- package/dist/engine/buffered-writer.js.map +0 -1
- package/dist/engine/catalog.d.ts.map +0 -1
- package/dist/engine/catalog.js.map +0 -1
- package/dist/engine/client.d.ts.map +0 -1
- package/dist/engine/client.js.map +0 -1
- package/dist/engine/coordinator.d.ts +0 -17
- package/dist/engine/coordinator.d.ts.map +0 -1
- package/dist/engine/coordinator.js +0 -60
- package/dist/engine/coordinator.js.map +0 -1
- package/dist/engine/database.d.ts.map +0 -1
- package/dist/engine/database.js.map +0 -1
- package/dist/engine/defaults.d.ts.map +0 -1
- package/dist/engine/defaults.js.map +0 -1
- package/dist/engine/errors.d.ts.map +0 -1
- package/dist/engine/errors.js.map +0 -1
- package/dist/engine/fts.d.ts.map +0 -1
- package/dist/engine/fts.js.map +0 -1
- package/dist/engine/group-index.d.ts.map +0 -1
- package/dist/engine/group-index.js.map +0 -1
- package/dist/engine/index.d.ts.map +0 -1
- package/dist/engine/index.js.map +0 -1
- package/dist/engine/join-index.d.ts.map +0 -1
- package/dist/engine/join-index.js.map +0 -1
- package/dist/engine/live.d.ts.map +0 -1
- package/dist/engine/live.js.map +0 -1
- package/dist/engine/memory.d.ts.map +0 -1
- package/dist/engine/memory.js.map +0 -1
- package/dist/engine/optimizer.d.ts.map +0 -1
- package/dist/engine/optimizer.js.map +0 -1
- package/dist/engine/query-cache.d.ts.map +0 -1
- package/dist/engine/query-cache.js.map +0 -1
- package/dist/engine/query.d.ts.map +0 -1
- package/dist/engine/query.js.map +0 -1
- package/dist/engine/result-wire.d.ts.map +0 -1
- package/dist/engine/result-wire.js.map +0 -1
- package/dist/engine/schema-wire.d.ts.map +0 -1
- package/dist/engine/schema-wire.js.map +0 -1
- package/dist/engine/schema.d.ts.map +0 -1
- package/dist/engine/schema.js.map +0 -1
- package/dist/engine/sort-keys.d.ts.map +0 -1
- package/dist/engine/sort-keys.js.map +0 -1
- package/dist/engine/sql-json.d.ts.map +0 -1
- package/dist/engine/sql-json.js.map +0 -1
- package/dist/engine/sql-semantics.d.ts.map +0 -1
- package/dist/engine/sql-semantics.js.map +0 -1
- package/dist/engine/vector.d.ts.map +0 -1
- package/dist/engine/vector.js.map +0 -1
- package/dist/engine/worker-host.d.ts.map +0 -1
- package/dist/engine/worker-host.js.map +0 -1
- package/dist/engine/worker.d.ts.map +0 -1
- package/dist/engine/worker.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/plan/index.d.ts.map +0 -1
- package/dist/plan/index.js.map +0 -1
- package/dist/storage/fixture-shape.d.ts +0 -42
- package/dist/storage/fixture-shape.d.ts.map +0 -1
- package/dist/storage/fixture-shape.js +0 -146
- package/dist/storage/fixture-shape.js.map +0 -1
- package/dist/storage/index.d.ts.map +0 -1
- package/dist/storage/index.js.map +0 -1
- package/dist/storage/indexeddb.d.ts.map +0 -1
- package/dist/storage/indexeddb.js.map +0 -1
- package/dist/storage/memory.d.ts.map +0 -1
- package/dist/storage/memory.js.map +0 -1
- package/dist/storage/opfs/files.d.ts.map +0 -1
- package/dist/storage/opfs/files.js.map +0 -1
- package/dist/storage/opfs/index.d.ts.map +0 -1
- package/dist/storage/opfs/index.js.map +0 -1
- package/dist/storage/opfs/leader.d.ts.map +0 -1
- package/dist/storage/opfs/leader.js.map +0 -1
- package/dist/storage/opfs/rpc.d.ts.map +0 -1
- package/dist/storage/opfs/rpc.js.map +0 -1
- package/dist/storage/opfs/store.d.ts.map +0 -1
- package/dist/storage/opfs/store.js.map +0 -1
- package/dist/storage/snapshot.d.ts.map +0 -1
- package/dist/storage/snapshot.js.map +0 -1
- package/dist/storage/toolkit/extents.d.ts.map +0 -1
- package/dist/storage/toolkit/extents.js.map +0 -1
- package/dist/storage/toolkit/index.d.ts.map +0 -1
- package/dist/storage/toolkit/index.js.map +0 -1
- package/dist/storage/toolkit/record-core.d.ts.map +0 -1
- package/dist/storage/toolkit/record-core.js.map +0 -1
- package/dist/storage/toolkit/sync-file.d.ts.map +0 -1
- package/dist/storage/toolkit/sync-file.js.map +0 -1
- package/dist/storage/toolkit/wal.d.ts.map +0 -1
- package/dist/storage/toolkit/wal.js.map +0 -1
- package/dist/storage/toolkit/wire.d.ts.map +0 -1
- package/dist/storage/toolkit/wire.js.map +0 -1
- package/dist/storage/types.d.ts.map +0 -1
- package/dist/storage/types.js.map +0 -1
- package/dist/testing/block-store-conformance.d.ts.map +0 -1
- package/dist/testing/block-store-conformance.js.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing/index.js.map +0 -1
- package/dist/testing/opfs-shim.d.ts.map +0 -1
- package/dist/testing/opfs-shim.js.map +0 -1
- package/dist/testing/seeds.d.ts +0 -11
- package/dist/testing/seeds.d.ts.map +0 -1
- package/dist/testing/seeds.js +0 -50
- package/dist/testing/seeds.js.map +0 -1
- package/dist/transactions/index.d.ts.map +0 -1
- package/dist/transactions/index.js.map +0 -1
- package/dist/worker-protocol/index.d.ts.map +0 -1
- package/dist/worker-protocol/index.js.map +0 -1
package/dist/engine/batch.js
CHANGED
|
@@ -15,24 +15,34 @@ export function toColumnarBatch(input) {
|
|
|
15
15
|
return input;
|
|
16
16
|
if (input.length === 0)
|
|
17
17
|
throw new TypeError("A batch needs at least one row");
|
|
18
|
-
// One pass over the rows, discovering columns in first-seen order.
|
|
19
|
-
//
|
|
20
|
-
// mention keeps its pre-filled nulls, which the per-column nullability check then accepts or
|
|
21
|
-
// rejects. Reading each row object once beats one full re-walk of every row per column.
|
|
18
|
+
// One pass over the rows, discovering columns in first-seen order. Values and omission are
|
|
19
|
+
// separate so an explicit NULL can never accidentally invoke a default.
|
|
22
20
|
const columnsByName = new Map();
|
|
21
|
+
const omittedByName = new Map();
|
|
23
22
|
for (let index = 0; index < input.length; index += 1) {
|
|
24
23
|
const row = input[index];
|
|
25
24
|
if (row === undefined)
|
|
26
25
|
continue;
|
|
27
26
|
for (const name of Object.keys(row)) {
|
|
27
|
+
const value = row[name];
|
|
28
|
+
if (value === undefined)
|
|
29
|
+
continue;
|
|
28
30
|
let values = columnsByName.get(name);
|
|
29
31
|
if (values === undefined) {
|
|
30
32
|
values = new Array(input.length).fill(null);
|
|
31
33
|
columnsByName.set(name, values);
|
|
34
|
+
omittedByName.set(name, new Array(input.length).fill(true));
|
|
32
35
|
}
|
|
33
|
-
values[index] =
|
|
36
|
+
values[index] = value;
|
|
37
|
+
const omitted = omittedByName.get(name);
|
|
38
|
+
if (omitted !== undefined)
|
|
39
|
+
omitted[index] = false;
|
|
34
40
|
}
|
|
35
41
|
}
|
|
36
|
-
|
|
42
|
+
const omitted = Object.fromEntries([...omittedByName].filter(([, values]) => values.some(Boolean)));
|
|
43
|
+
return {
|
|
44
|
+
columns: Object.fromEntries(columnsByName),
|
|
45
|
+
...(Object.keys(omitted).length === 0 ? {} : { omitted }),
|
|
46
|
+
rowCount: input.length,
|
|
47
|
+
};
|
|
37
48
|
}
|
|
38
|
-
//# sourceMappingURL=batch.js.map
|
|
@@ -24,6 +24,8 @@ export interface LifecycleFlushOptions {
|
|
|
24
24
|
document?: LifecycleDocumentTarget;
|
|
25
25
|
page?: LifecyclePageTarget;
|
|
26
26
|
}
|
|
27
|
+
/** Maximum accepted `add()` calls that have not completed. Callers must await for backpressure. */
|
|
28
|
+
export declare const MAX_BUFFERED_WRITER_PENDING_ADDS = 64;
|
|
27
29
|
/** Batches row-oriented writes by row count, estimated bytes, or age. */
|
|
28
30
|
export declare class BufferedTableWriter {
|
|
29
31
|
#private;
|
|
@@ -40,4 +42,3 @@ export declare class BufferedTableWriter {
|
|
|
40
42
|
}
|
|
41
43
|
/** Requests a non-blocking flush when the browser hides or unloads the page. */
|
|
42
44
|
export declare function attachLifecycleFlush(requester: LifecycleFlushRequester, options?: LifecycleFlushOptions): () => void;
|
|
43
|
-
//# sourceMappingURL=buffered-writer.d.ts.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { copyDate } from "../date-value.js";
|
|
2
|
+
/** Maximum accepted `add()` calls that have not completed. Callers must await for backpressure. */
|
|
3
|
+
export const MAX_BUFFERED_WRITER_PENDING_ADDS = 64;
|
|
1
4
|
/** Batches row-oriented writes by row count, estimated bytes, or age. */
|
|
2
5
|
export class BufferedTableWriter {
|
|
3
6
|
database;
|
|
@@ -11,6 +14,9 @@ export class BufferedTableWriter {
|
|
|
11
14
|
#estimatedBytes = 0;
|
|
12
15
|
#timer;
|
|
13
16
|
#inFlight;
|
|
17
|
+
#addTail = Promise.resolve();
|
|
18
|
+
#pendingAddCount = 0;
|
|
19
|
+
#acceptingAdds = true;
|
|
14
20
|
#closed = false;
|
|
15
21
|
constructor(database, tableName, options = {}) {
|
|
16
22
|
this.database = database;
|
|
@@ -29,14 +35,17 @@ export class BufferedTableWriter {
|
|
|
29
35
|
}
|
|
30
36
|
async add(row) {
|
|
31
37
|
this.#assertOpen();
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.#
|
|
35
|
-
|
|
36
|
-
if (this.#rows.length >= this.#maxRows || this.#estimatedBytes >= this.#maxBytes) {
|
|
37
|
-
return this.flush();
|
|
38
|
+
if (!this.#acceptingAdds)
|
|
39
|
+
return Promise.reject(new Error("Buffered writer is closing"));
|
|
40
|
+
if (this.#pendingAddCount >= MAX_BUFFERED_WRITER_PENDING_ADDS) {
|
|
41
|
+
return Promise.reject(new RangeError(`Buffered writer cannot queue more than ${String(MAX_BUFFERED_WRITER_PENDING_ADDS)} adds; await add() for backpressure`));
|
|
38
42
|
}
|
|
39
|
-
|
|
43
|
+
this.#pendingAddCount += 1;
|
|
44
|
+
const operation = this.#addTail.then(() => this.#addSerial(row));
|
|
45
|
+
this.#addTail = operation.then(() => undefined, () => undefined);
|
|
46
|
+
return operation.finally(() => {
|
|
47
|
+
this.#pendingAddCount -= 1;
|
|
48
|
+
});
|
|
40
49
|
}
|
|
41
50
|
async flush() {
|
|
42
51
|
if (this.#inFlight !== undefined)
|
|
@@ -70,6 +79,8 @@ export class BufferedTableWriter {
|
|
|
70
79
|
async close() {
|
|
71
80
|
if (this.#closed)
|
|
72
81
|
return undefined;
|
|
82
|
+
this.#acceptingAdds = false;
|
|
83
|
+
await this.#addTail;
|
|
73
84
|
let result;
|
|
74
85
|
while (this.#inFlight !== undefined || this.#rows.length > 0) {
|
|
75
86
|
result = await this.flush();
|
|
@@ -82,6 +93,9 @@ export class BufferedTableWriter {
|
|
|
82
93
|
}
|
|
83
94
|
discard() {
|
|
84
95
|
this.#assertOpen();
|
|
96
|
+
if (this.#pendingAddCount > 0) {
|
|
97
|
+
throw new Error("Cannot discard while buffered adds are pending");
|
|
98
|
+
}
|
|
85
99
|
const discarded = this.#rows.length;
|
|
86
100
|
this.#rows.length = 0;
|
|
87
101
|
this.#estimatedBytes = 0;
|
|
@@ -96,6 +110,18 @@ export class BufferedTableWriter {
|
|
|
96
110
|
await this.flush();
|
|
97
111
|
}
|
|
98
112
|
}
|
|
113
|
+
async #addSerial(row) {
|
|
114
|
+
const copy = cloneRow(row);
|
|
115
|
+
this.#rows.push(copy);
|
|
116
|
+
this.#estimatedBytes += estimateRowBytes(copy);
|
|
117
|
+
this.#scheduleAgeFlush();
|
|
118
|
+
if (this.#rows.length < this.#maxRows && this.#estimatedBytes < this.#maxBytes) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
if (this.#inFlight !== undefined)
|
|
122
|
+
await this.#inFlight;
|
|
123
|
+
return this.flush();
|
|
124
|
+
}
|
|
99
125
|
#scheduleAgeFlush() {
|
|
100
126
|
if (this.#timer !== undefined || this.#rows.length === 0 || this.#closed)
|
|
101
127
|
return;
|
|
@@ -140,7 +166,7 @@ function positiveWholeNumber(value, name) {
|
|
|
140
166
|
function cloneRow(row) {
|
|
141
167
|
return Object.fromEntries(Object.entries(row).map(([name, value]) => [
|
|
142
168
|
name,
|
|
143
|
-
value instanceof Date ?
|
|
169
|
+
value instanceof Date ? copyDate(value) : value,
|
|
144
170
|
]));
|
|
145
171
|
}
|
|
146
172
|
function estimateRowBytes(row) {
|
|
@@ -155,4 +181,3 @@ function estimateRowBytes(row) {
|
|
|
155
181
|
}
|
|
156
182
|
return bytes;
|
|
157
183
|
}
|
|
158
|
-
//# sourceMappingURL=buffered-writer.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Valid inputs beyond this length execute normally but are not retained in process-wide caches. */
|
|
2
|
+
export declare const MAX_CACHEABLE_TEXT_CHARACTERS: number;
|
|
3
|
+
/**
|
|
4
|
+
* Compilation happens before a query memory context exists. These limits therefore bound parser
|
|
5
|
+
* allocations and recursion independently of the execution budget. They are intentionally much
|
|
6
|
+
* larger than ordinary application SQL while remaining small enough for deterministic refusal.
|
|
7
|
+
*/
|
|
8
|
+
export declare const MAX_SQL_TEXT_CHARACTERS: number;
|
|
9
|
+
export declare const MAX_SQL_TOKENS = 4096;
|
|
10
|
+
export declare const MAX_SQL_NESTING_DEPTH = 128;
|
|
11
|
+
export declare const MAX_SQL_PARAMETERS = 4096;
|
|
12
|
+
/**
|
|
13
|
+
* Scalar functions that create a new string must not allocate an attacker-selected result before
|
|
14
|
+
* query memory accounting can observe it. Plain projection does not use this limit: a stored wide
|
|
15
|
+
* value can still be selected or streamed without asking a scalar function to expand it.
|
|
16
|
+
*/
|
|
17
|
+
export declare const MAX_SQL_SCALAR_RESULT_CHARACTERS: number;
|
|
18
|
+
/** Bounds object/array walks performed before an execution memory context exists. */
|
|
19
|
+
export declare const MAX_SQL_STRUCTURED_VALUE_ITEMS = 65536;
|
|
20
|
+
export declare const MAX_SQL_STRUCTURED_VALUE_DEPTH = 128;
|
|
21
|
+
/** SQL patterns compile outside the execution memory budget and may be retained in small caches. */
|
|
22
|
+
export declare const MAX_SQL_PATTERN_CHARACTERS: number;
|
|
23
|
+
/** Deterministic CPU ceiling for one non-trivial LIKE or SIMILAR TO match. */
|
|
24
|
+
export declare const MAX_SQL_PATTERN_MATCH_STEPS: number;
|
|
25
|
+
export declare const MAX_SQL_NUMERIC_DIGITS = 100000;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Valid inputs beyond this length execute normally but are not retained in process-wide caches. */
|
|
2
|
+
export const MAX_CACHEABLE_TEXT_CHARACTERS = 16 * 1024;
|
|
3
|
+
/**
|
|
4
|
+
* Compilation happens before a query memory context exists. These limits therefore bound parser
|
|
5
|
+
* allocations and recursion independently of the execution budget. They are intentionally much
|
|
6
|
+
* larger than ordinary application SQL while remaining small enough for deterministic refusal.
|
|
7
|
+
*/
|
|
8
|
+
export const MAX_SQL_TEXT_CHARACTERS = 1024 * 1024;
|
|
9
|
+
export const MAX_SQL_TOKENS = 4_096;
|
|
10
|
+
export const MAX_SQL_NESTING_DEPTH = 128;
|
|
11
|
+
export const MAX_SQL_PARAMETERS = 4_096;
|
|
12
|
+
/**
|
|
13
|
+
* Scalar functions that create a new string must not allocate an attacker-selected result before
|
|
14
|
+
* query memory accounting can observe it. Plain projection does not use this limit: a stored wide
|
|
15
|
+
* value can still be selected or streamed without asking a scalar function to expand it.
|
|
16
|
+
*/
|
|
17
|
+
export const MAX_SQL_SCALAR_RESULT_CHARACTERS = 1024 * 1024;
|
|
18
|
+
/** Bounds object/array walks performed before an execution memory context exists. */
|
|
19
|
+
export const MAX_SQL_STRUCTURED_VALUE_ITEMS = 65_536;
|
|
20
|
+
export const MAX_SQL_STRUCTURED_VALUE_DEPTH = 128;
|
|
21
|
+
/** SQL patterns compile outside the execution memory budget and may be retained in small caches. */
|
|
22
|
+
export const MAX_SQL_PATTERN_CHARACTERS = 16 * 1024;
|
|
23
|
+
/** Deterministic CPU ceiling for one non-trivial LIKE or SIMILAR TO match. */
|
|
24
|
+
export const MAX_SQL_PATTERN_MATCH_STEPS = 8 * 1024 * 1024;
|
|
25
|
+
export const MAX_SQL_NUMERIC_DIGITS = 100_000;
|
package/dist/engine/catalog.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ColumnDefault, type SecondaryIndexState, type SimpleDataType, type SqlDomain, type TableRecord } from "../storage/types.js";
|
|
2
2
|
/**
|
|
3
3
|
* The published shape of the catalog: everything a schema tool needs to diff a live database
|
|
4
4
|
* against a desired schema, without reading engine internals.
|
|
@@ -14,8 +14,11 @@ export interface CatalogColumn {
|
|
|
14
14
|
readonly id: string;
|
|
15
15
|
readonly name: string;
|
|
16
16
|
readonly type: SimpleDataType;
|
|
17
|
+
/** True for SQL INTEGER/SMALLINT/BIGINT columns, whose values must stay exactly representable. */
|
|
18
|
+
readonly integer?: true;
|
|
19
|
+
readonly sqlDomain?: SqlDomain;
|
|
17
20
|
readonly nullable: boolean;
|
|
18
|
-
/** Filled
|
|
21
|
+
/** Filled for omitted or SQL DEFAULT insert slots; never applied at read time. */
|
|
19
22
|
readonly defaultValue?: ColumnDefault;
|
|
20
23
|
/** String columns only: the closed set of values writes may draw from. */
|
|
21
24
|
readonly enumValues?: readonly string[];
|
|
@@ -26,9 +29,9 @@ export interface CatalogColumn {
|
|
|
26
29
|
}
|
|
27
30
|
export interface CatalogForeignKey {
|
|
28
31
|
readonly name: string;
|
|
29
|
-
readonly
|
|
32
|
+
readonly columns: readonly string[];
|
|
30
33
|
readonly parentTable: string;
|
|
31
|
-
readonly
|
|
34
|
+
readonly parentColumns: readonly string[];
|
|
32
35
|
readonly onDelete: "restrict" | "cascade" | "set null";
|
|
33
36
|
}
|
|
34
37
|
export interface CatalogCheck {
|
|
@@ -37,10 +40,23 @@ export interface CatalogCheck {
|
|
|
37
40
|
readonly sql: string;
|
|
38
41
|
}
|
|
39
42
|
export interface CatalogTrigger {
|
|
43
|
+
/** Immutable durable identity; stable until this exact trigger is dropped. */
|
|
44
|
+
readonly id: string;
|
|
40
45
|
readonly name: string;
|
|
41
46
|
readonly event: "insert" | "update" | "delete";
|
|
42
47
|
readonly timing: "before" | "after";
|
|
43
48
|
}
|
|
49
|
+
/** One SQL-declared secondary index, in declared key order. */
|
|
50
|
+
export interface CatalogIndex {
|
|
51
|
+
readonly name: string;
|
|
52
|
+
readonly columns: ReadonlyArray<{
|
|
53
|
+
readonly name: string;
|
|
54
|
+
readonly direction: "asc" | "desc";
|
|
55
|
+
}>;
|
|
56
|
+
readonly unique: boolean;
|
|
57
|
+
/** Build health is visible so inspection tools never present an invalid accelerator as ready. */
|
|
58
|
+
readonly state: SecondaryIndexState;
|
|
59
|
+
}
|
|
44
60
|
export interface CatalogTable {
|
|
45
61
|
readonly name: string;
|
|
46
62
|
/**
|
|
@@ -52,8 +68,12 @@ export interface CatalogTable {
|
|
|
52
68
|
readonly columns: readonly CatalogColumn[];
|
|
53
69
|
/** The unique key's column ID, absent on a table declared without one. */
|
|
54
70
|
readonly uniqueKeyColumnId?: string;
|
|
71
|
+
/** Declared PRIMARY KEY columns, including composite keys, in comparison order. */
|
|
72
|
+
readonly primaryKeyColumnIds?: readonly string[];
|
|
55
73
|
readonly foreignKeys: readonly CatalogForeignKey[];
|
|
56
74
|
readonly checks: readonly CatalogCheck[];
|
|
75
|
+
/** SQL-declared secondary indexes. Absent in catalogs produced before index introspection. */
|
|
76
|
+
readonly indexes?: readonly CatalogIndex[];
|
|
57
77
|
/**
|
|
58
78
|
* Reported but not declarable through the schema DSL: a trigger's body is a statement, not a
|
|
59
79
|
* column, so it stays SQL-only. A tool that rewrites triggers still needs to see them.
|
|
@@ -79,4 +99,3 @@ export interface Catalog {
|
|
|
79
99
|
}
|
|
80
100
|
/** Projects storage's table records into the published catalog, sorted by name for stable diffs. */
|
|
81
101
|
export declare function toCatalog(records: readonly TableRecord[]): Catalog;
|
|
82
|
-
//# sourceMappingURL=catalog.d.ts.map
|
package/dist/engine/catalog.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
import { secondaryIndexColumnIds, secondaryIndexDirections, } from "../storage/types.js";
|
|
2
|
+
import { externalSqlDomainValue } from "./sql-domains.js";
|
|
1
3
|
function toCatalogColumn(column) {
|
|
2
4
|
return {
|
|
3
5
|
id: column.id,
|
|
4
6
|
name: column.name,
|
|
5
7
|
type: column.type,
|
|
8
|
+
...(column.integer === true ? { integer: true } : {}),
|
|
9
|
+
...(column.sqlDomain === undefined ? {} : { sqlDomain: structuredClone(column.sqlDomain) }),
|
|
6
10
|
nullable: column.nullable,
|
|
7
11
|
...(column.defaultValue === undefined ? {} : { defaultValue: column.defaultValue }),
|
|
8
12
|
...(column.enumValues === undefined ? {} : { enumValues: [...column.enumValues] }),
|
|
9
|
-
...(column.backfill === undefined
|
|
13
|
+
...(column.backfill === undefined
|
|
14
|
+
? {}
|
|
15
|
+
: { backfill: externalSqlDomainValue(column.backfill) }),
|
|
10
16
|
isAutoIncrementing: column.defaultValue?.kind === "autoincrement",
|
|
11
17
|
};
|
|
12
18
|
}
|
|
@@ -16,26 +22,48 @@ export function toCatalog(records) {
|
|
|
16
22
|
const tables = [];
|
|
17
23
|
const views = [];
|
|
18
24
|
for (const record of byName) {
|
|
19
|
-
|
|
25
|
+
if (record.enumType !== undefined || record.sequence !== undefined)
|
|
26
|
+
continue;
|
|
27
|
+
const columns = record.columns.filter((column) => !column.hidden).map(toCatalogColumn);
|
|
20
28
|
if (record.view !== undefined) {
|
|
21
29
|
views.push({
|
|
22
30
|
name: record.name,
|
|
23
31
|
sql: record.view.sql,
|
|
24
32
|
columns,
|
|
25
|
-
managed: record.view.managed
|
|
33
|
+
managed: record.view.managed,
|
|
26
34
|
});
|
|
27
35
|
continue;
|
|
28
36
|
}
|
|
29
37
|
tables.push({
|
|
30
38
|
name: record.name,
|
|
31
|
-
managed: record.managed
|
|
39
|
+
managed: record.managed,
|
|
32
40
|
columns,
|
|
33
|
-
...(record.uniqueKeyColumnId === undefined
|
|
41
|
+
...(record.uniqueKeyColumnId === undefined ||
|
|
42
|
+
record.columns.find((column) => column.id === record.uniqueKeyColumnId)?.hidden === true
|
|
34
43
|
? {}
|
|
35
44
|
: { uniqueKeyColumnId: record.uniqueKeyColumnId }),
|
|
45
|
+
...(record.primaryKeyColumnIds === undefined
|
|
46
|
+
? {}
|
|
47
|
+
: { primaryKeyColumnIds: [...record.primaryKeyColumnIds] }),
|
|
36
48
|
foreignKeys: (record.foreignKeys ?? []).map((key) => ({ ...key })),
|
|
37
49
|
checks: (record.checks ?? []).map((check) => ({ ...check })),
|
|
38
|
-
|
|
50
|
+
...(record.secondaryIndexes === undefined
|
|
51
|
+
? {}
|
|
52
|
+
: {
|
|
53
|
+
indexes: Object.values(record.secondaryIndexes)
|
|
54
|
+
.map((index) => ({
|
|
55
|
+
name: index.name,
|
|
56
|
+
columns: secondaryIndexColumnIds(index).map((columnId, position) => ({
|
|
57
|
+
name: record.columns.find((column) => column.id === columnId)?.name ?? columnId,
|
|
58
|
+
direction: secondaryIndexDirections(index)[position] ?? "asc",
|
|
59
|
+
})),
|
|
60
|
+
unique: index.unique === true,
|
|
61
|
+
state: index.state,
|
|
62
|
+
}))
|
|
63
|
+
.sort((left, right) => left.name.localeCompare(right.name)),
|
|
64
|
+
}),
|
|
65
|
+
triggers: (record.triggers ?? []).map(({ id, name, event, timing }) => ({
|
|
66
|
+
id,
|
|
39
67
|
name,
|
|
40
68
|
event,
|
|
41
69
|
timing,
|
|
@@ -44,4 +72,3 @@ export function toCatalog(records) {
|
|
|
44
72
|
}
|
|
45
73
|
return { tables, views };
|
|
46
74
|
}
|
|
47
|
-
//# sourceMappingURL=catalog.js.map
|
package/dist/engine/client.d.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { type CompactionJobRecord, type GarbageCollectionJobRecord } from "../storage/
|
|
1
|
+
import { type CompactionJobRecord, type GarbageCollectionJobRecord, type StorageIntegrityMode, type StorageIntegrityReport, type StorageStats, type InterruptedSnapshotImport, type InterruptedSnapshotImportAbortResult } from "../storage/types.js";
|
|
2
2
|
import { type BatchRow, type InsertBatchInput } from "./batch.js";
|
|
3
3
|
import type { Catalog } from "./catalog.js";
|
|
4
|
-
import type { BatchValue, BufferPoolStats, StagedWriteResult, BufferedFlushResult, BufferedWriterOptions, CancelCompactionJobResult, CollectGarbageOptions, CollectGarbageStepOptions, CompactTableOptions, CompactTableResult, CompactTableStepOptions, CompactionJobProgress, CreateTableInput, DatabaseRow, MigrateOptions, DeleteBatchInput, DeleteBatchResult, ExecuteResult, GarbageCollectionProgress, GarbageCollectionResult, InsertBatchResult, QueryOptions, QuerySpillCleanupOptions, QuerySpillCleanupResult, ReadTableOptions, RunStatementOptions, SnapshotExportOptions, SnapshotImportOptions, TableDefinition, UpdateBatchInput, UpdateBatchResult, UpsertBatchResult,
|
|
5
|
-
import type { LiveQueryInput, LiveQueryStats, LiveQuerySubscribeOptions } from "./live.js";
|
|
4
|
+
import type { BatchValue, BufferPoolStats, StagedWriteResult, BufferedFlushResult, BufferedWriterOptions, CancelCompactionJobResult, CollectGarbageOptions, CollectGarbageStepOptions, CompactTableOptions, CompactTableResult, CompactTableStepOptions, CompactionJobProgress, CreateTableInput, DatabaseRow, MigrateOptions, DeleteBatchInput, DeleteBatchResult, ExecuteResult, GarbageCollectionProgress, GarbageCollectionResult, MaintenanceStatus, InsertBatchResult, QueryOptions, QueryCursorOptions, QuerySpillCleanupOptions, QuerySpillCleanupResult, ReadTableOptions, RunStatementOptions, SnapshotExportOptions, SnapshotImportOptions, TableDefinition, UpdateBatchInput, UpdateBatchResult, UpsertBatchResult, VisibleSegmentPage, VisibleSegmentPageOptions } from "./database.js";
|
|
5
|
+
import type { LiveQueryInput, LiveQueryInvalidation, LiveQueryObserveOptions, LiveQueryStats, LiveQuerySubscribeOptions } from "./live.js";
|
|
6
6
|
import type { CompiledQuery, CompiledStatement, QueryResult, QueryValue } from "./query.js";
|
|
7
7
|
import type { AnyTable, SchemaDefinition } from "./schema.js";
|
|
8
8
|
import { type WireMigrationStep } from "./schema-wire.js";
|
|
9
9
|
import type { StoreDescriptor, WireDatabaseOptions } from "./worker-host.js";
|
|
10
10
|
/**
|
|
11
11
|
* Main-thread async proxy of the full database API, talking to a worker that runs
|
|
12
|
-
* `@minnowdb/core/worker` (or a custom entry built on
|
|
12
|
+
* `@minnowdb/core/worker` (or a custom entry built on
|
|
13
|
+
* `exposeDatabase()` from `@minnowdb/core/worker-host`). Construction
|
|
13
14
|
* sends the init frame immediately; because the channel is ordered, calls may be issued without
|
|
14
15
|
* awaiting ready(). Everything here stays deliberately light — the heavy engine modules are
|
|
15
16
|
* imported as types only, so a main-thread bundle carries the proxy, not the executor.
|
|
@@ -21,9 +22,13 @@ import type { StoreDescriptor, WireDatabaseOptions } from "./worker-host.js";
|
|
|
21
22
|
*/
|
|
22
23
|
/** The slice of Worker (or MessagePort) the client needs. */
|
|
23
24
|
export interface ClientTransport {
|
|
24
|
-
postMessage(message: unknown
|
|
25
|
+
postMessage(message: unknown, options?: {
|
|
26
|
+
transfer: ArrayBuffer[];
|
|
27
|
+
}): void;
|
|
25
28
|
addEventListener(type: "message", listener: (event: MessageEvent<unknown>) => void): void;
|
|
26
29
|
addEventListener(type: "error" | "messageerror", listener: () => void): void;
|
|
30
|
+
removeEventListener?(type: "message", listener: (event: MessageEvent<unknown>) => void): void;
|
|
31
|
+
removeEventListener?(type: "error" | "messageerror", listener: () => void): void;
|
|
27
32
|
terminate?(): void;
|
|
28
33
|
}
|
|
29
34
|
export interface MinnowDatabaseClientOptions {
|
|
@@ -55,6 +60,7 @@ export interface ClientMigrationResult {
|
|
|
55
60
|
}
|
|
56
61
|
interface EventRoute {
|
|
57
62
|
onChange?: (result: QueryResult) => void;
|
|
63
|
+
onInvalidate?: (invalidation: LiveQueryInvalidation) => void;
|
|
58
64
|
onError?: (error: unknown) => void;
|
|
59
65
|
onComplete?: () => void;
|
|
60
66
|
/** Payload shape is the handle's own; only snapshot loads emit these today. */
|
|
@@ -77,6 +83,7 @@ export declare class MinnowDatabaseClient {
|
|
|
77
83
|
updateBatch(tableName: string, input: UpdateBatchInput): Promise<UpdateBatchResult>;
|
|
78
84
|
update(tableName: string, key: Exclude<BatchValue, null>, changes: Readonly<Record<string, BatchValue>>): Promise<UpdateBatchResult>;
|
|
79
85
|
deleteBatch(tableName: string, input: DeleteBatchInput): Promise<DeleteBatchResult>;
|
|
86
|
+
delete(tableName: string, key: Exclude<BatchValue, null>): Promise<DeleteBatchResult>;
|
|
80
87
|
bufferedWriter(tableName: string, options?: BufferedWriterOptions): ClientBufferedWriter;
|
|
81
88
|
readTable(tableName: string, versionOrOptions?: number | ReadTableOptions): Promise<DatabaseRow[]>;
|
|
82
89
|
/**
|
|
@@ -84,6 +91,8 @@ export declare class MinnowDatabaseClient {
|
|
|
84
91
|
* datetimes) and are rebuilt into row objects here; see `result-wire.ts`.
|
|
85
92
|
*/
|
|
86
93
|
query(sql: string, options?: QueryOptions): Promise<QueryResult>;
|
|
94
|
+
/** Pulls one transferred columnar page at a time, preserving worker backpressure. */
|
|
95
|
+
queryCursor(sql: string, options?: QueryCursorOptions): AsyncIterableIterator<QueryResult, undefined>;
|
|
87
96
|
run<TRow>(query: {
|
|
88
97
|
kind: "typed-query";
|
|
89
98
|
plan: CompiledQuery;
|
|
@@ -116,16 +125,28 @@ export declare class MinnowDatabaseClient {
|
|
|
116
125
|
* database; `onProgress` reports each slice as it lands.
|
|
117
126
|
*/
|
|
118
127
|
exportSnapshot(options?: SnapshotExportOptions): Promise<Uint8Array>;
|
|
128
|
+
/** Pulls at most one bounded worker chunk at a time; closing releases the worker-side pin. */
|
|
129
|
+
exportSnapshotStream(options?: SnapshotExportOptions): AsyncGenerator<Uint8Array, void, void>;
|
|
119
130
|
/**
|
|
120
131
|
* Loads a snapshot file into the worker's store, which must be empty. The bytes go over in the
|
|
121
132
|
* same slices the export comes back in, and the worker's load progress arrives as events, so a
|
|
122
133
|
* multi-megabyte restore can be shown moving rather than as a frozen tab.
|
|
123
134
|
*/
|
|
124
135
|
importSnapshot(bytes: Uint8Array, options?: SnapshotImportOptions): Promise<void>;
|
|
136
|
+
/** Uploads with one acknowledged worker chunk in flight; cancellation leaves resumable state. */
|
|
137
|
+
importSnapshotStream(source: AsyncIterable<Uint8Array>, options?: SnapshotImportOptions): Promise<void>;
|
|
125
138
|
/** The worker-side buffer pool's byte budget, residency, and lifetime counters. */
|
|
126
139
|
bufferPoolStats(): Promise<BufferPoolStats>;
|
|
140
|
+
maintenanceStatus(): Promise<MaintenanceStatus>;
|
|
141
|
+
checkIntegrity(options?: {
|
|
142
|
+
mode?: StorageIntegrityMode;
|
|
143
|
+
maxIssues?: number;
|
|
144
|
+
}): Promise<StorageIntegrityReport>;
|
|
145
|
+
storageStats(): Promise<StorageStats>;
|
|
146
|
+
inspectInterruptedImport(): Promise<InterruptedSnapshotImport | null>;
|
|
147
|
+
abortInterruptedImport(identity: string): Promise<InterruptedSnapshotImportAbortResult>;
|
|
127
148
|
liveQueries(options?: ClientLiveQueryOptions): ClientLiveQuerySet;
|
|
128
|
-
|
|
149
|
+
listVisibleSegmentPage(tableName: string, options?: VisibleSegmentPageOptions): Promise<VisibleSegmentPage>;
|
|
129
150
|
cleanupQuerySpill(options?: QuerySpillCleanupOptions): Promise<QuerySpillCleanupResult>;
|
|
130
151
|
compactTable(tableName: string, options?: CompactTableOptions): Promise<CompactTableResult>;
|
|
131
152
|
compactTableStep(tableName: string, options?: CompactTableStepOptions): Promise<CompactionJobProgress>;
|
|
@@ -198,6 +219,8 @@ export declare class ClientLiveQuerySet {
|
|
|
198
219
|
constructor(client: MinnowDatabaseClient, handleId: string, created: Promise<unknown>);
|
|
199
220
|
/** Registers a query (SQL or a compiled-plan envelope) and re-runs it on relevant changes. */
|
|
200
221
|
subscribe(query: LiveQueryInput, options: LiveQuerySubscribeOptions): Promise<ClientLiveSubscription>;
|
|
222
|
+
/** Registers dependency observation while leaving execution/result mapping to an adapter. */
|
|
223
|
+
observe(query: LiveQueryInput, options: LiveQueryObserveOptions): Promise<ClientLiveSubscription>;
|
|
201
224
|
stats(): Promise<LiveQueryStats>;
|
|
202
225
|
/** Hints the worker that this tab committed elsewhere (e.g. through another client). */
|
|
203
226
|
notifyLocalCommit(): void;
|
|
@@ -217,4 +240,3 @@ export declare class ClientLiveSubscription {
|
|
|
217
240
|
close(): Promise<void>;
|
|
218
241
|
}
|
|
219
242
|
export {};
|
|
220
|
-
//# sourceMappingURL=client.d.ts.map
|