import type { RawFetchResult, ExtractionResult, CachedContent, SearchResultItem, CacheStats } from '../types.js';
/**
 * Sanitize a user query for sqlite FTS5 MATCH.
 *
 * Why: bare tokens with `.` / `-` / `/` / `:` / digits-with-dot
 * (e.g. "5.4", "x-y", "https://foo") raise `fts5: syntax error near "."`.
 * Quoting tokens that aren't pure word-chars lets FTS5 treat them as phrases.
 * Already-quoted phrases and explicit operators (AND/OR/NOT/parens) pass through.
 */
export declare function sanitizeFtsQuery(q: string): string;
export declare function normalizeUrl(url: string): string;
export declare function cacheContent(result: RawFetchResult, extraction: ExtractionResult): void;
export declare function getCachedContent(url: string): CachedContent | null;
export declare function getCachedContentByNormalizedUrl(normalizedUrl: string): CachedContent | null;
export declare function getHashForNormalizedUrl(normalizedUrl: string): string | null;
/**
 * Slice S1 (C2): cached HTTP status for change-detection. Returns `null`
 * when the row was persisted before migration 006 added the column, so
 * callers must treat `null` as "unknown, body-hash is authoritative".
 */
export declare function getHttpStatusForNormalizedUrl(normalizedUrl: string): number | null;
/**
 * Slice S1 follow-up: read content_hash and http_status in a single
 * prepared SELECT. Change-detection needs both on the hot path and
 * coalescing them halves the index lookup cost. Returns `{ hash: null,
 * status: null }` when the URL is absent; `status` is also `null` for
 * legacy rows persisted before migration 006 added the http_status
 * column. Defensive try/catch mirrors getHttpStatusForNormalizedUrl —
 * an unexpected schema state (column missing on a half-migrated DB)
 * degrades to "no cached entry" instead of throwing through the hot
 * path.
 */
export declare function getHashAndStatusForNormalizedUrl(normalizedUrl: string): {
    hash: string | null;
    status: number | null;
};
export declare function getMarkdownForNormalizedUrl(normalizedUrl: string): string | null;
export declare function isExpired(cached: CachedContent): boolean;
export interface CacheLookupOptions {
    staleMaxSeconds?: number;
}
export declare function isCacheUsable(cached: CachedContent, opts?: CacheLookupOptions): {
    usable: boolean;
    stale: boolean;
};
export declare function searchCache(query: string): CachedContent[];
export interface CachedSearchResult {
    query: string;
    results: SearchResultItem[];
    engines_used: string[];
    searched_at: string;
    stale?: boolean;
}
/** Filter parameters that participate in the search cache key. Changing any
 * of these must force a cache miss because the cached payload is filter-
 * dependent (sub-ticket 2.3). */
export interface SearchCacheFilters {
    category?: string | null;
    include_domains?: string[] | null;
    exclude_domains?: string[] | null;
    max_results?: number | null;
    from_date?: string | null;
    to_date?: string | null;
    language?: string | null;
    time_range?: string | null;
    exact_match?: boolean | null;
}
/** Build a stable cache key string from a query and optional filter params.
 * Two requests with the same query but different filter values get distinct
 * keys, so cache lookups respect caller-specified constraints. */
export declare function buildSearchCacheKey(query: string, filters?: SearchCacheFilters): string;
export declare function cacheSearchResults(query: string, results: SearchResultItem[], enginesUsed: string[]): void;
export declare function getCachedSearchResults(query: string, opts?: CacheLookupOptions): CachedSearchResult | null;
export declare function searchCacheFiltered(options: {
    query?: string;
    urlPattern?: string;
    since?: string;
    limit?: number;
}): CachedContent[];
/**
 * BM25-ranked FTS5 search across cached pages. Returns normalized URLs
 * paired with their rank score. `rank` from FTS5 is negative (lower is
 * better in sqlite ordering), so we flip the sign to surface a "higher is
 * better" score for consumers (e.g. RRF input).
 */
export declare function ftsSearchRanked(query: string, limit: number): Array<{
    url: string;
    score: number;
}>;
export declare function clearCacheEntries(options: {
    query?: string;
    urlPattern?: string;
    since?: string;
}): number;
export declare function countCachedUrlsForDomain(domain: string): number;
export declare function getCacheStats(): CacheStats;
export declare function updateCacheEmbedding(url: string, embedding: Buffer, model: string, dims: number): boolean;
export interface EmbeddingData {
    embedding: Buffer;
    model: string;
    dims: number;
}
export declare function getEmbeddingForUrl(url: string, modelId?: string): EmbeddingData | null;
export interface StoredEmbedding {
    normalizedUrl: string;
    embedding: Buffer;
    model: string;
    dims: number;
}
export interface DomainRoutingRow {
    domain: string;
    preferPlaywright: boolean;
    httpFailures: number;
    preferTlsImpersonation: boolean;
    tlsSuccessCount: number;
    lastUpdated?: string;
}
export declare function getDomainRouting(domain: string): DomainRoutingRow | null;
/**
 * Record a successful TLS-impersonation fetch for the domain and flip the
 * `prefer_tls_impersonation` bit once `tls_success_count` reaches `threshold`.
 * Atomic so concurrent callers can't double-count.
 */
export declare function recordTlsImpersonationSuccess(domain: string, threshold: number): DomainRoutingRow | null;
export declare function getAllEmbeddings(modelId?: string): StoredEmbedding[];
//# sourceMappingURL=store.d.ts.map