@benjavicente/router-core 1.168.9 → 1.169.2

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 (169) hide show
  1. package/dist/cjs/Matches.cjs +1 -1
  2. package/dist/cjs/Matches.cjs.map +1 -1
  3. package/dist/cjs/config.cjs +1 -1
  4. package/dist/cjs/config.cjs.map +1 -1
  5. package/dist/cjs/defer.cjs +1 -1
  6. package/dist/cjs/defer.cjs.map +1 -1
  7. package/dist/cjs/hash-scroll.cjs +1 -1
  8. package/dist/cjs/hash-scroll.cjs.map +1 -1
  9. package/dist/cjs/index.cjs +4 -0
  10. package/dist/cjs/index.d.cts +3 -3
  11. package/dist/cjs/isServer/client.cjs +1 -1
  12. package/dist/cjs/isServer/client.cjs.map +1 -1
  13. package/dist/cjs/isServer/development.cjs +1 -1
  14. package/dist/cjs/isServer/development.cjs.map +1 -1
  15. package/dist/cjs/isServer/server.cjs +1 -1
  16. package/dist/cjs/isServer/server.cjs.map +1 -1
  17. package/dist/cjs/link.cjs +1 -1
  18. package/dist/cjs/link.cjs.map +1 -1
  19. package/dist/cjs/load-matches.cjs +26 -26
  20. package/dist/cjs/load-matches.cjs.map +1 -1
  21. package/dist/cjs/manifest.cjs +31 -0
  22. package/dist/cjs/manifest.cjs.map +1 -1
  23. package/dist/cjs/manifest.d.cts +8 -0
  24. package/dist/cjs/new-process-route-tree.cjs +55 -67
  25. package/dist/cjs/new-process-route-tree.cjs.map +1 -1
  26. package/dist/cjs/new-process-route-tree.d.cts +4 -26
  27. package/dist/cjs/not-found.cjs +1 -1
  28. package/dist/cjs/not-found.cjs.map +1 -1
  29. package/dist/cjs/path.cjs +1 -22
  30. package/dist/cjs/path.cjs.map +1 -1
  31. package/dist/cjs/root.cjs +1 -1
  32. package/dist/cjs/root.cjs.map +1 -1
  33. package/dist/cjs/route.cjs.map +1 -1
  34. package/dist/cjs/route.d.cts +6 -34
  35. package/dist/cjs/router.cjs +94 -80
  36. package/dist/cjs/router.cjs.map +1 -1
  37. package/dist/cjs/router.d.cts +6 -5
  38. package/dist/cjs/scroll-restoration-script/server.cjs +1 -1
  39. package/dist/cjs/scroll-restoration-script/server.cjs.map +1 -1
  40. package/dist/cjs/scroll-restoration.cjs +7 -7
  41. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  42. package/dist/cjs/searchParams.cjs +2 -2
  43. package/dist/cjs/searchParams.cjs.map +1 -1
  44. package/dist/cjs/ssr/constants.cjs +2 -2
  45. package/dist/cjs/ssr/constants.cjs.map +1 -1
  46. package/dist/cjs/ssr/createRequestHandler.cjs +2 -2
  47. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
  48. package/dist/cjs/ssr/serializer/RawStream.cjs +50 -41
  49. package/dist/cjs/ssr/serializer/RawStream.cjs.map +1 -1
  50. package/dist/cjs/ssr/serializer/RawStream.d.cts +12 -4
  51. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs +1 -1
  52. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs.map +1 -1
  53. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.d.cts +2 -2
  54. package/dist/cjs/ssr/serializer/seroval-plugins.cjs +1 -1
  55. package/dist/cjs/ssr/serializer/seroval-plugins.cjs.map +1 -1
  56. package/dist/cjs/ssr/serializer/seroval-plugins.d.cts +2 -1
  57. package/dist/cjs/ssr/serializer/transformer.cjs +16 -14
  58. package/dist/cjs/ssr/serializer/transformer.cjs.map +1 -1
  59. package/dist/cjs/ssr/serializer/transformer.d.cts +24 -23
  60. package/dist/cjs/ssr/ssr-client.cjs +9 -9
  61. package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
  62. package/dist/cjs/ssr/ssr-server.cjs +110 -22
  63. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  64. package/dist/cjs/ssr/ssr-server.d.cts +4 -2
  65. package/dist/cjs/ssr/transformStreamWithRouter.cjs +10 -7
  66. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
  67. package/dist/cjs/stores.cjs +57 -57
  68. package/dist/cjs/stores.cjs.map +1 -1
  69. package/dist/cjs/stores.d.cts +16 -16
  70. package/dist/cjs/utils.cjs +12 -7
  71. package/dist/cjs/utils.cjs.map +1 -1
  72. package/dist/cjs/utils.d.cts +1 -0
  73. package/dist/esm/Matches.js +1 -1
  74. package/dist/esm/Matches.js.map +1 -1
  75. package/dist/esm/config.js +1 -1
  76. package/dist/esm/config.js.map +1 -1
  77. package/dist/esm/defer.js +1 -1
  78. package/dist/esm/defer.js.map +1 -1
  79. package/dist/esm/hash-scroll.js +1 -1
  80. package/dist/esm/hash-scroll.js.map +1 -1
  81. package/dist/esm/index.d.ts +3 -3
  82. package/dist/esm/index.js +3 -3
  83. package/dist/esm/isServer/client.js +1 -1
  84. package/dist/esm/isServer/client.js.map +1 -1
  85. package/dist/esm/isServer/development.js +1 -1
  86. package/dist/esm/isServer/development.js.map +1 -1
  87. package/dist/esm/isServer/server.js +1 -1
  88. package/dist/esm/isServer/server.js.map +1 -1
  89. package/dist/esm/link.js +1 -1
  90. package/dist/esm/link.js.map +1 -1
  91. package/dist/esm/load-matches.js +26 -26
  92. package/dist/esm/load-matches.js.map +1 -1
  93. package/dist/esm/manifest.d.ts +8 -0
  94. package/dist/esm/manifest.js +28 -1
  95. package/dist/esm/manifest.js.map +1 -1
  96. package/dist/esm/new-process-route-tree.d.ts +4 -26
  97. package/dist/esm/new-process-route-tree.js +55 -68
  98. package/dist/esm/new-process-route-tree.js.map +1 -1
  99. package/dist/esm/not-found.js +1 -1
  100. package/dist/esm/not-found.js.map +1 -1
  101. package/dist/esm/path.js +1 -22
  102. package/dist/esm/path.js.map +1 -1
  103. package/dist/esm/root.js +1 -1
  104. package/dist/esm/root.js.map +1 -1
  105. package/dist/esm/route.d.ts +6 -34
  106. package/dist/esm/route.js.map +1 -1
  107. package/dist/esm/router.d.ts +6 -5
  108. package/dist/esm/router.js +96 -82
  109. package/dist/esm/router.js.map +1 -1
  110. package/dist/esm/scroll-restoration-script/server.js +1 -1
  111. package/dist/esm/scroll-restoration-script/server.js.map +1 -1
  112. package/dist/esm/scroll-restoration.js +7 -7
  113. package/dist/esm/scroll-restoration.js.map +1 -1
  114. package/dist/esm/searchParams.js +2 -2
  115. package/dist/esm/searchParams.js.map +1 -1
  116. package/dist/esm/ssr/constants.js +2 -2
  117. package/dist/esm/ssr/constants.js.map +1 -1
  118. package/dist/esm/ssr/createRequestHandler.js +2 -2
  119. package/dist/esm/ssr/createRequestHandler.js.map +1 -1
  120. package/dist/esm/ssr/serializer/RawStream.d.ts +12 -4
  121. package/dist/esm/ssr/serializer/RawStream.js +50 -41
  122. package/dist/esm/ssr/serializer/RawStream.js.map +1 -1
  123. package/dist/esm/ssr/serializer/ShallowErrorPlugin.d.ts +2 -2
  124. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js +1 -1
  125. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js.map +1 -1
  126. package/dist/esm/ssr/serializer/seroval-plugins.d.ts +2 -1
  127. package/dist/esm/ssr/serializer/seroval-plugins.js +1 -1
  128. package/dist/esm/ssr/serializer/seroval-plugins.js.map +1 -1
  129. package/dist/esm/ssr/serializer/transformer.d.ts +24 -23
  130. package/dist/esm/ssr/serializer/transformer.js +16 -14
  131. package/dist/esm/ssr/serializer/transformer.js.map +1 -1
  132. package/dist/esm/ssr/ssr-client.js +9 -9
  133. package/dist/esm/ssr/ssr-client.js.map +1 -1
  134. package/dist/esm/ssr/ssr-server.d.ts +4 -2
  135. package/dist/esm/ssr/ssr-server.js +110 -22
  136. package/dist/esm/ssr/ssr-server.js.map +1 -1
  137. package/dist/esm/ssr/transformStreamWithRouter.js +10 -7
  138. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
  139. package/dist/esm/stores.d.ts +16 -16
  140. package/dist/esm/stores.js +58 -58
  141. package/dist/esm/stores.js.map +1 -1
  142. package/dist/esm/utils.d.ts +1 -0
  143. package/dist/esm/utils.js +12 -8
  144. package/dist/esm/utils.js.map +1 -1
  145. package/package.json +4 -8
  146. package/skills/router-core/auth-and-guards/SKILL.md +41 -0
  147. package/skills/router-core/ssr/SKILL.md +59 -5
  148. package/skills/router-core/type-safety/SKILL.md +37 -42
  149. package/src/hash-scroll.ts +1 -1
  150. package/src/index.ts +9 -2
  151. package/src/load-matches.ts +14 -15
  152. package/src/manifest.ts +46 -0
  153. package/src/new-process-route-tree.ts +93 -106
  154. package/src/not-found.ts +1 -1
  155. package/src/path.ts +1 -27
  156. package/src/route.ts +10 -36
  157. package/src/router.ts +151 -140
  158. package/src/scroll-restoration.ts +1 -1
  159. package/src/ssr/createRequestHandler.ts +4 -5
  160. package/src/ssr/serializer/RawStream.ts +65 -56
  161. package/src/ssr/serializer/ShallowErrorPlugin.ts +2 -2
  162. package/src/ssr/serializer/seroval-plugins.ts +2 -1
  163. package/src/ssr/serializer/transformer.ts +71 -76
  164. package/src/ssr/ssr-client.ts +8 -12
  165. package/src/ssr/ssr-server.ts +170 -14
  166. package/src/ssr/transformStreamWithRouter.ts +3 -0
  167. package/src/stores.ts +86 -86
  168. package/src/utils.ts +7 -0
  169. package/bin/intent.js +0 -25
