1
0

indexedCache.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. (() => {
  2. const INDEXEDCACHE_STORAGE_NAME = "databank";
  3. const INDEXEDCACHE_DATABASE_NAME = "media";
  4. const INDEXEDCACHE_DBVERSION_COLUMN = "dbVersion";
  5. IDBTransaction.READ_WRITE = "readwrite";
  6. IDBTransaction.READ = "readonly";
  7. class IndexedCache
  8. {
  9. #version = parseInt(localStorage?.getItem(INDEXEDCACHE_DBVERSION_COLUMN)) || 0;
  10. #openReq = null;
  11. #db = null;
  12. #mediaStore = null;
  13. constructor()
  14. {
  15. this.#openReq = new Promise((ok, ko) => {
  16. const DBOpenRequest = window.indexedDB.open(INDEXEDCACHE_STORAGE_NAME, 1);
  17. DBOpenRequest.onerror = evt => {
  18. console.error("Failed to open db: ", evt);
  19. this.onDbReady();
  20. };
  21. DBOpenRequest.onupgradeneeded = evt => {
  22. let mediaStore = evt.target.result.createObjectStore(INDEXEDCACHE_DATABASE_NAME, {
  23. autoIncrement: true,
  24. });
  25. };
  26. DBOpenRequest.onsuccess = evt => {
  27. this.onDbReady(evt.target.result);
  28. };
  29. });
  30. MediaStorage.Instance.addEventListener("doneLoading", (evt) => {
  31. this.pushMedias(MediaStorage.Instance.medias, MediaStorage.Instance.getDbVersion());
  32. });
  33. }
  34. onDbReady(db, mediaStore) {
  35. this.#openReq = null;
  36. this.#db = db;
  37. this.#mediaStore = mediaStore;
  38. }
  39. #reduceMedia(media) {
  40. let mediaRawData = {
  41. date: media.getDateTs(),
  42. md5sum: media.md5sum,
  43. fixedSum: media.fixedSum,
  44. path: media.path,
  45. fileName: media.fileName,
  46. meta: media.meta,
  47. fixedTags: Array.from(media.fixedTags),
  48. tags: Array.from(media.tags),
  49. version: media.version,
  50. writeAccess: media.writeAccess
  51. };
  52. for (let i in mediaRawData.meta) {
  53. if (mediaRawData.meta[i].value instanceof Date)
  54. mediaRawData.meta[i].value = mediaRawData.meta[i].value.getTime();
  55. }
  56. return JSON.stringify(mediaRawData);
  57. }
  58. async listMedias() {
  59. await this.#openReq;
  60. if (!this.#db)
  61. return { medias: [], version: 0 };
  62. let data = [];
  63. try {
  64. await new Promise(ok => {
  65. let transaction = this.#db.transaction([INDEXEDCACHE_DATABASE_NAME], IDBTransaction.READ);
  66. transaction.oncomplete = ok;
  67. transaction.onerror = ok;
  68. let storage = transaction.objectStore(INDEXEDCACHE_DATABASE_NAME);
  69. let req = storage.getAll();
  70. req.onsuccess = () => {
  71. data = req.result.map(x => JSON.parse(x));
  72. }
  73. });
  74. }
  75. catch (err) {
  76. console.error(err);
  77. return { medias: [], version: 0 };
  78. }
  79. return { medias: data, version: data.length ? this.#version : 0 };
  80. }
  81. async pushMedias(mediaArr, version) {
  82. await this.#openReq;
  83. if (!this.#db)
  84. return;
  85. await new Promise(ok => {
  86. let transaction = this.#db.transaction([INDEXEDCACHE_DATABASE_NAME], IDBTransaction.READ_WRITE);
  87. transaction.oncomplete = ok;
  88. transaction.onerror = ok;
  89. let storage = transaction.objectStore(INDEXEDCACHE_DATABASE_NAME);
  90. mediaArr.forEach(x => storage.put(this.#reduceMedia(x), x.fixedSum));
  91. });
  92. localStorage?.setItem(INDEXEDCACHE_DBVERSION_COLUMN, version);
  93. this.#version = version;
  94. console.log("Done updating db");
  95. }
  96. async clean() {
  97. await this.#openReq;
  98. if (!this.#db)
  99. return;
  100. this.#db.transaction(INDEXEDCACHE_DATABASE_NAME, IDBTransaction.READ_WRITE);
  101. localStorage?.removeItem(INDEXEDCACHE_DBVERSION_COLUMN);
  102. this.#version = 0;
  103. }
  104. }
  105. window.indexedData = new IndexedCache();
  106. })();