Skip to content

Commit

Permalink
Refactor: cleanup zip writing code (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmercm committed Oct 8, 2022
1 parent 1331c25 commit a5a3a1e
Showing 1 changed file with 29 additions and 39 deletions.
68 changes: 29 additions & 39 deletions src/types/archives/zip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,52 +128,42 @@ export default class Zip extends Archive {
// overwrite an input zip file
const tempZipFile = fsPoly.mktempSync(this.getFilePath());
const writeStream = fs.createWriteStream(tempZipFile);
zipFile.outputStream.pipe(writeStream);

// Promise that resolves when we're done writing the zip
const zipClosed = new Promise<void>((resolveClosed) => {
const interval = setInterval(() => {
if (!writeStream.writable) {
clearInterval(interval);
resolveClosed();
}
}, 10);
const zipClosed = new Promise<void>((resolve, reject) => {
writeStream.on('close', () => resolve());
writeStream.on('error', (err) => reject(err));
});

return new Promise<void>((resolve, reject) => {
writeStream.on('close', () => {
try {
fs.renameSync(tempZipFile, this.getFilePath()); // overwrites
// Enqueue all archive entries to the zip
let zipEntriesQueued = 0;
const inputStreams = [...inputToOutput.entries()]
.map(async ([inputFile, outputArchiveEntry]) => inputFile
.extractToStream(async (readStream) => {
zipFile.addReadStream(readStream, outputArchiveEntry.getEntryPath());
zipEntriesQueued += 1;

// Leave the stream open until we're done writing the zip
await zipClosed;
}));

// Wait until all archive entries have been enqueued
await new Promise<void>((resolve) => {
const interval = setInterval(() => {
if (zipEntriesQueued === inputToOutput.size) {
clearInterval(interval);
resolve();
} catch (e) {
reject(e);
}
});
writeStream.on('error', (err) => reject(err));
zipFile.outputStream.pipe(writeStream);

// Start writing the zip when all entries have been enqueued
let zipEntriesQueued = 0;
new Promise<void>((resolveQueued) => {
const interval = setInterval(() => {
if (zipEntriesQueued === inputToOutput.size) {
clearInterval(interval);
resolveQueued();
}
});
})
.then(() => zipFile.end())
.catch((err) => reject(err));

// Enqueue all archive entries to the zip
[...inputToOutput.entries()]
.forEach(async ([inputFile, outputArchiveEntry]) => inputFile
.extractToStream(async (readStream) => {
zipFile.addReadStream(readStream, outputArchiveEntry.getEntryPath());
zipEntriesQueued += 1;

// Leave the stream open until we're done writing the zip
await zipClosed;
}));
});

// Start writing the zip file
zipFile.end();

// Wait until we've closed the input streams
await Promise.all(inputStreams);

fs.renameSync(tempZipFile, this.getFilePath()); // overwrites
}
}

0 comments on commit a5a3a1e

Please sign in to comment.