@tanstack/router-core 1.132.0-alpha.1 → 1.132.0-alpha.3

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 (115) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +7 -9
  3. package/dist/cjs/index.cjs +8 -2
  4. package/dist/cjs/index.cjs.map +1 -1
  5. package/dist/cjs/index.d.cts +6 -2
  6. package/dist/cjs/load-matches.cjs +636 -0
  7. package/dist/cjs/load-matches.cjs.map +1 -0
  8. package/dist/cjs/load-matches.d.cts +16 -0
  9. package/dist/cjs/qss.cjs +19 -19
  10. package/dist/cjs/qss.cjs.map +1 -1
  11. package/dist/cjs/qss.d.cts +6 -4
  12. package/dist/cjs/redirect.cjs +3 -3
  13. package/dist/cjs/redirect.cjs.map +1 -1
  14. package/dist/cjs/route.cjs.map +1 -1
  15. package/dist/cjs/route.d.cts +0 -4
  16. package/dist/cjs/router.cjs +64 -632
  17. package/dist/cjs/router.cjs.map +1 -1
  18. package/dist/cjs/router.d.cts +14 -26
  19. package/dist/cjs/scroll-restoration.cjs +20 -25
  20. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  21. package/dist/cjs/scroll-restoration.d.cts +0 -9
  22. package/dist/cjs/searchParams.cjs +7 -15
  23. package/dist/cjs/searchParams.cjs.map +1 -1
  24. package/dist/cjs/ssr/constants.cjs +5 -0
  25. package/dist/cjs/ssr/constants.cjs.map +1 -0
  26. package/dist/cjs/ssr/constants.d.cts +1 -0
  27. package/dist/cjs/ssr/{seroval-plugins.cjs → serializer/ShallowErrorPlugin.cjs} +2 -2
  28. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs.map +1 -0
  29. package/dist/cjs/ssr/{seroval-plugins.d.cts → serializer/ShallowErrorPlugin.d.cts} +1 -2
  30. package/dist/cjs/ssr/serializer/seroval-plugins.cjs +11 -0
  31. package/dist/cjs/ssr/serializer/seroval-plugins.cjs.map +1 -0
  32. package/dist/cjs/ssr/serializer/seroval-plugins.d.cts +2 -0
  33. package/dist/cjs/ssr/serializer/transformer.cjs +50 -0
  34. package/dist/cjs/ssr/serializer/transformer.cjs.map +1 -0
  35. package/dist/cjs/ssr/serializer/transformer.d.cts +18 -0
  36. package/dist/cjs/ssr/ssr-client.cjs +53 -40
  37. package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
  38. package/dist/cjs/ssr/ssr-client.d.cts +5 -1
  39. package/dist/cjs/ssr/ssr-server.cjs +12 -10
  40. package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
  41. package/dist/cjs/ssr/ssr-server.d.cts +0 -1
  42. package/dist/cjs/ssr/tsrScript.cjs +1 -1
  43. package/dist/cjs/ssr/tsrScript.cjs.map +1 -1
  44. package/dist/cjs/typePrimitives.d.cts +6 -6
  45. package/dist/cjs/utils.cjs +14 -7
  46. package/dist/cjs/utils.cjs.map +1 -1
  47. package/dist/cjs/utils.d.cts +2 -1
  48. package/dist/esm/Matches.d.ts +7 -9
  49. package/dist/esm/Matches.js.map +1 -1
  50. package/dist/esm/index.d.ts +6 -2
  51. package/dist/esm/index.js +9 -3
  52. package/dist/esm/index.js.map +1 -1
  53. package/dist/esm/load-matches.d.ts +16 -0
  54. package/dist/esm/load-matches.js +636 -0
  55. package/dist/esm/load-matches.js.map +1 -0
  56. package/dist/esm/qss.d.ts +6 -4
  57. package/dist/esm/qss.js +19 -19
  58. package/dist/esm/qss.js.map +1 -1
  59. package/dist/esm/redirect.js +3 -3
  60. package/dist/esm/redirect.js.map +1 -1
  61. package/dist/esm/route.d.ts +0 -4
  62. package/dist/esm/route.js.map +1 -1
  63. package/dist/esm/router.d.ts +14 -26
  64. package/dist/esm/router.js +64 -632
  65. package/dist/esm/router.js.map +1 -1
  66. package/dist/esm/scroll-restoration.d.ts +0 -9
  67. package/dist/esm/scroll-restoration.js +20 -25
  68. package/dist/esm/scroll-restoration.js.map +1 -1
  69. package/dist/esm/searchParams.js +7 -15
  70. package/dist/esm/searchParams.js.map +1 -1
  71. package/dist/esm/ssr/constants.d.ts +1 -0
  72. package/dist/esm/ssr/constants.js +5 -0
  73. package/dist/esm/ssr/constants.js.map +1 -0
  74. package/dist/esm/ssr/{seroval-plugins.d.ts → serializer/ShallowErrorPlugin.d.ts} +1 -2
  75. package/dist/esm/ssr/{seroval-plugins.js → serializer/ShallowErrorPlugin.js} +2 -2
  76. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js.map +1 -0
  77. package/dist/esm/ssr/serializer/seroval-plugins.d.ts +2 -0
  78. package/dist/esm/ssr/serializer/seroval-plugins.js +11 -0
  79. package/dist/esm/ssr/serializer/seroval-plugins.js.map +1 -0
  80. package/dist/esm/ssr/serializer/transformer.d.ts +18 -0
  81. package/dist/esm/ssr/serializer/transformer.js +50 -0
  82. package/dist/esm/ssr/serializer/transformer.js.map +1 -0
  83. package/dist/esm/ssr/ssr-client.d.ts +5 -1
  84. package/dist/esm/ssr/ssr-client.js +53 -40
  85. package/dist/esm/ssr/ssr-client.js.map +1 -1
  86. package/dist/esm/ssr/ssr-server.d.ts +0 -1
  87. package/dist/esm/ssr/ssr-server.js +12 -10
  88. package/dist/esm/ssr/ssr-server.js.map +1 -1
  89. package/dist/esm/ssr/tsrScript.js +1 -1
  90. package/dist/esm/ssr/tsrScript.js.map +1 -1
  91. package/dist/esm/typePrimitives.d.ts +6 -6
  92. package/dist/esm/utils.d.ts +2 -1
  93. package/dist/esm/utils.js +14 -7
  94. package/dist/esm/utils.js.map +1 -1
  95. package/package.json +1 -1
  96. package/src/Matches.ts +16 -8
  97. package/src/index.ts +12 -2
  98. package/src/load-matches.ts +955 -0
  99. package/src/qss.ts +27 -24
  100. package/src/redirect.ts +3 -3
  101. package/src/route.ts +10 -2
  102. package/src/router.ts +99 -893
  103. package/src/scroll-restoration.ts +25 -32
  104. package/src/searchParams.ts +8 -19
  105. package/src/ssr/constants.ts +1 -0
  106. package/src/ssr/{seroval-plugins.ts → serializer/ShallowErrorPlugin.ts} +2 -2
  107. package/src/ssr/serializer/seroval-plugins.ts +9 -0
  108. package/src/ssr/serializer/transformer.ts +78 -0
  109. package/src/ssr/ssr-client.ts +72 -44
  110. package/src/ssr/ssr-server.ts +18 -10
  111. package/src/ssr/tsrScript.ts +5 -1
  112. package/src/typePrimitives.ts +6 -6
  113. package/src/utils.ts +21 -10
  114. package/dist/cjs/ssr/seroval-plugins.cjs.map +0 -1
  115. package/dist/esm/ssr/seroval-plugins.js.map +0 -1
