Skip to content

Commit

Permalink
perf(react-router): constant editor performance regardless how large …
Browse files Browse the repository at this point in the history
…a file based route tree is (#2243)
  • Loading branch information
chorobin committed Sep 5, 2024
1 parent 3ecffa3 commit 0482da5
Show file tree
Hide file tree
Showing 85 changed files with 5,345 additions and 373 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ coverage
*.tgz
.wrangler

# tests
packages/router-generator/tests/**/*.gen.ts

# misc
.DS_Store
.env
Expand Down
123 changes: 111 additions & 12 deletions examples/react/large-file-based/src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,117 @@ declare module '@tanstack/react-router' {

// Create and export the route tree

export const routeTree = rootRoute.addChildren({
IndexRoute,
ParamsRouteRoute: ParamsRouteRoute.addChildren({
ParamsParamsPlaceholderRoute,
}),
SearchRouteRoute: SearchRouteRoute.addChildren({
SearchSearchPlaceholderRoute,
}),
AbsoluteRoute,
LinkPropsRoute,
RelativeRoute,
})
interface ParamsRouteRouteChildren {
ParamsParamsPlaceholderRoute: typeof ParamsParamsPlaceholderRoute
}

const ParamsRouteRouteChildren: ParamsRouteRouteChildren = {
ParamsParamsPlaceholderRoute: ParamsParamsPlaceholderRoute,
}

const ParamsRouteRouteWithChildren = ParamsRouteRoute._addFileChildren(
ParamsRouteRouteChildren,
)

interface SearchRouteRouteChildren {
SearchSearchPlaceholderRoute: typeof SearchSearchPlaceholderRoute
}

const SearchRouteRouteChildren: SearchRouteRouteChildren = {
SearchSearchPlaceholderRoute: SearchSearchPlaceholderRoute,
}

const SearchRouteRouteWithChildren = SearchRouteRoute._addFileChildren(
SearchRouteRouteChildren,
)

interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/params': typeof ParamsRouteRouteWithChildren
'/search': typeof SearchRouteRouteWithChildren
'/absolute': typeof AbsoluteRoute
'/linkProps': typeof LinkPropsRoute
'/relative': typeof RelativeRoute
'/params/$paramsPlaceholder': typeof ParamsParamsPlaceholderRoute
'/search/searchPlaceholder': typeof SearchSearchPlaceholderRoute
}

interface FileRoutesByTo {
'/': typeof IndexRoute
'/params': typeof ParamsRouteRouteWithChildren
'/search': typeof SearchRouteRouteWithChildren
'/absolute': typeof AbsoluteRoute
'/linkProps': typeof LinkPropsRoute
'/relative': typeof RelativeRoute
'/params/$paramsPlaceholder': typeof ParamsParamsPlaceholderRoute
'/search/searchPlaceholder': typeof SearchSearchPlaceholderRoute
}

interface FileRoutesById {
'/': typeof IndexRoute
'/params': typeof ParamsRouteRouteWithChildren
'/search': typeof SearchRouteRouteWithChildren
'/absolute': typeof AbsoluteRoute
'/linkProps': typeof LinkPropsRoute
'/relative': typeof RelativeRoute
'/params/$paramsPlaceholder': typeof ParamsParamsPlaceholderRoute
'/search/searchPlaceholder': typeof SearchSearchPlaceholderRoute
}

interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths:
| '/'
| '/params'
| '/search'
| '/absolute'
| '/linkProps'
| '/relative'
| '/params/$paramsPlaceholder'
| '/search/searchPlaceholder'
fileRoutesByTo: FileRoutesByTo
to:
| '/'
| '/params'
| '/search'
| '/absolute'
| '/linkProps'
| '/relative'
| '/params/$paramsPlaceholder'
| '/search/searchPlaceholder'
id:
| '/'
| '/params'
| '/search'
| '/absolute'
| '/linkProps'
| '/relative'
| '/params/$paramsPlaceholder'
| '/search/searchPlaceholder'
fileRoutesById: FileRoutesById
}

interface RootRouteChildren {
IndexRoute: typeof IndexRoute
ParamsRouteRoute: typeof ParamsRouteRouteWithChildren
SearchRouteRoute: typeof SearchRouteRouteWithChildren
AbsoluteRoute: typeof AbsoluteRoute
LinkPropsRoute: typeof LinkPropsRoute
RelativeRoute: typeof RelativeRoute
}

const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
ParamsRouteRoute: ParamsRouteRouteWithChildren,
SearchRouteRoute: SearchRouteRouteWithChildren,
AbsoluteRoute: AbsoluteRoute,
LinkPropsRoute: LinkPropsRoute,
RelativeRoute: RelativeRoute,
}

export const routeTree = rootRoute
._addFileChildren(rootRouteChildren)
._addFileTypes<FileRouteTypes>()

/* prettier-ignore-end */

Expand Down
37 changes: 15 additions & 22 deletions packages/react-router/src/Matches.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,31 +169,24 @@ export interface RouteMatch<

