idb.jsannotatedidb.jssource160 lines · 5.0 KB · raw
1/**
2 * @param key {string}
3 * @returns {Promise<Object.<string, Uint8Array>>}
4 */
5export function loadSaveFiles(key) {
6    return new Promise((resolve, reject) => {
7        const openReq = indexedDB.open("saves");
8
9        openReq.onerror = () => reject(`Failed to open IndexedDB for read, key ${key}`);
10
11        openReq.onupgradeneeded = (event) => {
12            const db = event.target.result;
13            db.createObjectStore("files", { keyPath: "key" });
14        };
15
16        openReq.onsuccess = (event) => {
17            const db = event.target.result;
18            const tx = db.transaction(["files"]);
19
20            tx.onerror = () => reject(`IndexedDB transaction error for key ${key}: ${tx.error}`);
21
22            const objectStore = tx.objectStore("files");
23            const objectReq = objectStore.get(key);
24
25            objectReq.onerror = () => reject(`Failed to read from IndexedDB for key ${key}`);
26
27            objectReq.onsuccess = (event) => {
28                const value = event.target.result;
29                if (!value || !value["data"]) {
30                    resolve({});
31                    return;
32                }
33
34                const files = {};
35                Object.keys(value["data"]).forEach((extension) => {
36                    files[extension] = value["data"][extension];
37                });
38
39                resolve(files);
40            };
41        };
42    });
43}
44
45/**
46 * @param key {string}
47 * @param extension {string}
48 * @param bytes {Uint8Array}
49 * @returns {Promise<void>}
50 */
51export function writeSaveFile(key, extension, bytes) {
52    return new Promise((resolve, reject) => {
53        const openReq = indexedDB.open("saves");
54
55        openReq.onerror = () => reject(`Failed to open IndexedDB for write, key ${key} extension ${extension}`);
56
57        openReq.onupgradeneeded = (event) => {
58            const db = event.target.result;
59            db.createObjectStore("files", { keyPath: "key" });
60        };
61
62        openReq.onsuccess = (event) => {
63            const db = event.target.result;
64            const tx = db.transaction(["files"], "readwrite");
65
66            tx.onerror = () => reject(`IndexedDB transaction error for key ${key} extension ${extension}: ${tx.error}`);
67
68            const objectStore = tx.objectStore("files");
69
70            const getReq = objectStore.get(key);
71
72            getReq.onerror = () => reject(`Failed to read from IndexedDB for key ${key} extension ${extension}`);
73
74            getReq.onsuccess = (event) => {
75                let value = event.target.result;
76                if (!value || !value["data"]) {
77                    value = { key, data: {} };
78                }
79
80                value["data"][extension] = bytes;
81
82                const putReq = objectStore.put(value);
83
84                putReq.onerror = () => reject(`Failed to write to IndexedDB for key ${key} extension ${extension}`);
85
86                putReq.onsuccess = () => resolve();
87            };
88        };
89    });
90}
91
92/**
93 * @param key {string}
94 * @returns {Promise<Uint8Array | null>}
95 */
96export function loadBios(key) {
97    return new Promise((resolve, reject) => {
98        const openReq = indexedDB.open("bios_roms");
99
100        openReq.onerror = () => reject(`Failed to open IndexedDB for read, key ${key}`);
101
102        openReq.onupgradeneeded = (event) => {
103            const db = event.target.result;
104            db.createObjectStore("files", { keyPath: "key" });
105        };
106
107        openReq.onsuccess = (event) => {
108            const db = event.target.result;
109            const tx = db.transaction(["files"]);
110
111            tx.onerror = () => reject(`IndexedDB transaction error for key ${key}: ${tx.error}`);
112
113            const objectStore = tx.objectStore("files");
114            const getReq = objectStore.get(key);
115
116            getReq.onerror = () => reject(`Failed to read from IndexedDB for key ${key}`);
117
118            getReq.onsuccess = (event) => {
119                const value = event.target.result;
120                if (value && value["data"]) {
121                    resolve(value["data"]);
122                } else {
123                    resolve(null);
124                }
125            };
126        };
127    });
128}
129
130/**
131 * @param key {string}
132 * @param bytes {Uint8Array}
133 * @returns {Promise<void>}
134 */
135export function writeBios(key, bytes) {
136    return new Promise((resolve, reject) => {
137        const openReq = indexedDB.open("bios_roms");
138
139        openReq.onerror = () => reject(`Failed to open IndexedDB for read, key ${key}`);
140
141        openReq.onupgradeneeded = (event) => {
142            const db = event.target.result;
143            db.createObjectStore("files", { keyPath: "key" });
144        };
145
146        openReq.onsuccess = (event) => {
147            const db = event.target.result;
148            const tx = db.transaction(["files"], "readwrite");
149
150            tx.onerror = () => reject(`IndexedDB transaction error for key ${key}: ${tx.error}`);
151
152            const objectStore = tx.objectStore("files");
153            const putReq = objectStore.put({ key, data: bytes });
154
155            putReq.onerror = () => reject(`Failed to write to IndexedDB for key ${key}`);
156
157            putReq.onsuccess = () => resolve();
158        };
159    });
160}