Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
wisp.place
1import { gzipSync } from 'zlib';
2
3/**
4 * Determine if a file should be gzip compressed based on its MIME type and filename
5 */
6export function shouldCompressFile(mimeType: string, fileName?: string): boolean {
7 // Never compress _redirects file - it needs to be plain text for the hosting service
8 if (fileName && (fileName.endsWith('/_redirects') || fileName === '_redirects')) {
9 return false;
10 }
11
12 // Compress text-based files and uncompressed audio formats
13 const compressibleTypes = [
14 'text/html',
15 'text/css',
16 'text/javascript',
17 'application/javascript',
18 'application/json',
19 'image/svg+xml',
20 'text/xml',
21 'application/xml',
22 'text/plain',
23 'application/x-javascript',
24 // Uncompressed audio formats (WAV, AIFF, etc.)
25 'audio/wav',
26 'audio/wave',
27 'audio/x-wav',
28 'audio/aiff',
29 'audio/x-aiff'
30 ];
31
32 // Check if mime type starts with any compressible type
33 return compressibleTypes.some(type => mimeType.startsWith(type));
34}
35
36/**
37 * Determines if a MIME type should benefit from gzip compression.
38 * Returns true for text-based web assets (HTML, CSS, JS, JSON, XML, SVG).
39 * Returns false for already-compressed formats (images, video, audio, PDFs).
40 */
41export function shouldCompressMimeType(mimeType: string | undefined): boolean {
42 if (!mimeType) return false;
43
44 const mime = mimeType.toLowerCase();
45
46 // Text-based web assets and uncompressed audio that benefit from compression
47 const compressibleTypes = [
48 'text/html',
49 'text/css',
50 'text/javascript',
51 'application/javascript',
52 'application/x-javascript',
53 'text/xml',
54 'application/xml',
55 'application/json',
56 'text/plain',
57 'image/svg+xml',
58 // Uncompressed audio formats
59 'audio/wav',
60 'audio/wave',
61 'audio/x-wav',
62 'audio/aiff',
63 'audio/x-aiff',
64 ];
65
66 if (compressibleTypes.some(type => mime === type || mime.startsWith(type))) {
67 return true;
68 }
69
70 // Already-compressed formats that should NOT be double-compressed
71 const alreadyCompressedPrefixes = [
72 'video/',
73 'audio/',
74 'image/',
75 'application/pdf',
76 'application/zip',
77 'application/gzip',
78 ];
79
80 if (alreadyCompressedPrefixes.some(prefix => mime.startsWith(prefix))) {
81 return false;
82 }
83
84 // Default to not compressing for unknown types
85 return false;
86}
87
88/**
89 * Compress a file using gzip with deterministic output
90 */
91export function compressFile(content: Buffer): Buffer {
92 return gzipSync(content, {
93 level: 9
94 });
95}