type PLimitFn = ((value: T, index: number) => Promise) | ((value: T, index: number) => void); /** Runs multiple async functions, with limited concurrency. */ export async function pLimit(items: T[], limit: number, fn: PLimitFn): Promise { // Iterate values in order, 0–N. items = items.slice().reverse(); let index = 0; // Spawn 'limit' concurrent functions. await Promise.all( [...Array(limit)].map(async () => { while (items.length > 0) { await fn(items.pop()!, index++); } }), ); }