From 6b9de85da9144250cd068a0710da3b16c86eabaf Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 23 Oct 2025 04:12:39 +0000 Subject: [PATCH 1/2] docs: Add JSDoc annotations to core router APIs Co-authored-by: tannerlinsley --- agents/jsdoc.md | 50 +++++++++++++++++++ packages/router-core/src/defer.ts | 5 ++ packages/router-core/src/path.ts | 8 +++ .../router-core/src/process-route-tree.ts | 8 +++ packages/router-core/src/redirect.ts | 7 +++ packages/router-core/src/root.ts | 1 + packages/router-core/src/router.ts | 23 +++++++-- .../router-core/src/scroll-restoration.ts | 5 ++ packages/router-core/src/searchParams.ts | 1 + .../src/ssr/serializer/transformer.ts | 6 +++ 10 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 agents/jsdoc.md diff --git a/agents/jsdoc.md b/agents/jsdoc.md new file mode 100644 index 00000000000..c5c43923403 --- /dev/null +++ b/agents/jsdoc.md @@ -0,0 +1,50 @@ +# JSDoc Annotations Notes + +Scope: Add concise JSDoc to public API in core (`packages/router-core`). We do not add type info in JSDoc (TypeScript handles types). Prefer linking to public docs where helpful. Only annotate publicly documented APIs. + +Added annotations (first batch of ~20): + +- packages/router-core/src/defer.ts + - `TSR_DEFERRED_PROMISE`: symbol docs for deferred state carrier + - `defer`: purpose, behavior, link to docs + +- packages/router-core/src/path.ts + - `exactPathTest`: behavior re trailing slashes + - `parsePathname`: describes segment parsing + LRU cache + +- packages/router-core/src/root.ts + - `rootRouteId`: stable root identifier + +- packages/router-core/src/router.ts + - `defaultSerializeError`: serializable error shape + - `trailingSlashOptions`: option docs + - `getLocationChangeInfo`: path/href/hash comparison + - `lazyFn`: lazy import helper behavior + - `getInitialRouterState`: initial state creation + - `getMatchedRoutes`: matched route chain and params + - `SearchParamError`, `PathParamError`: error purposes + +- packages/router-core/src/process-route-tree.ts + - `processRouteTree`: build maps and sorted flat list + +- packages/router-core/src/ssr/serializer/transformer.ts + - `createSerializationAdapter`: purpose + - `makeSsrSerovalPlugin`: server plugin + - `makeSerovalPlugin`: symmetric plugin + +- packages/router-core/src/scroll-restoration.ts + - `storageKey`: purpose + - `scrollRestorationCache`: in-memory handle + - `defaultGetScrollRestorationKey`: description + +- packages/router-core/src/searchParams.ts + - `defaultParseSearch`: default impl doc + +- packages/router-core/src/redirect.ts + - `redirect`: behavior + usage context + - `isRedirect`, `isResolvedRedirect`, `parseRedirect`: intent + +Notes: +- Prioritized core router APIs that appear in public docs (defer, search params helpers, redirect, path helpers, router utilities, SSR serialization hooks, scroll restoration helpers). +- Avoided modifying any existing detailed comment blocks unless adding a short summary header. +- Next likely targets: `composeRewrites`, `executeRewriteInput/Output`, `matchPathname`, `resolvePath`, `interpolatePath`, SSR entrypoints (`createRequestHandler`, JSON helper), and history exports in `@tanstack/history` are already documented in their own package. diff --git a/packages/router-core/src/defer.ts b/packages/router-core/src/defer.ts index 1b3eb5b0f86..2bae16301f0 100644 --- a/packages/router-core/src/defer.ts +++ b/packages/router-core/src/defer.ts @@ -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 = diff --git a/packages/router-core/src/path.ts b/packages/router-core/src/path.ts index edb5a8d22cb..a0dcda2a060 100644 --- a/packages/router-core/src/path.ts +++ b/packages/router-core/src/path.ts @@ -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, @@ -222,6 +226,10 @@ export const parseRoutePathSegments = ( cache?: ParsePathnameCache, ): ReadonlyArray => 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, diff --git a/packages/router-core/src/process-route-tree.ts b/packages/router-core/src/process-route-tree.ts index 221cedc26de..85ba1475fda 100644 --- a/packages/router-core/src/process-route-tree.ts +++ b/packages/router-core/src/process-route-tree.ts @@ -184,6 +184,14 @@ export type ProcessRouteTreeResult = { flatRoutes: Array } +/** + * 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({ routeTree, initRoute, diff --git a/packages/router-core/src/redirect.ts b/packages/router-core/src/redirect.ts index 4672bf3febf..61e1e07ff16 100644 --- a/packages/router-core/src/redirect.ts +++ b/packages/router-core/src/redirect.ts @@ -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 = '.', @@ -109,11 +113,13 @@ export function redirect< return response as Redirect } +/** 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, @@ -121,6 +127,7 @@ export function isResolvedRedirect( 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) { diff --git a/packages/router-core/src/root.ts b/packages/router-core/src/root.ts index 6aa46e3eb99..361ffa9ea1b 100644 --- a/packages/router-core/src/root.ts +++ b/packages/router-core/src/root.ts @@ -1,2 +1,3 @@ +/** Stable identifier used for the root route in a route tree. */ export const rootRouteId = '__root__' export type RootRouteId = typeof rootRouteId diff --git a/packages/router-core/src/router.ts b/packages/router-core/src/router.ts index 9ff9eb3dca6..fd97f6b132e 100644 --- a/packages/router-core/src/router.ts +++ b/packages/router-core/src/router.ts @@ -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 = { @@ -797,6 +801,7 @@ export function defaultSerializeError(err: unknown) { } } +/** Options for configuring trailing-slash behavior. */ export const trailingSlashOptions = { always: 'always', never: 'never', @@ -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 @@ -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) => @@ -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) => any>, TKey extends keyof T = 'default', @@ -2542,6 +2554,7 @@ export function lazyFn< } } +/** Create an initial RouterState from a parsed location. */ export function getInitialRouterState( location: ParsedLocation, ): RouterState { @@ -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({ pathname, routePathname, diff --git a/packages/router-core/src/scroll-restoration.ts b/packages/router-core/src/scroll-restoration.ts index cc6432221ce..f2e6fa16ad9 100644 --- a/packages/router-core/src/scroll-restoration.ts +++ b/packages/router-core/src/scroll-restoration.ts @@ -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) => void, wait: number) => { @@ -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() @@ -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. */ diff --git a/packages/router-core/src/searchParams.ts b/packages/router-core/src/searchParams.ts index f8b9205bebf..e748ac3176e 100644 --- a/packages/router-core/src/searchParams.ts +++ b/packages/router-core/src/searchParams.ts @@ -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( diff --git a/packages/router-core/src/ssr/serializer/transformer.ts b/packages/router-core/src/ssr/serializer/transformer.ts index e20c2e544c3..df86f965edd 100644 --- a/packages/router-core/src/ssr/serializer/transformer.ts +++ b/packages/router-core/src/ssr/serializer/transformer.ts @@ -32,6 +32,10 @@ export type UnionizeSerializationAdaptersInput< TAdapters extends ReadonlyArray, > = 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, @@ -154,6 +158,7 @@ export interface SerializationAdapterTypes< export type AnySerializationAdapter = SerializationAdapter +/** Create a Seroval plugin for server-side serialization only. */ export function makeSsrSerovalPlugin( serializationAdapter: AnySerializationAdapter, options: { didRun: boolean }, @@ -182,6 +187,7 @@ export function makeSsrSerovalPlugin( }) } +/** Create a Seroval plugin for client/server symmetric (de)serialization. */ export function makeSerovalPlugin( serializationAdapter: AnySerializationAdapter, ): Plugin { From 116e4c0d721cded724a8d0c145c520d391f1f842 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 23 Oct 2025 04:15:51 +0000 Subject: [PATCH 2/2] Remove JSDoc notes file Co-authored-by: tannerlinsley --- agents/jsdoc.md | 50 ------------------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 agents/jsdoc.md diff --git a/agents/jsdoc.md b/agents/jsdoc.md deleted file mode 100644 index c5c43923403..00000000000 --- a/agents/jsdoc.md +++ /dev/null @@ -1,50 +0,0 @@ -# JSDoc Annotations Notes - -Scope: Add concise JSDoc to public API in core (`packages/router-core`). We do not add type info in JSDoc (TypeScript handles types). Prefer linking to public docs where helpful. Only annotate publicly documented APIs. - -Added annotations (first batch of ~20): - -- packages/router-core/src/defer.ts - - `TSR_DEFERRED_PROMISE`: symbol docs for deferred state carrier - - `defer`: purpose, behavior, link to docs - -- packages/router-core/src/path.ts - - `exactPathTest`: behavior re trailing slashes - - `parsePathname`: describes segment parsing + LRU cache - -- packages/router-core/src/root.ts - - `rootRouteId`: stable root identifier - -- packages/router-core/src/router.ts - - `defaultSerializeError`: serializable error shape - - `trailingSlashOptions`: option docs - - `getLocationChangeInfo`: path/href/hash comparison - - `lazyFn`: lazy import helper behavior - - `getInitialRouterState`: initial state creation - - `getMatchedRoutes`: matched route chain and params - - `SearchParamError`, `PathParamError`: error purposes - -- packages/router-core/src/process-route-tree.ts - - `processRouteTree`: build maps and sorted flat list - -- packages/router-core/src/ssr/serializer/transformer.ts - - `createSerializationAdapter`: purpose - - `makeSsrSerovalPlugin`: server plugin - - `makeSerovalPlugin`: symmetric plugin - -- packages/router-core/src/scroll-restoration.ts - - `storageKey`: purpose - - `scrollRestorationCache`: in-memory handle - - `defaultGetScrollRestorationKey`: description - -- packages/router-core/src/searchParams.ts - - `defaultParseSearch`: default impl doc - -- packages/router-core/src/redirect.ts - - `redirect`: behavior + usage context - - `isRedirect`, `isResolvedRedirect`, `parseRedirect`: intent - -Notes: -- Prioritized core router APIs that appear in public docs (defer, search params helpers, redirect, path helpers, router utilities, SSR serialization hooks, scroll restoration helpers). -- Avoided modifying any existing detailed comment blocks unless adding a short summary header. -- Next likely targets: `composeRewrites`, `executeRewriteInput/Output`, `matchPathname`, `resolvePath`, `interpolatePath`, SSR entrypoints (`createRequestHandler`, JSON helper), and history exports in `@tanstack/history` are already documented in their own package.