Skip to content

Commit e95738e

Browse files
committed
Only find files once instead of per compressor
1 parent 8941c4e commit e95738e

File tree

3 files changed

+34
-36
lines changed

3 files changed

+34
-36
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"vitest": "3.2.4"
4848
},
4949
"engines": {
50-
"node": ">=22.15.0 <23.0.0 || >=23.8.0"
50+
"node": ">=22"
5151
},
5252
"packageManager": "pnpm@10.14.0-0+sha512.2cd47a0cbf5f1d1de7693a88307a0ede5be94e0d3b34853d800ee775efbea0650cb562b77605ec80bc8d925f5cd27c4dfe8bb04d3a0b76090784c664450d32d6"
5353
}

src/compress.ts

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ import type { AstroIntegrationLogger } from "astro";
1010

1111
export type { BrotliOptions, ZlibOptions, ZstdOptions };
1212

13-
interface CompressionOptions<O extends object> {
14-
dir: string;
15-
extensions: Array<string>;
13+
interface CompressionOptions {
14+
files: Array<string>;
1615
batchSize: number;
17-
enabled: boolean | O | undefined;
16+
enabled: boolean | undefined;
17+
options?: ZlibOptions | BrotliOptions | ZstdOptions | undefined;
1818
}
1919

20-
async function* walkDir(dir: string, extensions: Array<string>): AsyncGenerator<string> {
20+
export async function* walkDir(dir: string, extensions: Array<string>): AsyncGenerator<string> {
2121
const entries = await readdir(dir, { withFileTypes: true });
2222
for (const entry of entries) {
2323
const name = resolve(dir, entry.name);
@@ -33,31 +33,26 @@ const filterFile = (file: string, extensions: Array<string>): boolean => {
3333
return extensions.some((ext) => extname(file) === ext);
3434
};
3535

36-
const compress = async <T extends NodeJS.WritableStream, O extends object>(
36+
const compress = async <T extends NodeJS.WritableStream>(
3737
name: string,
3838
compressedFileNames: string,
39-
compressor: () => T,
39+
compressor: (options: ZlibOptions | BrotliOptions | ZstdOptions | undefined) => T,
4040
logger: AstroIntegrationLogger,
41-
{ dir, extensions, batchSize, enabled }: CompressionOptions<O>,
41+
{ files, batchSize, enabled, options }: CompressionOptions,
4242
): Promise<void> => {
43-
if (!enabled && typeof enabled !== "object") {
43+
if (!enabled) {
4444
logger.warn(`${name} compression disabled, skipping...`);
4545
return;
4646
}
4747

4848
const start = hrtime.bigint();
49-
const files = [];
50-
for await (const file of walkDir(dir, extensions)) {
51-
files.push(file);
52-
}
53-
5449
for (let i = 0; i < files.length; i += batchSize) {
5550
const batch = files.slice(i, i + batchSize);
5651
await Promise.all(
5752
batch.map(async (path) => {
5853
const source = createReadStream(path);
5954
const destination = createWriteStream(`${path}.${compressedFileNames}`);
60-
const comp = compressor();
55+
const comp = compressor(options);
6156
await stream.pipeline(source, comp, destination);
6257
}),
6358
);
@@ -68,50 +63,48 @@ const compress = async <T extends NodeJS.WritableStream, O extends object>(
6863
};
6964

7065
export const gzip = async (
71-
dir: string,
66+
files: Array<string>,
7267
logger: AstroIntegrationLogger,
73-
extensions: Array<string>,
7468
enabled?: boolean | ZlibOptions,
7569
batchSize = 10,
7670
): Promise<void> => {
77-
await compress("gzip", "gz", zlib.createGzip.bind({ level: 9 }), logger, {
78-
dir,
79-
extensions,
80-
enabled,
71+
await compress("gzip", "gz", zlib.createGzip, logger, {
72+
files,
73+
enabled: enabled === true || typeof enabled === "object",
74+
options: typeof enabled === "object" ? enabled : { level: zlib.constants.Z_BEST_COMPRESSION },
8175
batchSize,
8276
});
8377
};
8478

8579
export const brotli = async (
86-
dir: string,
80+
files: Array<string>,
8781
logger: AstroIntegrationLogger,
88-
extensions: Array<string>,
8982
enabled?: boolean | BrotliOptions,
9083
batchSize = 10,
9184
): Promise<void> => {
9285
await compress("brotli", "br", zlib.createBrotliCompress, logger, {
93-
dir,
94-
extensions,
95-
enabled,
86+
files,
87+
enabled: enabled === true,
88+
options: typeof enabled === "object" ? enabled : undefined,
9689
batchSize,
9790
});
9891
};
9992

10093
export const zstd = async (
101-
dir: string,
94+
files: Array<string>,
10295
logger: AstroIntegrationLogger,
103-
extensions: Array<string>,
10496
enabled?: boolean | ZstdOptions,
10597
batchSize = 10,
10698
): Promise<void> => {
10799
if (typeof zlib.createZstdCompress !== "function") {
108100
logger.warn("zstd compression is not supported in this Node.js version.");
109101
return;
110102
}
103+
111104
await compress("zstd", "zst", zlib.createZstdCompress, logger, {
112-
dir,
113-
extensions,
114-
enabled,
105+
files,
106+
enabled: enabled === true,
107+
options: typeof enabled === "object" ? enabled : undefined,
115108
batchSize,
116109
});
117110
};

src/index.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { fileURLToPath } from "node:url";
22

33
import type { AstroIntegration } from "astro";
44
import type { BrotliOptions, ZlibOptions, ZstdOptions } from "./compress.js";
5-
import { brotli, gzip, zstd } from "./compress.js";
5+
import { brotli, gzip, walkDir, zstd } from "./compress.js";
66

77
const defaultFileExtensions = [".css", ".js", ".html", ".xml", ".cjs", ".mjs", ".svg", ".txt"];
88

@@ -35,10 +35,15 @@ export default function (opts: Options = defaultOptions): AstroIntegration {
3535
hooks: {
3636
"astro:build:done": async ({ dir, logger }) => {
3737
const path = fileURLToPath(dir);
38+
const files = [];
39+
for await (const file of walkDir(path, options.fileExtensions)) {
40+
files.push(file);
41+
}
42+
3843
await Promise.allSettled([
39-
gzip(path, logger, options.fileExtensions, options.gzip, options.batchSize),
40-
brotli(path, logger, options.fileExtensions, options.brotli, options.batchSize),
41-
zstd(path, logger, options.fileExtensions, options.zstd, options.batchSize),
44+
gzip(files, logger, options.gzip, options.batchSize),
45+
brotli(files, logger, options.brotli, options.batchSize),
46+
zstd(files, logger, options.zstd, options.batchSize),
4247
]);
4348
logger.info("Compression finished\n");
4449
},

0 commit comments

Comments
 (0)