/**
 * Ranking rows for one reader: what they read, what readers like them read,
 * what is popular and recent — over rows a sentence route already chose.
 *
 * The route's plan picks the candidates ("recommande des articles publies"); this
 * orders them. Four signals, each in [0, 1], mixed by `weights`:
 *
 *  - content: TF-IDF cosine between each candidate's text and the texts of what
 *    the reader interacted with (their profile);
 *  - together: how often the candidate was read by the readers who read the
 *    reader's items ("readers of X also read Y");
 *  - popular: the candidate's own interaction count;
 *  - recent: a half-life decay on a date column.
 *
 * Items the reader already interacted with are left out. A reader with no
 * history gets popular and recent rows. Everything is computed per request
 * over the candidates, which suits hundreds to a few thousand rows.
 */
export type RecommendOptions = {
    /** the reader, or null for a visitor */
    user: unknown;
    /** the interactions: one row per (user, item), e.g. article views */
    interactions?: {
        table: string;
        user: string;
        item: string;
    };
    /** physical text columns of the candidate rows */
    text?: string[];
    /** physical date column for recency, and its half-life in days */
    date?: string;
    halfLife?: number;
    weights?: {
        content?: number;
        together?: number;
        popular?: number;
        recent?: number;
    };
    limit?: number;
    /** keep the rows the reader already interacted with (default: leave them out) */
    keepSeen?: boolean;
};
type Store = {
    all(sql: string, ...p: unknown[]): any;
};
/**
 * Rows ordered by how close their text is to a row or a text: "à lire aussi",
 * near-duplicates. Uses the embedder, and word overlap when it is absent.
 */
export declare function similar(rows: Record<string, any>[], o: {
    to: string;
    text: string[];
    exclude?: unknown;
    limit?: number;
    min?: number;
}): {
    score: number;
}[];
type Row = Record<string, any>;
export declare function rank(rows: Row[], o: RecommendOptions, store: Store, q: (s: string) => string): Promise<Row[]>;
export {};
