Skip to content

Instantly share code, notes, and snippets.

@mindon
Created May 7, 2023 17:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mindon/a2d7f0ef4f6a40555311c9715d0019a1 to your computer and use it in GitHub Desktop.
Save mindon/a2d7f0ef4f6a40555311c9715d0019a1 to your computer and use it in GitHub Desktop.
simple api to using indexeddb
const _DT = {id: 'de', name: 'data'};
// indexeddb
export function db$(id, name, todo) {
if (!win.indexedDB) {
return;
}
const { mode = "readonly" } = todo;
let req = indexedDB.open(id);
req.onsuccess = (evt) => {
const db = evt.target.result;
if (!db.objectStoreNames.contains(name)) {
todo(null, `no ${name} data`);
return;
}
todo(db.transaction([name], mode).objectStore(name));
};
req.onupgradeneeded = (evt) => {
const db = evt.target.result;
let store;
if (!db.objectStoreNames.contains(name)) {
store = db.createObjectStore(
name,
todo.options || { autoIncrement: true },
);
} else {
store = db.transaction([name], mode).objectStore(name);
}
todo(store);
};
req.onblocked = (evt) => {
todo(null, evt.target.error || "blocked");
};
req.onerror = (evt) => {
todo(null, evt.target.error || "error");
};
}
// req = async (store) => store.put|add|clear|delete
db$.do = async (req, options) => {
const { mode = "readwrite", name = _DT.name, id = _DT.id } = options || {};
return new Promise((resolve, reject) => {
const todo = async (store, err) => {
if (err || !store) {
return reject(err || "invalid store");
}
const r = req(store);
r.onsuccess = (evt) => {
resolve(evt.target.result);
};
r.onerror = (evt) => {
reject(evt.target.error);
};
return r;
};
todo.mode = mode;
db$(id, name, todo);
});
};
db$.get = async (key, options) => {
const { name = _DT.name, id = _DT.id } = options || {};
return new Promise((resolve, reject) => {
const todo = (store, err) => {
if (err || !store) {
return reject(err || "invalid store");
}
const req = store.get(key);
req.onerror = (evt) => {
reject(evt.target.error);
};
req.onsuccess = (evt) => {
resolve(evt.target.result);
};
};
todo.mode = "readonly";
db$(id, name, todo);
});
};
db$.count = async (options) => {
const { cond, cb, name = _DT.name, id = _DT.id } = options ||
{};
const result = [];
return new Promise((resolve, reject) => {
const todo = (store, err) => {
if (err || !store) {
return reject(err || "invalid store");
}
const stat = store.count(cond);
stat.onerror = (evt) => {
reject(evt.target.error);
};
stat.onsuccess = (evt) => {
const n = evt.target.result;
if (cb) {
cb(store, { resolve, reject, count: n });
} else {
resolve(n);
}
};
};
todo.mode = "readonly";
db$(id, name, todo);
});
};
db$.query = async (options) => {
const { cond = null, start = 0, n = 3, name = _DT.name, id = _DT.id } = options ||
{};
const result = [];
let total = 0;
return db$.count({
cond,
name,
id,
cb: (store, { resolve, reject, count }) => {
total = count;
const req = store.openCursor(cond, "prev");
let i = 0;
req.onsuccess = (evt) => {
const cursor = evt.target.result;
if (cursor) {
if (i < start) {
i += 1;
cursor.continue();
return;
}
result.push({ key: cursor.key, value: cursor.value });
if (n > 0 && result.length == n) {
resolve({ result, total });
return;
}
cursor.continue();
} else {
resolve({ result, total });
}
};
req.onerror = (evt) => {
reject(evt.target.error);
};
},
});
};
win.db$ = db$;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment