46 lines
1.3 KiB
TypeScript
46 lines
1.3 KiB
TypeScript
import { createWriteStream } from "fs";
|
|
import fs from "fs/promises";
|
|
import { Readable } from "stream";
|
|
import { pipeline } from "stream/promises";
|
|
|
|
export async function writeUploadedFile(file: File, destPath: string) {
|
|
const webStream = file.stream();
|
|
const nodeStream = Readable.fromWeb(webStream as Parameters<typeof Readable.fromWeb>[0]);
|
|
await pipeline(nodeStream, createWriteStream(destPath));
|
|
}
|
|
|
|
export async function moveFile(src: string, dest: string) {
|
|
try {
|
|
await fs.rename(src, dest);
|
|
} catch (err) {
|
|
const code = err && typeof err === "object" && "code" in err ? err.code : null;
|
|
if (code === "EXDEV") {
|
|
await fs.copyFile(src, dest);
|
|
await fs.unlink(src).catch(() => {});
|
|
return;
|
|
}
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
export async function mapWithConcurrency<T, R>(
|
|
items: T[],
|
|
concurrency: number,
|
|
fn: (item: T, index: number) => Promise<R>,
|
|
) {
|
|
const results: R[] = new Array(items.length);
|
|
let nextIndex = 0;
|
|
|
|
async function worker() {
|
|
while (nextIndex < items.length) {
|
|
const index = nextIndex;
|
|
nextIndex += 1;
|
|
results[index] = await fn(items[index], index);
|
|
}
|
|
}
|
|
|
|
const workers = Array.from({ length: Math.min(concurrency, items.length) }, () => worker());
|
|
await Promise.all(workers);
|
|
return results;
|
|
}
|