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
						
					
					
				| '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
 | |
| }
 |