You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
1.7 KiB
94 lines
1.7 KiB
3 years ago
|
'use strict'
|
||
|
|
||
|
const refs = {
|
||
|
exit: [],
|
||
|
beforeExit: []
|
||
|
}
|
||
|
const functions = {
|
||
|
exit: onExit,
|
||
|
beforeExit: onBeforeExit
|
||
|
}
|
||
|
const registry = new FinalizationRegistry(clear)
|
||
|
|
||
|
function install (event) {
|
||
|
if (refs[event].length > 0) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
process.on(event, functions[event])
|
||
|
}
|
||
|
|
||
|
function uninstall (event) {
|
||
|
if (refs[event].length > 0) {
|
||
|
return
|
||
|
}
|
||
|
process.removeListener(event, functions[event])
|
||
|
}
|
||
|
|
||
|
function onExit () {
|
||
|
callRefs('exit')
|
||
|
}
|
||
|
|
||
|
function onBeforeExit () {
|
||
|
callRefs('beforeExit')
|
||
|
}
|
||
|
|
||
|
function callRefs (event) {
|
||
|
for (const ref of refs[event]) {
|
||
|
const obj = ref.deref()
|
||
|
const fn = ref.fn
|
||
|
|
||
|
// This should always happen, however GC is
|
||
|
// undeterministic so it might not happen.
|
||
|
/* istanbul ignore else */
|
||
|
if (obj !== undefined) {
|
||
|
fn(obj, event)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function clear (ref) {
|
||
|
for (const event of ['exit', 'beforeExit']) {
|
||
|
const index = refs[event].indexOf(ref)
|
||
|
refs[event].splice(index, index + 1)
|
||
|
uninstall(event)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function _register (event, obj, fn) {
|
||
|
if (obj === undefined) {
|
||
|
throw new Error('the object can\'t be undefined')
|
||
|
}
|
||
|
install(event)
|
||
|
const ref = new WeakRef(obj)
|
||
|
ref.fn = fn
|
||
|
|
||
|
registry.register(obj, ref)
|
||
|
refs[event].push(ref)
|
||
|
}
|
||
|
|
||
|
function register (obj, fn) {
|
||
|
_register('exit', obj, fn)
|
||
|
}
|
||
|
|
||
|
function registerBeforeExit (obj, fn) {
|
||
|
_register('beforeExit', obj, fn)
|
||
|
}
|
||
|
|
||
|
function unregister (obj) {
|
||
|
registry.unregister(obj)
|
||
|
for (const event of ['exit', 'beforeExit']) {
|
||
|
refs[event] = refs[event].filter((ref) => {
|
||
|
const _obj = ref.deref()
|
||
|
return _obj && _obj !== obj
|
||
|
})
|
||
|
uninstall(event)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = {
|
||
|
register,
|
||
|
registerBeforeExit,
|
||
|
unregister
|
||
|
}
|