From b1a1f1712f9bb184f0cd7de308fbce7e71aefedb Mon Sep 17 00:00:00 2001 From: Marc MacLeod Date: Fri, 13 Sep 2024 13:40:29 -0500 Subject: [PATCH] chore: upgrade tanstack-router to latest Signed-off-by: Marc MacLeod --- examples/bun-react-router/package.json | 8 +- .../react-router-kitchen-sink/package.json | 24 +- examples/react-router-records/package.json | 14 +- examples/react-router-simple/package.json | 12 +- examples/remix-vite/package.json | 24 +- examples/solid-router-simple/package.json | 10 +- examples/tanstack-router-simple/package.json | 22 +- .../src/entry.client.tsx | 12 +- .../src/entry.server.tsx | 141 +- .../src/routeTree.gen.ts | 238 +- .../src/routes/__root.tsx | 47 +- .../src/routes/admin.index.tsx | 5 + .../src/routes/admin.members.index.lazy.tsx | 9 - .../src/routes/admin.members.index.tsx | 9 + .../src/routes/{admin.lazy.tsx => admin.tsx} | 4 +- .../src/routes/index.tsx | 11 +- .../tanstack-router-simple/vite.config.ts | 2 +- package.json | 6 +- packages/plugin-tanstack-query/package.json | 2 +- packages/plugin-tanstack-router/package.json | 4 +- packages/plugin-trpc-react/package.json | 6 +- packages/plugin-unhead/package.json | 2 +- packages/react/package.json | 2 +- packages/remix/package.json | 2 +- packages/renderer/package.json | 4 +- packages/trpc-react-query/package.json | 6 +- packages/vite/package.json | 10 +- yarn.lock | 4630 +++++++++++++++-- 28 files changed, 4552 insertions(+), 714 deletions(-) delete mode 100644 examples/tanstack-router-simple/src/routes/admin.members.index.lazy.tsx create mode 100644 examples/tanstack-router-simple/src/routes/admin.members.index.tsx rename examples/tanstack-router-simple/src/routes/{admin.lazy.tsx => admin.tsx} (77%) diff --git a/examples/bun-react-router/package.json b/examples/bun-react-router/package.json index 409f998..c0d333b 100644 --- a/examples/bun-react-router/package.json +++ b/examples/bun-react-router/package.json @@ -24,9 +24,9 @@ "@ssrx/vite": "latest", "@types/react": "18.2.51", "@types/react-dom": "18.2.18", - "@vitejs/plugin-react": "4.2.1", - "typescript": "5.3.3", - "vite": "5.0.12", - "vite-tsconfig-paths": "4.3.1" + "@vitejs/plugin-react": "4.3.1", + "typescript": "5.6.2", + "vite": "5.4.4", + "vite-tsconfig-paths": "4.3.2" } } diff --git a/examples/react-router-kitchen-sink/package.json b/examples/react-router-kitchen-sink/package.json index dcb85cf..9f12467 100644 --- a/examples/react-router-kitchen-sink/package.json +++ b/examples/react-router-kitchen-sink/package.json @@ -20,7 +20,7 @@ "debug": "tsx debug.ts" }, "dependencies": { - "@hono/node-server": "^1.7.0", + "@hono/node-server": "^1.12.2", "@lucia-auth/adapter-sqlite": "2.0.1", "@paralleldrive/cuid2": "2.2.2", "@radix-ui/react-slot": "^1.0.2", @@ -31,21 +31,21 @@ "@ssrx/plugin-trpc-react": "latest", "@ssrx/plugin-unhead": "latest", "@ssrx/react": "latest", - "@tanstack/react-query": "^5.18.1", - "@tanstack/react-query-devtools": "^5.18.1", - "@trpc/client": "10.45.0", - "@trpc/server": "10.45.0", + "@tanstack/react-query": "^5.56.2", + "@tanstack/react-query-devtools": "^5.56.2", + "@trpc/client": "10.45.2", + "@trpc/server": "10.45.2", "better-sqlite3": "9.3.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "drizzle-orm": "0.29.3", "drizzle-valibot": "0.1.1", - "hono": "3.12.10", + "hono": "3.12.12", "lucia": "2.7.7", "lucide-react": "^0.321.0", "react": "18.2.0", "react-dom": "18.2.0", - "react-error-boundary": "4.0.12", + "react-error-boundary": "4.0.13", "react-router-dom": "6.22.0", "react-router-typesafe-routes": "1.2.1", "tailwind-merge": "^1.14.0", @@ -57,15 +57,15 @@ "@types/better-sqlite3": "7.6.9", "@types/react": "18.2.51", "@types/react-dom": "18.2.18", - "@vitejs/plugin-react": "4.2.1", + "@vitejs/plugin-react": "4.3.1", "autoprefixer": "10.4.17", "drizzle-kit": "0.20.14", - "postcss": "8.4.33", + "postcss": "8.4.45", "rollup-plugin-analyzer": "4.0.0", "tailwindcss": "3.3.5", "tsx": "4.7.0", - "typescript": "5.3.3", - "vite": "5.0.12", - "vite-tsconfig-paths": "4.3.1" + "typescript": "5.6.2", + "vite": "5.4.4", + "vite-tsconfig-paths": "4.3.2" } } diff --git a/examples/react-router-records/package.json b/examples/react-router-records/package.json index 4ec6e56..f5b56cf 100644 --- a/examples/react-router-records/package.json +++ b/examples/react-router-records/package.json @@ -11,10 +11,10 @@ "typecheck": "tsc" }, "dependencies": { - "@hono/node-server": "^1.7.0", + "@hono/node-server": "^1.12.2", "@ssrx/plugin-react-router": "latest", "@ssrx/react": "latest", - "hono": "3.12.10", + "hono": "3.12.12", "react": "18.2.0", "react-dom": "18.2.0", "react-router-dom": "6.22.0" @@ -23,12 +23,12 @@ "@ssrx/vite": "latest", "@types/react": "18.2.51", "@types/react-dom": "18.2.18", - "@vitejs/plugin-react": "4.2.1", + "@vitejs/plugin-react": "4.3.1", "autoprefixer": "10.4.17", - "postcss": "8.4.33", + "postcss": "8.4.45", "tailwindcss": "3.3.5", - "typescript": "5.3.3", - "vite": "5.0.12", - "vite-tsconfig-paths": "4.3.1" + "typescript": "5.6.2", + "vite": "5.4.4", + "vite-tsconfig-paths": "4.3.2" } } diff --git a/examples/react-router-simple/package.json b/examples/react-router-simple/package.json index 12c2525..f76f28a 100644 --- a/examples/react-router-simple/package.json +++ b/examples/react-router-simple/package.json @@ -13,9 +13,9 @@ "typecheck": "tsc" }, "dependencies": { - "@hono/node-server": "^1.7.0", + "@hono/node-server": "^1.12.2", "@ssrx/react": "latest", - "hono": "3.12.10", + "hono": "3.12.12", "react": "18.2.0", "react-dom": "18.2.0", "react-router-dom": "6.22.0" @@ -24,9 +24,9 @@ "@ssrx/vite": "latest", "@types/react": "18.2.51", "@types/react-dom": "18.2.18", - "@vitejs/plugin-react": "4.2.1", - "typescript": "5.3.3", - "vite": "5.0.12", - "vite-tsconfig-paths": "4.3.1" + "@vitejs/plugin-react": "4.3.1", + "typescript": "5.6.2", + "vite": "5.4.4", + "vite-tsconfig-paths": "4.3.2" } } diff --git a/examples/remix-vite/package.json b/examples/remix-vite/package.json index 5314e23..e0a3e78 100644 --- a/examples/remix-vite/package.json +++ b/examples/remix-vite/package.json @@ -13,7 +13,7 @@ "typecheck": "tsc" }, "dependencies": { - "@hono/node-server": "^1.7.0", + "@hono/node-server": "^1.12.2", "@lucia-auth/adapter-sqlite": "2.0.1", "@paralleldrive/cuid2": "2.2.2", "@radix-ui/react-slot": "^1.0.2", @@ -25,22 +25,22 @@ "@remix-run/server-runtime": "2.6.0", "@ssrx/plugin-tanstack-query": "latest", "@ssrx/plugin-trpc-react": "latest", - "@tanstack/react-query": "^5.18.1", - "@tanstack/react-query-devtools": "^5.18.1", - "@trpc/client": "10.45.0", - "@trpc/server": "10.45.0", + "@tanstack/react-query": "^5.56.2", + "@tanstack/react-query-devtools": "^5.56.2", + "@trpc/client": "10.45.2", + "@trpc/server": "10.45.2", "better-sqlite3": "9.3.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.0", "drizzle-orm": "0.29.3", "drizzle-valibot": "0.1.1", - "hono": "3.12.10", + "hono": "3.12.12", "isbot": "~4.4.0", "lucia": "2.7.7", "lucide-react": "^0.321.0", "react": "18.2.0", "react-dom": "18.2.0", - "react-error-boundary": "4.0.12", + "react-error-boundary": "4.0.13", "remix-routes": "1.6.1", "tailwind-merge": "^1.14.0", "tailwindcss-animate": "^1.0.7", @@ -49,7 +49,7 @@ "devDependencies": { "@remix-run/dev": "2.6.0", "@ssrx/remix": "latest", - "@total-typescript/ts-reset": "~0.5.1", + "@total-typescript/ts-reset": "~0.6.1", "@types/better-sqlite3": "7.6.9", "@types/react": "18.2.51", "@types/react-dom": "18.2.18", @@ -58,11 +58,11 @@ "drizzle-kit": "0.20.14", "eslint-plugin-react": "7.33.2", "eslint-plugin-react-hooks": "4.6.0", - "postcss": "8.4.33", + "postcss": "8.4.45", "tailwindcss": "3.3.5", - "typescript": "5.3.3", + "typescript": "5.6.2", "typescript-remix-routes-plugin": "1.0.1", - "vite": "5.0.12", - "vite-tsconfig-paths": "4.3.1" + "vite": "5.4.4", + "vite-tsconfig-paths": "4.3.2" } } diff --git a/examples/solid-router-simple/package.json b/examples/solid-router-simple/package.json index edf771f..9e081c2 100644 --- a/examples/solid-router-simple/package.json +++ b/examples/solid-router-simple/package.json @@ -13,18 +13,18 @@ "typecheck": "tsc" }, "dependencies": { - "@hono/node-server": "^1.7.0", + "@hono/node-server": "^1.12.2", "@solidjs/meta": "~0.29.3", "@solidjs/router": "0.11.2", "@ssrx/solid": "latest", - "hono": "3.12.10", + "hono": "3.12.12", "solid-js": "1.8.12" }, "devDependencies": { "@ssrx/vite": "latest", - "typescript": "5.3.3", - "vite": "5.0.12", + "typescript": "5.6.2", + "vite": "5.4.4", "vite-plugin-solid": "2.9.1", - "vite-tsconfig-paths": "4.3.1" + "vite-tsconfig-paths": "4.3.2" } } diff --git a/examples/tanstack-router-simple/package.json b/examples/tanstack-router-simple/package.json index 25ee4b8..bc464fa 100644 --- a/examples/tanstack-router-simple/package.json +++ b/examples/tanstack-router-simple/package.json @@ -13,27 +13,27 @@ "typecheck": "tsc" }, "dependencies": { - "@hono/node-server": "^1.7.0", + "@hono/node-server": "^1.12.2", "@ssrx/plugin-tanstack-router": "latest", "@ssrx/react": "latest", "@ssrx/vite": "latest", - "@tanstack/react-router": "1.32.0", - "@tanstack/router-devtools": "1.32.0", - "@tanstack/router-vite-plugin": "1.31.18", - "hono": "3.12.10", - "jsesc": "3.0.2", + "@tanstack/react-router": "1.57.13", + "@tanstack/router-devtools": "1.57.13", + "@tanstack/start": "1.57.13", + "hono": "4.6.1", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { + "@tanstack/router-plugin": "1.57.13", "@types/react": "18.2.51", "@types/react-dom": "18.2.18", - "@vitejs/plugin-react": "4.2.1", + "@vitejs/plugin-react": "4.3.1", "autoprefixer": "10.4.17", - "postcss": "8.4.33", + "postcss": "8.4.45", "tailwindcss": "3.3.5", - "typescript": "5.3.3", - "vite": "5.0.12", - "vite-tsconfig-paths": "4.3.1" + "typescript": "5.6.2", + "vite": "5.4.4", + "vite-tsconfig-paths": "4.3.2" } } diff --git a/examples/tanstack-router-simple/src/entry.client.tsx b/examples/tanstack-router-simple/src/entry.client.tsx index c526ed1..2ca5672 100644 --- a/examples/tanstack-router-simple/src/entry.client.tsx +++ b/examples/tanstack-router-simple/src/entry.client.tsx @@ -1,4 +1,4 @@ -import { RouterProvider } from '@tanstack/react-router'; +import { StartClient } from '@tanstack/start'; import { hydrateRoot } from 'react-dom/client'; import { createRouter } from '~/router.tsx'; @@ -8,13 +8,5 @@ void render(); async function render() { const router = createRouter(); - if (!router.state.matches.length) { - // needed until https://github.com/TanStack/router/issues/1115 is resolved - // do NOT need if not using lazy file routes - await router.load(); - - void router.hydrate(); - } - - hydrateRoot(document, ); + hydrateRoot(document, ); } diff --git a/examples/tanstack-router-simple/src/entry.server.tsx b/examples/tanstack-router-simple/src/entry.server.tsx index 485ff25..cd4976a 100644 --- a/examples/tanstack-router-simple/src/entry.server.tsx +++ b/examples/tanstack-router-simple/src/entry.server.tsx @@ -1,6 +1,17 @@ import { renderAssets } from '@ssrx/react/server'; import { assetsForRequest } from '@ssrx/vite/runtime'; -import { createMemoryHistory, RouterProvider } from '@tanstack/react-router'; +import { + type AnyRouteMatch, + type AnyRouter, + createControlledPromise, + createMemoryHistory, + defer, + type ExtractedEntry, + isPlainArray, + isPlainObject, + type StreamState, +} from '@tanstack/react-router'; +import { StartServer } from '@tanstack/start/server'; import { createRouter } from '~/router.tsx'; @@ -14,6 +25,9 @@ export async function render(req: Request) { }, }); + // required if using defer() in loaders + router.serializeLoaderData = serializeLoaderData; + const url = new URL(req.url); const memoryHistory = createMemoryHistory({ initialEntries: [url.pathname + url.search], @@ -24,7 +38,130 @@ export async function render(req: Request) { // Wait for critical, non-deferred data await router.load(); - const app = ; + const app = ; return { app, router }; } + +/** + * This serializeLoaderData() function is required to support deferred data, but is not exported from @tanstack/start. + * + * For now, we're copying the implementation from: + * + * https://github.com/TanStack/router/blob/main/packages/start/src/client/serialization.tsx + */ +function serializeLoaderData( + dataType: '__beforeLoadContext' | 'loaderData', + data: any, + ctx: { + match: AnyRouteMatch; + router: AnyRouter; + }, +) { + if (!ctx.router.isServer) { + return data; + } + + (ctx.match as any).extracted = (ctx.match as any).extracted || []; + + const extracted = (ctx.match as any).extracted; + + const replacedLoaderData = replaceBy(data, (value, path) => { + const type = value instanceof ReadableStream ? 'stream' : value instanceof Promise ? 'promise' : undefined; + + if (type) { + const entry: ExtractedEntry = { + dataType, + type, + path, + id: extracted.length, + value, + matchIndex: ctx.match.index, + }; + + extracted.push(entry); + + // If it's a stream, we need to tee it so we can read it multiple times + if (type === 'stream') { + const [copy1, copy2] = value.tee(); + entry.streamState = createStreamState({ stream: copy2 }); + + return copy1; + } else { + void defer(value); + } + } + + return value; + }); + + return replacedLoaderData; +} + +function replaceBy(obj: T, cb: (value: any, path: Array) => any, path: Array = []): T { + if (isPlainArray(obj)) { + return obj.map((value, i) => replaceBy(value, cb, [...path, `${i}`])) as any; + } + + if (isPlainObject(obj)) { + // Do not allow objects with illegal + const newObj: any = {}; + + for (const key in obj) { + newObj[key] = replaceBy(obj[key], cb, [...path, key]); + } + + return newObj; + } + + // // Detect classes, functions, and other non-serializable objects + // // and return undefined. Exclude some known types that are serializable + // if ( + // typeof obj === 'function' || + // (typeof obj === 'object' && + // ![Object, Promise, ReadableStream].includes((obj as any)?.constructor)) + // ) { + // console.info(obj) + // warning(false, `Non-serializable value ☝️ found at ${path.join('.')}`) + // return undefined as any + // } + + const newObj = cb(obj, path); + + if (newObj !== obj) { + return newObj; + } + + return obj; +} + +// Readable stream with state is a stream that has a promise that resolves to the next chunk +function createStreamState({ stream }: { stream: ReadableStream }): StreamState { + const streamState: StreamState = { + promises: [], + }; + + const reader = stream.getReader(); + + const read = (index: number): any => { + streamState.promises[index] = createControlledPromise(); + + return reader.read().then(({ done, value }) => { + if (done) { + streamState.promises[index]!.resolve(null); + reader.releaseLock(); + return; + } + + streamState.promises[index]!.resolve(value); + + return read(index + 1); + }); + }; + + read(0).catch((err: any) => { + console.error('stream read error', err); + }); + + return streamState; +} diff --git a/examples/tanstack-router-simple/src/routeTree.gen.ts b/examples/tanstack-router-simple/src/routeTree.gen.ts index 583dae1..70432a2 100644 --- a/examples/tanstack-router-simple/src/routeTree.gen.ts +++ b/examples/tanstack-router-simple/src/routeTree.gen.ts @@ -8,30 +8,20 @@ // This file is auto-generated by TanStack Router -import { createFileRoute } from '@tanstack/react-router' - // Import Routes import { Route as rootRoute } from './routes/__root' import { Route as RedirectImport } from './routes/redirect' import { Route as LazyComponentImport } from './routes/lazy-component' +import { Route as AdminImport } from './routes/admin' import { Route as IndexImport } from './routes/index' import { Route as AdminIndexImport } from './routes/admin.index' import { Route as AdminMembersImport } from './routes/admin.members' +import { Route as AdminMembersIndexImport } from './routes/admin.members.index' import { Route as AdminMembersMemberIdImport } from './routes/admin.members.$memberId' -// Create Virtual Routes - -const AdminLazyImport = createFileRoute('/admin')() -const AdminMembersIndexLazyImport = createFileRoute('/admin/members/')() - // Create/Update Routes -const AdminLazyRoute = AdminLazyImport.update({ - path: '/admin', - getParentRoute: () => rootRoute, -} as any).lazy(() => import('./routes/admin.lazy').then((d) => d.Route)) - const RedirectRoute = RedirectImport.update({ path: '/redirect', getParentRoute: () => rootRoute, @@ -42,6 +32,11 @@ const LazyComponentRoute = LazyComponentImport.update({ getParentRoute: () => rootRoute, } as any) +const AdminRoute = AdminImport.update({ + path: '/admin', + getParentRoute: () => rootRoute, +} as any) + const IndexRoute = IndexImport.update({ path: '/', getParentRoute: () => rootRoute, @@ -49,20 +44,18 @@ const IndexRoute = IndexImport.update({ const AdminIndexRoute = AdminIndexImport.update({ path: '/', - getParentRoute: () => AdminLazyRoute, + getParentRoute: () => AdminRoute, } as any) const AdminMembersRoute = AdminMembersImport.update({ path: '/members', - getParentRoute: () => AdminLazyRoute, + getParentRoute: () => AdminRoute, } as any) -const AdminMembersIndexLazyRoute = AdminMembersIndexLazyImport.update({ +const AdminMembersIndexRoute = AdminMembersIndexImport.update({ path: '/', getParentRoute: () => AdminMembersRoute, -} as any).lazy(() => - import('./routes/admin.members.index.lazy').then((d) => d.Route), -) +} as any) const AdminMembersMemberIdRoute = AdminMembersMemberIdImport.update({ path: '/$memberId', @@ -74,35 +67,59 @@ const AdminMembersMemberIdRoute = AdminMembersMemberIdImport.update({ declare module '@tanstack/react-router' { interface FileRoutesByPath { '/': { + id: '/' + path: '/' + fullPath: '/' preLoaderRoute: typeof IndexImport parentRoute: typeof rootRoute } + '/admin': { + id: '/admin' + path: '/admin' + fullPath: '/admin' + preLoaderRoute: typeof AdminImport + parentRoute: typeof rootRoute + } '/lazy-component': { + id: '/lazy-component' + path: '/lazy-component' + fullPath: '/lazy-component' preLoaderRoute: typeof LazyComponentImport parentRoute: typeof rootRoute } '/redirect': { + id: '/redirect' + path: '/redirect' + fullPath: '/redirect' preLoaderRoute: typeof RedirectImport parentRoute: typeof rootRoute } - '/admin': { - preLoaderRoute: typeof AdminLazyImport - parentRoute: typeof rootRoute - } '/admin/members': { + id: '/admin/members' + path: '/members' + fullPath: '/admin/members' preLoaderRoute: typeof AdminMembersImport - parentRoute: typeof AdminLazyImport + parentRoute: typeof AdminImport } '/admin/': { + id: '/admin/' + path: '/' + fullPath: '/admin/' preLoaderRoute: typeof AdminIndexImport - parentRoute: typeof AdminLazyImport + parentRoute: typeof AdminImport } '/admin/members/$memberId': { + id: '/admin/members/$memberId' + path: '/$memberId' + fullPath: '/admin/members/$memberId' preLoaderRoute: typeof AdminMembersMemberIdImport parentRoute: typeof AdminMembersImport } '/admin/members/': { - preLoaderRoute: typeof AdminMembersIndexLazyImport + id: '/admin/members/' + path: '/' + fullPath: '/admin/members/' + preLoaderRoute: typeof AdminMembersIndexImport parentRoute: typeof AdminMembersImport } } @@ -110,17 +127,164 @@ declare module '@tanstack/react-router' { // Create and export the route tree -export const routeTree = rootRoute.addChildren([ - IndexRoute, - LazyComponentRoute, - RedirectRoute, - AdminLazyRoute.addChildren([ - AdminMembersRoute.addChildren([ - AdminMembersMemberIdRoute, - AdminMembersIndexLazyRoute, - ]), - AdminIndexRoute, - ]), -]) +interface AdminMembersRouteChildren { + AdminMembersMemberIdRoute: typeof AdminMembersMemberIdRoute + AdminMembersIndexRoute: typeof AdminMembersIndexRoute +} + +const AdminMembersRouteChildren: AdminMembersRouteChildren = { + AdminMembersMemberIdRoute: AdminMembersMemberIdRoute, + AdminMembersIndexRoute: AdminMembersIndexRoute, +} + +const AdminMembersRouteWithChildren = AdminMembersRoute._addFileChildren( + AdminMembersRouteChildren, +) + +interface AdminRouteChildren { + AdminMembersRoute: typeof AdminMembersRouteWithChildren + AdminIndexRoute: typeof AdminIndexRoute +} + +const AdminRouteChildren: AdminRouteChildren = { + AdminMembersRoute: AdminMembersRouteWithChildren, + AdminIndexRoute: AdminIndexRoute, +} + +const AdminRouteWithChildren = AdminRoute._addFileChildren(AdminRouteChildren) + +export interface FileRoutesByFullPath { + '/': typeof IndexRoute + '/admin': typeof AdminRouteWithChildren + '/lazy-component': typeof LazyComponentRoute + '/redirect': typeof RedirectRoute + '/admin/members': typeof AdminMembersRouteWithChildren + '/admin/': typeof AdminIndexRoute + '/admin/members/$memberId': typeof AdminMembersMemberIdRoute + '/admin/members/': typeof AdminMembersIndexRoute +} + +export interface FileRoutesByTo { + '/': typeof IndexRoute + '/lazy-component': typeof LazyComponentRoute + '/redirect': typeof RedirectRoute + '/admin': typeof AdminIndexRoute + '/admin/members/$memberId': typeof AdminMembersMemberIdRoute + '/admin/members': typeof AdminMembersIndexRoute +} + +export interface FileRoutesById { + __root__: typeof rootRoute + '/': typeof IndexRoute + '/admin': typeof AdminRouteWithChildren + '/lazy-component': typeof LazyComponentRoute + '/redirect': typeof RedirectRoute + '/admin/members': typeof AdminMembersRouteWithChildren + '/admin/': typeof AdminIndexRoute + '/admin/members/$memberId': typeof AdminMembersMemberIdRoute + '/admin/members/': typeof AdminMembersIndexRoute +} + +export interface FileRouteTypes { + fileRoutesByFullPath: FileRoutesByFullPath + fullPaths: + | '/' + | '/admin' + | '/lazy-component' + | '/redirect' + | '/admin/members' + | '/admin/' + | '/admin/members/$memberId' + | '/admin/members/' + fileRoutesByTo: FileRoutesByTo + to: + | '/' + | '/lazy-component' + | '/redirect' + | '/admin' + | '/admin/members/$memberId' + | '/admin/members' + id: + | '__root__' + | '/' + | '/admin' + | '/lazy-component' + | '/redirect' + | '/admin/members' + | '/admin/' + | '/admin/members/$memberId' + | '/admin/members/' + fileRoutesById: FileRoutesById +} + +export interface RootRouteChildren { + IndexRoute: typeof IndexRoute + AdminRoute: typeof AdminRouteWithChildren + LazyComponentRoute: typeof LazyComponentRoute + RedirectRoute: typeof RedirectRoute +} + +const rootRouteChildren: RootRouteChildren = { + IndexRoute: IndexRoute, + AdminRoute: AdminRouteWithChildren, + LazyComponentRoute: LazyComponentRoute, + RedirectRoute: RedirectRoute, +} + +export const routeTree = rootRoute + ._addFileChildren(rootRouteChildren) + ._addFileTypes() /* prettier-ignore-end */ + +/* ROUTE_MANIFEST_START +{ + "routes": { + "__root__": { + "filePath": "__root.tsx", + "children": [ + "/", + "/admin", + "/lazy-component", + "/redirect" + ] + }, + "/": { + "filePath": "index.tsx" + }, + "/admin": { + "filePath": "admin.tsx", + "children": [ + "/admin/members", + "/admin/" + ] + }, + "/lazy-component": { + "filePath": "lazy-component.tsx" + }, + "/redirect": { + "filePath": "redirect.tsx" + }, + "/admin/members": { + "filePath": "admin.members.tsx", + "parent": "/admin", + "children": [ + "/admin/members/$memberId", + "/admin/members/" + ] + }, + "/admin/": { + "filePath": "admin.index.tsx", + "parent": "/admin" + }, + "/admin/members/$memberId": { + "filePath": "admin.members.$memberId.tsx", + "parent": "/admin/members" + }, + "/admin/members/": { + "filePath": "admin.members.index.tsx", + "parent": "/admin/members" + } + } +} +ROUTE_MANIFEST_END */ diff --git a/examples/tanstack-router-simple/src/routes/__root.tsx b/examples/tanstack-router-simple/src/routes/__root.tsx index 883d79d..541bb76 100644 --- a/examples/tanstack-router-simple/src/routes/__root.tsx +++ b/examples/tanstack-router-simple/src/routes/__root.tsx @@ -1,10 +1,16 @@ import './__root.css'; import type { ErrorComponentProps } from '@tanstack/react-router'; -import { createRootRouteWithContext, ErrorComponent, Link, Outlet, useRouter } from '@tanstack/react-router'; +import { + createRootRouteWithContext, + ErrorComponent, + Link, + Outlet, + ScrollRestoration, + useRouter, +} from '@tanstack/react-router'; import { TanStackRouterDevtools } from '@tanstack/router-devtools'; -// @ts-expect-error no types -import jsesc from 'jsesc'; +import { Meta } from '@tanstack/start'; import type { RootRouterContext } from '~/router.ts'; @@ -24,6 +30,8 @@ function RootComponent() { {headTags?.()} + + @@ -51,9 +59,9 @@ function RootComponent() { - + - + {bodyTags?.()} @@ -68,32 +76,3 @@ function RootErrorComponent({ error }: ErrorComponentProps) { return ; } - -export function DehydrateRouter() { - const router = useRouter(); - - const dehydrated = router.dehydratedData || { - router: router.dehydrate(), - payload: router.options.dehydrate?.(), - }; - - // Use jsesc to escape the stringified JSON for use in a script tag - const stringified = jsesc(router.options.transformer.stringify(dehydrated), { - isScriptContext: true, - wrap: true, - }); - - return ( -