Skip to content

Commit 21627cb

Browse files
committed
fix: move code
1 parent 0c9a6a6 commit 21627cb

File tree

14 files changed

+1579
-1062
lines changed

14 files changed

+1579
-1062
lines changed

packages/plugin-bundle-stats/code-pushup.large-angular.config.ts

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
import bundleStatsPlugin, { type GroupingRule } from './src';
22

33
const nodeModulesGroup: GroupingRule[] = [
4-
// General node_modules group (processed second due to reverse order)
5-
{ patterns: ['**/node_modules/**', '**/node_modules/@*/**/*'], icon: '📦' },
6-
// Angular-specific group (processed first due to reverse order, takes precedence)
4+
// General node_modules group (processed third due to reverse order)
5+
{
6+
patterns: ['**/node_modules/**', '**/node_modules/@*/**/*'],
7+
icon: '📦',
8+
maxDepth: 2,
9+
},
10+
// Non-scoped Angular packages (processed second due to reverse order)
711
{
812
patterns: [
9-
'**/node_modules/@angular/**',
1013
'**/node_modules/ngx-*/**',
11-
'**/node_modules/@ngrx/**',
1214
'**/node_modules/ng-*/**',
1315
'**/node_modules/*angular*',
1416
],
1517
icon: '🅰️',
16-
maxDepth: 3,
18+
maxDepth: 2, // Gets ngx-toastr, ng-bootstrap, etc.
1719
},
18-
];
19-
20-
const generalGroups: GroupingRule[] = [
20+
// Scoped Angular packages (processed first due to reverse order, takes precedence)
2121
{
22-
// auto derived title from result
23-
patterns: ['**/packages/**'],
24-
icon: '📁',
22+
patterns: ['**/node_modules/@angular/**', '**/node_modules/@ngrx/**'],
23+
icon: '🅰️',
24+
maxDepth: 3, // Gets @angular/router, @angular/common, @ngrx/store, etc.
2525
},
2626
];
2727

