"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkersListr = void 0;
const listr2_1 = require("listr2");
const os_1 = require("os");
const ramda_1 = require("ramda");
const workerpool_1 = require("workerpool");
const MAX_THREADS = Math.min((0, os_1.cpus)().length, 4);
const DEFAULT_POOL_OPTIONS = {
    minWorkers: 1,
    maxWorkers: MAX_THREADS,
    workerType: 'process',
    forkOpts: { silent: true },
};
const DEFAULT_LISTR_OPTIONS = {
    concurrent: MAX_THREADS,
    exitOnError: false,
};
class WorkersListr {
    constructor(workerFile, poolOptions = {}, listrOptions = {}) {
        this.pool = (0, workerpool_1.pool)(workerFile, Object.assign(Object.assign({}, DEFAULT_POOL_OPTIONS), poolOptions));
        this.tasks = new listr2_1.Manager(Object.assign(Object.assign({}, DEFAULT_LISTR_OPTIONS), listrOptions));
    }
    add(tasks, options) {
        const listrTasks = tasks.map(this.getListrTask.bind(this));
        this.tasks.add(listrTasks, options);
        return this;
    }
    run() {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                yield this.tasks.runAll();
            }
            finally {
                this.pool.terminate();
            }
        });
    }
    getListrTask(workersListrTask) {
        const { taskData, subtasks, subtasksOptions } = workersListrTask, listrTask = __rest(workersListrTask, ["taskData", "subtasks", "subtasksOptions"]);
        const task = subtasks
            ? (ctx, task) => task.newListr(subtasks.map(this.getListrTask.bind(this)), subtasksOptions)
            : this.getTaskMethod(taskData);
        return (0, ramda_1.mergeLeft)({ task }, listrTask);
    }
    getTaskMethod(data) {
        const { method, args = [] } = data;
        return (ctx) => __awaiter(this, void 0, void 0, function* () {
            ctx[method] = yield this.pool.exec(method, [ctx, ...args]);
        });
    }
}
exports.WorkersListr = WorkersListr;
//# sourceMappingURL=WorkersListr.js.map