'use strict';

var chunkAF3E2D32_cjs = require('../chunk-AF3E2D32.cjs');
var jestWorker = require('jest-worker');
var stream = require('stream');

var RESTARTED = Symbol("restarted");
var cleanupWorkers = /* @__PURE__ */ chunkAF3E2D32_cjs.__name((worker) => {
  for (const curWorker of worker._workerPool?._workers || []) {
    curWorker._child?.kill("SIGINT");
  }
}, "cleanupWorkers");
var Worker = class {
  static {
    chunkAF3E2D32_cjs.__name(this, "Worker");
  }
  _worker;
  constructor(workerPath, options) {
    const { timeout, onRestart, logger = console, ...farmOptions } = options;
    let restartPromise;
    let resolveRestartPromise;
    let activeTasks = 0;
    this._worker = void 0;
    process.on("exit", () => {
      this.close();
    });
    const createWorker = /* @__PURE__ */ chunkAF3E2D32_cjs.__name(() => {
      this._worker = new jestWorker.Worker(workerPath, {
        ...farmOptions,
        forkOptions: {
          ...farmOptions.forkOptions,
          env: {
            ...farmOptions.forkOptions?.env ?? {},
            ...process.env,
            IS_NEXT_WORKER: "true"
          }
        },
        maxRetries: 0
      });
      restartPromise = new Promise((resolve) => {
        resolveRestartPromise = resolve;
      });
      if (!farmOptions.enableWorkerThreads) {
        for (const worker of this._worker._workerPool?._workers || []) {
          worker._child?.on("exit", (code, signal) => {
            if ((code || signal && signal !== "SIGINT") && this._worker) {
              logger.error(`Next.js build worker exited with code: ${code} and signal: ${signal}`);
              process.exit(code ?? 1);
            }
          });
          worker._child?.on("message", ([, data]) => {
            if (data && typeof data === "object" && "type" in data && data.type === "activity") {
              onActivity();
            }
          });
        }
      }
      let aborted = false;
      const onActivityAbort = /* @__PURE__ */ chunkAF3E2D32_cjs.__name(() => {
        if (!aborted) {
          options.onActivityAbort?.();
          aborted = true;
        }
      }, "onActivityAbort");
      const abortActivityStreamOnLog = new stream.Transform({
        transform(_chunk, _encoding, callback) {
          onActivityAbort();
          callback();
        }
      });
      this._worker.getStdout().pipe(abortActivityStreamOnLog);
      this._worker.getStderr().pipe(abortActivityStreamOnLog);
      this._worker.getStdout().pipe(process.stdout);
      this._worker.getStderr().pipe(process.stderr);
    }, "createWorker");
    createWorker();
    const onHanging = /* @__PURE__ */ chunkAF3E2D32_cjs.__name(() => {
      const worker = this._worker;
      if (!worker) return;
      const resolve = resolveRestartPromise;
      createWorker();
      logger.warn(`Sending SIGTERM signal to static worker due to timeout${timeout ? ` of ${timeout / 1e3} seconds` : ""}. Subsequent errors may be a result of the worker exiting.`);
      void worker.end().then(() => {
        resolve(RESTARTED);
      });
    }, "onHanging");
    let hangingTimer = false;
    const onActivity = /* @__PURE__ */ chunkAF3E2D32_cjs.__name(() => {
      if (hangingTimer) clearTimeout(hangingTimer);
      if (options.onActivity) options.onActivity();
      hangingTimer = activeTasks > 0 && setTimeout(onHanging, timeout);
    }, "onActivity");
    for (const method of farmOptions.exposedMethods) {
      if (method.startsWith("_")) continue;
      this[method] = timeout ? async (...args) => {
        activeTasks++;
        try {
          let attempts = 0;
          for (; ; ) {
            onActivity();
            const result = await Promise.race([
              // eslint-disable-next-line ts/no-unsafe-call
              this._worker[method](...args),
              restartPromise
            ]);
            if (result !== RESTARTED) return result;
            if (onRestart) onRestart(method, args, ++attempts);
          }
        } finally {
          activeTasks--;
          onActivity();
        }
      } : this._worker[method].bind(this._worker);
    }
  }
  async end() {
    const worker = this._worker;
    if (!worker) {
      throw new Error("Farm is ended, no more calls can be done to it");
    }
    cleanupWorkers(worker);
    this._worker = void 0;
    return worker.end();
  }
  /**
  * Quietly end the worker if it exists
  */
  close() {
    if (this._worker) {
      cleanupWorkers(this._worker);
      void this._worker.end();
    }
  }
};

exports.Worker = Worker;
//# sourceMappingURL=worker.cjs.map
//# sourceMappingURL=worker.cjs.map