feat(compression): Add cross-runtime response compression (Brotli/gzip), per-route decorators, and pre-compressed static file support

This commit is contained in:
2025-12-05 12:27:41 +00:00
parent cef6ce750e
commit 57d7fd6483
17 changed files with 1116 additions and 18 deletions

View File

@@ -31,6 +31,12 @@ SmartServe is a cross-platform HTTP server for Node.js, Deno, and Bun using:
- `ts/utils/utils.mime.ts` - MIME type detection
- `ts/utils/utils.etag.ts` - ETag generation
### Compression
- `ts/compression/compression.runtime.ts` - Cross-runtime compression (Node.js zlib, Web CompressionStream)
- `ts/compression/compression.middleware.ts` - Compression config and helpers
- `ts/utils/utils.encoding.ts` - Accept-Encoding parsing
- `ts/decorators/decorators.compress.ts` - @Compress and @NoCompress decorators
### Protocols
- `ts/protocols/webdav/webdav.handler.ts` - WebDAV RFC 4918 handler
- `ts/protocols/webdav/webdav.xml.ts` - XML generation (multistatus, lock responses)
@@ -149,9 +155,81 @@ const connections = server.getWebSocketConnections();
- Bun adapter stores peer ID/tags in `ws.data` for persistence across events
- Internal `_connectionCallbacks` passed to adapters for registry communication
## Compression
SmartServe supports automatic response compression with Brotli and gzip.
### Configuration
```typescript
const server = new SmartServe({
port: 3000,
// Simple: enable with defaults (compression is ON by default)
compression: true,
// Detailed configuration
compression: {
enabled: true,
algorithms: ['br', 'gzip'], // Brotli preferred, gzip fallback
threshold: 1024, // Don't compress < 1KB
level: 4, // Compression level
compressibleTypes: [ // Custom MIME types
'text/',
'application/json',
'application/javascript',
],
exclude: ['/api/stream/*'], // Skip certain paths
},
// Pre-compressed static files
static: {
root: './public',
precompressed: true, // Serve index.html.br, index.html.gz if available
},
});
```
### Per-Route Control
```typescript
@Controller('/api')
class ApiController {
@Get('/data')
getData() {
return { large: 'json' }; // Compressed by default
}
@Get('/stream')
@NoCompress() // Skip compression for SSE/streaming
getStream() {
return new Response(eventStream, {
headers: { 'Content-Type': 'text/event-stream' }
});
}
@Get('/heavy')
@Compress({ level: 11 }) // Force max brotli compression
getHeavy() {
return massiveData;
}
}
```
### Cross-Runtime Support
| Runtime | Brotli | gzip | Implementation |
|---------|--------|------|----------------|
| Node.js | ✅ | ✅ | Native zlib module |
| Deno | ⚠️ | ✅ | CompressionStream API |
| Bun | ⚠️ | ✅ | CompressionStream API |
Note: Brotli in Deno/Bun falls back to gzip if CompressionStream doesn't support it.
## TODO
- [x] WebDAV protocol support (PROPFIND, MKCOL, COPY, MOVE, LOCK, UNLOCK)
- [x] TypedRouter WebSocket integration
- [x] Brotli/gzip compression with per-route control
- [ ] HTTP/2 support investigation
- [ ] Performance benchmarks