@@ -26,13 +26,32 @@ class DatabaseSyncTree {
26
26
this . _tree = { } ;
27
27
this . _reverseLookup = { } ;
28
28
29
+ // we need to be able to register multiple listeners for a single event,
30
+ // *then delete a specific single listener for that event*, so we have to
31
+ // be able to identify specific listeners for removal which means we need
32
+ // to mirror the private registration accounting from upstream EventEmitter
33
+ // so we have access here and can do our single emitter removal
34
+ // This is a map of emitter-key <-> set of listener registrations
35
+ // The listener registrations have { context, listener, remove() }
36
+ this . _registry = { } ;
37
+
29
38
SharedEventEmitter . addListener ( 'database_sync_event' , this . _handleSyncEvent . bind ( this ) ) ;
30
39
}
31
40
32
41
get native ( ) {
33
42
return NativeModules . RNFBDatabaseQueryModule ;
34
43
}
35
44
45
+ // from upstream EventEmitter: initialize registrations for an emitter key
46
+ _allocate ( registry , eventType ) {
47
+ let registrations = registry [ eventType ] ;
48
+ if ( registrations == null ) {
49
+ registrations = new Set ( ) ;
50
+ registry [ eventType ] = registrations ;
51
+ }
52
+ return registrations ;
53
+ }
54
+
36
55
/**
37
56
* Handles an incoming event from native
38
57
* @param event
@@ -132,6 +151,13 @@ class DatabaseSyncTree {
132
151
if ( isString ( registrations ) ) {
133
152
this . removeRegistration ( registrations ) ;
134
153
SharedEventEmitter . removeAllListeners ( registrations ) ;
154
+
155
+ // mirror upstream accounting - clear out all registrations for this key
156
+ if ( registrations == null ) {
157
+ this . _registry = { } ;
158
+ } else {
159
+ delete this . _registry [ registrations ] ;
160
+ }
135
161
return 1 ;
136
162
}
137
163
@@ -141,6 +167,12 @@ class DatabaseSyncTree {
141
167
for ( let i = 0 , len = registrations . length ; i < len ; i ++ ) {
142
168
this . removeRegistration ( registrations [ i ] ) ;
143
169
SharedEventEmitter . removeAllListeners ( registrations [ i ] ) ;
170
+ // mirror upstream accounting - clear out all registrations for this key
171
+ if ( registrations [ i ] == null ) {
172
+ this . _registry = { } ;
173
+ } else {
174
+ delete this . _registry [ registrations [ i ] ] ;
175
+ }
144
176
}
145
177
146
178
return registrations . length ;
@@ -163,15 +195,10 @@ class DatabaseSyncTree {
163
195
const registration = registrations [ i ] ;
164
196
let subscriptions ;
165
197
166
- // EventEmitter in react-native < 0.70 had a `_subscriber` property with a method for subscriptions by type...
167
- if ( SharedEventEmitter . _subscriber ) {
168
- subscriptions = SharedEventEmitter . _subscriber . getSubscriptionsForType ( registration ) ;
169
- } else {
170
- // ...react-native 0.70 now stores subscribers as a map of Sets by type in `_registry`
171
- const registrySubscriptionsSet = SharedEventEmitter . _registry [ registration ] ;
172
- if ( registrySubscriptionsSet ) {
173
- subscriptions = Array . from ( registrySubscriptionsSet ) ;
174
- }
198
+ // get all registrations for this key so we can find our specific listener
199
+ const registrySubscriptionsSet = this . _registry [ registration ] ;
200
+ if ( registrySubscriptionsSet ) {
201
+ subscriptions = Array . from ( registrySubscriptionsSet ) ;
175
202
}
176
203
177
204
if ( subscriptions ) {
@@ -180,6 +207,7 @@ class DatabaseSyncTree {
180
207
// The subscription may have been removed during this event loop.
181
208
// its listener matches the listener in method parameters
182
209
if ( subscription && subscription . listener === listener ) {
210
+ this . _registry [ registration ] . delete ( subscription ) ;
183
211
subscription . remove ( ) ;
184
212
removed . push ( registration ) ;
185
213
this . removeRegistration ( registration ) ;
@@ -278,7 +306,12 @@ class DatabaseSyncTree {
278
306
subscription . remove ( ) ;
279
307
} ) ;
280
308
} else {
281
- SharedEventEmitter . addListener ( eventRegistrationKey , listener ) ;
309
+ const registration = SharedEventEmitter . addListener ( eventRegistrationKey , listener ) ;
310
+
311
+ // add this listener registration info to our emitter-key map
312
+ // in case we need to identify and remove a specific listener later
313
+ const registrations = this . _allocate ( this . _registry , eventRegistrationKey ) ;
314
+ registrations . add ( registration ) ;
282
315
}
283
316
284
317
return eventRegistrationKey ;
0 commit comments