import type { Cache } from './Cache.js'; import type { CacheEventEmitter } from './CacheEventEmitter.js'; import type { ExpirationManager } from './expires.js'; import type { StatsManager } from './stats.js'; export type { Cache, CacheEventEmitter }; /** * Key used for cache entries. */ export type Key = any[]; /** * A single argument in a cache key. */ export type Arg = Key[number]; /** * The internal cache node used in the cache's linked list. */ export interface CacheNode any> { /** * The [n]ext node in the cache order. */ n: CacheNode | undefined; /** * The [p]revious node in the cache order. */ p: CacheNode | undefined; /** * If present, the node has been [r]emovd from cache. */ r?: true; /** * The [k]ey for the given node in cache. */ k: Key; /** * The cached [v]alue returned from the function call. */ v: ReturnType; } /** * The type of cache event fired. */ export type CacheEventType = 'add' | 'delete' | 'hit' | 'update'; interface CacheEventBase any> { /** * The cache associated with the given memoized function. */ cache: Cache; /** * The key of the affected node. */ key: Key; /** * The reason (if any) the operation was performed on the node. */ reason?: string; /** * The value of the affected node. */ value: ReturnType; /** * The type of operation performed on the node. */ type: CacheEventType; } /** * Cache event fired when a new entry is added. */ export interface OnAddEvent any> extends CacheEventBase { type: 'add'; } /** * Cache event fired when an existing entry is deleted. */ export interface OnDeleteEvent any> extends CacheEventBase { type: 'delete'; } /** * Cache event fired when the topmost entry in cache is retrieved. */ export interface OnHitEvent any> extends CacheEventBase { type: 'hit'; } /** * Cache event fired when an existing entry in cache is updated. This * can be either updating the recency of an older entry in cache or * the resolution / rejection of an async entry. */ export interface OnUpdateEvent any> extends CacheEventBase { type: 'update'; } /** * Cache event fired when a cache change occurs. */ export type CacheEvent any> = Type extends 'add' ? OnAddEvent : Type extends 'delete' ? OnDeleteEvent : Type extends 'hit' ? OnHitEvent : Type extends 'update' ? OnUpdateEvent : never; /** * A listener for the given type of cache event. */ export type CacheEventListener any> = (event: CacheEvent) => void; /** * Method use to trigger a forced update of cache. */ export type ForceUpdate any> = (args: Parameters) => boolean; /** * Method to retrieve the expiration duration in milliseconds based on * the values in cache. */ export type GetExpires any> = (key: Key, value: ReturnType, cache: Cache) => number; /** * Method to determine if two complete keys are equal. */ export type IsKeyEqual = (cachedKey: Key, nextKey: Key) => boolean; /** * Method to determine if individual key items are equal. */ export type IsKeyItemEqual = (cachedKeyItem: Arg, nextKeyItem: Arg, index: number) => boolean; /** * Method to serialize the key into a stringified key. */ export type Serializer = (key: Key) => [string]; /** * Method to determine whether the cache entry should not expire. */ export type ShouldPersist any> = (key: Key, value: ReturnType, cache: Cache) => boolean; /** * Method to determine whether the cache entry should be removed on expire, or * start a new expiration period. */ export type ShouldRemoveOnExpire any> = (key: Key, value: ReturnType, time: number, cache: Cache) => boolean; /** * Method to transform the arguments passed into a custom key format. */ export type TransformKey any> = (args: Parameters) => Key; /** * Advanced configuration for the `expires` option. */ export interface ExpiresConfig any> { /** * The amount of time before the cache entry is automatically removed. */ after: number | GetExpires; /** * Determine whether the cache entry should never expire. */ shouldPersist?: ShouldPersist; /** * Determine whether the cache entry should be removed upon expiration. * If `false` is returned, a new expiration is generated (not persistent). */ shouldRemove?: ShouldRemoveOnExpire; /** * Whether the cache entry expiration should be reset upon being hit. */ update?: boolean; } /** * Statistics object for a specific `statsName` profile. */ export interface ProfileStats { calls: number; hits: number; name: string; usage: string; } /** * Statistics for all possible profiles who have stats collected. */ export interface GlobalStats { calls: number; hits: number; profiles: Record; usage: string; } interface OptionsBase any> { /** * Whether the result of calling the function is a promise. This * will automatically remove the entry from cache if the promise is * rejected to avoid caching error states. */ async?: boolean; /** * Whether the entry in cache should automatically remove itself * after a period of time. */ expires?: number | GetExpires | ExpiresConfig; /** * Method to determine whether to bypass the cache to force an update * of the underlying entry based on new results. * * This should only be necessary if the memoized function is not * deterministic due to side-effects. */ forceUpdate?: ForceUpdate; /** * Whether the two keys are equal in value. This is used to compare * the key the function is called with against a given cache key to * determine whether the cached entry can be used. * * @note * If provided, the `isKeyItemEqual` option will be ignored. */ isKeyEqual?: IsKeyEqual; /** * Whether the two args are equal in value. This is used to compare * specific arguments in order for a cached key versus the key the * function is called with to determine whether the cached entry * can be used. * * @default `Object.is` * * @note * This option will be ignored if the `isKeyEqual` option is provided. */ isKeyItemEqual?: 'deep' | 'shallow' | IsKeyItemEqual; /** * The maximum number of args to consider for caching. */ maxArgs?: number; /** * The maximum number of entries to store in cache. * @default 1 */ maxSize?: number; /** * Whether to serialize the arguments into a string value for cache * purposes. A custom serializer can also be provided, if the default * one is insufficient. * * This can potentially be faster than `isKeyItemEqual: 'deep'` in rare * cases, but can also be used to provide a deep equal check that handles * circular references. */ serialize?: boolean | Serializer; /** * The name to give this method when recording profiling stats. */ statsName?: string; /** * Transform the parameters passed into a custom key for storage in * cache. */ transformKey?: TransformKey; } export interface OptionsNoCustomEqual any> extends OptionsBase { isKeyEqual?: never; isKeyItemEqual?: never; } export interface OptionsKeyEqual any> extends OptionsBase { isKeyEqual: IsKeyEqual; isKeyItemEqual?: never; } export interface OptionsKeyItemEqual any> extends OptionsBase { isKeyEqual?: never; isKeyItemEqual?: 'deep' | 'shallow' | IsKeyItemEqual; } /** * Configuration options to drive how entries are stored, checked for cache breakage, * and evicted from cache. */ export type Options any> = OptionsNoCustomEqual | OptionsKeyEqual | OptionsKeyItemEqual; /** * [key, value] pair for a given entry in cache. */ export type CacheEntry any> = [Key, ReturnType]; /** * Snapshot of the current cache state as a set of [key, value] entries. */ export interface CacheSnapshot any> { entries: Array>; keys: Key[]; size: number; values: Array>; } /** * Method that has been memoized via `micro-memoize`. */ export type Memoized any, Opts extends Options> = Fn & { /** * The cache used for the memoized method. */ cache: Cache; /** * Manager for the expirations cache. This is only populated when * `options.expires` is set. */ expirationManager: ExpirationManager | null; /** * The original method that is memoized. */ fn: Fn; /** * Simple identifier that the function has been memoized. */ isMemoized: true; /** * Options passed for the memoized method. */ options: Opts; /** * Manager for the stats cache. This is only populated when `options.statsName` * is set. */ statsManager: StatsManager | null; }; export interface Memoize { any, Options<(...args: any[]) => any>>>(fn: Fn): Memoized; any, Options<(...args: any[]) => any>>, Opts extends Options>(fn: Fn, passedOptions: Opts): Memoized; any>(fn: Fn): Memoized; any, Opts extends Options>(fn: Fn, passedOptions: Opts): Memoized; }