Next.js website for Rocky Mountain Vending company featuring: - Product catalog with Stripe integration - Service areas and parts pages - Admin dashboard with Clerk authentication - SEO optimized pages with JSON-LD structured data Co-authored-by: Cursor <cursoragent@cursor.com>
213 lines
8.4 KiB
Text
213 lines
8.4 KiB
Text
import type { CacheNode } from '../../../shared/lib/app-router-types';
|
|
import type { FlightRouterState, FlightSegmentPath } from '../../../shared/lib/app-router-types';
|
|
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;
|
|
export interface Mutable {
|
|
mpaNavigation?: boolean;
|
|
patchedTree?: FlightRouterState;
|
|
renderedSearch?: string;
|
|
canonicalUrl?: string;
|
|
scrollableSegments?: FlightSegmentPath[];
|
|
pendingPush?: boolean;
|
|
cache?: CacheNode;
|
|
hashFragment?: string;
|
|
shouldScroll?: boolean;
|
|
preserveCustomHistoryState?: boolean;
|
|
onlyHashChange?: boolean;
|
|
collectedDebugInfo?: Array<unknown>;
|
|
}
|
|
export interface ServerActionMutable extends Mutable {
|
|
inFlightServerAction?: Promise<any> | null;
|
|
}
|
|
/**
|
|
* 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;
|
|
origin: Location['origin'];
|
|
}
|
|
export interface HmrRefreshAction {
|
|
type: typeof ACTION_HMR_REFRESH;
|
|
origin: Location['origin'];
|
|
}
|
|
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';
|
|
shouldScroll: boolean;
|
|
}
|
|
/**
|
|
* 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.
|
|
* - Only triggered in layout-router.
|
|
* - Creates a new cache and router state with the Flight data applied.
|
|
*/
|
|
export interface ServerPatchAction {
|
|
type: typeof ACTION_SERVER_PATCH;
|
|
navigatedAt: number;
|
|
serverResponse: FetchServerResponseResult;
|
|
previousTree: FlightRouterState;
|
|
}
|
|
/**
|
|
* 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.
|
|
* - `temporary` - a temporary prefetch entry is added to the cache, this is used when prefetch={false} is used in next/link or when you push a route programmatically.
|
|
*/
|
|
export declare enum PrefetchKind {
|
|
AUTO = "auto",
|
|
FULL = "full",
|
|
TEMPORARY = "temporary"
|
|
}
|
|
/**
|
|
* 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;
|
|
}
|
|
export type FocusAndScrollRef = {
|
|
/**
|
|
* If focus and scroll should be set in the layout-router's useEffect()
|
|
*/
|
|
apply: boolean;
|
|
/**
|
|
* The hash fragment that should be scrolled to.
|
|
*/
|
|
hashFragment: string | null;
|
|
/**
|
|
* The paths of the segments that should be focused.
|
|
*/
|
|
segmentPaths: FlightSegmentPath[];
|
|
/**
|
|
* 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;
|
|
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>;
|