@minnowdb/core 0.0.1 → 0.1.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/LICENSE +21 -0
- package/README.md +38 -1
- package/dist/block-format/block.d.ts +46 -0
- package/dist/block-format/block.d.ts.map +1 -0
- package/dist/block-format/block.js +244 -0
- package/dist/block-format/block.js.map +1 -0
- package/dist/block-format/checksum.d.ts +7 -0
- package/dist/block-format/checksum.d.ts.map +1 -0
- package/dist/block-format/checksum.js +56 -0
- package/dist/block-format/checksum.js.map +1 -0
- package/dist/block-format/codecs.d.ts +24 -0
- package/dist/block-format/codecs.d.ts.map +1 -0
- package/dist/block-format/codecs.js +102 -0
- package/dist/block-format/codecs.js.map +1 -0
- package/dist/block-format/column.d.ts +8 -0
- package/dist/block-format/column.d.ts.map +1 -0
- package/dist/block-format/column.js +166 -0
- package/dist/block-format/column.js.map +1 -0
- package/dist/block-format/index.d.ts +7 -0
- package/dist/block-format/index.d.ts.map +1 -0
- package/dist/block-format/index.js +7 -0
- package/dist/block-format/index.js.map +1 -0
- package/dist/block-format/physical.d.ts +20 -0
- package/dist/block-format/physical.d.ts.map +1 -0
- package/dist/block-format/physical.js +439 -0
- package/dist/block-format/physical.js.map +1 -0
- package/dist/block-format/types.d.ts +93 -0
- package/dist/block-format/types.d.ts.map +1 -0
- package/dist/block-format/types.js +2 -0
- package/dist/block-format/types.js.map +1 -0
- package/dist/engine/artifact-cache.d.ts +22 -0
- package/dist/engine/artifact-cache.d.ts.map +1 -0
- package/dist/engine/artifact-cache.js +68 -0
- package/dist/engine/artifact-cache.js.map +1 -0
- package/dist/engine/batch.d.ts +28 -0
- package/dist/engine/batch.d.ts.map +1 -0
- package/dist/engine/batch.js +38 -0
- package/dist/engine/batch.js.map +1 -0
- package/dist/engine/buffered-writer.d.ts +43 -0
- package/dist/engine/buffered-writer.d.ts.map +1 -0
- package/dist/engine/buffered-writer.js +158 -0
- package/dist/engine/buffered-writer.js.map +1 -0
- package/dist/engine/catalog.d.ts +82 -0
- package/dist/engine/catalog.d.ts.map +1 -0
- package/dist/engine/catalog.js +47 -0
- package/dist/engine/catalog.js.map +1 -0
- package/dist/engine/client.d.ts +211 -0
- package/dist/engine/client.d.ts.map +1 -0
- package/dist/engine/client.js +538 -0
- package/dist/engine/client.js.map +1 -0
- package/dist/engine/coordinator.d.ts +17 -0
- package/dist/engine/coordinator.d.ts.map +1 -0
- package/dist/engine/coordinator.js +60 -0
- package/dist/engine/coordinator.js.map +1 -0
- package/dist/engine/database.d.ts +661 -0
- package/dist/engine/database.d.ts.map +1 -0
- package/dist/engine/database.js +10313 -0
- package/dist/engine/database.js.map +1 -0
- package/dist/engine/defaults.d.ts +33 -0
- package/dist/engine/defaults.d.ts.map +1 -0
- package/dist/engine/defaults.js +87 -0
- package/dist/engine/defaults.js.map +1 -0
- package/dist/engine/errors.d.ts +55 -0
- package/dist/engine/errors.d.ts.map +1 -0
- package/dist/engine/errors.js +81 -0
- package/dist/engine/errors.js.map +1 -0
- package/dist/engine/fts.d.ts +93 -0
- package/dist/engine/fts.d.ts.map +1 -0
- package/dist/engine/fts.js +273 -0
- package/dist/engine/fts.js.map +1 -0
- package/dist/engine/group-index.d.ts +32 -0
- package/dist/engine/group-index.d.ts.map +1 -0
- package/dist/engine/group-index.js +366 -0
- package/dist/engine/group-index.js.map +1 -0
- package/dist/engine/index.d.ts +13 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +12 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/join-index.d.ts +12 -0
- package/dist/engine/join-index.d.ts.map +1 -0
- package/dist/engine/join-index.js +217 -0
- package/dist/engine/join-index.js.map +1 -0
- package/dist/engine/live.d.ts +86 -0
- package/dist/engine/live.d.ts.map +1 -0
- package/dist/engine/live.js +289 -0
- package/dist/engine/live.js.map +1 -0
- package/dist/engine/memory.d.ts +37 -0
- package/dist/engine/memory.d.ts.map +1 -0
- package/dist/engine/memory.js +119 -0
- package/dist/engine/memory.js.map +1 -0
- package/dist/engine/optimizer.d.ts +20 -0
- package/dist/engine/optimizer.d.ts.map +1 -0
- package/dist/engine/optimizer.js +1170 -0
- package/dist/engine/optimizer.js.map +1 -0
- package/dist/engine/query-cache.d.ts +10 -0
- package/dist/engine/query-cache.d.ts.map +1 -0
- package/dist/engine/query-cache.js +58 -0
- package/dist/engine/query-cache.js.map +1 -0
- package/dist/engine/query.d.ts +844 -0
- package/dist/engine/query.d.ts.map +1 -0
- package/dist/engine/query.js +7450 -0
- package/dist/engine/query.js.map +1 -0
- package/dist/engine/schema-wire.d.ts +92 -0
- package/dist/engine/schema-wire.d.ts.map +1 -0
- package/dist/engine/schema-wire.js +115 -0
- package/dist/engine/schema-wire.js.map +1 -0
- package/dist/engine/schema.d.ts +394 -0
- package/dist/engine/schema.d.ts.map +1 -0
- package/dist/engine/schema.js +709 -0
- package/dist/engine/schema.js.map +1 -0
- package/dist/engine/sort-keys.d.ts +36 -0
- package/dist/engine/sort-keys.d.ts.map +1 -0
- package/dist/engine/sort-keys.js +60 -0
- package/dist/engine/sort-keys.js.map +1 -0
- package/dist/engine/sql-json.d.ts +30 -0
- package/dist/engine/sql-json.d.ts.map +1 -0
- package/dist/engine/sql-json.js +120 -0
- package/dist/engine/sql-json.js.map +1 -0
- package/dist/engine/sql-semantics.d.ts +31 -0
- package/dist/engine/sql-semantics.d.ts.map +1 -0
- package/dist/engine/sql-semantics.js +121 -0
- package/dist/engine/sql-semantics.js.map +1 -0
- package/dist/engine/vector.d.ts +87 -0
- package/dist/engine/vector.d.ts.map +1 -0
- package/dist/engine/vector.js +4227 -0
- package/dist/engine/vector.js.map +1 -0
- package/dist/engine/worker-host.d.ts +48 -0
- package/dist/engine/worker-host.d.ts.map +1 -0
- package/dist/engine/worker-host.js +501 -0
- package/dist/engine/worker-host.js.map +1 -0
- package/dist/engine/worker.d.ts +2 -0
- package/dist/engine/worker.d.ts.map +1 -0
- package/dist/engine/worker.js +14 -0
- package/dist/engine/worker.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/plan/index.d.ts +17 -0
- package/dist/plan/index.d.ts.map +1 -0
- package/dist/plan/index.js +17 -0
- package/dist/plan/index.js.map +1 -0
- package/dist/storage/fixture-shape.d.ts +42 -0
- package/dist/storage/fixture-shape.d.ts.map +1 -0
- package/dist/storage/fixture-shape.js +146 -0
- package/dist/storage/fixture-shape.js.map +1 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/indexeddb.d.ts +139 -0
- package/dist/storage/indexeddb.d.ts.map +1 -0
- package/dist/storage/indexeddb.js +3161 -0
- package/dist/storage/indexeddb.js.map +1 -0
- package/dist/storage/memory.d.ts +121 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +1455 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/snapshot.d.ts +108 -0
- package/dist/storage/snapshot.d.ts.map +1 -0
- package/dist/storage/snapshot.js +276 -0
- package/dist/storage/snapshot.js.map +1 -0
- package/dist/storage/types.d.ts +895 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +1549 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/testing/index.d.ts +76 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +233 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/seeds.d.ts +11 -0
- package/dist/testing/seeds.d.ts.map +1 -0
- package/dist/testing/seeds.js +50 -0
- package/dist/testing/seeds.js.map +1 -0
- package/dist/transactions/index.d.ts +148 -0
- package/dist/transactions/index.d.ts.map +1 -0
- package/dist/transactions/index.js +662 -0
- package/dist/transactions/index.js.map +1 -0
- package/dist/worker-protocol/index.d.ts +84 -0
- package/dist/worker-protocol/index.d.ts.map +1 -0
- package/dist/worker-protocol/index.js +117 -0
- package/dist/worker-protocol/index.js.map +1 -0
- package/package.json +66 -16
- package/sql-feature-matrix.json +1275 -0
- package/index.d.ts +0 -1
- package/index.js +0 -1
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { copyScratchKey, encodeSingleScalarKey, equalsScratch, hashScratch, } from "./group-index.js";
|
|
2
|
+
const INITIAL_ENTRY_CAPACITY = 4;
|
|
3
|
+
const INITIAL_BUCKET_CAPACITY = 8;
|
|
4
|
+
const INITIAL_KEY_CAPACITY = 32;
|
|
5
|
+
const ENTRY_FIELDS = 6;
|
|
6
|
+
const UINT32_BYTES = Uint32Array.BYTES_PER_ELEMENT;
|
|
7
|
+
/** Collision-checked scalar-key hash index with typed duplicate row chains. */
|
|
8
|
+
export class ByteJoinIndex {
|
|
9
|
+
#memory;
|
|
10
|
+
#rowNext;
|
|
11
|
+
#buckets = new Int32Array(0);
|
|
12
|
+
#hashes = new Uint32Array(0);
|
|
13
|
+
#offsets = new Uint32Array(0);
|
|
14
|
+
#lengths = new Uint32Array(0);
|
|
15
|
+
#bucketNext = new Int32Array(0);
|
|
16
|
+
#rowHeads = new Int32Array(0);
|
|
17
|
+
#rowTails = new Int32Array(0);
|
|
18
|
+
#keys = new Uint8Array(0);
|
|
19
|
+
#keyLength = 0;
|
|
20
|
+
#entryCount = 0;
|
|
21
|
+
#unique = true;
|
|
22
|
+
#entryReservation;
|
|
23
|
+
#bucketReservation;
|
|
24
|
+
#keyReservation;
|
|
25
|
+
constructor(memory, rowCapacity) {
|
|
26
|
+
if (!Number.isSafeInteger(rowCapacity) || rowCapacity < 0) {
|
|
27
|
+
throw new RangeError("Join index row capacity must be a non-negative safe integer");
|
|
28
|
+
}
|
|
29
|
+
this.#memory = memory;
|
|
30
|
+
memory.reserve(safeProduct(rowCapacity, Int32Array.BYTES_PER_ELEMENT, "Join duplicate row chains"), "Join duplicate row chains");
|
|
31
|
+
this.#rowNext = new Int32Array(rowCapacity);
|
|
32
|
+
this.#rowNext.fill(-1);
|
|
33
|
+
}
|
|
34
|
+
get unique() {
|
|
35
|
+
return this.#unique;
|
|
36
|
+
}
|
|
37
|
+
add(value, row) {
|
|
38
|
+
if (!Number.isSafeInteger(row) || row < 0 || row >= this.#rowNext.length) {
|
|
39
|
+
throw new RangeError("Join index row is outside its declared capacity");
|
|
40
|
+
}
|
|
41
|
+
const length = encodeJoinKey(value);
|
|
42
|
+
if (length < 0)
|
|
43
|
+
return;
|
|
44
|
+
const hash = hashScratch(length);
|
|
45
|
+
const existing = this.#find(length, hash);
|
|
46
|
+
if (existing >= 0) {
|
|
47
|
+
const tail = this.#rowTails[existing] ?? -1;
|
|
48
|
+
if (tail < 0)
|
|
49
|
+
throw new Error("Join index row chain is corrupt");
|
|
50
|
+
this.#rowNext[tail] = row;
|
|
51
|
+
this.#rowTails[existing] = row;
|
|
52
|
+
this.#unique = false;
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const encoded = copyScratchKey(length);
|
|
56
|
+
const index = this.#entryCount;
|
|
57
|
+
this.#ensureEntryCapacity(index + 1);
|
|
58
|
+
this.#ensureBucketCapacity(index + 1);
|
|
59
|
+
this.#ensureKeyCapacity(encoded.byteLength);
|
|
60
|
+
const offset = this.#keyLength;
|
|
61
|
+
this.#keys.set(encoded, offset);
|
|
62
|
+
this.#keyLength += encoded.byteLength;
|
|
63
|
+
this.#hashes[index] = hash;
|
|
64
|
+
this.#offsets[index] = offset;
|
|
65
|
+
this.#lengths[index] = encoded.byteLength;
|
|
66
|
+
this.#rowHeads[index] = row;
|
|
67
|
+
this.#rowTails[index] = row;
|
|
68
|
+
const bucket = hash & (this.#buckets.length - 1);
|
|
69
|
+
this.#bucketNext[index] = this.#buckets[bucket] ?? -1;
|
|
70
|
+
this.#buckets[bucket] = index;
|
|
71
|
+
this.#entryCount += 1;
|
|
72
|
+
}
|
|
73
|
+
firstRow(value) {
|
|
74
|
+
const length = encodeJoinKey(value);
|
|
75
|
+
if (length < 0)
|
|
76
|
+
return -1;
|
|
77
|
+
const index = this.#find(length, hashScratch(length));
|
|
78
|
+
return index < 0 ? -1 : (this.#rowHeads[index] ?? -1);
|
|
79
|
+
}
|
|
80
|
+
nextRow(row) {
|
|
81
|
+
return row < 0 || row >= this.#rowNext.length ? -1 : (this.#rowNext[row] ?? -1);
|
|
82
|
+
}
|
|
83
|
+
/** Matches the scratch arena's first `length` bytes against stored keys without copying them. */
|
|
84
|
+
#find(length, hash) {
|
|
85
|
+
if (this.#buckets.length === 0)
|
|
86
|
+
return -1;
|
|
87
|
+
let index = this.#buckets[hash & (this.#buckets.length - 1)] ?? -1;
|
|
88
|
+
while (index >= 0) {
|
|
89
|
+
if (this.#hashes[index] === hash &&
|
|
90
|
+
this.#lengths[index] === length &&
|
|
91
|
+
equalsScratch(this.#keys, this.#offsets[index] ?? 0, length)) {
|
|
92
|
+
return index;
|
|
93
|
+
}
|
|
94
|
+
index = this.#bucketNext[index] ?? -1;
|
|
95
|
+
}
|
|
96
|
+
return -1;
|
|
97
|
+
}
|
|
98
|
+
#ensureEntryCapacity(required) {
|
|
99
|
+
if (required <= this.#hashes.length)
|
|
100
|
+
return;
|
|
101
|
+
let capacity = Math.max(INITIAL_ENTRY_CAPACITY, this.#hashes.length * 2);
|
|
102
|
+
while (capacity < required)
|
|
103
|
+
capacity = safeDouble(capacity, "Join index entries");
|
|
104
|
+
const reservation = this.#memory.reserve(safeProduct(capacity, ENTRY_FIELDS * UINT32_BYTES, "Join index entry storage"), "Join index entry storage");
|
|
105
|
+
try {
|
|
106
|
+
const hashes = new Uint32Array(capacity);
|
|
107
|
+
const offsets = new Uint32Array(capacity);
|
|
108
|
+
const lengths = new Uint32Array(capacity);
|
|
109
|
+
const bucketNext = new Int32Array(capacity);
|
|
110
|
+
const rowHeads = new Int32Array(capacity);
|
|
111
|
+
const rowTails = new Int32Array(capacity);
|
|
112
|
+
bucketNext.fill(-1);
|
|
113
|
+
rowHeads.fill(-1);
|
|
114
|
+
rowTails.fill(-1);
|
|
115
|
+
hashes.set(this.#hashes);
|
|
116
|
+
offsets.set(this.#offsets);
|
|
117
|
+
lengths.set(this.#lengths);
|
|
118
|
+
bucketNext.set(this.#bucketNext);
|
|
119
|
+
rowHeads.set(this.#rowHeads);
|
|
120
|
+
rowTails.set(this.#rowTails);
|
|
121
|
+
this.#hashes = hashes;
|
|
122
|
+
this.#offsets = offsets;
|
|
123
|
+
this.#lengths = lengths;
|
|
124
|
+
this.#bucketNext = bucketNext;
|
|
125
|
+
this.#rowHeads = rowHeads;
|
|
126
|
+
this.#rowTails = rowTails;
|
|
127
|
+
this.#entryReservation?.release();
|
|
128
|
+
this.#entryReservation = reservation;
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
reservation.release();
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
#ensureBucketCapacity(requiredEntries) {
|
|
136
|
+
let capacity = this.#buckets.length;
|
|
137
|
+
if (capacity === 0)
|
|
138
|
+
capacity = INITIAL_BUCKET_CAPACITY;
|
|
139
|
+
while (requiredEntries * 4 > capacity * 3) {
|
|
140
|
+
capacity = safeDouble(capacity, "Join index buckets");
|
|
141
|
+
}
|
|
142
|
+
if (capacity === this.#buckets.length)
|
|
143
|
+
return;
|
|
144
|
+
const reservation = this.#memory.reserve(safeProduct(capacity, Int32Array.BYTES_PER_ELEMENT, "Join index bucket storage"), "Join index bucket storage");
|
|
145
|
+
try {
|
|
146
|
+
const buckets = new Int32Array(capacity);
|
|
147
|
+
buckets.fill(-1);
|
|
148
|
+
for (let index = 0; index < this.#entryCount; index += 1) {
|
|
149
|
+
const bucket = (this.#hashes[index] ?? 0) & (capacity - 1);
|
|
150
|
+
this.#bucketNext[index] = buckets[bucket] ?? -1;
|
|
151
|
+
buckets[bucket] = index;
|
|
152
|
+
}
|
|
153
|
+
this.#buckets = buckets;
|
|
154
|
+
this.#bucketReservation?.release();
|
|
155
|
+
this.#bucketReservation = reservation;
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
reservation.release();
|
|
159
|
+
throw error;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
#ensureKeyCapacity(additionalBytes) {
|
|
163
|
+
const required = this.#keyLength + additionalBytes;
|
|
164
|
+
if (!Number.isSafeInteger(required))
|
|
165
|
+
throw new RangeError("Join key arena is too large");
|
|
166
|
+
if (required > 0xffff_ffff)
|
|
167
|
+
throw new RangeError("Join key arena exceeds uint32 offsets");
|
|
168
|
+
if (required <= this.#keys.byteLength)
|
|
169
|
+
return;
|
|
170
|
+
let capacity = Math.max(INITIAL_KEY_CAPACITY, this.#keys.byteLength * 2);
|
|
171
|
+
while (capacity < required)
|
|
172
|
+
capacity = safeDouble(capacity, "Join key arena");
|
|
173
|
+
const reservation = this.#memory.reserve(capacity, "Join key arena");
|
|
174
|
+
try {
|
|
175
|
+
const keys = new Uint8Array(capacity);
|
|
176
|
+
keys.set(this.#keys.subarray(0, this.#keyLength));
|
|
177
|
+
this.#keys = keys;
|
|
178
|
+
this.#keyReservation?.release();
|
|
179
|
+
this.#keyReservation = reservation;
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
reservation.release();
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Encodes one join key into the shared scratch arena and returns its byte length, or -1 for keys
|
|
189
|
+
* SQL equality can never match (null, undefined, NaN). Dates coerce to their epoch milliseconds,
|
|
190
|
+
* so a Date and its number representation join as the same key.
|
|
191
|
+
*/
|
|
192
|
+
function encodeJoinKey(value) {
|
|
193
|
+
const key = value instanceof Date ? value.getTime() : value;
|
|
194
|
+
if (key === null || key === undefined)
|
|
195
|
+
return -1;
|
|
196
|
+
if (typeof key === "number" && Number.isNaN(key))
|
|
197
|
+
return -1;
|
|
198
|
+
if (typeof key === "boolean" || typeof key === "number" || typeof key === "string") {
|
|
199
|
+
return encodeSingleScalarKey(key);
|
|
200
|
+
}
|
|
201
|
+
throw new TypeError("Join keys must be SQL scalar values");
|
|
202
|
+
}
|
|
203
|
+
function safeDouble(value, label) {
|
|
204
|
+
const doubled = value * 2;
|
|
205
|
+
if (!Number.isSafeInteger(doubled)) {
|
|
206
|
+
throw new RangeError(`${label} exceeds the safe integer range`);
|
|
207
|
+
}
|
|
208
|
+
return doubled;
|
|
209
|
+
}
|
|
210
|
+
function safeProduct(left, right, label) {
|
|
211
|
+
const product = left * right;
|
|
212
|
+
if (!Number.isSafeInteger(product)) {
|
|
213
|
+
throw new RangeError(`${label} exceeds the safe integer range`);
|
|
214
|
+
}
|
|
215
|
+
return product;
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=join-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join-index.js","sourceRoot":"","sources":["../../src/engine/join-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { type Manifest, type StoragePage } from "../storage/index.js";
|
|
2
|
+
import { type CompiledQuery, type QueryResult } from "./query.js";
|
|
3
|
+
/**
|
|
4
|
+
* Correctness-first live queries with selective re-execution. Every hint path — a local commit,
|
|
5
|
+
* a cross-tab channel message, a poll tick, or an explicit refresh — converges on the same
|
|
6
|
+
* authoritative check: read the durable manifest version, and when it moved, derive the changed
|
|
7
|
+
* tables from the persisted per-commit change sets in bounded pages. Missed hints therefore delay
|
|
8
|
+
* a refresh but can never produce a stale result, and a manifest without a change set (written
|
|
9
|
+
* before tracking, or outside a transaction) conservatively affects every subscription.
|
|
10
|
+
*
|
|
11
|
+
* Memory discipline: a subscription retains its plan text, dependency table IDs, and a numeric
|
|
12
|
+
* result digest — never result rows. Results flow to the subscriber and are dropped; unchanged
|
|
13
|
+
* digests suppress the notification entirely.
|
|
14
|
+
*/
|
|
15
|
+
export interface LiveQueryHintChannel {
|
|
16
|
+
postMessage(message: unknown): void;
|
|
17
|
+
addEventListener(type: "message", listener: () => void): void;
|
|
18
|
+
removeEventListener(type: "message", listener: () => void): void;
|
|
19
|
+
close?(): void;
|
|
20
|
+
}
|
|
21
|
+
export interface LiveQuerySetOptions {
|
|
22
|
+
readonly channel?: LiveQueryHintChannel;
|
|
23
|
+
/**
|
|
24
|
+
* Convenience form of `channel`: the set creates (and owns, closing it with the set) a
|
|
25
|
+
* BroadcastChannel of this name when the platform provides one. Ignored when `channel` is
|
|
26
|
+
* given or BroadcastChannel is unavailable.
|
|
27
|
+
*/
|
|
28
|
+
readonly channelName?: string;
|
|
29
|
+
readonly pollIntervalMs?: number;
|
|
30
|
+
/** Called once when the set closes; the owner uses this to drop its reference. */
|
|
31
|
+
readonly onClosed?: () => void;
|
|
32
|
+
}
|
|
33
|
+
export interface LiveQuerySubscribeOptions {
|
|
34
|
+
onChange(result: QueryResult): void;
|
|
35
|
+
onError?(error: unknown): void;
|
|
36
|
+
/** Called once when the subscription ends because the subscription or its set closed. */
|
|
37
|
+
onComplete?(): void;
|
|
38
|
+
}
|
|
39
|
+
export interface LiveQuerySubscription {
|
|
40
|
+
readonly dependencyTableIds: readonly string[];
|
|
41
|
+
close(): void;
|
|
42
|
+
}
|
|
43
|
+
export interface LiveQueryStats {
|
|
44
|
+
hints: number;
|
|
45
|
+
versionChecks: number;
|
|
46
|
+
sweeps: number;
|
|
47
|
+
reruns: number;
|
|
48
|
+
rerunsAvoided: number;
|
|
49
|
+
/** Re-runs skipped because the data layer proved the commits could not change the result. */
|
|
50
|
+
zoneSkips: number;
|
|
51
|
+
notificationsSuppressed: number;
|
|
52
|
+
lastSweepMs: number;
|
|
53
|
+
}
|
|
54
|
+
/** A live query: SQL text or a compiled-plan envelope from the typed builder. */
|
|
55
|
+
export type LiveQueryInput = string | {
|
|
56
|
+
kind: "typed-query";
|
|
57
|
+
plan: CompiledQuery;
|
|
58
|
+
};
|
|
59
|
+
interface LiveQueryHost {
|
|
60
|
+
currentVersion(): Promise<number | null>;
|
|
61
|
+
manifestPage(afterVersion: number | null, limit: number): Promise<StoragePage<Manifest, number>>;
|
|
62
|
+
dependencyTableIds(query: LiveQueryInput): Promise<Set<string>>;
|
|
63
|
+
execute(query: LiveQueryInput): Promise<QueryResult>;
|
|
64
|
+
/**
|
|
65
|
+
* Optional data-layer selectivity: whether commits in (after, until] to the given
|
|
66
|
+
* dependency tables can possibly change this query's result. A host answers false only
|
|
67
|
+
* on proof — e.g. every introduced segment is a data-neutral compaction rewrite, or every
|
|
68
|
+
* new insert block's zone statistics reject the query's predicates — so a false skips the
|
|
69
|
+
* re-run entirely. Errors and unknown shapes must answer true.
|
|
70
|
+
*/
|
|
71
|
+
changeCanAffect?(query: LiveQueryInput, tableIds: readonly string[], after: number | null, until: number): Promise<boolean>;
|
|
72
|
+
}
|
|
73
|
+
export declare class LiveQuerySet {
|
|
74
|
+
#private;
|
|
75
|
+
constructor(host: LiveQueryHost, options?: LiveQuerySetOptions);
|
|
76
|
+
get stats(): LiveQueryStats;
|
|
77
|
+
/** Registers a query, delivers its initial result, and re-runs it when its tables change. */
|
|
78
|
+
subscribe(query: LiveQueryInput, options: LiveQuerySubscribeOptions): Promise<LiveQuerySubscription>;
|
|
79
|
+
/** Called by the owning database after each local write commit; also hints other tabs. */
|
|
80
|
+
notifyLocalCommit(): void;
|
|
81
|
+
/** Runs one authoritative version check and selective re-execution sweep. */
|
|
82
|
+
refresh(): Promise<void>;
|
|
83
|
+
close(): void;
|
|
84
|
+
}
|
|
85
|
+
export {};
|
|
86
|
+
//# sourceMappingURL=live.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../src/engine/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAmB,MAAM,YAAY,CAAC;AAEnF;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,oBAAoB;IACnC,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACpC,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC9D,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IACjE,KAAK,CAAC,IAAI,IAAI,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,oBAAoB,CAAC;IACxC;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,yFAAyF;IACzF,UAAU,CAAC,IAAI,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,iFAAiF;AACjF,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAEnF,UAAU,aAAa;IACrB,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;IACjG,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACrD;;;;;;OAMG;IACH,eAAe,CAAC,CACd,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AA8CD,qBAAa,YAAY;;gBAyBX,IAAI,EAAE,aAAa,EAAE,OAAO,GAAE,mBAAwB;IAqBlE,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,6FAA6F;IACvF,SAAS,CACb,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,qBAAqB,CAAC;IAqCjC,0FAA0F;IAC1F,iBAAiB,IAAI,IAAI;IAKzB,6EAA6E;IACvE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B,KAAK,IAAI,IAAI;CAoJd"}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/** Companion to LiveQuerySet#stillOpen for the per-subscription flag. */
|
|
2
|
+
function isSubscriptionClosed(subscription) {
|
|
3
|
+
return subscription.closed;
|
|
4
|
+
}
|
|
5
|
+
function digestResult(result) {
|
|
6
|
+
let hash = 0x811c9dc5;
|
|
7
|
+
const mix = (text) => {
|
|
8
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
9
|
+
const code = text.charCodeAt(index);
|
|
10
|
+
hash = Math.imul(hash ^ (code & 0xff), 0x01000193) >>> 0;
|
|
11
|
+
hash = Math.imul(hash ^ (code >>> 8), 0x01000193) >>> 0;
|
|
12
|
+
}
|
|
13
|
+
hash = Math.imul(hash ^ 0xff, 0x01000193) >>> 0;
|
|
14
|
+
};
|
|
15
|
+
for (const column of result.columns)
|
|
16
|
+
mix(column);
|
|
17
|
+
for (const row of result.rows) {
|
|
18
|
+
for (const column of result.columns) {
|
|
19
|
+
const value = row[column] ?? null;
|
|
20
|
+
if (value === null)
|
|
21
|
+
mix("\0n");
|
|
22
|
+
else if (value instanceof Date)
|
|
23
|
+
mix(`\0d${String(value.getTime())}`);
|
|
24
|
+
else
|
|
25
|
+
mix(`\0${typeof value}${String(value)}`);
|
|
26
|
+
}
|
|
27
|
+
hash = Math.imul(hash ^ 0xfe, 0x01000193) >>> 0;
|
|
28
|
+
}
|
|
29
|
+
return hash;
|
|
30
|
+
}
|
|
31
|
+
export class LiveQuerySet {
|
|
32
|
+
#host;
|
|
33
|
+
#channel;
|
|
34
|
+
#channelListener = () => {
|
|
35
|
+
this.#hint();
|
|
36
|
+
};
|
|
37
|
+
#subscriptions = new Set();
|
|
38
|
+
#stats = {
|
|
39
|
+
hints: 0,
|
|
40
|
+
versionChecks: 0,
|
|
41
|
+
sweeps: 0,
|
|
42
|
+
reruns: 0,
|
|
43
|
+
rerunsAvoided: 0,
|
|
44
|
+
zoneSkips: 0,
|
|
45
|
+
notificationsSuppressed: 0,
|
|
46
|
+
lastSweepMs: 0,
|
|
47
|
+
};
|
|
48
|
+
#lastSeenVersion = null;
|
|
49
|
+
#sweepChain = Promise.resolve();
|
|
50
|
+
#sweepQueued = false;
|
|
51
|
+
#pollTimer;
|
|
52
|
+
#closed = false;
|
|
53
|
+
#ownsChannel;
|
|
54
|
+
#onClosed;
|
|
55
|
+
constructor(host, options = {}) {
|
|
56
|
+
this.#host = host;
|
|
57
|
+
if (options.channel !== undefined) {
|
|
58
|
+
this.#channel = options.channel;
|
|
59
|
+
this.#ownsChannel = false;
|
|
60
|
+
}
|
|
61
|
+
else if (options.channelName !== undefined && typeof BroadcastChannel !== "undefined") {
|
|
62
|
+
this.#channel = new BroadcastChannel(options.channelName);
|
|
63
|
+
this.#ownsChannel = true;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
this.#channel = undefined;
|
|
67
|
+
this.#ownsChannel = false;
|
|
68
|
+
}
|
|
69
|
+
this.#onClosed = options.onClosed;
|
|
70
|
+
this.#channel?.addEventListener("message", this.#channelListener);
|
|
71
|
+
if (options.pollIntervalMs !== undefined) {
|
|
72
|
+
this.#pollTimer = setInterval(() => {
|
|
73
|
+
this.#hint();
|
|
74
|
+
}, options.pollIntervalMs);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
get stats() {
|
|
78
|
+
return { ...this.#stats };
|
|
79
|
+
}
|
|
80
|
+
/** Registers a query, delivers its initial result, and re-runs it when its tables change. */
|
|
81
|
+
async subscribe(query, options) {
|
|
82
|
+
if (this.#closed)
|
|
83
|
+
throw new Error("Live query set is closed");
|
|
84
|
+
const dependencies = await this.#host.dependencyTableIds(query);
|
|
85
|
+
const version = await this.#host.currentVersion();
|
|
86
|
+
const subscription = {
|
|
87
|
+
query,
|
|
88
|
+
dependencies,
|
|
89
|
+
options,
|
|
90
|
+
digest: undefined,
|
|
91
|
+
seenVersion: version,
|
|
92
|
+
closed: false,
|
|
93
|
+
};
|
|
94
|
+
if (this.#lastSeenVersion === null || (version !== null && version < this.#lastSeenVersion)) {
|
|
95
|
+
this.#lastSeenVersion = version;
|
|
96
|
+
}
|
|
97
|
+
const result = await this.#host.execute(query);
|
|
98
|
+
subscription.digest = digestResult(result);
|
|
99
|
+
this.#subscriptions.add(subscription);
|
|
100
|
+
try {
|
|
101
|
+
options.onChange(result);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
// A throwing initial handler would leak an unclosable subscription; unregister first.
|
|
105
|
+
subscription.closed = true;
|
|
106
|
+
this.#subscriptions.delete(subscription);
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
dependencyTableIds: [...dependencies],
|
|
111
|
+
close: () => {
|
|
112
|
+
if (subscription.closed)
|
|
113
|
+
return;
|
|
114
|
+
subscription.closed = true;
|
|
115
|
+
this.#subscriptions.delete(subscription);
|
|
116
|
+
subscription.options.onComplete?.();
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/** Called by the owning database after each local write commit; also hints other tabs. */
|
|
121
|
+
notifyLocalCommit() {
|
|
122
|
+
this.#channel?.postMessage("minnow-commit");
|
|
123
|
+
this.#hint();
|
|
124
|
+
}
|
|
125
|
+
/** Runs one authoritative version check and selective re-execution sweep. */
|
|
126
|
+
async refresh() {
|
|
127
|
+
this.#hint();
|
|
128
|
+
await this.#sweepChain;
|
|
129
|
+
}
|
|
130
|
+
close() {
|
|
131
|
+
if (this.#closed)
|
|
132
|
+
return;
|
|
133
|
+
this.#closed = true;
|
|
134
|
+
this.#channel?.removeEventListener("message", this.#channelListener);
|
|
135
|
+
if (this.#ownsChannel)
|
|
136
|
+
this.#channel?.close?.();
|
|
137
|
+
if (this.#pollTimer !== undefined)
|
|
138
|
+
clearInterval(this.#pollTimer);
|
|
139
|
+
const subscriptions = [...this.#subscriptions];
|
|
140
|
+
this.#subscriptions.clear();
|
|
141
|
+
// Wake every remaining subscriber so iterators and UI bindings end instead of hanging.
|
|
142
|
+
for (const subscription of subscriptions) {
|
|
143
|
+
if (subscription.closed)
|
|
144
|
+
continue;
|
|
145
|
+
subscription.closed = true;
|
|
146
|
+
subscription.options.onComplete?.();
|
|
147
|
+
}
|
|
148
|
+
this.#onClosed?.();
|
|
149
|
+
}
|
|
150
|
+
#hint() {
|
|
151
|
+
if (this.#closed)
|
|
152
|
+
return;
|
|
153
|
+
this.#stats.hints += 1;
|
|
154
|
+
if (this.#sweepQueued)
|
|
155
|
+
return;
|
|
156
|
+
this.#sweepQueued = true;
|
|
157
|
+
this.#sweepChain = this.#sweepChain.then(async () => {
|
|
158
|
+
this.#sweepQueued = false;
|
|
159
|
+
try {
|
|
160
|
+
await this.#sweep();
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
for (const subscription of this.#subscriptions) {
|
|
164
|
+
subscription.options.onError?.(error);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Re-reads the closed flags through calls. `close()` runs while a sweep is suspended at an
|
|
171
|
+
* await, but control-flow analysis assumes flags cannot change across one, so a direct read
|
|
172
|
+
* would be narrowed to its pre-await value and the guard silently dropped.
|
|
173
|
+
*/
|
|
174
|
+
#stillOpen() {
|
|
175
|
+
return !this.#closed;
|
|
176
|
+
}
|
|
177
|
+
async #sweep() {
|
|
178
|
+
if (this.#closed || this.#subscriptions.size === 0)
|
|
179
|
+
return;
|
|
180
|
+
this.#stats.versionChecks += 1;
|
|
181
|
+
const current = await this.#host.currentVersion();
|
|
182
|
+
if (!this.#stillOpen() || current === null)
|
|
183
|
+
return;
|
|
184
|
+
const anyLagging = [...this.#subscriptions].some((subscription) => !subscription.closed &&
|
|
185
|
+
(subscription.seenVersion === null || subscription.seenVersion < current));
|
|
186
|
+
if (current === this.#lastSeenVersion && !anyLagging)
|
|
187
|
+
return;
|
|
188
|
+
const started = performance.now();
|
|
189
|
+
this.#stats.sweeps += 1;
|
|
190
|
+
// The changed-table window starts at the set-level version, so it only gates subscriptions
|
|
191
|
+
// that were up to date there. A lagging subscription's window starts earlier at its own
|
|
192
|
+
// seenVersion, so it re-runs unconditionally — the digest suppresses no-op notifications.
|
|
193
|
+
const changed = current === this.#lastSeenVersion
|
|
194
|
+
? new Set()
|
|
195
|
+
: await this.#changedTablesSince(this.#lastSeenVersion, current);
|
|
196
|
+
if (!this.#stillOpen())
|
|
197
|
+
return;
|
|
198
|
+
for (const subscription of [...this.#subscriptions]) {
|
|
199
|
+
if (subscription.closed)
|
|
200
|
+
continue;
|
|
201
|
+
if (subscription.seenVersion !== null && subscription.seenVersion >= current)
|
|
202
|
+
continue;
|
|
203
|
+
if (subscription.seenVersion === this.#lastSeenVersion) {
|
|
204
|
+
const affected = changed === "all" ||
|
|
205
|
+
[...subscription.dependencies].some((tableId) => changed.has(tableId));
|
|
206
|
+
if (!affected) {
|
|
207
|
+
this.#stats.rerunsAvoided += 1;
|
|
208
|
+
subscription.seenVersion = current;
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
if (changed !== "all" && this.#host.changeCanAffect !== undefined) {
|
|
212
|
+
const relevant = [...subscription.dependencies].filter((tableId) => changed.has(tableId));
|
|
213
|
+
let canAffect;
|
|
214
|
+
try {
|
|
215
|
+
canAffect = await this.#host.changeCanAffect(subscription.query, relevant, this.#lastSeenVersion, current);
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
canAffect = true;
|
|
219
|
+
}
|
|
220
|
+
if (!this.#stillOpen())
|
|
221
|
+
return;
|
|
222
|
+
if (isSubscriptionClosed(subscription))
|
|
223
|
+
continue;
|
|
224
|
+
if (!canAffect) {
|
|
225
|
+
this.#stats.rerunsAvoided += 1;
|
|
226
|
+
this.#stats.zoneSkips += 1;
|
|
227
|
+
subscription.seenVersion = current;
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
this.#stats.reruns += 1;
|
|
233
|
+
try {
|
|
234
|
+
const result = await this.#host.execute(subscription.query);
|
|
235
|
+
// The subscription (or the set) may have closed during the execute; a late onChange
|
|
236
|
+
// after onComplete would break the subscriber contract.
|
|
237
|
+
if (!this.#stillOpen() || isSubscriptionClosed(subscription))
|
|
238
|
+
continue;
|
|
239
|
+
subscription.seenVersion = current;
|
|
240
|
+
const digest = digestResult(result);
|
|
241
|
+
if (digest === subscription.digest) {
|
|
242
|
+
this.#stats.notificationsSuppressed += 1;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
subscription.digest = digest;
|
|
246
|
+
subscription.options.onChange(result);
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
if (!this.#stillOpen() || isSubscriptionClosed(subscription))
|
|
250
|
+
continue;
|
|
251
|
+
subscription.seenVersion = current;
|
|
252
|
+
subscription.options.onError?.(error);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
this.#lastSeenVersion = current;
|
|
256
|
+
this.#stats.lastSweepMs = performance.now() - started;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Unions the persisted change sets of every manifest in (after, until], reading bounded pages.
|
|
260
|
+
* A missing manifest version or a manifest without a change set widens to "all" — correctness
|
|
261
|
+
* over selectivity.
|
|
262
|
+
*/
|
|
263
|
+
async #changedTablesSince(after, until) {
|
|
264
|
+
const changed = new Set();
|
|
265
|
+
let cursor = after;
|
|
266
|
+
let expected = (after ?? -1) + 1;
|
|
267
|
+
for (;;) {
|
|
268
|
+
const page = await this.#host.manifestPage(cursor, 64);
|
|
269
|
+
for (const manifest of page.records) {
|
|
270
|
+
if (manifest.version > until)
|
|
271
|
+
return changed;
|
|
272
|
+
if (manifest.version !== expected)
|
|
273
|
+
return "all";
|
|
274
|
+
expected += 1;
|
|
275
|
+
if (manifest.changedTableIds === undefined)
|
|
276
|
+
return "all";
|
|
277
|
+
for (const tableId of manifest.changedTableIds)
|
|
278
|
+
changed.add(tableId);
|
|
279
|
+
if (manifest.version === until)
|
|
280
|
+
return changed;
|
|
281
|
+
}
|
|
282
|
+
if (page.nextCursor === null) {
|
|
283
|
+
return expected > until ? changed : "all";
|
|
284
|
+
}
|
|
285
|
+
cursor = page.nextCursor;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.js","sourceRoot":"","sources":["../../src/engine/live.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface QueryMemoryUsage {
|
|
2
|
+
readonly budgetBytes: number;
|
|
3
|
+
readonly usedBytes: number;
|
|
4
|
+
readonly peakBytes: number;
|
|
5
|
+
}
|
|
6
|
+
export declare class QueryMemoryBudgetError extends Error {
|
|
7
|
+
readonly label: string;
|
|
8
|
+
readonly requestedBytes: number;
|
|
9
|
+
readonly usedBytes: number;
|
|
10
|
+
readonly budgetBytes: number;
|
|
11
|
+
readonly name = "QueryMemoryBudgetError";
|
|
12
|
+
constructor(label: string, requestedBytes: number, usedBytes: number, budgetBytes: number);
|
|
13
|
+
}
|
|
14
|
+
export declare class QueryMemoryContext {
|
|
15
|
+
#private;
|
|
16
|
+
constructor(budgetBytes?: number, parent?: QueryMemoryContext);
|
|
17
|
+
get usage(): QueryMemoryUsage;
|
|
18
|
+
createChild(): QueryMemoryContext;
|
|
19
|
+
reserve(bytes: number, label: string): QueryMemoryReservation;
|
|
20
|
+
/**
|
|
21
|
+
* Reserves bytes that live until this context closes, without a per-call reservation object.
|
|
22
|
+
* The hot accumulation paths (result rows, spill pages) reserve once per row; tracking each
|
|
23
|
+
* row as a retained `QueryMemoryReservation` in a Set costs O(result rows) live objects on
|
|
24
|
+
* top of the rows themselves. Tallied bytes share the same budget and error semantics as
|
|
25
|
+
* `reserve` and are released together when the context closes.
|
|
26
|
+
*/
|
|
27
|
+
tally(bytes: number, label: string): void;
|
|
28
|
+
close(): void;
|
|
29
|
+
release(reservation: QueryMemoryReservation, bytes: number): void;
|
|
30
|
+
}
|
|
31
|
+
export declare class QueryMemoryReservation {
|
|
32
|
+
#private;
|
|
33
|
+
readonly bytes: number;
|
|
34
|
+
constructor(context: QueryMemoryContext, bytes: number);
|
|
35
|
+
release(): void;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=memory.d.ts.map
|