• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

streetsidesoftware / cspell / 23483618641

24 Mar 2026 09:59AM UTC coverage: 93.06% (+0.2%) from 92.904%
23483618641

push

github

web-flow
feat: make flatpack diff friendly (#8680)

Signed-off-by: Jason Dent <Jason3S@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

9631 of 11447 branches covered (84.14%)

1340 of 1373 new or added lines in 18 files covered. (97.6%)

9 existing lines in 3 files now uncovered.

19161 of 20590 relevant lines covered (93.06%)

29922.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.12
/packages/flatpack-json/src/optimizeFlatpacked.mts
1
import assert from 'node:assert';
2

3
import { getIndexesReferencedByElement } from './flatpacked.mjs';
4
import { StringTableBuilder } from './stringTable.mjs';
5
import type { ArrayBasedElements, Flatpacked, FlattenedElement, StringTableElement } from './types.mjs';
6
import { ElementType, supportedHeaders } from './types.mjs';
7

8
export function optimizeFlatpacked(data: Flatpacked): Flatpacked {
9
    const [header, maybeStringTable] = data;
67✔
10

11
    if (data[1] === undefined || data[2] === undefined) {
67✔
12
        return data;
10✔
13
    }
14

15
    if (!supportedHeaders.has(header)) {
57!
16
        throw new Error('Invalid header');
×
17
    }
18

19
    const stringTable =
20
        maybeStringTable && Array.isArray(maybeStringTable) && maybeStringTable[0] === ElementType.StringTable
57✔
21
            ? (maybeStringTable as StringTableElement)
22
            : undefined;
23

24
    const startIndex = stringTable ? 2 : 1;
57✔
25

26
    const elements = data.slice(startIndex);
57✔
27

28
    const elementRefs = elements.map((element, index) => ({
15,078✔
29
        origIndex: index + startIndex,
30
        refCount: 0,
31
        index: 0,
32
        element,
33
    }));
34
    const indexToRefElement = new Map<number, RefElement>(
57✔
35
        elementRefs.map((refElement) => [refElement.origIndex, refElement]),
15,078✔
36
    );
37

38
    const stringTableBuilder = new StringTableBuilder(stringTable);
57✔
39

40
    for (const refElement of elementRefs) {
57✔
41
        const indexes = getIndexesReferencedByElement(refElement.element);
15,078✔
42
        for (const index of indexes) {
15,078✔
43
            if (index < 0) {
101,474✔
44
                stringTableBuilder.addRef(-index);
69,109✔
45
                continue;
69,109✔
46
            }
47
            if (!index) {
32,365✔
48
                continue;
1,218✔
49
            }
50
            const ref = indexToRefElement.get(index);
31,147✔
51
            assert(ref, `Invalid reference index: ${index}`);
31,147✔
52
            ref.refCount++;
31,147✔
53
        }
54
    }
55

56
    const sortedRefElements = elementRefs.sort((a, b) => b.refCount - a.refCount || a.origIndex - b.origIndex);
35,258✔
57

58
    const indexMap = new Map<number, number>([
57✔
59
        [0, 0],
60
        [1, 1],
61
    ]);
62

63
    if (stringTable) {
57✔
64
        indexMap.set(2, 2);
37✔
65
    }
66

67
    for (const refElement of sortedRefElements) {
57✔
68
        const idx = indexMap.get(refElement.origIndex) ?? indexMap.size;
15,078✔
69
        refElement.index = idx;
15,078✔
70
        indexMap.set(refElement.origIndex, idx);
15,078✔
71
    }
72

73
    for (const [oldStrIndex, newStrIndex] of stringTableBuilder.sortEntriesByRefCount()) {
57✔
74
        if (!oldStrIndex || !newStrIndex) {
19,817✔
75
            continue;
57✔
76
        }
77
        indexMap.set(-oldStrIndex, -newStrIndex);
19,760✔
78
    }
79

80
    const stringTableElements = stringTable ? [stringTableBuilder.build()] : [];
57✔
81

82
    const result: Flatpacked = [header, ...stringTableElements];
57✔
83

84
    for (const refElement of sortedRefElements) {
57✔
85
        const element = patchIndexes(refElement.element, indexMap);
15,078✔
86
        result[refElement.index] = element;
15,078✔
87
    }
88

89
    return result;
57✔
90
}
91

92
function patchIndexes(elem: FlattenedElement, indexMap: Map<number, number>): FlattenedElement {
93
    function mapIndex(index: number): number {
94
        const v = indexMap.get(index);
101,478✔
95
        if (v === undefined && index < 0) return index;
101,478!
96
        assert(v !== undefined, `Invalid index: ${index}`);
101,478✔
97
        return v;
101,478✔
98
    }
99

100
    function mapIndexes(indexes: number[]): number[] {
101
        return indexes.map(mapIndex);
10,476✔
102
    }
103

104
    function handleArrayElement(element: ArrayBasedElements): FlattenedElement {
105
        switch (element[0]) {
14,944!
106
            case ElementType.Array: {
107
                return [element[0], ...mapIndexes(element.slice(1))];
10,472✔
108
            }
109
            case ElementType.Object: {
110
                return [element[0], mapIndex(element[1]), mapIndex(element[2])];
4,426✔
111
            }
112
            case ElementType.String: {
113
                return [element[0], ...mapIndexes(element.slice(1))];
4✔
114
            }
115
            case ElementType.SubString: {
UNCOV
116
                return element[3] !== undefined
×
117
                    ? [element[0], mapIndex(element[1]), element[2], element[3]]
118
                    : [element[0], mapIndex(element[1]), element[2]];
119
            }
120
            case ElementType.Set: {
121
                return [element[0], mapIndex(element[1])];
9✔
122
            }
123
            case ElementType.Map: {
124
                return [element[0], mapIndex(element[1]), mapIndex(element[2])];
5✔
125
            }
126
            case ElementType.RegExp: {
127
                return [element[0], mapIndex(element[1]), mapIndex(element[2])];
10✔
128
            }
129
            case ElementType.Date: {
130
                return element;
4✔
131
            }
132
            case ElementType.BigInt: {
133
                return [element[0], mapIndex(element[1])];
14✔
134
            }
135
        }
NEW
136
        if (!element.length) return [];
×
UNCOV
137
        assert(false, 'Invalid element type');
×
138
    }
139

140
    if (Array.isArray(elem)) {
15,078✔
141
        return handleArrayElement(elem as ArrayBasedElements);
14,944✔
142
    }
143

144
    if (typeof elem === 'string') {
134✔
145
        return elem;
68✔
146
    }
147

148
    if (typeof elem === 'number') {
66✔
149
        return elem;
54✔
150
    }
151

152
    if (typeof elem === 'object') {
12✔
153
        return elem;
8✔
154
    }
155

156
    assert(typeof elem === 'boolean', `Expected boolean, got ${typeof elem}`);
4✔
157
    return elem;
4✔
158
}
159

160
interface RefElement {
161
    origIndex: number;
162
    refCount: number;
163
    index: number;
164
    element: FlattenedElement;
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc