@remix-run/router 1.19.0 → 1.19.1
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/CHANGELOG.md +10 -0
- package/dist/index.d.ts +1 -1
- package/dist/router.cjs.js +45 -54
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.d.ts +2 -2
- package/dist/router.js +44 -53
- package/dist/router.js.map +1 -1
- package/dist/router.umd.js +45 -54
- package/dist/router.umd.js.map +1 -1
- package/dist/router.umd.min.js +2 -2
- package/dist/router.umd.min.js.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/index.ts +1 -1
- package/package.json +1 -1
- package/router.ts +50 -57
- package/utils.ts +1 -1
package/dist/router.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { History, Location, Path, To } from "./history";
|
|
2
2
|
import { Action as HistoryAction } from "./history";
|
|
3
|
-
import type { AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticRouteObject, DataStrategyFunction, DeferredData, DetectErrorBoundaryFunction, FormEncType, HTMLFormMethod, MapRoutePropertiesFunction, RouteData, Submission, UIMatch,
|
|
3
|
+
import type { AgnosticDataRouteMatch, AgnosticDataRouteObject, AgnosticRouteObject, DataStrategyFunction, DeferredData, DetectErrorBoundaryFunction, FormEncType, HTMLFormMethod, MapRoutePropertiesFunction, RouteData, Submission, UIMatch, AgnosticPatchRoutesOnNavigationFunction, DataWithResponseInit } from "./utils";
|
|
4
4
|
/**
|
|
5
5
|
* A Router instance manages all navigation and data loading/mutations
|
|
6
6
|
*/
|
|
@@ -285,7 +285,7 @@ export interface RouterInit {
|
|
|
285
285
|
future?: Partial<FutureConfig>;
|
|
286
286
|
hydrationData?: HydrationState;
|
|
287
287
|
window?: Window;
|
|
288
|
-
|
|
288
|
+
unstable_patchRoutesOnNavigation?: AgnosticPatchRoutesOnNavigationFunction;
|
|
289
289
|
unstable_dataStrategy?: DataStrategyFunction;
|
|
290
290
|
}
|
|
291
291
|
/**
|
package/dist/router.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @remix-run/router v1.19.
|
|
2
|
+
* @remix-run/router v1.19.1
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -1363,7 +1363,7 @@ function createRouter(init) {
|
|
|
1363
1363
|
let inFlightDataRoutes;
|
|
1364
1364
|
let basename = init.basename || "/";
|
|
1365
1365
|
let dataStrategyImpl = init.unstable_dataStrategy || defaultDataStrategy;
|
|
1366
|
-
let
|
|
1366
|
+
let patchRoutesOnNavigationImpl = init.unstable_patchRoutesOnNavigation;
|
|
1367
1367
|
// Config driven behavior flags
|
|
1368
1368
|
let future = _extends({
|
|
1369
1369
|
v7_fetcherPersist: false,
|
|
@@ -1377,6 +1377,10 @@ function createRouter(init) {
|
|
|
1377
1377
|
let unlistenHistory = null;
|
|
1378
1378
|
// Externally-provided functions to call on all state changes
|
|
1379
1379
|
let subscribers = new Set();
|
|
1380
|
+
// FIFO queue of previously discovered routes to prevent re-calling on
|
|
1381
|
+
// subsequent navigations to the same path
|
|
1382
|
+
let discoveredRoutesMaxSize = 1000;
|
|
1383
|
+
let discoveredRoutes = new Set();
|
|
1380
1384
|
// Externally-provided object to hold scroll restoration locations during routing
|
|
1381
1385
|
let savedScrollPositions = null;
|
|
1382
1386
|
// Externally-provided function to get scroll restoration keys
|
|
@@ -1392,7 +1396,7 @@ function createRouter(init) {
|
|
|
1392
1396
|
let initialScrollRestored = init.hydrationData != null;
|
|
1393
1397
|
let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);
|
|
1394
1398
|
let initialErrors = null;
|
|
1395
|
-
if (initialMatches == null && !
|
|
1399
|
+
if (initialMatches == null && !patchRoutesOnNavigationImpl) {
|
|
1396
1400
|
// If we do not match a user-provided-route, fall back to the root
|
|
1397
1401
|
// to allow the error boundary to take over
|
|
1398
1402
|
let error = getInternalRouterError(404, {
|
|
@@ -1407,7 +1411,7 @@ function createRouter(init) {
|
|
|
1407
1411
|
[route.id]: error
|
|
1408
1412
|
};
|
|
1409
1413
|
}
|
|
1410
|
-
// In SPA apps, if the user provided a
|
|
1414
|
+
// In SPA apps, if the user provided a patchRoutesOnNavigation implementation and
|
|
1411
1415
|
// our initial match is a splat route, clear them out so we run through lazy
|
|
1412
1416
|
// discovery on hydration in case there's a more accurate lazy route match.
|
|
1413
1417
|
// In SSR apps (with `hydrationData`), we expect that the server will send
|
|
@@ -1424,7 +1428,7 @@ function createRouter(init) {
|
|
|
1424
1428
|
initialized = false;
|
|
1425
1429
|
initialMatches = [];
|
|
1426
1430
|
// If partial hydration and fog of war is enabled, we will be running
|
|
1427
|
-
// `
|
|
1431
|
+
// `patchRoutesOnNavigation` during hydration so include any partial matches as
|
|
1428
1432
|
// the initial matches so we can properly render `HydrateFallback`'s
|
|
1429
1433
|
if (future.v7_partialHydration) {
|
|
1430
1434
|
let fogOfWar = checkFogOfWar(null, dataRoutes, init.history.location.pathname);
|
|
@@ -1541,7 +1545,7 @@ function createRouter(init) {
|
|
|
1541
1545
|
// Store blocker functions in a separate Map outside of router state since
|
|
1542
1546
|
// we don't need to update UI state if they change
|
|
1543
1547
|
let blockerFunctions = new Map();
|
|
1544
|
-
// Map of pending
|
|
1548
|
+
// Map of pending patchRoutesOnNavigation() promises (keyed by path/matches) so
|
|
1545
1549
|
// that we only kick them off once for a given combo
|
|
1546
1550
|
let pendingPatchRoutes = new Map();
|
|
1547
1551
|
// Flag to ignore the next history update, so we can revert the URL change on
|
|
@@ -3082,7 +3086,16 @@ function createRouter(init) {
|
|
|
3082
3086
|
return null;
|
|
3083
3087
|
}
|
|
3084
3088
|
function checkFogOfWar(matches, routesToUse, pathname) {
|
|
3085
|
-
if (
|
|
3089
|
+
if (patchRoutesOnNavigationImpl) {
|
|
3090
|
+
// Don't bother re-calling patchRouteOnMiss for a path we've already
|
|
3091
|
+
// processed. the last execution would have patched the route tree
|
|
3092
|
+
// accordingly so `matches` here are already accurate.
|
|
3093
|
+
if (discoveredRoutes.has(pathname)) {
|
|
3094
|
+
return {
|
|
3095
|
+
active: false,
|
|
3096
|
+
matches
|
|
3097
|
+
};
|
|
3098
|
+
}
|
|
3086
3099
|
if (!matches) {
|
|
3087
3100
|
let fogMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
|
|
3088
3101
|
return {
|
|
@@ -3090,11 +3103,10 @@ function createRouter(init) {
|
|
|
3090
3103
|
matches: fogMatches || []
|
|
3091
3104
|
};
|
|
3092
3105
|
} else {
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
//
|
|
3096
|
-
//
|
|
3097
|
-
// around and find out
|
|
3106
|
+
if (Object.keys(matches[0].params).length > 0) {
|
|
3107
|
+
// If we matched a dynamic param or a splat, it might only be because
|
|
3108
|
+
// we haven't yet discovered other routes that would match with a
|
|
3109
|
+
// higher score. Call patchRoutesOnNavigation just to be sure
|
|
3098
3110
|
let partialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
|
|
3099
3111
|
return {
|
|
3100
3112
|
active: true,
|
|
@@ -3110,12 +3122,11 @@ function createRouter(init) {
|
|
|
3110
3122
|
}
|
|
3111
3123
|
async function discoverRoutes(matches, pathname, signal) {
|
|
3112
3124
|
let partialMatches = matches;
|
|
3113
|
-
let route = partialMatches.length > 0 ? partialMatches[partialMatches.length - 1].route : null;
|
|
3114
3125
|
while (true) {
|
|
3115
3126
|
let isNonHMR = inFlightDataRoutes == null;
|
|
3116
3127
|
let routesToUse = inFlightDataRoutes || dataRoutes;
|
|
3117
3128
|
try {
|
|
3118
|
-
await loadLazyRouteChildren(
|
|
3129
|
+
await loadLazyRouteChildren(patchRoutesOnNavigationImpl, pathname, partialMatches, routesToUse, manifest, mapRouteProperties, pendingPatchRoutes, signal);
|
|
3119
3130
|
} catch (e) {
|
|
3120
3131
|
return {
|
|
3121
3132
|
type: "error",
|
|
@@ -3139,51 +3150,31 @@ function createRouter(init) {
|
|
|
3139
3150
|
};
|
|
3140
3151
|
}
|
|
3141
3152
|
let newMatches = matchRoutes(routesToUse, pathname, basename);
|
|
3142
|
-
let matchedSplat = false;
|
|
3143
3153
|
if (newMatches) {
|
|
3144
|
-
|
|
3145
|
-
if (leafRoute.index) {
|
|
3146
|
-
// If we found an index route, we can stop
|
|
3147
|
-
return {
|
|
3148
|
-
type: "success",
|
|
3149
|
-
matches: newMatches
|
|
3150
|
-
};
|
|
3151
|
-
}
|
|
3152
|
-
if (leafRoute.path && leafRoute.path.length > 0) {
|
|
3153
|
-
if (leafRoute.path === "*") {
|
|
3154
|
-
// If we found a splat route, we can't be sure there's not a
|
|
3155
|
-
// higher-scoring route down some partial matches trail so we need
|
|
3156
|
-
// to check that out
|
|
3157
|
-
matchedSplat = true;
|
|
3158
|
-
} else {
|
|
3159
|
-
// If we found a non-splat route, we can stop
|
|
3160
|
-
return {
|
|
3161
|
-
type: "success",
|
|
3162
|
-
matches: newMatches
|
|
3163
|
-
};
|
|
3164
|
-
}
|
|
3165
|
-
}
|
|
3166
|
-
}
|
|
3167
|
-
let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
|
|
3168
|
-
// If we are no longer partially matching anything, this was either a
|
|
3169
|
-
// legit splat match above, or it's a 404. Also avoid loops if the
|
|
3170
|
-
// second pass results in the same partial matches
|
|
3171
|
-
if (!newPartialMatches || partialMatches.map(m => m.route.id).join("-") === newPartialMatches.map(m => m.route.id).join("-")) {
|
|
3154
|
+
addToFifoQueue(pathname, discoveredRoutes);
|
|
3172
3155
|
return {
|
|
3173
3156
|
type: "success",
|
|
3174
|
-
matches:
|
|
3157
|
+
matches: newMatches
|
|
3175
3158
|
};
|
|
3176
3159
|
}
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
if (route.
|
|
3180
|
-
|
|
3160
|
+
let newPartialMatches = matchRoutesImpl(routesToUse, pathname, basename, true);
|
|
3161
|
+
// Avoid loops if the second pass results in the same partial matches
|
|
3162
|
+
if (!newPartialMatches || partialMatches.length === newPartialMatches.length && partialMatches.every((m, i) => m.route.id === newPartialMatches[i].route.id)) {
|
|
3163
|
+
addToFifoQueue(pathname, discoveredRoutes);
|
|
3181
3164
|
return {
|
|
3182
3165
|
type: "success",
|
|
3183
|
-
matches:
|
|
3166
|
+
matches: null
|
|
3184
3167
|
};
|
|
3185
3168
|
}
|
|
3169
|
+
partialMatches = newPartialMatches;
|
|
3170
|
+
}
|
|
3171
|
+
}
|
|
3172
|
+
function addToFifoQueue(path, queue) {
|
|
3173
|
+
if (queue.size >= discoveredRoutesMaxSize) {
|
|
3174
|
+
let first = queue.values().next().value;
|
|
3175
|
+
queue.delete(first);
|
|
3186
3176
|
}
|
|
3177
|
+
queue.add(path);
|
|
3187
3178
|
}
|
|
3188
3179
|
function _internalSetRoutes(newRoutes) {
|
|
3189
3180
|
manifest = {};
|
|
@@ -4012,15 +4003,15 @@ function shouldRevalidateLoader(loaderMatch, arg) {
|
|
|
4012
4003
|
return arg.defaultShouldRevalidate;
|
|
4013
4004
|
}
|
|
4014
4005
|
/**
|
|
4015
|
-
* Idempotent utility to execute
|
|
4006
|
+
* Idempotent utility to execute patchRoutesOnNavigation() to lazily load route
|
|
4016
4007
|
* definitions and update the routes/routeManifest
|
|
4017
4008
|
*/
|
|
4018
|
-
async function loadLazyRouteChildren(
|
|
4009
|
+
async function loadLazyRouteChildren(patchRoutesOnNavigationImpl, path, matches, routes, manifest, mapRouteProperties, pendingRouteChildren, signal) {
|
|
4019
4010
|
let key = [path, ...matches.map(m => m.route.id)].join("-");
|
|
4020
4011
|
try {
|
|
4021
4012
|
let pending = pendingRouteChildren.get(key);
|
|
4022
4013
|
if (!pending) {
|
|
4023
|
-
pending =
|
|
4014
|
+
pending = patchRoutesOnNavigationImpl({
|
|
4024
4015
|
path,
|
|
4025
4016
|
matches,
|
|
4026
4017
|
patch: (routeId, children) => {
|
|
@@ -4607,7 +4598,7 @@ function getInternalRouterError(status, _temp5) {
|
|
|
4607
4598
|
if (status === 400) {
|
|
4608
4599
|
statusText = "Bad Request";
|
|
4609
4600
|
if (type === "route-discovery") {
|
|
4610
|
-
errorMessage = "Unable to match URL \"" + pathname + "\" - the `
|
|
4601
|
+
errorMessage = "Unable to match URL \"" + pathname + "\" - the `unstable_patchRoutesOnNavigation()` " + ("function threw the following error:\n" + message);
|
|
4611
4602
|
} else if (method && pathname && routeId) {
|
|
4612
4603
|
errorMessage = "You made a " + method + " request to \"" + pathname + "\" but " + ("did not provide a `loader` for route \"" + routeId + "\", ") + "so there is no way to handle the request.";
|
|
4613
4604
|
} else if (type === "defer-action") {
|