@tanstack/react-router 0.0.1-beta.215 → 0.0.1-beta.217

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","sources":["../../src/route.ts"],"sourcesContent":["import { HistoryLocation } from '@tanstack/history'\nimport * as React from 'react'\nimport invariant from 'tiny-invariant'\nimport { useLoaderData, useMatch } from './Matches'\nimport { AnyRouteMatch } from './RouterProvider'\nimport { NavigateOptions, ParsePathParams, ToSubOptions } from './link'\nimport { ParsedLocation } from './location'\nimport { joinPaths, trimPath } from './path'\nimport { RoutePaths } from './routeInfo'\nimport { AnyRouter } from './router'\nimport { useParams } from './useParams'\nimport { useSearch } from './useSearch'\nimport {\n Assign,\n Expand,\n IsAny,\n NoInfer,\n PickRequired,\n UnionToIntersection,\n} from './utils'\nimport { BuildLocationFn, NavigateFn } from './RouterProvider'\n\nexport const rootRouteId = '__root__' as const\nexport type RootRouteId = typeof rootRouteId\nexport type AnyPathParams = {}\n\nexport type AnySearchSchema = {}\n\nexport type AnyContext = {}\n\nexport interface RouteContext {}\n\nexport interface RouteMeta {}\n\nexport type PreloadableObj = { preload?: () => Promise<void> }\n\nexport type RoutePathOptions<TCustomId, TPath> =\n | {\n path: TPath\n }\n | {\n id: TCustomId\n }\n\nexport type RoutePathOptionsIntersection<TCustomId, TPath> =\n UnionToIntersection<RoutePathOptions<TCustomId, TPath>>\n\nexport type MetaOptions = keyof PickRequired<RouteMeta> extends never\n ? {\n meta?: RouteMeta\n }\n : {\n meta: RouteMeta\n }\n\nexport type RouteOptions<\n TParentRoute extends AnyRoute = AnyRoute,\n TCustomId extends string = string,\n TPath extends string = string,\n TSearchSchema extends Record<string, any> = {},\n TFullSearchSchema extends Record<string, any> = TSearchSchema,\n TParams extends AnyPathParams = AnyPathParams,\n TAllParams extends AnyPathParams = TParams,\n TRouteContext extends RouteContext = RouteContext,\n TAllContext extends Record<string, any> = AnyContext,\n TLoaderData extends any = unknown,\n> = BaseRouteOptions<\n TParentRoute,\n TCustomId,\n TPath,\n TSearchSchema,\n TFullSearchSchema,\n TParams,\n TAllParams,\n TRouteContext,\n TAllContext,\n TLoaderData\n> &\n NoInfer<\n UpdatableRouteOptions<\n TFullSearchSchema,\n TAllParams,\n TAllContext,\n TLoaderData\n >\n >\n\nexport type ParamsFallback<\n TPath extends string,\n TParams,\n> = unknown extends TParams ? Record<ParsePathParams<TPath>, string> : TParams\n\ntype Prefix<T extends string, U extends string> = U extends `${T}${infer _}`\n ? U\n : never\n\nexport type BaseRouteOptions<\n TParentRoute extends AnyRoute = AnyRoute,\n TCustomId extends string = string,\n TPath extends string = string,\n TSearchSchema extends Record<string, any> = {},\n TFullSearchSchema extends Record<string, any> = TSearchSchema,\n TParams extends AnyPathParams = {},\n TAllParams = ParamsFallback<TPath, TParams>,\n TRouteContext extends RouteContext = RouteContext,\n TAllContext extends Record<string, any> = AnyContext,\n TLoaderData extends any = unknown,\n> = RoutePathOptions<TCustomId, TPath> & {\n getParentRoute: () => TParentRoute\n validateSearch?: SearchSchemaValidator<TSearchSchema>\n} & (keyof PickRequired<RouteContext> extends never\n ? // This async function is called before a route is loaded.\n // If an error is thrown here, the route's loader will not be called.\n // If thrown during a navigation, the navigation will be cancelled and the error will be passed to the `onError` function.\n // If thrown during a preload event, the error will be logged to the console.\n {\n beforeLoad?: BeforeLoadFn<\n TFullSearchSchema,\n TParentRoute,\n TAllParams,\n TRouteContext\n >\n }\n : {\n beforeLoad: BeforeLoadFn<\n TFullSearchSchema,\n TParentRoute,\n TAllParams,\n TRouteContext\n >\n }) & {\n loader?: RouteLoadFn<\n TAllParams,\n TFullSearchSchema,\n NoInfer<TAllContext>,\n NoInfer<TRouteContext>,\n TLoaderData\n >\n } & (\n | {\n // Both or none\n parseParams?: (\n rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>,\n ) => TParams extends Record<ParsePathParams<TPath>, any>\n ? TParams\n : 'parseParams must return an object'\n stringifyParams?: (\n params: NoInfer<ParamsFallback<TPath, TParams>>,\n ) => Record<ParsePathParams<TPath>, string>\n }\n | {\n stringifyParams?: never\n parseParams?: never\n }\n )\n\ntype BeforeLoadFn<\n TFullSearchSchema extends Record<string, any>,\n TParentRoute extends AnyRoute,\n TAllParams,\n TRouteContext,\n> = (opts: {\n search: TFullSearchSchema\n abortController: AbortController\n preload: boolean\n params: TAllParams\n context: TParentRoute['types']['allContext']\n location: ParsedLocation\n navigate: NavigateFn<AnyRoute>\n buildLocation: BuildLocationFn<AnyRoute>\n}) => Promise<TRouteContext> | TRouteContext | void\n\nexport type UpdatableRouteOptions<\n TFullSearchSchema extends Record<string, any>,\n TAllParams extends AnyPathParams,\n TAllContext extends AnyContext,\n TLoaderData extends any = unknown,\n> = MetaOptions & {\n // test?: (args: TAllContext) => void\n // If true, this route will be matched as case-sensitive\n caseSensitive?: boolean\n // If true, this route will be forcefully wrapped in a suspense boundary\n wrapInSuspense?: boolean\n // The content to be rendered when the route is matched. If no component is provided, defaults to `<Outlet />`\n component?: RouteComponent<\n TFullSearchSchema,\n TAllParams,\n TAllContext,\n TLoaderData\n >\n // The content to be rendered when the route encounters an error\n errorComponent?: ErrorRouteComponent<\n TFullSearchSchema,\n TAllParams,\n {}\n // TAllContext // TODO: I have no idea why this breaks the universe,\n // so we'll come back to it later.\n > //\n // If supported by your framework, the content to be rendered as the fallback content until the route is ready to render\n pendingComponent?: PendingRouteComponent<\n TFullSearchSchema,\n TAllParams,\n TAllContext\n >\n // Filter functions that can manipulate search params *before* they are passed to links and navigate\n // calls that match this route.\n preSearchFilters?: SearchFilter<TFullSearchSchema>[]\n // Filter functions that can manipulate search params *after* they are passed to links and navigate\n // calls that match this route.\n postSearchFilters?: SearchFilter<TFullSearchSchema>[]\n onError?: (err: any) => void\n // These functions are called as route matches are loaded, stick around and leave the active\n // matches\n onEnter?: (match: AnyRouteMatch) => void\n onTransition?: (match: AnyRouteMatch) => void\n onLeave?: (match: AnyRouteMatch) => void\n // Set this to true or false to specifically set whether or not this route should be preloaded. If unset, will\n // default to router.options.reloadOnWindowFocus\n reloadOnWindowFocus?: boolean\n}\n\nexport type ParseParamsOption<TPath extends string, TParams> = ParseParamsFn<\n TPath,\n TParams\n>\n\nexport type ParseParamsFn<TPath extends string, TParams> = (\n rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>,\n) => TParams extends Record<ParsePathParams<TPath>, any>\n ? TParams\n : 'parseParams must return an object'\n\nexport type ParseParamsObj<TPath extends string, TParams> = {\n parse?: ParseParamsFn<TPath, TParams>\n}\n\n// The parse type here allows a zod schema to be passed directly to the validator\nexport type SearchSchemaValidator<TReturn> =\n | SearchSchemaValidatorObj<TReturn>\n | SearchSchemaValidatorFn<TReturn>\n\nexport type SearchSchemaValidatorObj<TReturn> = {\n parse?: SearchSchemaValidatorFn<TReturn>\n}\n\nexport type SearchSchemaValidatorFn<TReturn> = (\n searchObj: Record<string, unknown>,\n) => TReturn\n\nexport type DefinedPathParamWarning =\n 'Path params cannot be redefined by child routes!'\n\nexport type ParentParams<TParentParams> = AnyPathParams extends TParentParams\n ? {}\n : {\n [Key in keyof TParentParams]?: DefinedPathParamWarning\n }\n\nexport type RouteLoadFn<\n TAllParams = {},\n TFullSearchSchema extends Record<string, any> = {},\n TAllContext extends Record<string, any> = AnyContext,\n TRouteContext extends Record<string, any> = AnyContext,\n TLoaderData extends any = unknown,\n> = (\n match: LoaderFnContext<\n TAllParams,\n TFullSearchSchema,\n TAllContext,\n TRouteContext\n > & {\n parentMatchPromise?: Promise<void>\n },\n) => Promise<TLoaderData> | TLoaderData\n\nexport interface LoaderFnContext<\n TAllParams = {},\n TFullSearchSchema extends Record<string, any> = {},\n TAllContext extends Record<string, any> = AnyContext,\n TRouteContext extends Record<string, any> = AnyContext,\n> {\n abortController: AbortController\n preload: boolean\n params: TAllParams\n search: TFullSearchSchema\n context: Expand<Assign<TAllContext, TRouteContext>>\n location: ParsedLocation<TFullSearchSchema>\n navigate: (opts: NavigateOptions<AnyRoute>) => Promise<void>\n}\n\nexport type SearchFilter<T, U = T> = (prev: T) => U\n\nexport type ResolveId<\n TParentRoute,\n TCustomId extends string,\n TPath extends string,\n> = TParentRoute extends { id: infer TParentId extends string }\n ? RoutePrefix<TParentId, string extends TCustomId ? TPath : TCustomId>\n : RootRouteId\n\nexport type InferFullSearchSchema<TRoute> = TRoute extends {\n types: {\n fullSearchSchema: infer TFullSearchSchema\n }\n}\n ? TFullSearchSchema\n : {}\n\nexport type ResolveFullSearchSchema<TParentRoute, TSearchSchema> = Expand<\n Assign<InferFullSearchSchema<TParentRoute>, TSearchSchema>\n>\n\nexport interface AnyRoute\n extends Route<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > {}\n\nexport type MergeFromFromParent<T, U> = IsAny<T, U, T & U>\n\nexport type StreamedPromise<T> = {\n promise: Promise<T>\n status: 'resolved' | 'pending'\n data: T\n resolve: (value: T) => void\n}\n\nexport type ResolveAllParams<\n TParentRoute extends AnyRoute,\n TParams extends AnyPathParams,\n> = Record<never, string> extends TParentRoute['types']['allParams']\n ? TParams\n : Expand<\n UnionToIntersection<TParentRoute['types']['allParams'] & TParams> & {}\n >\n\nexport type RouteConstraints = {\n TParentRoute: AnyRoute\n TPath: string\n TFullPath: string\n TCustomId: string\n TId: string\n TSearchSchema: AnySearchSchema\n TFullSearchSchema: AnySearchSchema\n TParams: Record<string, any>\n TAllParams: Record<string, any>\n TParentContext: AnyContext\n TRouteContext: RouteContext\n TAllContext: AnyContext\n TRouterContext: AnyContext\n TChildren: unknown\n TRouteTree: AnyRoute\n}\n\nexport class Route<\n TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute,\n TPath extends RouteConstraints['TPath'] = '/',\n TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<\n TParentRoute,\n TPath\n >,\n TCustomId extends RouteConstraints['TCustomId'] = string,\n TId extends RouteConstraints['TId'] = ResolveId<\n TParentRoute,\n TCustomId,\n TPath\n >,\n TSearchSchema extends RouteConstraints['TSearchSchema'] = {},\n TFullSearchSchema extends RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<\n TParentRoute,\n TSearchSchema\n >,\n TParams extends RouteConstraints['TParams'] = Expand<\n Record<ParsePathParams<TPath>, string>\n >,\n TAllParams extends RouteConstraints['TAllParams'] = ResolveAllParams<\n TParentRoute,\n TParams\n >,\n TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext,\n TAllContext extends Expand<\n Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>\n > = Expand<\n Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>\n >,\n TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext,\n TLoaderData extends any = unknown,\n TChildren extends RouteConstraints['TChildren'] = unknown,\n TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,\n> {\n isRoot: TParentRoute extends Route<any> ? true : false\n options: RouteOptions<\n TParentRoute,\n TCustomId,\n TPath,\n TSearchSchema,\n TFullSearchSchema,\n TParams,\n TAllParams,\n TRouteContext,\n TAllContext,\n TLoaderData\n >\n\n test!: Expand<\n Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>\n >\n\n // Set up in this.init()\n parentRoute!: TParentRoute\n id!: TId\n // customId!: TCustomId\n path!: TPath\n fullPath!: TFullPath\n to!: TrimPathRight<TFullPath>\n\n // Optional\n children?: TChildren\n originalIndex?: number\n router?: AnyRouter\n rank!: number\n\n constructor(\n options: RouteOptions<\n TParentRoute,\n TCustomId,\n TPath,\n TSearchSchema,\n TFullSearchSchema,\n TParams,\n TAllParams,\n TRouteContext,\n TAllContext,\n TLoaderData\n >,\n ) {\n this.options = (options as any) || {}\n this.isRoot = !options?.getParentRoute as any\n Route.__onInit(this)\n }\n\n types!: {\n parentRoute: TParentRoute\n path: TPath\n to: TrimPathRight<TFullPath>\n fullPath: TFullPath\n customId: TCustomId\n id: TId\n searchSchema: TSearchSchema\n fullSearchSchema: TFullSearchSchema\n params: TParams\n allParams: TAllParams\n routeContext: TRouteContext\n allContext: TAllContext\n children: TChildren\n routeTree: TRouteTree\n routerContext: TRouterContext\n loaderData: TLoaderData\n }\n\n init = (opts: { originalIndex: number }) => {\n this.originalIndex = opts.originalIndex\n\n const options = this.options as RouteOptions<\n TParentRoute,\n TCustomId,\n TPath,\n TSearchSchema,\n TFullSearchSchema,\n TParams,\n TAllParams,\n TRouteContext,\n TAllContext,\n TLoaderData\n > &\n RoutePathOptionsIntersection<TCustomId, TPath>\n\n const isRoot = !options?.path && !options?.id\n\n this.parentRoute = this.options?.getParentRoute?.()\n\n if (isRoot) {\n this.path = rootRouteId as TPath\n } else {\n invariant(\n this.parentRoute,\n `Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`,\n )\n }\n\n let path: undefined | string = isRoot ? rootRouteId : options.path\n\n // If the path is anything other than an index path, trim it up\n if (path && path !== '/') {\n path = trimPath(path)\n }\n\n const customId = options?.id || path\n\n // Strip the parentId prefix from the first level of children\n let id = isRoot\n ? rootRouteId\n : joinPaths([\n (this.parentRoute.id as any) === rootRouteId\n ? ''\n : this.parentRoute.id,\n customId,\n ])\n\n if (path === rootRouteId) {\n path = '/'\n }\n\n if (id !== rootRouteId) {\n id = joinPaths(['/', id])\n }\n\n const fullPath =\n id === rootRouteId ? '/' : joinPaths([this.parentRoute.fullPath, path])\n\n this.path = path as TPath\n this.id = id as TId\n // this.customId = customId as TCustomId\n this.fullPath = fullPath as TFullPath\n this.to = fullPath as TrimPathRight<TFullPath>\n }\n\n addChildren = <TNewChildren extends AnyRoute[]>(\n children: TNewChildren,\n ): Route<\n TParentRoute,\n TPath,\n TFullPath,\n TCustomId,\n TId,\n TSearchSchema,\n TFullSearchSchema,\n TParams,\n TAllParams,\n TRouteContext,\n TAllContext,\n TRouterContext,\n TNewChildren,\n TRouteTree\n > => {\n this.children = children as any\n return this as any\n }\n\n update = (\n options: UpdatableRouteOptions<\n TFullSearchSchema,\n TAllParams,\n Expand<\n Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>\n >,\n TLoaderData\n >,\n ) => {\n Object.assign(this.options, options)\n return this\n }\n\n static __onInit = (route: any) => {\n // This is a dummy static method that should get\n // replaced by a framework specific implementation if necessary\n }\n\n useMatch = <TSelected = TAllContext>(opts?: {\n select?: (search: TAllContext) => TSelected\n }): TSelected => {\n return useMatch({ ...opts, from: this.id }) as any\n }\n useRouteContext = <TSelected = TAllContext>(opts?: {\n select?: (search: TAllContext) => TSelected\n }): TSelected => {\n return useMatch({\n ...opts,\n from: this.id,\n select: (d: any) => (opts?.select ? opts.select(d.context) : d.context),\n } as any)\n }\n useSearch = <TSelected = TFullSearchSchema>(opts?: {\n select?: (search: TFullSearchSchema) => TSelected\n }): TSelected => {\n return useSearch({ ...opts, from: this.id } as any)\n }\n useParams = <TSelected = TAllParams>(opts?: {\n select?: (search: TAllParams) => TSelected\n }): TSelected => {\n return useParams({ ...opts, from: this.id } as any)\n }\n useLoaderData = <TSelected = TLoaderData>(opts?: {\n select?: (search: TLoaderData) => TSelected\n }): TSelected => {\n return useLoaderData({ ...opts, from: this.id } as any) as any\n }\n}\n\nexport type AnyRootRoute = RootRoute<any, any, any>\n\nexport function rootRouteWithContext<TRouterContext extends {}>() {\n return <\n TSearchSchema extends Record<string, any> = {},\n TRouteContext extends RouteContext = RouteContext,\n TLoaderData extends any = unknown,\n >(\n options?: Omit<\n RouteOptions<\n AnyRoute, // TParentRoute\n RootRouteId, // TCustomId\n '', // TPath\n TSearchSchema, // TSearchSchema\n TSearchSchema, // TFullSearchSchema\n {}, // TParams\n {}, // TAllParams\n TRouteContext, // TRouteContext\n Assign<TRouterContext, TRouteContext>, // TAllContext\n TLoaderData // TLoaderData\n >,\n | 'path'\n | 'id'\n | 'getParentRoute'\n | 'caseSensitive'\n | 'parseParams'\n | 'stringifyParams'\n >,\n ): RootRoute<TSearchSchema, TRouteContext, TRouterContext> => {\n return new RootRoute(options) as any\n }\n}\n\nexport class RootRoute<\n TSearchSchema extends Record<string, any> = {},\n TRouteContext extends RouteContext = RouteContext,\n TRouterContext extends {} = {},\n TLoaderData extends any = unknown,\n> extends Route<\n any, // TParentRoute\n '/', // TPath\n '/', // TFullPath\n string, // TCustomId\n RootRouteId, // TId\n TSearchSchema, // TSearchSchema\n TSearchSchema, // TFullSearchSchema\n {}, // TParams\n {}, // TAllParams\n TRouteContext, // TRouteContext\n Expand<Assign<TRouterContext, TRouteContext>>, // TAllContext\n TRouterContext, // TRouterContext\n TLoaderData,\n any, // TChildren\n any // TRouteTree\n> {\n constructor(\n options?: Omit<\n RouteOptions<\n AnyRoute, // TParentRoute\n RootRouteId, // TCustomId\n '', // TPath\n TSearchSchema, // TSearchSchema\n TSearchSchema, // TFullSearchSchema\n {}, // TParams\n {}, // TAllParams\n TRouteContext, // TRouteContext\n Assign<TRouterContext, TRouteContext>, // TAllContext\n TLoaderData\n >,\n | 'path'\n | 'id'\n | 'getParentRoute'\n | 'caseSensitive'\n | 'parseParams'\n | 'stringifyParams'\n >,\n ) {\n super(options as any)\n }\n}\n\nexport type ResolveFullPath<\n TParentRoute extends AnyRoute,\n TPath extends string,\n TPrefixed = RoutePrefix<TParentRoute['fullPath'], TPath>,\n> = TPrefixed extends RootRouteId ? '/' : TPrefixed\n\ntype RoutePrefix<\n TPrefix extends string,\n TPath extends string,\n> = string extends TPath\n ? RootRouteId\n : TPath extends string\n ? TPrefix extends RootRouteId\n ? TPath extends '/'\n ? '/'\n : `/${TrimPath<TPath>}`\n : `${TPrefix}/${TPath}` extends '/'\n ? '/'\n : `/${TrimPathLeft<`${TrimPathRight<TPrefix>}/${TrimPath<TPath>}`>}`\n : never\n\nexport type TrimPath<T extends string> = '' extends T\n ? ''\n : TrimPathRight<TrimPathLeft<T>>\n\nexport type TrimPathLeft<T extends string> =\n T extends `${RootRouteId}/${infer U}`\n ? TrimPathLeft<U>\n : T extends `/${infer U}`\n ? TrimPathLeft<U>\n : T\nexport type TrimPathRight<T extends string> = T extends '/'\n ? '/'\n : T extends `${infer U}/`\n ? TrimPathRight<U>\n : T\n\nexport type RouteMask<TRouteTree extends AnyRoute> = {\n routeTree: TRouteTree\n from: RoutePaths<TRouteTree>\n to?: any\n params?: any\n search?: any\n hash?: any\n state?: any\n unmaskOnReload?: boolean\n}\n\nexport function createRouteMask<\n TRouteTree extends AnyRoute,\n TFrom extends RoutePaths<TRouteTree>,\n TTo extends string,\n>(\n opts: {\n routeTree: TRouteTree\n } & ToSubOptions<TRouteTree, TFrom, TTo>,\n): RouteMask<TRouteTree> {\n return opts as any\n}\n\nexport type RouteProps<\n TFullSearchSchema extends Record<string, any> = AnySearchSchema,\n TAllParams extends AnyPathParams = AnyPathParams,\n TAllContext extends Record<string, any> = AnyContext,\n TLoaderData extends any = unknown,\n> = {\n useMatch: <TSelected = TAllContext>(opts?: {\n select?: (search: TAllContext) => TSelected\n }) => TSelected\n useRouteContext: <TSelected = TAllContext>(opts?: {\n select?: (search: TAllContext) => TSelected\n }) => TSelected\n useSearch: <TSelected = TFullSearchSchema>(opts?: {\n select?: (search: TFullSearchSchema) => TSelected\n }) => TSelected\n useParams: <TSelected = TAllParams>(opts?: {\n select?: (search: TAllParams) => TSelected\n }) => TSelected\n useLoaderData: <TSelected = TLoaderData>(opts?: {\n select?: (search: TLoaderData) => TSelected\n }) => TSelected\n}\n\nexport type ErrorRouteProps<\n TFullSearchSchema extends Record<string, any> = AnySearchSchema,\n TAllParams extends AnyPathParams = AnyPathParams,\n TAllContext extends Record<string, any> = AnyContext,\n> = {\n error: unknown\n info: { componentStack: string }\n} & RouteProps<TFullSearchSchema, TAllParams, TAllContext>\n\nexport type PendingRouteProps<\n TFullSearchSchema extends Record<string, any> = AnySearchSchema,\n TAllParams extends AnyPathParams = AnyPathParams,\n TAllContext extends Record<string, any> = AnyContext,\n> = RouteProps<TFullSearchSchema, TAllParams, TAllContext>\n//\n\nexport type ReactNode = any\n\nexport type SyncRouteComponent<TProps> =\n | ((props: TProps) => ReactNode)\n | React.LazyExoticComponent<(props: TProps) => ReactNode>\n\nexport type AsyncRouteComponent<TProps> = SyncRouteComponent<TProps> & {\n preload?: () => Promise<void>\n}\n\nexport type RouteComponent<\n TFullSearchSchema extends Record<string, any>,\n TAllParams extends AnyPathParams,\n TAllContext extends Record<string, any>,\n TLoaderData extends any = unknown,\n> = AsyncRouteComponent<\n RouteProps<TFullSearchSchema, TAllParams, TAllContext, TLoaderData>\n>\n\nexport type ErrorRouteComponent<\n TFullSearchSchema extends Record<string, any>,\n TAllParams extends AnyPathParams,\n TAllContext extends Record<string, any>,\n> = AsyncRouteComponent<\n ErrorRouteProps<TFullSearchSchema, TAllParams, TAllContext>\n>\n\nexport type PendingRouteComponent<\n TFullSearchSchema extends Record<string, any>,\n TAllParams extends AnyPathParams,\n TAllContext extends Record<string, any>,\n> = AsyncRouteComponent<\n PendingRouteProps<TFullSearchSchema, TAllParams, TAllContext>\n>\n\nexport type AnyRouteComponent = RouteComponent<any, any, any, any>\n"],"names":["rootRouteId","Route","constructor","options","isRoot","getParentRoute","__onInit","init","opts","originalIndex","path","id","parentRoute","invariant","trimPath","customId","joinPaths","fullPath","to","addChildren","children","update","Object","assign","route","useMatch","from","useRouteContext","select","d","context","useSearch","useParams","useLoaderData","rootRouteWithContext","RootRoute","createRouteMask"],"mappings":"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"}
1
+ {"version":3,"file":"route.js","sources":["../../src/route.ts"],"sourcesContent":["import { HistoryLocation } from '@tanstack/history'\nimport * as React from 'react'\nimport invariant from 'tiny-invariant'\nimport { useLoaderData, useMatch } from './Matches'\nimport { AnyRouteMatch } from './RouterProvider'\nimport { NavigateOptions, ParsePathParams, ToSubOptions } from './link'\nimport { ParsedLocation } from './location'\nimport { joinPaths, trimPath } from './path'\nimport { RoutePaths } from './routeInfo'\nimport { AnyRouter } from './router'\nimport { useParams } from './useParams'\nimport { useSearch } from './useSearch'\nimport {\n Assign,\n Expand,\n IsAny,\n NoInfer,\n PickRequired,\n UnionToIntersection,\n} from './utils'\nimport { BuildLocationFn, NavigateFn } from './RouterProvider'\n\nexport const rootRouteId = '__root__' as const\nexport type RootRouteId = typeof rootRouteId\nexport type AnyPathParams = {}\n\nexport type AnySearchSchema = {}\n\nexport type AnyContext = {}\n\nexport interface RouteContext {}\n\nexport interface RouteMeta {}\n\nexport type PreloadableObj = { preload?: () => Promise<void> }\n\nexport type RoutePathOptions<TCustomId, TPath> =\n | {\n path: TPath\n }\n | {\n id: TCustomId\n }\n\nexport type RoutePathOptionsIntersection<TCustomId, TPath> =\n UnionToIntersection<RoutePathOptions<TCustomId, TPath>>\n\nexport type MetaOptions = keyof PickRequired<RouteMeta> extends never\n ? {\n meta?: RouteMeta\n }\n : {\n meta: RouteMeta\n }\n\nexport type RouteOptions<\n TParentRoute extends AnyRoute = AnyRoute,\n TCustomId extends string = string,\n TPath extends string = string,\n TSearchSchema extends Record<string, any> = {},\n TFullSearchSchema extends Record<string, any> = TSearchSchema,\n TParams extends AnyPathParams = AnyPathParams,\n TAllParams extends AnyPathParams = TParams,\n TRouteContext extends RouteContext = RouteContext,\n TAllContext extends Record<string, any> = AnyContext,\n TLoaderData extends any = unknown,\n> = BaseRouteOptions<\n TParentRoute,\n TCustomId,\n TPath,\n TSearchSchema,\n TFullSearchSchema,\n TParams,\n TAllParams,\n TRouteContext,\n TAllContext,\n TLoaderData\n> &\n NoInfer<\n UpdatableRouteOptions<\n TFullSearchSchema,\n TAllParams,\n TAllContext,\n TLoaderData\n >\n >\n\nexport type ParamsFallback<\n TPath extends string,\n TParams,\n> = unknown extends TParams ? Record<ParsePathParams<TPath>, string> : TParams\n\ntype Prefix<T extends string, U extends string> = U extends `${T}${infer _}`\n ? U\n : never\n\nexport type BaseRouteOptions<\n TParentRoute extends AnyRoute = AnyRoute,\n TCustomId extends string = string,\n TPath extends string = string,\n TSearchSchema extends Record<string, any> = {},\n TFullSearchSchema extends Record<string, any> = TSearchSchema,\n TParams extends AnyPathParams = {},\n TAllParams = ParamsFallback<TPath, TParams>,\n TRouteContext extends RouteContext = RouteContext,\n TAllContext extends Record<string, any> = AnyContext,\n TLoaderData extends any = unknown,\n> = RoutePathOptions<TCustomId, TPath> & {\n getParentRoute: () => TParentRoute\n validateSearch?: SearchSchemaValidator<TSearchSchema>\n shouldReload?:\n | boolean\n | ((\n match: LoaderFnContext<\n TAllParams,\n TFullSearchSchema,\n TAllContext,\n TRouteContext\n >,\n ) => any)\n} & (keyof PickRequired<RouteContext> extends never\n ? // This async function is called before a route is loaded.\n // If an error is thrown here, the route's loader will not be called.\n // If thrown during a navigation, the navigation will be cancelled and the error will be passed to the `onError` function.\n // If thrown during a preload event, the error will be logged to the console.\n {\n beforeLoad?: BeforeLoadFn<\n TFullSearchSchema,\n TParentRoute,\n TAllParams,\n TRouteContext\n >\n }\n : {\n beforeLoad: BeforeLoadFn<\n TFullSearchSchema,\n TParentRoute,\n TAllParams,\n TRouteContext\n >\n }) & {\n loader?: RouteLoadFn<\n TAllParams,\n TFullSearchSchema,\n NoInfer<TAllContext>,\n NoInfer<TRouteContext>,\n TLoaderData\n >\n } & (\n | {\n // Both or none\n parseParams?: (\n rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>,\n ) => TParams extends Record<ParsePathParams<TPath>, any>\n ? TParams\n : 'parseParams must return an object'\n stringifyParams?: (\n params: NoInfer<ParamsFallback<TPath, TParams>>,\n ) => Record<ParsePathParams<TPath>, string>\n }\n | {\n stringifyParams?: never\n parseParams?: never\n }\n )\n\ntype BeforeLoadFn<\n TFullSearchSchema extends Record<string, any>,\n TParentRoute extends AnyRoute,\n TAllParams,\n TRouteContext,\n> = (opts: {\n search: TFullSearchSchema\n abortController: AbortController\n preload: boolean\n params: TAllParams\n context: TParentRoute['types']['allContext']\n location: ParsedLocation\n navigate: NavigateFn<AnyRoute>\n buildLocation: BuildLocationFn<AnyRoute>\n}) => Promise<TRouteContext> | TRouteContext | void\n\nexport type UpdatableRouteOptions<\n TFullSearchSchema extends Record<string, any>,\n TAllParams extends AnyPathParams,\n TAllContext extends AnyContext,\n TLoaderData extends any = unknown,\n> = MetaOptions & {\n // test?: (args: TAllContext) => void\n // If true, this route will be matched as case-sensitive\n caseSensitive?: boolean\n // If true, this route will be forcefully wrapped in a suspense boundary\n wrapInSuspense?: boolean\n // The content to be rendered when the route is matched. If no component is provided, defaults to `<Outlet />`\n component?: RouteComponent<\n TFullSearchSchema,\n TAllParams,\n TAllContext,\n TLoaderData\n >\n // The content to be rendered when the route encounters an error\n errorComponent?: ErrorRouteComponent<\n TFullSearchSchema,\n TAllParams,\n {}\n // TAllContext // TODO: I have no idea why this breaks the universe,\n // so we'll come back to it later.\n > //\n // If supported by your framework, the content to be rendered as the fallback content until the route is ready to render\n pendingComponent?: PendingRouteComponent<\n TFullSearchSchema,\n TAllParams,\n TAllContext\n >\n // Filter functions that can manipulate search params *before* they are passed to links and navigate\n // calls that match this route.\n preSearchFilters?: SearchFilter<TFullSearchSchema>[]\n // Filter functions that can manipulate search params *after* they are passed to links and navigate\n // calls that match this route.\n postSearchFilters?: SearchFilter<TFullSearchSchema>[]\n onError?: (err: any) => void\n // These functions are called as route matches are loaded, stick around and leave the active\n // matches\n onEnter?: (match: AnyRouteMatch) => void\n onTransition?: (match: AnyRouteMatch) => void\n onLeave?: (match: AnyRouteMatch) => void\n // Set this to true or false to specifically set whether or not this route should be preloaded. If unset, will\n // default to router.options.reloadOnWindowFocus\n reloadOnWindowFocus?: boolean\n}\n\nexport type ParseParamsOption<TPath extends string, TParams> = ParseParamsFn<\n TPath,\n TParams\n>\n\nexport type ParseParamsFn<TPath extends string, TParams> = (\n rawParams: IsAny<TPath, any, Record<ParsePathParams<TPath>, string>>,\n) => TParams extends Record<ParsePathParams<TPath>, any>\n ? TParams\n : 'parseParams must return an object'\n\nexport type ParseParamsObj<TPath extends string, TParams> = {\n parse?: ParseParamsFn<TPath, TParams>\n}\n\n// The parse type here allows a zod schema to be passed directly to the validator\nexport type SearchSchemaValidator<TReturn> =\n | SearchSchemaValidatorObj<TReturn>\n | SearchSchemaValidatorFn<TReturn>\n\nexport type SearchSchemaValidatorObj<TReturn> = {\n parse?: SearchSchemaValidatorFn<TReturn>\n}\n\nexport type SearchSchemaValidatorFn<TReturn> = (\n searchObj: Record<string, unknown>,\n) => TReturn\n\nexport type DefinedPathParamWarning =\n 'Path params cannot be redefined by child routes!'\n\nexport type ParentParams<TParentParams> = AnyPathParams extends TParentParams\n ? {}\n : {\n [Key in keyof TParentParams]?: DefinedPathParamWarning\n }\n\nexport type RouteLoadFn<\n TAllParams = {},\n TFullSearchSchema extends Record<string, any> = {},\n TAllContext extends Record<string, any> = AnyContext,\n TRouteContext extends Record<string, any> = AnyContext,\n TLoaderData extends any = unknown,\n> = (\n match: LoaderFnContext<\n TAllParams,\n TFullSearchSchema,\n TAllContext,\n TRouteContext\n >,\n) => Promise<TLoaderData> | TLoaderData\n\nexport interface LoaderFnContext<\n TAllParams = {},\n TFullSearchSchema extends Record<string, any> = {},\n TAllContext extends Record<string, any> = AnyContext,\n TRouteContext extends Record<string, any> = AnyContext,\n> {\n abortController: AbortController\n preload: boolean\n params: TAllParams\n search: TFullSearchSchema\n context: Expand<Assign<TAllContext, TRouteContext>>\n location: ParsedLocation<TFullSearchSchema>\n navigate: (opts: NavigateOptions<AnyRoute>) => Promise<void>\n parentMatchPromise?: Promise<void>\n cause: 'enter' | 'stay'\n}\n\nexport type SearchFilter<T, U = T> = (prev: T) => U\n\nexport type ResolveId<\n TParentRoute,\n TCustomId extends string,\n TPath extends string,\n> = TParentRoute extends { id: infer TParentId extends string }\n ? RoutePrefix<TParentId, string extends TCustomId ? TPath : TCustomId>\n : RootRouteId\n\nexport type InferFullSearchSchema<TRoute> = TRoute extends {\n types: {\n fullSearchSchema: infer TFullSearchSchema\n }\n}\n ? TFullSearchSchema\n : {}\n\nexport type ResolveFullSearchSchema<TParentRoute, TSearchSchema> = Expand<\n Assign<InferFullSearchSchema<TParentRoute>, TSearchSchema>\n>\n\nexport interface AnyRoute\n extends Route<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n > {}\n\nexport type MergeFromFromParent<T, U> = IsAny<T, U, T & U>\n\nexport type StreamedPromise<T> = {\n promise: Promise<T>\n status: 'resolved' | 'pending'\n data: T\n resolve: (value: T) => void\n}\n\nexport type ResolveAllParams<\n TParentRoute extends AnyRoute,\n TParams extends AnyPathParams,\n> = Record<never, string> extends TParentRoute['types']['allParams']\n ? TParams\n : Expand<\n UnionToIntersection<TParentRoute['types']['allParams'] & TParams> & {}\n >\n\nexport type RouteConstraints = {\n TParentRoute: AnyRoute\n TPath: string\n TFullPath: string\n TCustomId: string\n TId: string\n TSearchSchema: AnySearchSchema\n TFullSearchSchema: AnySearchSchema\n TParams: Record<string, any>\n TAllParams: Record<string, any>\n TParentContext: AnyContext\n TRouteContext: RouteContext\n TAllContext: AnyContext\n TRouterContext: AnyContext\n TChildren: unknown\n TRouteTree: AnyRoute\n}\n\nexport class Route<\n TParentRoute extends RouteConstraints['TParentRoute'] = AnyRoute,\n TPath extends RouteConstraints['TPath'] = '/',\n TFullPath extends RouteConstraints['TFullPath'] = ResolveFullPath<\n TParentRoute,\n TPath\n >,\n TCustomId extends RouteConstraints['TCustomId'] = string,\n TId extends RouteConstraints['TId'] = ResolveId<\n TParentRoute,\n TCustomId,\n TPath\n >,\n TSearchSchema extends RouteConstraints['TSearchSchema'] = {},\n TFullSearchSchema extends RouteConstraints['TFullSearchSchema'] = ResolveFullSearchSchema<\n TParentRoute,\n TSearchSchema\n >,\n TParams extends RouteConstraints['TParams'] = Expand<\n Record<ParsePathParams<TPath>, string>\n >,\n TAllParams extends RouteConstraints['TAllParams'] = ResolveAllParams<\n TParentRoute,\n TParams\n >,\n TRouteContext extends RouteConstraints['TRouteContext'] = RouteContext,\n TAllContext extends Expand<\n Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>\n > = Expand<\n Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>\n >,\n TRouterContext extends RouteConstraints['TRouterContext'] = AnyContext,\n TLoaderData extends any = unknown,\n TChildren extends RouteConstraints['TChildren'] = unknown,\n TRouteTree extends RouteConstraints['TRouteTree'] = AnyRoute,\n> {\n isRoot: TParentRoute extends Route<any> ? true : false\n options: RouteOptions<\n TParentRoute,\n TCustomId,\n TPath,\n TSearchSchema,\n TFullSearchSchema,\n TParams,\n TAllParams,\n TRouteContext,\n TAllContext,\n TLoaderData\n >\n\n test!: Expand<\n Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>\n >\n\n // Set up in this.init()\n parentRoute!: TParentRoute\n id!: TId\n // customId!: TCustomId\n path!: TPath\n fullPath!: TFullPath\n to!: TrimPathRight<TFullPath>\n\n // Optional\n children?: TChildren\n originalIndex?: number\n router?: AnyRouter\n rank!: number\n\n constructor(\n options: RouteOptions<\n TParentRoute,\n TCustomId,\n TPath,\n TSearchSchema,\n TFullSearchSchema,\n TParams,\n TAllParams,\n TRouteContext,\n TAllContext,\n TLoaderData\n >,\n ) {\n this.options = (options as any) || {}\n this.isRoot = !options?.getParentRoute as any\n Route.__onInit(this)\n }\n\n types!: {\n parentRoute: TParentRoute\n path: TPath\n to: TrimPathRight<TFullPath>\n fullPath: TFullPath\n customId: TCustomId\n id: TId\n searchSchema: TSearchSchema\n fullSearchSchema: TFullSearchSchema\n params: TParams\n allParams: TAllParams\n routeContext: TRouteContext\n allContext: TAllContext\n children: TChildren\n routeTree: TRouteTree\n routerContext: TRouterContext\n loaderData: TLoaderData\n }\n\n init = (opts: { originalIndex: number }) => {\n this.originalIndex = opts.originalIndex\n\n const options = this.options as RouteOptions<\n TParentRoute,\n TCustomId,\n TPath,\n TSearchSchema,\n TFullSearchSchema,\n TParams,\n TAllParams,\n TRouteContext,\n TAllContext,\n TLoaderData\n > &\n RoutePathOptionsIntersection<TCustomId, TPath>\n\n const isRoot = !options?.path && !options?.id\n\n this.parentRoute = this.options?.getParentRoute?.()\n\n if (isRoot) {\n this.path = rootRouteId as TPath\n } else {\n invariant(\n this.parentRoute,\n `Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`,\n )\n }\n\n let path: undefined | string = isRoot ? rootRouteId : options.path\n\n // If the path is anything other than an index path, trim it up\n if (path && path !== '/') {\n path = trimPath(path)\n }\n\n const customId = options?.id || path\n\n // Strip the parentId prefix from the first level of children\n let id = isRoot\n ? rootRouteId\n : joinPaths([\n (this.parentRoute.id as any) === rootRouteId\n ? ''\n : this.parentRoute.id,\n customId,\n ])\n\n if (path === rootRouteId) {\n path = '/'\n }\n\n if (id !== rootRouteId) {\n id = joinPaths(['/', id])\n }\n\n const fullPath =\n id === rootRouteId ? '/' : joinPaths([this.parentRoute.fullPath, path])\n\n this.path = path as TPath\n this.id = id as TId\n // this.customId = customId as TCustomId\n this.fullPath = fullPath as TFullPath\n this.to = fullPath as TrimPathRight<TFullPath>\n }\n\n addChildren = <TNewChildren extends AnyRoute[]>(\n children: TNewChildren,\n ): Route<\n TParentRoute,\n TPath,\n TFullPath,\n TCustomId,\n TId,\n TSearchSchema,\n TFullSearchSchema,\n TParams,\n TAllParams,\n TRouteContext,\n TAllContext,\n TRouterContext,\n TNewChildren,\n TRouteTree\n > => {\n this.children = children as any\n return this as any\n }\n\n update = (\n options: UpdatableRouteOptions<\n TFullSearchSchema,\n TAllParams,\n Expand<\n Assign<IsAny<TParentRoute['types']['allContext'], {}>, TRouteContext>\n >,\n TLoaderData\n >,\n ) => {\n Object.assign(this.options, options)\n return this\n }\n\n static __onInit = (route: any) => {\n // This is a dummy static method that should get\n // replaced by a framework specific implementation if necessary\n }\n\n useMatch = <TSelected = TAllContext>(opts?: {\n select?: (search: TAllContext) => TSelected\n }): TSelected => {\n return useMatch({ ...opts, from: this.id }) as any\n }\n useRouteContext = <TSelected = TAllContext>(opts?: {\n select?: (search: TAllContext) => TSelected\n }): TSelected => {\n return useMatch({\n ...opts,\n from: this.id,\n select: (d: any) => (opts?.select ? opts.select(d.context) : d.context),\n } as any)\n }\n useSearch = <TSelected = TFullSearchSchema>(opts?: {\n select?: (search: TFullSearchSchema) => TSelected\n }): TSelected => {\n return useSearch({ ...opts, from: this.id } as any)\n }\n useParams = <TSelected = TAllParams>(opts?: {\n select?: (search: TAllParams) => TSelected\n }): TSelected => {\n return useParams({ ...opts, from: this.id } as any)\n }\n useLoaderData = <TSelected = TLoaderData>(opts?: {\n select?: (search: TLoaderData) => TSelected\n }): TSelected => {\n return useLoaderData({ ...opts, from: this.id } as any) as any\n }\n}\n\nexport type AnyRootRoute = RootRoute<any, any, any>\n\nexport function rootRouteWithContext<TRouterContext extends {}>() {\n return <\n TSearchSchema extends Record<string, any> = {},\n TRouteContext extends RouteContext = RouteContext,\n TLoaderData extends any = unknown,\n >(\n options?: Omit<\n RouteOptions<\n AnyRoute, // TParentRoute\n RootRouteId, // TCustomId\n '', // TPath\n TSearchSchema, // TSearchSchema\n TSearchSchema, // TFullSearchSchema\n {}, // TParams\n {}, // TAllParams\n TRouteContext, // TRouteContext\n Assign<TRouterContext, TRouteContext>, // TAllContext\n TLoaderData // TLoaderData\n >,\n | 'path'\n | 'id'\n | 'getParentRoute'\n | 'caseSensitive'\n | 'parseParams'\n | 'stringifyParams'\n >,\n ): RootRoute<TSearchSchema, TRouteContext, TRouterContext> => {\n return new RootRoute(options) as any\n }\n}\n\nexport class RootRoute<\n TSearchSchema extends Record<string, any> = {},\n TRouteContext extends RouteContext = RouteContext,\n TRouterContext extends {} = {},\n TLoaderData extends any = unknown,\n> extends Route<\n any, // TParentRoute\n '/', // TPath\n '/', // TFullPath\n string, // TCustomId\n RootRouteId, // TId\n TSearchSchema, // TSearchSchema\n TSearchSchema, // TFullSearchSchema\n {}, // TParams\n {}, // TAllParams\n TRouteContext, // TRouteContext\n Expand<Assign<TRouterContext, TRouteContext>>, // TAllContext\n TRouterContext, // TRouterContext\n TLoaderData,\n any, // TChildren\n any // TRouteTree\n> {\n constructor(\n options?: Omit<\n RouteOptions<\n AnyRoute, // TParentRoute\n RootRouteId, // TCustomId\n '', // TPath\n TSearchSchema, // TSearchSchema\n TSearchSchema, // TFullSearchSchema\n {}, // TParams\n {}, // TAllParams\n TRouteContext, // TRouteContext\n Assign<TRouterContext, TRouteContext>, // TAllContext\n TLoaderData\n >,\n | 'path'\n | 'id'\n | 'getParentRoute'\n | 'caseSensitive'\n | 'parseParams'\n | 'stringifyParams'\n >,\n ) {\n super(options as any)\n }\n}\n\nexport type ResolveFullPath<\n TParentRoute extends AnyRoute,\n TPath extends string,\n TPrefixed = RoutePrefix<TParentRoute['fullPath'], TPath>,\n> = TPrefixed extends RootRouteId ? '/' : TPrefixed\n\ntype RoutePrefix<\n TPrefix extends string,\n TPath extends string,\n> = string extends TPath\n ? RootRouteId\n : TPath extends string\n ? TPrefix extends RootRouteId\n ? TPath extends '/'\n ? '/'\n : `/${TrimPath<TPath>}`\n : `${TPrefix}/${TPath}` extends '/'\n ? '/'\n : `/${TrimPathLeft<`${TrimPathRight<TPrefix>}/${TrimPath<TPath>}`>}`\n : never\n\nexport type TrimPath<T extends string> = '' extends T\n ? ''\n : TrimPathRight<TrimPathLeft<T>>\n\nexport type TrimPathLeft<T extends string> =\n T extends `${RootRouteId}/${infer U}`\n ? TrimPathLeft<U>\n : T extends `/${infer U}`\n ? TrimPathLeft<U>\n : T\nexport type TrimPathRight<T extends string> = T extends '/'\n ? '/'\n : T extends `${infer U}/`\n ? TrimPathRight<U>\n : T\n\nexport type RouteMask<TRouteTree extends AnyRoute> = {\n routeTree: TRouteTree\n from: RoutePaths<TRouteTree>\n to?: any\n params?: any\n search?: any\n hash?: any\n state?: any\n unmaskOnReload?: boolean\n}\n\nexport function createRouteMask<\n TRouteTree extends AnyRoute,\n TFrom extends RoutePaths<TRouteTree>,\n TTo extends string,\n>(\n opts: {\n routeTree: TRouteTree\n } & ToSubOptions<TRouteTree, TFrom, TTo>,\n): RouteMask<TRouteTree> {\n return opts as any\n}\n\nexport type RouteProps<\n TFullSearchSchema extends Record<string, any> = AnySearchSchema,\n TAllParams extends AnyPathParams = AnyPathParams,\n TAllContext extends Record<string, any> = AnyContext,\n TLoaderData extends any = unknown,\n> = {\n useMatch: <TSelected = TAllContext>(opts?: {\n select?: (search: TAllContext) => TSelected\n }) => TSelected\n useRouteContext: <TSelected = TAllContext>(opts?: {\n select?: (search: TAllContext) => TSelected\n }) => TSelected\n useSearch: <TSelected = TFullSearchSchema>(opts?: {\n select?: (search: TFullSearchSchema) => TSelected\n }) => TSelected\n useParams: <TSelected = TAllParams>(opts?: {\n select?: (search: TAllParams) => TSelected\n }) => TSelected\n useLoaderData: <TSelected = TLoaderData>(opts?: {\n select?: (search: TLoaderData) => TSelected\n }) => TSelected\n}\n\nexport type ErrorRouteProps<\n TFullSearchSchema extends Record<string, any> = AnySearchSchema,\n TAllParams extends AnyPathParams = AnyPathParams,\n TAllContext extends Record<string, any> = AnyContext,\n> = {\n error: unknown\n info: { componentStack: string }\n} & RouteProps<TFullSearchSchema, TAllParams, TAllContext>\n\nexport type PendingRouteProps<\n TFullSearchSchema extends Record<string, any> = AnySearchSchema,\n TAllParams extends AnyPathParams = AnyPathParams,\n TAllContext extends Record<string, any> = AnyContext,\n> = RouteProps<TFullSearchSchema, TAllParams, TAllContext>\n//\n\nexport type ReactNode = any\n\nexport type SyncRouteComponent<TProps> =\n | ((props: TProps) => ReactNode)\n | React.LazyExoticComponent<(props: TProps) => ReactNode>\n\nexport type AsyncRouteComponent<TProps> = SyncRouteComponent<TProps> & {\n preload?: () => Promise<void>\n}\n\nexport type RouteComponent<\n TFullSearchSchema extends Record<string, any>,\n TAllParams extends AnyPathParams,\n TAllContext extends Record<string, any>,\n TLoaderData extends any = unknown,\n> = AsyncRouteComponent<\n RouteProps<TFullSearchSchema, TAllParams, TAllContext, TLoaderData>\n>\n\nexport type ErrorRouteComponent<\n TFullSearchSchema extends Record<string, any>,\n TAllParams extends AnyPathParams,\n TAllContext extends Record<string, any>,\n> = AsyncRouteComponent<\n ErrorRouteProps<TFullSearchSchema, TAllParams, TAllContext>\n>\n\nexport type PendingRouteComponent<\n TFullSearchSchema extends Record<string, any>,\n TAllParams extends AnyPathParams,\n TAllContext extends Record<string, any>,\n> = AsyncRouteComponent<\n PendingRouteProps<TFullSearchSchema, TAllParams, TAllContext>\n>\n\nexport type AnyRouteComponent = RouteComponent<any, any, any, any>\n"],"names":["rootRouteId","Route","constructor","options","isRoot","getParentRoute","__onInit","init","opts","originalIndex","path","id","parentRoute","invariant","trimPath","customId","joinPaths","fullPath","to","addChildren","children","update","Object","assign","route","useMatch","from","useRouteContext","select","d","context","useSearch","useParams","useLoaderData","rootRouteWithContext","RootRoute","createRouteMask"],"mappings":"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"}
@@ -164,7 +164,7 @@ function isPlainObject(o) {
164
164
  function hasObjectPrototype(o) {
165
165
  return Object.prototype.toString.call(o) === '[object Object]';
166
166
  }
167
- function partialDeepEqual(a, b) {
167
+ function deepEqual(a, b, partial = false) {
168
168
  if (a === b) {
169
169
  return true;
170
170
  }
@@ -172,10 +172,15 @@ function partialDeepEqual(a, b) {
172
172
  return false;
173
173
  }
174
174
  if (isPlainObject(a) && isPlainObject(b)) {
175
- return !Object.keys(b).some(key => !partialDeepEqual(a[key], b[key]));
175
+ const aKeys = Object.keys(a);
176
+ const bKeys = Object.keys(b);
177
+ if (!partial && aKeys.length !== bKeys.length) {
178
+ return false;
179
+ }
180
+ return !bKeys.some(key => !(key in a) || !deepEqual(a[key], b[key], partial));
176
181
  }
177
182
  if (Array.isArray(a) && Array.isArray(b)) {
178
- return !(a.length !== b.length || a.some((item, index) => !partialDeepEqual(item, b[index])));
183
+ return !a.some((item, index) => !deepEqual(item, b[index], partial));
179
184
  }
180
185
  return false;
181
186
  }
@@ -211,11 +216,11 @@ function useRouteContext(opts) {
211
216
  }
212
217
  const useLayoutEffect = typeof window !== 'undefined' ? React__namespace.useLayoutEffect : React__namespace.useEffect;
213
218
 
219
+ exports.deepEqual = deepEqual;
214
220
  exports.functionalUpdate = functionalUpdate;
215
221
  exports.isPlainObject = isPlainObject;
216
222
  exports.isServer = isServer;
217
223
  exports.last = last;
218
- exports.partialDeepEqual = partialDeepEqual;
219
224
  exports.pick = pick;
220
225
  exports.replaceEqualDeep = replaceEqualDeep;
221
226
  exports.shallow = shallow;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\nimport { useMatch } from './Matches'\nimport { RouteMatch } from './RouterProvider'\nimport { AnyRoute } from './route'\nimport { ParseRoute, RouteIds, RoutesById, RouteById } from './routeInfo'\nimport { RegisteredRouter } from './router'\n\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\nexport type IsAny<T, Y, N = T> = 1 extends 0 & T ? Y : N\nexport type IsAnyBoolean<T> = 1 extends 0 & T ? true : false\nexport type IsKnown<T, Y, N> = unknown extends T ? N : Y\nexport type PickAsRequired<T, K extends keyof T> = Omit<T, K> &\n Required<Pick<T, K>>\nexport type PickAsPartial<T, K extends keyof T> = Omit<T, K> &\n Partial<Pick<T, K>>\nexport type PickUnsafe<T, K> = K extends keyof T ? Pick<T, K> : never\nexport type PickExtra<T, K> = {\n [TKey in keyof K as string extends TKey\n ? never\n : TKey extends keyof T\n ? never\n : TKey]: K[TKey]\n}\n\nexport type PickRequired<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K]\n}\n\n// export type Expand<T> = T\nexport type Expand<T> = T extends object\n ? T extends infer O\n ? { [K in keyof O]: O[K] }\n : never\n : T\n\nexport type UnionToIntersection<U> = (\n U extends any ? (k: U) => void : never\n) extends (k: infer I) => any\n ? I\n : never\n\n// type Compute<T> = { [K in keyof T]: T[K] } | never\n\n// type AllKeys<T> = T extends any ? keyof T : never\n\n// export type MergeUnion<T, Keys extends keyof T = keyof T> = Compute<\n// {\n// [K in Keys]: T[Keys]\n// } & {\n// [K in AllKeys<T>]?: T extends any\n// ? K extends keyof T\n// ? T[K]\n// : never\n// : never\n// }\n// >\n\nexport type Assign<Left, Right> = Omit<Left, keyof Right> & Right\n\nexport type AssignAll<T extends any[]> = T extends [infer Left, ...infer Right]\n ? Right extends any[]\n ? Assign<Left, AssignAll<Right>>\n : Left\n : {}\n\n// // Sample types to merge\n// type TypeA = {\n// shared: string\n// onlyInA: string\n// nested: {\n// shared: string\n// aProp: string\n// }\n// array: string[]\n// }\n\n// type TypeB = {\n// shared: number\n// onlyInB: number\n// nested: {\n// shared: number\n// bProp: number\n// }\n// array: number[]\n// }\n\n// type TypeC = {\n// shared: boolean\n// onlyInC: boolean\n// nested: {\n// shared: boolean\n// cProp: boolean\n// }\n// array: boolean[]\n// }\n\n// type Test = Expand<Assign<TypeA, TypeB>>\n\n// // Using DeepMerge to merge TypeA and TypeB\n// type MergedType = Expand<AssignAll<[TypeA, TypeB, TypeC]>>\n\nexport type Values<O> = O[ValueKeys<O>]\nexport type ValueKeys<O> = Extract<keyof O, PropertyKey>\n\nexport type DeepAwaited<T> = T extends Promise<infer A>\n ? DeepAwaited<A>\n : T extends Record<infer A, Promise<infer B>>\n ? { [K in A]: DeepAwaited<B> }\n : T\n\nexport type PathParamMask<TRoutePath extends string> =\n TRoutePath extends `${infer L}/$${infer C}/${infer R}`\n ? PathParamMask<`${L}/${string}/${R}`>\n : TRoutePath extends `${infer L}/$${infer C}`\n ? PathParamMask<`${L}/${string}`>\n : TRoutePath\n\nexport type Timeout = ReturnType<typeof setTimeout>\n\nexport type Updater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev?: TPrevious) => TResult)\n\nexport type NonNullableUpdater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev: TPrevious) => TResult)\n\nexport type PickExtract<T, U> = {\n [K in keyof T as T[K] extends U ? K : never]: T[K]\n}\n\nexport type PickExclude<T, U> = {\n [K in keyof T as T[K] extends U ? never : K]: T[K]\n}\n\n//\n\nexport const isServer = typeof document === 'undefined'\n\nexport function last<T>(arr: T[]) {\n return arr[arr.length - 1]\n}\n\nfunction isFunction(d: any): d is Function {\n return typeof d === 'function'\n}\n\nexport function functionalUpdate<TResult>(\n updater: Updater<TResult> | NonNullableUpdater<TResult>,\n previous: TResult,\n): TResult {\n if (isFunction(updater)) {\n return updater(previous as TResult)\n }\n\n return updater\n}\n\nexport function pick<T, K extends keyof T>(parent: T, keys: K[]): Pick<T, K> {\n return keys.reduce((obj: any, key: K) => {\n obj[key] = parent[key]\n return obj\n }, {} as any)\n}\n\n/**\n * This function returns `a` if `b` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between immutable JSON values for example.\n * Do not use this with signals\n */\nexport function replaceEqualDeep<T>(prev: any, _next: T): T {\n if (prev === _next) {\n return prev\n }\n\n const next = _next as any\n\n const array = Array.isArray(prev) && Array.isArray(next)\n\n if (array || (isPlainObject(prev) && isPlainObject(next))) {\n const prevSize = array ? prev.length : Object.keys(prev).length\n const nextItems = array ? next : Object.keys(next)\n const nextSize = nextItems.length\n const copy: any = array ? [] : {}\n\n let equalItems = 0\n\n for (let i = 0; i < nextSize; i++) {\n const key = array ? i : nextItems[i]\n copy[key] = replaceEqualDeep(prev[key], next[key])\n if (copy[key] === prev[key]) {\n equalItems++\n }\n }\n\n return prevSize === nextSize && equalItems === prevSize ? prev : copy\n }\n\n return next\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\nexport function isPlainObject(o: any) {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has modified constructor\n const ctor = o.constructor\n if (typeof ctor === 'undefined') {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\nfunction hasObjectPrototype(o: any) {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\nexport function partialDeepEqual(a: any, b: any): boolean {\n if (a === b) {\n return true\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n return !Object.keys(b).some((key) => !partialDeepEqual(a[key], b[key]))\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return !(\n a.length !== b.length ||\n a.some((item, index) => !partialDeepEqual(item, b[index]))\n )\n }\n\n return false\n}\n\nexport function useStableCallback<T extends (...args: any[]) => any>(fn: T): T {\n const fnRef = React.useRef(fn)\n fnRef.current = fn\n\n const ref = React.useRef((...args: any[]) => fnRef.current(...args))\n return ref.current as T\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n const keysA = Object.keys(objA)\n if (keysA.length !== Object.keys(objB).length) {\n return false\n }\n\n for (let i = 0; i < keysA.length; i++) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, keysA[i] as string) ||\n !Object.is(objA[keysA[i] as keyof T], objB[keysA[i] as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nexport type StrictOrFrom<TFrom> =\n | {\n from: TFrom\n strict?: true\n }\n | {\n from?: never\n strict: false\n }\n\nexport type RouteFromIdOrRoute<\n T,\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n> = T extends ParseRoute<TRouteTree>\n ? T\n : T extends RouteIds<TRouteTree>\n ? RoutesById<TRouteTree>[T]\n : T extends string\n ? RouteIds<TRouteTree>\n : never\n\nexport function useRouteContext<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,\n TStrict extends boolean = true,\n TRouteContext = RouteById<TRouteTree, TFrom>['types']['allContext'],\n TSelected = TRouteContext,\n>(\n opts: StrictOrFrom<TFrom> & {\n select?: (search: TRouteContext) => TSelected\n },\n): TStrict extends true ? TSelected : TSelected | undefined {\n return useMatch({\n ...(opts as any),\n select: (match: RouteMatch) =>\n opts?.select\n ? opts.select(match.context as TRouteContext)\n : match.context,\n })\n}\n\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n"],"names":["isServer","document","last","arr","length","isFunction","d","functionalUpdate","updater","previous","pick","parent","keys","reduce","obj","key","replaceEqualDeep","prev","_next","next","array","Array","isArray","isPlainObject","prevSize","Object","nextItems","nextSize","copy","equalItems","i","o","hasObjectPrototype","ctor","constructor","prot","prototype","hasOwnProperty","toString","call","partialDeepEqual","a","b","some","item","index","useStableCallback","fn","fnRef","React","useRef","current","ref","args","shallow","objA","objB","is","keysA","useRouteContext","opts","useMatch","select","match","context","useLayoutEffect","window","useEffect"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\nimport { useMatch } from './Matches'\nimport { RouteMatch } from './RouterProvider'\nimport { AnyRoute } from './route'\nimport { ParseRoute, RouteIds, RoutesById, RouteById } from './routeInfo'\nimport { RegisteredRouter } from './router'\n\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\nexport type IsAny<T, Y, N = T> = 1 extends 0 & T ? Y : N\nexport type IsAnyBoolean<T> = 1 extends 0 & T ? true : false\nexport type IsKnown<T, Y, N> = unknown extends T ? N : Y\nexport type PickAsRequired<T, K extends keyof T> = Omit<T, K> &\n Required<Pick<T, K>>\nexport type PickAsPartial<T, K extends keyof T> = Omit<T, K> &\n Partial<Pick<T, K>>\nexport type PickUnsafe<T, K> = K extends keyof T ? Pick<T, K> : never\nexport type PickExtra<T, K> = {\n [TKey in keyof K as string extends TKey\n ? never\n : TKey extends keyof T\n ? never\n : TKey]: K[TKey]\n}\n\nexport type PickRequired<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K]\n}\n\n// export type Expand<T> = T\nexport type Expand<T> = T extends object\n ? T extends infer O\n ? { [K in keyof O]: O[K] }\n : never\n : T\n\nexport type UnionToIntersection<U> = (\n U extends any ? (k: U) => void : never\n) extends (k: infer I) => any\n ? I\n : never\n\n// type Compute<T> = { [K in keyof T]: T[K] } | never\n\n// type AllKeys<T> = T extends any ? keyof T : never\n\n// export type MergeUnion<T, Keys extends keyof T = keyof T> = Compute<\n// {\n// [K in Keys]: T[Keys]\n// } & {\n// [K in AllKeys<T>]?: T extends any\n// ? K extends keyof T\n// ? T[K]\n// : never\n// : never\n// }\n// >\n\nexport type Assign<Left, Right> = Omit<Left, keyof Right> & Right\n\nexport type AssignAll<T extends any[]> = T extends [infer Left, ...infer Right]\n ? Right extends any[]\n ? Assign<Left, AssignAll<Right>>\n : Left\n : {}\n\n// // Sample types to merge\n// type TypeA = {\n// shared: string\n// onlyInA: string\n// nested: {\n// shared: string\n// aProp: string\n// }\n// array: string[]\n// }\n\n// type TypeB = {\n// shared: number\n// onlyInB: number\n// nested: {\n// shared: number\n// bProp: number\n// }\n// array: number[]\n// }\n\n// type TypeC = {\n// shared: boolean\n// onlyInC: boolean\n// nested: {\n// shared: boolean\n// cProp: boolean\n// }\n// array: boolean[]\n// }\n\n// type Test = Expand<Assign<TypeA, TypeB>>\n\n// // Using DeepMerge to merge TypeA and TypeB\n// type MergedType = Expand<AssignAll<[TypeA, TypeB, TypeC]>>\n\nexport type Values<O> = O[ValueKeys<O>]\nexport type ValueKeys<O> = Extract<keyof O, PropertyKey>\n\nexport type DeepAwaited<T> = T extends Promise<infer A>\n ? DeepAwaited<A>\n : T extends Record<infer A, Promise<infer B>>\n ? { [K in A]: DeepAwaited<B> }\n : T\n\nexport type PathParamMask<TRoutePath extends string> =\n TRoutePath extends `${infer L}/$${infer C}/${infer R}`\n ? PathParamMask<`${L}/${string}/${R}`>\n : TRoutePath extends `${infer L}/$${infer C}`\n ? PathParamMask<`${L}/${string}`>\n : TRoutePath\n\nexport type Timeout = ReturnType<typeof setTimeout>\n\nexport type Updater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev?: TPrevious) => TResult)\n\nexport type NonNullableUpdater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev: TPrevious) => TResult)\n\nexport type PickExtract<T, U> = {\n [K in keyof T as T[K] extends U ? K : never]: T[K]\n}\n\nexport type PickExclude<T, U> = {\n [K in keyof T as T[K] extends U ? never : K]: T[K]\n}\n\n//\n\nexport const isServer = typeof document === 'undefined'\n\nexport function last<T>(arr: T[]) {\n return arr[arr.length - 1]\n}\n\nfunction isFunction(d: any): d is Function {\n return typeof d === 'function'\n}\n\nexport function functionalUpdate<TResult>(\n updater: Updater<TResult> | NonNullableUpdater<TResult>,\n previous: TResult,\n): TResult {\n if (isFunction(updater)) {\n return updater(previous as TResult)\n }\n\n return updater\n}\n\nexport function pick<T, K extends keyof T>(parent: T, keys: K[]): Pick<T, K> {\n return keys.reduce((obj: any, key: K) => {\n obj[key] = parent[key]\n return obj\n }, {} as any)\n}\n\n/**\n * This function returns `a` if `b` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between immutable JSON values for example.\n * Do not use this with signals\n */\nexport function replaceEqualDeep<T>(prev: any, _next: T): T {\n if (prev === _next) {\n return prev\n }\n\n const next = _next as any\n\n const array = Array.isArray(prev) && Array.isArray(next)\n\n if (array || (isPlainObject(prev) && isPlainObject(next))) {\n const prevSize = array ? prev.length : Object.keys(prev).length\n const nextItems = array ? next : Object.keys(next)\n const nextSize = nextItems.length\n const copy: any = array ? [] : {}\n\n let equalItems = 0\n\n for (let i = 0; i < nextSize; i++) {\n const key = array ? i : nextItems[i]\n copy[key] = replaceEqualDeep(prev[key], next[key])\n if (copy[key] === prev[key]) {\n equalItems++\n }\n }\n\n return prevSize === nextSize && equalItems === prevSize ? prev : copy\n }\n\n return next\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\nexport function isPlainObject(o: any) {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has modified constructor\n const ctor = o.constructor\n if (typeof ctor === 'undefined') {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\nfunction hasObjectPrototype(o: any) {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\nexport function deepEqual(a: any, b: any, partial: boolean = false): boolean {\n if (a === b) {\n return true\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n\n if (!partial && aKeys.length !== bKeys.length) {\n return false\n }\n\n return !bKeys.some(\n (key) => !(key in a) || !deepEqual(a[key], b[key], partial),\n )\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n return !a.some((item, index) => !deepEqual(item, b[index], partial))\n }\n\n return false\n}\n\nexport function useStableCallback<T extends (...args: any[]) => any>(fn: T): T {\n const fnRef = React.useRef(fn)\n fnRef.current = fn\n\n const ref = React.useRef((...args: any[]) => fnRef.current(...args))\n return ref.current as T\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n const keysA = Object.keys(objA)\n if (keysA.length !== Object.keys(objB).length) {\n return false\n }\n\n for (let i = 0; i < keysA.length; i++) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, keysA[i] as string) ||\n !Object.is(objA[keysA[i] as keyof T], objB[keysA[i] as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nexport type StrictOrFrom<TFrom> =\n | {\n from: TFrom\n strict?: true\n }\n | {\n from?: never\n strict: false\n }\n\nexport type RouteFromIdOrRoute<\n T,\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n> = T extends ParseRoute<TRouteTree>\n ? T\n : T extends RouteIds<TRouteTree>\n ? RoutesById<TRouteTree>[T]\n : T extends string\n ? RouteIds<TRouteTree>\n : never\n\nexport function useRouteContext<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RouteIds<TRouteTree> = RouteIds<TRouteTree>,\n TStrict extends boolean = true,\n TRouteContext = RouteById<TRouteTree, TFrom>['types']['allContext'],\n TSelected = TRouteContext,\n>(\n opts: StrictOrFrom<TFrom> & {\n select?: (search: TRouteContext) => TSelected\n },\n): TStrict extends true ? TSelected : TSelected | undefined {\n return useMatch({\n ...(opts as any),\n select: (match: RouteMatch) =>\n opts?.select\n ? opts.select(match.context as TRouteContext)\n : match.context,\n })\n}\n\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n"],"names":["isServer","document","last","arr","length","isFunction","d","functionalUpdate","updater","previous","pick","parent","keys","reduce","obj","key","replaceEqualDeep","prev","_next","next","array","Array","isArray","isPlainObject","prevSize","Object","nextItems","nextSize","copy","equalItems","i","o","hasObjectPrototype","ctor","constructor","prot","prototype","hasOwnProperty","toString","call","deepEqual","a","b","partial","aKeys","bKeys","some","item","index","useStableCallback","fn","fnRef","React","useRef","current","ref","args","shallow","objA","objB","is","keysA","useRouteContext","opts","useMatch","select","match","context","useLayoutEffect","window","useEffect"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA;;AAaA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AAoCA;;MAEaA,QAAQ,GAAG,OAAOC,QAAQ,KAAK,YAAW;AAEhD,SAASC,IAAIA,CAAIC,GAAQ,EAAE;AAChC,EAAA,OAAOA,GAAG,CAACA,GAAG,CAACC,MAAM,GAAG,CAAC,CAAC,CAAA;AAC5B,CAAA;AAEA,SAASC,UAAUA,CAACC,CAAM,EAAiB;EACzC,OAAO,OAAOA,CAAC,KAAK,UAAU,CAAA;AAChC,CAAA;AAEO,SAASC,gBAAgBA,CAC9BC,OAAuD,EACvDC,QAAiB,EACR;AACT,EAAA,IAAIJ,UAAU,CAACG,OAAO,CAAC,EAAE;IACvB,OAAOA,OAAO,CAACC,QAAmB,CAAC,CAAA;AACrC,GAAA;AAEA,EAAA,OAAOD,OAAO,CAAA;AAChB,CAAA;AAEO,SAASE,IAAIA,CAAuBC,MAAS,EAAEC,IAAS,EAAc;EAC3E,OAAOA,IAAI,CAACC,MAAM,CAAC,CAACC,GAAQ,EAAEC,GAAM,KAAK;AACvCD,IAAAA,GAAG,CAACC,GAAG,CAAC,GAAGJ,MAAM,CAACI,GAAG,CAAC,CAAA;AACtB,IAAA,OAAOD,GAAG,CAAA;GACX,EAAE,EAAS,CAAC,CAAA;AACf,CAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACO,SAASE,gBAAgBA,CAAIC,IAAS,EAAEC,KAAQ,EAAK;EAC1D,IAAID,IAAI,KAAKC,KAAK,EAAE;AAClB,IAAA,OAAOD,IAAI,CAAA;AACb,GAAA;EAEA,MAAME,IAAI,GAAGD,KAAY,CAAA;AAEzB,EAAA,MAAME,KAAK,GAAGC,KAAK,CAACC,OAAO,CAACL,IAAI,CAAC,IAAII,KAAK,CAACC,OAAO,CAACH,IAAI,CAAC,CAAA;EAExD,IAAIC,KAAK,IAAKG,aAAa,CAACN,IAAI,CAAC,IAAIM,aAAa,CAACJ,IAAI,CAAE,EAAE;AACzD,IAAA,MAAMK,QAAQ,GAAGJ,KAAK,GAAGH,IAAI,CAACb,MAAM,GAAGqB,MAAM,CAACb,IAAI,CAACK,IAAI,CAAC,CAACb,MAAM,CAAA;IAC/D,MAAMsB,SAAS,GAAGN,KAAK,GAAGD,IAAI,GAAGM,MAAM,CAACb,IAAI,CAACO,IAAI,CAAC,CAAA;AAClD,IAAA,MAAMQ,QAAQ,GAAGD,SAAS,CAACtB,MAAM,CAAA;AACjC,IAAA,MAAMwB,IAAS,GAAGR,KAAK,GAAG,EAAE,GAAG,EAAE,CAAA;IAEjC,IAAIS,UAAU,GAAG,CAAC,CAAA;IAElB,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGH,QAAQ,EAAEG,CAAC,EAAE,EAAE;MACjC,MAAMf,GAAG,GAAGK,KAAK,GAAGU,CAAC,GAAGJ,SAAS,CAACI,CAAC,CAAC,CAAA;AACpCF,MAAAA,IAAI,CAACb,GAAG,CAAC,GAAGC,gBAAgB,CAACC,IAAI,CAACF,GAAG,CAAC,EAAEI,IAAI,CAACJ,GAAG,CAAC,CAAC,CAAA;MAClD,IAAIa,IAAI,CAACb,GAAG,CAAC,KAAKE,IAAI,CAACF,GAAG,CAAC,EAAE;AAC3Bc,QAAAA,UAAU,EAAE,CAAA;AACd,OAAA;AACF,KAAA;IAEA,OAAOL,QAAQ,KAAKG,QAAQ,IAAIE,UAAU,KAAKL,QAAQ,GAAGP,IAAI,GAAGW,IAAI,CAAA;AACvE,GAAA;AAEA,EAAA,OAAOT,IAAI,CAAA;AACb,CAAA;;AAEA;AACO,SAASI,aAAaA,CAACQ,CAAM,EAAE;AACpC,EAAA,IAAI,CAACC,kBAAkB,CAACD,CAAC,CAAC,EAAE;AAC1B,IAAA,OAAO,KAAK,CAAA;AACd,GAAA;;AAEA;AACA,EAAA,MAAME,IAAI,GAAGF,CAAC,CAACG,WAAW,CAAA;AAC1B,EAAA,IAAI,OAAOD,IAAI,KAAK,WAAW,EAAE;AAC/B,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;;AAEA;AACA,EAAA,MAAME,IAAI,GAAGF,IAAI,CAACG,SAAS,CAAA;AAC3B,EAAA,IAAI,CAACJ,kBAAkB,CAACG,IAAI,CAAC,EAAE;AAC7B,IAAA,OAAO,KAAK,CAAA;AACd,GAAA;;AAEA;AACA,EAAA,IAAI,CAACA,IAAI,CAACE,cAAc,CAAC,eAAe,CAAC,EAAE;AACzC,IAAA,OAAO,KAAK,CAAA;AACd,GAAA;;AAEA;AACA,EAAA,OAAO,IAAI,CAAA;AACb,CAAA;AAEA,SAASL,kBAAkBA,CAACD,CAAM,EAAE;EAClC,OAAON,MAAM,CAACW,SAAS,CAACE,QAAQ,CAACC,IAAI,CAACR,CAAC,CAAC,KAAK,iBAAiB,CAAA;AAChE,CAAA;AAEO,SAASS,SAASA,CAACC,CAAM,EAAEC,CAAM,EAAEC,OAAgB,GAAG,KAAK,EAAW;EAC3E,IAAIF,CAAC,KAAKC,CAAC,EAAE;AACX,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;AAEA,EAAA,IAAI,OAAOD,CAAC,KAAK,OAAOC,CAAC,EAAE;AACzB,IAAA,OAAO,KAAK,CAAA;AACd,GAAA;EAEA,IAAInB,aAAa,CAACkB,CAAC,CAAC,IAAIlB,aAAa,CAACmB,CAAC,CAAC,EAAE;AACxC,IAAA,MAAME,KAAK,GAAGnB,MAAM,CAACb,IAAI,CAAC6B,CAAC,CAAC,CAAA;AAC5B,IAAA,MAAMI,KAAK,GAAGpB,MAAM,CAACb,IAAI,CAAC8B,CAAC,CAAC,CAAA;IAE5B,IAAI,CAACC,OAAO,IAAIC,KAAK,CAACxC,MAAM,KAAKyC,KAAK,CAACzC,MAAM,EAAE;AAC7C,MAAA,OAAO,KAAK,CAAA;AACd,KAAA;AAEA,IAAA,OAAO,CAACyC,KAAK,CAACC,IAAI,CACf/B,GAAG,IAAK,EAAEA,GAAG,IAAI0B,CAAC,CAAC,IAAI,CAACD,SAAS,CAACC,CAAC,CAAC1B,GAAG,CAAC,EAAE2B,CAAC,CAAC3B,GAAG,CAAC,EAAE4B,OAAO,CAC5D,CAAC,CAAA;AACH,GAAA;AAEA,EAAA,IAAItB,KAAK,CAACC,OAAO,CAACmB,CAAC,CAAC,IAAIpB,KAAK,CAACC,OAAO,CAACoB,CAAC,CAAC,EAAE;IACxC,OAAO,CAACD,CAAC,CAACK,IAAI,CAAC,CAACC,IAAI,EAAEC,KAAK,KAAK,CAACR,SAAS,CAACO,IAAI,EAAEL,CAAC,CAACM,KAAK,CAAC,EAAEL,OAAO,CAAC,CAAC,CAAA;AACtE,GAAA;AAEA,EAAA,OAAO,KAAK,CAAA;AACd,CAAA;AAEO,SAASM,iBAAiBA,CAAoCC,EAAK,EAAK;AAC7E,EAAA,MAAMC,KAAK,GAAGC,gBAAK,CAACC,MAAM,CAACH,EAAE,CAAC,CAAA;EAC9BC,KAAK,CAACG,OAAO,GAAGJ,EAAE,CAAA;AAElB,EAAA,MAAMK,GAAG,GAAGH,gBAAK,CAACC,MAAM,CAAC,CAAC,GAAGG,IAAW,KAAKL,KAAK,CAACG,OAAO,CAAC,GAAGE,IAAI,CAAC,CAAC,CAAA;EACpE,OAAOD,GAAG,CAACD,OAAO,CAAA;AACpB,CAAA;AAEO,SAASG,OAAOA,CAAIC,IAAO,EAAEC,IAAO,EAAE;EAC3C,IAAIlC,MAAM,CAACmC,EAAE,CAACF,IAAI,EAAEC,IAAI,CAAC,EAAE;AACzB,IAAA,OAAO,IAAI,CAAA;AACb,GAAA;AAEA,EAAA,IACE,OAAOD,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,IACb,OAAOC,IAAI,KAAK,QAAQ,IACxBA,IAAI,KAAK,IAAI,EACb;AACA,IAAA,OAAO,KAAK,CAAA;AACd,GAAA;AAEA,EAAA,MAAME,KAAK,GAAGpC,MAAM,CAACb,IAAI,CAAC8C,IAAI,CAAC,CAAA;AAC/B,EAAA,IAAIG,KAAK,CAACzD,MAAM,KAAKqB,MAAM,CAACb,IAAI,CAAC+C,IAAI,CAAC,CAACvD,MAAM,EAAE;AAC7C,IAAA,OAAO,KAAK,CAAA;AACd,GAAA;AAEA,EAAA,KAAK,IAAI0B,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAG+B,KAAK,CAACzD,MAAM,EAAE0B,CAAC,EAAE,EAAE;AACrC,IAAA,IACE,CAACL,MAAM,CAACW,SAAS,CAACC,cAAc,CAACE,IAAI,CAACoB,IAAI,EAAEE,KAAK,CAAC/B,CAAC,CAAW,CAAC,IAC/D,CAACL,MAAM,CAACmC,EAAE,CAACF,IAAI,CAACG,KAAK,CAAC/B,CAAC,CAAC,CAAY,EAAE6B,IAAI,CAACE,KAAK,CAAC/B,CAAC,CAAC,CAAY,CAAC,EAChE;AACA,MAAA,OAAO,KAAK,CAAA;AACd,KAAA;AACF,GAAA;AACA,EAAA,OAAO,IAAI,CAAA;AACb,CAAA;AAuBO,SAASgC,eAAeA,CAO7BC,IAEC,EACyD;AAC1D,EAAA,OAAOC,gBAAQ,CAAC;AACd,IAAA,GAAID,IAAY;AAChBE,IAAAA,MAAM,EAAGC,KAAiB,IACxBH,IAAI,EAAEE,MAAM,GACRF,IAAI,CAACE,MAAM,CAACC,KAAK,CAACC,OAAwB,CAAC,GAC3CD,KAAK,CAACC,OAAAA;AACd,GAAC,CAAC,CAAA;AACJ,CAAA;AAEaC,MAAAA,eAAe,GAC1B,OAAOC,MAAM,KAAK,WAAW,GAAGjB,gBAAK,CAACgB,eAAe,GAAGhB,gBAAK,CAACkB;;;;;;;;;;;;;;"}
@@ -231,7 +231,7 @@ function isPlainObject(o) {
231
231
  function hasObjectPrototype(o) {
232
232
  return Object.prototype.toString.call(o) === '[object Object]';
233
233
  }
234
- function partialDeepEqual(a, b) {
234
+ function deepEqual(a, b, partial = false) {
235
235
  if (a === b) {
236
236
  return true;
237
237
  }
@@ -239,10 +239,15 @@ function partialDeepEqual(a, b) {
239
239
  return false;
240
240
  }
241
241
  if (isPlainObject(a) && isPlainObject(b)) {
242
- return !Object.keys(b).some(key => !partialDeepEqual(a[key], b[key]));
242
+ const aKeys = Object.keys(a);
243
+ const bKeys = Object.keys(b);
244
+ if (!partial && aKeys.length !== bKeys.length) {
245
+ return false;
246
+ }
247
+ return !bKeys.some(key => !(key in a) || !deepEqual(a[key], b[key], partial));
243
248
  }
244
249
  if (Array.isArray(a) && Array.isArray(b)) {
245
- return !(a.length !== b.length || a.some((item, index) => !partialDeepEqual(item, b[index])));
250
+ return !a.some((item, index) => !deepEqual(item, b[index], partial));
246
251
  }
247
252
  return false;
248
253
  }
@@ -1029,6 +1034,7 @@ function RouterProvider({
1029
1034
  loadPromise: Promise.resolve(),
1030
1035
  context: undefined,
1031
1036
  abortController: new AbortController(),
1037
+ shouldReloadDeps: undefined,
1032
1038
  fetchedAt: 0
1033
1039
  };
1034
1040
  return routeMatch;
@@ -1360,17 +1366,8 @@ function RouterProvider({
1360
1366
  if (match.isFetching) {
1361
1367
  loadPromise = getRouteMatch(state, match.id)?.loadPromise;
1362
1368
  } else {
1363
- matches[index] = match = {
1364
- ...match,
1365
- isFetching: true
1366
- };
1367
- const componentsPromise = Promise.all(componentTypes.map(async type => {
1368
- const component = route.options[type];
1369
- if (component?.preload) {
1370
- await component.preload();
1371
- }
1372
- }));
1373
- const loaderPromise = route.options.loader?.({
1369
+ const cause = state.matches.find(d => d.id === match.id) ? 'stay' : 'enter';
1370
+ const loaderContext = {
1374
1371
  params: match.params,
1375
1372
  search: match.search,
1376
1373
  preload: !!preload,
@@ -1381,9 +1378,42 @@ function RouterProvider({
1381
1378
  navigate: opts => navigate({
1382
1379
  ...opts,
1383
1380
  from: match.pathname
1384
- })
1385
- });
1386
- loadPromise = Promise.all([componentsPromise, loaderPromise]).then(d => d[1]);
1381
+ }),
1382
+ cause
1383
+ };
1384
+
1385
+ // Default to reloading the route all the time
1386
+ let shouldReload = true;
1387
+ let shouldReloadDeps = typeof route.options.shouldReload === 'function' ? route.options.shouldReload?.(loaderContext) : !!route.options.shouldReload;
1388
+ if (typeof shouldReloadDeps === 'object') {
1389
+ // compare the deps to see if they've changed
1390
+ shouldReload = !deepEqual(shouldReloadDeps, match.shouldReloadDeps);
1391
+ console.log(shouldReloadDeps, match.shouldReloadDeps, shouldReload);
1392
+ match.shouldReloadDeps = shouldReloadDeps;
1393
+ } else {
1394
+ shouldReload = !!shouldReloadDeps;
1395
+ }
1396
+
1397
+ // If the user doesn't want the route to reload, just
1398
+ // resolve with the existing loader data
1399
+
1400
+ if (!shouldReload) {
1401
+ loadPromise = Promise.resolve(match.loaderData);
1402
+ } else {
1403
+ // Otherwise, load the route
1404
+ matches[index] = match = {
1405
+ ...match,
1406
+ isFetching: true
1407
+ };
1408
+ const componentsPromise = Promise.all(componentTypes.map(async type => {
1409
+ const component = route.options[type];
1410
+ if (component?.preload) {
1411
+ await component.preload();
1412
+ }
1413
+ }));
1414
+ const loaderPromise = route.options.loader?.(loaderContext);
1415
+ loadPromise = Promise.all([componentsPromise, loaderPromise]).then(d => d[1]);
1416
+ }
1387
1417
  }
1388
1418
  matches[index] = match = {
1389
1419
  ...match,
@@ -1565,7 +1595,7 @@ function RouterProvider({
1565
1595
  // Combine the matches based on user options
1566
1596
  const pathTest = activeOptions?.exact ? latestLocationRef.current.pathname === next.pathname : pathIsFuzzyEqual;
1567
1597
  const hashTest = activeOptions?.includeHash ? latestLocationRef.current.hash === next.hash : true;
1568
- const searchTest = activeOptions?.includeSearch ?? true ? partialDeepEqual(latestLocationRef.current.search, next.search) : true;
1598
+ const searchTest = activeOptions?.includeSearch ?? true ? deepEqual(latestLocationRef.current.search, next.search, true) : true;
1569
1599
 
1570
1600
  // The final "active" test
1571
1601
  const isActive = pathTest && hashTest && searchTest;
@@ -1696,7 +1726,7 @@ function RouterProvider({
1696
1726
  return false;
1697
1727
  }
1698
1728
  if (match && (opts?.includeSearch ?? true)) {
1699
- return partialDeepEqual(baseLocation.search, next.search) ? match : false;
1729
+ return deepEqual(baseLocation.search, next.search, true) ? match : false;
1700
1730
  }
1701
1731
  return match;
1702
1732
  });
@@ -2397,5 +2427,5 @@ function Navigate(props) {
2397
2427
  return null;
2398
2428
  }
2399
2429
 
2400
- export { Block, CatchBoundary, CatchBoundaryImpl, ErrorComponent, FileRoute, Link, Match, MatchRoute, Matches, Navigate, Outlet, PathParamError, RootRoute, Route, Router, RouterProvider, ScrollRestoration, SearchParamError, cleanPath, componentTypes, createRouteMask, decode, defaultParseSearch, defaultStringifySearch, encode, functionalUpdate, getInitialRouterState, getRouteMatch, interpolatePath, isPlainObject, isRedirect, isServer, joinPaths, last, lazyFn, lazyRouteComponent, matchByPath, matchPathname, matchesContext, parsePathname, parseSearchWith, partialDeepEqual, pick, redirect, replaceEqualDeep, resolvePath, rootRouteId, rootRouteWithContext, routerContext, shallow, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, typedNavigate, useBlocker, useLayoutEffect$1 as useLayoutEffect, useLinkProps, useLoaderData, useMatch, useMatchRoute, useMatches, useNavigate, useParams, useRouteContext, useRouter, useRouterState, useScrollRestoration, useSearch, useStableCallback };
2430
+ export { Block, CatchBoundary, CatchBoundaryImpl, ErrorComponent, FileRoute, Link, Match, MatchRoute, Matches, Navigate, Outlet, PathParamError, RootRoute, Route, Router, RouterProvider, ScrollRestoration, SearchParamError, cleanPath, componentTypes, createRouteMask, decode, deepEqual, defaultParseSearch, defaultStringifySearch, encode, functionalUpdate, getInitialRouterState, getRouteMatch, interpolatePath, isPlainObject, isRedirect, isServer, joinPaths, last, lazyFn, lazyRouteComponent, matchByPath, matchPathname, matchesContext, parsePathname, parseSearchWith, pick, redirect, replaceEqualDeep, resolvePath, rootRouteId, rootRouteWithContext, routerContext, shallow, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, typedNavigate, useBlocker, useLayoutEffect$1 as useLayoutEffect, useLinkProps, useLoaderData, useMatch, useMatchRoute, useMatches, useNavigate, useParams, useRouteContext, useRouter, useRouterState, useScrollRestoration, useSearch, useStableCallback };
2401
2431
  //# sourceMappingURL=index.js.map