flatpack-json 9.7.0 → 9.8.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/dist/CompactStorage.d.mts +10 -0
- package/dist/CompactStorage.mjs +7 -0
- package/dist/Flatpack.d.mts +2 -86
- package/dist/Flatpack.mjs +5 -610
- package/dist/FlatpackData.d.mts +24 -0
- package/dist/FlatpackData.mjs +122 -0
- package/dist/FlatpackV1.d.mts +100 -0
- package/dist/FlatpackV1.mjs +642 -0
- package/dist/FlatpackV2.d.mts +16 -0
- package/dist/FlatpackV2.mjs +41 -0
- package/dist/RefCounter.d.mts +17 -0
- package/dist/RefCounter.mjs +42 -0
- package/dist/RefElements.d.mts +2 -2
- package/dist/Trie.d.mts +37 -7
- package/dist/Trie.mjs +95 -4
- package/dist/WeakCache.d.mts +15 -0
- package/dist/WeakCache.mjs +41 -0
- package/dist/flatpackUtil.d.mts +1 -2
- package/dist/flatpacked.d.mts +14 -0
- package/dist/flatpacked.mjs +129 -0
- package/dist/optimizeFlatpacked.mjs +54 -71
- package/dist/proxy.mjs +0 -1
- package/dist/storage.d.mts +3 -64
- package/dist/storage.mjs +31 -439
- package/dist/storageV1.d.mts +67 -0
- package/dist/storageV1.mjs +445 -0
- package/dist/storageV2.d.mts +70 -0
- package/dist/storageV2.mjs +451 -0
- package/dist/stringTable.d.mts +39 -0
- package/dist/stringTable.mjs +213 -0
- package/dist/stringify.d.mts +6 -1
- package/dist/stringify.mjs +31 -2
- package/dist/types.d.mts +63 -15
- package/dist/types.mjs +6 -2
- package/dist/unpack.d.mts +1 -1
- package/dist/unpack.mjs +70 -31
- package/dist/unpackedAnnotation.d.mts +23 -0
- package/dist/unpackedAnnotation.mjs +32 -0
- package/package.json +5 -5
package/dist/stringify.d.mts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import type { Flatpacked } from './types.mjs';
|
|
2
|
-
export
|
|
2
|
+
export interface StringifyOptions {
|
|
3
|
+
maxLineLength?: number;
|
|
4
|
+
maxBatchSize?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const DEFAULT_STRINGIFY_OPTIONS: Required<StringifyOptions>;
|
|
7
|
+
export declare function stringifyFlatpacked(input: Flatpacked, options?: StringifyOptions): string;
|
|
3
8
|
//# sourceMappingURL=stringify.d.mts.map
|
package/dist/stringify.mjs
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
const maxLineLength = 512;
|
|
2
|
+
const maxBatchSize = 64;
|
|
3
|
+
export const DEFAULT_STRINGIFY_OPTIONS = {
|
|
4
|
+
maxLineLength,
|
|
5
|
+
maxBatchSize,
|
|
6
|
+
};
|
|
7
|
+
export function stringifyFlatpacked(input, options) {
|
|
2
8
|
let result = '[\n' + JSON.stringify(input[0]);
|
|
3
9
|
let prev = '';
|
|
4
10
|
for (let i = 1; i < input.length; i++) {
|
|
5
|
-
const next =
|
|
11
|
+
const next = formatLine(input[i], options);
|
|
6
12
|
result += prev === next ? ',' : ',\n';
|
|
7
13
|
result += next;
|
|
8
14
|
prev = next;
|
|
@@ -10,4 +16,27 @@ export function stringifyFlatpacked(input) {
|
|
|
10
16
|
result += '\n]\n';
|
|
11
17
|
return result;
|
|
12
18
|
}
|
|
19
|
+
function formatLine(elem, options) {
|
|
20
|
+
if (!options || !Array.isArray(elem)) {
|
|
21
|
+
return JSON.stringify(elem);
|
|
22
|
+
}
|
|
23
|
+
const { maxLineLength, maxBatchSize } = { ...DEFAULT_STRINGIFY_OPTIONS, ...options };
|
|
24
|
+
const input = elem;
|
|
25
|
+
const result = [];
|
|
26
|
+
let line = '';
|
|
27
|
+
for (let i = 0; i < input.length; i++) {
|
|
28
|
+
if (line)
|
|
29
|
+
line += ',';
|
|
30
|
+
const next = JSON.stringify(input[i]);
|
|
31
|
+
if (line.length + next.length > maxLineLength || (i && i % maxBatchSize === 0)) {
|
|
32
|
+
result.push(line);
|
|
33
|
+
line = '';
|
|
34
|
+
}
|
|
35
|
+
line += next;
|
|
36
|
+
}
|
|
37
|
+
if (line) {
|
|
38
|
+
result.push(line);
|
|
39
|
+
}
|
|
40
|
+
return '[' + result.join('\n') + ']';
|
|
41
|
+
}
|
|
13
42
|
//# sourceMappingURL=stringify.mjs.map
|
package/dist/types.d.mts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RefCounter } from './RefCounter.mjs';
|
|
1
2
|
export type SimplePrimitive = string | number | boolean | null | undefined;
|
|
2
3
|
export type Primitive = SimplePrimitive | RegExp | Date | bigint;
|
|
3
4
|
export type PrimitiveSet = Set<Primitive | PrimitiveObject | PrimitiveArray | PrimitiveSet | PrimitiveMap>;
|
|
@@ -20,7 +21,8 @@ export declare enum ElementType {
|
|
|
20
21
|
Map = 5,
|
|
21
22
|
RegExp = 6,
|
|
22
23
|
Date = 7,
|
|
23
|
-
BigInt = 8
|
|
24
|
+
BigInt = 8,
|
|
25
|
+
StringTable = 128
|
|
24
26
|
}
|
|
25
27
|
interface EmptyObject {
|
|
26
28
|
readonly t?: ElementType.Object;
|
|
@@ -31,55 +33,63 @@ type ObjectBasedElements = EmptyObject;
|
|
|
31
33
|
* An array is used to represent the element.
|
|
32
34
|
* The first element is the type of the element.
|
|
33
35
|
*/
|
|
34
|
-
export type ArrayBasedElements = ArrayElement | BigIntElement | DateElement | MapElement | ObjectElement | ObjectWrapperElement | RegExpElement | SetElement | StringElement | SubStringElement;
|
|
35
|
-
|
|
36
|
+
export type ArrayBasedElements = ArrayElement | BigIntElement | DateElement | MapElement | ObjectElement | ObjectWrapperElement | RegExpElement | SetElement | StringElement | SubStringElement | StringTableElement;
|
|
37
|
+
/**
|
|
38
|
+
* The absolute index of an element in the Flatpacked array. The first element is the header,
|
|
39
|
+
* so the first element is at index 1.
|
|
40
|
+
*/
|
|
41
|
+
export type FlatpackIndex = number;
|
|
36
42
|
/**
|
|
37
43
|
* A Compound string element. Each index is a reference to a string element that is concatenated
|
|
38
44
|
* to form the final string.
|
|
39
45
|
*/
|
|
40
|
-
export type StringElement = readonly [type: ElementType.String, ...
|
|
46
|
+
export type StringElement = readonly [type: ElementType.String, ...FlatpackIndex[]];
|
|
41
47
|
/**
|
|
42
48
|
* A substring element. The first index is a reference to a string element.
|
|
43
49
|
* The second index is the length of the substring.
|
|
44
50
|
* The third index is the offset of the substring, defaults to 0.
|
|
45
51
|
*/
|
|
46
|
-
export type SubStringElement = readonly [type: ElementType.SubString, idx:
|
|
52
|
+
export type SubStringElement = readonly [type: ElementType.SubString, idx: FlatpackIndex, len: number, offset?: number];
|
|
47
53
|
/**
|
|
48
54
|
* An object element. The first index is a reference to an array of keys.
|
|
49
55
|
* The second index is a reference to an array of values.
|
|
50
56
|
*/
|
|
51
|
-
export type ObjectElement = readonly [type: ElementType.Object, keys:
|
|
57
|
+
export type ObjectElement = readonly [type: ElementType.Object, keys: FlatpackIndex, values: FlatpackIndex];
|
|
52
58
|
/**
|
|
53
59
|
* A Object wrapper element.
|
|
54
60
|
*/
|
|
55
|
-
export type ObjectWrapperElement = readonly [type: ElementType.Object, keys: 0, values:
|
|
61
|
+
export type ObjectWrapperElement = readonly [type: ElementType.Object, keys: 0, values: FlatpackIndex];
|
|
56
62
|
/**
|
|
57
63
|
* A set element. The first index is a reference to an array of keys.
|
|
58
64
|
*/
|
|
59
|
-
export type SetElement = readonly [type: ElementType.Set, keys:
|
|
65
|
+
export type SetElement = readonly [type: ElementType.Set, keys: FlatpackIndex];
|
|
60
66
|
/**
|
|
61
67
|
* A map element. The first index is a reference to an array of keys.
|
|
62
68
|
* The second index is a reference to an array of values.
|
|
63
69
|
*/
|
|
64
|
-
export type MapElement = readonly [type: ElementType.Map, keys:
|
|
70
|
+
export type MapElement = readonly [type: ElementType.Map, keys: FlatpackIndex, values: FlatpackIndex];
|
|
65
71
|
/**
|
|
66
72
|
* A regular expression element. The first index is a reference to a string element that represents the pattern.
|
|
67
73
|
* The second index is a reference to a string element that represents the flags.
|
|
68
74
|
*/
|
|
69
|
-
export type RegExpElement = readonly [type: ElementType.RegExp, pattern:
|
|
75
|
+
export type RegExpElement = readonly [type: ElementType.RegExp, pattern: FlatpackIndex, flags: FlatpackIndex];
|
|
70
76
|
/**
|
|
71
77
|
* A date element. The first index is the number of milliseconds since the epoch.
|
|
72
78
|
*/
|
|
73
79
|
export type DateElement = readonly [type: ElementType.Date, value: number];
|
|
74
|
-
export type BigIntElement = readonly [type: ElementType.BigInt, value:
|
|
80
|
+
export type BigIntElement = readonly [type: ElementType.BigInt, value: FlatpackIndex];
|
|
75
81
|
/**
|
|
76
82
|
* An array element. Each index is a reference to an element.
|
|
77
83
|
*/
|
|
78
|
-
export type ArrayElement = readonly [type: ElementType.Array, ...
|
|
79
|
-
export type
|
|
84
|
+
export type ArrayElement = readonly [type: ElementType.Array, ...FlatpackIndex[]];
|
|
85
|
+
export type EmptyElement = readonly [];
|
|
86
|
+
export type StringTableEntry = string | number[];
|
|
87
|
+
export type StringTableElement = readonly [type: ElementType.StringTable, ...StringTableEntry[]];
|
|
88
|
+
export type FlattenedElement = Readonly<PrimitiveElement | ObjectBasedElements | ArrayBasedElements | StringTableElement | EmptyElement>;
|
|
80
89
|
type Header = string;
|
|
81
90
|
export type Flatpacked = [Header, ...FlattenedElement[]];
|
|
82
|
-
export type
|
|
91
|
+
export type RawUnpacked = Serializable;
|
|
92
|
+
export type Unpacked = AnnotateUnpacked<RawUnpacked>;
|
|
83
93
|
export declare const blockSplitRegex: RegExp;
|
|
84
94
|
export interface FlatpackOptions {
|
|
85
95
|
/**
|
|
@@ -97,18 +107,56 @@ export interface FlatpackOptions {
|
|
|
97
107
|
* Try to optimize the size of the output.
|
|
98
108
|
*/
|
|
99
109
|
optimize?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* The format of the output. If not specified, the latest format will be used.
|
|
112
|
+
*/
|
|
113
|
+
format?: 'V1' | 'V2';
|
|
114
|
+
/**
|
|
115
|
+
* Meta data to use when packing a value. This is used mainly to minimize the difference between the output of two similar values.
|
|
116
|
+
*/
|
|
117
|
+
meta?: UnpackMetaData | undefined;
|
|
100
118
|
}
|
|
101
119
|
/**
|
|
102
120
|
* Legacy header for Flatpack JSON.
|
|
103
121
|
*/
|
|
104
122
|
export declare const dataHeaderV0_1: "Dehydrated JSON v1";
|
|
123
|
+
export declare const dataHeaderV1_0: "Flatpack JSON v1";
|
|
124
|
+
export declare const dataHeaderV2_0: "Flatpack JSON v2";
|
|
125
|
+
export type Headers = typeof dataHeaderV0_1 | typeof dataHeaderV1_0 | typeof dataHeaderV2_0;
|
|
105
126
|
/**
|
|
106
127
|
* The current header for Flatpack JSON.
|
|
107
128
|
*/
|
|
108
|
-
export declare const dataHeader:
|
|
129
|
+
export declare const dataHeader: string;
|
|
109
130
|
/**
|
|
110
131
|
* The set of supported headers for Flatpack JSON.
|
|
111
132
|
*/
|
|
112
133
|
export declare const supportedHeaders: Set<string>;
|
|
134
|
+
export interface FlatpackApi {
|
|
135
|
+
setValue(value: Serializable): void;
|
|
136
|
+
toJSON(): Flatpacked;
|
|
137
|
+
stringify(): string;
|
|
138
|
+
toValue(): Unpacked;
|
|
139
|
+
}
|
|
140
|
+
export declare const symbolFlatpackAnnotation: unique symbol;
|
|
141
|
+
export interface UnpackMetaData {
|
|
142
|
+
/** The source of the unpacked data */
|
|
143
|
+
flatpack: Flatpacked;
|
|
144
|
+
/** The reference count of elements. */
|
|
145
|
+
referenced: RefCounter<number>;
|
|
146
|
+
/**
|
|
147
|
+
* The index of the root element in the flatpack.
|
|
148
|
+
* In most cases, this will be 2 or 1 (if there is NOT a string table), but can be higher if there are more meta elements.
|
|
149
|
+
* The string table is a meta element, and should be included before the root element if it exists.
|
|
150
|
+
*/
|
|
151
|
+
rootIndex: FlatpackIndex;
|
|
152
|
+
}
|
|
153
|
+
export interface UnpackedAnnotation {
|
|
154
|
+
meta: UnpackMetaData;
|
|
155
|
+
index: number;
|
|
156
|
+
}
|
|
157
|
+
export interface UnpackedAnnotated {
|
|
158
|
+
[symbolFlatpackAnnotation]?: UnpackedAnnotation;
|
|
159
|
+
}
|
|
160
|
+
export type AnnotateUnpacked<T> = T extends null ? T : T extends object ? T & UnpackedAnnotated : T;
|
|
113
161
|
export {};
|
|
114
162
|
//# sourceMappingURL=types.d.mts.map
|
package/dist/types.mjs
CHANGED
|
@@ -9,18 +9,22 @@ export var ElementType;
|
|
|
9
9
|
ElementType[ElementType["RegExp"] = 6] = "RegExp";
|
|
10
10
|
ElementType[ElementType["Date"] = 7] = "Date";
|
|
11
11
|
ElementType[ElementType["BigInt"] = 8] = "BigInt";
|
|
12
|
+
ElementType[ElementType["StringTable"] = 128] = "StringTable";
|
|
12
13
|
})(ElementType || (ElementType = {}));
|
|
13
14
|
export const blockSplitRegex = /^sha\d/;
|
|
14
15
|
/**
|
|
15
16
|
* Legacy header for Flatpack JSON.
|
|
16
17
|
*/
|
|
17
18
|
export const dataHeaderV0_1 = 'Dehydrated JSON v1';
|
|
19
|
+
export const dataHeaderV1_0 = 'Flatpack JSON v1';
|
|
20
|
+
export const dataHeaderV2_0 = 'Flatpack JSON v2';
|
|
18
21
|
/**
|
|
19
22
|
* The current header for Flatpack JSON.
|
|
20
23
|
*/
|
|
21
|
-
export const dataHeader =
|
|
24
|
+
export const dataHeader = dataHeaderV2_0;
|
|
22
25
|
/**
|
|
23
26
|
* The set of supported headers for Flatpack JSON.
|
|
24
27
|
*/
|
|
25
|
-
export const supportedHeaders = new Set([dataHeaderV0_1,
|
|
28
|
+
export const supportedHeaders = new Set([dataHeaderV0_1, dataHeaderV1_0, dataHeaderV2_0]);
|
|
29
|
+
export const symbolFlatpackAnnotation = Symbol.for('flatpackAnnotation');
|
|
26
30
|
//# sourceMappingURL=types.mjs.map
|
package/dist/unpack.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Flatpacked, Unpacked } from './types.mjs';
|
|
2
|
-
export declare function fromJSON(data: Flatpacked):
|
|
2
|
+
export declare function fromJSON<T = Unpacked>(data: Flatpacked): T;
|
|
3
3
|
export declare function parse(data: string): Unpacked;
|
|
4
4
|
//# sourceMappingURL=unpack.d.mts.map
|
package/dist/unpack.mjs
CHANGED
|
@@ -1,28 +1,48 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
|
-
import {
|
|
2
|
+
import { getFlatpackedRootIdx } from './flatpacked.mjs';
|
|
3
|
+
import { RefCounter } from './RefCounter.mjs';
|
|
4
|
+
import { StringTable } from './stringTable.mjs';
|
|
5
|
+
import { ElementType, supportedHeaders, symbolFlatpackAnnotation } from './types.mjs';
|
|
3
6
|
export function fromJSON(data) {
|
|
4
7
|
const [header] = data;
|
|
8
|
+
let stringTable;
|
|
5
9
|
if (!supportedHeaders.has(header)) {
|
|
6
10
|
throw new Error('Invalid header');
|
|
7
11
|
}
|
|
8
12
|
const cache = new Map([[0, undefined]]);
|
|
9
13
|
/**
|
|
10
|
-
* indexes that have been referenced by
|
|
14
|
+
* indexes that have been referenced by multiple objects.
|
|
15
|
+
* A count of 1 means that there is only 1 reference.
|
|
11
16
|
*/
|
|
12
|
-
const referenced = new
|
|
17
|
+
const referenced = new RefCounter();
|
|
18
|
+
const meta = {
|
|
19
|
+
flatpack: data,
|
|
20
|
+
referenced,
|
|
21
|
+
rootIndex: getFlatpackedRootIdx(data),
|
|
22
|
+
};
|
|
23
|
+
return idxToValue(1);
|
|
24
|
+
function cacheValue(idx, value) {
|
|
25
|
+
assert(!cache.has(idx), `Index ${idx} already exists in cache`);
|
|
26
|
+
cache.set(idx, value);
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
function getCachedValue(idx) {
|
|
30
|
+
referenced.add(idx);
|
|
31
|
+
return cache.get(idx);
|
|
32
|
+
}
|
|
13
33
|
function mergeKeysValues(keys, values) {
|
|
14
34
|
return keys.map((key, i) => [key, values[i]]);
|
|
15
35
|
}
|
|
16
36
|
function toSet(idx, elem) {
|
|
17
37
|
const [_, k] = elem;
|
|
18
38
|
const s = k ? new Set(idxToArr(k)) : new Set();
|
|
19
|
-
|
|
39
|
+
cacheValue(idx, s);
|
|
20
40
|
return s;
|
|
21
41
|
}
|
|
22
42
|
function toMap(idx, elem) {
|
|
23
43
|
const [_, k, v] = elem;
|
|
24
44
|
const m = !k || !v ? new Map() : new Map(mergeKeysValues(idxToArr(k), idxToArr(v)));
|
|
25
|
-
|
|
45
|
+
cacheValue(idx, m);
|
|
26
46
|
return m;
|
|
27
47
|
}
|
|
28
48
|
function toRegExp(idx, elem) {
|
|
@@ -30,24 +50,24 @@ export function fromJSON(data) {
|
|
|
30
50
|
const p = idxToValue(pattern);
|
|
31
51
|
const f = idxToValue(flags);
|
|
32
52
|
const r = new RegExp(p, f);
|
|
33
|
-
|
|
53
|
+
cacheValue(idx, r);
|
|
34
54
|
return r;
|
|
35
55
|
}
|
|
36
56
|
function toBigInt(idx, elem) {
|
|
37
57
|
const [_, vIdx] = elem;
|
|
38
58
|
const r = BigInt(idxToValue(vIdx));
|
|
39
|
-
|
|
59
|
+
cacheValue(idx, r);
|
|
40
60
|
return r;
|
|
41
61
|
}
|
|
42
62
|
function toDate(idx, elem) {
|
|
43
63
|
const [_, value] = elem;
|
|
44
64
|
const r = new Date(value);
|
|
45
|
-
|
|
65
|
+
cacheValue(idx, r);
|
|
46
66
|
return r;
|
|
47
67
|
}
|
|
48
68
|
function toString(idx, elem) {
|
|
49
|
-
const s = typeof elem === 'string' ? elem :
|
|
50
|
-
|
|
69
|
+
const s = typeof elem === 'string' ? elem : idxToString(elem.slice(1));
|
|
70
|
+
cacheValue(idx, s);
|
|
51
71
|
return s;
|
|
52
72
|
}
|
|
53
73
|
function toObj(idx, elem) {
|
|
@@ -55,11 +75,11 @@ export function fromJSON(data) {
|
|
|
55
75
|
// Object Wrapper
|
|
56
76
|
if (!k && v) {
|
|
57
77
|
const obj = Object(idxToValue(v));
|
|
58
|
-
|
|
78
|
+
cacheValue(idx, obj);
|
|
59
79
|
return obj;
|
|
60
80
|
}
|
|
61
81
|
const obj = {};
|
|
62
|
-
|
|
82
|
+
cacheValue(idx, obj);
|
|
63
83
|
if (!k || !v)
|
|
64
84
|
return obj;
|
|
65
85
|
const keys = idxToArr(k);
|
|
@@ -68,6 +88,10 @@ export function fromJSON(data) {
|
|
|
68
88
|
return obj;
|
|
69
89
|
}
|
|
70
90
|
function idxToArr(idx) {
|
|
91
|
+
const found = getCachedValue(idx);
|
|
92
|
+
if (found !== undefined) {
|
|
93
|
+
return found;
|
|
94
|
+
}
|
|
71
95
|
const element = data[idx];
|
|
72
96
|
assert(isArrayElement(element));
|
|
73
97
|
return toArr(idx, element);
|
|
@@ -75,12 +99,12 @@ export function fromJSON(data) {
|
|
|
75
99
|
function toArr(idx, element) {
|
|
76
100
|
const placeHolder = [];
|
|
77
101
|
const refs = element.slice(1);
|
|
78
|
-
|
|
102
|
+
cacheValue(idx, placeHolder);
|
|
79
103
|
const arr = refs.map(idxToValue);
|
|
80
104
|
// check if the array has been referenced by another object.
|
|
81
|
-
if (!referenced.
|
|
105
|
+
if (!referenced.isReferenced(idx)) {
|
|
82
106
|
// It has not, just replace the placeholder with the array.
|
|
83
|
-
|
|
107
|
+
cacheValue(idx, arr);
|
|
84
108
|
return arr;
|
|
85
109
|
}
|
|
86
110
|
placeHolder.push(...arr);
|
|
@@ -89,13 +113,13 @@ export function fromJSON(data) {
|
|
|
89
113
|
function handleSubStringElement(idx, refs) {
|
|
90
114
|
const [_t, sIdx, len, offset = 0] = refs;
|
|
91
115
|
const s = `${idxToValue(sIdx)}`.slice(offset, offset + len);
|
|
92
|
-
|
|
116
|
+
cacheValue(idx, s);
|
|
93
117
|
return s;
|
|
94
118
|
}
|
|
95
119
|
function handleArrayElement(idx, element) {
|
|
96
120
|
switch (element[0]) {
|
|
97
121
|
case ElementType.Array: {
|
|
98
|
-
|
|
122
|
+
return toArr(idx, element);
|
|
99
123
|
}
|
|
100
124
|
case ElementType.Object: {
|
|
101
125
|
return toObj(idx, element);
|
|
@@ -121,22 +145,26 @@ export function fromJSON(data) {
|
|
|
121
145
|
case ElementType.BigInt: {
|
|
122
146
|
return toBigInt(idx, element);
|
|
123
147
|
}
|
|
148
|
+
case ElementType.StringTable: {
|
|
149
|
+
stringTable = new StringTable(element);
|
|
150
|
+
return idxToValue(idx + 1);
|
|
151
|
+
}
|
|
124
152
|
}
|
|
125
|
-
return
|
|
153
|
+
return undefined;
|
|
154
|
+
}
|
|
155
|
+
function idxToString(idx) {
|
|
156
|
+
return joinToString(idx.map((i) => idxToValue(i)));
|
|
126
157
|
}
|
|
127
158
|
function idxToValue(idx) {
|
|
128
159
|
if (!idx)
|
|
129
160
|
return undefined;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
referenced.add(idx);
|
|
134
|
-
return found;
|
|
161
|
+
if (idx < 0) {
|
|
162
|
+
referenced.add(idx);
|
|
163
|
+
return stringTable?.get(-idx);
|
|
135
164
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return joinToString(parts);
|
|
165
|
+
const found = getCachedValue(idx);
|
|
166
|
+
if (found !== undefined) {
|
|
167
|
+
return annotateUnpacked(found, { meta, index: idx });
|
|
140
168
|
}
|
|
141
169
|
const element = data[idx];
|
|
142
170
|
if (typeof element === 'object') {
|
|
@@ -144,15 +172,17 @@ export function fromJSON(data) {
|
|
|
144
172
|
if (element === null)
|
|
145
173
|
return null;
|
|
146
174
|
if (Array.isArray(element))
|
|
147
|
-
return handleArrayElement(idx, element)
|
|
148
|
-
|
|
175
|
+
return annotateUnpacked(handleArrayElement(idx, element), {
|
|
176
|
+
meta,
|
|
177
|
+
index: idx,
|
|
178
|
+
});
|
|
179
|
+
return annotateUnpacked({}, { meta, index: idx });
|
|
149
180
|
}
|
|
150
181
|
return element;
|
|
151
182
|
}
|
|
152
|
-
return idxToValue(1);
|
|
153
183
|
}
|
|
154
184
|
function joinToString(parts) {
|
|
155
|
-
return parts.
|
|
185
|
+
return parts.flat().join('');
|
|
156
186
|
}
|
|
157
187
|
function isArrayElement(value) {
|
|
158
188
|
return Array.isArray(value) && value[0] === ElementType.Array;
|
|
@@ -160,4 +190,13 @@ function isArrayElement(value) {
|
|
|
160
190
|
export function parse(data) {
|
|
161
191
|
return fromJSON(JSON.parse(data));
|
|
162
192
|
}
|
|
193
|
+
function annotateUnpacked(value, meta) {
|
|
194
|
+
if (value && typeof value === 'object') {
|
|
195
|
+
if (Object.hasOwn(value, symbolFlatpackAnnotation)) {
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
return Object.defineProperty(value, symbolFlatpackAnnotation, { value: meta });
|
|
199
|
+
}
|
|
200
|
+
return value;
|
|
201
|
+
}
|
|
163
202
|
//# sourceMappingURL=unpack.mjs.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Serializable, UnpackedAnnotated, UnpackedAnnotation, UnpackMetaData } from './types.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Get the annotation from an unpacked value. This is only available from values that have been unpacked with the
|
|
4
|
+
* `UnpackedAnnotated` type. If the value is not annotated, this will return undefined.
|
|
5
|
+
* @param data - The unpacked value to extract the meta data from.
|
|
6
|
+
* @returns The meta data or undefined if the value is not annotated.
|
|
7
|
+
*/
|
|
8
|
+
export declare function extractUnpackedAnnotation(data: Serializable): UnpackedAnnotation | undefined;
|
|
9
|
+
/**
|
|
10
|
+
* Get the meta data from an unpacked value. This is only available from values that have been unpacked with the
|
|
11
|
+
* `UnpackedAnnotated` type. If the value is not annotated, this will return undefined.
|
|
12
|
+
* @param data - The unpacked value to extract the meta data from.
|
|
13
|
+
* @returns The meta data or undefined if the value is not annotated.
|
|
14
|
+
*/
|
|
15
|
+
export declare function extractUnpackedMetaData(data: Serializable): UnpackMetaData | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Check if a value has an unpacked annotation. This is only available from values that have been unpacked with the
|
|
18
|
+
* `UnpackedAnnotated` type.
|
|
19
|
+
* @param value - any value to test
|
|
20
|
+
* @returns `value` has UnpackedAnnotation.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isUnpackedAnnotated<T>(value: T): value is T & UnpackedAnnotated;
|
|
23
|
+
//# sourceMappingURL=unpackedAnnotation.d.mts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { symbolFlatpackAnnotation } from './types.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Get the annotation from an unpacked value. This is only available from values that have been unpacked with the
|
|
4
|
+
* `UnpackedAnnotated` type. If the value is not annotated, this will return undefined.
|
|
5
|
+
* @param data - The unpacked value to extract the meta data from.
|
|
6
|
+
* @returns The meta data or undefined if the value is not annotated.
|
|
7
|
+
*/
|
|
8
|
+
export function extractUnpackedAnnotation(data) {
|
|
9
|
+
if (isUnpackedAnnotated(data)) {
|
|
10
|
+
return data[symbolFlatpackAnnotation];
|
|
11
|
+
}
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get the meta data from an unpacked value. This is only available from values that have been unpacked with the
|
|
16
|
+
* `UnpackedAnnotated` type. If the value is not annotated, this will return undefined.
|
|
17
|
+
* @param data - The unpacked value to extract the meta data from.
|
|
18
|
+
* @returns The meta data or undefined if the value is not annotated.
|
|
19
|
+
*/
|
|
20
|
+
export function extractUnpackedMetaData(data) {
|
|
21
|
+
return extractUnpackedAnnotation(data)?.meta;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Check if a value has an unpacked annotation. This is only available from values that have been unpacked with the
|
|
25
|
+
* `UnpackedAnnotated` type.
|
|
26
|
+
* @param value - any value to test
|
|
27
|
+
* @returns `value` has UnpackedAnnotation.
|
|
28
|
+
*/
|
|
29
|
+
export function isUnpackedAnnotated(value) {
|
|
30
|
+
return typeof value === 'object' && value !== null && Object.hasOwn(value, symbolFlatpackAnnotation);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=unpackedAnnotation.mjs.map
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public",
|
|
5
5
|
"provenance": true
|
|
6
6
|
},
|
|
7
|
-
"version": "9.
|
|
7
|
+
"version": "9.8.0",
|
|
8
8
|
"description": "A library to normalize / flatten JSON objects to reduce the size.",
|
|
9
9
|
"keywords": [
|
|
10
10
|
"cspell",
|
|
@@ -53,9 +53,9 @@
|
|
|
53
53
|
"node": ">=20"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@cspell/filetypes": "9.
|
|
57
|
-
"diff": "^8.0.
|
|
58
|
-
"flatted": "^3.
|
|
56
|
+
"@cspell/filetypes": "9.8.0",
|
|
57
|
+
"diff": "^8.0.4",
|
|
58
|
+
"flatted": "^3.4.2"
|
|
59
59
|
},
|
|
60
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "c822013ce676dffb5fa5544567c25a3ae666718f"
|
|
61
61
|
}
|