can we use indexedb?
koraysels opened this issue · 3 comments
koraysels commented
Can we use indexDB instead of localStorage? There is an issue in latest electron wrapper that clears localStorage when the app closes...
polemius commented
Here is a example how you could use indexDB:
import React from "react";
import ReactDOM from "react-dom/client";
import { atom, RecoilRoot, useRecoilState } from "recoil";
import { recoilPersist } from "recoil-persist";
const getIndexDBStorage = async () => {
const openConnection = async () => {
return new Promise((resolve, reject) => {
const DBOpenRequest = window.indexedDB.open("recoil-persist");
DBOpenRequest.onerror = () => reject("Error open database");
DBOpenRequest.onsuccess = (event) => {
resolve(event.target.result);
};
DBOpenRequest.onupgradeneeded = (event) => {
const db = event.target.result;
db.createObjectStore("recoil-persist");
};
});
};
const database = await openConnection();
const storage = {
setItem: (key, value) => {
if (database === undefined) {
return;
}
return new Promise((resolve, reject) => {
const putRequest = database
.transaction(["recoil-persist"], "readwrite")
.objectStore("recoil-persist")
.put(value, key);
putRequest.onsuccess = () => {
resolve();
};
putRequest.onerror = () => {
reject();
};
});
},
getItem: (key) => {
if (database === undefined) {
return;
}
return new Promise((resolve, reject) => {
const result = database
.transaction(["recoil-persist"], "readwrite")
.objectStore("recoil-persist")
.get(key);
result.onsuccess = (event) => {
resolve(event.target.result);
};
result.onerror = () => {
reject();
};
});
},
};
return storage;
};
const { persistAtom } = recoilPersist({
storage: await getIndexDBStorage(),
});
const counterState = atom({
key: "count",
default: 0,
effects_UNSTABLE: [persistAtom],
});
function App() {
const [count, setCount] = useRecoilState(counterState);
return (
<div>
<h3>Counter: {count}</h3>
<button onClick={() => setCount(count + 1)}>Increase</button>
<button onClick={() => setCount(count - 1)}>Decrease</button>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<RecoilRoot>
<App />
</RecoilRoot>
</React.StrictMode>
);
koraysels commented
nice! going to give it a go ;)
koraysels commented
this works! thank you so much, Converted it to typescript:
const getIndexDBStorage = async () => {
const openConnection = async () => {
return new Promise<IDBDatabase>((resolve, reject) => {
const DBOpenRequest = window.indexedDB.open("recoil-persist");
DBOpenRequest.onerror = () => reject("Error open database");
DBOpenRequest.onsuccess = () => {
resolve(DBOpenRequest.result as IDBDatabase);
};
DBOpenRequest.onupgradeneeded = () => {
const db = DBOpenRequest.result as IDBDatabase;
db.createObjectStore("recoil-persist");
};
});
};
const database = await openConnection();
const storage = {
setItem: (key: string, value: any) => {
if (database === undefined) {
return;
}
return new Promise<void>((resolve, reject) => {
const putRequest = database
.transaction(["recoil-persist"], "readwrite")
.objectStore("recoil-persist")
.put(value, key);
putRequest.onsuccess = () => {
resolve();
};
putRequest.onerror = () => {
reject();
};
});
},
getItem: (key: string): string | Promise<string> | null => {
if (database === undefined) {
return null;
}
return new Promise<string>((resolve, reject) => {
const result = database
.transaction(["recoil-persist"], "readwrite")
.objectStore("recoil-persist")
.get(key);
result.onsuccess = () => {
resolve(result.result);
};
result.onerror = () => {
reject();
};
});
},
};
return storage;
};
export default getIndexDBStorage;