@@ -85,6 +85,7 @@ const {
85
85
validateString,
86
86
} = require ( 'internal/validators' ) ;
87
87
88
+ const kEvents = Symbol ( 'kEvents' ) ;
88
89
const kCapture = Symbol ( 'kCapture' ) ;
89
90
const kErrorMonitor = Symbol ( 'events.errorMonitor' ) ;
90
91
const kMaxEventTargetListeners = Symbol ( 'events.maxEventTargetListeners' ) ;
@@ -262,8 +263,7 @@ ObjectDefineProperty(EventEmitter.prototype, kCapture, {
262
263
enumerable : false ,
263
264
} ) ;
264
265
265
- EventEmitter . prototype . _events = undefined ;
266
- EventEmitter . prototype . _eventsCount = 0 ;
266
+ EventEmitter . prototype [ kEvents ] = undefined ;
267
267
EventEmitter . prototype . _maxListeners = undefined ;
268
268
269
269
// By default EventEmitters will print a warning if more than 10 listeners are
@@ -287,6 +287,40 @@ ObjectDefineProperty(EventEmitter, 'defaultMaxListeners', {
287
287
} ,
288
288
} ) ;
289
289
290
+ // _events and _eventsCount are Legacy
291
+ ObjectDefineProperty ( EventEmitter , '_events' , {
292
+ __proto__ : null ,
293
+ enumerable : true ,
294
+ get : function ( ) {
295
+ // TODO - maybe in order to not break the ecosystem, create a Proxy that will update the events map
296
+ const events = this [ kEvents ] ;
297
+ if ( events === undefined ) {
298
+ return undefined ;
299
+ }
300
+
301
+ return Object . fromEntries ( events . entries ( ) ) ;
302
+ } ,
303
+ set : function ( events ) {
304
+ this [ kEvents ] = new Map ( events ) ;
305
+ } ,
306
+ } ) ;
307
+
308
+ ObjectDefineProperty ( EventEmitter , '_eventsCount' , {
309
+ __proto__ : null ,
310
+ enumerable : true ,
311
+ get : function ( ) {
312
+ const events = this [ kEvents ] ;
313
+ if ( events === undefined ) {
314
+ return 0 ;
315
+ }
316
+
317
+ return events . size ;
318
+ } ,
319
+ set : function ( ) {
320
+ // TODO - throw, this is not supported
321
+ } ,
322
+ } ) ;
323
+
290
324
ObjectDefineProperties ( EventEmitter , {
291
325
kMaxEventTargetListeners : {
292
326
__proto__ : null ,
@@ -339,11 +373,9 @@ EventEmitter.setMaxListeners =
339
373
// If you're updating this function definition, please also update any
340
374
// re-definitions, such as the one in the Domain module (lib/domain.js).
341
375
EventEmitter . init = function ( opts ) {
342
-
343
- if ( this . _events === undefined ||
344
- this . _events === ObjectGetPrototypeOf ( this ) . _events ) {
345
- this . _events = { } ;
346
- this . _eventsCount = 0 ;
376
+ if ( this [ kEvents ] === undefined ||
377
+ this [ kEvents ] === ObjectGetPrototypeOf ( this ) [ kEvents ] ) {
378
+ this [ kEvents ] = new Map ( )
347
379
}
348
380
349
381
this . _maxListeners = this . _maxListeners || undefined ;
@@ -462,11 +494,11 @@ function enhanceStackTrace(err, own) {
462
494
EventEmitter . prototype . emit = function emit ( type , ...args ) {
463
495
let doError = ( type === 'error' ) ;
464
496
465
- const events = this . _events ;
497
+ const events = this [ kEvents ] ;
466
498
if ( events !== undefined ) {
467
- if ( doError && events [ kErrorMonitor ] !== undefined )
499
+ if ( doError && events . has ( kErrorMonitor ) )
468
500
this . emit ( kErrorMonitor , ...args ) ;
469
- doError = ( doError && events . error === undefined ) ;
501
+ doError = ( doError && ! events . has ( ' error' ) ) ;
470
502
} else if ( ! doError )
471
503
return false ;
472
504
@@ -506,7 +538,7 @@ EventEmitter.prototype.emit = function emit(type, ...args) {
506
538
throw err ; // Unhandled 'error' event
507
539
}
508
540
509
- const handler = events [ type ] ;
541
+ const handler = events . get ( type ) ;
510
542
511
543
if ( handler === undefined )
512
544
return false ;
@@ -547,10 +579,9 @@ function _addListener(target, type, listener, prepend) {
547
579
548
580
checkListener ( listener ) ;
549
581
550
- events = target . _events ;
582
+ events = target [ kEvents ] ;
551
583
if ( events === undefined ) {
552
- events = target . _events = { __proto__ : null } ;
553
- target . _eventsCount = 0 ;
584
+ events = target [ kEvents ] = new Map ( ) ;
554
585
} else {
555
586
// To avoid recursion in the case that type === "newListener"! Before
556
587
// adding it to the listeners, first emit "newListener".
@@ -559,21 +590,20 @@ function _addListener(target, type, listener, prepend) {
559
590
listener . listener ?? listener ) ;
560
591
561
592
// Re-assign `events` because a newListener handler could have caused the
562
- // this._events to be assigned to a new object
563
- events = target . _events ;
593
+ // this[kEvents] to be assigned to a new object
594
+ events = target [ kEvents ] ;
564
595
}
565
- existing = events [ type ] ;
596
+ existing = events . get ( type ) ;
566
597
}
567
598
568
599
if ( existing === undefined ) {
569
600
// Optimize the case of one listener. Don't need the extra array object.
570
- events [ type ] = listener ;
571
- ++ target . _eventsCount ;
601
+ events . set ( type , listener ) ;
572
602
} else {
573
603
if ( typeof existing === 'function' ) {
574
604
// Adding the second element, need to change to array.
575
- existing = events [ type ] =
576
- prepend ? [ listener , existing ] : [ existing , listener ] ;
605
+ existing = prepend ? [ listener , existing ] : [ existing , listener ] ;
606
+ events . set ( type , existing ) ;
577
607
// If we've already got an array, just append.
578
608
} else if ( prepend ) {
579
609
existing . unshift ( listener ) ;
@@ -677,20 +707,22 @@ EventEmitter.prototype.removeListener =
677
707
function removeListener ( type , listener ) {
678
708
checkListener ( listener ) ;
679
709
680
- const events = this . _events ;
710
+ const events = this [ kEvents ] ;
681
711
if ( events === undefined )
682
712
return this ;
683
713
684
- const list = events [ type ] ;
714
+ const list = events . get ( type ) ;
685
715
if ( list === undefined )
686
716
return this ;
687
717
688
718
if ( list === listener || list . listener === listener ) {
689
- if ( -- this . _eventsCount === 0 )
690
- this . _events = { __proto__ : null } ;
719
+ if ( this [ kEvents ] . size === 1 )
720
+ // TODO - this is no longer creating new objects
721
+ // this[kEvents].clear();
722
+ this [ kEvents ] = new Map ( ) ;
691
723
else {
692
- delete events [ type ] ;
693
- if ( events . removeListener )
724
+ events . delete ( type ) ;
725
+ if ( events . has ( ' removeListener' ) )
694
726
this . emit ( 'removeListener' , type , list . listener || listener ) ;
695
727
}
696
728
} else if ( typeof list !== 'function' ) {
@@ -715,9 +747,9 @@ EventEmitter.prototype.removeListener =
715
747
}
716
748
717
749
if ( list . length === 1 )
718
- events [ type ] = list [ 0 ] ;
750
+ events . set ( type , list [ 0 ] ) ;
719
751
720
- if ( events . removeListener !== undefined )
752
+ if ( events . has ( ' removeListener' ) )
721
753
this . emit ( 'removeListener' , type , listener ) ;
722
754
}
723
755
@@ -735,37 +767,38 @@ EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
735
767
*/
736
768
EventEmitter . prototype . removeAllListeners =
737
769
function removeAllListeners ( type ) {
738
- const events = this . _events ;
770
+ const events = this [ kEvents ] ;
739
771
if ( events === undefined )
740
772
return this ;
741
773
742
774
// Not listening for removeListener, no need to emit
743
- if ( events . removeListener === undefined ) {
775
+ if ( ! events . has ( ' removeListener' ) ) {
744
776
if ( arguments . length === 0 ) {
745
- this . _events = { __proto__ : null } ;
746
- this . _eventsCount = 0 ;
747
- } else if ( events [ type ] !== undefined ) {
748
- if ( -- this . _eventsCount === 0 )
749
- this . _events = { __proto__ : null } ;
777
+ // this[kEvents].clear();
778
+ this [ kEvents ] = new Map ( ) ;
779
+ } else if ( events . has ( type ) ) {
780
+ if ( this [ kEvents ] . size === 1 )
781
+ // this[kEvents].clear();
782
+ this [ kEvents ] = new Map ( ) ;
750
783
else
751
- delete events [ type ] ;
784
+ this [ kEvents ] . delete ( type ) ;
752
785
}
753
786
return this ;
754
787
}
755
788
756
789
// Emit removeListener for all listeners on all events
757
790
if ( arguments . length === 0 ) {
758
- for ( const key of ReflectOwnKeys ( events ) ) {
791
+ for ( const key of events . keys ( ) ) {
759
792
if ( key === 'removeListener' ) continue ;
760
793
this . removeAllListeners ( key ) ;
761
794
}
762
795
this . removeAllListeners ( 'removeListener' ) ;
763
- this . _events = { __proto__ : null } ;
764
- this . _eventsCount = 0 ;
796
+ // this[kEvents].clear() ;
797
+ this [ kEvents ] = new Map ( ) ;
765
798
return this ;
766
799
}
767
800
768
- const listeners = events [ type ] ;
801
+ const listeners = events . get ( type ) ;
769
802
770
803
if ( typeof listeners === 'function' ) {
771
804
this . removeListener ( type , listeners ) ;
@@ -780,12 +813,12 @@ EventEmitter.prototype.removeAllListeners =
780
813
} ;
781
814
782
815
function _listeners ( target , type , unwrap ) {
783
- const events = target . _events ;
816
+ const events = target [ kEvents ] ;
784
817
785
818
if ( events === undefined )
786
819
return [ ] ;
787
820
788
- const evlistener = events [ type ] ;
821
+ const evlistener = events . get ( type ) ;
789
822
if ( evlistener === undefined )
790
823
return [ ] ;
791
824
@@ -841,10 +874,10 @@ EventEmitter.prototype.listenerCount = listenerCount;
841
874
* @returns {number }
842
875
*/
843
876
function listenerCount ( type , listener ) {
844
- const events = this . _events ;
877
+ const events = this [ kEvents ] ;
845
878
846
879
if ( events !== undefined ) {
847
- const evlistener = events [ type ] ;
880
+ const evlistener = events . get ( type ) ;
848
881
849
882
if ( typeof evlistener === 'function' ) {
850
883
if ( listener != null ) {
@@ -878,7 +911,7 @@ function listenerCount(type, listener) {
878
911
* @returns {any[] }
879
912
*/
880
913
EventEmitter . prototype . eventNames = function eventNames ( ) {
881
- return this . _eventsCount > 0 ? ReflectOwnKeys ( this . _events ) : [ ] ;
914
+ return this [ kEvents ] . size > 0 ? Array . from ( this [ kEvents ] . keys ( ) ) : [ ] ;
882
915
} ;
883
916
884
917
function arrayClone ( arr ) {
0 commit comments