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 */