Extract common functionality between unzip implementations

This commit is contained in:
Koen Vlaswinkel
2023-12-19 15:00:08 +01:00
parent 7c00768c90
commit 7a1f157225
2 changed files with 42 additions and 35 deletions

View File

@@ -1,30 +1,16 @@
import { availableParallelism } from "os"; import { availableParallelism } from "os";
import { openZip, readZipEntries, unzipFile } from "./unzip"; import { unzipToDirectory } from "./unzip";
import PQueue from "p-queue"; import PQueue from "p-queue";
export async function unzipToDirectoryConcurrently( export async function unzipToDirectoryConcurrently(
archivePath: string, archivePath: string,
destinationPath: string, destinationPath: string,
): Promise<void> { ): Promise<void> {
const zipFile = await openZip(archivePath, { const queue = new PQueue({
autoClose: false, concurrency: availableParallelism(),
strictFileNames: true,
lazyEntries: true,
}); });
try { return unzipToDirectory(archivePath, destinationPath, async (tasks) => {
const entries = await readZipEntries(zipFile); await queue.addAll(tasks);
});
const queue = new PQueue({
concurrency: availableParallelism(),
});
await queue.addAll(
entries.map((entry) => async () => {
await unzipFile(zipFile, entry, destinationPath);
}),
);
} finally {
zipFile.close();
}
} }

View File

@@ -109,7 +109,7 @@ async function copyStream(
* @param entry * @param entry
* @param rootDestinationPath * @param rootDestinationPath
*/ */
export async function unzipFile( async function unzipFile(
zipFile: ZipFile, zipFile: ZipFile,
entry: ZipEntry, entry: ZipEntry,
rootDestinationPath: string, rootDestinationPath: string,
@@ -140,6 +140,37 @@ export async function unzipFile(
} }
} }
/**
* Unzips all files from a zip archive. Please use
* `unzipToDirectoryConcurrently` or `unzipToDirectorySequentially` instead
* of this function.
*
* @param archivePath
* @param destinationPath
* @param taskRunner A function that runs the tasks (either sequentially or concurrently).
*/
export async function unzipToDirectory(
archivePath: string,
destinationPath: string,
taskRunner: (tasks: Array<() => Promise<void>>) => Promise<void>,
): Promise<void> {
const zipFile = await openZip(archivePath, {
autoClose: false,
strictFileNames: true,
lazyEntries: true,
});
try {
const entries = await readZipEntries(zipFile);
await taskRunner(
entries.map((entry) => () => unzipFile(zipFile, entry, destinationPath)),
);
} finally {
zipFile.close();
}
}
/** /**
* Sequentially unzips all files from a zip archive. Please use * Sequentially unzips all files from a zip archive. Please use
* `unzipToDirectoryConcurrently` if you can. This function is only * `unzipToDirectoryConcurrently` if you can. This function is only
@@ -152,19 +183,9 @@ export async function unzipToDirectorySequentially(
archivePath: string, archivePath: string,
destinationPath: string, destinationPath: string,
): Promise<void> { ): Promise<void> {
const zipFile = await openZip(archivePath, { return unzipToDirectory(archivePath, destinationPath, async (tasks) => {
autoClose: false, for (const task of tasks) {
strictFileNames: true, await task();
lazyEntries: true,
});
try {
const entries = await readZipEntries(zipFile);
for (const entry of entries) {
await unzipFile(zipFile, entry, destinationPath);
} }
} finally { });
zipFile.close();
}
} }