From c64c1d5f7d0f7aa8a14385b54e511227549b5490 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Sat, 21 Mar 2026 21:41:39 +0100 Subject: [PATCH 1/4] fix: strip invariant and warning strings from prod bundles --- .../start-convex-trellaux/convex/board.ts | 2 +- .../start-convex-trellaux/convex/invariant.ts | 5 + .../react/start-convex-trellaux/package.json | 1 - .../src/components/Board.tsx | 2 +- .../src/components/Card.tsx | 2 +- .../src/components/Column.tsx | 2 +- .../src/components/NewCard.tsx | 2 +- .../src/components/NewColumn.tsx | 2 +- .../start-convex-trellaux/src/invariant.ts | 5 + examples/react/start-trellaux/package.json | 1 - .../start-trellaux/src/components/Board.tsx | 2 +- .../start-trellaux/src/components/Card.tsx | 2 +- .../start-trellaux/src/components/Column.tsx | 2 +- .../start-trellaux/src/components/NewCard.tsx | 2 +- .../src/components/NewColumn.tsx | 2 +- examples/react/start-trellaux/src/db/board.ts | 2 +- .../react/start-trellaux/src/invariant.ts | 5 + packages/react-router/package.json | 4 +- packages/react-router/src/Match.tsx | 101 +++++++++++++----- packages/react-router/src/Matches.tsx | 8 +- packages/react-router/src/fileRoute.ts | 15 ++- .../react-router/src/renderRouteNotFound.tsx | 12 +-- packages/react-router/src/useMatch.tsx | 29 +++-- packages/react-router/src/useRouter.tsx | 12 ++- packages/react-router/tests/redirect.test.tsx | 15 ++- packages/react-start-client/package.json | 4 +- packages/react-start-client/src/renderRSC.tsx | 8 +- packages/router-core/package.json | 4 +- packages/router-core/src/index.ts | 1 + packages/router-core/src/invariant.ts | 3 + packages/router-core/src/load-matches.ts | 15 ++- .../router-core/src/new-process-route-tree.ts | 15 ++- packages/router-core/src/route.ts | 13 ++- packages/router-core/src/ssr/ssr-client.ts | 41 ++++--- packages/router-core/src/ssr/ssr-server.ts | 10 +- packages/router-devtools-core/package.json | 3 +- .../src/BaseTanStackRouterDevtoolsPanel.tsx | 15 ++- packages/solid-router/package.json | 4 +- packages/solid-router/src/Match.tsx | 38 ++++--- packages/solid-router/src/Matches.tsx | 8 +- packages/solid-router/src/fileRoute.ts | 15 ++- .../solid-router/src/renderRouteNotFound.tsx | 12 +-- packages/solid-router/src/useMatch.tsx | 24 +++-- packages/solid-router/src/useRouter.tsx | 12 ++- packages/solid-router/tests/redirect.test.tsx | 17 ++- packages/solid-start-client/package.json | 4 +- packages/start-client-core/package.json | 4 +- .../src/client-rpc/serverFnFetcher.ts | 20 +++- packages/start-server-core/package.json | 3 +- .../src/server-functions-handler.ts | 15 ++- packages/vue-router/package.json | 4 +- packages/vue-router/src/Match.tsx | 36 +++++-- packages/vue-router/src/Matches.tsx | 8 +- packages/vue-router/src/fileRoute.ts | 15 ++- .../vue-router/src/renderRouteNotFound.tsx | 12 +-- packages/vue-router/src/useMatch.tsx | 36 ++++--- packages/vue-router/src/useRouter.tsx | 12 ++- packages/vue-router/tests/redirect.test.tsx | 9 +- packages/vue-start-client/package.json | 4 +- pnpm-lock.yaml | 65 ----------- 60 files changed, 420 insertions(+), 326 deletions(-) create mode 100644 examples/react/start-convex-trellaux/convex/invariant.ts create mode 100644 examples/react/start-convex-trellaux/src/invariant.ts create mode 100644 examples/react/start-trellaux/src/invariant.ts create mode 100644 packages/router-core/src/invariant.ts diff --git a/examples/react/start-convex-trellaux/convex/board.ts b/examples/react/start-convex-trellaux/convex/board.ts index bae241a7734..f585a01cd33 100644 --- a/examples/react/start-convex-trellaux/convex/board.ts +++ b/examples/react/start-convex-trellaux/convex/board.ts @@ -1,4 +1,4 @@ -import invariant from 'tiny-invariant' +import { invariant } from './invariant' import { v } from 'convex/values' import { type QueryCtx, diff --git a/examples/react/start-convex-trellaux/convex/invariant.ts b/examples/react/start-convex-trellaux/convex/invariant.ts new file mode 100644 index 00000000000..8aae0868323 --- /dev/null +++ b/examples/react/start-convex-trellaux/convex/invariant.ts @@ -0,0 +1,5 @@ +export function invariant(value: unknown, message: string): asserts value { + if (!value) { + throw new Error(message) + } +} diff --git a/examples/react/start-convex-trellaux/package.json b/examples/react/start-convex-trellaux/package.json index 171c516d08a..355f8309c6f 100644 --- a/examples/react/start-convex-trellaux/package.json +++ b/examples/react/start-convex-trellaux/package.json @@ -28,7 +28,6 @@ "react-hot-toast": "^2.5.1", "redaxios": "^0.5.1", "tailwind-merge": "^2.6.0", - "tiny-invariant": "^1.3.3", "zod": "^3.24.2" }, "devDependencies": { diff --git a/examples/react/start-convex-trellaux/src/components/Board.tsx b/examples/react/start-convex-trellaux/src/components/Board.tsx index 327603e2046..ac78c7baae5 100644 --- a/examples/react/start-convex-trellaux/src/components/Board.tsx +++ b/examples/react/start-convex-trellaux/src/components/Board.tsx @@ -1,5 +1,5 @@ import { useCallback, useMemo, useRef } from 'react' -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { useSuspenseQuery } from '@tanstack/react-query' import { convexQuery } from '@convex-dev/react-query' import { api } from '../../convex/_generated/api.js' diff --git a/examples/react/start-convex-trellaux/src/components/Card.tsx b/examples/react/start-convex-trellaux/src/components/Card.tsx index eacf87d7598..23f77ca2b2c 100644 --- a/examples/react/start-convex-trellaux/src/components/Card.tsx +++ b/examples/react/start-convex-trellaux/src/components/Card.tsx @@ -1,4 +1,4 @@ -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { forwardRef, useState } from 'react' import { CONTENT_TYPES } from '../types' diff --git a/examples/react/start-convex-trellaux/src/components/Column.tsx b/examples/react/start-convex-trellaux/src/components/Column.tsx index dd90e02ee71..b9a59887833 100644 --- a/examples/react/start-convex-trellaux/src/components/Column.tsx +++ b/examples/react/start-convex-trellaux/src/components/Column.tsx @@ -1,5 +1,5 @@ import { forwardRef, useCallback, useMemo, useRef, useState } from 'react' -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { twMerge } from 'tailwind-merge' import { flushSync } from 'react-dom' diff --git a/examples/react/start-convex-trellaux/src/components/NewCard.tsx b/examples/react/start-convex-trellaux/src/components/NewCard.tsx index 47cadcf5aee..99b0b148390 100644 --- a/examples/react/start-convex-trellaux/src/components/NewCard.tsx +++ b/examples/react/start-convex-trellaux/src/components/NewCard.tsx @@ -1,5 +1,5 @@ import { useRef } from 'react' -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { ItemMutationFields } from '../types' import { useCreateItemMutation } from '../queries' diff --git a/examples/react/start-convex-trellaux/src/components/NewColumn.tsx b/examples/react/start-convex-trellaux/src/components/NewColumn.tsx index 50a7d608c55..0cd1f6aa532 100644 --- a/examples/react/start-convex-trellaux/src/components/NewColumn.tsx +++ b/examples/react/start-convex-trellaux/src/components/NewColumn.tsx @@ -1,5 +1,5 @@ import { useRef, useState } from 'react' -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { Icon } from '../icons/icons' import { useCreateColumnMutation } from '../queries' diff --git a/examples/react/start-convex-trellaux/src/invariant.ts b/examples/react/start-convex-trellaux/src/invariant.ts new file mode 100644 index 00000000000..8aae0868323 --- /dev/null +++ b/examples/react/start-convex-trellaux/src/invariant.ts @@ -0,0 +1,5 @@ +export function invariant(value: unknown, message: string): asserts value { + if (!value) { + throw new Error(message) + } +} diff --git a/examples/react/start-trellaux/package.json b/examples/react/start-trellaux/package.json index 7a76758fe8d..7c4df69ed87 100644 --- a/examples/react/start-trellaux/package.json +++ b/examples/react/start-trellaux/package.json @@ -23,7 +23,6 @@ "react-hot-toast": "^2.5.1", "redaxios": "^0.5.1", "tailwind-merge": "^2.6.0", - "tiny-invariant": "^1.3.3", "zod": "^3.24.2" }, "devDependencies": { diff --git a/examples/react/start-trellaux/src/components/Board.tsx b/examples/react/start-trellaux/src/components/Board.tsx index 0b43e1d9237..0ba9a3c288d 100644 --- a/examples/react/start-trellaux/src/components/Board.tsx +++ b/examples/react/start-trellaux/src/components/Board.tsx @@ -1,5 +1,5 @@ import { useCallback, useMemo, useRef } from 'react' -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { useSuspenseQuery } from '@tanstack/react-query' import { boardQueries, useUpdateBoardMutation } from '../queries.js' import { NewColumn } from './NewColumn.js' diff --git a/examples/react/start-trellaux/src/components/Card.tsx b/examples/react/start-trellaux/src/components/Card.tsx index 6c73ca079fb..729b93d2f85 100644 --- a/examples/react/start-trellaux/src/components/Card.tsx +++ b/examples/react/start-trellaux/src/components/Card.tsx @@ -1,4 +1,4 @@ -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { forwardRef, useState } from 'react' import { CONTENT_TYPES } from '../types' diff --git a/examples/react/start-trellaux/src/components/Column.tsx b/examples/react/start-trellaux/src/components/Column.tsx index f9fddaaf5f3..9f3387c61fc 100644 --- a/examples/react/start-trellaux/src/components/Column.tsx +++ b/examples/react/start-trellaux/src/components/Column.tsx @@ -1,5 +1,5 @@ import { forwardRef, useCallback, useMemo, useRef, useState } from 'react' -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { twMerge } from 'tailwind-merge' import { flushSync } from 'react-dom' diff --git a/examples/react/start-trellaux/src/components/NewCard.tsx b/examples/react/start-trellaux/src/components/NewCard.tsx index 8201083bb36..b46f965c8b5 100644 --- a/examples/react/start-trellaux/src/components/NewCard.tsx +++ b/examples/react/start-trellaux/src/components/NewCard.tsx @@ -1,5 +1,5 @@ import { useRef } from 'react' -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { ItemMutationFields } from '../types' import { useCreateItemMutation } from '../queries' diff --git a/examples/react/start-trellaux/src/components/NewColumn.tsx b/examples/react/start-trellaux/src/components/NewColumn.tsx index acb6c82cfb9..655b380743c 100644 --- a/examples/react/start-trellaux/src/components/NewColumn.tsx +++ b/examples/react/start-trellaux/src/components/NewColumn.tsx @@ -1,5 +1,5 @@ import { useRef, useState } from 'react' -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { Icon } from '../icons/icons' import { useCreateColumnMutation } from '../queries' diff --git a/examples/react/start-trellaux/src/db/board.ts b/examples/react/start-trellaux/src/db/board.ts index 92f94967e9c..ee80aeb9f7f 100644 --- a/examples/react/start-trellaux/src/db/board.ts +++ b/examples/react/start-trellaux/src/db/board.ts @@ -1,6 +1,6 @@ import crypto from 'node:crypto' import { createServerFn } from '@tanstack/react-start' -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import * as z from 'zod' import { deleteColumnSchema, diff --git a/examples/react/start-trellaux/src/invariant.ts b/examples/react/start-trellaux/src/invariant.ts new file mode 100644 index 00000000000..8aae0868323 --- /dev/null +++ b/examples/react/start-trellaux/src/invariant.ts @@ -0,0 +1,5 @@ +export function invariant(value: unknown, message: string): asserts value { + if (!value) { + throw new Error(message) + } +} diff --git a/packages/react-router/package.json b/packages/react-router/package.json index cfc57e0077f..ee7adffc7c1 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -99,9 +99,7 @@ "@tanstack/history": "workspace:*", "@tanstack/react-store": "^0.9.2", "@tanstack/router-core": "workspace:*", - "isbot": "^5.1.22", - "tiny-invariant": "^1.3.3", - "tiny-warning": "^1.0.3" + "isbot": "^5.1.22" }, "devDependencies": { "@testing-library/jest-dom": "^6.6.3", diff --git a/packages/react-router/src/Match.tsx b/packages/react-router/src/Match.tsx index 36b41ef1240..ba21ee3896a 100644 --- a/packages/react-router/src/Match.tsx +++ b/packages/react-router/src/Match.tsx @@ -1,10 +1,9 @@ import * as React from 'react' import { useStore } from '@tanstack/react-store' -import invariant from 'tiny-invariant' -import warning from 'tiny-warning' import { createControlledPromise, getLocationChangeInfo, + invariant, isNotFound, isRedirect, rootRouteId, @@ -33,10 +32,15 @@ export const Match = React.memo(function MatchImpl({ if (isServer ?? router.isServer) { const match = router.stores.activeMatchStoresById.get(matchId)?.state - invariant( - match, - `Could not find match for matchId "${matchId}". Please file an issue!`, - ) + if (!match) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Could not find match for matchId "${matchId}". Please file an issue!`, + ) + } + + invariant() + } const routeId = match.routeId as string const parentRouteId = (router.routesById[routeId] as AnyRoute).parentRoute @@ -62,10 +66,15 @@ export const Match = React.memo(function MatchImpl({ // and reconcileMatchPool reuses stores for the same matchId. // eslint-disable-next-line react-hooks/rules-of-hooks const matchStore = router.stores.activeMatchStoresById.get(matchId) - invariant( - matchStore, - `Could not find match for matchId "${matchId}". Please file an issue!`, - ) + if (!matchStore) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Could not find match for matchId "${matchId}". Please file an issue!`, + ) + } + + invariant() + } // eslint-disable-next-line react-hooks/rules-of-hooks const resetKey = useStore(router.stores.loadedAt, (loadedAt) => loadedAt) // eslint-disable-next-line react-hooks/rules-of-hooks @@ -162,7 +171,9 @@ function MatchView({ onCatch={(error, errorInfo) => { // Forward not found errors (we don't want to show the error component for these) if (isNotFound(error)) throw error - warning(false, `Error in route match: ${matchId}`) + if (process.env.NODE_ENV !== 'production') { + console.warn(`Warning: Error in route match: ${matchId}`) + } routeOnCatch?.(error, errorInfo) }} > @@ -249,10 +260,15 @@ export const MatchInner = React.memo(function MatchInnerImpl({ if (isServer ?? router.isServer) { const match = router.stores.activeMatchStoresById.get(matchId)?.state - invariant( - match, - `Could not find match for matchId "${matchId}". Please file an issue!`, - ) + if (!match) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Could not find match for matchId "${matchId}". Please file an issue!`, + ) + } + + invariant() + } const routeId = match.routeId as string const route = router.routesById[routeId] as AnyRoute @@ -282,12 +298,24 @@ export const MatchInner = React.memo(function MatchInnerImpl({ } if (match.status === 'notFound') { - invariant(isNotFound(match.error), 'Expected a notFound error') + if (!isNotFound(match.error)) { + if (process.env.NODE_ENV !== 'production') { + throw new Error('Invariant failed: Expected a notFound error') + } + + invariant() + } return renderRouteNotFound(router, route, match.error) } if (match.status === 'redirected') { - invariant(isRedirect(match.error), 'Expected a redirect error') + if (!isRedirect(match.error)) { + if (process.env.NODE_ENV !== 'production') { + throw new Error('Invariant failed: Expected a redirect error') + } + + invariant() + } throw router.getMatch(match.id)?._nonReactive.loadPromise } @@ -312,10 +340,15 @@ export const MatchInner = React.memo(function MatchInnerImpl({ // eslint-disable-next-line react-hooks/rules-of-hooks const matchStore = router.stores.activeMatchStoresById.get(matchId) - invariant( - matchStore, - `Could not find match for matchId "${matchId}". Please file an issue!`, - ) + if (!matchStore) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Could not find match for matchId "${matchId}". Please file an issue!`, + ) + } + + invariant() + } // eslint-disable-next-line react-hooks/rules-of-hooks const match = useStore(matchStore, (value) => value) const routeId = match.routeId as string @@ -384,14 +417,26 @@ export const MatchInner = React.memo(function MatchInnerImpl({ } if (match.status === 'notFound') { - invariant(isNotFound(match.error), 'Expected a notFound error') + if (!isNotFound(match.error)) { + if (process.env.NODE_ENV !== 'production') { + throw new Error('Invariant failed: Expected a notFound error') + } + + invariant() + } return renderRouteNotFound(router, route, match.error) } if (match.status === 'redirected') { // Redirects should be handled by the router transition. If we happen to // encounter a redirect here, it's a bug. Let's warn, but render nothing. - invariant(isRedirect(match.error), 'Expected a redirect error') + if (!isRedirect(match.error)) { + if (process.env.NODE_ENV !== 'production') { + throw new Error('Invariant failed: Expected a redirect error') + } + + invariant() + } // warning( // false, @@ -479,7 +524,15 @@ export const Outlet = React.memo(function OutletImpl() { ) : null if (parentGlobalNotFound) { - invariant(route, 'Could not resolve route for Outlet render') + if (!route) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + 'Invariant failed: Could not resolve route for Outlet render', + ) + } + + invariant() + } return renderRouteNotFound(router, route, undefined) } diff --git a/packages/react-router/src/Matches.tsx b/packages/react-router/src/Matches.tsx index 953a49401bf..f7f61d6e9b3 100644 --- a/packages/react-router/src/Matches.tsx +++ b/packages/react-router/src/Matches.tsx @@ -1,5 +1,4 @@ import * as React from 'react' -import warning from 'tiny-warning' import { useStore } from '@tanstack/react-store' import { replaceEqualDeep, rootRouteId } from '@tanstack/router-core' import { isServer } from '@tanstack/router-core/isServer' @@ -100,11 +99,10 @@ function MatchesInner() { onCatch={ process.env.NODE_ENV !== 'production' ? (error) => { - warning( - false, - `The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`, + console.warn( + `Warning: The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`, ) - warning(false, error.message || error.toString()) + console.warn(`Warning: ${error.message || error.toString()}`) } : undefined } diff --git a/packages/react-router/src/fileRoute.ts b/packages/react-router/src/fileRoute.ts index c38c24485fb..aeccbc20443 100644 --- a/packages/react-router/src/fileRoute.ts +++ b/packages/react-router/src/fileRoute.ts @@ -1,4 +1,3 @@ -import warning from 'tiny-warning' import { createRoute } from './route' import { useMatch } from './useMatch' @@ -151,10 +150,11 @@ export class FileRoute< THandlers > => { if (process.env.NODE_ENV !== 'production') { - warning( - this.silent, - 'FileRoute is deprecated and will be removed in the next major version. Use the createFileRoute(path)(options) function instead.', - ) + if (!this.silent) { + console.warn( + 'Warning: FileRoute is deprecated and will be removed in the next major version. Use the createFileRoute(path)(options) function instead.', + ) + } } const route = createRoute(options as any) ;(route as any).isRoot = false @@ -187,9 +187,8 @@ export function FileRouteLoader< >, ) => TLoaderFn { if (process.env.NODE_ENV !== 'production') { - warning( - false, - `FileRouteLoader is deprecated and will be removed in the next major version. Please place the loader function in the the main route file, inside the \`createFileRoute('/path/to/file')(options)\` options`, + console.warn( + `Warning: FileRouteLoader is deprecated and will be removed in the next major version. Please place the loader function in the the main route file, inside the \`createFileRoute('/path/to/file')(options)\` options`, ) } return (loaderFn) => loaderFn as any diff --git a/packages/react-router/src/renderRouteNotFound.tsx b/packages/react-router/src/renderRouteNotFound.tsx index 225a013beae..f8374ebd7c2 100644 --- a/packages/react-router/src/renderRouteNotFound.tsx +++ b/packages/react-router/src/renderRouteNotFound.tsx @@ -1,5 +1,4 @@ import * as React from 'react' -import warning from 'tiny-warning' import { DefaultGlobalNotFound } from './not-found' import type { AnyRoute, AnyRouter } from '@tanstack/router-core' @@ -21,11 +20,12 @@ export function renderRouteNotFound( return } - if (process.env.NODE_ENV === 'development') { - warning( - route.options.notFoundComponent, - `A notFoundError was encountered on the route with ID "${route.id}", but a notFoundComponent option was not configured, nor was a router level defaultNotFoundComponent configured. Consider configuring at least one of these to avoid TanStack Router's overly generic defaultNotFoundComponent (

Not Found

)`, - ) + if (process.env.NODE_ENV !== 'production') { + if (!route.options.notFoundComponent) { + console.warn( + `Warning: A notFoundError was encountered on the route with ID "${route.id}", but a notFoundComponent option was not configured, nor was a router level defaultNotFoundComponent configured. Consider configuring at least one of these to avoid TanStack Router's overly generic defaultNotFoundComponent (

Not Found

)`, + ) + } } return diff --git a/packages/react-router/src/useMatch.tsx b/packages/react-router/src/useMatch.tsx index 26dbc1082fe..8048e24521e 100644 --- a/packages/react-router/src/useMatch.tsx +++ b/packages/react-router/src/useMatch.tsx @@ -1,8 +1,7 @@ import * as React from 'react' import { useStore } from '@tanstack/react-store' -import { replaceEqualDeep } from '@tanstack/router-core' +import { invariant, replaceEqualDeep } from '@tanstack/router-core' import { isServer } from '@tanstack/router-core/isServer' -import invariant from 'tiny-invariant' import { dummyMatchContext, matchContext } from './matchContext' import { useRouter } from './useRouter' import type { @@ -119,10 +118,15 @@ export function useMatch< if (isServer ?? router.isServer) { const match = matchStore?.state - invariant( - !((opts.shouldThrow ?? true) && !match), - `Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`, - ) + if ((opts.shouldThrow ?? true) && !match) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`, + ) + } + + invariant() + } if (match === undefined) { return undefined as any @@ -139,10 +143,15 @@ export function useMatch< // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static return useStore(matchStore ?? dummyStore, (match) => { - invariant( - !((opts.shouldThrow ?? true) && !match), - `Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`, - ) + if ((opts.shouldThrow ?? true) && !match) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`, + ) + } + + invariant() + } if (match === undefined) { return undefined diff --git a/packages/react-router/src/useRouter.tsx b/packages/react-router/src/useRouter.tsx index 1bc4220f383..51364f4e84e 100644 --- a/packages/react-router/src/useRouter.tsx +++ b/packages/react-router/src/useRouter.tsx @@ -1,5 +1,4 @@ import * as React from 'react' -import warning from 'tiny-warning' import { routerContext } from './routerContext' import type { AnyRouter, RegisteredRouter } from '@tanstack/router-core' @@ -17,9 +16,12 @@ export function useRouter(opts?: { warn?: boolean }): TRouter { const value = React.useContext(routerContext) - warning( - !((opts?.warn ?? true) && !value), - 'useRouter must be used inside a component!', - ) + if (process.env.NODE_ENV !== 'production') { + if ((opts?.warn ?? true) && !value) { + console.warn( + 'Warning: useRouter must be used inside a component!', + ) + } + } return value as any } diff --git a/packages/react-router/tests/redirect.test.tsx b/packages/react-router/tests/redirect.test.tsx index b8b42d5e0e3..0b1d644db60 100644 --- a/packages/react-router/tests/redirect.test.tsx +++ b/packages/react-router/tests/redirect.test.tsx @@ -8,7 +8,6 @@ import { import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' -import invariant from 'tiny-invariant' import { Link, RouterProvider, @@ -300,9 +299,9 @@ describe('redirect', () => { expect(router.state.redirect).toBeDefined() expect(router.state.redirect).toBeInstanceOf(Response) - invariant(router.state.redirect) + const redirectResponse = router.state.redirect! - expect(router.state.redirect.options).toEqual({ + expect(redirectResponse.options).toEqual({ _fromLocation: expect.objectContaining({ hash: '', href: '/', @@ -352,10 +351,10 @@ describe('redirect', () => { expect(currentRedirect).toBeDefined() expect(currentRedirect).toBeInstanceOf(Response) - invariant(currentRedirect) - expect(currentRedirect.status).toEqual(307) - expect(currentRedirect.headers.get('Location')).toEqual('/about') - expect(currentRedirect.options).toEqual({ + const redirectResponse = currentRedirect! + expect(redirectResponse.status).toEqual(307) + expect(redirectResponse.headers.get('Location')).toEqual('/about') + expect(redirectResponse.options).toEqual({ _fromLocation: { external: false, hash: '', @@ -366,7 +365,7 @@ describe('redirect', () => { searchStr: '', state: { __TSR_index: 0, - __TSR_key: currentRedirect.options._fromLocation!.state.__TSR_key, + __TSR_key: redirectResponse.options._fromLocation!.state.__TSR_key, key: currentRedirect.options._fromLocation!.state.key, }, }, diff --git a/packages/react-start-client/package.json b/packages/react-start-client/package.json index d098b360a08..88dfa2f150d 100644 --- a/packages/react-start-client/package.json +++ b/packages/react-start-client/package.json @@ -61,9 +61,7 @@ "dependencies": { "@tanstack/react-router": "workspace:*", "@tanstack/router-core": "workspace:*", - "@tanstack/start-client-core": "workspace:*", - "tiny-invariant": "^1.3.3", - "tiny-warning": "^1.0.3" + "@tanstack/start-client-core": "workspace:*" }, "devDependencies": { "@testing-library/react": "^16.2.0", diff --git a/packages/react-start-client/src/renderRSC.tsx b/packages/react-start-client/src/renderRSC.tsx index 4832f074b61..bc8482fc538 100644 --- a/packages/react-start-client/src/renderRSC.tsx +++ b/packages/react-start-client/src/renderRSC.tsx @@ -1,6 +1,6 @@ // TODO: RSCs import { isValidElement } from 'react' -import invariant from 'tiny-invariant' +import { invariant } from '@tanstack/router-core' import type React from 'react' export function renderRsc(input: any): React.JSX.Element { @@ -68,7 +68,11 @@ export function renderRsc(input: any): React.JSX.Element { // return element - invariant(false, 'renderRSC() is coming soon!') + if (process.env.NODE_ENV !== 'production') { + throw new Error('Invariant failed: renderRSC() is coming soon!') + } + + invariant() }) .then((element) => { input.state.value = element diff --git a/packages/router-core/package.json b/packages/router-core/package.json index 63c008514a1..cedab4baef8 100644 --- a/packages/router-core/package.json +++ b/packages/router-core/package.json @@ -165,9 +165,7 @@ "@tanstack/history": "workspace:*", "cookie-es": "^2.0.0", "seroval": "^1.4.2", - "seroval-plugins": "^1.4.2", - "tiny-invariant": "^1.3.3", - "tiny-warning": "^1.0.3" + "seroval-plugins": "^1.4.2" }, "devDependencies": { "@tanstack/store": "^0.9.2", diff --git a/packages/router-core/src/index.ts b/packages/router-core/src/index.ts index ad1389ff23b..649c4fac14e 100644 --- a/packages/router-core/src/index.ts +++ b/packages/router-core/src/index.ts @@ -2,6 +2,7 @@ export * from './global' export { TSR_DEFERRED_PROMISE, defer } from './defer' export type { DeferredPromiseState, DeferredPromise } from './defer' +export { invariant } from './invariant' export { preloadWarning } from './link' export type { IsRequiredParams, diff --git a/packages/router-core/src/invariant.ts b/packages/router-core/src/invariant.ts new file mode 100644 index 00000000000..926b8793a9b --- /dev/null +++ b/packages/router-core/src/invariant.ts @@ -0,0 +1,3 @@ +export function invariant(): never { + throw new Error('Invariant failed') +} diff --git a/packages/router-core/src/load-matches.ts b/packages/router-core/src/load-matches.ts index 84071950781..d212c72b926 100644 --- a/packages/router-core/src/load-matches.ts +++ b/packages/router-core/src/load-matches.ts @@ -1,5 +1,5 @@ -import invariant from 'tiny-invariant' import { isServer } from '@tanstack/router-core/isServer' +import { invariant } from './invariant' import { createControlledPromise, isPromise } from './utils' import { isNotFound } from './not-found' import { rootRouteId } from './root' @@ -1076,10 +1076,15 @@ export async function loadMatches(arg: { notFoundToThrow, ) - invariant( - renderedBoundaryIndex !== undefined, - 'Could not find match for notFound boundary', - ) + if (renderedBoundaryIndex === undefined) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + 'Invariant failed: Could not find match for notFound boundary', + ) + } + + invariant() + } const boundaryMatch = inner.matches[renderedBoundaryIndex]! const boundaryRoute = inner.router.looseRoutesById[boundaryMatch.routeId]! diff --git a/packages/router-core/src/new-process-route-tree.ts b/packages/router-core/src/new-process-route-tree.ts index 213f559f943..6ba6a45c870 100644 --- a/packages/router-core/src/new-process-route-tree.ts +++ b/packages/router-core/src/new-process-route-tree.ts @@ -1,4 +1,4 @@ -import invariant from 'tiny-invariant' +import { invariant } from './invariant' import { createLRUCache } from './lru-cache' import { last } from './utils' import type { LRUCache } from './lru-cache' @@ -811,10 +811,15 @@ export function processRouteTree< parseSegments(caseSensitive, data, routeTree, 1, segmentTree, 0, (route) => { initRoute?.(route, index) - invariant( - !(route.id in routesById), - `Duplicate routes found with id: ${String(route.id)}`, - ) + if (route.id in routesById) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Duplicate routes found with id: ${String(route.id)}`, + ) + } + + invariant() + } routesById[route.id] = route diff --git a/packages/router-core/src/route.ts b/packages/router-core/src/route.ts index ef80228c8bc..7217f883ab6 100644 --- a/packages/router-core/src/route.ts +++ b/packages/router-core/src/route.ts @@ -1,4 +1,4 @@ -import invariant from 'tiny-invariant' +import { invariant } from './invariant' import { joinPaths, trimPathLeft, trimPathRight } from './path' import { notFound } from './not-found' import { redirect } from './redirect' @@ -1808,10 +1808,13 @@ export class BaseRoute< if (isRoot) { this._path = rootRouteId as TPath } else if (!this.parentRoute) { - invariant( - false, - `Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`, - ) + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Child Route instances must pass a 'getParentRoute: () => ParentRoute' option that returns a Route instance.`, + ) + } + + invariant() } let path: undefined | string = isRoot ? rootRouteId : options?.path diff --git a/packages/router-core/src/ssr/ssr-client.ts b/packages/router-core/src/ssr/ssr-client.ts index 49c4627ad22..b2ea33e92bf 100644 --- a/packages/router-core/src/ssr/ssr-client.ts +++ b/packages/router-core/src/ssr/ssr-client.ts @@ -1,4 +1,4 @@ -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { isNotFound } from '../not-found' import { createControlledPromise } from '../utils' import { hydrateSsrMatchId } from './ssr-match-id' @@ -38,10 +38,15 @@ function hydrateMatch( } export async function hydrate(router: AnyRouter): Promise { - invariant( - window.$_TSR, - 'Expected to find bootstrap data on window.$_TSR, but we did not. Please file an issue!', - ) + if (!window.$_TSR) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + 'Invariant failed: Expected to find bootstrap data on window.$_TSR, but we did not. Please file an issue!', + ) + } + + invariant() + } const serializationAdapters = router.options.serializationAdapters as | Array @@ -57,10 +62,15 @@ export async function hydrate(router: AnyRouter): Promise { } window.$_TSR.initialized = true - invariant( - window.$_TSR.router, - 'Expected to find a dehydrated data on window.$_TSR.router, but we did not. Please file an issue!', - ) + if (!window.$_TSR.router) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + 'Invariant failed: Expected to find a dehydrated data on window.$_TSR.router, but we did not. Please file an issue!', + ) + } + + invariant() + } const dehydratedRouter = window.$_TSR.router dehydratedRouter.matches.forEach((dehydratedMatch) => { @@ -258,10 +268,15 @@ export async function hydrate(router: AnyRouter): Promise { // this will prevent that other pending components are rendered but hydration is not blocked if (isSpaMode) { const match = matches[1] - invariant( - match, - 'Expected to find a match below the root match in SPA mode.', - ) + if (!match) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + 'Invariant failed: Expected to find a match below the root match in SPA mode.', + ) + } + + invariant() + } setMatchForcePending(match) match._displayPending = true diff --git a/packages/router-core/src/ssr/ssr-server.ts b/packages/router-core/src/ssr/ssr-server.ts index 0d262ade8a3..3fdd8b24bc8 100644 --- a/packages/router-core/src/ssr/ssr-server.ts +++ b/packages/router-core/src/ssr/ssr-server.ts @@ -1,5 +1,5 @@ import { crossSerializeStream, getCrossReferenceHeader } from 'seroval' -import invariant from 'tiny-invariant' +import { invariant } from '../invariant' import { decodePath } from '../utils' import { createLRUCache } from '../lru-cache' import minifiedTsrBootStrapScript from './tsrScript?script-string' @@ -201,7 +201,13 @@ export function attachRouterServerSsrUtils({ router.serverSsr!.injectHtml(html) }, dehydrate: async () => { - invariant(!_dehydrated, 'router is already dehydrated!') + if (_dehydrated) { + if (process.env.NODE_ENV !== 'production') { + throw new Error('Invariant failed: router is already dehydrated!') + } + + invariant() + } let matchesToDehydrate = router.stores.activeMatchesSnapshot.state if (router.isShell()) { // In SPA mode we only want to dehydrate the root match diff --git a/packages/router-devtools-core/package.json b/packages/router-devtools-core/package.json index 9f8cef77380..5ab08258695 100644 --- a/packages/router-devtools-core/package.json +++ b/packages/router-devtools-core/package.json @@ -63,8 +63,7 @@ }, "dependencies": { "clsx": "^2.1.1", - "goober": "^2.1.16", - "tiny-invariant": "^1.3.3" + "goober": "^2.1.16" }, "devDependencies": { "solid-js": "^1.9.10", diff --git a/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx b/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx index 4ba50cf1cd0..ef68d8ef998 100644 --- a/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx +++ b/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx @@ -1,5 +1,5 @@ import { clsx as cx } from 'clsx' -import { default as invariant } from 'tiny-invariant' +import { invariant } from '@tanstack/router-core' import { interpolatePath, rootRouteId, trimPath } from '@tanstack/router-core' import { For, @@ -264,10 +264,15 @@ export const BaseTanStackRouterDevtoolsPanel = const styles = useStyles() const { className, style, ...otherPanelProps } = panelProps - invariant( - router, - 'No router was found for the TanStack Router Devtools. Please place the devtools in the component tree or pass the router instance to the devtools manually.', - ) + if (!router) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + 'Invariant failed: No router was found for the TanStack Router Devtools. Please place the devtools in the component tree or pass the router instance to the devtools manually.', + ) + } + + invariant() + } // useStore(router.stores.__store) diff --git a/packages/solid-router/package.json b/packages/solid-router/package.json index 585f140f8e5..0b618676917 100644 --- a/packages/solid-router/package.json +++ b/packages/solid-router/package.json @@ -109,9 +109,7 @@ "@solidjs/meta": "^0.29.4", "@tanstack/history": "workspace:*", "@tanstack/router-core": "workspace:*", - "isbot": "^5.1.22", - "tiny-invariant": "^1.3.3", - "tiny-warning": "^1.0.3" + "isbot": "^5.1.22" }, "devDependencies": { "@solidjs/testing-library": "^0.8.10", diff --git a/packages/solid-router/src/Match.tsx b/packages/solid-router/src/Match.tsx index 9ac0e485ea3..2f2320360df 100644 --- a/packages/solid-router/src/Match.tsx +++ b/packages/solid-router/src/Match.tsx @@ -1,9 +1,8 @@ import * as Solid from 'solid-js' -import invariant from 'tiny-invariant' -import warning from 'tiny-warning' import { createControlledPromise, getLocationChangeInfo, + invariant, isNotFound, isRedirect, rootRouteId, @@ -119,10 +118,11 @@ export const Match = (props: { matchId: string }) => { onCatch={(error: Error) => { // Forward not found errors (we don't want to show the error component for these) if (isNotFound(error)) throw error - warning( - false, - `Error in route match: ${currentMatchState().routeId}`, - ) + if (process.env.NODE_ENV !== 'production') { + console.warn( + `Warning: Error in route match: ${currentMatchState().routeId}`, + ) + } routeOnCatch()?.(error) }} > @@ -342,10 +342,15 @@ export const MatchInner = (): any => { {(_) => { - invariant( - isNotFound(currentMatch().error), - 'Expected a notFound error', - ) + if (!isNotFound(currentMatch().error)) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + 'Invariant failed: Expected a notFound error', + ) + } + + invariant() + } // Use Show with keyed to ensure re-render when routeId changes return ( @@ -359,10 +364,15 @@ export const MatchInner = (): any => { {(_) => { - invariant( - isRedirect(currentMatch().error), - 'Expected a redirect error', - ) + if (!isRedirect(currentMatch().error)) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + 'Invariant failed: Expected a redirect error', + ) + } + + invariant() + } const [loaderResult] = Solid.createResource(async () => { await new Promise((r) => setTimeout(r, 0)) diff --git a/packages/solid-router/src/Matches.tsx b/packages/solid-router/src/Matches.tsx index 636a9a73244..1a317693eb6 100644 --- a/packages/solid-router/src/Matches.tsx +++ b/packages/solid-router/src/Matches.tsx @@ -1,5 +1,4 @@ import * as Solid from 'solid-js' -import warning from 'tiny-warning' import { replaceEqualDeep, rootRouteId } from '@tanstack/router-core' import { isServer } from '@tanstack/router-core/isServer' import { CatchBoundary, ErrorComponent } from './CatchBoundary' @@ -103,11 +102,10 @@ function MatchesInner() { onCatch={ process.env.NODE_ENV !== 'production' ? (error) => { - warning( - false, - `The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`, + console.warn( + `Warning: The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`, ) - warning(false, error.message || error.toString()) + console.warn(`Warning: ${error.message || error.toString()}`) } : undefined } diff --git a/packages/solid-router/src/fileRoute.ts b/packages/solid-router/src/fileRoute.ts index dbe12dd722d..5fbdc73d5f6 100644 --- a/packages/solid-router/src/fileRoute.ts +++ b/packages/solid-router/src/fileRoute.ts @@ -1,4 +1,3 @@ -import warning from 'tiny-warning' import { createRoute } from './route' import { useMatch } from './useMatch' @@ -140,10 +139,11 @@ export class FileRoute< THandlers > => { if (process.env.NODE_ENV !== 'production') { - warning( - this.silent, - 'FileRoute is deprecated and will be removed in the next major version. Use the createFileRoute(path)(options) function instead.', - ) + if (!this.silent) { + console.warn( + 'Warning: FileRoute is deprecated and will be removed in the next major version. Use the createFileRoute(path)(options) function instead.', + ) + } } const route = createRoute(options as any) ;(route as any).isRoot = false @@ -177,9 +177,8 @@ export function FileRouteLoader< >, ) => TLoaderFn { if (process.env.NODE_ENV !== 'production') { - warning( - false, - `FileRouteLoader is deprecated and will be removed in the next major version. Please place the loader function in the the main route file, inside the \`createFileRoute('/path/to/file')(options)\` options`, + console.warn( + `Warning: FileRouteLoader is deprecated and will be removed in the next major version. Please place the loader function in the the main route file, inside the \`createFileRoute('/path/to/file')(options)\` options`, ) } return (loaderFn) => loaderFn as any diff --git a/packages/solid-router/src/renderRouteNotFound.tsx b/packages/solid-router/src/renderRouteNotFound.tsx index 9160e624995..078a632e08c 100644 --- a/packages/solid-router/src/renderRouteNotFound.tsx +++ b/packages/solid-router/src/renderRouteNotFound.tsx @@ -1,4 +1,3 @@ -import warning from 'tiny-warning' import { DefaultGlobalNotFound } from './not-found' import type { AnyRoute, AnyRouter } from '@tanstack/router-core' @@ -20,11 +19,12 @@ export function renderRouteNotFound( return } - if (process.env.NODE_ENV === 'development') { - warning( - route.options.notFoundComponent, - `A notFoundError was encountered on the route with ID "${route.id}", but a notFoundComponent option was not configured, nor was a router level defaultNotFoundComponent configured. Consider configuring at least one of these to avoid TanStack Router's overly generic defaultNotFoundComponent (

Not Found

)`, - ) + if (process.env.NODE_ENV !== 'production') { + if (!route.options.notFoundComponent) { + console.warn( + `Warning: A notFoundError was encountered on the route with ID "${route.id}", but a notFoundComponent option was not configured, nor was a router level defaultNotFoundComponent configured. Consider configuring at least one of these to avoid TanStack Router's overly generic defaultNotFoundComponent (