export type MakeRouteMatch<
TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],
TRouteId = ParseRoute<TRouteTree>['id'],
TRouteId = RouteIds<TRouteTree>,
TStrict extends boolean = true,
TTypes extends AnyRoute['types'] = RouteById<TRouteTree, TRouteId>['types'],
TFullPath = TTypes['fullPath'],
TAllParams = TStrict extends false
> = RouteMatch<
TRouteId,
RouteById<TRouteTree, TRouteId>['types']['fullPath'],
TStrict extends false
? AllParams<TRouteTree>
: TTypes['allParams'],
TFullSearchSchema = TStrict extends false
: RouteById<TRouteTree, TRouteId>['types']['allParams'],
TStrict extends false
? FullSearchSchema<TRouteTree>
: TTypes['fullSearchSchema'],
TLoaderData = TStrict extends false
: RouteById<TRouteTree, TRouteId>['types']['fullSearchSchema'],
TStrict extends false
? AllLoaderData<TRouteTree>
: TTypes['loaderData'],
TAllContext = TStrict extends false
: RouteById<TRouteTree, TRouteId>['types']['loaderData'],
TStrict extends false
? AllContext<TRouteTree>
: TTypes['allContext'],
TLoaderDeps = TTypes['loaderDeps'],
> = RouteMatch<
TRouteId,
TFullPath,
TAllParams,
TFullSearchSchema,
TLoaderData,
TAllContext,
TLoaderDeps
: RouteById<TRouteTree, TRouteId>['types']['allContext'],
RouteById<TRouteTree, TRouteId>['types']['loaderDeps']
>

export type AnyRouteMatch = RouteMatch<any, any, any, any, any, any, any>
Expand Down Expand Up @@ -264,11 +257,11 @@ export interface MatchRouteOptions {

export type UseMatchRouteOptions<
TRouter extends AnyRouter = RegisteredRouter,
TFrom extends RoutePaths<TRouter['routeTree']> = RoutePaths<
TFrom extends RoutePaths<TRouter['routeTree']> | string = RoutePaths<
TRouter['routeTree']
>,
TTo extends string = '',
TMaskFrom extends RoutePaths<TRouter['routeTree']> = TFrom,
TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,
TMaskTo extends string = '',
TOptions extends ToOptions<
TRouter,
Expand Down
8 changes: 4 additions & 4 deletions packages/react-router/src/RouterProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ export interface MatchLocation {
}

export type NavigateFn = <
TTo extends string,
TRouter extends AnyRouter = RegisteredRouter,
TRouter extends RegisteredRouter,
TTo extends string | undefined,
TFrom extends RoutePaths<TRouter['routeTree']> | string = string,
TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,
TMaskTo extends string = '',
Expand All @@ -42,8 +42,8 @@ export type NavigateFn = <
) => Promise<void>

export type BuildLocationFn = <
TTo extends string,
TRouter extends AnyRouter = RegisteredRouter,
TRouter extends RegisteredRouter,
TTo extends string | undefined,
TFrom extends RoutePaths<TRouter['routeTree']> | string = string,
TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,
TMaskTo extends string = '',
Expand Down
26 changes: 25 additions & 1 deletion packages/react-router/src/fileRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import type {
AnySearchValidator,
FileBaseRouteOptions,
ResolveParams,
RootRoute,
Route,
RouteConstraints,
RouteLoaderFn,
UpdatableRouteOptions,
} from './route'
import type { MakeRouteMatch } from './Matches'
import type { RegisteredRouter } from './router'
import type { AnyRouter, RegisteredRouter } from './router'
import type { RouteById, RouteIds } from './routeInfo'

export interface FileRoutesByPath {
Expand All @@ -29,6 +30,29 @@ export interface FileRoutesByPath {
// }
}

export interface FileRouteTypes {
fileRoutesByFullPath: any
fullPaths: any
to: any
fileRoutesByTo: any
id: any
fileRoutesById: any
}

export type InferFileRouteTypes<TRouteTree extends AnyRoute> =
TRouteTree extends RootRoute<
any,
any,
any,
any,
any,
any,
any,
infer TFileRouteTypes extends FileRouteTypes
>
? TFileRouteTypes
: never

export function createFileRoute<
TFilePath extends keyof FileRoutesByPath,
TParentRoute extends AnyRoute = FileRoutesByPath[TFilePath]['parentRoute'],
Expand Down
11 changes: 10 additions & 1 deletion packages/react-router/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ export {
createLazyRoute,
createLazyFileRoute,
} from './fileRoute'
export type { FileRoutesByPath, LazyRouteOptions } from './fileRoute'
export type {
FileRoutesByPath,
FileRouteTypes,
LazyRouteOptions,
} from './fileRoute'

export * from './history'

Expand Down Expand Up @@ -88,6 +92,8 @@ export type {
MatchRouteOptions,
UseMatchRouteOptions,
MakeMatchRouteOptions,
MakeRouteMatch,
MakeRouteMatchUnion,
} from './Matches'

export { matchContext } from './matchContext'
Expand Down Expand Up @@ -230,6 +236,9 @@ export type {
RoutePaths,
FullSearchSchema,
AllParams,
AllLoaderData,
FullSearchSchemaInput,
AllContext,
} from './routeInfo'

export {
Expand Down
Loading

0 comments on commit 0482da5

Please sign in to comment.