import type { CreateReporter, Reporter } from './reporter';
import { StandardSchemaV1 } from './StandardSchemaV1';
export interface CacheMetadata {
    createdTime: number;
    ttl?: number | null;
    swr?: number | null;
    /** @deprecated use swr instead */
    readonly swv?: number | null;
}
export interface CacheEntry<Value = unknown> {
    metadata: CacheMetadata;
    value: Value;
}
export type Eventually<Value> = Value | null | undefined | Promise<Value | null | undefined>;
export interface Cache<Value = any> {
    name?: string;
    get: (key: string) => Eventually<CacheEntry<Value>>;
    set: (key: string, value: CacheEntry<Value>) => unknown | Promise<unknown>;
    delete: (key: string) => unknown | Promise<unknown>;
}
export interface GetFreshValueContext {
    readonly metadata: CacheMetadata;
    readonly background: boolean;
}
export declare const HANDLE: unique symbol;
export type GetFreshValue<Value> = {
    (context: GetFreshValueContext): Promise<Value> | Value;
    [HANDLE]?: () => void;
};
export declare const MIGRATED: unique symbol;
export type MigratedValue<Value> = {
    [MIGRATED]: boolean;
    value: Value;
};
export type ValueCheckResultOk<Value> = true | undefined | null | void | MigratedValue<Value>;
export type ValueCheckResultInvalid = false | string;
export type ValueCheckResult<Value> = ValueCheckResultOk<Value> | ValueCheckResultInvalid;
export type CheckValue<Value> = (value: unknown, migrate: (value: Value, updateCache?: boolean) => MigratedValue<Value>) => ValueCheckResult<Value> | Promise<ValueCheckResult<Value>>;
/**
 * @deprecated use a library supporting Standard Schema
 * @see https://github.com/standard-schema/standard-schema?tab=readme-ov-file#what-schema-libraries-implement-the-spec
 * @todo remove in next major version
 */
export interface Schema<Value, InputValue> {
    _input: InputValue;
    parseAsync(value: unknown): Promise<Value>;
}
export interface CachifiedOptions<Value> {
    /**
     * Required
     *
     * The key this value is cached by
     * Must be unique for each value
     */
    key: string;
    /**
     * Required
     *
     * Cache implementation to use
     *
     * Must conform with signature
     *  - set(key: string, value: object): void | Promise<void>
     *  - get(key: string): object | Promise<object>
     *  - delete(key: string): void | Promise<void>
     */
    cache: Cache;
    /**
     * Required
     *
     * Function that is called when no valid value is in cache for given key
     * Basically what we would do if we wouldn't use a cache
     *
     * Can be async and must return fresh value or throw
     *
     * receives context object as argument
     *  - context.metadata.ttl?: number
     *  - context.metadata.swr?: number
     *  - context.metadata.createdTime: number
     *  - context.background: boolean
     */
    getFreshValue: GetFreshValue<Value>;
    /**
     * Time To Live; often also referred to as max age
     *
     * Amount of milliseconds the value should stay in cache
     * before we get a fresh one
     *
     * Setting any negative value will disable caching
     * Can be infinite
     *
     * Default: `Infinity`
     */
    ttl?: number;
    /**
     * Amount of milliseconds that a value with exceeded ttl is still returned
     * while a fresh value is refreshed in the background
     *
     * Should be positive, can be infinite
     *
     * Default: `0`
     */
    staleWhileRevalidate?: number;
    /**
     * Alias for staleWhileRevalidate
     */
    swr?: number;
    /**
     * Validator that checks every cached and fresh value to ensure type safety
     *
     * Can be a standard schema validator or a custom validator function
     * @see https://github.com/standard-schema/standard-schema?tab=readme-ov-file#what-schema-libraries-implement-the-spec
     *
     * Value considered ok when:
     *  - schema succeeds
     *  - validator returns
     *    - true
     *    - migrate(newValue)
     *    - undefined
     *    - null
     *
     * Value considered bad when:
     *  - schema throws
     *  - validator:
     *    - returns false
     *    - returns reason as string
     *    - throws
     *
     * A validator function receives two arguments:
     *  1. the value
     *  2. a migrate callback, see https://github.com/epicweb-dev/cachified#migrating-values
     *
     * Default: `undefined` - no validation
     */
    checkValue?: CheckValue<Value> | StandardSchemaV1<unknown, Value> | Schema<Value, unknown>;
    /**
     * Set true to not even try reading the currently cached value
     *
     * Will write new value to cache even when cached value is
     * still valid.
     *
     * Default: `false`
     */
    forceFresh?: boolean;
    /**
     * Whether or not to fall back to cache when getting a forced fresh value
     * fails
     *
     * Can also be a positive number as the maximum age in milliseconds that a
     * fallback value might have
     *
     * Default: `Infinity`
     */
    fallbackToCache?: boolean | number;
    /**
     * Amount of time in milliseconds before revalidation of a stale
     * cache entry is started
     *
     * Must be positive and finite
     *
     * Default: `0`
     * @deprecated manually delay background refreshes in getFreshValue instead
     * @see https://github.com/epicweb-dev/cachified/issues/132
     */
    staleRefreshTimeout?: number;
    /**
     * @deprecated pass reporter as second argument to cachified
     */
    reporter?: never;
    /**
     * Promises passed to `waitUntil` represent background tasks which must be
     * completed before the server can shutdown. e.g. swr cache revalidation
     *
     * Useful for serverless environments such as Cloudflare Workers.
     *
     * Default: `undefined`
     */
    waitUntil?: (promise: Promise<unknown>) => void;
}
export type CachifiedOptionsWithSchema<Value, InternalValue> = Omit<CachifiedOptions<Value>, 'checkValue' | 'getFreshValue'> & {
    checkValue: StandardSchemaV1<unknown, Value> | Schema<Value, InternalValue>;
    getFreshValue: GetFreshValue<InternalValue>;
};
export interface Context<Value> extends Omit<Required<CachifiedOptions<Value>>, 'fallbackToCache' | 'reporter' | 'checkValue' | 'swr'> {
    checkValue: CheckValue<Value>;
    report: Reporter<Value>;
    fallbackToCache: number;
    metadata: CacheMetadata;
}
export declare function createContext<Value>({ fallbackToCache, checkValue, ...options }: CachifiedOptions<Value>, reporter?: CreateReporter<Value>): Context<Value>;
export declare function staleWhileRevalidate(metadata: CacheMetadata): number | null;
export declare function totalTtl(metadata?: CacheMetadata): number;
export declare function createCacheMetaData({ ttl, swr, createdTime, }?: Partial<Omit<CacheMetadata, 'swv'>>): {
    ttl: number | null;
    swr: number | null;
    createdTime: number;
};
export declare function createCacheEntry<Value>(value: Value, metadata?: Partial<Omit<CacheMetadata, 'swv'>>): CacheEntry<Value>;
