UNPKG

@sv443-network/coreutils

Version:

Cross-platform, general-purpose, JavaScript core library for Node, Deno and the browser. Intended to be used in conjunction with `@sv443-network/userutils` and `@sv443-network/djsutils`, but can be used independently as well.

87 lines (86 loc) 5.86 kB
/** * @module TieredCache * This module contains the TieredCache class, which is a cache that can have multiple tiers with different max TTLs, with data being moved between tiers based on what is fetched the most. */ import { DataStore, type DataStoreData } from "./DataStore.js"; import { NanoEmitter, type NanoEmitterOptions } from "./NanoEmitter.js"; import type { DataStoreEngine } from "./DataStoreEngine.js"; import type { Prettify } from "./types.js"; /** Options for the {@linkcode TieredCache} class. */ export type TieredCacheOptions<TData extends DataStoreData> = Prettify<{ /** Unique identifier for this cache. */ id: string; /** The available cache tiers. */ tiers: TieredCacheTierOptions<TData>[]; /** Optional options to pass to the {@linkcode NanoEmitter} constructor. */ nanoEmitterOptions?: NanoEmitterOptions; }>; /** Options object as resolved by the {@linkcode TieredCache.resolveTierOpts()} method. */ type TieredCacheResolvedTierOpts<TData extends DataStoreData> = Prettify<TieredCacheTierOptions<TData> & Pick<Required<TieredCacheTierOptions<TData>>, "compressionFormat">>; /** Options for when a {@linkcode TieredCache} entry goes stale. */ export type TieredCacheStaleOptions = Prettify<{ /** The method to use for determining which entries are stale. `recency` = least recently used, `frequency` = least frequently used, `relevance` = combination of both (default). */ method?: "relevance" | "recency" | "frequency"; /** Maximum time to live for the data in this tier in seconds. */ ttl?: number; /** Maximum amount of entries to keep in this tier. */ amount?: number; /** The index of the cache tier to send the entry to when it goes stale. Defaults to the next available tier, or deletes the entry if there is none. */ sendToTier?: number; }>; /** Options for entry propagation between {@linkcode TieredCache} tiers. */ export type TieredCachePropagateTierOptions = Prettify<{ /** The index of the cache tier to propagate the entry to. Use negative numbers for accessing from the end, just like `Array.prototype.at()`. Use `1` for the second tier, use `-1` for the last. */ index: number; /** Whether to propagate created entries to the cache with this index. Defaults to true. */ created?: boolean; /** Whether to propagate updated entries to the cache with this index. Defaults to true. */ updated?: boolean; /** Whether to propagate deleted entries to the cache with this index. Defaults to true. */ deleted?: boolean; /** Whether to propagate accessed entries to the cache with this index. Defaults to true. */ accessed?: boolean; }>; /** Options for each {@linkcode TieredCache} tier. */ export type TieredCacheTierOptions<TData extends DataStoreData> = Prettify<{ /** * Engine used for persistent storage. Can be a function that returns a DataStoreEngine or a DataStoreEngine instance. * If this property is not set, this tier will not persist data and only keeps it in memory. * - ⚠️ **Don't reuse instances in multiple tiers and make sure the ID is always unique!** */ engine?: (() => DataStoreEngine<TData>) | DataStoreEngine<TData>; /** Which compression format to use for this tier's persistent storage. Defaults to `deflate-raw` - set to `null` to disable compression. */ compressionFormat?: CompressionFormat | null; /** Options for when an entry goes stale, making it move to a lower tier or get fully deleted. */ staleOptions?: TieredCacheStaleOptions; /** To which tiers to propagate created and updated entries. Defaults to the next tier and all properties set to their default. */ propagateTiers?: TieredCachePropagateTierOptions[]; }>; /** Events that can be emitted by the {@linkcode TieredCache} class. */ export type TieredCacheEventMap = {}; /** * Cache class that can have multiple tiers with different max TTLs, with data being moved between tiers based on what is fetched the most. * Persists data using DataStore and DataStoreEngines. * The zeroth tier contains the most accessed data, and the last tier contains the least accessed data, so it is recommended to use slower storage engines for the last tier(s). */ export declare class TieredCache<TData extends DataStoreData> extends NanoEmitter<TieredCacheEventMap> { protected options: TieredCacheOptions<TData>; protected stores: Map<number, DataStore<TData>>; /** * Creates a new TieredCache instance. * It is a cache that can have multiple tiers with different max TTLs, with data being moved between tiers based on what is fetched the most. * It persists data using DataStore and DataStoreEngines. * The zeroth tier contains the most accessed data, and the last tier contains the least accessed data, so it is recommended to use slower storage engines for the last tier(s). * If the given {@linkcode options} are invalid, a {@linkcode ValidationError} is thrown. */ constructor(options: TieredCacheOptions<TData>); /** Validates the options for this cache and throws an Error containing all problems if they're invalid. Should be called once in the constructor. */ protected validateOptions(opts: TieredCacheOptions<TData>): void; get(matching: string | ((tier: TieredCacheTierOptions<TData>) => boolean)): Promise<TData | undefined>; upsert(matching: string | ((tier: TieredCacheTierOptions<TData>) => boolean), data: TData): Promise<boolean>; /** Loads all persistent data from all tiers and initializes the DataStore instances. */ loadData(): Promise<PromiseSettledResult<TData>[]>; /** Returns the options for the specified tier, after filling in all defaults. */ protected resolveTierOpts(index: number): Prettify<TieredCacheResolvedTierOpts<TData>> | undefined; } export {};