import { openDB, IndexNames, StoreNames, StoreValue } from "idb"; import getDb, { NovelDb } from "./getDb"; export async function putItem>( storeNames: N, item: StoreValue ) { const db = await getDb(); const tx = db.transaction(storeNames, "readwrite"); const store = tx.store; store.put(item); return tx.done; } export async function delItem>( storeNames: N, key: NovelDb[N]["key"] ) { const db = await getDb(); const tx = db.transaction(storeNames, "readwrite"); const store = tx.store; store.delete(key); return tx.done; } export async function getItem>( storeNames: N, key: NovelDb[N]["key"] ) { const db = await getDb(); const tx = db.transaction(storeNames, "readonly"); const store = tx.store; return store.get(key); } export const putHistoryItem = (item: HistoryItem) => putItem("history", item); export const delHistoryItem = (key: string) => delItem("history", key); export const getHistoryItem = (key: string) => getItem("history", key); export async function getList< N extends StoreNames, R extends [any, any, boolean?, boolean?] >( storeName: N, index?: IndexNames, page = 0, pageSize = 20, direction: IDBCursorDirection = "next", rage?: R ): Promise> { const db = await getDb(); const tx = db.transaction(storeName, "readonly"); const store = tx.store; const keyRangeValue = rage ? IDBKeyRange.bound.apply(void 0, rage) : null; let [cursor, total] = await Promise.all([ index ? store.index(index).openCursor(keyRangeValue, direction) : store.openCursor(), store.count(), ]); type ValueItem = StoreValue; const list: ValueItem[] = []; const res: PageList = { list, total, page, pageSize, }; if (!cursor) return res; if (page > 0) { cursor = await cursor.advance(page * pageSize); } while (cursor) { list.push(cursor.value); if (pageSize === list.length) { break; } cursor = await cursor.continue(); } return res; } function genGetList< N extends StoreNames, R extends [any, any, boolean?, boolean?] >( storeName: N, index?: IndexNames, direction: IDBCursorDirection = "next", defaultRange?: R ) { return async function ( page = 0, pageSize = 20, rage = defaultRange ): Promise> { return getList(storeName, index, page, pageSize, direction, rage); }; } export const getHistoryList = genGetList( "history", "historyIsReading", "prev", [ [1, 0], [1, new Date()], ] ); export const getFavoriteList = genGetList( "history", "historyIsFavorite", "prev", [1, 1] );