@@ -29,9 +29,10 @@ import { Platform } from '../platform/platform';
29
29
import { hardAssert , debugAssert } from '../util/assert' ;
30
30
import { AsyncQueue } from '../util/async_queue' ;
31
31
import { Code , FirestoreError } from '../util/error' ;
32
- import { forEach } from '../util/obj' ;
33
32
import { logError , logDebug } from '../util/log' ;
34
33
import { SortedSet } from '../util/sorted_set' ;
34
+ import { SortedMap } from '../util/sorted_map' ;
35
+ import { primitiveComparator } from '../util/misc' ;
35
36
import { isSafeInteger } from '../util/types' ;
36
37
import {
37
38
QueryTargetState ,
@@ -475,12 +476,14 @@ export class WebStorageSharedClientState implements SharedClientState {
475
476
private readonly storage : Storage ;
476
477
private readonly localClientStorageKey : string ;
477
478
private readonly sequenceNumberKey : string ;
478
- private readonly activeClients : { [ key : string ] : ClientState } = { } ;
479
479
private readonly storageListener = this . handleWebStorageEvent . bind ( this ) ;
480
480
private readonly onlineStateKey : string ;
481
481
private readonly clientStateKeyRe : RegExp ;
482
482
private readonly mutationBatchKeyRe : RegExp ;
483
483
private readonly queryTargetKeyRe : RegExp ;
484
+ private activeClients = new SortedMap < string , ClientState > (
485
+ primitiveComparator
486
+ ) ;
484
487
private started = false ;
485
488
private currentUser : User ;
486
489
@@ -519,7 +522,10 @@ export class WebStorageSharedClientState implements SharedClientState {
519
522
this . sequenceNumberKey = createWebStorageSequenceNumberKey (
520
523
this . persistenceKey
521
524
) ;
522
- this . activeClients [ this . localClientId ] = new LocalClientState ( ) ;
525
+ this . activeClients = this . activeClients . insert (
526
+ this . localClientId ,
527
+ new LocalClientState ( )
528
+ ) ;
523
529
524
530
this . clientStateKeyRe = new RegExp (
525
531
`^${ CLIENT_STATE_KEY_PREFIX } _${ escapedPersistenceKey } _([^_]*)$`
@@ -576,7 +582,10 @@ export class WebStorageSharedClientState implements SharedClientState {
576
582
storageItem
577
583
) ;
578
584
if ( clientState ) {
579
- this . activeClients [ clientState . clientId ] = clientState ;
585
+ this . activeClients = this . activeClients . insert (
586
+ clientState . clientId ,
587
+ clientState
588
+ ) ;
580
589
}
581
590
}
582
591
}
@@ -611,24 +620,17 @@ export class WebStorageSharedClientState implements SharedClientState {
611
620
}
612
621
613
622
getAllActiveQueryTargets ( ) : TargetIdSet {
614
- let activeTargets = targetIdSet ( ) ;
615
- forEach ( this . activeClients , ( key , value ) => {
616
- activeTargets = activeTargets . unionWith ( value . activeTargetIds ) ;
617
- } ) ;
618
- return activeTargets ;
623
+ return this . extractActiveQueryTargets ( this . activeClients ) ;
619
624
}
620
625
621
626
isActiveQueryTarget ( targetId : TargetId ) : boolean {
622
- // This is not using `obj.forEach` since `forEach` doesn't support early
623
- // return.
624
- for ( const clientId in this . activeClients ) {
625
- if ( this . activeClients . hasOwnProperty ( clientId ) ) {
626
- if ( this . activeClients [ clientId ] . activeTargetIds . has ( targetId ) ) {
627
- return true ;
628
- }
627
+ let found = false ;
628
+ this . activeClients . forEach ( ( key , value ) => {
629
+ if ( value . activeTargetIds . has ( targetId ) ) {
630
+ found = true ;
629
631
}
630
- }
631
- return false ;
632
+ } ) ;
633
+ return found ;
632
634
}
633
635
634
636
addPendingMutation ( batchId : BatchId ) : void {
@@ -823,7 +825,7 @@ export class WebStorageSharedClientState implements SharedClientState {
823
825
}
824
826
825
827
private get localClientState ( ) : LocalClientState {
826
- return this . activeClients [ this . localClientId ] as LocalClientState ;
828
+ return this . activeClients . get ( this . localClientId ) as LocalClientState ;
827
829
}
828
830
829
831
private persistClientState ( ) : void {
@@ -979,26 +981,23 @@ export class WebStorageSharedClientState implements SharedClientState {
979
981
clientId : ClientId ,
980
982
clientState : RemoteClientState | null
981
983
) : Promise < void > {
982
- const existingTargets = this . getAllActiveQueryTargets ( ) ;
983
-
984
- if ( clientState ) {
985
- this . activeClients [ clientId ] = clientState ;
986
- } else {
987
- delete this . activeClients [ clientId ] ;
988
- }
984
+ const updatedClients = clientState
985
+ ? this . activeClients . insert ( clientId , clientState )
986
+ : this . activeClients . remove ( clientId ) ;
989
987
990
- const newTargets = this . getAllActiveQueryTargets ( ) ;
988
+ const existingTargets = this . extractActiveQueryTargets ( this . activeClients ) ;
989
+ const newTargets = this . extractActiveQueryTargets ( updatedClients ) ;
991
990
992
991
const addedTargets : TargetId [ ] = [ ] ;
993
992
const removedTargets : TargetId [ ] = [ ] ;
994
993
995
- newTargets . forEach ( async targetId => {
994
+ newTargets . forEach ( targetId => {
996
995
if ( ! existingTargets . has ( targetId ) ) {
997
996
addedTargets . push ( targetId ) ;
998
997
}
999
998
} ) ;
1000
999
1001
- existingTargets . forEach ( async targetId => {
1000
+ existingTargets . forEach ( targetId => {
1002
1001
if ( ! newTargets . has ( targetId ) ) {
1003
1002
removedTargets . push ( targetId ) ;
1004
1003
}
@@ -1007,7 +1006,9 @@ export class WebStorageSharedClientState implements SharedClientState {
1007
1006
return this . syncEngine ! . applyActiveTargetsChange (
1008
1007
addedTargets ,
1009
1008
removedTargets
1010
- ) ;
1009
+ ) . then ( ( ) => {
1010
+ this . activeClients = updatedClients ;
1011
+ } ) ;
1011
1012
}
1012
1013
1013
1014
private handleOnlineStateEvent ( onlineState : SharedOnlineState ) : void {
@@ -1016,10 +1017,20 @@ export class WebStorageSharedClientState implements SharedClientState {
1016
1017
// IndexedDb. If a client does not update their IndexedDb client state
1017
1018
// within 5 seconds, it is considered inactive and we don't emit an online
1018
1019
// state event.
1019
- if ( this . activeClients [ onlineState . clientId ] ) {
1020
+ if ( this . activeClients . get ( onlineState . clientId ) ) {
1020
1021
this . onlineStateHandler ! ( onlineState . onlineState ) ;
1021
1022
}
1022
1023
}
1024
+
1025
+ private extractActiveQueryTargets (
1026
+ clients : SortedMap < string , ClientState >
1027
+ ) : SortedSet < TargetId > {
1028
+ let activeTargets = targetIdSet ( ) ;
1029
+ clients . forEach ( ( kev , value ) => {
1030
+ activeTargets = activeTargets . unionWith ( value . activeTargetIds ) ;
1031
+ } ) ;
1032
+ return activeTargets ;
1033
+ }
1023
1034
}
1024
1035
1025
1036
function fromWebStorageSequenceNumber (
0 commit comments