82f2b76e25
We now use webpack instead of SystemJS, effectively bundling modules into one file (plus commons chunks) for every entry point. This results in a much smaller extension size (almost half). Furthermore we use yarn/npm even for extension run-time dependencies. This relieves us from manually vendoring and building dependencies. It's also easier to understand for new developers familiar with node.
158 lines
3.8 KiB
JavaScript
158 lines
3.8 KiB
JavaScript
// 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.
|
|
var assert = require('assert')
|
|
var signals = require('./signals.js')
|
|
|
|
var EE = require('events')
|
|
/* istanbul ignore if */
|
|
if (typeof EE !== 'function') {
|
|
EE = EE.EventEmitter
|
|
}
|
|
|
|
var emitter
|
|
if (process.__signal_exit_emitter__) {
|
|
emitter = process.__signal_exit_emitter__
|
|
} else {
|
|
emitter = process.__signal_exit_emitter__ = new EE()
|
|
emitter.count = 0
|
|
emitter.emitted = {}
|
|
}
|
|
|
|
// Because this emitter is a global, we have to check to see if a
|
|
// previous version of this library failed to enable infinite listeners.
|
|
// I know what you're about to say. But literally everything about
|
|
// signal-exit is a compromise with evil. Get used to it.
|
|
if (!emitter.infinite) {
|
|
emitter.setMaxListeners(Infinity)
|
|
emitter.infinite = true
|
|
}
|
|
|
|
module.exports = function (cb, opts) {
|
|
assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler')
|
|
|
|
if (loaded === false) {
|
|
load()
|
|
}
|
|
|
|
var ev = 'exit'
|
|
if (opts && opts.alwaysLast) {
|
|
ev = 'afterexit'
|
|
}
|
|
|
|
var remove = function () {
|
|
emitter.removeListener(ev, cb)
|
|
if (emitter.listeners('exit').length === 0 &&
|
|
emitter.listeners('afterexit').length === 0) {
|
|
unload()
|
|
}
|
|
}
|
|
emitter.on(ev, cb)
|
|
|
|
return remove
|
|
}
|
|
|
|
module.exports.unload = unload
|
|
function unload () {
|
|
if (!loaded) {
|
|
return
|
|
}
|
|
loaded = false
|
|
|
|
signals.forEach(function (sig) {
|
|
try {
|
|
process.removeListener(sig, sigListeners[sig])
|
|
} catch (er) {}
|
|
})
|
|
process.emit = originalProcessEmit
|
|
process.reallyExit = originalProcessReallyExit
|
|
emitter.count -= 1
|
|
}
|
|
|
|
function emit (event, code, signal) {
|
|
if (emitter.emitted[event]) {
|
|
return
|
|
}
|
|
emitter.emitted[event] = true
|
|
emitter.emit(event, code, signal)
|
|
}
|
|
|
|
// { <signal>: <listener fn>, ... }
|
|
var sigListeners = {}
|
|
signals.forEach(function (sig) {
|
|
sigListeners[sig] = function listener () {
|
|
// 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.
|
|
var listeners = process.listeners(sig)
|
|
if (listeners.length === emitter.count) {
|
|
unload()
|
|
emit('exit', null, sig)
|
|
/* istanbul ignore next */
|
|
emit('afterexit', null, sig)
|
|
/* istanbul ignore next */
|
|
process.kill(process.pid, sig)
|
|
}
|
|
}
|
|
})
|
|
|
|
module.exports.signals = function () {
|
|
return signals
|
|
}
|
|
|
|
module.exports.load = load
|
|
|
|
var loaded = false
|
|
|
|
function load () {
|
|
if (loaded) {
|
|
return
|
|
}
|
|
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.
|
|
emitter.count += 1
|
|
|
|
signals = signals.filter(function (sig) {
|
|
try {
|
|
process.on(sig, sigListeners[sig])
|
|
return true
|
|
} catch (er) {
|
|
return false
|
|
}
|
|
})
|
|
|
|
process.emit = processEmit
|
|
process.reallyExit = processReallyExit
|
|
}
|
|
|
|
var originalProcessReallyExit = process.reallyExit
|
|
function processReallyExit (code) {
|
|
process.exitCode = code || 0
|
|
emit('exit', process.exitCode, null)
|
|
/* istanbul ignore next */
|
|
emit('afterexit', process.exitCode, null)
|
|
/* istanbul ignore next */
|
|
originalProcessReallyExit.call(process, process.exitCode)
|
|
}
|
|
|
|
var originalProcessEmit = process.emit
|
|
function processEmit (ev, arg) {
|
|
if (ev === 'exit') {
|
|
if (arg !== undefined) {
|
|
process.exitCode = arg
|
|
}
|
|
var ret = originalProcessEmit.apply(this, arguments)
|
|
emit('exit', process.exitCode, null)
|
|
/* istanbul ignore next */
|
|
emit('afterexit', process.exitCode, null)
|
|
return ret
|
|
} else {
|
|
return originalProcessEmit.apply(this, arguments)
|
|
}
|
|
}
|