import { Directive, InjectionKey, Plugin, PropType, Ref, ShallowRef, VNode } from "vue"; import { NavigationOptions, NavigationTarget, Navigator, Navigator as Navigator$1, Params, Router, RouterError, SearchParams, State } from "@real-router/core"; import { RouteUtils } from "@real-router/route-utils"; import { RouterTransitionSnapshot, RouterTransitionSnapshot as RouterTransitionSnapshot$1 } from "@real-router/sources"; //#region src/components/RouteView/types.d.ts interface RouteViewProps { readonly nodeName: string; readonly keepAlive?: boolean; } interface MatchProps { readonly segment: string; readonly exact?: boolean; readonly fallback?: VNode | (() => VNode); readonly keepAlive?: boolean; } interface SelfProps { /** Fallback content while children are suspended. */ readonly fallback?: VNode | (() => VNode); } type NotFoundProps = Record; //#endregion //#region src/components/RouteView/RouteView.d.ts export declare const RouteView: { new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins> & Readonly<{}>, () => VNode | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, import("vue").PublicProps, { keepAlive: boolean; }, true, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, { P: {}; B: {}; D: {}; C: {}; M: {}; Defaults: {}; }, Readonly> & Readonly<{}>, () => VNode | null, {}, {}, {}, { keepAlive: boolean; }>; __isFragment?: never; __isTeleport?: never; __isSuspense?: never; } & import("vue").ComponentOptionsBase> & Readonly<{}>, () => VNode | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, { keepAlive: boolean; }, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & { Match: import("vue").DefineComponent; required: true; }; exact: { type: BooleanConstructor; default: boolean; }; fallback: { type: import("vue").PropType VNode)>; default: undefined; }; keepAlive: { type: BooleanConstructor; default: boolean; }; }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly; required: true; }; exact: { type: BooleanConstructor; default: boolean; }; fallback: { type: import("vue").PropType VNode)>; default: undefined; }; keepAlive: { type: BooleanConstructor; default: boolean; }; }>> & Readonly<{}>, { fallback: VNode | (() => VNode); keepAlive: boolean; exact: boolean; }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>; Self: import("vue").FunctionalComponent; NotFound: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>; }; //#endregion //#region src/components/Link.d.ts export declare const Link: import("vue").DefineComponent; default: undefined; }; routeParams: { type: PropType; default: undefined; }; routeSearch: { type: PropType; default: undefined; }; routeOptions: { type: PropType; default: () => Readonly<{}>; }; class: { type: StringConstructor; default: undefined; }; activeClassName: { type: StringConstructor; default: string; }; activeStrict: { type: BooleanConstructor; default: boolean; }; ignoreQueryParams: { type: BooleanConstructor; default: boolean; }; target: { type: StringConstructor; default: undefined; }; /** * URL fragment (decoded form, no leading "#") (#532). * - omitted/`undefined` → preserve current fragment on same-route navigation * - `""` → clear fragment * - non-empty → set fragment */ hash: { type: StringConstructor; default: undefined; }; }>, () => import("vue").VNode, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly; default: undefined; }; routeParams: { type: PropType; default: undefined; }; routeSearch: { type: PropType; default: undefined; }; routeOptions: { type: PropType; default: () => Readonly<{}>; }; class: { type: StringConstructor; default: undefined; }; activeClassName: { type: StringConstructor; default: string; }; activeStrict: { type: BooleanConstructor; default: boolean; }; ignoreQueryParams: { type: BooleanConstructor; default: boolean; }; target: { type: StringConstructor; default: undefined; }; /** * URL fragment (decoded form, no leading "#") (#532). * - omitted/`undefined` → preserve current fragment on same-route navigation * - `""` → clear fragment * - non-empty → set fragment */ hash: { type: StringConstructor; default: undefined; }; }>> & Readonly<{}>, { routeName: string; to: NavigationTarget; routeParams: Params; routeSearch: SearchParams; routeOptions: NavigationOptions; class: string; activeClassName: string; activeStrict: boolean; ignoreQueryParams: boolean; target: string; hash: string; }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>; //#endregion //#region src/components/RouterErrorBoundary.d.ts export declare const RouterErrorBoundary: import("vue").DefineComponent void) => VNode>; required: true; }; onError: { type: PropType<(error: RouterError, toRoute: State | null, fromRoute: State | null) => void>; default: undefined; }; }>, () => VNode, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly void) => VNode>; required: true; }; onError: { type: PropType<(error: RouterError, toRoute: State | null, fromRoute: State | null) => void>; default: undefined; }; }>> & Readonly<{}>, { onError: (error: RouterError, toRoute: State | null, fromRoute: State | null) => void; }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>; type RouterErrorBoundaryProps = InstanceType["$props"]; //#endregion //#region src/directives/vLink.d.ts interface LinkDirectiveValue { name: string; params?: Params; options?: NavigationOptions; } export declare const vLink: Directive; //#endregion //#region src/composables/useRouter.d.ts export declare const useRouter: () => Router; //#endregion //#region src/composables/useNavigator.d.ts export declare const useNavigator: () => Navigator$1; //#endregion //#region src/composables/useRouteUtils.d.ts export declare const useRouteUtils: () => RouteUtils; //#endregion //#region src/types.d.ts /** * `route`/`previousRoute` are read-only reactive references. They may be * implemented as `shallowRef` or `computed` depending on the composable * (`useRoute` mirrors via `shallowRef`, `useRouteNode` derives via `computed`), * but consumers only need `.value` read access — typed as `Readonly>`. */ interface RouteContext

