2026-01-13 14:49:19 +01:00

78 lines
3.2 KiB
TypeScript

import { IndexedDBError } from './IndexedDBError'
import type { CoreAccessors } from './core'
import { getObjectStore } from './store'
export async function openCursor(accessors: CoreAccessors, direction?: IDBCursorDirection, range?: IDBKeyRange): Promise<IDBCursorWithValue | null> {
const {storeName} = accessors.getConfig()
try {
const store = await getObjectStore(accessors, 'readonly')
const request = range ? store.openCursor(range, direction) : store.openCursor(direction)
return await wrapCursorRequest(request, 'openCursor', storeName)
} catch (error) {
throw ensureIndexedDBError(error, 'openCursor', storeName)
}
}
export async function openCursorOnIndex(
accessors: CoreAccessors,
indexName: string,
direction?: IDBCursorDirection,
range?: IDBKeyRange
): Promise<IDBCursorWithValue | null> {
const {storeName} = accessors.getConfig()
try {
const store = await getObjectStore(accessors, 'readonly')
const index = store.index(indexName)
const request = range ? index.openCursor(range, direction) : index.openCursor(direction)
return await wrapCursorRequest(request, 'openCursorOnIndex', storeName)
} catch (error) {
throw ensureIndexedDBError(error, 'openCursorOnIndex', storeName)
}
}
export async function count(accessors: CoreAccessors, range?: IDBKeyRange): Promise<number> {
const {storeName} = accessors.getConfig()
try {
const store = await getObjectStore(accessors, 'readonly')
const request = range ? store.count(range) : store.count()
return await wrapNumberRequest(request, 'count', storeName)
} catch (error) {
throw ensureIndexedDBError(error, 'count', storeName)
}
}
export async function countByIndex(accessors: CoreAccessors, indexName: string, range?: IDBKeyRange): Promise<number> {
const {storeName} = accessors.getConfig()
try {
const store = await getObjectStore(accessors, 'readonly')
const index = store.index(indexName)
const request = range ? index.count(range) : index.count()
return await wrapNumberRequest(request, 'countByIndex', storeName)
} catch (error) {
throw ensureIndexedDBError(error, 'countByIndex', storeName)
}
}
function wrapCursorRequest(requestParam: IDBRequest, operation: string, storeName: string): Promise<IDBCursorWithValue | null> {
return new Promise((resolve, reject) => {
const request = requestParam
request.onsuccess = (): void => resolve(request.result as IDBCursorWithValue | null)
request.onerror = (): void => reject(new IndexedDBError(`Failed to ${operation}: ${request.error}`, operation, storeName, request.error))
})
}
function wrapNumberRequest(requestParam: IDBRequest, operation: string, storeName: string): Promise<number> {
return new Promise((resolve, reject) => {
const request = requestParam
request.onsuccess = (): void => resolve(request.result as number)
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)
}