@@ -11,6 +11,7 @@ const searchParams = require("./searchParams.cjs");
11
11
  const root = require("./root.cjs");
12
12
  const redirect = require("./redirect.cjs");
13
13
  const lruCache = require("./lru-cache.cjs");
14
+ const loadMatches = require("./load-matches.cjs");
14
15
  function defaultSerializeError(err) {
15
16
  if (err instanceof Error) {
16
17
  const obj = {
@@ -212,13 +213,8 @@ class RouterCore {
212
213
  const match = this.getMatch(id);
213
214
  if (!match) return;
214
215
  match.abortController.abort();
215
- this.updateMatch(id, (prev) => {
216
- clearTimeout(prev.pendingTimeout);
217
- return {
218
- ...prev,
219
- pendingTimeout: void 0
220
- };
221
- });
216
+ clearTimeout(match._nonReactive.pendingTimeout);
217
+ match._nonReactive.pendingTimeout = void 0;
222
218
  };
223
219
  this.cancelMatches = () => {
224
220
  this.state.pendingMatches?.forEach((match) => {
@@ -232,7 +228,7 @@ class RouterCore {
232
228
  _buildLocation: true
233
229
  });
234
230
  const lastMatch = utils.last(allCurrentLocationMatches);
235
- let fromPath = lastMatch.fullPath;
231
+ let fromPath = this.resolvePathWithBase(lastMatch.fullPath, ".");
236
232
  const toPath = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : this.resolvePathWithBase(fromPath, ".");
237
233
  const routeIsChanging = !!dest.to && !comparePaths(dest.to.toString(), fromPath) && !comparePaths(toPath, fromPath);
238
234
  if (dest.unsafeRelative === "path") {
@@ -244,10 +240,10 @@ class RouterCore {
244
240
  dest.from,
245
241
  void 0
246
242
  ).matchedRoutes;
247
- const matchedFrom = [...allCurrentLocationMatches].reverse().find((d) => {
243
+ const matchedFrom = utils.findLast(allCurrentLocationMatches, (d) => {
248
244
  return comparePaths(d.fullPath, fromPath);
249
245
  });
250
- const matchedCurrent = [...allFromMatches].reverse().find((d) => {
246
+ const matchedCurrent = utils.findLast(allFromMatches, (d) => {
251
247
  return comparePaths(d.fullPath, currentLocation.pathname);
252
248
  });
253
249
  if (!matchedFrom && !matchedCurrent) {
@@ -255,37 +251,35 @@ class RouterCore {
255
251
  }
256
252
  }
257
253
  }
254
+ fromPath = this.resolvePathWithBase(fromPath, ".");
258
255
  const fromSearch = lastMatch.search;
259
256
  const fromParams = { ...lastMatch.params };
260
257
  const nextTo = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : this.resolvePathWithBase(fromPath, ".");
261
- let nextParams = dest.params === false || dest.params === null ? {} : (dest.params ?? true) === true ? fromParams : {
262
- ...fromParams,
263
- ...utils.functionalUpdate(dest.params, fromParams)
264
- };
258
+ const nextParams = dest.params === false || dest.params === null ? {} : (dest.params ?? true) === true ? fromParams : Object.assign(
259
+ fromParams,
260
+ utils.functionalUpdate(dest.params, fromParams)
261
+ );
265
262
  const interpolatedNextTo = path.interpolatePath({
266
263
  path: nextTo,
267
- params: nextParams ?? {},
264
+ params: nextParams,
268
265
  parseCache: this.parsePathnameCache
269
266
  }).interpolatedPath;
270
- const destRoutes = this.matchRoutes(
271
- interpolatedNextTo,
272
- {},
273
- {
274
- _buildLocation: true
275
- }
276
- ).map((d) => this.looseRoutesById[d.routeId]);
267
+ const destRoutes = this.matchRoutes(interpolatedNextTo, void 0, {
268
+ _buildLocation: true
269
+ }).map((d) => this.looseRoutesById[d.routeId]);
277
270
  if (Object.keys(nextParams).length > 0) {
278
- destRoutes.map((route) => {
279
- return route.options.params?.stringify ?? route.options.stringifyParams;
280
- }).filter(Boolean).forEach((fn) => {
281
- nextParams = { ...nextParams, ...fn(nextParams) };
282
- });
271
+ for (const route of destRoutes) {
272
+ const fn = route.options.params?.stringify ?? route.options.stringifyParams;
273
+ if (fn) {
274
+ Object.assign(nextParams, fn(nextParams));
275
+ }
276
+ }
283
277
  }
284
278
  const nextPathname = path.interpolatePath({
285
279
  // Use the original template path for interpolation
286
280
  // This preserves the original parameter syntax including optional parameters
287
281
  path: nextTo,
288
- params: nextParams ?? {},
282
+ params: nextParams,
289
283
  leaveWildcards: false,
290
284
  leaveParams: opts.leaveParams,
291
285
  decodeCharMap: this.pathParamsDecodeCharMap,
@@ -293,19 +287,19 @@ class RouterCore {
293
287
  }).interpolatedPath;
294
288
  let nextSearch = fromSearch;
295
289
  if (opts._includeValidateSearch && this.options.search?.strict) {
296
- let validatedSearch = {};
290
+ const validatedSearch = {};
297
291
  destRoutes.forEach((route) => {
298
- try {
299
- if (route.options.validateSearch) {
300
- validatedSearch = {
301
- ...validatedSearch,
302
- ...validateSearch(route.options.validateSearch, {
292
+ if (route.options.validateSearch) {
293
+ try {
294
+ Object.assign(
295
+ validatedSearch,
296
+ validateSearch(route.options.validateSearch, {
303
297
  ...validatedSearch,
304
298
  ...nextSearch
305
- }) ?? {}
306
- };
299
+ })
300
+ );
301
+ } catch {
307
302
  }
308
- } catch {
309
303
  }
310
304
  });
311
305
  nextSearch = validatedSearch;
@@ -357,7 +351,7 @@ class RouterCore {
357
351
  if (foundMask) {
358
352
  const { from: _from, ...maskProps } = foundMask;
359
353
  maskedDest = {
360
- ...utils.pick(opts, ["from"]),
354
+ from: opts.from,
361
355
  ...maskProps,
362
356
  params
363
357
  };
@@ -372,7 +366,7 @@ class RouterCore {
372
366
  };
373
367
  if (opts.mask) {
374
368
  return buildWithMatches(opts, {
375
- ...utils.pick(opts, ["from"]),
369
+ from: opts.from,
376
370
  ...opts.mask
377
371
  });
378
372
  }
@@ -568,10 +562,12 @@ class RouterCore {
568
562
  location: next
569
563
  })
570
564
  });
571
- await this.loadMatches({
565
+ await loadMatches.loadMatches({
566
+ router: this,
572
567
  sync: opts?.sync,
573
568
  matches: this.state.pendingMatches,
574
569
  location: next,
570
+ updateMatch: this.updateMatch,
575
571
  // eslint-disable-next-line @typescript-eslint/require-await
576
572
  onReady: async () => {
577
573
  this.startViewTransition(async () => {
@@ -695,510 +691,13 @@ class RouterCore {
695
691
  const findFn = (d) => d.id === matchId;
696
692
  return this.state.cachedMatches.find(findFn) ?? this.state.pendingMatches?.find(findFn) ?? this.state.matches.find(findFn);
697
693
  };
698
- this.loadMatches = async ({
699
- location,
700
- matches,
701
- preload: allPreload,
702
- onReady,
703
- updateMatch = this.updateMatch,
704
- sync
705
- }) => {
706
- let firstBadMatchIndex;
707
- let rendered = false;
708
- const triggerOnReady = async () => {
709
- if (!rendered) {
710
- rendered = true;
711
- await onReady?.();
712
- }
713
- };
714
- const resolvePreload = (matchId) => {
715
- return !!(allPreload && !this.state.matches.some((d) => d.id === matchId));
716
- };
717
- if (!this.isServer && this.state.matches.some((d) => d._forcePending)) {
718
- triggerOnReady();
719
- }
720
- const handleRedirectAndNotFound = (match, err) => {
721
- if (redirect.isRedirect(err) || notFound.isNotFound(err)) {
722
- if (redirect.isRedirect(err)) {
723
- if (err.redirectHandled) {
724
- if (!err.options.reloadDocument) {
725
- throw err;
726
- }
727
- }
728
- }
729
- match.beforeLoadPromise?.resolve();
730
- match.loaderPromise?.resolve();
731
- updateMatch(match.id, (prev) => ({
732
- ...prev,
733
- status: redirect.isRedirect(err) ? "redirected" : notFound.isNotFound(err) ? "notFound" : "error",
734
- isFetching: false,
735
- error: err,
736
- beforeLoadPromise: void 0,
737
- loaderPromise: void 0
738
- }));
739
- if (!err.routeId) {
740
- err.routeId = match.routeId;
741
- }
742
- match.loadPromise?.resolve();
743
- if (redirect.isRedirect(err)) {
744
- rendered = true;
745
- err.options._fromLocation = location;
746
- err.redirectHandled = true;
747
- err = this.resolveRedirect(err);
748
- throw err;
749
- } else if (notFound.isNotFound(err)) {
750
- this._handleNotFound(matches, err, {
751
- updateMatch
752
- });
753
- throw err;
754
- }
755
- }
756
- };
757
- const shouldSkipLoader = (matchId) => {
758
- const match = this.getMatch(matchId);
759
- if (!this.isServer && match._dehydrated) {
760
- return true;
761
- }
762
- if (this.isServer) {
763
- if (match.ssr === false) {
764
- return true;
765
- }
766
- }
767
- return false;
768
- };
769
- try {
770
- await new Promise((resolveAll, rejectAll) => {
771
- ;
772
- (async () => {
773
- try {
774
- const handleSerialError = (index, err, routerCode) => {
775
- const { id: matchId, routeId } = matches[index];
776
- const route = this.looseRoutesById[routeId];
777
- if (err instanceof Promise) {
778
- throw err;
779
- }
780
- err.routerCode = routerCode;
781
- firstBadMatchIndex = firstBadMatchIndex ?? index;
782
- handleRedirectAndNotFound(this.getMatch(matchId), err);
783
- try {
784
- route.options.onError?.(err);
785
- } catch (errorHandlerErr) {
786
- err = errorHandlerErr;
787
- handleRedirectAndNotFound(this.getMatch(matchId), err);
788
- }
789
- updateMatch(matchId, (prev) => {
790
- prev.beforeLoadPromise?.resolve();
791
- prev.loadPromise?.resolve();
792
- return {
793
- ...prev,
794
- error: err,
795
- status: "error",
796
- isFetching: false,
797
- updatedAt: Date.now(),
798
- abortController: new AbortController(),
799
- beforeLoadPromise: void 0
800
- };
801
- });
802
- };
803
- for (const [index, { id: matchId, routeId }] of matches.entries()) {
804
- const existingMatch = this.getMatch(matchId);
805
- const parentMatchId = matches[index - 1]?.id;
806
- const parentMatch = parentMatchId ? this.getMatch(parentMatchId) : void 0;
807
- const route = this.looseRoutesById[routeId];
808
- const pendingMs = route.options.pendingMs ?? this.options.defaultPendingMs;
809
- if (this.isServer) {
810
- let ssr;
811
- if (this.isShell()) {
812
- ssr = matchId === root.rootRouteId;
813
- } else {
814
- const defaultSsr = this.options.defaultSsr ?? true;
815
- if (parentMatch?.ssr === false) {
816
- ssr = false;
817
- } else {
818
- let tempSsr;
819
- if (route.options.ssr === void 0) {
820
- tempSsr = defaultSsr;
821
- } else if (typeof route.options.ssr === "function") {
822
- let makeMaybe = function(value, error) {
823
- if (error) {
824
- return { status: "error", error };
825
- }
826
- return { status: "success", value };
827
- };
828
- const { search, params } = this.getMatch(matchId);
829
- const ssrFnContext = {
830
- search: makeMaybe(search, existingMatch.searchError),
831
- params: makeMaybe(params, existingMatch.paramsError),
832
- location,
833
- matches: matches.map((match) => ({
834
- index: match.index,
835
- pathname: match.pathname,
836
- fullPath: match.fullPath,
837
- staticData: match.staticData,
838
- id: match.id,
839
- routeId: match.routeId,
840
- search: makeMaybe(match.search, match.searchError),
841
- params: makeMaybe(match.params, match.paramsError),
842
- ssr: match.ssr
843
- }))
844
- };
845
- tempSsr = await route.options.ssr(ssrFnContext) ?? defaultSsr;
846
- } else {
847
- tempSsr = route.options.ssr;
848
- }
849
- if (tempSsr === true && parentMatch?.ssr === "data-only") {
850
- ssr = "data-only";
851
- } else {
852
- ssr = tempSsr;
853
- }
854
- }
855
- }
856
- updateMatch(matchId, (prev) => ({
857
- ...prev,
858
- ssr
859
- }));
860
- }
861
- if (shouldSkipLoader(matchId)) {
862
- continue;
863
- }
864
- const shouldPending = !!(onReady && !this.isServer && !resolvePreload(matchId) && (route.options.loader || route.options.beforeLoad || routeNeedsPreload(route)) && typeof pendingMs === "number" && pendingMs !== Infinity && (route.options.pendingComponent ?? this.options?.defaultPendingComponent));
865
- let executeBeforeLoad = true;
866
- const setupPendingTimeout = () => {
867
- if (shouldPending && this.getMatch(matchId).pendingTimeout === void 0) {
868
- const pendingTimeout = setTimeout(() => {
869
- try {
870
- triggerOnReady();
871
- } catch {
872
- }
873
- }, pendingMs);
874
- updateMatch(matchId, (prev) => ({
875
- ...prev,
876
- pendingTimeout
877
- }));
878
- }
879
- };
880
- if (
881
- // If we are in the middle of a load, either of these will be present
882
- // (not to be confused with `loadPromise`, which is always defined)
883
- existingMatch.beforeLoadPromise || existingMatch.loaderPromise
884
- ) {
885
- setupPendingTimeout();
886
- await existingMatch.beforeLoadPromise;
887
- const match = this.getMatch(matchId);
888
- if (match.status === "error") {
889
- executeBeforeLoad = true;
890
- } else if (match.preload && (match.status === "redirected" || match.status === "notFound")) {
891
- handleRedirectAndNotFound(match, match.error);
892
- }
893
- }
894
- if (executeBeforeLoad) {
895
- try {
896
- updateMatch(matchId, (prev) => {
897
- const prevLoadPromise = prev.loadPromise;
898
- return {
899
- ...prev,
900
- loadPromise: utils.createControlledPromise(() => {
901
- prevLoadPromise?.resolve();
902
- }),
903
- beforeLoadPromise: utils.createControlledPromise()
904
- };
905
- });
906
- const { paramsError, searchError } = this.getMatch(matchId);
907
- if (paramsError) {
908
- handleSerialError(index, paramsError, "PARSE_PARAMS");
909
- }
910
- if (searchError) {
911
- handleSerialError(index, searchError, "VALIDATE_SEARCH");
912
- }
913
- setupPendingTimeout();
914
- const abortController = new AbortController();
915
- const parentMatchContext = parentMatch?.context ?? this.options.context ?? {};
916
- updateMatch(matchId, (prev) => ({
917
- ...prev,
918
- isFetching: "beforeLoad",
919
- fetchCount: prev.fetchCount + 1,
920
- abortController,
921
- context: {
922
- ...parentMatchContext,
923
- ...prev.__routeContext
924
- }
925
- }));
926
- const { search, params, context, cause } = this.getMatch(matchId);
927
- const preload = resolvePreload(matchId);
928
- const beforeLoadFnContext = {
929
- search,
930
- abortController,
931
- params,
932
- preload,
933
- context,
934
- location,
935
- navigate: (opts) => this.navigate({ ...opts, _fromLocation: location }),
936
- buildLocation: this.buildLocation,
937
- cause: preload ? "preload" : cause,
938
- matches
939
- };
940
- const beforeLoadContext = await route.options.beforeLoad?.(beforeLoadFnContext);
941
- if (redirect.isRedirect(beforeLoadContext) || notFound.isNotFound(beforeLoadContext)) {
942
- handleSerialError(index, beforeLoadContext, "BEFORE_LOAD");
943
- }
944
- updateMatch(matchId, (prev) => {
945
- return {
946
- ...prev,
947
- __beforeLoadContext: beforeLoadContext,
948
- context: {
949
- ...parentMatchContext,
950
- ...prev.__routeContext,
951
- ...beforeLoadContext
952
- },
953
- abortController
954
- };
955
- });
956
- } catch (err) {
957
- handleSerialError(index, err, "BEFORE_LOAD");
958
- }
959
- updateMatch(matchId, (prev) => {
960
- prev.beforeLoadPromise?.resolve();
961
- return {
962
- ...prev,
963
- beforeLoadPromise: void 0,
964
- isFetching: false
965
- };
966
- });
967
- }
968
- }
969
- const validResolvedMatches = matches.slice(0, firstBadMatchIndex);
970
- const matchPromises = [];
971
- validResolvedMatches.forEach(({ id: matchId, routeId }, index) => {
972
- matchPromises.push(
973
- (async () => {
974
- let loaderShouldRunAsync = false;
975
- let loaderIsRunningAsync = false;
976
- const route = this.looseRoutesById[routeId];
977
- const executeHead = async () => {
978
- const match = this.getMatch(matchId);
979
- if (!match) {
980
- return;
981
- }
982
- const assetContext = {
983
- matches,
984
- match,
985
- params: match.params,
986
- loaderData: match.loaderData
987
- };
988
- const headFnContent = await route.options.head?.(assetContext);
989
- const meta = headFnContent?.meta;
990
- const links = headFnContent?.links;
991
- const headScripts = headFnContent?.scripts;
992
- const styles = headFnContent?.styles;
993
- const scripts = await route.options.scripts?.(assetContext);
994
- const headers = await route.options.headers?.(assetContext);
995
- return {
996
- meta,
997
- links,
998
- headScripts,
999
- headers,
1000
- scripts,
1001
- styles
1002
- };
1003
- };
1004
- const potentialPendingMinPromise = async () => {
1005
- const latestMatch = this.getMatch(matchId);
1006
- if (latestMatch.minPendingPromise) {
1007
- await latestMatch.minPendingPromise;
1008
- }
1009
- };
1010
- const prevMatch = this.getMatch(matchId);
1011
- if (shouldSkipLoader(matchId)) {
1012
- if (this.isServer) {
1013
- const head = await executeHead();
1014
- updateMatch(matchId, (prev) => ({
1015
- ...prev,
1016
- ...head
1017
- }));
1018
- return this.getMatch(matchId);
1019
- }
1020
- } else if (prevMatch.loaderPromise) {
1021
- if (prevMatch.status === "success" && !sync && !prevMatch.preload) {
1022
- return this.getMatch(matchId);
1023
- }
1024
- await prevMatch.loaderPromise;
1025
- const match = this.getMatch(matchId);
1026
- if (match.error) {
1027
- handleRedirectAndNotFound(match, match.error);
1028
- }
1029
- } else {
1030
- const parentMatchPromise = matchPromises[index - 1];
1031
- const getLoaderContext = () => {
1032
- const {
1033
- params,
1034
- loaderDeps,
1035
- abortController,
1036
- context,
1037
- cause
1038
- } = this.getMatch(matchId);
1039
- const preload2 = resolvePreload(matchId);
1040
- return {
1041
- params,
1042
- deps: loaderDeps,
1043
- preload: !!preload2,
1044
- parentMatchPromise,
1045
- abortController,
1046
- context,
1047
- location,
1048
- navigate: (opts) => this.navigate({ ...opts, _fromLocation: location }),
1049
- cause: preload2 ? "preload" : cause,
1050
- route
1051
- };
1052
- };
1053
- const age = Date.now() - this.getMatch(matchId).updatedAt;
1054
- const preload = resolvePreload(matchId);
1055
- const staleAge = preload ? route.options.preloadStaleTime ?? this.options.defaultPreloadStaleTime ?? 3e4 : route.options.staleTime ?? this.options.defaultStaleTime ?? 0;
1056
- const shouldReloadOption = route.options.shouldReload;
1057
- const shouldReload = typeof shouldReloadOption === "function" ? shouldReloadOption(getLoaderContext()) : shouldReloadOption;
1058
- updateMatch(matchId, (prev) => ({
1059
- ...prev,
1060
- loaderPromise: utils.createControlledPromise(),
1061
- preload: !!preload && !this.state.matches.some((d) => d.id === matchId)
1062
- }));
1063
- const runLoader = async () => {
1064
- try {
1065
- try {
1066
- if (!this.isServer || this.isServer && this.getMatch(matchId).ssr === true) {
1067
- this.loadRouteChunk(route);
1068
- }
1069
- updateMatch(matchId, (prev) => ({
1070
- ...prev,
1071
- isFetching: "loader"
1072
- }));
1073
- const loaderData = await route.options.loader?.(getLoaderContext());
1074
- handleRedirectAndNotFound(
1075
- this.getMatch(matchId),
1076
- loaderData
1077
- );
1078
- updateMatch(matchId, (prev) => ({
1079
- ...prev,
1080
- loaderData
1081
- }));
1082
- await route._lazyPromise;
1083
- const head = await executeHead();
1084
- await potentialPendingMinPromise();
1085
- await route._componentsPromise;
1086
- updateMatch(matchId, (prev) => ({
1087
- ...prev,
1088
- error: void 0,
1089
- status: "success",
1090
- isFetching: false,
1091
- updatedAt: Date.now(),
1092
- ...head
1093
- }));
1094
- } catch (e) {
1095
- let error = e;
1096
- await potentialPendingMinPromise();
1097
- handleRedirectAndNotFound(this.getMatch(matchId), e);
1098
- try {
1099
- route.options.onError?.(e);
1100
- } catch (onErrorError) {
1101
- error = onErrorError;
1102
- handleRedirectAndNotFound(
1103
- this.getMatch(matchId),
1104
- onErrorError
1105
- );
1106
- }
1107
- const head = await executeHead();
1108
- updateMatch(matchId, (prev) => ({
1109
- ...prev,
1110
- error,
1111
- status: "error",
1112
- isFetching: false,
1113
- ...head
1114
- }));
1115
- }
1116
- } catch (err) {
1117
- const head = await executeHead();
1118
- updateMatch(matchId, (prev) => ({
1119
- ...prev,
1120
- loaderPromise: void 0,
1121
- ...head
1122
- }));
1123
- handleRedirectAndNotFound(this.getMatch(matchId), err);
1124
- }
1125
- };
1126
- const { status, invalid } = this.getMatch(matchId);
1127
- loaderShouldRunAsync = status === "success" && (invalid || (shouldReload ?? age > staleAge));
1128
- if (preload && route.options.preload === false) {
1129
- } else if (loaderShouldRunAsync && !sync) {
1130
- loaderIsRunningAsync = true;
1131
- (async () => {
1132
- try {
1133
- await runLoader();
1134
- const { loaderPromise, loadPromise } = this.getMatch(matchId);
1135
- loaderPromise?.resolve();
1136
- loadPromise?.resolve();
1137
- updateMatch(matchId, (prev) => ({
1138
- ...prev,
1139
- loaderPromise: void 0
1140
- }));
1141
- } catch (err) {
1142
- if (redirect.isRedirect(err)) {
1143
- await this.navigate(err.options);
1144
- }
1145
- }
1146
- })();
1147
- } else if (status !== "success" || loaderShouldRunAsync && sync) {
1148
- await runLoader();
1149
- } else {
1150
- const head = await executeHead();
1151
- updateMatch(matchId, (prev) => ({
1152
- ...prev,
1153
- ...head
1154
- }));
1155
- }
1156
- }
1157
- if (!loaderIsRunningAsync) {
1158
- const { loaderPromise, loadPromise } = this.getMatch(matchId);
1159
- loaderPromise?.resolve();
1160
- loadPromise?.resolve();
1161
- }
1162
- updateMatch(matchId, (prev) => {
1163
- clearTimeout(prev.pendingTimeout);
1164
- return {
1165
- ...prev,
1166
- isFetching: loaderIsRunningAsync ? prev.isFetching : false,
1167
- loaderPromise: loaderIsRunningAsync ? prev.loaderPromise : void 0,
1168
- invalid: false,
1169
- pendingTimeout: void 0,
1170
- _dehydrated: void 0
1171
- };
1172
- });
1173
- return this.getMatch(matchId);
1174
- })()
1175
- );
1176
- });
1177
- await Promise.all(matchPromises);
1178
- resolveAll();
1179
- } catch (err) {
1180
- rejectAll(err);
1181
- }
1182
- })();
1183
- });
1184
- await triggerOnReady();
1185
- } catch (err) {
1186
- if (redirect.isRedirect(err) || notFound.isNotFound(err)) {
1187
- if (notFound.isNotFound(err) && !allPreload) {
1188
- await triggerOnReady();
1189
- }
1190
- throw err;
1191
- }
1192
- }
1193
- return matches;
1194
- };
1195
694
  this.invalidate = (opts) => {
1196
695
  const invalidate = (d) => {
1197
696
  if (opts?.filter?.(d) ?? true) {
1198
697
  return {
1199
698
  ...d,
1200
699
  invalid: true,
1201
- ...opts?.forcePending || d.status === "error" ? { status: "pending", error: void 0 } : {}
700
+ ...opts?.forcePending || d.status === "error" ? { status: "pending", error: void 0 } : void 0
1202
701
  };
1203
702
  }
1204
703
  return d;
@@ -1256,31 +755,7 @@ class RouterCore {
1256
755
  };
1257
756
  this.clearCache({ filter });
1258
757
  };
1259
- this.loadRouteChunk = (route) => {
1260
- if (route._lazyPromise === void 0) {
1261
- if (route.lazyFn) {
1262
- route._lazyPromise = route.lazyFn().then((lazyRoute) => {
1263
- const { id: _id, ...options2 } = lazyRoute.options;
1264
- Object.assign(route.options, options2);
1265
- });
1266
- } else {
1267
- route._lazyPromise = Promise.resolve();
1268
- }
1269
- }
1270
- if (route._componentsPromise === void 0) {
1271
- route._componentsPromise = route._lazyPromise.then(
1272
- () => Promise.all(
1273
- componentTypes.map(async (type) => {
1274
- const component = route.options[type];
1275
- if (component?.preload) {
1276
- await component.preload();
1277
- }
1278
- })
1279
- )
1280
- );
1281
- }
1282
- return route._componentsPromise;
1283
- };
758
+ this.loadRouteChunk = loadMatches.loadRouteChunk;
1284
759
  this.preloadRoute = async (opts) => {
1285
760
  const next = this.buildLocation(opts);
1286
761
  let matches = this.matchRoutes(next, {
@@ -1308,7 +783,8 @@ class RouterCore {
1308
783
  });
1309
784
  });
1310
785
  try {
1311
- matches = await this.loadMatches({
786
+ matches = await loadMatches.loadMatches({
787
+ router: this,
1312
788
  matches,
1313
789
  location: next,
1314
790
  preload: true,
@@ -1375,39 +851,6 @@ class RouterCore {
1375
851
  }
1376
852
  return match;
1377
853
  };
1378
- this._handleNotFound = (matches, err, {
1379
- updateMatch = this.updateMatch
1380
- } = {}) => {
1381
- const routeCursor = this.routesById[err.routeId ?? ""] ?? this.routeTree;
1382
- const matchesByRouteId = {};
1383
- for (const match of matches) {
1384
- matchesByRouteId[match.routeId] = match;
1385
- }
1386
- if (!routeCursor.options.notFoundComponent && this.options?.defaultNotFoundComponent) {
1387
- routeCursor.options.notFoundComponent = this.options.defaultNotFoundComponent;
1388
- }
1389
- invariant(
1390
- routeCursor.options.notFoundComponent,
1391
- "No notFoundComponent found. Please set a notFoundComponent on your route or provide a defaultNotFoundComponent to the router."
1392
- );
1393
- const matchForRoute = matchesByRouteId[routeCursor.id];
1394
- invariant(
1395
- matchForRoute,
1396
- "Could not find match for route: " + routeCursor.id
1397
- );
1398
- updateMatch(matchForRoute.id, (prev) => ({
1399
- ...prev,
1400
- status: "notFound",
1401
- error: err,
1402
- isFetching: false
1403
- }));
1404
- if (err.routerCode === "BEFORE_LOAD" && routeCursor.parentRoute) {
1405
- err.routeId = routeCursor.parentRoute.id;
1406
- this._handleNotFound(matches, err, {
1407
- updateMatch
1408
- });
1409
- }
1410
- };
1411
854
  this.hasNotFoundMatch = () => {
1412
855
  return this.__store.state.matches.some(
1413
856
  (d) => d.status === "notFound" || d.globalNotFound
@@ -1495,16 +938,16 @@ class RouterCore {
1495
938
  const matches = [];
1496
939
  const getParentContext = (parentMatch) => {
1497
940
  const parentMatchId = parentMatch?.id;
1498
- const parentContext = !parentMatchId ? this.options.context ?? {} : parentMatch.context ?? this.options.context ?? {};
941
+ const parentContext = !parentMatchId ? this.options.context ?? void 0 : parentMatch.context ?? this.options.context ?? void 0;
1499
942
  return parentContext;
1500
943
  };
1501
944
  matchedRoutes.forEach((route, index) => {
1502
945
  const parentMatch = matches[index - 1];
1503
946
  const [preMatchSearch, strictMatchSearch, searchError] = (() => {
1504
947
  const parentSearch = parentMatch?.search ?? next.search;
1505
- const parentStrictSearch = parentMatch?._strictSearch ?? {};
948
+ const parentStrictSearch = parentMatch?._strictSearch ?? void 0;
1506
949
  try {
1507
- const strictSearch = validateSearch(route.options.validateSearch, { ...parentSearch }) ?? {};
950
+ const strictSearch = validateSearch(route.options.validateSearch, { ...parentSearch }) ?? void 0;
1508
951
  return [
1509
952
  {
1510
953
  ...parentSearch,
@@ -1558,7 +1001,7 @@ class RouterCore {
1558
1001
  _strictSearch: strictMatchSearch
1559
1002
  };
1560
1003
  } else {
1561
- const status = route.options.loader || route.options.beforeLoad || route.lazyFn || routeNeedsPreload(route) ? "pending" : "success";
1004
+ const status = route.options.loader || route.options.beforeLoad || route.lazyFn || loadMatches.routeNeedsPreload(route) ? "pending" : "success";
1562
1005
  match = {
1563
1006
  id: matchId,
1564
1007
  index,
@@ -1574,7 +1017,10 @@ class RouterCore {
1574
1017
  isFetching: false,
1575
1018
  error: void 0,
1576
1019
  paramsError: parseErrors[index],
1577
- __routeContext: {},
1020
+ __routeContext: void 0,
1021
+ _nonReactive: {
1022
+ loadPromise: utils.createControlledPromise()
1023
+ },
1578
1024
  __beforeLoadContext: void 0,
1579
1025
  context: {},
1580
1026
  abortController: new AbortController(),
@@ -1588,7 +1034,6 @@ class RouterCore {
1588
1034
  headScripts: void 0,
1589
1035
  meta: void 0,
1590
1036
  staticData: route.options.staticData || {},
1591
- loadPromise: utils.createControlledPromise(),
1592
1037
  fullPath: route.fullPath
1593
1038
  };
1594
1039
  }
@@ -1610,19 +1055,21 @@ class RouterCore {
1610
1055
  if (!existingMatch && opts?._buildLocation !== true) {
1611
1056
  const parentMatch = matches[index - 1];
1612
1057
  const parentContext = getParentContext(parentMatch);
1613
- const contextFnContext = {
1614
- deps: match.loaderDeps,
1615
- params: match.params,
1616
- context: parentContext,
1617
- location: next,
1618
- navigate: (opts2) => this.navigate({ ...opts2, _fromLocation: next }),
1619
- buildLocation: this.buildLocation,
1620
- cause: match.cause,
1621
- abortController: match.abortController,
1622
- preload: !!match.preload,
1623
- matches
1624
- };
1625
- match.__routeContext = route.options.context?.(contextFnContext) ?? {};
1058
+ if (route.options.context) {
1059
+ const contextFnContext = {
1060
+ deps: match.loaderDeps,
1061
+ params: match.params,
1062
+ context: parentContext ?? {},
1063
+ location: next,
1064
+ navigate: (opts2) => this.navigate({ ...opts2, _fromLocation: next }),
1065
+ buildLocation: this.buildLocation,
1066
+ cause: match.cause,
1067
+ abortController: match.abortController,
1068
+ preload: !!match.preload,
1069
+ matches
1070
+ };
1071
+ match.__routeContext = route.options.context(contextFnContext) ?? void 0;
1072
+ }
1626
1073
  match.context = {
1627
1074
  ...parentContext,
1628
1075
  ...match.__routeContext,
@@ -1681,20 +1128,6 @@ function validateSearch(validateSearch2, input) {
1681
1128
  }
1682
1129
  return {};
1683
1130
  }
1684
- const componentTypes = [
1685
- "component",
1686
- "errorComponent",
1687
- "pendingComponent",
1688
- "notFoundComponent"
1689
- ];
1690
- function routeNeedsPreload(route) {
1691
- for (const componentType of componentTypes) {
1692
- if (route.options[componentType]?.preload) {
1693
- return true;
1694
- }
1695
- }
1696
- return false;
1697
- }
1698
1131
  const REQUIRED_PARAM_BASE_SCORE = 0.5;
1699
1132
  const OPTIONAL_PARAM_BASE_SCORE = 0.4;
1700
1133
  const WILDCARD_PARAM_BASE_SCORE = 0.25;
@@ -1925,7 +1358,7 @@ function applySearchMiddleware({
1925
1358
  try {
1926
1359
  const validatedSearch = {
1927
1360
  ...result,
1928
- ...validateSearch(route.options.validateSearch, result) ?? {}
1361
+ ...validateSearch(route.options.validateSearch, result) ?? void 0
1929
1362
  };
1930
1363
  return validatedSearch;
1931
1364
  } catch {
@@ -1963,7 +1396,6 @@ function applySearchMiddleware({
1963
1396
  exports.PathParamError = PathParamError;
1964
1397
  exports.RouterCore = RouterCore;
1965
1398
  exports.SearchParamError = SearchParamError;
1966
- exports.componentTypes = componentTypes;
1967
1399
  exports.defaultSerializeError = defaultSerializeError;
1968
1400
  exports.getInitialRouterState = getInitialRouterState;
1969
1401
  exports.getLocationChangeInfo = getLocationChangeInfo;