From 954cb17e14051bdf4ab9568c1a9d190d2232422d Mon Sep 17 00:00:00 2001 From: Nikita Madeev Date: Tue, 26 Nov 2024 11:25:08 +0300 Subject: [PATCH] fix: :bug: Svelte store is the primary source of truth, while chrome storage is secondary. --- src/storage.ts | 63 ++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/src/storage.ts b/src/storage.ts index bae7512..a0186f0 100644 --- a/src/storage.ts +++ b/src/storage.ts @@ -1,4 +1,4 @@ -import { writable, type Writable } from "svelte/store"; +import { writable, type Updater, type Writable } from "svelte/store"; /** * Creates a persistent Svelte store backed by Chrome's sync storage. @@ -8,48 +8,45 @@ import { writable, type Writable } from "svelte/store"; * @returns A writable Svelte store */ export function persistentStore(key: string, initialValue: T): Writable { - const store = writable(initialValue); - // Ensure each value is updated exactly once in store and in chrome storage - let storeValueQueue: T[] = []; - let chromeValueQueue: T[] = []; + const store = writable(initialValue); - function watchStore() { - store.subscribe((value) => { - if (chromeValueQueue.length > 0 && value === chromeValueQueue[0]) { - chromeValueQueue.shift(); - return; - } - - storeValueQueue.push(value); - chrome.storage.sync.set({ [key]: value }); - }); + function updateChromeStorage(value: T): void { + chrome.storage.sync.set({ [key]: value }); } - function watchChrome() { + function watchChromeStorage() { chrome.storage.sync.onChanged.addListener((changes) => { - if (!Object.hasOwn(changes, key)) return; - - const value = changes[key].newValue as T; - if (storeValueQueue.length > 0 && value === storeValueQueue[0]) { - storeValueQueue.shift(); - return; + if (Object.hasOwn(changes, key)) { + store.set(changes[key].newValue); } + }); + } - chromeValueQueue.push(value); - store.set(value); + function initStoreFromChromeStorage() { + chrome.storage.sync.get(key).then((result) => { + if (Object.hasOwn(result, key)) { + store.set(result[key]); + } }); } - // Initialize the store with the value from Chrome storage - chrome.storage.sync.get(key).then((result) => { - const value = Object.hasOwn(result, key) ? result[key] : initialValue; - chromeValueQueue.push(value); - store.set(value); - watchStore(); - watchChrome(); - }); + initStoreFromChromeStorage(); + watchChromeStorage(); - return store; + return { + set(this: void, value: T): void { + store.set(value); + updateChromeStorage(value); + }, + update(this: void, updater: Updater): void { + return store.update((prev: T): T => { + const value = updater(prev); + updateChromeStorage(value); + return value; + }); + }, + subscribe: store.subscribe, + }; } export const count = persistentStore("count", 10);