import { FileStat } from '../../types.ts';
import type { Clock } from '../../utils/clock.ts';
import { type IdSource } from '../../utils/ids.ts';
import { type Evicted, type ListResult, type LookupResult, type SetDirOptions } from './config.ts';
import { IndexCacheStore } from './store.ts';
interface RedisPipeline {
    eval: (script: string, options: {
        keys: string[];
        arguments: string[];
    }) => RedisPipeline;
    set: (key: string, value: string, options?: {
        NX: boolean;
    }) => RedisPipeline;
    del: (key: string) => RedisPipeline;
    exec: () => Promise<unknown>;
}
export interface RedisClientLike {
    connect: () => Promise<unknown>;
    get: (key: string) => Promise<string | null>;
    mGet: (keys: string[]) => Promise<(string | null)[]>;
    set: (key: string, value: string, options?: {
        NX: boolean;
    }) => Promise<unknown>;
    del: (key: string | string[]) => Promise<unknown>;
    multi: () => RedisPipeline;
    eval: (script: string, options: {
        keys: string[];
        arguments: string[];
    }) => Promise<unknown>;
    exists: (key: string) => Promise<number>;
    scanIterator: (options: {
        MATCH: string;
        COUNT?: number;
    }) => AsyncIterable<string | string[]>;
    isOpen: boolean;
    quit: () => Promise<unknown>;
}
export declare class RedisIndexCacheStore extends IndexCacheStore {
    readonly ttl: number;
    private readonly url;
    private readonly providedClient;
    private readonly entryPrefix;
    private readonly childrenPrefix;
    private readonly tombstonePrefix;
    private readonly keyPrefix;
    private readonly pathsKey;
    private readonly generationKey;
    private readonly initializingGenerations;
    private clientPromise;
    private readonly seedLock;
    private readonly pendingSeeds;
    private readonly listings;
    private closed;
    private readonly ids;
    constructor(options?: {
        ttl?: number;
        clock?: Clock;
        /**
         * Where generation and lease tokens are drawn; the system source by default.
         * The tokens only fence clients of one server apart, so a seeded source,
         * which mints the same tokens on every run, needs a server that is itself
         * part of the replayed run.
         */
        ids?: IdSource;
        url?: string;
        client?: RedisClientLike;
        keyPrefix?: string;
    });
    private entryKey;
    private childrenKey;
    private client;
    seed(entries: ReadonlyMap<string, FileStat>, children: ReadonlyMap<string, readonly string[]>, expiresAt: Date, version?: string | null): void;
    private trackPaths;
    private recoverPaths;
    private evalComplete;
    private generation;
    private flushSeed;
    entries(): Promise<Map<string, FileStat>>;
    get(vfsPath: string): Promise<LookupResult>;
    getMany(vfsPaths: readonly string[]): Promise<Map<string, FileStat>>;
    put(vfsPath: string, entry: FileStat): Promise<void>;
    addEntry(vfsPath: string, entry: FileStat, expiredAt?: Date | null): Promise<void>;
    replaceIfUnchanged(path: string, predecessor: string, entry: FileStat): Promise<boolean>;
    /**
     * A folder's listing, read from Redis at most once per command.
     *
     * Inside a shell command, a later call for the same folder is answered
     * from this process's memory while no listing write to this key prefix
     * has finished in this process since the read began, the read is under
     * LISTING_TRUST_WINDOW seconds old, and the listing has not reached its
     * own expiry. A write by another process is therefore seen within that
     * window, and by every new command at its first read. Outside a command,
     * and on the fallback storage while more than one command is live, every
     * call reads Redis. On the fallback storage a call outside any command
     * while exactly one command is live is served from that command's memo,
     * under the same write counting and window.
     */
    listDir(vfsPath: string, child?: string): Promise<ListResult>;
    private readListing;
    setDir(vfsPath: string, entries: readonly [string, FileStat][], expiredAt?: Date | null, options?: SetDirOptions): Promise<Evicted[]>;
    setPartialDir(vfsPath: string, entries: readonly [string, FileStat][], expiredAt?: Date | null): Promise<void>;
    private storeDir;
    refillToken(): Promise<string>;
    invalidateMissing(paths: readonly string[]): Promise<boolean>;
    refillDir(path: string, entries: readonly [string, FileStat][], token: string, expiredAt?: Date | null, options?: SetDirOptions & {
        partial?: boolean;
    }): Promise<Evicted[] | null>;
    invalidateEntry(vfsPath: string): Promise<void>;
    invalidateDir(vfsPath: string): Promise<void>;
    private deletePaths;
    invalidatePrefix(vfsPath: string, excluded?: readonly string[], remember?: boolean): Promise<void>;
    holdsSubtree(vfsPath: string): Promise<boolean>;
    invalidate(): Promise<void>;
    clear(): Promise<void>;
    close(): Promise<void>;
}
export {};
//# sourceMappingURL=redis.d.ts.map