react-router 8.4.0 → 8.5.0
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 +51 -1
- package/dist/development/dom-export.d.ts +2 -1
- package/dist/development/dom-export.js +1 -1
- package/dist/development/index-react-server-client.js +2 -2
- package/dist/development/index-react-server.d.ts +583 -165
- package/dist/development/index-react-server.js +27 -19
- package/dist/development/index.d.ts +9 -8
- package/dist/development/index.js +5 -4
- package/dist/development/lib/actions.js +1 -1
- package/dist/development/lib/components.js +22 -3
- package/dist/development/lib/context.d.ts +6 -1
- package/dist/development/lib/context.js +1 -1
- package/dist/development/lib/dom/dom.d.ts +3 -0
- package/dist/development/lib/dom/dom.js +1 -1
- package/dist/development/lib/dom/global.d.ts +35 -0
- package/dist/development/lib/dom/lib.d.ts +34 -9
- package/dist/development/lib/dom/lib.js +17 -6
- package/dist/development/lib/dom/server.js +2 -2
- package/dist/development/lib/dom/ssr/components.js +12 -9
- package/dist/development/lib/dom/ssr/data.js +1 -1
- package/dist/development/lib/dom/ssr/entry.d.ts +9 -2
- package/dist/development/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/development/lib/dom/ssr/fallback.js +1 -1
- package/dist/development/lib/dom/ssr/fog-of-war.d.ts +3 -2
- package/dist/development/lib/dom/ssr/fog-of-war.js +14 -11
- package/dist/development/lib/dom/ssr/hydration.js +1 -1
- package/dist/development/lib/dom/ssr/invariant.js +1 -1
- package/dist/development/lib/dom/ssr/links.js +1 -1
- package/dist/development/lib/dom/ssr/markup.js +1 -1
- package/dist/development/lib/dom/ssr/route-discovery.d.ts +120 -0
- package/dist/development/lib/dom/ssr/route-discovery.js +415 -0
- package/dist/development/lib/dom/ssr/routeModules.js +1 -1
- package/dist/development/lib/dom/ssr/routes-test-stub.js +2 -2
- package/dist/development/lib/dom/ssr/routes.d.ts +2 -2
- package/dist/development/lib/dom/ssr/routes.js +8 -8
- package/dist/development/lib/dom/ssr/server.js +3 -1
- package/dist/development/lib/dom/ssr/single-fetch.d.ts +28 -2
- package/dist/development/lib/dom/ssr/single-fetch.js +73 -55
- package/dist/development/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/development/lib/dom-export/hydrated-router.d.ts +28 -0
- package/dist/development/lib/dom-export/hydrated-router.js +32 -12
- package/dist/development/lib/errors.js +1 -1
- package/dist/development/lib/hooks.d.ts +3 -3
- package/dist/development/lib/hooks.js +4 -4
- package/dist/development/lib/href.js +1 -1
- package/dist/development/lib/router/history.js +1 -1
- package/dist/development/lib/router/instrumentation.js +1 -1
- package/dist/development/lib/router/matcher-route-pattern.js +1 -1
- package/dist/development/lib/router/matcher-route-pattern.preload.js +1 -1
- package/dist/development/lib/router/matcher.js +1 -1
- package/dist/development/lib/router/navigation.js +1 -1
- package/dist/development/lib/router/router.d.ts +6 -0
- package/dist/development/lib/router/router.js +157 -65
- package/dist/development/lib/router/url.js +1 -1
- package/dist/development/lib/router/utils.d.ts +24 -4
- package/dist/development/lib/router/utils.js +4 -3
- package/dist/development/lib/rsc/browser.js +2 -2
- package/dist/development/lib/rsc/errorBoundaries.js +1 -1
- package/dist/development/lib/rsc/html-stream/browser.js +1 -1
- package/dist/development/lib/rsc/html-stream/server.js +24 -12
- package/dist/development/lib/rsc/route-modules.js +1 -1
- package/dist/development/lib/rsc/server.rsc.d.ts +3 -2
- package/dist/development/lib/rsc/server.ssr.js +1 -1
- package/dist/development/lib/server-runtime/build.d.ts +14 -0
- package/dist/development/lib/server-runtime/cookies.js +1 -1
- package/dist/development/lib/server-runtime/crypto.js +1 -1
- package/dist/development/lib/server-runtime/data.js +1 -1
- package/dist/development/lib/server-runtime/dev.js +1 -1
- package/dist/development/lib/server-runtime/entry.js +1 -1
- package/dist/development/lib/server-runtime/errors.js +1 -1
- package/dist/development/lib/server-runtime/headers.js +1 -1
- package/dist/development/lib/server-runtime/invariant.js +1 -1
- package/dist/development/lib/server-runtime/mode.js +1 -1
- package/dist/development/lib/server-runtime/routeMatching.js +1 -1
- package/dist/development/lib/server-runtime/routes.d.ts +1 -1
- package/dist/development/lib/server-runtime/routes.js +1 -1
- package/dist/development/lib/server-runtime/server.js +12 -4
- package/dist/development/lib/server-runtime/serverHandoff.d.ts +17 -0
- package/dist/development/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/development/lib/server-runtime/sessions/cookieStorage.js +1 -1
- package/dist/development/lib/server-runtime/sessions/memoryStorage.js +1 -1
- package/dist/development/lib/server-runtime/sessions.js +1 -1
- package/dist/development/lib/server-runtime/single-fetch.js +1 -1
- package/dist/development/lib/server-runtime/urls.js +1 -1
- package/dist/development/lib/server-runtime/warnings.js +1 -1
- package/dist/development/lib/types/internal.js +1 -1
- package/dist/development/lib/types/route-data.d.ts +2 -2
- package/dist/development/lib/types/route-module-annotations.d.ts +1 -1
- package/dist/development/route-pattern.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/development/vendor/turbo-stream-v2/utils.js +1 -1
- package/dist/production/dom-export.d.ts +2 -1
- package/dist/production/dom-export.js +1 -1
- package/dist/production/index-react-server-client.js +2 -2
- package/dist/production/index-react-server.d.ts +583 -165
- package/dist/production/index-react-server.js +27 -19
- package/dist/production/index.d.ts +9 -8
- package/dist/production/index.js +5 -4
- package/dist/production/lib/actions.js +1 -1
- package/dist/production/lib/components.js +22 -3
- package/dist/production/lib/context.d.ts +6 -1
- package/dist/production/lib/context.js +1 -1
- package/dist/production/lib/dom/dom.d.ts +3 -0
- package/dist/production/lib/dom/dom.js +1 -1
- package/dist/production/lib/dom/global.d.ts +35 -0
- package/dist/production/lib/dom/lib.d.ts +34 -9
- package/dist/production/lib/dom/lib.js +17 -6
- package/dist/production/lib/dom/server.js +2 -2
- package/dist/production/lib/dom/ssr/components.js +12 -9
- package/dist/production/lib/dom/ssr/data.js +1 -1
- package/dist/production/lib/dom/ssr/entry.d.ts +9 -2
- package/dist/production/lib/dom/ssr/errorBoundaries.js +1 -1
- package/dist/production/lib/dom/ssr/fallback.js +1 -1
- package/dist/production/lib/dom/ssr/fog-of-war.d.ts +3 -2
- package/dist/production/lib/dom/ssr/fog-of-war.js +14 -11
- package/dist/production/lib/dom/ssr/hydration.js +1 -1
- package/dist/production/lib/dom/ssr/invariant.js +1 -1
- package/dist/production/lib/dom/ssr/links.js +1 -1
- package/dist/production/lib/dom/ssr/markup.js +1 -1
- package/dist/production/lib/dom/ssr/route-discovery.d.ts +120 -0
- package/dist/production/lib/dom/ssr/route-discovery.js +415 -0
- package/dist/production/lib/dom/ssr/routeModules.js +1 -1
- package/dist/production/lib/dom/ssr/routes-test-stub.js +2 -2
- package/dist/production/lib/dom/ssr/routes.d.ts +2 -2
- package/dist/production/lib/dom/ssr/routes.js +8 -8
- package/dist/production/lib/dom/ssr/server.js +3 -1
- package/dist/production/lib/dom/ssr/single-fetch.d.ts +28 -2
- package/dist/production/lib/dom/ssr/single-fetch.js +73 -55
- package/dist/production/lib/dom-export/dom-router-provider.js +1 -1
- package/dist/production/lib/dom-export/hydrated-router.d.ts +28 -0
- package/dist/production/lib/dom-export/hydrated-router.js +32 -12
- package/dist/production/lib/errors.js +1 -1
- package/dist/production/lib/hooks.d.ts +3 -3
- package/dist/production/lib/hooks.js +3 -3
- package/dist/production/lib/href.js +1 -1
- package/dist/production/lib/router/history.js +1 -1
- package/dist/production/lib/router/instrumentation.js +1 -1
- package/dist/production/lib/router/matcher-route-pattern.js +1 -1
- package/dist/production/lib/router/matcher-route-pattern.preload.js +1 -1
- package/dist/production/lib/router/matcher.js +1 -1
- package/dist/production/lib/router/navigation.js +1 -1
- package/dist/production/lib/router/router.d.ts +6 -0
- package/dist/production/lib/router/router.js +157 -65
- package/dist/production/lib/router/url.js +1 -1
- package/dist/production/lib/router/utils.d.ts +24 -4
- package/dist/production/lib/router/utils.js +4 -3
- package/dist/production/lib/rsc/browser.js +2 -2
- package/dist/production/lib/rsc/errorBoundaries.js +1 -1
- package/dist/production/lib/rsc/html-stream/browser.js +1 -1
- package/dist/production/lib/rsc/html-stream/server.js +24 -12
- package/dist/production/lib/rsc/route-modules.js +1 -1
- package/dist/production/lib/rsc/server.rsc.d.ts +3 -2
- package/dist/production/lib/rsc/server.ssr.js +1 -1
- package/dist/production/lib/server-runtime/build.d.ts +14 -0
- package/dist/production/lib/server-runtime/cookies.js +1 -1
- package/dist/production/lib/server-runtime/crypto.js +1 -1
- package/dist/production/lib/server-runtime/data.js +1 -1
- package/dist/production/lib/server-runtime/dev.js +1 -1
- package/dist/production/lib/server-runtime/entry.js +1 -1
- package/dist/production/lib/server-runtime/errors.js +1 -1
- package/dist/production/lib/server-runtime/headers.js +1 -1
- package/dist/production/lib/server-runtime/invariant.js +1 -1
- package/dist/production/lib/server-runtime/mode.js +1 -1
- package/dist/production/lib/server-runtime/routeMatching.js +1 -1
- package/dist/production/lib/server-runtime/routes.d.ts +1 -1
- package/dist/production/lib/server-runtime/routes.js +1 -1
- package/dist/production/lib/server-runtime/server.js +12 -4
- package/dist/production/lib/server-runtime/serverHandoff.d.ts +17 -0
- package/dist/production/lib/server-runtime/serverHandoff.js +1 -1
- package/dist/production/lib/server-runtime/sessions/cookieStorage.js +1 -1
- package/dist/production/lib/server-runtime/sessions/memoryStorage.js +1 -1
- package/dist/production/lib/server-runtime/sessions.js +1 -1
- package/dist/production/lib/server-runtime/single-fetch.js +1 -1
- package/dist/production/lib/server-runtime/urls.js +1 -1
- package/dist/production/lib/server-runtime/warnings.js +1 -1
- package/dist/production/lib/types/internal.js +1 -1
- package/dist/production/lib/types/route-data.d.ts +2 -2
- package/dist/production/lib/types/route-module-annotations.d.ts +1 -1
- package/dist/production/route-pattern.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/flatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/turbo-stream.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/unflatten.js +1 -1
- package/dist/production/vendor/turbo-stream-v2/utils.js +1 -1
- package/docs/explanation/lazy-route-discovery.md +4 -0
- package/docs/explanation/sessions-and-cookies.md +108 -4
- package/docs/how-to/custom-fetch.md +218 -0
- package/docs/how-to/data-strategy.md +23 -1
- package/docs/how-to/middleware.md +1 -0
- package/docs/how-to/optimize-revalidation.md +2 -2
- package/docs/how-to/pre-rendering.md +23 -1
- package/docs/how-to/route-discovery.md +145 -0
- package/docs/how-to/spa.md +2 -0
- package/docs/how-to/view-transitions.md +80 -13
- package/docs/start/framework/navigating.md +5 -9
- package/docs/start/framework/rendering.md +37 -0
- package/package.json +9 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.5.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { PROTOCOL_RELATIVE_URL_REGEX, normalizeProtocolRelativeUrl } from "./url.js";
|
|
12
12
|
import { createBrowserURLImpl, createLocation, createPath, invariant, parsePath, warning } from "./history.js";
|
|
13
|
-
import { ErrorResponseImpl, RouterContextProvider, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, createDataFunctionUrl, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, prependBasename, removeDoubleSlashes, resolveTo, stripBasename } from "./utils.js";
|
|
13
|
+
import { DiscoveryCancelledError, ErrorResponseImpl, RouterContextProvider, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, createDataFunctionUrl, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, prependBasename, removeDoubleSlashes, resolveTo, stripBasename } from "./utils.js";
|
|
14
14
|
import { consumeInstrumentationClientResultMetaReceiver, getRouteInstrumentationUpdates, instrumentClientSideRouter } from "./instrumentation.js";
|
|
15
15
|
import { V6RegExMatcher } from "./matcher.js";
|
|
16
16
|
import { getRoutePatternMatcher } from "./matcher-route-pattern.preload.js";
|
|
@@ -114,6 +114,7 @@ var DataRoutes = class {
|
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
};
|
|
117
|
+
const clientErrors = /* @__PURE__ */ new WeakMap();
|
|
117
118
|
/**
|
|
118
119
|
* Create a router and listen to history POP navigations
|
|
119
120
|
*/
|
|
@@ -142,7 +143,6 @@ function createRouter(init) {
|
|
|
142
143
|
let dataStrategyImpl = init.dataStrategy || defaultDataStrategyWithMiddleware;
|
|
143
144
|
let unlistenHistory = null;
|
|
144
145
|
let subscribers = /* @__PURE__ */ new Set();
|
|
145
|
-
let bufferedInitialStateUpdate = null;
|
|
146
146
|
let savedScrollPositions = null;
|
|
147
147
|
let getScrollRestorationKey = null;
|
|
148
148
|
let getScrollPosition = null;
|
|
@@ -213,6 +213,8 @@ function createRouter(init) {
|
|
|
213
213
|
blockers: /* @__PURE__ */ new Map()
|
|
214
214
|
};
|
|
215
215
|
let pendingAction = "POP";
|
|
216
|
+
let pendingPopstateDelta = 0;
|
|
217
|
+
let pendingDiscoveryCancellation;
|
|
216
218
|
let pendingPopstateNavigationDfd = null;
|
|
217
219
|
let pendingPreventScrollReset = false;
|
|
218
220
|
let pendingNavigationController;
|
|
@@ -273,6 +275,7 @@ function createRouter(init) {
|
|
|
273
275
|
pendingPopstateNavigationDfd = null;
|
|
274
276
|
return;
|
|
275
277
|
}
|
|
278
|
+
if (future.unstable_customRouteDiscovery) pendingPopstateDelta += delta || 0;
|
|
276
279
|
return startNavigation(historyAction, location);
|
|
277
280
|
});
|
|
278
281
|
if (isBrowser) {
|
|
@@ -294,19 +297,16 @@ function createRouter(init) {
|
|
|
294
297
|
}
|
|
295
298
|
function subscribe(fn) {
|
|
296
299
|
subscribers.add(fn);
|
|
297
|
-
if (bufferedInitialStateUpdate) {
|
|
298
|
-
let { newErrors } = bufferedInitialStateUpdate;
|
|
299
|
-
bufferedInitialStateUpdate = null;
|
|
300
|
-
fn(state, {
|
|
301
|
-
deletedFetchers: [],
|
|
302
|
-
newErrors,
|
|
303
|
-
viewTransitionOpts: void 0,
|
|
304
|
-
flushSync: false
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
300
|
return () => subscribers.delete(fn);
|
|
308
301
|
}
|
|
309
302
|
function updateState(newState, opts = {}) {
|
|
303
|
+
let newErrors = newState.errors ?? null;
|
|
304
|
+
let cachedErrors = newErrors ? clientErrors.get(newErrors) : void 0;
|
|
305
|
+
if (cachedErrors !== void 0) newErrors = cachedErrors;
|
|
306
|
+
if (newState.errors !== void 0 || newState.initialized) {
|
|
307
|
+
if (state.errors) clientErrors.delete(state.errors);
|
|
308
|
+
if (newState.errors) clientErrors.set(newState.errors, newErrors);
|
|
309
|
+
}
|
|
310
310
|
if (newState.matches) newState.matches = newState.matches.map((m) => {
|
|
311
311
|
let route = manifest[m.route.id];
|
|
312
312
|
let matchRoute = m.route;
|
|
@@ -329,10 +329,9 @@ function createRouter(init) {
|
|
|
329
329
|
fetchersQueuedForDeletion.forEach((key) => {
|
|
330
330
|
if (!state.fetchers.has(key) && !fetchControllers.has(key)) unmountedFetchers.push(key);
|
|
331
331
|
});
|
|
332
|
-
if (subscribers.size === 0) bufferedInitialStateUpdate = { newErrors: newState.errors ?? null };
|
|
333
332
|
[...subscribers].forEach((subscriber) => subscriber(state, {
|
|
334
333
|
deletedFetchers: unmountedFetchers,
|
|
335
|
-
newErrors
|
|
334
|
+
newErrors,
|
|
336
335
|
viewTransitionOpts: opts.viewTransitionOpts,
|
|
337
336
|
flushSync: opts.flushSync === true
|
|
338
337
|
}));
|
|
@@ -397,17 +396,22 @@ function createRouter(init) {
|
|
|
397
396
|
viewTransitionOpts,
|
|
398
397
|
flushSync: flushSync === true
|
|
399
398
|
});
|
|
399
|
+
resetPendingNavigation();
|
|
400
|
+
pendingPopstateNavigationDfd?.resolve();
|
|
401
|
+
pendingPopstateNavigationDfd = null;
|
|
402
|
+
pendingRevalidationDfd?.resolve();
|
|
403
|
+
pendingRevalidationDfd = null;
|
|
404
|
+
}
|
|
405
|
+
function resetPendingNavigation() {
|
|
406
|
+
pendingPopstateDelta = 0;
|
|
400
407
|
pendingAction = "POP";
|
|
401
408
|
pendingPreventScrollReset = false;
|
|
402
409
|
pendingViewTransitionEnabled = false;
|
|
403
410
|
isUninterruptedRevalidation = false;
|
|
404
411
|
isRevalidationRequired = false;
|
|
405
|
-
pendingPopstateNavigationDfd?.resolve();
|
|
406
|
-
pendingPopstateNavigationDfd = null;
|
|
407
|
-
pendingRevalidationDfd?.resolve();
|
|
408
|
-
pendingRevalidationDfd = null;
|
|
409
412
|
}
|
|
410
413
|
async function navigate(to, opts) {
|
|
414
|
+
if (pendingDiscoveryCancellation) await pendingDiscoveryCancellation;
|
|
411
415
|
pendingPopstateNavigationDfd?.resolve();
|
|
412
416
|
pendingPopstateNavigationDfd = null;
|
|
413
417
|
if (typeof to === "number") {
|
|
@@ -484,22 +488,28 @@ function createRouter(init) {
|
|
|
484
488
|
});
|
|
485
489
|
}
|
|
486
490
|
function revalidate() {
|
|
491
|
+
if (pendingDiscoveryCancellation) return pendingDiscoveryCancellation.then(revalidate);
|
|
487
492
|
if (!pendingRevalidationDfd) pendingRevalidationDfd = createDeferred();
|
|
488
493
|
interruptActiveLoads();
|
|
489
494
|
updateState({ revalidation: "loading" });
|
|
490
495
|
let promise = pendingRevalidationDfd.promise;
|
|
491
496
|
if (state.navigation.state === "submitting") return promise;
|
|
492
497
|
if (state.navigation.state === "idle") {
|
|
493
|
-
startNavigation(state.historyAction, state.location, {
|
|
498
|
+
startNavigation(state.historyAction, state.location, {
|
|
499
|
+
startUninterruptedRevalidation: true,
|
|
500
|
+
dataStrategyInitiator: "revalidation"
|
|
501
|
+
});
|
|
494
502
|
return promise;
|
|
495
503
|
}
|
|
496
504
|
startNavigation(pendingAction || state.historyAction, state.navigation.location, {
|
|
497
505
|
overrideNavigation: state.navigation,
|
|
506
|
+
dataStrategyInitiator: "revalidation",
|
|
498
507
|
enableViewTransition: pendingViewTransitionEnabled === true
|
|
499
508
|
});
|
|
500
509
|
return promise;
|
|
501
510
|
}
|
|
502
511
|
async function startNavigation(historyAction, location, opts) {
|
|
512
|
+
if (pendingDiscoveryCancellation) await pendingDiscoveryCancellation;
|
|
503
513
|
pendingNavigationController && pendingNavigationController.abort();
|
|
504
514
|
pendingNavigationController = null;
|
|
505
515
|
pendingAction = historyAction;
|
|
@@ -535,6 +545,7 @@ function createRouter(init) {
|
|
|
535
545
|
} : void 0;
|
|
536
546
|
pendingNavigationController = new AbortController();
|
|
537
547
|
let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission);
|
|
548
|
+
let dataStrategyInitiator = opts?.initialHydration ? "initialization" : opts?.dataStrategyInitiator ?? "navigation";
|
|
538
549
|
let scopedContext = init.getContext ? await init.getContext() : new RouterContextProvider();
|
|
539
550
|
let pendingActionResult;
|
|
540
551
|
if (opts && opts.pendingError) pendingActionResult = [findNearestBoundary(matches).route.id, {
|
|
@@ -542,7 +553,7 @@ function createRouter(init) {
|
|
|
542
553
|
error: opts.pendingError
|
|
543
554
|
}];
|
|
544
555
|
else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) {
|
|
545
|
-
let actionResult = await handleAction(request, location, opts.submission, matches, historyAction, scopedContext, fogOfWar.active, opts && opts.initialHydration === true, {
|
|
556
|
+
let actionResult = await handleAction(request, dataStrategyInitiator, location, opts.submission, matches, historyAction, scopedContext, fogOfWar.active, opts && opts.initialHydration === true, {
|
|
546
557
|
replace: opts.replace,
|
|
547
558
|
flushSync
|
|
548
559
|
});
|
|
@@ -566,7 +577,7 @@ function createRouter(init) {
|
|
|
566
577
|
fogOfWar.active = false;
|
|
567
578
|
request = createClientSideRequest(init.history, request.url, request.signal);
|
|
568
579
|
}
|
|
569
|
-
let { shortCircuited, matches: updatedMatches, loaderData, errors, workingFetchers } = await handleLoaders(request, location, matches, historyAction, scopedContext, fogOfWar.active, loadingNavigation, opts && opts.submission, opts && opts.fetcherSubmission, opts && opts.replace, opts && opts.initialHydration === true, flushSync, pendingActionResult, opts && opts.callSiteDefaultShouldRevalidate);
|
|
580
|
+
let { shortCircuited, matches: updatedMatches, loaderData, errors, workingFetchers } = await handleLoaders(request, dataStrategyInitiator, location, matches, historyAction, scopedContext, fogOfWar.active, loadingNavigation, opts && opts.submission, opts && opts.fetcherSubmission, opts && opts.replace, opts && opts.initialHydration === true, flushSync, pendingActionResult, opts && opts.callSiteDefaultShouldRevalidate);
|
|
570
581
|
if (shortCircuited) return;
|
|
571
582
|
pendingNavigationController = null;
|
|
572
583
|
completeNavigation(location, {
|
|
@@ -577,13 +588,57 @@ function createRouter(init) {
|
|
|
577
588
|
...workingFetchers ? { fetchers: workingFetchers } : {}
|
|
578
589
|
});
|
|
579
590
|
}
|
|
580
|
-
|
|
581
|
-
|
|
591
|
+
function cancelDiscoveryNavigation() {
|
|
592
|
+
let cancellation = createDeferred();
|
|
593
|
+
pendingDiscoveryCancellation = cancellation.promise;
|
|
594
|
+
let delta = pendingPopstateDelta;
|
|
595
|
+
let popstateNavigationDfd = pendingPopstateNavigationDfd;
|
|
596
|
+
pendingPopstateNavigationDfd = null;
|
|
597
|
+
pendingNavigationController?.abort();
|
|
598
|
+
pendingNavigationController = null;
|
|
599
|
+
resetPendingNavigation();
|
|
600
|
+
pendingRevalidationDfd?.resolve();
|
|
601
|
+
pendingRevalidationDfd = null;
|
|
602
|
+
let blockers = new Map(state.blockers);
|
|
603
|
+
blockers.forEach((blocker, key) => {
|
|
604
|
+
if (blocker.state === "proceeding") blockers.set(key, IDLE_BLOCKER);
|
|
605
|
+
});
|
|
606
|
+
let fetchers = new Map(state.fetchers);
|
|
607
|
+
let didUpdateFetchers = markFetchRedirectsDone(fetchers);
|
|
608
|
+
fetchers.forEach((fetcher, key) => {
|
|
609
|
+
if (fetcher.state === "loading" && !fetchControllers.has(key)) {
|
|
610
|
+
fetchers.set(key, getDoneFetcher(fetcher.data));
|
|
611
|
+
didUpdateFetchers = true;
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
cancelledFetcherLoads.clear();
|
|
615
|
+
updateState({
|
|
616
|
+
navigation: IDLE_NAVIGATION,
|
|
617
|
+
revalidation: "idle",
|
|
618
|
+
blockers,
|
|
619
|
+
...didUpdateFetchers ? { fetchers } : {}
|
|
620
|
+
});
|
|
621
|
+
function finishCancellation() {
|
|
622
|
+
pendingDiscoveryCancellation = void 0;
|
|
623
|
+
popstateNavigationDfd?.resolve();
|
|
624
|
+
cancellation.resolve();
|
|
625
|
+
}
|
|
626
|
+
if (delta) {
|
|
627
|
+
unblockBlockerHistoryUpdate = finishCancellation;
|
|
628
|
+
init.history.go(-delta);
|
|
629
|
+
} else finishCancellation();
|
|
630
|
+
return cancellation.promise;
|
|
631
|
+
}
|
|
632
|
+
async function handleAction(request, dataStrategyInitiator, location, submission, matches, historyAction, scopedContext, isFogOfWar, initialHydration, opts = {}) {
|
|
633
|
+
if (!future.unstable_customRouteDiscovery) interruptActiveLoads();
|
|
582
634
|
updateState({ navigation: getSubmittingNavigation(location, matches, historyAction, submission) }, { flushSync: opts.flushSync === true });
|
|
583
635
|
if (isFogOfWar) {
|
|
584
636
|
let discoverResult = await discoverRoutes(matches, location.pathname, request.signal);
|
|
585
|
-
if (discoverResult.type === "aborted") return { shortCircuited: true };
|
|
586
|
-
else if (discoverResult.type === "
|
|
637
|
+
if (future.unstable_customRouteDiscovery && request.signal.aborted || discoverResult.type === "aborted") return { shortCircuited: true };
|
|
638
|
+
else if (discoverResult.type === "cancelled") {
|
|
639
|
+
await cancelDiscoveryNavigation();
|
|
640
|
+
return { shortCircuited: true };
|
|
641
|
+
} else if (discoverResult.type === "error") {
|
|
587
642
|
if (discoverResult.partialMatches.length === 0) {
|
|
588
643
|
let { matches, route } = getShortCircuitMatches(dataRoutes.activeRoutes);
|
|
589
644
|
return {
|
|
@@ -613,6 +668,7 @@ function createRouter(init) {
|
|
|
613
668
|
};
|
|
614
669
|
} else matches = discoverResult.matches;
|
|
615
670
|
}
|
|
671
|
+
if (future.unstable_customRouteDiscovery) interruptActiveLoads();
|
|
616
672
|
let result;
|
|
617
673
|
let actionMatch = getTargetMatch(matches, location);
|
|
618
674
|
if (!actionMatch.route.action && !actionMatch.route.lazy) result = {
|
|
@@ -624,7 +680,7 @@ function createRouter(init) {
|
|
|
624
680
|
})
|
|
625
681
|
};
|
|
626
682
|
else {
|
|
627
|
-
let results = await callDataStrategy(request, location, getTargetedDataStrategyMatches(mapRouteProperties, manifest, request, location, matches, actionMatch, initialHydration ? [] : hydrationRouteProperties, scopedContext), scopedContext, null);
|
|
683
|
+
let results = await callDataStrategy(request, location, getTargetedDataStrategyMatches(mapRouteProperties, manifest, request, location, matches, actionMatch, initialHydration ? [] : hydrationRouteProperties, scopedContext), scopedContext, null, dataStrategyInitiator, historyAction);
|
|
628
684
|
result = results[actionMatch.route.id];
|
|
629
685
|
if (!result) {
|
|
630
686
|
for (let match of matches) if (results[match.route.id]) {
|
|
@@ -638,7 +694,7 @@ function createRouter(init) {
|
|
|
638
694
|
let replace;
|
|
639
695
|
if (opts && opts.replace != null) replace = opts.replace;
|
|
640
696
|
else replace = normalizeRedirectLocation(result.response.headers.get("Location"), new URL(request.url), basename, init.history) === state.location.pathname + state.location.search;
|
|
641
|
-
await startRedirectNavigation(request, result, true, {
|
|
697
|
+
await startRedirectNavigation(request, result, true, dataStrategyInitiator, {
|
|
642
698
|
submission,
|
|
643
699
|
replace
|
|
644
700
|
});
|
|
@@ -661,7 +717,7 @@ function createRouter(init) {
|
|
|
661
717
|
pendingActionResult: [actionMatch.route.id, result]
|
|
662
718
|
};
|
|
663
719
|
}
|
|
664
|
-
async function handleLoaders(request, location, matches, historyAction, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace, initialHydration, flushSync, pendingActionResult, callSiteDefaultShouldRevalidate) {
|
|
720
|
+
async function handleLoaders(request, dataStrategyInitiator, location, matches, historyAction, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace, initialHydration, flushSync, pendingActionResult, callSiteDefaultShouldRevalidate) {
|
|
665
721
|
let loadingNavigation = overrideNavigation || getLoadingNavigation(location, matches, historyAction, submission);
|
|
666
722
|
let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);
|
|
667
723
|
let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration;
|
|
@@ -674,8 +730,11 @@ function createRouter(init) {
|
|
|
674
730
|
}, { flushSync });
|
|
675
731
|
}
|
|
676
732
|
let discoverResult = await discoverRoutes(matches, location.pathname, request.signal);
|
|
677
|
-
if (discoverResult.type === "aborted") return { shortCircuited: true };
|
|
678
|
-
else if (discoverResult.type === "
|
|
733
|
+
if (future.unstable_customRouteDiscovery && request.signal.aborted || discoverResult.type === "aborted") return { shortCircuited: true };
|
|
734
|
+
else if (discoverResult.type === "cancelled") {
|
|
735
|
+
await cancelDiscoveryNavigation();
|
|
736
|
+
return { shortCircuited: true };
|
|
737
|
+
} else if (discoverResult.type === "error") {
|
|
679
738
|
if (discoverResult.partialMatches.length === 0) {
|
|
680
739
|
let { matches, route } = getShortCircuitMatches(dataRoutes.activeRoutes);
|
|
681
740
|
return {
|
|
@@ -697,7 +756,10 @@ function createRouter(init) {
|
|
|
697
756
|
loaderData: {},
|
|
698
757
|
errors: { [route.id]: error }
|
|
699
758
|
};
|
|
700
|
-
} else
|
|
759
|
+
} else {
|
|
760
|
+
matches = discoverResult.matches;
|
|
761
|
+
if (initialHydration && !request.signal.aborted) updateState({ matches });
|
|
762
|
+
}
|
|
701
763
|
}
|
|
702
764
|
let { dsMatches, revalidatingFetchers } = getMatchesToLoad(request, scopedContext, mapRouteProperties, manifest, init.history, state, matches, activeSubmission, location, initialHydration ? [] : hydrationRouteProperties, initialHydration === true, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, dataRouteMatcher, pendingActionResult, callSiteDefaultShouldRevalidate);
|
|
703
765
|
pendingNavigationLoadId = ++incrementingLoadId;
|
|
@@ -729,27 +791,31 @@ function createRouter(init) {
|
|
|
729
791
|
});
|
|
730
792
|
let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((f) => abortFetcher(f.key));
|
|
731
793
|
if (pendingNavigationController) pendingNavigationController.signal.addEventListener("abort", abortPendingFetchRevalidations);
|
|
732
|
-
let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(dsMatches, revalidatingFetchers, request, location, scopedContext);
|
|
794
|
+
let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(dsMatches, revalidatingFetchers, request, location, scopedContext, dataStrategyInitiator, historyAction);
|
|
733
795
|
if (request.signal.aborted) return { shortCircuited: true };
|
|
734
796
|
if (pendingNavigationController) pendingNavigationController.signal.removeEventListener("abort", abortPendingFetchRevalidations);
|
|
735
797
|
revalidatingFetchers.forEach((rf) => fetchControllers.delete(rf.key));
|
|
736
798
|
let redirect = findRedirect(loaderResults);
|
|
737
799
|
if (redirect) {
|
|
738
|
-
await startRedirectNavigation(request, redirect.result, true, { replace });
|
|
800
|
+
await startRedirectNavigation(request, redirect.result, true, dataStrategyInitiator, { replace });
|
|
739
801
|
return { shortCircuited: true };
|
|
740
802
|
}
|
|
741
803
|
redirect = findRedirect(fetcherResults);
|
|
742
804
|
if (redirect) {
|
|
743
805
|
fetchRedirectIds.add(redirect.key);
|
|
744
|
-
await startRedirectNavigation(request, redirect.result, true, { replace });
|
|
806
|
+
await startRedirectNavigation(request, redirect.result, true, dataStrategyInitiator, { replace });
|
|
745
807
|
return { shortCircuited: true };
|
|
746
808
|
}
|
|
747
809
|
let workingFetchers = new Map(state.fetchers);
|
|
748
810
|
let { loaderData, errors } = processLoaderData(state, matches, loaderResults, pendingActionResult, revalidatingFetchers, fetcherResults, workingFetchers);
|
|
749
|
-
if (initialHydration && state.errors)
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
811
|
+
if (initialHydration && state.errors) {
|
|
812
|
+
let newClientErrors = errors ?? null;
|
|
813
|
+
errors = {
|
|
814
|
+
...state.errors,
|
|
815
|
+
...errors
|
|
816
|
+
};
|
|
817
|
+
clientErrors.set(errors, newClientErrors);
|
|
818
|
+
}
|
|
753
819
|
let didUpdateFetcherRedirects = markFetchRedirectsDone(workingFetchers);
|
|
754
820
|
let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId, workingFetchers);
|
|
755
821
|
let shouldUpdateFetchers = didUpdateFetcherRedirects || didAbortFetchLoads || revalidatingFetchers.length > 0;
|
|
@@ -775,6 +841,7 @@ function createRouter(init) {
|
|
|
775
841
|
return workingFetchers;
|
|
776
842
|
}
|
|
777
843
|
async function fetch(key, routeId, href, opts) {
|
|
844
|
+
if (pendingDiscoveryCancellation) await pendingDiscoveryCancellation;
|
|
778
845
|
abortFetcher(key);
|
|
779
846
|
let flushSync = (opts && opts.flushSync) === true;
|
|
780
847
|
let instrumentationResultMetaReceiver = consumeInstrumentationClientResultMetaReceiver(router);
|
|
@@ -807,15 +874,22 @@ function createRouter(init) {
|
|
|
807
874
|
await handleFetcherLoader(key, loadMatch, matches, scopedContext, flushSync, preventScrollReset, submission);
|
|
808
875
|
}
|
|
809
876
|
async function handleFetcherAction(key, routeId, path, requestMatches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission, callSiteDefaultShouldRevalidate) {
|
|
810
|
-
interruptActiveLoads();
|
|
877
|
+
if (!future.unstable_customRouteDiscovery) interruptActiveLoads();
|
|
811
878
|
fetchLoadMatches.delete(key);
|
|
812
|
-
|
|
879
|
+
let existingFetcher = state.fetchers.get(key);
|
|
880
|
+
updateFetcherState(key, getSubmittingFetcher(submission, existingFetcher), { flushSync });
|
|
813
881
|
let abortController = new AbortController();
|
|
882
|
+
if (future.unstable_customRouteDiscovery) fetchControllers.set(key, abortController);
|
|
814
883
|
let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission);
|
|
815
884
|
if (isFogOfWar) {
|
|
816
885
|
let discoverResult = await discoverRoutes(requestMatches, new URL(fetchRequest.url).pathname, fetchRequest.signal, key);
|
|
817
|
-
if (discoverResult.type === "aborted") return;
|
|
818
|
-
else if (discoverResult.type === "
|
|
886
|
+
if (future.unstable_customRouteDiscovery && fetchRequest.signal.aborted || discoverResult.type === "aborted") return;
|
|
887
|
+
else if (discoverResult.type === "cancelled") {
|
|
888
|
+
fetchControllers.delete(key);
|
|
889
|
+
fetchLoadMatches.delete(key);
|
|
890
|
+
updateFetcherState(key, getDoneFetcher(existingFetcher?.data), { flushSync });
|
|
891
|
+
return;
|
|
892
|
+
} else if (discoverResult.type === "error") {
|
|
819
893
|
setFetcherError(key, routeId, discoverResult.error, { flushSync });
|
|
820
894
|
return;
|
|
821
895
|
} else if (!discoverResult.matches) {
|
|
@@ -832,10 +906,11 @@ function createRouter(init) {
|
|
|
832
906
|
}), { flushSync });
|
|
833
907
|
return;
|
|
834
908
|
}
|
|
909
|
+
if (future.unstable_customRouteDiscovery) interruptActiveLoads();
|
|
835
910
|
fetchControllers.set(key, abortController);
|
|
836
911
|
let originatingLoadId = incrementingLoadId;
|
|
837
912
|
let fetchMatches = getTargetedDataStrategyMatches(mapRouteProperties, manifest, fetchRequest, path, requestMatches, match, hydrationRouteProperties, scopedContext);
|
|
838
|
-
let actionResults = await callDataStrategy(fetchRequest, path, fetchMatches, scopedContext, key);
|
|
913
|
+
let actionResults = await callDataStrategy(fetchRequest, path, fetchMatches, scopedContext, key, "fetcher");
|
|
839
914
|
let actionResult = actionResults[match.route.id];
|
|
840
915
|
if (!actionResult) {
|
|
841
916
|
for (let match of fetchMatches) if (actionResults[match.route.id]) {
|
|
@@ -861,7 +936,7 @@ function createRouter(init) {
|
|
|
861
936
|
} else {
|
|
862
937
|
fetchRedirectIds.add(key);
|
|
863
938
|
updateFetcherState(key, getLoadingFetcher(submission));
|
|
864
|
-
return startRedirectNavigation(fetchRequest, actionResult, false, {
|
|
939
|
+
return startRedirectNavigation(fetchRequest, actionResult, false, "fetcher", {
|
|
865
940
|
fetcherSubmission: submission,
|
|
866
941
|
preventScrollReset
|
|
867
942
|
});
|
|
@@ -893,7 +968,7 @@ function createRouter(init) {
|
|
|
893
968
|
updateState({ fetchers: workingFetchers });
|
|
894
969
|
let abortPendingFetchRevalidations = () => revalidatingFetchers.forEach((rf) => abortFetcher(rf.key));
|
|
895
970
|
abortController.signal.addEventListener("abort", abortPendingFetchRevalidations);
|
|
896
|
-
let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(dsMatches, revalidatingFetchers, revalidationRequest, nextLocation, scopedContext);
|
|
971
|
+
let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(dsMatches, revalidatingFetchers, revalidationRequest, nextLocation, scopedContext, "fetcher");
|
|
897
972
|
if (abortController.signal.aborted) {
|
|
898
973
|
if (fetchReloadIds.get(key) === loadId) fetchReloadIds.delete(key);
|
|
899
974
|
return;
|
|
@@ -915,13 +990,13 @@ function createRouter(init) {
|
|
|
915
990
|
let redirect = findRedirect(loaderResults);
|
|
916
991
|
if (redirect) {
|
|
917
992
|
state = getRedirectStateWithDoneFetcher(state);
|
|
918
|
-
return startRedirectNavigation(revalidationRequest, redirect.result, false, { preventScrollReset });
|
|
993
|
+
return startRedirectNavigation(revalidationRequest, redirect.result, false, "fetcher", { preventScrollReset });
|
|
919
994
|
}
|
|
920
995
|
redirect = findRedirect(fetcherResults);
|
|
921
996
|
if (redirect) {
|
|
922
997
|
fetchRedirectIds.add(redirect.key);
|
|
923
998
|
state = getRedirectStateWithDoneFetcher(state);
|
|
924
|
-
return startRedirectNavigation(revalidationRequest, redirect.result, false, { preventScrollReset });
|
|
999
|
+
return startRedirectNavigation(revalidationRequest, redirect.result, false, "fetcher", { preventScrollReset });
|
|
925
1000
|
}
|
|
926
1001
|
let finalFetchers = new Map(state.fetchers);
|
|
927
1002
|
if (fetcherIsMounted) finalFetchers.set(key, getDoneFetcher(actionResult.data));
|
|
@@ -950,11 +1025,17 @@ function createRouter(init) {
|
|
|
950
1025
|
let existingFetcher = state.fetchers.get(key);
|
|
951
1026
|
updateFetcherState(key, getLoadingFetcher(submission, existingFetcher ? existingFetcher.data : void 0), { flushSync });
|
|
952
1027
|
let abortController = new AbortController();
|
|
1028
|
+
if (future.unstable_customRouteDiscovery) fetchControllers.set(key, abortController);
|
|
953
1029
|
let fetchRequest = createClientSideRequest(init.history, path, abortController.signal);
|
|
954
1030
|
if (loadMatch.isDiscovering) {
|
|
955
1031
|
let discoverResult = await discoverRoutes(matches, new URL(fetchRequest.url).pathname, fetchRequest.signal, key);
|
|
956
|
-
if (discoverResult.type === "aborted") return;
|
|
957
|
-
else if (discoverResult.type === "
|
|
1032
|
+
if (future.unstable_customRouteDiscovery && fetchRequest.signal.aborted || discoverResult.type === "aborted") return;
|
|
1033
|
+
else if (discoverResult.type === "cancelled") {
|
|
1034
|
+
fetchControllers.delete(key);
|
|
1035
|
+
fetchLoadMatches.delete(key);
|
|
1036
|
+
updateFetcherState(key, getDoneFetcher(existingFetcher?.data), { flushSync });
|
|
1037
|
+
return;
|
|
1038
|
+
} else if (discoverResult.type === "error") {
|
|
958
1039
|
setFetcherError(key, routeId, discoverResult.error, { flushSync });
|
|
959
1040
|
return;
|
|
960
1041
|
} else if (!discoverResult.matches) {
|
|
@@ -968,7 +1049,7 @@ function createRouter(init) {
|
|
|
968
1049
|
let match = getTargetMatch(matches, path);
|
|
969
1050
|
fetchControllers.set(key, abortController);
|
|
970
1051
|
let originatingLoadId = incrementingLoadId;
|
|
971
|
-
let results = await callDataStrategy(fetchRequest, path, getTargetedDataStrategyMatches(mapRouteProperties, manifest, fetchRequest, path, matches, match, hydrationRouteProperties, scopedContext), scopedContext, key);
|
|
1052
|
+
let results = await callDataStrategy(fetchRequest, path, getTargetedDataStrategyMatches(mapRouteProperties, manifest, fetchRequest, path, matches, match, hydrationRouteProperties, scopedContext), scopedContext, key, "fetcher");
|
|
972
1053
|
let result = results[match.route.id];
|
|
973
1054
|
if (!result) {
|
|
974
1055
|
for (let match of matches) if (results[match.route.id]) {
|
|
@@ -987,7 +1068,7 @@ function createRouter(init) {
|
|
|
987
1068
|
return;
|
|
988
1069
|
} else {
|
|
989
1070
|
fetchRedirectIds.add(key);
|
|
990
|
-
await startRedirectNavigation(fetchRequest, result, false, { preventScrollReset });
|
|
1071
|
+
await startRedirectNavigation(fetchRequest, result, false, "fetcher", { preventScrollReset });
|
|
991
1072
|
return;
|
|
992
1073
|
}
|
|
993
1074
|
if (isErrorResult(result)) {
|
|
@@ -1015,7 +1096,7 @@ function createRouter(init) {
|
|
|
1015
1096
|
* actually touch history until we've processed redirects, so we just use
|
|
1016
1097
|
* the history action from the original navigation (PUSH or REPLACE).
|
|
1017
1098
|
*/
|
|
1018
|
-
async function startRedirectNavigation(request, redirect, isNavigation, { submission, fetcherSubmission, preventScrollReset, replace } = {}) {
|
|
1099
|
+
async function startRedirectNavigation(request, redirect, isNavigation, dataStrategyInitiator, { submission, fetcherSubmission, preventScrollReset, replace } = {}) {
|
|
1019
1100
|
if (!isNavigation) {
|
|
1020
1101
|
pendingPopstateNavigationDfd?.resolve();
|
|
1021
1102
|
pendingPopstateNavigationDfd = null;
|
|
@@ -1052,20 +1133,22 @@ function createRouter(init) {
|
|
|
1052
1133
|
formAction: location
|
|
1053
1134
|
},
|
|
1054
1135
|
preventScrollReset: preventScrollReset || pendingPreventScrollReset,
|
|
1055
|
-
enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0
|
|
1136
|
+
enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0,
|
|
1137
|
+
dataStrategyInitiator
|
|
1056
1138
|
});
|
|
1057
1139
|
else await startNavigation(redirectNavigationType, redirectLocation, {
|
|
1058
1140
|
overrideNavigation: getLoadingNavigation(redirectLocation, [], redirectNavigationType, submission),
|
|
1059
1141
|
fetcherSubmission,
|
|
1060
1142
|
preventScrollReset: preventScrollReset || pendingPreventScrollReset,
|
|
1061
|
-
enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0
|
|
1143
|
+
enableViewTransition: isNavigation ? pendingViewTransitionEnabled : void 0,
|
|
1144
|
+
dataStrategyInitiator
|
|
1062
1145
|
});
|
|
1063
1146
|
}
|
|
1064
|
-
async function callDataStrategy(request, path, matches, scopedContext, fetcherKey) {
|
|
1147
|
+
async function callDataStrategy(request, path, matches, scopedContext, fetcherKey, initiator, navigationType = null) {
|
|
1065
1148
|
let results;
|
|
1066
1149
|
let dataResults = {};
|
|
1067
1150
|
try {
|
|
1068
|
-
results = await callDataStrategyImpl(dataStrategyImpl, request, path, matches, fetcherKey, scopedContext, false);
|
|
1151
|
+
results = await callDataStrategyImpl(dataStrategyImpl, request, path, matches, fetcherKey, initiator, scopedContext, false, navigationType);
|
|
1069
1152
|
} catch (e) {
|
|
1070
1153
|
matches.filter((m) => m.shouldLoad).forEach((m) => {
|
|
1071
1154
|
dataResults[m.route.id] = {
|
|
@@ -1092,11 +1175,11 @@ function createRouter(init) {
|
|
|
1092
1175
|
} else dataResults[routeId] = await convertDataStrategyResultToDataResult(result);
|
|
1093
1176
|
return dataResults;
|
|
1094
1177
|
}
|
|
1095
|
-
async function callLoadersAndMaybeResolveData(matches, fetchersToLoad, request, location, scopedContext) {
|
|
1096
|
-
let loaderResultsPromise = callDataStrategy(request, location, matches, scopedContext, null);
|
|
1178
|
+
async function callLoadersAndMaybeResolveData(matches, fetchersToLoad, request, location, scopedContext, initiator, navigationType = null) {
|
|
1179
|
+
let loaderResultsPromise = callDataStrategy(request, location, matches, scopedContext, null, initiator, navigationType);
|
|
1097
1180
|
let fetcherResultsPromise = Promise.all(fetchersToLoad.map(async (f) => {
|
|
1098
1181
|
if (f.matches && f.match && f.request && f.controller) {
|
|
1099
|
-
let result = (await callDataStrategy(f.request, f.path, f.matches, scopedContext, f.key))[f.match.route.id];
|
|
1182
|
+
let result = (await callDataStrategy(f.request, f.path, f.matches, scopedContext, f.key, initiator, navigationType))[f.match.route.id];
|
|
1100
1183
|
return { [f.key]: result };
|
|
1101
1184
|
} else return Promise.resolve({ [f.key]: {
|
|
1102
1185
|
type: "error",
|
|
@@ -1110,7 +1193,8 @@ function createRouter(init) {
|
|
|
1110
1193
|
}
|
|
1111
1194
|
function interruptActiveLoads() {
|
|
1112
1195
|
isRevalidationRequired = true;
|
|
1113
|
-
fetchLoadMatches.forEach((
|
|
1196
|
+
fetchLoadMatches.forEach((loadMatch, key) => {
|
|
1197
|
+
if (future.unstable_customRouteDiscovery && loadMatch.isDiscovering) return;
|
|
1114
1198
|
if (fetchControllers.has(key)) cancelledFetcherLoads.add(key);
|
|
1115
1199
|
abortFetcher(key);
|
|
1116
1200
|
});
|
|
@@ -1136,6 +1220,8 @@ function createRouter(init) {
|
|
|
1136
1220
|
}
|
|
1137
1221
|
function resetFetcher(key, opts) {
|
|
1138
1222
|
abortFetcher(key, opts?.reason);
|
|
1223
|
+
fetchLoadMatches.delete(key);
|
|
1224
|
+
cancelledFetcherLoads.delete(key);
|
|
1139
1225
|
updateFetcherState(key, getDoneFetcher(null));
|
|
1140
1226
|
}
|
|
1141
1227
|
function deleteFetcher(fetchers, key) {
|
|
@@ -1308,6 +1394,10 @@ function createRouter(init) {
|
|
|
1308
1394
|
}
|
|
1309
1395
|
});
|
|
1310
1396
|
} catch (e) {
|
|
1397
|
+
if (future.unstable_customRouteDiscovery) {
|
|
1398
|
+
if (signal.aborted) return { type: "aborted" };
|
|
1399
|
+
if (e instanceof DiscoveryCancelledError) return { type: "cancelled" };
|
|
1400
|
+
}
|
|
1311
1401
|
return {
|
|
1312
1402
|
type: "error",
|
|
1313
1403
|
error: e,
|
|
@@ -1768,7 +1858,7 @@ function createStaticHandler(routes, opts) {
|
|
|
1768
1858
|
};
|
|
1769
1859
|
}
|
|
1770
1860
|
async function callDataStrategy(request, location, matches, isRouteRequest, requestContext, dataStrategy) {
|
|
1771
|
-
let results = await callDataStrategyImpl(dataStrategy || defaultDataStrategy, request, location, matches, null, requestContext, true);
|
|
1861
|
+
let results = await callDataStrategyImpl(dataStrategy || defaultDataStrategy, request, location, matches, null, "static", requestContext, true);
|
|
1772
1862
|
let dataResults = {};
|
|
1773
1863
|
await Promise.all(matches.map(async (match) => {
|
|
1774
1864
|
if (!(match.route.id in results)) return;
|
|
@@ -2409,7 +2499,7 @@ function getTargetedDataStrategyMatches(mapRouteProperties, manifest, request, p
|
|
|
2409
2499
|
return getDataStrategyMatch(mapRouteProperties, manifest, request, path, getRoutePattern(matches), match, lazyRoutePropertiesToSkip, scopedContext, true, shouldRevalidateArgs);
|
|
2410
2500
|
});
|
|
2411
2501
|
}
|
|
2412
|
-
async function callDataStrategyImpl(dataStrategyImpl, request, path, matches, fetcherKey, scopedContext, isStaticHandler) {
|
|
2502
|
+
async function callDataStrategyImpl(dataStrategyImpl, request, path, matches, fetcherKey, initiator, scopedContext, isStaticHandler, navigationType = null) {
|
|
2413
2503
|
if (matches.some((m) => m._lazyPromises?.middleware)) await Promise.all(matches.map((m) => m._lazyPromises?.middleware));
|
|
2414
2504
|
let dataStrategyArgs = {
|
|
2415
2505
|
request,
|
|
@@ -2417,7 +2507,9 @@ async function callDataStrategyImpl(dataStrategyImpl, request, path, matches, fe
|
|
|
2417
2507
|
pattern: getRoutePattern(matches),
|
|
2418
2508
|
params: matches[0].params,
|
|
2419
2509
|
context: scopedContext,
|
|
2420
|
-
matches
|
|
2510
|
+
matches,
|
|
2511
|
+
unstable_initiator: initiator,
|
|
2512
|
+
unstable_navigationType: initiator === "navigation" ? navigationType : null
|
|
2421
2513
|
};
|
|
2422
2514
|
let runClientMiddleware = isStaticHandler ? () => {
|
|
2423
2515
|
throw new Error("You cannot call `runClientMiddleware()` from a static handler `dataStrategy`. Middleware is run outside of `dataStrategy` during SSR in order to bubble up the Response. You can enable middleware via the `respond` API in `query`/`queryRoute`");
|
|
@@ -3014,4 +3106,4 @@ function createDeferred() {
|
|
|
3014
3106
|
};
|
|
3015
3107
|
}
|
|
3016
3108
|
//#endregion
|
|
3017
|
-
export { IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, createDataRouteMatcher, createRouter, createStaticHandler, getStaticContextFromError, hasInvalidProtocol, isDataWithResponseInit, isMutationMethod, isRedirectResponse, isRedirectStatusCode, isResponse };
|
|
3109
|
+
export { IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, clientErrors, createDataRouteMatcher, createRouter, createStaticHandler, getStaticContextFromError, hasInvalidProtocol, isDataWithResponseInit, isMutationMethod, isRedirectResponse, isRedirectStatusCode, isResponse };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { Location, Path, To } from "./history.js";
|
|
2
|
+
import { Action, Location, Path, To } from "./history.js";
|
|
3
3
|
import * as React$1 from "react";
|
|
4
4
|
|
|
5
5
|
//#region lib/router/utils.d.ts
|
|
@@ -389,6 +389,11 @@ interface DataStrategyMatch extends RouteMatch<string, DataRouteObject> {
|
|
|
389
389
|
*/
|
|
390
390
|
resolve: (handlerOverride?: (handler: (ctx?: unknown) => DataFunctionReturnValue) => DataFunctionReturnValue) => Promise<DataStrategyResult>;
|
|
391
391
|
}
|
|
392
|
+
/**
|
|
393
|
+
* The operation that initiated a data strategy execution. Static handler
|
|
394
|
+
* executions use `"static"`.
|
|
395
|
+
*/
|
|
396
|
+
type DataStrategyInitiator = "initialization" | "navigation" | "fetcher" | "revalidation" | "static";
|
|
392
397
|
interface DataStrategyFunctionArgs<Context = DefaultContext> extends DataFunctionArgs<Context> {
|
|
393
398
|
/**
|
|
394
399
|
* Matches for this route extended with Data strategy APIs
|
|
@@ -396,8 +401,23 @@ interface DataStrategyFunctionArgs<Context = DefaultContext> extends DataFunctio
|
|
|
396
401
|
matches: DataStrategyMatch[];
|
|
397
402
|
runClientMiddleware: (cb: DataStrategyFunction<Context>) => Promise<Record<string, DataStrategyResult>>;
|
|
398
403
|
/**
|
|
399
|
-
* The
|
|
400
|
-
*
|
|
404
|
+
* The operation that initiated this data strategy execution
|
|
405
|
+
*
|
|
406
|
+
* This field is experimental and subject to breaking changes.
|
|
407
|
+
*/
|
|
408
|
+
unstable_initiator: DataStrategyInitiator;
|
|
409
|
+
/**
|
|
410
|
+
* The history action (`"PUSH"`, `"REPLACE"`, or `"POP"`) for a navigation-
|
|
411
|
+
* initiated execution, including fetchers reloaded by that navigation.
|
|
412
|
+
* `null` for initialization, fetcher, revalidation, and static executions.
|
|
413
|
+
*
|
|
414
|
+
* This field is experimental and subject to breaking changes.
|
|
415
|
+
*/
|
|
416
|
+
unstable_navigationType: Action | null;
|
|
417
|
+
/**
|
|
418
|
+
* The key of the fetcher targeted by this data strategy execution, otherwise
|
|
419
|
+
* `null`. Fetchers reloaded during a navigation or revalidation retain that
|
|
420
|
+
* `unstable_initiator` while providing their key here.
|
|
401
421
|
*/
|
|
402
422
|
fetcherKey: string | null;
|
|
403
423
|
}
|
|
@@ -962,4 +982,4 @@ declare class ErrorResponseImpl implements ErrorResponse {
|
|
|
962
982
|
*/
|
|
963
983
|
declare function isRouteErrorResponse(error: any): error is ErrorResponse;
|
|
964
984
|
//#endregion
|
|
965
|
-
export { ActionFunction, ActionFunctionArgs, BaseRouteObject, DataRouteMatch, DataRouteObject, DataStrategyFunction, DataStrategyFunctionArgs, DataStrategyMatch, DataStrategyResult, DataWithResponseInit, ErrorResponse, ErrorResponseImpl, FormEncType, FormMethod, HTMLFormMethod, IndexRouteObject, LazyRouteFunction, LoaderFunction, LoaderFunctionArgs, MapRoutePropertiesFunction, MaybePromise, MiddlewareFunction, MiddlewareNextFunction, NonIndexRouteObject, ParamParseKey, Params, PatchRoutesOnNavigationFunction, PatchRoutesOnNavigationFunctionArgs, PathMatch, PathParam, PathPattern, RedirectFunction, RouteBranch, RouteData, RouteManifest, RouteMatch, RouteObject, RouterContext, RouterContextProvider, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, Submission, TrackedPromise, UIMatch, createContext, data, defaultMapRouteProperties, generatePath, isRouteErrorResponse, matchPath, matchRoutes, redirect, redirectDocument, replace, resolvePath };
|
|
985
|
+
export { ActionFunction, ActionFunctionArgs, BaseRouteObject, DataRouteMatch, DataRouteObject, DataStrategyFunction, DataStrategyFunctionArgs, DataStrategyInitiator, DataStrategyMatch, DataStrategyResult, DataWithResponseInit, ErrorResponse, ErrorResponseImpl, FormEncType, FormMethod, HTMLFormMethod, IndexRouteObject, LazyRouteFunction, LoaderFunction, LoaderFunctionArgs, MapRoutePropertiesFunction, MaybePromise, MiddlewareFunction, MiddlewareNextFunction, NonIndexRouteObject, ParamParseKey, Params, PatchRoutesOnNavigationFunction, PatchRoutesOnNavigationFunctionArgs, PathMatch, PathParam, PathPattern, RedirectFunction, RouteBranch, RouteData, RouteManifest, RouteMatch, RouteObject, RouterContext, RouterContextProvider, ShouldRevalidateFunction, ShouldRevalidateFunctionArgs, Submission, TrackedPromise, UIMatch, createContext, data, defaultMapRouteProperties, generatePath, isRouteErrorResponse, matchPath, matchRoutes, redirect, redirectDocument, replace, resolvePath };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* react-router v8.
|
|
2
|
+
* react-router v8.5.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -129,6 +129,7 @@ var RouterContextProvider = class {
|
|
|
129
129
|
this.#map.set(context, value);
|
|
130
130
|
}
|
|
131
131
|
};
|
|
132
|
+
var DiscoveryCancelledError = class extends Error {};
|
|
132
133
|
const unsupportedLazyRouteObjectKeys = new Set([
|
|
133
134
|
"lazy",
|
|
134
135
|
"caseSensitive",
|
|
@@ -514,7 +515,7 @@ function compilePath(path, caseSensitive = false, end = true) {
|
|
|
514
515
|
return "(?:/([^\\/]*))?";
|
|
515
516
|
}
|
|
516
517
|
return "/([^\\/]+)";
|
|
517
|
-
}).replace(/\/([\
|
|
518
|
+
}).replace(/\/((?:[^/?()[\]*^\\]|\\.)+)\?(?=\/|$|\()/g, "(?:/$1)?");
|
|
518
519
|
if (path.endsWith("*")) {
|
|
519
520
|
params.push({ paramName: "*" });
|
|
520
521
|
regexpSource += path === "*" || path === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$";
|
|
@@ -875,4 +876,4 @@ function parseToInfo(_to, basename) {
|
|
|
875
876
|
};
|
|
876
877
|
}
|
|
877
878
|
//#endregion
|
|
878
|
-
export { ErrorResponseImpl, RouterContextProvider, SUPPORTED_ERROR_TYPES, compilePath, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, createContext, createDataFunctionUrl, data, decodePath, defaultMapRouteProperties, encodePathParam, explodeOptionalSegments, flattenAndRankRoutes, generatePath, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isBrowser, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, joinPaths, matchPath, matchRoutes, matchRoutesImpl, normalizePathname, parseToInfo, prependBasename, redirect, redirectDocument, removeDoubleSlashes, removeTrailingSlash, replace, resolvePath, resolveTo, stripBasename };
|
|
879
|
+
export { DiscoveryCancelledError, ErrorResponseImpl, RouterContextProvider, SUPPORTED_ERROR_TYPES, compilePath, convertRouteMatchToUiMatch, convertRoutesToDataRoutes, createContext, createDataFunctionUrl, data, decodePath, defaultMapRouteProperties, encodePathParam, explodeOptionalSegments, flattenAndRankRoutes, generatePath, getPathContributingMatches, getResolveToMatches, getRoutePattern, isAbsoluteUrl, isBrowser, isRouteErrorResponse, isUnsupportedLazyRouteFunctionKey, isUnsupportedLazyRouteObjectKey, joinPaths, matchPath, matchRoutes, matchRoutesImpl, normalizePathname, parseToInfo, prependBasename, redirect, redirectDocument, removeDoubleSlashes, removeTrailingSlash, replace, resolvePath, resolveTo, stripBasename };
|