import { type ModuleCompatibility } from "@telorun/analyzer"; import type { ModuleVersion } from "./build-import-upgrades.js"; export type { ModuleCompatibility }; /** * Host capability: the `telo.yaml` text of one version of a module, or `null` * when this host cannot address it (a transport it does not speak, a ref with * no version segment). Rejecting is equally fine — both read as "not known", * never as "incompatible". * * Narrow on purpose, and separate from {@link ModuleVersionLookup}: enumerating * versions and reading one manifest are different routes with different costs, * and a host caches or throttles them differently. */ export type ModuleManifestReader = (baseRef: string, version: string) => Promise; /** The question an upgrade asks of a candidate version. */ export type VersionCompatibilityCheck = (baseRef: string, version: string) => Promise; /** * A compatibility check backed by `read`, memoized per module and version for * the lifetime of the returned function. * * The cache is not an optimization detail — an IDE re-derives its upgrade * affordances on every keystroke, and a published version's declared * requirement is immutable, so refetching it would be pure waste against an * answer that cannot have changed. In-flight promises are shared, so the * concurrent lookups one file's imports produce collapse to one read each. * * The verdict is always the analyzer's {@link manifestCompatibility}: an IDE * reports NO host versions, because it is not the machine that will run the * manifest. Only the telo surface is checked here; a host requirement still * surfaces at the load gate when the manifest is actually run. */ export declare function createVersionCompatibility(read: ModuleManifestReader, teloVersion?: string): VersionCompatibilityCheck; /** A check that answers `unknown` for everything — the honest reading for a * host with no way to fetch a candidate manifest. Never blocks an upgrade. */ export declare const uncheckedVersionCompatibility: VersionCompatibilityCheck; /** Why a candidate was not offered. `unknown` never appears: a version that * could not be read is offered, since an unreachable source must not silently * freeze an author's imports. */ export type IncompatibilityReason = Exclude; export interface VersionSelection { /** The newest version this runtime can host that is also newer than the * current one, or `null` when there is none. */ best: ModuleVersion | null; /** The newest candidate overall, when it is NOT `best` — what was held back. * Reported rather than swallowed: without it an upgrade affordance says * "up to date" while newer versions exist, which is a silent ceiling and a * worse report than the load failure this whole check replaces. */ heldBack: { version: string; reason: IncompatibilityReason; } | null; } /** * The newest version whose declared requirement accepts this runtime, among * those newer than `currentVersion`. * * Walks newest-first and stops at the first satisfied candidate, so the common * case — the newest version is compatible — costs a single manifest read. * Candidates older than the current version are never considered: an upgrade * that walks backwards is a downgrade nobody asked for. Pass `null` for an * import that does not exist yet, where every published version is a candidate * and there is nothing to walk backwards from. */ export declare function selectCompatibleVersion(baseRef: string, versions: readonly ModuleVersion[], currentVersion: string | null, isCompatible: VersionCompatibilityCheck, options?: { includePrerelease?: boolean; }): Promise; /** One version as a picker renders it: what it is, and what this runtime makes * of it. */ export interface MarkedVersion extends ModuleVersion { compatibility: ModuleCompatibility; } /** * Every version, each carrying its own verdict — what a deliberate pick needs. * * Unlike {@link selectCompatibleVersion} this cannot short-circuit: a picker * marks entries it is not going to choose, so every entry has to be asked. That * is why the two are separate operations rather than one with a flag — the * automatic path must stay one read, and the picker is an explicit action on a * single import whose reads are cached from then on. */ export declare function markVersionCompatibility(baseRef: string, versions: readonly ModuleVersion[], isCompatible: VersionCompatibilityCheck): Promise; /** * Why nothing in a marked list can be offered, or `null` when something can. * * A picker has to state this outright: a list where every row is marked * explains nothing on its own, and the reader is left thinking the tool is * broken. A reason rather than a boolean because the two rejections have * different remedies — see {@link describeRemedy}. `unknown` counts as * offerable: a version this host could not check is not one it may refuse. */ export declare function noneRunnableReason(versions: readonly MarkedVersion[]): IncompatibilityReason | null; //# sourceMappingURL=version-compatibility.d.ts.map