aboutsummaryrefslogtreecommitdiff
path: root/modules/core/core-bundle.js
diff options
context:
space:
mode:
authorAgando <roduccomm@gmail.com>2026-06-19 18:01:04 +0200
committerAgando <roduccomm@gmail.com>2026-06-19 18:01:04 +0200
commit82270d6f2685d84d5c9b4a454ae7260de75d34cf (patch)
tree1827e5854589bff4f0bb4baa915f010dccc026ad /modules/core/core-bundle.js
parent0eca39021874a673933ebb82b973002b682e7a4b (diff)
auto: 2026-06-19_18:01 changes
Diffstat (limited to 'modules/core/core-bundle.js')
-rw-r--r--modules/core/core-bundle.js57
1 files changed, 55 insertions, 2 deletions
diff --git a/modules/core/core-bundle.js b/modules/core/core-bundle.js
index af59d06..2e57be6 100644
--- a/modules/core/core-bundle.js
+++ b/modules/core/core-bundle.js
@@ -374,6 +374,20 @@ class VirtualFileSystem {
return this._loadLegacy();
}
}
+ // P0: Check IndexedDB fallback if localStorage is empty
+ try {
+ const idbData = await this._loadFromIndexedDB();
+ if (idbData) {
+ const text = await this._decompress(idbData);
+ const data = JSON.parse(text);
+ this.root = data.root || this.root;
+ this.currentPath = data.currentPath || [];
+ this._usingIndexedDB = true;
+ this._purgeTrash();
+ console.info('FS loaded from IndexedDB fallback');
+ return true;
+ }
+ } catch (e) { /* IndexedDB not available or empty */ }
return this._loadLegacy();
} catch (e) { console.error('FS load error:', e); return false; }
}
@@ -413,14 +427,50 @@ class VirtualFileSystem {
const json = JSON.stringify({ root: this.root, currentPath: this.currentPath });
const compressed = await this._compress(json);
if (compressed) {
- localStorage.setItem('webx11_filesystem_v2', compressed);
- localStorage.removeItem('webx11_filesystem');
+ try {
+ localStorage.setItem('webx11_filesystem_v2', compressed);
+ localStorage.removeItem('webx11_filesystem');
+ } catch (quotaErr) {
+ // P0: IndexedDB fallback when localStorage quota exceeded
+ console.warn('localStorage quota exceeded, falling back to IndexedDB:', quotaErr.message);
+ await this._saveToIndexedDB(compressed);
+ this._usingIndexedDB = true;
+ }
} else {
localStorage.setItem('webx11_filesystem', json);
}
} catch (e) { console.error('FS save error:', e); }
}, 2000);
}
+ // P0: IndexedDB fallback storage for large VFS data
+ _openIDB() {
+ return new Promise((resolve, reject) => {
+ const req = indexedDB.open('webx11_vfs', 1);
+ req.onupgradeneeded = () => {
+ req.result.createObjectStore('vfs');
+ };
+ req.onsuccess = () => resolve(req.result);
+ req.onerror = () => reject(req.error);
+ });
+ }
+ async _saveToIndexedDB(data) {
+ const db = await this._openIDB();
+ return new Promise((resolve, reject) => {
+ const tx = db.transaction('vfs', 'readwrite');
+ tx.objectStore('vfs').put(data, 'filesystem_v2');
+ tx.oncomplete = () => { db.close(); resolve(true); };
+ tx.onerror = () => { db.close(); reject(tx.error); };
+ });
+ }
+ async _loadFromIndexedDB() {
+ const db = await this._openIDB();
+ return new Promise((resolve, reject) => {
+ const tx = db.transaction('vfs', 'readonly');
+ const req = tx.objectStore('vfs').get('filesystem_v2');
+ req.onsuccess = () => { db.close(); resolve(req.result || null); };
+ req.onerror = () => { db.close(); reject(req.error); };
+ });
+ }
getCurrentDir() {
let dir = this.root;
for (let part of this.currentPath) {
@@ -919,6 +969,9 @@ class VirtualFileSystem {
this.currentPath = [];
// Wipe all localStorage keys
['webx11_filesystem', 'webx11_filesystem_v2'].forEach(k => localStorage.removeItem(k));
+ // P0: Also clear IndexedDB fallback
+ try { indexedDB.deleteDatabase('webx11_vfs'); } catch (e) {}
+ this._usingIndexedDB = false;
return true;
}
}