import { IndexedDBError } from './IndexedDBError' import type { CoreAccessors } from './core' import { getObjectStore } from './store' export async function getValue(accessors: CoreAccessors, key: string | number): Promise { const {storeName} = accessors.getConfig() try { const store = await getObjectStore(accessors, 'readonly') return await wrapRequest(store.get(key), 'get', storeName, (r) => (r.result as T) ?? null) } catch (error) { throw ensureIndexedDBError(error, 'get', storeName) } } export async function getByIndex(accessors: CoreAccessors, indexName: string, key: string | number): Promise { const {storeName} = accessors.getConfig() try { const store = await getObjectStore(accessors, 'readonly') const index = store.index(indexName) return await wrapRequest(index.get(key), 'getByIndex', storeName, (r) => (r.result as T) ?? null) } catch (error) { throw ensureIndexedDBError(error, 'getByIndex', storeName) } } export async function getAllByIndex(accessors: CoreAccessors, indexName: string, key?: IDBValidKey | IDBKeyRange): Promise { const {storeName} = accessors.getConfig() try { const store = await getObjectStore(accessors, 'readonly') const index = store.index(indexName) const request = key !== undefined ? index.getAll(key) : index.getAll() return await wrapRequest(request, 'getAllByIndex', storeName, (r) => (r.result as T[]) ?? []) } catch (error) { throw ensureIndexedDBError(error, 'getAllByIndex', storeName) } } export async function getAll(accessors: CoreAccessors, range?: IDBKeyRange, count?: number): Promise { const {storeName} = accessors.getConfig() try { const store = await getObjectStore(accessors, 'readonly') const request = range ? store.getAll(range, count) : store.getAll(undefined, count) return await wrapRequest(request, 'getAll', storeName, (r) => (r.result as T[]) ?? []) } catch (error) { throw ensureIndexedDBError(error, 'getAll', storeName) } } function wrapRequest( requestParam: IDBRequest, operation: string, storeName: string, mapResult: (request: IDBRequest) => TResult ): Promise { return new Promise((resolve, reject) => { const request = requestParam request.onsuccess = (): void => resolve(mapResult(request)) request.onerror = (): void => reject(new IndexedDBError(`Failed to ${operation}: ${request.error}`, operation, storeName, request.error)) }) } function ensureIndexedDBError(error: unknown, operation: string, storeName: string): IndexedDBError { if (error instanceof IndexedDBError) { return error } return new IndexedDBError(error instanceof Error ? error.message : 'Unknown error', operation, storeName, error) }