这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@insaindesign
Copy link

localForage is incompatible with recoil-storage, return types are different.

localForage.getItem() returns Promise<null|string>. which makes getState return null, as there is no check for null from a promise.

localForage.setItem() returns Promise<string>. but recoil-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.

src/index.ts Outdated
}

const parseState = (toParse: string) => {
const parseState = (toParse: string | null | undefined): PersistState => {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should change this to PersistItemValue

@dende-h
Copy link

dende-h commented Apr 19, 2023

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]
});

@dende-h
Copy link

dende-h commented Apr 20, 2023

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 = {};
					});
				}
			}
		});
	};

@polemius polemius force-pushed the master branch 2 times, most recently from 050c87f to 2f70d34 Compare May 17, 2023 06:56
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