-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhandler.ts
More file actions
67 lines (60 loc) · 1.86 KB
/
handler.ts
File metadata and controls
67 lines (60 loc) · 1.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
* @file `onExit` — register a callback for process exit / signal. Triggers
* `load()` on first call. Returns a remover that unregisters the callback and
* calls `unload()` once both `exit` and `afterexit` listener lists empty
* out.
*/
import { TypeErrorCtor } from '../../primordials/error'
import { getEmitter, globalProcess, isLoaded } from './_internal'
import { load, unload } from './lifecycle'
import type { OnExitOptions } from './types'
/**
* Register a callback to run on process exit or signal.
*
* @example
* ```typescript
* const remove = onExit((code, signal) => {
* console.log(`Exiting with code ${code}, signal ${signal}`)
* })
* // Later, to unregister:
* remove()
* ```
*/
/*@__NO_SIDE_EFFECTS__*/
export function onExit(
// oxlint-disable-next-line socket/prefer-undefined-over-null -- mirrors upstream signal-exit API (signal/code are `null` for non-signal/non-exit events).
cb: (code: number | null, signal: string | null) => void,
options?: OnExitOptions | undefined,
): () => void {
// !globalProcess never fires in Node tests.
/* c8 ignore start */
if (!globalProcess) {
return function remove() {}
}
/* c8 ignore stop */
if (typeof cb !== 'function') {
throw new TypeErrorCtor('a callback must be provided for exit handler')
}
if (isLoaded() === false) {
load()
}
const { alwaysLast } = { __proto__: null, ...options } as OnExitOptions
let eventName = 'exit'
if (alwaysLast) {
eventName = 'afterexit'
}
const emitter = getEmitter()
emitter.on(eventName, cb)
return function remove() {
emitter.removeListener(eventName, cb)
// afterexit listener cleanup; tested via the alwaysLast path.
/* c8 ignore start */
if (
!emitter.listeners('exit').length &&
!emitter.listeners('afterexit').length
) {
unload()
}
/* c8 ignore stop */
}
}