78 lines
3.2 KiB
TypeScript
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)
|
|
}
|