import type Redis from 'ioredis';
import type { RedisKey } from 'ioredis';
import type { AcquiredResult, AcquireDesire, AcquireOptions } from './Acquire';
import type { AcquireHelper } from './AcquireHelper';
interface Parser {
    parse: (text: string) => any;
    stringify: (value: any) => string;
}
interface CacheOptions {
    redis: Redis;
    parser?: Parser;
    acquire?: AcquireHelper;
    acquireType?: AcquireType;
}
declare type Key = RedisKey | number;
declare type AcquireType = 'lua' | 'pipeline';
declare type Mapping<T> = {
    [id: string]: T;
};
declare type ValueSource<K extends Key, T> = Mapping<T> | T[] | Map<K, T>;
declare type ValueMap<T> = Mapping<T | undefined>;
declare type Awaitable<T> = T | Promise<T>;
declare const NOT_FOUND_VALUE: undefined;
declare type CacheReturn<T> = T | typeof NOT_FOUND_VALUE;
declare class Cache {
    redis: Redis;
    private readonly acquireHelper;
    protected prefix: string;
    protected parser: Parser;
    /**
     * @param options - Either an ioredis instance directly or a CacheOptions object
     *   with a `redis` property plus optional `parser`, `acquire`, and
     *   `acquireType`. Throws if the redis instance doesn't satisfy the ioredis
     *   interface check.
     */
    constructor(options: Redis | CacheOptions);
    private createAcquireHelper;
    /**
     * Binds all prototype methods of Cache to a target instance so they can be
     * destructured and called without losing the `this` context.
     *
     * @returns The same target instance after binding.
     */
    static bindAll(target: Cache): Cache;
    /**
     * Read-through cache for a single key. Checks the cache first; if the value
     * is missing, calls `fn` to produce it, stores the result, and returns it.
     *
     * @param key - Cache key to look up.
     * @param fn - Factory function invoked on cache miss.
     * @param ttl - Optional TTL in seconds. If omitted the value is stored
     *   without expiry.
     */
    cache<T>(key: Key, fn: () => Awaitable<T>, ttl?: number): Promise<T>;
    /**
     * Retrieves a single cached value by key. Returns `undefined` when the key
     * is not found (the `NOT_FOUND_VALUE` sentinel), making it safe to
     * distinguish a cache miss from a stored value.
     */
    getCache<T>(key: Key): Promise<CacheReturn<T>>;
    /**
     * Stores a single value in the cache. The value is serialized through the
     * configured parser (default: JSON).
     *
     * @param ttl - Optional TTL in seconds. Uses `SETEX` when provided, plain
     *   `SET` otherwise.
     */
    setCache(key: Key, value: any, ttl?: number): Promise<"OK">;
    /**
     * Read-through cache for multiple keys in a single batch. Executes a single
     * `MGET` for all keys, then calls `fn` for any missing keys and stores the
     * result via `MSET` (or pipelined `SETEX` when TTL is provided).
     *
     * @param keys - List of logical keys to fetch.
     * @param fn - Factory invoked with the subset of keys that were not cached.
     *   Must return values in the same order as the supplied keys.
     * @param prefix - Optional string (or number) prepended to every key before
     *   interacting with Redis. The prefix is stripped from cached results.
     * @param ttl - Optional TTL in seconds for newly stored values.
     */
    manyCache<K extends Key, T>(keys: K[], fn: (keys: K[]) => Awaitable<ValueSource<K, T>>, prefix?: Key, ttl?: number): Promise<T[]>;
    /**
     * Retrieves multiple cached values by their keys using `MGET`. Returns an
     * array aligned with the input keys where missing entries are `undefined`
     * (the `NOT_FOUND_VALUE` sentinel).
     */
    getManyCache<T = any>(keys: Key[]): Promise<CacheReturn<T>[]>;
    /**
     * Stores multiple key-value pairs atomically. Uses `MSET` when no TTL is
     * given; otherwise uses a pipeline of `MSET` + per-key `EXPIRE` commands.
     *
     * @param valueMap - A plain object mapping string keys to serialisable values.
     * @param ttl - Optional TTL in seconds applied to every key in the batch.
     */
    setManyCache(valueMap: {
        [id: string]: any;
    }, ttl?: number): Promise<[error: Error | null, result: unknown][] | "OK" | null>;
    /**
     * Deletes one or more keys from the cache.
     *
     * @returns The number of keys that were actually removed.
     */
    deleteCache(...keys: Key[]): Promise<number>;
    /**
     * Deletes all keys matching a glob pattern by iterating with `SCAN` in
     * batches. The `keyPrefix` configured on the ioredis instance is
     * automatically prepended to the pattern so callers don't need to include it.
     *
     * @param pattern - Redis glob pattern (e.g. `user:*`).
     * @param batch - Number of keys to scan and delete per pipeline (default 100).
     */
    deletePattern(pattern: string, batch?: number): Promise<void>;
    /**
     * Read-through cache for a single field inside a Redis hash. Checks the hash
     * first; on miss calls `fn`, stores the result, and returns it.
     *
     * @param key - The Redis hash key.
     * @param id - The field name within the hash.
     * @param fn - Factory function invoked on cache miss.
     */
    hashCache<T>(key: Key, id: Key, fn: () => Awaitable<T>): Promise<T>;
    /**
     * Retrieves a single field from a Redis hash. Returns `undefined` (the
     * `NOT_FOUND_VALUE` sentinel) when the field does not exist.
     */
    getHashCache<T>(key: Key, id: Key): Promise<CacheReturn<T>>;
    /**
     * Stores a single field in a Redis hash. The value is serialised through the
     * configured parser.
     */
    setHashCache(key: Key, id: Key, value: any): Promise<number>;
    /**
     * Read-through cache for multiple fields within a single Redis hash. Issues
     * a single `HMGET`, calls `fn` for any missing fields, persists them with
     * `HMSET`, and returns the merged result aligned with the input `ids`.
     *
     * @param key - The Redis hash key.
     * @param ids - Field names to fetch.
     * @param fn - Factory invoked with the subset of field names that are not
     *   cached. Must return values in the same order.
     */
    hashManyCache<K extends Key, T>(key: Key, ids: K[], fn: (ids: K[]) => Awaitable<ValueSource<K, T>>): Promise<T[]>;
    /**
     * Retrieves multiple fields from a Redis hash using `HMGET`. Returns an
     * array aligned with the input `ids` where missing fields are `undefined`
     * (the `NOT_FOUND_VALUE` sentinel).
     */
    getHashManyCache<T>(key: Key, ids: Key[]): Promise<CacheReturn<T>[]>;
    /**
     * Stores multiple fields in a Redis hash atomically using `HMSET`.
     *
     * @param key - The Redis hash key.
     * @param valueMap - A plain object mapping field names to serialisable values.
     */
    setHashManyCache(key: Key, valueMap: {
        [id: string]: any;
    }): Promise<never[] | "OK">;
    /**
     * Deletes one or more fields from a Redis hash.
     *
     * @returns The number of fields that were actually removed.
     */
    deleteHashCache(key: Key, ...ids: Key[]): Promise<number>;
    /**
     * Atomically increments (or decrements) a Redis key and invokes `fn` with
     * the updated value. On failure the increment is automatically rolled back.
     *
     * @param key - Redis key holding the counter.
     * @param amount - Amount to add (use a negative number to decrement).
     * @param fn - Callback receiving current, acquired, and lacking amounts.
     * @param options - When `float` is true uses `INCRBYFLOAT`; `limit` caps
     *   how much can be acquired.
     */
    acquire<T>(key: Key, amount: number, fn: (currentAmount: number, acquiredAmount: number, lackingAmount: number) => Awaitable<T>, options?: AcquireOptions | boolean): Promise<T>;
    /**
     * Atomically increments (or decrements) a field inside a Redis hash and
     * invokes `fn` with the updated value.
     *
     * @param key - The Redis hash key.
     * @param id - The field name within the hash.
     * @param amount - Amount to add.
     * @param fn - Callback receiving current, acquired, and lacking amounts.
     * @param options - When `float` is true uses `HINCRBYFLOAT`; `limit` caps
     *   how much can be acquired.
     */
    hashAcquire<T>(key: Key, id: Key, amount: number, fn: (currentAmount: number, acquiredAmount: number, lackingAmount: number) => Awaitable<T>, options?: AcquireOptions | boolean): Promise<T>;
    /**
     * Atomically modifies multiple counters through the configured acquire
     * helper. Each desired change is specified as an `AcquireDesire` item; `fn`
     * receives the final values.
     */
    acquireMany<K extends string | number, T>(items: AcquireDesire<K>[], fn: (acquireResult: AcquiredResult<K>[]) => Awaitable<T>, options?: AcquireOptions): Promise<T>;
    /**
     * Atomically modifies multiple fields inside a single Redis hash counter
     * through the configured acquire helper.
     *
     * @param hashKey - The Redis hash key containing the counters.
     * @param items - Desired changes for each field.
     * @param fn - Callback receiving the array of results.
     */
    hashAcquireMany<K extends string | number, T>(hashKey: string, items: AcquireDesire<K>[], fn: (acquireResult: AcquiredResult<K>[]) => Awaitable<T>, options?: AcquireOptions): Promise<T>;
    /**
     * Filters the input `keys` down to those whose corresponding entry in
     * `cachedValues` is `NOT_FOUND_VALUE`.
     */
    protected _getUncachedKeys<K extends Key, T>(keys: K[], cachedValues: CacheReturn<T>[]): K[];
    /**
     * Merges a set of cached values with a map of uncached values. Where a
     * cached entry is `NOT_FOUND_VALUE`, the corresponding value is looked up
     * from `uncachedValueMap` by key.
     */
    protected _mergeCacheValues<K extends Key, T>(cachedValues: CacheReturn<T>[], keys: K[], uncachedValueMap: ValueMap<T>): T[];
    /**
     * Returns a new map with every key prefixed by `prefix`. Used internally
     * by `manyCache` to apply the configured prefix before storing.
     */
    protected _prefixValueMap<T>(valueMap: ValueMap<T>, prefix: Key): ValueMap<T>;
    /**
     * Converts a value map into a flat array of `[key, stringifiedValue, key,
     * stringifiedValue, ...]` suitable for `MSET` / `HMSET`. Entries whose
     * value is `NOT_FOUND_VALUE` are skipped.
     */
    protected _buildSetParams: (valueMap: {
        [id: string]: any;
    }) => string[];
    /**
     * Normalises a `ValueSource` (array, `Map`, or plain object) into a uniform
     * `ValueMap` keyed by the string representation of each id. Array and `Map`
     * sources are aligned with `ids` by position.
     */
    protected _buildValueMap<K extends Key, T>(ids: K[], valueMap: ValueSource<K, T>): ValueMap<T>;
}
export default Cache;
