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<any, any>[];
    revalidate: ShouldRevalidateFn<any, any>[];
    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<any>;
    revalidate: ShouldRevalidateFn<any, any>[];
    /** 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<TEnv = any> = {
    from: URL;
    to: URL;
    params: Record<string, string>;
    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<TEnv = any> = (ctx: InterceptSelectorContext<TEnv>) => 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<any, any, any>;
    middleware: MiddlewareFn<any, any>[];
    revalidate: ShouldRevalidateFn<any, any>[];
    errorBoundary: (ReactNode | ErrorBoundaryHandler)[];
    notFoundBoundary: (ReactNode | NotFoundBoundaryHandler)[];
    loader: LoaderEntry[];
    loading?: ReactNode | false;
    layout?: ReactNode | Handler<any, any, any>;
    when: InterceptWhenFn[];
};
export type EntryPropSegments = {
    loader: LoaderEntry[];
    layout: EntryData[];
    parallel: EntryData[];
    intercept: InterceptEntry[];
};
export type EntryData = ({
    type: "route";
    handler: Handler<any, any, any>;
    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[]> | 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<any, any, any>;
    loading?: ReactNode | false;
    /** Set when handler is a Static definition (build-time only) */
    isStaticPrerender?: true;
} & EntryPropCommon & EntryPropDatas & EntryPropSegments) | ({
    type: "parallel";
    handler: Record<`@${string}`, Handler<any, any, any> | 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<any, any, any>;
    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<string, EntryData>;
    namespace: string;
    parent: EntryData | null;
    counters: Record<string, number>;
    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<string, string>;
    /** URL patterns grouped by include prefix for separate entry creation */
    patternsByPrefix?: Map<string, Map<string, string>>;
    /** Trailing slash config per route name */
    trailingSlash?: Map<string, "never" | "always" | "ignore">;
    /** Search param schemas per route name */
    searchSchemas?: Map<string, Record<string, string>>;
    /** 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?: <T>(fn: () => T | Promise<T>) => T | Promise<T>;
    /** Tracked includes for build-time manifest generation */
    trackedIncludes?: TrackedInclude[];
}
export declare const RSCRouterContext: AsyncLocalStorage<HelperContext>;
export declare const getContext: () => {
    context: AsyncLocalStorage<HelperContext>;
    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: <T>(namespace: string, parent: EntryData | null, callback: (...args: any[]) => T) => T;
    runWithStore: <T>(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<T>(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