import type { CacheNode, ScrollRef } from '../../../shared/lib/app-router-types';
import type { FlightRouterState } from '../../../shared/lib/app-router-types';
import type { NavigationSeed } from '../segment-cache/navigation';
import type { FetchServerResponseResult } from './fetch-server-response';
export declare const ACTION_REFRESH = "refresh";
export declare const ACTION_NAVIGATE = "navigate";
export declare const ACTION_RESTORE = "restore";
export declare const ACTION_SERVER_PATCH = "server-patch";
export declare const ACTION_HMR_REFRESH = "hmr-refresh";
export declare const ACTION_SERVER_ACTION = "server-action";
export type RouterChangeByServerResponse = ({ navigatedAt, previousTree, serverResponse, }: {
    navigatedAt: number;
    previousTree: FlightRouterState;
    serverResponse: FetchServerResponseResult;
}) => void;
/**
 * Refresh triggers a refresh of the full page data.
 * - fetches the Flight data and fills rsc at the root of the cache.
 * - The router state is updated at the root.
 */
export interface RefreshAction {
    type: typeof ACTION_REFRESH;
    /**
     * Bypass invalidating the segment cache. Used by the Instant Navigation
     * Testing API to preserve prefetched data when refreshing after an MPA
     * navigation. Not exposed in production builds by default.
     */
    bypassCacheInvalidation?: boolean;
}
export interface HmrRefreshAction {
    type: typeof ACTION_HMR_REFRESH;
}
export type ServerActionDispatcher = (args: Omit<ServerActionAction, 'type' | 'mutable' | 'navigate' | 'changeByServerResponse' | 'cache'>) => void;
export interface ServerActionAction {
    type: typeof ACTION_SERVER_ACTION;
    actionId: string;
    actionArgs: any[];
    resolve: (value: any) => void;
    reject: (reason?: any) => void;
    didRevalidate?: boolean;
}
/**
 * Navigate triggers a navigation to the provided url. It supports two types: `push` and `replace`.
 *
 * `navigateType`:
 * - `push` - pushes a new history entry in the browser history
 * - `replace` - replaces the current history entry in the browser history
 *
 * Navigate has multiple cache heuristics:
 * - page was prefetched
 *  - Apply router state tree from prefetch
 *  - Apply Flight data from prefetch to the cache
 *  - If Flight data is a string, it's a redirect and the state is updated to trigger a redirect
 *  - Check if hard navigation is needed
 *    - Hard navigation happens when a dynamic parameter below the common layout changed
 *    - When hard navigation is needed the cache is invalidated below the flightSegmentPath
 *    - The missing cache nodes of the page will be fetched in layout-router and trigger the SERVER_PATCH action
 *  - If hard navigation is not needed
 *    - The cache is reused
 *    - If any cache nodes are missing they'll be fetched in layout-router and trigger the SERVER_PATCH action
 * - page was not prefetched
 *  - The navigate was called from `next/router` (`router.push()` / `router.replace()`) / `next/link` without prefetched data available (e.g. the prefetch didn't come back from the server before clicking the link)
 *    - Flight data is fetched in the reducer (suspends the reducer)
 *    - Router state tree is created based on Flight data
 *    - Cache is filled based on the Flight data
 *
 * Above steps explain 3 cases:
 * - `soft` - Reuses the existing cache and fetches missing nodes in layout-router.
 * - `hard` - Creates a new cache where cache nodes are removed below the common layout and fetches missing nodes in layout-router.
 * - `optimistic` (explicit no prefetch) - Creates a new cache and kicks off the data fetch in the reducer. The data fetch is awaited in the layout-router.
 */
export interface NavigateAction {
    type: typeof ACTION_NAVIGATE;
    url: URL;
    isExternalUrl: boolean;
    locationSearch: Location['search'];
    navigateType: 'push' | 'replace';
    scrollBehavior: ScrollBehavior;
}
/**
 * Restore applies the provided router state.
 * - Used for `popstate` (back/forward navigation) where a known router state has to be applied.
 * - Also used when syncing the router state with `pushState`/`replaceState` calls.
 * - Router state is applied as-is from the history state, if available.
 * - If the history state does not contain the router state, the existing router state is used.
 * - If any cache node is missing it will be fetched in layout-router during rendering and the server-patch case.
 * - If existing cache nodes match these are used.
 */
