fix(core): update
This commit is contained in:
		| @@ -3,6 +3,6 @@ | ||||
|  */ | ||||
| export const commitinfo = { | ||||
|   name: '@api.global/typedserver', | ||||
|   version: '3.0.13', | ||||
|   version: '3.0.14', | ||||
|   description: 'easy serving of static files' | ||||
| } | ||||
|   | ||||
| @@ -1,8 +1,14 @@ | ||||
| import * as plugins from '../typedserver.plugins.js'; | ||||
|  | ||||
| export type TCompressionMethod = 'gzip' | 'deflate' | 'br' | 'none'; | ||||
| export interface ICompressionResult { | ||||
|   result: Buffer; | ||||
|   compressionMethod: TCompressionMethod; | ||||
| } | ||||
|  | ||||
| export class Compressor { | ||||
|   private _cache: Map<string, Buffer>; | ||||
|   private MAX_CACHE_SIZE: number = 20 * 1024 * 1024; // 20 MB | ||||
|   private MAX_CACHE_SIZE: number = 100 * 1024 * 1024; // 100 MB | ||||
|  | ||||
|   constructor() { | ||||
|     this._cache = new Map<string, Buffer>(); | ||||
| @@ -46,10 +52,12 @@ export class Compressor { | ||||
|  | ||||
|       switch (method) { | ||||
|         case 'gzip': | ||||
|           plugins.zlib.gzip(content, callback); | ||||
|           plugins.zlib.gzip(content, { | ||||
|             level: 1, | ||||
|           },callback,); | ||||
|           break; | ||||
|         case 'br': | ||||
|           plugins.zlib.brotliCompress(content, callback); | ||||
|           plugins.zlib.brotliCompress(content, {}, callback); | ||||
|           break; | ||||
|         case 'deflate': | ||||
|           plugins.zlib.deflate(content, callback); | ||||
| @@ -61,15 +69,22 @@ export class Compressor { | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   public determineCompression(acceptEncoding: string | string[]) { | ||||
|   public determineCompression(acceptEncoding: string | string[], preferredCompressionMethodsArg: TCompressionMethod[] = []) { | ||||
|     // Ensure acceptEncoding is a single string | ||||
|     const encodingString = Array.isArray(acceptEncoding) | ||||
|       ? acceptEncoding.join(', ') | ||||
|       : acceptEncoding; | ||||
|  | ||||
|     let compressionMethod: 'gzip' | 'deflate' | 'br' | 'none' = 'none'; | ||||
|     let compressionMethod: TCompressionMethod = 'none'; | ||||
|  | ||||
|     // Check and prioritize compression methods | ||||
|     // Prioritize preferred compression methods if provided | ||||
|     for (const preferredMethod of preferredCompressionMethodsArg) { | ||||
|       if (new RegExp(`\\b${preferredMethod}\\b`).test(encodingString)) { | ||||
|         return preferredMethod; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     // Fallback to default prioritization if no preferred method matches | ||||
|     if (/\bbr\b/.test(encodingString)) { | ||||
|       compressionMethod = 'br'; | ||||
|     } else if (/\bgzip\b/.test(encodingString)) { | ||||
| @@ -81,9 +96,9 @@ export class Compressor { | ||||
|     return compressionMethod; | ||||
|   } | ||||
|  | ||||
|   public async maybeCompress(requestHeaders: plugins.http.IncomingHttpHeaders, content: Buffer) { | ||||
|   public async maybeCompress(requestHeaders: plugins.http.IncomingHttpHeaders, content: Buffer, preferredCompressionMethodsArg?: TCompressionMethod[]): Promise<ICompressionResult> { | ||||
|     const acceptEncoding = requestHeaders['accept-encoding']; | ||||
|     const compressionMethod = this.determineCompression(acceptEncoding); | ||||
|     const compressionMethod = this.determineCompression(acceptEncoding, preferredCompressionMethodsArg); | ||||
|     const result = await this.compressContent(content, compressionMethod); | ||||
|     return { | ||||
|       result, | ||||
| @@ -92,15 +107,21 @@ export class Compressor { | ||||
|   } | ||||
|  | ||||
|   public createCompressionStream(method: 'gzip' | 'deflate' | 'br' | 'none') { | ||||
|     let compressionStream: any; | ||||
|     switch (method) { | ||||
|       case 'gzip': | ||||
|         return plugins.zlib.createGzip(); | ||||
|         compressionStream = plugins.zlib.createGzip(); | ||||
|       case 'br': | ||||
|         return plugins.zlib.createBrotliCompress(); | ||||
|         compressionStream = plugins.zlib.createBrotliCompress({ | ||||
|           chunkSize: 16 * 1024, | ||||
|           params: { | ||||
|              | ||||
|           }, | ||||
|         }); | ||||
|       case 'deflate': | ||||
|         return plugins.zlib.createDeflate(); | ||||
|         compressionStream = plugins.zlib.createDeflate(); | ||||
|       default: | ||||
|         throw new Error('Invalid compression method'); | ||||
|         compressionStream = plugins.smartstream.createPassThrough(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,7 @@ import * as plugins from '../typedserver.plugins.js'; | ||||
| import * as interfaces from '../interfaces/index.js'; | ||||
|  | ||||
| import { Handler } from './classes.handler.js'; | ||||
| import { Compressor } from './classes.compressor.js'; | ||||
| import { Compressor, type TCompressionMethod, type ICompressionResult } from './classes.compressor.js'; | ||||
|  | ||||
| export class HandlerStatic extends Handler { | ||||
|   public compressor = new Compressor(); | ||||
| @@ -13,6 +13,8 @@ export class HandlerStatic extends Handler { | ||||
|       responseModifier?: interfaces.TResponseModifier; | ||||
|       headers?: { [key: string]: string }; | ||||
|       serveIndexHtmlDefault?: boolean; | ||||
|       enableCompression?: boolean; | ||||
|       preferredCompressionMethod?: 'gzip' | 'deflate' | 'br'; | ||||
|     } | ||||
|   ) { | ||||
|     super('GET', async (req, res) => { | ||||
| @@ -118,10 +120,16 @@ export class HandlerStatic extends Handler { | ||||
|       } | ||||
|  | ||||
|       // lets finally deal with compression | ||||
|       const compressionResult = await this.compressor.maybeCompress(requestHeaders, fileBuffer); | ||||
|       let compressionResult: ICompressionResult; | ||||
|  | ||||
|       if (optionsArg && optionsArg.enableCompression) { | ||||
|         compressionResult = await this.compressor.maybeCompress(requestHeaders, fileBuffer); | ||||
|       } | ||||
|  | ||||
|       res.status(200); | ||||
|       res.header('Content-Encoding', compressionResult.compressionMethod); | ||||
|       if (compressionResult?.compressionMethod) { | ||||
|         res.header('Content-Encoding', compressionResult.compressionMethod); | ||||
|       } | ||||
|       res.write(compressionResult.result); | ||||
|       res.end(); | ||||
|     }); | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import * as http from 'http'; | ||||
| import * as https from 'https'; | ||||
| import * as net from 'net'; | ||||
| import * as path from 'path'; | ||||
| import * as stream from 'stream'; | ||||
| import * as zlib from 'zlib'; | ||||
|  | ||||
| export { http, https, net, path, zlib }; | ||||
|   | ||||
| @@ -3,6 +3,6 @@ | ||||
|  */ | ||||
| export const commitinfo = { | ||||
|   name: '@api.global/typedserver', | ||||
|   version: '3.0.13', | ||||
|   version: '3.0.14', | ||||
|   description: 'easy serving of static files' | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user