/** * Linker data structures for semantic cross-shard resolution (plan #2, Phase 1). * * Two pure "symbol tables" the boundary resolver (Phase 2) links against — * derivable entirely from data already present in a merged catalog plus the * resolved `Shard[]`: * * 1. {@link ExportIndex} — per-package map of exported function name → * occurrences (`visibility === 'exported'`). The export symbol table: * "given a package and a callee name, which exported occurrences match?" * 2. {@link PackageManifestIndex} — package `name` → its on-disk manifest * (`name`, dir, `exports` map). Lets {@link resolveSpecifierToPackage} * turn a bare import specifier (`@scope/pkg[/subpath]`) into the package * group the {@link ExportIndex} is keyed by. * * Engine-layer and language-agnostic: no TypeScript parser, no AST. The only * effect is reading each package's `package.json` from disk in * {@link buildPackageManifestIndex}; everything else is plain map/path/JSON * math. These structures are UNUSED by resolution logic in Phase 1 — Phase 2 * wires them into `resolveCrossBoundaryCalls`. * * Package-key alignment (the linchpin Phase 2 depends on): the boundary * resolver buckets occurrences by `packageOf(occ.filePath)` — the path segment * under `packages/` (e.g. `core`, `graph`, `languages`), NOT the package.json * `name`. So {@link buildExportIndex} keys by exactly that, and * {@link resolveSpecifierToPackage} returns a `packageGroup` derived by running * `packageOf` over the manifest's project-relative dir — so a specifier's * resolved group matches the `ExportIndex` keys verbatim. */ import type { Shard } from './shard-model.js'; import type { Catalog, FunctionOccurrence } from '../../types.js'; /** * Per-package export symbol table: `package` → (`name` → exported occurrences). * * The outer key is `packageOf(filePath)` (the `packages/` group), * matching the bucketing the boundary resolver uses; the inner key is a * function's `simpleName`. Only `visibility === 'exported'` occurrences are * present — module-local and private occurrences are excluded, since an import * specifier can only reach a package's exports. * * Insertion order follows catalog iteration. Consumers MUST match by name, not * order; the inner arrays are the deterministic candidate set for a name. */ export type ExportIndex = ReadonlyMap>; /** * Bucket every exported occurrence in `catalog` by its package group then by * its simple name. Deterministic and allocation-lean: one pass over * `catalog.functions`, no sorting (matching is by name, not order). * * The package key is `packageOf(occ.filePath)` — identical to what the * cross-shard resolver buckets by — so Phase 2 can look up * `exportIndex.get(packageGroup)` where `packageGroup` comes from * {@link resolveSpecifierToPackage}. */ export declare function buildExportIndex(catalog: Catalog): ExportIndex; /** * One workspace package's manifest facts the specifier resolver needs. * * `dir` is the package's PROJECT-RELATIVE root (e.g. `packages/core`) — the * form `packageOf` expects — derived from the shard's absolute `rootDir` * against the common project root. `exportsMap` is the raw `exports` field * (when an object), used to gate subpath resolution. */ export interface PackageManifest { readonly name: string; readonly dir: string; readonly exportsMap?: Record; } /** Package `name` → its {@link PackageManifest}. */ export type PackageManifestIndex = ReadonlyMap; /** * Read each shard's `package.json` (`name`, `exports`) and index it by package * name. Reuses the already-resolved `Shard[]` (no re-discovery); a shard whose * `rootDir` has no readable/parseable `package.json`, or whose manifest has no * string `name`, is skipped (it simply won't be specifier-resolvable). * * `projectRoot` is the common root all shard file paths are relativized * against, so each manifest's `dir` is in the same project-relative form * `packageOf` consumes. */ export declare function buildPackageManifestIndex(shards: readonly Shard[], projectRoot: string): PackageManifestIndex; /** The outcome of resolving a bare import specifier to a workspace package. */ export interface ResolvedSpecifier { /** The `packageOf`-aligned group key — looks up into an {@link ExportIndex}. */ readonly packageGroup: string; /** The `exports` subpath (`./errors`) when the specifier addressed one. */ readonly subpath?: string; } /** * Resolve a bare import specifier (`@scope/pkg` or `@scope/pkg/subpath`, or the * unscoped `pkg` / `pkg/subpath`) to the package group an {@link ExportIndex} * is keyed by, plus the addressed `exports` subpath when present. * * Returns `undefined` (→ Phase 2 declines, emits no edge) when: * - the specifier is relative (`./x`) or empty — not a bare package import; * - the package name is not in `manifestIndex` (external / untracked dep); * - a subpath is present but is NOT declared in the package's `exports` map. * * **V1 subpath scope (open question decided here):** resolve the package ROOT * export and only those subpaths LITERALLY declared as keys in `exports` * (`./errors`, `./languages/parse-cache.js`). Glob/conditional `exports` * resolution is deferred. A package with no object `exports` is treated as * exposing only its root — any subpath against it is unmappable → `undefined`. * The returned `packageGroup` is the same for root and subpath (the subpath * lives inside the same package); Phase 2 narrows by name within that group. */ export declare function resolveSpecifierToPackage(specifier: string, manifestIndex: PackageManifestIndex): ResolvedSpecifier | undefined; //# sourceMappingURL=export-index.d.ts.map