UNPKG

jinaga

Version:

Data management for web and mobile applications.

72 lines (64 loc) 2.96 kB
import { FactReference } from '../storage'; function upgradingToVersion({ newVersion, oldVersion }: IDBVersionChangeEvent, ver: number) { return newVersion && newVersion >= ver && oldVersion < ver; } function openDatabase(indexName: string): Promise<IDBDatabase> { return new Promise((resolve, reject) => { const request = global.indexedDB.open(indexName, 2); request.onsuccess = _ => resolve(request.result); request.onerror = _ => reject(`Error opening database ${indexName}: ${JSON.stringify(request.error, null, 2)}.`); request.onupgradeneeded = ev => { const db = request.result; if (upgradingToVersion(ev, 1)) { db.createObjectStore('login'); db.createObjectStore('fact'); db.createObjectStore('ancestor'); const edgeObjectStore = db.createObjectStore('edge', { keyPath: ['successor', 'predecessor', 'role'] }); edgeObjectStore.createIndex('predecessor', ['predecessor', 'role'], { unique: false }); edgeObjectStore.createIndex('successor', ['successor', 'role'], { unique: false }); edgeObjectStore.createIndex('all', 'successor', { unique: false }); db.createObjectStore('queue'); } if (upgradingToVersion(ev, 2)) { db.createObjectStore('bookmark'); const specificationObjectStore = db.createObjectStore('specification'); specificationObjectStore.createIndex('mru', '', { unique: false }); } } }); } export async function withDatabase<T>(indexName: string, action: (db: IDBDatabase) => Promise<T>) { const db = await openDatabase(indexName); const result = await action(db); db.close(); return result; } export async function withTransaction<T>(db: IDBDatabase, storeNames: string[], mode: IDBTransactionMode, action: (transaction: IDBTransaction) => Promise<T>) { const transaction = db.transaction(storeNames, mode); const transactionComplete = new Promise<void>((resolve, reject) => { transaction.oncomplete = _ => resolve(); transaction.onerror = _ => reject(`Error executing transaction ${JSON.stringify(transaction.error?.message, null, 2)}`); }); const [result, v] = await Promise.all([action(transaction), transactionComplete]); return result; } export function execRequest<T>(request: IDBRequest) { return new Promise<T>((resolve, reject) => { request.onsuccess = (_: Event) => resolve(request.result); request.onerror = (_: Event) => reject(`Error executing request ${JSON.stringify(request.error?.message, null, 2)}`); }); } export function factKey(fact: FactReference) { return `${fact.type}:${fact.hash}`; } export function keyToReference(key: string): FactReference { const regex = /([^:]*):(.*)/; const match = regex.exec(key); if (!match) { throw new Error(`Invalid key ${key}`); } const [ _, type, hash ] = match; return { type, hash }; }