@@ -243,19 +243,9 @@ const config = {
243243
blacklist: [],
244244
},
245245
},
246-
insights: [
247-
...productGroups,
248-
...badGroups,
249-
...generalGroups,
250-
...nodeModulesGroup,
251-
],
246+
insights: [...productGroups, ...badGroups, ...nodeModulesGroup],
252247
artefactTree: {
253-
groups: [
254-
...productGroups,
255-
...badGroups,
256-
...generalGroups,
257-
...nodeModulesGroup,
258-
],
248+
groups: [...productGroups, ...badGroups, ...nodeModulesGroup],
259249
pruning: {
260250
maxDepth: 5,
261251
minSize: 1_000, // Reduced from 50_000 to show smaller files (1KB threshold)
@@ -298,13 +288,6 @@ const config = {
298288
},
299289
artefactTree: {
300290
groups: [
301-
{
302-
title: 'Styles',
303-
patterns: ['**/styles-*.css'],
304-
icon: '🎨', // Add icon for styles group
305-
maxDepth: 2, // Enable intermediate folder creation for nested sources
306-
},
307-
...generalGroups,
308291
...nodeModulesGroup,
309292
...badGroups,
310293
...productGroups, // Process product groups first for better specificity (last in array = first processed)

packages/plugin-bundle-stats/src/lib/runner/audits/details/table.ts

Lines changed: 67 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -3,117 +3,36 @@ import { formatBytes } from '@code-pushup/utils';
33
import type { GroupingRule } from '../../types.js';
44
import type { UnifiedStats } from '../../unify/unified-stats.types.js';
55
import {
6-
findMatchingRule,
7-
generateGroupKey,
8-
matchesAnyPattern,
9-
} from './utils/match-pattern.js';
10-
import { type GroupData, createGroupManager } from './utils/table-utils.js';
6+
type GroupData,
7+
createGroupManager,
8+
findOrCreateGroupFromRule,
9+
processForTable,
10+
} from './utils/grouping-engine.js';
1111

1212
const DEFAULT_GROUP_NAME = 'Group';
1313
const REST_GROUP_NAME = 'Rest';
1414

1515
export type InsightsConfig = GroupingRule[];
1616

17-
const globalRuleMatchCache = new Map<
18-
string,
19-
{ ruleIndex: number; groupKey: string } | null
20-
>();
21-
22-
interface CompiledRule {
23-
rule: GroupingRule;
24-
matcher: (path: string) => boolean;
25-
groupKeyCache: Map<string, string>;
26-
ruleIndex: number;
27-
}
28-
29-
export function clearRuleMatchCache(): void {
30-
globalRuleMatchCache.clear();
31-
}
32-
33-
function compileGroupingRules(rules: GroupingRule[]): CompiledRule[] {
34-
return rules.map((rule, ruleIndex) => {
35-
const { patterns } = rule;
36-
37-
const matcher = (filePath: string): boolean => {
38-
return matchesAnyPattern(filePath, patterns, {
39-
matchBase: true,
40-
normalizeRelativePaths: true,
41-
});
42-
};
43-
44-
return {
45-
rule,
46-
matcher,
47-
groupKeyCache: new Map<string, string>(),
48-
ruleIndex,
49-
};
50-
});
51-
}
52-
53-
function findMatchingCompiledRule(
54-
filePath: string,
55-
compiledRules: CompiledRule[],
56-
): CompiledRule | null {
57-
const cached = globalRuleMatchCache.get(filePath);
58-
if (cached !== undefined) {
59-
return cached ? compiledRules[cached.ruleIndex] || null : null;
60-
}
61-
62-
// Process rules in reverse order to match tree logic precedence
63-
// More specific rules (later in array) take precedence over general ones
64-
for (let i = compiledRules.length - 1; i >= 0; i--) {
65-
const compiledRule = compiledRules[i];
66-
if (compiledRule && compiledRule.matcher(filePath)) {
67-
globalRuleMatchCache.set(filePath, {
68-
ruleIndex: compiledRule.ruleIndex,
69-
groupKey: '',
70-
});
71-
return compiledRule;
72-
}
73-
}
74-
75-
globalRuleMatchCache.set(filePath, null);
76-
return null;
77-
}
78-
79-
function getCachedGroupKey(
80-
filePath: string,
81-
compiledRule: CompiledRule,
82-
preferRuleTitle: boolean = false,
83-
): string {
84-
const globalCached = globalRuleMatchCache.get(filePath);
85-
if (globalCached && globalCached.groupKey) {
86-
return globalCached.groupKey;
87-
}
88-
89-
let groupKey = compiledRule.groupKeyCache.get(filePath);
90-
if (!groupKey) {
91-
groupKey = generateGroupKey(filePath, compiledRule.rule, preferRuleTitle);
92-
compiledRule.groupKeyCache.set(filePath, groupKey);
93-
94-
if (globalCached) {
95-
globalCached.groupKey = groupKey;
96-
}
97-
}
98-
return groupKey;
99-
}
100-
101-
export function formatEntryPoint(title: string, icon?: string): string {
102-
return icon ? `${icon} ${title}` : title;
103-
}
104-
17+
/**
18+
* Simplified aggregation using direct functions. Simple table grouping without engine complexity.
19+
*/
10520
export function aggregateAndSortGroups(
10621
statsSlice: UnifiedStats,
10722
insights: InsightsConfig,
108-
): { groups: GroupData[]; restGroup: Omit<GroupData, 'icon'> } {
23+
): { groups: GroupData[]; restGroup: { title: string; bytes: number } } {
10924
const groupingRules = insights || [];
110-
111-
const compiledRules = compileGroupingRules(groupingRules);
11225
const groupManager = createGroupManager<GroupData>();
11326

27+
// Pre-create groups
11428
for (const rule of groupingRules) {
11529
const effectiveTitle = rule.title || DEFAULT_GROUP_NAME;
116-
groupManager.findOrCreateGroup(effectiveTitle, rule, effectiveTitle);
30+
findOrCreateGroupFromRule(
31+
groupManager,
32+
effectiveTitle,
33+
rule,
34+
effectiveTitle,
35+
);
11736
}
11837

11938
const remainingBytesInChunks: Record<string, number> = {};
@@ -123,6 +42,7 @@ export function aggregateAndSortGroups(
12342
remainingBytesInChunks[key] = bytes;
12443
}
12544

45+
// Process inputs with simple functions
12646
for (const [outputKey, output] of outputEntries) {
12747
if (!output.inputs) {
12848
continue;
@@ -134,109 +54,106 @@ export function aggregateAndSortGroups(
13454
continue;
13555
}
13656

137-
const matchingCompiledRule = findMatchingCompiledRule(
57+
// Use simple function for rule matching and key generation
58+
const { rule, groupKey } = processForTable(
13859
inputPath,
139-
compiledRules,
60+
groupingRules,
61+
true,
14062
);
141-
if (matchingCompiledRule) {
142-
// For input files, prefer rule title to support explicit titles like "Theme Park Package"
143-
const groupKey = getCachedGroupKey(
144-
inputPath,
145-
matchingCompiledRule,
146-
true,
147-
);
148-
const group = groupManager.findOrCreateGroup(
63+
if (rule && groupKey) {
64+
const group = findOrCreateGroupFromRule(
65+
groupManager,
14966
groupKey,
150-
matchingCompiledRule.rule,
151-
matchingCompiledRule.rule.title || groupKey,
67+
rule,
68+
rule.title || groupKey,
15269
);
15370

154-
group.totalBytes += input.bytes;
71+
group.bytes += input.bytes;
15572
remainingBytesInChunks[outputKey] =
15673
(remainingBytesInChunks[outputKey] || 0) - input.bytes;
15774
}
15875
}
15976
}
16077

78+
// Process outputs with simple functions
16179
for (const [outputKey] of outputEntries) {
16280
const remainingBytes = remainingBytesInChunks[outputKey];
16381
if (remainingBytes == null || remainingBytes <= 0) {
16482
continue;
16583
}
16684

167-
const matchingCompiledRule = findMatchingCompiledRule(
168-
outputKey,
169-
compiledRules,
170-
);
171-
if (matchingCompiledRule) {
172-
const groupKey = getCachedGroupKey(
173-
outputKey,
174-
matchingCompiledRule,
175-
false,
176-
);
177-
const group = groupManager.findOrCreateGroup(
85+
const { rule, groupKey } = processForTable(outputKey, groupingRules, true);
86+
if (rule && groupKey) {
87+
const group = findOrCreateGroupFromRule(
88+
groupManager,
17889
groupKey,
179-
matchingCompiledRule.rule,
180-
matchingCompiledRule.rule.title || groupKey,
90+
rule,
91+
rule.title || groupKey,
18192
);
18293

183-
group.totalBytes += remainingBytes;
94+
group.bytes += remainingBytes;
18495
remainingBytesInChunks[outputKey] = 0;
18596
}
18697
}
18798

18899
const restGroup = {
189-
totalBytes: Object.values(remainingBytesInChunks).reduce(
100+
bytes: Object.values(remainingBytesInChunks).reduce(
190101
(acc, bytes) => acc + bytes,
191102
0,
192103
),
193104
title: REST_GROUP_NAME,
194105
};
195106

196107
const groups = groupManager.getGroupsWithData();
197-
groups.sort((a, b) => b.totalBytes - a.totalBytes);
108+
groups.sort((a, b) => b.bytes - a.bytes);
198109

199110
return { groups, restGroup };
200111
}
201112

202-
export function formatGroupsAsTable({
203-
groups,
204-
restGroup,
205-
}: {
206-
groups: GroupData[];
207-
restGroup: Omit<GroupData, 'icon'>;
208-
}): Table {
209-
const tableRows: string[][] = [];
210-
for (const group of groups) {
211-
const entryPoint = formatEntryPoint(group.title, group.icon);
212-
const size = formatBytes(group.totalBytes);
113+
/**
114+
* Transforms aggregated group data into table format. Creates table rows from group statistics.
115+
*/
116+
export function createTable(
117+
groups: GroupData[],
118+
restGroup: { title: string; bytes: number },
119+
): Table {
120+
const rows: { group: string; modules: string; size: string }[] = [];
213121

214-
tableRows.push([entryPoint, size]);
122+
for (const group of groups) {
123+
if (group.bytes > 0) {
124+
rows.push({
125+
group: `${group.icon || '📁'} ${group.title}`,
126+
modules: group.sources.toString(),
127+
size: formatBytes(group.bytes),
128+
});
129+
}
215130
}
216131

217-
if (restGroup.totalBytes > 0) {
218-
const entryPoint = formatEntryPoint(restGroup.title);
219-
const size = formatBytes(restGroup.totalBytes);
220-
221-
tableRows.push([entryPoint, size]);
132+
if (restGroup.bytes > 0) {
133+
rows.push({
134+
group: '📄 Rest',
135+
modules: '-',
136+
size: formatBytes(restGroup.bytes),
137+
});
222138
}
223139

224140
return {
225141
columns: [
226142
{ key: 'group', label: 'Group', align: 'left' },
227-
{ key: 'size', label: 'Size', align: 'center' },
143+
{ key: 'modules', label: 'Modules', align: 'right' },
144+
{ key: 'size', label: 'Size', align: 'right' },
228145
],
229-
rows: tableRows.map(([group = '', size = '']) => ({
230-
group,
231-
size,
232-
})),
146+
rows,
233147
};
234148
}
235149

150+
/**
151+
* Creates insights table from stats and grouping rules. Combines aggregation and table formatting.
152+
*/
236153
export function createInsightsTable(
237154
statsSlice: UnifiedStats,
238-
insights: GroupingRule[],
155+
insights: InsightsConfig,
239156
): Table {
240157
const { groups, restGroup } = aggregateAndSortGroups(statsSlice, insights);
241-
return formatGroupsAsTable({ groups, restGroup });
158+
return createTable(groups, restGroup);
242159
}

0 commit comments

Comments
 (0)