From f7af1eefc4e94b535c00fbc87a29c5540caca1fb Mon Sep 17 00:00:00 2001 From: Aaron Boodman Date: Mon, 29 Mar 2021 15:12:37 -1000 Subject: [PATCH] Handle storage events correctly with memstore and other edge cases. Fixes #345. --- src/replicache.ts | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/replicache.ts b/src/replicache.ts index 4bd5886b..a8ae441c 100644 --- a/src/replicache.ts +++ b/src/replicache.ts @@ -258,15 +258,16 @@ export class Replicache implements ReadTransaction { }); if (hasBroadcastChannel) { this._broadcastChannel = new BroadcastChannel(storageKeyName(this._name)); - this._broadcastChannel.onmessage = e => { - this._checkChange(e.data); - }; + this._broadcastChannel.onmessage = () => this._onStorage(); } else { - window.addEventListener('storage', this._onStorage); + window.addEventListener('storage', (e: StorageEvent) => { + if (e.key === storageKeyName(this._name)) { + this._onStorage(); + } + }); } this._setRoot(this._getRoot()); await this._root; - window.addEventListener('storage', this._onStorage); } /** @@ -358,11 +359,12 @@ export class Replicache implements ReadTransaction { // Callback for when window.onstorage fires which happens when a different tab // changes the db. - private _onStorage = (e: StorageEvent): void => { - if (e.key === storageKeyName(this._name)) { - this._checkChange(e.newValue as string); - } - }; + private async _onStorage() { + // Cannot just use the value from the other tab, because it can be behind us. + // Also, in the case of memstore, it will have a totally different, unrelated + // hash chain. + this._checkChange(await this._getRoot()); + } private async _checkChange(root: string | undefined): Promise { const currentRoot = await this._root; // instantaneous except maybe first time