@@ -37,34 +37,23 @@ import {
37
37
QueryTargetState ,
38
38
SharedClientStateSyncer
39
39
} from './shared_client_state_syncer' ;
40
+ import {
41
+ CLIENT_STATE_KEY_PREFIX ,
42
+ ClientStateSchema ,
43
+ createWebStorageClientStateKey ,
44
+ createWebStorageMutationBatchKey ,
45
+ createWebStorageOnlineStateKey ,
46
+ createWebStorageQueryTargetMetadataKey ,
47
+ createWebStorageSequenceNumberKey ,
48
+ MUTATION_BATCH_KEY_PREFIX ,
49
+ MutationMetadataSchema ,
50
+ QUERY_TARGET_KEY_PREFIX ,
51
+ QueryTargetStateSchema ,
52
+ SharedOnlineStateSchema
53
+ } from './shared_client_state_schema' ;
40
54
41
55
const LOG_TAG = 'SharedClientState' ;
42
56
43
- // The format of the LocalStorage key that stores the client state is:
44
- // firestore_clients_<persistence_prefix>_<instance_key>
45
- const CLIENT_STATE_KEY_PREFIX = 'firestore_clients' ;
46
-
47
- // The format of the WebStorage key that stores the mutation state is:
48
- // firestore_mutations_<persistence_prefix>_<batch_id>
49
- // (for unauthenticated users)
50
- // or: firestore_mutations_<persistence_prefix>_<batch_id>_<user_uid>
51
- //
52
- // 'user_uid' is last to avoid needing to escape '_' characters that it might
53
- // contain.
54
- const MUTATION_BATCH_KEY_PREFIX = 'firestore_mutations' ;
55
-
56
- // The format of the WebStorage key that stores a query target's metadata is:
57
- // firestore_targets_<persistence_prefix>_<target_id>
58
- const QUERY_TARGET_KEY_PREFIX = 'firestore_targets' ;
59
-
60
- // The WebStorage prefix that stores the primary tab's online state. The
61
- // format of the key is:
62
- // firestore_online_state_<persistence_prefix>
63
- const ONLINE_STATE_KEY_PREFIX = 'firestore_online_state' ;
64
- // The WebStorage key prefix for the key that stores the last sequence number allocated. The key
65
- // looks like 'firestore_sequence_number_<persistence_prefix>'.
66
- const SEQUENCE_NUMBER_KEY_PREFIX = 'firestore_sequence_number' ;
67
-
68
57
/**
69
58
* A randomly-generated key assigned to each Firestore instance at startup.
70
59
*/
@@ -186,17 +175,6 @@ export interface SharedClientState {
186
175
writeSequenceNumber ( sequenceNumber : ListenSequenceNumber ) : void ;
187
176
}
188
177
189
- /**
190
- * The JSON representation of a mutation batch's metadata as used during
191
- * WebStorage serialization. The UserId and BatchId is omitted as it is
192
- * encoded as part of the key.
193
- */
194
- interface MutationMetadataSchema {
195
- state : MutationBatchState ;
196
- error ?: { code : string ; message : string } ; // Only set when state === 'rejected'
197
- updateTimeMs : number ;
198
- }
199
-
200
178
/**
201
179
* Holds the state of a mutation batch, including its user ID, batch ID and
202
180
* whether the batch is 'pending', 'acknowledged' or 'rejected'.
@@ -280,16 +258,6 @@ export class MutationMetadata {
280
258
}
281
259
}
282
260
283
- /**
284
- * The JSON representation of a query target's state as used during WebStorage
285
- * serialization. The TargetId is omitted as it is encoded as part of the key.
286
- */
287
- interface QueryTargetStateSchema {
288
- state : QueryTargetState ;
289
- error ?: { code : string ; message : string } ; // Only set when state === 'rejected'
290
- updateTimeMs : number ;
291
- }
292
-
293
261
/**
294
262
* Holds the state of a query target, including its target ID and whether the
295
263
* target is 'not-current', 'current' or 'rejected'.
@@ -370,16 +338,6 @@ export class QueryTargetMetadata {
370
338
}
371
339
}
372
340
373
- /**
374
- * The JSON representation of a clients's metadata as used during WebStorage
375
- * serialization. The ClientId is omitted here as it is encoded as part of the
376
- * key.
377
- */
378
- interface ClientStateSchema {
379
- activeTargetIds : number [ ] ;
380
- updateTimeMs : number ;
381
- }
382
-
383
341
/**
384
342
* Metadata state of a single client denoting the query targets it is actively
385
343
* listening to.
@@ -434,20 +392,6 @@ class RemoteClientState implements ClientState {
434
392
}
435
393
}
436
394
437
- /**
438
- * The JSON representation of the system's online state, as written by the
439
- * primary client.
440
- */
441
- export interface SharedOnlineStateSchema {
442
- /**
443
- * The clientId of the client that wrote this onlineState value. Tracked so
444
- * that on startup, clients can check if this client is still active when
445
- * determining whether to apply this value or not.
446
- */
447
- readonly clientId : string ;
448
- readonly onlineState : string ;
449
- }
450
-
451
395
/**
452
396
* This class represents the online state for all clients participating in
453
397
* multi-tab. The online state is only written to by the primary client, and
@@ -567,10 +511,13 @@ export class WebStorageSharedClientState implements SharedClientState {
567
511
568
512
this . storage = this . platform . window ! . localStorage ;
569
513
this . currentUser = initialUser ;
570
- this . localClientStorageKey = this . toWebStorageClientStateKey (
514
+ this . localClientStorageKey = createWebStorageClientStateKey (
515
+ this . persistenceKey ,
571
516
this . localClientId
572
517
) ;
573
- this . sequenceNumberKey = `${ SEQUENCE_NUMBER_KEY_PREFIX } _${ persistenceKey } ` ;
518
+ this . sequenceNumberKey = createWebStorageSequenceNumberKey (
519
+ this . persistenceKey
520
+ ) ;
574
521
this . activeClients [ this . localClientId ] = new LocalClientState ( ) ;
575
522
576
523
this . clientStateKeyRe = new RegExp (
@@ -583,7 +530,7 @@ export class WebStorageSharedClientState implements SharedClientState {
583
530
`^${ QUERY_TARGET_KEY_PREFIX } _${ escapedPersistenceKey } _(\\d+)$`
584
531
) ;
585
532
586
- this . onlineStateKey = ` ${ ONLINE_STATE_KEY_PREFIX } _ ${ persistenceKey } ` ;
533
+ this . onlineStateKey = createWebStorageOnlineStateKey ( this . persistenceKey ) ;
587
534
588
535
// Rather than adding the storage observer during start(), we add the
589
536
// storage observer during initialization. This ensures that we collect
@@ -620,7 +567,7 @@ export class WebStorageSharedClientState implements SharedClientState {
620
567
}
621
568
622
569
const storageItem = this . getItem (
623
- this . toWebStorageClientStateKey ( clientId )
570
+ createWebStorageClientStateKey ( this . persistenceKey , clientId )
624
571
) ;
625
572
if ( storageItem ) {
626
573
const clientState = RemoteClientState . fromWebStorageEntry (
@@ -707,7 +654,7 @@ export class WebStorageSharedClientState implements SharedClientState {
707
654
// by another tab
708
655
if ( this . isActiveQueryTarget ( targetId ) ) {
709
656
const storageItem = this . storage . getItem (
710
- this . toWebStorageQueryTargetMetadataKey ( targetId )
657
+ createWebStorageQueryTargetMetadataKey ( this . persistenceKey , targetId )
711
658
) ;
712
659
713
660
if ( storageItem ) {
@@ -737,7 +684,9 @@ export class WebStorageSharedClientState implements SharedClientState {
737
684
}
738
685
739
686
clearQueryState ( targetId : TargetId ) : void {
740
- this . removeItem ( this . toWebStorageQueryTargetMetadataKey ( targetId ) ) ;
687
+ this . removeItem (
688
+ createWebStorageQueryTargetMetadataKey ( this . persistenceKey , targetId )
689
+ ) ;
741
690
}
742
691
743
692
updateQueryState (
@@ -891,12 +840,20 @@ export class WebStorageSharedClientState implements SharedClientState {
891
840
state ,
892
841
error
893
842
) ;
894
- const mutationKey = this . toWebStorageMutationBatchKey ( batchId ) ;
843
+ const mutationKey = createWebStorageMutationBatchKey (
844
+ this . persistenceKey ,
845
+ this . currentUser ,
846
+ batchId
847
+ ) ;
895
848
this . setItem ( mutationKey , mutationState . toWebStorageJSON ( ) ) ;
896
849
}
897
850
898
851
private removeMutationState ( batchId : BatchId ) : void {
899
- const mutationKey = this . toWebStorageMutationBatchKey ( batchId ) ;
852
+ const mutationKey = createWebStorageMutationBatchKey (
853
+ this . persistenceKey ,
854
+ this . currentUser ,
855
+ batchId
856
+ ) ;
900
857
this . removeItem ( mutationKey ) ;
901
858
}
902
859
@@ -913,37 +870,14 @@ export class WebStorageSharedClientState implements SharedClientState {
913
870
state : QueryTargetState ,
914
871
error ?: FirestoreError
915
872
) : void {
916
- const targetKey = this . toWebStorageQueryTargetMetadataKey ( targetId ) ;
873
+ const targetKey = createWebStorageQueryTargetMetadataKey (
874
+ this . persistenceKey ,
875
+ targetId
876
+ ) ;
917
877
const targetMetadata = new QueryTargetMetadata ( targetId , state , error ) ;
918
878
this . setItem ( targetKey , targetMetadata . toWebStorageJSON ( ) ) ;
919
879
}
920
880
921
- /** Assembles the key for a client state in WebStorage */
922
- private toWebStorageClientStateKey ( clientId : ClientId ) : string {
923
- assert (
924
- clientId . indexOf ( '_' ) === - 1 ,
925
- `Client key cannot contain '_', but was '${ clientId } '`
926
- ) ;
927
-
928
- return `${ CLIENT_STATE_KEY_PREFIX } _${ this . persistenceKey } _${ clientId } ` ;
929
- }
930
-
931
- /** Assembles the key for a query state in WebStorage */
932
- private toWebStorageQueryTargetMetadataKey ( targetId : TargetId ) : string {
933
- return `${ QUERY_TARGET_KEY_PREFIX } _${ this . persistenceKey } _${ targetId } ` ;
934
- }
935
-
936
- /** Assembles the key for a mutation batch in WebStorage */
937
- private toWebStorageMutationBatchKey ( batchId : BatchId ) : string {
938
- let mutationKey = `${ MUTATION_BATCH_KEY_PREFIX } _${ this . persistenceKey } _${ batchId } ` ;
939
-
940
- if ( this . currentUser . isAuthenticated ( ) ) {
941
- mutationKey += `_${ this . currentUser . uid } ` ;
942
- }
943
-
944
- return mutationKey ;
945
- }
946
-
947
881
/**
948
882
* Parses a client state key in WebStorage. Returns null if the key does not
949
883
* match the expected key format.
0 commit comments