35 lines
1.2 KiB
TypeScript
35 lines
1.2 KiB
TypeScript
// @ts-nocheck
|
|
export type TxMode = 'readonly' | 'readwrite';
|
|
|
|
export function openDB(): Promise<IDBDatabase> {
|
|
return new Promise((resolve, reject) => {
|
|
const req = indexedDB.open('guest-upload-queue', 1);
|
|
req.onupgradeneeded = () => {
|
|
const db = req.result;
|
|
if (!db.objectStoreNames.contains('items')) {
|
|
const store = db.createObjectStore('items', { keyPath: 'id', autoIncrement: true });
|
|
store.createIndex('status', 'status', { unique: false });
|
|
store.createIndex('nextAttemptAt', 'nextAttemptAt', { unique: false });
|
|
}
|
|
};
|
|
req.onsuccess = () => resolve(req.result);
|
|
req.onerror = () => reject(req.error);
|
|
});
|
|
}
|
|
|
|
export async function withStore<T>(mode: TxMode, fn: (store: IDBObjectStore) => void | Promise<T>): Promise<T> {
|
|
const db = await openDB();
|
|
return new Promise((resolve, reject) => {
|
|
const tx = db.transaction('items', mode);
|
|
const store = tx.objectStore('items');
|
|
let result: unknown;
|
|
const wrap = async () => {
|
|
try { result = await fn(store); } catch (e) { reject(e); }
|
|
};
|
|
wrap();
|
|
tx.oncomplete = () => resolve(result);
|
|
tx.onerror = () => reject(tx.error);
|
|
tx.onabort = () => reject(tx.error);
|
|
});
|
|
}
|