Skip to content

Compatibility with localForage#55

Open
insaindesign wants to merge 3 commits into
polemius:masterfrom
insaindesign:master
Open

Compatibility with localForage#55
insaindesign wants to merge 3 commits into
polemius:masterfrom
insaindesign:master

Conversation

@insaindesign

Copy link
Copy Markdown

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.

Comment thread src/index.ts Outdated
}

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

Copy link
Copy Markdown
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

dende-h commented Apr 19, 2023

Copy link
Copy Markdown

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

dende-h commented Apr 20, 2023

Copy link
Copy Markdown

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