474b09c7f2
* perf: add perf_hooks * perf: add cache * fix: test * feat: support bloom filter * feat: caching token black list * perf: caching i18n instance * fix: test * fix: test * chore: remove prePerfHooks on app * chore: improve i18n instances cache * chore: remove performance measure * fix: package.json * perf: optimize cache strategy * fix: test * fix: bug * test: storer of auth-manager * fix: afterDestroy hook when updating null value * fix: version * chore: fix bug and add test * fix: test * fix: test
107 lines
2.8 KiB
TypeScript
107 lines
2.8 KiB
TypeScript
import { Cache as BasicCache, Milliseconds } from 'cache-manager';
|
|
|
|
export class Cache {
|
|
name: string;
|
|
prefix?: string;
|
|
store: BasicCache;
|
|
|
|
constructor({ name, prefix, store }: { name: string; store: BasicCache; prefix?: string }) {
|
|
this.name = name;
|
|
this.prefix = prefix;
|
|
this.store = store;
|
|
}
|
|
|
|
key(key: string): string {
|
|
return this.prefix ? `${this.prefix}:${key}` : key;
|
|
}
|
|
|
|
async set(key: string, value: unknown, ttl?: Milliseconds): Promise<void> {
|
|
await this.store.set(this.key(key), value, ttl);
|
|
}
|
|
|
|
async get<T>(key: string): Promise<T> {
|
|
return await this.store.get(this.key(key));
|
|
}
|
|
|
|
async del(key: string): Promise<void> {
|
|
await this.store.del(this.key(key));
|
|
}
|
|
|
|
async reset(): Promise<void> {
|
|
await this.store.reset();
|
|
}
|
|
|
|
async wrap<T>(key: string, fn: () => Promise<T>, ttl?: Milliseconds): Promise<T> {
|
|
return await this.store.wrap(this.key(key), fn, ttl);
|
|
}
|
|
|
|
async wrapWithCondition<T>(
|
|
key: string,
|
|
fn: () => T | Promise<T>,
|
|
options?: {
|
|
useCache?: boolean;
|
|
isCacheable?: (val: unknown) => boolean | Promise<boolean>;
|
|
ttl?: Milliseconds;
|
|
},
|
|
): Promise<T> {
|
|
const { useCache, isCacheable, ttl } = options || {};
|
|
if (useCache === false) {
|
|
return await fn();
|
|
}
|
|
const value = await this.get<T>(key);
|
|
if (value) {
|
|
return value;
|
|
}
|
|
const result = await fn();
|
|
const cacheable = isCacheable ? await isCacheable(result) : result;
|
|
if (!cacheable) {
|
|
return result;
|
|
}
|
|
await this.set(key, result, ttl);
|
|
return result;
|
|
}
|
|
|
|
async mset(args: [string, unknown][], ttl?: Milliseconds): Promise<void> {
|
|
await this.store.store.mset(
|
|
args.map(([key, value]) => [this.key(key), value]),
|
|
ttl,
|
|
);
|
|
}
|
|
|
|
async mget(...args: string[]): Promise<unknown[]> {
|
|
args = args.map((key) => this.key(key));
|
|
return await this.store.store.mget(...args);
|
|
}
|
|
|
|
async mdel(...args: string[]): Promise<void> {
|
|
args = args.map((key) => this.key(key));
|
|
await this.store.store.mdel(...args);
|
|
}
|
|
|
|
async keys(pattern?: string): Promise<string[]> {
|
|
const keys = await this.store.store.keys(pattern);
|
|
return keys.map((key) => key.replace(`${this.name}:`, ''));
|
|
}
|
|
|
|
async ttl(key: string): Promise<number> {
|
|
return await this.store.store.ttl(this.key(key));
|
|
}
|
|
|
|
async setValueInObject(key: string, objectKey: string, value: unknown) {
|
|
const object = (await this.get(key)) || {};
|
|
object[objectKey] = value;
|
|
await this.set(key, object);
|
|
}
|
|
|
|
async getValueInObject(key: string, objectKey: string) {
|
|
const object = (await this.get(key)) || {};
|
|
return object[objectKey];
|
|
}
|
|
|
|
async delValueInObject(key: string, objectKey: string) {
|
|
const object = (await this.get(key)) || {};
|
|
delete object[objectKey];
|
|
await this.set(key, object);
|
|
}
|
|
}
|