import * as idb from 'idb-keyval'; let supported = true; const inMemoryCache = new Map<string, any>(); { var db = indexedDB.open('idb-test'); db.onerror = () => { supported = false; }; } export async function keys() { if (supported) { try { const keys = await idb.keys(); return Array.from(keys).map(k => k.toString()); } catch (e) {} } return Array.from(inMemoryCache.keys()); } export async function set(key, value) { // all values are saved in memory in case IDB fails later, but only retrieved after IDB fails. inMemoryCache.set(key, value); if (supported) { try { await idb.set(key, value); return; } catch (e) {} } } export async function get(key) { if (supported) { try { return await idb.get(key); } catch (e) {} } return inMemoryCache.get(key); } export async function getMany(keys) { if (supported) { try { return await idb.getMany(keys); } catch (e) {} } const values: any[] = []; for (const key of keys) { values.push(inMemoryCache.get(key)); } return values; } export async function setMany(items: [string, any][]) { // all values are saved in memory in case IDB fails later, but only retrieved after IDB fails. for (const [key, value] of items) { inMemoryCache.set(key, value); } if (supported) { try { await idb.setMany(items); return; } catch (e) {} } } export async function entries() { if (supported) { try { const entries = await idb.entries(); return Array.from(entries) .map(([key, value]) => [key.toString(), value]); } catch (e) {} } return Array.from(inMemoryCache.entries()); } export async function del(key: string) { // all values are saved in memory in case IDB fails later, but only retrieved after IDB fails. inMemoryCache.delete(key); if (supported) { try { await idb.del(key); return; } catch (e) {} } } export async function delMany(keys: string[]) { // all values are saved in memory in case IDB fails later, but only retrieved after IDB fails. for (const key of keys) { inMemoryCache.delete(key); } if (supported) { try { await idb.delMany(keys); return; } catch (e) {} } }