import { Store } from './stores.js';
export { Entry, MemoryStore, MemoryStoreConfig, RedisStore, RedisStoreConfig, Value } from './stores.js';
import { ValueType } from '@supabase-cache-helpers/postgrest-core';
import { PostgrestSingleResponse, PostgrestMaybeSingleResponse, PostgrestResponse } from '@supabase/postgrest-js';
import 'ioredis';

interface Context {
    waitUntil: (p: Promise<unknown>) => void;
}
declare class DefaultStatefulContext implements Context {
    waitUntil<TPromise = unknown>(_p: Promise<TPromise>): void;
}

type QueryCacheOpts = {
    stores: Store[];
    fresh: number;
    stale: number;
};
type OperationOpts = Pick<QueryCacheOpts, 'fresh' | 'stale'>;
declare class QueryCache {
    private readonly inner;
    /**
     * To prevent concurrent requests of the same data, all queries are deduplicated using
     * this map.
     */
    private readonly runningQueries;
    constructor(ctx: Context, opts: QueryCacheOpts);
    /**
     * Invalidate cache entries for a given table, optionally filtered by an eq filter.
     *
     * @example
     * ```ts
     * // Invalidate all queries for a table
     * await cache.invalidateQueries({
     *   schema: 'public',
     *   table: 'posts'
     * });
     *
     * // Invalidate only queries that filter by user_id=5
     * await cache.invalidateQueries({
     *   schema: 'public',
     *   table: 'posts',
     *   filter: { path: 'user_id', value: 5 }
     * });
     * ```
     */
    invalidateQueries({ schema, table, filter, }: {
        schema: string;
        table: string;
        filter?: {
            path: string;
            value: ValueType;
        };
    }): Promise<void>;
    /**
     * Perform a cached postgrest query
     */
    query<Result>(query: PromiseLike<PostgrestSingleResponse<Result>>, opts?: Partial<OperationOpts> & {
        store?: (result: PostgrestSingleResponse<Result>) => boolean;
    }): Promise<PostgrestSingleResponse<Result>>;
    /**
     * Perform a cached postgrest query
     */
    query<Result>(query: PromiseLike<PostgrestMaybeSingleResponse<Result>>, opts?: Partial<OperationOpts> & {
        store?: (result: PostgrestMaybeSingleResponse<Result>) => boolean;
    }): Promise<PostgrestMaybeSingleResponse<Result>>;
    /**
     * Perform a cached postgrest query
     */
    query<Result>(query: PromiseLike<PostgrestResponse<Result>>, opts?: Partial<OperationOpts> & {
        store?: (result: PostgrestResponse<Result>) => boolean;
    }): Promise<PostgrestResponse<Result>>;
    /**
     * Perform a cached postgrest query
     */
    swr<Result>(query: PromiseLike<PostgrestSingleResponse<Result>>, opts?: OperationOpts): Promise<PostgrestSingleResponse<Result>>;
    /**
     * Perform a cached postgrest query
     */
    swr<Result>(query: PromiseLike<PostgrestMaybeSingleResponse<Result>>, opts?: OperationOpts): Promise<PostgrestMaybeSingleResponse<Result>>;
    /**
     * Perform a cached postgrest query
     */
    swr<Result>(query: PromiseLike<PostgrestResponse<Result>>, opts?: OperationOpts): Promise<PostgrestResponse<Result>>;
    /**
     * Deduplicating the origin load helps when the same value is requested many times at once and is
     * not yet in the cache. If we don't deduplicate, we'd create a lot of unnecessary load on the db.
     */
    private dedupeQuery;
}

export { type Context, DefaultStatefulContext, type OperationOpts, QueryCache, type QueryCacheOpts, Store };
