UNPKG

cache-entanglement

Version:

Manage caches that are dependent on each other efficiently.

99 lines (98 loc) 5.55 kB
import type { CacheData } from './CacheData'; import { LRUMap } from './utils/LRUMap'; type Deferred<T> = T | Promise<T>; type ValueRecord<T> = { [key: string]: T; }; export type CacheGetter<R extends ValueRecord<any>> = (key: string, cache: R, ...initialParameter: any) => any; export type CacheGetterParams<C extends CacheGetter<any>> = C extends (key: string, cache: any, ...parameter: infer P) => any ? P : never; export type DependencyMap = ValueRecord<CacheEntanglement<DependencyMap, CacheGetter<any>>>; export type DependencyCacheData<T extends (DependencyMap | ValueRecord<any>)> = { [K in keyof T]: T[K] extends CacheEntanglement<any, infer R> ? CacheData<Awaited<ReturnType<R>>> : CacheData<T[K]>; }; export type BeforeUpdateHookSync<D extends DependencyMap, G extends CacheGetter<DependencyCacheData<D>>> = (key: string, dependencyKey: string, ...initialParameter: CacheGetterParams<G>) => void; export type BeforeUpdateHookAsync<D extends DependencyMap, G extends CacheGetter<DependencyCacheData<D>>> = (key: string, dependencyKey: string, ...initialParameter: CacheGetterParams<G>) => Promise<void>; export type BeforeUpdateHook<D extends DependencyMap, G extends CacheGetter<DependencyCacheData<D>>> = BeforeUpdateHookSync<D, G> | BeforeUpdateHookAsync<D, G>; export interface CacheEntanglementConstructorOption<D extends DependencyMap, G extends CacheGetter<DependencyCacheData<D>>> { /** * The dependencies of the cache value. * The key of the object is the name of the dependency, and the value is the CacheEntanglement instance. * The dependency cache value is passed to the creation function as the second parameter. */ dependencies?: D; /** * A hook that is called before the cache value is updated. * This hook is called before the creation function is called. * You can use this hook to update the dependency cache values before the creation function is called. * @param key The key of the cache value to be updated. * @param dependencyKey The key of the dependency cache value to be updated. * @param initialParameter The parameter of the cache creation function passed when creating the instance. */ beforeUpdateHook?: BeforeUpdateHook<D, G>; /** * The capacity of the cache. * If the number of cache values exceeds this value, the least recently used cache values will be removed. */ capacity?: number; } export declare abstract class CacheEntanglement<D extends DependencyMap, G extends CacheGetter<DependencyCacheData<D>>> { protected readonly creation: G; protected readonly beforeUpdateHook: BeforeUpdateHook<D, G>; protected readonly capacity: number; protected readonly dependencies: D; protected readonly caches: LRUMap<string, CacheData<Awaited<ReturnType<G>>>>; protected readonly parameters: Map<string, CacheGetterParams<G>>; protected readonly assignments: CacheEntanglement<any, any>[]; protected readonly dependencyProperties: (keyof D)[]; protected readonly updateRequirements: Set<string>; constructor(creation: G, option?: CacheEntanglementConstructorOption<D, G>); protected abstract recache(key: string): Deferred<CacheData<Awaited<ReturnType<G>>> | undefined>; protected abstract resolve(key: string, ...parameter: CacheGetterParams<G>): Deferred<CacheData<Awaited<ReturnType<G>>>>; protected bubbleUpdateSignal(key: string): void; protected dependencyKey(key: string): string; /** * Returns all keys stored in the instance. */ keys(): IterableIterator<string>; /** * Deletes all cache values stored in the instance. */ clear(): void; /** * Checks if there is a cache value stored in the key within the instance. * @param key The key to search. */ exists(key: string): boolean; /** * Checks if there is a cache value stored in the key within the instance. * This method is an alias for `exists`. * @param key The key to search. */ has(key: string): boolean; /** * Deletes the cache value stored in the key within the instance. * @param key The key to delete. */ delete(key: string): void; /** * Returns the cache value stored in the key within the instance. If the cached value is not present, an error is thrown. * @param key The key to search. */ abstract get(key: string): Deferred<CacheData<Awaited<ReturnType<G>>>>; /** * Returns the cache value of the key assigned to the instance. * If the cached value is not present, the creation function is called, and the returned value is cached. * And this value is returned. * @param key The key value of the cache value. This value must be unique within the instance. * @param parameter The parameter of the cache creation function passed when creating the instance. */ abstract cache(key: string, ...parameter: CacheGetterParams<G>): Deferred<CacheData<Awaited<ReturnType<G>>>>; /** * Re-calls the creation function passed when creating the instance and stores the returned value in the cache again. * And this value is returned. This is used to forcefully update the value. * @param key The key value of the cache value. This value must be unique within the instance. * @param parameter The parameter of the cache creation function passed when creating the instance. */ abstract update(key: string, ...parameter: CacheGetterParams<G>): Deferred<CacheData<Awaited<ReturnType<G>>>>; } export {};