124 lines
2.9 KiB
TypeScript
124 lines
2.9 KiB
TypeScript
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<T = any>(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<T = any>(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<boolean> {
|
|
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);
|
|
}
|
|
}
|