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