{ navigator: Navigator$1; route: Readonly | undefined>>; previousRoute: Readonly>; } interface LinkProps

{ /** * Route name (channel form). Optional because the descriptor form (`to`) omits * it. The two forms are mutually exclusive — enforced at runtime by * `resolveLinkTarget` (dev-warn on conflict, `to` wins). Vue's `defineComponent` * props are runtime-validated, so the exclusion is a runtime contract here * (react/preact/solid enforce it in the type). */ routeName?: string; routeParams?: P; /** * Query (search) params for the link's target (RFC-4 M2, #1548) — parallel to * `routeParams`, the path/query split's view-layer channel. */ routeSearch?: SearchParams; /** * Descriptor form (RFC-4 M2 B2, #1548): `to={{ name, params?, search? }}` — * mutually exclusive with the channel props above. */ to?: NavigationTarget

; routeOptions?: NavigationOptions; class?: string; activeClassName?: string; activeStrict?: boolean; ignoreQueryParams?: boolean; target?: string; /** * URL fragment (#532). Decoded, no leading `#`. Tri-state: * - `undefined` (default) — preserves current `state.context.url.hash` on click. * - `""` — clears the hash. * - `"value"` — sets the hash; click routes through `navigateWithHash`, * which auto-adds `force: true, hashChange: true` for same-route hash * transitions (bypasses core's SAME_STATES check). * Active state is hash-aware when `hash` is set. */ hash?: string; } //#endregion //#region src/composables/useRoute.d.ts /** * Return shape for `useRoute()` — `RouteContext

