2024-03-16 23:29:42 +00:00
|
|
|
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;
|
2024-06-08 08:30:03 +00:00
|
|
|
fileArg.ondata = async (flateError, dat, final) => {
|
2024-03-16 23:29:42 +00:00
|
|
|
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;
|
2024-03-16 23:35:17 +00:00
|
|
|
this.streamtools.push(streamFile);
|
2024-03-16 23:29:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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);
|
2024-03-16 23:42:19 +00:00
|
|
|
await this.streamtools.push(null);
|
2024-03-16 23:29:42 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
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 {
|
2024-06-08 10:46:43 +00:00
|
|
|
constructor() {
|
2024-03-16 23:29:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public getCompressionStream() {
|
|
|
|
return new CompressZipTransform();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getDecompressionStream() {
|
|
|
|
return new DecompressZipTransform();
|
|
|
|
}
|
|
|
|
}
|