1
+ // @ts -check
1
2
import path from 'node:path'
2
3
import { markdownTable } from 'markdown-table'
3
4
import prettyBytes from 'pretty-bytes'
4
5
import { readdir } from 'node:fs/promises'
5
6
import { existsSync } from 'node:fs'
6
7
7
- interface SizeResult {
8
- size : number
9
- gzip : number
10
- brotli : number
11
- }
8
+ /**
9
+ * @typedef {Object } SizeResult
10
+ * @property {number } size
11
+ * @property {number } gzip
12
+ * @property {number } brotli
13
+ */
12
14
13
- interface BundleResult extends SizeResult {
14
- file : string
15
- }
15
+ /**
16
+ * @typedef { SizeResult & { file: string } } BundleResult
17
+ */
16
18
17
- type UsageResult = Record < string , SizeResult & { name : string } >
19
+ /**
20
+ * @typedef {Record<string, SizeResult & { name: string }> } UsageResult
21
+ */
18
22
19
23
const currDir = path . resolve ( 'temp/size' )
20
24
const prevDir = path . resolve ( 'temp/size-prev' )
@@ -23,53 +27,60 @@ const sizeHeaders = ['Size', 'Gzip', 'Brotli']
23
27
24
28
run ( )
25
29
30
+ /**
31
+ * Runs the main process of rendering file and usage data
32
+ */
26
33
async function run ( ) {
27
34
await renderFiles ( )
28
35
await renderUsages ( )
29
36
30
37
process . stdout . write ( output )
31
38
}
32
39
40
+ /**
41
+ * Renders file sizes and diffs between current and previous versions
42
+ */
33
43
async function renderFiles ( ) {
34
- const filterFiles = ( files : string [ ] ) =>
44
+ const filterFiles = files =>
35
45
files . filter ( file => file [ 0 ] !== '_' && ! file . endsWith ( '.txt' ) )
36
46
37
47
const curr = filterFiles ( await readdir ( currDir ) )
38
48
const prev = existsSync ( prevDir ) ? filterFiles ( await readdir ( prevDir ) ) : [ ]
39
49
const fileList = new Set ( [ ...curr , ...prev ] )
40
50
41
- const rows : string [ ] [ ] = [ ]
51
+ const rows = [ ]
42
52
for ( const file of fileList ) {
43
53
const currPath = path . resolve ( currDir , file )
44
54
const prevPath = path . resolve ( prevDir , file )
45
55
46
- const curr = await importJSON < BundleResult > ( currPath )
47
- const prev = await importJSON < BundleResult > ( prevPath )
56
+ const curr = await importJSON ( currPath )
57
+ const prev = await importJSON ( prevPath )
48
58
const fileName = curr ?. file || prev ?. file || ''
49
59
50
60
if ( ! curr ) {
51
61
rows . push ( [ `~~${ fileName } ~~` ] )
52
- } else
62
+ } else {
53
63
rows . push ( [
54
64
fileName ,
55
65
`${ prettyBytes ( curr . size ) } ${ getDiff ( curr . size , prev ?. size ) } ` ,
56
66
`${ prettyBytes ( curr . gzip ) } ${ getDiff ( curr . gzip , prev ?. gzip ) } ` ,
57
67
`${ prettyBytes ( curr . brotli ) } ${ getDiff ( curr . brotli , prev ?. brotli ) } ` ,
58
68
] )
69
+ }
59
70
}
60
71
61
72
output += '### Bundles\n\n'
62
73
output += markdownTable ( [ [ 'File' , ...sizeHeaders ] , ...rows ] )
63
74
output += '\n\n'
64
75
}
65
76
77
+ /**
78
+ * Renders usage data comparing current and previous usage results
79
+ */
66
80
async function renderUsages ( ) {
67
- const curr = ( await importJSON < UsageResult > (
68
- path . resolve ( currDir , '_usages.json' ) ,
69
- ) ) !
70
- const prev = await importJSON < UsageResult > (
71
- path . resolve ( prevDir , '_usages.json' ) ,
72
- )
81
+ const curr = await importJSON ( path . resolve ( currDir , '_usages.json' ) )
82
+ const prev = await importJSON ( path . resolve ( prevDir , '_usages.json' ) )
83
+
73
84
output += '\n### Usages\n\n'
74
85
75
86
const data = Object . values ( curr )
@@ -86,17 +97,31 @@ async function renderUsages() {
86
97
`${ prettyBytes ( usage . brotli ) } ${ diffBrotli } ` ,
87
98
]
88
99
} )
89
- . filter ( ( usage ) : usage is string [ ] => ! ! usage )
100
+ . filter ( usage => ! ! usage )
90
101
91
102
output += `${ markdownTable ( [ [ 'Name' , ...sizeHeaders ] , ...data ] ) } \n\n`
92
103
}
93
104
94
- async function importJSON < T > ( path : string ) : Promise < T | undefined > {
95
- if ( ! existsSync ( path ) ) return undefined
96
- return ( await import ( path , { assert : { type : 'json' } } ) ) . default
105
+ /**
106
+ * Imports JSON data from a specified path
107
+ *
108
+ * @template T
109
+ * @param {string } filePath - Path to the JSON file
110
+ * @returns {Promise<T | undefined> } The JSON content or undefined if the file does not exist
111
+ */
112
+ async function importJSON ( filePath ) {
113
+ if ( ! existsSync ( filePath ) ) return undefined
114
+ return ( await import ( filePath , { assert : { type : 'json' } } ) ) . default
97
115
}
98
116
99
- function getDiff ( curr : number , prev ?: number ) {
117
+ /**
118
+ * Calculates the difference between the current and previous sizes
119
+ *
120
+ * @param {number } curr - The current size
121
+ * @param {number } [prev] - The previous size
122
+ * @returns {string } The difference in pretty format
123
+ */
124
+ function getDiff ( curr , prev ) {
100
125
if ( prev === undefined ) return ''
101
126
const diff = curr - prev
102
127
if ( diff === 0 ) return ''
0 commit comments