smartarchive/ts/classes.ziptools.ts
2024-06-08 12:46:43 +02:00

75 lines
2.2 KiB
TypeScript

import type { SmartArchive } from './classes.smartarchive.js';
import * as plugins from './plugins.js';
class DecompressZipTransform extends plugins.smartstream.SmartDuplex<ArrayBufferLike> {
private streamtools: plugins.smartstream.IStreamTools;
private unzipper = new plugins.fflate.Unzip(async (fileArg) => {
let resultBuffer: Buffer;
fileArg.ondata = async (flateError, 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 {
constructor() {
}
public getCompressionStream() {
return new CompressZipTransform();
}
public getDecompressionStream() {
return new DecompressZipTransform();
}
}