` with `route` narrowed * to the non-nullable variant. The composable throws when `route.value` * would be `undefined`, so consumers can read `.value.params.x` without a * nullable guard. Extracted from inline duplication at two call sites. */ type UseRouteReturn

= Omit, "route"> & { route: Readonly>>; }; export declare const useRoute:

() => UseRouteReturn

; //#endregion //#region src/composables/useRouteNode.d.ts export declare function useRouteNode(nodeName: string): RouteContext; //#endregion //#region src/composables/useRouterTransition.d.ts export declare function useRouterTransition(): ShallowRef; //#endregion //#region src/composables/useRouteExit.d.ts interface RouteExitContext { /** The route being left. */ route: State; /** The route being navigated to. */ nextRoute: State; /** * AbortSignal that fires when this navigation is superseded by a later * one (rapid clicks). Already filtered: when the handler runs, * `signal.aborted` is guaranteed to be `false`. Use * `signal.addEventListener("abort", cleanup, { once: true })` for * cleanup that must run on cancellation. */ signal: AbortSignal; } interface UseRouteExitOptions { /** * Skip the handler when `route.name === nextRoute.name` * (sort/filter/query-only navigations on the same route). Default: * `true`. */ skipSameRoute?: boolean; } type RouteExitHandler = (context: RouteExitContext) => void | Promise; /** * Subscribe to the router's leave-window with the universal guards baked * in. Wraps `router.subscribeLeave` so consumers don't repeat the same * boilerplate every time: * * - **Reentrant abort pre-check**: if `signal.aborted` is already `true` * when the handler would run (rapid navigation superseded a slower * one), the handler is skipped entirely. * - **Same-route skip**: by default, `route.name === nextRoute.name` * short-circuits the handler — query-only navigations skip the work. * Opt out with `skipSameRoute: false`. * * Cleanup is bound to the component's effect scope via `onScopeDispose`. * * If the handler returns a Promise, the router blocks on it. If the * Promise resolves, navigation proceeds. If it **rejects**, the router * rejects `navigate()` with the handler's **original error** (a value that * is not an `Error` arrives wrapped in one) and emits `TRANSITION_ERROR` — * it is NOT re-coded to `TRANSITION_CANCELLED` (that arises when the * navigation's `signal` aborts). A handler that rejects with a * `RouterError(TRANSITION_CANCELLED)` itself cancels the navigation quietly: * `navigate()` rejects with that error and the router emits * `TRANSITION_CANCEL` instead (#2787). * * **Handler reactivity (Vue):** Vue composables run **once** during * `setup()`; `handler` is captured in closure at the call site. To vary * behavior over time, read refs/computeds inside the handler body — do * not rely on swapping the handler reference. * * **Under `` (#1221):** a deactivated (sleeping) page does not run * the handler on unrelated navigations — critically, its async exit is not * spliced into every navigation's leave cycle (where it would block the app). * * @example Animation * ```ts * const ref = useTemplateRef("box"); * * useRouteExit(async ({ signal }) => { * const el = ref.value; * if (!el) return; * el.classList.add("fade-out"); * const cleanup = () => el.classList.remove("fade-out"); * signal.addEventListener("abort", cleanup, { once: true }); * try { * el.getBoundingClientRect(); * await Promise.allSettled(el.getAnimations().map((a) => a.finished)); * } finally { * cleanup(); * } * }); * ``` * * @example Auto-save form draft * ```ts * useRouteExit(async ({ signal }) => { * if (formState.value.dirty) { * await api.saveDraft(formState.value, { signal }); * } * }); * ``` * * @example Detecting that you are leaving a subtree * ```ts * const inProducts = (name: string) => * name === "products" || name.startsWith("products."); * * useRouteExit(({ route, nextRoute }) => { * if (inProducts(route.name) && !inProducts(nextRoute.name)) { * // leaving the products subtree entirely — flush product-related caches * productCache.clear(); * } * }); * ``` * * ⚠ Do NOT read `nextRoute.transition` here. `nextRoute` is the PENDING target, * and the pipeline gives it the neutral default — empty `segments`, optional * flags `undefined` — so the example this replaced read `[]` and `undefined` * whatever the navigation was. (It threw outright until real-router#1976 * attached the field.) The real metadata is written at the COMMIT: read it in * `router.subscribe`, `onTransitionSuccess`, or `getState()`. */ export declare function useRouteExit(handler: RouteExitHandler, options?: UseRouteExitOptions): void; //#endregion //#region src/composables/useRouteEnter.d.ts interface RouteEnterContext { /** The route that was just activated. */ route: State; /** The route that was active immediately before this navigation. */ previousRoute: State; } type RouteEnterHandler = (context: RouteEnterContext) => void; interface UseRouteEnterOptions { /** * Skip the handler when `route.name === previousRoute.name` * (sort/filter/query-only navigations on the same route). Default: * `true`. Symmetric with `useRouteExit`'s same-name option. */ skipSameRoute?: boolean; } /** * Fire `handler` once when the component mounts as a result of a * navigation. Mirror of `useRouteExit` for the entry side. * * What this composable covers that an ad-hoc `watch` + `useRoute()` * doesn't: * * - **Skip-initial**: `watch` (with default `immediate: false`) plus the * explicit `route.transition.from` guard ensures the handler doesn't * fire on the very first state committed by `router.start()`. * - **Same-route skip** (default): handler is skipped when * `route.transition.from === route.name`. Sort/filter/query-only * navigations re-trigger the watcher, but they are not "entries" in * the animation / analytics sense. Opt out with * `skipSameRoute: false`. * - **Mount-time `route` / `previousRoute` snapshot**: handler receives * the values that were live at the moment of the new state, not the * latest ones (which may have moved on if the user navigated again * before the watcher drained). * * **Handler reactivity (Vue):** Vue composables run **once** during * `setup()`; `handler` is captured in closure at the call site. To vary * behavior over time, read refs/computeds inside the handler body. * * **Under `` (#1221):** a deactivated (sleeping) page does not fire * the handler on unrelated navigations, and waking it does not re-fire — * reactivation is not a mount (use Vue's native `onActivated` to re-run on show). * * @example Direction-aware entry animation * ```ts * useRouteEnter(({ route }) => { * const direction = route.context.browser?.direction; * ref.value?.classList.add( * direction === "back" ? "slide-from-left" : "slide-from-right", * ); * }); * ``` * * @example Analytics page-enter event (skip-initial built-in) * ```ts * useRouteEnter(({ route, previousRoute }) => { * analytics.track("page_enter", { * route: route.name, * from: previousRoute.name, * }); * }); * ``` * * @example Reading rich transition metadata via `route.transition` * ```ts * useRouteEnter(({ route }) => { * // ⚠ NOT `transition.redirected` — the router never sets it (it only ever * // carries what a caller passed as `{ redirected: true }`), so branching on * // it here is silently dead for a `forwardTo` or a guard redirect. * // `from` needs no check: this hook does not fire without one. * showToast(`Arrived from ${route.transition.from}`); * }); * ``` */ export declare function useRouteEnter(handler: RouteEnterHandler, options?: UseRouteEnterOptions): void; //#endregion //#region src/createRouterPlugin.d.ts export declare function createRouterPlugin(router: Router): Plugin<[]>; //#endregion //#region src/dom-utils/direction-tracker.d.ts interface DirectionTracker { destroy: () => void; } /** * Track navigation direction (forward / back) and write it to * `` on every leave. CSS / JS readers consume * the attribute via `html[data-nav-direction="back"]` selectors or * `document.documentElement.dataset.navDirection`. * * Mechanism-agnostic — works identically whether downstream UI uses CSS * `@keyframes`, View Transitions pseudo-elements, or library state * (motion's `motion.div initial={{ x: ... }}`). * * Implementation: * - On install, set `data-nav-direction="forward"` baseline. * - Attach a `popstate` listener that flips an internal flag to * `true`. Browser back/forward navigation triggers popstate; user * clicks on `` / programmatic `router.navigate(...)` do not. * - On every `subscribeLeave`, write * `popstateFlag ? "back" : "forward"` and reset the flag. * - A `popstate` that arrives while a transition is in flight arms the * flag of the transition after it, which is the one a URL plugin starts * for it. * * Returns `{ destroy }` to clean up the listener and clear the dataset * attribute. */ export declare function createDirectionTracker(router: Router): DirectionTracker; //#endregion //#region src/dom-utils/route-announcer.d.ts interface RouteAnnouncerOptions { prefix?: string; getAnnouncementText?: (route: State) => string; } //#endregion //#region src/dom-utils/scroll-restore.d.ts type ScrollRestorationMode = "restore" | "top" | "native"; interface ScrollRestorationOptions { mode?: ScrollRestorationMode | undefined; anchorScrolling?: boolean | undefined; scrollContainer?: (() => HTMLElement | null) | undefined; /** * Scroll behavior passed to `scrollTo({ behavior })` and * `scrollIntoView({ behavior })`. * * - `"auto"` (default) — browser-defined, usually instant. * - `"instant"` — explicit instant jump (no animation). * - `"smooth"` — animated transition. Note: smooth restore on back/traverse * can feel disorienting if the user expects to land at the saved position * immediately. Recommended for `mode: "top"` or anchor scroll only. * * See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/ScrollToOptions/behavior). */ behavior?: ScrollBehavior | undefined; /** * sessionStorage key for persisting saved scroll positions. Default: * `"real-router:scroll"`. Override only when multiple independent * `RouterProvider` instances share the same document and you need to * isolate their scroll stores (e.g. micro-frontends, embedded widgets, * or testing). For a single app with one provider the default is fine. */ storageKey?: string | undefined; } //#endregion //#region src/dom-utils/scroll-spy.d.ts /** * Router-coordinated scroll spy (#575). * * On `IntersectionObserver` notifications the utility picks the topmost * visible anchor inside the configured scroll container and emits a forced * same-route transition with `{ hash, replace: true, force: true, hashChange: * true }` through `router.navigate(...)`. The URL plugin * (`@real-router/browser-plugin` or `@real-router/navigation-plugin`) updates * `state.context.url.hash` so sibling hash-aware `` re-highlights * via the standard `createActiveRouteSource` pipeline. * * **Anti-flicker gates** (RFC §5.2): * 1. `getTransitionSource(router).getSnapshot().isTransitioning` — skip emits * while a transition is in-flight (re-entrant lock). * 2. `coolingDown` — set on a user-driven hash transition (e.g. `` * click + smooth `scrollIntoView`). Cleared on `scrollend` or after a * 500ms safety timeout. Spy's own emits are excluded via the synchronous * `selfEmitting` flag — required so the spy doesn't rate-limit itself. * * **Self-healing** (RFC §7.3): if the initial URL contains a hash without a * matching `id` (e.g. `/page#nonexistent`), the first IO event emitted right * after observe()-ing picks the topmost real anchor and corrects the URL. * * **Hash-only transition pipeline cost** (RFC §5.3): for same-route same- * params hash-only navigations, `getTransitionPath` returns empty * `toDeactivate` / `toActivate` arrays, so `runGuards` is a no-op. The only * work is the URL plugin's `onTransitionSuccess` write and the * `getTransitionSource` flip — cheap. * * **Architecture**: decomposed into 4 private subsystem closure factories * (`createUrlPluginDetector`, `createCooldown`, `createDebouncer`, * `createObserverPair`). The main `createScrollSpy` wires them together * around the shared `silenced` / `destroyed` / `selfEmitting` flags and the * `flush()` emit logic. Each subsystem owns its state + cleanup; `destroy()` * delegates to each. See section banners below. * * @returns A `ScrollSpy` handle whose `destroy()` is idempotent. */ interface ScrollSpyOptions { /** * CSS selector for anchor candidates. Empty string `""` or `undefined` * disables the spy (returns a NOOP handle). Common values: * `"[id]"`, `"[id]:is(h1,h2,h3)"`, `"section[id]"`. */ selector: string; /** * `IntersectionObserver` `rootMargin`. Default * `"-20% 0px -60% 0px"` — an anchor is considered "active" once it crosses * into the top 20 % of the viewport (or scroll container). */ rootMargin?: string | undefined; /** * Lazy getter for the scrollable container. Consulted at creation and * re-consulted on every reconcile (DOM mutation), so a container that * MOUNTS or CHANGES after the spy is created is honoured: the * `IntersectionObserver` root and `MutationObserver` target — both immutable * once constructed — are rebuilt to match (#780). `null` (or a missing * getter) falls back to the window viewport (`root: null` on the * `IntersectionObserver`). */ scrollContainer?: (() => HTMLElement | null) | undefined; } //#endregion //#region src/RouterProvider.d.ts export declare const RouterProvider: import("vue").DefineComponent; required: true; }; announceNavigation: { type: PropType; default: boolean; }; scrollRestoration: { type: PropType; }; scrollSpy: { type: PropType; }; viewTransitions: { type: BooleanConstructor; default: boolean; }; }>, () => import("vue").VNode[] | undefined, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly; required: true; }; announceNavigation: { type: PropType; default: boolean; }; scrollRestoration: { type: PropType; }; scrollSpy: { type: PropType; }; viewTransitions: { type: BooleanConstructor; default: boolean; }; }>> & Readonly<{}>, { announceNavigation: boolean | RouteAnnouncerOptions; viewTransitions: boolean; }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>; //#endregion //#region src/context.d.ts export declare const RouterKey: InjectionKey; export declare const NavigatorKey: InjectionKey; export declare const RouteKey: InjectionKey; //#endregion export type { DirectionTracker, LinkDirectiveValue, LinkProps, Navigator, RouteContext, RouteEnterContext, RouteEnterHandler, RouteExitContext, RouteExitHandler, MatchProps as RouteViewMatchProps, NotFoundProps as RouteViewNotFoundProps, RouteViewProps, SelfProps as RouteViewSelfProps, RouterErrorBoundaryProps, RouterTransitionSnapshot, UseRouteEnterOptions, UseRouteExitOptions }; //# sourceMappingURL=index.d.ts.map