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