@tanstack/router-core 1.167.5 → 1.168.1

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 (60) hide show
  1. package/dist/cjs/index.cjs +3 -0
  2. package/dist/cjs/index.d.cts +2 -0
  3. package/dist/cjs/load-matches.cjs +14 -9
  4. package/dist/cjs/load-matches.cjs.map +1 -1
  5. package/dist/cjs/router.cjs +135 -151
  6. package/dist/cjs/router.cjs.map +1 -1
  7. package/dist/cjs/router.d.cts +16 -10
  8. package/dist/cjs/scroll-restoration.cjs +5 -4
  9. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  10. package/dist/cjs/ssr/createRequestHandler.cjs +2 -2
  11. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
  12. package/dist/cjs/ssr/ssr-client.cjs +14 -17
  13. package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
  14. package/dist/cjs/ssr/ssr-server.cjs +1 -1
  15. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  16. package/dist/cjs/stores.cjs +148 -0
  17. package/dist/cjs/stores.cjs.map +1 -0
  18. package/dist/cjs/stores.d.cts +70 -0
  19. package/dist/cjs/utils.cjs +7 -0
  20. package/dist/cjs/utils.cjs.map +1 -1
  21. package/dist/cjs/utils.d.cts +1 -0
  22. package/dist/esm/index.d.ts +2 -0
  23. package/dist/esm/index.js +2 -1
  24. package/dist/esm/load-matches.js +14 -9
  25. package/dist/esm/load-matches.js.map +1 -1
  26. package/dist/esm/router.d.ts +16 -10
  27. package/dist/esm/router.js +135 -151
  28. package/dist/esm/router.js.map +1 -1
  29. package/dist/esm/scroll-restoration.js +5 -4
  30. package/dist/esm/scroll-restoration.js.map +1 -1
  31. package/dist/esm/ssr/createRequestHandler.js +2 -2
  32. package/dist/esm/ssr/createRequestHandler.js.map +1 -1
  33. package/dist/esm/ssr/ssr-client.js +14 -17
  34. package/dist/esm/ssr/ssr-client.js.map +1 -1
  35. package/dist/esm/ssr/ssr-server.js +1 -1
  36. package/dist/esm/ssr/ssr-server.js.map +1 -1
  37. package/dist/esm/stores.d.ts +70 -0
  38. package/dist/esm/stores.js +146 -0
  39. package/dist/esm/stores.js.map +1 -0
  40. package/dist/esm/utils.d.ts +1 -0
  41. package/dist/esm/utils.js +7 -1
  42. package/dist/esm/utils.js.map +1 -1
  43. package/package.json +2 -2
  44. package/skills/router-core/search-params/SKILL.md +19 -25
  45. package/src/index.ts +11 -0
  46. package/src/load-matches.ts +23 -11
  47. package/src/router.ts +238 -252
  48. package/src/scroll-restoration.ts +6 -5
  49. package/src/ssr/createRequestHandler.ts +5 -4
  50. package/src/ssr/ssr-client.ts +17 -18
  51. package/src/ssr/ssr-server.ts +1 -1
  52. package/src/stores.ts +342 -0
  53. package/src/utils.ts +9 -0
  54. package/dist/cjs/utils/batch.cjs +0 -16
  55. package/dist/cjs/utils/batch.cjs.map +0 -1
  56. package/dist/cjs/utils/batch.d.cts +0 -1
  57. package/dist/esm/utils/batch.d.ts +0 -1
  58. package/dist/esm/utils/batch.js +0 -15
  59. package/dist/esm/utils/batch.js.map +0 -1
  60. package/src/utils/batch.ts +0 -18
@@ -1,5 +1,4 @@
1
1
  require("./_virtual/_rolldown/runtime.cjs");
2
- const require_batch = require("./utils/batch.cjs");
3
2
  const require_utils = require("./utils.cjs");
4
3
  const require_lru_cache = require("./lru-cache.cjs");
5
4
  const require_new_process_route_tree = require("./new-process-route-tree.cjs");
@@ -11,7 +10,7 @@ const require_root = require("./root.cjs");
11
10
  const require_redirect = require("./redirect.cjs");
12
11
  const require_load_matches = require("./load-matches.cjs");
13
12
  const require_rewrite = require("./rewrite.cjs");
14
- let _tanstack_store = require("@tanstack/store");
13
+ const require_stores = require("./stores.cjs");
15
14
  let _tanstack_history = require("@tanstack/history");
