@tanstack/router-core 1.171.16-pre.0 → 1.171.16

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.
@@ -1,4 +1,3 @@
1
- const require_utils = require("./utils.cjs");
2
1
  const require_not_found = require("./not-found.cjs");
3
2
  const require_redirect = require("./redirect.cjs");
4
3
  const require_ssr_match_id = require("./ssr/ssr-match-id.cjs");
@@ -11,14 +10,16 @@ function replaceRouteChunk(route, lazyFn) {
11
10
  function preloadComponent(route, type) {
12
11
  return route.options[type]?.preload?.();
13
12
  }
14
- function loadComponents(route) {
13
+ function loadComponents(route, onPendingReady) {
15
14
  const component = preloadComponent(route, "component");
16
15
  const pending = preloadComponent(route, "pendingComponent");
17
- if (component && pending) return Promise.all([component, pending]).then(() => {});
18
- return component ?? pending;
16
+ const pendingReady = onPendingReady && pending ? pending.then(onPendingReady) : pending;
17
+ if (onPendingReady && !pending) onPendingReady();
18
+ if (component && pendingReady) return Promise.all([component, pendingReady]).then(() => {});
19
+ return component ?? pendingReady;
19
20
  }
20
- function loadRouteChunk(route, componentType) {
21
- const afterLazy = () => componentType === false ? void 0 : componentType ? preloadComponent(route, componentType) : loadComponents(route);
21
+ function loadRouteChunk(route, componentType, onPendingReady) {
22
+ const afterLazy = () => componentType === false ? void 0 : componentType ? preloadComponent(route, componentType) : loadComponents(route, onPendingReady);
22
23
  const current = route._lazy;
23
24
  if (current) return current === true ? afterLazy() : current.then(afterLazy);
24
25
  if (!route.lazyFn) return afterLazy();
@@ -107,7 +108,7 @@ function navigateFrom(router, location) {
107
108
  _fromLocation: location
108
109
  });
109
110
  }
110
- async function contextualize(router, lane, options, end) {
111
+ async function contextualize(router, lane, options, end, planSuccessfulLane) {
111
112
  const [location, matches] = lane;
112
113
  const signal = options[0].signal;
113
114
  const preload = !!options[4];
@@ -188,35 +189,21 @@ async function contextualize(router, lane, options, end) {
188
189
  setFetching(router, match, false, options[0]);
189
190
  }
190
191
  }
192
+ planSuccessfulLane();
191
193
  }
192
- function releaseOwnedFlight(router, id, flight) {
194
+ function releaseOwnedFlight(router, match, flight) {
193
195
  if (!flight || --flight[2]) return;
194
- if (router._flights?.get(id) === flight) router._flights.delete(id);
196
+ if (router._flights?.get(match.id) === flight) {
197
+ const current = router._tx;
198
+ if (current && !current[0].signal.aborted && !(process.env.NODE_ENV !== "production" && current[6]) && !current[3].includes(match) && current[3].some((candidate) => candidate.id === match.id) && current[3].some((candidate) => candidate.isFetching === "beforeLoad")) return;
199
+ router._flights.delete(match.id);
200
+ }
195
201
  return flight[1];
196
202
  }
197
203
  function releaseFlight(router, match) {
198
204
  const flight = match._flight;
199
205
  match._flight = void 0;
200
- releaseOwnedFlight(router, match.id, flight)?.abort();
201
- }
202
- function laneInputs(router, location) {
203
- const masked = location.maskedLocation;
204
- return [
205
- router.routeTree,
206
- router.options.context ?? {},
207
- router.options.additionalContext,
208
- require_router._getUserHistoryState(location.state),
209
- location.search,
210
- masked && [
211
- masked.href,
212
- require_router._getUserHistoryState(masked.state),
213
- masked.search,
214
- masked.unmaskOnReload
215
- ]
216
- ];
217
- }
218
- function samePreloadLane(preload, router, location, redirects) {
219
- return preload[3] === router._committed && preload[5] === redirects && require_utils.deepEqual(preload[4], laneInputs(router, location)) && !preload[0].some((match) => getRoute(router, match).options.preload === false);
206
+ releaseOwnedFlight(router, match, flight)?.abort();
220
207
  }
221
208
  /**
222
209
  * Not passing in a `next` ownership recipient
@@ -227,14 +214,31 @@ function transferMatchResources(router, previous, next) {
227
214
  for (const match of previous) if (!next?.includes(match)) {
228
215
  const flight = match._flight;
229
216
  match._flight = void 0;
230
- const controller = releaseOwnedFlight(router, match.id, flight);
217
+ const controller = releaseOwnedFlight(router, match, flight);
231
218
  if (controller) abort.push(controller);
232
219
  }
233
220
  for (const controller of abort) controller.abort();
234
221
  }
235
- function discardPreload(router, preload) {
236
- preload[1].abort();
237
- transferMatchResources(router, preload[0]);
222
+ function transferPredecessorResources(router, previous, next) {
223
+ const abort = [];
224
+ for (const match of previous) if (!next.includes(match)) {
225
+ const flight = match._flight;
226
+ match._flight = void 0;
227
+ if (flight?.[2] === 1 && router._flights?.get(match.id) === flight && !(process.env.NODE_ENV !== "production" && router._tx?.[6]) && next.some((candidate) => candidate.id === match.id)) flight[2] = 0;
228
+ else {
229
+ const controller = releaseOwnedFlight(router, match, flight);
230
+ if (controller) abort.push(controller);
231
+ }
232
+ }
233
+ for (const controller of abort) controller.abort();
234
+ }
235
+ function releaseUnownedFlights(router) {
236
+ const abort = [];
237
+ for (const [id, flight] of router._flights ?? []) if (!flight[2]) {
238
+ router._flights.delete(id);
239
+ abort.push(flight[1]);
240
+ }
241
+ for (const controller of abort) controller.abort();
238
242
  }
239
243
  function acquireMatchResources(matches) {
240
244
  for (const match of matches) {
@@ -273,38 +277,30 @@ async function loadResource(router, lane, match, route, loader, parentMatchPromi
273
277
  if (signal.aborted) return [CANCELED];
274
278
  if (!loader) return [SUCCESS, void 0];
275
279
  let flight = match._flight;
276
- let joined = !!flight;
277
280
  setFetching(router, match, "loader", owner);
278
281
  try {
279
- for (;;) {
280
- if (!flight) {
281
- const controller = new AbortController();
282
- flight = [
283
- Promise.resolve().then(() => loader(getLoaderContext(router, lane, match, route, controller, parentMatchPromise, preload))).then((value) => normalize(value, false, route.id), (cause) => normalize(cause, true, route.id)).then((result) => {
284
- return result[0] === ERROR && match._flight === flight ? normalizeError(route, result[1]) : result;
285
- }),
286
- controller,
287
- 1
288
- ];
289
- (router._flights ??= /* @__PURE__ */ new Map()).set(match.id, flight);
290
- }
291
- match._flight = flight;
292
- match.abortController = flight[1];
293
- try {
294
- const outcome = await waitFor(flight[0], signal);
295
- if (!joined || outcome[0] === SUCCESS || outcome[0] === REDIRECTED) return outcome;
296
- } catch (cause) {
297
- if (cause === signal) {
298
- releaseFlight(router, match);
299
- return [CANCELED];
300
- }
301
- throw cause;
302
- }
303
- releaseFlight(router, match);
304
- if (signal.aborted) return [CANCELED];
305
- flight = void 0;
306
- joined = false;
282
+ if (!flight) {
283
+ const controller = new AbortController();
284
+ flight = [
285
+ Promise.resolve().then(() => loader(getLoaderContext(router, lane, match, route, controller, parentMatchPromise, preload))).then((value) => normalize(value, false, route.id), (cause) => normalize(cause, true, route.id)).then((result) => {
286
+ if (result[0] !== SUCCESS && router._flights?.get(match.id) === flight) {
287
+ router._flights.delete(match.id);
288
+ if (!flight[2]) controller.abort();
289
+ }
290
+ return result[0] === ERROR && flight[2] ? normalizeError(route, result[1]) : result;
291
+ }),
292
+ controller,
293
+ 1
294
+ ];
295
+ (router._flights ??= /* @__PURE__ */ new Map()).set(match.id, flight);
307
296
  }
297
+ match._flight = flight;
298
+ match.abortController = flight[1];
299
+ return await waitFor(flight[0], signal);
300
+ } catch (cause) {
301
+ if (cause !== signal) throw cause;
302
+ releaseFlight(router, match);
303
+ return [CANCELED];
308
304
  } finally {
309
305
  setFetching(router, match, false, owner);
310
306
  }
