/**
 * Helper class to push actions to a pool of workers.
 */
class WorkerPool {
    /**
     * Constructor
     * @param workers Array of workers to use for actions
     */
    constructor(workers) {
        this._pendingActions = new Array();
        this._workerInfos = workers.map((worker) => ({
            workerPromise: Promise.resolve(worker),
            idle: true,
        }));
    }
    /**
     * Terminates all workers and clears any pending actions.
     */
    dispose() {
        for (const workerInfo of this._workerInfos) {
            // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then
            workerInfo.workerPromise.then((worker) => {
                worker.terminate();
            });
        }
        this._workerInfos.length = 0;
        this._pendingActions.length = 0;
    }
    /**
     * Pushes an action to the worker pool. If all the workers are active, the action will be
     * pended until a worker has completed its action.
     * @param action The action to perform. Call onComplete when the action is complete.
     */
    push(action) {
        if (!this._executeOnIdleWorker(action)) {
            this._pendingActions.push(action);
        }
    }
    _executeOnIdleWorker(action) {
        for (const workerInfo of this._workerInfos) {
            if (workerInfo.idle) {
                this._execute(workerInfo, action);
                return true;
            }
        }
        return false;
    }
    _execute(workerInfo, action) {
        workerInfo.idle = false;
        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then
        workerInfo.workerPromise.then((worker) => {
            action(worker, () => {
                const nextAction = this._pendingActions.shift();
                if (nextAction) {
                    this._execute(workerInfo, nextAction);
                }
                else {
                    workerInfo.idle = true;
                }
            });
        });
    }
}
/**
 * Similar to the WorkerPool class except it creates and destroys workers automatically with a maximum of `maxWorkers` workers.
 * Workers are terminated when it is idle for at least `idleTimeElapsedBeforeRelease` milliseconds.
 */
class AutoReleaseWorkerPool extends WorkerPool {
    constructor(maxWorkers, createWorkerAsync, options = AutoReleaseWorkerPool.DefaultOptions) {
        super([]);
        this._maxWorkers = maxWorkers;
        this._createWorkerAsync = createWorkerAsync;
        this._options = options;
    }
    push(action) {
        if (!this._executeOnIdleWorker(action)) {
            if (this._workerInfos.length < this._maxWorkers) {
                const workerInfo = {
                    workerPromise: this._createWorkerAsync(),
                    idle: false,
                };
                this._workerInfos.push(workerInfo);
                this._execute(workerInfo, action);
            }
            else {
                this._pendingActions.push(action);
            }
        }
    }
    _execute(workerInfo, action) {
        // Reset the idle timeout.
        if (workerInfo.timeoutId) {
            clearTimeout(workerInfo.timeoutId);
            delete workerInfo.timeoutId;
        }
        super._execute(workerInfo, (worker, onComplete) => {
            action(worker, () => {
                onComplete();
                if (workerInfo.idle) {
                    // Schedule the worker to be terminated after the elapsed time.
                    workerInfo.timeoutId = setTimeout(() => {
                        // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then
                        workerInfo.workerPromise.then((worker) => {
                            worker.terminate();
                        });
                        const indexOf = this._workerInfos.indexOf(workerInfo);
                        if (indexOf !== -1) {
                            this._workerInfos.splice(indexOf, 1);
                        }
                    }, this._options.idleTimeElapsedBeforeRelease);
                }
            });
        });
    }
}
/**
 * Default options for the constructor.
 * Override to change the defaults.
 */
AutoReleaseWorkerPool.DefaultOptions = {
    idleTimeElapsedBeforeRelease: 1000,
};

export { AutoReleaseWorkerPool as A };
//# sourceMappingURL=workerPool-DP4ZCjkC.js.map
