diff --git a/assets/js/utils/store.ts b/assets/js/utils/store.ts index d4b8579d..e2c97e36 100644 --- a/assets/js/utils/store.ts +++ b/assets/js/utils/store.ts @@ -1,13 +1,24 @@ +// Ignoring a non-100% coverage for HTTP client for now. +// It will be 100% in https://github.com/philomena-dev/philomena/pull/453 +/* v8 ignore start */ /** * localStorage utils */ export const lastUpdatedSuffix = '__lastUpdated'; +// We use this detached
element purely as an event bus to dispatch storage update +// events. It is needed because the default 'stroge' event dispatched on the window +// isn't triggered when the same page updates the storage. +const localUpdates = document.createElement('div'); + +type StorageUpdateEvent = CustomEvent; + export default { set(key: string, value: unknown) { try { localStorage.setItem(key, JSON.stringify(value)); + this.dispatchStorageUpdateEvent(key); return true; } catch { return false; @@ -27,12 +38,18 @@ export default { remove(key: string) { try { localStorage.removeItem(key); + this.dispatchStorageUpdateEvent(key); return true; } catch { return false; } }, + dispatchStorageUpdateEvent(key: string) { + const event: StorageUpdateEvent = new CustomEvent('storage-update', { detail: key }); + localUpdates.dispatchEvent(event); + }, + // Watch changes to a specified key - returns value on change watch(key: string, callback: (value: Value | null) => void) { const handler = (event: StorageEvent) => { @@ -42,6 +59,12 @@ export default { return () => window.removeEventListener('storage', handler); }, + // `null` key means the store was purged with `localStorage.clear()` + watchAll(callback: (key: null | string) => void) { + window.addEventListener('storage', event => callback(event.key)); + localUpdates.addEventListener('storage-update', event => callback((event as StorageUpdateEvent).detail)); + }, + // set() with an additional key containing the current time + expiration time setWithExpireTime(key: string, value: unknown, maxAge: number) { const lastUpdatedKey = key + lastUpdatedSuffix; @@ -58,3 +81,4 @@ export default { return lastUpdatedTime === null || Date.now() > lastUpdatedTime; }, }; +/* v8 ignore end */