import type { SmartArchive } from './classes.smartarchive.js'; import * as plugins from './plugins.js'; class DecompressZipTransform extends plugins.smartstream.SmartDuplex { private streamtools: plugins.smartstream.IStreamTools; private unzipper = new plugins.fflate.Unzip(async (fileArg) => { let resultBuffer: Buffer; fileArg.ondata = async (dataArg, dat, final) => { resultBuffer? resultBuffer = Buffer.concat([resultBuffer, Buffer.from(dat)]) : resultBuffer = Buffer.from(dat); if (final) { const streamFile = plugins.smartfile.StreamFile.fromBuffer(resultBuffer); streamFile.relativeFilePath = fileArg.name; this.streamtools.push(streamFile); } } fileArg.start(); }); constructor() { super({ objectMode: true, writeFunction: async (chunkArg: Buffer, streamtoolsArg) => { this.streamtools? null : this.streamtools = streamtoolsArg; this.unzipper.push(chunkArg, false); }, finalFunction: async () => { this.unzipper.push(Buffer.from(''), true); await plugins.smartdelay.delayFor(0); await this.streamtools.push(null); } }); this.unzipper.register(plugins.fflate.UnzipInflate); } } // This class wraps fflate's zip in a Node.js Transform stream for compression export class CompressZipTransform extends plugins.stream.Transform { files: { [fileName: string]: Uint8Array }; constructor() { super(); this.files = {}; } _transform(chunk: Buffer, encoding: BufferEncoding, callback: plugins.stream.TransformCallback) { // Simple example: storing chunks in memory before finalizing ZIP in _flush this.files['file.txt'] = new Uint8Array(chunk); callback(); } _flush(callback: plugins.stream.TransformCallback) { plugins.fflate.zip(this.files, (err, zipped) => { if (err) { callback(err); } else { this.push(Buffer.from(zipped)); callback(); } }); } } export class ZipTools { smartArchiveRef: SmartArchive; constructor(smartArchiveRefArg: SmartArchive) { this.smartArchiveRef = smartArchiveRefArg; } public getCompressionStream() { return new CompressZipTransform(); } public getDecompressionStream() { return new DecompressZipTransform(); } }