feat: add IDBFS availability check and improve error handling in Anisette and WasmBridge

This commit is contained in:
2026-03-01 16:00:43 +08:00
parent d0bb6f357e
commit eaa30795db
2 changed files with 33 additions and 14 deletions

View File

@@ -149,10 +149,12 @@ export class Anisette {
async provision(): Promise<void> { async provision(): Promise<void> {
await this.provisioning.provision(this.dsid); await this.provisioning.provision(this.dsid);
// Sync provisioning state to IndexedDB (browser only) // Sync provisioning state to IndexedDB (browser only)
if (this.bridge.isIdbfsAvailable()) {
try { try {
await this.bridge.syncIdbfsToStorage(); await this.bridge.syncIdbfsToStorage();
} catch { } catch (err) {
// Ignore errors in Node.js or if IDBFS unavailable console.error("[anisette] Failed to sync to IDBFS:", err);
}
} }
} }
@@ -171,11 +173,15 @@ export class Anisette {
const deviceJsonBytes = encodeUtf8(JSON.stringify(this.device.toJson(), null, 2)); const deviceJsonBytes = encodeUtf8(JSON.stringify(this.device.toJson(), null, 2));
this.bridge = new WasmBridge(this.wasmModule); this.bridge = new WasmBridge(this.wasmModule);
// Mount + load persisted IDBFS in browser environment
if (this.bridge.isIdbfsAvailable()) {
mountIdbfsPaths(this.bridge, this.libraryPath, this.provisioningPath); mountIdbfsPaths(this.bridge, this.libraryPath, this.provisioningPath);
try { try {
await this.bridge.syncIdbfsFromStorage(); await this.bridge.syncIdbfsFromStorage();
} catch { } catch {
// Ignore errors - might be first run or Node.js // Ignore errors - might be first run or no existing data
}
} }
if (adiPb) { if (adiPb) {

View File

@@ -216,13 +216,24 @@ export class WasmBridge {
}; };
} }
/**
* Check if IDBFS is available (browser environment only).
*/
isIdbfsAvailable(): boolean {
try {
return !!(this.m.FS && this.m.FS.filesystems?.IDBFS);
} catch {
return false;
}
}
/** /**
* Initialize IDBFS for browser persistence. * Initialize IDBFS for browser persistence.
* Only works in browser environments with IDBFS available. * Only works in browser environments with IDBFS available.
*/ */
initIdbfs(path: string): void { initIdbfs(path: string): void {
// Check if FS and IDBFS are available (browser only) // Check if FS and IDBFS are available (browser only)
if (!this.m.FS || !this.m.FS.filesystems?.IDBFS) { if (!this.isIdbfsAvailable()) {
return; // Node.js or environment without IDBFS return; // Node.js or environment without IDBFS
} }
@@ -248,10 +259,11 @@ export class WasmBridge {
/** /**
* Sync IDBFS from IndexedDB to memory (async). * Sync IDBFS from IndexedDB to memory (async).
* Must be called after initIdbfs to load existing data from IndexedDB. * Must be called after initIdbfs to load existing data from IndexedDB.
* Only works in browser environments with IDBFS available.
*/ */
async syncIdbfsFromStorage(): Promise<void> { async syncIdbfsFromStorage(): Promise<void> {
if (!this.m.FS) { if (!this.isIdbfsAvailable()) {
return; // FS not available return; // IDBFS not available, skip silently
} }
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@@ -269,10 +281,11 @@ export class WasmBridge {
/** /**
* Sync IDBFS from memory to IndexedDB (async). * Sync IDBFS from memory to IndexedDB (async).
* Must be called after modifying files to persist them. * Must be called after modifying files to persist them.
* Only works in browser environments with IDBFS available.
*/ */
async syncIdbfsToStorage(): Promise<void> { async syncIdbfsToStorage(): Promise<void> {
if (!this.m.FS) { if (!this.isIdbfsAvailable()) {
return; // FS not available return; // IDBFS not available, skip silently
} }
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {