Spaces:
Running
Running
| import type { AssetRecord } from "../lib/types"; | |
| const STORAGE_DB_NAME = "onnx-web-inspector"; | |
| const STORAGE_STORE_NAME = "assets"; | |
| export function useAssetStorage() { | |
| let assetDbPromise: Promise<IDBDatabase> | null = null; | |
| async function getAssetDb(): Promise<IDBDatabase> { | |
| if (!("indexedDB" in window)) { | |
| throw new Error("IndexedDB is not available in this browser."); | |
| } | |
| if (!assetDbPromise) { | |
| assetDbPromise = new Promise((resolve, reject) => { | |
| const request = window.indexedDB.open(STORAGE_DB_NAME, 1); | |
| request.onupgradeneeded = () => { | |
| request.result.createObjectStore(STORAGE_STORE_NAME, { keyPath: "key" }); | |
| }; | |
| request.onsuccess = () => resolve(request.result); | |
| request.onerror = () => reject(request.error || new Error("Failed to open IndexedDB.")); | |
| }); | |
| } | |
| return assetDbPromise; | |
| } | |
| async function persistAsset(key: "model" | "image", asset: AssetRecord): Promise<void> { | |
| const db = await getAssetDb(); | |
| await new Promise<void>((resolve, reject) => { | |
| const tx = db.transaction(STORAGE_STORE_NAME, "readwrite"); | |
| tx.oncomplete = () => resolve(); | |
| tx.onerror = () => reject(tx.error || new Error("Failed to save asset.")); | |
| tx.objectStore(STORAGE_STORE_NAME).put({ | |
| key, | |
| name: asset.name, | |
| size: asset.size, | |
| type: asset.type, | |
| blob: asset.blob, | |
| savedAt: Date.now(), | |
| }); | |
| }); | |
| } | |
| async function loadPersistedAsset(key: "model" | "image"): Promise<AssetRecord | null> { | |
| const db = await getAssetDb(); | |
| const record = await new Promise<Record<string, unknown> | null>((resolve, reject) => { | |
| const tx = db.transaction(STORAGE_STORE_NAME, "readonly"); | |
| const request = tx.objectStore(STORAGE_STORE_NAME).get(key); | |
| request.onsuccess = () => resolve((request.result as Record<string, unknown>) || null); | |
| request.onerror = () => reject(request.error || new Error("Failed to load saved asset.")); | |
| }); | |
| const blob = record?.blob; | |
| if (!(blob instanceof Blob)) { | |
| return null; | |
| } | |
| return { | |
| name: typeof record?.name === "string" ? record.name : `${key}.bin`, | |
| size: typeof record?.size === "number" ? record.size : blob.size, | |
| type: typeof record?.type === "string" ? record.type : blob.type, | |
| blob, | |
| saved: true, | |
| }; | |
| } | |
| async function deletePersistedAsset(key: "model" | "image"): Promise<void> { | |
| const db = await getAssetDb(); | |
| await new Promise<void>((resolve, reject) => { | |
| const tx = db.transaction(STORAGE_STORE_NAME, "readwrite"); | |
| tx.oncomplete = () => resolve(); | |
| tx.onerror = () => reject(tx.error || new Error("Failed to delete asset.")); | |
| tx.objectStore(STORAGE_STORE_NAME).delete(key); | |
| }); | |
| } | |
| return { | |
| persistAsset, | |
| loadPersistedAsset, | |
| deletePersistedAsset, | |
| }; | |
| } | |