import { createStore, UseStore, get, set, del, clear, keys, values, entries, update, setMany, getMany, delMany } from 'idb-keyval'; /** * 缓存存储选项 */ export type CacheStoreOpts = { /** * 数据库名称 */ dbName?: string; /** * 存储空间名称 */ storeName?: string; }; export class BaseCacheStore { store: UseStore; constructor(opts?: CacheStoreOpts) { this.store = createStore(opts?.dbName || 'default-db', opts?.storeName || 'cache-store'); } async get(key: string) { return get(key, this.store); } async set(key: string, value: any) { return set(key, value, this.store); } async del(key: string) { return del(key, this.store); } async clear() { return clear(this.store); } async keys() { return keys(this.store); } async values() { return values(this.store); } async entries() { return entries(this.store); } async update(key: string, updater: (value: any) => any) { return update(key, updater, this.store); } async setMany(entries: [string, any][]) { return setMany(entries, this.store); } async getMany(keys: string[]) { return getMany(keys, this.store); } async delMany(keys: string[]) { return delMany(keys, this.store); } } /** * 缓存存储 */ export class CacheStore extends BaseCacheStore { constructor(opts?: CacheStoreOpts) { super(opts); } async getData(key: string) { const data = await this.get(key); return data.data as T; } async setData(key: string, data: any) { return this.set(key, data); } /** * 获取缓存数据,并检查是否过期 * @param key 缓存键 * @returns 缓存数据 */ async getCheckData(key: string) { const data = await this.get(key); if (data.expireTime && data.expireTime < Date.now()) { await super.del(key); return null; } return data.data as T; } /** * 设置缓存数据,并检查是否过期 * @param key 缓存键 * @param data 缓存数据 * @param opts 缓存选项 * @returns 缓存数据 */ async setCheckData(key: string, data: any, opts?: { expireTime?: number; updatedAt?: number }) { const now = Date.now(); const expireTime = now + (opts?.expireTime || 1000 * 60 * 60 * 24 * 10); const newData = { data, updatedAt: opts?.updatedAt || Date.now(), expireTime, }; await this.set(key, newData); return data; } async checkNew(key: string, data: any): Promise { const existing = await this.get(key); if (!existing) { return true; } if (!data?.updatedAt) { return false; } const updatedAt = new Date(data.updatedAt).getTime(); if (isNaN(updatedAt)) { return false; } return updatedAt > existing.updatedAt; } /** * 删除缓存数据 * @param key 缓存键 * @returns 缓存数据 */ async delCheckData(key: string) { return this.del(key); } }