import React, { useContext, type ReactNode } from 'react' import { getContextKey } from './matchers' import type { ErrorBoundaryProps } from './views/Try' export type DynamicConvention = { name: string; deep: boolean; notFound?: boolean } export type LoadedRoute = { ErrorBoundary?: React.ComponentType default?: React.ComponentType unstable_settings?: Record getNavOptions?: (args: any) => any generateStaticParams?: (props: { params?: Record }) => Record[] loader?: (props: { params?: Record }) => Record[] } export type RouteNode = { /** The type of RouteNode */ type: 'route' | 'api' | 'layout' /** Load a route into memory. Returns the exports from a route. */ loadRoute: () => Partial /** Loaded initial route name. */ initialRouteName?: string /** nested routes */ children: RouteNode[] /** Is the route a dynamic path */ dynamic: null | DynamicConvention[] /** `index`, `error-boundary`, etc. */ route: string /** Context Module ID, used for matching children. */ contextKey: string /** Added in-memory */ generated?: boolean /** Internal screens like the directory or the auto 404 should be marked as internal. */ internal?: boolean /** File paths for async entry modules that should be included in the initial chunk request to ensure the runtime JavaScript matches the statically rendered HTML representation. */ entryPoints?: string[] } const CurrentRouteContext = React.createContext(null) if (process.env.NODE_ENV !== 'production') { CurrentRouteContext.displayName = 'RouteNode' } /** Return the RouteNode at the current contextual boundary. */ export function useRouteNode(): RouteNode | null { return useContext(CurrentRouteContext) } export function useContextKey(): string { const node = useRouteNode() if (node == null) { throw new Error('No filename found. This is likely a bug in router.') } return getContextKey(node.contextKey) } /** Provides the matching routes and filename to the children. */ export function Route({ children, node }: { children: ReactNode; node: RouteNode }) { return {children} }