import type { MaybeCallable } from "./misc";
export interface CachedRefreshedValueOptions<TValue> {
    /** Delay between calling resolver. */
    delayMs: MaybeCallable<number>;
    /** Log a timeout Error if a resolver takes more than X ms to complete. */
    warningTimeoutMs: MaybeCallable<number>;
    /** The handler deps.handler() is called every deps.delayMs (typically,
     * frequently); if it returns a different value than previously (using "==="
     * comparison), then waiting for the next delayMs is interrupted prematurely,
     * and the value gets refreshed. This allows to frequently recheck for some
     * configuration changes and act accordingly. */
    deps: {
        delayMs: MaybeCallable<number>;
        handler: () => unknown | Promise<unknown>;
    };
    /** The name of the resolverFn function. Used in error messages. */
    resolverName?: string;
    /** A resolver function that returns the value. It's assumed that this
     * function would eventually either resolve or throw. */
    resolverFn: () => Promise<TValue>;
    /** An error handler. */
    onError: (error: unknown, elapsed: number) => void;
    /** A custom delay implementation. */
    delay: (ms: number) => Promise<void>;
}
/**
 * Utility class to provide a caching layer for a resolverFn with the following
 * assumptions:
 * - The value is stable and does not change frequently.
 * - The resolverFn can throw or take more time to resolve (e.g. outage). In
 *   that case, the cached value is still valid, unless a fresh value is
 *   requested with refreshAndWait().
 *
 * The implementation is as follows:
 * - Once value is accessed, we schedule an endless loop of calling resolver to
 *   get latest value.
 * - The result is cached, so next calls will return it immediately in most of
 *   the cases.
 * - Once every delayMs we call resolverFn to get latest value. All calls during
 *   this time will get previous value (if available).
 */
export declare class CachedRefreshedValue<TValue> {
    readonly options: CachedRefreshedValueOptions<TValue>;
    /** Latest value pulled from the cache. */
    private latestValue;
    /** Deferred promise containing the next value. Fulfilled promises are
     * replaced right away. */
    private nextValue;
    /** Each time before resolverFn() is called, this value is increased. */
    private resolverFnCallCount;
    /** Whether the instance is destroyed or not. Used to prevent memory leaks in
     * unit tests. */
    private destroyedError;
    /** A callback to skip the current delay() call. */
    private skipDelay;
    /**
     * Initializes the instance.
     */
    constructor(options: CachedRefreshedValueOptions<TValue>);
    /**
     * Returns latest cached value. If the value has been calculated at least
     * once, then it is guaranteed that in the worst case, it will be returned
     * immediately. I.e. this method never blocks once at least one calculation
     * succeeded in the past. (But it may block during the very first call.)
     */
    cached(): Promise<TValue>;
    /**
     * Triggers the call to resolverFn() ASAP (i.e. sooner than the next interval
     * specified in delayMs) and waits for the next complete SUCCESSFUL cache
     * refresh. If the method is called during the period of time when the
     * resolverFn() is already running, then it waits till it finishes, and then
     * waits again till the next resolverFn() call finishes, so we're sure that
     * it's a strong barrier.
     */
    refreshAndWait(): Promise<void>;
    /**
     * Destroys the instance. Stops refreshing the value and any call to it will
     * result in an error.
     */
    destroy(): void;
    private refreshLoop;
    /**
     * A never throwing version of options.onError().
     */
    private onError;
}
//# sourceMappingURL=CachedRefreshedValue.d.ts.map