import { PromiseHolder, Undefinable } from '@thermopylae/core.declarations';
import { Cache, CacheEvent, CacheEventListener } from '../contracts/cache';
/**
 * Asynchronous function which retrieves *value* of the `key`.
 *
 * @param key	Key, value of which needs to be retrieved.
 *
 * @returns		A tuple containing value of the key and optional argument's bundle used for key insertion. <br/>
 * 				Notice that `null` is a valid value.
 * 				If key doesn't have any value, `undefined` needs to be returned. <br/>
 * 				If arguments bundle will be returned, it will override the one returned by {@link KeyConfigProvider}.
 * 				If arguments bundle won't be returned, the one returned by {@link KeyConfigProvider} will be used.
 */
declare type KeyRetriever<Key, Value, ArgumentsBundle = unknown> = (key: Key) => Promise<[Value | undefined, ArgumentsBundle | undefined]>;
/**
 * Function which provides arguments bundle used by different cache operations (for the moment only {@link Cache.set} operation)
 * for the specified `key`.
 *
 * @param key	Key, args bundle of which is needed.
 *
 * @returns		Arguments bundle. If `key` doesn't require any arguments, `undefined` needs to be returned.
 */
declare type KeyConfigProvider<Key, ArgumentsBundle> = (key: Key) => ArgumentsBundle | undefined;
interface RenewableCacheOptions<Key, Value, ArgumentsBundle> {
    /**
     * Synchronous implementation of the {@link Cache}.
     */
    cache: Cache<Key, PromiseHolder<Undefinable<Value>>, ArgumentsBundle>;
    /**
     * Retriever function.
     */
    keyRetriever: KeyRetriever<Key, Value, ArgumentsBundle>;
    /**
     * Optional key config provider which will be used when no explicit arguments bundle was provided to cache operation.
     */
    keyConfigProvider?: KeyConfigProvider<Key, ArgumentsBundle>;
}
/**
 * Asynchronous implementation of the {@link Cache}, which auto fills itself by using {@link KeyRetriever}. <br/>
 * In case key was requested and it's missing, retriever will be called to obtain it's value
 * which will be saved in the cache and then returned to client. <br/>
 * If you don't want to pass each time same arguments bundle for cache operations, you can provide a {@link KeyConfigProvider}.
 * This function will be called each time an operation is performed on `key`. Returned arguments bundle will be forwarded
 * to the underlying {@link Cache} implementation. This is especially useful for {@link Cache.get} operation which
 * needs to automatically insert missing keys and use an arguments bundle for them.
 *
 * @template Key				Type of the key.
 * @template Value				Type of the value.
 * @template ArgumentsBundle	Type of the arguments bundle.
 */
declare class RenewableCache<Key, Value, ArgumentsBundle = unknown> implements Cache<Key, Value, ArgumentsBundle, 'promise', PromiseHolder<Undefinable<Value>>> {
    private readonly options;
    constructor(options: RenewableCacheOptions<Key, Value, ArgumentsBundle>);
    /**
     * @inheritDoc
     */
    get size(): number;
    /**
     * @inheritDoc
     */
    get(key: Key, argsBundle?: ArgumentsBundle): Promise<Value | undefined>;
    /**
     * @inheritDoc
     */
    has(key: Key): boolean;
    /**
     * Insert/update *key*-*value* pair. <br/>
     * Due to auto fill nature of the cache, you can use this method explicitly set a value for the key and (maybe)
     * overwrite the value provided by retriever.
     *
     * @param key			Key.
     * @param value			Value.
     * @param argsBundle	Arguments bundle.
     */
    set(key: Key, value: Value, argsBundle?: ArgumentsBundle): void;
    /**
     * @inheritDoc
     */
    del(key: Key): boolean;
    /**
     * @inheritDoc
     */
    clear(): void;
    /**
     * @inheritDoc
     */
    keys(): Array<Key>;
    /**
     * @inheritDoc
     */
    on(event: CacheEvent, listener: CacheEventListener<Key, PromiseHolder<Value | undefined>>): this;
    /**
     * @inheritDoc
     */
    off(event: CacheEvent, listener: CacheEventListener<Key, PromiseHolder<Value | undefined>>): this;
    private static buildPromiseHolder;
    private static defaultKeyConfigProvider;
}
export { RenewableCache, KeyRetriever, KeyConfigProvider };
