@tanstack/react-router 1.81.6 → 1.81.9

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.
@@ -371,7 +371,7 @@ export interface RouterErrorSerializer<TSerializedError> {
371
371
  serialize: (err: unknown) => TSerializedError;
372
372
  deserialize: (err: TSerializedError) => unknown;
373
373
  }
374
- export interface RouterState<TRouteTree extends AnyRoute = AnyRoute, TRouteMatch = MakeRouteMatch<TRouteTree>> {
374
+ export interface RouterState<TRouteTree extends AnyRoute = AnyRoute, TRouteMatch = MakeRouteMatchUnion> {
375
375
  status: 'pending' | 'idle';
376
376
  loadedAt: number;
377
377
  isLoading: boolean;
@@ -496,7 +496,7 @@ export declare class Router<in out TRouteTree extends AnyRoute, in out TTrailing
496
496
  constructor(options: RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TDehydrated, TSerializedError>);
497
497
  startReactTransition: (fn: () => void) => void;
498
498
  update: (newOptions: RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TDehydrated, TSerializedError>) => void;
499
- get state(): RouterState<TRouteTree, MakeRouteMatch<TRouteTree>>;
499
+ get state(): RouterState<TRouteTree, import('./Matches.cjs').RouteMatch<any, any, any, any, any, any, any>>;
500
500
  buildRouteTree: () => void;
501
501
  subscribe: <TType extends keyof RouterEvents>(eventType: TType, fn: ListenerFn<RouterEvents[TType]>) => () => void;
502
502
  emit: (routerEvent: RouterEvent) => void;
@@ -531,7 +531,7 @@ export declare class Router<in out TRouteTree extends AnyRoute, in out TTrailing
531
531
  load: () => Promise<void>;
532
532
  startViewTransition: (fn: () => Promise<void>) => void;
533
533
  updateMatch: (id: string, updater: (match: AnyRouteMatch) => AnyRouteMatch) => AnyRouteMatch;
534
- getMatch: (matchId: string) => MakeRouteMatch<TRouteTree> | undefined;
534
+ getMatch: (matchId: string) => import('./Matches.cjs').RouteMatch<any, any, any, any, any, any, any> | undefined;
535
535
  loadMatches: ({ location, matches, preload, onReady, updateMatch, }: {
536
536
  location: ParsedLocation;
537
537
  matches: Array<AnyRouteMatch>;
@@ -22,7 +22,9 @@ function _interopNamespaceDefault(e) {
22
22
  }
23
23
  const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
24
24
  function useMatch(opts) {
25
- const nearestMatchId = React__namespace.useContext(matchContext.matchContext);
25
+ const nearestMatchId = React__namespace.useContext(
26
+ opts.from ? matchContext.dummyMatchContext : matchContext.matchContext
27
+ );
26
28
  const matchSelection = useRouterState.useRouterState({
27
29
  select: (state) => {
28
30
  const match = state.matches.find(
@@ -1 +1 @@
1
- {"version":3,"file":"useMatch.cjs","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":["React","matchContext","useRouterState"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAqEO,SAAS,SAQd,MAQ6E;AACvE,QAAA,iBAAiBA,iBAAM,WAAWC,yBAAY;AAEpD,QAAM,iBAAiBC,eAAAA,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.cjs","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":["React","dummyMatchContext","matchContext","useRouterState"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAqEO,SAAS,SAQd,MAQ6E;AAC7E,QAAM,iBAAiBA,iBAAM;AAAA,IAC3B,KAAK,OAAOC,iCAAoBC,aAAAA;AAAAA,EAClC;AAEA,QAAM,iBAAiBC,eAAAA,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,2 +1,3 @@
1
1
  import * as React from 'react';
2
2
  export declare const matchContext: React.Context<string | undefined>;
3
+ export declare const dummyMatchContext: React.Context<string | undefined>;
@@ -1,6 +1,10 @@
1
1
  import * as React from "react";
2
2
  const matchContext = React.createContext(void 0);
3
+ const dummyMatchContext = React.createContext(
4
+ void 0
5
+ );
3
6
  export {
7
+ dummyMatchContext,
4
8
  matchContext
5
9
  };
6
10
  //# sourceMappingURL=matchContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"matchContext.js","sources":["../../src/matchContext.tsx"],"sourcesContent":["import * as React from 'react'\n\nexport const matchContext = React.createContext<string | undefined>(undefined)\n"],"names":[],"mappings":";AAEa,MAAA,eAAe,MAAM,cAAkC,MAAS;"}
1
+ {"version":3,"file":"matchContext.js","sources":["../../src/matchContext.tsx"],"sourcesContent":["import * as React from 'react'\n\nexport const matchContext = React.createContext<string | undefined>(undefined)\n\n// N.B. this only exists so we can conditionally call useContext on it when we are not interested in the nearest match\nexport const dummyMatchContext = React.createContext<string | undefined>(\n undefined,\n)\n"],"names":[],"mappings":";AAEa,MAAA,eAAe,MAAM,cAAkC,MAAS;AAGtE,MAAM,oBAAoB,MAAM;AAAA,EACrC;AACF;"}
@@ -371,7 +371,7 @@ export interface RouterErrorSerializer<TSerializedError> {
371
371
  serialize: (err: unknown) => TSerializedError;
372
372
  deserialize: (err: TSerializedError) => unknown;
373
373
  }
374
- export interface RouterState<TRouteTree extends AnyRoute = AnyRoute, TRouteMatch = MakeRouteMatch<TRouteTree>> {
374
+ export interface RouterState<TRouteTree extends AnyRoute = AnyRoute, TRouteMatch = MakeRouteMatchUnion> {
375
375
  status: 'pending' | 'idle';
376
376
  loadedAt: number;
377
377
  isLoading: boolean;
@@ -496,7 +496,7 @@ export declare class Router<in out TRouteTree extends AnyRoute, in out TTrailing
496
496
  constructor(options: RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TDehydrated, TSerializedError>);
497
497
  startReactTransition: (fn: () => void) => void;
498
498
  update: (newOptions: RouterConstructorOptions<TRouteTree, TTrailingSlashOption, TDefaultStructuralSharingOption, TDehydrated, TSerializedError>) => void;
499
- get state(): RouterState<TRouteTree, MakeRouteMatch<TRouteTree>>;
499
+ get state(): RouterState<TRouteTree, import('./Matches.js').RouteMatch<any, any, any, any, any, any, any>>;
500
500
  buildRouteTree: () => void;
501
501
  subscribe: <TType extends keyof RouterEvents>(eventType: TType, fn: ListenerFn<RouterEvents[TType]>) => () => void;
502
502
  emit: (routerEvent: RouterEvent) => void;
@@ -531,7 +531,7 @@ export declare class Router<in out TRouteTree extends AnyRoute, in out TTrailing
531
531
  load: () => Promise<void>;
532
532
  startViewTransition: (fn: () => Promise<void>) => void;
533
533
  updateMatch: (id: string, updater: (match: AnyRouteMatch) => AnyRouteMatch) => AnyRouteMatch;
534
- getMatch: (matchId: string) => MakeRouteMatch<TRouteTree> | undefined;
534
+ getMatch: (matchId: string) => import('./Matches.js').RouteMatch<any, any, any, any, any, any, any> | undefined;
535
535
  loadMatches: ({ location, matches, preload, onReady, updateMatch, }: {
536
536
  location: ParsedLocation;
537
537
  matches: Array<AnyRouteMatch>;
@@ -1554,13 +1554,17 @@ class Router {
1554
1554
  decodeCharMap: this.pathParamsDecodeCharMap
1555
1555
  }) + loaderDepsHash;
1556
1556
  const existingMatch = this.getMatch(matchId);
1557
- const cause = this.state.matches.find((d) => d.id === matchId) ? "stay" : "enter";
1557
+ const previousMatch = this.state.matches.find(
1558
+ (d) => d.routeId === route.id
1559
+ );
1560
+ const cause = previousMatch ? "stay" : "enter";
1558
1561
  let match;
1559
1562
  if (existingMatch) {
1560
1563
  match = {
1561
1564
  ...existingMatch,
1562
1565
  cause,
1563
- params: routeParams
1566
+ params: previousMatch ? replaceEqualDeep(previousMatch.params, routeParams) : routeParams,
1567
+ search: previousMatch ? replaceEqualDeep(previousMatch.search, preMatchSearch) : replaceEqualDeep(existingMatch.search, preMatchSearch)
1564
1568
  };
1565
1569
  } else {
1566
1570
  const status = route.options.loader || route.options.beforeLoad || route.lazyFn || routeNeedsPreload(route) ? "pending" : "success";
@@ -1568,10 +1572,10 @@ class Router {
1568
1572
  id: matchId,
1569
1573
  index,
1570
1574
  routeId: route.id,
1571
- params: routeParams,
1575
+ params: previousMatch ? replaceEqualDeep(previousMatch.params, routeParams) : routeParams,
1572
1576
  pathname: joinPaths([this.basepath, interpolatedPath]),
1573
1577
  updatedAt: Date.now(),
1574
- search: {},
1578
+ search: previousMatch ? replaceEqualDeep(previousMatch.search, preMatchSearch) : preMatchSearch,
1575
1579
  searchError: void 0,
1576
1580
  status,
1577
1581
  isFetching: false,
@@ -1583,7 +1587,7 @@ class Router {
1583
1587
  abortController: new AbortController(),
1584
1588
  fetchCount: 0,
1585
1589
  cause,
1586
- loaderDeps,
1590
+ loaderDeps: previousMatch ? replaceEqualDeep(previousMatch.loaderDeps, loaderDeps) : loaderDeps,
1587
1591
  invalid: false,
1588
1592
  preload: false,
1589
1593
  links: (_d = (_c = route.options).links) == null ? void 0 : _d.call(_c),
@@ -1607,7 +1611,6 @@ class Router {
1607
1611
  if (!(opts == null ? void 0 : opts.preload)) {
1608
1612
  match.globalNotFound = globalNotFoundRouteId === route.id;
1609
1613
  }
1610
- match.search = replaceEqualDeep(match.search, preMatchSearch);
1611
1614
  match.searchError = searchError;
1612
1615
  const parentMatchId = parentMatch == null ? void 0 : parentMatch.id;
1613
1616
  const parentContext = !parentMatchId ? this.options.context ?? {} : parentMatch.context ?? this.options.context ?? {};