/**
 * `FlexSearchStore` — pure-JS lexical search store that replaces both
 * `LanceStore` and `HybridQuery`. BM25-style ranking only; no
 * embeddings, no native binaries, no network.
 *
 * - Document index via FlexSearch's `Document` class.
 * - Three indexed fields: `title` (forward + LatinAdvanced),
 *   `text` (forward + LatinAdvanced), `identifier_text` (strict +
 *   Simple, derived from `text`/`title` via camel/snake/kebab/path
 *   splitting).
 * - Tag filtering on `source_id`, `project_id`, `archived`.
 * - Per-document `weight` and recency boost applied post-rank.
 * - `parent_id` collapse keeps the single highest-scoring chunk per
 *   logical entry.
 * - Persistence to `<dataDir>/index/<key>.json` with atomic tmp+rename
 *   and a 500ms trailing debounce.
 *
 * See docs/design/portable-search.md §4, §5, §6, §9.
 */
import { type MetaRow } from "./meta.js";
import type { Indexable, SearchQuery, SearchResult, SearchResults } from "./types.js";
export declare const FLEX_VERSION = "0.8.158";
export interface FlexDoc {
    id: string;
    source_id: Indexable["sourceId"];
    project_id: string;
    entity_type: SearchResult["type"];
    parent_id: string | null;
    archived: boolean;
    /** Stringified boolean — FlexSearch `tag` values are strings. */
    archived_tag: "true" | "false";
    timestamp: number;
    content_hash: string;
    weight: number;
    role: string | null;
    title: string | null;
    text: string;
    identifier_text: string;
    goal_id: string | null;
    session_id: string | null;
    session_title: string | null;
    file_path: string | null;
    start_line: number | null;
    end_line: number | null;
}
export interface FlexSearchStoreOpenOptions {
    /** Directory holding the index (e.g. `.bobbit/state/search.flex`). */
    dataDir: string;
}
export interface FlexSearchStats {
    rowCountsBySource: {
        goals: number;
        sessions: number;
        messages: number;
        staff: number;
        files: number;
    };
    totalRows: number;
    datasetBytes: number;
    lastRebuildAt: number | null;
}
/**
 * Extract identifier-like tokens from text: camelCase, snake_case,
 * kebab-case, dotted paths, and file paths split on `/`, `\`, `.`.
 * The raw token and its decomposed parts both appear so that exact
 * matches on either form succeed under strict tokenization.
 */
export declare function extractIdentifierTokens(text: string): string;
/** Build the tag filter object consumed by FlexSearch `.search(..., {tag})`. */
export declare function buildTagFilter(q: SearchQuery): Array<{
    field: string;
    tag: string | string[];
}>;
export declare class FlexSearchStore {
    readonly dataDir: string;
    private _idx;
    private readonly _docs;
    private _saveTimer;
    private _flushInFlight;
    private _flushAgain;
    private _closed;
    private constructor();
    private static _newIndex;
    static open(opts: FlexSearchStoreOpenOptions): Promise<FlexSearchStore>;
    upsert(docs: FlexDoc[]): Promise<void>;
    deleteByIds(ids: string[]): Promise<void>;
    /**
     * Structured filter-style delete. Unlike LanceStore's raw-SQL filter
     * this accepts only known keys — no injection surface.
     */
    deleteWhere(filter: {
        source_id?: Indexable["sourceId"];
        session_id?: string;
        project_id?: string;
        parent_id?: string | string[] | null;
    }): Promise<void>;
    clear(): Promise<void>;
    /**
     * Lookup by id — used for contentHash deduplication in the Indexer.
     * Synchronous; the backing Map is always in memory.
     */
    getById(id: string): FlexDoc | null;
    /** Return the contentHash of any doc whose `id === id` OR `parent_id === id`. */
    getHashForEntry(entryId: string): string | null;
    count(filter?: {
        source_id?: Indexable["sourceId"];
        project_id?: string;
    }): number;
    list(opts: {
        source_id?: Indexable["sourceId"];
        project_id?: string;
        limit: number;
    }): FlexDoc[];
    search(q: SearchQuery): Promise<SearchResults>;
    private _matchesTagFilter;
    readMeta(): Promise<MetaRow | null>;
    writeMeta(meta: MetaRow): Promise<void>;
    /** Passthrough no-op. Kept for SearchService.compact() compatibility. */
    compact(): Promise<void>;
    /** Flush pending writes. Used by SearchService.close(). */
    close(): Promise<void>;
    private _scheduleSave;
    private _flushNow;
    private _doFlush;
    private __doFlush;
    private _loadFromDisk;
    private _prepare;
}
export declare function recencyMultiplier(timestamp: number, nowMs?: number): number;
export declare function toSearchResult(doc: FlexDoc, query: string, finalScore: number): SearchResult;
//# sourceMappingURL=flex-store.d.ts.map