Spaces:
Sleeping
Sleeping
| (function () { | |
| const DB_NAME = 'ShortTrackOffline'; | |
| const DB_VERSION = 1; | |
| let dbInstance = null; | |
| const cache = new Map(); | |
| function open() { | |
| return new Promise((resolve, reject) => { | |
| if (dbInstance) { resolve(dbInstance); return; } | |
| const req = indexedDB.open(DB_NAME, DB_VERSION); | |
| req.onupgradeneeded = (e) => { | |
| const db = e.target.result; | |
| if (!db.objectStoreNames.contains('data')) { | |
| db.createObjectStore('data', { keyPath: 'key' }); | |
| } | |
| }; | |
| req.onsuccess = (e) => { dbInstance = e.target.result; resolve(dbInstance); }; | |
| req.onerror = (e) => reject(e.target.error); | |
| }); | |
| } | |
| async function save(key, data) { | |
| cache.set(key, data); | |
| try { | |
| const db = await open(); | |
| const tx = db.transaction('data', 'readwrite'); | |
| tx.objectStore('data').put({ key, data, updatedAt: Date.now() }); | |
| await new Promise((res, rej) => { tx.oncomplete = res; tx.onerror = rej; }); | |
| } catch (e) { console.log('OfflineStore.save error:', e); } | |
| } | |
| async function get(key) { | |
| try { | |
| const db = await open(); | |
| const tx = db.transaction('data', 'readonly'); | |
| const req = tx.objectStore('data').get(key); | |
| return new Promise((resolve) => { req.onsuccess = () => resolve(req.result?.data || null); req.onerror = () => resolve(null); }); | |
| } catch (e) { return null; } | |
| } | |
| function cacheGet(key) { | |
| return cache.get(key); | |
| } | |
| function cacheSet(key, data) { | |
| cache.set(key, data); | |
| } | |
| function cacheDelete(key) { | |
| cache.delete(key); | |
| } | |
| async function restoreCache() { | |
| try { | |
| const db = await open(); | |
| const tx = db.transaction('data', 'readonly'); | |
| const store = tx.objectStore('data'); | |
| return new Promise((resolve) => { | |
| const req = store.openCursor(); | |
| req.onsuccess = (e) => { | |
| const cursor = e.target.result; | |
| if (cursor) { | |
| cache.set(cursor.value.key, cursor.value.data); | |
| cursor.continue(); | |
| } else { | |
| resolve(); | |
| } | |
| }; | |
| req.onerror = () => resolve(); | |
| }); | |
| } catch (e) { return; } | |
| } | |
| async function remove(key) { | |
| cache.delete(key); | |
| try { | |
| const db = await open(); | |
| const tx = db.transaction('data', 'readwrite'); | |
| tx.objectStore('data').delete(key); | |
| } catch (e) {} | |
| } | |
| window.OfflineStore = { | |
| open, | |
| save, | |
| get, | |
| cacheGet, | |
| cacheSet, | |
| cacheDelete, | |
| restoreCache, | |
| remove, | |
| get cache() { return cache; }, | |
| }; | |
| })(); | |