@tanstack/router-core
Version:
Modern and scalable routing for React applications
237 lines (236 loc) • 9.62 kB
text/typescript
import { LRUCache } from './lru-cache.cjs';
export declare const SEGMENT_TYPE_PATHNAME = 0;
export declare const SEGMENT_TYPE_PARAM = 1;
export declare const SEGMENT_TYPE_WILDCARD = 2;
export declare const SEGMENT_TYPE_OPTIONAL_PARAM = 3;
declare const SEGMENT_TYPE_INDEX = 4;
declare const SEGMENT_TYPE_PATHLESS = 5;
/**
* All the kinds of segments that can be present in a route path.
*/
export type SegmentKind = typeof SEGMENT_TYPE_PATHNAME | typeof SEGMENT_TYPE_PARAM | typeof SEGMENT_TYPE_WILDCARD | typeof SEGMENT_TYPE_OPTIONAL_PARAM;
/**
* All the kinds of segments that can be present in the segment tree.
*/
type ExtendedSegmentKind = SegmentKind | typeof SEGMENT_TYPE_INDEX | typeof SEGMENT_TYPE_PATHLESS;
type ParsedSegment = Uint16Array & {
/** segment type (0 = pathname, 1 = param, 2 = wildcard, 3 = optional param) */
0: SegmentKind;
/** index of the end of the prefix */
1: number;
/** index of the start of the value */
2: number;
/** index of the end of the value */
3: number;
/** index of the start of the suffix */
4: number;
/** index of the end of the segment */
5: number;
};
/**
* Populates the `output` array with the parsed representation of the given `segment` string.
*
* Usage:
* ```ts
* let output
* let cursor = 0
* while (cursor < path.length) {
* output = parseSegment(path, cursor, output)
* const end = output[5]
* cursor = end + 1
* ```
*
* `output` is stored outside to avoid allocations during repeated calls. It doesn't need to be typed
* or initialized, it will be done automatically.
*/
export declare function parseSegment(
/** The full path string containing the segment. */
path: string,
/** The starting index of the segment within the path. */
start: number,
/** A Uint16Array (length: 6) to populate with the parsed segment data. */
output?: Uint16Array): ParsedSegment;
type StaticSegmentNode<T extends RouteLike> = SegmentNode<T> & {
kind: typeof SEGMENT_TYPE_PATHNAME | typeof SEGMENT_TYPE_PATHLESS | typeof SEGMENT_TYPE_INDEX;
};
type DynamicSegmentNode<T extends RouteLike> = SegmentNode<T> & {
kind: typeof SEGMENT_TYPE_PARAM | typeof SEGMENT_TYPE_WILDCARD | typeof SEGMENT_TYPE_OPTIONAL_PARAM;
prefix?: string;
suffix?: string;
caseSensitive: boolean;
};
type AnySegmentNode<T extends RouteLike> = StaticSegmentNode<T> | DynamicSegmentNode<T>;
type SegmentNode<T extends RouteLike> = {
kind: ExtendedSegmentKind;
pathless: Array<StaticSegmentNode<T>> | null;
/** Exact index segment (highest priority) */
index: StaticSegmentNode<T> | null;
/** Static segments (2nd priority) */
static: Map<string, StaticSegmentNode<T>> | null;
/** Case insensitive static segments (3rd highest priority) */
staticInsensitive: Map<string, StaticSegmentNode<T>> | null;
/** Dynamic segments ($param) */
dynamic: Array<DynamicSegmentNode<T>> | null;
/** Optional dynamic segments ({-$param}) */
optional: Array<DynamicSegmentNode<T>> | null;
/** Wildcard segments ($ - lowest priority) */
wildcard: Array<DynamicSegmentNode<T>> | null;
/** Terminal route (if this path can end here) */
route: T | null;
/** The full path for this segment node (will only be valid on leaf nodes) */
fullPath: string;
parent: AnySegmentNode<T> | null;
depth: number;
/** route.options.params.parse function, set on the last node of the route */
parse: null | ((params: Record<string, string>) => any);
/** options.skipRouteOnParseError.params ?? false */
skipOnParamError: boolean;
/** options.skipRouteOnParseError.priority ?? 0 */
parsingPriority: number;
};
type RouteLike = {
id?: string;
path?: string;
children?: Array<RouteLike>;
parentRoute?: RouteLike;
isRoot?: boolean;
options?: {
skipRouteOnParseError?: {
params?: boolean;
priority?: number;
};
caseSensitive?: boolean;
params?: {
parse?: (params: Record<string, string>) => any;
};
};
} & ({
fullPath: string;
from?: never;
} | {
fullPath?: never;
from: string;
});
export type ProcessedTree<TTree extends Extract<RouteLike, {
fullPath: string;
}>, TFlat extends Extract<RouteLike, {
from: string;
}>, TSingle extends Extract<RouteLike, {
from: string;
}>> = {
/** a representation of the `routeTree` as a segment tree */
segmentTree: AnySegmentNode<TTree>;
/** a mini route tree generated from the flat `routeMasks` list */
masksTree: AnySegmentNode<TFlat> | null;
/** @deprecated keep until v2 so that `router.matchRoute` can keep not caring about the actual route tree */
singleCache: LRUCache<string, AnySegmentNode<TSingle>>;
/** a cache of route matches from the `segmentTree` */
matchCache: LRUCache<string, RouteMatch<TTree> | null>;
/** a cache of route matches from the `masksTree` */
flatCache: LRUCache<string, ReturnType<typeof findMatch<TFlat>>> | null;
};
export declare function processRouteMasks<TRouteLike extends Extract<RouteLike, {
from: string;
}>>(routeList: Array<TRouteLike>, processedTree: ProcessedTree<any, TRouteLike, any>): void;
/**
* Take an arbitrary list of routes, create a tree from them (if it hasn't been created already), and match a path against it.
*/
export declare function findFlatMatch<T extends Extract<RouteLike, {
from: string;
}>>(
/** The path to match. */
path: string,
/** The `processedTree` returned by the initial `processRouteTree` call. */
processedTree: ProcessedTree<any, T, any>): {
route: T;
/**
* The raw (unparsed) params extracted from the path.
* This will be the exhaustive list of all params defined in the route's path.
*/
rawParams: Record<string, string>;
/**
* The accumlulated parsed params of each route in the branch that had `skipRouteOnParseError` enabled.
* Will not contain all params defined in the route's path. Those w/ a `params.parse` but no `skipRouteOnParseError` will need to be parsed separately.
*/
parsedParams?: Record<string, unknown>;
} | null;
/**
* @deprecated keep until v2 so that `router.matchRoute` can keep not caring about the actual route tree
*/
export declare function findSingleMatch(from: string, caseSensitive: boolean, fuzzy: boolean, path: string, processedTree: ProcessedTree<any, any, {
from: string;
}>): {
route: {
from: string;
};
/**
* The raw (unparsed) params extracted from the path.
* This will be the exhaustive list of all params defined in the route's path.
*/
rawParams: Record<string, string>;
/**
* The accumlulated parsed params of each route in the branch that had `skipRouteOnParseError` enabled.
* Will not contain all params defined in the route's path. Those w/ a `params.parse` but no `skipRouteOnParseError` will need to be parsed separately.
*/
parsedParams?: Record<string, unknown>;
} | null;
type RouteMatch<T extends Extract<RouteLike, {
fullPath: string;
}>> = {
route: T;
rawParams: Record<string, string>;
parsedParams?: Record<string, unknown>;
branch: ReadonlyArray<T>;
};
export declare function findRouteMatch<T extends Extract<RouteLike, {
fullPath: string;
}>>(
/** The path to match against the route tree. */
path: string,
/** The `processedTree` returned by the initial `processRouteTree` call. */
processedTree: ProcessedTree<T, any, any>,
/** If `true`, allows fuzzy matching (partial matches), i.e. which node in the tree would have been an exact match if the `path` had been shorter? */
fuzzy?: boolean): RouteMatch<T> | null;
/** Trim trailing slashes (except preserving root '/'). */
export declare function trimPathRight(path: string): string;
export interface ProcessRouteTreeResult<TRouteLike extends Extract<RouteLike, {
fullPath: string;
}> & {
id: string;
}> {
/** Should be considered a black box, needs to be provided to all matching functions in this module. */
processedTree: ProcessedTree<TRouteLike, any, any>;
/** A lookup map of routes by their unique IDs. */
routesById: Record<string, TRouteLike>;
/** A lookup map of routes by their trimmed full paths. */
routesByPath: Record<string, TRouteLike>;
}
/**
* Processes a route tree into a segment trie for efficient path matching.
* Also builds lookup maps for routes by ID and by trimmed full path.
*/
export declare function processRouteTree<TRouteLike extends Extract<RouteLike, {
fullPath: string;
}> & {
id: string;
}>(
/** The root of the route tree to process. */
routeTree: TRouteLike,
/** Whether matching should be case sensitive by default (overridden by individual route options). */
caseSensitive?: boolean,
/** Optional callback invoked for each route during processing. */
initRoute?: (route: TRouteLike, index: number) => void): ProcessRouteTreeResult<TRouteLike>;
declare function findMatch<T extends RouteLike>(path: string, segmentTree: AnySegmentNode<T>, fuzzy?: boolean): {
route: T;
/**
* The raw (unparsed) params extracted from the path.
* This will be the exhaustive list of all params defined in the route's path.
*/
rawParams: Record<string, string>;
/**
* The accumlulated parsed params of each route in the branch that had `skipRouteOnParseError` enabled.
* Will not contain all params defined in the route's path. Those w/ a `params.parse` but no `skipRouteOnParseError` will need to be parsed separately.
*/
parsedParams?: Record<string, unknown>;
} | null;
export {};