// Bounded async fan-out. // // The corpus is big enough that an unbounded `Promise.all` over a per-video or // per-channel list is a file-descriptor bomb, not a speed-up: the largest // channel here holds 11,224 video dirs, and opening all of them at once starves // every other reader in the process. Every fan-out over corpus-shaped work goes // through this instead. // // Order-preserving: `out[i]` is always the result for `items[i]`, regardless of // completion order. Rejection semantics match `Promise.all` — the first // rejection wins and already-started work keeps running to completion. export async function mapConcurrent( items: readonly T[], limit: number, fn: (item: T, index: number) => Promise, ): Promise { const out = new Array(items.length); if (items.length === 0) return out; const width = Math.max(1, Math.min(Math.floor(limit), items.length)); let next = 0; const worker = async (): Promise => { for (;;) { const i = next++; if (i >= items.length) return; out[i] = await fn(items[i], i); } }; await Promise.all(Array.from({ length: width }, worker)); return out; }