Spaces:
Running
Running
File size: 3,160 Bytes
d646dd7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | /* Persistent browser cache for review-side derived data.
*
* The source videos/parquet files remain server-side. This store only keeps
* transport responses for 2D keypoints, 3D landmarks and glove frames. The
* cache is best-effort: private/incognito browsers or quota pressure simply
* fall back to the normal network path.
*/
(function () {
'use strict';
const DB_NAME = 'egodata-review-cache';
const DB_VERSION = 1;
const STORE = 'payloads';
let dbPromise = null;
function open() {
if (dbPromise) return dbPromise;
if (!window.indexedDB) return Promise.resolve(null);
dbPromise = new Promise(resolve => {
try {
const request = indexedDB.open(DB_NAME, DB_VERSION);
request.onupgradeneeded = () => {
const db = request.result;
if (!db.objectStoreNames.contains(STORE)) {
db.createObjectStore(STORE, { keyPath: 'key' });
}
};
request.onsuccess = () => resolve(request.result);
request.onerror = () => resolve(null);
request.onblocked = () => resolve(null);
} catch (_) { resolve(null); }
});
return dbPromise;
}
async function get(key) {
const db = await open();
if (!db || !key) return null;
return new Promise(resolve => {
try {
const tx = db.transaction(STORE, 'readonly');
const req = tx.objectStore(STORE).get(key);
req.onsuccess = () => resolve(req.result || null);
req.onerror = () => resolve(null);
} catch (_) { resolve(null); }
});
}
async function put(key, value) {
const db = await open();
if (!db || !key) return false;
return new Promise(resolve => {
try {
const tx = db.transaction(STORE, 'readwrite');
tx.objectStore(STORE).put({ key, value, savedAt: Date.now() });
tx.oncomplete = () => resolve(true);
tx.onerror = () => resolve(false);
tx.onabort = () => resolve(false);
} catch (_) { resolve(false); }
});
}
async function removeEpisode(episodeId) {
const db = await open();
if (!db || !episodeId) return;
return new Promise(resolve => {
try {
const tx = db.transaction(STORE, 'readwrite');
const store = tx.objectStore(STORE);
const req = store.openCursor();
req.onsuccess = () => {
const cursor = req.result;
if (!cursor) return;
if (String(cursor.key).startsWith(`${episodeId}:`)) cursor.delete();
cursor.continue();
};
tx.oncomplete = () => resolve();
tx.onerror = () => resolve();
tx.onabort = () => resolve();
} catch (_) { resolve(); }
});
}
window.EgoMediaCache = { get, put, removeEpisode };
})();
|