/**
 * @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.ts";
import { NanoEmitter, type NanoEmitterOptions } from "./NanoEmitter.ts";
import type { DataStoreEngine } from "./DataStoreEngine.ts";
import type { Prettify } from "./types.ts";
/** 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, true>>;
    /**
     * 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 {};
