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