@tanstack/react-router 1.18.2 → 1.18.4

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.
Files changed (52) hide show
  1. package/dist/cjs/Matches.cjs +75 -24
  2. package/dist/cjs/Matches.cjs.map +1 -1
  3. package/dist/cjs/Matches.d.cts +2 -3
  4. package/dist/cjs/RouterProvider.cjs +1 -10
  5. package/dist/cjs/RouterProvider.cjs.map +1 -1
  6. package/dist/cjs/awaited.cjs +2 -4
  7. package/dist/cjs/awaited.cjs.map +1 -1
  8. package/dist/cjs/fileRoute.cjs +6 -1
  9. package/dist/cjs/fileRoute.cjs.map +1 -1
  10. package/dist/cjs/fileRoute.d.cts +7 -6
  11. package/dist/cjs/link.cjs.map +1 -1
  12. package/dist/cjs/not-found.cjs.map +1 -1
  13. package/dist/cjs/not-found.d.cts +11 -1
  14. package/dist/cjs/redirects.cjs +1 -1
  15. package/dist/cjs/redirects.cjs.map +1 -1
  16. package/dist/cjs/route.cjs +3 -2
  17. package/dist/cjs/route.cjs.map +1 -1
  18. package/dist/cjs/route.d.cts +25 -24
  19. package/dist/cjs/router.cjs +172 -143
  20. package/dist/cjs/router.cjs.map +1 -1
  21. package/dist/cjs/router.d.cts +12 -8
  22. package/dist/esm/Matches.d.ts +2 -3
  23. package/dist/esm/Matches.js +67 -16
  24. package/dist/esm/Matches.js.map +1 -1
  25. package/dist/esm/RouterProvider.js +1 -10
  26. package/dist/esm/RouterProvider.js.map +1 -1
  27. package/dist/esm/awaited.js +2 -4
  28. package/dist/esm/awaited.js.map +1 -1
  29. package/dist/esm/fileRoute.d.ts +7 -6
  30. package/dist/esm/fileRoute.js +6 -1
  31. package/dist/esm/fileRoute.js.map +1 -1
  32. package/dist/esm/link.js.map +1 -1
  33. package/dist/esm/not-found.d.ts +11 -1
  34. package/dist/esm/not-found.js.map +1 -1
  35. package/dist/esm/redirects.js +1 -1
  36. package/dist/esm/redirects.js.map +1 -1
  37. package/dist/esm/route.d.ts +25 -24
  38. package/dist/esm/route.js +3 -2
  39. package/dist/esm/route.js.map +1 -1
  40. package/dist/esm/router.d.ts +12 -8
  41. package/dist/esm/router.js +163 -134
  42. package/dist/esm/router.js.map +1 -1
  43. package/package.json +1 -1
  44. package/src/Matches.tsx +100 -27
  45. package/src/RouterProvider.tsx +1 -12
  46. package/src/awaited.tsx +3 -5
  47. package/src/fileRoute.ts +16 -4
  48. package/src/link.tsx +0 -2
  49. package/src/not-found.tsx +11 -1
  50. package/src/redirects.ts +2 -1
  51. package/src/route.ts +55 -114
  52. package/src/router.ts +267 -175
@@ -65,7 +65,10 @@ class Router {
65
65
  onUpdate: () => {
66
66
  this.__store.state = {
67
67
  ...this.state,
68
- status: this.state.isTransitioning || this.state.isLoading ? "pending" : "idle"
68
+ status: this.state.isTransitioning || this.state.isLoading ? "pending" : "idle",
69
+ cachedMatches: this.state.cachedMatches.filter(
70
+ (d) => !["redirected"].includes(d.status)
71
+ )
69
72
  };
70
73
  }
71
74
  });
@@ -219,7 +222,7 @@ class Router {
219
222
  }
220
223
  return false;
221
224
  });
222
- let routeCursor = foundRoute || this.routesById["__root__"];
225
+ let routeCursor = foundRoute || this.routesById[rootRouteId];
223
226
  let matchedRoutes = [routeCursor];
224
227
  let isGlobalNotFound = false;
