diff --git a/packages/core-app-api/src/apis/implementations/StorageApi/WebStorage.ts b/packages/core-app-api/src/apis/implementations/StorageApi/WebStorage.ts index c17cc56494..0f56a608c1 100644 --- a/packages/core-app-api/src/apis/implementations/StorageApi/WebStorage.ts +++ b/packages/core-app-api/src/apis/implementations/StorageApi/WebStorage.ts @@ -24,6 +24,14 @@ import ObservableImpl from 'zen-observable'; const buckets = new Map(); +window.addEventListener('storage', event => { + for (const [bucketPath, webStorage] of buckets.entries()) { + if (event.key?.startsWith(bucketPath)) { + webStorage.handleStorageChange(event.key); + } + } +}); + /** * An implementation of the storage API, that uses the browser's local storage. * @@ -89,17 +97,13 @@ export class WebStorage implements StorageApi { observe$( key: string, ): Observable> { - this.addStorageEventListener(); return this.observable.filter(({ key: messageKey }) => messageKey === key); } - private addStorageEventListener() { - window.addEventListener('storage', event => { - if (event.key?.includes(this.namespace)) { - const key = event.key.replace(`${this.namespace}/`, ''); - this.notifyChanges(key); - } - }); + handleStorageChange(eventKey: StorageEvent['key']) { + if (!eventKey?.startsWith(this.namespace)) return; + const key = eventKey?.replace(`${this.namespace}/`, ''); + this.notifyChanges(key); } private getKeyName(key: string) { diff --git a/packages/core-plugin-api/src/apis/definitions/StorageApi.ts b/packages/core-plugin-api/src/apis/definitions/StorageApi.ts index 1506e5f143..f8c0948ec6 100644 --- a/packages/core-plugin-api/src/apis/definitions/StorageApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/StorageApi.ts @@ -85,6 +85,14 @@ export interface StorageApi { key: string, ): Observable>; + /** + * Synchronizes stored data across multiple tabs or windows by using the + * browser's StorageEvent API. + * + * @param eventKey - The key of a storage event object + */ + handleStorageChange(eventKey: StorageEvent['key']): void; + /** * Returns an immediate snapshot value for the given key, if possible. *