Skip to content

Instantly share code, notes, and snippets.

@awinogradov
Last active September 30, 2023 03:14
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save awinogradov/ac46ec0944a1b0e942a353a5471f9b6a to your computer and use it in GitHub Desktop.
Save awinogradov/ac46ec0944a1b0e942a353a5471f9b6a to your computer and use it in GitHub Desktop.
localStorage via IndexDB polyfill
(() => {
const id = window.location;
const connection = indexedDB.open("canvas"); // one version all the time
connection.onupgradeneeded = () => {
console.log("Creating storage in the IndexDB instance");
const db = connection.result;
db.onversionchange = function () {
db.close();
window.location.reload();
};
if (!db.objectStoreNames.contains("fakeLocalStorage")) {
db.createObjectStore("fakeLocalStorage");
}
};
connection.onerror = () =>
console.log("indexDB connecttion failed", connection.error);
connection.onsuccess = () => {
console.log("indexDB connected successfully");
let fakeLocalStorage;
const transaction = connection.result.transaction(
"fakeLocalStorage",
"readwrite"
);
const storage = transaction.objectStore("fakeLocalStorage");
const replicaReq = storage.get("replica");
replicaReq.onsuccess = function () {
console.log("Fetched successfully", replicaReq.result);
fakeLocalStorage = new Map(
replicaReq.result
? Object.entries(JSON.parse(replicaReq.result))
: undefined
);
};
replicaReq.onerror = () => console.log("No way!", replicaReq.error);
const saveReplica = () => {
const transaction = connection.result.transaction(
"fakeLocalStorage",
"readwrite"
);
const storage = transaction.objectStore("fakeLocalStorage");
const replica = Object.fromEntries(fakeLocalStorage.entries());
const saveReq = storage.put(JSON.stringify(replica), "replica");
saveReq.onsuccess = () => console.log("Saved!");
};
class FakeLocalStorage {
getItem(key) {
const stringKey = String(key);
if (fakeLocalStorage.has(key)) {
return String(fakeLocalStorage.get(stringKey));
}
return null;
}
setItem(key, val) {
fakeLocalStorage.set(String(key), String(val));
saveReplica();
}
removeItem(key) {
fakeLocalStorage.delete(key);
saveReplica();
}
clear() {
fakeLocalStorage.clear();
saveReplica();
}
key(i) {
if (arguments.length === 0) {
throw new TypeError(
"Failed to execute 'key' on 'Storage': 1 argument required, but only 0 present."
); // this is a TypeError implemented on Chrome, Firefox throws Not enough arguments to Storage.key.
}
var arr = Array.from(fakeLocalStorage.keys());
return arr[i];
}
get length() {
return fakeLocalStorage.size;
}
}
const instance = new FakeLocalStorage();
global.localStorage = new Proxy(instance, {
set: function (obj, prop, value) {
if (LocalStorage.prototype.hasOwnProperty(prop)) {
instance[prop] = value;
} else {
instance.setItem(prop, value);
}
return true;
},
get: function (target, name) {
if (LocalStorage.prototype.hasOwnProperty(name)) {
return instance[name];
}
if (valuesMap.has(name)) {
return instance.getItem(name);
}
},
});
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment