@minnowdb/core 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +4326 -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 +4318 -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
package/dist/storage/types.d.ts
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import type { DatabaseSnapshot, SnapshotLoadProgress } from "./snapshot.js";
|
|
2
1
|
export declare const storeNames: readonly ["catalog", "manifests", "segments", "blocks", "transactions", "leases", "statistics", "temp", "gc"];
|
|
3
|
-
|
|
2
|
+
export declare const MAX_MANIFEST_CHANGED_TABLE_IDS = 1024;
|
|
3
|
+
export declare function canonicalManifestChangedTableIds(ids: readonly string[]): string[];
|
|
4
|
+
export declare function validateCanonicalManifestChangedTableIds(ids: readonly string[]): string[];
|
|
5
|
+
/**
|
|
6
|
+
* The bounded manifest record every commit publishes. Block membership is paged separately;
|
|
7
|
+
* reading this record must never materialize a database-sized ID array.
|
|
8
|
+
*/
|
|
4
9
|
export interface ManifestSummary {
|
|
5
10
|
version: number;
|
|
6
11
|
previousVersion: number | null;
|
|
7
12
|
createdAt: string;
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
changedTableIds
|
|
13
|
+
/** Exact live payload membership cardinality at this version. */
|
|
14
|
+
liveBlockCount: number;
|
|
15
|
+
/** Exact sum of stored payload bytes in the live membership at this version. */
|
|
16
|
+
liveBlockBytes: number;
|
|
17
|
+
/** Table IDs whose logical content changed; empty means compaction or another logical no-op. */
|
|
18
|
+
changedTableIds: string[];
|
|
14
19
|
/** A pruned descriptor remains readable for commit reconciliation but cannot be pinned. */
|
|
15
20
|
prunedAt?: string;
|
|
16
21
|
/**
|
|
@@ -24,34 +29,80 @@ export interface ManifestSummary {
|
|
|
24
29
|
count: number;
|
|
25
30
|
}>;
|
|
26
31
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
32
|
+
/** Public/cold manifest inspection is bounded metadata only. */
|
|
33
|
+
export type Manifest = ManifestSummary;
|
|
30
34
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
* One payload's bounded manifest-membership interval. The block is visible at version `v` iff
|
|
36
|
+
* `addedVersion <= v && (removedVersion === null || v < removedVersion)`. `byteLength` and the
|
|
37
|
+
* payload bytes are immutable while this record exists; `removedVersion`, when present, is
|
|
38
|
+
* strictly greater than `addedVersion`.
|
|
39
|
+
*
|
|
40
|
+
* A retired ID cannot be added again while this provenance record or a transaction/job that
|
|
41
|
+
* names it is retained. Once every readable/pinned version in the interval and every recovery
|
|
42
|
+
* root is gone, garbage collection removes payload and provenance together; no immortal ID
|
|
43
|
+
* tombstone is required.
|
|
37
44
|
*/
|
|
38
|
-
export interface
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
export
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
export interface ManifestBlockRecord {
|
|
46
|
+
readonly blockId: string;
|
|
47
|
+
readonly byteLength: number;
|
|
48
|
+
/** CRC-32 of the exact stored payload, computed once before the first durable write. */
|
|
49
|
+
readonly checksum: number;
|
|
50
|
+
readonly addedVersion: number;
|
|
51
|
+
readonly removedVersion: number | null;
|
|
52
|
+
}
|
|
53
|
+
export interface ListManifestBlockPageInput {
|
|
54
|
+
readonly version: number;
|
|
55
|
+
readonly afterBlockId: string | null;
|
|
56
|
+
readonly limit: number;
|
|
57
|
+
}
|
|
58
|
+
export interface ListRetiredManifestBlockPageInput {
|
|
59
|
+
/** Includes records retired at or before this published version. */
|
|
60
|
+
readonly removedThroughVersion: number;
|
|
61
|
+
readonly afterBlockId: string | null;
|
|
62
|
+
readonly limit: number;
|
|
63
|
+
}
|
|
64
|
+
export interface ManifestBlockPage {
|
|
65
|
+
readonly records: ReadonlyArray<Pick<ManifestBlockRecord, "blockId" | "byteLength" | "checksum">>;
|
|
66
|
+
readonly nextCursor: string | null;
|
|
67
|
+
}
|
|
68
|
+
/** Input for adapter-internal manifest construction; not a public store mutation. */
|
|
69
|
+
export interface CreateManifestInput {
|
|
70
|
+
changedTableIds: readonly string[];
|
|
51
71
|
expectedVersion: number | null;
|
|
52
|
-
|
|
72
|
+
liveBlockCount: number;
|
|
73
|
+
liveBlockBytes: number;
|
|
53
74
|
createdAt?: string;
|
|
54
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* The stored manifest is the same bounded summary returned publicly. Exact block membership is
|
|
78
|
+
* represented once by `ManifestBlockRecord` intervals; checkpoint/delta arrays are deliberately
|
|
79
|
+
* absent from the v1 layout.
|
|
80
|
+
*/
|
|
81
|
+
export type StoredManifestRecord = ManifestSummary;
|
|
82
|
+
/**
|
|
83
|
+
* One atomic user-table drop. The store compares both catalog and manifest revisions, derives
|
|
84
|
+
* every block that the table's segments still contribute to that exact manifest, publishes one
|
|
85
|
+
* successor without those blocks, and removes all table-owned metadata in the same durable
|
|
86
|
+
* step. Stored block payloads remain for lease-aware collection.
|
|
87
|
+
*/
|
|
88
|
+
export interface DropTableInput {
|
|
89
|
+
tableId: string;
|
|
90
|
+
expectedTableRevision: number;
|
|
91
|
+
expectedManifestVersion: number | null;
|
|
92
|
+
/** Catalog epoch of the complete dependency proof used to authorize this drop. */
|
|
93
|
+
expectedCatalogEpoch: number;
|
|
94
|
+
committedAt: string;
|
|
95
|
+
}
|
|
96
|
+
/** One atomic column retirement; see `CatalogStore.dropTableColumn`. */
|
|
97
|
+
export interface DropTableColumnInput {
|
|
98
|
+
tableId: string;
|
|
99
|
+
columnId: string;
|
|
100
|
+
expectedTableRevision: number;
|
|
101
|
+
expectedManifestVersion: number | null;
|
|
102
|
+
/** Catalog epoch of the complete dependency proof used to authorize this drop. */
|
|
103
|
+
expectedCatalogEpoch: number;
|
|
104
|
+
committedAt: string;
|
|
105
|
+
}
|
|
55
106
|
export declare const simpleDataTypes: readonly ["boolean", "number", "string", "datetime"];
|
|
56
107
|
export type SimpleDataType = (typeof simpleDataTypes)[number];
|
|
57
108
|
/** PostgreSQL logical domains layered over the four stable physical block encodings. */
|
|
@@ -124,6 +175,14 @@ export interface TableColumnRecord {
|
|
|
124
175
|
/** Engine-generated row-addressing column; stored and indexed, never exposed as SQL schema. */
|
|
125
176
|
hidden?: true;
|
|
126
177
|
}
|
|
178
|
+
export declare const MAX_TABLE_COLUMNS = 1024;
|
|
179
|
+
export declare const MAX_ENUM_VALUES = 4096;
|
|
180
|
+
export declare const MAX_SECONDARY_INDEXES = 1024;
|
|
181
|
+
export declare const MAX_TABLE_TRIGGERS = 256;
|
|
182
|
+
export declare const MAX_TRIGGER_STATEMENTS = 256;
|
|
183
|
+
export declare const MAX_TABLE_CONSTRAINTS = 1024;
|
|
184
|
+
export declare const MAX_TABLE_RECORD_CHARACTERS = 1048576;
|
|
185
|
+
export declare const MAX_TABLE_RECORD_ENTRIES = 65536;
|
|
127
186
|
/**
|
|
128
187
|
* The single authority on which enum declarations are legal, shared by the schema DSL's
|
|
129
188
|
* `column.enum()` and the engine's `createTable`: at least one value, every value a non-empty
|
|
@@ -178,18 +237,18 @@ export type SecondaryIndexDirection = "asc" | "desc";
|
|
|
178
237
|
*/
|
|
179
238
|
export interface SecondaryIndexRecord {
|
|
180
239
|
name: string;
|
|
181
|
-
/** First indexed column,
|
|
240
|
+
/** First indexed column, repeated for constant-time scalar catalog access. */
|
|
182
241
|
columnId: string;
|
|
183
|
-
/** Ordered key columns.
|
|
184
|
-
columnIds
|
|
185
|
-
/** Declared key direction per column.
|
|
186
|
-
directions
|
|
242
|
+
/** Ordered key columns. */
|
|
243
|
+
columnIds: string[];
|
|
244
|
+
/** Declared key direction per column. */
|
|
245
|
+
directions: SecondaryIndexDirection[];
|
|
187
246
|
/** SQL UNIQUE: enforced through an atomic, separately namespaced membership set. */
|
|
188
247
|
unique?: true;
|
|
189
248
|
/** The membership set has been seeded and must be enforced, independent of postings state. */
|
|
190
249
|
uniqueEnforced?: true;
|
|
191
|
-
/**
|
|
192
|
-
termEncoding
|
|
250
|
+
/** Prefix-free composite encoding used by every v1 secondary index. */
|
|
251
|
+
termEncoding: "tuple-v1";
|
|
193
252
|
storage: "postings-v1";
|
|
194
253
|
storageColumnId: string;
|
|
195
254
|
locator: "row-id" | "key-hash-v1";
|
|
@@ -199,6 +258,12 @@ export interface SecondaryIndexRecord {
|
|
|
199
258
|
/** Manifest version the base build covers; commit deltas above it merge at read time. */
|
|
200
259
|
buildFromVersion: number;
|
|
201
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Whether a secondary-index replacement changes the contract a staged writer must honor.
|
|
263
|
+
* Physical posting-build state is deliberately excluded: postings are only a reverified pruning
|
|
264
|
+
* accelerator. Index identity, key shape, and UNIQUE enforcement are structural.
|
|
265
|
+
*/
|
|
266
|
+
export declare function secondaryIndexWriteContractChanged(previous: Readonly<Record<string, SecondaryIndexRecord>> | null | undefined, next: Readonly<Record<string, SecondaryIndexRecord>> | null | undefined): boolean;
|
|
202
267
|
export interface TableRecord {
|
|
203
268
|
id: string;
|
|
204
269
|
name: string;
|
|
@@ -211,16 +276,14 @@ export interface TableRecord {
|
|
|
211
276
|
ftsColumns?: Record<string, FtsColumnIndexRecord>;
|
|
212
277
|
/** Durable secondary indexes keyed by stable index ID. */
|
|
213
278
|
secondaryIndexes?: Record<string, SecondaryIndexRecord>;
|
|
214
|
-
/** AFTER triggers on this table, fired by the committing writer
|
|
279
|
+
/** BEFORE/AFTER triggers on this table, fired by the committing writer in its transaction. */
|
|
215
280
|
triggers?: TriggerRecord[];
|
|
216
|
-
/** FOREIGN KEY constraints.
|
|
281
|
+
/** FOREIGN KEY constraints. Column tuples are always explicit, including scalar keys. */
|
|
217
282
|
foreignKeys?: Array<{
|
|
218
283
|
name: string;
|
|
219
|
-
|
|
220
|
-
columns?: string[];
|
|
284
|
+
columns: string[];
|
|
221
285
|
parentTable: string;
|
|
222
|
-
|
|
223
|
-
parentColumns?: string[];
|
|
286
|
+
parentColumns: string[];
|
|
224
287
|
onDelete: "restrict" | "cascade" | "set null";
|
|
225
288
|
}>;
|
|
226
289
|
/**
|
|
@@ -234,12 +297,10 @@ export interface TableRecord {
|
|
|
234
297
|
}>;
|
|
235
298
|
/**
|
|
236
299
|
* True when `migrate()` created this table from a schema declaration, which makes the schema
|
|
237
|
-
* authoritative over it: dropping the declaration may drop the table.
|
|
238
|
-
*
|
|
239
|
-
* migration removes it — the same rule views follow, and it matters more here because a
|
|
240
|
-
* table holds rows.
|
|
300
|
+
* authoritative over it: dropping the declaration may drop the table. `CREATE TABLE` records
|
|
301
|
+
* false explicitly.
|
|
241
302
|
*/
|
|
242
|
-
managed
|
|
303
|
+
managed: boolean;
|
|
243
304
|
/**
|
|
244
305
|
* A view rather than a table: the query text it stands for, and no segments of its own. The
|
|
245
306
|
* `columns` are the query's inferred output schema, so a view answers the same catalog
|
|
@@ -248,12 +309,10 @@ export interface TableRecord {
|
|
|
248
309
|
view?: {
|
|
249
310
|
sql: string;
|
|
250
311
|
/**
|
|
251
|
-
* True when `migrate()` created this view from a schema declaration
|
|
252
|
-
*
|
|
253
|
-
* `CREATE VIEW`, or one written before this field existed, is absent-or-false and no
|
|
254
|
-
* migration will remove it.
|
|
312
|
+
* True when `migrate()` created this view from a schema declaration. `CREATE VIEW` records
|
|
313
|
+
* false explicitly.
|
|
255
314
|
*/
|
|
256
|
-
managed
|
|
315
|
+
managed: boolean;
|
|
257
316
|
};
|
|
258
317
|
/** Internal catalog object backing CREATE TYPE ... AS ENUM; never exposed as a table. */
|
|
259
318
|
enumType?: {
|
|
@@ -267,23 +326,36 @@ export interface TableRecord {
|
|
|
267
326
|
columnId: string;
|
|
268
327
|
};
|
|
269
328
|
createdAt: string;
|
|
270
|
-
/** Compare-and-swap revision for catalog evolution
|
|
271
|
-
revision
|
|
329
|
+
/** Compare-and-swap revision for catalog evolution. */
|
|
330
|
+
revision: number;
|
|
272
331
|
}
|
|
332
|
+
/** Exact UTF-8 bytes used when the canonical record-wire JSON codec persists a table record. */
|
|
333
|
+
export declare function catalogRecordRetainedBytes(record: TableRecord): number;
|
|
334
|
+
export declare function manifestRecordRetainedBytes(record: Manifest): number;
|
|
335
|
+
/**
|
|
336
|
+
* Admission charge for one manifest summary, including the exact canonical tombstone bytes that
|
|
337
|
+
* later reclamation may add. Reserving them up front prevents quota deadlock at the byte ceiling.
|
|
338
|
+
*/
|
|
339
|
+
export declare function manifestRecordRetainedReservationBytes(record: Manifest): number;
|
|
340
|
+
export declare function segmentRecordRetainedBytes(record: SegmentRecord): number;
|
|
341
|
+
/** Hard catalog cardinality/text bounds shared by engine, adapters, checkpoints, and snapshots. */
|
|
342
|
+
export declare function validateTableRecordBounds(record: TableRecord): void;
|
|
273
343
|
/** Validates the durable identities and ownership rules of one table's secondary indexes. */
|
|
274
344
|
export declare function validateSecondaryIndexes(record: TableRecord): void;
|
|
275
|
-
/** Ordered catalog column IDs for
|
|
345
|
+
/** Ordered catalog column IDs for one canonical secondary-index record. */
|
|
276
346
|
export declare function secondaryIndexColumnIds(index: SecondaryIndexRecord): readonly string[];
|
|
277
|
-
/** Declared directions for
|
|
347
|
+
/** Declared directions for one canonical secondary-index record. */
|
|
278
348
|
export declare function secondaryIndexDirections(index: SecondaryIndexRecord): readonly SecondaryIndexDirection[];
|
|
279
349
|
/** Unique-membership namespace owned by one physical secondary index. */
|
|
280
350
|
export declare function secondaryUniqueKeyNamespace(tableId: string, indexId: string): string;
|
|
281
351
|
/**
|
|
282
|
-
* One
|
|
352
|
+
* One row trigger: catalog-persisted on its table record so the catalog epoch makes it
|
|
283
353
|
* visible to every tab immediately, and executed by the committing writer inside the same
|
|
284
354
|
* transaction as the triggering write — the write and its derivations publish atomically.
|
|
285
355
|
*/
|
|
286
356
|
export interface TriggerRecord {
|
|
357
|
+
/** Immutable durable identity. Names may be reused only after this trigger is gone. */
|
|
358
|
+
id: string;
|
|
287
359
|
name: string;
|
|
288
360
|
event: "insert" | "update" | "delete";
|
|
289
361
|
/**
|
|
@@ -312,7 +384,25 @@ export declare class TableRecordConflictError extends Error {
|
|
|
312
384
|
readonly name = "TableRecordConflictError";
|
|
313
385
|
constructor(tableId: string, expectedRevision: number, actualRevision: number | null);
|
|
314
386
|
}
|
|
387
|
+
/** A catalog drop lost a race with durable work that still owns records for the table. */
|
|
388
|
+
export declare class TableInUseError extends Error {
|
|
389
|
+
readonly tableId: string;
|
|
390
|
+
readonly ownerKind: "transaction" | "compaction job" | "foreign key" | "pending foreign key" | "accelerator build";
|
|
391
|
+
readonly ownerId: string;
|
|
392
|
+
readonly name = "TableInUseError";
|
|
393
|
+
constructor(tableId: string, ownerKind: "transaction" | "compaction job" | "foreign key" | "pending foreign key" | "accelerator build", ownerId: string);
|
|
394
|
+
}
|
|
395
|
+
/** Refuses a commit that would cross the persisted level-zero fragmentation safety ceiling. */
|
|
396
|
+
export declare class CompactionBacklogError extends Error {
|
|
397
|
+
readonly tableName: string;
|
|
398
|
+
readonly levelZeroSegments: number;
|
|
399
|
+
readonly limit: number;
|
|
400
|
+
readonly name = "CompactionBacklogError";
|
|
401
|
+
constructor(tableName: string, levelZeroSegments: number, limit: number);
|
|
402
|
+
}
|
|
315
403
|
export type SegmentKind = "insert" | "upsert" | "update" | "delete" | "base";
|
|
404
|
+
/** Absolute visible level-zero ceiling; every commit that adds L0 must enforce this or lower. */
|
|
405
|
+
export declare const MAX_LEVEL_ZERO_SEGMENTS = 4096;
|
|
316
406
|
/** Maps a contiguous segment-row run to its immutable hidden row IDs. */
|
|
317
407
|
export interface RowIdSpan {
|
|
318
408
|
readonly rowStart: number;
|
|
@@ -327,20 +417,17 @@ export interface SegmentRecord {
|
|
|
327
417
|
rowIdStart: bigint;
|
|
328
418
|
rowIdEndExclusive: bigint;
|
|
329
419
|
columnBlockIds: Record<string, string[]>;
|
|
330
|
-
kind
|
|
420
|
+
kind: SegmentKind;
|
|
331
421
|
keyColumnId?: string;
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
/** Missing on legacy records, where commit order supplies the logical order. */
|
|
335
|
-
logicalOrder?: number;
|
|
422
|
+
level: number;
|
|
423
|
+
logicalOrder: number;
|
|
336
424
|
/**
|
|
337
425
|
* Staging position inside the owning transaction. Orders segments of one commit relative
|
|
338
|
-
* to each other (an in-scope update must fold after the in-scope insert it patches)
|
|
339
|
-
* missing on legacy records, which never shared a key within one commit.
|
|
426
|
+
* to each other (an in-scope update must fold after the in-scope insert it patches).
|
|
340
427
|
*/
|
|
341
|
-
commitOrdinal
|
|
342
|
-
/**
|
|
343
|
-
rowIdSpans
|
|
428
|
+
commitOrdinal: number;
|
|
429
|
+
/** Empty for a contiguous row-ID envelope; merged bases record every retained range. */
|
|
430
|
+
rowIdSpans: readonly RowIdSpan[];
|
|
344
431
|
/** Monotone policy ordinal for an immutable append-row-range level-two partition. */
|
|
345
432
|
readonly partitionOrdinal?: number;
|
|
346
433
|
createdAt: string;
|
|
@@ -349,15 +436,82 @@ export interface RowIdRange {
|
|
|
349
436
|
start: bigint;
|
|
350
437
|
endExclusive: bigint;
|
|
351
438
|
}
|
|
439
|
+
/** Largest persisted row ID/posting value; the wire format is canonical unsigned 64-bit. */
|
|
440
|
+
export declare const MAX_ROW_ID: bigint;
|
|
441
|
+
/** One past `MAX_ROW_ID`, allowed only for exclusive range/counter ends. */
|
|
442
|
+
export declare const MAX_ROW_ID_EXCLUSIVE_END: bigint;
|
|
443
|
+
/** Auto-increment values are exposed as exact JavaScript numbers and therefore stop here. */
|
|
444
|
+
export declare const MAX_AUTO_INCREMENT_VALUE: bigint;
|
|
445
|
+
export declare const MAX_AUTO_INCREMENT_EXCLUSIVE_END: bigint;
|
|
352
446
|
export type LeaseKind = "reader" | "backup";
|
|
447
|
+
/** A live owner renews; an abandoned durable pin expires within one hour. */
|
|
448
|
+
export declare const MAX_LEASE_TTL_MS: number;
|
|
449
|
+
/** Durable resource ceilings; adapters sweep expired owners before atomically refusing creation. */
|
|
450
|
+
export declare const MAX_ACTIVE_LEASES = 4096;
|
|
451
|
+
export declare const MAX_ACTIVE_TEMP_OWNERS = 1024;
|
|
452
|
+
export declare const MAX_TEMP_RUNS_PER_OWNER = 1024;
|
|
453
|
+
export declare const MAX_TEMP_PAGES_PER_OWNER = 16384;
|
|
454
|
+
export declare const MAX_TEMP_RUNS_TOTAL = 65536;
|
|
455
|
+
export declare const MAX_TEMP_PAGES_TOTAL = 262144;
|
|
456
|
+
export declare const MAX_TEMP_BYTES_PER_OWNER: number;
|
|
457
|
+
export declare const MAX_TEMP_BYTES_TOTAL: number;
|
|
458
|
+
export declare const MAX_ACTIVE_COMPACTION_JOBS = 1024;
|
|
459
|
+
export declare const MAX_ACTIVE_GARBAGE_COLLECTION_JOBS = 1;
|
|
460
|
+
export declare const MAX_ACTIVE_UNIQUE_KEY_BUILDS = 1024;
|
|
461
|
+
export declare const MAX_ACTIVE_FTS_BASE_BUILDS = 128;
|
|
462
|
+
export declare const MAX_ACTIVE_SECONDARY_INDEX_BUILDS = 128;
|
|
463
|
+
export declare const MAX_ACCELERATOR_BUILD_STAGED_BYTES_TOTAL: number;
|
|
464
|
+
export declare const MAX_ACCELERATOR_BUILD_STAGED_ENTRIES_TOTAL = 16777216;
|
|
465
|
+
export declare const MAX_ACTIVE_TRANSACTIONS = 4096;
|
|
466
|
+
export declare const MAX_GLOBAL_STAGED_ARTIFACT_BYTES: number;
|
|
467
|
+
export declare const MAX_GLOBAL_STAGED_BLOCKS = 65536;
|
|
468
|
+
export declare const MAX_GLOBAL_STAGED_SEGMENTS = 65536;
|
|
469
|
+
/** Catalog enumeration remains bounded even for cold public inspection APIs. */
|
|
470
|
+
export declare const MAX_CATALOG_RECORDS = 4096;
|
|
471
|
+
/** Total canonical UTF-8 record-wire bytes retained by the durable catalog. */
|
|
472
|
+
export declare const MAX_CATALOG_RETAINED_BYTES: number;
|
|
473
|
+
export declare const MAX_MANIFEST_RECORDS = 65536;
|
|
474
|
+
export declare const MAX_MANIFEST_RETAINED_BYTES: number;
|
|
475
|
+
export declare const MAX_SEGMENT_RECORDS = 1048576;
|
|
476
|
+
export declare const MAX_SEGMENT_RETAINED_BYTES: number;
|
|
477
|
+
/** Durable diagnostic/provenance tails are pruned before admitting more terminal records. */
|
|
478
|
+
export declare const MAX_TERMINAL_TRANSACTION_RECORDS = 65536;
|
|
479
|
+
export declare const MAX_TERMINAL_COMPACTION_JOB_RECORDS = 4096;
|
|
480
|
+
export declare const MAX_COMPLETED_GARBAGE_COLLECTION_JOB_RECORDS = 1024;
|
|
481
|
+
/** An old renewable pin may not force unbounded history retention while writes continue. */
|
|
482
|
+
export declare const MAX_PINNED_MANIFEST_VERSION_LAG = 4096;
|
|
483
|
+
export declare const MAX_PINNED_RETIRED_BLOCKS = 65536;
|
|
484
|
+
export declare const MAX_PINNED_RETIRED_BYTES: number;
|
|
485
|
+
/** Total obsolete physical history is refused before it can consume an origin indefinitely. */
|
|
486
|
+
export declare const MAX_RETIRED_HISTORY_BYTES: number;
|
|
487
|
+
/** A durable resource family reached its fixed corruption/growth safety ceiling. */
|
|
488
|
+
export declare class StorageResourceLimitError extends Error {
|
|
489
|
+
readonly resource: "lease" | "temp owner" | "temp run" | "temp page" | "temporary run total" | "temporary page total" | "temp owner byte" | "temporary byte" | "compaction job" | "garbage collection job" | "unique-key build" | "full-text build" | "secondary-index build" | "accelerator build byte" | "accelerator build entry" | "transaction" | "staged artifact byte" | "staged block" | "staged segment" | "catalog record" | "catalog byte" | "manifest record" | "manifest byte" | "segment record" | "segment byte" | "terminal transaction" | "terminal compaction job" | "completed garbage collection job" | "pinned manifest version lag" | "pinned retired block" | "pinned retired byte" | "snapshot accelerator byte" | "snapshot accelerator entry" | "retired history byte";
|
|
490
|
+
readonly count: number;
|
|
491
|
+
readonly limit: number;
|
|
492
|
+
readonly name = "StorageResourceLimitError";
|
|
493
|
+
constructor(resource: "lease" | "temp owner" | "temp run" | "temp page" | "temporary run total" | "temporary page total" | "temp owner byte" | "temporary byte" | "compaction job" | "garbage collection job" | "unique-key build" | "full-text build" | "secondary-index build" | "accelerator build byte" | "accelerator build entry" | "transaction" | "staged artifact byte" | "staged block" | "staged segment" | "catalog record" | "catalog byte" | "manifest record" | "manifest byte" | "segment record" | "segment byte" | "terminal transaction" | "terminal compaction job" | "completed garbage collection job" | "pinned manifest version lag" | "pinned retired block" | "pinned retired byte" | "snapshot accelerator byte" | "snapshot accelerator entry" | "retired history byte", count: number, limit: number);
|
|
494
|
+
}
|
|
353
495
|
export interface LeaseRecord {
|
|
354
496
|
id: string;
|
|
355
497
|
kind: LeaseKind;
|
|
356
498
|
manifestVersion: number | null;
|
|
357
499
|
ownerId: string;
|
|
500
|
+
/** Issuance cutoff used to prove the initial expiry is bounded. */
|
|
501
|
+
createdAt: string;
|
|
358
502
|
expiresAt: string;
|
|
359
503
|
revision: number;
|
|
360
504
|
}
|
|
505
|
+
export interface RenewLeaseInput {
|
|
506
|
+
id: string;
|
|
507
|
+
expectedRevision: number;
|
|
508
|
+
/** A persisted expiry at or before this boundary is irrevocably expired. */
|
|
509
|
+
expiresAtCutoff: string;
|
|
510
|
+
expiresAt: string;
|
|
511
|
+
}
|
|
512
|
+
export interface MoveLeaseInput extends RenewLeaseInput {
|
|
513
|
+
manifestVersion: number | null;
|
|
514
|
+
}
|
|
361
515
|
export declare const compactionJobStates: readonly ["planned", "running", "ready", "published", "cancelled", "aborted"];
|
|
362
516
|
export type CompactionJobState = (typeof compactionJobStates)[number];
|
|
363
517
|
export interface CompactionJobCursor {
|
|
@@ -501,19 +655,18 @@ export interface CompactionJobRecord {
|
|
|
501
655
|
sourceStoredBytes: number;
|
|
502
656
|
outputStoredBytes: number;
|
|
503
657
|
logicalBytes: number;
|
|
504
|
-
|
|
505
|
-
readonly rewritePlan?: CompactionRewritePlan;
|
|
658
|
+
readonly rewritePlan: CompactionRewritePlan;
|
|
506
659
|
/** Null for copy-v1; points at the next output for rechunk-v1. */
|
|
507
|
-
outputCursor
|
|
660
|
+
outputCursor: CompactionOutputCursor | null;
|
|
508
661
|
/** Immutable execution budget. Zero for copy-v1 jobs. */
|
|
509
|
-
readonly memoryBudgetBytes
|
|
662
|
+
readonly memoryBudgetBytes: number;
|
|
510
663
|
/** Immutable planner estimate. Zero for copy-v1 jobs. */
|
|
511
|
-
readonly minimumMemoryBytes
|
|
512
|
-
/** Immutable stored bytes from newly promoted level-zero sources.
|
|
513
|
-
readonly level0SourceStoredBytes
|
|
514
|
-
/** Immutable stored bytes from the retained level-one anchor.
|
|
515
|
-
readonly anchorSourceStoredBytes
|
|
516
|
-
/** Output partition assigned by the append-row-range L2 policy.
|
|
664
|
+
readonly minimumMemoryBytes: number;
|
|
665
|
+
/** Immutable stored bytes from newly promoted level-zero sources. */
|
|
666
|
+
readonly level0SourceStoredBytes: number;
|
|
667
|
+
/** Immutable stored bytes from the retained level-one anchor. */
|
|
668
|
+
readonly anchorSourceStoredBytes: number;
|
|
669
|
+
/** Output partition assigned by the append-row-range L2 policy. */
|
|
517
670
|
readonly outputPartitionOrdinal?: number;
|
|
518
671
|
/** Immutable maximum compaction output bytes per newly promoted L0 byte. */
|
|
519
672
|
readonly maxWriteAmplification?: number;
|
|
@@ -527,8 +680,8 @@ export interface CompactionJobRecord {
|
|
|
527
680
|
* write-amplification budget.
|
|
528
681
|
*/
|
|
529
682
|
readonly priorAttemptOutputStoredBytes?: number;
|
|
530
|
-
peakWorkingBytes
|
|
531
|
-
outputLogicalBytes
|
|
683
|
+
peakWorkingBytes: number;
|
|
684
|
+
outputLogicalBytes: number;
|
|
532
685
|
targetLevel: number;
|
|
533
686
|
state: CompactionJobState;
|
|
534
687
|
transactionId: string | null;
|
|
@@ -556,6 +709,16 @@ export interface CompactionJobRecordUpdate {
|
|
|
556
709
|
updatedAt: string;
|
|
557
710
|
error?: string | null;
|
|
558
711
|
}
|
|
712
|
+
/** Every segment ID owned by a compaction job, including merge partition outputs. */
|
|
713
|
+
export declare function compactionOutputSegmentIds(job: Pick<CompactionJobRecord, "outputSegmentId" | "rewritePlan">): string[];
|
|
714
|
+
/**
|
|
715
|
+
* Proves that a compaction transaction stages exactly the immutable job output. This is kept in
|
|
716
|
+
* the storage contract (rather than only in the engine) so adapters reject forged, reordered, or
|
|
717
|
+
* partially journaled output before publication and while loading durable state.
|
|
718
|
+
*/
|
|
719
|
+
export declare function assertCompactionOutputProvenance(job: CompactionJobRecord, table: TableRecord, transaction: Pick<TransactionRecord, "id" | "pendingBlockIds" | "pendingSegmentIds">, sourceSegments: readonly SegmentRecord[], outputSegments: readonly SegmentRecord[], options?: {
|
|
720
|
+
readonly allowOutputPrefix?: boolean;
|
|
721
|
+
}): void;
|
|
559
722
|
export declare class CompactionJobConflictError extends Error {
|
|
560
723
|
readonly jobId: string;
|
|
561
724
|
readonly expectedRevision: number;
|
|
@@ -591,6 +754,52 @@ export interface CreateGarbageCollectionJobInput {
|
|
|
591
754
|
/** Fixed cutoff used to decide which persisted leases protect a manifest for this job. */
|
|
592
755
|
leaseCutoff: string;
|
|
593
756
|
createdAt: string;
|
|
757
|
+
/** Present while bounded discovery is still paging durable metadata. */
|
|
758
|
+
discovery?: GarbageCollectionDiscovery;
|
|
759
|
+
}
|
|
760
|
+
export type GarbageCollectionDiscoveryPhase = "manifests" | "manifest-blocks" | "segments" | "transactions" | "compactions" | "complete";
|
|
761
|
+
export interface GarbageCollectionDiscovery {
|
|
762
|
+
phase: GarbageCollectionDiscoveryPhase;
|
|
763
|
+
currentManifestVersion: number | null;
|
|
764
|
+
retainAboveVersion: number;
|
|
765
|
+
retainAfter: number;
|
|
766
|
+
maxPlanningItems: number;
|
|
767
|
+
manifestCursor: number | null;
|
|
768
|
+
segmentCursor: string | null;
|
|
769
|
+
transactionCursor: string | null;
|
|
770
|
+
compactionCursor: string | null;
|
|
771
|
+
visitedRecords: number;
|
|
772
|
+
/**
|
|
773
|
+
* When a bounded candidate array fills, reclamation completes this job and the next job
|
|
774
|
+
* resumes this discovery phase instead of restarting at the beginning.
|
|
775
|
+
*/
|
|
776
|
+
resumePhase?: Exclude<GarbageCollectionDiscoveryPhase, "complete"> | null;
|
|
777
|
+
/** Older continuation resumed only after this job first discovers newly eligible manifests. */
|
|
778
|
+
postManifestPhase?: Exclude<GarbageCollectionDiscoveryPhase, "complete" | "manifests"> | null;
|
|
779
|
+
/** Exact within-record provenance offset; every named artifact is examined at most once. */
|
|
780
|
+
artifactCursor?: GarbageCollectionArtifactCursor | null;
|
|
781
|
+
}
|
|
782
|
+
export interface GarbageCollectionArtifactCursor {
|
|
783
|
+
family: "manifest" | "transaction" | "compaction";
|
|
784
|
+
/** Decimal manifest version for `manifest`; durable record ID for the other families. */
|
|
785
|
+
recordId: string;
|
|
786
|
+
/** Exact lexical manifest-membership cursor; null for transaction/compaction arrays. */
|
|
787
|
+
blockId: string | null;
|
|
788
|
+
blockIndex: number;
|
|
789
|
+
segmentIndex: number;
|
|
790
|
+
}
|
|
791
|
+
/** Absolute per-call bound for durable maintenance candidate arrays and storage transactions. */
|
|
792
|
+
export declare const MAX_MAINTENANCE_BATCH_ITEMS = 1024;
|
|
793
|
+
export declare function boundedMaintenanceBatchItems(value: number, label: string): number;
|
|
794
|
+
export interface UpdateGarbageCollectionPlanningInput {
|
|
795
|
+
jobId: string;
|
|
796
|
+
expectedRevision: number;
|
|
797
|
+
candidateManifestVersions?: readonly number[];
|
|
798
|
+
candidateSegmentIds?: readonly string[];
|
|
799
|
+
candidateBlockIds?: readonly string[];
|
|
800
|
+
candidateTransactionIds?: readonly string[];
|
|
801
|
+
discovery: GarbageCollectionDiscovery;
|
|
802
|
+
updatedAt: string;
|
|
594
803
|
}
|
|
595
804
|
export interface GarbageCollectionJobRecord {
|
|
596
805
|
id: string;
|
|
@@ -618,6 +827,8 @@ export interface GarbageCollectionJobRecord {
|
|
|
618
827
|
leaseCutoff: string;
|
|
619
828
|
createdAt: string;
|
|
620
829
|
updatedAt: string;
|
|
830
|
+
/** Omitted only for explicitly supplied bounded candidate jobs; no discovery scan is needed. */
|
|
831
|
+
discovery?: GarbageCollectionDiscovery;
|
|
621
832
|
}
|
|
622
833
|
export interface RunGarbageCollectionStepInput {
|
|
623
834
|
jobId: string;
|
|
@@ -686,9 +897,29 @@ export declare class LeaseConflictError extends Error {
|
|
|
686
897
|
readonly name = "LeaseConflictError";
|
|
687
898
|
constructor(leaseId: string, expectedRevision: number, actualRevision: number | null);
|
|
688
899
|
}
|
|
900
|
+
/** A renewal/move cutoff reached the persisted expiry; expiry is irrevocable. */
|
|
901
|
+
export declare class LeaseExpiredError extends Error {
|
|
902
|
+
readonly leaseId: string;
|
|
903
|
+
readonly expiresAt: string;
|
|
904
|
+
readonly expiresAtCutoff: string;
|
|
905
|
+
readonly name = "LeaseExpiredError";
|
|
906
|
+
constructor(leaseId: string, expiresAt: string, expiresAtCutoff: string);
|
|
907
|
+
}
|
|
908
|
+
/** Refuses a lease release from a different durable owner. */
|
|
909
|
+
export declare class LeaseOwnerConflictError extends Error {
|
|
910
|
+
readonly leaseId: string;
|
|
911
|
+
readonly expectedOwnerId: string;
|
|
912
|
+
readonly actualOwnerId: string;
|
|
913
|
+
readonly name = "LeaseOwnerConflictError";
|
|
914
|
+
constructor(leaseId: string, expectedOwnerId: string, actualOwnerId: string);
|
|
915
|
+
}
|
|
689
916
|
export type TransactionStatus = "active" | "committed" | "aborted";
|
|
690
917
|
export interface TransactionRecord {
|
|
691
918
|
id: string;
|
|
919
|
+
/** Stable writer identity; liveness renewals never contend on the data revision. */
|
|
920
|
+
ownerId: string;
|
|
921
|
+
/** Durable writer liveness deadline. Expired active records are atomically aborted by GC. */
|
|
922
|
+
expiresAt: string;
|
|
692
923
|
snapshotVersion: number | null;
|
|
693
924
|
pendingBlockIds: string[];
|
|
694
925
|
pendingSegmentIds: string[];
|
|
@@ -697,6 +928,33 @@ export interface TransactionRecord {
|
|
|
697
928
|
startedAt: string;
|
|
698
929
|
updatedAt: string;
|
|
699
930
|
committedVersion: number | null;
|
|
931
|
+
/**
|
|
932
|
+
* Structural catalog epoch captured atomically with the transaction snapshot. Every active
|
|
933
|
+
* transaction carries this storage-owned guard; commit rejects it if DDL changed the schema
|
|
934
|
+
* used to prepare the staged artifacts. Terminal records drop the guard.
|
|
935
|
+
*/
|
|
936
|
+
schemaEpochGuard?: number;
|
|
937
|
+
/**
|
|
938
|
+
* Catalog record owned exclusively by this active transaction. It is invisible to catalog
|
|
939
|
+
* reads until commit; abort/expiry discards the reservation with the transaction.
|
|
940
|
+
*/
|
|
941
|
+
pendingTable?: TableRecord;
|
|
942
|
+
/** Next row id for the pending table, advanced atomically as insert artifacts stage. */
|
|
943
|
+
pendingTableNextRowId?: bigint;
|
|
944
|
+
/** Catalog epoch captured atomically when the pending table was admitted. */
|
|
945
|
+
catalogEpochGuard?: number;
|
|
946
|
+
}
|
|
947
|
+
export interface AbortTransactionIfExpiredInput {
|
|
948
|
+
transactionId: string;
|
|
949
|
+
expectedOwnerId: string;
|
|
950
|
+
expiresAtCutoff: string;
|
|
951
|
+
updatedAt: string;
|
|
952
|
+
}
|
|
953
|
+
export interface RenewTransactionInput {
|
|
954
|
+
transactionId: string;
|
|
955
|
+
ownerId: string;
|
|
956
|
+
expiresAtCutoff: string;
|
|
957
|
+
expiresAt: string;
|
|
700
958
|
}
|
|
701
959
|
export interface TransactionRecordUpdate {
|
|
702
960
|
snapshotVersion?: number | null;
|
|
@@ -705,10 +963,15 @@ export interface TransactionRecordUpdate {
|
|
|
705
963
|
status?: TransactionStatus;
|
|
706
964
|
updatedAt: string;
|
|
707
965
|
committedVersion?: number | null;
|
|
966
|
+
/** Storage-owned advancement while staging rows for a pending table. */
|
|
967
|
+
pendingTableNextRowId?: bigint;
|
|
708
968
|
}
|
|
709
969
|
export interface BeginTransactionInput {
|
|
710
|
-
/**
|
|
711
|
-
|
|
970
|
+
/**
|
|
971
|
+
* Record to create; the store atomically stamps both `snapshotVersion` and
|
|
972
|
+
* `schemaEpochGuard` from its current state.
|
|
973
|
+
*/
|
|
974
|
+
record: Omit<TransactionRecord, "snapshotVersion" | "schemaEpochGuard">;
|
|
712
975
|
/** Reserve this many row ids for the table in the same atomic step. */
|
|
713
976
|
reserveRowIds?: {
|
|
714
977
|
tableId: string;
|
|
@@ -724,6 +987,15 @@ export interface BeginTransactionInput {
|
|
|
724
987
|
count: number;
|
|
725
988
|
atLeast?: bigint;
|
|
726
989
|
};
|
|
990
|
+
/**
|
|
991
|
+
* Reserves one invisible catalog record and its initial row-id state in the same atomic step.
|
|
992
|
+
* The expected epoch closes schema/FK races between planning and begin; commit rechecks it.
|
|
993
|
+
*/
|
|
994
|
+
pendingTable?: {
|
|
995
|
+
record: TableRecord;
|
|
996
|
+
nextRowId: bigint;
|
|
997
|
+
expectedCatalogEpoch: number;
|
|
998
|
+
};
|
|
727
999
|
}
|
|
728
1000
|
export interface BeginTransactionResult {
|
|
729
1001
|
record: TransactionRecord;
|
|
@@ -737,6 +1009,332 @@ export interface StageTransactionArtifactsInput {
|
|
|
737
1009
|
segments: readonly SegmentRecord[];
|
|
738
1010
|
updatedAt: string;
|
|
739
1011
|
}
|
|
1012
|
+
/** Maximum immutable payloads accepted by one atomic staging/WAL operation. */
|
|
1013
|
+
export declare const MAX_TRANSACTION_STAGE_BLOCKS = 64;
|
|
1014
|
+
/** Maximum segment records accepted by one atomic staging/WAL operation. */
|
|
1015
|
+
export declare const MAX_TRANSACTION_STAGE_SEGMENTS = 64;
|
|
1016
|
+
/**
|
|
1017
|
+
* Maximum block bytes accepted by one atomic staging/WAL operation. The limit still admits one
|
|
1018
|
+
* maximum-size physical block; callers split collections of smaller blocks into bounded calls.
|
|
1019
|
+
*/
|
|
1020
|
+
export declare const MAX_TRANSACTION_STAGE_BYTES: number;
|
|
1021
|
+
/** Durable journal ceilings prevent a forgotten or hostile transaction growing without bound. */
|
|
1022
|
+
export declare const MAX_TRANSACTION_PENDING_BLOCKS = 4096;
|
|
1023
|
+
export declare const MAX_TRANSACTION_PENDING_SEGMENTS = 4096;
|
|
1024
|
+
/** Storage-boundary preflight shared by staging and single-shot write implementations. */
|
|
1025
|
+
export declare function assertTransactionArtifactBatchLimits(blocks: readonly BlockWrite[], segments: readonly SegmentRecord[]): void;
|
|
1026
|
+
/** Preflight for the complete persisted journal after a bounded staging operation. */
|
|
1027
|
+
export declare function assertTransactionArtifactJournalLimits(pendingBlockIds: readonly string[], pendingSegmentIds: readonly string[]): void;
|
|
1028
|
+
/**
|
|
1029
|
+
* Atomically rewinds one active transaction's artifact journal to an earlier set and removes
|
|
1030
|
+
* exactly the artifacts that are no longer reachable. Journals are canonically sorted, so an
|
|
1031
|
+
* adapter validates the retained and removed lists as a duplicate-free, disjoint, exact
|
|
1032
|
+
* partition of its current journal before changing records or bytes.
|
|
1033
|
+
*/
|
|
1034
|
+
export interface RollbackTransactionArtifactsInput {
|
|
1035
|
+
transactionId: string;
|
|
1036
|
+
expectedRevision: number;
|
|
1037
|
+
pendingBlockIds: readonly string[];
|
|
1038
|
+
pendingSegmentIds: readonly string[];
|
|
1039
|
+
removeBlockIds: readonly string[];
|
|
1040
|
+
removeSegmentIds: readonly string[];
|
|
1041
|
+
updatedAt: string;
|
|
1042
|
+
}
|
|
1043
|
+
export type StorageIntegrityMode = "metadata" | "full";
|
|
1044
|
+
export interface StorageIntegrityIssue {
|
|
1045
|
+
readonly code: string;
|
|
1046
|
+
readonly location: string;
|
|
1047
|
+
readonly message: string;
|
|
1048
|
+
}
|
|
1049
|
+
export interface StorageIntegrityReport {
|
|
1050
|
+
readonly mode: StorageIntegrityMode;
|
|
1051
|
+
readonly ok: boolean;
|
|
1052
|
+
readonly checkedRecords: number;
|
|
1053
|
+
readonly checkedBlocks: number;
|
|
1054
|
+
readonly checkedBytes: number;
|
|
1055
|
+
/** Total findings; `issues` itself is bounded by `maxIssues`. */
|
|
1056
|
+
readonly issueCount: number;
|
|
1057
|
+
readonly issues: readonly StorageIntegrityIssue[];
|
|
1058
|
+
}
|
|
1059
|
+
export interface StorageStats {
|
|
1060
|
+
readonly backend: string;
|
|
1061
|
+
/** Bytes reachable as current database records or payloads. */
|
|
1062
|
+
readonly logicalBytes: number;
|
|
1063
|
+
/** Actual substrate allocation where available; IndexedDB cannot report this per database. */
|
|
1064
|
+
readonly physicalBytes: number | null;
|
|
1065
|
+
readonly liveBlockCount: number;
|
|
1066
|
+
/** Stored payloads outside the current manifest, including staged and retired bytes. */
|
|
1067
|
+
readonly obsoleteBlockCount: number;
|
|
1068
|
+
readonly liveBlockBytes: number;
|
|
1069
|
+
readonly obsoleteBlockBytes: number;
|
|
1070
|
+
readonly temporaryBytes: number;
|
|
1071
|
+
readonly walBytes: number | null;
|
|
1072
|
+
readonly checkpointBytes: number | null;
|
|
1073
|
+
readonly orphanBytes: number | null;
|
|
1074
|
+
readonly manifestCount: number;
|
|
1075
|
+
readonly transactionCount: number;
|
|
1076
|
+
readonly segmentCount: number;
|
|
1077
|
+
readonly maintenance?: {
|
|
1078
|
+
readonly degraded: boolean;
|
|
1079
|
+
readonly consecutiveFailures: number;
|
|
1080
|
+
readonly lastError: string | null;
|
|
1081
|
+
readonly walLimitBytes: number | null;
|
|
1082
|
+
/** Durable garbage awaiting safe physical deletion, when the substrate separates the two. */
|
|
1083
|
+
readonly cleanupDebtBytes: number | null;
|
|
1084
|
+
/** Refusal/backpressure ceiling for cleanup debt, or null when the substrate has no debt. */
|
|
1085
|
+
readonly cleanupLimitBytes: number | null;
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
export interface InterruptedSnapshotImport {
|
|
1089
|
+
readonly identity: string;
|
|
1090
|
+
readonly version: number;
|
|
1091
|
+
readonly createdAt: string;
|
|
1092
|
+
readonly stagedBlockCount: number;
|
|
1093
|
+
readonly stagedBytes: number;
|
|
1094
|
+
}
|
|
1095
|
+
export interface InterruptedSnapshotImportAbortResult {
|
|
1096
|
+
readonly identity: string;
|
|
1097
|
+
readonly removedBlockCount: number;
|
|
1098
|
+
readonly removedBytes: number;
|
|
1099
|
+
}
|
|
1100
|
+
/** A snapshot session is renewable but can never pin storage for more than one hour unattended. */
|
|
1101
|
+
export declare const MAX_SNAPSHOT_SESSION_TTL_MS: number;
|
|
1102
|
+
/** Snapshot v1 is an ordered bounded record stream; no database-sized collection is in header. */
|
|
1103
|
+
export declare const SNAPSHOT_FRAME_KINDS: readonly ["catalog-page", "segment-page", "transaction-page", "unique-page", "posting-page", "block"];
|
|
1104
|
+
export type SnapshotFrameKind = (typeof SNAPSHOT_FRAME_KINDS)[number];
|
|
1105
|
+
export declare const MAX_SNAPSHOT_FRAME_ITEMS = 1024;
|
|
1106
|
+
export declare const MAX_SNAPSHOT_METADATA_FRAME_BYTES: number;
|
|
1107
|
+
export declare const MAX_SNAPSHOT_FRAME_BATCH_ITEMS = 64;
|
|
1108
|
+
export declare const MAX_SNAPSHOT_METADATA_BATCH_BYTES: number;
|
|
1109
|
+
/** One block frame is permitted; metadata frames still use MAX_SNAPSHOT_METADATA_BATCH_BYTES. */
|
|
1110
|
+
export declare const MAX_SNAPSHOT_FRAME_BATCH_BYTES: number;
|
|
1111
|
+
/**
|
|
1112
|
+
* Framed restore builds accelerator generations in a disposable core before one atomic publish.
|
|
1113
|
+
* These aggregate ceilings keep that validation heap bounded until generations become a native
|
|
1114
|
+
* chunk-backed structure rather than one materialized in-memory collection.
|
|
1115
|
+
*/
|
|
1116
|
+
export declare const MAX_SNAPSHOT_IMPORT_ACCELERATOR_RETAINED_BYTES: number;
|
|
1117
|
+
export declare const MAX_SNAPSHOT_IMPORT_ACCELERATOR_RETAINED_ENTRIES = 16777216;
|
|
1118
|
+
export interface SnapshotKindSummary {
|
|
1119
|
+
readonly frameCount: number;
|
|
1120
|
+
readonly itemCount: number;
|
|
1121
|
+
readonly storedBytes: number;
|
|
1122
|
+
}
|
|
1123
|
+
/** One table plus its durable allocation counters; memberships/postings are separate pages. */
|
|
1124
|
+
export interface SnapshotCatalogItem {
|
|
1125
|
+
readonly kind: "table";
|
|
1126
|
+
readonly record: TableRecord;
|
|
1127
|
+
readonly nextRowId: bigint;
|
|
1128
|
+
readonly autoIncrement: ReadonlyArray<{
|
|
1129
|
+
readonly columnId: string;
|
|
1130
|
+
readonly next: bigint;
|
|
1131
|
+
}>;
|
|
1132
|
+
}
|
|
1133
|
+
export interface SnapshotSegmentItem {
|
|
1134
|
+
readonly kind: "segment";
|
|
1135
|
+
readonly record: SegmentRecord;
|
|
1136
|
+
}
|
|
1137
|
+
export interface SnapshotTransactionItem {
|
|
1138
|
+
readonly kind: "transaction";
|
|
1139
|
+
readonly record: TransactionRecord;
|
|
1140
|
+
}
|
|
1141
|
+
/** Descriptor precedes this generation's chunks; tokens are globally strict lexical order. */
|
|
1142
|
+
export interface SnapshotUniqueGenerationItem {
|
|
1143
|
+
readonly kind: "unique-generation";
|
|
1144
|
+
readonly tableId: string;
|
|
1145
|
+
readonly indexId: string | null;
|
|
1146
|
+
readonly namespaceId: string;
|
|
1147
|
+
readonly generationId: string;
|
|
1148
|
+
readonly chunkCount: number;
|
|
1149
|
+
readonly tokenCount: number;
|
|
1150
|
+
}
|
|
1151
|
+
export interface SnapshotUniqueChunkItem {
|
|
1152
|
+
readonly kind: "unique-chunk";
|
|
1153
|
+
readonly namespaceId: string;
|
|
1154
|
+
readonly generationId: string;
|
|
1155
|
+
readonly ordinal: number;
|
|
1156
|
+
readonly keyTokens: readonly string[];
|
|
1157
|
+
}
|
|
1158
|
+
export type SnapshotUniqueItem = SnapshotUniqueGenerationItem | SnapshotUniqueChunkItem;
|
|
1159
|
+
/**
|
|
1160
|
+
* Complete canonical postings generation at the captured version. Both full-text and scalar
|
|
1161
|
+
* secondary accelerators use this base format; deltas are merged during bounded export, so a
|
|
1162
|
+
* restore never needs pre-snapshot history.
|
|
1163
|
+
*/
|
|
1164
|
+
export interface SnapshotPostingGenerationItem {
|
|
1165
|
+
readonly kind: "posting-generation";
|
|
1166
|
+
readonly tableId: string;
|
|
1167
|
+
readonly ownerKind: "fts-column" | "secondary-index";
|
|
1168
|
+
readonly ownerId: string;
|
|
1169
|
+
readonly storageColumnId: string;
|
|
1170
|
+
readonly generationId: string;
|
|
1171
|
+
readonly coversVersion: number;
|
|
1172
|
+
readonly chunkCount: number;
|
|
1173
|
+
/** Exact safe sum of every posting frequency; secondary-index frequencies are always one. */
|
|
1174
|
+
readonly totalTokens: number;
|
|
1175
|
+
}
|
|
1176
|
+
export interface SnapshotPostingChunkItem {
|
|
1177
|
+
readonly kind: "posting-chunk";
|
|
1178
|
+
readonly storageColumnId: string;
|
|
1179
|
+
readonly generationId: string;
|
|
1180
|
+
readonly ordinal: number;
|
|
1181
|
+
readonly postings: readonly FtsPosting[];
|
|
1182
|
+
}
|
|
1183
|
+
export type SnapshotPostingItem = SnapshotPostingGenerationItem | SnapshotPostingChunkItem;
|
|
1184
|
+
export type SnapshotMetadataItem = SnapshotCatalogItem | SnapshotSegmentItem | SnapshotTransactionItem | SnapshotUniqueItem | SnapshotPostingItem;
|
|
1185
|
+
/** Modeled heap retained by one framed accelerator chunk during atomic snapshot validation. */
|
|
1186
|
+
export declare function snapshotAcceleratorItemRetainedUsage(item: SnapshotUniqueChunkItem | SnapshotPostingChunkItem): {
|
|
1187
|
+
bytes: number;
|
|
1188
|
+
entries: number;
|
|
1189
|
+
};
|
|
1190
|
+
/** Shared arithmetic boundary used by streaming adapters and allocation-free cap tests. */
|
|
1191
|
+
export declare function assertSnapshotImportAcceleratorUsage(bytes: number, entries: number): void;
|
|
1192
|
+
/**
|
|
1193
|
+
* Canonical compressed container header. It remains O(1) with database size: the six entries
|
|
1194
|
+
* below contain counts and byte totals only, never record descriptors, keys, or postings.
|
|
1195
|
+
*/
|
|
1196
|
+
export interface SnapshotFrameStreamHeader {
|
|
1197
|
+
readonly formatVersion: 1;
|
|
1198
|
+
readonly databaseVersion: number;
|
|
1199
|
+
readonly createdAt: string;
|
|
1200
|
+
readonly kinds: Readonly<Record<SnapshotFrameKind, SnapshotKindSummary>>;
|
|
1201
|
+
}
|
|
1202
|
+
/**
|
|
1203
|
+
* One exact body frame. Frames are globally contiguous by `sequence` and grouped in
|
|
1204
|
+
* `SNAPSHOT_FRAME_KINDS` order. Within kinds, tables/segments/transactions/blocks order by ID;
|
|
1205
|
+
* UNIQUE generations order by namespace (descriptor, then contiguous chunk ordinals), and
|
|
1206
|
+
* posting generations by storageColumnId using the same descriptor/chunk rule. Metadata
|
|
1207
|
+
* payloads use canonical adapter encoding and contain at
|
|
1208
|
+
* most MAX_SNAPSHOT_FRAME_ITEMS/MAX_SNAPSHOT_METADATA_FRAME_BYTES; a block frame contains one
|
|
1209
|
+
* ID plus one stored block and may use MAX_STORED_BLOCK_BYTE_LENGTH. `checksum` covers the exact
|
|
1210
|
+
* payload. Metadata payloads use the single core-owned snapshot wire codec; adapters must not
|
|
1211
|
+
* substitute substrate encodings. Lost-ack replay must additionally compare the complete
|
|
1212
|
+
* persisted bytes.
|
|
1213
|
+
*/
|
|
1214
|
+
export interface SnapshotFrame {
|
|
1215
|
+
readonly sequence: number;
|
|
1216
|
+
readonly kind: SnapshotFrameKind;
|
|
1217
|
+
readonly itemCount: number;
|
|
1218
|
+
/** Block ID for a block frame; null for core-wire-encoded metadata pages. */
|
|
1219
|
+
readonly key: string | null;
|
|
1220
|
+
readonly payload: Uint8Array;
|
|
1221
|
+
readonly checksum: number;
|
|
1222
|
+
}
|
|
1223
|
+
export interface SnapshotFrameFooter {
|
|
1224
|
+
readonly frameCount: number;
|
|
1225
|
+
readonly itemCount: number;
|
|
1226
|
+
readonly storedBytes: number;
|
|
1227
|
+
/** Rolling checksum over every canonical frame header and payload in sequence order. */
|
|
1228
|
+
readonly checksum: number;
|
|
1229
|
+
}
|
|
1230
|
+
export interface BeginSnapshotFrameExportInput {
|
|
1231
|
+
readonly ownerId: string;
|
|
1232
|
+
readonly createdAt: string;
|
|
1233
|
+
readonly expiresAt: string;
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Export begin atomically captures a frozen catalog/segment/transaction/accelerator generation
|
|
1237
|
+
* into bounded durable pages and records only an exact manifest version/cursor for blocks (it
|
|
1238
|
+
* must not copy block descriptors). It creates the backup lease in the same operation.
|
|
1239
|
+
* Catalog-only writes after begin cannot change the session.
|
|
1240
|
+
*/
|
|
1241
|
+
export interface SnapshotFrameExportSession {
|
|
1242
|
+
readonly sessionId: string;
|
|
1243
|
+
readonly ownerId: string;
|
|
1244
|
+
readonly expiresAt: string;
|
|
1245
|
+
readonly header: SnapshotFrameStreamHeader;
|
|
1246
|
+
}
|
|
1247
|
+
export interface ReadSnapshotExportFrameInput {
|
|
1248
|
+
readonly sessionId: string;
|
|
1249
|
+
readonly ownerId: string;
|
|
1250
|
+
readonly sequence: number;
|
|
1251
|
+
readonly expiresAtCutoff: string;
|
|
1252
|
+
readonly expiresAt: string;
|
|
1253
|
+
}
|
|
1254
|
+
export interface BeginSnapshotFrameImportInput {
|
|
1255
|
+
readonly identity: string;
|
|
1256
|
+
readonly ownerId: string;
|
|
1257
|
+
readonly createdAt: string;
|
|
1258
|
+
readonly expiresAt: string;
|
|
1259
|
+
readonly header: SnapshotFrameStreamHeader;
|
|
1260
|
+
}
|
|
1261
|
+
export interface SnapshotFrameImportSession {
|
|
1262
|
+
readonly identity: string;
|
|
1263
|
+
readonly ownerId: string;
|
|
1264
|
+
readonly version: number;
|
|
1265
|
+
readonly createdAt: string;
|
|
1266
|
+
readonly expiresAt: string;
|
|
1267
|
+
readonly nextSequence: number;
|
|
1268
|
+
readonly stagedBytes: number;
|
|
1269
|
+
}
|
|
1270
|
+
export interface RenewSnapshotFrameImportInput {
|
|
1271
|
+
readonly identity: string;
|
|
1272
|
+
readonly ownerId: string;
|
|
1273
|
+
readonly expiresAtCutoff: string;
|
|
1274
|
+
readonly expiresAt: string;
|
|
1275
|
+
}
|
|
1276
|
+
export interface AppendSnapshotImportFramesInput extends RenewSnapshotFrameImportInput {
|
|
1277
|
+
/** Bounded contiguous frames; replayed sequences compare complete persisted bytes. */
|
|
1278
|
+
readonly frames: readonly SnapshotFrame[];
|
|
1279
|
+
}
|
|
1280
|
+
export interface FinishSnapshotFrameImportInput {
|
|
1281
|
+
readonly identity: string;
|
|
1282
|
+
readonly ownerId: string;
|
|
1283
|
+
readonly expiresAtCutoff: string;
|
|
1284
|
+
readonly footer: SnapshotFrameFooter;
|
|
1285
|
+
}
|
|
1286
|
+
export interface CloseSnapshotExportInput {
|
|
1287
|
+
readonly sessionId: string;
|
|
1288
|
+
readonly ownerId: string;
|
|
1289
|
+
}
|
|
1290
|
+
export interface CancelSnapshotImportInput {
|
|
1291
|
+
readonly identity: string;
|
|
1292
|
+
readonly ownerId: string;
|
|
1293
|
+
}
|
|
1294
|
+
export declare class SnapshotImportConflictError extends Error {
|
|
1295
|
+
readonly identity: string;
|
|
1296
|
+
readonly ownerId: string;
|
|
1297
|
+
readonly name = "SnapshotImportConflictError";
|
|
1298
|
+
constructor(identity: string, ownerId: string, message: string);
|
|
1299
|
+
}
|
|
1300
|
+
/**
|
|
1301
|
+
* Persisted bytes belong to a recognized storage family, but not to the version this reader
|
|
1302
|
+
* supports. This is deliberately distinct from corruption: callers must not infer that repair,
|
|
1303
|
+
* recreation, or deletion is safe merely because versions differ.
|
|
1304
|
+
*/
|
|
1305
|
+
export declare class StorageFormatVersionError extends Error {
|
|
1306
|
+
readonly backend: string;
|
|
1307
|
+
readonly location: string;
|
|
1308
|
+
readonly actualVersion: number | null;
|
|
1309
|
+
readonly supportedVersion: number;
|
|
1310
|
+
readonly relation: "older" | "newer";
|
|
1311
|
+
readonly name = "StorageFormatVersionError";
|
|
1312
|
+
constructor(backend: string, location: string, actualVersion: number | null, supportedVersion: number, relation: "older" | "newer");
|
|
1313
|
+
}
|
|
1314
|
+
/** A native IndexedDB schema upgrade is waiting for another connection to close. */
|
|
1315
|
+
export declare class IndexedDbSchemaUpgradeBlockedError extends Error {
|
|
1316
|
+
readonly databaseName: string;
|
|
1317
|
+
readonly oldVersion: number;
|
|
1318
|
+
readonly requestedVersion: number;
|
|
1319
|
+
readonly name = "IndexedDbSchemaUpgradeBlockedError";
|
|
1320
|
+
constructor(databaseName: string, oldVersion: number, requestedVersion: number);
|
|
1321
|
+
}
|
|
1322
|
+
/** Persisted metadata or payload failed an adapter's fail-closed integrity checks. */
|
|
1323
|
+
export declare class StorageCorruptionError extends Error {
|
|
1324
|
+
readonly backend: string;
|
|
1325
|
+
readonly location: string;
|
|
1326
|
+
readonly name = "StorageCorruptionError";
|
|
1327
|
+
constructor(backend: string, location: string, message: string);
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* A remote OPFS leader may have committed a mutation whose acknowledgement was lost.
|
|
1331
|
+
* Reconcile stable identities or revisions before retrying the named operation.
|
|
1332
|
+
*/
|
|
1333
|
+
export declare class OpfsUncertainOutcomeError extends Error {
|
|
1334
|
+
readonly method: string;
|
|
1335
|
+
readonly name = "OpfsUncertainOutcomeError";
|
|
1336
|
+
constructor(method: string);
|
|
1337
|
+
}
|
|
740
1338
|
/**
|
|
741
1339
|
* The commit input carries only the change: added blocks are the transaction's journaled pending
|
|
742
1340
|
* blocks, removals are the superseded ids. The store derives the published manifest from its
|
|
@@ -747,7 +1345,22 @@ export interface CommitTransactionInput {
|
|
|
747
1345
|
changedTableIds?: readonly string[];
|
|
748
1346
|
expectedTransactionRevision: number;
|
|
749
1347
|
expectedManifestVersion: number | null;
|
|
1348
|
+
/**
|
|
1349
|
+
* Required when blocks are retired. The store atomically proves this ready compaction job is
|
|
1350
|
+
* owned by the transaction and that `removedBlockIds` exactly names its still-current,
|
|
1351
|
+
* unaliased source set. Ordinary commits cannot retire visible blocks.
|
|
1352
|
+
*/
|
|
1353
|
+
compactionJobId?: string;
|
|
750
1354
|
removedBlockIds?: readonly string[];
|
|
1355
|
+
/**
|
|
1356
|
+
* Atomic post-commit fragmentation ceilings. Exactly one entry is mandatory for every table
|
|
1357
|
+
* receiving a pending level-zero segment, no unrelated entry is allowed, and no limit may
|
|
1358
|
+
* exceed `MAX_LEVEL_ZERO_SEGMENTS`.
|
|
1359
|
+
*/
|
|
1360
|
+
levelZeroSegmentLimits?: ReadonlyArray<{
|
|
1361
|
+
tableId: string;
|
|
1362
|
+
limit: number;
|
|
1363
|
+
}>;
|
|
751
1364
|
/**
|
|
752
1365
|
* Per-table unique-key changes, in operation order. Multi-entry commits come from atomic
|
|
753
1366
|
* write scopes; entries for the same table apply sequentially, so in-scope conflicts
|
|
@@ -770,7 +1383,9 @@ export interface WriteTransactionInput extends Omit<CommitTransactionInput, "tra
|
|
|
770
1383
|
* auto-increment reservation); its journal is extended and its revision compare-and-swapped
|
|
771
1384
|
* (`TransactionRecordConflictError`). `{ record }` begins the transaction in the same step —
|
|
772
1385
|
* a fresh record (revision 0, empty journal) the store pins at `expectedManifestVersion` —
|
|
773
|
-
* so a write that needed no reservation costs one round trip in total.
|
|
1386
|
+
* so a write that needed no reservation costs one round trip in total. A fresh record carries
|
|
1387
|
+
* the `schemaEpochGuard` captured with its preparation; the store rejects a stale guard before
|
|
1388
|
+
* persisting any part of the write.
|
|
774
1389
|
*/
|
|
775
1390
|
transaction: {
|
|
776
1391
|
id: string;
|
|
@@ -787,12 +1402,188 @@ export interface UniqueKeyChanges {
|
|
|
787
1402
|
requireAbsent: boolean;
|
|
788
1403
|
remove?: boolean;
|
|
789
1404
|
}
|
|
1405
|
+
/** Bounded calls used to seed an arbitrarily large UNIQUE namespace without heap materialization. */
|
|
1406
|
+
export declare const MAX_UNIQUE_KEY_BUILD_TOKENS_PER_CHUNK = 4096;
|
|
1407
|
+
export declare const MAX_UNIQUE_KEY_BUILD_CHUNK_BYTES: number;
|
|
1408
|
+
export declare const MAX_UNIQUE_KEY_BUILD_TTL_MS: number;
|
|
1409
|
+
export declare const MAX_UNIQUE_KEY_BUILD_STAGED_BYTES: number;
|
|
1410
|
+
export declare const MAX_UNIQUE_KEY_BUILD_STAGED_BYTES_TOTAL: number;
|
|
1411
|
+
export interface UniqueKeyBuildRecord {
|
|
1412
|
+
buildId: string;
|
|
1413
|
+
tableId: string;
|
|
1414
|
+
indexId: string;
|
|
1415
|
+
namespaceId: string;
|
|
1416
|
+
ownerId: string;
|
|
1417
|
+
state: "active" | "completed";
|
|
1418
|
+
nextOrdinal: number;
|
|
1419
|
+
tokenCount: number;
|
|
1420
|
+
retainedBytes: number;
|
|
1421
|
+
expiresAt: string;
|
|
1422
|
+
createdAt: string;
|
|
1423
|
+
updatedAt: string;
|
|
1424
|
+
completedAt?: string;
|
|
1425
|
+
}
|
|
1426
|
+
export interface BeginUniqueKeyBuildInput {
|
|
1427
|
+
buildId: string;
|
|
1428
|
+
tableId: string;
|
|
1429
|
+
indexId: string;
|
|
1430
|
+
namespaceId: string;
|
|
1431
|
+
ownerId: string;
|
|
1432
|
+
expiresAt: string;
|
|
1433
|
+
createdAt: string;
|
|
1434
|
+
}
|
|
1435
|
+
export interface AppendUniqueKeyBuildChunkInput {
|
|
1436
|
+
buildId: string;
|
|
1437
|
+
ownerId: string;
|
|
1438
|
+
expiresAtCutoff: string;
|
|
1439
|
+
ordinal: number;
|
|
1440
|
+
keyTokens: readonly string[];
|
|
1441
|
+
updatedAt: string;
|
|
1442
|
+
}
|
|
1443
|
+
export interface FinishUniqueKeyBuildInput {
|
|
1444
|
+
buildId: string;
|
|
1445
|
+
ownerId: string;
|
|
1446
|
+
expiresAtCutoff: string;
|
|
1447
|
+
expectedTableRevision: number;
|
|
1448
|
+
expectedManifestVersion: number | null;
|
|
1449
|
+
chunkCount: number;
|
|
1450
|
+
coversVersion: number;
|
|
1451
|
+
completedAt: string;
|
|
1452
|
+
}
|
|
1453
|
+
export interface RenewUniqueKeyBuildInput {
|
|
1454
|
+
buildId: string;
|
|
1455
|
+
ownerId: string;
|
|
1456
|
+
expiresAtCutoff: string;
|
|
1457
|
+
expiresAt: string;
|
|
1458
|
+
updatedAt: string;
|
|
1459
|
+
}
|
|
1460
|
+
export interface AbortUniqueKeyBuildInput {
|
|
1461
|
+
buildId: string;
|
|
1462
|
+
ownerId: string;
|
|
1463
|
+
expiresAtCutoff: string;
|
|
1464
|
+
}
|
|
1465
|
+
/**
|
|
1466
|
+
* A bounded background fold of one already-enforced UNIQUE namespace. Begin freezes the exact
|
|
1467
|
+
* immutable base generation and delta prefix through `throughVersion`; later commits keep
|
|
1468
|
+
* appending canonical `(namespace, token, version)` add/remove records to a separate ordered
|
|
1469
|
+
* tail. Each step resolves at most one bounded lexical token window
|
|
1470
|
+
* into a new immutable generation. Finish swaps the generation and drops only the frozen tail
|
|
1471
|
+
* prefix atomically, so no commit copies database-sized membership and readers always see an
|
|
1472
|
+
* exact base+tail view.
|
|
1473
|
+
*/
|
|
1474
|
+
export interface UniqueKeyFoldRecord {
|
|
1475
|
+
foldId: string;
|
|
1476
|
+
tableId: string;
|
|
1477
|
+
indexId: string | null;
|
|
1478
|
+
namespaceId: string;
|
|
1479
|
+
ownerId: string;
|
|
1480
|
+
state: "active" | "completed";
|
|
1481
|
+
sourceGenerationId: string | null;
|
|
1482
|
+
outputGenerationId: string;
|
|
1483
|
+
throughVersion: number;
|
|
1484
|
+
afterToken: string | null;
|
|
1485
|
+
nextOrdinal: number;
|
|
1486
|
+
tokenCount: number;
|
|
1487
|
+
retainedBytes: number;
|
|
1488
|
+
createdAt: string;
|
|
1489
|
+
updatedAt: string;
|
|
1490
|
+
expiresAt: string;
|
|
1491
|
+
completedAt?: string;
|
|
1492
|
+
}
|
|
1493
|
+
export interface BeginUniqueKeyFoldInput {
|
|
1494
|
+
foldId: string;
|
|
1495
|
+
tableId: string;
|
|
1496
|
+
indexId: string | null;
|
|
1497
|
+
namespaceId: string;
|
|
1498
|
+
ownerId: string;
|
|
1499
|
+
outputGenerationId: string;
|
|
1500
|
+
expectedManifestVersion: number;
|
|
1501
|
+
createdAt: string;
|
|
1502
|
+
expiresAt: string;
|
|
1503
|
+
}
|
|
1504
|
+
export interface RunUniqueKeyFoldStepInput {
|
|
1505
|
+
foldId: string;
|
|
1506
|
+
ownerId: string;
|
|
1507
|
+
expiresAtCutoff: string;
|
|
1508
|
+
expiresAt: string;
|
|
1509
|
+
updatedAt: string;
|
|
1510
|
+
maxTokens: number;
|
|
1511
|
+
}
|
|
1512
|
+
export interface FinishUniqueKeyFoldInput {
|
|
1513
|
+
foldId: string;
|
|
1514
|
+
ownerId: string;
|
|
1515
|
+
expiresAtCutoff: string;
|
|
1516
|
+
expectedSourceGenerationId: string | null;
|
|
1517
|
+
expectedThroughVersion: number;
|
|
1518
|
+
chunkCount: number;
|
|
1519
|
+
completedAt: string;
|
|
1520
|
+
}
|
|
1521
|
+
export interface AbortUniqueKeyFoldInput {
|
|
1522
|
+
foldId: string;
|
|
1523
|
+
ownerId: string;
|
|
1524
|
+
expiresAtCutoff: string;
|
|
1525
|
+
}
|
|
1526
|
+
/** Validates one staged seed call before an adapter opens a transaction or WAL frame. */
|
|
1527
|
+
export declare function uniqueKeyBuildChunkRetainedBytes(keyTokens: readonly string[]): number;
|
|
1528
|
+
export declare class UniqueKeyBuildConflictError extends Error {
|
|
1529
|
+
readonly buildId: string;
|
|
1530
|
+
readonly reason: string;
|
|
1531
|
+
readonly name = "UniqueKeyBuildConflictError";
|
|
1532
|
+
constructor(buildId: string, reason: string);
|
|
1533
|
+
}
|
|
790
1534
|
/** One term's postings within a commit delta or base chunk: parallel rowId/tf arrays. */
|
|
791
1535
|
export interface FtsPosting {
|
|
792
1536
|
term: string;
|
|
793
1537
|
rowIds: bigint[];
|
|
794
1538
|
tf: number[];
|
|
795
1539
|
}
|
|
1540
|
+
export declare const MAX_POSTING_BUILD_TTL_MS: number;
|
|
1541
|
+
export interface BeginPostingBuildInput {
|
|
1542
|
+
tableId: string;
|
|
1543
|
+
columnId: string;
|
|
1544
|
+
buildId: string;
|
|
1545
|
+
ownerId: string;
|
|
1546
|
+
createdAt: string;
|
|
1547
|
+
expiresAt: string;
|
|
1548
|
+
}
|
|
1549
|
+
export interface RenewPostingBuildInput {
|
|
1550
|
+
tableId: string;
|
|
1551
|
+
columnId: string;
|
|
1552
|
+
buildId: string;
|
|
1553
|
+
ownerId: string;
|
|
1554
|
+
expiresAtCutoff: string;
|
|
1555
|
+
expiresAt: string;
|
|
1556
|
+
updatedAt: string;
|
|
1557
|
+
}
|
|
1558
|
+
export interface AppendPostingBuildChunkInput extends RenewPostingBuildInput {
|
|
1559
|
+
ordinal: number;
|
|
1560
|
+
chunk: readonly FtsPosting[];
|
|
1561
|
+
}
|
|
1562
|
+
export interface FinishPostingBuildInput {
|
|
1563
|
+
tableId: string;
|
|
1564
|
+
columnId: string;
|
|
1565
|
+
buildId: string;
|
|
1566
|
+
ownerId: string;
|
|
1567
|
+
expiresAtCutoff: string;
|
|
1568
|
+
coversVersion: number;
|
|
1569
|
+
chunkCount: number;
|
|
1570
|
+
totalTokens: number;
|
|
1571
|
+
completedAt: string;
|
|
1572
|
+
}
|
|
1573
|
+
export interface AbortPostingBuildInput {
|
|
1574
|
+
tableId: string;
|
|
1575
|
+
columnId: string;
|
|
1576
|
+
buildId: string;
|
|
1577
|
+
ownerId: string;
|
|
1578
|
+
expiresAtCutoff: string;
|
|
1579
|
+
}
|
|
1580
|
+
export declare class PostingBuildConflictError extends Error {
|
|
1581
|
+
readonly buildId: string;
|
|
1582
|
+
readonly ownerId: string;
|
|
1583
|
+
readonly reason: string;
|
|
1584
|
+
readonly name = "PostingBuildConflictError";
|
|
1585
|
+
constructor(buildId: string, ownerId: string, reason: string);
|
|
1586
|
+
}
|
|
796
1587
|
/** One indexed column's contribution from one commit: postings for the commit's new rows. */
|
|
797
1588
|
export interface FtsColumnDelta {
|
|
798
1589
|
columnId: string;
|
|
@@ -811,11 +1602,37 @@ export interface FtsChanges {
|
|
|
811
1602
|
tableId: string;
|
|
812
1603
|
columns: readonly FtsColumnDelta[];
|
|
813
1604
|
}
|
|
1605
|
+
/** In-memory and atomic-publish bounds for one transaction's accelerator/key deltas. */
|
|
1606
|
+
export declare const MAX_TRANSACTION_COMMIT_DELTA_BYTES: number;
|
|
1607
|
+
export declare const MAX_TRANSACTION_COMMIT_DELTA_ENTRIES = 1048576;
|
|
1608
|
+
export declare function transactionCommitDeltaRetainedBytes(uniqueKeyChanges: readonly UniqueKeyChanges[], ftsChanges: readonly FtsChanges[]): {
|
|
1609
|
+
bytes: number;
|
|
1610
|
+
entries: number;
|
|
1611
|
+
};
|
|
814
1612
|
/** The per-term candidate row IDs a full-text index lookup returns, aligned with the query. */
|
|
815
1613
|
export interface FtsCandidates {
|
|
816
1614
|
/** Per requested term: ascending unique row IDs whose indexed column contained the term. */
|
|
817
1615
|
rowIdsByTerm: bigint[][];
|
|
818
|
-
|
|
1616
|
+
/** The bounded read stopped before collecting every matching row; callers must scan. */
|
|
1617
|
+
overflow: boolean;
|
|
1618
|
+
}
|
|
1619
|
+
/** Aggregate row-id ceiling for one postings candidate read. Overflow falls back to a scan. */
|
|
1620
|
+
export declare const MAX_FTS_CANDIDATE_ROW_IDS = 65536;
|
|
1621
|
+
/** Query-term cardinality shared by the parser and every postings adapter boundary. */
|
|
1622
|
+
export declare const MAX_FTS_QUERY_TERMS = 32;
|
|
1623
|
+
/** Retained metadata/value ceiling for one ordered postings read. Overflow falls back to a scan. */
|
|
1624
|
+
export declare const MAX_FTS_ORDERED_READ_BYTES: number;
|
|
1625
|
+
/** Hard public mutation bounds for one streamed postings-build chunk. */
|
|
1626
|
+
export declare const MAX_FTS_POSTINGS_PER_CHUNK = 65536;
|
|
1627
|
+
export declare const MAX_FTS_POSTING_ROW_IDS_PER_CHUNK = 1048576;
|
|
1628
|
+
export declare const MAX_FTS_POSTING_TERM_CHARACTERS = 65536;
|
|
1629
|
+
/** Indexed string values are bounded; non-indexed block strings retain the physical block cap. */
|
|
1630
|
+
export declare const MAX_INDEXED_STRING_CHARACTERS = 16384;
|
|
1631
|
+
/** Maximum normalized tokens retained from one indexed document. */
|
|
1632
|
+
export declare const MAX_FTS_TOKENS_PER_DOCUMENT = 4096;
|
|
1633
|
+
/** Bounded catalog/TOC cardinality. Oversized accelerators invalidate and queries scan. */
|
|
1634
|
+
export declare const MAX_FTS_BASE_CHUNKS = 4096;
|
|
1635
|
+
export declare const MAX_FTS_DELTA_CHUNKS = 128;
|
|
819
1636
|
/** One exact/prefix term lookup or a lexicographic term range over a postings index. */
|
|
820
1637
|
export type FtsPostingQuery = {
|
|
821
1638
|
term: string;
|
|
@@ -826,6 +1643,8 @@ export type FtsPostingQuery = {
|
|
|
826
1643
|
upper?: string;
|
|
827
1644
|
upperInclusive?: boolean;
|
|
828
1645
|
};
|
|
1646
|
+
/** Strict, bounded runtime validation shared by every adapter before any postings read. */
|
|
1647
|
+
export declare function validateFtsPostingQueries(value: unknown, label?: string): asserts value is readonly FtsPostingQuery[];
|
|
829
1648
|
/** Whether a stored term belongs to one exact, prefix, or range lookup. */
|
|
830
1649
|
export declare function ftsPostingQueryMatches(term: string, query: FtsPostingQuery): boolean;
|
|
831
1650
|
/**
|
|
@@ -833,12 +1652,19 @@ export declare function ftsPostingQueryMatches(term: string, query: FtsPostingQu
|
|
|
833
1652
|
* term-match rule (exact, or prefix as a term range) and the sorted-unique row-id shape must
|
|
834
1653
|
* never drift between backends — pruning would silently differ per store.
|
|
835
1654
|
*/
|
|
836
|
-
export declare function collectFtsCandidates(chunkLists: Iterable<readonly FtsPosting[]>, terms: readonly FtsPostingQuery[]): FtsCandidates;
|
|
1655
|
+
export declare function collectFtsCandidates(chunkLists: Iterable<readonly FtsPosting[]>, terms: readonly FtsPostingQuery[], maxRowIds?: number): FtsCandidates;
|
|
1656
|
+
/** Validates the fixed memory ceilings accepted by one ordered postings read. */
|
|
1657
|
+
export declare function validateFtsOrderedReadLimits(maxRowIds?: number, maxRetainedBytes?: number): void;
|
|
837
1658
|
/**
|
|
838
1659
|
* K-way merges sorted base/delta chunks into canonical term order. Only one term's row map and
|
|
839
1660
|
* one cursor per chunk stay live beyond the returned postings, avoiding a second index-sized map.
|
|
840
1661
|
*/
|
|
841
1662
|
export declare function collectFtsPostings(chunkLists: Iterable<readonly FtsPosting[]>): FtsPosting[];
|
|
1663
|
+
/** Bounded ordered merge; overflow deliberately returns no partial authoritative answer. */
|
|
1664
|
+
export declare function collectFtsPostingsBounded(chunkLists: Iterable<readonly FtsPosting[]>, maxRowIds?: number, maxRetainedBytes?: number): {
|
|
1665
|
+
postings: FtsPosting[];
|
|
1666
|
+
overflow: boolean;
|
|
1667
|
+
};
|
|
842
1668
|
/**
|
|
843
1669
|
* Shared stale-writer policy for both stores' commit steps: a commit that adds segments to a
|
|
844
1670
|
* table with active full-text columns but no covering delta flips the uncovered columns to
|
|
@@ -873,6 +1699,13 @@ export declare class WriteConflictError extends Error {
|
|
|
873
1699
|
readonly name = "WriteConflictError";
|
|
874
1700
|
constructor(expectedVersion: number | null, actualVersion: number | null);
|
|
875
1701
|
}
|
|
1702
|
+
/** Staged write artifacts were prepared against a structurally different catalog. */
|
|
1703
|
+
export declare class SchemaConflictError extends Error {
|
|
1704
|
+
readonly expectedEpoch: number;
|
|
1705
|
+
readonly actualEpoch: number;
|
|
1706
|
+
readonly name = "SchemaConflictError";
|
|
1707
|
+
constructor(expectedEpoch: number, actualEpoch: number);
|
|
1708
|
+
}
|
|
876
1709
|
export declare class TransactionRecordConflictError extends Error {
|
|
877
1710
|
readonly transactionId: string;
|
|
878
1711
|
readonly expectedRevision: number;
|
|
@@ -890,11 +1723,45 @@ export interface TempRunPage {
|
|
|
890
1723
|
pageIndex: number;
|
|
891
1724
|
bytes: Uint8Array;
|
|
892
1725
|
}
|
|
1726
|
+
/**
|
|
1727
|
+
* Atomically adopts an unpublished compaction output left by an aborted attempt. The adapter
|
|
1728
|
+
* verifies that `segment` exactly matches the stored immutable record apart from its owner,
|
|
1729
|
+
* that the old owner is the expected aborted revision, and that the replacement is the active
|
|
1730
|
+
* transaction linked to `compactionJobId`. It then retags the segment and moves its journal
|
|
1731
|
+
* membership from the old owner to the replacement while advancing both transaction revisions.
|
|
1732
|
+
*/
|
|
1733
|
+
export interface AdoptAbortedSegmentInput {
|
|
1734
|
+
segment: SegmentRecord;
|
|
1735
|
+
expectedAbortedTransactionId: string;
|
|
1736
|
+
expectedAbortedTransactionRevision: number;
|
|
1737
|
+
replacementTransactionId: string;
|
|
1738
|
+
expectedReplacementTransactionRevision: number;
|
|
1739
|
+
compactionJobId: string;
|
|
1740
|
+
updatedAt: string;
|
|
1741
|
+
}
|
|
1742
|
+
/** Hard storage-boundary limits for one scratch-page write. */
|
|
1743
|
+
export declare const MAX_TEMP_RUN_PAGES_PER_BATCH = 64;
|
|
1744
|
+
export declare const MAX_TEMP_RUN_PAGE_BYTES: number;
|
|
1745
|
+
export declare const MAX_TEMP_RUN_BATCH_BYTES: number;
|
|
1746
|
+
/**
|
|
1747
|
+
* Refuses an oversized scratch write before an adapter starts a transaction or appends a WAL
|
|
1748
|
+
* record. Query execution splits pages and batches to these limits, so the limits bound atomic
|
|
1749
|
+
* storage work without limiting the total size of a spill.
|
|
1750
|
+
*/
|
|
1751
|
+
export declare function assertTempRunPageBatchLimits(pages: readonly TempRunPage[]): void;
|
|
893
1752
|
export interface TempOwnerRecord {
|
|
894
1753
|
ownerId: string;
|
|
1754
|
+
createdAt: string;
|
|
895
1755
|
expiresAt: string;
|
|
896
1756
|
revision: number;
|
|
897
1757
|
}
|
|
1758
|
+
export declare const MAX_TEMP_OWNER_TTL_MS: number;
|
|
1759
|
+
export interface RenewTempOwnerInput {
|
|
1760
|
+
ownerId: string;
|
|
1761
|
+
expectedRevision: number;
|
|
1762
|
+
expiresAtCutoff: string;
|
|
1763
|
+
expiresAt: string;
|
|
1764
|
+
}
|
|
898
1765
|
export declare class TempOwnerConflictError extends Error {
|
|
899
1766
|
readonly ownerId: string;
|
|
900
1767
|
readonly expectedRevision: number;
|
|
@@ -910,14 +1777,9 @@ export declare class TempOwnerConflictError extends Error {
|
|
|
910
1777
|
*/
|
|
911
1778
|
export interface QueryCatalogState {
|
|
912
1779
|
manifestVersion: number | null;
|
|
913
|
-
/**
|
|
914
|
-
* Exact block set of manifestVersion, when resolving it was part of the same atomic read.
|
|
915
|
-
* Lets the engine pin that already-resolved snapshot instead of reading a large manifest twice.
|
|
916
|
-
*/
|
|
917
|
-
manifestBlockIds?: string[];
|
|
918
1780
|
/** Positional per requested name; undefined where the table does not exist. */
|
|
919
1781
|
tables: Array<TableRecord | undefined>;
|
|
920
|
-
/** Current-manifest segments of the found tables, sorted by id
|
|
1782
|
+
/** Current-manifest segments of the found tables, sorted by id. */
|
|
921
1783
|
segments: SegmentRecord[];
|
|
922
1784
|
/** Records for the segments' transaction ids; missing records are omitted. */
|
|
923
1785
|
transactions: TransactionRecord[];
|
|
@@ -929,41 +1791,106 @@ export interface QueryCatalogState {
|
|
|
929
1791
|
catalogEpoch?: number;
|
|
930
1792
|
}
|
|
931
1793
|
/**
|
|
932
|
-
* The
|
|
933
|
-
*
|
|
1794
|
+
* The change counters a reader or writer needs, read together in one atomic storage
|
|
1795
|
+
* transaction. `manifestVersion` moves on
|
|
934
1796
|
* every data commit. `catalogEpoch` moves on every catalog mutation — table creation, table
|
|
935
1797
|
* record updates (schema migration, full-text index stamps), and every manifest publish —
|
|
936
1798
|
* so an unchanged epoch proves cached catalog state is byte-identical to a fresh read.
|
|
937
1799
|
* Physical garbage collection does not move the epoch: it only deletes records that are
|
|
938
1800
|
* already invisible at every leased version, so cached state stays result-equivalent.
|
|
1801
|
+
* `schemaEpoch` is deliberately narrower: it moves only for structural catalog changes, so
|
|
1802
|
+
* writers can reject old-schema artifacts without making concurrent ordinary writes conflict.
|
|
939
1803
|
*/
|
|
940
1804
|
export interface CatalogProbe {
|
|
941
1805
|
manifestVersion: number | null;
|
|
942
1806
|
catalogEpoch: number;
|
|
1807
|
+
/** Advances only when structural catalog state changes, never for an ordinary data commit. */
|
|
1808
|
+
schemaEpoch: number;
|
|
1809
|
+
}
|
|
1810
|
+
/** Optional serializable guard for a catalog mutation whose proof read multiple records. */
|
|
1811
|
+
export interface CatalogMutationOptions {
|
|
1812
|
+
/** Reject unless the complete catalog is still at this epoch. */
|
|
1813
|
+
expectedCatalogEpoch?: number;
|
|
1814
|
+
}
|
|
1815
|
+
/** Atomic replacement fields for one catalog record. */
|
|
1816
|
+
export interface TableRecordUpdate extends CatalogMutationOptions {
|
|
1817
|
+
columns?: TableColumnRecord[];
|
|
1818
|
+
/** Replaces the full-text index state map; null clears it. */
|
|
1819
|
+
ftsColumns?: Record<string, FtsColumnIndexRecord> | null;
|
|
1820
|
+
/** Replaces the secondary-index state map; null clears it. */
|
|
1821
|
+
secondaryIndexes?: Record<string, SecondaryIndexRecord> | null;
|
|
1822
|
+
/** Additional manifest CAS used when publishing a UNIQUE build from a stable snapshot. */
|
|
1823
|
+
expectedManifestVersion?: {
|
|
1824
|
+
value: number | null;
|
|
1825
|
+
};
|
|
1826
|
+
/** Atomically seeds one secondary UNIQUE membership namespace while activating enforcement. */
|
|
1827
|
+
uniqueKeySeed?: {
|
|
1828
|
+
namespaceId: string;
|
|
1829
|
+
keyTokens: readonly string[];
|
|
1830
|
+
};
|
|
1831
|
+
/** Atomically advances a newly declared auto-increment column's durable counter. */
|
|
1832
|
+
autoIncrementSeed?: {
|
|
1833
|
+
columnId: string;
|
|
1834
|
+
atLeast: bigint;
|
|
1835
|
+
};
|
|
1836
|
+
/** Replaces the trigger list; null clears it. */
|
|
1837
|
+
triggers?: TriggerRecord[] | null;
|
|
1838
|
+
/** Replaces a view definition in place; null converts the record back to a table. */
|
|
1839
|
+
view?: TableRecord["view"] | null;
|
|
943
1840
|
}
|
|
944
1841
|
/**
|
|
945
1842
|
* Bulk payload storage: immutable, opaque byte blobs keyed by structured ids.
|
|
946
1843
|
*
|
|
947
|
-
* Blocks are
|
|
948
|
-
*
|
|
1844
|
+
* Blocks are written only through transaction staging, which creates their durable provenance
|
|
1845
|
+
* in the same atomic step and rejects duplicate ids without a partial write. Ids contain `/` separators
|
|
949
1846
|
* (`table/<uuid>/segment/<uuid>/part/000001`) and sort lexically; treat them as opaque keys.
|
|
950
1847
|
* Reads MUST return bytes the caller may mutate freely (a fresh copy or freshly deserialized
|
|
951
1848
|
* buffer), and writes MUST NOT alias the caller's buffer — the engine may reuse it.
|
|
952
1849
|
*
|
|
953
|
-
* Published blocks are retired by superseding them in a commit
|
|
954
|
-
* lease-aware
|
|
1850
|
+
* Published blocks are retired by superseding them in a commit; only the store's atomic
|
|
1851
|
+
* lease-aware collection step can physically delete payloads once no reader can reach them.
|
|
955
1852
|
*/
|
|
1853
|
+
/** Maximum manifest-membership ids accepted by one storage call. */
|
|
1854
|
+
export declare const MAX_MANIFEST_BLOCK_PRESENCE_IDS = 1024;
|
|
1855
|
+
/** Maximum UTF-16 code units in any opaque storage identity. */
|
|
1856
|
+
export declare const MAX_STORAGE_ID_CHARACTERS = 1024;
|
|
1857
|
+
/** Maximum UTF-16 code units in a persisted catalog name. */
|
|
1858
|
+
export declare const MAX_CATALOG_NAME_CHARACTERS = 1024;
|
|
1859
|
+
/** Public adapter database-name bound; names commonly become substrate keys or path segments. */
|
|
1860
|
+
export declare const MAX_STORAGE_DATABASE_NAME_CHARACTERS = 256;
|
|
1861
|
+
/** Maximum positional items accepted by one public bulk-read operation. */
|
|
1862
|
+
export declare const MAX_STORAGE_BULK_READ_ITEMS = 1024;
|
|
1863
|
+
/** Maximum aggregate payload bytes returned by one getBlocks call. */
|
|
1864
|
+
export declare const MAX_BLOCK_READ_BATCH_BYTES: number;
|
|
1865
|
+
export declare class BlockReadBatchTooLargeError extends RangeError {
|
|
1866
|
+
readonly requestedBytes: number;
|
|
1867
|
+
readonly limitBytes: number;
|
|
1868
|
+
readonly name = "BlockReadBatchTooLargeError";
|
|
1869
|
+
constructor(requestedBytes: number, limitBytes?: number);
|
|
1870
|
+
}
|
|
1871
|
+
export declare function assertStorageBulkReadItems(items: readonly unknown[], label: string): void;
|
|
1872
|
+
export declare function validateStorageId(value: unknown, label?: string): string;
|
|
1873
|
+
export declare function validateCatalogName(value: unknown, label?: string): string;
|
|
1874
|
+
export declare function validateStorageDatabaseName(value: unknown): string;
|
|
956
1875
|
export interface BlockPayloadStore {
|
|
957
|
-
addBlock(id: string, bytes: Uint8Array): Promise<void>;
|
|
958
|
-
/** All or nothing: an internal or existing duplicate id fails the whole batch unwritten. */
|
|
959
|
-
addBlocks(blocks: readonly BlockWrite[]): Promise<void>;
|
|
960
1876
|
getBlock(id: string): Promise<Uint8Array | undefined>;
|
|
961
1877
|
/** Positional per requested id; undefined where a block does not exist. */
|
|
962
1878
|
getBlocks(ids: readonly string[]): Promise<Array<Uint8Array | undefined>>;
|
|
963
|
-
/**
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1879
|
+
/**
|
|
1880
|
+
* Reads one block only when it belongs to the exact readable manifest version. The membership
|
|
1881
|
+
* check and payload read are one storage operation: callers must never fetch a block first and
|
|
1882
|
+
* then race a separate manifest check. A missing/pruned manifest or non-member id returns
|
|
1883
|
+
* undefined. A readable member whose payload is missing or unreadable is corruption and MUST
|
|
1884
|
+
* throw StorageCorruptionError. Reader leases keep a selected version from being pruned while
|
|
1885
|
+
* it is in use.
|
|
1886
|
+
*/
|
|
1887
|
+
readManifestBlock(version: number | null, id: string): Promise<Uint8Array | undefined>;
|
|
1888
|
+
/**
|
|
1889
|
+
* Positional membership in the exact readable manifest version. Implementations must bound the
|
|
1890
|
+
* input at MAX_MANIFEST_BLOCK_PRESENCE_IDS; callers window larger sets. A missing/pruned
|
|
1891
|
+
* manifest returns false for every id.
|
|
1892
|
+
*/
|
|
1893
|
+
hasManifestBlocks(version: number | null, ids: readonly string[]): Promise<boolean[]>;
|
|
967
1894
|
}
|
|
968
1895
|
/**
|
|
969
1896
|
* The table catalog: schema records, the counters that keep writes collision-free, and
|
|
@@ -978,48 +1905,40 @@ export interface BlockPayloadStore {
|
|
|
978
1905
|
*/
|
|
979
1906
|
export interface CatalogStore {
|
|
980
1907
|
/** Fails on a duplicate id or name. Advances the catalog epoch. */
|
|
981
|
-
addTable(record: TableRecord): Promise<void>;
|
|
1908
|
+
addTable(record: TableRecord, options?: CatalogMutationOptions): Promise<void>;
|
|
982
1909
|
getTable(id: string): Promise<TableRecord | undefined>;
|
|
983
1910
|
getTableByName(name: string): Promise<TableRecord | undefined>;
|
|
984
|
-
/** Sorted by table name. */
|
|
1911
|
+
/** Sorted by table name; MAX_CATALOG_RECORDS makes this array globally bounded. */
|
|
985
1912
|
listTables(): Promise<TableRecord[]>;
|
|
986
1913
|
/**
|
|
987
1914
|
* Replaces catalog metadata atomically. When `columns` removes a column, the same operation
|
|
988
1915
|
* must also discard that column's full-text catalog entry, base chunks, and commit deltas.
|
|
989
1916
|
*/
|
|
990
|
-
updateTable(id: string, expectedRevision: number, update:
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
/** Additional manifest CAS used when publishing a UNIQUE build from a stable snapshot. */
|
|
997
|
-
expectedManifestVersion?: {
|
|
998
|
-
value: number | null;
|
|
999
|
-
};
|
|
1000
|
-
/**
|
|
1001
|
-
* Atomically seeds one secondary UNIQUE membership namespace while publishing the catalog
|
|
1002
|
-
* record that activates enforcement. Duplicate tokens reject the entire operation.
|
|
1003
|
-
*/
|
|
1004
|
-
uniqueKeySeed?: {
|
|
1005
|
-
namespaceId: string;
|
|
1006
|
-
keyTokens: readonly string[];
|
|
1007
|
-
};
|
|
1008
|
-
/** Replaces the trigger list; null clears it. */
|
|
1009
|
-
triggers?: TriggerRecord[] | null;
|
|
1010
|
-
}): Promise<TableRecord>;
|
|
1011
|
-
/**
|
|
1012
|
-
* Removes a table's catalog record together with everything else keyed to it: its segments,
|
|
1013
|
-
* its full-text base chunks and commit deltas, its unique-key membership, and its row-id and
|
|
1014
|
-
* autoincrement counters. One step, so a crash cannot leave a segment pointing at a table
|
|
1015
|
-
* that no longer exists. Advances the catalog epoch, and fails with a
|
|
1016
|
-
* `TableRecordConflictError` on a revision mismatch, like `updateTable`.
|
|
1017
|
-
*
|
|
1018
|
-
* The table's blocks are the caller's business: they are retired by superseding them in a
|
|
1019
|
-
* commit, which leaves the bytes for the lease-aware collector rather than deleting data a
|
|
1020
|
-
* pinned reader may still be reading.
|
|
1917
|
+
updateTable(id: string, expectedRevision: number, update: TableRecordUpdate): Promise<TableRecord>;
|
|
1918
|
+
/**
|
|
1919
|
+
* Removes a segment-free catalog object such as a view. Must refuse when any segment names the
|
|
1920
|
+
* record; populated tables use `dropTable`, whose manifest retirement and catalog removal are
|
|
1921
|
+
* inseparable. Advances the catalog epoch and fails with `TableRecordConflictError` on a stale
|
|
1922
|
+
* revision.
|
|
1021
1923
|
*/
|
|
1022
|
-
removeTable(id: string, expectedRevision: number): Promise<void>;
|
|
1924
|
+
removeTable(id: string, expectedRevision: number, options?: CatalogMutationOptions): Promise<void>;
|
|
1925
|
+
/**
|
|
1926
|
+
* Atomically retires all live table blocks, removes the catalog/segments/counters/indexes,
|
|
1927
|
+
* and publishes the successor manifest. A table revision mismatch throws
|
|
1928
|
+
* `TableRecordConflictError`; a manifest mismatch throws `WriteConflictError`; an active
|
|
1929
|
+
* transaction or nonterminal compaction owner throws `TableInUseError`. Any rejection leaves
|
|
1930
|
+
* the catalog, manifest, jobs, transaction journals, segments, counters, indexes, and payloads
|
|
1931
|
+
* unchanged. A success returns the one manifest summary it published.
|
|
1932
|
+
*/
|
|
1933
|
+
dropTable(input: DropTableInput): Promise<ManifestSummary>;
|
|
1934
|
+
/**
|
|
1935
|
+
* Atomically removes one safe non-key column from catalog metadata and every table segment,
|
|
1936
|
+
* removes its posting accelerator, and publishes a successor retiring only removed column
|
|
1937
|
+
* blocks that no remaining segment reference owns. CAS/busy errors match `dropTable`; any
|
|
1938
|
+
* rejection changes nothing, payload bytes stay available to pinned historical readers, and
|
|
1939
|
+
* success returns the exactly one published manifest summary.
|
|
1940
|
+
*/
|
|
1941
|
+
dropTableColumn(input: DropTableColumnInput): Promise<ManifestSummary>;
|
|
1023
1942
|
reserveRowIds(tableId: string, count: number): Promise<RowIdRange>;
|
|
1024
1943
|
/**
|
|
1025
1944
|
* Atomically reserves `count` auto-increment values for the column, first bumping the
|
|
@@ -1028,6 +1947,36 @@ export interface CatalogStore {
|
|
|
1028
1947
|
reserveAutoIncrement(tableId: string, columnId: string, count: number, atLeast?: bigint): Promise<RowIdRange>;
|
|
1029
1948
|
/** Which of the given key tokens already exist for the table, deduplicated and sorted. */
|
|
1030
1949
|
getExistingUniqueKeys(tableId: string, keyTokens: readonly string[]): Promise<string[]>;
|
|
1950
|
+
/**
|
|
1951
|
+
* Starts or takes over the exact catalog-owned UNIQUE builder. One active session per namespace
|
|
1952
|
+
* and MAX_ACTIVE_UNIQUE_KEY_BUILDS globally are enforced atomically. Repeating the same active
|
|
1953
|
+
* owner/header is idempotent; an expired owner is irrevocably replaced with an empty stage.
|
|
1954
|
+
*/
|
|
1955
|
+
beginUniqueKeyBuild(input: BeginUniqueKeyBuildInput): Promise<UniqueKeyBuildRecord>;
|
|
1956
|
+
getUniqueKeyBuild(buildId: string): Promise<UniqueKeyBuildRecord | undefined>;
|
|
1957
|
+
/** Refuses at/past the cutoff, so a dead builder can never be resurrected. */
|
|
1958
|
+
renewUniqueKeyBuild(input: RenewUniqueKeyBuildInput): Promise<UniqueKeyBuildRecord>;
|
|
1959
|
+
/**
|
|
1960
|
+
* Appends the exact next ordinal. Same-ordinal lost-ack replay compares the persisted tokens
|
|
1961
|
+
* byte-for-byte; a changed replay or duplicate within/across chunks refuses without mutation.
|
|
1962
|
+
*/
|
|
1963
|
+
appendUniqueKeyBuildChunk(input: AppendUniqueKeyBuildChunkInput): Promise<UniqueKeyBuildRecord>;
|
|
1964
|
+
/**
|
|
1965
|
+
* Atomically verifies the exact building catalog owner, table+manifest CAS, completed chunk
|
|
1966
|
+
* count, and then publishes both the durable membership namespace and ready catalog state.
|
|
1967
|
+
* A same-build completed retry is a no-op; no catalog/membership intermediate state exists.
|
|
1968
|
+
*/
|
|
1969
|
+
finishUniqueKeyBuild(input: FinishUniqueKeyBuildInput): Promise<TableRecord>;
|
|
1970
|
+
/** Exact owner may abort; after expiry any caller may reclaim. Returns false when absent. */
|
|
1971
|
+
abortUniqueKeyBuild(input: AbortUniqueKeyBuildInput): Promise<boolean>;
|
|
1972
|
+
/** Starts or takes over a bounded base+tail membership fold; see `UniqueKeyFoldRecord`. */
|
|
1973
|
+
beginUniqueKeyFold?(input: BeginUniqueKeyFoldInput): Promise<UniqueKeyFoldRecord>;
|
|
1974
|
+
getUniqueKeyFold?(foldId: string): Promise<UniqueKeyFoldRecord | undefined>;
|
|
1975
|
+
/** Advances at most `maxTokens` lexical keys and renews the exact live owner. */
|
|
1976
|
+
runUniqueKeyFoldStep?(input: RunUniqueKeyFoldStepInput): Promise<UniqueKeyFoldRecord>;
|
|
1977
|
+
/** Atomically promotes the output generation and removes only the frozen delta prefix. */
|
|
1978
|
+
finishUniqueKeyFold?(input: FinishUniqueKeyFoldInput): Promise<UniqueKeyFoldRecord>;
|
|
1979
|
+
abortUniqueKeyFold?(input: AbortUniqueKeyFoldInput): Promise<boolean>;
|
|
1031
1980
|
}
|
|
1032
1981
|
/**
|
|
1033
1982
|
* Versions and visibility: manifests (the set of live block ids at each version), segments
|
|
@@ -1036,12 +1985,14 @@ export interface CatalogStore {
|
|
|
1036
1985
|
*
|
|
1037
1986
|
* This is where the whole consistency story lives. `commitTransaction` is THE atomic step of
|
|
1038
1987
|
* the database: in one durable, all-or-nothing action it validates the transaction record's
|
|
1039
|
-
* revision and active status, compare-and-swaps the
|
|
1988
|
+
* revision and active status, verifies its structural `schemaEpochGuard`, compare-and-swaps the
|
|
1989
|
+
* current manifest version, publishes the
|
|
1040
1990
|
* next manifest, finalizes the transaction's segments, applies unique-key changes (failing
|
|
1041
1991
|
* with `UniqueKeyConflictError` on a `requireAbsent` violation), applies full-text deltas,
|
|
1042
1992
|
* and flips the transaction record to committed. No intermediate state may ever be
|
|
1043
|
-
* observable, including after a crash at any moment.
|
|
1044
|
-
* `
|
|
1993
|
+
* observable, including after a crash at any moment. Schema conflicts MUST be
|
|
1994
|
+
* `SchemaConflictError`, version conflicts `WriteConflictError`, and revision conflicts
|
|
1995
|
+
* `TransactionRecordConflictError` — the exact
|
|
1045
1996
|
* exported classes; the engine's retry and rebase loops match on them, and the worker client
|
|
1046
1997
|
* rehydrates them by name across the thread boundary.
|
|
1047
1998
|
*/
|
|
@@ -1050,21 +2001,30 @@ export interface TransactionStore {
|
|
|
1050
2001
|
/** The current version alone, without materializing the manifest's block list. */
|
|
1051
2002
|
getCurrentManifestVersion(): Promise<number | null>;
|
|
1052
2003
|
getManifest(version: number): Promise<Manifest | undefined>;
|
|
1053
|
-
|
|
2004
|
+
/**
|
|
2005
|
+
* Exact ID-ordered membership at one historically published version. Implementations resolve
|
|
2006
|
+
* this from interval provenance without reconstructing or cloning a complete manifest. It must
|
|
2007
|
+
* remain pageable after the summary tombstone is removed so bounded maintenance can drain the
|
|
2008
|
+
* retired payload interval; callers separately use `getManifest`/leases to authorize reads.
|
|
2009
|
+
* A version newer than the current database returns an empty page. `limit` is storage-bounded.
|
|
2010
|
+
*/
|
|
2011
|
+
listManifestBlockPage(input: ListManifestBlockPageInput): Promise<ManifestBlockPage>;
|
|
2012
|
+
/**
|
|
2013
|
+
* ID-ordered retired provenance, independent of bounded manifest-summary tombstones. This is
|
|
2014
|
+
* the durable garbage-discovery index: every record whose non-null `removedVersion` is at most
|
|
2015
|
+
* `removedThroughVersion` appears exactly once in a full cursor traversal.
|
|
2016
|
+
*/
|
|
2017
|
+
listRetiredManifestBlockPage(input: ListRetiredManifestBlockPageInput): Promise<ManifestBlockPage>;
|
|
1054
2018
|
listManifestPage(afterVersion: number | null, limit: number): Promise<StoragePage<Manifest, number>>;
|
|
1055
2019
|
/**
|
|
1056
|
-
*
|
|
1057
|
-
*
|
|
1058
|
-
*
|
|
2020
|
+
* Fails on a duplicate id; the record's snapshot version and pending ids must be valid. When
|
|
2021
|
+
* an active record omits `schemaEpochGuard`, the store stamps its current structural epoch in
|
|
2022
|
+
* the same atomic creation step. A supplied stale guard throws `SchemaConflictError`.
|
|
1059
2023
|
*/
|
|
1060
|
-
publishManifest(input: PublishManifestInput): Promise<Manifest>;
|
|
1061
|
-
/** Fails on a duplicate id; the record's snapshot version and pending ids must be valid. */
|
|
1062
2024
|
createTransaction(record: TransactionRecord): Promise<void>;
|
|
1063
2025
|
getTransaction(id: string): Promise<TransactionRecord | undefined>;
|
|
1064
2026
|
/** Positional per requested id; undefined where a record does not exist. */
|
|
1065
2027
|
getTransactions(ids: readonly string[]): Promise<Array<TransactionRecord | undefined>>;
|
|
1066
|
-
/** Sorted by startedAt, then id. */
|
|
1067
|
-
listTransactions(): Promise<TransactionRecord[]>;
|
|
1068
2028
|
listTransactionPage(afterId: string | null, limit: number): Promise<StoragePage<TransactionRecord, string>>;
|
|
1069
2029
|
/**
|
|
1070
2030
|
* Compare-and-swap on `expectedRevision` (`TransactionRecordConflictError` on a mismatch).
|
|
@@ -1072,15 +2032,35 @@ export interface TransactionStore {
|
|
|
1072
2032
|
* committed.
|
|
1073
2033
|
*/
|
|
1074
2034
|
updateTransaction(id: string, expectedRevision: number, update: TransactionRecordUpdate): Promise<TransactionRecord>;
|
|
2035
|
+
/**
|
|
2036
|
+
* Extends a matching active writer's durable deadline without changing its data revision.
|
|
2037
|
+
* Returns false after ownership is lost or the transaction becomes terminal.
|
|
2038
|
+
*/
|
|
2039
|
+
renewTransaction(input: RenewTransactionInput): Promise<boolean>;
|
|
2040
|
+
/**
|
|
2041
|
+
* Atomically aborts an active transaction only when both its owner still matches and its
|
|
2042
|
+
* durable deadline is at or before the cutoff. A concurrent renewal wins by returning
|
|
2043
|
+
* undefined; a successful abort preserves artifact provenance and advances the data revision.
|
|
2044
|
+
*/
|
|
2045
|
+
abortTransactionIfExpired(input: AbortTransactionIfExpiredInput): Promise<TransactionRecord | undefined>;
|
|
1075
2046
|
/** Publishes the next version; the summary omits the block list, which commits never need. */
|
|
1076
2047
|
commitTransaction(input: CommitTransactionInput): Promise<ManifestSummary>;
|
|
1077
|
-
addSegment(record: SegmentRecord): Promise<void>;
|
|
1078
2048
|
getSegment(id: string): Promise<SegmentRecord | undefined>;
|
|
1079
|
-
/** Sorted by id; `tableId` filters. */
|
|
1080
|
-
listSegments(tableId?: string): Promise<SegmentRecord[]>;
|
|
1081
2049
|
/** Sorted by id, after the exclusive cursor; bounded for maintenance scans. */
|
|
1082
2050
|
listSegmentPage(afterId: string | null, limit: number): Promise<StoragePage<SegmentRecord, string>>;
|
|
1083
|
-
|
|
2051
|
+
/** Table-indexed ID page; query/compaction paths never scan unrelated segment history. */
|
|
2052
|
+
listTableSegmentPage(tableId: string, afterId: string | null, limit: number): Promise<StoragePage<SegmentRecord, string>>;
|
|
2053
|
+
/**
|
|
2054
|
+
* Removes an unpublished segment left by the exact aborted owner and unjournals it from that
|
|
2055
|
+
* transaction in the same atomic step. Returns false when the segment is already absent.
|
|
2056
|
+
* Any owner mismatch, non-aborted/missing owner, readable-manifest block reference, active
|
|
2057
|
+
* transaction pending-segment reference, or nonterminal compaction reference rejects without
|
|
2058
|
+
* mutation. A block alias in another journal is safe: this operation deletes segment metadata,
|
|
2059
|
+
* never payload bytes.
|
|
2060
|
+
*/
|
|
2061
|
+
removeAbortedSegment(id: string, expectedTransactionId: string): Promise<boolean>;
|
|
2062
|
+
/** See `AdoptAbortedSegmentInput`; returns the updated replacement transaction journal. */
|
|
2063
|
+
adoptAbortedSegment(input: AdoptAbortedSegmentInput): Promise<TransactionRecord>;
|
|
1084
2064
|
}
|
|
1085
2065
|
/**
|
|
1086
2066
|
* Reader pins. A lease is a stored record with an expiry that protects one manifest version
|
|
@@ -1090,15 +2070,28 @@ export interface TransactionStore {
|
|
|
1090
2070
|
* tabs safe.
|
|
1091
2071
|
*/
|
|
1092
2072
|
export interface LeaseStore {
|
|
1093
|
-
/**
|
|
2073
|
+
/**
|
|
2074
|
+
* Fails on a duplicate id or unavailable manifest. Before enforcing MAX_ACTIVE_LEASES, an
|
|
2075
|
+
* adapter sweeps a bounded expired page; creation and the final count check are atomic.
|
|
2076
|
+
*/
|
|
1094
2077
|
createLease(record: LeaseRecord): Promise<void>;
|
|
1095
2078
|
getLease(id: string): Promise<LeaseRecord | undefined>;
|
|
1096
|
-
/** Sorted by id. */
|
|
2079
|
+
/** Sorted by id; MAX_ACTIVE_LEASES makes this array globally bounded. */
|
|
1097
2080
|
listLeases(): Promise<LeaseRecord[]>;
|
|
1098
|
-
|
|
2081
|
+
/** Bounded expiry/id-ordered page containing only records expired at the fixed cutoff. */
|
|
2082
|
+
listExpiredLeasePage(expiresAtCutoff: string, afterCursor: string | null, limit: number): Promise<StoragePage<LeaseRecord, string>>;
|
|
2083
|
+
renewLease(input: RenewLeaseInput): Promise<LeaseRecord>;
|
|
1099
2084
|
/** True when removed; false (without removing) when the lease has not yet expired. */
|
|
1100
2085
|
removeLeaseIfExpired(id: string, expectedRevision: number, expiresAtCutoff: string): Promise<boolean>;
|
|
1101
|
-
|
|
2086
|
+
/**
|
|
2087
|
+
* Releases an existing lease only for its durable owner. A concurrent same-owner renewal may
|
|
2088
|
+
* still be removed safely; a different owner throws `LeaseOwnerConflictError` without change.
|
|
2089
|
+
* Returns false when the lease is already absent.
|
|
2090
|
+
*/
|
|
2091
|
+
removeLease(input: {
|
|
2092
|
+
id: string;
|
|
2093
|
+
ownerId: string;
|
|
2094
|
+
}): Promise<boolean>;
|
|
1102
2095
|
}
|
|
1103
2096
|
/**
|
|
1104
2097
|
* Background-maintenance bookkeeping: the resumable job records that let compaction and
|
|
@@ -1114,9 +2107,16 @@ export interface LeaseStore {
|
|
|
1114
2107
|
* needs.
|
|
1115
2108
|
*/
|
|
1116
2109
|
export interface MaintenanceStore {
|
|
2110
|
+
/**
|
|
2111
|
+
* Atomically enforces one nonterminal job per table and MAX_ACTIVE_COMPACTION_JOBS globally;
|
|
2112
|
+
* terminal history does not count and is pruned separately.
|
|
2113
|
+
*/
|
|
1117
2114
|
createCompactionJob(record: CompactionJobRecord): Promise<void>;
|
|
1118
2115
|
getCompactionJob(id: string): Promise<CompactionJobRecord | undefined>;
|
|
1119
|
-
/**
|
|
2116
|
+
/**
|
|
2117
|
+
* Sorted by createdAt, then id; `tableId` filters. The returned array is bounded by the
|
|
2118
|
+
* enforced active and terminal compaction-job record quotas above.
|
|
2119
|
+
*/
|
|
1120
2120
|
listCompactionJobs(tableId?: string): Promise<CompactionJobRecord[]>;
|
|
1121
2121
|
listCompactionJobPage(afterId: string | null, limit: number): Promise<StoragePage<CompactionJobRecord, string>>;
|
|
1122
2122
|
updateCompactionJob(id: string, expectedRevision: number, update: CompactionJobRecordUpdate): Promise<CompactionJobRecord>;
|
|
@@ -1126,19 +2126,33 @@ export interface MaintenanceStore {
|
|
|
1126
2126
|
* cancelled and its active transaction aborted — atomically.
|
|
1127
2127
|
*/
|
|
1128
2128
|
cancelCompactionJob(id: string, expectedRevision: number, cancelledAt: string): Promise<CompactionJobRecord>;
|
|
1129
|
-
|
|
2129
|
+
/**
|
|
2130
|
+
* Removes only published, cancelled, or aborted diagnostics. Returns false when missing or
|
|
2131
|
+
* when an existing source/output block or segment would lose its last durable provenance/root;
|
|
2132
|
+
* collection can remove that payload first. Nonterminal removal throws without mutation.
|
|
2133
|
+
*/
|
|
2134
|
+
removeCompactionJob(id: string): Promise<boolean>;
|
|
1130
2135
|
/** Validates candidate provenance against persisted records before accepting the job. */
|
|
1131
2136
|
createGarbageCollectionJob(input: CreateGarbageCollectionJobInput): Promise<GarbageCollectionJobRecord>;
|
|
2137
|
+
/** CAS-appends one bounded discovery page; no payload or catalog data is changed. */
|
|
2138
|
+
updateGarbageCollectionPlanning(input: UpdateGarbageCollectionPlanningInput): Promise<GarbageCollectionJobRecord>;
|
|
1132
2139
|
getGarbageCollectionJob(id: string): Promise<GarbageCollectionJobRecord | undefined>;
|
|
1133
|
-
/**
|
|
2140
|
+
/**
|
|
2141
|
+
* Sorted by createdAt, then id. The returned array is bounded by the enforced active and
|
|
2142
|
+
* completed garbage-collection record quotas above.
|
|
2143
|
+
*/
|
|
1134
2144
|
listGarbageCollectionJobs(): Promise<GarbageCollectionJobRecord[]>;
|
|
2145
|
+
/** Bounded page sorted by id; maintenance paths use this instead of materializing history. */
|
|
2146
|
+
listGarbageCollectionJobPage(afterId: string | null, limit: number): Promise<StoragePage<GarbageCollectionJobRecord, string>>;
|
|
1135
2147
|
runGarbageCollectionStep(input: RunGarbageCollectionStepInput): Promise<GarbageCollectionStepResult>;
|
|
1136
2148
|
/**
|
|
1137
|
-
*
|
|
1138
|
-
*
|
|
1139
|
-
*
|
|
2149
|
+
* Removes at most `maxItems` obsolete summary tombstones while retaining the checkpoint prefix
|
|
2150
|
+
* readable deltas need. Retired block provenance, not the summary, is durable garbage
|
|
2151
|
+
* discovery; `runGarbageCollectionStep` removes each payload and its provenance atomically, so
|
|
2152
|
+
* deleting a summary cannot strand an undiscoverable block.
|
|
1140
2153
|
*/
|
|
1141
|
-
removePrunedManifestRecords(): Promise<number>;
|
|
2154
|
+
removePrunedManifestRecords(maxItems: number): Promise<number>;
|
|
2155
|
+
/** Removes only a completed diagnostic; planned/running collection is refused. */
|
|
1142
2156
|
removeGarbageCollectionJob(id: string): Promise<void>;
|
|
1143
2157
|
}
|
|
1144
2158
|
/**
|
|
@@ -1149,6 +2163,10 @@ export interface MaintenanceStore {
|
|
|
1149
2163
|
*/
|
|
1150
2164
|
export interface FtsIndexStore {
|
|
1151
2165
|
/** Removes every base chunk and commit delta owned by one column. */
|
|
2166
|
+
/**
|
|
2167
|
+
* Removes posting storage only when the current catalog no longer owns it as a ready/building
|
|
2168
|
+
* accelerator (absent or invalid is safe). Refusal leaves catalog and postings unchanged.
|
|
2169
|
+
*/
|
|
1152
2170
|
removeFtsColumn(tableId: string, columnId: string): Promise<void>;
|
|
1153
2171
|
/**
|
|
1154
2172
|
* Replaces one column's full-text base chunks (term-range partitioned, term-sorted within
|
|
@@ -1171,7 +2189,7 @@ export interface FtsIndexStore {
|
|
|
1171
2189
|
* needing snapshot-exact statistics must detect `coversVersion > upToVersion` and fall
|
|
1172
2190
|
* back (candidates stay a safe superset either way).
|
|
1173
2191
|
*/
|
|
1174
|
-
readFtsCandidates(tableId: string, columnId: string, terms: readonly FtsPostingQuery[], upToVersion: number): Promise<FtsCandidates & {
|
|
2192
|
+
readFtsCandidates(tableId: string, columnId: string, terms: readonly FtsPostingQuery[], upToVersion: number, maxRowIds?: number): Promise<FtsCandidates & {
|
|
1175
2193
|
deltaChunkCount: number;
|
|
1176
2194
|
totalTokens: number;
|
|
1177
2195
|
coversVersion: number;
|
|
@@ -1181,8 +2199,10 @@ export interface FtsIndexStore {
|
|
|
1181
2199
|
* Canonical term/posting order from the same snapshot-bounded base-plus-delta view. This is a
|
|
1182
2200
|
* materialized cold path for ordered and covering scans; callers must not retain the result.
|
|
1183
2201
|
*/
|
|
1184
|
-
readFtsPostings(tableId: string, columnId: string, upToVersion: number): Promise<{
|
|
2202
|
+
readFtsPostings(tableId: string, columnId: string, upToVersion: number, maxRowIds?: number, maxRetainedBytes?: number): Promise<{
|
|
1185
2203
|
postings: FtsPosting[];
|
|
2204
|
+
/** The bounded merge stopped early; callers must scan and may rebuild the accelerator. */
|
|
2205
|
+
overflow: boolean;
|
|
1186
2206
|
deltaChunkCount: number;
|
|
1187
2207
|
coversVersion: number;
|
|
1188
2208
|
hasBase: boolean;
|
|
@@ -1195,6 +2215,7 @@ export interface FtsIndexStore {
|
|
|
1195
2215
|
* records are real records with the usual compare-and-swap (`TempOwnerConflictError`).
|
|
1196
2216
|
*/
|
|
1197
2217
|
export interface TempSpillStore {
|
|
2218
|
+
/** Atomically enforces the per-owner run/page ceilings before storing payload bytes. */
|
|
1198
2219
|
putTempRunPage(page: TempRunPage): Promise<void>;
|
|
1199
2220
|
/**
|
|
1200
2221
|
* Optional: writes a batch of pages in one storage round trip. Callers fall back to
|
|
@@ -1206,13 +2227,16 @@ export interface TempSpillStore {
|
|
|
1206
2227
|
removeTempRun(ownerId: string, runId: string): Promise<void>;
|
|
1207
2228
|
/** Removes the owner record and every page under the owner. */
|
|
1208
2229
|
removeTempOwner(ownerId: string): Promise<void>;
|
|
2230
|
+
/** Sweeps a bounded expired page before atomically enforcing MAX_ACTIVE_TEMP_OWNERS. */
|
|
1209
2231
|
createTempOwner(record: TempOwnerRecord): Promise<void>;
|
|
1210
2232
|
getTempOwner(ownerId: string): Promise<TempOwnerRecord | undefined>;
|
|
1211
|
-
renewTempOwner(
|
|
2233
|
+
renewTempOwner(input: RenewTempOwnerInput): Promise<TempOwnerRecord>;
|
|
1212
2234
|
/** Sweeps pages too when it removes; owners found only via orphaned pages count as expired. */
|
|
1213
2235
|
removeTempOwnerIfExpired(ownerId: string, expiresAtCutoff: string): Promise<boolean>;
|
|
1214
2236
|
/** Owner ids from records and from orphaned pages alike, deduplicated, sorted, paged. */
|
|
1215
2237
|
listTempOwnerIdsPage(afterOwnerId: string | null, limit: number): Promise<StoragePage<string, string>>;
|
|
2238
|
+
/** Actual expired candidates only, ordered by expiry then owner id. */
|
|
2239
|
+
listExpiredTempOwnerPage(expiresAtCutoff: string, afterCursor: string | null, limit: number): Promise<StoragePage<string, string>>;
|
|
1216
2240
|
}
|
|
1217
2241
|
/**
|
|
1218
2242
|
* The complete storage contract: a database is `MinnowDatabase` plus one implementation of
|
|
@@ -1227,8 +2251,10 @@ export interface TempSpillStore {
|
|
|
1227
2251
|
*
|
|
1228
2252
|
* - **Atomicity.** Every method is all-or-nothing, including after a crash at any moment.
|
|
1229
2253
|
* `commitTransaction` and `runGarbageCollectionStep` mutate several record families in one
|
|
1230
|
-
* durable step. A method that resolves has happened;
|
|
1231
|
-
*
|
|
2254
|
+
* durable step. A local adapter method that resolves has happened; one that rejects has not
|
|
2255
|
+
* happened. The narrow transport-loss exception is an OPFS follower call that throws
|
|
2256
|
+
* `OpfsUncertainOutcomeError`: its prior leader may have committed the named mutation before
|
|
2257
|
+
* losing the reply, so callers must inspect/reopen instead of blindly repeating it.
|
|
1232
2258
|
* - **Conflicts are typed, by exact class.** Compare-and-swap failures throw the exported
|
|
1233
2259
|
* error classes (`WriteConflictError`, `TransactionRecordConflictError`,
|
|
1234
2260
|
* `TableRecordConflictError`, `LeaseConflictError`, `CompactionJobConflictError`,
|
|
@@ -1242,10 +2268,10 @@ export interface TempSpillStore {
|
|
|
1242
2268
|
* received records and bytes must be copied or serialized before the call resolves.
|
|
1243
2269
|
* - **Deterministic ordering.** List methods sort as documented on each capability interface;
|
|
1244
2270
|
* pagination cursors are stable under concurrent writes.
|
|
1245
|
-
* - **Optional means atomic.**
|
|
1246
|
-
* in one atomic step may say so; callers trust a present method completely and fall
|
|
1247
|
-
*
|
|
1248
|
-
* trench coat.
|
|
2271
|
+
* - **Optional means atomic.** Optional accelerator methods exist so an adapter that can do
|
|
2272
|
+
* something in one atomic step may say so; callers trust a present method completely and fall
|
|
2273
|
+
* back to safe sequential calls when it is absent. Never implement one as sequential calls in
|
|
2274
|
+
* a trench coat.
|
|
1249
2275
|
* - **Multiple connections are normal.** Several instances (tabs) may open one database.
|
|
1250
2276
|
* Readers must never block writers; competing writers must resolve through the typed
|
|
1251
2277
|
* conflicts. How is the adapter's business — storage transactions, a write-ahead log behind
|
|
@@ -1265,46 +2291,51 @@ export interface BlockStore extends BlockPayloadStore, CatalogStore, Transaction
|
|
|
1265
2291
|
* generation per retry. Required because an index build must never materialize one
|
|
1266
2292
|
* database-sized storage value as a fallback.
|
|
1267
2293
|
*/
|
|
1268
|
-
beginFtsBaseBuild(
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
totalTokens: number;
|
|
1274
|
-
}): Promise<void>;
|
|
1275
|
-
abortFtsBaseBuild(tableId: string, columnId: string, buildId: string): Promise<void>;
|
|
2294
|
+
beginFtsBaseBuild(input: BeginPostingBuildInput): Promise<void>;
|
|
2295
|
+
renewFtsBaseBuild(input: RenewPostingBuildInput): Promise<void>;
|
|
2296
|
+
writeFtsBaseBuildChunk(input: AppendPostingBuildChunkInput): Promise<void>;
|
|
2297
|
+
finishFtsBaseBuild(input: FinishPostingBuildInput): Promise<void>;
|
|
2298
|
+
abortFtsBaseBuild(input: AbortPostingBuildInput): Promise<void>;
|
|
1276
2299
|
/**
|
|
1277
|
-
*
|
|
1278
|
-
*
|
|
1279
|
-
*
|
|
2300
|
+
* The current manifest version, catalog epoch, and structural schema epoch in one atomic read.
|
|
2301
|
+
* An unchanged manifest/catalog pair proves cached query state is current; the schema epoch is
|
|
2302
|
+
* the narrower write-serialization guard and does not move for ordinary commits.
|
|
1280
2303
|
*/
|
|
1281
|
-
getCatalogProbe
|
|
2304
|
+
getCatalogProbe(): Promise<CatalogProbe>;
|
|
1282
2305
|
/**
|
|
1283
|
-
* Optional
|
|
1284
|
-
*
|
|
1285
|
-
*
|
|
1286
|
-
* listSegments/getTransactions instead. Callers fall back to those calls when this is absent.
|
|
2306
|
+
* Optional atomic query-catalog read. The returned tables, segments, transaction owners, and
|
|
2307
|
+
* probe epoch must come from one storage snapshot; engines use the sequential stable-epoch
|
|
2308
|
+
* fallback when an adapter does not provide it.
|
|
1287
2309
|
*/
|
|
1288
|
-
getQueryCatalogState?(
|
|
2310
|
+
getQueryCatalogState?(names: readonly string[]): Promise<QueryCatalogState>;
|
|
1289
2311
|
/**
|
|
1290
|
-
*
|
|
1291
|
-
* and optionally reserves row ids
|
|
1292
|
-
*
|
|
2312
|
+
* Reads the current manifest and schema epoch, creates the transaction record pinned to both,
|
|
2313
|
+
* and optionally reserves row ids or an invisible pending table in one atomic storage
|
|
2314
|
+
* transaction. Required because these reservations cannot be emulated safely by sequential
|
|
2315
|
+
* calls.
|
|
1293
2316
|
*/
|
|
1294
|
-
beginTransaction
|
|
2317
|
+
beginTransaction(input: BeginTransactionInput): Promise<BeginTransactionResult>;
|
|
1295
2318
|
/**
|
|
1296
|
-
*
|
|
1297
|
-
*
|
|
1298
|
-
*
|
|
1299
|
-
* crash
|
|
2319
|
+
* Required atomic staging boundary: saves blocks and segments and appends their ids to the
|
|
2320
|
+
* active transaction journal in one durable operation. It is equivalent to addBlocks +
|
|
2321
|
+
* addSegment(s) + one updateTransaction only when those changes commit atomically; there is no
|
|
2322
|
+
* sequential fallback because a crash could otherwise strand bytes or publish a dangling id.
|
|
2323
|
+
* A local refusal has no effect; the documented OPFS follower uncertain-outcome error means
|
|
2324
|
+
* the complete operation may have happened and must never be converted to an ordinary error.
|
|
1300
2325
|
*/
|
|
1301
|
-
stageTransactionArtifacts
|
|
2326
|
+
stageTransactionArtifacts(input: StageTransactionArtifactsInput): Promise<TransactionRecord>;
|
|
2327
|
+
/**
|
|
2328
|
+
* Required atomic savepoint rewind. Compare-and-swaps the journal, validates retained and
|
|
2329
|
+
* removed ids as its exact duplicate-free partition, and removes only the unreachable removed
|
|
2330
|
+
* artifacts in the same durable operation. A refusal leaves both journal and bytes unchanged.
|
|
2331
|
+
*/
|
|
2332
|
+
rollbackTransactionArtifacts(input: RollbackTransactionArtifactsInput): Promise<TransactionRecord>;
|
|
1302
2333
|
/**
|
|
1303
2334
|
* Optional: the single-shot write — begin (or continue) a transaction, stage its blocks and
|
|
1304
2335
|
* segments, and commit, all in one atomic storage transaction. Must be exactly equivalent to
|
|
1305
2336
|
* `stageTransactionArtifacts` followed by `commitTransaction` (preceded by `createTransaction`
|
|
1306
2337
|
* at `expectedManifestVersion` when the input carries a fresh record): the same validation,
|
|
1307
|
-
* the same typed conflicts (`WriteConflictError`, `TransactionRecordConflictError`,
|
|
2338
|
+
* the same typed conflicts (`SchemaConflictError`, `WriteConflictError`, `TransactionRecordConflictError`,
|
|
1308
2339
|
* `UniqueKeyConflictError`), the same finalized records afterwards — and nothing at all
|
|
1309
2340
|
* written when any part refuses, including the fresh record. This is what lets a simple
|
|
1310
2341
|
* write cost one durable storage commit instead of three; callers fall back to the sequence
|
|
@@ -1315,29 +2346,52 @@ export interface BlockStore extends BlockPayloadStore, CatalogStore, Transaction
|
|
|
1315
2346
|
* Optional: re-pins a lease to another manifest version and renews it, in one atomic step —
|
|
1316
2347
|
* `createLease` at the new version plus `removeLease` of the old pin, as one round trip that
|
|
1317
2348
|
* keeps the record and its id. Compare-and-swap on `expectedRevision` (`LeaseConflictError`);
|
|
1318
|
-
* the target version's manifest must be available (`SnapshotManifestMissingError`), and a
|
|
1319
|
-
*
|
|
2349
|
+
* the target version's manifest must be available (`SnapshotManifestMissingError`), and a refused
|
|
2350
|
+
* move leaves the lease exactly as it was. An already-expired pin cannot be moved or renewed,
|
|
2351
|
+
* and the new expiry is capped by `MAX_LEASE_TTL_MS`. The engine uses it to carry its shared
|
|
1320
2352
|
* reader pin forward after each commit; callers fall back to create + remove when absent.
|
|
1321
2353
|
*/
|
|
1322
|
-
moveLease?(
|
|
2354
|
+
moveLease?(input: MoveLeaseInput): Promise<LeaseRecord>;
|
|
1323
2355
|
/**
|
|
1324
|
-
*
|
|
1325
|
-
*
|
|
1326
|
-
*
|
|
2356
|
+
* Native bounded snapshot v1. Built-in adapters implement this complete family together.
|
|
2357
|
+
* Export reads exactly one globally ordered frame at a time from a durable frozen generation;
|
|
2358
|
+
* close releases that generation and its lease. No method returns a database-sized array.
|
|
1327
2359
|
*/
|
|
1328
|
-
|
|
2360
|
+
beginSnapshotFrameExport?(input: BeginSnapshotFrameExportInput): Promise<SnapshotFrameExportSession>;
|
|
2361
|
+
readSnapshotExportFrame?(input: ReadSnapshotExportFrameInput): Promise<SnapshotFrame | undefined>;
|
|
2362
|
+
closeSnapshotFrameExport?(input: CloseSnapshotExportInput): Promise<boolean>;
|
|
1329
2363
|
/**
|
|
1330
|
-
*
|
|
1331
|
-
*
|
|
2364
|
+
* Native bounded import. Append atomically accepts only contiguous bounded frames and exact
|
|
2365
|
+
* lost-ack replay bytes. Finish validates header/footer counts, order, checksums, complete
|
|
2366
|
+
* catalog/segment/transaction/index cross-references, and atomically promotes all staged
|
|
2367
|
+
* generations; rejection leaves the current database unchanged.
|
|
1332
2368
|
*/
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
2369
|
+
beginSnapshotFrameImport?(input: BeginSnapshotFrameImportInput): Promise<SnapshotFrameImportSession>;
|
|
2370
|
+
renewSnapshotFrameImport?(input: RenewSnapshotFrameImportInput): Promise<SnapshotFrameImportSession>;
|
|
2371
|
+
appendSnapshotImportFrames?(input: AppendSnapshotImportFramesInput): Promise<SnapshotFrameImportSession>;
|
|
2372
|
+
finishSnapshotFrameImport?(input: FinishSnapshotFrameImportInput): Promise<void>;
|
|
2373
|
+
cancelSnapshotFrameImport?(input: CancelSnapshotImportInput): Promise<InterruptedSnapshotImportAbortResult>;
|
|
2374
|
+
/** Bounded, fail-closed verification of control records and optionally every live block. */
|
|
2375
|
+
checkIntegrity?(options?: {
|
|
2376
|
+
mode?: StorageIntegrityMode;
|
|
2377
|
+
maxIssues?: number;
|
|
2378
|
+
}): Promise<StorageIntegrityReport>;
|
|
2379
|
+
/** Explicit storage accounting; adapters do not run this on query or write hot paths. */
|
|
2380
|
+
getStorageStats?(): Promise<StorageStats>;
|
|
2381
|
+
/** Returns the durable marker for an unpublished snapshot import, if this adapter has one. */
|
|
2382
|
+
inspectInterruptedImport?(): Promise<InterruptedSnapshotImport | null>;
|
|
2383
|
+
/** Atomically abandons the named unpublished import and removes all staged state. */
|
|
2384
|
+
abortInterruptedImport?(identity: string): Promise<InterruptedSnapshotImportAbortResult>;
|
|
1336
2385
|
/**
|
|
1337
2386
|
* Optional: what this database's data occupies in its substrate, in bytes — the number an
|
|
1338
2387
|
* application shows a user next to the quota, and what the benchmarks report.
|
|
1339
2388
|
*/
|
|
1340
2389
|
getLogicalStorageBytes?(): Promise<number>;
|
|
2390
|
+
/**
|
|
2391
|
+
* Optional deterministic channel for commit hints between connections to the same durable
|
|
2392
|
+
* database. The engine creates the BroadcastChannel; stores only expose identity.
|
|
2393
|
+
*/
|
|
2394
|
+
readonly liveQueryChannelName?: string;
|
|
1341
2395
|
/**
|
|
1342
2396
|
* Releases whatever the connection holds (open handles, channels, timers) without flushing
|
|
1343
2397
|
* or deleting anything. Synchronous; safe to call twice. Data durability must never depend
|
|
@@ -1345,17 +2399,16 @@ export interface BlockStore extends BlockPayloadStore, CatalogStore, Transaction
|
|
|
1345
2399
|
*/
|
|
1346
2400
|
close(): void;
|
|
1347
2401
|
}
|
|
1348
|
-
export declare function createManifest(input:
|
|
1349
|
-
/**
|
|
1350
|
-
* Normalizes the additive L2 partition metadata while preserving legacy segment records verbatim.
|
|
1351
|
-
*/
|
|
2402
|
+
export declare function createManifest(input: CreateManifestInput): Manifest;
|
|
2403
|
+
/** Strictly clones the one canonical v1 segment shape. */
|
|
1352
2404
|
export declare function normalizeSegmentRecord(record: SegmentRecord): SegmentRecord;
|
|
1353
2405
|
export declare function updateTransactionRecord(record: TransactionRecord, update: TransactionRecordUpdate): TransactionRecord;
|
|
1354
2406
|
export declare function createGarbageCollectionJobRecord(input: CreateGarbageCollectionJobInput): GarbageCollectionJobRecord;
|
|
2407
|
+
export declare function normalizeGarbageCollectionDiscovery(discovery: GarbageCollectionDiscovery): GarbageCollectionDiscovery;
|
|
2408
|
+
export declare function updateGarbageCollectionPlanningRecord(record: GarbageCollectionJobRecord, input: UpdateGarbageCollectionPlanningInput): GarbageCollectionJobRecord;
|
|
1355
2409
|
export declare function normalizeGarbageCollectionJobRecord(record: GarbageCollectionJobRecord): GarbageCollectionJobRecord;
|
|
1356
2410
|
export declare function advanceGarbageCollectionJobRecord(record: GarbageCollectionJobRecord, accounting: GarbageCollectionStepAccounting): GarbageCollectionJobRecord;
|
|
1357
2411
|
export declare function normalizeCompactionJobRecord(record: CompactionJobRecord): CompactionJobRecord;
|
|
1358
2412
|
export declare function updateCompactionJobRecord(record: CompactionJobRecord, update: CompactionJobRecordUpdate): CompactionJobRecord;
|
|
1359
2413
|
/** Floors an integer-times-double product without rounding the binary double upward. */
|
|
1360
2414
|
export declare function floorWholeNumberProduct(left: number, right: number, label: string): number;
|
|
1361
|
-
//# sourceMappingURL=types.d.ts.map
|