import { __name } from './chunk-IBAHCH6O.js';
import process from 'process';

var asyncCallbacks = /* @__PURE__ */ new Set();
var callbacks = /* @__PURE__ */ new Set();
var isCalled = false;
var isRegistered = false;
async function flushStdio() {
  const flush = /* @__PURE__ */ __name((stream) => new Promise((resolve) => {
    if (!stream || !stream.writable || stream.writableEnded || stream.destroyed) {
      resolve();
      return;
    }
    const onError = /* @__PURE__ */ __name(() => {
      stream.off("error", onError);
      resolve();
    }, "onError");
    stream.once("error", onError);
    try {
      stream.write("", () => {
        stream.off("error", onError);
        resolve();
      });
    } catch {
      stream.off("error", onError);
      resolve();
    }
  }), "flush");
  const timeout = new Promise((resolve) => {
    setTimeout(resolve, 1e3);
  });
  await Promise.race([
    Promise.all([flush(process.stdout), flush(process.stderr)]),
    timeout
  ]);
}
__name(flushStdio, "flushStdio");
async function exit(shouldManuallyExit, isSynchronous, signal) {
  if (isCalled) {
    return;
  }
  isCalled = true;
  if (asyncCallbacks.size > 0 && isSynchronous) {
    console.error([
      "SYNCHRONOUS TERMINATION NOTICE:",
      "When explicitly exiting the process via process.exit or via a parent process,",
      "asynchronous tasks in your exitHooks will not run. Either remove these tasks,",
      "use gracefulExit() instead of process.exit(), or ensure your parent process",
      "sends a SIGINT to the process running this code."
    ].join(" "));
  }
  let exitCode = 0;
  if (signal > 0) {
    exitCode = 128 + signal;
  } else if (typeof process.exitCode === "number" || typeof process.exitCode === "string") {
    exitCode = process.exitCode;
  }
  const done = /* @__PURE__ */ __name((force = false) => {
    if (force === true || shouldManuallyExit === true) {
      process.exit(exitCode);
    }
  }, "done");
  for (const callback of callbacks) {
    callback(exitCode);
  }
  if (isSynchronous) {
    done();
    return;
  }
  const promises = [];
  let forceAfter = 0;
  for (const [callback, wait] of asyncCallbacks) {
    forceAfter = Math.max(forceAfter, wait);
    promises.push(Promise.resolve(callback(exitCode)));
  }
  const asyncTimer = forceAfter > 0 ? setTimeout(() => {
    done(true);
  }, forceAfter) : void 0;
  await Promise.all(promises);
  clearTimeout(asyncTimer);
  await flushStdio();
  done();
}
__name(exit, "exit");
function addHook(options) {
  const { onExit, wait, isSynchronous } = options;
  const asyncCallbackConfig = [onExit, wait];
  if (isSynchronous) {
    callbacks.add(onExit);
  } else {
    asyncCallbacks.add(asyncCallbackConfig);
  }
  if (!isRegistered) {
    isRegistered = true;
    process.once("beforeExit", exit.bind(void 0, true, false, -128));
    process.once("SIGINT", exit.bind(void 0, true, false, 2));
    process.once("SIGTERM", exit.bind(void 0, true, false, 15));
    process.once("exit", exit.bind(void 0, false, true, 0));
    process.on("message", (message) => {
      if (message === "shutdown") {
        exit(true, true, -128);
      }
    });
  }
  return () => {
    if (isSynchronous) {
      callbacks.delete(onExit);
    } else {
      asyncCallbacks.delete(asyncCallbackConfig);
    }
  };
}
__name(addHook, "addHook");
function asyncExitHook(onExit, options = {}) {
  if (typeof onExit !== "function") {
    throw new TypeError("onExit must be a function");
  }
  if (!(typeof options.wait === "number" && options.wait > 0)) {
    throw new TypeError("wait must be set to a positive numeric value");
  }
  return addHook({
    onExit,
    wait: options.wait,
    isSynchronous: false
  });
}
__name(asyncExitHook, "asyncExitHook");
function gracefulExit(signal) {
  if (signal !== void 0) {
    process.exitCode = signal;
  }
  exit(true, false, -128);
}
__name(gracefulExit, "gracefulExit");

export { asyncExitHook, gracefulExit };
//# sourceMappingURL=chunk-XQSWW35O.js.map
//# sourceMappingURL=chunk-XQSWW35O.js.map