export interface RestoreAction {
    type: typeof ACTION_RESTORE;
    url: URL;
    historyState: AppHistoryState | undefined;
}
export type AppHistoryState = {
    tree: FlightRouterState;
    renderedSearch: string;
};
/**
 * Server-patch applies the provided Flight data to the cache and router tree.
 */
export interface ServerPatchAction {
    type: typeof ACTION_SERVER_PATCH;
    previousTree: FlightRouterState;
    url: URL;
    nextUrl: string | null;
    seed: NavigationSeed | null;
    mpa: boolean;
    navigateType: 'push' | 'replace';
}
/**
 * PrefetchKind defines the type of prefetching that should be done.
 * - `auto` - if the page is dynamic, prefetch the page data partially, if static prefetch the page data fully.
 * - `full` - prefetch the page data fully.
 */
export declare enum PrefetchKind {
    AUTO = "auto",
    FULL = "full"
}
/**
 * Prefetch adds the provided FlightData to the prefetch cache
 * - Creates the router state tree based on the patch in FlightData
 * - Adds the FlightData to the prefetch cache
 * - In ACTION_NAVIGATE the prefetch cache is checked and the router state tree and FlightData are applied.
 */
export interface PushRef {
    /**
     * If the app-router should push a new history entry in app-router's useEffect()
     */
    pendingPush: boolean;
    /**
     * Multi-page navigation through location.href.
     */
    mpaNavigation: boolean;
    /**
     * Skip applying the router state to the browser history state.
     */
    preserveCustomHistoryState: boolean;
}
/**
 * Controls the scroll behavior for a navigation.
 */
export declare const enum ScrollBehavior {
    /** Use per-node ScrollRef to decide whether to scroll. */
    Default = 0,
    /** Suppress scroll entirely (e.g. scroll={false} on Link or router.push). */
    NoScroll = 1
}
export type FocusAndScrollRef = {
    /**
     * The scroll ref from the most recent navigation. Set to whatever was
     * accumulated during tree construction (or null if nothing was
     * accumulated). On the next navigation, if new scroll targets are
     * created, the previous scrollRef is invalidated by setting
     * `current = false`.
     */
    scrollRef: ScrollRef | null;
    /**
     * When true, the scroll handler uses `focusAndScrollRef.scrollRef`
     * for every segment regardless of per-node state. Used for hash-only
     * navigations where every segment should be treated as a scroll
     * target. When false, the handler checks `cacheNode.scrollRef`
     * instead (per-node), so only segments that actually navigated scroll.
     */
    forceScroll: boolean;
    /**
     * The hash fragment that should be scrolled to.
     */
    hashFragment: string | null;
    /**
     * If only the URLs hash fragment changed
     */
    onlyHashChange: boolean;
};
/**
 * Handles keeping the state of app-router.
 */
export type AppRouterState = {
    /**
     * The router state, this is written into the history state in app-router using replaceState/pushState.
     * - Has to be serializable as it is written into the history state.
     * - Holds which segments and parallel routes are shown on the screen.
     */
    tree: FlightRouterState;
    /**
     * The cache holds React nodes for every segment that is shown on screen as well as previously shown segments.
     * It also holds in-progress data requests.
     */
    cache: CacheNode;
    /**
     * Decides if the update should create a new history entry and if the navigation has to trigger a browser navigation.
     */
    pushRef: PushRef;
    /**
     * Decides if the update should apply scroll and focus management.
     */
    focusAndScrollRef: FocusAndScrollRef;
    /**
     * The canonical url that is pushed/replaced.
     * - This is the url you see in the browser.
     */
    canonicalUrl: string;
    /**
     * The search query observed by the server during rendering. This may be
     * different from the canonical URL's search query if the server performed
     * a rewrite. Even though a client component won't observe this (unless it
     * were passed from a Server component), the client router needs to know this
     * so it can properly cache segment data; it'ss part of a page segment's
     * cache key.
     */
    renderedSearch: string;
    /**
     * The underlying "url" representing the UI state, which is used for intercepting routes.
     */
    nextUrl: string | null;
    /**
     * The previous next-url that was used previous to a dynamic navigation.
     */
    previousNextUrl: string | null;
    debugInfo: Array<unknown> | null;
};
export type ReadonlyReducerState = Readonly<AppRouterState>;
export type ReducerState = (Promise<AppRouterState> & {
    _debugInfo?: Array<unknown>;
}) | AppRouterState;
export type ReducerActions = Readonly<RefreshAction | NavigateAction | RestoreAction | ServerPatchAction | HmrRefreshAction | ServerActionAction>;
