type Accessor<T> = () => T;
interface RouteDefinition {
    readonly id: string;
    readonly path?: string;
    readonly index?: true;
    readonly children?: readonly RouteDefinition[];
    readonly adapter?: RouteAdapter;
    readonly render?: (context: RenderContext) => Element;
    readonly reuseKey?: (context: Match) => string;
}
interface Match {
    readonly id: string;
    readonly params: Readonly<Record<string, string>>;
    readonly definition: RouteDefinition;
}
interface LocationState {
    readonly url: URL;
    readonly key: string;
    readonly matches: readonly {
        readonly id: string;
        readonly params: Readonly<Record<string, string>>;
    }[];
}
interface RenderContext {
    /** Destination snapshot for one-time route initialization. */
    readonly url: URL;
    readonly location: Accessor<LocationState>;
    readonly params: Readonly<Record<string, string>>;
    readonly outlet: HTMLElement;
    /** Aborts if preparation is cancelled or this owner is released; retained owners stay live. */
    readonly signal: AbortSignal;
}
interface NavigationContext {
    readonly url: URL;
    readonly matches: readonly Match[];
    readonly signal: AbortSignal;
    readonly revalidate: boolean;
    readonly location: Accessor<LocationState>;
}
interface PreparedView {
    readonly title?: string;
    readonly status?: number;
    readonly focus?: HTMLElement;
    validate(): void;
    commit(): void;
    activate(): Promise<void>;
    dispose(): void;
}
interface Redirect {
    readonly redirect: string;
}
interface ActionOutcome {
    readonly outcome: 'success' | 'validation' | 'error' | 'redirect';
    readonly status: number;
    readonly data: Readonly<Record<string, unknown>>;
}
interface AdapterSession {
    initialize?(context: NavigationContext): Promise<void>;
    prepare(context: NavigationContext): Promise<PreparedView | Redirect>;
    allowsAction?(url: URL): boolean;
    admitAction?(data: unknown, response: Response, url: URL): ActionOutcome;
    invalidate?(): void;
    dispose(): void;
}
interface RouteAdapter {
    readonly kind: 'browser' | 'html' | 'native';
    connect(root: HTMLElement): AdapterSession;
}
interface RouterOptions {
    readonly routes: readonly RouteDefinition[];
    readonly root: HTMLElement;
    readonly adapter: RouteAdapter;
    readonly base?: string;
    readonly statusRegion?: HTMLElement;
    readonly title?: (location: LocationState) => string;
    readonly onError?: (code: string) => void;
    readonly onAction?: (outcome: ActionOutcome, form: HTMLFormElement) => void;
    readonly checkContext?: (signal: AbortSignal) => Promise<boolean>;
    readonly contextChannel?: string;
    /** Public, build-specific recovery namespace. Never put a user identifier here. */
    readonly recoveryKey?: string;
    /** Explicit server/application attestation that this GET is safe to speculate. */
    readonly canPrefetch?: (url: URL) => boolean;
}
type NavigationResult = {
    kind: 'committed';
    location: LocationState;
    ready: Promise<void>;
} | {
    kind: 'cancelled';
    reason: 'superseded' | 'unchanged' | 'disposed';
} | {
    kind: 'blocked';
} | {
    kind: 'document-navigation';
    reason: string;
} | {
    kind: 'failed';
    code: string;
};
type SubmissionResult = {
    kind: 'success';
} | {
    kind: 'validation' | 'error';
    status: number;
    data: Readonly<Record<string, unknown>>;
} | {
    kind: 'busy' | 'unsupported' | 'uncertain' | 'disposed';
};
interface Router {
    readonly location: Accessor<LocationState>;
    readonly pending: Accessor<URL | undefined>;
    readonly mutation: Accessor<'idle' | 'submitting' | 'revalidating' | 'uncertain'>;
    readonly ready: Promise<void>;
    navigate(to: string | URL, options?: {
        replace?: boolean;
    }): Promise<NavigationResult>;
    revalidate(): Promise<NavigationResult>;
    prefetch(to: string | URL): Promise<'completed' | 'skipped' | 'cancelled'>;
    submit(form: HTMLFormElement, submitter?: HTMLElement): Promise<SubmissionResult>;
    beforeLeave(check: (next: URL, signal: AbortSignal) => boolean | Promise<boolean>): () => void;
    invalidateContext(): void;
    /** Clear the unknown-outcome latch only after application status/idempotency evidence. */
    resolveUncertain(check: (signal: AbortSignal) => Promise<boolean>): Promise<boolean>;
    dispose(): void;
}
declare class NavigationError extends Error {
    readonly code: string;
    readonly documentRecovery: boolean;
    readonly revoke: boolean;
    constructor(code: string, documentRecovery?: boolean, revoke?: boolean);
}

/** One coordinator per Document. Private/native response cache capacity is deliberately zero. */
declare function createRouter(input: RouterOptions): Router;

/** Copy and validate caller configuration; mutation of the source never changes matching. */
declare function defineRoutes(input: readonly RouteDefinition[]): readonly RouteDefinition[];
declare function matchRoutes(routes: readonly RouteDefinition[], pathname: string): readonly Match[] | null;

/** Each route render runs once inside a separately disposable Forma root. */
declare function createBrowserAdapter(): RouteAdapter;

interface NavigationBootstrap {
    readonly registrations: Readonly<Record<string, (element: HTMLElement, props: Record<string, unknown> | null) => unknown>>;
    readonly app: string;
    readonly build: string;
    readonly group: string;
    readonly owners: readonly string[];
}
declare function createNativeAdapter(bootstrap: NavigationBootstrap): RouteAdapter;

interface HtmlPage {
    readonly path: string;
    /** SHA-256 of the complete UTF-8 generated document, emitted at build time. */
    readonly sha256: string;
    readonly title: string;
    /** Build-generated identity of the immutable head/policy/assets. */
    readonly head: string;
}
interface HtmlAdapterOptions {
    readonly head: string;
    readonly pages: readonly HtmlPage[];
}
/** Explicitly registered static documents. Only the marked region is ever parsed. */
declare function createHtmlAdapter(options: HtmlAdapterOptions): RouteAdapter;

interface LinkProps {
    href: string | URL;
    children?: string | Node | readonly (string | Node)[];
    target?: string;
    download?: string;
    class?: string;
    /** Leave this link to the browser. */
    native?: boolean;
    document?: Document;
}
/** An ordinary anchor; interception belongs to the root coordinator. */
declare function Link(props: LinkProps): HTMLAnchorElement;
/** Return the exact child outlet supplied to a browser route render. */
declare function Outlet(props: {
    outlet: HTMLElement;
}): HTMLElement;

export { type Accessor, type ActionOutcome, type AdapterSession, type HtmlAdapterOptions, type HtmlPage, Link, type LinkProps, type LocationState, type Match, type NavigationBootstrap, type NavigationContext, NavigationError, type NavigationResult, Outlet, type PreparedView, type Redirect, type RenderContext, type RouteAdapter, type RouteDefinition, type Router, type RouterOptions, type SubmissionResult, createBrowserAdapter, createHtmlAdapter, createNativeAdapter, createRouter, defineRoutes, matchRoutes };
