Skip to content

Commit a2ca679

Browse files
Next round of review comments
1 parent 84420b6 commit a2ca679

File tree

5 files changed

+177
-122
lines changed

5 files changed

+177
-122
lines changed

packages/firestore/src/local/shared_client_state.ts

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ const CLIENT_STATE_KEY_PREFIX = 'fs_clients';
3636
// The format of the LocalStorage key that stores the mutation state is:
3737
// fs_mutations_<persistence_prefix>_<batch_id> (for unauthenticated users)
3838
// or: fs_mutations_<persistence_prefix>_<batch_id>_<user_uid>
39+
//
40+
// 'user_uid' is last to avoid needing to escape '_' characters that it might
41+
// contain.
3942
const MUTATION_BATCH_KEY_PREFIX = 'fs_mutations';
4043

4144
/**
@@ -53,11 +56,11 @@ export type ClientKey = string;
5356
* `SharedClientState` is primarily used for synchronization in Multi-Tab
5457
* environments. Each tab is responsible for registering its active query
5558
* targets and mutations. `SharedClientState` will then notify the listener
56-
* passed to `subscribe()` for updates to mutations and queries that originated
57-
* in other clients.
59+
* assigned to `.syncEngine` for updates to mutations and queries that
60+
* originated in other clients.
5861
*
59-
* To receive notifications, both `subscribe()` and `start()` have to be called
60-
* in order.
62+
* To receive notifications, `.syncEngine` has to be assigned before calling
63+
* `start()`.
6164
*
6265
* TODO(multitab): Add callbacks to SyncEngine
6366
*/
@@ -115,7 +118,7 @@ interface MutationMetadataSchema {
115118
}
116119

117120
/**
118-
* Holds the state of a mutation batch, including its user ID, batch ID annd
121+
* Holds the state of a mutation batch, including its user ID, batch ID and
119122
* whether the batch is 'pending', 'acknowledged' or 'rejected'.
120123
*/
121124
// Visible for testing
@@ -181,15 +184,18 @@ export class MutationMetadata {
181184
}
182185

183186
toLocalStorageJSON(): string {
184-
const batchState: MutationMetadataSchema = {
187+
const batchMetadata: MutationMetadataSchema = {
185188
state: this.state
186189
};
187190

188191
if (this.error) {
189-
batchState.error = { code: this.error.code, message: this.error.message };
192+
batchMetadata.error = {
193+
code: this.error.code,
194+
message: this.error.message
195+
};
190196
}
191197

192-
return JSON.stringify(batchState);
198+
return JSON.stringify(batchMetadata);
193199
}
194200
}
195201