@@ -29,7 +29,7 @@ function defaultSerializeError(err) {
29
29
  return { data: err };
30
30
  }
31
31
  /** Options for configuring trailing-slash behavior. */
32
- var trailingSlashOptions = {
32
+ const trailingSlashOptions = {
33
33
  always: "always",
34
34
  never: "never",
35
35
  preserve: "preserve"
@@ -70,6 +70,7 @@ var RouterCore = class {
70
70
  this.subscribers = /* @__PURE__ */ new Set();
71
71
  this.isScrollRestoring = false;
72
72
  this.isScrollRestorationSetup = false;
73
+ this.routeBranchCache = /* @__PURE__ */ new WeakMap();
73
74
  this.startTransition = (fn) => fn();
74
75
  this.update = (newOptions) => {
75
76
  if (process.env.NODE_ENV !== "production") {
@@ -133,8 +134,8 @@ var RouterCore = class {
133
134
  if (this.history) this.updateLatestLocation();
134
135
  needsLocationUpdate = true;
135
136
  }
136
- if (needsLocationUpdate && this.stores) this.stores.location.setState(() => this.latestLocation);
137
- if (typeof window !== "undefined" && "CSS" in window && typeof window.CSS?.supports === "function") this.isViewTransitionTypesSupported = window.CSS.supports("selector(:active-view-transition-type(a)");
137
+ if (needsLocationUpdate && this.stores) this.stores.location.set(this.latestLocation);
138
+ if (typeof window !== "undefined" && "CSS" in window && typeof window.CSS?.supports === "function") this.isViewTransitionTypesSupported = window.CSS.supports("selector(:active-view-transition-type(a))");
138
139
  };
139
140
  this.updateLatestLocation = () => {
140
141
  this.latestLocation = this.parseLocation(this.history.location, this.latestLocation);
@@ -210,7 +211,7 @@ var RouterCore = class {
210
211
  this.resolvePathWithBase = (from, path) => {
211
212
  return require_path.resolvePath({
212
213
  base: from,
213
- to: require_path.cleanPath(path),
214
+ to: path.includes("//") ? require_path.cleanPath(path) : path,
214
215
  trailingSlash: this.options.trailingSlash,
215
216
  cache: this.resolvePathCache
216
217
  });
@@ -237,12 +238,12 @@ var RouterCore = class {
237
238
  match._nonReactive.pendingTimeout = void 0;
238
239
  };
239
240
  this.cancelMatches = () => {
240
- this.stores.pendingMatchesId.state.forEach((matchId) => {
241
+ this.stores.pendingIds.get().forEach((matchId) => {
241
242
  this.cancelMatch(matchId);
242
243
  });
243
- this.stores.matchesId.state.forEach((matchId) => {
244
- if (this.stores.pendingMatchStoresById.has(matchId)) return;
245
- const match = this.stores.activeMatchStoresById.get(matchId)?.state;
244
+ this.stores.matchesId.get().forEach((matchId) => {
245
+ if (this.stores.pendingMatchStores.has(matchId)) return;
246
+ const match = this.stores.matchStores.get(matchId)?.get();
246
247
  if (!match) return;
247
248
  if (match.status === "pending" || match.isFetching === "loader") this.cancelMatch(matchId);
248
249
  });
@@ -262,15 +263,22 @@ var RouterCore = class {
262
263
  if (!matchedFrom && !matchedCurrent) console.warn(`Could not find match for from: ${dest.from}`);
263
264
  }
264
265
  const defaultedFromPath = dest.unsafeRelative === "path" ? currentLocation.pathname : dest.from ?? lightweightResult.fullPath;
265
- const fromPath = this.resolvePathWithBase(defaultedFromPath, ".");
266
+ const destTo = dest.to ? `${dest.to}` : void 0;
266
267
  const fromSearch = lightweightResult.search;
267
268
  const fromParams = Object.assign(Object.create(null), lightweightResult.params);
268
- const nextTo = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : this.resolvePathWithBase(fromPath, ".");
269
+ const sourcePath = destTo?.charCodeAt(0) === 47 ? "/" : this.resolvePathWithBase(defaultedFromPath, ".");
270
+ const nextTo = destTo ? this.resolvePathWithBase(sourcePath, destTo) : sourcePath;
269
271
  const nextParams = dest.params === false || dest.params === null ? Object.create(null) : (dest.params ?? true) === true ? fromParams : Object.assign(fromParams, require_utils.functionalUpdate(dest.params, fromParams));
270
- const destMatchResult = this.getMatchedRoutes(nextTo);
271
- let destRoutes = destMatchResult.matchedRoutes;
272
- if ((!destMatchResult.foundRoute || destMatchResult.foundRoute.path !== "/" && destMatchResult.routeParams["**"]) && this.options.notFoundRoute) destRoutes = [...destRoutes, this.options.notFoundRoute];
273
- if (Object.keys(nextParams).length > 0) for (const route of destRoutes) {
272
+ const destRoute = this.routesByPath[require_path.trimPathRight(nextTo)];
273
+ let destRoutes;
274
+ if (destRoute) destRoutes = this.getRouteBranch(destRoute);
275
+ else if (nextTo.includes("$")) destRoutes = [];
276
+ else {
277
+ const destMatchResult = this.getMatchedRoutes(nextTo);
278
+ destRoutes = destMatchResult.matchedRoutes;
279
+ if (this.options.notFoundRoute && (!destMatchResult.foundRoute || destMatchResult.foundRoute.path !== "/" && destMatchResult.routeParams["**"])) destRoutes = [...destRoutes, this.options.notFoundRoute];
280
+ }
281
+ if (destRoutes.length && require_utils.hasKeys(nextParams)) for (const route of destRoutes) {
274
282
  const fn = route.options.params?.stringify ?? route.options.stringifyParams;
275
283
  if (fn) try {
276
284
  Object.assign(nextParams, fn(nextParams));
@@ -282,6 +290,9 @@ var RouterCore = class {
282
290
  decoder: this.pathParamsDecoder,
283
291
  server: this.isServer
284
292
  }).interpolatedPath).path;
293
+ if (process.env.NODE_ENV !== "production" && destRoute && !opts.leaveParams) try {
294
+ if (this.getMatchedRoutes(nextPathname).foundRoute?.id !== destRoute.id) console.warn(`Generated path "${nextPathname}" for route "${destRoute.id}" did not match the same route after params.stringify.`);
295
+ } catch {}
285
296
  let nextSearch = fromSearch;
286
297
  if (opts._includeValidateSearch && this.options.search?.strict) {
287
298
  const validatedSearch = {};
@@ -510,29 +521,28 @@ var RouterCore = class {
510
521
  }
511
522
  }
512
523
  const pendingMatches = this.matchRoutes(this.latestLocation);
513
- const nextCachedMatches = this.stores.cachedMatchesSnapshot.state.filter((d) => !pendingMatches.some((e) => e.id === d.id));
524
+ const nextCachedMatches = this.stores.cachedMatches.get().filter((d) => !pendingMatches.some((e) => e.id === d.id));
514
525
  this.batch(() => {
515
- this.stores.status.setState(() => "pending");
516
- this.stores.statusCode.setState(() => 200);
517
- this.stores.isLoading.setState(() => true);
518
- this.stores.location.setState(() => this.latestLocation);
519
- this.stores.setPendingMatches(pendingMatches);
520
- this.stores.setCachedMatches(nextCachedMatches);
526
+ this.stores.status.set("pending");
527
+ this.stores.statusCode.set(200);
528
+ this.stores.isLoading.set(true);
529
+ this.stores.location.set(this.latestLocation);
530
+ this.stores.setPending(pendingMatches);
531
+ this.stores.setCached(nextCachedMatches);
521
532
  });
522
533
  };
523
534
  this.load = async (opts) => {
524
535
  let redirect;
525
536
  let notFound;
526
537
  let loadPromise;
527
- const previousLocation = this.stores.resolvedLocation.state ?? this.stores.location.state;
538
+ const previousLocation = this.stores.resolvedLocation.get() ?? this.stores.location.get();
528
539
  loadPromise = new Promise((resolve) => {
529
540
  this.startTransition(async () => {
530
541
  try {
531
542
  this.beforeLoad();
532
543
  const next = this.latestLocation;
533
- const prevLocation = this.stores.resolvedLocation.state;
534
- const locationChangeInfo = getLocationChangeInfo(next, prevLocation);
535
- if (!this.stores.redirect.state) this.emit({
544
+ const locationChangeInfo = getLocationChangeInfo(next, this.stores.resolvedLocation.get());
545
+ if (!this.stores.redirect.get()) this.emit({
536
546
  type: "onBeforeNavigate",
537
547
  ...locationChangeInfo
538
548
  });
@@ -544,7 +554,7 @@ var RouterCore = class {
544
554
  router: this,
545
555
  sync: opts?.sync,
546
556
  forceStaleReload: previousLocation.href === next.href,
547
- matches: this.stores.pendingMatchesSnapshot.state,
557
+ matches: this.stores.pendingMatches.get(),
548
558
  location: next,
549
559
  updateMatch: this.updateMatch,
550
560
  onReady: async () => {
@@ -555,19 +565,19 @@ var RouterCore = class {
555
565
  let hookEnteringMatches = null;
556
566
  let hookStayingMatches = null;
557
567
  this.batch(() => {
558
- const pendingMatches = this.stores.pendingMatchesSnapshot.state;
568
+ const pendingMatches = this.stores.pendingMatches.get();
559
569
  const mountPending = pendingMatches.length;
560
- const currentMatches = this.stores.activeMatchesSnapshot.state;
561
- exitingMatches = mountPending ? currentMatches.filter((match) => !this.stores.pendingMatchStoresById.has(match.id)) : null;
570
+ const currentMatches = this.stores.matches.get();
571
+ exitingMatches = mountPending ? currentMatches.filter((match) => !this.stores.pendingMatchStores.has(match.id)) : null;
562
572
  const pendingRouteIds = /* @__PURE__ */ new Set();
563
- for (const s of this.stores.pendingMatchStoresById.values()) if (s.routeId) pendingRouteIds.add(s.routeId);
573
+ for (const s of this.stores.pendingMatchStores.values()) if (s.routeId) pendingRouteIds.add(s.routeId);
564
574
  const activeRouteIds = /* @__PURE__ */ new Set();
565
- for (const s of this.stores.activeMatchStoresById.values()) if (s.routeId) activeRouteIds.add(s.routeId);
575
+ for (const s of this.stores.matchStores.values()) if (s.routeId) activeRouteIds.add(s.routeId);
566
576
  hookExitingMatches = mountPending ? currentMatches.filter((match) => !pendingRouteIds.has(match.routeId)) : null;
567
577
  hookEnteringMatches = mountPending ? pendingMatches.filter((match) => !activeRouteIds.has(match.routeId)) : null;
568
578
  hookStayingMatches = mountPending ? pendingMatches.filter((match) => activeRouteIds.has(match.routeId)) : currentMatches;
569
- this.stores.isLoading.setState(() => false);
570
- this.stores.loadedAt.setState(() => Date.now());
579
+ this.stores.isLoading.set(false);
580
+ this.stores.loadedAt.set(Date.now());
571
581
  /**
572
582
  * When committing new matches, cache any exiting matches that are still usable.
573
583
  * Routes that resolved with `status: 'error'` or `status: 'notFound'` are
@@ -575,9 +585,9 @@ var RouterCore = class {
575
585
  * or reloads re-run their loaders instead of reusing the failed/not-found data.
576
586
  */
577
587
  if (mountPending) {
578
- this.stores.setActiveMatches(pendingMatches);
579
- this.stores.setPendingMatches([]);
580
- this.stores.setCachedMatches([...this.stores.cachedMatchesSnapshot.state, ...exitingMatches.filter((d) => d.status !== "error" && d.status !== "notFound" && d.status !== "redirected")]);
588
+ this.stores.setMatches(pendingMatches);
589
+ this.stores.setPending([]);
590
+ this.stores.setCached([...this.stores.cachedMatches.get(), ...exitingMatches.filter((d) => d.status !== "error" && d.status !== "notFound" && d.status !== "redirected")]);
581
591
  this.clearExpiredCache();
582
592
  }
583
593
  });
@@ -602,10 +612,10 @@ var RouterCore = class {
602
612
  ignoreBlocker: true
603
613
  });
604
614
  } else if (require_not_found.isNotFound(err)) notFound = err;
605
- const nextStatusCode = redirect ? redirect.status : notFound ? 404 : this.stores.activeMatchesSnapshot.state.some((d) => d.status === "error") ? 500 : 200;
615
+ const nextStatusCode = redirect ? redirect.status : notFound ? 404 : this.stores.matches.get().some((d) => d.status === "error") ? 500 : 200;
606
616
  this.batch(() => {
607
- this.stores.statusCode.setState(() => nextStatusCode);
608
- this.stores.redirect.setState(() => redirect);
617
+ this.stores.statusCode.set(nextStatusCode);
618
+ this.stores.redirect.set(redirect);
609
619
  });
610
620
  }
611
621
  if (this.latestLoadPromise === loadPromise) {
@@ -621,8 +631,8 @@ var RouterCore = class {
621
631
  while (this.latestLoadPromise && loadPromise !== this.latestLoadPromise) await this.latestLoadPromise;
622
632
  let newStatusCode = void 0;
623
633
  if (this.hasNotFoundMatch()) newStatusCode = 404;
624
- else if (this.stores.activeMatchesSnapshot.state.some((d) => d.status === "error")) newStatusCode = 500;
625
- if (newStatusCode !== void 0) this.stores.statusCode.setState(() => newStatusCode);
634
+ else if (this.stores.matches.get().some((d) => d.status === "error")) newStatusCode = 500;
635
+ if (newStatusCode !== void 0) this.stores.statusCode.set(newStatusCode);
626
636
  };
627
637
  this.startViewTransition = (fn) => {
628
638
  const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
@@ -631,7 +641,7 @@ var RouterCore = class {
631
641
  let startViewTransitionParams;
632
642
  if (typeof shouldViewTransition === "object" && this.isViewTransitionTypesSupported) {
633
643
  const next = this.latestLocation;
634
- const prevLocation = this.stores.resolvedLocation.state;
644
+ const prevLocation = this.stores.resolvedLocation.get();
635
645
  const resolvedViewTransitionTypes = typeof shouldViewTransition.types === "function" ? shouldViewTransition.types(getLocationChangeInfo(next, prevLocation)) : shouldViewTransition.types;
636
646
  if (resolvedViewTransitionTypes === false) {
637
647
  fn();
@@ -647,27 +657,27 @@ var RouterCore = class {
647
657
  };
648
658
  this.updateMatch = (id, updater) => {
649
659
  this.startTransition(() => {
650
- const pendingMatch = this.stores.pendingMatchStoresById.get(id);
660
+ const pendingMatch = this.stores.pendingMatchStores.get(id);
651
661
  if (pendingMatch) {
652
- pendingMatch.setState(updater);
662
+ pendingMatch.set(updater);
653
663
  return;
654
664
  }
655
- const activeMatch = this.stores.activeMatchStoresById.get(id);
665
+ const activeMatch = this.stores.matchStores.get(id);
656
666
  if (activeMatch) {
657
- activeMatch.setState(updater);
667
+ activeMatch.set(updater);
658
668
  return;
659
669
  }
660
- const cachedMatch = this.stores.cachedMatchStoresById.get(id);
670
+ const cachedMatch = this.stores.cachedMatchStores.get(id);
661
671
  if (cachedMatch) {
662
- const next = updater(cachedMatch.state);
672
+ const next = updater(cachedMatch.get());
663
673
  if (next.status === "redirected") {
664
- if (this.stores.cachedMatchStoresById.delete(id)) this.stores.cachedMatchesId.setState((prev) => prev.filter((matchId) => matchId !== id));
665
- } else cachedMatch.setState(() => next);
674
+ if (this.stores.cachedMatchStores.delete(id)) this.stores.cachedIds.set((prev) => prev.filter((matchId) => matchId !== id));
675
+ } else cachedMatch.set(next);
666
676
  }
667
677
  });
668
678
  };
669
679
  this.getMatch = (matchId) => {
670
- return this.stores.cachedMatchStoresById.get(matchId)?.state ?? this.stores.pendingMatchStoresById.get(matchId)?.state ?? this.stores.activeMatchStoresById.get(matchId)?.state;
680
+ return this.stores.cachedMatchStores.get(matchId)?.get() ?? this.stores.pendingMatchStores.get(matchId)?.get() ?? this.stores.matchStores.get(matchId)?.get();
671
681
  };
672
682
  this.invalidate = (opts) => {
673
683
  const invalidate = (d) => {
@@ -682,9 +692,9 @@ var RouterCore = class {
682
692
  return d;
683
693
  };
684
694
  this.batch(() => {
685
- this.stores.setActiveMatches(this.stores.activeMatchesSnapshot.state.map(invalidate));
686
- this.stores.setCachedMatches(this.stores.cachedMatchesSnapshot.state.map(invalidate));
687
- this.stores.setPendingMatches(this.stores.pendingMatchesSnapshot.state.map(invalidate));
695
+ this.stores.setMatches(this.stores.matches.get().map(invalidate));
696
+ this.stores.setCached(this.stores.cachedMatches.get().map(invalidate));
697
+ this.stores.setPending(this.stores.pendingMatches.get().map(invalidate));
688
698
  });
689
699
  this.shouldViewTransition = false;
690
700
  return this.load({ sync: opts?.sync });
@@ -713,8 +723,8 @@ var RouterCore = class {
713
723
  };
714
724
  this.clearCache = (opts) => {
715
725
  const filter = opts?.filter;
716
- if (filter !== void 0) this.stores.setCachedMatches(this.stores.cachedMatchesSnapshot.state.filter((m) => !filter(m)));
717
- else this.stores.setCachedMatches([]);
726
+ if (filter !== void 0) this.stores.setCached(this.stores.cachedMatches.get().filter((m) => !filter(m)));
727
+ else this.stores.setCached([]);
718
728
  };
719
729
  this.clearExpiredCache = () => {
720
730
  const now = Date.now();
@@ -735,12 +745,12 @@ var RouterCore = class {
735
745
  preload: true,
736
746
  dest: opts
737
747
  });
738
- const activeMatchIds = new Set([...this.stores.matchesId.state, ...this.stores.pendingMatchesId.state]);
739
- const loadedMatchIds = new Set([...activeMatchIds, ...this.stores.cachedMatchesId.state]);
748
+ const activeMatchIds = new Set([...this.stores.matchesId.get(), ...this.stores.pendingIds.get()]);
749
+ const loadedMatchIds = new Set([...activeMatchIds, ...this.stores.cachedIds.get()]);
740
750
  const matchesToCache = matches.filter((match) => !loadedMatchIds.has(match.id));
741
751
  if (matchesToCache.length) {
742
- const cachedMatches = this.stores.cachedMatchesSnapshot.state;
743
- this.stores.setCachedMatches([...cachedMatches, ...matchesToCache]);
752
+ const cachedMatches = this.stores.cachedMatches.get();
753
+ this.stores.setCached([...cachedMatches, ...matchesToCache]);
744
754
  }
745
755
  try {
746
756
  matches = await require_load_matches.loadMatches({
@@ -774,8 +784,8 @@ var RouterCore = class {
774
784
  leaveParams: true
775
785
  };
776
786
  const next = this.buildLocation(matchLocation);
777
- if (opts?.pending && this.stores.status.state !== "pending") return false;
778
- const baseLocation = (opts?.pending === void 0 ? !this.stores.isLoading.state : opts.pending) ? this.latestLocation : this.stores.resolvedLocation.state || this.stores.location.state;
787
+ if (opts?.pending && this.stores.status.get() !== "pending") return false;
788
+ const baseLocation = (opts?.pending === void 0 ? !this.stores.isLoading.get() : opts.pending) ? this.latestLocation : this.stores.resolvedLocation.get() || this.stores.location.get();
779
789
  const match = require_new_process_route_tree.findSingleMatch(next.pathname, opts?.caseSensitive ?? false, opts?.fuzzy ?? false, baseLocation.pathname, this.processedTree);
780
790
  if (!match) return false;
781
791
  if (location.params) {
@@ -785,7 +795,7 @@ var RouterCore = class {
785
795
  return match.rawParams;
786
796
  };
787
797
  this.hasNotFoundMatch = () => {
788
- return this.stores.activeMatchesSnapshot.state.some((d) => d.status === "notFound" || d.globalNotFound);
798
+ return this.stores.matches.get().some((d) => d.status === "notFound" || d.globalNotFound);
789
799
  };
790
800
  this.getStoreConfig = getStoreConfig;
791
801
  this.update({
@@ -809,7 +819,7 @@ var RouterCore = class {
809
819
  return !!this.options.isPrerendering;
810
820
  }
811
821
  get state() {
812
- return this.stores.__store.state;
822
+ return this.stores.__store.get();
813
823
  }
814
824
  setRoutes({ routesById, routesByPath, processedTree }) {
815
825
  this.routesById = routesById;
@@ -821,6 +831,14 @@ var RouterCore = class {
821
831
  this.routesById[notFoundRoute.id] = notFoundRoute;
822
832
  }
823
833
  }
834
+ getRouteBranch(route) {
835
+ let branch = this.routeBranchCache.get(route);
836
+ if (!branch) {
837
+ branch = require_new_process_route_tree.buildRouteBranch(route);
838
+ this.routeBranchCache.set(route, branch);
839
+ }
840
+ return branch;
841
+ }
824
842
  get looseRoutesById() {
825
843
  return this.routesById;
826
844
  }
@@ -829,7 +847,7 @@ var RouterCore = class {
829
847
  }
830
848
  matchRoutesInternal(next, opts) {
831
849
  const matchedRoutesResult = this.getMatchedRoutes(next.pathname);
832
- const { foundRoute, routeParams, parsedParams } = matchedRoutesResult;
850
+ const { foundRoute, routeParams } = matchedRoutesResult;
833
851
  let { matchedRoutes } = matchedRoutesResult;
834
852
  let isGlobalNotFound = false;
835
853
  if (foundRoute ? foundRoute.path !== "/" && routeParams["**"] : require_path.trimPathRight(next.pathname)) if (this.options.notFoundRoute) matchedRoutes = [...matchedRoutes, this.options.notFoundRoute];
@@ -837,7 +855,7 @@ var RouterCore = class {
837
855
  const globalNotFoundRouteId = isGlobalNotFound ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes) : void 0;
838
856
  const matches = new Array(matchedRoutes.length);
839
857
  const previousActiveMatchesByRouteId = /* @__PURE__ */ new Map();
840
- for (const store of this.stores.activeMatchStoresById.values()) if (store.routeId) previousActiveMatchesByRouteId.set(store.routeId, store.state);
858
+ for (const store of this.stores.matchStores.values()) if (store.routeId) previousActiveMatchesByRouteId.set(store.routeId, store.get());
841
859
  for (let index = 0; index < matchedRoutes.length; index++) {
842
860
  const route = matchedRoutes[index];
843
861
  const parentMatch = matches[index - 1];
@@ -881,7 +899,7 @@ var RouterCore = class {
881
899
  const strictParams = existingMatch?._strictParams ?? usedParams;
882
900
  let paramsError = void 0;
883
901
  if (!existingMatch) try {
884
- extractStrictParams(route, usedParams, parsedParams, strictParams);
902
+ extractStrictParams(route, strictParams);
885
903
  } catch (err) {
886
904
  if (require_not_found.isNotFound(err) || require_redirect.isRedirect(err)) paramsError = err;
887
905
  else paramsError = new PathParamError(err.message, { cause: err });
@@ -987,21 +1005,21 @@ var RouterCore = class {
987
1005
  * operations like AbortController, ControlledPromise, loaderDeps, and full match objects.
988
1006
  */
989
1007
  matchRoutesLightweight(location) {
990
- const { matchedRoutes, routeParams, parsedParams } = this.getMatchedRoutes(location.pathname);
1008
+ const { matchedRoutes, routeParams } = this.getMatchedRoutes(location.pathname);
991
1009
  const lastRoute = require_utils.last(matchedRoutes);
992
1010
  const accumulatedSearch = { ...location.search };
993
1011
  for (const route of matchedRoutes) try {
994
1012
  Object.assign(accumulatedSearch, validateSearch(route.options.validateSearch, accumulatedSearch));
995
1013
  } catch {}
996
- const lastStateMatchId = require_utils.last(this.stores.matchesId.state);
997
- const lastStateMatch = lastStateMatchId && this.stores.activeMatchStoresById.get(lastStateMatchId)?.state;
1014
+ const lastStateMatchId = require_utils.last(this.stores.matchesId.get());
1015
+ const lastStateMatch = lastStateMatchId && this.stores.matchStores.get(lastStateMatchId)?.get();
998
1016
  const canReuseParams = lastStateMatch && lastStateMatch.routeId === lastRoute.id && lastStateMatch.pathname === location.pathname;
999
1017
  let params;
1000
1018
  if (canReuseParams) params = lastStateMatch.params;
1001
1019
  else {
1002
1020
  const strictParams = Object.assign(Object.create(null), routeParams);
1003
1021
  for (const route of matchedRoutes) try {
1004
- extractStrictParams(route, routeParams, parsedParams ?? {}, strictParams);
1022
+ extractStrictParams(route, strictParams);
1005
1023
  } catch {}
1006
1024
  params = strictParams;
1007
1025
  }
@@ -1017,7 +1035,7 @@ var RouterCore = class {
1017
1035
  var SearchParamError = class extends Error {};
1018
1036
  /** Error thrown when path parameter parsing/validation fails. */
1019
1037
  var PathParamError = class extends Error {};
1020
- var normalize = (str) => str.endsWith("/") && str.length > 1 ? str.slice(0, -1) : str;
1038
+ const normalize = (str) => str.endsWith("/") && str.length > 1 ? str.slice(0, -1) : str;
1021
1039
  function comparePaths(a, b) {
1022
1040
  return normalize(a) === normalize(b);
1023
1041
  }
@@ -1063,18 +1081,15 @@ function getMatchedRoutes({ pathname, routesById, processedTree }) {
1063
1081
  const routeParams = Object.create(null);
1064
1082
  const trimmedPath = require_path.trimPathRight(pathname);
1065
1083
  let foundRoute = void 0;
1066
- let parsedParams = void 0;
1067
1084
  const match = require_new_process_route_tree.findRouteMatch(trimmedPath, processedTree, true);
1068
1085
  if (match) {
1069
1086
  foundRoute = match.route;
1070
1087
  Object.assign(routeParams, match.rawParams);
1071
- parsedParams = Object.assign(Object.create(null), match.parsedParams);
1072
1088
  }
1073
1089
  return {
1074
1090
  matchedRoutes: match?.branch || [routesById["__root__"]],
1075
1091
  routeParams,
1076
- foundRoute,
1077
- parsedParams
1092
+ foundRoute
1078
1093
  };
1079
1094
  }
1080
1095
  /**
@@ -1150,12 +1165,11 @@ function findGlobalNotFoundRouteId(notFoundMode, routes) {
1150
1165
  }
1151
1166
  return require_root.rootRouteId;
1152
1167
  }
1153
- function extractStrictParams(route, referenceParams, parsedParams, accumulatedParams) {
1168
+ function extractStrictParams(route, accumulatedParams) {
1154
1169
  const parseParams = route.options.params?.parse ?? route.options.parseParams;
1155
- if (parseParams) if (route.options.skipRouteOnParseError) {
1156
- for (const key in referenceParams) if (key in parsedParams) accumulatedParams[key] = parsedParams[key];
1157
- } else {
1170
+ if (parseParams) {
1158
1171
  const result = parseParams(accumulatedParams);
1172
+ if (result === false) throw new Error("Route params.parse returned false for a matched route");
1159
1173
  Object.assign(accumulatedParams, result);
1160
1174
  }
1161
1175
  }