/** Minimal promise concurrency limiter (no dependency). `const limit = pLimit(4); await Promise.all(items.map(i => limit(() => work(i))))` */
export default function pLimit (concurrency: number) {
  const max = Math.max(1, Math.floor(concurrency) || 1)
  let active = 0
  const queue: Array<() => void> = []
  const next = () => { active--; const run = queue.shift(); if (run) run() }
  return <T>(fn: () => Promise<T>): Promise<T> => new Promise<T>((resolve, reject) => {
    const run = () => { active++; fn().then(resolve, reject).finally(next) }
    if (active < max) run(); else queue.push(run)
  })
}
