Open insaindesign opened 2 years ago
Hello. Compatibility with localForage is what I am looking for. localStorage had capacity concerns. With this code I was able to save and update to IndexedDB. However, after the DB data is set on the first load, the update is set to the initial value in the onSet function. Therefore, after the initial load, if the reload is performed again without updating the data, the DB data will be lost. My atom code is as follows.
/* eslint-disable @typescript-eslint/no-empty-function /
/ eslint-disable @typescript-eslint/ban-ts-comment */
import { atom } from "recoil";
import { recoilPersist } from "../../components/util/customRecoilPersist";
import { draftObject } from "../selector/editorState";
import localforage from "localforage";
export type draftObjectArray = draftObject[];
localforage.config({
driver: localforage.INDEXEDDB,
name: "drafts",
version: 2,
storeName: "draftObject"
});
const { persistAtom } = recoilPersist({
key: "recoil-indexeddb",
storage: typeof window === "undefined" ? undefined : localforage
});
export const drafts = atom({
key: "drafts",
default: [],
effects_UNSTABLE: [persistAtom]
});
Skipping onSet only on the first load as shown below worked as expected, but I am not very confident that it is a good method. If you have a better solution, please let me know.
let firstFlug = false;
const persistAtom: AtomEffect<any> = ({ onSet, node, trigger, setSelf }) => {
if (trigger === "get") {
getState().then((s) => {
if (s.hasOwnProperty(node.key)) {
setSelf(s[node.key]);
firstFlug = true;
} else {
if (!firstFlug) firstFlug = true;
}
});
}
onSet((newValue, _, isReset) => {
if (firstFlug) {
if (isReset) {
pendingChanges.reset[node.key] = true;
delete pendingChanges.updates[node.key];
} else {
pendingChanges.updates[node.key] = newValue;
}
if (!pendingChanges.queue) {
pendingChanges.queue = getState().then((state) => {
if (JSON.stringify(state[node.key]) !== JSON.stringify(newValue)) {
updateState(state, pendingChanges);
}
pendingChanges.queue = null;
pendingChanges.reset = {};
pendingChanges.updates = {};
});
}
}
});
};
localForage
is incompatible withrecoil-storage
, return types are different.localForage.getItem()
returnsPromise<null|string>
. which makes getState return null, as there is no check fornull
from a promise.localForage.setItem()
returnsPromise<string>
. butrecoil-storage
doesn't care about that anyway, so doesn't have to enforce those types.Making getState return a Promise always simplifies the code a lot, though that commit doesn't need to be part of this, but it better enforces the types.