@@ -29,54 +29,94 @@ export function events<
2929 E extends { [ P in string ] : any [ ] } = { [ P in string ] : any [ ] }
3030> ( ) : [ Events < E > , EventEmitter < E > ] {
3131 const e = new EventTarget ( ) ;
32- const callbacks = new Map < keyof E , Map < string , ( e : Event ) => void > > ( ) ;
32+ const callbacks = new Map <
33+ keyof E ,
34+ Map <
35+ EventCallback < E [ keyof E ] > ,
36+ { fn : ( e : Event ) => void ; fingerprint : string }
37+ >
38+ > ( ) ;
3339
3440 const getEventCallback = < T extends keyof E > (
3541 type : T ,
3642 cb : EventCallback < E [ T ] > ,
37- ignoreExisting = false
43+ fingerprint : string ,
44+ checkFingerprint = false
3845 ) : ( ( e : Event ) => void ) => {
39- const fingerprint = getFunctionFingerprintString ( cb ) ;
4046 let ecbs = callbacks . get ( type ) ;
4147 if ( ! ecbs ) {
4248 ecbs = new Map ( ) ;
4349 callbacks . set ( type , ecbs ) ;
4450 }
4551
46- let ecb = ecbs . get ( fingerprint ) ;
47- if ( ! ecb || ignoreExisting ) {
48- ecb = ( e : Event ) : void => {
49- cb ( ...( e as CustomEvent ) . detail ) ;
52+ let ecb = ecbs . get ( cb as EventCallback ) ;
53+
54+ if ( checkFingerprint && ! ecb ) {
55+ // try get by fingerprint
56+ for ( const [ _key , value ] of ecbs . entries ( ) ) {
57+ if ( value . fingerprint === fingerprint ) {
58+ ecb = value ;
59+ break ;
60+ }
61+ }
62+ }
63+
64+ if ( ! ecb ) {
65+ ecb = {
66+ fn : ( e : Event ) : void => {
67+ cb ( ...( e as CustomEvent ) . detail ) ;
68+ } ,
69+ fingerprint
5070 } ;
51- ecbs . set ( fingerprint , ecb ) ;
71+ ecbs . set ( cb as EventCallback , ecb ) ;
5272 }
5373
54- return ecb ;
74+ return ecb . fn ;
5575 } ;
5676
57- const deleteEventCallback = ( type : keyof E , cb : EventCallback ) : void => {
77+ const deleteEventCallback = (
78+ type : keyof E ,
79+ cb : EventCallback ,
80+ fingerprint : string
81+ ) : void => {
5882 const ecbs = callbacks . get ( type ) ;
59- const fingerprint = getFunctionFingerprintString ( cb ) ;
6083 if ( ecbs ) {
61- ecbs . delete ( fingerprint ) ;
84+ if ( ecbs . has ( cb ) ) {
85+ ecbs . delete ( cb ) ;
86+ } else {
87+ // try delete by fingerprint
88+ for ( const [ key , value ] of ecbs . entries ( ) ) {
89+ if ( value . fingerprint === fingerprint ) {
90+ ecbs . delete ( key ) ;
91+ break ;
92+ }
93+ }
94+ }
6295 if ( ecbs . size === 0 ) {
6396 callbacks . delete ( type ) ;
6497 }
6598 }
6699 } ;
67100
68101 const on = < T extends keyof E > ( type : T , callback : EventCallback < E [ T ] > ) => {
69- const ecb = getEventCallback ( type , callback , true ) ;
70- e . addEventListener ( String ( type ) , ecb ) ;
102+ const fingerprint = getFunctionFingerprintString ( callback ) ;
103+ // Note: when binding callbacks, we don't check fingerprint,
104+ // because the previous one could be out of lifecycle but with the same fingerprint.
105+ const ecbFn = getEventCallback ( type , callback , fingerprint ) ;
106+ e . addEventListener ( String ( type ) , ecbFn ) ;
71107 } ;
72108 const off = < T extends keyof E > ( type : T , callback : EventCallback < E [ T ] > ) => {
73- const ecb = getEventCallback ( type , callback ) ;
74- e . removeEventListener ( String ( type ) , ecb ) ;
75- deleteEventCallback ( type , ecb ) ;
109+ const fingerprint = getFunctionFingerprintString ( callback ) ;
110+ const ecbFn = getEventCallback ( type , callback , fingerprint , true ) ;
111+ // Note: we check fingerprint here to ensure we remove the correct callback.
112+ // because the same callback becomes different after synchronization, but the fingerprint remains the same.
113+ e . removeEventListener ( String ( type ) , ecbFn ) ;
114+ deleteEventCallback ( type , ecbFn , fingerprint ) ;
76115 } ;
77116 const once = < T extends keyof E > ( type : T , callback : EventCallback < E [ T ] > ) => {
78- const ecb = getEventCallback ( type , callback , true ) ;
79- e . addEventListener ( String ( type ) , ecb , { once : true } ) ;
117+ const fingerprint = getFunctionFingerprintString ( callback ) ;
118+ const ecbFn = getEventCallback ( type , callback , fingerprint ) ;
119+ e . addEventListener ( String ( type ) , ecbFn , { once : true } ) ;
80120 } ;
81121
82122 const events = {
0 commit comments