/** * Minimal structural view of a parsed heap snapshot. `@memlab`'s * IHeapSnapshot satisfies it; tests use small hand-built graphs. */ export type HeapEdgeLike = { type: string; name_or_index: string | number; fromNode: HeapNodeLike; }; export type HeapNodeLike = { id: number; type: string; name: string; self_size: number; retainedSize: number; referrers: HeapEdgeLike[]; /** Outgoing edges; optional because test fixtures rarely need them. */ references?: Array<{ name_or_index: string | number; }>; }; export type HeapLike = { nodes: { forEach(callback: (node: HeapNodeLike) => void): void; }; }; export type DiffOptions = { /** Type-level deltas smaller than this are dropped. Default 20 KiB. */ minTypeDeltaBytes?: number; /** Retained-size growth for an existing node to be reported. Default 100 KiB. */ grownThresholdBytes?: number; /** Retained size for a new node to be considered. Default 2 KiB. */ newThresholdBytes?: number; /** * Baseline nodes with retained size below this floor are not tracked for * growth — the memory guard that keeps the baseline summary small. * Default 50 KiB. */ bigRetainedFloorBytes?: number; maxFindings?: number; chainDepth?: number; }; export type TypeDelta = { type: string; deltaBytes: number; }; export type NodeFinding = { kind: "grown" | "new"; nodeType: string; name: string; /** Retained-size delta for grown nodes; absolute retained size for new ones. */ retainedBytes: number; retainerChain: string; /** Bundler module ids seen along the chain (needs `resolveNumeric`). */ moduleIds: number[]; }; export type HeapDiff = { typeDeltas: TypeDelta[]; grownNodes: NodeFinding[]; newNodes: NodeFinding[]; }; /** * Compact summary of a baseline heap. This is all that stays resident after * the baseline snapshot is parsed — never the heap itself. */ export type BaselineSummary = { nodeIds: Set; bigRetained: Map; typeSelfSizes: Map; }; export declare function summarizeBaseline(heap: HeapLike, options?: DiffOptions): BaselineSummary; /** * Walks referrers upward preferring strong, non-synthetic edges and refusing * to revisit nodes, producing a single human-readable ownership chain. */ export declare function retainerChain(node: HeapNodeLike, depth: number): string; export declare function diffAgainstBaseline(baseline: BaselineSummary, after: HeapLike, options?: DiffOptions): HeapDiff; export declare class SnapshotError extends Error { /** * Bytes that had to fit in one string, when that is why the snapshot was * refused. Carried on the error so the caller — which knows the load that * produced it — can work out what would have fit. */ readonly parsedBytes?: number; constructor(message: string, parsedBytes?: number); } /** * How many bytes of a snapshot memlab actually has to hold in one string. * * Null when the file does not look like the layout above, in which case the * caller falls back to judging it by its total size — what this tool did for * every snapshot before it was measured that the two are wildly different: on * a 1342.9 MB snapshot of a leaking route, 1340.5 MB were `nodes` and `edges` * and 2.4 MB reached `JSON.parse`. Refusing that one cost the attribution on * the worst leak in the run. */ export declare function parsedSectionBytes(file: string, fileSize: number): Promise; /** * Cheap structural check before handing a file to memlab. * * memlab does not throw on malformed input — it calls `process.exit(1)`, * which no try/catch can intercept. Without this guard a truncated snapshot * (disk full, process killed mid-write) killed the CLI outright and took a * multi-hour run's results with it. Reads O(1) bytes, not the whole file. */ export declare function assertReadableSnapshot(file: string): Promise; export type HeapLoader = (file: string) => Promise; /** * Diffs two snapshot files parsing them strictly sequentially: the baseline * heap is reduced to its compact summary and released before the after heap * is parsed, so at most one full heap graph is resident at any time. */ export declare function diffSnapshotFiles(baselineFile: string, afterFile: string, options?: DiffOptions, loadHeap?: HeapLoader): Promise;