@@ -19,26 +19,45 @@ const DistroUtils = require('./distro.js');
1919const Entity = require ( './entity.js' ) ;
2020const debug = require ( 'debug' ) ( 'rclnodejs:client' ) ;
2121
22- // Polyfill for AbortSignal.any() for Node.js <= 18.20
22+ // Polyfill for AbortSignal.any() for Node.js <= 20.3.0
2323// AbortSignal.any() was added in Node.js 20.3.0
2424// See https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/any_static
2525if ( ! AbortSignal . any ) {
2626 AbortSignal . any = function ( signals ) {
27+ // Filter out null/undefined values and validate inputs
28+ const validSignals = Array . isArray ( signals )
29+ ? signals . filter ( ( signal ) => signal != null )
30+ : [ ] ;
31+
32+ // If no valid signals, return a never-aborting signal
33+ if ( validSignals . length === 0 ) {
34+ return new AbortController ( ) . signal ;
35+ }
36+
2737 const controller = new AbortController ( ) ;
38+ const listeners = [ ] ;
39+
40+ // Cleanup function to remove all event listeners
41+ const cleanup = ( ) => {
42+ listeners . forEach ( ( { signal, listener } ) => {
43+ signal . removeEventListener ( 'abort' , listener ) ;
44+ } ) ;
45+ } ;
2846
29- for ( const signal of signals ) {
47+ for ( const signal of validSignals ) {
3048 if ( signal . aborted ) {
49+ cleanup ( ) ;
3150 controller . abort ( signal . reason ) ;
32- break ;
51+ return controller . signal ;
3352 }
3453
35- signal . addEventListener (
36- 'abort' ,
37- ( ) => {
38- controller . abort ( signal . reason ) ;
39- } ,
40- { once : true }
41- ) ;
54+ const listener = ( ) => {
55+ cleanup ( ) ;
56+ controller . abort ( signal . reason ) ;
57+ } ;
58+
59+ signal . addEventListener ( 'abort' , listener ) ;
60+ listeners . push ( { signal , listener } ) ;
4261 }
4362
4463 return controller . signal ;
0 commit comments