import path from "node:path";
import { Thread, Worker, spawn } from "@chainsafe/threads";
import { chainConfigToJson } from "@lodestar/config";
// Worker constructor consider the path relative to the current working directory
const WORKER_DIR = process.env.NODE_ENV === "test" ? "../../../../lib/chain/archiveStore/historicalState" : "./";
/**
 * HistoricalStateRegen limits the damage from recreating historical states
 * by running regen in a separate worker thread.
 */
export class HistoricalStateRegen {
    api;
    logger;
    constructor(modules) {
        this.api = modules.api;
        this.logger = modules.logger;
        modules.signal?.addEventListener("abort", () => this.close(), { once: true });
    }
    static async init(modules) {
        const workerData = {
            chainConfigJson: chainConfigToJson(modules.config),
            genesisValidatorsRoot: modules.config.genesisValidatorsRoot,
            genesisTime: modules.opts.genesisTime,
            maxConcurrency: 1,
            maxLength: 50,
            dbLocation: modules.opts.dbLocation,
            metricsEnabled: Boolean(modules.metrics),
            loggerOpts: modules.logger.toOpts(),
        };
        const worker = new Worker(path.join(WORKER_DIR, "worker.js"), {
            suppressTranspileTS: Boolean(globalThis.Bun),
            workerData,
        });
        const api = await spawn(worker, {
            // A Lodestar Node may do very expensive task at start blocking the event loop and causing
            // the initialization to timeout. The number below is big enough to almost disable the timeout
            timeout: 5 * 60 * 1000,
        });
        return new HistoricalStateRegen({ ...modules, api });
    }
    async scrapeMetrics() {
        return this.api.scrapeMetrics();
    }
    async close() {
        await this.api.close();
        this.logger.debug("Terminating historical state worker");
        await Thread.terminate(this.api);
        this.logger.debug("Terminated historical state worker");
    }
    async getHistoricalState(slot) {
        return this.api.getHistoricalState(slot);
    }
}
//# sourceMappingURL=historicalStateRegen.js.map