import * as plugins from './plugins.js'; import type { TCompressionLevel } from './interfaces.js'; /** * Transform stream for GZIP compression using fflate */ export class GzipCompressionTransform extends plugins.stream.Transform { private gzip: plugins.fflate.Gzip; constructor(level: TCompressionLevel = 6) { super(); // Create a streaming Gzip compressor this.gzip = new plugins.fflate.Gzip({ level }, (chunk, final) => { this.push(Buffer.from(chunk)); if (final) { this.push(null); } }); } _transform( chunk: Buffer, encoding: BufferEncoding, callback: plugins.stream.TransformCallback ): void { try { this.gzip.push(chunk, false); callback(); } catch (err) { callback(err as Error); } } _flush(callback: plugins.stream.TransformCallback): void { try { this.gzip.push(new Uint8Array(0), true); callback(); } catch (err) { callback(err as Error); } } } /** * Transform stream for GZIP decompression using fflate */ export class GzipDecompressionTransform extends plugins.stream.Transform { private gunzip: plugins.fflate.Gunzip; constructor() { super(); // Create a streaming Gunzip decompressor this.gunzip = new plugins.fflate.Gunzip((chunk, final) => { this.push(Buffer.from(chunk)); if (final) { this.push(null); } }); } _transform( chunk: Buffer, encoding: BufferEncoding, callback: plugins.stream.TransformCallback ): void { try { this.gunzip.push(chunk, false); callback(); } catch (err) { callback(err as Error); } } _flush(callback: plugins.stream.TransformCallback): void { try { this.gunzip.push(new Uint8Array(0), true); callback(); } catch (err) { callback(err as Error); } } } /** * GZIP compression and decompression utilities */ export class GzipTools { /** * Get a streaming compression transform */ public getCompressionStream(level?: TCompressionLevel): plugins.stream.Transform { return new GzipCompressionTransform(level); } /** * Get a streaming decompression transform */ public getDecompressionStream(): plugins.stream.Transform { return new GzipDecompressionTransform(); } /** * Compress data synchronously */ public compressSync(data: Buffer, level?: TCompressionLevel): Buffer { const options = level !== undefined ? { level } : undefined; return Buffer.from(plugins.fflate.gzipSync(data, options)); } /** * Decompress data synchronously */ public decompressSync(data: Buffer): Buffer { return Buffer.from(plugins.fflate.gunzipSync(data)); } /** * Compress data asynchronously */ public async compress(data: Buffer, level?: TCompressionLevel): Promise { return new Promise((resolve, reject) => { const options = level !== undefined ? { level } : undefined; plugins.fflate.gzip(data, options as plugins.fflate.AsyncGzipOptions, (err, result) => { if (err) reject(err); else resolve(Buffer.from(result)); }); }); } /** * Decompress data asynchronously */ public async decompress(data: Buffer): Promise { return new Promise((resolve, reject) => { plugins.fflate.gunzip(data, (err, result) => { if (err) reject(err); else resolve(Buffer.from(result)); }); }); } }