@@ -366,13 +372,14 @@ export class LocalClientState implements ClientState {
366372
*/
367373
// TODO(multitab): Rename all usages of LocalStorage to WebStorage to better differentiate from LocalClient.
368374
export class WebStorageSharedClientState implements SharedClientState {
375+
syncEngine: SharedClientStateSyncer | null;
376+
369377
private readonly storage: Storage;
370378
private readonly localClientStorageKey: string;
371379
private readonly activeClients: { [key: string]: ClientState } = {};
372380
private readonly storageListener = this.handleLocalStorageEvent.bind(this);
373381
private readonly clientStateKeyRe: RegExp;
374382
private readonly mutationBatchKeyRe: RegExp;
375-
private syncEngine: SharedClientStateSyncer | null;
376383
private user: User;
377384
private started = false;
378385

@@ -395,7 +402,7 @@ export class WebStorageSharedClientState implements SharedClientState {
395402
`^${CLIENT_STATE_KEY_PREFIX}_${persistenceKey}_([^_]*)$`
396403
);
397404
this.mutationBatchKeyRe = new RegExp(
398-
`^${MUTATION_BATCH_KEY_PREFIX}_${persistenceKey}_(\\d*)(?:_(.*))$`
405+
`^${MUTATION_BATCH_KEY_PREFIX}_${persistenceKey}_(\\d+)(?:_(.*))?$`
399406
);
400407
}
401408

@@ -404,17 +411,9 @@ export class WebStorageSharedClientState implements SharedClientState {
404411
return typeof window !== 'undefined' && window.localStorage != null;
405412
}
406413

407-
subscribe(syncEngine: SharedClientStateSyncer) {
408-
this.syncEngine = syncEngine;
409-
}
410-
411414
// TODO(multitab): Handle user changes.
412415
start(initialUser: User, knownClients: ClientKey[]): void {
413416
assert(!this.started, 'WebStorageSharedClientState already started');
414-
assert(
415-
this.syncEngine !== null,
416-
'Start() called before subscribing to events'
417-
);
418417
window.addEventListener('storage', this.storageListener);
419418

420419
for (const clientKey of knownClients) {
@@ -486,6 +485,7 @@ export class WebStorageSharedClientState implements SharedClientState {
486485
}
487486

488487
private handleLocalStorageEvent(event: StorageEvent): void {
488+
console.log(event.key);
489489
if (!this.started) {
490490
return;
491491
}
@@ -497,21 +497,21 @@ export class WebStorageSharedClientState implements SharedClientState {
497497
'Received LocalStorage notification for local change.'
498498
);
499499

500-
if (event.newValue == null) {
501-
if (this.clientStateKeyRe.test(event.key)) {
502-
const clientId = this.fromLocalStorageClientStateKey(event.key);
503-
delete this.activeClients[clientId];
504-
}
505-
} else {
506-
if (this.clientStateKeyRe.test(event.key)) {
500+
if (this.clientStateKeyRe.test(event.key)) {
501+
if (event.newValue != null) {
507502
const clientState = this.fromLocalStorageClientState(
508503
event.key,
509504
event.newValue
510505
);
511506
if (clientState) {
512507
this.activeClients[clientState.clientId] = clientState;
513508
}
514-
} else if (this.mutationBatchKeyRe.test(event.key)) {
509+
} else {
510+
const clientId = this.fromLocalStorageClientStateKey(event.key);
511+
delete this.activeClients[clientId];
512+
}
513+
} else if (this.mutationBatchKeyRe.test(event.key)) {
514+
if (event.newValue !== null) {
515515
const mutationMetadata = this.fromLocalStorageMutationMetadata(
516516
event.key,
517517
event.newValue
@@ -618,6 +618,11 @@ export class WebStorageSharedClientState implements SharedClientState {
618618
private async handleMutationBatchEvent(
619619
mutationBatch: MutationMetadata
620620
): Promise<void> {
621+
assert(
622+
this.syncEngine !== null,
623+
'syncEngine property must be set in order to handle events'
624+
);
625+
621626
if (mutationBatch.user.uid !== this.user.uid) {
622627
debug(
623628
LOG_TAG,

packages/firestore/src/local/shared_client_state_syncer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { BatchId } from '../core/types';
1818
import { FirestoreError } from '../util/error';
1919

2020
/**
21-
* A interface that describes the actions the SharedClientState class needs to
21+
* An interface that describes the actions the SharedClientState class needs to
2222
* perform on a cooperating synchronization engine.
2323
*/
2424
export interface SharedClientStateSyncer {

packages/firestore/src/remote/remote_syncer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { FirestoreError } from '../util/error';
2121
import { RemoteEvent } from './remote_event';
2222

2323
/**
24-
* A interface that describes the actions the RemoteStore needs to perform on
24+
* An interface that describes the actions the RemoteStore needs to perform on
2525
* a cooperating synchronization engine.
2626
*/
2727
export interface RemoteSyncer {

packages/firestore/test/unit/local/persistence_test_helpers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export async function testWebStorageSharedClientState(
118118

119119
knownInstances.push(SECONDARY_INSTANCE_KEY);
120120

121-
secondaryClientState.subscribe(new NoOpSharedClientStateSyncer());
121+
secondaryClientState.syncEngine = new NoOpSharedClientStateSyncer();
122122
await secondaryClientState.start(user, [SECONDARY_INSTANCE_KEY]);
123123

124124
for (const batchId of existingMutationBatchIds) {
@@ -136,7 +136,7 @@ export async function testWebStorageSharedClientState(
136136
TEST_PERSISTENCE_PREFIX,
137137
instanceKey
138138
);
139-
sharedClientState.subscribe(sharedClientSyncer);
139+
sharedClientState.syncEngine = sharedClientSyncer;
140140
await sharedClientState.start(user, knownInstances);
141141
return sharedClientState;
142142
}

0 commit comments

Comments
 (0)