/** * Full-rebuild and incremental-rebuild catalog assembly. * * Owns the parse → walk → resolve stages and stitches the resolver's * edge map into the catalog skeleton. The `ParsedProject` is created * inside each rebuild path and stays internal so V8 can reclaim the * AST as soon as `resolveCallSites` returns. * * `runStage` is passed in by the orchestrator so we don't reimport * the progress/pressure-monitor wrapper here. */ import { type EngineMode } from '../../cache/engine-version.js'; import type { GraphProgressCallback, GraphStage } from './types.js'; import type { DiscoverOutput, GraphLanguageAdapter } from '../../lang-adapter/types.js'; import type { Catalog, CrossBoundaryCall, ParseError, ResolutionMode, ResolutionStats } from '../../types.js'; import type { PressureMonitor } from '../pressure-monitor.js'; import type { Attributes } from '@opensip-cli/core'; /** * Arguments to a {@link RunStage} invocation: the stage label, the * live-view/pressure plumbing, the work to run, and optional result * labelers for the progress detail line and span attributes. */ export interface RunStageArgs { readonly stage: GraphStage; readonly onProgress: GraphProgressCallback | undefined; readonly monitor: PressureMonitor | undefined; /** The stage work. May be sync or async — async stages (e.g. the cooperative * resolve) let the live view's spinner animate (ADR-0016). */ readonly fn: () => T | Promise; readonly detailFn?: (result: T) => string | undefined; readonly attrsFn?: (result: T) => Attributes; } /** * Shape of the `runStage` helper passed in by the orchestrator. * Kept here as a type alias so catalog-builder doesn't import the * concrete function (which lives in orchestrate.ts at the parent * level) and we avoid a circular dependency. * * Async: `runStage` awaits its `fn` and yields to the event loop so the live * view animates during long stages (ADR-0016). */ export type RunStage = (args: RunStageArgs) => Promise; /** Inputs to the full-rebuild {@link buildAndResolveCatalog}. */ export interface CatalogBuildOptions { readonly runStage: RunStage; readonly adapter: GraphLanguageAdapter; readonly discovery: DiscoverOutput; readonly resolutionMode: ResolutionMode; readonly onProgress?: GraphProgressCallback; readonly monitor?: PressureMonitor; /** * Sharded build (plan #2): when true, request cross-boundary call * descriptors from the adapter and surface them in the return for the * cross-shard pass. Off for ordinary single-process builds. */ readonly emitBoundaryCalls?: boolean; /** * Which build engine owns this catalog (Phase 2 determinism). Folded into * the catalog `cacheKey` via {@link stampEngineVersion} so the exact * (single-program) and sharded engines — which share the single * `graph_catalog` row / shard-fragment cache but build structurally * incompatible catalogs — never read each other's persisted rows. Defaults * to `'exact'` (the single-program path); the shard worker passes * `'sharded'`. */ readonly engineMode?: EngineMode; } /** * Run Stage 1 + Stage 2 and return only the catalog and resolution * stats. The parsed project is created inside this function and does * not escape — once edge resolution returns, it is unreachable from * any caller, so V8 can reclaim the bound AST before Stage 3 * (`buildIndexes`) and the cache write run. */ export declare function buildAndResolveCatalog(options: CatalogBuildOptions): Promise<{ readonly catalog: Catalog; readonly resolutionStats: ResolutionStats; readonly boundaryCalls?: readonly CrossBoundaryCall[]; readonly parseErrors: readonly ParseError[]; }>; /** * Wave 4 incremental rebuild — re-walk only changed files plus their * transitive edge-dependents, then merge with cached entries for * unchanged files. * * Algorithm: * 1. Parse the project once over ALL current files (the resolver * pass needs the full program for cross-file symbol lookup). * 2. Convert the absolute changed-files set to project-relative * paths so we can match the catalog's filePath field. * 3. Iterate to fixpoint: walk closure files, identify hashes that * vanished or changed, find unchanged files whose cached edges * reference those hashes, add them to the closure, repeat until * no new dependents are discovered. * 4. Merge cached entries for files NOT in the closure with * freshly-walked-and-resolved entries for files IN the closure. * * Correctness vs full rebuild: every file whose cached edges might * point at a stale hash is itself re-walked. After the fixpoint, no * cached edge dangles. Verified by `incremental rebuild produces a * catalog identical to a full rebuild` test. */ export interface IncrementalCatalogBuildOptions { readonly runStage: RunStage; readonly adapter: GraphLanguageAdapter; readonly discovery: DiscoverOutput; readonly cachedCatalog: Catalog; readonly changedFilesAbs: readonly string[]; readonly resolutionMode: ResolutionMode; readonly onProgress?: GraphProgressCallback; readonly monitor?: PressureMonitor; /** Emit cross-boundary descriptors for the re-walked closure (Phase 3 * convergence — the exact path recovers them so warm == cold). */ readonly emitBoundaryCalls?: boolean; } export declare function buildAndResolveCatalogIncremental(options: IncrementalCatalogBuildOptions): Promise<{ readonly catalog: Catalog; readonly resolutionStats: ResolutionStats; readonly boundaryCalls?: readonly CrossBoundaryCall[]; readonly parseErrors: readonly ParseError[]; }>; //# sourceMappingURL=catalog-builder.d.ts.map