/** * Wait for the DOM to stop changing. * * Network idle is not enough for a single-page app. The framework renders * AFTER the chunk request resolves, and nothing is in flight while it does, so * a network-quiet gate returns while the page still reads "Loading...". That * is not a cosmetic problem for a scanner: a half-rendered page has different * controls, so it gets a different view identity, thinner content for a goal * to match against, and — worst — an incomplete set of outbound links, which * silently removes routes from the graph. * * Measured on a real scan before this existed: four of five recorded views * contained "Loading...", and the home page had no footer links at all. */ export interface DomStabilityOptions { /** Consecutive identical samples required before the DOM counts as stable. */ stableSamples?: number; /** Delay between samples. */ pollMs?: number; /** Hard cap. A page that never stops changing must not stall the scan. */ timeout?: number; } export declare const DOM_STABILITY_DEFAULTS: Required; export interface DomStabilityDeps { now?: () => number; sleep?: (ms: number) => Promise; /** Called when the cap was hit before the DOM settled. */ onTimeout?: () => void; } /** * Resolve once `sample` returns the same fingerprint `stableSamples` times in * a row, or once the cap elapses. * * Returning on the cap rather than throwing is deliberate: a page with a * spinner, a clock or a polling widget never settles, and a scan of it should * be slightly stale rather than dead. */ export declare function waitForStableDom(sample: () => Promise, options?: DomStabilityOptions, deps?: DomStabilityDeps): Promise; /** * A cheap fingerprint of what the page currently shows. * * Element count catches structure appearing; text length catches a spinner * being replaced by content. Together they cover the two ways a lazy route * finishes rendering. */ export declare const DOM_FINGERPRINT_SCRIPT: () => string; //# sourceMappingURL=dom-stability.d.ts.map