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>
231 lines
8.3 KiB
Text
231 lines
8.3 KiB
Text
/**
|
|
* App Router types - Client-safe types for the Next.js App Router
|
|
*
|
|
* This file contains type definitions that can be safely imported
|
|
* by both client-side and server-side code without circular dependencies.
|
|
*/
|
|
import type { FetchServerResponseResult } from '../../client/components/router-reducer/fetch-server-response';
|
|
import type React from 'react';
|
|
export type LoadingModuleData = [React.JSX.Element, React.ReactNode, React.ReactNode] | null;
|
|
/** viewport metadata node */
|
|
export type HeadData = React.ReactNode;
|
|
export type ChildSegmentMap = Map<string, CacheNode>;
|
|
/**
|
|
* Cache node used in app-router / layout-router.
|
|
*/
|
|
export type CacheNode = ReadyCacheNode | LazyCacheNode;
|
|
export type LazyCacheNode = {
|
|
/**
|
|
* When rsc is null, this is a lazily-initialized cache node.
|
|
*
|
|
* If the app attempts to render it, it triggers a lazy data fetch,
|
|
* postpones the render, and schedules an update to a new tree.
|
|
*
|
|
* TODO: This mechanism should not be used when PPR is enabled, though it
|
|
* currently is in some cases until we've implemented partial
|
|
* segment fetching.
|
|
*/
|
|
rsc: null;
|
|
/**
|
|
* A prefetched version of the segment data. See explanation in corresponding
|
|
* field of ReadyCacheNode (below).
|
|
*
|
|
* Since LazyCacheNode mostly only exists in the non-PPR implementation, this
|
|
* will usually be null, but it could have been cloned from a previous
|
|
* CacheNode that was created by the PPR implementation. Eventually we want
|
|
* to migrate everything away from LazyCacheNode entirely.
|
|
*/
|
|
prefetchRsc: React.ReactNode;
|
|
/**
|
|
* A pending response for the lazy data fetch. If this is not present
|
|
* during render, it is lazily created.
|
|
*/
|
|
lazyData: Promise<FetchServerResponseResult> | null;
|
|
prefetchHead: HeadData | null;
|
|
head: HeadData;
|
|
loading: LoadingModuleData | Promise<LoadingModuleData>;
|
|
/**
|
|
* Child parallel routes.
|
|
*/
|
|
parallelRoutes: Map<string, ChildSegmentMap>;
|
|
/**
|
|
* The timestamp of the navigation that last updated the CacheNode's data. If
|
|
* a CacheNode is reused from a previous navigation, this value is not
|
|
* updated. Used to track the staleness of the data.
|
|
*/
|
|
navigatedAt: number;
|
|
};
|
|
export type ReadyCacheNode = {
|
|
/**
|
|
* When rsc is not null, it represents the RSC data for the
|
|
* corresponding segment.
|
|
*
|
|
* `null` is a valid React Node but because segment data is always a
|
|
* <LayoutRouter> component, we can use `null` to represent empty.
|
|
*
|
|
* TODO: For additional type safety, update this type to
|
|
* Exclude<React.ReactNode, null>. Need to update createEmptyCacheNode to
|
|
* accept rsc as an argument, or just inline the callers.
|
|
*/
|
|
rsc: React.ReactNode;
|
|
/**
|
|
* Represents a static version of the segment that can be shown immediately,
|
|
* and may or may not contain dynamic holes. It's prefetched before a
|
|
* navigation occurs.
|
|
*
|
|
* During rendering, we will choose whether to render `rsc` or `prefetchRsc`
|
|
* with `useDeferredValue`. As with the `rsc` field, a value of `null` means
|
|
* no value was provided. In this case, the LayoutRouter will go straight to
|
|
* rendering the `rsc` value; if that one is also missing, it will suspend and
|
|
* trigger a lazy fetch.
|
|
*/
|
|
prefetchRsc: React.ReactNode;
|
|
/**
|
|
* There should never be a lazy data request in this case.
|
|
*/
|
|
lazyData: null;
|
|
prefetchHead: HeadData | null;
|
|
head: HeadData;
|
|
loading: LoadingModuleData | Promise<LoadingModuleData>;
|
|
parallelRoutes: Map<string, ChildSegmentMap>;
|
|
navigatedAt: number;
|
|
};
|
|
export type DynamicParamTypes = 'catchall' | 'catchall-intercepted' | 'optional-catchall' | 'dynamic' | 'dynamic-intercepted';
|
|
export type DynamicParamTypesShort = 'c' | 'ci' | 'oc' | 'd' | 'di';
|
|
export type Segment = string | [
|
|
paramName: string,
|
|
paramCacheKey: string,
|
|
dynamicParamType: DynamicParamTypesShort
|
|
];
|
|
/**
|
|
* Router state
|
|
*/
|
|
export type FlightRouterState = [
|
|
segment: Segment,
|
|
parallelRoutes: {
|
|
[parallelRouterKey: string]: FlightRouterState;
|
|
},
|
|
url?: string | null,
|
|
/**
|
|
* "refresh" and "refetch", despite being similarly named, have different
|
|
* semantics:
|
|
* - "refetch" is used during a request to inform the server where rendering
|
|
* should start from.
|
|
*
|
|
* - "refresh" is used by the client to mark that a segment should re-fetch the
|
|
* data from the server for the current segment. It uses the "url" property
|
|
* above to determine where to fetch from.
|
|
*
|
|
* - "inside-shared-layout" is used during a prefetch request to inform the
|
|
* server that even if the segment matches, it should be treated as if it's
|
|
* within the "new" part of a navigation — inside the shared layout. If
|
|
* the segment doesn't match, then it has no effect, since it would be
|
|
* treated as new regardless. If it does match, though, the server does not
|
|
* need to render it, because the client already has it.
|
|
*
|
|
* - "metadata-only" instructs the server to skip rendering the segments and
|
|
* only send the head data.
|
|
*
|
|
* A bit confusing, but that's because it has only one extremely narrow use
|
|
* case — during a non-PPR prefetch, the server uses it to find the first
|
|
* loading boundary beneath a shared layout.
|
|
*
|
|
* TODO: We should rethink the protocol for dynamic requests. It might not
|
|
* make sense for the client to send a FlightRouterState, since this type is
|
|
* overloaded with concerns.
|
|
*/
|
|
refresh?: 'refetch' | 'refresh' | 'inside-shared-layout' | 'metadata-only' | null,
|
|
isRootLayout?: boolean,
|
|
/**
|
|
* Only present when responding to a tree prefetch request. Indicates whether
|
|
* there is a loading boundary somewhere in the tree. The client cache uses
|
|
* this to determine if it can skip the data prefetch request.
|
|
*/
|
|
hasLoadingBoundary?: HasLoadingBoundary
|
|
];
|
|
export declare const enum HasLoadingBoundary {
|
|
SegmentHasLoadingBoundary = 1,
|
|
SubtreeHasLoadingBoundary = 2,
|
|
SubtreeHasNoLoadingBoundary = 3
|
|
}
|
|
/**
|
|
* Individual Flight response path
|
|
*/
|
|
export type FlightSegmentPath = any[] | [
|
|
segment: Segment,
|
|
parallelRouterKey: string,
|
|
segment: Segment,
|
|
parallelRouterKey: string,
|
|
segment: Segment,
|
|
parallelRouterKey: string
|
|
];
|
|
/**
|
|
* Represents a tree of segments and the Flight data (i.e. React nodes) that
|
|
* correspond to each one. The tree is isomorphic to the FlightRouterState;
|
|
* however in the future we want to be able to fetch arbitrary partial segments
|
|
* without having to fetch all its children. So this response format will
|
|
* likely change.
|
|
*/
|
|
export type CacheNodeSeedData = [
|
|
node: React.ReactNode | null,
|
|
parallelRoutes: {
|
|
[parallelRouterKey: string]: CacheNodeSeedData | null;
|
|
},
|
|
loading: LoadingModuleData | Promise<LoadingModuleData>,
|
|
isPartial: boolean,
|
|
/** TODO: this doesn't feel like it belongs here, because it's only used during build, in `collectSegmentData` */
|
|
hasRuntimePrefetch: boolean
|
|
];
|
|
export type FlightDataSegment = [
|
|
Segment,
|
|
FlightRouterState,
|
|
CacheNodeSeedData | null,
|
|
HeadData,
|
|
boolean
|
|
];
|
|
export type FlightDataPath = any[] | [
|
|
...FlightSegmentPath[],
|
|
...FlightDataSegment
|
|
];
|
|
/**
|
|
* The Flight response data
|
|
*/
|
|
export type FlightData = Array<FlightDataPath> | string;
|
|
export type ActionResult = Promise<any>;
|
|
export type InitialRSCPayload = {
|
|
/** buildId */
|
|
b: string;
|
|
/** initialCanonicalUrlParts */
|
|
c: string[];
|
|
/** initialRenderedSearch */
|
|
q: string;
|
|
/** couldBeIntercepted */
|
|
i: boolean;
|
|
/** initialFlightData */
|
|
f: FlightDataPath[];
|
|
/** missingSlots */
|
|
m: Set<string> | undefined;
|
|
/** GlobalError */
|
|
G: [React.ComponentType<any>, React.ReactNode | undefined];
|
|
/** postponed */
|
|
s: boolean;
|
|
/** prerendered */
|
|
S: boolean;
|
|
};
|
|
export type NavigationFlightResponse = {
|
|
/** buildId */
|
|
b: string;
|
|
/** flightData */
|
|
f: FlightData;
|
|
/** prerendered */
|
|
S: boolean;
|
|
};
|
|
export type ActionFlightResponse = {
|
|
/** actionResult */
|
|
a: ActionResult;
|
|
/** buildId */
|
|
b: string;
|
|
/** flightData */
|
|
f: FlightData;
|
|
};
|
|
export type RSCPayload = InitialRSCPayload | NavigationFlightResponse | ActionFlightResponse;
|