import { type Entry } from '../entry/entry.js';
/**
 * A detected N+1 LOOP pattern within a single batch: one driving "parent" query
 * (the SELECT that produced the rows being iterated) followed by N similarly-
 * shaped "child" queries (the per-row lookups). Richer than the flat
 * {@link detectNPlusOne} family-count: it attributes a likely parent and weights
 * by the total time WASTED in the loop, so the worst offenders rank first.
 */
export interface NPlusOnePattern {
    /** The repeated child query's family hash. */
    childFamilyHash: string;
    /** A representative child SQL (template/text). */
    childSql: string;
    /** How many times the child query ran in the batch (>= threshold). */
    count: number;
    /** Sum of the child queries' durations (ms) — the "wasted" time, the rank key. */
    totalDurationMs: number;
    /**
     * The family hash of the query that most likely drove the loop — the distinct
     * query immediately preceding the loop in record order — or `null` when the
     * loop is the first thing in the batch (no identifiable parent).
     */
    parentFamilyHash: string | null;
    /** The likely-parent SQL, or `null` when there is no identifiable parent. */
    parentSql: string | null;
    /** A representative child entry id (deep-link / hydration seam). */
    representativeId: string;
    /** The batch the pattern was found in. */
    batchId: string;
}
export interface NPlusOnePatternOptions {
    /** Minimum repetitions of one child template to flag a loop. */
    threshold: number;
}
/**
 * Detect N+1 loop patterns in a batch's query entries. For each query family that
 * repeats `>= threshold` times, we emit a pattern weighted by the loop's total
 * duration and attribute the likely driving parent (the distinct query that ran
 * just before the loop began). Pure; ordered by total wasted duration desc.
 *
 * DESIGN: the flat {@link detectNPlusOne} only answers "did family X repeat N
 * times". This adds the two things that make an N+1 actionable — *which* query
 * caused it, and *how much time* it cost — modelled on how Sentry/Laravel
 * surface N+1: the loop body plus the originating parent span, ranked by cost.
 */
export declare function detectNPlusOnePatterns(entries: Entry[], options: NPlusOnePatternOptions): NPlusOnePattern[];
/** The content shape of a synthetic N+1 insight entry (see {@link toSyntheticInsightEntry}). */
export interface NPlusOneInsightContent {
    kind: 'n-plus-one';
    childSql: string;
    parentSql: string | null;
    count: number;
    totalDurationMs: number;
    message: string;
}
/**
 * Convert a detected pattern into a SYNTHETIC insight entry so the loop surfaces
 * in the same entry stream as everything else (deep-linked to its batch). It is
 * NOT a captured event — `id` is derived deterministically from the batch +
 * child family so re-running detection over the same batch yields a stable id
 * (idempotent ingestion). Carries the `n-plus-one` + `insight` tags for filtering.
 */
export declare function toSyntheticInsightEntry(pattern: NPlusOnePattern, at?: Date): Entry<NPlusOneInsightContent>;
//# sourceMappingURL=n-plus-one-pattern.d.ts.map