@alwatr/exit-hook
Version:
A utility for registering exit handlers in Node.js.
94 lines (83 loc) • 2.45 kB
text/typescript
/**
* Array of callback functions to be called when the process is exiting.
*/
let callbacks: (() => void)[] | null = null;
/**
* True whether the process is exiting to prevent calling the callbacks more than once.
*/
let exiting = false;
/**
* Add a callback function to be called when the process is exiting.
*
* @param callback The callback function to be called when the process is exiting.
*
* @example
* ```typescript
* const saveAllData = () => {
* // save all data
* };
*
* existHook(saveAllData);
* ```
*/
export function exitHook(callback: () => void): void {
if (callbacks === null) {
registerExitEvents();
callbacks = [];
}
callbacks.push(callback);
}
/**
* A once callback to be called on process exit event.
*/
function onExit_(signal: number | 'SIGINT' | 'SIGTERM') {
console.log('onExit({signal: %s})', signal);
if (exiting === true || callbacks === null) return;
exiting = true;
for (const callback of callbacks) {
try {
callback();
}
catch (error) {
console.error('Error in exit hook callback:', error);
}
}
if (signal === 'SIGINT' || signal === 'SIGTERM') {
setTimeout(() => {
process.exit(0);
});
}
}
/**
* Register process exit events.
*/
function registerExitEvents(): void {
/**
* This event emitted when Node.js empties its event loop and has no additional work to schedule.
* Normally, the Node.js process will exit when there is no work scheduled,
* but a listener registered on the 'beforeExit' event can make **asynchronous calls**, and thereby cause the Node.js process to continue.
*
* @see https://nodejs.org/api/process.html#event-beforeexit
*/
// process.once('beforeExit', onExit_);
/**
* This event is emitted when the Node.js process is about to exit as a result of either:
* 1- The `process.exit()` method being called explicitly.
* 2- The Node.js event loop no longer having any additional work to perform.
*
* @see https://nodejs.org/api/process.html#event-exit
*/
process.once('exit', onExit_);
/**
* This event is emitted in terminal mode before exiting with code 128 + signal number.
*
* @see https://nodejs.org/api/process.html#signal-events
*/
process.once('SIGTERM', onExit_);
/**
* This event is emitted when `Ctrl+C` is pressed.
*
* @see https://nodejs.org/api/process.html#signal-events
*/
process.once('SIGINT', onExit_);
}