@tanstack/react-router 1.81.6 → 1.81.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,11 @@
1
1
  import * as React from "react";
2
2
  import invariant from "tiny-invariant";
3
3
  import { useRouterState } from "./useRouterState.js";
4
- import { matchContext } from "./matchContext.js";
4
+ import { dummyMatchContext, matchContext } from "./matchContext.js";
5
5
  function useMatch(opts) {
6
- const nearestMatchId = React.useContext(matchContext);
6
+ const nearestMatchId = React.useContext(
7
+ opts.from ? dummyMatchContext : matchContext
8
+ );
7
9
  const matchSelection = useRouterState({
8
10
  select: (state) => {
9
11
  const match = state.matches.find(
@@ -1 +1 @@
1
- {"version":3,"file":"useMatch.js","sources":["../../src/useMatch.tsx"],"sourcesContent":["import * as React from 'react'\nimport invariant from 'tiny-invariant'\nimport { useRouterState } from './useRouterState'\nimport { matchContext } from './matchContext'\nimport type {\n StructuralSharingOption,\n ValidateSelected,\n} from './structuralSharing'\nimport type { AnyRouter, RegisteredRouter } from './router'\nimport type { MakeRouteMatch } from './Matches'\nimport type { StrictOrFrom, ThrowOrOptional } from './utils'\n\nexport interface UseMatchBaseOptions<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TThrow,\n TSelected,\n TStructuralSharing extends boolean,\n> {\n select?: (\n match: MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>,\n ) => ValidateSelected<TRouter, TSelected, TStructuralSharing>\n shouldThrow?: TThrow\n}\n\nexport type UseMatchRoute<out TFrom> = <\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n TStructuralSharing extends boolean = boolean,\n>(\n opts?: UseMatchBaseOptions<\n TRouter,\n TFrom,\n true,\n true,\n TSelected,\n TStructuralSharing\n > &\n StructuralSharingOption<TRouter, TSelected, TStructuralSharing>,\n) => UseMatchResult<TRouter, TFrom, true, TSelected>\n\nexport type UseMatchOptions<\n TRouter extends AnyRouter,\n TFrom extends string | undefined,\n TStrict extends boolean,\n TSelected,\n TThrow extends boolean,\n TStructuralSharing extends boolean,\n> = StrictOrFrom<TRouter, TFrom, TStrict> &\n UseMatchBaseOptions<\n TRouter,\n TFrom,\n TStrict,\n TThrow,\n TSelected,\n TStructuralSharing\n > &\n StructuralSharingOption<TRouter, TSelected, TStructuralSharing>\n\nexport type UseMatchResult<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TSelected,\n> = unknown extends TSelected\n ? MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>\n : TSelected\n\nexport function useMatch<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string | undefined = undefined,\n TStrict extends boolean = true,\n TThrow extends boolean = true,\n TSelected = unknown,\n TStructuralSharing extends boolean = boolean,\n>(\n opts: UseMatchOptions<\n TRouter,\n TFrom,\n TStrict,\n TSelected,\n TThrow,\n TStructuralSharing\n >,\n): ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow> {\n const nearestMatchId = React.useContext(matchContext)\n\n const matchSelection = useRouterState({\n select: (state: any) => {\n const match = state.matches.find((d: any) =>\n opts.from ? opts.from === d.routeId : d.id === nearestMatchId,\n )\n invariant(\n !((opts.shouldThrow ?? true) && !match),\n `Could not find ${opts.from ? `an active match from \"${opts.from}\"` : 'a nearest match!'}`,\n )\n\n if (match === undefined) {\n return undefined\n }\n\n return opts.select ? opts.select(match) : match\n },\n structuralSharing: opts.structuralSharing,\n } as any)\n\n return matchSelection as any\n}\n"],"names":[],"mappings":";;;;AAqEO,SAAS,SAQd,MAQ6E;AACvE,QAAA,iBAAiB,MAAM,WAAW,YAAY;AAEpD,QAAM,iBAAiB,eAAe;AAAA,IACpC,QAAQ,CAAC,UAAe;AAChB,YAAA,QAAQ,MAAM,QAAQ;AAAA,QAAK,CAAC,MAChC,KAAK,OAAO,KAAK,SAAS,EAAE,UAAU,EAAE,OAAO;AAAA,MACjD;AACA;AAAA,QACE,GAAG,KAAK,eAAe,SAAS,CAAC;AAAA,QACjC,kBAAkB,KAAK,OAAO,yBAAyB,KAAK,IAAI,MAAM,kBAAkB;AAAA,MAC1F;AAEA,UAAI,UAAU,QAAW;AAChB,eAAA;AAAA,MAAA;AAGT,aAAO,KAAK,SAAS,KAAK,OAAO,KAAK,IAAI;AAAA,IAC5C;AAAA,IACA,mBAAmB,KAAK;AAAA,EAAA,CAClB;AAED,SAAA;AACT;"}
1
+ {"version":3,"file":"useMatch.js","sources":["../../src/useMatch.tsx"],"sourcesContent":["import * as React from 'react'\nimport invariant from 'tiny-invariant'\nimport { useRouterState } from './useRouterState'\nimport { dummyMatchContext, matchContext } from './matchContext'\nimport type {\n StructuralSharingOption,\n ValidateSelected,\n} from './structuralSharing'\nimport type { AnyRouter, RegisteredRouter } from './router'\nimport type { MakeRouteMatch } from './Matches'\nimport type { StrictOrFrom, ThrowOrOptional } from './utils'\n\nexport interface UseMatchBaseOptions<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TThrow,\n TSelected,\n TStructuralSharing extends boolean,\n> {\n select?: (\n match: MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>,\n ) => ValidateSelected<TRouter, TSelected, TStructuralSharing>\n shouldThrow?: TThrow\n}\n\nexport type UseMatchRoute<out TFrom> = <\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n TStructuralSharing extends boolean = boolean,\n>(\n opts?: UseMatchBaseOptions<\n TRouter,\n TFrom,\n true,\n true,\n TSelected,\n TStructuralSharing\n > &\n StructuralSharingOption<TRouter, TSelected, TStructuralSharing>,\n) => UseMatchResult<TRouter, TFrom, true, TSelected>\n\nexport type UseMatchOptions<\n TRouter extends AnyRouter,\n TFrom extends string | undefined,\n TStrict extends boolean,\n TSelected,\n TThrow extends boolean,\n TStructuralSharing extends boolean,\n> = StrictOrFrom<TRouter, TFrom, TStrict> &\n UseMatchBaseOptions<\n TRouter,\n TFrom,\n TStrict,\n TThrow,\n TSelected,\n TStructuralSharing\n > &\n StructuralSharingOption<TRouter, TSelected, TStructuralSharing>\n\nexport type UseMatchResult<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TSelected,\n> = unknown extends TSelected\n ? MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>\n : TSelected\n\nexport function useMatch<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends string | undefined = undefined,\n TStrict extends boolean = true,\n TThrow extends boolean = true,\n TSelected = unknown,\n TStructuralSharing extends boolean = boolean,\n>(\n opts: UseMatchOptions<\n TRouter,\n TFrom,\n TStrict,\n TSelected,\n TThrow,\n TStructuralSharing\n >,\n): ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow> {\n const nearestMatchId = React.useContext(\n opts.from ? dummyMatchContext : matchContext,\n )\n\n const matchSelection = useRouterState({\n select: (state: any) => {\n const match = state.matches.find((d: any) =>\n opts.from ? opts.from === d.routeId : d.id === nearestMatchId,\n )\n invariant(\n !((opts.shouldThrow ?? true) && !match),\n `Could not find ${opts.from ? `an active match from \"${opts.from}\"` : 'a nearest match!'}`,\n )\n\n if (match === undefined) {\n return undefined\n }\n\n return opts.select ? opts.select(match) : match\n },\n structuralSharing: opts.structuralSharing,\n } as any)\n\n return matchSelection as any\n}\n"],"names":[],"mappings":";;;;AAqEO,SAAS,SAQd,MAQ6E;AAC7E,QAAM,iBAAiB,MAAM;AAAA,IAC3B,KAAK,OAAO,oBAAoB;AAAA,EAClC;AAEA,QAAM,iBAAiB,eAAe;AAAA,IACpC,QAAQ,CAAC,UAAe;AAChB,YAAA,QAAQ,MAAM,QAAQ;AAAA,QAAK,CAAC,MAChC,KAAK,OAAO,KAAK,SAAS,EAAE,UAAU,EAAE,OAAO;AAAA,MACjD;AACA;AAAA,QACE,GAAG,KAAK,eAAe,SAAS,CAAC;AAAA,QACjC,kBAAkB,KAAK,OAAO,yBAAyB,KAAK,IAAI,MAAM,kBAAkB;AAAA,MAC1F;AAEA,UAAI,UAAU,QAAW;AAChB,eAAA;AAAA,MAAA;AAGT,aAAO,KAAK,SAAS,KAAK,OAAO,KAAK,IAAI;AAAA,IAC5C;AAAA,IACA,mBAAmB,KAAK;AAAA,EAAA,CAClB;AAED,SAAA;AACT;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-router",
3
- "version": "1.81.6",
3
+ "version": "1.81.7",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -1,3 +1,8 @@
1
1
  import * as React from 'react'
2
2
 
3
3
  export const matchContext = React.createContext<string | undefined>(undefined)
4
+
5
+ // N.B. this only exists so we can conditionally call useContext on it when we are not interested in the nearest match
6
+ export const dummyMatchContext = React.createContext<string | undefined>(
7
+ undefined,
8
+ )
package/src/router.ts CHANGED
@@ -490,7 +490,7 @@ export interface RouterErrorSerializer<TSerializedError> {
490
490
 
491
491
  export interface RouterState<
492
492
  TRouteTree extends AnyRoute = AnyRoute,
493
- TRouteMatch = MakeRouteMatch<TRouteTree>,
493
+ TRouteMatch = MakeRouteMatchUnion,
494
494
  > {
495
495
  status: 'pending' | 'idle'
496
496
  loadedAt: number
@@ -1242,9 +1242,11 @@ export class Router<
1242
1242
  // pending matches that are still loading
1243
1243
  const existingMatch = this.getMatch(matchId)
1244
1244
 
1245
- const cause = this.state.matches.find((d) => d.id === matchId)
1246
- ? 'stay'
1247
- : 'enter'
1245
+ const previousMatch = this.state.matches.find(
1246
+ (d) => d.routeId === route.id,
1247
+ )
1248
+
1249
+ const cause = previousMatch ? 'stay' : 'enter'
1248
1250
 
1249
1251
  let match: AnyRouteMatch
1250
1252
 
@@ -1252,7 +1254,12 @@ export class Router<
1252
1254
  match = {
1253
1255
  ...existingMatch,
1254
1256
  cause,
1255
- params: routeParams,
1257
+ params: previousMatch
1258
+ ? replaceEqualDeep(previousMatch.params, routeParams)
1259
+ : routeParams,
1260
+ search: previousMatch
1261
+ ? replaceEqualDeep(previousMatch.search, preMatchSearch)
1262
+ : replaceEqualDeep(existingMatch.search, preMatchSearch),
1256
1263
  }
1257
1264
  } else {
1258
1265
  const status =
@@ -1267,10 +1274,14 @@ export class Router<
1267
1274
  id: matchId,
1268
1275
  index,
1269
1276
  routeId: route.id,
1270
- params: routeParams,
1277
+ params: previousMatch
1278
+ ? replaceEqualDeep(previousMatch.params, routeParams)
1279
+ : routeParams,
1271
1280
  pathname: joinPaths([this.basepath, interpolatedPath]),
1272
1281
  updatedAt: Date.now(),
1273
- search: {} as any,
1282
+ search: previousMatch
1283
+ ? replaceEqualDeep(previousMatch.search, preMatchSearch)
1284
+ : preMatchSearch,
1274
1285
  searchError: undefined,
1275
1286
  status,
1276
1287
  isFetching: false,
@@ -1282,7 +1293,9 @@ export class Router<
1282
1293
  abortController: new AbortController(),
1283
1294
  fetchCount: 0,
1284
1295
  cause,
1285
- loaderDeps,
1296
+ loaderDeps: previousMatch
1297
+ ? replaceEqualDeep(previousMatch.loaderDeps, loaderDeps)
1298
+ : loaderDeps,
1286
1299
  invalid: false,
1287
1300
  preload: false,
1288
1301
  links: route.options.links?.(),
@@ -1314,10 +1327,7 @@ export class Router<
1314
1327
  match.globalNotFound = globalNotFoundRouteId === route.id
1315
1328
  }
1316
1329
 
1317
- // Regardless of whether we're reusing an existing match or creating
1318
- // a new one, we need to update the match's search params
1319
- match.search = replaceEqualDeep(match.search, preMatchSearch)
1320
- // And also update the searchError if there is one
1330
+ // update the searchError if there is one
1321
1331
  match.searchError = searchError
1322
1332
 
1323
1333
  const parentMatchId = parentMatch?.id
package/src/useMatch.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react'
2
2
  import invariant from 'tiny-invariant'
3
3
  import { useRouterState } from './useRouterState'
4
- import { matchContext } from './matchContext'
4
+ import { dummyMatchContext, matchContext } from './matchContext'
5
5
  import type {
6
6
  StructuralSharingOption,
7
7
  ValidateSelected,
@@ -84,7 +84,9 @@ export function useMatch<
84
84
  TStructuralSharing
85
85
  >,
86
86
  ): ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow> {
87
- const nearestMatchId = React.useContext(matchContext)
87
+ const nearestMatchId = React.useContext(
88
+ opts.from ? dummyMatchContext : matchContext,
89
+ )
88
90
 
89
91
  const matchSelection = useRouterState({
90
92
  select: (state: any) => {