@tanstack/router-core 1.166.2 → 1.166.4
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/load-matches.cjs +31 -4
- package/dist/cjs/load-matches.cjs.map +1 -1
- package/dist/cjs/load-matches.d.cts +1 -0
- package/dist/cjs/router.cjs +2 -0
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/esm/load-matches.d.ts +1 -0
- package/dist/esm/load-matches.js +31 -4
- package/dist/esm/load-matches.js.map +1 -1
- package/dist/esm/router.js +2 -0
- package/dist/esm/router.js.map +1 -1
- package/package.json +1 -1
- package/src/load-matches.ts +51 -6
- package/src/router.ts +2 -0
package/package.json
CHANGED
package/src/load-matches.ts
CHANGED
|
@@ -33,6 +33,7 @@ type InnerLoadContext = {
|
|
|
33
33
|
updateMatch: UpdateMatchFn
|
|
34
34
|
matches: Array<AnyRouteMatch>
|
|
35
35
|
preload?: boolean
|
|
36
|
+
forceStaleReload?: boolean
|
|
36
37
|
onReady?: () => Promise<void>
|
|
37
38
|
sync?: boolean
|
|
38
39
|
}
|
|
@@ -166,7 +167,10 @@ const shouldSkipLoader = (
|
|
|
166
167
|
inner: InnerLoadContext,
|
|
167
168
|
matchId: string,
|
|
168
169
|
): boolean => {
|
|
169
|
-
const match = inner.router.getMatch(matchId)
|
|
170
|
+
const match = inner.router.getMatch(matchId)
|
|
171
|
+
if (!match) {
|
|
172
|
+
return true
|
|
173
|
+
}
|
|
170
174
|
// upon hydration, we skip the loader if the match has been dehydrated on the server
|
|
171
175
|
if (!(isServer ?? inner.router.isServer) && match._nonReactive.dehydrated) {
|
|
172
176
|
return true
|
|
@@ -179,6 +183,21 @@ const shouldSkipLoader = (
|
|
|
179
183
|
return false
|
|
180
184
|
}
|
|
181
185
|
|
|
186
|
+
const syncMatchContext = (
|
|
187
|
+
inner: InnerLoadContext,
|
|
188
|
+
matchId: string,
|
|
189
|
+
index: number,
|
|
190
|
+
): void => {
|
|
191
|
+
const nextContext = buildMatchContext(inner, index)
|
|
192
|
+
|
|
193
|
+
inner.updateMatch(matchId, (prev) => {
|
|
194
|
+
return {
|
|
195
|
+
...prev,
|
|
196
|
+
context: nextContext,
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
|
|
182
201
|
const handleSerialError = (
|
|
183
202
|
inner: InnerLoadContext,
|
|
184
203
|
index: number,
|
|
@@ -479,8 +498,6 @@ const executeBeforeLoad = (
|
|
|
479
498
|
|
|
480
499
|
batch(() => {
|
|
481
500
|
pending()
|
|
482
|
-
// Only store __beforeLoadContext here, don't update context yet
|
|
483
|
-
// Context will be updated in loadRouteMatch after loader completes
|
|
484
501
|
inner.updateMatch(matchId, (prev) => ({
|
|
485
502
|
...prev,
|
|
486
503
|
__beforeLoadContext: beforeLoadContext,
|
|
@@ -762,6 +779,7 @@ const loadRouteMatch = async (
|
|
|
762
779
|
async function handleLoader(
|
|
763
780
|
preload: boolean,
|
|
764
781
|
prevMatch: AnyRouteMatch,
|
|
782
|
+
previousRouteMatchId: string | undefined,
|
|
765
783
|
match: AnyRouteMatch,
|
|
766
784
|
route: AnyRoute,
|
|
767
785
|
) {
|
|
@@ -787,8 +805,15 @@ const loadRouteMatch = async (
|
|
|
787
805
|
|
|
788
806
|
// If the route is successful and still fresh, just resolve
|
|
789
807
|
const { status, invalid } = match
|
|
808
|
+
const staleMatchShouldReload =
|
|
809
|
+
age > staleAge &&
|
|
810
|
+
(!!inner.forceStaleReload ||
|
|
811
|
+
match.cause === 'enter' ||
|
|
812
|
+
(previousRouteMatchId !== undefined &&
|
|
813
|
+
previousRouteMatchId !== match.id))
|
|
790
814
|
loaderShouldRunAsync =
|
|
791
|
-
status === 'success' &&
|
|
815
|
+
status === 'success' &&
|
|
816
|
+
(invalid || (shouldReload ?? staleMatchShouldReload))
|
|
792
817
|
if (preload && route.options.preload === false) {
|
|
793
818
|
// Do nothing
|
|
794
819
|
} else if (loaderShouldRunAsync && !inner.sync) {
|
|
@@ -808,6 +833,8 @@ const loadRouteMatch = async (
|
|
|
808
833
|
})()
|
|
809
834
|
} else if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {
|
|
810
835
|
await runLoader(inner, matchPromises, matchId, index, route)
|
|
836
|
+
} else {
|
|
837
|
+
syncMatchContext(inner, matchId, index)
|
|
811
838
|
}
|
|
812
839
|
}
|
|
813
840
|
|
|
@@ -817,11 +844,22 @@ const loadRouteMatch = async (
|
|
|
817
844
|
const route = inner.router.looseRoutesById[routeId]!
|
|
818
845
|
|
|
819
846
|
if (shouldSkipLoader(inner, matchId)) {
|
|
847
|
+
const match = inner.router.getMatch(matchId)
|
|
848
|
+
if (!match) {
|
|
849
|
+
return inner.matches[index]!
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
syncMatchContext(inner, matchId, index)
|
|
853
|
+
|
|
820
854
|
if (isServer ?? inner.router.isServer) {
|
|
821
855
|
return inner.router.getMatch(matchId)!
|
|
822
856
|
}
|
|
823
857
|
} else {
|
|
824
858
|
const prevMatch = inner.router.getMatch(matchId)! // This is where all of the stale-while-revalidate magic happens
|
|
859
|
+
const previousRouteMatchId =
|
|
860
|
+
inner.router.state.matches[index]?.routeId === routeId
|
|
861
|
+
? inner.router.state.matches[index]!.id
|
|
862
|
+
: inner.router.state.matches.find((d) => d.routeId === routeId)?.id
|
|
825
863
|
const preload = resolvePreload(inner, matchId)
|
|
826
864
|
|
|
827
865
|
// there is a loaderPromise, so we are in the middle of a load
|
|
@@ -840,7 +878,13 @@ const loadRouteMatch = async (
|
|
|
840
878
|
}
|
|
841
879
|
|
|
842
880
|
if (match.status === 'pending') {
|
|
843
|
-
await handleLoader(
|
|
881
|
+
await handleLoader(
|
|
882
|
+
preload,
|
|
883
|
+
prevMatch,
|
|
884
|
+
previousRouteMatchId,
|
|
885
|
+
match,
|
|
886
|
+
route,
|
|
887
|
+
)
|
|
844
888
|
}
|
|
845
889
|
} else {
|
|
846
890
|
const nextPreload =
|
|
@@ -854,7 +898,7 @@ const loadRouteMatch = async (
|
|
|
854
898
|
}))
|
|
855
899
|
}
|
|
856
900
|
|
|
857
|
-
await handleLoader(preload, prevMatch, match, route)
|
|
901
|
+
await handleLoader(preload, prevMatch, previousRouteMatchId, match, route)
|
|
858
902
|
}
|
|
859
903
|
}
|
|
860
904
|
const match = inner.router.getMatch(matchId)!
|
|
@@ -886,6 +930,7 @@ export async function loadMatches(arg: {
|
|
|
886
930
|
location: ParsedLocation
|
|
887
931
|
matches: Array<AnyRouteMatch>
|
|
888
932
|
preload?: boolean
|
|
933
|
+
forceStaleReload?: boolean
|
|
889
934
|
onReady?: () => Promise<void>
|
|
890
935
|
updateMatch: UpdateMatchFn
|
|
891
936
|
sync?: boolean
|
package/src/router.ts
CHANGED
|
@@ -2364,6 +2364,7 @@ export class RouterCore<
|
|
|
2364
2364
|
let redirect: AnyRedirect | undefined
|
|
2365
2365
|
let notFound: NotFoundError | undefined
|
|
2366
2366
|
let loadPromise: Promise<void>
|
|
2367
|
+
const previousLocation = this.state.resolvedLocation ?? this.state.location
|
|
2367
2368
|
|
|
2368
2369
|
// eslint-disable-next-line prefer-const
|
|
2369
2370
|
loadPromise = new Promise<void>((resolve) => {
|
|
@@ -2394,6 +2395,7 @@ export class RouterCore<
|
|
|
2394
2395
|
await loadMatches({
|
|
2395
2396
|
router: this,
|
|
2396
2397
|
sync: opts?.sync,
|
|
2398
|
+
forceStaleReload: previousLocation.href === next.href,
|
|
2397
2399
|
matches: this.state.pendingMatches as Array<AnyRouteMatch>,
|
|
2398
2400
|
location: next,
|
|
2399
2401
|
updateMatch: this.updateMatch,
|