/**
 * Tiny bounded-concurrency pool. Cap N tasks in flight; queue the rest.
 *
 * Why inline instead of `p-limit`?
 *   p-limit went ESM-only at v4. We use `await import('p-limit')` from
 *   server code, which works in production Node, but Jest's default
 *   transform can't load ESM-only packages from CJS test files and
 *   throws `SyntaxError: Cannot use import statement outside a module`.
 *   Fighting with `transformIgnorePatterns` would be longer than this
 *   18-line helper.
 *
 * Usage:
 *   const limit = boundedPool(5);
 *   const results = await Promise.all(items.map(item => limit(() => work(item))));
 */

export function boundedPool(maxConcurrent: number) {
    let active = 0;
    const queue: (() => void)[] = [];

    function next() {
        active--;
        const job = queue.shift();
        if (job) job();
    }

    return function limit<T>(fn: () => Promise<T>): Promise<T> {
        return new Promise<T>((resolve, reject) => {
            const run = () => {
                active++;
                fn().then(resolve, reject).finally(next);
            };
            if (active < maxConcurrent) run();
            else queue.push(run);
        });
    };
}
