File size: 2,892 Bytes
817dfdc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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,
  };
}