(() => { const INDEXEDCACHE_STORAGE_NAME = "databank"; const INDEXEDCACHE_DATABASE_NAME = "media"; const INDEXEDCACHE_DBVERSION_COLUMN = "dbVersion"; IDBTransaction.READ_WRITE = "readwrite"; IDBTransaction.READ = "readonly"; class IndexedCache { #version = parseInt(localStorage?.getItem(INDEXEDCACHE_DBVERSION_COLUMN)) || 0; #openReq = null; #db = null; #mediaStore = null; constructor() { this.#openReq = new Promise((ok, ko) => { const DBOpenRequest = window.indexedDB.open(INDEXEDCACHE_STORAGE_NAME, 1); DBOpenRequest.onerror = evt => { console.error("Failed to open db: ", evt); this.onDbReady(); }; DBOpenRequest.onupgradeneeded = evt => { let mediaStore = evt.target.result.createObjectStore(INDEXEDCACHE_DATABASE_NAME, { autoIncrement: true, }); }; DBOpenRequest.onsuccess = evt => { this.onDbReady(evt.target.result); }; }); MediaStorage.Instance.addEventListener("doneLoading", (evt) => { this.pushMedias(MediaStorage.Instance.medias, MediaStorage.Instance.getDbVersion()); }); } onDbReady(db, mediaStore) { this.#openReq = null; this.#db = db; this.#mediaStore = mediaStore; } #reduceMedia(media) { let mediaRawData = { date: media.getDateTs(), md5sum: media.md5sum, fixedSum: media.fixedSum, path: media.path, fileName: media.fileName, meta: media.meta, fixedTags: Array.from(media.fixedTags), tags: Array.from(media.tags), version: media.version, writeAccess: media.writeAccess }; for (let i in mediaRawData.meta) { if (mediaRawData.meta[i].value instanceof Date) mediaRawData.meta[i].value = mediaRawData.meta[i].value.getTime(); } return JSON.stringify(mediaRawData); } async listMedias() { await this.#openReq; if (!this.#db) return { medias: [], version: 0 }; let data = []; try { await new Promise(ok => { let transaction = this.#db.transaction([INDEXEDCACHE_DATABASE_NAME], IDBTransaction.READ); transaction.oncomplete = ok; transaction.onerror = ok; let storage = transaction.objectStore(INDEXEDCACHE_DATABASE_NAME); let req = storage.getAll(); req.onsuccess = () => { data = req.result.map(x => JSON.parse(x)); } }); } catch (err) { console.error(err); return { medias: [], version: 0 }; } return { medias: data, version: data.length ? this.#version : 0 }; } async pushMedias(mediaArr, version) { await this.#openReq; if (!this.#db) return; await new Promise(ok => { let transaction = this.#db.transaction([INDEXEDCACHE_DATABASE_NAME], IDBTransaction.READ_WRITE); transaction.oncomplete = ok; transaction.onerror = ok; let storage = transaction.objectStore(INDEXEDCACHE_DATABASE_NAME); mediaArr.forEach(x => storage.put(this.#reduceMedia(x), x.fixedSum)); }); localStorage?.setItem(INDEXEDCACHE_DBVERSION_COLUMN, version); this.#version = version; console.log("Done updating db"); } async clean() { await this.#openReq; if (!this.#db) return; this.#db.transaction(INDEXEDCACHE_DATABASE_NAME, IDBTransaction.READ_WRITE); localStorage?.removeItem(INDEXEDCACHE_DBVERSION_COLUMN); this.#version = 0; } } window.indexedData = new IndexedCache(); })();