@cspell/normalize-json 8.14.2 → 8.14.3

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/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { fromJSON, parse, stringify, toJSON } from './dehydrate.mjs';
1
+ export * from 'flatpack-json';
2
2
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { fromJSON, parse, stringify, toJSON } from './dehydrate.mjs';
1
+ export * from 'flatpack-json';
2
2
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "8.14.2",
6
+ "version": "8.14.3",
7
7
  "description": "A library to normalize JSON objects to reduce the size.",
8
8
  "keywords": [
9
9
  "cspell",
@@ -51,8 +51,11 @@
51
51
  "engines": {
52
52
  "node": ">=18"
53
53
  },
54
+ "dependencies": {
55
+ "flatpack-json": "8.14.3"
56
+ },
54
57
  "devDependencies": {
55
- "@cspell/filetypes": "8.14.2"
58
+ "@cspell/filetypes": "8.14.3"
56
59
  },
57
- "gitHead": "9f7c1831d4765d35f289b2a623133fc21bee4dcd"
60
+ "gitHead": "ce996377857f5d7c3e70f27fc512afbe605562f8"
58
61
  }
@@ -1,53 +0,0 @@
1
- type Primitive = string | number | boolean | null | undefined | RegExp | Date | bigint;
2
- type PrimitiveSet = Set<Primitive | PrimitiveObject | PrimitiveArray | PrimitiveSet | PrimitiveMap>;
3
- type PrimitiveMap = Map<Primitive | PrimitiveObject | PrimitiveArray | PrimitiveSet | PrimitiveMap, Primitive | PrimitiveObject | PrimitiveArray | PrimitiveSet | PrimitiveMap>;
4
- interface PrimitiveObject {
5
- readonly [key: string]: Primitive | PrimitiveObject | PrimitiveArray | PrimitiveSet | PrimitiveMap;
6
- }
7
- type PrimitiveArray = readonly (Primitive | PrimitiveObject | PrimitiveArray | PrimitiveSet | PrimitiveMap)[];
8
- type PrimitiveElement = Primitive;
9
- type Serializable = Primitive | PrimitiveObject | PrimitiveArray | PrimitiveSet | PrimitiveMap;
10
- declare enum ElementType {
11
- Array = 0,
12
- Object = 1,
13
- String = 2,
14
- SubString = 3,
15
- Set = 4,
16
- Map = 5,
17
- RegExp = 6,
18
- Date = 7,
19
- BigInt = 8
20
- }
21
- interface EmptyObject {
22
- readonly t?: ElementType.Object;
23
- }
24
- type ObjectBasedElements = EmptyObject;
25
- type ArrayBasedElements = ArrayElement | BigIntElement | DateElement | MapElement | ObjectElement | RegExpElement | SetElement | StringElement | SubStringElement;
26
- type Index = number;
27
- type StringElement = readonly [type: ElementType.String, ...Index[]];
28
- type SubStringElement = readonly [type: ElementType.SubString, Index, len: number, offset?: number];
29
- type ObjectElement = readonly [type: ElementType.Object, keys: Index, values: Index];
30
- type SetElement = readonly [type: ElementType.Set, keys: Index];
31
- type MapElement = readonly [type: ElementType.Map, keys: Index, values: Index];
32
- type RegExpElement = readonly [type: ElementType.RegExp, pattern: Index, flags: Index];
33
- type DateElement = readonly [type: ElementType.Date, value: number];
34
- type BigIntElement = readonly [type: ElementType.BigInt, value: Index];
35
- type ArrayElement = readonly [type: ElementType.Array, ...Index[]];
36
- type Element = Readonly<PrimitiveElement | ObjectBasedElements | ArrayBasedElements>;
37
- type Header = string;
38
- type Dehydrated = [Header, ...Element[]];
39
- type Hydrated = Readonly<Serializable>;
40
- export interface NormalizeJsonOptions {
41
- sortKeys?: boolean;
42
- /**
43
- * Dedupe objects and arrays.
44
- * Implies `sortKeys`.
45
- */
46
- dedupe?: boolean;
47
- }
48
- export declare function toJSON<V extends Serializable>(json: V, options?: NormalizeJsonOptions): Dehydrated;
49
- export declare function fromJSON(data: Dehydrated): Hydrated;
50
- export declare function parse(data: string): Hydrated;
51
- export declare function stringify(data: Hydrated): string;
52
- export {};
53
- //# sourceMappingURL=dehydrate.d.mts.map
@@ -1,524 +0,0 @@
1
- import assert from 'node:assert';
2
- var ElementType;
3
- (function (ElementType) {
4
- ElementType[ElementType["Array"] = 0] = "Array";
5
- ElementType[ElementType["Object"] = 1] = "Object";
6
- ElementType[ElementType["String"] = 2] = "String";
7
- ElementType[ElementType["SubString"] = 3] = "SubString";
8
- ElementType[ElementType["Set"] = 4] = "Set";
9
- ElementType[ElementType["Map"] = 5] = "Map";
10
- ElementType[ElementType["RegExp"] = 6] = "RegExp";
11
- ElementType[ElementType["Date"] = 7] = "Date";
12
- ElementType[ElementType["BigInt"] = 8] = "BigInt";
13
- })(ElementType || (ElementType = {}));
14
- const blockSplitRegex = /^sha\d/;
15
- const dataHeader = 'Dehydrated JSON v1';
16
- const collator = new Intl.Collator('en', {
17
- usage: 'sort',
18
- numeric: true,
19
- sensitivity: 'variant',
20
- caseFirst: 'upper',
21
- ignorePunctuation: false,
22
- });
23
- const compare = collator.compare;
24
- const forceStringPrimitives = false;
25
- const minSubStringLen = 4;
26
- export function toJSON(json, options) {
27
- const data = [dataHeader];
28
- const dedupe = options?.dedupe ?? true;
29
- const sortKeys = options?.sortKeys || dedupe;
30
- let emptyObjIdx = 0;
31
- const cache = new Map([[undefined, 0]]);
32
- const referenced = new Set();
33
- const cachedArrays = new Map();
34
- const knownStrings = new Trie();
35
- const cachedElements = new Map();
36
- function primitiveToIdx(value) {
37
- if (typeof value === 'string')
38
- return stringToIdx(value);
39
- if (typeof value === 'bigint')
40
- return bigintToIdx(value);
41
- const found = cache.get(value);
42
- if (found !== undefined) {
43
- return found;
44
- }
45
- const idx = data.push(value) - 1;
46
- cache.set(value, idx);
47
- return idx;
48
- }
49
- function addSubStringRef(idxString, value, offset) {
50
- const found = cache.get(value);
51
- if (found !== undefined) {
52
- return found;
53
- }
54
- const sub = offset
55
- ? [ElementType.SubString, idxString, value.length, offset]
56
- : [ElementType.SubString, idxString, value.length];
57
- const idx = data.push(sub) - 1;
58
- cache.set(value, idx);
59
- return idx;
60
- }
61
- function addKnownString(idx, value) {
62
- if (value.length >= minSubStringLen) {
63
- knownStrings.add(value.length > 256 ? value.slice(0, 256) : value, { idx });
64
- }
65
- }
66
- function addStringPrimitive(value) {
67
- const idx = data.push(value) - 1;
68
- addKnownString(idx, value);
69
- cache.set(value, idx);
70
- return idx;
71
- }
72
- function duplicateIndex(idx) {
73
- const element = data[idx];
74
- const duplicate = data.push(element) - 1;
75
- return duplicate;
76
- }
77
- function stringToIdx(value) {
78
- const found = cache.get(value);
79
- if (found !== undefined) {
80
- return found;
81
- }
82
- if (forceStringPrimitives || value.length < minSubStringLen || blockSplitRegex.test(value)) {
83
- return addStringPrimitive(value);
84
- }
85
- const trieFound = knownStrings.find(value);
86
- if (!trieFound || !trieFound.data || trieFound.found.length < minSubStringLen) {
87
- return addStringPrimitive(value);
88
- }
89
- const { data: tData, found: subStr } = trieFound;
90
- const sIdx = addSubStringRef(tData.idx, subStr, tData.offset);
91
- if (subStr === value)
92
- return sIdx;
93
- const v = [sIdx, stringToIdx(value.slice(subStr.length))];
94
- const idx = data.push([ElementType.String, ...v]) - 1;
95
- cache.set(value, idx);
96
- addKnownString(idx, value);
97
- return idx;
98
- }
99
- function objSetToIdx(value) {
100
- const found = cache.get(value);
101
- if (found !== undefined) {
102
- referenced.add(found);
103
- return found;
104
- }
105
- const idx = data.push(0) - 1;
106
- cache.set(value, idx);
107
- const keys = [...value];
108
- const k = createUniqueKeys(keys);
109
- const element = [ElementType.Set, k];
110
- return storeElement(value, idx, element);
111
- }
112
- function createUniqueKeys(keys) {
113
- let k = arrToIdx(keys);
114
- const elementKeys = data[k];
115
- const uniqueKeys = new Set(elementKeys.slice(1));
116
- if (uniqueKeys.size !== keys.length) {
117
- // one or more of the keys got deduped. We need to duplicate it.
118
- uniqueKeys.clear();
119
- const indexes = elementKeys.slice(1).map((idx) => {
120
- if (uniqueKeys.has(idx)) {
121
- return duplicateIndex(idx);
122
- }
123
- uniqueKeys.add(idx);
124
- return idx;
125
- });
126
- k = createArrayElementFromIndexValues(data.length, indexes);
127
- }
128
- return k;
129
- }
130
- function objMapToIdx(value) {
131
- const found = cache.get(value);
132
- if (found !== undefined) {
133
- referenced.add(found);
134
- return found;
135
- }
136
- const idx = data.push(0) - 1;
137
- cache.set(value, idx);
138
- const entries = [...value.entries()];
139
- const k = createUniqueKeys(entries.map(([key]) => key));
140
- const v = arrToIdx(entries.map(([, value]) => value));
141
- const element = [ElementType.Map, k, v];
142
- return storeElement(value, idx, element);
143
- }
144
- function objRegExpToIdx(value) {
145
- const found = cache.get(value);
146
- if (found !== undefined) {
147
- return found;
148
- }
149
- const idx = data.push(0) - 1;
150
- cache.set(value, idx);
151
- const element = [ElementType.RegExp, stringToIdx(value.source), stringToIdx(value.flags)];
152
- return storeElement(value, idx, element);
153
- }
154
- function objDateToIdx(value) {
155
- const found = cache.get(value);
156
- if (found !== undefined) {
157
- return found;
158
- }
159
- const idx = data.push(0) - 1;
160
- cache.set(value, idx);
161
- const element = [ElementType.Date, value.getTime()];
162
- return storeElement(value, idx, element);
163
- }
164
- function bigintToIdx(value) {
165
- const found = cache.get(value);
166
- if (found !== undefined) {
167
- return found;
168
- }
169
- const idx = data.push(0) - 1;
170
- cache.set(value, idx);
171
- const element = [
172
- ElementType.BigInt,
173
- primitiveToIdx(value <= Number.MAX_SAFE_INTEGER && value >= -Number.MAX_SAFE_INTEGER
174
- ? Number(value)
175
- : value.toString()),
176
- ];
177
- return storeElement(value, idx, element);
178
- }
179
- function objToIdx(value) {
180
- const found = cache.get(value);
181
- if (found !== undefined) {
182
- referenced.add(found);
183
- return found;
184
- }
185
- if (isObjectWrapper(value)) {
186
- const idx = data.push({}) - 1;
187
- cache.set(value, idx);
188
- const element = [ElementType.Object, 0, valueToIdx(value.valueOf())];
189
- return storeElement(value, idx, element);
190
- }
191
- const entries = Object.entries(value);
192
- if (!entries.length) {
193
- if (emptyObjIdx) {
194
- return emptyObjIdx;
195
- }
196
- const idx = data.push({}) - 1;
197
- emptyObjIdx = idx;
198
- return idx;
199
- }
200
- const idx = data.push(0) - 1;
201
- cache.set(value, idx);
202
- if (sortKeys) {
203
- entries.sort(([a], [b]) => compare(a, b));
204
- }
205
- const k = arrToIdx(entries.map(([key]) => key));
206
- const v = arrToIdx(entries.map(([, value]) => value));
207
- const element = [ElementType.Object, k, v];
208
- return storeElement(value, idx, element);
209
- }
210
- function storeElement(value, idx, element) {
211
- const useIdx = dedupe ? cacheElement(idx, element) : idx;
212
- if (useIdx !== idx && idx === data.length - 1) {
213
- data.length = idx;
214
- cache.set(value, useIdx);
215
- return useIdx;
216
- }
217
- data[idx] = element;
218
- return idx;
219
- }
220
- function cacheElement(elemIdx, element) {
221
- let map = cachedElements;
222
- for (let i = 0; i < element.length - 1; i++) {
223
- const idx = element[i];
224
- let found = map.get(idx);
225
- if (!found) {
226
- found = new Map();
227
- map.set(idx, found);
228
- }
229
- assert(found instanceof Map);
230
- map = found;
231
- }
232
- const idx = element[element.length - 1];
233
- const foundIdx = map.get(idx);
234
- if (typeof foundIdx === 'number') {
235
- return referenced.has(elemIdx) ? elemIdx : foundIdx;
236
- }
237
- map.set(idx, elemIdx);
238
- return elemIdx;
239
- }
240
- function stashArray(idx, element) {
241
- const indexHash = simpleHash(element);
242
- let found = cachedArrays.get(indexHash);
243
- if (!found) {
244
- found = [];
245
- cachedArrays.set(indexHash, found);
246
- }
247
- const foundIdx = found.find((entry) => isEqual(entry.v, element));
248
- if (foundIdx) {
249
- return referenced.has(idx) ? idx : foundIdx.idx;
250
- }
251
- found.push({ idx, v: element });
252
- return idx;
253
- }
254
- function createArrayElementFromIndexValues(idx, indexValues) {
255
- const element = [ElementType.Array, ...indexValues];
256
- const useIdx = dedupe ? stashArray(idx, element) : idx;
257
- if (useIdx !== idx) {
258
- assert(data.length == idx + 1, `Expected ${idx + 1} but got ${data.length}`);
259
- data.length = idx;
260
- return useIdx;
261
- }
262
- data[idx] = element;
263
- return idx;
264
- }
265
- function arrToIdx(value) {
266
- const found = cache.get(value);
267
- if (found !== undefined) {
268
- referenced.add(found);
269
- return found;
270
- }
271
- const idx = data.push(0) - 1;
272
- cache.set(value, idx);
273
- const useIdx = createArrayElementFromIndexValues(idx, value.map((idx) => valueToIdx(idx)));
274
- cache.set(value, useIdx);
275
- return useIdx;
276
- }
277
- function valueToIdx(value) {
278
- if (value === null) {
279
- // eslint-disable-next-line unicorn/no-null
280
- return primitiveToIdx(null);
281
- }
282
- if (typeof value === 'object') {
283
- if (value instanceof Set) {
284
- return objSetToIdx(value);
285
- }
286
- if (value instanceof Map) {
287
- return objMapToIdx(value);
288
- }
289
- if (value instanceof RegExp) {
290
- return objRegExpToIdx(value);
291
- }
292
- if (Array.isArray(value)) {
293
- return arrToIdx(value);
294
- }
295
- if (value instanceof Date) {
296
- return objDateToIdx(value);
297
- }
298
- return objToIdx(value);
299
- }
300
- return primitiveToIdx(value);
301
- }
302
- valueToIdx(json);
303
- return data;
304
- }
305
- function isEqual(a, b) {
306
- if (a.length !== b.length)
307
- return false;
308
- for (let i = 0; i < a.length; i++) {
309
- if (a[i] !== b[i])
310
- return false;
311
- }
312
- return true;
313
- }
314
- function simpleHash(values) {
315
- let hash = Math.sqrt(values.length);
316
- for (const value of values) {
317
- hash += value * value;
318
- }
319
- return hash;
320
- }
321
- export function fromJSON(data) {
322
- const [header] = data;
323
- if (header !== dataHeader) {
324
- throw new Error('Invalid header');
325
- }
326
- const cache = new Map([[0, undefined]]);
327
- /**
328
- * indexes that have been referenced by other objects.
329
- */
330
- const referenced = new Set();
331
- function mergeKeysValues(keys, values) {
332
- return keys.map((key, i) => [key, values[i]]);
333
- }
334
- function toSet(idx, elem) {
335
- const [_, k] = elem;
336
- const s = k ? new Set(idxToArr(k)) : new Set();
337
- cache.set(idx, s);
338
- return s;
339
- }
340
- function toMap(idx, elem) {
341
- const [_, k, v] = elem;
342
- const m = !k || !v ? new Map() : new Map(mergeKeysValues(idxToArr(k), idxToArr(v)));
343
- cache.set(idx, m);
344
- return m;
345
- }
346
- function toRegExp(idx, elem) {
347
- const [_, pattern, flags] = elem;
348
- const p = idxToValue(pattern);
349
- const f = idxToValue(flags);
350
- const r = new RegExp(p, f);
351
- cache.set(idx, r);
352
- return r;
353
- }
354
- function toBigInt(idx, elem) {
355
- const [_, vIdx] = elem;
356
- const r = BigInt(idxToValue(vIdx));
357
- cache.set(idx, r);
358
- return r;
359
- }
360
- function toDate(idx, elem) {
361
- const [_, value] = elem;
362
- const r = new Date(value);
363
- cache.set(idx, r);
364
- return r;
365
- }
366
- function toString(idx, elem) {
367
- const s = typeof elem === 'string' ? elem : idxToValue(elem.slice(1));
368
- cache.set(idx, s);
369
- return s;
370
- }
371
- function toObj(idx, elem) {
372
- const [_, k, v] = elem;
373
- // Object Wrapper
374
- if (!k && v) {
375
- const obj = Object(idxToValue(v));
376
- cache.set(idx, obj);
377
- return obj;
378
- }
379
- const obj = {};
380
- cache.set(idx, obj);
381
- if (!k || !v)
382
- return obj;
383
- const keys = idxToArr(k);
384
- const values = idxToArr(v);
385
- Object.assign(obj, Object.fromEntries(mergeKeysValues(keys, values)));
386
- return obj;
387
- }
388
- function idxToArr(idx) {
389
- const element = data[idx];
390
- assert(isArrayElement(element));
391
- return toArr(idx, element);
392
- }
393
- function toArr(idx, element) {
394
- const placeHolder = [];
395
- const refs = element.slice(1);
396
- cache.set(idx, placeHolder);
397
- const arr = refs.map(idxToValue);
398
- // check if the array has been referenced by another object.
399
- if (!referenced.has(idx)) {
400
- // It has not, just replace the placeholder with the array.
401
- cache.set(idx, arr);
402
- return arr;
403
- }
404
- placeHolder.push(...arr);
405
- return placeHolder;
406
- }
407
- function handleSubStringElement(idx, refs) {
408
- const [_t, sIdx, len, offset = 0] = refs;
409
- const s = `${idxToValue(sIdx)}`.slice(offset, offset + len);
410
- cache.set(idx, s);
411
- return s;
412
- }
413
- function handleArrayElement(idx, element) {
414
- switch (element[0]) {
415
- case ElementType.Array: {
416
- break;
417
- }
418
- case ElementType.Object: {
419
- return toObj(idx, element);
420
- }
421
- case ElementType.String: {
422
- return toString(idx, element);
423
- }
424
- case ElementType.SubString: {
425
- return handleSubStringElement(idx, element);
426
- }
427
- case ElementType.Set: {
428
- return toSet(idx, element);
429
- }
430
- case ElementType.Map: {
431
- return toMap(idx, element);
432
- }
433
- case ElementType.RegExp: {
434
- return toRegExp(idx, element);
435
- }
436
- case ElementType.Date: {
437
- return toDate(idx, element);
438
- }
439
- case ElementType.BigInt: {
440
- return toBigInt(idx, element);
441
- }
442
- }
443
- return toArr(idx, element);
444
- }
445
- function idxToValue(idx) {
446
- if (!idx)
447
- return undefined;
448
- const found = cache.get(idx);
449
- if (found !== undefined) {
450
- if (typeof idx === 'number')
451
- referenced.add(idx);
452
- return found;
453
- }
454
- if (Array.isArray(idx)) {
455
- // it is a nested string;
456
- const parts = idx.map((i) => idxToValue(i));
457
- return joinToString(parts);
458
- }
459
- const element = data[idx];
460
- if (typeof element === 'object') {
461
- // eslint-disable-next-line unicorn/no-null
462
- if (element === null)
463
- return null;
464
- if (Array.isArray(element))
465
- return handleArrayElement(idx, element);
466
- return {};
467
- }
468
- return element;
469
- }
470
- return idxToValue(1);
471
- }
472
- function joinToString(parts) {
473
- return parts.map((a) => (Array.isArray(a) ? joinToString(a) : a)).join('');
474
- }
475
- function isArrayElement(value) {
476
- return Array.isArray(value) && value[0] === ElementType.Array;
477
- }
478
- function isObjectWrapper(value) {
479
- return (typeof value === 'object' &&
480
- value !== null &&
481
- typeof value.valueOf === 'function' &&
482
- value.valueOf() !== value);
483
- }
484
- class Trie {
485
- root = { d: undefined, c: new Map() };
486
- add(key, data) {
487
- let node = this.root;
488
- for (const k of key) {
489
- let c = node.c;
490
- if (!c) {
491
- node.c = c = new Map();
492
- }
493
- let n = c.get(k);
494
- if (!n) {
495
- c.set(k, (n = { d: data }));
496
- }
497
- node = n;
498
- }
499
- }
500
- find(key) {
501
- let node = this.root;
502
- let found = '';
503
- for (const k of key) {
504
- const c = node.c;
505
- if (!c) {
506
- break;
507
- }
508
- const n = c.get(k);
509
- if (!n) {
510
- break;
511
- }
512
- found += k;
513
- node = n;
514
- }
515
- return { data: node.d, found };
516
- }
517
- }
518
- export function parse(data) {
519
- return fromJSON(JSON.parse(data));
520
- }
521
- export function stringify(data) {
522
- return JSON.stringify(toJSON(data));
523
- }
524
- //# sourceMappingURL=dehydrate.mjs.map