import { type AttributedDiff } from "./attribution.js"; import type { BuildRunResult } from "./build-run.js"; import { diffSnapshotFiles, type HeapDiff } from "./heap-diff.js"; import { extractModuleRegistry } from "./module-registry.js"; export type BuildAttribution = { diff: HeapDiff; attributed: AttributedDiff; /** Modules the registry resolved. Zero means every finding stays unattributed. */ registrySize: number; /** Share of the worker's observed growth the snapshot pair spans, 0 to 1. */ bracketed: number; baselineRssBytes: number; afterRssBytes: number; /** Where the pair was stored, so the finding can be checked by hand. */ baselineFile: string; afterFile: string; }; /** * Why a run that asked for attribution came back without one. * * An absent section and a failed diff read the same in a report, and they are * opposite findings: one says nobody asked what the worker retained, the other * says the question was asked and the evidence could not be read. The build * path fails this way hardest on the builds worth measuring — a snapshot past * roughly a gigabyte of worker rss cannot be parsed back, so the bigger the * build grew, the likelier the report says nothing about what grew. */ export type BuildAttributionGap = { /** * `capture-missed`: the run was told to capture and never got a usable pair. * `snapshot-unreadable`: the pair exists and the diff refused it. */ reason: "capture-missed" | "snapshot-unreadable"; detail: string; }; /** Narrows the outcome of `attributeBuildCapture`. */ export declare function isAttributionGap(outcome: BuildAttribution | BuildAttributionGap | null): outcome is BuildAttributionGap; export type BuildAttributionDeps = { diff: typeof diffSnapshotFiles; registry: typeof extractModuleRegistry; }; /** * Names what a build's worker retained, from the pair the run captured. * * Never throws on a failure path. A build measurement stands on its curve and * its verdict; this is an addition to the report, and an addition that can * fail must not be able to take the report with it. It returns a gap instead, * so the report can tell a question nobody asked from one it could not answer. * Null is reserved for the run that never asked. * * The registry is read from `.next/server` *after* the build, never during it: * a half-written chunk can resolve a module id to the wrong source, and naming * the wrong owner confidently is worse than naming none. */ export declare function attributeBuildCapture(result: BuildRunResult, appDir: string, onProgress?: (message: string) => void, deps?: BuildAttributionDeps): Promise;