@quereus/store 4.9.0 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -5
- package/dist/src/common/cached-kv-store.d.ts.map +1 -1
- package/dist/src/common/cached-kv-store.js +21 -6
- package/dist/src/common/cached-kv-store.js.map +1 -1
- package/dist/src/common/index.d.ts +1 -0
- package/dist/src/common/index.d.ts.map +1 -1
- package/dist/src/common/index.js +2 -0
- package/dist/src/common/index.js.map +1 -1
- package/dist/src/common/kv-store.d.ts +53 -1
- package/dist/src/common/kv-store.d.ts.map +1 -1
- package/dist/src/common/memory-store.d.ts.map +1 -1
- package/dist/src/common/memory-store.js +9 -1
- package/dist/src/common/memory-store.js.map +1 -1
- package/dist/src/common/paged-iterate.d.ts +42 -0
- package/dist/src/common/paged-iterate.d.ts.map +1 -0
- package/dist/src/common/paged-iterate.js +113 -0
- package/dist/src/common/paged-iterate.js.map +1 -0
- package/dist/src/common/serialization.d.ts +11 -1
- package/dist/src/common/serialization.d.ts.map +1 -1
- package/dist/src/common/serialization.js +114 -31
- package/dist/src/common/serialization.js.map +1 -1
- package/dist/src/testing/index.d.ts +5 -1
- package/dist/src/testing/index.d.ts.map +1 -1
- package/dist/src/testing/index.js +5 -1
- package/dist/src/testing/index.js.map +1 -1
- package/dist/src/testing/kv-conformance.d.ts +52 -3
- package/dist/src/testing/kv-conformance.d.ts.map +1 -1
- package/dist/src/testing/kv-conformance.js +152 -7
- package/dist/src/testing/kv-conformance.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -190,9 +190,9 @@ db.registerModule('store', module);
|
|
|
190
190
|
**Validate a new backend against the shared conformance suite.** `@quereus/store/testing`
|
|
191
191
|
exports `runKVStoreConformance(name, makeBackend)` — one parameterized battery of
|
|
192
192
|
behavioral tests written against the `KVStore` contract (point ops, ordering, range
|
|
193
|
-
iteration, streaming across page boundaries, batch semantics, optional persistence,
|
|
194
|
-
cross-backend encoded-key ordering). Wire a tiny lifecycle adapter
|
|
195
|
-
so any drift from the contract fails a test:
|
|
193
|
+
iteration, streaming across page boundaries, batch semantics, optional persistence,
|
|
194
|
+
cross-backend encoded-key ordering, and bounded iteration). Wire a tiny lifecycle adapter
|
|
195
|
+
and run it under Mocha so any drift from the contract fails a test:
|
|
196
196
|
|
|
197
197
|
```typescript
|
|
198
198
|
import { runKVStoreConformance } from '@quereus/store/testing';
|
|
@@ -202,11 +202,20 @@ runKVStoreConformance('MyCustomStore', () => ({
|
|
|
202
202
|
// Omit `reopen` for a non-persistent backend; supply it (reopen the SAME keyspace
|
|
203
203
|
// without wiping) to also exercise the persistence tier.
|
|
204
204
|
teardown: async () => { /* close handles, remove backing storage */ },
|
|
205
|
+
// Optional. The battery holds only a KVStore handle and cannot see what the backend
|
|
206
|
+
// reads underneath, so supply a counter over whatever the store reads FROM plus the
|
|
207
|
+
// backend's batch size, and the bounded-iteration tier also measures reads. Omit it
|
|
208
|
+
// and that tier still checks that abandoning an iteration releases resources.
|
|
209
|
+
readMeter: { entriesRead: () => myBackingReads, maxReadAhead: 1 },
|
|
205
210
|
}));
|
|
206
211
|
```
|
|
207
212
|
|
|
208
|
-
See `test/kv-conformance.spec.ts` (in-memory), and the
|
|
209
|
-
|
|
213
|
+
See `test/kv-conformance.spec.ts` (in-memory), and the `test/conformance.spec.ts` of each
|
|
214
|
+
backend plugin — LevelDB, IndexedDB, React Native LevelDB, NativeScript SQLite — for worked
|
|
215
|
+
adapters. The two mobile plugins run against an in-process stand-in for their native module
|
|
216
|
+
(a mock LevelDB, and better-sqlite3 behind the NativeScript SQLite interface), which is what
|
|
217
|
+
makes them testable off-device; the NativeScript one uses a temp file database so it also
|
|
218
|
+
drives the persistence tier.
|
|
210
219
|
|
|
211
220
|
**If your provider implements `beginAtomicBatch`, also run the provider suite.** The same
|
|
212
221
|
entry point exports `runKVProviderConformance(name, makeProviderBackend)` — the battery for
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cached-kv-store.d.ts","sourceRoot":"","sources":["../../../src/common/cached-kv-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAW,YAAY,EAAE,MAAM,eAAe,CAAC;AAEzG,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC5B,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"cached-kv-store.d.ts","sourceRoot":"","sources":["../../../src/common/cached-kv-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAW,YAAY,EAAE,MAAM,eAAe,CAAC;AAEzG,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC5B,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AA0BD;;;;;;;GAOG;AACH,qBAAa,aAAc,YAAW,OAAO;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;IAGlC,OAAO,CAAC,IAAI,CAAwB;IACpC,OAAO,CAAC,IAAI,CAAwB;IACpC,OAAO,CAAC,GAAG,CAA8B;IACzC,OAAO,CAAC,UAAU,CAAK;gBAEX,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY;IAOlD,4CAA4C;IAC5C,aAAa,IAAI,OAAO;IAIlB,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAiBrD,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBtC,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9E,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBpE,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC,OAAO,CAAC;IAKzD,KAAK,IAAI,UAAU;IAIb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,gBAAgB,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3D,8CAA8C;IAC9C,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAKjC,6CAA6C;IAC7C,aAAa,IAAI,IAAI;IASrB,OAAO,CAAC,QAAQ;IAmBhB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,KAAK;CASb"}
|
|
@@ -6,6 +6,20 @@
|
|
|
6
6
|
* Iteration always delegates to the underlying store (range consistency is hard).
|
|
7
7
|
*/
|
|
8
8
|
import { bytesToHex } from './bytes.js';
|
|
9
|
+
/**
|
|
10
|
+
* Copy a value across the cache boundary.
|
|
11
|
+
*
|
|
12
|
+
* The cache must OWN every buffer it holds and must never hand one out: `get()`'s
|
|
13
|
+
* read-buffer contract says a caller mutating a returned value cannot corrupt stored
|
|
14
|
+
* data, and the same has to hold for a value the caller passed to `put()` and then
|
|
15
|
+
* scribbled on. Without this the cache aliases the caller's buffer in both directions
|
|
16
|
+
* and a later cache hit serves the scribbles. One allocation per cached read is the
|
|
17
|
+
* same cost every real backend already pays (LevelDB deserializes, IndexedDB
|
|
18
|
+
* structured-clones).
|
|
19
|
+
*/
|
|
20
|
+
function copyValue(value) {
|
|
21
|
+
return value === undefined ? undefined : new Uint8Array(value);
|
|
22
|
+
}
|
|
9
23
|
/**
|
|
10
24
|
* Read-through LRU cache wrapper for a KVStore.
|
|
11
25
|
*
|
|
@@ -41,11 +55,12 @@ export class CachedKVStore {
|
|
|
41
55
|
const node = this.map.get(hex);
|
|
42
56
|
if (node) {
|
|
43
57
|
this.moveToHead(node);
|
|
44
|
-
return node.value;
|
|
58
|
+
return copyValue(node.value);
|
|
45
59
|
}
|
|
46
|
-
// Cache miss — read from underlying
|
|
60
|
+
// Cache miss — read from underlying. The underlying hands back a fresh buffer per
|
|
61
|
+
// read, so the caller gets that one and the cache keeps its own copy.
|
|
47
62
|
const value = await this.store.get(key);
|
|
48
|
-
this.addEntry(hex, value, key.length + (value?.length ?? 0));
|
|
63
|
+
this.addEntry(hex, copyValue(value), key.length + (value?.length ?? 0));
|
|
49
64
|
return value;
|
|
50
65
|
}
|
|
51
66
|
async has(key) {
|
|
@@ -59,7 +74,7 @@ export class CachedKVStore {
|
|
|
59
74
|
}
|
|
60
75
|
// Cache miss — delegate to underlying, then cache the result
|
|
61
76
|
const value = await this.store.get(key);
|
|
62
|
-
this.addEntry(hex, value, key.length + (value?.length ?? 0));
|
|
77
|
+
this.addEntry(hex, copyValue(value), key.length + (value?.length ?? 0));
|
|
63
78
|
return value !== undefined;
|
|
64
79
|
}
|
|
65
80
|
async put(key, value, options) {
|
|
@@ -72,13 +87,13 @@ export class CachedKVStore {
|
|
|
72
87
|
const existing = this.map.get(hex);
|
|
73
88
|
if (existing) {
|
|
74
89
|
this.totalBytes -= existing.size;
|
|
75
|
-
existing.value = value;
|
|
90
|
+
existing.value = new Uint8Array(value); // cache owns its buffer — see copyValue
|
|
76
91
|
existing.size = key.length + value.length;
|
|
77
92
|
this.totalBytes += existing.size;
|
|
78
93
|
this.moveToHead(existing);
|
|
79
94
|
}
|
|
80
95
|
else {
|
|
81
|
-
this.addEntry(hex, value, key.length + value.length);
|
|
96
|
+
this.addEntry(hex, new Uint8Array(value), key.length + value.length);
|
|
82
97
|
}
|
|
83
98
|
}
|
|
84
99
|
async delete(key, options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cached-kv-store.js","sourceRoot":"","sources":["../../../src/common/cached-kv-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cached-kv-store.js","sourceRoot":"","sources":["../../../src/common/cached-kv-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Common utilities for the persistent store module.
|
|
3
3
|
*/
|
|
4
4
|
export type { KVStore, KVEntry, WriteBatch, WriteOptions, BatchOp, AtomicBatch, IterateOptions, KVStoreFactory, KVStoreOptions, KVStoreProvider, } from './kv-store.js';
|
|
5
|
+
export { pagedIterate, type FetchBatch } from './paged-iterate.js';
|
|
5
6
|
export { encodeValue, encodeCompositeKey, decodeValue, decodeCompositeKey, BUILTIN_KEY_NORMALIZER_RESOLVER, assertNoUnpairedSurrogate, findUnpairedSurrogate, type EncodeOptions, type KeyValueTransform, } from './encoding.js';
|
|
6
7
|
export { serializeRow, deserializeRow, serializeValue, deserializeValue, serializeStats, deserializeStats, type TableStats, } from './serialization.js';
|
|
7
8
|
export { STORE_SUFFIX, CATALOG_STORE_NAME, STATS_STORE_NAME, buildDataStoreName, buildIndexStoreName, buildStatsStoreName, buildStatsKey, buildDataKey, buildIndexKey, type IndexKeyHalf, buildCatalogKey, buildViewCatalogKey, buildMaterializedViewCatalogKey, parseMaterializedViewCatalogKey, buildMetaCatalogKey, CLEAN_SHUTDOWN_META_NAME, STALE_MVS_META_NAME, classifyCatalogKey, type CatalogEntryKind, buildFullScanBounds, buildIndexPrefixBounds, buildPkPrefixBounds, buildCatalogScanBounds, KEY_PREFIX, buildTablePrefix, buildTableScanBounds, buildIndexScanBounds, buildMetaKey, buildMetaScanBounds, } from './key-builder.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/common/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,OAAO,EACP,OAAO,EACP,UAAU,EACV,YAAY,EACZ,OAAO,EACP,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,+BAA+B,EAC/B,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACN,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,KAAK,YAAY,EACjB,eAAe,EACf,mBAAmB,EACnB,+BAA+B,EAC/B,+BAA+B,EAC/B,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EAEtB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGzI,OAAO,EACL,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGlE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGxE,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGrF,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAIrD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAG9F,OAAO,EACN,yBAAyB,EACzB,YAAY,EACZ,KAAK,yBAAyB,GAC9B,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/common/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,YAAY,EACV,OAAO,EACP,OAAO,EACP,UAAU,EACV,YAAY,EACZ,OAAO,EACP,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,GAChB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGnE,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,+BAA+B,EAC/B,yBAAyB,EACzB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACN,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,KAAK,YAAY,EACjB,eAAe,EACf,mBAAmB,EACnB,+BAA+B,EAC/B,+BAA+B,EAC/B,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EAEtB,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGzI,OAAO,EACL,sBAAsB,EACtB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGlE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGxE,OAAO,EAAE,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGrF,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAIrD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAC7F,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAG9F,OAAO,EACN,yBAAyB,EACzB,YAAY,EACZ,KAAK,yBAAyB,GAC9B,MAAM,qBAAqB,CAAC"}
|
package/dist/src/common/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Common utilities for the persistent store module.
|
|
3
3
|
*/
|
|
4
|
+
// Bounded paging for backends without a streaming cursor
|
|
5
|
+
export { pagedIterate } from './paged-iterate.js';
|
|
4
6
|
// Key encoding
|
|
5
7
|
export { encodeValue, encodeCompositeKey, decodeValue, decodeCompositeKey, BUILTIN_KEY_NORMALIZER_RESOLVER, assertNoUnpairedSurrogate, findUnpairedSurrogate, } from './encoding.js';
|
|
6
8
|
// Row serialization
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/common/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgBH,eAAe;AACf,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,+BAA+B,EAC/B,yBAAyB,EACzB,qBAAqB,GAGtB,MAAM,eAAe,CAAC;AAEvB,oBAAoB;AACpB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,GAEjB,MAAM,oBAAoB,CAAC;AAE5B,yBAAyB;AACzB,OAAO,EACN,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,aAAa,EAEb,eAAe,EACf,mBAAmB,EACnB,+BAA+B,EAC/B,+BAA+B,EAC/B,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAElB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB;AACtB,8BAA8B;AAC9B,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,SAAS;AACT,OAAO,EACL,iBAAiB,GAKlB,MAAM,aAAa,CAAC;AAErB,sEAAsE;AACtE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEzI,sBAAsB;AACtB,OAAO,EACL,sBAAsB,GAIvB,MAAM,kBAAkB,CAAC;AAE1B,gCAAgC;AAChC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAElE,qBAAqB;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,0BAA0B;AAC1B,OAAO,EAAE,aAAa,EAAqB,MAAM,sBAAsB,CAAC;AAExE,qCAAqC;AACrC,OAAO,EAAE,UAAU,EAAsB,MAAM,kBAAkB,CAAC;AAGlE,yDAAyD;AACzD,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAEhC,wDAAwD;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,qFAAqF;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,wFAAwF;AACxF,mEAAmE;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,4BAA4B;AAC5B,OAAO,EACN,yBAAyB,EACzB,YAAY,GAEZ,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/common/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgBH,yDAAyD;AACzD,OAAO,EAAE,YAAY,EAAmB,MAAM,oBAAoB,CAAC;AAEnE,eAAe;AACf,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,+BAA+B,EAC/B,yBAAyB,EACzB,qBAAqB,GAGtB,MAAM,eAAe,CAAC;AAEvB,oBAAoB;AACpB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,GAEjB,MAAM,oBAAoB,CAAC;AAE5B,yBAAyB;AACzB,OAAO,EACN,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,aAAa,EACb,YAAY,EACZ,aAAa,EAEb,eAAe,EACf,mBAAmB,EACnB,+BAA+B,EAC/B,+BAA+B,EAC/B,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAElB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB;AACtB,8BAA8B;AAC9B,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,mBAAmB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,SAAS;AACT,OAAO,EACL,iBAAiB,GAKlB,MAAM,aAAa,CAAC;AAErB,sEAAsE;AACtE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAEzI,sBAAsB;AACtB,OAAO,EACL,sBAAsB,GAIvB,MAAM,kBAAkB,CAAC;AAE1B,gCAAgC;AAChC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAElE,qBAAqB;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,0BAA0B;AAC1B,OAAO,EAAE,aAAa,EAAqB,MAAM,sBAAsB,CAAC;AAExE,qCAAqC;AACrC,OAAO,EAAE,UAAU,EAAsB,MAAM,kBAAkB,CAAC;AAGlE,yDAAyD;AACzD,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAEhC,wDAAwD;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,qFAAqF;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,wFAAwF;AACxF,mEAAmE;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIhD,4BAA4B;AAC5B,OAAO,EACN,yBAAyB,EACzB,YAAY,GAEZ,MAAM,qBAAqB,CAAC"}
|
|
@@ -16,7 +16,11 @@ export interface IterateOptions {
|
|
|
16
16
|
lt?: Uint8Array;
|
|
17
17
|
/** Iterate in reverse order. */
|
|
18
18
|
reverse?: boolean;
|
|
19
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Maximum number of entries to return. Omitted means unbounded and `0` means no
|
|
21
|
+
* entries; a NEGATIVE limit is not a valid input — backends disagree on it
|
|
22
|
+
* (`abstract-level` reads `-1` as unbounded, the in-memory store as zero).
|
|
23
|
+
*/
|
|
20
24
|
limit?: number;
|
|
21
25
|
}
|
|
22
26
|
/**
|
|
@@ -114,6 +118,14 @@ export interface AtomicBatch {
|
|
|
114
118
|
/**
|
|
115
119
|
* Abstract key-value store interface.
|
|
116
120
|
* Provides sorted key-value storage with range iteration support.
|
|
121
|
+
*
|
|
122
|
+
* BUFFER OWNERSHIP. Every buffer crossing this interface is independent of the store's
|
|
123
|
+
* internal state: `get` and `iterate` hand back buffers the caller may scribble on
|
|
124
|
+
* without corrupting stored data, and `put`/`delete` do not retain the caller's buffer,
|
|
125
|
+
* so mutating it afterwards changes nothing stored. A backend that deserializes per read
|
|
126
|
+
* (LevelDB, IndexedDB) gets this for free; one holding live buffers (the in-memory store,
|
|
127
|
+
* a cache wrapper) must copy at the boundary. Tiers 1 and 3 of
|
|
128
|
+
* `runKVStoreConformance` enforce it.
|
|
117
129
|
*/
|
|
118
130
|
export interface KVStore {
|
|
119
131
|
/**
|
|
@@ -138,6 +150,46 @@ export interface KVStore {
|
|
|
138
150
|
/**
|
|
139
151
|
* Iterate over key-value pairs in sorted order.
|
|
140
152
|
* Keys are compared lexicographically by bytes.
|
|
153
|
+
*
|
|
154
|
+
* BOUNDED PEAK. Peak memory must be independent of how many entries the range
|
|
155
|
+
* holds. An implementation may buffer a FIXED-SIZE batch — IndexedDB pages 256
|
|
156
|
+
* entries at a time, `abstract-level` hands back one entry per `next()` — but it
|
|
157
|
+
* must never read the whole range before yielding the first entry. Reason: a full
|
|
158
|
+
* table scan calls `iterate(buildFullScanBounds())` with NO limit, and the mobile
|
|
159
|
+
* backends that run this code have the least memory headroom of any of them.
|
|
160
|
+
*
|
|
161
|
+
* A backend whose dataset is already wholly resident in memory by construction
|
|
162
|
+
* (`InMemoryKVStore`) satisfies this trivially — the requirement bounds reads from
|
|
163
|
+
* BACKING STORAGE, and such a backend has none.
|
|
164
|
+
*
|
|
165
|
+
* EARLY TERMINATION IS CHEAP. A consumer that stops after k entries must cost
|
|
166
|
+
* roughly k entries of work, not the size of the range: `limit: 10` over a million
|
|
167
|
+
* rows must not read a million rows. Concretely, reads from backing storage must
|
|
168
|
+
* stay within `k + (one batch)`, whatever the implementation's batch size is.
|
|
169
|
+
*
|
|
170
|
+
* TOTAL WORK IS LINEAR. Draining the whole range must read about one entry per
|
|
171
|
+
* entry. A paged backend resumes from the LAST KEY SEEN — never by re-reading from
|
|
172
|
+
* the start and discarding a growing prefix. `limit`/`offset` paging is O(n²) reads
|
|
173
|
+
* yet still looks fine to a peak-memory check, so this is stated separately.
|
|
174
|
+
*
|
|
175
|
+
* EARLY TERMINATION RELEASES RESOURCES. When the consumer `break`s or throws, the
|
|
176
|
+
* returned iterable's `return()`/`throw()` runs; the implementation must close its
|
|
177
|
+
* cursor / transaction / statement there — a `try/finally` around the yield loop —
|
|
178
|
+
* not only on natural exhaustion. After an abandoned iteration the store must still
|
|
179
|
+
* serve `get`/`iterate` normally and `close()` must still resolve.
|
|
180
|
+
*
|
|
181
|
+
* NO SNAPSHOT PROMISE. Batching splits one logical read into several physical ones,
|
|
182
|
+
* so a write committed mid-scan may become visible partway through a scan where a
|
|
183
|
+
* single-shot read could not have shown it. `iterate` therefore does NOT promise a
|
|
184
|
+
* point-in-time view and consumers must not assume one. This is honest about what
|
|
185
|
+
* the stack already does: `StoreTable`'s scan merges the transaction coordinator's
|
|
186
|
+
* pending ops over the committed range, and the store stack declares
|
|
187
|
+
* `readCommittedSnapshot: false`. A real snapshot read is separate, future work.
|
|
188
|
+
*
|
|
189
|
+
* Backends without a streaming cursor (a SQL `select` hands back a whole result set)
|
|
190
|
+
* should page with {@link pagedIterate} rather than re-deriving the resume edge.
|
|
191
|
+
* `runKVStoreConformance`'s bounded-iteration tier enforces all of the above for any
|
|
192
|
+
* backend whose adapter supplies a read meter.
|
|
141
193
|
*/
|
|
142
194
|
iterate(options?: IterateOptions): AsyncIterable<KVEntry>;
|
|
143
195
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kv-store.d.ts","sourceRoot":"","sources":["../../../src/common/kv-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,gEAAgE;IAChE,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,6BAA6B;IAC7B,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB,wDAAwD;IACxD,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,gCAAgC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB
|
|
1
|
+
{"version":3,"file":"kv-store.d.ts","sourceRoot":"","sources":["../../../src/common/kv-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../../src/common/memory-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAsBhG;;;GAGG;AACH,qBAAa,eAAgB,YAAW,OAAO;IAC7C,OAAO,CAAC,IAAI,CAA6D;IACzE,OAAO,CAAC,MAAM,CAAS;IAEjB,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAWrD,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAS/E,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/D,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrC,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../../src/common/memory-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAsBhG;;;GAGG;AACH,qBAAa,eAAgB,YAAW,OAAO;IAC7C,OAAO,CAAC,IAAI,CAA6D;IACzE,OAAO,CAAC,MAAM,CAAS;IAEjB,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAWrD,GAAG,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAS/E,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/D,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrC,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,aAAa,CAAC,OAAO,CAAC;IA0DhE,KAAK,IAAI,UAAU;IA2Bb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,gBAAgB,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAajE;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,OAAO,CAAC,SAAS;CAKlB"}
|
|
@@ -62,7 +62,15 @@ export class InMemoryKVStore {
|
|
|
62
62
|
}
|
|
63
63
|
async *iterate(options) {
|
|
64
64
|
this.checkOpen();
|
|
65
|
-
// Sort entries by hex key for correct ordering
|
|
65
|
+
// Sort entries by hex key for correct ordering.
|
|
66
|
+
// This materializes and sorts the WHOLE map on every call, so even a `limit: 1`
|
|
67
|
+
// scan is O(n log n) and allocates an n-entry array. That does not violate
|
|
68
|
+
// KVStore.iterate's bounded-peak requirement — the requirement bounds reads from
|
|
69
|
+
// backing storage and this store's dataset is already wholly resident — and it is
|
|
70
|
+
// fine while the memory store backs test-sized data and build-time seeds.
|
|
71
|
+
// NOTE: if the memory store ever backs large tables with frequent small-limit
|
|
72
|
+
// scans, keep a sorted key index (or a sorted-insert structure) instead of
|
|
73
|
+
// re-sorting per call.
|
|
66
74
|
const entries = Array.from(this.data.entries())
|
|
67
75
|
.sort((a, b) => compareHex(a[0], b[0]));
|
|
68
76
|
// Apply reverse if requested
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../../src/common/memory-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxC;;;;GAIG;AACH,MAAM,QAAQ,GAAG,UAAU,CAAC;AAE5B;;;;;;;;GAQG;AACH,SAAS,UAAU,CAAC,CAAS,EAAE,CAAS;IACtC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,eAAe;IAClB,IAAI,GAAG,IAAI,GAAG,EAAkD,CAAC;IACjE,MAAM,GAAG,KAAK,CAAC;IAEvB,KAAK,CAAC,GAAG,CAAC,GAAe;QACvB,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,+EAA+E;QAC/E,+EAA+E;QAC/E,8EAA8E;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC;QACnD,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACnE,CAAC;IAED,8EAA8E;IAC9E,+DAA+D;IAC/D,KAAK,CAAC,GAAG,CAAC,GAAe,EAAE,KAAiB,EAAE,QAAuB;QACnE,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,4CAA4C;QAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YAC3B,GAAG,EAAE,IAAI,UAAU,CAAC,GAAG,CAAC;YACxB,KAAK,EAAE,IAAI,UAAU,CAAC,KAAK,CAAC;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAe,EAAE,QAAuB;QACnD,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAe;QACvB,IAAI,CAAC,SAAS,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,CAAC,OAAO,CAAC,OAAwB;QACrC,IAAI,CAAC,SAAS,EAAE,CAAC;QAEjB
|
|
1
|
+
{"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../../src/common/memory-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared batch/resume loop for KVStore backends that cannot stream.
|
|
3
|
+
*
|
|
4
|
+
* Some backends have no cursor to hold open across a consumer `await`: a SQL
|
|
5
|
+
* `select` hands back a whole result set, and an IndexedDB readonly transaction
|
|
6
|
+
* auto-commits while idle. Those backends satisfy {@link KVStore.iterate}'s
|
|
7
|
+
* bounded-peak requirement by paging — read a fixed-size batch, yield it, resume
|
|
8
|
+
* just past the last key seen — so peak memory is one batch regardless of how many
|
|
9
|
+
* entries the range holds.
|
|
10
|
+
*
|
|
11
|
+
* The resume edge is the subtle part, and the reason this lives in one place rather
|
|
12
|
+
* than being re-derived per backend:
|
|
13
|
+
* - forward tightens the LOWER bound, reverse tightens the UPPER bound, both
|
|
14
|
+
* EXCLUSIVE so no entry is yielded twice;
|
|
15
|
+
* - the resume key is captured BEFORE yielding, because entries are handed to the
|
|
16
|
+
* consumer by reference and a consumer that mutates a yielded key must not
|
|
17
|
+
* perturb where the next batch resumes from;
|
|
18
|
+
* - an exhausted edge can collapse the bounds to an empty range, which must read
|
|
19
|
+
* as "exhausted" rather than throw.
|
|
20
|
+
*/
|
|
21
|
+
import type { IterateOptions, KVEntry } from './kv-store.js';
|
|
22
|
+
/**
|
|
23
|
+
* Fetch up to `want` entries for the given bounds.
|
|
24
|
+
*
|
|
25
|
+
* `bounds` is already resume-adjusted and carries `reverse`; it never carries
|
|
26
|
+
* `limit` — the cap is `want`, passed separately so a backend can push it into its
|
|
27
|
+
* query. Returning FEWER than `want` entries signals the range is exhausted, so an
|
|
28
|
+
* implementation must return a full batch whenever one is available. Returning MORE
|
|
29
|
+
* than `want` is a programming error and {@link pagedIterate} throws on it.
|
|
30
|
+
*/
|
|
31
|
+
export type FetchBatch = (bounds: IterateOptions, want: number) => Promise<KVEntry[]>;
|
|
32
|
+
/**
|
|
33
|
+
* Drive a non-streaming backend as a bounded async iterable: fetch a batch, yield it,
|
|
34
|
+
* resume past the last key seen. Peak is one batch regardless of range size, and a
|
|
35
|
+
* consumer that stops after k entries costs at most one batch beyond k.
|
|
36
|
+
*
|
|
37
|
+
* @param options - The caller's iterate options (bounds, `reverse`, `limit`).
|
|
38
|
+
* @param fetchBatch - Backend read for one batch. See {@link FetchBatch}.
|
|
39
|
+
* @param batchSize - Entries per batch. Defaults to {@link DEFAULT_BATCH_SIZE}.
|
|
40
|
+
*/
|
|
41
|
+
export declare function pagedIterate(options: IterateOptions | undefined, fetchBatch: FetchBatch, batchSize?: number): AsyncIterable<KVEntry>;
|
|
42
|
+
//# sourceMappingURL=paged-iterate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paged-iterate.d.ts","sourceRoot":"","sources":["../../../src/common/paged-iterate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAK7D;;;;;;;;GAQG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;AA6CtF;;;;;;;;GAQG;AACH,wBAAuB,YAAY,CAClC,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,UAAU,EAAE,UAAU,EACtB,SAAS,GAAE,MAA2B,GACpC,aAAa,CAAC,OAAO,CAAC,CAoCxB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared batch/resume loop for KVStore backends that cannot stream.
|
|
3
|
+
*
|
|
4
|
+
* Some backends have no cursor to hold open across a consumer `await`: a SQL
|
|
5
|
+
* `select` hands back a whole result set, and an IndexedDB readonly transaction
|
|
6
|
+
* auto-commits while idle. Those backends satisfy {@link KVStore.iterate}'s
|
|
7
|
+
* bounded-peak requirement by paging — read a fixed-size batch, yield it, resume
|
|
8
|
+
* just past the last key seen — so peak memory is one batch regardless of how many
|
|
9
|
+
* entries the range holds.
|
|
10
|
+
*
|
|
11
|
+
* The resume edge is the subtle part, and the reason this lives in one place rather
|
|
12
|
+
* than being re-derived per backend:
|
|
13
|
+
* - forward tightens the LOWER bound, reverse tightens the UPPER bound, both
|
|
14
|
+
* EXCLUSIVE so no entry is yielded twice;
|
|
15
|
+
* - the resume key is captured BEFORE yielding, because entries are handed to the
|
|
16
|
+
* consumer by reference and a consumer that mutates a yielded key must not
|
|
17
|
+
* perturb where the next batch resumes from;
|
|
18
|
+
* - an exhausted edge can collapse the bounds to an empty range, which must read
|
|
19
|
+
* as "exhausted" rather than throw.
|
|
20
|
+
*/
|
|
21
|
+
import { compareBytes } from './bytes.js';
|
|
22
|
+
/** Default entries per batch when the caller does not pick one. */
|
|
23
|
+
const DEFAULT_BATCH_SIZE = 256;
|
|
24
|
+
/** Derive the lower/upper edges of `options`, preferring the inclusive form. */
|
|
25
|
+
function edgesOf(options) {
|
|
26
|
+
let lower;
|
|
27
|
+
let upper;
|
|
28
|
+
if (options?.gte)
|
|
29
|
+
lower = { key: options.gte, open: false };
|
|
30
|
+
else if (options?.gt)
|
|
31
|
+
lower = { key: options.gt, open: true };
|
|
32
|
+
if (options?.lte)
|
|
33
|
+
upper = { key: options.lte, open: false };
|
|
34
|
+
else if (options?.lt)
|
|
35
|
+
upper = { key: options.lt, open: true };
|
|
36
|
+
return { lower, upper };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* True when the edges describe a range that can hold nothing: crossed, or a single
|
|
40
|
+
* point excluded by either edge. Reached on the resume iteration when a batch fills
|
|
41
|
+
* exactly to a boundary key that also equals an inclusive opposite bound.
|
|
42
|
+
*/
|
|
43
|
+
function isEmptyRange(lower, upper) {
|
|
44
|
+
if (!lower || !upper)
|
|
45
|
+
return false;
|
|
46
|
+
const c = compareBytes(lower.key, upper.key);
|
|
47
|
+
return c > 0 || (c === 0 && (lower.open || upper.open));
|
|
48
|
+
}
|
|
49
|
+
/** Rebuild an {@link IterateOptions} from explicit edges, dropping `limit`. */
|
|
50
|
+
function boundsOf(lower, upper, reverse) {
|
|
51
|
+
const bounds = {};
|
|
52
|
+
if (lower) {
|
|
53
|
+
if (lower.open)
|
|
54
|
+
bounds.gt = lower.key;
|
|
55
|
+
else
|
|
56
|
+
bounds.gte = lower.key;
|
|
57
|
+
}
|
|
58
|
+
if (upper) {
|
|
59
|
+
if (upper.open)
|
|
60
|
+
bounds.lt = upper.key;
|
|
61
|
+
else
|
|
62
|
+
bounds.lte = upper.key;
|
|
63
|
+
}
|
|
64
|
+
if (reverse)
|
|
65
|
+
bounds.reverse = true;
|
|
66
|
+
return bounds;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Drive a non-streaming backend as a bounded async iterable: fetch a batch, yield it,
|
|
70
|
+
* resume past the last key seen. Peak is one batch regardless of range size, and a
|
|
71
|
+
* consumer that stops after k entries costs at most one batch beyond k.
|
|
72
|
+
*
|
|
73
|
+
* @param options - The caller's iterate options (bounds, `reverse`, `limit`).
|
|
74
|
+
* @param fetchBatch - Backend read for one batch. See {@link FetchBatch}.
|
|
75
|
+
* @param batchSize - Entries per batch. Defaults to {@link DEFAULT_BATCH_SIZE}.
|
|
76
|
+
*/
|
|
77
|
+
export async function* pagedIterate(options, fetchBatch, batchSize = DEFAULT_BATCH_SIZE) {
|
|
78
|
+
if (!Number.isInteger(batchSize) || batchSize < 1) {
|
|
79
|
+
throw new Error(`pagedIterate: batchSize must be a positive integer, got ${batchSize}`);
|
|
80
|
+
}
|
|
81
|
+
const reverse = options?.reverse ?? false;
|
|
82
|
+
const { lower, upper } = edgesOf(options);
|
|
83
|
+
let remaining = options?.limit; // undefined ⇒ unbounded
|
|
84
|
+
let resumeKey; // last key yielded — exclusive resume edge
|
|
85
|
+
for (;;) {
|
|
86
|
+
if (remaining !== undefined && remaining <= 0)
|
|
87
|
+
return;
|
|
88
|
+
const want = remaining === undefined ? batchSize : Math.min(batchSize, remaining);
|
|
89
|
+
// Resume just past the last key seen: forward tightens the lower bound,
|
|
90
|
+
// reverse tightens the upper bound — exclusive so no entry repeats.
|
|
91
|
+
const effLower = !reverse && resumeKey !== undefined ? { key: resumeKey, open: true } : lower;
|
|
92
|
+
const effUpper = reverse && resumeKey !== undefined ? { key: resumeKey, open: true } : upper;
|
|
93
|
+
if (isEmptyRange(effLower, effUpper))
|
|
94
|
+
return;
|
|
95
|
+
const batch = await fetchBatch(boundsOf(effLower, effUpper, reverse), want);
|
|
96
|
+
if (batch.length > want) {
|
|
97
|
+
throw new Error(`pagedIterate: fetchBatch returned ${batch.length} entries for want=${want}`);
|
|
98
|
+
}
|
|
99
|
+
// Capture the resume boundary BEFORE yielding, and as a COPY: entries go to the
|
|
100
|
+
// consumer by reference, and a consumer that mutates a yielded key must not move
|
|
101
|
+
// where the next batch resumes from.
|
|
102
|
+
const nextResumeKey = batch.length > 0 ? new Uint8Array(batch[batch.length - 1].key) : undefined;
|
|
103
|
+
for (const entry of batch) {
|
|
104
|
+
yield entry;
|
|
105
|
+
}
|
|
106
|
+
if (remaining !== undefined)
|
|
107
|
+
remaining -= batch.length;
|
|
108
|
+
if (batch.length < want)
|
|
109
|
+
return; // range exhausted before filling the batch
|
|
110
|
+
resumeKey = nextResumeKey;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=paged-iterate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paged-iterate.js","sourceRoot":"","sources":["../../../src/common/paged-iterate.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,8 +4,18 @@
|
|
|
4
4
|
* Uses extended JSON format that preserves SQL value types:
|
|
5
5
|
* - bigint: { "$bigint": "12345678901234567890" }
|
|
6
6
|
* - Uint8Array: { "$blob": "base64..." }
|
|
7
|
-
* - JSON objects with marker-colliding keys: { "$json": { "$bigint": "not-a-bigint" } }
|
|
8
7
|
* - Other types: Native JSON representation
|
|
8
|
+
*
|
|
9
|
+
* JSON/object values whose own keys collide with a marker name are escaped on
|
|
10
|
+
* write by prefixing one extra `$` (`$bigint` -> `$$bigint`, `$$blob` ->
|
|
11
|
+
* `$$$blob`) and unescaped on read. Escaping happens per key at any depth, so
|
|
12
|
+
* a marker-shaped object can never be confused with a real marker no matter
|
|
13
|
+
* how deeply it is nested.
|
|
14
|
+
*
|
|
15
|
+
* Escaping (not wrapping) is required because `JSON.parse` invokes the reviver
|
|
16
|
+
* bottom-up: an enclosing `{"$json": ...}` wrapper is visited *after* the value
|
|
17
|
+
* it was meant to protect, so the inner object would already have been decoded
|
|
18
|
+
* (or thrown) before the wrapper could suppress it.
|
|
9
19
|
*/
|
|
10
20
|
import type { Row, SqlValue } from '@quereus/quereus';
|
|
11
21
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../../src/common/serialization.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../../src/common/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAiDtD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,CAGjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,GAAG,CAOtD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,GAAG,UAAU,CAG1D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,CAG7D;AA+ID;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAE5D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAE/D"}
|