@quereus/store 4.3.0 → 4.3.2
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 +486 -436
- package/dist/src/common/bytes.d.ts +4 -1
- package/dist/src/common/bytes.d.ts.map +1 -1
- package/dist/src/common/bytes.js +23 -2
- package/dist/src/common/bytes.js.map +1 -1
- package/dist/src/common/cached-kv-store.d.ts.map +1 -1
- package/dist/src/common/cached-kv-store.js +6 -13
- package/dist/src/common/cached-kv-store.js.map +1 -1
- package/dist/src/common/encoding.d.ts +69 -26
- package/dist/src/common/encoding.d.ts.map +1 -1
- package/dist/src/common/encoding.js +292 -230
- package/dist/src/common/encoding.js.map +1 -1
- package/dist/src/common/index.d.ts +1 -1
- package/dist/src/common/index.d.ts.map +1 -1
- package/dist/src/common/index.js +1 -1
- package/dist/src/common/index.js.map +1 -1
- package/dist/src/common/key-builder.d.ts +5 -1
- package/dist/src/common/key-builder.d.ts.map +1 -1
- package/dist/src/common/key-builder.js +30 -2
- package/dist/src/common/key-builder.js.map +1 -1
- package/dist/src/common/kv-store.d.ts +1 -1
- package/dist/src/common/memory-store.d.ts.map +1 -1
- package/dist/src/common/memory-store.js +21 -6
- package/dist/src/common/memory-store.js.map +1 -1
- package/dist/src/common/serialization.d.ts.map +1 -1
- package/dist/src/common/serialization.js +6 -3
- package/dist/src/common/serialization.js.map +1 -1
- package/dist/src/common/store-module.d.ts +293 -26
- package/dist/src/common/store-module.d.ts.map +1 -1
- package/dist/src/common/store-module.js +1543 -612
- package/dist/src/common/store-module.js.map +1 -1
- package/dist/src/common/store-table.d.ts +515 -36
- package/dist/src/common/store-table.d.ts.map +1 -1
- package/dist/src/common/store-table.js +873 -100
- package/dist/src/common/store-table.js.map +1 -1
- package/dist/src/common/transaction.d.ts +8 -5
- package/dist/src/common/transaction.d.ts.map +1 -1
- package/dist/src/common/transaction.js +32 -5
- package/dist/src/common/transaction.js.map +1 -1
- package/dist/src/testing/kv-conformance.d.ts +47 -0
- package/dist/src/testing/kv-conformance.d.ts.map +1 -0
- package/dist/src/testing/kv-conformance.js +418 -0
- package/dist/src/testing/kv-conformance.js.map +1 -0
- package/package.json +17 -5
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
* Keys are compared as unsigned bytes, matching the lexicographic ordering
|
|
5
5
|
* every KVStore implementation guarantees for `iterate()`.
|
|
6
6
|
*/
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Hex-encode a key for use as a Map/Set lookup. Lowercase, two chars per byte —
|
|
9
|
+
* see {@link HEX_BYTE} for the ordering contract callers depend on.
|
|
10
|
+
*/
|
|
8
11
|
export declare function bytesToHex(key: Uint8Array): string;
|
|
9
12
|
/** Byte-wise equality check for Uint8Arrays. */
|
|
10
13
|
export declare function bytesEqual(a: Uint8Array, b: Uint8Array): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../../../src/common/bytes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"bytes.d.ts","sourceRoot":"","sources":["../../../src/common/bytes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqBH;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAMlD;AAED,gDAAgD;AAChD,wBAAgB,UAAU,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAMhE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,CAMjE"}
|
package/dist/src/common/bytes.js
CHANGED
|
@@ -4,9 +4,30 @@
|
|
|
4
4
|
* Keys are compared as unsigned bytes, matching the lexicographic ordering
|
|
5
5
|
* every KVStore implementation guarantees for `iterate()`.
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
// NOTE: the ~10 other byte→hex encoders in `packages/quereus` (util/serialization.ts,
|
|
8
|
+
// util/key-tuple-codec.ts, vtab/memory/utils/primary-key-encode.ts, planner/analysis/*)
|
|
9
|
+
// duplicate this logic. They live in a different package with their own key concerns;
|
|
10
|
+
// consolidating them is a separate future cleanup, deliberately out of scope here.
|
|
11
|
+
/**
|
|
12
|
+
* Precomputed two-char lowercase hex for every byte value (0x00–0xff).
|
|
13
|
+
*
|
|
14
|
+
* The output MUST stay lowercase, zero-padded, exactly two chars per byte:
|
|
15
|
+
* {@link bytesToHex} keys are compared as strings in `InMemoryKVStore`, and
|
|
16
|
+
* `[0-9a-f]` is the only alphabet where `localeCompare` on hex matches
|
|
17
|
+
* unsigned-byte order (see `memory-store.ts` `compareHex`). Any other alphabet
|
|
18
|
+
* (upper-case, unpadded) would silently mis-order every store test's oracle.
|
|
19
|
+
*/
|
|
20
|
+
const HEX_BYTE = Array.from({ length: 256 }, (_unused, b) => b.toString(16).padStart(2, '0'));
|
|
21
|
+
/**
|
|
22
|
+
* Hex-encode a key for use as a Map/Set lookup. Lowercase, two chars per byte —
|
|
23
|
+
* see {@link HEX_BYTE} for the ordering contract callers depend on.
|
|
24
|
+
*/
|
|
8
25
|
export function bytesToHex(key) {
|
|
9
|
-
|
|
26
|
+
let hex = '';
|
|
27
|
+
for (let i = 0; i < key.length; i++) {
|
|
28
|
+
hex += HEX_BYTE[key[i]];
|
|
29
|
+
}
|
|
30
|
+
return hex;
|
|
10
31
|
}
|
|
11
32
|
/** Byte-wise equality check for Uint8Arrays. */
|
|
12
33
|
export function bytesEqual(a, b) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../../src/common/bytes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,
|
|
1
|
+
{"version":3,"file":"bytes.js","sourceRoot":"","sources":["../../../src/common/bytes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sFAAsF;AACtF,wFAAwF;AACxF,sFAAsF;AACtF,mFAAmF;AAEnF;;;;;;;;GAQG;AACH,MAAM,QAAQ,GAAsB,KAAK,CAAC,IAAI,CAC7C,EAAE,MAAM,EAAE,GAAG,EAAE,EACf,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAC/C,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,GAAe;IACzC,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,UAAU,CAAC,CAAa,EAAE,CAAa;IACtD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,CAAa,EAAE,CAAa;IACxD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cached-kv-store.d.ts","sourceRoot":"","sources":["../../../src/common/cached-kv-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
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;AAWD;;;;;;;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;IAgBrD,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"}
|
|
@@ -5,14 +5,7 @@
|
|
|
5
5
|
* Write-through on put/delete, with negative cache entries for known-absent keys.
|
|
6
6
|
* Iteration always delegates to the underlying store (range consistency is hard).
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
function toHex(arr) {
|
|
10
|
-
let hex = '';
|
|
11
|
-
for (let i = 0; i < arr.length; i++) {
|
|
12
|
-
hex += (arr[i] < 16 ? '0' : '') + arr[i].toString(16);
|
|
13
|
-
}
|
|
14
|
-
return hex;
|
|
15
|
-
}
|
|
8
|
+
import { bytesToHex } from './bytes.js';
|
|
16
9
|
/**
|
|
17
10
|
* Read-through LRU cache wrapper for a KVStore.
|
|
18
11
|
*
|
|
@@ -44,7 +37,7 @@ export class CachedKVStore {
|
|
|
44
37
|
async get(key) {
|
|
45
38
|
if (!this.enabled)
|
|
46
39
|
return this.store.get(key);
|
|
47
|
-
const hex =
|
|
40
|
+
const hex = bytesToHex(key);
|
|
48
41
|
const node = this.map.get(hex);
|
|
49
42
|
if (node) {
|
|
50
43
|
this.moveToHead(node);
|
|
@@ -58,7 +51,7 @@ export class CachedKVStore {
|
|
|
58
51
|
async has(key) {
|
|
59
52
|
if (!this.enabled)
|
|
60
53
|
return this.store.has(key);
|
|
61
|
-
const hex =
|
|
54
|
+
const hex = bytesToHex(key);
|
|
62
55
|
const node = this.map.get(hex);
|
|
63
56
|
if (node) {
|
|
64
57
|
this.moveToHead(node);
|
|
@@ -75,7 +68,7 @@ export class CachedKVStore {
|
|
|
75
68
|
await this.store.put(key, value, options);
|
|
76
69
|
if (!this.enabled)
|
|
77
70
|
return;
|
|
78
|
-
const hex =
|
|
71
|
+
const hex = bytesToHex(key);
|
|
79
72
|
const existing = this.map.get(hex);
|
|
80
73
|
if (existing) {
|
|
81
74
|
this.totalBytes -= existing.size;
|
|
@@ -93,7 +86,7 @@ export class CachedKVStore {
|
|
|
93
86
|
if (!this.enabled)
|
|
94
87
|
return;
|
|
95
88
|
// Insert negative cache entry (known absent)
|
|
96
|
-
const hex =
|
|
89
|
+
const hex = bytesToHex(key);
|
|
97
90
|
const existing = this.map.get(hex);
|
|
98
91
|
if (existing) {
|
|
99
92
|
this.totalBytes -= existing.size;
|
|
@@ -122,7 +115,7 @@ export class CachedKVStore {
|
|
|
122
115
|
}
|
|
123
116
|
/** Invalidate a single key from the cache. */
|
|
124
117
|
invalidate(key) {
|
|
125
|
-
const hex =
|
|
118
|
+
const hex = bytesToHex(key);
|
|
126
119
|
this.removeEntry(hex);
|
|
127
120
|
}
|
|
128
121
|
/** Invalidate all entries from the cache. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cached-kv-store.js","sourceRoot":"","sources":["../../../src/common/cached-kv-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"cached-kv-store.js","sourceRoot":"","sources":["../../../src/common/cached-kv-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,41 +6,51 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Type prefixes ensure correct cross-type ordering:
|
|
8
8
|
* 0x00 - NULL (sorts first)
|
|
9
|
-
* 0x01 -
|
|
10
|
-
* 0x02 - REAL (IEEE 754 with sign flip)
|
|
9
|
+
* 0x01 - NUMERIC (bigint + number unified; orders by value across int/real)
|
|
11
10
|
* 0x03 - TEXT (UTF-8, null-terminated, NOCASE by default)
|
|
12
|
-
* 0x04 - BLOB (
|
|
11
|
+
* 0x04 - BLOB (raw bytes, escaped + null-terminated)
|
|
13
12
|
*
|
|
14
13
|
* Collation support:
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* @param encoder The encoder implementation
|
|
14
|
+
* A TEXT/OBJECT value's key bytes are produced by running the value through the
|
|
15
|
+
* collation's KEY NORMALIZER — the `(s: string) => string` whose output equality
|
|
16
|
+
* partitions strings exactly as the collation's comparator does. Normalizers are
|
|
17
|
+
* resolved through `EncodeOptions.normalizers`, which callers holding a `Database`
|
|
18
|
+
* must set to `db.getKeyNormalizerResolver()` so key bytes and value comparisons
|
|
19
|
+
* agree on which strings are the same value.
|
|
20
|
+
*
|
|
21
|
+
* Unpaired surrogates:
|
|
22
|
+
* A TEXT value holding an unpaired surrogate (a half of a surrogate pair with no
|
|
23
|
+
* matching other half) is REJECTED here rather than encoded — see
|
|
24
|
+
* {@link findUnpairedSurrogate}. It is a legal JS string and a legal in-memory
|
|
25
|
+
* Quereus text value, but it is not valid Unicode and no UTF-8 byte sequence encodes
|
|
26
|
+
* it, so it has no faithful key bytes. This is the one deliberate behavioural
|
|
27
|
+
* divergence between a memory table (accepts the value) and a store-backed table
|
|
28
|
+
* (raises at encode time). The alternative — `TextEncoder`'s silent fold to U+FFFD —
|
|
29
|
+
* maps all 2048 lone surrogates onto one key, merging distinct rows.
|
|
32
30
|
*/
|
|
33
|
-
|
|
31
|
+
import type { SqlValue, KeyNormalizerResolver } from '@quereus/quereus';
|
|
34
32
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
33
|
+
* Built-ins-only key-normalizer resolver: the default when no `Database` is threaded to
|
|
34
|
+
* an encode call site. Knows exactly BINARY / NOCASE / RTRIM, with the engine's own
|
|
35
|
+
* normalizer functions (never a store-local copy — a divergent RTRIM here would key rows
|
|
36
|
+
* the engine's `RTRIM_COLLATION` comparator calls distinct at identical bytes).
|
|
37
|
+
*
|
|
38
|
+
* Throws on any other name rather than falling back: guessing a normalizer would encode
|
|
39
|
+
* two comparator-distinct values to the same key, or split one value across two keys.
|
|
38
40
|
*/
|
|
39
|
-
export declare
|
|
41
|
+
export declare const BUILTIN_KEY_NORMALIZER_RESOLVER: KeyNormalizerResolver;
|
|
40
42
|
/** Options for encoding keys. */
|
|
41
43
|
export interface EncodeOptions {
|
|
42
|
-
/** Collation name for TEXT values. Default: 'NOCASE'. */
|
|
44
|
+
/** Collation name for TEXT/OBJECT values. Default: 'NOCASE'. */
|
|
43
45
|
collation?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Resolves a collation name to the string normalizer that produces its key bytes.
|
|
48
|
+
* Supply `db.getKeyNormalizerResolver()` so key bytes and value comparisons agree
|
|
49
|
+
* on which strings are the same value. Defaults to
|
|
50
|
+
* {@link BUILTIN_KEY_NORMALIZER_RESOLVER} (BINARY / NOCASE / RTRIM only; throws on
|
|
51
|
+
* any other name) for the rare call site that holds no `Database`.
|
|
52
|
+
*/
|
|
53
|
+
normalizers?: KeyNormalizerResolver;
|
|
44
54
|
}
|
|
45
55
|
/**
|
|
46
56
|
* Encode a single SQL value into a sortable byte array.
|
|
@@ -63,6 +73,39 @@ export declare function encodeValue(value: SqlValue, options?: EncodeOptions): U
|
|
|
63
73
|
* per-column override on an integer/real/blob member is a harmless no-op.
|
|
64
74
|
*/
|
|
65
75
|
export declare function encodeCompositeKey(values: SqlValue[], options?: EncodeOptions, directions?: ReadonlyArray<boolean>, collations?: ReadonlyArray<string | undefined>): Uint8Array;
|
|
76
|
+
/**
|
|
77
|
+
* Offset of the first UNPAIRED surrogate code unit in `value`, or -1 when every surrogate
|
|
78
|
+
* it holds is the high half of a well-formed high+low pair (an astral character) or the
|
|
79
|
+
* low half of one.
|
|
80
|
+
*
|
|
81
|
+
* A JS string is a sequence of 16-bit code units, not of Unicode characters. A character
|
|
82
|
+
* above U+FFFF is a surrogate PAIR: a high unit (U+D800–U+DBFF) followed by a low unit
|
|
83
|
+
* (U+DC00–U+DFFF). A surrogate with no matching partner is legal in a JS string but is
|
|
84
|
+
* not valid Unicode — it denotes no character, and no UTF-8 byte sequence encodes it.
|
|
85
|
+
*/
|
|
86
|
+
export declare function findUnpairedSurrogate(value: string): number;
|
|
87
|
+
/**
|
|
88
|
+
* Raise on a string the store cannot key (or persist as schema text) faithfully.
|
|
89
|
+
*
|
|
90
|
+
* `TextEncoder` replaces EVERY unpaired surrogate with U+FFFD (bytes `EF BF BD`), so all
|
|
91
|
+
* 2048 of them would encode to the same three bytes: two distinct text values would share
|
|
92
|
+
* one primary-key / index-key byte string (producing a spurious `UNIQUE` violation or —
|
|
93
|
+
* worse — an upsert that overwrites an unrelated row), and two distinct identifiers or DDL
|
|
94
|
+
* texts would share one catalog key or be silently mangled on write. Refusing the value is
|
|
95
|
+
* the only answer that never merges rows or corrupts persisted text.
|
|
96
|
+
*
|
|
97
|
+
* Runs on whatever string is ABOUT to be encoded — for a TEXT value that is the normalized
|
|
98
|
+
* string (a custom key normalizer that slices a string can itself split a surrogate pair,
|
|
99
|
+
* so the reported offset is into the normalizer's output; for BINARY and the case-folding
|
|
100
|
+
* built-ins it is the caller's own offset). `describe` names what's being validated, so the
|
|
101
|
+
* message reads naturally for a TEXT value, an identifier, or a block of persisted DDL text.
|
|
102
|
+
*
|
|
103
|
+
* NOTE: a store written BEFORE this guard existed may hold rows whose text key was folded
|
|
104
|
+
* to U+FFFD. They still scan (decoding to `'�'`), but no lone-surrogate literal can
|
|
105
|
+
* address them any more — the encode raises first. If pre-guard stores ever have to be
|
|
106
|
+
* opened, a one-time migration must rewrite or reject those rows; nothing detects them today.
|
|
107
|
+
*/
|
|
108
|
+
export declare function assertNoUnpairedSurrogate(value: string, describe: string): void;
|
|
66
109
|
/**
|
|
67
110
|
* Decode a single value from a byte array.
|
|
68
111
|
* Returns the decoded value and the number of bytes consumed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../../src/common/encoding.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../../src/common/encoding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAgB,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAOtF;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B,EAAE,qBAO7C,CAAC;AAEF,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,qBAAqB,CAAC;CACrC;AA8BD;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,UAAU,CAgChF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,QAAQ,EAAE,EAClB,OAAO,CAAC,EAAE,aAAa,EACvB,UAAU,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,EACnC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,SAAS,CAAC,GAC7C,UAAU,CAoBZ;AA6GD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAc3D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAW/E;AAgED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,UAAU,EAClB,MAAM,GAAE,MAAU,EAClB,OAAO,CAAC,EAAE,aAAa,GACtB;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CA0BxC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,aAAa,GACtB,QAAQ,EAAE,CAeZ"}
|