@@ -349,10 +345,10 @@ function createLoaderTask(router, lane, index, tasks, semanticParent, options) {
349
345
  const route = getRoute(router, match);
350
346
  const preload = !!options[4];
351
347
  const plannedCacheMatch = preload ? router._cache.get(match.id) : void 0;
348
+ let configured;
352
349
  let reload = false;
353
350
  let reloadFailure;
354
351
  try {
355
- let configured;
356
352
  if (match.status === "success") {
357
353
  configured = route.options.shouldReload;
358
354
  if (typeof configured === "function") configured = configured(getLoaderContext(router, lane, match, route, options[0], semanticParent, preload));
@@ -373,20 +369,23 @@ function createLoaderTask(router, lane, index, tasks, semanticParent, options) {
373
369
  }
374
370
  const routeLoader = route.options.loader;
375
371
  const loader = typeof routeLoader === "function" ? routeLoader : routeLoader?.handler;
372
+ let donor = (!preload || route.options.preload !== false) && routeLoader && !(process.env.NODE_ENV !== "production" && router._tx?.[6]) ? router._flights?.get(match.id) : void 0;
373
+ if (donor === match._flight || reloadFailure) donor = void 0;
374
+ else if (donor && !reload && !preload && configured === void 0) reload = true;
375
+ else if (!reload) donor = void 0;
376
376
  const background = !!(routeLoader && reload && match.status === "success" && !preload && !options[5] && ((typeof routeLoader === "function" ? void 0 : routeLoader?.staleReloadMode) ?? router.options.defaultStaleReloadMode) !== "blocking");
377
377
  const loaded = reload && (!preload || route.options.preload !== false);
378
378
  const blocking = loaded && !background && (match.status !== "success" || !!routeLoader);
379
+ const onLazyReady = route.lazyFn && route._lazy !== true ? options[8] : void 0;
379
380
  if (loaded && !routeLoader) {
380
381
  match.invalid = false;
381
382
  match.updatedAt = Date.now();
382
383
  }
383
- let donor = loaded && routeLoader ? router._flights?.get(match.id) : void 0;
384
- if (donor === match._flight) donor = void 0;
385
- else if (donor) donor[2]++;
384
+ if (donor) donor[2]++;
386
385
  if (blocking) {
387
386
  const acceptedFlight = match._flight;
388
387
  match._flight = donor;
389
- releaseOwnedFlight(router, match.id, acceptedFlight)?.abort();
388
+ releaseOwnedFlight(router, match, acceptedFlight)?.abort();
390
389
  if (match.status === "success") match.status = "pending";
391
390
  options[8]?.();
392
391
  }
@@ -395,15 +394,13 @@ function createLoaderTask(router, lane, index, tasks, semanticParent, options) {
395
394
  if (blocking) {
396
395
  settleInto(match, result, preload);
397
396
  if (result[0] === SUCCESS) {
398
- if (preload && routeLoader) cacheLoaderMatch(router, match, plannedCacheMatch);
397
+ if (preload && routeLoader && !options[0].signal.aborted) cacheLoaderMatch(router, match, plannedCacheMatch);
399
398
  match.status = "pending";
400
399
  }
401
400
  }
402
401
  return result;
403
402
  });
404
- const chunkFailure = waitFor(Promise.resolve().then(() => loadRouteChunk(route)), options[0].signal).then(() => {
405
- options[8]?.();
406
- }, (cause) => [index, normalizeLaneError(route, cause, options)]).then((failure) => outcome.then((result) => {
403
+ const chunkFailure = waitFor(Promise.resolve().then(() => loadRouteChunk(route, void 0, onLazyReady)), options[0].signal).then(() => void 0, (cause) => [index, normalizeLaneError(route, cause, options)]).then((failure) => outcome.then((result) => {
407
404
  if (blocking && !failure && result[0] === SUCCESS && match.status === "pending" && options[2]()) {
408
405
  match.status = "success";
409
406
  options[8]?.();
@@ -603,20 +600,26 @@ async function executeClientLane(router, location, matches, options) {
603
600
  plannedBoundary = boundary;
604
601
  }
605
602
  let end = plannedBoundary < 0 ? matches.length : plannedBoundary + 1;
606
- const failure = await contextualize(router, matched, options, end);
607
- if (failure) options[5] = true;
608
603
  const tasks = [];
609
604
  const start = options[7] ?? 0;
610
605
  let semanticParent = start ? Promise.resolve(matched[1][start - 1]) : void 0;
611
- end = failure?.[0] ?? end;
612
- if (failure?.[1][0] === NOT_FOUND) {
613
- failure[2] = await getNotFoundBoundary(router, matched[1], failure, options[0].signal);
614
- end = Math.min(end, failure[2] + 1);
615
- } else if ((failure?.[1][0] ?? 0) >= REDIRECTED) end = 0;
616
- for (let index = start; index < end; index++) {
617
- if (options[0].signal.aborted) break;
618
- semanticParent = createLoaderTask(router, matched, index, tasks, semanticParent, options);
619
- }
606
+ const planSuccessfulLane = () => {
607
+ for (let index = start; index < end; index++) {
608
+ if (options[0].signal.aborted) break;
609
+ semanticParent = createLoaderTask(router, matched, index, tasks, semanticParent, options);
610
+ }
611
+ };
612
+ const failure = await contextualize(router, matched, options, end, planSuccessfulLane);
613
+ if (failure) {
614
+ options[5] = true;
615
+ end = failure[0];
616
+ if (failure[1][0] === NOT_FOUND) {
617
+ failure[2] = await getNotFoundBoundary(router, matched[1], failure, options[0].signal);
618
+ end = Math.min(end, failure[2] + 1);
619
+ } else if (failure[1][0] >= REDIRECTED) end = 0;
620
+ planSuccessfulLane();
621
+ }
622
+ if (options[2]() && !options[4]) releaseUnownedFlights(router);
620
623
  let reduced;
621
624
  try {
622
625
  const reduction = reduceLane(router, matched, tasks, options[0], options[1], settleTasks(tasks, failure, matched[2]), options[8]);
@@ -706,7 +709,7 @@ function offerPending(router, tx) {
706
709
  _flight: void 0
707
710
  }));
708
711
  offered[boundary].status = "pending";
709
- const ack = router.startTransition(() => router.stores.setMatches(offered), offered, true).then((rendered) => {
712
+ const ack = router.startTransition(() => router.stores.setMatches(offered), offered).then((rendered) => {
710
713
  if (rendered && router._pending === session && session[4] === ack && !session[2]) session[2] = Date.now() + min;
711
714
  return rendered;
712
715
  });
@@ -803,16 +806,17 @@ function rollbackPublication(router, tx, lane, checkpoint) {
803
806
  return true;
804
807
  }
805
808
  async function transitionRefresh(router, tx, lane, changeInfo) {
809
+ const refresh = tx[6];
806
810
  const checkpoint = {
807
811
  previousMatches: router._committed,
808
- previousPresentation: tx[6]?.[0] ?? router.stores.matches.get(),
812
+ previousPresentation: refresh[0],
809
813
  previousCache: router._cache,
810
814
  commitPromise: router._commitPromise,
811
815
  published: false
812
816
  };
813
817
  const commit = () => {
814
818
  finishPending(router, tx);
815
- router._rollbackRefresh = rollback;
819
+ refresh[2] = rollback;
816
820
  commitRefreshMatches(router, tx, lane[1], checkpoint);
817
821
  if (!checkpoint.published || router._tx !== tx) return;
818
822
  router.emit({
@@ -825,16 +829,16 @@ async function transitionRefresh(router, tx, lane, changeInfo) {
825
829
  });
826
830
  };
827
831
  const rollback = () => {
828
- if (router._rollbackRefresh === rollback) router._rollbackRefresh = void 0;
832
+ if (refresh[2] === rollback) refresh[2] = void 0;
829
833
  const restored = rollbackPublication(router, tx, lane, checkpoint);
830
834
  router._cancelTransition?.();
831
835
  return restored;
832
836
  };
833
837
  try {
834
838
  const rendered = await router.startTransition(commit, lane[1]);
835
- if (router._rollbackRefresh === rollback) router._rollbackRefresh = void 0;
839
+ if (refresh[2] === rollback) refresh[2] = void 0;
836
840
  if (checkpoint.published) {
837
- const handoff = tx[6]?.[1];
841
+ const handoff = refresh[1];
838
842
  if (handoff && router._handoff === handoff) handoff[1]();
839
843
  if (router._tx === tx) tx[6] = void 0;
840
844
  }
@@ -911,7 +915,7 @@ async function runBackground(router, tx, base, tasks, settlement) {
911
915
  publishMatches(router, projected[1]);
912
916
  transferMatchResources(router, base, projected[1]);
913
917
  }
914
- async function runClientTransaction(router, tx, forceStaleReload, onReady, sync, resolvedPrefix, adopted, retained) {
918
+ async function runClientTransaction(router, tx, forceStaleReload, onReady, sync, resolvedPrefix) {
915
919
  const options = [
916
920
  tx[0],
917
921
  tx[1],
@@ -923,24 +927,7 @@ async function runClientTransaction(router, tx, forceStaleReload, onReady, sync,
923
927
  resolvedPrefix,
924
928
  onReady
925
929
  ];
926
- let result;
927
- try {
928
- result = adopted ? await adopted[2] : await executeClientLane(router, tx[2], tx[3], options);
929
- } finally {
930
- if (retained) discardPreload(router, retained);
931
- }
932
- if (adopted && router._tx === tx && (isControl(result) && result[0] === CANCELED || !isControl(result) && result[1].some((match) => match.status !== "success" || match._notFound))) {
933
- const donors = tx[3];
934
- tx[3] = [];
935
- transferMatchResources(router, donors);
936
- tx[0].abort();
937
- if (router._tx !== tx) return;
938
- const controller = new AbortController();
939
- tx[0] = options[0] = controller;
940
- tx[3] = router.matchRoutes(tx[2], { _controller: controller });
941
- acquireMatchResources(tx[3]);
942
- result = await executeClientLane(router, tx[2], tx[3], options);
943
- }
930
+ const result = await executeClientLane(router, tx[2], tx[3], options);
944
931
  if (isControl(result)) {
945
932
  if (result[0] === REDIRECTED && router._tx === tx) {
946
933
  finishPending(router, tx);
@@ -1036,7 +1023,7 @@ async function runClientTransaction(router, tx, forceStaleReload, onReady, sync,
1036
1023
  async function loadClientRoute(router, opts) {
1037
1024
  let rematerialize = false;
1038
1025
  if (process.env.NODE_ENV !== "production") {
1039
- router._rollbackRefresh?.();
1026
+ router._tx?.[6]?.[2]?.();
1040
1027
  rematerialize = !!router._refreshNextLoad || !!router._tx?.[6];
1041
1028
  }
1042
1029
  const refreshPresentation = rematerialize ? router.stores.matches.get() : void 0;
@@ -1046,10 +1033,6 @@ async function loadClientRoute(router, opts) {
1046
1033
  const location = router.latestLocation;
1047
1034
  const pendingLocation = router._pendingLocation;
1048
1035
  const redirects = pendingLocation?.href === location.href ? pendingLocation._redirects ?? 0 : 0;
1049
- if (opts?._dedupe && !redirects && previousOwner && !rematerialize && previousOwner[2].href === location.href && router.stores.status.get() === "pending") {
1050
- await awaitCurrent(router);
1051
- return;
1052
- }
1053
1036
  const handoff = router._handoff;
1054
1037
  const hydrationController = rematerialize ? void 0 : handoff?.[0]();
1055
1038
  const preflight = new AbortController();
@@ -1057,7 +1040,7 @@ async function loadClientRoute(router, opts) {
1057
1040
  router._preflight = preflight;
1058
1041
  if (!rematerialize && !hydrationController) handoff?.[1]();
1059
1042
  previousPreflight?.abort();
1060
- if (preflight.signal.aborted || router._tx !== previousOwner) {
1043
+ if (preflight.signal.aborted) {
1061
1044
  await awaitCurrent(router, previousOwner);
1062
1045
  return;
1063
1046
  }
@@ -1066,71 +1049,44 @@ async function loadClientRoute(router, opts) {
1066
1049
  type: "onBeforeNavigate",
1067
1050
  ...changeInfo
1068
1051
  });
1069
- if (!preflight.signal.aborted && router._tx === previousOwner) router.emit({
1052
+ if (!preflight.signal.aborted) router.emit({
1070
1053
  type: "onBeforeLoad",
1071
1054
  ...changeInfo
1072
1055
  });
1073
- if (preflight.signal.aborted || router._tx !== previousOwner) {
1074
- preflight.abort();
1056
+ if (preflight.signal.aborted) {
1075
1057
  await awaitCurrent(router, previousOwner);
1076
1058
  return;
1077
1059
  }
1078
1060
  const sameHref = previousLocation.href === location.href;
1079
- let adopted = router._preloads?.get(location.href);
1080
- let retained;
1081
- if (rematerialize && adopted) {
1082
- router._preloads.delete(location.href);
1083
- discardPreload(router, adopted);
1084
- adopted = void 0;
1085
- if (preflight.signal.aborted || router._tx !== previousOwner) {
1086
- preflight.abort();
1087
- await awaitCurrent(router, previousOwner);
1088
- return;
1089
- }
1090
- }
1091
- if (adopted && (hydrationController || !samePreloadLane(adopted, router, pendingLocation?.href === location.href ? pendingLocation : location, redirects))) {
1092
- router._preloads.delete(location.href);
1093
- retained = adopted;
1094
- adopted = void 0;
1095
- }
1096
1061
  let matches;
1097
1062
  let controller = preflight;
1098
- let resolvedPrefix;
1099
- if (adopted) {
1100
- controller = adopted[1];
1101
- matches = adopted[0];
1102
- router._preloads.delete(location.href);
1103
- } else {
1104
- try {
1105
- matches = process.env.NODE_ENV !== "production" && rematerialize ? router.matchRoutes(location, {
1106
- _controller: preflight,
1107
- _rematerialize: true
1108
- }) : router.matchRoutes(location, { _controller: preflight });
1109
- acquireMatchResources(matches);
1110
- } catch (cause) {
1111
- preflight.abort();
1112
- if (retained) discardPreload(router, retained);
1113
- if (!require_redirect.isRedirect(cause)) {
1114
- if (process.env.NODE_ENV !== "production" && rematerialize) router._refreshNextLoad = void 0;
1115
- await awaitCurrent(router);
1116
- router._commitPromise?.resolve();
1117
- router._commitPromise = void 0;
1118
- return;
1119
- }
1120
- await router.navigate({
1121
- ...cause.options,
1122
- replace: true,
1123
- ignoreBlocker: true
1124
- });
1125
- await awaitCurrent(router, previousOwner);
1063
+ try {
1064
+ matches = process.env.NODE_ENV !== "production" && rematerialize ? router.matchRoutes(location, {
1065
+ _controller: preflight,
1066
+ _rematerialize: true
1067
+ }) : router.matchRoutes(location, { _controller: preflight });
1068
+ acquireMatchResources(matches);
1069
+ } catch (cause) {
1070
+ preflight.abort();
1071
+ if (!require_redirect.isRedirect(cause)) {
1072
+ if (process.env.NODE_ENV !== "production" && rematerialize) router._refreshNextLoad = void 0;
1073
+ await awaitCurrent(router);
1074
+ router._commitPromise?.resolve();
1075
+ router._commitPromise = void 0;
1126
1076
  return;
1127
1077
  }
1128
- resolvedPrefix = hydrationController ? handoff[1](matches) : void 0;
1129
- if (resolvedPrefix) controller = hydrationController;
1130
- else hydrationController?.abort();
1078
+ await router.navigate({
1079
+ ...cause.options,
1080
+ replace: true,
1081
+ ignoreBlocker: true
1082
+ });
1083
+ await awaitCurrent(router, previousOwner);
1084
+ return;
1131
1085
  }
1132
- if (router._preflight !== preflight || router._tx !== previousOwner) {
1133
- preflight.abort();
1086
+ const resolvedPrefix = hydrationController ? handoff[1](matches) : void 0;
1087
+ if (resolvedPrefix) controller = hydrationController;
1088
+ else hydrationController?.abort();
1089
+ if (preflight.signal.aborted) {
1134
1090
  transferMatchResources(router, matches);
1135
1091
  await awaitCurrent(router, previousOwner);
1136
1092
  return;
@@ -1142,7 +1098,7 @@ async function loadClientRoute(router, opts) {
1142
1098
  location,
1143
1099
  matches,
1144
1100
  Date.now(),
1145
- Promise.resolve().then(() => runClientTransaction(router, tx, sameHref, () => offerPending(router, tx), opts?.sync, resolvedPrefix, adopted, retained)).catch(() => {
1101
+ Promise.resolve().then(() => runClientTransaction(router, tx, sameHref, () => offerPending(router, tx), opts?.sync, resolvedPrefix)).catch(() => {
1146
1102
  if (router._tx === tx) restoreCommitted(router, tx);
1147
1103
  })
1148
1104
  ];
@@ -1151,14 +1107,13 @@ async function loadClientRoute(router, opts) {
1151
1107
  router._refreshNextLoad = void 0;
1152
1108
  }
1153
1109
  router._tx = tx;
1154
- if (!rematerialize && router._handoff === handoff) router._handoff = void 0;
1155
1110
  if (previousOwner) {
1156
1111
  for (const match of router.stores.matches.get()) {
1157
1112
  if (router._tx !== tx) break;
1158
1113
  if (match.isFetching) setFetching(router, match, false);
1159
1114
  }
1160
1115
  previousOwner[0].abort();
1161
- transferMatchResources(router, previousOwner[3]);
1116
+ transferPredecessorResources(router, previousOwner[3], tx[3]);
1162
1117
  }
1163
1118
  if (router._tx !== tx) {
1164
1119
  transferMatchResources(router, tx[3]);
@@ -1178,7 +1133,7 @@ async function loadClientRoute(router, opts) {
1178
1133
  }
1179
1134
  }
1180
1135
  async function refreshClientRoute(router) {
1181
- router._rollbackRefresh?.();
1136
+ router._tx?.[6]?.[2]?.();
1182
1137
  const pending = router._tx;
1183
1138
  if (pending && !pending[6] && router.stores.status.get() === "pending") {
1184
1139
  await pending[5];
@@ -1189,72 +1144,45 @@ async function refreshClientRoute(router) {
1189
1144
  router._refreshNextLoad = true;
1190
1145
  await loadClientRoute(router, { sync: true });
1191
1146
  }
1192
- function followPreloadRedirect(router, result, location, owner, redirects) {
1193
- if (result[0] === REDIRECTED && !result[1].options.reloadDocument && router._tx === owner) return preloadClientRoute(router, {
1194
- ...result[1].options,
1195
- _fromLocation: location
1196
- }, redirects + 1);
1197
- }
1198
1147
  async function preloadClientRoute(router, opts, redirects = 0) {
1199
1148
  if (redirects > 20) return;
1200
- const owner = router._tx;
1201
- if (process.env.NODE_ENV !== "production" && (router._refreshNextLoad || owner?.[6])) return;
1149
+ if (process.env.NODE_ENV !== "production" && (router._refreshNextLoad || router._tx?.[6])) return;
1202
1150
  const location = opts._builtLocation ?? router.buildLocation(opts);
1203
1151
  const base = router._committed;
1204
1152
  const controller = new AbortController();
1205
1153
  let matches;
1206
- let preload;
1207
- let replaced;
1208
1154
  try {
1209
- const pending = router._preloads?.get(location.href);
1210
- if (pending) {
1211
- if (samePreloadLane(pending, router, location, redirects)) {
1212
- const result = await pending[2];
1213
- return isControl(result) ? followPreloadRedirect(router, result, location, owner, redirects) : result[1];
1214
- }
1215
- router._preloads.delete(location.href);
1216
- replaced = pending;
1217
- }
1218
1155
  matches = router.matchRoutes(location, { _controller: controller });
1219
1156
  acquireMatchResources(matches);
1220
- const promise = Promise.resolve().then(() => executeClientLane(router, location, matches, [
1221
- controller,
1222
- redirects,
1223
- () => true,
1224
- base,
1225
- true
1226
- ])).finally(() => {
1227
- if (replaced) discardPreload(router, replaced);
1228
- });
1229
- preload = [
1230
- matches,
1231
- controller,
1232
- promise,
1233
- base,
1234
- laneInputs(router, location),
1235
- redirects
1236
- ];
1237
- (router._preloads ??= /* @__PURE__ */ new Map()).set(location.href, preload);
1238
- const result = await promise;
1239
- if (router._preloads?.get(location.href) !== preload) return isControl(result) ? void 0 : result[1];
1240
- router._preloads.delete(location.href);
1241
- if (isControl(result)) {
1242
- controller.abort();
1243
- transferMatchResources(router, matches);
1244
- return followPreloadRedirect(router, result, location, owner, redirects);
1245
- }
1246
- transferMatchResources(router, result[1]);
1247
- controller.abort();
1248
- return result[1];
1249
1157
  } catch (cause) {
1250
- if (!preload || router._preloads?.get(location.href) === preload) {
1251
- if (preload) router._preloads.delete(location.href);
1158
+ controller.abort();
1159
+ if (!require_not_found.isNotFound(cause)) console.error(cause);
1160
+ return;
1161
+ }
1162
+ (router._preloads ??= /* @__PURE__ */ new Map()).set(controller, matches);
1163
+ let active;
1164
+ try {
1165
+ let result;
1166
+ try {
1167
+ result = await executeClientLane(router, location, matches, [
1168
+ controller,
1169
+ redirects,
1170
+ () => true,
1171
+ base,
1172
+ true
1173
+ ]);
1174
+ } finally {
1175
+ active = router._preloads.delete(controller);
1176
+ transferMatchResources(router, matches);
1252
1177
  controller.abort();
1253
- if (matches) transferMatchResources(router, matches);
1254
1178
  }
1255
- if (router._tx !== owner) return;
1179
+ if (!isControl(result)) return result[1];
1180
+ if (active && result[0] === REDIRECTED && !result[1].options.reloadDocument) return preloadClientRoute(router, {
1181
+ ...result[1].options,
1182
+ _fromLocation: location
1183
+ }, redirects + 1);
1184
+ } catch (cause) {
1256
1185
  if (!require_not_found.isNotFound(cause)) console.error(cause);
1257
- return;
1258
1186
  }
1259
1187
  }
1260
1188
  async function hydrate(router) {
@@ -1269,32 +1197,30 @@ async function hydrate(router) {
1269
1197
  const dehydratedRouter = tsr.router;
1270
1198
  if (process.env.NODE_ENV !== "production" && !dehydratedRouter) throw new Error("Invariant failed: Expected to find a dehydrated data on window.$_TSR.router, but we did not. Please file an issue!");
1271
1199
  router.ssr = { manifest: dehydratedRouter.manifest };
1272
- const nonce = document.querySelector("meta[property=\"csp-nonce\"]")?.content;
1273
- router.options.ssr = { nonce };
1200
+ router.options.ssr = { nonce: document.querySelector("meta[property=\"csp-nonce\"]")?.content };
1274
1201
  const dehydratedMatches = dehydratedRouter.matches;
1275
1202
  const controller = new AbortController();
1276
1203
  const previousPreflight = router._preflight;
1277
1204
  router._preflight = controller;
1278
1205
  previousPreflight?.abort();
1279
- const retire = (cause) => {
1280
- if (router._preflight === controller) router._preflight = void 0;
1281
- controller.abort(cause);
1282
- return false;
1283
- };
1284
- const isCurrent = () => !router._tx && router._preflight === controller && !controller.signal.aborted || retire();
1206
+ const isCurrent = () => router._preflight === controller;
1285
1207
  let location;
1286
1208
  let candidates;
1287
- let handoffInputs;
1209
+ let handoffHistoryHref;
1210
+ let handoffHistoryState;
1288
1211
  try {
1289
1212
  await waitFor(router.options.hydrate?.(dehydratedRouter.dehydratedData), controller.signal);
1290
1213
  if (!isCurrent()) return;
1214
+ const historyLocation = router.history.location;
1215
+ handoffHistoryHref = historyLocation.href;
1216
+ handoffHistoryState = historyLocation.state;
1291
1217
  router.updateLatestLocation();
1292
1218
  location = router.latestLocation;
1293
1219
  router.stores.location.set(location);
1294
- handoffInputs = laneInputs(router, location);
1295
1220
  candidates = router.matchRoutes(location, { _controller: controller });
1296
1221
  } catch (cause) {
1297
- retire(cause);
1222
+ if (isCurrent()) router._preflight = void 0;
1223
+ controller.abort(cause);
1298
1224
  if (cause !== controller.signal) throw cause;
1299
1225
  }
1300
1226
  if (!isCurrent()) return;
@@ -1343,7 +1269,6 @@ async function hydrate(router) {
1343
1269
  committed.push(candidate);
1344
1270
  if (candidate.ssr === "data-only") pendingBoundary ??= index;
1345
1271
  }
1346
- let verifiedContextEnd = verifiedAssetEnd;
1347
1272
  if (!isTerminal && committed.length === shared && shared < candidates.length) pendingBoundary = shared;
1348
1273
  const chunks = committed.map(async (match) => {
1349
1274
  try {
@@ -1359,15 +1284,11 @@ async function hydrate(router) {
1359
1284
  try {
1360
1285
  while (chunkFailure < chunks.length && await waitFor(chunks[chunkFailure], controller.signal)) chunkFailure++;
1361
1286
  } catch {
1362
- isCurrent();
1363
1287
  return;
1364
1288
  }
1365
1289
  if (!isCurrent()) return;
1366
- if (chunkFailure < committed.length) {
1367
- verifiedContextEnd = Math.min(verifiedContextEnd, chunkFailure);
1368
- retryFrom(chunkFailure);
1369
- }
1370
- const contextEnd = Math.max(pendingBoundary === committed.length ? committed.length + 1 : committed.length, verifiedContextEnd);
1290
+ if (chunkFailure < committed.length) retryFrom(chunkFailure);
1291
+ const contextEnd = Math.max(pendingBoundary === committed.length ? committed.length + 1 : committed.length, chunkFailure < chunks.length ? chunkFailure : verifiedAssetEnd);
1371
1292
  for (let index = 0; index < contextEnd; index++) {
1372
1293
  const match = candidates[index];
1373
1294
  const route = getRoute(router, match);
@@ -1411,7 +1332,7 @@ async function hydrate(router) {
1411
1332
  let dataOnlyAssetEnd;
1412
1333
  if (needsClientLoad && pendingBoundary !== void 0) {
1413
1334
  const boundary = presented[pendingBoundary];
1414
- dataOnlyAssetEnd = boundary.status === "success" && boundary.ssr === "data-only" && boundary.error === void 0 && !boundary._notFound && verifiedAssetEnd > pendingBoundary + 1 ? verifiedAssetEnd : void 0;
1335
+ dataOnlyAssetEnd = boundary.ssr === "data-only" && verifiedAssetEnd > pendingBoundary + 1 ? verifiedAssetEnd : void 0;
1415
1336
  presented = presented.slice();
1416
1337
  presented[pendingBoundary] = {
1417
1338
  ...boundary,
@@ -1420,19 +1341,22 @@ async function hydrate(router) {
1420
1341
  _assetEnd: dataOnlyAssetEnd
1421
1342
  };
1422
1343
  }
1423
- const claim = () => needsClientLoad && !router._tx && router.latestLocation.state === location.state && require_utils.deepEqual(handoffInputs, laneInputs(router, router.latestLocation)) && router._committed === committedMatches && committedMatches.length && !controller.signal.aborted ? controller : void 0;
1344
+ const claim = () => {
1345
+ const historyLocation = router.history.location;
1346
+ return needsClientLoad && !router._tx && historyLocation.href === handoffHistoryHref && historyLocation.state === handoffHistoryState && router._committed === committedMatches && committedMatches.length && !controller.signal.aborted ? controller : void 0;
1347
+ };
1424
1348
  const handoff = [claim, (matches) => {
1425
1349
  if (router._handoff !== handoff) return;
1350
+ router._handoff = void 0;
1426
1351
  const prefix = committedMatches.length;
1427
1352
  if (!matches || !claim() || committedMatches.some((match, index) => match.id !== matches[index]?.id)) {
1428
- router._handoff = void 0;
1429
1353
  controller.abort();
1430
1354
  return;
1431
1355
  }
1432
1356
  let handoffAssetEnd = dataOnlyAssetEnd;
1433
1357
  if (handoffAssetEnd !== void 0) {
1434
1358
  for (let index = prefix; index < handoffAssetEnd; index++) if (candidates[index]?.id !== matches[index]?.id) {
1435
- handoffAssetEnd = index > (pendingBoundary ?? -1) + 1 ? index : void 0;
1359
+ handoffAssetEnd = index > pendingBoundary + 1 ? index : void 0;
1436
1360
  break;
1437
1361
  }
1438
1362
  }
@@ -1465,6 +1389,5 @@ exports.loadRouteChunk = loadRouteChunk;
1465
1389
  exports.preloadClientRoute = preloadClientRoute;
1466
1390
  exports.refreshClientRoute = refreshClientRoute;
1467
1391
  exports.replaceRouteChunk = replaceRouteChunk;
1468
- exports.transferMatchResources = transferMatchResources;
1469
1392
 
1470
1393
  //# sourceMappingURL=load-client.cjs.map