import Dexie, { Table } from "dexie"; import type { KV, KVStore } from "./kv_store.ts"; export class DexieKVStore implements KVStore { db: Dexie; items: Table; constructor( dbName: string, tableName: string, indexedDB?: any, IDBKeyRange?: any, ) { this.db = new Dexie(dbName, { indexedDB, IDBKeyRange, }); this.db.version(1).stores({ [tableName]: "key", }); this.items = this.db.table(tableName); } async del(key: string) { await this.items.delete(key); } async deletePrefix(prefix: string) { await this.items.where("key").startsWith(prefix).delete(); } async deleteAll() { await this.items.clear(); } async set(key: string, value: any) { await this.items.put({ key, value, }); } async batchSet(kvs: KV[]) { await this.items.bulkPut( kvs.map(({ key, value }) => ({ key, value, })), ); } async batchDelete(keys: string[]) { await this.items.bulkDelete(keys); } async batchGet( keys: string[], ): Promise<(any | undefined)[]> { return (await this.items.bulkGet(keys)).map((result) => result?.value); } async get(key: string): Promise { const result = await this.items.get({ key }); return result ? result.value : null; } async has(key: string): Promise { return await this.items.get({ key, }) !== undefined; } async queryPrefix( keyPrefix: string, ): Promise<{ key: string; value: any }[]> { const results = await this.items.where("key").startsWith(keyPrefix) .toArray(); return results.map((result) => ({ key: result.key, value: result.value, })); } }