mapLimit (concurrency)
Concurrent async map with a concurrency cap — apply an async fn across an array running at most N at a time, preserving order. A tiny worker pool for fan-out fetches/jobs. No deps.
// Concurrent async map with a concurrency cap. Applies `fn` across `items`, running at
// most `limit` at a time, preserving input order. A tiny worker-pool — no deps.
// Extracted from WC26 (fetching ~40 match details in parallel without hammering the upstream).
//
// const details = await mapLimit(matchIds, 6, (id) => fetchMatch(id));
export async function mapLimit<T, R>(
items: T[],
limit: number,
fn: (item: T, index: number) => Promise<R>,
): Promise<R[]> {
const out: R[] = new Array(items.length);
let i = 0;
const workers = Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, async () => {
while (i < items.length) {
const idx = i++;
out[idx] = await fn(items[idx], idx);
}
});
await Promise.all(workers);
return out;
}