225
228
  if (
@@ -240,6 +243,20 @@ class Router {
240
243
  if (routeCursor)
241
244
  matchedRoutes.unshift(routeCursor);
242
245
  }
246
+ const globalNotFoundRouteId = (() => {
247
+ if (!isGlobalNotFound) {
248
+ return void 0;
249
+ }
250
+ if (this.options.notFoundMode !== "root") {
251
+ for (let i = matchedRoutes.length - 1; i >= 0; i--) {
252
+ const route = matchedRoutes[i];
253
+ if (route.children) {
254
+ return route.id;
255
+ }
256
+ }
257
+ }
258
+ return rootRouteId;
259
+ })();
243
260
  const parseErrors = matchedRoutes.map((route) => {
244
261
  let parsedParamsError;
245
262
  if (route.options.parseParams) {
@@ -297,12 +314,11 @@ class Router {
297
314
  params: routeParams,
298
315
  leaveWildcards: true
299
316
  }) + loaderDepsHash;
300
- const existingMatch = getRouteMatch(this.state, matchId);
317
+ let existingMatch = getRouteMatch(this.state, matchId);
301
318
  const cause = this.state.matches.find((d) => d.id === matchId) ? "stay" : "enter";
302
319
  const match = existingMatch ? {
303
320
  ...existingMatch,
304
321
  cause,
305
- notFoundError: isGlobalNotFound && route.id === rootRouteId ? { global: true } : void 0,
306
322
  params: routeParams
307
323
  } : {
308
324
  id: matchId,
@@ -326,11 +342,13 @@ class Router {
326
342
  loaderDeps,
327
343
  invalid: false,
328
344
  preload: false,
329
- notFoundError: isGlobalNotFound && route.id === rootRouteId ? { global: true } : void 0,
330
345
  links: (_d = (_c = route.options).links) == null ? void 0 : _d.call(_c),
331
346
  scripts: (_f = (_e = route.options).scripts) == null ? void 0 : _f.call(_e),
332
347
  staticData: route.options.staticData || {}
333
348
  };
349
+ if (!(opts == null ? void 0 : opts.preload)) {
350
+ match.globalNotFound = globalNotFoundRouteId === route.id;
351
+ }
334
352
  match.search = replaceEqualDeep(match.search, preMatchSearch);
335
353
  match.searchError = searchError;
336
354
  matches.push(match);
@@ -338,8 +356,6 @@ class Router {
338
356
  return matches;
339
357
  };
340
358
  this.cancelMatch = (id) => {
341
- var _a, _b;
342
- (_b = (_a = getRouteMatch(this.state, id)) == null ? void 0 : _a.abortController) == null ? void 0 : _b.abort();
343
359
  };
344
360
  this.cancelMatches = () => {
345
361
  var _a;
@@ -349,13 +365,9 @@ class Router {
349
365
  };
350
366
  this.buildLocation = (opts) => {
351
367
  const build = (dest = {}, matches) => {
352
- var _a, _b;
368
+ var _a, _b, _c;
353
369
  const relevantMatches = this.state.pendingMatches || this.state.matches;
354
370
  const fromSearch = ((_a = relevantMatches[relevantMatches.length - 1]) == null ? void 0 : _a.search) || this.latestLocation.search;
355
- let pathname = this.resolvePathWithBase(
356
- dest.from ?? this.latestLocation.pathname,
357
- `${dest.to ?? ""}`
358
- );
359
371
  const fromMatches = this.matchRoutes(
360
372
  this.latestLocation.pathname,
361
373
  fromSearch
@@ -363,7 +375,12 @@ class Router {
363
375
  const stayingMatches = matches == null ? void 0 : matches.filter(
364
376
  (d) => fromMatches == null ? void 0 : fromMatches.find((e) => e.routeId === d.routeId)
365
377
  );
366
- const prevParams = { ...(_b = last(fromMatches)) == null ? void 0 : _b.params };
378
+ const fromRoute = this.looseRoutesById[(_b = last(fromMatches)) == null ? void 0 : _b.routeId];
379
+ let pathname = dest.to ? this.resolvePathWithBase(
380
+ dest.from ?? this.latestLocation.pathname,
381
+ `${dest.to}`
382
+ ) : fromRoute == null ? void 0 : fromRoute.fullPath;
383
+ const prevParams = { ...(_c = last(fromMatches)) == null ? void 0 : _c.params };
367
384
  let nextParams = (dest.params ?? true) === true ? prevParams : { ...prevParams, ...functionalUpdate(dest.params, prevParams) };
368
385
  if (nextParams) {
369
386
  matches == null ? void 0 : matches.map((d) => this.looseRoutesById[d.routeId].options.stringifyParams).filter(Boolean).forEach((fn) => {
@@ -455,7 +472,7 @@ class Router {
455
472
  if (this.navigateTimeout)
456
473
  clearTimeout(this.navigateTimeout);
457
474
  const isSameUrl = this.latestLocation.href === next.href;
458
- if (!isSameUrl || !next.replace) {
475
+ if (!isSameUrl) {
459
476
  let { maskedLocation, ...nextHistory } = next;
460
477
  if (maskedLocation) {
461
478
  nextHistory = {
@@ -529,13 +546,14 @@ class Router {
529
546
  };
530
547
  this.loadMatches = async ({
531
548
  checkLatest,
549
+ location,
532
550
  matches,
533
551
  preload
534
552
  }) => {
535
553
  var _a, _b;
536
554
  let latestPromise;
537
555
  let firstBadMatchIndex;
538
- const updateMatch = (match) => {
556
+ const updateMatch = (match, opts) => {
539
557
  var _a2;
540
558
  const isPending = (_a2 = this.state.pendingMatches) == null ? void 0 : _a2.find(
541
559
  (d) => d.id === match.id
@@ -543,36 +561,43 @@ class Router {
543
561
  const isMatched = this.state.matches.find((d) => d.id === match.id);
544
562
  const matchesKey = isPending ? "pendingMatches" : isMatched ? "matches" : "cachedMatches";
545
563
  this.__store.setState((s) => {
546
- var _a3;
564
+ var _a3, _b2;
547
565
  return {
548
566
  ...s,
549
- [matchesKey]: (_a3 = s[matchesKey]) == null ? void 0 : _a3.map(
550
- (d) => d.id === match.id ? match : d
551
- )
567
+ [matchesKey]: (opts == null ? void 0 : opts.remove) ? (_a3 = s[matchesKey]) == null ? void 0 : _a3.filter((d) => d.id !== match.id) : (_b2 = s[matchesKey]) == null ? void 0 : _b2.map((d) => d.id === match.id ? match : d)
552
568
  };
553
569
  });
554
570
  };
571
+ const handleMatchSpecialError = (match, err) => {
572
+ match = {
573
+ ...match,
574
+ status: isRedirect(err) ? "redirected" : isNotFound(err) ? "notFound" : "error",
575
+ isFetching: false,
576
+ error: err
577
+ };
578
+ updateMatch(match);
579
+ if (!err.routeId) {
580
+ err.routeId = match.routeId;
581
+ }
582
+ throw err;
583
+ };
555
584
  for (let [index, match] of matches.entries()) {
556
585
  const parentMatch = matches[index - 1];
557
586
  const route = this.looseRoutesById[match.routeId];
558
587
  const abortController = new AbortController();
559
- const handleError = (err, code) => {
588
+ const handleSerialError = (err, code) => {
560
589
  var _a2, _b2;
561
590
  err.routerCode = code;
562
591
  firstBadMatchIndex = firstBadMatchIndex ?? index;
563
- if (isRedirect(err)) {
564
- throw err;
565
- }
566
- if (isNotFound(err)) {
567
- err.routeId = match.routeId;
568
- throw err;
592
+ if (isRedirect(err) || isNotFound(err)) {
593
+ handleMatchSpecialError(match, err);
569
594
  }
570
595
  try {
571
596
  (_b2 = (_a2 = route.options).onError) == null ? void 0 : _b2.call(_a2, err);
572
597
  } catch (errorHandlerErr) {
573
598
  err = errorHandlerErr;
574
- if (isRedirect(errorHandlerErr)) {
575
- throw errorHandlerErr;
599
+ if (isRedirect(err) || isNotFound(err)) {
600
+ handleMatchSpecialError(match, errorHandlerErr);
576
601
  }
577
602
  }
578
603
  matches[index] = match = {
@@ -583,13 +608,13 @@ class Router {
583
608
  abortController: new AbortController()
584
609
  };
585
610
  };
611
+ if (match.paramsError) {
612
+ handleSerialError(match.paramsError, "PARSE_PARAMS");
613
+ }
614
+ if (match.searchError) {
615
+ handleSerialError(match.searchError, "VALIDATE_SEARCH");
616
+ }
586
617
  try {
587
- if (match.paramsError) {
588
- handleError(match.paramsError, "PARSE_PARAMS");
589
- }
590
- if (match.searchError) {
591
- handleError(match.searchError, "VALIDATE_SEARCH");
592
- }
593
618
  const parentContext = (parentMatch == null ? void 0 : parentMatch.context) ?? this.options.context ?? {};
594
619
  const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
595
620
  const pendingPromise = typeof pendingMs === "number" && pendingMs <= 0 ? Promise.resolve() : new Promise((r) => setTimeout(r, pendingMs));
@@ -599,14 +624,13 @@ class Router {
599
624
  params: match.params,
600
625
  preload: !!preload,
601
626
  context: parentContext,
602
- location: this.state.location,
603
- // TOOD: just expose state and router, etc
627
+ location,
604
628
  navigate: (opts) => this.navigate({ ...opts, from: match.pathname }),
605
629
  buildLocation: this.buildLocation,
606
630
  cause: preload ? "preload" : match.cause
607
631
  })) ?? {};
608
- if (isRedirect(beforeLoadContext)) {
609
- throw beforeLoadContext;
632
+ if (isRedirect(beforeLoadContext) || isNotFound(beforeLoadContext)) {
633
+ handleSerialError(beforeLoadContext, "BEFORE_LOAD");
610
634
  }
611
635
  const context = {
612
636
  ...parentContext,
@@ -620,7 +644,7 @@ class Router {
620
644
  pendingPromise
621
645
  };
622
646
  } catch (err) {
623
- handleError(err, "BEFORE_LOAD");
647
+ handleSerialError(err, "BEFORE_LOAD");
624
648
  break;
625
649
  }
626
650
  }
@@ -633,12 +657,8 @@ class Router {
633
657
  const parentMatchPromise = matchPromises[index - 1];
634
658
  const route = this.looseRoutesById[match.routeId];
635
659
  const handleError = (err) => {
636
- if (isRedirect(err)) {
637
- throw err;
638
- }
639
- if (isNotFound(err)) {
640
- err.routeId = match.routeId;
641
- throw err;
660
+ if (isRedirect(err) || isNotFound(err)) {
661
+ handleMatchSpecialError(match, err);
642
662
  }
643
663
  };
644
664
  let loadPromise;
@@ -649,7 +669,6 @@ class Router {
649
669
  let didShowPending = false;
650
670
  const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
651
671
  const pendingMinMs = route.options.pendingMinMs ?? this.options.defaultPendingMinMs;
652
- const shouldPending = !preload && typeof pendingMs === "number" && (route.options.pendingComponent ?? this.options.defaultPendingComponent);
653
672
  const loaderContext = {
654
673
  params: match.params,
655
674
  deps: match.loaderDeps,
@@ -657,53 +676,47 @@ class Router {
657
676
  parentMatchPromise,
658
677
  abortController: match.abortController,
659
678
  context: match.context,
660
- location: this.state.location,
679
+ location,
661
680
  navigate: (opts) => this.navigate({ ...opts, from: match.pathname }),
662
- cause: preload ? "preload" : match.cause
681
+ cause: preload ? "preload" : match.cause,
682
+ route
663
683
  };
664
684
  const fetch = async () => {
665
- var _a3, _b2, _c, _d, _e, _f, _g, _h;
666
- if (match.isFetching) {
667
- loadPromise = (_a3 = getRouteMatch(this.state, match.id)) == null ? void 0 : _a3.loadPromise;
668
- } else {
669
- if (match.fetchCount && match.status === "success") {
670
- resolve();
685
+ var _a3, _b2, _c, _d, _e, _f, _g, _h, _i, _j;
686
+ try {
687
+ if (match.isFetching) {
688
+ loadPromise = (_a3 = getRouteMatch(this.state, match.id)) == null ? void 0 : _a3.loadPromise;
689
+ } else {
690
+ matches[index] = match = {
691
+ ...match,
692
+ isFetching: true,
693
+ fetchCount: match.fetchCount + 1
694
+ };
695
+ const lazyPromise = ((_b2 = route.lazyFn) == null ? void 0 : _b2.call(route).then((lazyRoute) => {
696
+ Object.assign(route.options, lazyRoute.options);
697
+ })) || Promise.resolve();
698
+ const componentsPromise = lazyPromise.then(
699
+ () => Promise.all(
700
+ componentTypes.map(async (type) => {
701
+ const component = route.options[type];
702
+ if (component == null ? void 0 : component.preload) {
703
+ await component.preload();
704
+ }
705
+ })
706
+ )
707
+ );
708
+ const loaderPromise = (_d = (_c = route.options).loader) == null ? void 0 : _d.call(_c, loaderContext);
709
+ loadPromise = Promise.all([
710
+ componentsPromise,
711
+ loaderPromise,
712
+ lazyPromise
713
+ ]).then((d) => d[1]);
671
714
  }
672
715
  matches[index] = match = {
673
716
  ...match,
674
- isFetching: true,
675
- fetchCount: match.fetchCount + 1
717
+ loadPromise
676
718
  };
677
- const lazyPromise = ((_b2 = route.lazyFn) == null ? void 0 : _b2.call(route).then((lazyRoute) => {
678
- Object.assign(route.options, lazyRoute.options);
679
- })) || Promise.resolve();
680
- const componentsPromise = lazyPromise.then(
681
- () => Promise.all(
682
- componentTypes.map(async (type) => {
683
- const component = route.options[type];
684
- if (component == null ? void 0 : component.preload) {
685
- await component.preload();
686
- }
687
- })
688
- )
689
- );
690
- async function loader() {
691
- var _a4, _b3;
692
- return await ((_b3 = (_a4 = route.options).loader) == null ? void 0 : _b3.call(_a4, loaderContext));
693
- }
694
- const loaderPromise = loader();
695
- loadPromise = Promise.all([
696
- componentsPromise,
697
- loaderPromise,
698
- lazyPromise
699
- ]).then((d) => d[1]);
700
- }
701
- matches[index] = match = {
702
- ...match,
703
- loadPromise
704
- };
705
- updateMatch(match);
706
- try {
719
+ updateMatch(match);
707
720
  const loaderData = await loadPromise;
708
721
  if (latestPromise = checkLatest())
709
722
  return await latestPromise;
@@ -714,11 +727,11 @@ class Router {
714
727
  if (latestPromise = checkLatest())
715
728
  return await latestPromise;
716
729
  const [meta, headers] = await Promise.all([
717
- (_d = (_c = route.options).meta) == null ? void 0 : _d.call(_c, {
730
+ (_f = (_e = route.options).meta) == null ? void 0 : _f.call(_e, {
718
731
  params: match.params,
719
732
  loaderData
720
733
  }),
721
- (_f = (_e = route.options).headers) == null ? void 0 : _f.call(_e, {
734
+ (_h = (_g = route.options).headers) == null ? void 0 : _h.call(_g, {
722
735
  loaderData
723
736
  })
724
737
  ]);
@@ -738,7 +751,7 @@ class Router {
738
751
  return await latestPromise;
739
752
  handleError(error);
740
753
  try {
741
- (_h = (_g = route.options).onError) == null ? void 0 : _h.call(_g, error);
754
+ (_j = (_i = route.options).onError) == null ? void 0 : _j.call(_i, error);
742
755
  } catch (onErrorError) {
743
756
  error = onErrorError;
744
757
  handleError(onErrorError);
@@ -761,8 +774,26 @@ class Router {
761
774
  ...match,
762
775
  preload: !!preload && !this.state.matches.find((d) => d.id === match.id)
763
776
  };
764
- try {
765
- if (match.status !== "success") {
777
+ if (match.status === "success" && (match.invalid || (shouldReload ?? age > staleAge))) {
778
+ (async () => {
779
+ try {
780
+ await fetch();
781
+ } catch (err) {
782
+ console.info("Background Fetching Error", err);
783
+ if (isRedirect(err)) {
784
+ const isActive = (this.state.pendingMatches || this.state.matches).find((d) => d.id === match.id);
785
+ handleError(err);
786
+ if (isActive) {
787
+ this.handleRedirect(err);
788
+ }
789
+ }
790
+ }
791
+ })();
792
+ return resolve();
793
+ }
794
+ const shouldPending = !preload && typeof pendingMs === "number" && (route.options.pendingComponent ?? this.options.defaultPendingComponent);
795
+ if (match.status !== "success") {
796
+ try {
766
797
  if (shouldPending) {
767
798
  (_a2 = match.pendingPromise) == null ? void 0 : _a2.then(async () => {
768
799
  if (latestPromise = checkLatest())
@@ -777,11 +808,9 @@ class Router {
777
808
  });
778
809
  }
779
810
  await fetch();
780
- } else if (match.invalid || (shouldReload ?? age > staleAge)) {
781
- fetch();
811
+ } catch (err) {
812
+ reject(err);
782
813
  }
783
- } catch (err) {
784
- reject(err);
785
814
  }
786
815
  resolve();
787
816
  })
@@ -837,15 +866,20 @@ class Router {
837
866
  }));
838
867
  });
839
868
  try {
869
+ let redirected;
870
+ let notFound;
840
871
  try {
841
872
  await this.loadMatches({
842
873
  matches: pendingMatches,
874
+ location: next,
843
875
  checkLatest: () => this.checkLatest(promise)
844
876
  });
845
877
  } catch (err) {
846
878
  if (isRedirect(err)) {
879
+ redirected = err;
847
880
  this.handleRedirect(err);
848
881
  } else if (isNotFound(err)) {
882
+ notFound = err;
849
883
  this.handleNotFound(pendingMatches, err);
850
884
  }
851
885
  }
@@ -870,7 +904,8 @@ class Router {
870
904
  cachedMatches: [
871
905
  ...s.cachedMatches,
872
906
  ...exitingMatches.filter((d) => d.status !== "error")
873
- ]
907
+ ],
908
+ statusCode: (redirected == null ? void 0 : redirected.code) || notFound ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200
874
909
  }));
875
910
  this.cleanCache();
876
911
  });
@@ -895,6 +930,7 @@ class Router {
895
930
  if (latestPromise = this.checkLatest(promise)) {
896
931
  return latestPromise;
897
932
  }
933
+ console.log("Load Error", err);
898
934
  reject(err);
899
935
  }
900
936
  });
@@ -905,10 +941,9 @@ class Router {
905
941
  if (!err.href) {
906
942
  err.href = this.buildLocation(err).href;
907
943
  }
908
- if (isServer) {
909
- throw err;
944
+ if (!isServer) {
945
+ this.navigate({ ...err, replace: true });
910
946
  }
911
- this.navigate(err);
912
947
  };
913
948
  this.cleanCache = () => {
914
949
  this.__store.setState((s) => {
@@ -925,11 +960,12 @@ class Router {
925
960
  };
926
961
  });
927
962
  };
928
- this.preloadRoute = async (navigateOpts = this.state.location) => {
963
+ this.preloadRoute = async (opts) => {
929
964
  var _a;
930
- let next = this.buildLocation(navigateOpts);
965
+ let next = this.buildLocation(opts);
931
966
  let matches = this.matchRoutes(next.pathname, next.search, {
932
- throwOnError: true
967
+ throwOnError: true,
968
+ preload: true
933
969
  });
934
970
  const loadedMatchIds = Object.fromEntries(
935
971
  (_a = [
@@ -951,14 +987,16 @@ class Router {
951
987
  try {
952
988
  matches = await this.loadMatches({
953
989
  matches,
990
+ location: next,
954
991
  preload: true,
955
992
  checkLatest: () => void 0
956
993
  });
957
994
  return matches;
958
995
  } catch (err) {
959
- if (!isRedirect(err) && !isNotFound(err)) {
960
- console.error(err);
996
+ if (isRedirect(err)) {
997
+ return await this.preloadRoute(err);
961
998
  }
999
+ console.error(err);
962
1000
  return void 0;
963
1001
  }
964
1002
  };
@@ -1045,15 +1083,7 @@ class Router {
1045
1083
  return {
1046
1084
  state: {
1047
1085
  dehydratedMatches: this.state.matches.map((d) => ({
1048
- ...pick(d, [
1049
- "id",
1050
- "status",
1051
- "updatedAt",
1052
- "loaderData",
1053
- // Not-founds that occur during SSR don't require the client to load data before
1054
- // triggering in order to prevent the flicker of the loading component
1055
- "notFoundError"
1056
- ]),
1086
+ ...pick(d, ["id", "status", "updatedAt", "loaderData"]),
1057
1087
  // If an error occurs server-side during SSRing,
1058
1088
  // send a small subset of the error to the client
1059
1089
  error: d.error ? {
@@ -1115,30 +1145,28 @@ class Router {
1115
1145
  };
1116
1146
  this.handleNotFound = (matches, err) => {
1117
1147
  const matchesByRouteId = Object.fromEntries(
1118
- matches.map((match) => [match.routeId, match])
1148
+ matches.map((match2) => [match2.routeId, match2])
1119
1149
  );
1120
- if (!err.global && err.routeId) {
1121
- let currentRoute = this.looseRoutesById[err.routeId];
1122
- if (currentRoute) {
1123
- while (!currentRoute.options.notFoundComponent) {
1124
- currentRoute = currentRoute == null ? void 0 : currentRoute.parentRoute;
1125
- invariant(
1126
- currentRoute,
1127
- "Found invalid route tree while trying to find not-found handler."
1128
- );
1129
- if (currentRoute.id === rootRouteId)
1130
- break;
1131
- }
1132
- const match = matchesByRouteId[currentRoute.id];
1133
- invariant(match, "Could not find match for route: " + currentRoute.id);
1134
- match.notFoundError = err;
1135
- return;
1136
- }
1150
+ let routeCursor = (err.global ? this.looseRoutesById[rootRouteId] : this.looseRoutesById[err.routeId]) || this.looseRoutesById[rootRouteId];
1151
+ while (!routeCursor.options.notFoundComponent && !this.options.defaultNotFoundComponent && routeCursor.id !== rootRouteId) {
1152
+ routeCursor = routeCursor == null ? void 0 : routeCursor.parentRoute;
1153
+ invariant(
1154
+ routeCursor,
1155
+ "Found invalid route tree while trying to find not-found handler."
1156
+ );
1137
1157
  }
1138
- matchesByRouteId[rootRouteId].notFoundError = err;
1158
+ let match = matchesByRouteId[routeCursor.id];
1159
+ invariant(match, "Could not find match for route: " + routeCursor.id);
1160
+ Object.assign(match, {
1161
+ status: "notFound",
1162
+ error: err,
1163
+ isFetching: false
1164
+ });
1139
1165
  };
1140
1166
  this.hasNotFoundMatch = () => {
1141
- return this.__store.state.matches.some((d) => d.notFoundError);
1167
+ return this.__store.state.matches.some(
1168
+ (d) => d.status === "notFound" || d.globalNotFound
1169
+ );
1142
1170
  };
1143
1171
  this.update({
1144
1172
  defaultPreloadDelay: 50,
@@ -1186,7 +1214,8 @@ function getInitialRouterState(location) {
1186
1214
  matches: [],
1187
1215
  pendingMatches: [],
1188
1216
  cachedMatches: [],
1189
- lastUpdated: 0
1217
+ lastUpdated: 0,
1218
+ statusCode: 200
1190
1219
  };
1191
1220
  }
1192
1221
  function defaultSerializeError(err) {