Not Found

)`, + ) + } } return diff --git a/packages/solid-router/src/useMatch.tsx b/packages/solid-router/src/useMatch.tsx index 7c8cae93a55..d8c6f8ec97e 100644 --- a/packages/solid-router/src/useMatch.tsx +++ b/packages/solid-router/src/useMatch.tsx @@ -1,6 +1,5 @@ import * as Solid from 'solid-js' -import invariant from 'tiny-invariant' -import { replaceEqualDeep } from '@tanstack/router-core' +import { invariant, replaceEqualDeep } from '@tanstack/router-core' import { nearestMatchContext } from './matchContext' import { useRouter } from './useRouter' import type { @@ -92,14 +91,19 @@ export function useMatch< ? Boolean(router.stores.pendingRouteIds.state[opts.from!]) : (nearestMatch?.hasPending() ?? false) - invariant( - !( - !hasPendingMatch && - !router.stores.isTransitioning.state && - (opts.shouldThrow ?? true) - ), - `Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`, - ) + if ( + !hasPendingMatch && + !router.stores.isTransitioning.state && + (opts.shouldThrow ?? true) + ) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`, + ) + } + + invariant() + } }) return Solid.createMemo((prev: TSelected | undefined) => { diff --git a/packages/solid-router/src/useRouter.tsx b/packages/solid-router/src/useRouter.tsx index 33cd163cebf..89b53e9d57f 100644 --- a/packages/solid-router/src/useRouter.tsx +++ b/packages/solid-router/src/useRouter.tsx @@ -1,5 +1,4 @@ import * as Solid from 'solid-js' -import warning from 'tiny-warning' import { routerContext } from './routerContext' import type { AnyRouter, RegisteredRouter } from '@tanstack/router-core' @@ -7,9 +6,12 @@ export function useRouter(opts?: { warn?: boolean }): TRouter { const value = Solid.useContext(routerContext as any) - warning( - !((opts?.warn ?? true) && !value), - 'useRouter must be used inside a component!', - ) + if (process.env.NODE_ENV !== 'production') { + if ((opts?.warn ?? true) && !value) { + console.warn( + 'Warning: useRouter must be used inside a component!', + ) + } + } return value as any } diff --git a/packages/solid-router/tests/redirect.test.tsx b/packages/solid-router/tests/redirect.test.tsx index df3326ada03..5d3ecc898ac 100644 --- a/packages/solid-router/tests/redirect.test.tsx +++ b/packages/solid-router/tests/redirect.test.tsx @@ -2,7 +2,6 @@ import { cleanup, fireEvent, render, screen } from '@solidjs/testing-library' import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest' -import invariant from 'tiny-invariant' import { Link, RouterProvider, @@ -293,9 +292,9 @@ describe('redirect', () => { expect(router.state.redirect).toBeDefined() expect(router.state.redirect).toBeInstanceOf(Response) - invariant(router.state.redirect) + const redirectResponse = router.state.redirect! - expect(router.state.redirect.options).toEqual({ + expect(redirectResponse.options).toEqual({ _fromLocation: expect.objectContaining({ hash: '', href: '/', @@ -346,10 +345,10 @@ describe('redirect', () => { expect(currentRedirect).toBeDefined() expect(currentRedirect).toBeInstanceOf(Response) - invariant(currentRedirect) - expect(currentRedirect.status).toEqual(307) - expect(currentRedirect.headers.get('Location')).toEqual('/about') - expect(currentRedirect.options).toEqual({ + const redirectResponse = currentRedirect! + expect(redirectResponse.status).toEqual(307) + expect(redirectResponse.headers.get('Location')).toEqual('/about') + expect(redirectResponse.options).toEqual({ _fromLocation: { external: false, publicHref: '/', @@ -360,8 +359,8 @@ describe('redirect', () => { searchStr: '', state: { __TSR_index: 0, - __TSR_key: currentRedirect.options._fromLocation!.state.__TSR_key, - key: currentRedirect.options._fromLocation!.state.key, + __TSR_key: redirectResponse.options._fromLocation!.state.__TSR_key, + key: redirectResponse.options._fromLocation!.state.key, }, }, href: '/about', diff --git a/packages/solid-start-client/package.json b/packages/solid-start-client/package.json index 21d835cac0e..8448041eb76 100644 --- a/packages/solid-start-client/package.json +++ b/packages/solid-start-client/package.json @@ -61,9 +61,7 @@ "dependencies": { "@tanstack/router-core": "workspace:*", "@tanstack/solid-router": "workspace:*", - "@tanstack/start-client-core": "workspace:*", - "tiny-invariant": "^1.3.3", - "tiny-warning": "^1.0.3" + "@tanstack/start-client-core": "workspace:*" }, "devDependencies": { "@solidjs/testing-library": "^0.8.10", diff --git a/packages/start-client-core/package.json b/packages/start-client-core/package.json index d33f3d260d8..37c39c6907d 100644 --- a/packages/start-client-core/package.json +++ b/packages/start-client-core/package.json @@ -85,9 +85,7 @@ "@tanstack/router-core": "workspace:*", "@tanstack/start-fn-stubs": "workspace:*", "@tanstack/start-storage-context": "workspace:*", - "seroval": "^1.4.2", - "tiny-invariant": "^1.3.3", - "tiny-warning": "^1.0.3" + "seroval": "^1.4.2" }, "devDependencies": { "@tanstack/intent": "^0.0.14", diff --git a/packages/start-client-core/src/client-rpc/serverFnFetcher.ts b/packages/start-client-core/src/client-rpc/serverFnFetcher.ts index 7d543b1df07..0843709ed94 100644 --- a/packages/start-client-core/src/client-rpc/serverFnFetcher.ts +++ b/packages/start-client-core/src/client-rpc/serverFnFetcher.ts @@ -5,7 +5,7 @@ import { parseRedirect, } from '@tanstack/router-core' import { fromCrossJSON, toJSONAsync } from 'seroval' -import invariant from 'tiny-invariant' +import { invariant } from '@tanstack/router-core' import { getDefaultSerovalPlugins } from '../getDefaultSerovalPlugins' import { TSS_CONTENT_TYPE_FRAMED, @@ -185,7 +185,15 @@ async function getResponse(fn: () => Promise) { } const contentType = response.headers.get('content-type') - invariant(contentType, 'expected content-type header to be set') + if (!contentType) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + 'Invariant failed: expected content-type header to be set', + ) + } + + invariant() + } const serializedByStart = !!response.headers.get(X_TSS_SERIALIZED) // If the response is serialized by the start server, we need to process it @@ -239,7 +247,13 @@ async function getResponse(fn: () => Promise) { result = fromCrossJSON(jsonPayload, { plugins: serovalPlugins! }) } - invariant(result, 'expected result to be resolved') + if (!result) { + if (process.env.NODE_ENV !== 'production') { + throw new Error('Invariant failed: expected result to be resolved') + } + + invariant() + } if (result instanceof Error) { throw result } diff --git a/packages/start-server-core/package.json b/packages/start-server-core/package.json index 65d0ac83906..25b4df51153 100644 --- a/packages/start-server-core/package.json +++ b/packages/start-server-core/package.json @@ -83,8 +83,7 @@ "@tanstack/start-client-core": "workspace:*", "@tanstack/start-storage-context": "workspace:*", "h3-v2": "npm:h3@2.0.1-rc.16", - "seroval": "^1.4.2", - "tiny-invariant": "^1.3.3" + "seroval": "^1.4.2" }, "devDependencies": { "@standard-schema/spec": "^1.0.0", diff --git a/packages/start-server-core/src/server-functions-handler.ts b/packages/start-server-core/src/server-functions-handler.ts index 4f5067a7ebd..82fee8e3945 100644 --- a/packages/start-server-core/src/server-functions-handler.ts +++ b/packages/start-server-core/src/server-functions-handler.ts @@ -3,7 +3,7 @@ import { isNotFound, isRedirect, } from '@tanstack/router-core' -import invariant from 'tiny-invariant' +import { invariant } from '@tanstack/router-core' import { TSS_FORMDATA_CONTEXT, X_TSS_RAW_RESPONSE, @@ -88,10 +88,15 @@ export const handleServerAction = async ({ ) ) { // We don't support GET requests with FormData payloads... that seems impossible - invariant( - methodUpper !== 'GET', - 'GET requests with FormData payloads are not supported', - ) + if (methodUpper === 'GET') { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + 'Invariant failed: GET requests with FormData payloads are not supported', + ) + } + + invariant() + } const formData = await request.formData() const serializedContext = formData.get(TSS_FORMDATA_CONTEXT) formData.delete(TSS_FORMDATA_CONTEXT) diff --git a/packages/vue-router/package.json b/packages/vue-router/package.json index ce142fdfc48..7e98229837b 100644 --- a/packages/vue-router/package.json +++ b/packages/vue-router/package.json @@ -78,9 +78,7 @@ "@tanstack/vue-store": "^0.9.2", "@vue/runtime-dom": "^3.5.25", "isbot": "^5.1.22", - "jsesc": "^3.0.2", - "tiny-invariant": "^1.3.3", - "tiny-warning": "^1.0.3" + "jsesc": "^3.0.2" }, "devDependencies": { "@tanstack/intent": "^0.0.14", diff --git a/packages/vue-router/src/Match.tsx b/packages/vue-router/src/Match.tsx index ddc4cb83c25..104ec3a2908 100644 --- a/packages/vue-router/src/Match.tsx +++ b/packages/vue-router/src/Match.tsx @@ -1,9 +1,8 @@ import * as Vue from 'vue' -import invariant from 'tiny-invariant' -import warning from 'tiny-warning' import { createControlledPromise, getLocationChangeInfo, + invariant, isNotFound, isRedirect, rootRouteId, @@ -42,10 +41,15 @@ export const Match = Vue.defineComponent({ props.matchId, )?.routeId - invariant( - routeId, - `Could not find routeId for matchId "${props.matchId}". Please file an issue!`, - ) + if (!routeId) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Could not find routeId for matchId "${props.matchId}". Please file an issue!`, + ) + } + + invariant() + } // Static route-tree check: is this route a direct child of the root? // parentRoute is set at build time, so no reactive tracking needed. @@ -187,7 +191,9 @@ export const Match = Vue.defineComponent({ onCatch: (error: Error) => { // Forward not found errors (we don't want to show the error component for these) if (isNotFound(error)) throw error - warning(false, `Error in route match: ${actualMatchId}`) + if (process.env.NODE_ENV !== 'production') { + console.warn(`Warning: Error in route match: ${actualMatchId}`) + } routeOnCatch.value?.(error) }, children: content, @@ -358,12 +364,24 @@ export const MatchInner = Vue.defineComponent({ } if (match.value.status === 'notFound') { - invariant(isNotFound(match.value.error), 'Expected a notFound error') + if (!isNotFound(match.value.error)) { + if (process.env.NODE_ENV !== 'production') { + throw new Error('Invariant failed: Expected a notFound error') + } + + invariant() + } return renderRouteNotFound(router, route.value, match.value.error) } if (match.value.status === 'redirected') { - invariant(isRedirect(match.value.error), 'Expected a redirect error') + if (!isRedirect(match.value.error)) { + if (process.env.NODE_ENV !== 'production') { + throw new Error('Invariant failed: Expected a redirect error') + } + + invariant() + } throw router.getMatch(match.value.id)?._nonReactive.loadPromise } diff --git a/packages/vue-router/src/Matches.tsx b/packages/vue-router/src/Matches.tsx index 88c1875550a..b3de324dbe9 100644 --- a/packages/vue-router/src/Matches.tsx +++ b/packages/vue-router/src/Matches.tsx @@ -1,5 +1,4 @@ import * as Vue from 'vue' -import warning from 'tiny-warning' import { isServer } from '@tanstack/router-core/isServer' import { useStore } from '@tanstack/vue-store' import { CatchBoundary } from './CatchBoundary' @@ -129,11 +128,10 @@ const MatchesInner = Vue.defineComponent({ onCatch: process.env.NODE_ENV !== 'production' ? (error: Error) => { - warning( - false, - `The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`, + console.warn( + `Warning: The following error wasn't caught by any route! At the very least, consider setting an 'errorComponent' in your RootRoute!`, ) - warning(false, error.message || error.toString()) + console.warn(`Warning: ${error.message || error.toString()}`) } : undefined, children: childElement, diff --git a/packages/vue-router/src/fileRoute.ts b/packages/vue-router/src/fileRoute.ts index 94ae9ccb9fa..e377665307c 100644 --- a/packages/vue-router/src/fileRoute.ts +++ b/packages/vue-router/src/fileRoute.ts @@ -1,4 +1,3 @@ -import warning from 'tiny-warning' import { createRoute } from './route' import { useMatch } from './useMatch' @@ -140,10 +139,11 @@ export class FileRoute< THandlers > => { if (process.env.NODE_ENV !== 'production') { - warning( - this.silent, - 'FileRoute is deprecated and will be removed in the next major version. Use the createFileRoute(path)(options) function instead.', - ) + if (!this.silent) { + console.warn( + 'Warning: FileRoute is deprecated and will be removed in the next major version. Use the createFileRoute(path)(options) function instead.', + ) + } } const route = createRoute(options as any) ;(route as any).isRoot = false @@ -177,9 +177,8 @@ export function FileRouteLoader< >, ) => TLoaderFn { if (process.env.NODE_ENV !== 'production') { - warning( - false, - `FileRouteLoader is deprecated and will be removed in the next major version. Please place the loader function in the the main route file, inside the \`createFileRoute('/path/to/file')(options)\` options`, + console.warn( + `Warning: FileRouteLoader is deprecated and will be removed in the next major version. Please place the loader function in the the main route file, inside the \`createFileRoute('/path/to/file')(options)\` options`, ) } return (loaderFn) => loaderFn as any diff --git a/packages/vue-router/src/renderRouteNotFound.tsx b/packages/vue-router/src/renderRouteNotFound.tsx index 63ec147f7e8..600a66a7f5f 100644 --- a/packages/vue-router/src/renderRouteNotFound.tsx +++ b/packages/vue-router/src/renderRouteNotFound.tsx @@ -1,5 +1,4 @@ import * as Vue from 'vue' -import warning from 'tiny-warning' import { DefaultGlobalNotFound } from './not-found' import type { AnyRoute, AnyRouter } from '@tanstack/router-core' @@ -21,11 +20,12 @@ export function renderRouteNotFound( return Vue.h(router.options.defaultNotFoundComponent as any, data) } - if (process.env.NODE_ENV === 'development') { - warning( - route.options.notFoundComponent, - `A notFoundError was encountered on the route with ID "${route.id}", but a notFoundComponent option was not configured, nor was a router level defaultNotFoundComponent configured. Consider configuring at least one of these to avoid TanStack Router's overly generic defaultNotFoundComponent (

Not Found

)`, - ) + if (process.env.NODE_ENV !== 'production') { + if (!route.options.notFoundComponent) { + console.warn( + `Warning: A notFoundError was encountered on the route with ID "${route.id}", but a notFoundComponent option was not configured, nor was a router level defaultNotFoundComponent configured. Consider configuring at least one of these to avoid TanStack Router's overly generic defaultNotFoundComponent (

Not Found

)`, + ) + } } return Vue.h(DefaultGlobalNotFound) diff --git a/packages/vue-router/src/useMatch.tsx b/packages/vue-router/src/useMatch.tsx index c7ac0e96b7a..d4d54b02154 100644 --- a/packages/vue-router/src/useMatch.tsx +++ b/packages/vue-router/src/useMatch.tsx @@ -1,7 +1,7 @@ import * as Vue from 'vue' +import { invariant } from '@tanstack/router-core' import { useStore } from '@tanstack/vue-store' import { isServer } from '@tanstack/router-core/isServer' -import invariant from 'tiny-invariant' import { injectDummyPendingMatch, injectPendingMatch, @@ -87,10 +87,15 @@ export function useMatch< : undefined const match = matchStore?.state - invariant( - !((opts.shouldThrow ?? true) && !match), - `Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`, - ) + if ((opts.shouldThrow ?? true) && !match) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`, + ) + } + + invariant() + } if (match === undefined) { return Vue.ref(undefined) as Vue.Ref< @@ -151,14 +156,19 @@ export function useMatch< const hasPendingMatch = opts.from ? Boolean(hasPendingRouteMatch?.value[opts.from!]) : hasPendingNearestMatch.value - invariant( - !( - !hasPendingMatch && - !isTransitioning.value && - (opts.shouldThrow ?? true) - ), - `Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`, - ) + if ( + !hasPendingMatch && + !isTransitioning.value && + (opts.shouldThrow ?? true) + ) { + if (process.env.NODE_ENV !== 'production') { + throw new Error( + `Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`, + ) + } + + invariant() + } return undefined } diff --git a/packages/vue-router/src/useRouter.tsx b/packages/vue-router/src/useRouter.tsx index aa90b01a02f..e0fd91292bb 100644 --- a/packages/vue-router/src/useRouter.tsx +++ b/packages/vue-router/src/useRouter.tsx @@ -1,5 +1,4 @@ import * as Vue from 'vue' -import warning from 'tiny-warning' import { routerContext } from './routerContext' import type { AnyRouter, RegisteredRouter } from '@tanstack/router-core' @@ -7,9 +6,12 @@ export function useRouter(opts?: { warn?: boolean }): TRouter { const value = Vue.inject(routerContext as any, null) - warning( - !((opts?.warn ?? true) && !value), - 'useRouter must be used inside a component!', - ) + if (process.env.NODE_ENV !== 'production') { + if ((opts?.warn ?? true) && !value) { + console.warn( + 'Warning: useRouter must be used inside a component!', + ) + } + } return value as any } diff --git a/packages/vue-router/tests/redirect.test.tsx b/packages/vue-router/tests/redirect.test.tsx index fc9a998157e..f198f8adf68 100644 --- a/packages/vue-router/tests/redirect.test.tsx +++ b/packages/vue-router/tests/redirect.test.tsx @@ -1,7 +1,6 @@ import { cleanup, fireEvent, render, screen } from '@testing-library/vue' import { afterEach, describe, expect, test, vi } from 'vitest' -import invariant from 'tiny-invariant' import { Link, @@ -283,9 +282,9 @@ describe('redirect', () => { expect(router.state.redirect).toBeDefined() expect(router.state.redirect).toBeInstanceOf(Response) - invariant(router.state.redirect) + const redirectResponse = router.state.redirect! - expect(router.state.redirect.options).toEqual({ + expect(redirectResponse.options).toEqual({ _fromLocation: expect.objectContaining({ hash: '', href: '/', @@ -335,9 +334,9 @@ describe('redirect', () => { expect(currentRedirect).toBeDefined() expect(currentRedirect).toBeInstanceOf(Response) - invariant(currentRedirect) + const redirectResponse = currentRedirect! - expect(currentRedirect.options).toEqual({ + expect(redirectResponse.options).toEqual({ _fromLocation: expect.objectContaining({ hash: '', href: '/', diff --git a/packages/vue-start-client/package.json b/packages/vue-start-client/package.json index c1a6ccab939..5a49f771e19 100644 --- a/packages/vue-start-client/package.json +++ b/packages/vue-start-client/package.json @@ -61,9 +61,7 @@ "dependencies": { "@tanstack/router-core": "workspace:*", "@tanstack/vue-router": "workspace:*", - "@tanstack/start-client-core": "workspace:*", - "tiny-invariant": "^1.3.3", - "tiny-warning": "^1.0.3" + "@tanstack/start-client-core": "workspace:*" }, "devDependencies": { "@testing-library/vue": "^8.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 81b0857a537..78b11833717 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8765,9 +8765,6 @@ importers: tailwind-merge: specifier: ^2.6.0 version: 2.6.0 - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 zod: specifier: ^3.24.2 version: 3.25.57 @@ -9172,9 +9169,6 @@ importers: tailwind-merge: specifier: ^2.6.0 version: 2.6.0 - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 zod: specifier: ^3.24.2 version: 3.25.57 @@ -11762,12 +11756,6 @@ importers: isbot: specifier: ^5.1.22 version: 5.1.28 - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 - tiny-warning: - specifier: ^1.0.3 - version: 1.0.3 devDependencies: '@testing-library/jest-dom': specifier: ^6.6.3 @@ -11907,12 +11895,6 @@ importers: react-dom: specifier: ^19.2.3 version: 19.2.3(react@19.2.3) - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 - tiny-warning: - specifier: ^1.0.3 - version: 1.0.3 devDependencies: '@testing-library/react': specifier: ^16.2.0 @@ -11991,12 +11973,6 @@ importers: seroval-plugins: specifier: ^1.4.2 version: 1.4.2(seroval@1.4.2) - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 - tiny-warning: - specifier: ^1.0.3 - version: 1.0.3 devDependencies: '@tanstack/intent': specifier: ^0.0.14 @@ -12056,9 +12032,6 @@ importers: goober: specifier: ^2.1.16 version: 2.1.16(csstype@3.1.3) - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 devDependencies: solid-js: specifier: 1.9.10 @@ -12259,12 +12232,6 @@ importers: isbot: specifier: ^5.1.22 version: 5.1.28 - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 - tiny-warning: - specifier: ^1.0.3 - version: 1.0.3 devDependencies: '@solidjs/testing-library': specifier: ^0.8.10 @@ -12395,12 +12362,6 @@ importers: solid-js: specifier: 1.9.10 version: 1.9.10 - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 - tiny-warning: - specifier: ^1.0.3 - version: 1.0.3 devDependencies: '@solidjs/testing-library': specifier: ^0.8.10 @@ -12463,12 +12424,6 @@ importers: seroval: specifier: ^1.4.2 version: 1.4.2 - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 - tiny-warning: - specifier: ^1.0.3 - version: 1.0.3 devDependencies: '@tanstack/intent': specifier: ^0.0.14 @@ -12582,9 +12537,6 @@ importers: seroval: specifier: ^1.4.2 version: 1.4.2 - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 devDependencies: '@standard-schema/spec': specifier: ^1.0.0 @@ -12684,12 +12636,6 @@ importers: jsesc: specifier: ^3.0.2 version: 3.1.0 - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 - tiny-warning: - specifier: ^1.0.3 - version: 1.0.3 devDependencies: '@tanstack/intent': specifier: ^0.0.14 @@ -12820,12 +12766,6 @@ importers: '@tanstack/vue-router': specifier: workspace:* version: link:../vue-router - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 - tiny-warning: - specifier: ^1.0.3 - version: 1.0.3 devDependencies: '@testing-library/jest-dom': specifier: ^6.6.3 @@ -24260,9 +24200,6 @@ packages: tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} - tiny-warning@1.0.3: - resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} - tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -38480,8 +38417,6 @@ snapshots: tiny-invariant@1.3.3: {} - tiny-warning@1.0.3: {} - tinybench@2.9.0: {} tinyexec@0.3.2: {} From be913e7938d3aa1466244449ee4cdf80a3b248f0 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Sat, 21 Mar 2026 22:02:16 +0100 Subject: [PATCH 2/4] fix: address review feedback on example invariants --- examples/react/start-convex-trellaux/convex/invariant.ts | 4 ++-- .../react/start-convex-trellaux/src/components/Column.tsx | 2 +- examples/react/start-convex-trellaux/src/invariant.ts | 4 ++-- examples/react/start-trellaux/src/components/Column.tsx | 2 +- examples/react/start-trellaux/src/invariant.ts | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/react/start-convex-trellaux/convex/invariant.ts b/examples/react/start-convex-trellaux/convex/invariant.ts index 8aae0868323..41fcded35ef 100644 --- a/examples/react/start-convex-trellaux/convex/invariant.ts +++ b/examples/react/start-convex-trellaux/convex/invariant.ts @@ -1,5 +1,5 @@ -export function invariant(value: unknown, message: string): asserts value { +export function invariant(value: unknown, message?: string): asserts value { if (!value) { - throw new Error(message) + throw new Error(message ?? 'Invariant failed') } } diff --git a/examples/react/start-convex-trellaux/src/components/Column.tsx b/examples/react/start-convex-trellaux/src/components/Column.tsx index b9a59887833..fdf2916f6b1 100644 --- a/examples/react/start-convex-trellaux/src/components/Column.tsx +++ b/examples/react/start-convex-trellaux/src/components/Column.tsx @@ -1,8 +1,8 @@ import { forwardRef, useCallback, useMemo, useRef, useState } from 'react' -import { invariant } from '../invariant' import { twMerge } from 'tailwind-merge' import { flushSync } from 'react-dom' +import { invariant } from '../invariant' import { CONTENT_TYPES } from '../types' import { Icon } from '../icons/icons' import { diff --git a/examples/react/start-convex-trellaux/src/invariant.ts b/examples/react/start-convex-trellaux/src/invariant.ts index 8aae0868323..41fcded35ef 100644 --- a/examples/react/start-convex-trellaux/src/invariant.ts +++ b/examples/react/start-convex-trellaux/src/invariant.ts @@ -1,5 +1,5 @@ -export function invariant(value: unknown, message: string): asserts value { +export function invariant(value: unknown, message?: string): asserts value { if (!value) { - throw new Error(message) + throw new Error(message ?? 'Invariant failed') } } diff --git a/examples/react/start-trellaux/src/components/Column.tsx b/examples/react/start-trellaux/src/components/Column.tsx index 9f3387c61fc..a95faedb54a 100644 --- a/examples/react/start-trellaux/src/components/Column.tsx +++ b/examples/react/start-trellaux/src/components/Column.tsx @@ -1,8 +1,8 @@ import { forwardRef, useCallback, useMemo, useRef, useState } from 'react' -import { invariant } from '../invariant' import { twMerge } from 'tailwind-merge' import { flushSync } from 'react-dom' +import { invariant } from '../invariant' import { CONTENT_TYPES } from '../types' import { Icon } from '../icons/icons' import { diff --git a/examples/react/start-trellaux/src/invariant.ts b/examples/react/start-trellaux/src/invariant.ts index 8aae0868323..41fcded35ef 100644 --- a/examples/react/start-trellaux/src/invariant.ts +++ b/examples/react/start-trellaux/src/invariant.ts @@ -1,5 +1,5 @@ -export function invariant(value: unknown, message: string): asserts value { +export function invariant(value: unknown, message?: string): asserts value { if (!value) { - throw new Error(message) + throw new Error(message ?? 'Invariant failed') } } From 7080e2903add1dd5dc5f924067931a5c2f170f88 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Sat, 21 Mar 2026 22:25:39 +0100 Subject: [PATCH 3/4] fix: resolve CI lint and type failures --- packages/react-router/tests/redirect.test.tsx | 2 +- .../src/BaseTanStackRouterDevtoolsPanel.tsx | 11 ----------- .../src/client-rpc/serverFnFetcher.ts | 2 +- .../start-server-core/src/server-functions-handler.ts | 2 +- 4 files changed, 3 insertions(+), 14 deletions(-) diff --git a/packages/react-router/tests/redirect.test.tsx b/packages/react-router/tests/redirect.test.tsx index 0b1d644db60..a391d02898f 100644 --- a/packages/react-router/tests/redirect.test.tsx +++ b/packages/react-router/tests/redirect.test.tsx @@ -366,7 +366,7 @@ describe('redirect', () => { state: { __TSR_index: 0, __TSR_key: redirectResponse.options._fromLocation!.state.__TSR_key, - key: currentRedirect.options._fromLocation!.state.key, + key: redirectResponse.options._fromLocation!.state.key, }, }, href: '/about', diff --git a/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx b/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx index ef68d8ef998..883d07f6a65 100644 --- a/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx +++ b/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx @@ -1,5 +1,4 @@ import { clsx as cx } from 'clsx' -import { invariant } from '@tanstack/router-core' import { interpolatePath, rootRouteId, trimPath } from '@tanstack/router-core' import { For, @@ -264,16 +263,6 @@ export const BaseTanStackRouterDevtoolsPanel = const styles = useStyles() const { className, style, ...otherPanelProps } = panelProps - if (!router) { - if (process.env.NODE_ENV !== 'production') { - throw new Error( - 'Invariant failed: No router was found for the TanStack Router Devtools. Please place the devtools in the component tree or pass the router instance to the devtools manually.', - ) - } - - invariant() - } - // useStore(router.stores.__store) const [currentTab, setCurrentTab] = useLocalStorage< diff --git a/packages/start-client-core/src/client-rpc/serverFnFetcher.ts b/packages/start-client-core/src/client-rpc/serverFnFetcher.ts index 0843709ed94..a260928a11f 100644 --- a/packages/start-client-core/src/client-rpc/serverFnFetcher.ts +++ b/packages/start-client-core/src/client-rpc/serverFnFetcher.ts @@ -1,11 +1,11 @@ import { createRawStreamDeserializePlugin, encode, + invariant, isNotFound, parseRedirect, } from '@tanstack/router-core' import { fromCrossJSON, toJSONAsync } from 'seroval' -import { invariant } from '@tanstack/router-core' import { getDefaultSerovalPlugins } from '../getDefaultSerovalPlugins' import { TSS_CONTENT_TYPE_FRAMED, diff --git a/packages/start-server-core/src/server-functions-handler.ts b/packages/start-server-core/src/server-functions-handler.ts index 82fee8e3945..7b3b34585be 100644 --- a/packages/start-server-core/src/server-functions-handler.ts +++ b/packages/start-server-core/src/server-functions-handler.ts @@ -1,9 +1,9 @@ import { createRawStreamRPCPlugin, + invariant, isNotFound, isRedirect, } from '@tanstack/router-core' -import { invariant } from '@tanstack/router-core' import { TSS_FORMDATA_CONTEXT, X_TSS_RAW_RESPONSE, From ab841275984e36e4d8db8080c2c62a44f11af3a2 Mon Sep 17 00:00:00 2001 From: Sheraff Date: Sun, 22 Mar 2026 08:45:33 +0100 Subject: [PATCH 4/4] changeset --- .changeset/light-coins-hear.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .changeset/light-coins-hear.md diff --git a/.changeset/light-coins-hear.md b/.changeset/light-coins-hear.md new file mode 100644 index 00000000000..56212448572 --- /dev/null +++ b/.changeset/light-coins-hear.md @@ -0,0 +1,14 @@ +--- +'@tanstack/router-devtools-core': patch +'@tanstack/react-start-client': patch +'@tanstack/solid-start-client': patch +'@tanstack/start-client-core': patch +'@tanstack/start-server-core': patch +'@tanstack/vue-start-client': patch +'@tanstack/react-router': patch +'@tanstack/solid-router': patch +'@tanstack/router-core': patch +'@tanstack/vue-router': patch +--- + +Replace tiny-invariant and tiny-warning with in-house solution for bundle-size