22
33import { arrayOf , type } from 'arktype' ;
44import * as fs from 'node:fs/promises' ;
5+ import { ResultsTable } from './resultsTable.ts' ;
56
67// Define schema for benchmark results
78const ResultRecord = type ( {
@@ -24,118 +25,88 @@ function groupResultsByTest(results: typeof BenchmarkResults.infer) {
2425 return grouped ;
2526}
2627
27- function calculateTrendMessage (
28- prSize : number | undefined ,
29- targetSize : number | undefined ,
30- ) : string {
31- if ( prSize === undefined || targetSize === undefined ) {
32- return '' ;
33- }
34- if ( prSize === targetSize ) {
35- return '(➖)' ;
36- }
37- const diff = prSize - targetSize ;
38- const percent = ( ( diff / targetSize ) * 100 ) . toFixed ( 1 ) ;
39- if ( diff > 0 ) {
40- return `($\${\\color{red}+${ percent } \\\\%}$$)` ;
41- }
42- return `($\${\\color{green}${ percent } \\\\%}$$)` ;
43- }
44-
45- function prettifySize ( size : number | undefined ) {
46- if ( size === undefined ) {
47- return 'N/A' ;
48- }
49- const units = [ 'B' , 'kB' , 'MB' , 'GB' , 'TB' ] ;
50- let unitIndex = 0 ;
51- let sizeInUnits = size ;
52- while ( sizeInUnits > 1024 && unitIndex < units . length ) {
53- sizeInUnits /= 1024 ;
54- unitIndex += 1 ;
55- }
56- return `${
57- Number . isInteger ( sizeInUnits ) ? sizeInUnits : sizeInUnits . toFixed ( 2 )
58- } ${ units [ unitIndex ] } `;
59- }
60-
6128async function generateReport (
6229 prResults : typeof BenchmarkResults . infer ,
6330 targetResults : typeof BenchmarkResults . infer ,
6431) {
6532 const prGrouped = groupResultsByTest ( prResults ) ;
6633 const targetGrouped = groupResultsByTest ( targetResults ) ;
6734
68- // Get all unique bundlers from both branches
35+ // All unique bundlers from both branches
6936 const allBundlers = new Set ( [
7037 ...new Set ( prResults . map ( ( r ) => r . bundler ) ) ,
7138 ...new Set ( targetResults . map ( ( r ) => r . bundler ) ) ,
7239 ] ) ;
7340
74- // Get all unique tests from both branches
41+ // All unique tests from both branches
7542 const allTests = new Set ( [
7643 ...Object . keys ( prGrouped ) ,
7744 ...Object . keys ( targetGrouped ) ,
7845 ] ) ;
7946
80- let output = '\n\n' ;
47+ // Split tests into static and dynamic
48+ const staticTests = [ ...allTests ] . filter ( ( t ) => ! t . includes ( '_from_' ) )
49+ . sort ( ) ;
50+ const dynamicTests = [ ...allTests ] . filter ( ( t ) => t . includes ( '_from_' ) )
51+ . sort ( ) ;
8152
8253 // Summary statistics
83- let totalIncrease = 0 ,
84- totalDecrease = 0 ,
85- totalUnchanged = 0 ,
86- totalUnknown = 0 ;
54+ let totalDecreased = 0 ;
55+ let totalIncreased = 0 ;
56+ let totalUnchanged = 0 ;
57+ let totalUnknown = 0 ;
8758
8859 for ( const test of allTests ) {
8960 for ( const bundler of allBundlers ) {
9061 const prSize = prGrouped [ test ] ?. [ bundler ] ;
9162 const targetSize = targetGrouped [ test ] ?. [ bundler ] ;
9263
9364 if ( targetSize === undefined || prSize === undefined ) totalUnknown ++ ;
94- else if ( prSize > targetSize ) totalIncrease ++ ;
95- else if ( prSize < targetSize ) totalDecrease ++ ;
65+ else if ( prSize > targetSize ) totalIncreased ++ ;
66+ else if ( prSize < targetSize ) totalDecreased ++ ;
9667 else totalUnchanged ++ ;
9768 }
9869 }
9970
100- output += '## 📊 Bundle Size Comparison\n\n' ;
101- output += '## 📈 Summary\n\n' ;
102- output += `- 📈 **Increased**: ${ totalIncrease } bundles\n` ;
103- output += `- 📉 **Decreased**: ${ totalDecrease } bundles\n` ;
104- output += `- ➖ **Unchanged**: ${ totalUnchanged } bundles\n\n` ;
105- output += `- ❔ **Unknown**: ${ totalUnknown } bundles\n\n` ;
106-
107- // Main comparison table
108- output += '## 📋 Bundle Size Comparison\n\n' ;
109-
110- // Table header
111- output += '| Test' ;
112- for ( const bundler of allBundlers ) {
113- output += ` | ${ bundler } ` ;
114- }
115- output += ' |\n' ;
71+ // Comparison tables
72+ const staticTable = new ResultsTable ( allBundlers , 0.005 ) ;
73+ const dynamicTable = new ResultsTable ( allBundlers , 0.005 ) ;
74+ const allTable = new ResultsTable ( allBundlers , 0 ) ;
11675
117- // Table separator
118- output += '|---------' ;
119- for ( const _ of allBundlers ) {
120- output += '|---------' ;
121- }
122- output += ' |\n' ;
76+ staticTests . forEach ( ( test ) => {
77+ const prResults = prGrouped [ test ] ;
78+ const targetResults = targetGrouped [ test ] ;
79+ staticTable . addRow ( test , prResults , targetResults ) ;
80+ allTable . addRow ( test , prResults , targetResults ) ;
81+ } ) ;
12382
124- // Table rows
125- for ( const test of [ ...allTests ] . sort ( ) ) {
126- output += `| ${ test } ` ;
83+ dynamicTests . forEach ( ( test ) => {
84+ const prResults = prGrouped [ test ] ;
85+ const targetResults = targetGrouped [ test ] ;
86+ dynamicTable . addRow ( test , prResults , targetResults ) ;
87+ allTable . addRow ( test , prResults , targetResults ) ;
88+ } ) ;
12789
128- for ( const bundler of allBundlers ) {
129- const prSize = prGrouped [ test ] ?. [ bundler ] ;
130- const targetSize = targetGrouped [ test ] ?. [ bundler ] ;
90+ // Markdown generation
91+ let output = '' ;
13192
132- output += ` | ${ prettifySize ( prSize ) } ${
133- calculateTrendMessage ( prSize , targetSize )
134- } `;
135- }
136- output += ' |\n' ;
93+ output += '## 📊 Bundle Size Comparison\n\n' ;
94+ output += '| 🟢 Decreased | ➖ Unchanged | 🔴 Increased | ❔ Unknown |\n' ;
95+ output += '| :---: | :---: | :---: | :---: |\n' ;
96+ output +=
97+ `| **${ totalDecreased } ** | **${ totalUnchanged } ** | **${ totalIncreased } ** | **${ totalUnknown } ** |\n\n` ;
98+
99+ output += `## 👀 Notable results\n\n` ;
100+ output += `### Static test results:\n${ staticTable } \n\n` ;
101+ output += `### Dynamic test results:\n${ dynamicTable } \n\n` ;
102+
103+ output += `## 📋 All results\n\n` ;
104+ output += `${ allTable } \n\n` ;
105+
106+ if ( allBundlers . size === 1 ) {
107+ output +=
108+ `If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.\n` ;
137109 }
138- output += '\n' ;
139110
140111 return output ;
141112}
0 commit comments