@tanstack/react-router 0.0.1-beta.222 → 0.0.1-beta.224
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/build/cjs/Matches.js.map +1 -1
- package/build/cjs/RouterProvider.js +56 -955
- package/build/cjs/RouterProvider.js.map +1 -1
- package/build/cjs/fileRoute.js.map +1 -1
- package/build/cjs/route.js.map +1 -1
- package/build/cjs/router.js +953 -39
- package/build/cjs/router.js.map +1 -1
- package/build/cjs/scroll-restoration.js +5 -9
- package/build/cjs/scroll-restoration.js.map +1 -1
- package/build/cjs/useSearch.js.map +1 -1
- package/build/cjs/utils.js.map +1 -1
- package/build/esm/index.js +895 -889
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +369 -363
- package/build/types/Matches.d.ts +25 -2
- package/build/types/RouterProvider.d.ts +4 -45
- package/build/types/fileRoute.d.ts +5 -5
- package/build/types/route.d.ts +3 -1
- package/build/types/router.d.ts +50 -5
- package/build/umd/index.development.js +895 -889
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +2 -2
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -2
- package/src/Matches.tsx +38 -2
- package/src/RouterProvider.tsx +58 -1342
- package/src/fileRoute.ts +1 -1
- package/src/route.ts +24 -1
- package/src/router.ts +1320 -45
- package/src/scroll-restoration.tsx +5 -5
- package/src/useSearch.tsx +1 -1
- package/src/utils.ts +1 -1
|
@@ -1106,274 +1106,34 @@
|
|
|
1106
1106
|
return typeof opts.select === 'function' ? opts.select(match?.loaderData) : match?.loaderData;
|
|
1107
1107
|
}
|
|
1108
1108
|
|
|
1109
|
-
//
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
//
|
|
1120
|
-
|
|
1121
|
-
//
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i]);
|
|
1134
|
-
}
|
|
1135
|
-
} else {
|
|
1136
|
-
str && (str += '&');
|
|
1137
|
-
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
return (pfx || '') + str;
|
|
1142
|
-
}
|
|
1143
|
-
function toValue(mix) {
|
|
1144
|
-
if (!mix) return '';
|
|
1145
|
-
var str = decodeURIComponent(mix);
|
|
1146
|
-
if (str === 'false') return false;
|
|
1147
|
-
if (str === 'true') return true;
|
|
1148
|
-
return +str * 0 === 0 && +str + '' === str ? +str : str;
|
|
1149
|
-
}
|
|
1150
|
-
function decode(str) {
|
|
1151
|
-
var tmp,
|
|
1152
|
-
k,
|
|
1153
|
-
out = {},
|
|
1154
|
-
arr = str.split('&');
|
|
1155
|
-
while (tmp = arr.shift()) {
|
|
1156
|
-
tmp = tmp.split('=');
|
|
1157
|
-
k = tmp.shift();
|
|
1158
|
-
if (out[k] !== void 0) {
|
|
1159
|
-
out[k] = [].concat(out[k], toValue(tmp.shift()));
|
|
1160
|
-
} else {
|
|
1161
|
-
out[k] = toValue(tmp.shift());
|
|
1162
|
-
}
|
|
1163
|
-
}
|
|
1164
|
-
return out;
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
const defaultParseSearch = parseSearchWith(JSON.parse);
|
|
1168
|
-
const defaultStringifySearch = stringifySearchWith(JSON.stringify, JSON.parse);
|
|
1169
|
-
function parseSearchWith(parser) {
|
|
1170
|
-
return searchStr => {
|
|
1171
|
-
if (searchStr.substring(0, 1) === '?') {
|
|
1172
|
-
searchStr = searchStr.substring(1);
|
|
1173
|
-
}
|
|
1174
|
-
let query = decode(searchStr);
|
|
1175
|
-
|
|
1176
|
-
// Try to parse any query params that might be json
|
|
1177
|
-
for (let key in query) {
|
|
1178
|
-
const value = query[key];
|
|
1179
|
-
if (typeof value === 'string') {
|
|
1180
|
-
try {
|
|
1181
|
-
query[key] = parser(value);
|
|
1182
|
-
} catch (err) {
|
|
1183
|
-
//
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
return query;
|
|
1188
|
-
};
|
|
1189
|
-
}
|
|
1190
|
-
function stringifySearchWith(stringify, parser) {
|
|
1191
|
-
function stringifyValue(val) {
|
|
1192
|
-
if (typeof val === 'object' && val !== null) {
|
|
1193
|
-
try {
|
|
1194
|
-
return stringify(val);
|
|
1195
|
-
} catch (err) {
|
|
1196
|
-
// silent
|
|
1197
|
-
}
|
|
1198
|
-
} else if (typeof val === 'string' && typeof parser === 'function') {
|
|
1199
|
-
try {
|
|
1200
|
-
// Check if it's a valid parseable string.
|
|
1201
|
-
// If it is, then stringify it again.
|
|
1202
|
-
parser(val);
|
|
1203
|
-
return stringify(val);
|
|
1204
|
-
} catch (err) {
|
|
1205
|
-
// silent
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
return val;
|
|
1209
|
-
}
|
|
1210
|
-
return search => {
|
|
1211
|
-
search = {
|
|
1212
|
-
...search
|
|
1213
|
-
};
|
|
1214
|
-
if (search) {
|
|
1215
|
-
Object.keys(search).forEach(key => {
|
|
1216
|
-
const val = search[key];
|
|
1217
|
-
if (typeof val === 'undefined' || val === undefined) {
|
|
1218
|
-
delete search[key];
|
|
1219
|
-
} else {
|
|
1220
|
-
search[key] = stringifyValue(val);
|
|
1221
|
-
}
|
|
1222
|
-
});
|
|
1223
|
-
}
|
|
1224
|
-
const searchStr = encode(search).toString();
|
|
1225
|
-
return searchStr ? `?${searchStr}` : '';
|
|
1226
|
-
};
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1229
|
-
//
|
|
1230
|
-
|
|
1231
|
-
//
|
|
1232
|
-
|
|
1233
|
-
const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
|
|
1234
|
-
class Router {
|
|
1235
|
-
// dehydratedData?: TDehydrated
|
|
1236
|
-
// resetNextScroll = false
|
|
1237
|
-
// tempLocationKey = `${Math.round(Math.random() * 10000000)}`
|
|
1238
|
-
constructor(options) {
|
|
1239
|
-
this.options = {
|
|
1240
|
-
defaultPreloadDelay: 50,
|
|
1241
|
-
context: undefined,
|
|
1242
|
-
...options,
|
|
1243
|
-
stringifySearch: options?.stringifySearch ?? defaultStringifySearch,
|
|
1244
|
-
parseSearch: options?.parseSearch ?? defaultParseSearch
|
|
1245
|
-
};
|
|
1246
|
-
this.routeTree = this.options.routeTree;
|
|
1247
|
-
}
|
|
1248
|
-
subscribers = new Set();
|
|
1249
|
-
subscribe = (eventType, fn) => {
|
|
1250
|
-
const listener = {
|
|
1251
|
-
eventType,
|
|
1252
|
-
fn
|
|
1253
|
-
};
|
|
1254
|
-
this.subscribers.add(listener);
|
|
1255
|
-
return () => {
|
|
1256
|
-
this.subscribers.delete(listener);
|
|
1257
|
-
};
|
|
1258
|
-
};
|
|
1259
|
-
emit = routerEvent => {
|
|
1260
|
-
this.subscribers.forEach(listener => {
|
|
1261
|
-
if (listener.eventType === routerEvent.type) {
|
|
1262
|
-
listener.fn(routerEvent);
|
|
1263
|
-
}
|
|
1264
|
-
});
|
|
1265
|
-
};
|
|
1266
|
-
|
|
1267
|
-
// dehydrate = (): DehydratedRouter => {
|
|
1268
|
-
// return {
|
|
1269
|
-
// state: {
|
|
1270
|
-
// dehydratedMatches: state.matches.map((d) =>
|
|
1271
|
-
// pick(d, ['fetchedAt', 'invalid', 'id', 'status', 'updatedAt']),
|
|
1272
|
-
// ),
|
|
1273
|
-
// },
|
|
1274
|
-
// }
|
|
1275
|
-
// }
|
|
1276
|
-
|
|
1277
|
-
// hydrate = async (__do_not_use_server_ctx?: HydrationCtx) => {
|
|
1278
|
-
// let _ctx = __do_not_use_server_ctx
|
|
1279
|
-
// // Client hydrates from window
|
|
1280
|
-
// if (typeof document !== 'undefined') {
|
|
1281
|
-
// _ctx = window.__TSR_DEHYDRATED__
|
|
1282
|
-
// }
|
|
1283
|
-
|
|
1284
|
-
// invariant(
|
|
1285
|
-
// _ctx,
|
|
1286
|
-
// 'Expected to find a __TSR_DEHYDRATED__ property on window... but we did not. Did you forget to render <DehydrateRouter /> in your app?',
|
|
1287
|
-
// )
|
|
1288
|
-
|
|
1289
|
-
// const ctx = _ctx
|
|
1290
|
-
// this.dehydratedData = ctx.payload as any
|
|
1291
|
-
// this.options.hydrate?.(ctx.payload as any)
|
|
1292
|
-
// const dehydratedState = ctx.router.state
|
|
1293
|
-
|
|
1294
|
-
// let matches = this.matchRoutes(
|
|
1295
|
-
// state.location.pathname,
|
|
1296
|
-
// state.location.search,
|
|
1297
|
-
// ).map((match) => {
|
|
1298
|
-
// const dehydratedMatch = dehydratedState.dehydratedMatches.find(
|
|
1299
|
-
// (d) => d.id === match.id,
|
|
1300
|
-
// )
|
|
1301
|
-
|
|
1302
|
-
// invariant(
|
|
1303
|
-
// dehydratedMatch,
|
|
1304
|
-
// `Could not find a client-side match for dehydrated match with id: ${match.id}!`,
|
|
1305
|
-
// )
|
|
1306
|
-
|
|
1307
|
-
// if (dehydratedMatch) {
|
|
1308
|
-
// return {
|
|
1309
|
-
// ...match,
|
|
1310
|
-
// ...dehydratedMatch,
|
|
1311
|
-
// }
|
|
1312
|
-
// }
|
|
1313
|
-
// return match
|
|
1314
|
-
// })
|
|
1315
|
-
|
|
1316
|
-
// this.setState((s) => {
|
|
1317
|
-
// return {
|
|
1318
|
-
// ...s,
|
|
1319
|
-
// matches: dehydratedState.dehydratedMatches as any,
|
|
1320
|
-
// }
|
|
1321
|
-
// })
|
|
1322
|
-
// }
|
|
1323
|
-
|
|
1324
|
-
// resolveMatchPromise = (matchId: string, key: string, value: any) => {
|
|
1325
|
-
// state.matches
|
|
1326
|
-
// .find((d) => d.id === matchId)
|
|
1327
|
-
// ?.__promisesByKey[key]?.resolve(value)
|
|
1328
|
-
// }
|
|
1329
|
-
|
|
1330
|
-
// setRouteMatch = (
|
|
1331
|
-
// id: string,
|
|
1332
|
-
// pending: boolean,
|
|
1333
|
-
// updater: NonNullableUpdater<RouteMatch<TRouteTree>>,
|
|
1334
|
-
// ) => {
|
|
1335
|
-
// const key = pending ? 'pendingMatches' : 'matches'
|
|
1336
|
-
|
|
1337
|
-
// this.setState((prev) => {
|
|
1338
|
-
// return {
|
|
1339
|
-
// ...prev,
|
|
1340
|
-
// [key]: prev[key].map((d) => {
|
|
1341
|
-
// if (d.id === id) {
|
|
1342
|
-
// return functionalUpdate(updater, d)
|
|
1343
|
-
// }
|
|
1344
|
-
|
|
1345
|
-
// return d
|
|
1346
|
-
// }),
|
|
1347
|
-
// }
|
|
1348
|
-
// })
|
|
1349
|
-
// }
|
|
1350
|
-
|
|
1351
|
-
// setPendingRouteMatch = (
|
|
1352
|
-
// id: string,
|
|
1353
|
-
// updater: NonNullableUpdater<RouteMatch<TRouteTree>>,
|
|
1354
|
-
// ) => {
|
|
1355
|
-
// this.setRouteMatch(id, true, updater)
|
|
1356
|
-
// }
|
|
1357
|
-
}
|
|
1358
|
-
|
|
1359
|
-
// A function that takes an import() argument which is a function and returns a new function that will
|
|
1360
|
-
// proxy arguments from the caller to the imported function, retaining all type
|
|
1361
|
-
// information along the way
|
|
1362
|
-
function lazyFn(fn, key) {
|
|
1363
|
-
return async (...args) => {
|
|
1364
|
-
const imported = await fn();
|
|
1365
|
-
return imported[key || 'default'](...args);
|
|
1366
|
-
};
|
|
1367
|
-
}
|
|
1368
|
-
|
|
1109
|
+
// export type RouterContext<
|
|
1110
|
+
// TRouteTree extends AnyRoute,
|
|
1111
|
+
// // TDehydrated extends Record<string, any>,
|
|
1112
|
+
// > = {
|
|
1113
|
+
// buildLink: BuildLinkFn<TRouteTree>
|
|
1114
|
+
// state: RouterState<TRouteTree>
|
|
1115
|
+
// navigate: NavigateFn<TRouteTree>
|
|
1116
|
+
// matchRoute: MatchRouteFn<TRouteTree>
|
|
1117
|
+
// routeTree: TRouteTree
|
|
1118
|
+
// routesById: RoutesById<TRouteTree>
|
|
1119
|
+
// options: RouterOptions<TRouteTree>
|
|
1120
|
+
// history: RouterHistory
|
|
1121
|
+
// load: LoadFn
|
|
1122
|
+
// buildLocation: BuildLocationFn<TRouteTree>
|
|
1123
|
+
// subscribe: Router<TRouteTree>['subscribe']
|
|
1124
|
+
// resetNextScrollRef: React.MutableRefObject<boolean>
|
|
1125
|
+
// injectedHtmlRef: React.MutableRefObject<InjectedHtmlEntry[]>
|
|
1126
|
+
// injectHtml: (entry: InjectedHtmlEntry) => void
|
|
1127
|
+
// dehydrateData: <T>(
|
|
1128
|
+
// key: any,
|
|
1129
|
+
// getData: T | (() => Promise<T> | T),
|
|
1130
|
+
// ) => () => void
|
|
1131
|
+
// hydrateData: <T>(key: any) => T | undefined
|
|
1132
|
+
// }
|
|
1369
1133
|
const routerContext = /*#__PURE__*/React__namespace.createContext(null);
|
|
1370
1134
|
if (typeof document !== 'undefined') {
|
|
1371
1135
|
window.__TSR_ROUTER_CONTEXT__ = routerContext;
|
|
1372
1136
|
}
|
|
1373
|
-
const preloadWarning = 'Error preloading route! ☝️';
|
|
1374
|
-
function isCtrlEvent(e) {
|
|
1375
|
-
return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
|
|
1376
|
-
}
|
|
1377
1137
|
class SearchParamError extends Error {}
|
|
1378
1138
|
class PathParamError extends Error {}
|
|
1379
1139
|
function getInitialRouterState(location) {
|
|
@@ -1390,66 +1150,55 @@
|
|
|
1390
1150
|
router,
|
|
1391
1151
|
...rest
|
|
1392
1152
|
}) {
|
|
1393
|
-
|
|
1153
|
+
// Allow the router to update options on the router instance
|
|
1154
|
+
router.updateOptions({
|
|
1394
1155
|
...router.options,
|
|
1395
1156
|
...rest,
|
|
1396
1157
|
context: {
|
|
1397
1158
|
...router.options.context,
|
|
1398
1159
|
...rest?.context
|
|
1399
1160
|
}
|
|
1400
|
-
};
|
|
1401
|
-
const history = React__namespace.useState(() => options.history ?? createBrowserHistory())[0];
|
|
1402
|
-
const tempLocationKeyRef = React__namespace.useRef(`${Math.round(Math.random() * 10000000)}`);
|
|
1403
|
-
const resetNextScrollRef = React__namespace.useRef(true);
|
|
1404
|
-
const navigateTimeoutRef = React__namespace.useRef(null);
|
|
1405
|
-
const latestLoadPromiseRef = React__namespace.useRef(Promise.resolve());
|
|
1406
|
-
const checkLatest = promise => {
|
|
1407
|
-
return latestLoadPromiseRef.current !== promise ? latestLoadPromiseRef.current : undefined;
|
|
1408
|
-
};
|
|
1409
|
-
const parseLocation = useStableCallback(previousLocation => {
|
|
1410
|
-
const parse = ({
|
|
1411
|
-
pathname,
|
|
1412
|
-
search,
|
|
1413
|
-
hash,
|
|
1414
|
-
state
|
|
1415
|
-
}) => {
|
|
1416
|
-
const parsedSearch = options.parseSearch(search);
|
|
1417
|
-
return {
|
|
1418
|
-
pathname: pathname,
|
|
1419
|
-
searchStr: search,
|
|
1420
|
-
search: replaceEqualDeep(previousLocation?.search, parsedSearch),
|
|
1421
|
-
hash: hash.split('#').reverse()[0] ?? '',
|
|
1422
|
-
href: `${pathname}${search}${hash}`,
|
|
1423
|
-
state: replaceEqualDeep(previousLocation?.state, state)
|
|
1424
|
-
};
|
|
1425
|
-
};
|
|
1426
|
-
const location = parse(history.location);
|
|
1427
|
-
let {
|
|
1428
|
-
__tempLocation,
|
|
1429
|
-
__tempKey
|
|
1430
|
-
} = location.state;
|
|
1431
|
-
if (__tempLocation && (!__tempKey || __tempKey === tempLocationKeyRef.current)) {
|
|
1432
|
-
// Sync up the location keys
|
|
1433
|
-
const parsedTempLocation = parse(__tempLocation);
|
|
1434
|
-
parsedTempLocation.state.key = location.state.key;
|
|
1435
|
-
delete parsedTempLocation.state.__tempLocation;
|
|
1436
|
-
return {
|
|
1437
|
-
...parsedTempLocation,
|
|
1438
|
-
maskedLocation: location
|
|
1439
|
-
};
|
|
1440
|
-
}
|
|
1441
|
-
return location;
|
|
1442
1161
|
});
|
|
1443
|
-
const
|
|
1444
|
-
const [preState, setState] = React__namespace.useState(() => getInitialRouterState(latestLocationRef.current));
|
|
1162
|
+
const [preState, setState] = React__namespace.useState(() => router.state);
|
|
1445
1163
|
const [isTransitioning, startReactTransition] = React__namespace.useTransition();
|
|
1446
|
-
const pendingMatchesRef = React__namespace.useRef([]);
|
|
1447
1164
|
const state = React__namespace.useMemo(() => ({
|
|
1448
1165
|
...preState,
|
|
1449
1166
|
status: isTransitioning ? 'pending' : 'idle',
|
|
1450
|
-
location: isTransitioning ?
|
|
1451
|
-
pendingMatches:
|
|
1167
|
+
location: isTransitioning ? router.latestLocation : preState.location,
|
|
1168
|
+
pendingMatches: router.pendingMatches
|
|
1452
1169
|
}), [preState, isTransitioning]);
|
|
1170
|
+
router.setState = setState;
|
|
1171
|
+
router.state = state;
|
|
1172
|
+
router.startReactTransition = startReactTransition;
|
|
1173
|
+
React__namespace.useLayoutEffect(() => {
|
|
1174
|
+
const unsub = router.history.subscribe(() => {
|
|
1175
|
+
router.latestLocation = router.parseLocation(router.latestLocation);
|
|
1176
|
+
if (state.location !== router.latestLocation) {
|
|
1177
|
+
startReactTransition(() => {
|
|
1178
|
+
try {
|
|
1179
|
+
router.load();
|
|
1180
|
+
} catch (err) {
|
|
1181
|
+
console.error(err);
|
|
1182
|
+
}
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
});
|
|
1186
|
+
const nextLocation = router.buildLocation({
|
|
1187
|
+
search: true,
|
|
1188
|
+
params: true,
|
|
1189
|
+
hash: true,
|
|
1190
|
+
state: true
|
|
1191
|
+
});
|
|
1192
|
+
if (state.location.href !== nextLocation.href) {
|
|
1193
|
+
router.commitLocation({
|
|
1194
|
+
...nextLocation,
|
|
1195
|
+
replace: true
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
return () => {
|
|
1199
|
+
unsub();
|
|
1200
|
+
};
|
|
1201
|
+
}, [history]);
|
|
1453
1202
|
React__namespace.useLayoutEffect(() => {
|
|
1454
1203
|
if (!isTransitioning && state.resolvedLocation !== state.location) {
|
|
1455
1204
|
router.emit({
|
|
@@ -1458,135 +1207,592 @@
|
|
|
1458
1207
|
toLocation: state.location,
|
|
1459
1208
|
pathChanged: state.location.href !== state.resolvedLocation?.href
|
|
1460
1209
|
});
|
|
1461
|
-
|
|
1210
|
+
router.pendingMatches = [];
|
|
1462
1211
|
setState(s => ({
|
|
1463
1212
|
...s,
|
|
1464
1213
|
resolvedLocation: s.location
|
|
1465
1214
|
}));
|
|
1466
1215
|
}
|
|
1467
1216
|
});
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
const routesByPath = {};
|
|
1475
|
-
const recurseRoutes = routes => {
|
|
1476
|
-
routes.forEach((route, i) => {
|
|
1477
|
-
route.init({
|
|
1478
|
-
originalIndex: i
|
|
1479
|
-
});
|
|
1480
|
-
const existingRoute = routesById[route.id];
|
|
1481
|
-
invariant(!existingRoute, `Duplicate routes found with id: ${String(route.id)}`);
|
|
1482
|
-
routesById[route.id] = route;
|
|
1483
|
-
if (!route.isRoot && route.path) {
|
|
1484
|
-
const trimmedFullPath = trimPathRight(route.fullPath);
|
|
1485
|
-
if (!routesByPath[trimmedFullPath] || route.fullPath.endsWith('/')) {
|
|
1486
|
-
routesByPath[trimmedFullPath] = route;
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
const children = route.children;
|
|
1490
|
-
if (children?.length) {
|
|
1491
|
-
recurseRoutes(children);
|
|
1492
|
-
}
|
|
1493
|
-
});
|
|
1494
|
-
};
|
|
1495
|
-
recurseRoutes([router.routeTree]);
|
|
1496
|
-
return [routesById, routesByPath];
|
|
1497
|
-
}, []);
|
|
1498
|
-
const looseRoutesById = routesById;
|
|
1499
|
-
const flatRoutes = React__namespace.useMemo(() => Object.values(routesByPath).map((d, i) => {
|
|
1500
|
-
const trimmed = trimPath(d.fullPath);
|
|
1501
|
-
const parsed = parsePathname(trimmed);
|
|
1502
|
-
while (parsed.length > 1 && parsed[0]?.value === '/') {
|
|
1503
|
-
parsed.shift();
|
|
1504
|
-
}
|
|
1505
|
-
const score = parsed.map(d => {
|
|
1506
|
-
if (d.type === 'param') {
|
|
1507
|
-
return 0.5;
|
|
1508
|
-
}
|
|
1509
|
-
if (d.type === 'wildcard') {
|
|
1510
|
-
return 0.25;
|
|
1217
|
+
React__namespace.useLayoutEffect(() => {
|
|
1218
|
+
startReactTransition(() => {
|
|
1219
|
+
try {
|
|
1220
|
+
router.load();
|
|
1221
|
+
} catch (err) {
|
|
1222
|
+
console.error(err);
|
|
1511
1223
|
}
|
|
1512
|
-
return 1;
|
|
1513
1224
|
});
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1225
|
+
}, []);
|
|
1226
|
+
return /*#__PURE__*/React__namespace.createElement(routerContext.Provider, {
|
|
1227
|
+
value: router
|
|
1228
|
+
}, /*#__PURE__*/React__namespace.createElement(Matches, null));
|
|
1229
|
+
}
|
|
1230
|
+
function getRouteMatch(state, id) {
|
|
1231
|
+
return [...state.pendingMatches, ...state.matches].find(d => d.id === id);
|
|
1232
|
+
}
|
|
1233
|
+
function useRouterState(opts) {
|
|
1234
|
+
const {
|
|
1235
|
+
state
|
|
1236
|
+
} = useRouter();
|
|
1237
|
+
// return useStore(router.__store, opts?.select as any)
|
|
1238
|
+
return opts?.select ? opts.select(state) : state;
|
|
1239
|
+
}
|
|
1240
|
+
function useRouter() {
|
|
1241
|
+
const resolvedContext = window.__TSR_ROUTER_CONTEXT__ || routerContext;
|
|
1242
|
+
const value = React__namespace.useContext(resolvedContext);
|
|
1243
|
+
warning(value, 'useRouter must be used inside a <RouterProvider> component!');
|
|
1244
|
+
return value;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
function defer(_promise) {
|
|
1248
|
+
const promise = _promise;
|
|
1249
|
+
if (!promise.__deferredState) {
|
|
1250
|
+
promise.__deferredState = {
|
|
1251
|
+
uid: Math.random().toString(36).slice(2),
|
|
1252
|
+
status: 'pending'
|
|
1520
1253
|
};
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1254
|
+
const state = promise.__deferredState;
|
|
1255
|
+
promise.then(data => {
|
|
1256
|
+
state.status = 'success';
|
|
1257
|
+
state.data = data;
|
|
1258
|
+
}).catch(error => {
|
|
1259
|
+
state.status = 'error';
|
|
1260
|
+
state.error = error;
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
return promise;
|
|
1264
|
+
}
|
|
1265
|
+
function isDehydratedDeferred(obj) {
|
|
1266
|
+
return typeof obj === 'object' && obj !== null && !(obj instanceof Promise) && !obj.then && '__deferredState' in obj;
|
|
1267
|
+
}
|
|
1530
1268
|
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1269
|
+
function useAwaited({
|
|
1270
|
+
promise
|
|
1271
|
+
}) {
|
|
1272
|
+
const router = useRouter();
|
|
1273
|
+
let state = promise.__deferredState;
|
|
1274
|
+
const key = `__TSR__DEFERRED__${state.uid}`;
|
|
1275
|
+
if (isDehydratedDeferred(promise)) {
|
|
1276
|
+
state = router.hydrateData(key);
|
|
1277
|
+
promise = Promise.resolve(state.data);
|
|
1278
|
+
promise.__deferredState = state;
|
|
1279
|
+
}
|
|
1280
|
+
if (state.status === 'pending') {
|
|
1281
|
+
throw promise;
|
|
1282
|
+
}
|
|
1283
|
+
if (state.status === 'error') {
|
|
1284
|
+
throw state.error;
|
|
1285
|
+
}
|
|
1286
|
+
router.dehydrateData(key, state);
|
|
1287
|
+
return [state.data];
|
|
1288
|
+
}
|
|
1289
|
+
function Await(props) {
|
|
1290
|
+
const awaited = useAwaited(props);
|
|
1291
|
+
return props.children(...awaited);
|
|
1292
|
+
}
|
|
1537
1293
|
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1294
|
+
class FileRoute {
|
|
1295
|
+
constructor(path) {
|
|
1296
|
+
this.path = path;
|
|
1297
|
+
}
|
|
1298
|
+
createRoute = options => {
|
|
1299
|
+
const route = new Route(options);
|
|
1300
|
+
route.isRoot = false;
|
|
1301
|
+
return route;
|
|
1302
|
+
};
|
|
1303
|
+
}
|
|
1544
1304
|
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1305
|
+
function lazyRouteComponent(importer, exportName) {
|
|
1306
|
+
let loadPromise;
|
|
1307
|
+
const load = () => {
|
|
1308
|
+
if (!loadPromise) {
|
|
1309
|
+
loadPromise = importer();
|
|
1548
1310
|
}
|
|
1311
|
+
return loadPromise;
|
|
1312
|
+
};
|
|
1313
|
+
const lazyComp = /*#__PURE__*/React__namespace.lazy(async () => {
|
|
1314
|
+
const moduleExports = await load();
|
|
1315
|
+
const comp = moduleExports[exportName ?? 'default'];
|
|
1316
|
+
return {
|
|
1317
|
+
default: comp
|
|
1318
|
+
};
|
|
1319
|
+
});
|
|
1320
|
+
lazyComp.preload = load;
|
|
1321
|
+
return lazyComp;
|
|
1322
|
+
}
|
|
1549
1323
|
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
let foundRoute = flatRoutes.find(route => {
|
|
1559
|
-
const matchedParams = matchPathname(basepath, trimPathRight(pathname), {
|
|
1560
|
-
to: route.fullPath,
|
|
1561
|
-
caseSensitive: route.options.caseSensitive ?? options.caseSensitive,
|
|
1562
|
-
fuzzy: false
|
|
1563
|
-
});
|
|
1564
|
-
if (matchedParams) {
|
|
1565
|
-
routeParams = matchedParams;
|
|
1566
|
-
return true;
|
|
1324
|
+
function _extends() {
|
|
1325
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
1326
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
1327
|
+
var source = arguments[i];
|
|
1328
|
+
for (var key in source) {
|
|
1329
|
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
1330
|
+
target[key] = source[key];
|
|
1331
|
+
}
|
|
1567
1332
|
}
|
|
1568
|
-
return false;
|
|
1569
|
-
});
|
|
1570
|
-
let routeCursor = foundRoute || routesById['__root__'];
|
|
1571
|
-
let matchedRoutes = [routeCursor];
|
|
1572
|
-
// let includingLayouts = true
|
|
1573
|
-
while (routeCursor?.parentRoute) {
|
|
1574
|
-
routeCursor = routeCursor.parentRoute;
|
|
1575
|
-
if (routeCursor) matchedRoutes.unshift(routeCursor);
|
|
1576
1333
|
}
|
|
1334
|
+
return target;
|
|
1335
|
+
};
|
|
1336
|
+
return _extends.apply(this, arguments);
|
|
1337
|
+
}
|
|
1577
1338
|
|
|
1578
|
-
|
|
1579
|
-
|
|
1339
|
+
function useLinkProps(options) {
|
|
1340
|
+
const {
|
|
1341
|
+
buildLink
|
|
1342
|
+
} = useRouter();
|
|
1343
|
+
const match = useMatch({
|
|
1344
|
+
strict: false
|
|
1345
|
+
});
|
|
1346
|
+
const {
|
|
1347
|
+
// custom props
|
|
1348
|
+
type,
|
|
1349
|
+
children,
|
|
1350
|
+
target,
|
|
1351
|
+
activeProps = () => ({
|
|
1352
|
+
className: 'active'
|
|
1353
|
+
}),
|
|
1354
|
+
inactiveProps = () => ({}),
|
|
1355
|
+
activeOptions,
|
|
1356
|
+
disabled,
|
|
1357
|
+
hash,
|
|
1358
|
+
search,
|
|
1359
|
+
params,
|
|
1360
|
+
to,
|
|
1361
|
+
state,
|
|
1362
|
+
mask,
|
|
1363
|
+
preload,
|
|
1364
|
+
preloadDelay,
|
|
1365
|
+
replace,
|
|
1366
|
+
startTransition,
|
|
1367
|
+
resetScroll,
|
|
1368
|
+
// element props
|
|
1369
|
+
style,
|
|
1370
|
+
className,
|
|
1371
|
+
onClick,
|
|
1372
|
+
onFocus,
|
|
1373
|
+
onMouseEnter,
|
|
1374
|
+
onMouseLeave,
|
|
1375
|
+
onTouchStart,
|
|
1376
|
+
...rest
|
|
1377
|
+
} = options;
|
|
1378
|
+
const linkInfo = buildLink({
|
|
1379
|
+
from: options.to ? match.pathname : undefined,
|
|
1380
|
+
...options
|
|
1381
|
+
});
|
|
1382
|
+
if (linkInfo.type === 'external') {
|
|
1383
|
+
const {
|
|
1384
|
+
href
|
|
1385
|
+
} = linkInfo;
|
|
1386
|
+
return {
|
|
1387
|
+
href
|
|
1388
|
+
};
|
|
1389
|
+
}
|
|
1390
|
+
const {
|
|
1391
|
+
handleClick,
|
|
1392
|
+
handleFocus,
|
|
1393
|
+
handleEnter,
|
|
1394
|
+
handleLeave,
|
|
1395
|
+
handleTouchStart,
|
|
1396
|
+
isActive,
|
|
1397
|
+
next
|
|
1398
|
+
} = linkInfo;
|
|
1399
|
+
const composeHandlers = handlers => e => {
|
|
1400
|
+
if (e.persist) e.persist();
|
|
1401
|
+
handlers.filter(Boolean).forEach(handler => {
|
|
1402
|
+
if (e.defaultPrevented) return;
|
|
1403
|
+
handler(e);
|
|
1404
|
+
});
|
|
1405
|
+
};
|
|
1580
1406
|
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1407
|
+
// Get the active props
|
|
1408
|
+
const resolvedActiveProps = isActive ? functionalUpdate(activeProps, {}) ?? {} : {};
|
|
1409
|
+
|
|
1410
|
+
// Get the inactive props
|
|
1411
|
+
const resolvedInactiveProps = isActive ? {} : functionalUpdate(inactiveProps, {}) ?? {};
|
|
1412
|
+
return {
|
|
1413
|
+
...resolvedActiveProps,
|
|
1414
|
+
...resolvedInactiveProps,
|
|
1415
|
+
...rest,
|
|
1416
|
+
href: disabled ? undefined : next.maskedLocation ? next.maskedLocation.href : next.href,
|
|
1417
|
+
onClick: composeHandlers([onClick, handleClick]),
|
|
1418
|
+
onFocus: composeHandlers([onFocus, handleFocus]),
|
|
1419
|
+
onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),
|
|
1420
|
+
onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),
|
|
1421
|
+
onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),
|
|
1422
|
+
target,
|
|
1423
|
+
style: {
|
|
1424
|
+
...style,
|
|
1425
|
+
...resolvedActiveProps.style,
|
|
1426
|
+
...resolvedInactiveProps.style
|
|
1427
|
+
},
|
|
1428
|
+
className: [className, resolvedActiveProps.className, resolvedInactiveProps.className].filter(Boolean).join(' ') || undefined,
|
|
1429
|
+
...(disabled ? {
|
|
1430
|
+
role: 'link',
|
|
1431
|
+
'aria-disabled': true
|
|
1432
|
+
} : undefined),
|
|
1433
|
+
['data-status']: isActive ? 'active' : undefined
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
const Link = /*#__PURE__*/React__namespace.forwardRef((props, ref) => {
|
|
1437
|
+
const linkProps = useLinkProps(props);
|
|
1438
|
+
return /*#__PURE__*/React__namespace.createElement("a", _extends({
|
|
1439
|
+
ref: ref
|
|
1440
|
+
}, linkProps, {
|
|
1441
|
+
children: typeof props.children === 'function' ? props.children({
|
|
1442
|
+
isActive: linkProps['data-status'] === 'active'
|
|
1443
|
+
}) : props.children
|
|
1444
|
+
}));
|
|
1445
|
+
});
|
|
1446
|
+
|
|
1447
|
+
// @ts-nocheck
|
|
1448
|
+
|
|
1449
|
+
// qss has been slightly modified and inlined here for our use cases (and compression's sake). We've included it as a hard dependency for MIT license attribution.
|
|
1450
|
+
|
|
1451
|
+
function encode(obj, pfx) {
|
|
1452
|
+
var k,
|
|
1453
|
+
i,
|
|
1454
|
+
tmp,
|
|
1455
|
+
str = '';
|
|
1456
|
+
for (k in obj) {
|
|
1457
|
+
if ((tmp = obj[k]) !== void 0) {
|
|
1458
|
+
if (Array.isArray(tmp)) {
|
|
1459
|
+
for (i = 0; i < tmp.length; i++) {
|
|
1460
|
+
str && (str += '&');
|
|
1461
|
+
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp[i]);
|
|
1462
|
+
}
|
|
1463
|
+
} else {
|
|
1464
|
+
str && (str += '&');
|
|
1465
|
+
str += encodeURIComponent(k) + '=' + encodeURIComponent(tmp);
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
return (pfx || '') + str;
|
|
1470
|
+
}
|
|
1471
|
+
function toValue(mix) {
|
|
1472
|
+
if (!mix) return '';
|
|
1473
|
+
var str = decodeURIComponent(mix);
|
|
1474
|
+
if (str === 'false') return false;
|
|
1475
|
+
if (str === 'true') return true;
|
|
1476
|
+
return +str * 0 === 0 && +str + '' === str ? +str : str;
|
|
1477
|
+
}
|
|
1478
|
+
function decode(str) {
|
|
1479
|
+
var tmp,
|
|
1480
|
+
k,
|
|
1481
|
+
out = {},
|
|
1482
|
+
arr = str.split('&');
|
|
1483
|
+
while (tmp = arr.shift()) {
|
|
1484
|
+
tmp = tmp.split('=');
|
|
1485
|
+
k = tmp.shift();
|
|
1486
|
+
if (out[k] !== void 0) {
|
|
1487
|
+
out[k] = [].concat(out[k], toValue(tmp.shift()));
|
|
1488
|
+
} else {
|
|
1489
|
+
out[k] = toValue(tmp.shift());
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
return out;
|
|
1493
|
+
}
|
|
1494
|
+
|
|
1495
|
+
// Detect if we're in the DOM
|
|
1496
|
+
|
|
1497
|
+
function redirect(opts) {
|
|
1498
|
+
opts.isRedirect = true;
|
|
1499
|
+
return opts;
|
|
1500
|
+
}
|
|
1501
|
+
function isRedirect(obj) {
|
|
1502
|
+
return !!obj?.isRedirect;
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
const defaultParseSearch = parseSearchWith(JSON.parse);
|
|
1506
|
+
const defaultStringifySearch = stringifySearchWith(JSON.stringify, JSON.parse);
|
|
1507
|
+
function parseSearchWith(parser) {
|
|
1508
|
+
return searchStr => {
|
|
1509
|
+
if (searchStr.substring(0, 1) === '?') {
|
|
1510
|
+
searchStr = searchStr.substring(1);
|
|
1511
|
+
}
|
|
1512
|
+
let query = decode(searchStr);
|
|
1513
|
+
|
|
1514
|
+
// Try to parse any query params that might be json
|
|
1515
|
+
for (let key in query) {
|
|
1516
|
+
const value = query[key];
|
|
1517
|
+
if (typeof value === 'string') {
|
|
1518
|
+
try {
|
|
1519
|
+
query[key] = parser(value);
|
|
1520
|
+
} catch (err) {
|
|
1521
|
+
//
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
return query;
|
|
1526
|
+
};
|
|
1527
|
+
}
|
|
1528
|
+
function stringifySearchWith(stringify, parser) {
|
|
1529
|
+
function stringifyValue(val) {
|
|
1530
|
+
if (typeof val === 'object' && val !== null) {
|
|
1531
|
+
try {
|
|
1532
|
+
return stringify(val);
|
|
1533
|
+
} catch (err) {
|
|
1534
|
+
// silent
|
|
1535
|
+
}
|
|
1536
|
+
} else if (typeof val === 'string' && typeof parser === 'function') {
|
|
1537
|
+
try {
|
|
1538
|
+
// Check if it's a valid parseable string.
|
|
1539
|
+
// If it is, then stringify it again.
|
|
1540
|
+
parser(val);
|
|
1541
|
+
return stringify(val);
|
|
1542
|
+
} catch (err) {
|
|
1543
|
+
// silent
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
return val;
|
|
1547
|
+
}
|
|
1548
|
+
return search => {
|
|
1549
|
+
search = {
|
|
1550
|
+
...search
|
|
1551
|
+
};
|
|
1552
|
+
if (search) {
|
|
1553
|
+
Object.keys(search).forEach(key => {
|
|
1554
|
+
const val = search[key];
|
|
1555
|
+
if (typeof val === 'undefined' || val === undefined) {
|
|
1556
|
+
delete search[key];
|
|
1557
|
+
} else {
|
|
1558
|
+
search[key] = stringifyValue(val);
|
|
1559
|
+
}
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
const searchStr = encode(search).toString();
|
|
1563
|
+
return searchStr ? `?${searchStr}` : '';
|
|
1564
|
+
};
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
//
|
|
1568
|
+
|
|
1569
|
+
const componentTypes = ['component', 'errorComponent', 'pendingComponent'];
|
|
1570
|
+
const preloadWarning = 'Error preloading route! ☝️';
|
|
1571
|
+
class Router {
|
|
1572
|
+
// Option-independent properties
|
|
1573
|
+
tempLocationKey = `${Math.round(Math.random() * 10000000)}`;
|
|
1574
|
+
resetNextScroll = true;
|
|
1575
|
+
navigateTimeout = null;
|
|
1576
|
+
latestLoadPromise = Promise.resolve();
|
|
1577
|
+
subscribers = new Set();
|
|
1578
|
+
pendingMatches = [];
|
|
1579
|
+
injectedHtml = [];
|
|
1580
|
+
|
|
1581
|
+
// Must build in constructor
|
|
1582
|
+
|
|
1583
|
+
constructor(options) {
|
|
1584
|
+
this.updateOptions({
|
|
1585
|
+
defaultPreloadDelay: 50,
|
|
1586
|
+
context: undefined,
|
|
1587
|
+
...options,
|
|
1588
|
+
stringifySearch: options?.stringifySearch ?? defaultStringifySearch,
|
|
1589
|
+
parseSearch: options?.parseSearch ?? defaultParseSearch
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
startReactTransition = () => {
|
|
1593
|
+
warning(false, 'startReactTransition implementation is missing. If you see this, please file an issue.');
|
|
1594
|
+
};
|
|
1595
|
+
setState = () => {
|
|
1596
|
+
warning(false, 'setState implementation is missing. If you see this, please file an issue.');
|
|
1597
|
+
};
|
|
1598
|
+
updateOptions = newOptions => {
|
|
1599
|
+
this.options;
|
|
1600
|
+
this.options = {
|
|
1601
|
+
...this.options,
|
|
1602
|
+
...newOptions
|
|
1603
|
+
};
|
|
1604
|
+
this.basepath = `/${trimPath(newOptions.basepath ?? '') ?? ''}`;
|
|
1605
|
+
if (!this.history || this.options.history && this.options.history !== this.history) {
|
|
1606
|
+
this.history = this.options.history ?? createBrowserHistory();
|
|
1607
|
+
this.latestLocation = this.parseLocation();
|
|
1608
|
+
}
|
|
1609
|
+
if (this.options.routeTree !== this.routeTree) {
|
|
1610
|
+
this.routeTree = this.options.routeTree;
|
|
1611
|
+
this.buildRouteTree();
|
|
1612
|
+
}
|
|
1613
|
+
if (!this.state) {
|
|
1614
|
+
this.state = getInitialRouterState(this.latestLocation);
|
|
1615
|
+
}
|
|
1616
|
+
};
|
|
1617
|
+
buildRouteTree = () => {
|
|
1618
|
+
this.routesById = {};
|
|
1619
|
+
this.routesByPath = {};
|
|
1620
|
+
const recurseRoutes = childRoutes => {
|
|
1621
|
+
childRoutes.forEach((childRoute, i) => {
|
|
1622
|
+
// if (typeof childRoute === 'function') {
|
|
1623
|
+
// childRoute = (childRoute as any)()
|
|
1624
|
+
// }
|
|
1625
|
+
childRoute.init({
|
|
1626
|
+
originalIndex: i
|
|
1627
|
+
});
|
|
1628
|
+
const existingRoute = this.routesById[childRoute.id];
|
|
1629
|
+
invariant(!existingRoute, `Duplicate routes found with id: ${String(childRoute.id)}`);
|
|
1630
|
+
this.routesById[childRoute.id] = childRoute;
|
|
1631
|
+
if (!childRoute.isRoot && childRoute.path) {
|
|
1632
|
+
const trimmedFullPath = trimPathRight(childRoute.fullPath);
|
|
1633
|
+
if (!this.routesByPath[trimmedFullPath] || childRoute.fullPath.endsWith('/')) {
|
|
1634
|
+
this.routesByPath[trimmedFullPath] = childRoute;
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
const children = childRoute.children;
|
|
1638
|
+
if (children?.length) {
|
|
1639
|
+
recurseRoutes(children);
|
|
1640
|
+
}
|
|
1641
|
+
});
|
|
1642
|
+
};
|
|
1643
|
+
recurseRoutes([this.routeTree]);
|
|
1644
|
+
this.flatRoutes = Object.values(this.routesByPath).map((d, i) => {
|
|
1645
|
+
const trimmed = trimPath(d.fullPath);
|
|
1646
|
+
const parsed = parsePathname(trimmed);
|
|
1647
|
+
while (parsed.length > 1 && parsed[0]?.value === '/') {
|
|
1648
|
+
parsed.shift();
|
|
1649
|
+
}
|
|
1650
|
+
const score = parsed.map(d => {
|
|
1651
|
+
if (d.type === 'param') {
|
|
1652
|
+
return 0.5;
|
|
1653
|
+
}
|
|
1654
|
+
if (d.type === 'wildcard') {
|
|
1655
|
+
return 0.25;
|
|
1656
|
+
}
|
|
1657
|
+
return 1;
|
|
1658
|
+
});
|
|
1659
|
+
return {
|
|
1660
|
+
child: d,
|
|
1661
|
+
trimmed,
|
|
1662
|
+
parsed,
|
|
1663
|
+
index: i,
|
|
1664
|
+
score
|
|
1665
|
+
};
|
|
1666
|
+
}).sort((a, b) => {
|
|
1667
|
+
let isIndex = a.trimmed === '/' ? 1 : b.trimmed === '/' ? -1 : 0;
|
|
1668
|
+
if (isIndex !== 0) return isIndex;
|
|
1669
|
+
const length = Math.min(a.score.length, b.score.length);
|
|
1670
|
+
|
|
1671
|
+
// Sort by length of score
|
|
1672
|
+
if (a.score.length !== b.score.length) {
|
|
1673
|
+
return b.score.length - a.score.length;
|
|
1674
|
+
}
|
|
1675
|
+
|
|
1676
|
+
// Sort by min available score
|
|
1677
|
+
for (let i = 0; i < length; i++) {
|
|
1678
|
+
if (a.score[i] !== b.score[i]) {
|
|
1679
|
+
return b.score[i] - a.score[i];
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
// Sort by min available parsed value
|
|
1684
|
+
for (let i = 0; i < length; i++) {
|
|
1685
|
+
if (a.parsed[i].value !== b.parsed[i].value) {
|
|
1686
|
+
return a.parsed[i].value > b.parsed[i].value ? 1 : -1;
|
|
1687
|
+
}
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
// Sort by length of trimmed full path
|
|
1691
|
+
if (a.trimmed !== b.trimmed) {
|
|
1692
|
+
return a.trimmed > b.trimmed ? 1 : -1;
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
// Sort by original index
|
|
1696
|
+
return a.index - b.index;
|
|
1697
|
+
}).map((d, i) => {
|
|
1698
|
+
d.child.rank = i;
|
|
1699
|
+
return d.child;
|
|
1700
|
+
});
|
|
1701
|
+
};
|
|
1702
|
+
subscribe = (eventType, fn) => {
|
|
1703
|
+
const listener = {
|
|
1704
|
+
eventType,
|
|
1705
|
+
fn
|
|
1706
|
+
};
|
|
1707
|
+
this.subscribers.add(listener);
|
|
1708
|
+
return () => {
|
|
1709
|
+
this.subscribers.delete(listener);
|
|
1710
|
+
};
|
|
1711
|
+
};
|
|
1712
|
+
emit = routerEvent => {
|
|
1713
|
+
this.subscribers.forEach(listener => {
|
|
1714
|
+
if (listener.eventType === routerEvent.type) {
|
|
1715
|
+
listener.fn(routerEvent);
|
|
1716
|
+
}
|
|
1717
|
+
});
|
|
1718
|
+
};
|
|
1719
|
+
checkLatest = promise => {
|
|
1720
|
+
return this.latestLoadPromise !== promise ? this.latestLoadPromise : undefined;
|
|
1721
|
+
};
|
|
1722
|
+
parseLocation = previousLocation => {
|
|
1723
|
+
const parse = ({
|
|
1724
|
+
pathname,
|
|
1725
|
+
search,
|
|
1726
|
+
hash,
|
|
1727
|
+
state
|
|
1728
|
+
}) => {
|
|
1729
|
+
const parsedSearch = this.options.parseSearch(search);
|
|
1730
|
+
return {
|
|
1731
|
+
pathname: pathname,
|
|
1732
|
+
searchStr: search,
|
|
1733
|
+
search: replaceEqualDeep(previousLocation?.search, parsedSearch),
|
|
1734
|
+
hash: hash.split('#').reverse()[0] ?? '',
|
|
1735
|
+
href: `${pathname}${search}${hash}`,
|
|
1736
|
+
state: replaceEqualDeep(previousLocation?.state, state)
|
|
1737
|
+
};
|
|
1738
|
+
};
|
|
1739
|
+
const location = parse(this.history.location);
|
|
1740
|
+
let {
|
|
1741
|
+
__tempLocation,
|
|
1742
|
+
__tempKey
|
|
1743
|
+
} = location.state;
|
|
1744
|
+
if (__tempLocation && (!__tempKey || __tempKey === this.tempLocationKey)) {
|
|
1745
|
+
// Sync up the location keys
|
|
1746
|
+
const parsedTempLocation = parse(__tempLocation);
|
|
1747
|
+
parsedTempLocation.state.key = location.state.key;
|
|
1748
|
+
delete parsedTempLocation.state.__tempLocation;
|
|
1749
|
+
return {
|
|
1750
|
+
...parsedTempLocation,
|
|
1751
|
+
maskedLocation: location
|
|
1752
|
+
};
|
|
1753
|
+
}
|
|
1754
|
+
return location;
|
|
1755
|
+
};
|
|
1756
|
+
resolvePathWithBase = (from, path) => {
|
|
1757
|
+
return resolvePath(this.basepath, from, cleanPath(path));
|
|
1758
|
+
};
|
|
1759
|
+
get looseRoutesById() {
|
|
1760
|
+
return this.routesById;
|
|
1761
|
+
}
|
|
1762
|
+
matchRoutes = (pathname, locationSearch, opts) => {
|
|
1763
|
+
let routeParams = {};
|
|
1764
|
+
let foundRoute = this.flatRoutes.find(route => {
|
|
1765
|
+
const matchedParams = matchPathname(this.basepath, trimPathRight(pathname), {
|
|
1766
|
+
to: route.fullPath,
|
|
1767
|
+
caseSensitive: route.options.caseSensitive ?? this.options.caseSensitive,
|
|
1768
|
+
fuzzy: false
|
|
1769
|
+
});
|
|
1770
|
+
if (matchedParams) {
|
|
1771
|
+
routeParams = matchedParams;
|
|
1772
|
+
return true;
|
|
1773
|
+
}
|
|
1774
|
+
return false;
|
|
1775
|
+
});
|
|
1776
|
+
let routeCursor = foundRoute || this.routesById['__root__'];
|
|
1777
|
+
let matchedRoutes = [routeCursor];
|
|
1778
|
+
// let includingLayouts = true
|
|
1779
|
+
while (routeCursor?.parentRoute) {
|
|
1780
|
+
routeCursor = routeCursor.parentRoute;
|
|
1781
|
+
if (routeCursor) matchedRoutes.unshift(routeCursor);
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
// Existing matches are matches that are already loaded along with
|
|
1785
|
+
// pending matches that are still loading
|
|
1786
|
+
|
|
1787
|
+
const parseErrors = matchedRoutes.map(route => {
|
|
1788
|
+
let parsedParamsError;
|
|
1789
|
+
if (route.options.parseParams) {
|
|
1790
|
+
try {
|
|
1791
|
+
const parsedParams = route.options.parseParams(routeParams);
|
|
1792
|
+
// Add the parsed params to the accumulated params bag
|
|
1793
|
+
Object.assign(routeParams, parsedParams);
|
|
1794
|
+
} catch (err) {
|
|
1795
|
+
parsedParamsError = new PathParamError(err.message, {
|
|
1590
1796
|
cause: err
|
|
1591
1797
|
});
|
|
1592
1798
|
if (opts?.throwOnError) {
|
|
@@ -1604,10 +1810,12 @@
|
|
|
1604
1810
|
// Waste not, want not. If we already have a match for this route,
|
|
1605
1811
|
// reuse it. This is important for layout routes, which might stick
|
|
1606
1812
|
// around between navigation actions that only change leaf routes.
|
|
1607
|
-
const existingMatch = getRouteMatch(state, matchId);
|
|
1813
|
+
const existingMatch = getRouteMatch(this.state, matchId);
|
|
1814
|
+
const cause = this.state.matches.find(d => d.id === matchId) ? 'stay' : 'enter';
|
|
1608
1815
|
if (existingMatch) {
|
|
1609
1816
|
return {
|
|
1610
|
-
...existingMatch
|
|
1817
|
+
...existingMatch,
|
|
1818
|
+
cause
|
|
1611
1819
|
};
|
|
1612
1820
|
}
|
|
1613
1821
|
|
|
@@ -1617,7 +1825,7 @@
|
|
|
1617
1825
|
id: matchId,
|
|
1618
1826
|
routeId: route.id,
|
|
1619
1827
|
params: routeParams,
|
|
1620
|
-
pathname: joinPaths([basepath, interpolatedPath]),
|
|
1828
|
+
pathname: joinPaths([this.basepath, interpolatedPath]),
|
|
1621
1829
|
updatedAt: Date.now(),
|
|
1622
1830
|
routeSearch: {},
|
|
1623
1831
|
search: {},
|
|
@@ -1631,7 +1839,8 @@
|
|
|
1631
1839
|
context: undefined,
|
|
1632
1840
|
abortController: new AbortController(),
|
|
1633
1841
|
shouldReloadDeps: undefined,
|
|
1634
|
-
fetchedAt: 0
|
|
1842
|
+
fetchedAt: 0,
|
|
1843
|
+
cause
|
|
1635
1844
|
};
|
|
1636
1845
|
return routeMatch;
|
|
1637
1846
|
});
|
|
@@ -1641,7 +1850,7 @@
|
|
|
1641
1850
|
// so that we can use the parent match's search params and context
|
|
1642
1851
|
matches.forEach((match, i) => {
|
|
1643
1852
|
const parentMatch = matches[i - 1];
|
|
1644
|
-
const route = looseRoutesById[match.routeId];
|
|
1853
|
+
const route = this.looseRoutesById[match.routeId];
|
|
1645
1854
|
const searchInfo = (() => {
|
|
1646
1855
|
// Validate the search params and stabilize them
|
|
1647
1856
|
const parentSearchInfo = {
|
|
@@ -1675,28 +1884,28 @@
|
|
|
1675
1884
|
Object.assign(match, searchInfo);
|
|
1676
1885
|
});
|
|
1677
1886
|
return matches;
|
|
1678
|
-
}
|
|
1679
|
-
|
|
1680
|
-
getRouteMatch(state, id)?.abortController?.abort();
|
|
1681
|
-
}
|
|
1682
|
-
|
|
1683
|
-
state.matches.forEach(match => {
|
|
1684
|
-
cancelMatch(match.id);
|
|
1887
|
+
};
|
|
1888
|
+
cancelMatch = id => {
|
|
1889
|
+
getRouteMatch(this.state, id)?.abortController?.abort();
|
|
1890
|
+
};
|
|
1891
|
+
cancelMatches = () => {
|
|
1892
|
+
this.state.matches.forEach(match => {
|
|
1893
|
+
this.cancelMatch(match.id);
|
|
1685
1894
|
});
|
|
1686
|
-
}
|
|
1687
|
-
|
|
1895
|
+
};
|
|
1896
|
+
buildLocation = opts => {
|
|
1688
1897
|
const build = (dest = {}, matches) => {
|
|
1689
|
-
const from =
|
|
1898
|
+
const from = this.latestLocation;
|
|
1690
1899
|
const fromPathname = dest.from ?? from.pathname;
|
|
1691
|
-
let pathname = resolvePathWithBase(fromPathname, `${dest.to ?? ''}`);
|
|
1692
|
-
const fromMatches = matchRoutes(fromPathname, from.search);
|
|
1900
|
+
let pathname = this.resolvePathWithBase(fromPathname, `${dest.to ?? ''}`);
|
|
1901
|
+
const fromMatches = this.matchRoutes(fromPathname, from.search);
|
|
1693
1902
|
const stayingMatches = matches?.filter(d => fromMatches?.find(e => e.routeId === d.routeId));
|
|
1694
1903
|
const prevParams = {
|
|
1695
1904
|
...last(fromMatches)?.params
|
|
1696
1905
|
};
|
|
1697
1906
|
let nextParams = (dest.params ?? true) === true ? prevParams : functionalUpdate(dest.params, prevParams);
|
|
1698
1907
|
if (nextParams) {
|
|
1699
|
-
matches?.map(d => looseRoutesById[d.routeId].options.stringifyParams).filter(Boolean).forEach(fn => {
|
|
1908
|
+
matches?.map(d => this.looseRoutesById[d.routeId].options.stringifyParams).filter(Boolean).forEach(fn => {
|
|
1700
1909
|
nextParams = {
|
|
1701
1910
|
...nextParams,
|
|
1702
1911
|
...fn(nextParams)
|
|
@@ -1704,8 +1913,8 @@
|
|
|
1704
1913
|
});
|
|
1705
1914
|
}
|
|
1706
1915
|
pathname = interpolatePath(pathname, nextParams ?? {});
|
|
1707
|
-
const preSearchFilters = stayingMatches?.map(match => looseRoutesById[match.routeId].options.preSearchFilters ?? []).flat().filter(Boolean) ?? [];
|
|
1708
|
-
const postSearchFilters = stayingMatches?.map(match => looseRoutesById[match.routeId].options.postSearchFilters ?? []).flat().filter(Boolean) ?? [];
|
|
1916
|
+
const preSearchFilters = stayingMatches?.map(match => this.looseRoutesById[match.routeId].options.preSearchFilters ?? []).flat().filter(Boolean) ?? [];
|
|
1917
|
+
const postSearchFilters = stayingMatches?.map(match => this.looseRoutesById[match.routeId].options.postSearchFilters ?? []).flat().filter(Boolean) ?? [];
|
|
1709
1918
|
|
|
1710
1919
|
// Pre filters first
|
|
1711
1920
|
const preFilteredSearch = preSearchFilters?.length ? preSearchFilters?.reduce((prev, next) => next(prev), from.search) : from.search;
|
|
@@ -1719,7 +1928,7 @@
|
|
|
1719
1928
|
// Then post filters
|
|
1720
1929
|
const postFilteredSearch = postSearchFilters?.length ? postSearchFilters.reduce((prev, next) => next(prev), destSearch) : destSearch;
|
|
1721
1930
|
const search = replaceEqualDeep(from.search, postFilteredSearch);
|
|
1722
|
-
const searchStr = options.stringifySearch(search);
|
|
1931
|
+
const searchStr = this.options.stringifySearch(search);
|
|
1723
1932
|
const hash = dest.hash === true ? from.hash : dest.hash ? functionalUpdate(dest.hash, from.hash) : from.hash;
|
|
1724
1933
|
const hashStr = hash ? `#${hash}` : '';
|
|
1725
1934
|
let nextState = dest.state === true ? from.state : dest.state ? functionalUpdate(dest.state, from.state) : from.state;
|
|
@@ -1730,7 +1939,7 @@
|
|
|
1730
1939
|
searchStr,
|
|
1731
1940
|
state: nextState,
|
|
1732
1941
|
hash,
|
|
1733
|
-
href: history.createHref(`${pathname}${searchStr}${hashStr}`),
|
|
1942
|
+
href: this.history.createHref(`${pathname}${searchStr}${hashStr}`),
|
|
1734
1943
|
unmaskOnReload: dest.unmaskOnReload
|
|
1735
1944
|
};
|
|
1736
1945
|
};
|
|
@@ -1739,8 +1948,8 @@
|
|
|
1739
1948
|
let maskedNext = maskedDest ? build(maskedDest) : undefined;
|
|
1740
1949
|
if (!maskedNext) {
|
|
1741
1950
|
let params = {};
|
|
1742
|
-
let foundMask = options.routeMasks?.find(d => {
|
|
1743
|
-
const match = matchPathname(basepath, next.pathname, {
|
|
1951
|
+
let foundMask = this.options.routeMasks?.find(d => {
|
|
1952
|
+
const match = matchPathname(this.basepath, next.pathname, {
|
|
1744
1953
|
to: d.from,
|
|
1745
1954
|
caseSensitive: false,
|
|
1746
1955
|
fuzzy: false
|
|
@@ -1760,8 +1969,8 @@
|
|
|
1760
1969
|
maskedNext = build(maskedDest);
|
|
1761
1970
|
}
|
|
1762
1971
|
}
|
|
1763
|
-
const nextMatches = matchRoutes(next.pathname, next.search);
|
|
1764
|
-
const maskedMatches = maskedNext ? matchRoutes(maskedNext.pathname, maskedNext.search) : undefined;
|
|
1972
|
+
const nextMatches = this.matchRoutes(next.pathname, next.search);
|
|
1973
|
+
const maskedMatches = maskedNext ? this.matchRoutes(maskedNext.pathname, maskedNext.search) : undefined;
|
|
1765
1974
|
const maskedFinal = maskedNext ? build(maskedDest, maskedMatches) : undefined;
|
|
1766
1975
|
const final = build(dest, nextMatches);
|
|
1767
1976
|
if (maskedFinal) {
|
|
@@ -1776,13 +1985,13 @@
|
|
|
1776
1985
|
});
|
|
1777
1986
|
}
|
|
1778
1987
|
return buildWithMatches(opts);
|
|
1779
|
-
}
|
|
1780
|
-
|
|
1988
|
+
};
|
|
1989
|
+
commitLocation = async ({
|
|
1781
1990
|
startTransition,
|
|
1782
1991
|
...next
|
|
1783
1992
|
}) => {
|
|
1784
|
-
if (
|
|
1785
|
-
const isSameUrl =
|
|
1993
|
+
if (this.navigateTimeout) clearTimeout(this.navigateTimeout);
|
|
1994
|
+
const isSameUrl = this.latestLocation.href === next.href;
|
|
1786
1995
|
|
|
1787
1996
|
// If the next urls are the same and we're not replacing,
|
|
1788
1997
|
// do nothing
|
|
@@ -1809,37 +2018,37 @@
|
|
|
1809
2018
|
}
|
|
1810
2019
|
}
|
|
1811
2020
|
};
|
|
1812
|
-
if (nextHistory.unmaskOnReload ?? options.unmaskOnReload ?? false) {
|
|
1813
|
-
nextHistory.state.__tempKey =
|
|
2021
|
+
if (nextHistory.unmaskOnReload ?? this.options.unmaskOnReload ?? false) {
|
|
2022
|
+
nextHistory.state.__tempKey = this.tempLocationKey;
|
|
1814
2023
|
}
|
|
1815
2024
|
}
|
|
1816
2025
|
const apply = () => {
|
|
1817
|
-
history[next.replace ? 'replace' : 'push'](nextHistory.href, nextHistory.state);
|
|
2026
|
+
this.history[next.replace ? 'replace' : 'push'](nextHistory.href, nextHistory.state);
|
|
1818
2027
|
};
|
|
1819
2028
|
if (startTransition ?? true) {
|
|
1820
|
-
startReactTransition(apply);
|
|
2029
|
+
this.startReactTransition(apply);
|
|
1821
2030
|
} else {
|
|
1822
2031
|
apply();
|
|
1823
2032
|
}
|
|
1824
2033
|
}
|
|
1825
|
-
|
|
1826
|
-
return
|
|
1827
|
-
}
|
|
1828
|
-
|
|
2034
|
+
this.resetNextScroll = next.resetScroll ?? true;
|
|
2035
|
+
return this.latestLoadPromise;
|
|
2036
|
+
};
|
|
2037
|
+
buildAndCommitLocation = ({
|
|
1829
2038
|
replace,
|
|
1830
2039
|
resetScroll,
|
|
1831
2040
|
startTransition,
|
|
1832
2041
|
...rest
|
|
1833
2042
|
} = {}) => {
|
|
1834
|
-
const location = buildLocation(rest);
|
|
1835
|
-
return commitLocation({
|
|
2043
|
+
const location = this.buildLocation(rest);
|
|
2044
|
+
return this.commitLocation({
|
|
1836
2045
|
...location,
|
|
1837
2046
|
startTransition,
|
|
1838
2047
|
replace,
|
|
1839
2048
|
resetScroll
|
|
1840
2049
|
});
|
|
1841
|
-
}
|
|
1842
|
-
|
|
2050
|
+
};
|
|
2051
|
+
navigate = ({
|
|
1843
2052
|
from,
|
|
1844
2053
|
to = '',
|
|
1845
2054
|
...rest
|
|
@@ -1857,13 +2066,13 @@
|
|
|
1857
2066
|
isExternal = true;
|
|
1858
2067
|
} catch (e) {}
|
|
1859
2068
|
invariant(!isExternal, 'Attempting to navigate to external url with this.navigate!');
|
|
1860
|
-
return buildAndCommitLocation({
|
|
2069
|
+
return this.buildAndCommitLocation({
|
|
1861
2070
|
...rest,
|
|
1862
2071
|
from: fromString,
|
|
1863
2072
|
to: toString
|
|
1864
2073
|
});
|
|
1865
|
-
}
|
|
1866
|
-
|
|
2074
|
+
};
|
|
2075
|
+
loadMatches = async ({
|
|
1867
2076
|
checkLatest,
|
|
1868
2077
|
matches,
|
|
1869
2078
|
preload
|
|
@@ -1875,7 +2084,7 @@
|
|
|
1875
2084
|
try {
|
|
1876
2085
|
for (let [index, match] of matches.entries()) {
|
|
1877
2086
|
const parentMatch = matches[index - 1];
|
|
1878
|
-
const route = looseRoutesById[match.routeId];
|
|
2087
|
+
const route = this.looseRoutesById[match.routeId];
|
|
1879
2088
|
const handleError = (err, code) => {
|
|
1880
2089
|
err.routerCode = code;
|
|
1881
2090
|
firstBadMatchIndex = firstBadMatchIndex ?? index;
|
|
@@ -1904,19 +2113,21 @@
|
|
|
1904
2113
|
if (match.searchError) {
|
|
1905
2114
|
handleError(match.searchError, 'VALIDATE_SEARCH');
|
|
1906
2115
|
}
|
|
1907
|
-
const parentContext = parentMatch?.context ?? options.context ?? {};
|
|
2116
|
+
const parentContext = parentMatch?.context ?? this.options.context ?? {};
|
|
1908
2117
|
const beforeLoadContext = (await route.options.beforeLoad?.({
|
|
1909
2118
|
search: match.search,
|
|
1910
2119
|
abortController: match.abortController,
|
|
1911
2120
|
params: match.params,
|
|
1912
2121
|
preload: !!preload,
|
|
1913
2122
|
context: parentContext,
|
|
1914
|
-
location: state.location,
|
|
1915
|
-
|
|
2123
|
+
location: this.state.location,
|
|
2124
|
+
// TOOD: just expose state and router, etc
|
|
2125
|
+
navigate: opts => this.navigate({
|
|
1916
2126
|
...opts,
|
|
1917
2127
|
from: match.pathname
|
|
1918
2128
|
}),
|
|
1919
|
-
buildLocation
|
|
2129
|
+
buildLocation: this.buildLocation,
|
|
2130
|
+
cause: match.cause
|
|
1920
2131
|
})) ?? {};
|
|
1921
2132
|
const context = {
|
|
1922
2133
|
...parentContext,
|
|
@@ -1933,7 +2144,7 @@
|
|
|
1933
2144
|
}
|
|
1934
2145
|
} catch (err) {
|
|
1935
2146
|
if (isRedirect(err)) {
|
|
1936
|
-
if (!preload) navigate(err);
|
|
2147
|
+
if (!preload) this.navigate(err);
|
|
1937
2148
|
return matches;
|
|
1938
2149
|
}
|
|
1939
2150
|
throw err;
|
|
@@ -1943,11 +2154,11 @@
|
|
|
1943
2154
|
validResolvedMatches.forEach((match, index) => {
|
|
1944
2155
|
matchPromises.push((async () => {
|
|
1945
2156
|
const parentMatchPromise = matchPromises[index - 1];
|
|
1946
|
-
const route = looseRoutesById[match.routeId];
|
|
2157
|
+
const route = this.looseRoutesById[match.routeId];
|
|
1947
2158
|
const handleIfRedirect = err => {
|
|
1948
2159
|
if (isRedirect(err)) {
|
|
1949
2160
|
if (!preload) {
|
|
1950
|
-
navigate(err);
|
|
2161
|
+
this.navigate(err);
|
|
1951
2162
|
}
|
|
1952
2163
|
return true;
|
|
1953
2164
|
}
|
|
@@ -1960,9 +2171,8 @@
|
|
|
1960
2171
|
invalid: false
|
|
1961
2172
|
};
|
|
1962
2173
|
if (match.isFetching) {
|
|
1963
|
-
loadPromise = getRouteMatch(state, match.id)?.loadPromise;
|
|
2174
|
+
loadPromise = getRouteMatch(this.state, match.id)?.loadPromise;
|
|
1964
2175
|
} else {
|
|
1965
|
-
const cause = state.matches.find(d => d.id === match.id) ? 'stay' : 'enter';
|
|
1966
2176
|
const loaderContext = {
|
|
1967
2177
|
params: match.params,
|
|
1968
2178
|
search: match.search,
|
|
@@ -1970,20 +2180,20 @@
|
|
|
1970
2180
|
parentMatchPromise,
|
|
1971
2181
|
abortController: match.abortController,
|
|
1972
2182
|
context: match.context,
|
|
1973
|
-
location: state.location,
|
|
1974
|
-
navigate: opts => navigate({
|
|
2183
|
+
location: this.state.location,
|
|
2184
|
+
navigate: opts => this.navigate({
|
|
1975
2185
|
...opts,
|
|
1976
2186
|
from: match.pathname
|
|
1977
2187
|
}),
|
|
1978
|
-
cause
|
|
2188
|
+
cause: match.cause
|
|
1979
2189
|
};
|
|
1980
2190
|
|
|
1981
2191
|
// Default to reloading the route all the time
|
|
1982
2192
|
let shouldReload = true;
|
|
1983
2193
|
let shouldReloadDeps = typeof route.options.shouldReload === 'function' ? route.options.shouldReload?.(loaderContext) : !!(route.options.shouldReload ?? true);
|
|
1984
|
-
if (cause === 'enter') {
|
|
2194
|
+
if (match.cause === 'enter') {
|
|
1985
2195
|
match.shouldReloadDeps = shouldReloadDeps;
|
|
1986
|
-
} else if (cause === 'stay') {
|
|
2196
|
+
} else if (match.cause === 'stay') {
|
|
1987
2197
|
if (typeof shouldReloadDeps === 'object') {
|
|
1988
2198
|
// compare the deps to see if they've changed
|
|
1989
2199
|
shouldReload = !deepEqual(shouldReloadDeps, match.shouldReloadDeps);
|
|
@@ -2019,7 +2229,7 @@
|
|
|
2019
2229
|
loadPromise
|
|
2020
2230
|
};
|
|
2021
2231
|
if (!preload) {
|
|
2022
|
-
setState(s => ({
|
|
2232
|
+
this.setState(s => ({
|
|
2023
2233
|
...s,
|
|
2024
2234
|
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2025
2235
|
}));
|
|
@@ -2054,7 +2264,7 @@
|
|
|
2054
2264
|
};
|
|
2055
2265
|
}
|
|
2056
2266
|
if (!preload) {
|
|
2057
|
-
setState(s => ({
|
|
2267
|
+
this.setState(s => ({
|
|
2058
2268
|
...s,
|
|
2059
2269
|
matches: s.matches.map(d => d.id === match.id ? match : d)
|
|
2060
2270
|
}));
|
|
@@ -2063,17 +2273,17 @@
|
|
|
2063
2273
|
});
|
|
2064
2274
|
await Promise.all(matchPromises);
|
|
2065
2275
|
return matches;
|
|
2066
|
-
}
|
|
2067
|
-
|
|
2276
|
+
};
|
|
2277
|
+
load = async () => {
|
|
2068
2278
|
const promise = new Promise(async (resolve, reject) => {
|
|
2069
|
-
const next =
|
|
2070
|
-
const prevLocation = state.resolvedLocation;
|
|
2279
|
+
const next = this.latestLocation;
|
|
2280
|
+
const prevLocation = this.state.resolvedLocation;
|
|
2071
2281
|
const pathDidChange = prevLocation.href !== next.href;
|
|
2072
2282
|
let latestPromise;
|
|
2073
2283
|
|
|
2074
2284
|
// Cancel any pending matches
|
|
2075
|
-
cancelMatches(
|
|
2076
|
-
|
|
2285
|
+
this.cancelMatches();
|
|
2286
|
+
this.emit({
|
|
2077
2287
|
type: 'onBeforeLoad',
|
|
2078
2288
|
fromLocation: prevLocation,
|
|
2079
2289
|
toLocation: next,
|
|
@@ -2081,14 +2291,14 @@
|
|
|
2081
2291
|
});
|
|
2082
2292
|
|
|
2083
2293
|
// Match the routes
|
|
2084
|
-
let matches = matchRoutes(next.pathname, next.search, {
|
|
2294
|
+
let matches = this.matchRoutes(next.pathname, next.search, {
|
|
2085
2295
|
debug: true
|
|
2086
2296
|
});
|
|
2087
|
-
|
|
2088
|
-
const previousMatches = state.matches;
|
|
2297
|
+
this.pendingMatches = matches;
|
|
2298
|
+
const previousMatches = this.state.matches;
|
|
2089
2299
|
|
|
2090
2300
|
// Ingest the new matches
|
|
2091
|
-
setState(s => ({
|
|
2301
|
+
this.setState(s => ({
|
|
2092
2302
|
...s,
|
|
2093
2303
|
status: 'pending',
|
|
2094
2304
|
location: next,
|
|
@@ -2097,9 +2307,9 @@
|
|
|
2097
2307
|
try {
|
|
2098
2308
|
try {
|
|
2099
2309
|
// Load the matches
|
|
2100
|
-
await loadMatches({
|
|
2310
|
+
await this.loadMatches({
|
|
2101
2311
|
matches,
|
|
2102
|
-
checkLatest: () => checkLatest(promise)
|
|
2312
|
+
checkLatest: () => this.checkLatest(promise)
|
|
2103
2313
|
});
|
|
2104
2314
|
} catch (err) {
|
|
2105
2315
|
// swallow this error, since we'll display the
|
|
@@ -2107,12 +2317,12 @@
|
|
|
2107
2317
|
}
|
|
2108
2318
|
|
|
2109
2319
|
// Only apply the latest transition
|
|
2110
|
-
if (latestPromise = checkLatest(promise)) {
|
|
2320
|
+
if (latestPromise = this.checkLatest(promise)) {
|
|
2111
2321
|
return latestPromise;
|
|
2112
2322
|
}
|
|
2113
|
-
const exitingMatchIds = previousMatches.filter(id => !
|
|
2114
|
-
const enteringMatchIds =
|
|
2115
|
-
const stayingMatchIds = previousMatches.filter(id =>
|
|
2323
|
+
const exitingMatchIds = previousMatches.filter(id => !this.pendingMatches.includes(id));
|
|
2324
|
+
const enteringMatchIds = this.pendingMatches.filter(id => !previousMatches.includes(id));
|
|
2325
|
+
const stayingMatchIds = previousMatches.filter(id => this.pendingMatches.includes(id))
|
|
2116
2326
|
|
|
2117
2327
|
// setState((s) => ({
|
|
2118
2328
|
// ...s,
|
|
@@ -2124,10 +2334,10 @@
|
|
|
2124
2334
|
;
|
|
2125
2335
|
[[exitingMatchIds, 'onLeave'], [enteringMatchIds, 'onEnter'], [stayingMatchIds, 'onTransition']].forEach(([matches, hook]) => {
|
|
2126
2336
|
matches.forEach(match => {
|
|
2127
|
-
looseRoutesById[match.routeId].options[hook]?.(match);
|
|
2337
|
+
this.looseRoutesById[match.routeId].options[hook]?.(match);
|
|
2128
2338
|
});
|
|
2129
2339
|
});
|
|
2130
|
-
|
|
2340
|
+
this.emit({
|
|
2131
2341
|
type: 'onLoad',
|
|
2132
2342
|
fromLocation: prevLocation,
|
|
2133
2343
|
toLocation: next,
|
|
@@ -2136,28 +2346,28 @@
|
|
|
2136
2346
|
resolve();
|
|
2137
2347
|
} catch (err) {
|
|
2138
2348
|
// Only apply the latest transition
|
|
2139
|
-
if (latestPromise = checkLatest(promise)) {
|
|
2349
|
+
if (latestPromise = this.checkLatest(promise)) {
|
|
2140
2350
|
return latestPromise;
|
|
2141
2351
|
}
|
|
2142
2352
|
reject(err);
|
|
2143
2353
|
}
|
|
2144
2354
|
});
|
|
2145
|
-
|
|
2146
|
-
return
|
|
2147
|
-
}
|
|
2148
|
-
|
|
2149
|
-
let next = buildLocation(navigateOpts);
|
|
2150
|
-
let matches = matchRoutes(next.pathname, next.search, {
|
|
2355
|
+
this.latestLoadPromise = promise;
|
|
2356
|
+
return this.latestLoadPromise;
|
|
2357
|
+
};
|
|
2358
|
+
preloadRoute = async (navigateOpts = this.state.location) => {
|
|
2359
|
+
let next = this.buildLocation(navigateOpts);
|
|
2360
|
+
let matches = this.matchRoutes(next.pathname, next.search, {
|
|
2151
2361
|
throwOnError: true
|
|
2152
2362
|
});
|
|
2153
|
-
await loadMatches({
|
|
2363
|
+
await this.loadMatches({
|
|
2154
2364
|
matches,
|
|
2155
2365
|
preload: true,
|
|
2156
2366
|
checkLatest: () => undefined
|
|
2157
2367
|
});
|
|
2158
2368
|
return [last(matches), matches];
|
|
2159
|
-
}
|
|
2160
|
-
|
|
2369
|
+
};
|
|
2370
|
+
buildLink = dest => {
|
|
2161
2371
|
// If this link simply reloads the current route,
|
|
2162
2372
|
// make sure it has a new key so it will trigger a data refresh
|
|
2163
2373
|
|
|
@@ -2183,18 +2393,18 @@
|
|
|
2183
2393
|
};
|
|
2184
2394
|
} catch (e) {}
|
|
2185
2395
|
const nextOpts = dest;
|
|
2186
|
-
const next = buildLocation(nextOpts);
|
|
2187
|
-
const preload = userPreload ?? options.defaultPreload;
|
|
2188
|
-
const preloadDelay = userPreloadDelay ?? options.defaultPreloadDelay ?? 0;
|
|
2396
|
+
const next = this.buildLocation(nextOpts);
|
|
2397
|
+
const preload = userPreload ?? this.options.defaultPreload;
|
|
2398
|
+
const preloadDelay = userPreloadDelay ?? this.options.defaultPreloadDelay ?? 0;
|
|
2189
2399
|
|
|
2190
2400
|
// Compare path/hash for matches
|
|
2191
|
-
const currentPathSplit =
|
|
2401
|
+
const currentPathSplit = this.latestLocation.pathname.split('/');
|
|
2192
2402
|
const nextPathSplit = next.pathname.split('/');
|
|
2193
2403
|
const pathIsFuzzyEqual = nextPathSplit.every((d, i) => d === currentPathSplit[i]);
|
|
2194
|
-
// Combine the matches based on user options
|
|
2195
|
-
const pathTest = activeOptions?.exact ?
|
|
2196
|
-
const hashTest = activeOptions?.includeHash ?
|
|
2197
|
-
const searchTest = activeOptions?.includeSearch ?? true ? deepEqual(
|
|
2404
|
+
// Combine the matches based on user this.options
|
|
2405
|
+
const pathTest = activeOptions?.exact ? this.latestLocation.pathname === next.pathname : pathIsFuzzyEqual;
|
|
2406
|
+
const hashTest = activeOptions?.includeHash ? this.latestLocation.hash === next.hash : true;
|
|
2407
|
+
const searchTest = activeOptions?.includeSearch ?? true ? deepEqual(this.latestLocation.search, next.search, true) : true;
|
|
2198
2408
|
|
|
2199
2409
|
// The final "active" test
|
|
2200
2410
|
const isActive = pathTest && hashTest && searchTest;
|
|
@@ -2205,7 +2415,7 @@
|
|
|
2205
2415
|
e.preventDefault();
|
|
2206
2416
|
|
|
2207
2417
|
// All is well? Navigate!
|
|
2208
|
-
commitLocation({
|
|
2418
|
+
this.commitLocation({
|
|
2209
2419
|
...next,
|
|
2210
2420
|
replace,
|
|
2211
2421
|
resetScroll,
|
|
@@ -2217,384 +2427,184 @@
|
|
|
2217
2427
|
// The click handler
|
|
2218
2428
|
const handleFocus = e => {
|
|
2219
2429
|
if (preload) {
|
|
2220
|
-
preloadRoute(nextOpts).catch(err => {
|
|
2430
|
+
this.preloadRoute(nextOpts).catch(err => {
|
|
2221
2431
|
console.warn(err);
|
|
2222
2432
|
console.warn(preloadWarning);
|
|
2223
2433
|
});
|
|
2224
2434
|
}
|
|
2225
2435
|
};
|
|
2226
2436
|
const handleTouchStart = e => {
|
|
2227
|
-
preloadRoute(nextOpts).catch(err => {
|
|
2437
|
+
this.preloadRoute(nextOpts).catch(err => {
|
|
2228
2438
|
console.warn(err);
|
|
2229
2439
|
console.warn(preloadWarning);
|
|
2230
2440
|
});
|
|
2231
2441
|
};
|
|
2232
|
-
const handleEnter = e => {
|
|
2233
|
-
const target = e.target || {};
|
|
2234
|
-
if (preload) {
|
|
2235
|
-
if (target.preloadTimeout) {
|
|
2236
|
-
return;
|
|
2237
|
-
}
|
|
2238
|
-
target.preloadTimeout = setTimeout(() => {
|
|
2239
|
-
target.preloadTimeout = null;
|
|
2240
|
-
preloadRoute(nextOpts).catch(err => {
|
|
2241
|
-
console.warn(err);
|
|
2242
|
-
console.warn(preloadWarning);
|
|
2243
|
-
});
|
|
2244
|
-
}, preloadDelay);
|
|
2245
|
-
}
|
|
2246
|
-
};
|
|
2247
|
-
const handleLeave = e => {
|
|
2248
|
-
const target = e.target || {};
|
|
2249
|
-
if (target.preloadTimeout) {
|
|
2250
|
-
clearTimeout(target.preloadTimeout);
|
|
2251
|
-
target.preloadTimeout = null;
|
|
2252
|
-
}
|
|
2253
|
-
};
|
|
2254
|
-
return {
|
|
2255
|
-
type: 'internal',
|
|
2256
|
-
next,
|
|
2257
|
-
handleFocus,
|
|
2258
|
-
handleClick,
|
|
2259
|
-
handleEnter,
|
|
2260
|
-
handleLeave,
|
|
2261
|
-
handleTouchStart,
|
|
2262
|
-
isActive,
|
|
2263
|
-
disabled
|
|
2264
|
-
};
|
|
2265
|
-
});
|
|
2266
|
-
React__namespace.useLayoutEffect(() => {
|
|
2267
|
-
const unsub = history.subscribe(() => {
|
|
2268
|
-
latestLocationRef.current = parseLocation(latestLocationRef.current);
|
|
2269
|
-
if (state.location !== latestLocationRef.current) {
|
|
2270
|
-
startReactTransition(() => {
|
|
2271
|
-
try {
|
|
2272
|
-
load();
|
|
2273
|
-
} catch (err) {
|
|
2274
|
-
console.error(err);
|
|
2275
|
-
}
|
|
2276
|
-
});
|
|
2277
|
-
}
|
|
2278
|
-
});
|
|
2279
|
-
const nextLocation = buildLocation({
|
|
2280
|
-
search: true,
|
|
2281
|
-
params: true,
|
|
2282
|
-
hash: true,
|
|
2283
|
-
state: true
|
|
2284
|
-
});
|
|
2285
|
-
if (state.location.href !== nextLocation.href) {
|
|
2286
|
-
commitLocation({
|
|
2287
|
-
...nextLocation,
|
|
2288
|
-
replace: true
|
|
2289
|
-
});
|
|
2290
|
-
}
|
|
2291
|
-
return () => {
|
|
2292
|
-
unsub();
|
|
2293
|
-
};
|
|
2294
|
-
}, [history]);
|
|
2295
|
-
const matchRoute = useStableCallback((location, opts) => {
|
|
2296
|
-
location = {
|
|
2297
|
-
...location,
|
|
2298
|
-
to: location.to ? resolvePathWithBase(location.from || '', location.to) : undefined
|
|
2299
|
-
};
|
|
2300
|
-
const next = buildLocation(location);
|
|
2301
|
-
if (opts?.pending && state.status !== 'pending') {
|
|
2302
|
-
return false;
|
|
2303
|
-
}
|
|
2304
|
-
const baseLocation = opts?.pending ? latestLocationRef.current : state.resolvedLocation;
|
|
2305
|
-
|
|
2306
|
-
// const baseLocation = state.resolvedLocation
|
|
2307
|
-
|
|
2308
|
-
if (!baseLocation) {
|
|
2309
|
-
return false;
|
|
2310
|
-
}
|
|
2311
|
-
const match = matchPathname(basepath, baseLocation.pathname, {
|
|
2312
|
-
...opts,
|
|
2313
|
-
to: next.pathname
|
|
2314
|
-
});
|
|
2315
|
-
if (!match) {
|
|
2316
|
-
return false;
|
|
2317
|
-
}
|
|
2318
|
-
if (match && (opts?.includeSearch ?? true)) {
|
|
2319
|
-
return deepEqual(baseLocation.search, next.search, true) ? match : false;
|
|
2320
|
-
}
|
|
2321
|
-
return match;
|
|
2322
|
-
});
|
|
2323
|
-
const injectedHtmlRef = React__namespace.useRef([]);
|
|
2324
|
-
const injectHtml = useStableCallback(async html => {
|
|
2325
|
-
injectedHtmlRef.current.push(html);
|
|
2326
|
-
});
|
|
2327
|
-
const dehydrateData = useStableCallback((key, getData) => {
|
|
2328
|
-
if (typeof document === 'undefined') {
|
|
2329
|
-
const strKey = typeof key === 'string' ? key : JSON.stringify(key);
|
|
2330
|
-
injectHtml(async () => {
|
|
2331
|
-
const id = `__TSR_DEHYDRATED__${strKey}`;
|
|
2332
|
-
const data = typeof getData === 'function' ? await getData() : getData;
|
|
2333
|
-
return `<script id='${id}' suppressHydrationWarning>window["__TSR_DEHYDRATED__${escapeJSON(strKey)}"] = ${JSON.stringify(data)}
|
|
2334
|
-
;(() => {
|
|
2335
|
-
var el = document.getElementById('${id}')
|
|
2336
|
-
el.parentElement.removeChild(el)
|
|
2337
|
-
})()
|
|
2338
|
-
</script>`;
|
|
2339
|
-
});
|
|
2340
|
-
return () => hydrateData(key);
|
|
2341
|
-
}
|
|
2342
|
-
return () => undefined;
|
|
2343
|
-
});
|
|
2344
|
-
const hydrateData = useStableCallback(key => {
|
|
2345
|
-
if (typeof document !== 'undefined') {
|
|
2346
|
-
const strKey = typeof key === 'string' ? key : JSON.stringify(key);
|
|
2347
|
-
return window[`__TSR_DEHYDRATED__${strKey}`];
|
|
2348
|
-
}
|
|
2349
|
-
return undefined;
|
|
2350
|
-
});
|
|
2351
|
-
React__namespace.useLayoutEffect(() => {
|
|
2352
|
-
startReactTransition(() => {
|
|
2353
|
-
try {
|
|
2354
|
-
load();
|
|
2355
|
-
} catch (err) {
|
|
2356
|
-
console.error(err);
|
|
2357
|
-
}
|
|
2358
|
-
});
|
|
2359
|
-
}, []);
|
|
2360
|
-
const routerContextValue = {
|
|
2361
|
-
routeTree: router.routeTree,
|
|
2362
|
-
navigate,
|
|
2363
|
-
buildLink,
|
|
2364
|
-
state,
|
|
2365
|
-
matchRoute,
|
|
2366
|
-
routesById,
|
|
2367
|
-
options,
|
|
2368
|
-
history,
|
|
2369
|
-
load,
|
|
2370
|
-
buildLocation,
|
|
2371
|
-
subscribe: router.subscribe,
|
|
2372
|
-
resetNextScrollRef,
|
|
2373
|
-
injectedHtmlRef,
|
|
2374
|
-
injectHtml,
|
|
2375
|
-
dehydrateData,
|
|
2376
|
-
hydrateData
|
|
2377
|
-
};
|
|
2378
|
-
return /*#__PURE__*/React__namespace.createElement(routerContext.Provider, {
|
|
2379
|
-
value: routerContextValue
|
|
2380
|
-
}, /*#__PURE__*/React__namespace.createElement(Matches, null));
|
|
2381
|
-
}
|
|
2382
|
-
function getRouteMatch(state, id) {
|
|
2383
|
-
return [...state.pendingMatches, ...state.matches].find(d => d.id === id);
|
|
2384
|
-
}
|
|
2385
|
-
function useRouterState(opts) {
|
|
2386
|
-
const {
|
|
2387
|
-
state
|
|
2388
|
-
} = useRouter();
|
|
2389
|
-
// return useStore(router.__store, opts?.select as any)
|
|
2390
|
-
return opts?.select ? opts.select(state) : state;
|
|
2391
|
-
}
|
|
2392
|
-
function useRouter() {
|
|
2393
|
-
const resolvedContext = window.__TSR_ROUTER_CONTEXT__ || routerContext;
|
|
2394
|
-
const value = React__namespace.useContext(resolvedContext);
|
|
2395
|
-
warning(value, 'useRouter must be used inside a <RouterProvider> component!');
|
|
2396
|
-
return value;
|
|
2397
|
-
}
|
|
2398
|
-
|
|
2399
|
-
function defer(_promise) {
|
|
2400
|
-
const promise = _promise;
|
|
2401
|
-
if (!promise.__deferredState) {
|
|
2402
|
-
promise.__deferredState = {
|
|
2403
|
-
uid: Math.random().toString(36).slice(2),
|
|
2404
|
-
status: 'pending'
|
|
2405
|
-
};
|
|
2406
|
-
const state = promise.__deferredState;
|
|
2407
|
-
promise.then(data => {
|
|
2408
|
-
state.status = 'success';
|
|
2409
|
-
state.data = data;
|
|
2410
|
-
}).catch(error => {
|
|
2411
|
-
state.status = 'error';
|
|
2412
|
-
state.error = error;
|
|
2413
|
-
});
|
|
2414
|
-
}
|
|
2415
|
-
return promise;
|
|
2416
|
-
}
|
|
2417
|
-
function isDehydratedDeferred(obj) {
|
|
2418
|
-
return typeof obj === 'object' && obj !== null && !(obj instanceof Promise) && !obj.then && '__deferredState' in obj;
|
|
2419
|
-
}
|
|
2420
|
-
|
|
2421
|
-
function useAwaited({
|
|
2422
|
-
promise
|
|
2423
|
-
}) {
|
|
2424
|
-
const router = useRouter();
|
|
2425
|
-
let state = promise.__deferredState;
|
|
2426
|
-
const key = `__TSR__DEFERRED__${state.uid}`;
|
|
2427
|
-
if (isDehydratedDeferred(promise)) {
|
|
2428
|
-
state = router.hydrateData(key);
|
|
2429
|
-
promise = Promise.resolve(state.data);
|
|
2430
|
-
promise.__deferredState = state;
|
|
2431
|
-
}
|
|
2432
|
-
if (state.status === 'pending') {
|
|
2433
|
-
throw promise;
|
|
2434
|
-
}
|
|
2435
|
-
if (state.status === 'error') {
|
|
2436
|
-
throw state.error;
|
|
2437
|
-
}
|
|
2438
|
-
router.dehydrateData(key, state);
|
|
2439
|
-
return [state.data];
|
|
2440
|
-
}
|
|
2441
|
-
function Await(props) {
|
|
2442
|
-
const awaited = useAwaited(props);
|
|
2443
|
-
return props.children(...awaited);
|
|
2444
|
-
}
|
|
2445
|
-
|
|
2446
|
-
class FileRoute {
|
|
2447
|
-
constructor(path) {
|
|
2448
|
-
this.path = path;
|
|
2449
|
-
}
|
|
2450
|
-
createRoute = options => {
|
|
2451
|
-
const route = new Route(options);
|
|
2452
|
-
route.isRoot = false;
|
|
2453
|
-
return route;
|
|
2454
|
-
};
|
|
2455
|
-
}
|
|
2456
|
-
|
|
2457
|
-
function lazyRouteComponent(importer, exportName) {
|
|
2458
|
-
let loadPromise;
|
|
2459
|
-
const load = () => {
|
|
2460
|
-
if (!loadPromise) {
|
|
2461
|
-
loadPromise = importer();
|
|
2462
|
-
}
|
|
2463
|
-
return loadPromise;
|
|
2464
|
-
};
|
|
2465
|
-
const lazyComp = /*#__PURE__*/React__namespace.lazy(async () => {
|
|
2466
|
-
const moduleExports = await load();
|
|
2467
|
-
const comp = moduleExports[exportName ?? 'default'];
|
|
2468
|
-
return {
|
|
2469
|
-
default: comp
|
|
2470
|
-
};
|
|
2471
|
-
});
|
|
2472
|
-
lazyComp.preload = load;
|
|
2473
|
-
return lazyComp;
|
|
2474
|
-
}
|
|
2475
|
-
|
|
2476
|
-
function _extends() {
|
|
2477
|
-
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
2478
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
2479
|
-
var source = arguments[i];
|
|
2480
|
-
for (var key in source) {
|
|
2481
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
2482
|
-
target[key] = source[key];
|
|
2442
|
+
const handleEnter = e => {
|
|
2443
|
+
const target = e.target || {};
|
|
2444
|
+
if (preload) {
|
|
2445
|
+
if (target.preloadTimeout) {
|
|
2446
|
+
return;
|
|
2483
2447
|
}
|
|
2448
|
+
target.preloadTimeout = setTimeout(() => {
|
|
2449
|
+
target.preloadTimeout = null;
|
|
2450
|
+
this.preloadRoute(nextOpts).catch(err => {
|
|
2451
|
+
console.warn(err);
|
|
2452
|
+
console.warn(preloadWarning);
|
|
2453
|
+
});
|
|
2454
|
+
}, preloadDelay);
|
|
2484
2455
|
}
|
|
2485
|
-
}
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
buildLink
|
|
2494
|
-
} = useRouter();
|
|
2495
|
-
const match = useMatch({
|
|
2496
|
-
strict: false
|
|
2497
|
-
});
|
|
2498
|
-
const {
|
|
2499
|
-
// custom props
|
|
2500
|
-
type,
|
|
2501
|
-
children,
|
|
2502
|
-
target,
|
|
2503
|
-
activeProps = () => ({
|
|
2504
|
-
className: 'active'
|
|
2505
|
-
}),
|
|
2506
|
-
inactiveProps = () => ({}),
|
|
2507
|
-
activeOptions,
|
|
2508
|
-
disabled,
|
|
2509
|
-
hash,
|
|
2510
|
-
search,
|
|
2511
|
-
params,
|
|
2512
|
-
to,
|
|
2513
|
-
state,
|
|
2514
|
-
mask,
|
|
2515
|
-
preload,
|
|
2516
|
-
preloadDelay,
|
|
2517
|
-
replace,
|
|
2518
|
-
startTransition,
|
|
2519
|
-
resetScroll,
|
|
2520
|
-
// element props
|
|
2521
|
-
style,
|
|
2522
|
-
className,
|
|
2523
|
-
onClick,
|
|
2524
|
-
onFocus,
|
|
2525
|
-
onMouseEnter,
|
|
2526
|
-
onMouseLeave,
|
|
2527
|
-
onTouchStart,
|
|
2528
|
-
...rest
|
|
2529
|
-
} = options;
|
|
2530
|
-
const linkInfo = buildLink({
|
|
2531
|
-
from: options.to ? match.pathname : undefined,
|
|
2532
|
-
...options
|
|
2533
|
-
});
|
|
2534
|
-
if (linkInfo.type === 'external') {
|
|
2535
|
-
const {
|
|
2536
|
-
href
|
|
2537
|
-
} = linkInfo;
|
|
2456
|
+
};
|
|
2457
|
+
const handleLeave = e => {
|
|
2458
|
+
const target = e.target || {};
|
|
2459
|
+
if (target.preloadTimeout) {
|
|
2460
|
+
clearTimeout(target.preloadTimeout);
|
|
2461
|
+
target.preloadTimeout = null;
|
|
2462
|
+
}
|
|
2463
|
+
};
|
|
2538
2464
|
return {
|
|
2539
|
-
|
|
2465
|
+
type: 'internal',
|
|
2466
|
+
next,
|
|
2467
|
+
handleFocus,
|
|
2468
|
+
handleClick,
|
|
2469
|
+
handleEnter,
|
|
2470
|
+
handleLeave,
|
|
2471
|
+
handleTouchStart,
|
|
2472
|
+
isActive,
|
|
2473
|
+
disabled
|
|
2540
2474
|
};
|
|
2541
|
-
}
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2475
|
+
};
|
|
2476
|
+
matchRoute = (location, opts) => {
|
|
2477
|
+
location = {
|
|
2478
|
+
...location,
|
|
2479
|
+
to: location.to ? this.resolvePathWithBase(location.from || '', location.to) : undefined
|
|
2480
|
+
};
|
|
2481
|
+
const next = this.buildLocation(location);
|
|
2482
|
+
if (opts?.pending && this.state.status !== 'pending') {
|
|
2483
|
+
return false;
|
|
2484
|
+
}
|
|
2485
|
+
const baseLocation = opts?.pending ? this.latestLocation : this.state.resolvedLocation;
|
|
2486
|
+
|
|
2487
|
+
// const baseLocation = state.resolvedLocation
|
|
2488
|
+
|
|
2489
|
+
if (!baseLocation) {
|
|
2490
|
+
return false;
|
|
2491
|
+
}
|
|
2492
|
+
const match = matchPathname(this.basepath, baseLocation.pathname, {
|
|
2493
|
+
...opts,
|
|
2494
|
+
to: next.pathname
|
|
2556
2495
|
});
|
|
2496
|
+
if (!match) {
|
|
2497
|
+
return false;
|
|
2498
|
+
}
|
|
2499
|
+
if (match && (opts?.includeSearch ?? true)) {
|
|
2500
|
+
return deepEqual(baseLocation.search, next.search, true) ? match : false;
|
|
2501
|
+
}
|
|
2502
|
+
return match;
|
|
2503
|
+
};
|
|
2504
|
+
injectHtml = async html => {
|
|
2505
|
+
this.injectedHtml.push(html);
|
|
2506
|
+
};
|
|
2507
|
+
dehydrateData = (key, getData) => {
|
|
2508
|
+
if (typeof document === 'undefined') {
|
|
2509
|
+
const strKey = typeof key === 'string' ? key : JSON.stringify(key);
|
|
2510
|
+
this.injectHtml(async () => {
|
|
2511
|
+
const id = `__TSR_DEHYDRATED__${strKey}`;
|
|
2512
|
+
const data = typeof getData === 'function' ? await getData() : getData;
|
|
2513
|
+
return `<script id='${id}' suppressHydrationWarning>window["__TSR_DEHYDRATED__${escapeJSON(strKey)}"] = ${JSON.stringify(data)}
|
|
2514
|
+
;(() => {
|
|
2515
|
+
var el = document.getElementById('${id}')
|
|
2516
|
+
el.parentElement.removeChild(el)
|
|
2517
|
+
})()
|
|
2518
|
+
</script>`;
|
|
2519
|
+
});
|
|
2520
|
+
return () => this.hydrateData(key);
|
|
2521
|
+
}
|
|
2522
|
+
return () => undefined;
|
|
2523
|
+
};
|
|
2524
|
+
hydrateData = key => {
|
|
2525
|
+
if (typeof document !== 'undefined') {
|
|
2526
|
+
const strKey = typeof key === 'string' ? key : JSON.stringify(key);
|
|
2527
|
+
return window[`__TSR_DEHYDRATED__${strKey}`];
|
|
2528
|
+
}
|
|
2529
|
+
return undefined;
|
|
2557
2530
|
};
|
|
2558
2531
|
|
|
2559
|
-
//
|
|
2560
|
-
|
|
2532
|
+
// dehydrate = (): DehydratedRouter => {
|
|
2533
|
+
// return {
|
|
2534
|
+
// state: {
|
|
2535
|
+
// dehydratedMatches: this.state.matches.map((d) =>
|
|
2536
|
+
// pick(d, ['fetchedAt', 'invalid', 'id', 'status', 'updatedAt']),
|
|
2537
|
+
// ),
|
|
2538
|
+
// },
|
|
2539
|
+
// }
|
|
2540
|
+
// }
|
|
2561
2541
|
|
|
2562
|
-
//
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2542
|
+
// hydrate = async (__do_not_use_server_ctx?: HydrationCtx) => {
|
|
2543
|
+
// let _ctx = __do_not_use_server_ctx
|
|
2544
|
+
// // Client hydrates from window
|
|
2545
|
+
// if (typeof document !== 'undefined') {
|
|
2546
|
+
// _ctx = window.__TSR_DEHYDRATED__
|
|
2547
|
+
// }
|
|
2548
|
+
|
|
2549
|
+
// invariant(
|
|
2550
|
+
// _ctx,
|
|
2551
|
+
// 'Expected to find a __TSR_DEHYDRATED__ property on window... but we did not. Did you forget to render <DehydrateRouter /> in your app?',
|
|
2552
|
+
// )
|
|
2553
|
+
|
|
2554
|
+
// const ctx = _ctx
|
|
2555
|
+
// this.dehydratedData = ctx.payload as any
|
|
2556
|
+
// this.options.hydrate?.(ctx.payload as any)
|
|
2557
|
+
// const dehydratedState = ctx.router.state
|
|
2558
|
+
|
|
2559
|
+
// let matches = this.matchRoutes(
|
|
2560
|
+
// this.state.location.pathname,
|
|
2561
|
+
// this.state.location.search,
|
|
2562
|
+
// ).map((match) => {
|
|
2563
|
+
// const dehydratedMatch = dehydratedState.dehydratedMatches.find(
|
|
2564
|
+
// (d) => d.id === match.id,
|
|
2565
|
+
// )
|
|
2566
|
+
|
|
2567
|
+
// invariant(
|
|
2568
|
+
// dehydratedMatch,
|
|
2569
|
+
// `Could not find a client-side match for dehydrated match with id: ${match.id}!`,
|
|
2570
|
+
// )
|
|
2571
|
+
|
|
2572
|
+
// if (dehydratedMatch) {
|
|
2573
|
+
// return {
|
|
2574
|
+
// ...match,
|
|
2575
|
+
// ...dehydratedMatch,
|
|
2576
|
+
// }
|
|
2577
|
+
// }
|
|
2578
|
+
// return match
|
|
2579
|
+
// })
|
|
2580
|
+
|
|
2581
|
+
// this.setState((s) => {
|
|
2582
|
+
// return {
|
|
2583
|
+
// ...s,
|
|
2584
|
+
// matches: dehydratedState.dehydratedMatches as any,
|
|
2585
|
+
// }
|
|
2586
|
+
// })
|
|
2587
|
+
// }
|
|
2588
|
+
|
|
2589
|
+
// resolveMatchPromise = (matchId: string, key: string, value: any) => {
|
|
2590
|
+
// state.matches
|
|
2591
|
+
// .find((d) => d.id === matchId)
|
|
2592
|
+
// ?.__promisesByKey[key]?.resolve(value)
|
|
2593
|
+
// }
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
// A function that takes an import() argument which is a function and returns a new function that will
|
|
2597
|
+
// proxy arguments from the caller to the imported function, retaining all type
|
|
2598
|
+
// information along the way
|
|
2599
|
+
function lazyFn(fn, key) {
|
|
2600
|
+
return async (...args) => {
|
|
2601
|
+
const imported = await fn();
|
|
2602
|
+
return imported[key || 'default'](...args);
|
|
2586
2603
|
};
|
|
2587
2604
|
}
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
ref: ref
|
|
2592
|
-
}, linkProps, {
|
|
2593
|
-
children: typeof props.children === 'function' ? props.children({
|
|
2594
|
-
isActive: linkProps['data-status'] === 'active'
|
|
2595
|
-
}) : props.children
|
|
2596
|
-
}));
|
|
2597
|
-
});
|
|
2605
|
+
function isCtrlEvent(e) {
|
|
2606
|
+
return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
|
|
2607
|
+
}
|
|
2598
2608
|
|
|
2599
2609
|
const useLayoutEffect = typeof window !== 'undefined' ? React__namespace.useLayoutEffect : React__namespace.useEffect;
|
|
2600
2610
|
const windowKey = 'window';
|
|
@@ -2604,11 +2614,7 @@
|
|
|
2604
2614
|
const sessionsStorage = typeof window !== 'undefined' && window.sessionStorage;
|
|
2605
2615
|
const defaultGetKey = location => location.state.key;
|
|
2606
2616
|
function useScrollRestoration(options) {
|
|
2607
|
-
const
|
|
2608
|
-
state,
|
|
2609
|
-
subscribe,
|
|
2610
|
-
resetNextScrollRef
|
|
2611
|
-
} = useRouter();
|
|
2617
|
+
const router = useRouter();
|
|
2612
2618
|
useLayoutEffect(() => {
|
|
2613
2619
|
const getKey = options?.getKey || defaultGetKey;
|
|
2614
2620
|
if (sessionsStorage) {
|
|
@@ -2664,7 +2670,7 @@
|
|
|
2664
2670
|
if (typeof document !== 'undefined') {
|
|
2665
2671
|
document.addEventListener('scroll', onScroll, true);
|
|
2666
2672
|
}
|
|
2667
|
-
const unsubOnBeforeLoad = subscribe('onBeforeLoad', event => {
|
|
2673
|
+
const unsubOnBeforeLoad = router.subscribe('onBeforeLoad', event => {
|
|
2668
2674
|
if (event.pathChanged) {
|
|
2669
2675
|
const restoreKey = getKey(event.fromLocation);
|
|
2670
2676
|
for (const elementSelector in cache.state.next) {
|
|
@@ -2694,12 +2700,12 @@
|
|
|
2694
2700
|
}
|
|
2695
2701
|
}
|
|
2696
2702
|
});
|
|
2697
|
-
const unsubOnResolved = subscribe('onResolved', event => {
|
|
2703
|
+
const unsubOnResolved = router.subscribe('onResolved', event => {
|
|
2698
2704
|
if (event.pathChanged) {
|
|
2699
|
-
if (!
|
|
2705
|
+
if (!router.resetNextScroll) {
|
|
2700
2706
|
return;
|
|
2701
2707
|
}
|
|
2702
|
-
|
|
2708
|
+
router.resetNextScroll = true;
|
|
2703
2709
|
const getKey = options?.getKey || defaultGetKey;
|
|
2704
2710
|
const restoreKey = getKey(event.toLocation);
|
|
2705
2711
|
let windowRestored = false;
|