@tanstack/router-core 1.171.16-pre.0 → 1.171.17
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.
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +5 -3
- package/dist/cjs/load-client.cjs +169 -246
- package/dist/cjs/load-client.cjs.map +1 -1
- package/dist/cjs/load-client.d.cts +10 -39
- package/dist/cjs/router.cjs +42 -22
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +14 -10
- package/dist/esm/link.d.ts +5 -3
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/load-client.d.ts +10 -39
- package/dist/esm/load-client.js +171 -247
- package/dist/esm/load-client.js.map +1 -1
- package/dist/esm/router.d.ts +14 -10
- package/dist/esm/router.js +44 -23
- package/dist/esm/router.js.map +1 -1
- package/package.json +3 -3
- package/skills/router-core/SKILL.md +23 -4
- package/skills/router-core/auth-and-guards/SKILL.md +10 -10
- package/skills/router-core/code-splitting/SKILL.md +5 -4
- package/skills/router-core/data-loading/SKILL.md +30 -18
- package/skills/router-core/navigation/SKILL.md +5 -4
- package/skills/router-core/not-found-and-errors/SKILL.md +5 -4
- package/skills/router-core/path-params/SKILL.md +5 -4
- package/skills/router-core/search-params/SKILL.md +5 -4
- package/skills/router-core/ssr/SKILL.md +5 -4
- package/skills/router-core/type-safety/SKILL.md +11 -4
- package/src/link.ts +5 -3
- package/src/load-client.ts +582 -632
- package/src/router.ts +87 -44
package/dist/cjs/load-client.cjs
CHANGED
|
@@ -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
|
-
|
|
18
|
-
|
|
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,
|
|
194
|
+
function releaseOwnedFlight(router, match, flight) {
|
|
193
195
|
if (!flight || --flight[2]) return;
|
|
194
|
-
if (router._flights?.get(id) === flight)
|
|
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
|
|
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
|
|
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
|
|
236
|
-
|
|
237
|
-
|
|
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
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
1
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
match.
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
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 (
|
|
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 (
|
|
839
|
+
if (refresh[2] === rollback) refresh[2] = void 0;
|
|
836
840
|
if (checkpoint.published) {
|
|
837
|
-
const handoff =
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
|
1052
|
+
if (!preflight.signal.aborted) router.emit({
|
|
1070
1053
|
type: "onBeforeLoad",
|
|
1071
1054
|
...changeInfo
|
|
1072
1055
|
});
|
|
1073
|
-
if (preflight.signal.aborted
|
|
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
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
router.
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
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
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1078
|
+
await router.navigate({
|
|
1079
|
+
...cause.options,
|
|
1080
|
+
replace: true,
|
|
1081
|
+
ignoreBlocker: true
|
|
1082
|
+
});
|
|
1083
|
+
await awaitCurrent(router, previousOwner);
|
|
1084
|
+
return;
|
|
1131
1085
|
}
|
|
1132
|
-
|
|
1133
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
1251
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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 = () =>
|
|
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 >
|
|
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
|