import { AsyncLocalStorage } from "node:async_hooks"; import type { ReactNode } from "react"; import type { PartialCacheOptions, ErrorBoundaryHandler, Handler, LoaderDefinition, MiddlewareFn, NotFoundBoundaryHandler, ShouldRevalidateFn } from "../types"; /** * Performance metric entry for a single measured operation * * @internal This type is an implementation detail and may change without notice. */ export interface PerformanceMetric { label: string; duration: number; startTime: number; } /** * Request-scoped metrics store * * @internal This type is an implementation detail and may change without notice. */ export interface MetricsStore { enabled: boolean; requestStart: number; metrics: PerformanceMetric[]; } /** * Cache configuration for an entry * When set, this entry and its children will use this cache config * unless overridden by a nested cache() call. * * @internal This type is an implementation detail and may change without notice. */ export type EntryCacheConfig = { /** Cache options (false means caching disabled for this entry) - ttl is optional, uses defaults */ options: PartialCacheOptions | false; }; /** * Entry data structure for manifest * * @internal This type is an implementation detail and may change without notice. */ export type EntryPropCommon = { id: string; shortCode: string; parent: EntryData | null; /** Cache configuration for this entry (set by cache() DSL) */ cache?: EntryCacheConfig; /** URL prefix from include() scope, used for MountContext on client */ mountPath?: string; }; /** * @internal This type is an implementation detail and may change without notice. */ export type EntryPropDatas = { middleware: MiddlewareFn[]; revalidate: ShouldRevalidateFn[]; errorBoundary: (ReactNode | ErrorBoundaryHandler)[]; notFoundBoundary: (ReactNode | NotFoundBoundaryHandler)[]; }; /** * Loader entry stored in EntryData * Contains the loader definition and its revalidation rules * * @internal This type is an implementation detail and may change without notice. */ export type LoaderEntry = { loader: LoaderDefinition; revalidate: ShouldRevalidateFn[]; /** Cache config for this specific loader (loaders are NOT cached by default) */ cache?: EntryCacheConfig; }; /** * Segments state for intercept context * Matches the structure from useSegments() for consistency * * @internal This type is an implementation detail and may change without notice. */ export type InterceptSegmentsState = { /** URL path segments (e.g., /shop/products/123 → ["shop", "products", "123"]) */ path: readonly string[]; /** Matched segment IDs in order (layouts and routes only, e.g., ["L0", "L0L1", "L0L1R0"]) */ ids: readonly string[]; }; /** * Context passed to intercept selector functions (when()) * Contains navigation context to determine if interception should occur. * * Note: when() is evaluated during route matching, BEFORE middleware runs. * So ctx.get()/ctx.use() are not available, but env (platform bindings) is. * * @internal This type is an implementation detail and may change without notice. */ export type InterceptSelectorContext = { from: URL; to: URL; params: Record; request: Request; env: TEnv; segments: InterceptSegmentsState; }; /** * Selector function for conditional interception * Returns true to intercept, false to skip and fall through to route handler * * @internal This type is an implementation detail and may change without notice. */ export type InterceptWhenFn = (ctx: InterceptSelectorContext) => boolean; /** * Intercept entry stored in EntryData * Contains the slot name, route to intercept, and handler * * @internal This type is an implementation detail and may change without notice. */ export type InterceptEntry = { slotName: `@${string}`; routeName: string; handler: ReactNode | Handler; middleware: MiddlewareFn[]; revalidate: ShouldRevalidateFn[]; errorBoundary: (ReactNode | ErrorBoundaryHandler)[]; notFoundBoundary: (ReactNode | NotFoundBoundaryHandler)[]; loader: LoaderEntry[]; loading?: ReactNode | false; layout?: ReactNode | Handler; when: InterceptWhenFn[]; }; export type EntryPropSegments = { loader: LoaderEntry[]; layout: EntryData[]; parallel: EntryData[]; intercept: InterceptEntry[]; }; export type EntryData = ({ type: "route"; handler: Handler; loading?: ReactNode | false; /** URL pattern for this route (used by path() in urls()) */ pattern?: string; /** Set when handler is a Prerender definition */ isPrerender?: true; /** Original PrerenderHandlerDefinition (for build-time getParams access) */ prerenderDef?: { getParams?: () => Promise | any[]; options?: { passthrough?: boolean; }; }; /** Set when handler is a Static definition (build-time only) */ isStaticPrerender?: true; /** Response type for non-RSC routes (json, text, image, any) */ responseType?: string; } & EntryPropCommon & EntryPropDatas & EntryPropSegments) | ({ type: "layout"; handler: ReactNode | Handler; loading?: ReactNode | false; /** Set when handler is a Static definition (build-time only) */ isStaticPrerender?: true; } & EntryPropCommon & EntryPropDatas & EntryPropSegments) | ({ type: "parallel"; handler: Record<`@${string}`, Handler | ReactNode>; loading?: ReactNode | false; /** Set when any parallel slot is a Static definition */ isStaticPrerender?: true; } & EntryPropCommon & EntryPropDatas & EntryPropSegments) | ({ type: "cache"; /** Cache entries create cache boundaries and render like layouts (with Outlet) */ handler: ReactNode | Handler; loading?: ReactNode | false; } & EntryPropCommon & EntryPropDatas & EntryPropSegments); /** * Tracked include info for build-time manifest generation */ export interface TrackedInclude { prefix: string; fullPrefix: string; namePrefix?: string; patterns: unknown; lazy: boolean; } /** * Context stored in AsyncLocalStorage */ interface HelperContext { manifest: Map; namespace: string; parent: EntryData | null; counters: Record; forRoute?: string; mountIndex?: number; metrics?: MetricsStore; /** True when rendering for SSR (document requests) */ isSSR?: boolean; /** URL patterns map for path() routes (route name -> pattern) */ patterns?: Map; /** URL patterns grouped by include prefix for separate entry creation */ patternsByPrefix?: Map>; /** Trailing slash config per route name */ trailingSlash?: Map; /** Search param schemas per route name */ searchSchemas?: Map>; /** URL prefix from include() - applied to all path() patterns */ urlPrefix?: string; /** Name prefix from include() - applied to all named routes */ namePrefix?: string; /** Run helper for cleaner middleware code */ run?: (fn: () => T | Promise) => T | Promise; /** Tracked includes for build-time manifest generation */ trackedIncludes?: TrackedInclude[]; } export declare const RSCRouterContext: AsyncLocalStorage; export declare const getContext: () => { context: AsyncLocalStorage; getStore: () => HelperContext; getParent: () => EntryData | null; getOrCreateStore: (forRoute?: string) => HelperContext; getNextIndex: (type: (string & {}) | "layout" | "parallel" | "middleware" | "revalidate") => string; getShortCode: (type: "layout" | "parallel" | "route" | "loader" | "cache") => string; run: (namespace: string, parent: EntryData | null, callback: (...args: any[]) => T) => T; runWithStore: (store: HelperContext, namespace: string, parent: EntryData | null, callback: (...args: any[]) => T) => T; }; /** * Run a callback with specific URL and name prefixes * Used by include() to apply prefixes to nested patterns */ export declare function runWithPrefixes(urlPrefix: string, namePrefix: string | undefined, callback: () => T): T; /** * Get current URL prefix from context */ export declare function getUrlPrefix(): string; /** * Get current name prefix from context */ export declare function getNamePrefix(): string | undefined; export type { HelperContext }; /** * Track performance of a code block (no-op if metrics not enabled) * Returns a done() callback to mark completion and record duration * * @example * ```typescript * const done = track("route-matching"); * // ... do work ... * done(); // Records duration * ``` */ export declare function track(label: string): () => void; //# sourceMappingURL=context.d.ts.map