Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chrome backed stores #28

Merged
merged 6 commits into from
Sep 17, 2024
Merged

Chrome backed stores #28

merged 6 commits into from
Sep 17, 2024

Conversation

Saba-Sabato
Copy link
Contributor

Hey,
First - @NekitCorp thanks a lot for creating this!
I was unhappy that the different components (Options, Overlay, popup) weren't communicating with each other, especially across different tabs. So I wrote an implementation that is backed by chrome.storage, and it syncs beautifully!

This also lets us do away with all the promises and extra boilerplate code, and just do things the Svelte way.

chrome backed stores

@NekitCorp
Copy link
Owner

NekitCorp commented Sep 12, 2024

Hi! Wow! This is a really awesome idea! 😮 Thank you very much for your contribution! 🔥

src/storage.ts Outdated Show resolved Hide resolved
src/storage.ts Outdated Show resolved Hide resolved
@Saba-Sabato
Copy link
Contributor Author

Never mind, I solved it. Just needed to look at it from a different perspective. Take a look, it's quite straightforward.

@NekitCorp
Copy link
Owner

NekitCorp commented Sep 17, 2024

Never mind, I solved it. Just needed to look at it from a different perspective. Take a look, it's quite straightforward.

Yes, this option seems to be the most protected from asynchronous race. It still seems to me that there is some case that will lead to desynchronization of arrays, but I couldn't find a single case, so let's leave this option 🙂 I'll leave some comments on the code itself, but the idea itself seems great to me 👍

I'll leave one more option just for history. If problems arise in the future, so we can come back to this thread and look at other options:

Another option based on timestamps
export function persistentStore<T>(key: string, initialValue: T): Writable<T> {
    const store = writable(initialValue);
    let timestamp = new Date().getTime();

    function updateStorage(value: T): void {
        timestamp = new Date().getTime();
        chrome.storage.sync.set({ [key]: [value, timestamp] });
    }

    function watchChrome() {
        chrome.storage.sync.onChanged.addListener((changes) => {
            // The value is stored in the format `[value: T, timestamp: number]`.
            // Update the store only when the `timestamp` is greater than the current one.
            if (
                Object.hasOwn(changes, key) &&
                Array.isArray(changes[key].newValue) &&
                changes[key].newValue.length === 2 &&
                typeof changes[key].newValue[1] === "number" &&
                changes[key].newValue[1] > timestamp
            ) {
                store.set(changes[key].newValue[0]);
            }
        });
    }

    // Initialize the store with the value from Chrome storage.
    chrome.storage.sync.get(key).then((result) => {
        if (Object.hasOwn(result, key)) {
            store.set(result[key][0]);
        }

        watchChrome();
    });

    return {
        set(this: void, value: T): void {
            store.set(value);
            updateStorage(value);
        },
        update(this: void, updater: Updater<T>): void {
            return store.update((prev: T): T => {
                const value = updater(prev);
                updateStorage(value);
                return value;
            });
        },
        subscribe: store.subscribe,
    };
}

Thank you very much for your patience and searching for the best option!

src/storage.ts Outdated Show resolved Hide resolved
src/storage.ts Outdated Show resolved Hide resolved
src/storage.ts Outdated Show resolved Hide resolved
src/storage.ts Outdated Show resolved Hide resolved
src/storage.ts Outdated Show resolved Hide resolved
@NekitCorp
Copy link
Owner

Thank you very much for your contribution!

@NekitCorp NekitCorp merged commit bd3c79d into NekitCorp:main Sep 17, 2024
1 check passed
@Saba-Sabato Saba-Sabato deleted the chrome-backed-stores branch September 18, 2024 11:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants