/** * Shared browser-side navigation coordinator. * * This module is the client runtime contract used by browser-router, * react-router, and HMR code to coordinate ownership, cross-runtime handoff, * current-page reloads, and stale-navigation cancellation. * * The coordinator stays framework-agnostic: browser runtimes register their * capabilities here, and the coordinator arbitrates which runtime currently * owns the document and which navigation transaction is still current. * * @module */ /** Logical owner name for a browser navigation runtime. */ export type EcoNavigationOwner = 'none' | 'browser-router' | 'react-router' | (string & {}); /** HTML attribute used to persist the rendered document owner across navigations. */ export declare const ECO_DOCUMENT_OWNER_ATTRIBUTE = "data-eco-document-owner"; /** High-level navigation direction understood by browser runtimes. */ export type EcoNavigationDirection = 'forward' | 'back' | 'replace'; /** Navigation request sent between browser runtimes. */ export type EcoNavigationRequest = { href: string; direction?: EcoNavigationDirection; source?: EcoNavigationOwner; }; /** Navigation handoff request that includes a pre-fetched document. */ export type EcoNavigationHandoffRequest = EcoNavigationRequest & { finalHref?: string; targetOwner: EcoNavigationOwner; document: Document; html?: string; /** * Reports whether the source runtime's original navigation has already been * superseded. * * Target runtimes use this to ignore handoff work that arrives after a newer * navigation has already claimed ownership. */ isStaleSourceNavigation?: () => boolean; }; /** Request to reload the current page through the active runtime. */ export type EcoReloadRequest = { /** * Clears runtime-owned caches before reloading. * * Runtimes use this when a reload must discard persisted client state such as * cached layouts or route-local module instances. */ clearCache?: boolean; /** * Explicit page module URL to load for the reload. * * This is primarily used by HMR-aware runtimes so a current-page reload can * reuse the active hot module entry instead of rediscovering the static page * bootstrap asset from the fetched HTML document. */ moduleUrl?: string; source?: EcoNavigationOwner; }; /** Snapshot of the coordinator's current runtime ownership state. */ export type EcoNavigationOwnerState = { owner: EcoNavigationOwner; canHandleSpaNavigation: boolean; }; /** * Coordinator-managed navigation transaction. * * Runtimes use this to determine whether async work has become stale and to * cancel or complete the active navigation sequence. */ export type EcoNavigationTransaction = { id: number; signal: AbortSignal; isCurrent: () => boolean; cancel: () => void; complete: () => void; }; export type EcoNavigationRuntimeEvent = { type: 'owner-change'; owner: EcoNavigationOwner; previousOwner: EcoNavigationOwner; reason: 'set' | 'claim' | 'release' | 'document' | 'unregister'; } | { type: 'registration-change'; owner: EcoNavigationOwner; status: 'registered' | 'unregistered'; }; export type EcoNavigationRuntimeListener = (event: EcoNavigationRuntimeEvent) => void; export type EcoNavigationRuntimeRegistration = { owner: EcoNavigationOwner; navigate?: (request: EcoNavigationRequest) => Promise; handoffNavigation?: (request: EcoNavigationHandoffRequest) => Promise; /** * Reloads the current page through the runtime's local navigation mechanism. * * Implementations may honor `request.moduleUrl` to force a specific page entry * and `request.clearCache` to discard persisted runtime state before reloading. */ reloadCurrentPage?: (request?: EcoReloadRequest) => Promise; /** * Releases runtime-owned client state before another runtime commits a new * document. * * This hook intentionally does not run as part of `requestHandoff()`. The * accepting runtime decides when cleanup is safe so cross-runtime handoffs do * not blank the current page before the incoming document is ready. */ cleanupBeforeHandoff?: () => void | Promise; }; /** Public browser-side navigation coordinator interface. */ export interface EcoNavigationRuntime { /** Returns the currently active runtime owner and whether it can handle SPA navigation. */ getOwnerState(): EcoNavigationOwnerState; /** Starts a new navigation transaction, invalidating the previously active one. */ beginNavigationTransaction(): EcoNavigationTransaction; /** Reports whether a navigation transaction is still in flight. */ hasPendingNavigationTransaction(): boolean; /** Cancels the active navigation transaction, if one exists. */ cancelCurrentNavigationTransaction(): void; /** Forces the current owner value without checking registrations. */ setOwner(owner: EcoNavigationOwner): void; /** Claims ownership for a runtime that is ready to drive SPA navigation. */ claimOwnership(owner: EcoNavigationOwner): void; /** Releases ownership when the given runtime no longer controls the document. */ releaseOwnership(owner: EcoNavigationOwner): void; /** Resolves document ownership from the rendered owner marker or fallback. */ resolveDocumentOwner(doc: Document, fallbackOwner?: EcoNavigationOwner): EcoNavigationOwner; /** Reads and adopts the rendered document owner as the active runtime owner. */ adoptDocumentOwner(doc: Document, fallbackOwner?: EcoNavigationOwner): EcoNavigationOwner; /** Returns whether the active owner is some runtime other than the given owner. */ isOwnedByAnotherRuntime(owner: EcoNavigationOwner): boolean; /** Subscribes to ownership and registration change events. */ subscribe(listener: EcoNavigationRuntimeListener): () => void; /** Registers a runtime implementation with the coordinator. */ register(runtime: EcoNavigationRuntimeRegistration): () => void; /** Requests navigation through another eligible registered runtime. */ requestNavigation(request: EcoNavigationRequest): Promise; /** * Hands a pre-fetched document to the target runtime. * * The coordinator delegates the document but does not clean up the current * owner first. Cleanup timing belongs to the accepting runtime so a stale or * superseded handoff cannot tear down the current page prematurely. */ requestHandoff(request: EcoNavigationHandoffRequest): Promise; /** Requests the active runtime to reload the current page. */ reloadCurrentPage(request?: EcoReloadRequest): Promise; /** Runs a target runtime's cleanup hook before handoff. */ cleanupOwner(owner: EcoNavigationOwner): Promise; /** Runs cleanup for whichever runtime currently owns the document. */ cleanupCurrentOwner(): Promise; } /** * Reads the explicit browser document owner marker from a rendered HTML document. * * Documents without a marker return `null`, allowing runtimes to fall back to * their local default behavior without scanning hydration scripts. */ export declare function getEcoDocumentOwner(doc: Document): EcoNavigationOwner | null; /** * Returns the singleton browser-side navigation coordinator. * * The coordinator centralizes ownership, handoff, and current-page reload * requests across browser runtimes through one internal protocol. * * @param windowObject - Window-like object that stores the singleton runtime. * @returns The shared browser navigation coordinator. */ export declare function getEcoNavigationRuntime(windowObject?: Window & typeof globalThis): EcoNavigationRuntime;