@minnowdb/core 0.3.0 → 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 +4 -2
- 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 +0 -1
- package/dist/engine/artifact-cache.js +0 -1
- package/dist/engine/batch.d.ts +5 -2
- package/dist/engine/batch.js +0 -1
- 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 +5 -6
- package/dist/engine/catalog.js +5 -5
- package/dist/engine/client.d.ts +27 -7
- package/dist/engine/client.js +197 -31
- package/dist/engine/database.d.ts +161 -38
- package/dist/engine/database.js +4320 -1523
- package/dist/engine/defaults.d.ts +0 -1
- package/dist/engine/defaults.js +2 -4
- 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 +39 -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 -11
- package/dist/engine/index.js +12 -10
- 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 +499 -129
- 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 +4 -4
- package/dist/engine/query-api.d.ts +3 -0
- package/dist/engine/query-api.js +3 -0
- package/dist/engine/query-cache.d.ts +0 -1
- package/dist/engine/query-cache.js +4 -4
- package/dist/engine/query.d.ts +4 -7
- package/dist/engine/query.js +348 -155
- package/dist/engine/result-wire.d.ts +0 -1
- package/dist/engine/result-wire.js +2 -2
- package/dist/engine/schema-wire.d.ts +1 -2
- package/dist/engine/schema-wire.js +0 -1
- package/dist/engine/schema.d.ts +3 -8
- package/dist/engine/schema.js +41 -24
- package/dist/engine/sort-keys.d.ts +0 -1
- package/dist/engine/sort-keys.js +2 -2
- package/dist/engine/sql-domains.d.ts +6 -1
- package/dist/engine/sql-domains.js +209 -45
- package/dist/engine/sql-driver.d.ts +2 -2
- package/dist/engine/sql-driver.js +0 -1
- package/dist/engine/sql-json.d.ts +0 -1
- package/dist/engine/sql-json.js +53 -7
- package/dist/engine/sql-semantics.d.ts +8 -5
- package/dist/engine/sql-semantics.js +427 -65
- package/dist/engine/typed-live.d.ts +67 -0
- package/dist/engine/typed-live.js +349 -0
- package/dist/engine/vector.d.ts +7 -1
- package/dist/engine/vector.js +202 -58
- package/dist/engine/worker-host.d.ts +8 -2
- package/dist/engine/worker-host.js +616 -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 +0 -1
- package/dist/plan/index.js +0 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.js +1 -1
- package/dist/storage/indexeddb.d.ts +74 -65
- package/dist/storage/indexeddb.js +12301 -2076
- package/dist/storage/memory.d.ts +56 -66
- package/dist/storage/memory.js +1004 -139
- 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 +403 -91
- package/dist/storage/opfs/leader.js +4306 -602
- package/dist/storage/opfs/rpc.d.ts +15 -3
- package/dist/storage/opfs/rpc.js +223 -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 +26 -121
- package/dist/storage/opfs/store.js +436 -388
- 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 -99
- package/dist/storage/snapshot.js +33 -309
- package/dist/storage/toolkit/extents.d.ts +41 -7
- package/dist/storage/toolkit/extents.js +402 -39
- package/dist/storage/toolkit/index.d.ts +3 -4
- package/dist/storage/toolkit/index.js +27 -3
- package/dist/storage/toolkit/record-core.d.ts +174 -61
- package/dist/storage/toolkit/record-core.js +5401 -849
- 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 +4 -6
- package/dist/storage/toolkit/wire.js +80 -25
- package/dist/storage/types.d.ts +1271 -218
- package/dist/storage/types.js +1471 -138
- package/dist/testing/block-store-conformance.d.ts +0 -1
- package/dist/testing/block-store-conformance.js +877 -138
- package/dist/testing/index.d.ts +42 -31
- package/dist/testing/index.js +100 -68
- package/dist/testing/opfs-shim.d.ts +13 -3
- package/dist/testing/opfs-shim.js +40 -6
- package/dist/testing/simulator.d.ts +0 -1
- package/dist/testing/simulator.js +43 -12
- package/dist/testing/sqllogictest.d.ts +0 -1
- package/dist/testing/sqllogictest.js +0 -1
- package/dist/transactions/index.d.ts +81 -20
- package/dist/transactions/index.js +1050 -268
- package/dist/worker-protocol/index.d.ts +3 -2
- package/dist/worker-protocol/index.js +2 -5
- package/package.json +49 -1
- 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-domains.d.ts.map +0 -1
- package/dist/engine/sql-domains.js.map +0 -1
- package/dist/engine/sql-driver.d.ts.map +0 -1
- package/dist/engine/sql-driver.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/testing/simulator.d.ts.map +0 -1
- package/dist/testing/simulator.js.map +0 -1
- package/dist/testing/sqllogictest.d.ts.map +0 -1
- package/dist/testing/sqllogictest.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
|
@@ -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 ColumnDefault, type SecondaryIndexState, type SimpleDataType, type SqlDomain, type TableRecord } from "../storage/
|
|
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.
|
|
@@ -29,11 +29,9 @@ export interface CatalogColumn {
|
|
|
29
29
|
}
|
|
30
30
|
export interface CatalogForeignKey {
|
|
31
31
|
readonly name: string;
|
|
32
|
-
readonly
|
|
33
|
-
readonly columns?: readonly string[];
|
|
32
|
+
readonly columns: readonly string[];
|
|
34
33
|
readonly parentTable: string;
|
|
35
|
-
readonly
|
|
36
|
-
readonly parentColumns?: readonly string[];
|
|
34
|
+
readonly parentColumns: readonly string[];
|
|
37
35
|
readonly onDelete: "restrict" | "cascade" | "set null";
|
|
38
36
|
}
|
|
39
37
|
export interface CatalogCheck {
|
|
@@ -42,6 +40,8 @@ export interface CatalogCheck {
|
|
|
42
40
|
readonly sql: string;
|
|
43
41
|
}
|
|
44
42
|
export interface CatalogTrigger {
|
|
43
|
+
/** Immutable durable identity; stable until this exact trigger is dropped. */
|
|
44
|
+
readonly id: string;
|
|
45
45
|
readonly name: string;
|
|
46
46
|
readonly event: "insert" | "update" | "delete";
|
|
47
47
|
readonly timing: "before" | "after";
|
|
@@ -99,4 +99,3 @@ export interface Catalog {
|
|
|
99
99
|
}
|
|
100
100
|
/** Projects storage's table records into the published catalog, sorted by name for stable diffs. */
|
|
101
101
|
export declare function toCatalog(records: readonly TableRecord[]): Catalog;
|
|
102
|
-
//# sourceMappingURL=catalog.d.ts.map
|
package/dist/engine/catalog.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { secondaryIndexColumnIds, secondaryIndexDirections, } from "../storage/
|
|
1
|
+
import { secondaryIndexColumnIds, secondaryIndexDirections, } from "../storage/types.js";
|
|
2
2
|
import { externalSqlDomainValue } from "./sql-domains.js";
|
|
3
3
|
function toCatalogColumn(column) {
|
|
4
4
|
return {
|
|
@@ -30,13 +30,13 @@ export function toCatalog(records) {
|
|
|
30
30
|
name: record.name,
|
|
31
31
|
sql: record.view.sql,
|
|
32
32
|
columns,
|
|
33
|
-
managed: record.view.managed
|
|
33
|
+
managed: record.view.managed,
|
|
34
34
|
});
|
|
35
35
|
continue;
|
|
36
36
|
}
|
|
37
37
|
tables.push({
|
|
38
38
|
name: record.name,
|
|
39
|
-
managed: record.managed
|
|
39
|
+
managed: record.managed,
|
|
40
40
|
columns,
|
|
41
41
|
...(record.uniqueKeyColumnId === undefined ||
|
|
42
42
|
record.columns.find((column) => column.id === record.uniqueKeyColumnId)?.hidden === true
|
|
@@ -62,7 +62,8 @@ export function toCatalog(records) {
|
|
|
62
62
|
}))
|
|
63
63
|
.sort((left, right) => left.name.localeCompare(right.name)),
|
|
64
64
|
}),
|
|
65
|
-
triggers: (record.triggers ?? []).map(({ name, event, timing }) => ({
|
|
65
|
+
triggers: (record.triggers ?? []).map(({ id, name, event, timing }) => ({
|
|
66
|
+
id,
|
|
66
67
|
name,
|
|
67
68
|
event,
|
|
68
69
|
timing,
|
|
@@ -71,4 +72,3 @@ export function toCatalog(records) {
|
|
|
71
72
|
}
|
|
72
73
|
return { tables, views };
|
|
73
74
|
}
|
|
74
|
-
//# 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,7 +22,9 @@ 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;
|
|
27
30
|
removeEventListener?(type: "message", listener: (event: MessageEvent<unknown>) => void): void;
|
|
@@ -57,6 +60,7 @@ export interface ClientMigrationResult {
|
|
|
57
60
|
}
|
|
58
61
|
interface EventRoute {
|
|
59
62
|
onChange?: (result: QueryResult) => void;
|
|
63
|
+
onInvalidate?: (invalidation: LiveQueryInvalidation) => void;
|
|
60
64
|
onError?: (error: unknown) => void;
|
|
61
65
|
onComplete?: () => void;
|
|
62
66
|
/** Payload shape is the handle's own; only snapshot loads emit these today. */
|
|
@@ -79,6 +83,7 @@ export declare class MinnowDatabaseClient {
|
|
|
79
83
|
updateBatch(tableName: string, input: UpdateBatchInput): Promise<UpdateBatchResult>;
|
|
80
84
|
update(tableName: string, key: Exclude<BatchValue, null>, changes: Readonly<Record<string, BatchValue>>): Promise<UpdateBatchResult>;
|
|
81
85
|
deleteBatch(tableName: string, input: DeleteBatchInput): Promise<DeleteBatchResult>;
|
|
86
|
+
delete(tableName: string, key: Exclude<BatchValue, null>): Promise<DeleteBatchResult>;
|
|
82
87
|
bufferedWriter(tableName: string, options?: BufferedWriterOptions): ClientBufferedWriter;
|
|
83
88
|
readTable(tableName: string, versionOrOptions?: number | ReadTableOptions): Promise<DatabaseRow[]>;
|
|
84
89
|
/**
|
|
@@ -86,6 +91,8 @@ export declare class MinnowDatabaseClient {
|
|
|
86
91
|
* datetimes) and are rebuilt into row objects here; see `result-wire.ts`.
|
|
87
92
|
*/
|
|
88
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>;
|
|
89
96
|
run<TRow>(query: {
|
|
90
97
|
kind: "typed-query";
|
|
91
98
|
plan: CompiledQuery;
|
|
@@ -118,16 +125,28 @@ export declare class MinnowDatabaseClient {
|
|
|
118
125
|
* database; `onProgress` reports each slice as it lands.
|
|
119
126
|
*/
|
|
120
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>;
|
|
121
130
|
/**
|
|
122
131
|
* Loads a snapshot file into the worker's store, which must be empty. The bytes go over in the
|
|
123
132
|
* same slices the export comes back in, and the worker's load progress arrives as events, so a
|
|
124
133
|
* multi-megabyte restore can be shown moving rather than as a frozen tab.
|
|
125
134
|
*/
|
|
126
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>;
|
|
127
138
|
/** The worker-side buffer pool's byte budget, residency, and lifetime counters. */
|
|
128
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>;
|
|
129
148
|
liveQueries(options?: ClientLiveQueryOptions): ClientLiveQuerySet;
|
|
130
|
-
|
|
149
|
+
listVisibleSegmentPage(tableName: string, options?: VisibleSegmentPageOptions): Promise<VisibleSegmentPage>;
|
|
131
150
|
cleanupQuerySpill(options?: QuerySpillCleanupOptions): Promise<QuerySpillCleanupResult>;
|
|
132
151
|
compactTable(tableName: string, options?: CompactTableOptions): Promise<CompactTableResult>;
|
|
133
152
|
compactTableStep(tableName: string, options?: CompactTableStepOptions): Promise<CompactionJobProgress>;
|
|
@@ -200,6 +219,8 @@ export declare class ClientLiveQuerySet {
|
|
|
200
219
|
constructor(client: MinnowDatabaseClient, handleId: string, created: Promise<unknown>);
|
|
201
220
|
/** Registers a query (SQL or a compiled-plan envelope) and re-runs it on relevant changes. */
|
|
202
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>;
|
|
203
224
|
stats(): Promise<LiveQueryStats>;
|
|
204
225
|
/** Hints the worker that this tab committed elsewhere (e.g. through another client). */
|
|
205
226
|
notifyLocalCommit(): void;
|
|
@@ -219,4 +240,3 @@ export declare class ClientLiveSubscription {
|
|
|
219
240
|
close(): Promise<void>;
|
|
220
241
|
}
|
|
221
242
|
export {};
|
|
222
|
-
//# sourceMappingURL=client.d.ts.map
|
package/dist/engine/client.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { CompactionJobConflictError, GarbageCollectionJobConflictError, LeaseConflictError, SnapshotManifestMissingError, TableRecordConflictError, TempOwnerConflictError, TransactionRecordConflictError, UniqueKeyConflictError, UniqueIndexCoverageError, WriteConflictError, } from "../storage/
|
|
2
|
-
import {
|
|
1
|
+
import { BlockReadBatchTooLargeError, CompactionBacklogError, CompactionJobConflictError, GarbageCollectionJobConflictError, IndexedDbSchemaUpgradeBlockedError, LeaseConflictError, LeaseExpiredError, LeaseOwnerConflictError, PostingBuildConflictError, SnapshotManifestMissingError, SnapshotImportConflictError, SchemaConflictError, StorageResourceLimitError, TableInUseError, TableRecordConflictError, TempOwnerConflictError, TransactionRecordConflictError, UniqueKeyBuildConflictError, UniqueKeyConflictError, UniqueIndexCoverageError, WriteConflictError, StorageCorruptionError, StorageFormatVersionError, OpfsUncertainOutcomeError, } from "../storage/types.js";
|
|
2
|
+
import { MAX_SNAPSHOT_STREAM_CHUNK_BYTES } from "../storage/snapshot.js";
|
|
3
|
+
import { parseRpcResponse, MAX_DATABASE_RPC_IN_FLIGHT, protocolVersion, } from "../worker-protocol/index.js";
|
|
3
4
|
import { toColumnarBatch } from "./batch.js";
|
|
4
|
-
import { CompactionJobCancelledError, CompactionMemoryBudgetError, CompactionWriteAmplificationError, MissingKeyError, SqlCompileError, UniqueConstraintError, } from "./errors.js";
|
|
5
|
+
import { CompactionJobCancelledError, CompactionMemoryBudgetError, CompactionWriteAmplificationError, MaintenanceBacklogError, MissingKeyError, SqlCompileError, UniqueConstraintError, VisibleSegmentCursorStaleError, } from "./errors.js";
|
|
5
6
|
import { QueryMemoryBudgetError } from "./memory.js";
|
|
6
7
|
import { decodeQueryResult } from "./result-wire.js";
|
|
7
8
|
import { serializeSchema } from "./schema-wire.js";
|
|
@@ -10,25 +11,56 @@ import { serializeSchema } from "./schema-wire.js";
|
|
|
10
11
|
* database is tens of round trips, small enough that no single structured clone is long enough
|
|
11
12
|
* to be felt as a dropped frame.
|
|
12
13
|
*/
|
|
13
|
-
const SNAPSHOT_CHUNK_BYTES =
|
|
14
|
+
const SNAPSHOT_CHUNK_BYTES = MAX_SNAPSHOT_STREAM_CHUNK_BYTES;
|
|
15
|
+
const MAX_SNAPSHOT_BYTE_ARRAY_LENGTH = 0xffffffff;
|
|
16
|
+
async function* clientSnapshotChunks(bytes) {
|
|
17
|
+
for (let offset = 0; offset < bytes.byteLength; offset += SNAPSHOT_CHUNK_BYTES) {
|
|
18
|
+
yield bytes.subarray(offset, offset + SNAPSHOT_CHUNK_BYTES);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function throwIfClientSnapshotAborted(signal) {
|
|
22
|
+
if (signal?.aborted !== true)
|
|
23
|
+
return;
|
|
24
|
+
if (signal.reason instanceof Error)
|
|
25
|
+
throw signal.reason;
|
|
26
|
+
const error = new Error("Snapshot operation was aborted", { cause: signal.reason });
|
|
27
|
+
error.name = "AbortError";
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
14
30
|
const errorRegistry = new Map([
|
|
15
31
|
UniqueConstraintError,
|
|
16
32
|
MissingKeyError,
|
|
33
|
+
CompactionBacklogError,
|
|
17
34
|
CompactionMemoryBudgetError,
|
|
18
35
|
CompactionWriteAmplificationError,
|
|
19
36
|
CompactionJobCancelledError,
|
|
37
|
+
MaintenanceBacklogError,
|
|
20
38
|
SqlCompileError,
|
|
21
39
|
QueryMemoryBudgetError,
|
|
40
|
+
VisibleSegmentCursorStaleError,
|
|
41
|
+
BlockReadBatchTooLargeError,
|
|
22
42
|
WriteConflictError,
|
|
43
|
+
SchemaConflictError,
|
|
23
44
|
UniqueKeyConflictError,
|
|
24
45
|
UniqueIndexCoverageError,
|
|
25
46
|
TableRecordConflictError,
|
|
26
47
|
CompactionJobConflictError,
|
|
27
48
|
GarbageCollectionJobConflictError,
|
|
49
|
+
IndexedDbSchemaUpgradeBlockedError,
|
|
28
50
|
SnapshotManifestMissingError,
|
|
51
|
+
SnapshotImportConflictError,
|
|
52
|
+
TableInUseError,
|
|
29
53
|
TransactionRecordConflictError,
|
|
30
54
|
LeaseConflictError,
|
|
55
|
+
LeaseExpiredError,
|
|
56
|
+
LeaseOwnerConflictError,
|
|
57
|
+
StorageResourceLimitError,
|
|
31
58
|
TempOwnerConflictError,
|
|
59
|
+
UniqueKeyBuildConflictError,
|
|
60
|
+
PostingBuildConflictError,
|
|
61
|
+
StorageCorruptionError,
|
|
62
|
+
StorageFormatVersionError,
|
|
63
|
+
OpfsUncertainOutcomeError,
|
|
32
64
|
].map((constructor) => [constructor.name, constructor]));
|
|
33
65
|
function rehydrateError(serialized) {
|
|
34
66
|
const constructor = errorRegistry.get(serialized.name);
|
|
@@ -147,6 +179,9 @@ export class MinnowDatabaseClient {
|
|
|
147
179
|
async deleteBatch(tableName, input) {
|
|
148
180
|
return (await this.#call("deleteBatch", [tableName, input]));
|
|
149
181
|
}
|
|
182
|
+
async delete(tableName, key) {
|
|
183
|
+
return (await this.#call("delete", [tableName, key]));
|
|
184
|
+
}
|
|
150
185
|
bufferedWriter(tableName, options = {}) {
|
|
151
186
|
const handleId = crypto.randomUUID();
|
|
152
187
|
const { onError, ...wireOptions } = options;
|
|
@@ -167,6 +202,50 @@ export class MinnowDatabaseClient {
|
|
|
167
202
|
async query(sql, options) {
|
|
168
203
|
return decodeQueryResult(await this.#call("query", options === undefined ? [sql] : [sql, options]));
|
|
169
204
|
}
|
|
205
|
+
/** Pulls one transferred columnar page at a time, preserving worker backpressure. */
|
|
206
|
+
queryCursor(sql, options = {}) {
|
|
207
|
+
const call = this.#call.bind(this);
|
|
208
|
+
const invoke = this._invoke.bind(this);
|
|
209
|
+
const handleId = crypto.randomUUID();
|
|
210
|
+
const { signal, onStats, ...wireOptions } = options;
|
|
211
|
+
if (onStats !== undefined) {
|
|
212
|
+
throw new TypeError("Query cursor onStats callbacks are not available across a worker");
|
|
213
|
+
}
|
|
214
|
+
async function* batches() {
|
|
215
|
+
let opened = false;
|
|
216
|
+
let closing;
|
|
217
|
+
const close = () => {
|
|
218
|
+
if (!opened)
|
|
219
|
+
return Promise.resolve();
|
|
220
|
+
closing ??= invoke(handleId, "close", []).catch(() => undefined);
|
|
221
|
+
return closing;
|
|
222
|
+
};
|
|
223
|
+
const onAbort = () => {
|
|
224
|
+
void close();
|
|
225
|
+
};
|
|
226
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
227
|
+
try {
|
|
228
|
+
signal?.throwIfAborted();
|
|
229
|
+
await call("queryCursorOpen", [handleId, sql, wireOptions]);
|
|
230
|
+
opened = true;
|
|
231
|
+
if (signal?.aborted === true) {
|
|
232
|
+
await close();
|
|
233
|
+
signal.throwIfAborted();
|
|
234
|
+
}
|
|
235
|
+
for (;;) {
|
|
236
|
+
const next = (await invoke(handleId, "next", []));
|
|
237
|
+
if (next.done)
|
|
238
|
+
return undefined;
|
|
239
|
+
yield decodeQueryResult(next.batch);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
finally {
|
|
243
|
+
signal?.removeEventListener("abort", onAbort);
|
|
244
|
+
await close();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return batches();
|
|
248
|
+
}
|
|
170
249
|
async run(query) {
|
|
171
250
|
return decodeQueryResult(await this.#call("run", [query])).rows;
|
|
172
251
|
}
|
|
@@ -235,30 +314,56 @@ export class MinnowDatabaseClient {
|
|
|
235
314
|
* database; `onProgress` reports each slice as it lands.
|
|
236
315
|
*/
|
|
237
316
|
async exportSnapshot(options = {}) {
|
|
317
|
+
const chunks = [];
|
|
318
|
+
let byteLength = 0;
|
|
319
|
+
for await (const chunk of this.exportSnapshotStream(options)) {
|
|
320
|
+
byteLength += chunk.byteLength;
|
|
321
|
+
if (!Number.isSafeInteger(byteLength) || byteLength > MAX_SNAPSHOT_BYTE_ARRAY_LENGTH) {
|
|
322
|
+
throw new RangeError("Snapshot exceeds the byte-array API's 4 GiB limit");
|
|
323
|
+
}
|
|
324
|
+
chunks.push(chunk);
|
|
325
|
+
}
|
|
326
|
+
const bytes = new Uint8Array(byteLength);
|
|
327
|
+
let offset = 0;
|
|
328
|
+
for (const chunk of chunks) {
|
|
329
|
+
bytes.set(chunk, offset);
|
|
330
|
+
offset += chunk.byteLength;
|
|
331
|
+
}
|
|
332
|
+
return bytes;
|
|
333
|
+
}
|
|
334
|
+
/** Pulls at most one bounded worker chunk at a time; closing releases the worker-side pin. */
|
|
335
|
+
async *exportSnapshotStream(options = {}) {
|
|
336
|
+
throwIfClientSnapshotAborted(options.signal);
|
|
238
337
|
options.onProgress?.({ phase: "reading", transferredBytes: 0, totalBytes: 0 });
|
|
239
338
|
const opened = (await this.#call("exportSnapshotOpen", []));
|
|
240
|
-
|
|
241
|
-
|
|
339
|
+
let transferredBytes = 0;
|
|
340
|
+
let succeeded = false;
|
|
242
341
|
try {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
options.onProgress?.({ phase: "transfer", transferredBytes
|
|
342
|
+
for (;;) {
|
|
343
|
+
throwIfClientSnapshotAborted(options.signal);
|
|
344
|
+
const next = (await this._invoke(opened.handleId, "read", []));
|
|
345
|
+
if (next.done)
|
|
346
|
+
break;
|
|
347
|
+
throwIfClientSnapshotAborted(options.signal);
|
|
348
|
+
if (!(next.chunk instanceof Uint8Array) || next.chunk.byteLength === 0) {
|
|
349
|
+
throw new Error("Snapshot transfer returned an invalid chunk");
|
|
350
|
+
}
|
|
351
|
+
yield next.chunk;
|
|
352
|
+
transferredBytes += next.chunk.byteLength;
|
|
353
|
+
options.onProgress?.({ phase: "transfer", transferredBytes, totalBytes: 0 });
|
|
255
354
|
}
|
|
355
|
+
succeeded = true;
|
|
256
356
|
}
|
|
257
357
|
finally {
|
|
258
358
|
await this._invoke(opened.handleId, "close", []).catch(() => undefined);
|
|
359
|
+
if (succeeded) {
|
|
360
|
+
options.onProgress?.({
|
|
361
|
+
phase: "done",
|
|
362
|
+
transferredBytes,
|
|
363
|
+
totalBytes: transferredBytes,
|
|
364
|
+
});
|
|
365
|
+
}
|
|
259
366
|
}
|
|
260
|
-
options.onProgress?.({ phase: "done", transferredBytes: totalBytes, totalBytes });
|
|
261
|
-
return bytes;
|
|
262
367
|
}
|
|
263
368
|
/**
|
|
264
369
|
* Loads a snapshot file into the worker's store, which must be empty. The bytes go over in the
|
|
@@ -266,6 +371,10 @@ export class MinnowDatabaseClient {
|
|
|
266
371
|
* multi-megabyte restore can be shown moving rather than as a frozen tab.
|
|
267
372
|
*/
|
|
268
373
|
async importSnapshot(bytes, options = {}) {
|
|
374
|
+
await this.importSnapshotStream(clientSnapshotChunks(bytes), options);
|
|
375
|
+
}
|
|
376
|
+
/** Uploads with one acknowledged worker chunk in flight; cancellation leaves resumable state. */
|
|
377
|
+
async importSnapshotStream(source, options = {}) {
|
|
269
378
|
const handleId = crypto.randomUUID();
|
|
270
379
|
const { onProgress } = options;
|
|
271
380
|
this.#events.set(handleId, {
|
|
@@ -278,17 +387,25 @@ export class MinnowDatabaseClient {
|
|
|
278
387
|
}),
|
|
279
388
|
});
|
|
280
389
|
try {
|
|
390
|
+
throwIfClientSnapshotAborted(options.signal);
|
|
281
391
|
await this.#call("importSnapshotOpen", [handleId]);
|
|
282
|
-
for (
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
392
|
+
for await (const input of source) {
|
|
393
|
+
throwIfClientSnapshotAborted(options.signal);
|
|
394
|
+
if (!(input instanceof Uint8Array)) {
|
|
395
|
+
throw new TypeError("Snapshot stream chunks must be Uint8Array values");
|
|
396
|
+
}
|
|
397
|
+
for (let offset = 0; offset < input.byteLength; offset += SNAPSHOT_CHUNK_BYTES) {
|
|
398
|
+
// Copy the bounded window: cloning a subarray would otherwise transfer its whole backing
|
|
399
|
+
// file on every request.
|
|
400
|
+
const chunk = input.slice(offset, offset + SNAPSHOT_CHUNK_BYTES);
|
|
401
|
+
await this.#post("rpc-call", handleId, "write", [chunk], [chunk.buffer]);
|
|
402
|
+
throwIfClientSnapshotAborted(options.signal);
|
|
403
|
+
}
|
|
286
404
|
}
|
|
287
405
|
await this._invoke(handleId, "finish", []);
|
|
288
406
|
}
|
|
289
407
|
catch (error) {
|
|
290
|
-
|
|
291
|
-
await this._invoke(handleId, "close", []).catch(() => undefined);
|
|
408
|
+
await this._invoke(handleId, options.signal?.aborted === true ? "cancel" : "close", []).catch(() => undefined);
|
|
292
409
|
throw error;
|
|
293
410
|
}
|
|
294
411
|
finally {
|
|
@@ -299,14 +416,31 @@ export class MinnowDatabaseClient {
|
|
|
299
416
|
async bufferPoolStats() {
|
|
300
417
|
return (await this.#call("bufferPoolStats", []));
|
|
301
418
|
}
|
|
419
|
+
async maintenanceStatus() {
|
|
420
|
+
return (await this.#call("maintenanceStatus", []));
|
|
421
|
+
}
|
|
422
|
+
async checkIntegrity(options = {}) {
|
|
423
|
+
return (await this.#call("checkIntegrity", [options]));
|
|
424
|
+
}
|
|
425
|
+
async storageStats() {
|
|
426
|
+
return (await this.#call("storageStats", []));
|
|
427
|
+
}
|
|
428
|
+
async inspectInterruptedImport() {
|
|
429
|
+
return (await this.#call("inspectInterruptedImport", []));
|
|
430
|
+
}
|
|
431
|
+
async abortInterruptedImport(identity) {
|
|
432
|
+
return (await this.#call("abortInterruptedImport", [
|
|
433
|
+
identity,
|
|
434
|
+
]));
|
|
435
|
+
}
|
|
302
436
|
liveQueries(options = {}) {
|
|
303
437
|
const handleId = crypto.randomUUID();
|
|
304
438
|
const created = this.#call("liveQueries", [handleId, options]);
|
|
305
439
|
return new ClientLiveQuerySet(this, handleId, created);
|
|
306
440
|
}
|
|
307
441
|
// --- Maintenance ------------------------------------------------------------------------------
|
|
308
|
-
async
|
|
309
|
-
return (await this.#call("
|
|
442
|
+
async listVisibleSegmentPage(tableName, options) {
|
|
443
|
+
return (await this.#call("listVisibleSegmentPage", options === undefined ? [tableName] : [tableName, options]));
|
|
310
444
|
}
|
|
311
445
|
async cleanupQuerySpill(options) {
|
|
312
446
|
return (await this.#call("cleanupQuerySpill", options === undefined ? [] : [options]));
|
|
@@ -379,15 +513,18 @@ export class MinnowDatabaseClient {
|
|
|
379
513
|
throw new Error("Database client is closed");
|
|
380
514
|
return this.#post("rpc-call", null, method, args);
|
|
381
515
|
}
|
|
382
|
-
async #post(kind, handleId, method, args) {
|
|
516
|
+
async #post(kind, handleId, method, args, transfer, bypassLimit = kind === "rpc-init" || method === "dispose") {
|
|
383
517
|
if (this.#fatal !== undefined)
|
|
384
518
|
throw this.#fatal;
|
|
519
|
+
if (!bypassLimit && this.#pending.size >= MAX_DATABASE_RPC_IN_FLIGHT) {
|
|
520
|
+
throw new RangeError(`A database worker connection cannot hold more than ${String(MAX_DATABASE_RPC_IN_FLIGHT)} in-flight requests`);
|
|
521
|
+
}
|
|
385
522
|
const requestId = crypto.randomUUID();
|
|
386
523
|
return new Promise((resolve, reject) => {
|
|
387
524
|
this.#pending.set(requestId, { resolve, reject });
|
|
388
525
|
this.#transport.postMessage(kind === "rpc-init"
|
|
389
526
|
? { version: protocolVersion, requestId, kind, payload: args[0] }
|
|
390
|
-
: { version: protocolVersion, requestId, kind, handleId, method, args });
|
|
527
|
+
: { version: protocolVersion, requestId, kind, handleId, method, args }, transfer === undefined ? undefined : { transfer });
|
|
391
528
|
});
|
|
392
529
|
}
|
|
393
530
|
#receive(message) {
|
|
@@ -400,6 +537,9 @@ export class MinnowDatabaseClient {
|
|
|
400
537
|
return;
|
|
401
538
|
if (response.event === "change")
|
|
402
539
|
route.onChange?.(decodeQueryResult(response.payload));
|
|
540
|
+
else if (response.event === "invalidate") {
|
|
541
|
+
route.onInvalidate?.(response.payload);
|
|
542
|
+
}
|
|
403
543
|
else if (response.event === "error") {
|
|
404
544
|
route.onError?.(rehydrateError(response.payload));
|
|
405
545
|
}
|
|
@@ -517,6 +657,33 @@ export class ClientLiveQuerySet {
|
|
|
517
657
|
throw error;
|
|
518
658
|
}
|
|
519
659
|
}
|
|
660
|
+
/** Registers dependency observation while leaving execution/result mapping to an adapter. */
|
|
661
|
+
async observe(query, options) {
|
|
662
|
+
await this.#created;
|
|
663
|
+
const subscriptionId = crypto.randomUUID();
|
|
664
|
+
const state = { completed: false };
|
|
665
|
+
this.client._routeEvents(subscriptionId, {
|
|
666
|
+
onInvalidate: options.onInvalidate.bind(options),
|
|
667
|
+
...(options.onError === undefined ? {} : { onError: options.onError.bind(options) }),
|
|
668
|
+
onComplete: () => {
|
|
669
|
+
state.completed = true;
|
|
670
|
+
this.#subscriptionIds.delete(subscriptionId);
|
|
671
|
+
options.onComplete?.();
|
|
672
|
+
},
|
|
673
|
+
});
|
|
674
|
+
try {
|
|
675
|
+
const created = (await this.client._invoke(this.handleId, "observe", [
|
|
676
|
+
subscriptionId,
|
|
677
|
+
query,
|
|
678
|
+
]));
|
|
679
|
+
this.#subscriptionIds.add(subscriptionId);
|
|
680
|
+
return new ClientLiveSubscription(this.client, subscriptionId, created.dependencyTableIds, () => this.#subscriptionIds.delete(subscriptionId), state);
|
|
681
|
+
}
|
|
682
|
+
catch (error) {
|
|
683
|
+
this.client._unrouteEvents(subscriptionId);
|
|
684
|
+
throw error;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
520
687
|
async stats() {
|
|
521
688
|
await this.#created;
|
|
522
689
|
return (await this.client._invoke(this.handleId, "stats", []));
|
|
@@ -570,4 +737,3 @@ export class ClientLiveSubscription {
|
|
|
570
737
|
}
|
|
571
738
|
}
|
|
572
739
|
}
|
|
573
|
-
//# sourceMappingURL=client.js.map
|