// 동시 실행 N개로 제한하는 작은 헬퍼 (외부 의존성 추가 없음).
// 일괄 PATCH/DELETE 같은 batch 작업에서 GPU 서버 / API / SSE에 부하 폭탄을
// 던지지 않도록 사용. plan 5대 원칙 #4.
//
// 사용 예:
//   const limit = pLimit(5);
//   const results = await Promise.allSettled(
//     ids.map((id) => limit(() => api(`/documents/${id}`, { method: 'PATCH', body })))
//   );

export function pLimit(concurrency: number) {
  let active = 0;
  const queue: Array<() => void> = [];

  const next = () => {
    active--;
    if (queue.length > 0) {
      queue.shift()!();
    }
  };

  return async function run<T>(fn: () => Promise<T>): Promise<T> {
    if (active >= concurrency) {
      await new Promise<void>((resolve) => queue.push(resolve));
    }
    active++;
    try {
      return await fn();
    } finally {
      next();
    }
  };
}
