feat(compression): Add cross-runtime response compression (Brotli/gzip), per-route decorators, and pre-compressed static file support
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user