File Explorer

/var/lang/lib/node_modules/npm/node_modules/signal-exit/dist/mjs

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

index.js8.9 KB · 275 lines
// Note: since nyc uses this module to output coverage, any lines// that are in the direct sync flow of nyc's outputCoverage are// ignored, since we can never get coverage for them.// grab a reference to node's real process object right awayimport { signals } from './signals.js';export { signals };const processOk = (process) => !!process &&    typeof process === 'object' &&    typeof process.removeListener === 'function' &&    typeof process.emit === 'function' &&    typeof process.reallyExit === 'function' &&    typeof process.listeners === 'function' &&    typeof process.kill === 'function' &&    typeof process.pid === 'number' &&    typeof process.on === 'function';const kExitEmitter = Symbol.for('signal-exit emitter');const global = globalThis;const ObjectDefineProperty = Object.defineProperty.bind(Object);// teeny special purpose eeclass Emitter {    emitted = {        afterExit: false,        exit: false,    };    listeners = {        afterExit: [],        exit: [],    };    count = 0;    id = Math.random();    constructor() {        if (global[kExitEmitter]) {            return global[kExitEmitter];        }        ObjectDefineProperty(global, kExitEmitter, {            value: this,            writable: false,            enumerable: false,            configurable: false,        });    }    on(ev, fn) {        this.listeners[ev].push(fn);    }    removeListener(ev, fn) {        const list = this.listeners[ev];        const i = list.indexOf(fn);        /* c8 ignore start */        if (i === -1) {            return;        }        /* c8 ignore stop */        if (i === 0 && list.length === 1) {            list.length = 0;        }        else {            list.splice(i, 1);        }    }    emit(ev, code, signal) {        if (this.emitted[ev]) {            return false;        }        this.emitted[ev] = true;        let ret = false;        for (const fn of this.listeners[ev]) {            ret = fn(code, signal) === true || ret;        }        if (ev === 'exit') {            ret = this.emit('afterExit', code, signal) || ret;        }        return ret;    }}class SignalExitBase {}const signalExitWrap = (handler) => {    return {        onExit(cb, opts) {            return handler.onExit(cb, opts);        },        load() {            return handler.load();        },        unload() {            return handler.unload();        },    };};class SignalExitFallback extends SignalExitBase {    onExit() {        return () => { };    }    load() { }    unload() { }}class SignalExit extends SignalExitBase {    // "SIGHUP" throws an `ENOSYS` error on Windows,    // so use a supported signal instead    /* c8 ignore start */    #hupSig = process.platform === 'win32' ? 'SIGINT' : 'SIGHUP';    /* c8 ignore stop */    #emitter = new Emitter();    #process;    #originalProcessEmit;    #originalProcessReallyExit;    #sigListeners = {};    #loaded = false;    constructor(process) {        super();        this.#process = process;        // { <signal>: <listener fn>, ... }        this.#sigListeners = {};        for (const sig of signals) {            this.#sigListeners[sig] = () => {                // If there are no other listeners, an exit is coming!                // Simplest way: remove us and then re-send the signal.                // We know that this will kill the process, so we can                // safely emit now.                const listeners = this.#process.listeners(sig);                let { count } = this.#emitter;                // This is a workaround for the fact that signal-exit v3 and signal                // exit v4 are not aware of each other, and each will attempt to let                // the other handle it, so neither of them do. To correct this, we                // detect if we're the only handler *except* for previous versions                // of signal-exit, and increment by the count of listeners it has                // created.                /* c8 ignore start */                const p = process;                if (typeof p.__signal_exit_emitter__ === 'object' &&                    typeof p.__signal_exit_emitter__.count === 'number') {                    count += p.__signal_exit_emitter__.count;                }                /* c8 ignore stop */                if (listeners.length === count) {                    this.unload();                    const ret = this.#emitter.emit('exit', null, sig);                    /* c8 ignore start */                    const s = sig === 'SIGHUP' ? this.#hupSig : sig;                    if (!ret)                        process.kill(process.pid, s);                    /* c8 ignore stop */                }            };        }        this.#originalProcessReallyExit = process.reallyExit;        this.#originalProcessEmit = process.emit;    }    onExit(cb, opts) {        /* c8 ignore start */        if (!processOk(this.#process)) {            return () => { };        }        /* c8 ignore stop */        if (this.#loaded === false) {            this.load();        }        const ev = opts?.alwaysLast ? 'afterExit' : 'exit';        this.#emitter.on(ev, cb);        return () => {            this.#emitter.removeListener(ev, cb);            if (this.#emitter.listeners['exit'].length === 0 &&                this.#emitter.listeners['afterExit'].length === 0) {                this.unload();            }        };    }    load() {        if (this.#loaded) {            return;        }        this.#loaded = true;        // This is the number of onSignalExit's that are in play.        // It's important so that we can count the correct number of        // listeners on signals, and don't wait for the other one to        // handle it instead of us.        this.#emitter.count += 1;        for (const sig of signals) {            try {                const fn = this.#sigListeners[sig];                if (fn)                    this.#process.on(sig, fn);            }            catch (_) { }        }        this.#process.emit = (ev, ...a) => {            return this.#processEmit(ev, ...a);        };        this.#process.reallyExit = (code) => {            return this.#processReallyExit(code);        };    }    unload() {        if (!this.#loaded) {            return;        }        this.#loaded = false;        signals.forEach(sig => {            const listener = this.#sigListeners[sig];            /* c8 ignore start */            if (!listener) {                throw new Error('Listener not defined for signal: ' + sig);            }            /* c8 ignore stop */            try {                this.#process.removeListener(sig, listener);                /* c8 ignore start */            }            catch (_) { }            /* c8 ignore stop */        });        this.#process.emit = this.#originalProcessEmit;        this.#process.reallyExit = this.#originalProcessReallyExit;        this.#emitter.count -= 1;    }    #processReallyExit(code) {        /* c8 ignore start */        if (!processOk(this.#process)) {            return 0;        }        this.#process.exitCode = code || 0;        /* c8 ignore stop */        this.#emitter.emit('exit', this.#process.exitCode, null);        return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);    }    #processEmit(ev, ...args) {        const og = this.#originalProcessEmit;        if (ev === 'exit' && processOk(this.#process)) {            if (typeof args[0] === 'number') {                this.#process.exitCode = args[0];                /* c8 ignore start */            }            /* c8 ignore start */            const ret = og.call(this.#process, ev, ...args);            /* c8 ignore start */            this.#emitter.emit('exit', this.#process.exitCode, null);            /* c8 ignore stop */            return ret;        }        else {            return og.call(this.#process, ev, ...args);        }    }}const process = globalThis.process;// wrap so that we call the method on the actual handler, without// exporting it directly.export const {/** * Called when the process is exiting, whether via signal, explicit * exit, or running out of stuff to do. * * If the global process object is not suitable for instrumentation, * then this will be a no-op. * * Returns a function that may be used to unload signal-exit. */onExit,/** * Load the listeners.  Likely you never need to call this, unless * doing a rather deep integration with signal-exit functionality. * Mostly exposed for the benefit of testing. * * @internal */load,/** * Unload the listeners.  Likely you never need to call this, unless * doing a rather deep integration with signal-exit functionality. * Mostly exposed for the benefit of testing. * * @internal */unload, } = signalExitWrap(processOk(process) ? new SignalExit(process) : new SignalExitFallback());//# sourceMappingURL=index.js.map