1
+ "use strict" ;
2
+ var _a ;
3
+ Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
4
+ exports . unload = exports . load = exports . onExit = exports . signals = void 0 ;
5
+ // Note: since nyc uses this module to output coverage, any lines
6
+ // that are in the direct sync flow of nyc's outputCoverage are
7
+ // ignored, since we can never get coverage for them.
8
+ // grab a reference to node's real process object right away
9
+ const signals_js_1 = require ( "./signals.js" ) ;
10
+ Object . defineProperty ( exports , "signals" , { enumerable : true , get : function ( ) { return signals_js_1 . signals ; } } ) ;
11
+ const processOk = ( process ) => ! ! process &&
12
+ typeof process === 'object' &&
13
+ typeof process . removeListener === 'function' &&
14
+ typeof process . emit === 'function' &&
15
+ typeof process . reallyExit === 'function' &&
16
+ typeof process . listeners === 'function' &&
17
+ typeof process . kill === 'function' &&
18
+ typeof process . pid === 'number' &&
19
+ typeof process . on === 'function' ;
20
+ const kExitEmitter = Symbol . for ( 'signal-exit emitter' ) ;
21
+ const global = globalThis ;
22
+ const ObjectDefineProperty = Object . defineProperty . bind ( Object ) ;
23
+ // teeny tiny ee
24
+ class Emitter {
25
+ emitted = {
26
+ afterExit : false ,
27
+ exit : false ,
28
+ } ;
29
+ listeners = {
30
+ afterExit : [ ] ,
31
+ exit : [ ] ,
32
+ } ;
33
+ count = 0 ;
34
+ id = Math . random ( ) ;
35
+ constructor ( ) {
36
+ if ( global [ kExitEmitter ] ) {
37
+ console . error ( 'reusing global emitter' ) ;
38
+ return global [ kExitEmitter ] ;
39
+ }
40
+ ObjectDefineProperty ( global , kExitEmitter , {
41
+ value : this ,
42
+ writable : false ,
43
+ enumerable : false ,
44
+ configurable : false ,
45
+ } ) ;
46
+ }
47
+ on ( ev , fn ) {
48
+ this . listeners [ ev ] . push ( fn ) ;
49
+ }
50
+ removeListener ( ev , fn ) {
51
+ const list = this . listeners [ ev ] ;
52
+ const i = list . indexOf ( fn ) ;
53
+ /* c8 ignore start */
54
+ if ( i === - 1 ) {
55
+ return ;
56
+ }
57
+ /* c8 ignore stop */
58
+ if ( i === 0 && list . length === 1 ) {
59
+ list . length = 0 ;
60
+ }
61
+ else {
62
+ list . splice ( i , 1 ) ;
63
+ }
64
+ }
65
+ emit ( ev , code , signal ) {
66
+ if ( this . emitted [ ev ] ) {
67
+ return ;
68
+ }
69
+ this . emitted [ ev ] = true ;
70
+ for ( const fn of this . listeners [ ev ] ) {
71
+ fn ( code , signal ) ;
72
+ }
73
+ }
74
+ }
75
+ class SignalExitBase {
76
+ }
77
+ const signalExitWrap = ( handler ) => {
78
+ return {
79
+ onExit ( cb , opts ) {
80
+ return handler . onExit ( cb , opts ) ;
81
+ } ,
82
+ load ( ) {
83
+ return handler . load ( ) ;
84
+ } ,
85
+ unload ( ) {
86
+ return handler . unload ( ) ;
87
+ } ,
88
+ } ;
89
+ } ;
90
+ class SignalExitFallback extends SignalExitBase {
91
+ onExit ( ) {
92
+ return ( ) => { } ;
93
+ }
94
+ load ( ) { }
95
+ unload ( ) { }
96
+ }
97
+ class SignalExit extends SignalExitBase {
98
+ // "SIGHUP" throws an `ENOSYS` error on Windows,
99
+ // so use a supported signal instead
100
+ /* c8 ignore start */
101
+ #hupSig = process . platform === 'win32' ? 'SIGINT' : 'SIGHUP' ;
102
+ /* c8 ignore stop */
103
+ #emitter = new Emitter ( ) ;
104
+ #process;
105
+ #originalProcessEmit;
106
+ #originalProcessReallyExit;
107
+ #sigListeners = { } ;
108
+ #loaded = false ;
109
+ constructor ( process ) {
110
+ super ( ) ;
111
+ this . #process = process ;
112
+ // { <signal>: <listener fn>, ... }
113
+ this . #sigListeners = { } ;
114
+ for ( const sig of signals_js_1 . signals ) {
115
+ this . #sigListeners[ sig ] = ( ) => {
116
+ // If there are no other listeners, an exit is coming!
117
+ // Simplest way: remove us and then re-send the signal.
118
+ // We know that this will kill the process, so we can
119
+ // safely emit now.
120
+ const listeners = this . #process. listeners ( sig ) ;
121
+ let { count } = this . #emitter;
122
+ // This is a workaround for the fact that signal-exit v3 and signal
123
+ // exit v4 are not aware of each other, and each will attempt to let
124
+ // the other handle it, so neither of them do. To correct this, we
125
+ // detect if we're the only handler *except* for previous versions
126
+ // of signal-exit.
127
+ /* c8 ignore start */
128
+ //@ts -ignore
129
+ if ( typeof process . __signal_exit_emitter__ === 'object' )
130
+ count ++ ;
131
+ /* c8 ignore stop */
132
+ if ( listeners . length === count ) {
133
+ this . unload ( ) ;
134
+ this . #emitter. emit ( 'exit' , null , sig ) ;
135
+ this . #emitter. emit ( 'afterExit' , null , sig ) ;
136
+ /* c8 ignore start */
137
+ process . kill ( process . pid , sig === 'SIGHUP' ? this . #hupSig : sig ) ;
138
+ /* c8 ignore stop */
139
+ }
140
+ } ;
141
+ }
142
+ this . #originalProcessReallyExit = process . reallyExit ;
143
+ this . #originalProcessEmit = process . emit ;
144
+ }
145
+ onExit ( cb , opts ) {
146
+ /* c8 ignore start */
147
+ if ( ! processOk ( this . #process) ) {
148
+ return ( ) => { } ;
149
+ }
150
+ /* c8 ignore stop */
151
+ if ( this . #loaded === false ) {
152
+ this . load ( ) ;
153
+ }
154
+ const ev = opts ?. alwaysLast ? 'afterExit' : 'exit' ;
155
+ this . #emitter. on ( ev , cb ) ;
156
+ return ( ) => {
157
+ this . #emitter. removeListener ( ev , cb ) ;
158
+ if ( this . #emitter. listeners [ 'exit' ] . length === 0 &&
159
+ this . #emitter. listeners [ 'afterExit' ] . length === 0 ) {
160
+ this . unload ( ) ;
161
+ }
162
+ } ;
163
+ }
164
+ load ( ) {
165
+ if ( this . #loaded) {
166
+ return ;
167
+ }
168
+ this . #loaded = true ;
169
+ // This is the number of onSignalExit's that are in play.
170
+ // It's important so that we can count the correct number of
171
+ // listeners on signals, and don't wait for the other one to
172
+ // handle it instead of us.
173
+ this . #emitter. count += 1 ;
174
+ for ( const sig of signals_js_1 . signals ) {
175
+ try {
176
+ const fn = this . #sigListeners[ sig ] ;
177
+ if ( fn )
178
+ this . #process. on ( sig , fn ) ;
179
+ }
180
+ catch ( _ ) { }
181
+ }
182
+ this . #process. emit = ( ev , ...a ) => {
183
+ return this . #processEmit( ev , ...a ) ;
184
+ } ;
185
+ this . #process. reallyExit = ( code ) => {
186
+ return this . #processReallyExit( code ) ;
187
+ } ;
188
+ }
189
+ unload ( ) {
190
+ if ( ! this . #loaded) {
191
+ return ;
192
+ }
193
+ this . #loaded = false ;
194
+ signals_js_1 . signals . forEach ( sig => {
195
+ const listener = this . #sigListeners[ sig ] ;
196
+ /* c8 ignore start */
197
+ if ( ! listener ) {
198
+ throw new Error ( 'Listener not defined for signal: ' + sig ) ;
199
+ }
200
+ /* c8 ignore stop */
201
+ try {
202
+ this . #process. removeListener ( sig , listener ) ;
203
+ /* c8 ignore start */
204
+ }
205
+ catch ( _ ) { }
206
+ /* c8 ignore stop */
207
+ } ) ;
208
+ this . #process. emit = this . #originalProcessEmit;
209
+ this . #process. reallyExit = this . #originalProcessReallyExit;
210
+ this . #emitter. count -= 1 ;
211
+ }
212
+ #processReallyExit( code ) {
213
+ /* c8 ignore start */
214
+ if ( ! processOk ( this . #process) ) {
215
+ return 0 ;
216
+ }
217
+ this . #process. exitCode = code || 0 ;
218
+ /* c8 ignore stop */
219
+ this . #emitter. emit ( 'exit' , this . #process. exitCode , null ) ;
220
+ this . #emitter. emit ( 'afterExit' , this . #process. exitCode , null ) ;
221
+ return this . #originalProcessReallyExit. call ( this . #process, this . #process. exitCode ) ;
222
+ }
223
+ #processEmit( ev , ...args ) {
224
+ const og = this . #originalProcessEmit;
225
+ if ( ev === 'exit' && processOk ( this . #process) ) {
226
+ if ( typeof args [ 0 ] === 'number' ) {
227
+ this . #process. exitCode = args [ 0 ] ;
228
+ /* c8 ignore start */
229
+ }
230
+ /* c8 ignore start */
231
+ const ret = og . call ( this . #process, ev , ...args ) ;
232
+ /* c8 ignore start */
233
+ this . #emitter. emit ( 'exit' , this . #process. exitCode , null ) ;
234
+ this . #emitter. emit ( 'afterExit' , this . #process. exitCode , null ) ;
235
+ /* c8 ignore stop */
236
+ return ret ;
237
+ }
238
+ else {
239
+ return og . call ( this . #process, ev , ...args ) ;
240
+ }
241
+ }
242
+ }
243
+ const process = globalThis . process ;
244
+ // wrap so that we call the method on the actual handler, without
245
+ // exporting it directly.
246
+ _a = signalExitWrap ( processOk ( process ) ? new SignalExit ( process ) : new SignalExitFallback ( ) ) ,
247
+ /**
248
+ * Called when the process is exiting, whether via signal, explicit
249
+ * exit, or running out of stuff to do.
250
+ *
251
+ * If the global process object is not suitable for instrumentation,
252
+ * then this will be a no-op.
253
+ *
254
+ * Returns a function that may be used to unload signal-exit.
255
+ */
256
+ exports . onExit = _a . onExit ,
257
+ /**
258
+ * Load the listeners. Likely you never need to call this, unless
259
+ * doing a rather deep integration with signal-exit functionality.
260
+ * Mostly exposed for the benefit of testing.
261
+ *
262
+ * @internal
263
+ */
264
+ exports . load = _a . load ,
265
+ /**
266
+ * Unload the listeners. Likely you never need to call this, unless
267
+ * doing a rather deep integration with signal-exit functionality.
268
+ * Mostly exposed for the benefit of testing.
269
+ *
270
+ * @internal
271
+ */
272
+ exports . unload = _a . unload ;
273
+ //# sourceMappingURL=index.js.map
0 commit comments