Add a method to async interact with the local storage

This commit is contained in:
Gigiaj 2025-06-20 16:19:50 -05:00
parent fd2d7fff17
commit 89695a9acc

View file

@ -0,0 +1,48 @@
import { atom, PrimitiveAtom } from 'jotai';
import type { SetStateAction } from 'jotai';
import { get as getFromDB, set as setInDB } from 'idb-keyval';
export const setIndexedDBItem = async <T>(key: string, value: T) => {
await setInDB(key, value);
};
export const atomWithIndexedDB = <T>(key: string, initialValue: T): PrimitiveAtom<T> => {
const channel = new BroadcastChannel(key);
const baseAtom = atom(initialValue);
let isInitialized = false;
baseAtom.onMount = (setAtom) => {
(async () => {
const storedValue = await getFromDB<T>(key);
if (storedValue !== undefined && !isInitialized) {
setAtom(storedValue);
}
isInitialized = true;
})();
const handleChange = (event: MessageEvent) => {
setAtom(event.data);
};
channel.addEventListener('message', handleChange);
return () => {
channel.removeEventListener('message', handleChange);
};
};
const derivedAtom = atom<T, [SetStateAction<T>], void>(
(get) => get(baseAtom),
(get, set, update: SetStateAction<T>) => {
const currentValue = get(baseAtom);
const newValue =
typeof update === 'function' ? (update as (prev: T) => T)(currentValue) : update;
isInitialized = true;
set(baseAtom, newValue);
setIndexedDBItem(key, newValue);
channel.postMessage(newValue);
}
);
return derivedAtom;
};