16
15
  let _tanstack_router_core_isServer = require("@tanstack/router-core/isServer");
17
16
  //#region src/router.ts
@@ -38,11 +37,11 @@ var trailingSlashOptions = {
38
37
  };
39
38
  /**
40
39
  * Compute whether path, href or hash changed between previous and current
41
- * resolved locations in router state.
40
+ * resolved locations.
42
41
  */
43
- function getLocationChangeInfo(routerState) {
44
- const fromLocation = routerState.resolvedLocation;
45
- const toLocation = routerState.location;
42
+ function getLocationChangeInfo(location, resolvedLocation) {
43
+ const fromLocation = resolvedLocation;
44
+ const toLocation = location;
46
45
  return {
47
46
  fromLocation,
48
47
  toLocation,
@@ -51,24 +50,20 @@ function getLocationChangeInfo(routerState) {
51
50
  hashChanged: fromLocation?.hash !== toLocation.hash
52
51
  };
53
52
  }
54
- function filterRedirectedCachedMatches(matches) {
55
- const filtered = matches.filter((d) => d.status !== "redirected");
56
- return filtered.length === matches.length ? matches : filtered;
57
- }
58
- function createServerStore(initialState) {
59
- const store = {
60
- state: initialState,
61
- setState: (updater) => {
62
- store.state = updater(store.state);
63
- }
64
- };
65
- return store;
66
- }
53
+ /**
54
+ * Core, framework-agnostic router engine that powers TanStack Router.
55
+ *
56
+ * Provides navigation, matching, loading, preloading, caching and event APIs
57
+ * used by framework adapters (React/Solid). Prefer framework helpers like
58
+ * `createRouter` in app code.
59
+ *
60
+ * @link https://tanstack.com/router/latest/docs/framework/react/api/router/RouterType
61
+ */
67
62
  var RouterCore = class {
68
63
  /**
69
64
  * @deprecated Use the `createRouter` function instead
70
65
  */
71
- constructor(options) {
66
+ constructor(options, getStoreConfig) {
72
67
  this.tempLocationKey = `${Math.round(Math.random() * 1e7)}`;
73
68
  this.resetNextScroll = true;
74
69
  this.shouldViewTransition = void 0;
@@ -117,10 +112,11 @@ var RouterCore = class {
117
112
  }
118
113
  this.setRoutes(processRouteTreeResult);
119
114
  }
120
- if (!this.__store && this.latestLocation) if (_tanstack_router_core_isServer.isServer ?? this.isServer) this.__store = createServerStore(getInitialRouterState(this.latestLocation));
121
- else {
122
- this.__store = (0, _tanstack_store.createStore)(getInitialRouterState(this.latestLocation));
123
- require_scroll_restoration.setupScrollRestoration(this);
115
+ if (!this.stores && this.latestLocation) {
116
+ const config = this.getStoreConfig(this);
117
+ this.batch = config.batch;
118
+ this.stores = require_stores.createRouterStores(getInitialRouterState(this.latestLocation), config);
119
+ if (!(_tanstack_router_core_isServer.isServer ?? this.isServer)) require_scroll_restoration.setupScrollRestoration(this);
124
120
  }
125
121
  let needsLocationUpdate = false;
126
122
  const nextBasepath = this.options.basepath ?? "/";
@@ -135,10 +131,7 @@ var RouterCore = class {
135
131
  if (this.history) this.updateLatestLocation();
136
132
  needsLocationUpdate = true;
137
133
  }
138
- if (needsLocationUpdate && this.__store) this.__store.setState((s) => ({
139
- ...s,
140
- location: this.latestLocation
141
- }));
134
+ if (needsLocationUpdate && this.stores) this.stores.location.setState(() => this.latestLocation);
142
135
  if (typeof window !== "undefined" && "CSS" in window && typeof window.CSS?.supports === "function") this.isViewTransitionTypesSupported = window.CSS.supports("selector(:active-view-transition-type(a)");
143
136
  };
144
137
  this.updateLatestLocation = () => {
@@ -242,14 +235,14 @@ var RouterCore = class {
242
235
  match._nonReactive.pendingTimeout = void 0;
243
236
  };
244
237
  this.cancelMatches = () => {
245
- const currentPendingMatches = this.state.matches.filter((match) => match.status === "pending");
246
- const currentLoadingMatches = this.state.matches.filter((match) => match.isFetching === "loader");
247
- new Set([
248
- ...this.state.pendingMatches ?? [],
249
- ...currentPendingMatches,
250
- ...currentLoadingMatches
251
- ]).forEach((match) => {
252
- this.cancelMatch(match.id);
238
+ this.stores.pendingMatchesId.state.forEach((matchId) => {
239
+ this.cancelMatch(matchId);
240
+ });
241
+ this.stores.matchesId.state.forEach((matchId) => {
242
+ if (this.stores.pendingMatchStoresById.has(matchId)) return;
243
+ const match = this.stores.activeMatchStoresById.get(matchId)?.state;
244
+ if (!match) return;
245
+ if (match.status === "pending" || match.isFetching === "loader") this.cancelMatch(matchId);
253
246
  });
254
247
  };
255
248
  this.buildLocation = (opts) => {
@@ -515,83 +508,85 @@ var RouterCore = class {
515
508
  }
516
509
  }
517
510
  const pendingMatches = this.matchRoutes(this.latestLocation);
518
- this.__store.setState((s) => ({
519
- ...s,
520
- status: "pending",
521
- statusCode: 200,
522
- isLoading: true,
523
- location: this.latestLocation,
524
- pendingMatches,
525
- cachedMatches: s.cachedMatches.filter((d) => !pendingMatches.some((e) => e.id === d.id))
526
- }));
511
+ const nextCachedMatches = this.stores.cachedMatchesSnapshot.state.filter((d) => !pendingMatches.some((e) => e.id === d.id));
512
+ this.batch(() => {
513
+ this.stores.status.setState(() => "pending");
514
+ this.stores.statusCode.setState(() => 200);
515
+ this.stores.isLoading.setState(() => true);
516
+ this.stores.location.setState(() => this.latestLocation);
517
+ this.stores.setPendingMatches(pendingMatches);
518
+ this.stores.setCachedMatches(nextCachedMatches);
519
+ });
527
520
  };
528
521
  this.load = async (opts) => {
529
522
  let redirect;
530
523
  let notFound;
531
524
  let loadPromise;
532
- const previousLocation = this.state.resolvedLocation ?? this.state.location;
525
+ const previousLocation = this.stores.resolvedLocation.state ?? this.stores.location.state;
533
526
  loadPromise = new Promise((resolve) => {
534
527
  this.startTransition(async () => {
535
528
  try {
536
529
  this.beforeLoad();
537
530
  const next = this.latestLocation;
538
- const prevLocation = this.state.resolvedLocation;
539
- if (!this.state.redirect) this.emit({
531
+ const prevLocation = this.stores.resolvedLocation.state;
532
+ const locationChangeInfo = getLocationChangeInfo(next, prevLocation);
533
+ if (!this.stores.redirect.state) this.emit({
540
534
  type: "onBeforeNavigate",
541
- ...getLocationChangeInfo({
542
- resolvedLocation: prevLocation,
543
- location: next
544
- })
535
+ ...locationChangeInfo
545
536
  });
546
537
  this.emit({
547
538
  type: "onBeforeLoad",
548
- ...getLocationChangeInfo({
549
- resolvedLocation: prevLocation,
550
- location: next
551
- })
539
+ ...locationChangeInfo
552
540
  });
553
541
  await require_load_matches.loadMatches({
554
542
  router: this,
555
543
  sync: opts?.sync,
556
544
  forceStaleReload: previousLocation.href === next.href,
557
- matches: this.state.pendingMatches,
545
+ matches: this.stores.pendingMatchesSnapshot.state,
558
546
  location: next,
559
547
  updateMatch: this.updateMatch,
560
548
  onReady: async () => {
561
549
  this.startTransition(() => {
562
550
  this.startViewTransition(async () => {
563
- let exitingMatches = [];
564
- let hookExitingMatches = [];
565
- let hookEnteringMatches = [];
566
- let hookStayingMatches = [];
567
- require_batch.batch(() => {
568
- this.__store.setState((s) => {
569
- const previousMatches = s.matches;
570
- const newMatches = s.pendingMatches || s.matches;
571
- exitingMatches = previousMatches.filter((match) => !newMatches.some((d) => d.id === match.id));
572
- hookExitingMatches = previousMatches.filter((match) => !newMatches.some((d) => d.routeId === match.routeId));
573
- hookEnteringMatches = newMatches.filter((match) => !previousMatches.some((d) => d.routeId === match.routeId));
574
- hookStayingMatches = newMatches.filter((match) => previousMatches.some((d) => d.routeId === match.routeId));
575
- return {
576
- ...s,
577
- isLoading: false,
578
- loadedAt: Date.now(),
579
- matches: newMatches,
580
- pendingMatches: void 0,
581
- cachedMatches: [...s.cachedMatches, ...exitingMatches.filter((d) => d.status !== "error" && d.status !== "notFound" && d.status !== "redirected")]
582
- };
583
- });
584
- this.clearExpiredCache();
551
+ let exitingMatches = null;
552
+ let hookExitingMatches = null;
553
+ let hookEnteringMatches = null;
554
+ let hookStayingMatches = null;
555
+ this.batch(() => {
556
+ const pendingMatches = this.stores.pendingMatchesSnapshot.state;
557
+ const mountPending = pendingMatches.length;
558
+ const currentMatches = this.stores.activeMatchesSnapshot.state;
559
+ exitingMatches = mountPending ? currentMatches.filter((match) => !this.stores.pendingMatchStoresById.has(match.id)) : null;
560
+ const pendingRouteIds = /* @__PURE__ */ new Set();
561
+ for (const s of this.stores.pendingMatchStoresById.values()) if (s.routeId) pendingRouteIds.add(s.routeId);
562
+ const activeRouteIds = /* @__PURE__ */ new Set();
563
+ for (const s of this.stores.activeMatchStoresById.values()) if (s.routeId) activeRouteIds.add(s.routeId);
564
+ hookExitingMatches = mountPending ? currentMatches.filter((match) => !pendingRouteIds.has(match.routeId)) : null;
565
+ hookEnteringMatches = mountPending ? pendingMatches.filter((match) => !activeRouteIds.has(match.routeId)) : null;
566
+ hookStayingMatches = mountPending ? pendingMatches.filter((match) => activeRouteIds.has(match.routeId)) : currentMatches;
567
+ this.stores.isLoading.setState(() => false);
568
+ this.stores.loadedAt.setState(() => Date.now());
569
+ /**
570
+ * When committing new matches, cache any exiting matches that are still usable.
571
+ * Routes that resolved with `status: 'error'` or `status: 'notFound'` are
572
+ * deliberately excluded from `cachedMatches` so that subsequent invalidations
573
+ * or reloads re-run their loaders instead of reusing the failed/not-found data.
574
+ */
575
+ if (mountPending) {
576
+ this.stores.setActiveMatches(pendingMatches);
577
+ this.stores.setPendingMatches([]);
578
+ this.stores.setCachedMatches([...this.stores.cachedMatchesSnapshot.state, ...exitingMatches.filter((d) => d.status !== "error" && d.status !== "notFound" && d.status !== "redirected")]);
579
+ this.clearExpiredCache();
580
+ }
585
581
  });
586
- [
582
+ for (const [matches, hook] of [
587
583
  [hookExitingMatches, "onLeave"],
588
584
  [hookEnteringMatches, "onEnter"],
589
585
  [hookStayingMatches, "onStay"]
590
- ].forEach(([matches, hook]) => {
591
- matches.forEach((match) => {
592
- this.looseRoutesById[match.routeId].options[hook]?.(match);
593
- });
594
- });
586
+ ]) {
587
+ if (!matches) continue;
588
+ for (const match of matches) this.looseRoutesById[match.routeId].options[hook]?.(match);
589
+ }
595
590
  });
596
591
  });
597
592
  }
@@ -605,11 +600,11 @@ var RouterCore = class {
605
600
  ignoreBlocker: true
606
601
  });
607
602
  } else if (require_not_found.isNotFound(err)) notFound = err;
608
- this.__store.setState((s) => ({
609
- ...s,
610
- statusCode: redirect ? redirect.status : notFound ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
611
- redirect
612
- }));
603
+ const nextStatusCode = redirect ? redirect.status : notFound ? 404 : this.stores.activeMatchesSnapshot.state.some((d) => d.status === "error") ? 500 : 200;
604
+ this.batch(() => {
605
+ this.stores.statusCode.setState(() => nextStatusCode);
606
+ this.stores.redirect.setState(() => redirect);
607
+ });
613
608
  }
614
609
  if (this.latestLoadPromise === loadPromise) {
615
610
  this.commitLocationPromise?.resolve();
@@ -624,11 +619,8 @@ var RouterCore = class {
624
619
  while (this.latestLoadPromise && loadPromise !== this.latestLoadPromise) await this.latestLoadPromise;
625
620
  let newStatusCode = void 0;
626
621
  if (this.hasNotFoundMatch()) newStatusCode = 404;
627
- else if (this.__store.state.matches.some((d) => d.status === "error")) newStatusCode = 500;
628
- if (newStatusCode !== void 0) this.__store.setState((s) => ({
629
- ...s,
630
- statusCode: newStatusCode
631
- }));
622
+ else if (this.stores.activeMatchesSnapshot.state.some((d) => d.status === "error")) newStatusCode = 500;
623
+ if (newStatusCode !== void 0) this.stores.statusCode.setState(() => newStatusCode);
632
624
  };
633
625
  this.startViewTransition = (fn) => {
634
626
  const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
@@ -637,11 +629,8 @@ var RouterCore = class {
637
629
  let startViewTransitionParams;
638
630
  if (typeof shouldViewTransition === "object" && this.isViewTransitionTypesSupported) {
639
631
  const next = this.latestLocation;
640
- const prevLocation = this.state.resolvedLocation;
641
- const resolvedViewTransitionTypes = typeof shouldViewTransition.types === "function" ? shouldViewTransition.types(getLocationChangeInfo({
642
- resolvedLocation: prevLocation,
643
- location: next
644
- })) : shouldViewTransition.types;
632
+ const prevLocation = this.stores.resolvedLocation.state;
633
+ const resolvedViewTransitionTypes = typeof shouldViewTransition.types === "function" ? shouldViewTransition.types(getLocationChangeInfo(next, prevLocation)) : shouldViewTransition.types;
645
634
  if (resolvedViewTransitionTypes === false) {
646
635
  fn();
647
636
  return;
@@ -656,20 +645,27 @@ var RouterCore = class {
656
645
  };
657
646
  this.updateMatch = (id, updater) => {
658
647
  this.startTransition(() => {
659
- const matchesKey = this.state.pendingMatches?.some((d) => d.id === id) ? "pendingMatches" : this.state.matches.some((d) => d.id === id) ? "matches" : this.state.cachedMatches.some((d) => d.id === id) ? "cachedMatches" : "";
660
- if (matchesKey) if (matchesKey === "cachedMatches") this.__store.setState((s) => ({
661
- ...s,
662
- cachedMatches: filterRedirectedCachedMatches(s.cachedMatches.map((d) => d.id === id ? updater(d) : d))
663
- }));
664
- else this.__store.setState((s) => ({
665
- ...s,
666
- [matchesKey]: s[matchesKey]?.map((d) => d.id === id ? updater(d) : d)
667
- }));
648
+ const pendingMatch = this.stores.pendingMatchStoresById.get(id);
649
+ if (pendingMatch) {
650
+ pendingMatch.setState(updater);
651
+ return;
652
+ }
653
+ const activeMatch = this.stores.activeMatchStoresById.get(id);
654
+ if (activeMatch) {
655
+ activeMatch.setState(updater);
656
+ return;
657
+ }
658
+ const cachedMatch = this.stores.cachedMatchStoresById.get(id);
659
+ if (cachedMatch) {
660
+ const next = updater(cachedMatch.state);
661
+ if (next.status === "redirected") {
662
+ if (this.stores.cachedMatchStoresById.delete(id)) this.stores.cachedMatchesId.setState((prev) => prev.filter((matchId) => matchId !== id));
663
+ } else cachedMatch.setState(() => next);
664
+ }
668
665
  });
669
666
  };
670
667
  this.getMatch = (matchId) => {
671
- const findFn = (d) => d.id === matchId;
672
- return this.state.cachedMatches.find(findFn) ?? this.state.pendingMatches?.find(findFn) ?? this.state.matches.find(findFn);
668
+ return this.stores.cachedMatchStoresById.get(matchId)?.state ?? this.stores.pendingMatchStoresById.get(matchId)?.state ?? this.stores.activeMatchStoresById.get(matchId)?.state;
673
669
  };
674
670
  this.invalidate = (opts) => {
675
671
  const invalidate = (d) => {
@@ -683,12 +679,11 @@ var RouterCore = class {
683
679
  };
684
680
  return d;
685
681
  };
686
- this.__store.setState((s) => ({
687
- ...s,
688
- matches: s.matches.map(invalidate),
689
- cachedMatches: s.cachedMatches.map(invalidate),
690
- pendingMatches: s.pendingMatches?.map(invalidate)
691
- }));
682
+ this.batch(() => {
683
+ this.stores.setActiveMatches(this.stores.activeMatchesSnapshot.state.map(invalidate));
684
+ this.stores.setCachedMatches(this.stores.cachedMatchesSnapshot.state.map(invalidate));
685
+ this.stores.setPendingMatches(this.stores.pendingMatchesSnapshot.state.map(invalidate));
686
+ });
692
687
  this.shouldViewTransition = false;
693
688
  return this.load({ sync: opts?.sync });
694
689
  };
@@ -716,26 +711,17 @@ var RouterCore = class {
716
711
  };
717
712
  this.clearCache = (opts) => {
718
713
  const filter = opts?.filter;
719
- if (filter !== void 0) this.__store.setState((s) => {
720
- return {
721
- ...s,
722
- cachedMatches: s.cachedMatches.filter((m) => !filter(m))
723
- };
724
- });
725
- else this.__store.setState((s) => {
726
- return {
727
- ...s,
728
- cachedMatches: []
729
- };
730
- });
714
+ if (filter !== void 0) this.stores.setCachedMatches(this.stores.cachedMatchesSnapshot.state.filter((m) => !filter(m)));
715
+ else this.stores.setCachedMatches([]);
731
716
  };
732
717
  this.clearExpiredCache = () => {
718
+ const now = Date.now();
733
719
  const filter = (d) => {
734
720
  const route = this.looseRoutesById[d.routeId];
735
721
  if (!route.options.loader) return true;
736
722
  const gcTime = (d.preload ? route.options.preloadGcTime ?? this.options.defaultPreloadGcTime : route.options.gcTime ?? this.options.defaultGcTime) ?? 300 * 1e3;
737
723
  if (d.status === "error") return true;
738
- return Date.now() - d.updatedAt >= gcTime;
724
+ return now - d.updatedAt >= gcTime;
739
725
  };
740
726
  this.clearCache({ filter });
741
727
  };
@@ -747,16 +733,13 @@ var RouterCore = class {
747
733
  preload: true,
748
734
  dest: opts
749
735
  });
750
- const activeMatchIds = new Set([...this.state.matches, ...this.state.pendingMatches ?? []].map((d) => d.id));
751
- const loadedMatchIds = new Set([...activeMatchIds, ...this.state.cachedMatches.map((d) => d.id)]);
752
- require_batch.batch(() => {
753
- matches.forEach((match) => {
754
- if (!loadedMatchIds.has(match.id)) this.__store.setState((s) => ({
755
- ...s,
756
- cachedMatches: [...s.cachedMatches, match]
757
- }));
758
- });
759
- });
736
+ const activeMatchIds = new Set([...this.stores.matchesId.state, ...this.stores.pendingMatchesId.state]);
737
+ const loadedMatchIds = new Set([...activeMatchIds, ...this.stores.cachedMatchesId.state]);
738
+ const matchesToCache = matches.filter((match) => !loadedMatchIds.has(match.id));
739
+ if (matchesToCache.length) {
740
+ const cachedMatches = this.stores.cachedMatchesSnapshot.state;
741
+ this.stores.setCachedMatches([...cachedMatches, ...matchesToCache]);
742
+ }
760
743
  try {
761
744
  matches = await require_load_matches.loadMatches({
762
745
  router: this,
@@ -789,8 +772,8 @@ var RouterCore = class {
789
772
  leaveParams: true
790
773
  };
791
774
  const next = this.buildLocation(matchLocation);
792
- if (opts?.pending && this.state.status !== "pending") return false;
793
- const baseLocation = (opts?.pending === void 0 ? !this.state.isLoading : opts.pending) ? this.latestLocation : this.state.resolvedLocation || this.state.location;
775
+ if (opts?.pending && this.stores.status.state !== "pending") return false;
776
+ const baseLocation = (opts?.pending === void 0 ? !this.stores.isLoading.state : opts.pending) ? this.latestLocation : this.stores.resolvedLocation.state || this.stores.location.state;
794
777
  const match = require_new_process_route_tree.findSingleMatch(next.pathname, opts?.caseSensitive ?? false, opts?.fuzzy ?? false, baseLocation.pathname, this.processedTree);
795
778
  if (!match) return false;
796
779
  if (location.params) {
@@ -800,8 +783,9 @@ var RouterCore = class {
800
783
  return match.rawParams;
801
784
  };
802
785
  this.hasNotFoundMatch = () => {
803
- return this.__store.state.matches.some((d) => d.status === "notFound" || d.globalNotFound);
786
+ return this.stores.activeMatchesSnapshot.state.some((d) => d.status === "notFound" || d.globalNotFound);
804
787
  };
788
+ this.getStoreConfig = getStoreConfig;
805
789
  this.update({
806
790
  defaultPreloadDelay: 50,
807
791
  defaultPendingMs: 1e3,
@@ -823,7 +807,7 @@ var RouterCore = class {
823
807
  return !!this.options.isPrerendering;
824
808
  }
825
809
  get state() {
826
- return this.__store.state;
810
+ return this.stores.__store.state;
827
811
  }
828
812
  setRoutes({ routesById, routesByPath, processedTree }) {
829
813
  this.routesById = routesById;
@@ -850,7 +834,8 @@ var RouterCore = class {
850
834
  else isGlobalNotFound = true;
851
835
  const globalNotFoundRouteId = isGlobalNotFound ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes) : void 0;
852
836
  const matches = new Array(matchedRoutes.length);
853
- const previousMatchesByRouteId = new Map(this.state.matches.map((match) => [match.routeId, match]));
837
+ const previousActiveMatchesByRouteId = /* @__PURE__ */ new Map();
838
+ for (const store of this.stores.activeMatchStoresById.values()) if (store.routeId) previousActiveMatchesByRouteId.set(store.routeId, store.state);
854
839
  for (let index = 0; index < matchedRoutes.length; index++) {
855
840
  const route = matchedRoutes[index];
856
841
  const parentMatch = matches[index - 1];
@@ -890,7 +875,7 @@ var RouterCore = class {
890
875
  });
891
876
  const matchId = route.id + interpolatedPath + loaderDepsHash;
892
877
  const existingMatch = this.getMatch(matchId);
893
- const previousMatch = previousMatchesByRouteId.get(route.id);
878
+ const previousMatch = previousActiveMatchesByRouteId.get(route.id);
894
879
  const strictParams = existingMatch?._strictParams ?? usedParams;
895
880
  let paramsError = void 0;
896
881
  if (!existingMatch) try {
@@ -961,7 +946,7 @@ var RouterCore = class {
961
946
  const match = matches[index];
962
947
  const route = this.looseRoutesById[match.routeId];
963
948
  const existingMatch = this.getMatch(match.id);
964
- const previousMatch = previousMatchesByRouteId.get(match.routeId);
949
+ const previousMatch = previousActiveMatchesByRouteId.get(match.routeId);
965
950
  match.params = previousMatch ? require_utils.nullReplaceEqualDeep(previousMatch.params, routeParams) : routeParams;
966
951
  if (!existingMatch) {
967
952
  const parentMatch = matches[index - 1];
@@ -1006,8 +991,9 @@ var RouterCore = class {
1006
991
  for (const route of matchedRoutes) try {
1007
992
  Object.assign(accumulatedSearch, validateSearch(route.options.validateSearch, accumulatedSearch));
1008
993
  } catch {}
1009
- const lastStateMatch = require_utils.last(this.state.matches);
1010
- const canReuseParams = lastStateMatch && lastStateMatch.routeId === lastRoute.id && location.pathname === this.state.location.pathname;
994
+ const lastStateMatchId = require_utils.last(this.stores.matchesId.state);
995
+ const lastStateMatch = lastStateMatchId && this.stores.activeMatchStoresById.get(lastStateMatchId)?.state;
996
+ const canReuseParams = lastStateMatch && lastStateMatch.routeId === lastRoute.id && lastStateMatch.pathname === location.pathname;
1011
997
  let params;
1012
998
  if (canReuseParams) params = lastStateMatch.params;
1013
999
  else {
@@ -1052,8 +1038,6 @@ function getInitialRouterState(location) {
1052
1038
  resolvedLocation: void 0,
1053
1039
  location,
1054
1040
  matches: [],
1055
- pendingMatches: [],
1056
- cachedMatches: [],
1057
1041
  statusCode: 200
1058
1042
  };
1059
1043
  }