import { RedisClientOptions } from 'redis';

type CacheEntry = {
    value: unknown;
    lastModified: number;
    tags: string[];
};
type CreateRedisStringsHandlerOptions = {
    /** Redis redisUrl to use.
     * @default process.env.REDIS_URL? process.env.REDIS_URL : process.env.REDISHOST
            ? `redis://${process.env.REDISHOST}:${process.env.REDISPORT}`
            : 'redis://localhost:6379'
     */
    redisUrl?: string;
    /** Redis database number to use. Uses DB 0 for production, DB 1 otherwise
     * @default process.env.VERCEL_ENV === 'production' ? 0 : 1
     */
    database?: number;
    /** Prefix added to all Redis keys
     * @default process.env.VERCEL_URL || 'UNDEFINED_URL_'
     */
    keyPrefix?: string;
    /** Timeout in milliseconds for time critical Redis operations (during cache get, which blocks site rendering).
     *  If redis get is not fulfilled within this time, the cache handler will return null so site rendering will
     *  not be blocked further and site can fallback to re-render/re-fetch the content.
     * @default 500
     */
    getTimeoutMs?: number;
    /** Number of entries to query in one batch during full sync of shared tags hash map
     * @default 250
     */
    revalidateTagQuerySize?: number;
    /** Key used to store shared tags hash map in Redis
     * @default '__sharedTags__'
     */
    sharedTagsKey?: string;
    /** Average interval in milliseconds between tag map full re-syncs
     * @default 3600000 (1 hour)
     */
    avgResyncIntervalMs?: number;
    /** Enable deduplication of Redis get requests via internal in-memory cache
     * @default true
     */
    redisGetDeduplication?: boolean;
    /** Time in milliseconds to cache Redis get results in memory. Set this to 0 to disable in-memory caching completely
     * @default 10000
     */
    inMemoryCachingTime?: number;
    /** Default stale age in seconds for cached items
     * @default 1209600 (14 days)
     */
    defaultStaleAge?: number;
    /** Function to calculate expire age (redis TTL value) from stale age
     * @default Production: staleAge * 2, Other: staleAge * 1.2
     */
    estimateExpireAge?: (staleAge: number) => number;
    /** Kill container on Redis client error if error threshold is reached
     * @default 0 (0 means no error threshold)
     */
    killContainerOnErrorThreshold?: number;
    /** Additional Redis client socket options
     * @example { tls: true, rejectUnauthorized: false }
     */
    socketOptions?: RedisClientOptions['socket'];
    /** Additional Redis client options to be passed directly to createClient
     * @example { username: 'user', password: 'pass' }
     */
    clientOptions?: Omit<RedisClientOptions, 'url' | 'database' | 'socket'>;
};
declare class RedisStringsHandler {
    private client;
    private sharedTagsMap;
    private revalidatedTagsMap;
    private inMemoryDeduplicationCache;
    private getTimeoutMs;
    private redisGet;
    private redisDeduplicationHandler;
    private deduplicatedRedisGet;
    private keyPrefix;
    private redisGetDeduplication;
    private inMemoryCachingTime;
    private defaultStaleAge;
    private estimateExpireAge;
    private killContainerOnErrorThreshold;
    constructor({ redisUrl, database, keyPrefix, sharedTagsKey, getTimeoutMs, revalidateTagQuerySize, avgResyncIntervalMs, redisGetDeduplication, inMemoryCachingTime, defaultStaleAge, estimateExpireAge, killContainerOnErrorThreshold, socketOptions, clientOptions, }: CreateRedisStringsHandlerOptions);
    resetRequestCache(): void;
    private clientReadyCalls;
    private assertClientIsReady;
    get(key: string, ctx: {
        kind: 'APP_ROUTE' | 'APP_PAGE';
        isRoutePPREnabled: boolean;
        isFallback: boolean;
    } | {
        kind: 'FETCH';
        revalidate: number;
        fetchUrl: string;
        fetchIdx: number;
        tags: string[];
        softTags: string[];
        isFallback: boolean;
    }): Promise<CacheEntry | null>;
    set(key: string, data: {
        kind: 'APP_PAGE';
        status: number;
        headers: {
            'x-nextjs-stale-time': string;
            'x-next-cache-tags': string;
        };
        html: string;
        rscData: Buffer;
        segmentData: unknown;
        postboned: unknown;
    } | {
        kind: 'APP_ROUTE';
        status: number;
        headers: {
            'cache-control'?: string;
            'x-nextjs-stale-time': string;
            'x-next-cache-tags': string;
        };
        body: Buffer;
    } | {
        kind: 'FETCH';
        data: {
            headers: Record<string, string>;
            body: string;
            status: number;
            url: string;
        };
        revalidate: number | false;
    }, ctx: {
        isRoutePPREnabled: boolean;
        isFallback: boolean;
        tags?: string[];
        revalidate?: number | false;
        cacheControl?: {
            revalidate: 5;
            expire: undefined;
        };
    }): Promise<void>;
    revalidateTag(tagOrTags: string | string[], ...rest: any[]): Promise<void>;
}

declare class CachedHandler {
    constructor(options: CreateRedisStringsHandlerOptions);
    get(...args: Parameters<RedisStringsHandler['get']>): ReturnType<RedisStringsHandler['get']>;
    set(...args: Parameters<RedisStringsHandler['set']>): ReturnType<RedisStringsHandler['set']>;
    revalidateTag(...args: Parameters<RedisStringsHandler['revalidateTag']>): ReturnType<RedisStringsHandler['revalidateTag']>;
    resetRequestCache(...args: Parameters<RedisStringsHandler['resetRequestCache']>): ReturnType<RedisStringsHandler['resetRequestCache']>;
}

export { RedisStringsHandler, CachedHandler as default };
