Created
May 7, 2023 17:06
-
-
Save mindon/a2d7f0ef4f6a40555311c9715d0019a1 to your computer and use it in GitHub Desktop.
simple api to using indexeddb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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