Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/router-core/src/defer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { defaultSerializeError } from './router'

/**
* Well-known symbol used by {@link defer} to tag a promise with
* its deferred state. Consumers can read `promise[TSR_DEFERRED_PROMISE]`
* to access `status`, `data`, or `error`.
*/
export const TSR_DEFERRED_PROMISE = Symbol.for('TSR_DEFERRED_PROMISE')

export type DeferredPromiseState<T> =
Expand Down
8 changes: 8 additions & 0 deletions packages/router-core/src/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ export function removeTrailingSlash(value: string, basepath: string): string {
// see the usage in the isActive under useLinkProps
// /sample/path1 = /sample/path1/
// /sample/path1/some <> /sample/path1
/**
* Compare two pathnames for exact equality after normalizing trailing slashes
* relative to the provided `basepath`.
*/
export function exactPathTest(
pathName1: string,
pathName2: string,
Expand Down Expand Up @@ -222,6 +226,10 @@ export const parseRoutePathSegments = (
cache?: ParsePathnameCache,
): ReadonlyArray<Segment> => parsePathname(pathname, cache, false)

/**
* Parse a pathname into an array of typed segments used by the router's
* matcher. Results are optionally cached via an LRU cache.
*/
export const parsePathname = (
pathname?: string,
cache?: ParsePathnameCache,
Expand Down
8 changes: 8 additions & 0 deletions packages/router-core/src/process-route-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,14 @@ export type ProcessRouteTreeResult<TRouteLike extends RouteLike> = {
flatRoutes: Array<TRouteLike>
}

/**
* Build lookup maps and a specificity-sorted flat list from a route tree.
* Returns `routesById`, `routesByPath`, and `flatRoutes`.
*/
/**
* Build lookup maps and a specificity-sorted flat list from a route tree.
* Returns `routesById`, `routesByPath`, and `flatRoutes`.
*/
export function processRouteTree<TRouteLike extends RouteLike>({
routeTree,
initRoute,
Expand Down
7 changes: 7 additions & 0 deletions packages/router-core/src/redirect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ export type ResolvedRedirect<
* @returns A Response augmented with router navigation options.
* @link https://tanstack.com/router/latest/docs/framework/react/api/router/redirectFunction
*/
/**
* Create a redirect Response understood by TanStack Router.
* Use inside loaders/beforeLoad or server handlers to trigger navigation.
*/
export function redirect<
TRouter extends AnyRouter = RegisteredRouter,
const TTo extends string | undefined = '.',
Expand Down Expand Up @@ -109,18 +113,21 @@ export function redirect<
return response as Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>
}

/** Check whether a value is a TanStack Router redirect Response. */
/** Check whether a value is a TanStack Router redirect Response. */
export function isRedirect(obj: any): obj is AnyRedirect {
return obj instanceof Response && !!(obj as any).options
}

/** True if value is a redirect with a resolved `href` location. */
/** True if value is a redirect with a resolved `href` location. */
export function isResolvedRedirect(
obj: any,
): obj is AnyRedirect & { options: { href: string } } {
return isRedirect(obj) && !!obj.options.href
}

/** Parse a serialized redirect object back into a redirect Response. */
/** Parse a serialized redirect object back into a redirect Response. */
export function parseRedirect(obj: any) {
if (obj !== null && typeof obj === 'object' && obj.isSerializedRedirect) {
Expand Down
1 change: 1 addition & 0 deletions packages/router-core/src/root.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/** Stable identifier used for the root route in a route tree. */
export const rootRouteId = '__root__'
export type RootRouteId = typeof rootRouteId
23 changes: 20 additions & 3 deletions packages/router-core/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,10 @@ export interface ViewTransitionOptions {
}

// TODO where is this used? can we remove this?
/**
* Convert an unknown error into a minimal, serializable object.
* Includes name and message (and stack in development).
*/
export function defaultSerializeError(err: unknown) {
if (err instanceof Error) {
const obj = {
Expand All @@ -797,6 +801,7 @@ export function defaultSerializeError(err: unknown) {
}
}

/** Options for configuring trailing-slash behavior. */
export const trailingSlashOptions = {
always: 'always',
never: 'never',
Expand All @@ -806,6 +811,10 @@ export const trailingSlashOptions = {
export type TrailingSlashOption =
(typeof trailingSlashOptions)[keyof typeof trailingSlashOptions]

/**
* Compute whether path, href or hash changed between previous and current
* resolved locations in router state.
*/
export function getLocationChangeInfo(routerState: {
resolvedLocation?: ParsedLocation
location: ParsedLocation
Expand Down Expand Up @@ -2517,8 +2526,10 @@ export class RouterCore<
}
}

/** Error thrown when search parameter validation fails. */
export class SearchParamError extends Error {}

/** Error thrown when path parameter parsing/validation fails. */
export class PathParamError extends Error {}

const normalize = (str: string) =>
Expand All @@ -2527,9 +2538,10 @@ function comparePaths(a: string, b: string) {
return normalize(a) === normalize(b)
}

// A function that takes an import() argument which is a function and returns a new function that will
// proxy arguments from the caller to the imported function, retaining all type
// information along the way
/**
* Lazily import a module function and forward arguments to it, retaining
* parameter and return types for the selected export key.
*/
export function lazyFn<
T extends Record<string, (...args: Array<any>) => any>,
TKey extends keyof T = 'default',
Expand All @@ -2542,6 +2554,7 @@ export function lazyFn<
}
}

/** Create an initial RouterState from a parsed location. */
export function getInitialRouterState(
location: ParsedLocation,
): RouterState<any> {
Expand Down Expand Up @@ -2587,6 +2600,10 @@ function validateSearch(validateSearch: AnyValidator, input: unknown): unknown {
return {}
}

/**
* Build the matched route chain and extract params for a pathname.
* Falls back to the root route if no specific route is found.
*/
export function getMatchedRoutes<TRouteLike extends RouteLike>({
pathname,
routePathname,
Expand Down
5 changes: 5 additions & 0 deletions packages/router-core/src/scroll-restoration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ function getSafeSessionStorage() {
}

/** SessionStorage key used to persist scroll restoration state. */
/** SessionStorage key used to store scroll positions across navigations. */
export const storageKey = 'tsr-scroll-restoration-v1_3'

const throttle = (fn: (...args: Array<any>) => void, wait: number) => {
Expand Down Expand Up @@ -71,6 +72,7 @@ function createScrollRestorationCache(): ScrollRestorationCache | null {
}
}

/** In-memory handle to the persisted scroll restoration cache. */
/** In-memory handle to the persisted scroll restoration cache. */
export const scrollRestorationCache = createScrollRestorationCache()

Expand All @@ -81,6 +83,9 @@ export const scrollRestorationCache = createScrollRestorationCache()
* The `location.href` is used as a fallback to support the use case where the location state is not available like the initial render.
*/

/**
* Default scroll restoration cache key: location state key or full href.
*/
/**
* Default scroll restoration cache key: location state key or full href.
*/
Expand Down
1 change: 1 addition & 0 deletions packages/router-core/src/searchParams.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { decode, encode } from './qss'
import type { AnySchema } from './validators'

/** Default `parseSearch` that strips leading '?' and JSON-parses values. */
/** Default `parseSearch` that strips leading '?' and JSON-parses values. */
export const defaultParseSearch = parseSearchWith(JSON.parse)
export const defaultStringifySearch = stringifySearchWith(
Expand Down
6 changes: 6 additions & 0 deletions packages/router-core/src/ssr/serializer/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export type UnionizeSerializationAdaptersInput<
TAdapters extends ReadonlyArray<AnySerializationAdapter>,
> = TAdapters[number]['~types']['input']

/**
* Create a strongly-typed serialization adapter for SSR hydration.
* Use to register custom types with the router serializer.
*/
export function createSerializationAdapter<
TInput = unknown,
TOutput = unknown,
Expand Down Expand Up @@ -154,6 +158,7 @@ export interface SerializationAdapterTypes<

export type AnySerializationAdapter = SerializationAdapter<any, any, any>

/** Create a Seroval plugin for server-side serialization only. */
export function makeSsrSerovalPlugin(
serializationAdapter: AnySerializationAdapter,
options: { didRun: boolean },
Expand Down Expand Up @@ -182,6 +187,7 @@ export function makeSsrSerovalPlugin(
})
}

/** Create a Seroval plugin for client/server symmetric (de)serialization. */
export function makeSerovalPlugin(
serializationAdapter: AnySerializationAdapter,
): Plugin<any, SerovalNode> {
Expand Down
Loading