68 lines
2.8 KiB
TypeScript
68 lines
2.8 KiB
TypeScript
import { IndexedDBError } from './IndexedDBError'
|
|
import type { CoreAccessors } from './core'
|
|
import { getObjectStore } from './store'
|
|
|
|
export async function getValue<T>(accessors: CoreAccessors, key: string | number): Promise<T | null> {
|
|
const {storeName} = accessors.getConfig()
|
|
try {
|
|
const store = await getObjectStore(accessors, 'readonly')
|
|
return await wrapRequest<T | null>(store.get(key), 'get', storeName, (r) => (r.result as T) ?? null)
|
|
} catch (error) {
|
|
throw ensureIndexedDBError(error, 'get', storeName)
|
|
}
|
|
}
|
|
|
|
export async function getByIndex<T>(accessors: CoreAccessors, indexName: string, key: string | number): Promise<T | null> {
|
|
const {storeName} = accessors.getConfig()
|
|
try {
|
|
const store = await getObjectStore(accessors, 'readonly')
|
|
const index = store.index(indexName)
|
|
return await wrapRequest<T | null>(index.get(key), 'getByIndex', storeName, (r) => (r.result as T) ?? null)
|
|
} catch (error) {
|
|
throw ensureIndexedDBError(error, 'getByIndex', storeName)
|
|
}
|
|
}
|
|
|
|
export async function getAllByIndex<T>(accessors: CoreAccessors, indexName: string, key?: IDBValidKey | IDBKeyRange): Promise<T[]> {
|
|
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<T[]>(request, 'getAllByIndex', storeName, (r) => (r.result as T[]) ?? [])
|
|
} catch (error) {
|
|
throw ensureIndexedDBError(error, 'getAllByIndex', storeName)
|
|
}
|
|
}
|
|
|
|
export async function getAll<T>(accessors: CoreAccessors, range?: IDBKeyRange, count?: number): Promise<T[]> {
|
|
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<T[]>(request, 'getAll', storeName, (r) => (r.result as T[]) ?? [])
|
|
} catch (error) {
|
|
throw ensureIndexedDBError(error, 'getAll', storeName)
|
|
}
|
|
}
|
|
|
|
function wrapRequest<TResult>(
|
|
requestParam: IDBRequest,
|
|
operation: string,
|
|
storeName: string,
|
|
mapResult: (request: IDBRequest) => TResult
|
|
): Promise<TResult> {
|
|
return new Promise<TResult>((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)
|
|
}
|