All files / src/utils bounded-map.ts

100% Statements 13/13
100% Branches 2/2
100% Functions 2/2
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29            38x         76x 76x 76x 76x 91x 297x 297x 297x   15x 15x       76x 65x    
/**
 * Run `task` on every item with at most `limit` running at once; results keep the item
 * order. A worker takes the next item as soon as its previous one finishes, so one slow
 * request does not hold back a whole batch. After the first failure no new item starts,
 * and the promise rejects with that failure.
 */
export async function mapBounded<T, R>(
  items: readonly T[],
  limit: number,
  task: (item: T) => Promise<R>,
): Promise<R[]> {
  const results = new Array<R>(items.length);
  let next = 0;
  let failed = false;
  const worker = async (): Promise<void> => {
    while (!failed && next < items.length) {
      const index = next++;
      try {
        results[index] = await task(items[index]);
      } catch (error) {
        failed = true;
        throw error;
      }
    }
  };
  await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker));
  return results;
}