react-router 7.2.0 → 7.3.0-pre.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +259 -0
  2. package/dist/development/{chunk-HA7DTUK3.mjs → chunk-W5LWFPOT.mjs} +851 -336
  3. package/dist/development/dom-export.d.mts +13 -3
  4. package/dist/development/dom-export.d.ts +13 -3
  5. package/dist/development/dom-export.js +371 -79
  6. package/dist/development/dom-export.mjs +14 -5
  7. package/dist/development/{fog-of-war-Cm1iXIp7.d.ts → fog-of-war-CvttGpNz.d.ts} +93 -9
  8. package/dist/{production/fog-of-war-Cm1iXIp7.d.ts → development/fog-of-war-Da8gpnoZ.d.mts} +93 -9
  9. package/dist/{production/data-CQbyyGzl.d.mts → development/future-ldDp5FKH.d.mts} +11 -1
  10. package/dist/development/{data-CQbyyGzl.d.mts → future-ldDp5FKH.d.ts} +11 -1
  11. package/dist/development/index.d.mts +16 -14
  12. package/dist/development/index.d.ts +16 -14
  13. package/dist/development/index.js +853 -336
  14. package/dist/development/index.mjs +6 -2
  15. package/dist/development/lib/types/route-module.d.mts +24 -6
  16. package/dist/development/lib/types/route-module.d.ts +24 -6
  17. package/dist/development/lib/types/route-module.js +1 -1
  18. package/dist/development/lib/types/route-module.mjs +1 -1
  19. package/dist/{production/route-data-BmvbmBej.d.mts → development/route-data-H2S3hwhf.d.mts} +66 -13
  20. package/dist/development/{route-data-BmvbmBej.d.mts → route-data-H2S3hwhf.d.ts} +66 -13
  21. package/dist/production/{chunk-Z4EF7MSU.mjs → chunk-ZITGHOQF.mjs} +851 -336
  22. package/dist/production/dom-export.d.mts +13 -3
  23. package/dist/production/dom-export.d.ts +13 -3
  24. package/dist/production/dom-export.js +371 -79
  25. package/dist/production/dom-export.mjs +14 -5
  26. package/dist/production/{fog-of-war-BALYJxf_.d.mts → fog-of-war-CvttGpNz.d.ts} +93 -9
  27. package/dist/{development/fog-of-war-BALYJxf_.d.mts → production/fog-of-war-Da8gpnoZ.d.mts} +93 -9
  28. package/dist/{development/data-CQbyyGzl.d.ts → production/future-ldDp5FKH.d.mts} +11 -1
  29. package/dist/production/{data-CQbyyGzl.d.ts → future-ldDp5FKH.d.ts} +11 -1
  30. package/dist/production/index.d.mts +16 -14
  31. package/dist/production/index.d.ts +16 -14
  32. package/dist/production/index.js +853 -336
  33. package/dist/production/index.mjs +6 -2
  34. package/dist/production/lib/types/route-module.d.mts +24 -6
  35. package/dist/production/lib/types/route-module.d.ts +24 -6
  36. package/dist/production/lib/types/route-module.js +1 -1
  37. package/dist/production/lib/types/route-module.mjs +1 -1
  38. package/dist/{development/route-data-BmvbmBej.d.ts → production/route-data-H2S3hwhf.d.mts} +66 -13
  39. package/dist/production/{route-data-BmvbmBej.d.ts → route-data-H2S3hwhf.d.ts} +66 -13
  40. package/package.json +3 -2
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v7.2.0
2
+ * react-router v7.3.0-pre.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -8,6 +8,12 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
+ var __typeError = (msg) => {
12
+ throw TypeError(msg);
13
+ };
14
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
15
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
16
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
11
17
 
12
18
  // lib/router/history.ts
13
19
  var Action = /* @__PURE__ */ ((Action2) => {
@@ -350,6 +356,33 @@ function getUrlBasedHistory(getLocation, createHref2, validateLocation, options
350
356
  }
351
357
 
352
358
  // lib/router/utils.ts
359
+ function unstable_createContext(defaultValue) {
360
+ return { defaultValue };
361
+ }
362
+ var _map;
363
+ var unstable_RouterContextProvider = class {
364
+ constructor(init) {
365
+ __privateAdd(this, _map, /* @__PURE__ */ new Map());
366
+ if (init) {
367
+ for (let [context, value] of init) {
368
+ this.set(context, value);
369
+ }
370
+ }
371
+ }
372
+ get(context) {
373
+ if (__privateGet(this, _map).has(context)) {
374
+ return __privateGet(this, _map).get(context);
375
+ }
376
+ if (context.defaultValue !== void 0) {
377
+ return context.defaultValue;
378
+ }
379
+ throw new Error("No value found for context");
380
+ }
381
+ set(context, value) {
382
+ __privateGet(this, _map).set(context, value);
383
+ }
384
+ };
385
+ _map = new WeakMap();
353
386
  var immutableRouteKeys = /* @__PURE__ */ new Set([
354
387
  "lazy",
355
388
  "caseSensitive",
@@ -907,9 +940,9 @@ function createRouter(init) {
907
940
  );
908
941
  let inFlightDataRoutes;
909
942
  let basename = init.basename || "/";
910
- let dataStrategyImpl = init.dataStrategy || defaultDataStrategy;
911
- let patchRoutesOnNavigationImpl = init.patchRoutesOnNavigation;
943
+ let dataStrategyImpl = init.dataStrategy || defaultDataStrategyWithMiddleware;
912
944
  let future = {
945
+ unstable_middleware: false,
913
946
  ...init.future
914
947
  };
915
948
  let unlistenHistory = null;
@@ -921,7 +954,7 @@ function createRouter(init) {
921
954
  let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);
922
955
  let initialMatchesIsFOW = false;
923
956
  let initialErrors = null;
924
- if (initialMatches == null && !patchRoutesOnNavigationImpl) {
957
+ if (initialMatches == null && !init.patchRoutesOnNavigation) {
925
958
  let error = getInternalRouterError(404, {
926
959
  pathname: init.history.location.pathname
927
960
  });
@@ -1352,6 +1385,9 @@ function createRouter(init) {
1352
1385
  pendingNavigationController.signal,
1353
1386
  opts && opts.submission
1354
1387
  );
1388
+ let scopedContext = new unstable_RouterContextProvider(
1389
+ init.unstable_getContext ? await init.unstable_getContext() : void 0
1390
+ );
1355
1391
  let pendingActionResult;
1356
1392
  if (opts && opts.pendingError) {
1357
1393
  pendingActionResult = [
@@ -1364,6 +1400,7 @@ function createRouter(init) {
1364
1400
  location,
1365
1401
  opts.submission,
1366
1402
  matches,
1403
+ scopedContext,
1367
1404
  fogOfWar.active,
1368
1405
  { replace: opts.replace, flushSync }
1369
1406
  );
@@ -1404,6 +1441,7 @@ function createRouter(init) {
1404
1441
  request,
1405
1442
  location,
1406
1443
  matches,
1444
+ scopedContext,
1407
1445
  fogOfWar.active,
1408
1446
  loadingNavigation,
1409
1447
  opts && opts.submission,
@@ -1424,7 +1462,7 @@ function createRouter(init) {
1424
1462
  errors
1425
1463
  });
1426
1464
  }
1427
- async function handleAction(request, location, submission, matches, isFogOfWar, opts = {}) {
1465
+ async function handleAction(request, location, submission, matches, scopedContext, isFogOfWar, opts = {}) {
1428
1466
  interruptActiveLoads();
1429
1467
  let navigation = getSubmittingNavigation(location, submission);
1430
1468
  updateState({ navigation }, { flushSync: opts.flushSync === true });
@@ -1480,13 +1518,21 @@ function createRouter(init) {
1480
1518
  } else {
1481
1519
  let results = await callDataStrategy(
1482
1520
  "action",
1483
- state,
1484
1521
  request,
1485
1522
  [actionMatch],
1486
1523
  matches,
1524
+ scopedContext,
1487
1525
  null
1488
1526
  );
1489
1527
  result = results[actionMatch.route.id];
1528
+ if (!result) {
1529
+ for (let match of matches) {
1530
+ if (results[match.route.id]) {
1531
+ result = results[match.route.id];
1532
+ break;
1533
+ }
1534
+ }
1535
+ }
1490
1536
  if (request.signal.aborted) {
1491
1537
  return { shortCircuited: true };
1492
1538
  }
@@ -1524,7 +1570,7 @@ function createRouter(init) {
1524
1570
  pendingActionResult: [actionMatch.route.id, result]
1525
1571
  };
1526
1572
  }
1527
- async function handleLoaders(request, location, matches, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync, pendingActionResult) {
1573
+ async function handleLoaders(request, location, matches, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync, pendingActionResult) {
1528
1574
  let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission);
1529
1575
  let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);
1530
1576
  let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration;
@@ -1634,11 +1680,11 @@ function createRouter(init) {
1634
1680
  );
1635
1681
  }
1636
1682
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
1637
- state,
1638
1683
  matches,
1639
1684
  matchesToLoad,
1640
1685
  revalidatingFetchers,
1641
- request
1686
+ request,
1687
+ scopedContext
1642
1688
  );
1643
1689
  if (request.signal.aborted) {
1644
1690
  return { shortCircuited: true };
@@ -1746,6 +1792,9 @@ function createRouter(init) {
1746
1792
  return;
1747
1793
  }
1748
1794
  let match = getTargetMatch(matches, path);
1795
+ let scopedContext = new unstable_RouterContextProvider(
1796
+ init.unstable_getContext ? await init.unstable_getContext() : void 0
1797
+ );
1749
1798
  let preventScrollReset = (opts && opts.preventScrollReset) === true;
1750
1799
  if (submission && isMutationMethod(submission.formMethod)) {
1751
1800
  await handleFetcherAction(
@@ -1754,6 +1803,7 @@ function createRouter(init) {
1754
1803
  path,
1755
1804
  match,
1756
1805
  matches,
1806
+ scopedContext,
1757
1807
  fogOfWar.active,
1758
1808
  flushSync,
1759
1809
  preventScrollReset,
@@ -1768,13 +1818,14 @@ function createRouter(init) {
1768
1818
  path,
1769
1819
  match,
1770
1820
  matches,
1821
+ scopedContext,
1771
1822
  fogOfWar.active,
1772
1823
  flushSync,
1773
1824
  preventScrollReset,
1774
1825
  submission
1775
1826
  );
1776
1827
  }
1777
- async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, preventScrollReset, submission) {
1828
+ async function handleFetcherAction(key, routeId, path, match, requestMatches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission) {
1778
1829
  interruptActiveLoads();
1779
1830
  fetchLoadMatches.delete(key);
1780
1831
  function detectAndHandle405Error(m) {
@@ -1807,7 +1858,8 @@ function createRouter(init) {
1807
1858
  let discoverResult = await discoverRoutes(
1808
1859
  requestMatches,
1809
1860
  path,
1810
- fetchRequest.signal
1861
+ fetchRequest.signal,
1862
+ key
1811
1863
  );
1812
1864
  if (discoverResult.type === "aborted") {
1813
1865
  return;
@@ -1834,10 +1886,10 @@ function createRouter(init) {
1834
1886
  let originatingLoadId = incrementingLoadId;
1835
1887
  let actionResults = await callDataStrategy(
1836
1888
  "action",
1837
- state,
1838
1889
  fetchRequest,
1839
1890
  [match],
1840
1891
  requestMatches,
1892
+ scopedContext,
1841
1893
  key
1842
1894
  );
1843
1895
  let actionResult = actionResults[match.route.id];
@@ -1921,11 +1973,11 @@ function createRouter(init) {
1921
1973
  abortPendingFetchRevalidations
1922
1974
  );
1923
1975
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
1924
- state,
1925
1976
  matches,
1926
1977
  matchesToLoad,
1927
1978
  revalidatingFetchers,
1928
- revalidationRequest
1979
+ revalidationRequest,
1980
+ scopedContext
1929
1981
  );
1930
1982
  if (abortController.signal.aborted) {
1931
1983
  return;
@@ -1992,7 +2044,7 @@ function createRouter(init) {
1992
2044
  isRevalidationRequired = false;
1993
2045
  }
1994
2046
  }
1995
- async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, preventScrollReset, submission) {
2047
+ async function handleFetcherLoader(key, routeId, path, match, matches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission) {
1996
2048
  let existingFetcher = state.fetchers.get(key);
1997
2049
  updateFetcherState(
1998
2050
  key,
@@ -2012,7 +2064,8 @@ function createRouter(init) {
2012
2064
  let discoverResult = await discoverRoutes(
2013
2065
  matches,
2014
2066
  path,
2015
- fetchRequest.signal
2067
+ fetchRequest.signal,
2068
+ key
2016
2069
  );
2017
2070
  if (discoverResult.type === "aborted") {
2018
2071
  return;
@@ -2036,10 +2089,10 @@ function createRouter(init) {
2036
2089
  let originatingLoadId = incrementingLoadId;
2037
2090
  let results = await callDataStrategy(
2038
2091
  "loader",
2039
- state,
2040
2092
  fetchRequest,
2041
2093
  [match],
2042
2094
  matches,
2095
+ scopedContext,
2043
2096
  key
2044
2097
  );
2045
2098
  let result = results[match.route.id];
@@ -2141,20 +2194,21 @@ function createRouter(init) {
2141
2194
  });
2142
2195
  }
2143
2196
  }
2144
- async function callDataStrategy(type, state2, request, matchesToLoad, matches, fetcherKey) {
2197
+ async function callDataStrategy(type, request, matchesToLoad, matches, scopedContext, fetcherKey) {
2145
2198
  let results;
2146
2199
  let dataResults = {};
2147
2200
  try {
2148
2201
  results = await callDataStrategyImpl(
2149
2202
  dataStrategyImpl,
2150
2203
  type,
2151
- state2,
2152
2204
  request,
2153
2205
  matchesToLoad,
2154
2206
  matches,
2155
2207
  fetcherKey,
2156
2208
  manifest,
2157
- mapRouteProperties2
2209
+ mapRouteProperties2,
2210
+ scopedContext,
2211
+ future.unstable_middleware
2158
2212
  );
2159
2213
  } catch (e) {
2160
2214
  matchesToLoad.forEach((m) => {
@@ -2186,13 +2240,13 @@ function createRouter(init) {
2186
2240
  }
2187
2241
  return dataResults;
2188
2242
  }
2189
- async function callLoadersAndMaybeResolveData(state2, matches, matchesToLoad, fetchersToLoad, request) {
2243
+ async function callLoadersAndMaybeResolveData(matches, matchesToLoad, fetchersToLoad, request, scopedContext) {
2190
2244
  let loaderResultsPromise = callDataStrategy(
2191
2245
  "loader",
2192
- state2,
2193
2246
  request,
2194
2247
  matchesToLoad,
2195
2248
  matches,
2249
+ scopedContext,
2196
2250
  null
2197
2251
  );
2198
2252
  let fetcherResultsPromise = Promise.all(
@@ -2200,10 +2254,10 @@ function createRouter(init) {
2200
2254
  if (f.matches && f.match && f.controller) {
2201
2255
  let results = await callDataStrategy(
2202
2256
  "loader",
2203
- state2,
2204
2257
  createClientSideRequest(init.history, f.path, f.controller.signal),
2205
2258
  [f.match],
2206
2259
  f.matches,
2260
+ scopedContext,
2207
2261
  f.key
2208
2262
  );
2209
2263
  let result = results[f.match.route.id];
@@ -2425,7 +2479,7 @@ function createRouter(init) {
2425
2479
  return null;
2426
2480
  }
2427
2481
  function checkFogOfWar(matches, routesToUse, pathname) {
2428
- if (patchRoutesOnNavigationImpl) {
2482
+ if (init.patchRoutesOnNavigation) {
2429
2483
  if (!matches) {
2430
2484
  let fogMatches = matchRoutesImpl(
2431
2485
  routesToUse,
@@ -2448,8 +2502,8 @@ function createRouter(init) {
2448
2502
  }
2449
2503
  return { active: false, matches: null };
2450
2504
  }
2451
- async function discoverRoutes(matches, pathname, signal) {
2452
- if (!patchRoutesOnNavigationImpl) {
2505
+ async function discoverRoutes(matches, pathname, signal, fetcherKey) {
2506
+ if (!init.patchRoutesOnNavigation) {
2453
2507
  return { type: "success", matches };
2454
2508
  }
2455
2509
  let partialMatches = matches;
@@ -2458,10 +2512,11 @@ function createRouter(init) {
2458
2512
  let routesToUse = inFlightDataRoutes || dataRoutes;
2459
2513
  let localManifest = manifest;
2460
2514
  try {
2461
- await patchRoutesOnNavigationImpl({
2515
+ await init.patchRoutesOnNavigation({
2462
2516
  signal,
2463
2517
  path: pathname,
2464
2518
  matches: partialMatches,
2519
+ fetcherKey,
2465
2520
  patch: (routeId, children) => {
2466
2521
  if (signal.aborted) return;
2467
2522
  patchRoutesImpl(
@@ -2580,17 +2635,21 @@ function createStaticHandler(routes, opts) {
2580
2635
  );
2581
2636
  async function query(request, {
2582
2637
  requestContext,
2638
+ filterMatchesToLoad,
2583
2639
  skipLoaderErrorBubbling,
2584
- dataStrategy
2640
+ skipRevalidation,
2641
+ dataStrategy,
2642
+ unstable_respond: respond
2585
2643
  } = {}) {
2586
2644
  let url = new URL(request.url);
2587
2645
  let method = request.method;
2588
2646
  let location = createLocation("", createPath(url), null, "default");
2589
2647
  let matches = matchRoutes(dataRoutes, location, basename);
2648
+ requestContext = requestContext != null ? requestContext : new unstable_RouterContextProvider();
2590
2649
  if (!isValidMethod(method) && method !== "HEAD") {
2591
2650
  let error = getInternalRouterError(405, { method });
2592
2651
  let { matches: methodNotAllowedMatches, route } = getShortCircuitMatches(dataRoutes);
2593
- return {
2652
+ let staticContext = {
2594
2653
  basename,
2595
2654
  location,
2596
2655
  matches: methodNotAllowedMatches,
@@ -2603,10 +2662,11 @@ function createStaticHandler(routes, opts) {
2603
2662
  loaderHeaders: {},
2604
2663
  actionHeaders: {}
2605
2664
  };
2665
+ return respond ? respond(staticContext) : staticContext;
2606
2666
  } else if (!matches) {
2607
2667
  let error = getInternalRouterError(404, { pathname: location.pathname });
2608
2668
  let { matches: notFoundMatches, route } = getShortCircuitMatches(dataRoutes);
2609
- return {
2669
+ let staticContext = {
2610
2670
  basename,
2611
2671
  location,
2612
2672
  matches: notFoundMatches,
@@ -2619,6 +2679,90 @@ function createStaticHandler(routes, opts) {
2619
2679
  loaderHeaders: {},
2620
2680
  actionHeaders: {}
2621
2681
  };
2682
+ return respond ? respond(staticContext) : staticContext;
2683
+ }
2684
+ if (respond && matches.some((m) => m.route.unstable_middleware)) {
2685
+ invariant(
2686
+ requestContext instanceof unstable_RouterContextProvider,
2687
+ "When using middleware in `staticHandler.query()`, any provided `requestContext` must bean instance of `unstable_RouterContextProvider`"
2688
+ );
2689
+ try {
2690
+ let tailIdx = [...matches].reverse().findIndex((m) => !filterMatchesToLoad || filterMatchesToLoad(m));
2691
+ let lowestLoadingIdx = tailIdx < 0 ? 0 : matches.length - 1 - tailIdx;
2692
+ let renderedStaticContext;
2693
+ let response = await runMiddlewarePipeline(
2694
+ {
2695
+ request,
2696
+ matches,
2697
+ params: matches[0].params,
2698
+ // If we're calling middleware then it must be enabled so we can cast
2699
+ // this to the proper type knowing it's not an `AppLoadContext`
2700
+ context: requestContext
2701
+ },
2702
+ lowestLoadingIdx,
2703
+ true,
2704
+ async () => {
2705
+ let result2 = await queryImpl(
2706
+ request,
2707
+ location,
2708
+ matches,
2709
+ requestContext,
2710
+ dataStrategy || null,
2711
+ skipLoaderErrorBubbling === true,
2712
+ null,
2713
+ filterMatchesToLoad || null,
2714
+ skipRevalidation === true
2715
+ );
2716
+ if (isResponse(result2)) {
2717
+ return result2;
2718
+ }
2719
+ renderedStaticContext = { location, basename, ...result2 };
2720
+ let res = await respond(renderedStaticContext);
2721
+ return res;
2722
+ },
2723
+ async (e) => {
2724
+ if (isResponse(e.error)) {
2725
+ return e.error;
2726
+ }
2727
+ if (renderedStaticContext) {
2728
+ if (e.routeId in renderedStaticContext.loaderData) {
2729
+ renderedStaticContext.loaderData[e.routeId] = void 0;
2730
+ }
2731
+ return respond(
2732
+ getStaticContextFromError(
2733
+ dataRoutes,
2734
+ renderedStaticContext,
2735
+ e.error,
2736
+ findNearestBoundary(matches, e.routeId).route.id
2737
+ )
2738
+ );
2739
+ } else {
2740
+ let loaderIdx = matches.findIndex((m) => m.route.loader);
2741
+ let boundary = loaderIdx >= 0 ? findNearestBoundary(matches, matches[loaderIdx].route.id) : findNearestBoundary(matches);
2742
+ return respond({
2743
+ matches,
2744
+ location,
2745
+ basename,
2746
+ loaderData: {},
2747
+ actionData: null,
2748
+ errors: {
2749
+ [boundary.route.id]: e.error
2750
+ },
2751
+ statusCode: isRouteErrorResponse(e.error) ? e.error.status : 500,
2752
+ actionHeaders: {},
2753
+ loaderHeaders: {}
2754
+ });
2755
+ }
2756
+ }
2757
+ );
2758
+ invariant(isResponse(response), "Expected a response in query()");
2759
+ return response;
2760
+ } catch (e) {
2761
+ if (isResponse(e)) {
2762
+ return e;
2763
+ }
2764
+ throw e;
2765
+ }
2622
2766
  }
2623
2767
  let result = await queryImpl(
2624
2768
  request,
@@ -2627,7 +2771,9 @@ function createStaticHandler(routes, opts) {
2627
2771
  requestContext,
2628
2772
  dataStrategy || null,
2629
2773
  skipLoaderErrorBubbling === true,
2630
- null
2774
+ null,
2775
+ filterMatchesToLoad || null,
2776
+ skipRevalidation === true
2631
2777
  );
2632
2778
  if (isResponse(result)) {
2633
2779
  return result;
@@ -2637,12 +2783,14 @@ function createStaticHandler(routes, opts) {
2637
2783
  async function queryRoute(request, {
2638
2784
  routeId,
2639
2785
  requestContext,
2640
- dataStrategy
2786
+ dataStrategy,
2787
+ unstable_respond: respond
2641
2788
  } = {}) {
2642
2789
  let url = new URL(request.url);
2643
2790
  let method = request.method;
2644
2791
  let location = createLocation("", createPath(url), null, "default");
2645
2792
  let matches = matchRoutes(dataRoutes, location, basename);
2793
+ requestContext = requestContext != null ? requestContext : new unstable_RouterContextProvider();
2646
2794
  if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") {
2647
2795
  throw getInternalRouterError(405, { method });
2648
2796
  } else if (!matches) {
@@ -2657,6 +2805,56 @@ function createStaticHandler(routes, opts) {
2657
2805
  } else if (!match) {
2658
2806
  throw getInternalRouterError(404, { pathname: location.pathname });
2659
2807
  }
2808
+ if (respond && matches.some((m) => m.route.unstable_middleware)) {
2809
+ invariant(
2810
+ requestContext instanceof unstable_RouterContextProvider,
2811
+ "When using middleware in `staticHandler.queryRoute()`, any provided `requestContext` must bean instance of `unstable_RouterContextProvider`"
2812
+ );
2813
+ let response = await runMiddlewarePipeline(
2814
+ {
2815
+ request,
2816
+ matches,
2817
+ params: matches[0].params,
2818
+ // If we're calling middleware then it must be enabled so we can cast
2819
+ // this to the proper type knowing it's not an `AppLoadContext`
2820
+ context: requestContext
2821
+ },
2822
+ matches.length - 1,
2823
+ true,
2824
+ async () => {
2825
+ let result2 = await queryImpl(
2826
+ request,
2827
+ location,
2828
+ matches,
2829
+ requestContext,
2830
+ dataStrategy || null,
2831
+ false,
2832
+ match,
2833
+ null,
2834
+ false
2835
+ );
2836
+ if (isResponse(result2)) {
2837
+ return respond(result2);
2838
+ }
2839
+ let error2 = result2.errors ? Object.values(result2.errors)[0] : void 0;
2840
+ if (error2 !== void 0) {
2841
+ throw error2;
2842
+ }
2843
+ let value = result2.actionData ? Object.values(result2.actionData)[0] : Object.values(result2.loaderData)[0];
2844
+ return typeof value === "string" ? new Response(value) : Response.json(value);
2845
+ },
2846
+ (e) => {
2847
+ if (isResponse(e.error)) {
2848
+ return respond(e.error);
2849
+ }
2850
+ return new Response(String(e.error), {
2851
+ status: 500,
2852
+ statusText: "Unexpected Server Error"
2853
+ });
2854
+ }
2855
+ );
2856
+ return response;
2857
+ }
2660
2858
  let result = await queryImpl(
2661
2859
  request,
2662
2860
  location,
@@ -2664,7 +2862,9 @@ function createStaticHandler(routes, opts) {
2664
2862
  requestContext,
2665
2863
  dataStrategy || null,
2666
2864
  false,
2667
- match
2865
+ match,
2866
+ null,
2867
+ false
2668
2868
  );
2669
2869
  if (isResponse(result)) {
2670
2870
  return result;
@@ -2681,7 +2881,7 @@ function createStaticHandler(routes, opts) {
2681
2881
  }
2682
2882
  return void 0;
2683
2883
  }
2684
- async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch) {
2884
+ async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, skipRevalidation) {
2685
2885
  invariant(
2686
2886
  request.signal,
2687
2887
  "query()/queryRoute() requests must contain an AbortController signal"
@@ -2695,7 +2895,9 @@ function createStaticHandler(routes, opts) {
2695
2895
  requestContext,
2696
2896
  dataStrategy,
2697
2897
  skipLoaderErrorBubbling,
2698
- routeMatch != null
2898
+ routeMatch != null,
2899
+ filterMatchesToLoad,
2900
+ skipRevalidation
2699
2901
  );
2700
2902
  return result2;
2701
2903
  }
@@ -2705,7 +2907,8 @@ function createStaticHandler(routes, opts) {
2705
2907
  requestContext,
2706
2908
  dataStrategy,
2707
2909
  skipLoaderErrorBubbling,
2708
- routeMatch
2910
+ routeMatch,
2911
+ filterMatchesToLoad
2709
2912
  );
2710
2913
  return isResponse(result) ? result : {
2711
2914
  ...result,
@@ -2725,7 +2928,7 @@ function createStaticHandler(routes, opts) {
2725
2928
  throw e;
2726
2929
  }
2727
2930
  }
2728
- async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest) {
2931
+ async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest, filterMatchesToLoad, skipRevalidation) {
2729
2932
  let result;
2730
2933
  if (!actionMatch.route.action && !actionMatch.route.lazy) {
2731
2934
  let error = getInternalRouterError(405, {
@@ -2779,6 +2982,36 @@ function createStaticHandler(routes, opts) {
2779
2982
  actionHeaders: {}
2780
2983
  };
2781
2984
  }
2985
+ if (skipRevalidation) {
2986
+ if (isErrorResult(result)) {
2987
+ let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
2988
+ return {
2989
+ statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
2990
+ actionData: null,
2991
+ actionHeaders: {
2992
+ ...result.headers ? { [actionMatch.route.id]: result.headers } : {}
2993
+ },
2994
+ matches,
2995
+ loaderData: {},
2996
+ errors: {
2997
+ [boundaryMatch.route.id]: result.error
2998
+ },
2999
+ loaderHeaders: {}
3000
+ };
3001
+ } else {
3002
+ return {
3003
+ actionData: {
3004
+ [actionMatch.route.id]: result.data
3005
+ },
3006
+ actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {},
3007
+ matches,
3008
+ loaderData: {},
3009
+ errors: null,
3010
+ statusCode: result.statusCode || 200,
3011
+ loaderHeaders: {}
3012
+ };
3013
+ }
3014
+ }
2782
3015
  let loaderRequest = new Request(request.url, {
2783
3016
  headers: request.headers,
2784
3017
  redirect: request.redirect,
@@ -2786,17 +3019,18 @@ function createStaticHandler(routes, opts) {
2786
3019
  });
2787
3020
  if (isErrorResult(result)) {
2788
3021
  let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
2789
- let context2 = await loadRouteData(
3022
+ let handlerContext2 = await loadRouteData(
2790
3023
  loaderRequest,
2791
3024
  matches,
2792
3025
  requestContext,
2793
3026
  dataStrategy,
2794
3027
  skipLoaderErrorBubbling,
2795
3028
  null,
3029
+ filterMatchesToLoad,
2796
3030
  [boundaryMatch.route.id, result]
2797
3031
  );
2798
3032
  return {
2799
- ...context2,
3033
+ ...handlerContext2,
2800
3034
  statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
2801
3035
  actionData: null,
2802
3036
  actionHeaders: {
@@ -2804,16 +3038,17 @@ function createStaticHandler(routes, opts) {
2804
3038
  }
2805
3039
  };
2806
3040
  }
2807
- let context = await loadRouteData(
3041
+ let handlerContext = await loadRouteData(
2808
3042
  loaderRequest,
2809
3043
  matches,
2810
3044
  requestContext,
2811
3045
  dataStrategy,
2812
3046
  skipLoaderErrorBubbling,
2813
- null
3047
+ null,
3048
+ filterMatchesToLoad
2814
3049
  );
2815
3050
  return {
2816
- ...context,
3051
+ ...handlerContext,
2817
3052
  actionData: {
2818
3053
  [actionMatch.route.id]: result.data
2819
3054
  },
@@ -2822,7 +3057,7 @@ function createStaticHandler(routes, opts) {
2822
3057
  actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {}
2823
3058
  };
2824
3059
  }
2825
- async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) {
3060
+ async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, pendingActionResult) {
2826
3061
  let isRouteRequest = routeMatch != null;
2827
3062
  if (isRouteRequest && !routeMatch?.route.loader && !routeMatch?.route.lazy) {
2828
3063
  throw getInternalRouterError(400, {
@@ -2833,7 +3068,7 @@ function createStaticHandler(routes, opts) {
2833
3068
  }
2834
3069
  let requestMatches = routeMatch ? [routeMatch] : pendingActionResult && isErrorResult(pendingActionResult[1]) ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]) : matches;
2835
3070
  let matchesToLoad = requestMatches.filter(
2836
- (m) => m.route.loader || m.route.lazy
3071
+ (m) => (m.route.loader || m.route.lazy) && (!filterMatchesToLoad || filterMatchesToLoad(m))
2837
3072
  );
2838
3073
  if (matchesToLoad.length === 0) {
2839
3074
  return {
@@ -2862,7 +3097,7 @@ function createStaticHandler(routes, opts) {
2862
3097
  if (request.signal.aborted) {
2863
3098
  throwStaticHandlerAbortedError(request, isRouteRequest);
2864
3099
  }
2865
- let context = processRouteLoaderData(
3100
+ let handlerContext = processRouteLoaderData(
2866
3101
  matches,
2867
3102
  results,
2868
3103
  pendingActionResult,
@@ -2874,11 +3109,11 @@ function createStaticHandler(routes, opts) {
2874
3109
  );
2875
3110
  matches.forEach((match) => {
2876
3111
  if (!executedLoaders.has(match.route.id)) {
2877
- context.loaderData[match.route.id] = null;
3112
+ handlerContext.loaderData[match.route.id] = null;
2878
3113
  }
2879
3114
  });
2880
3115
  return {
2881
- ...context,
3116
+ ...handlerContext,
2882
3117
  matches
2883
3118
  };
2884
3119
  }
@@ -2886,14 +3121,15 @@ function createStaticHandler(routes, opts) {
2886
3121
  let results = await callDataStrategyImpl(
2887
3122
  dataStrategy || defaultDataStrategy,
2888
3123
  type,
2889
- null,
2890
3124
  request,
2891
3125
  matchesToLoad,
2892
3126
  matches,
2893
3127
  null,
2894
3128
  manifest,
2895
3129
  mapRouteProperties2,
2896
- requestContext
3130
+ requestContext,
3131
+ false
3132
+ // middleware not done via dataStrategy in the static handler
2897
3133
  );
2898
3134
  let dataResults = {};
2899
3135
  await Promise.all(
@@ -2926,15 +3162,15 @@ function createStaticHandler(routes, opts) {
2926
3162
  queryRoute
2927
3163
  };
2928
3164
  }
2929
- function getStaticContextFromError(routes, context, error) {
2930
- let newContext = {
2931
- ...context,
3165
+ function getStaticContextFromError(routes, handlerContext, error, boundaryId) {
3166
+ let errorBoundaryId = boundaryId || handlerContext._deepestRenderedBoundaryId || routes[0].id;
3167
+ return {
3168
+ ...handlerContext,
2932
3169
  statusCode: isRouteErrorResponse(error) ? error.status : 500,
2933
3170
  errors: {
2934
- [context._deepestRenderedBoundaryId || routes[0].id]: error
3171
+ [errorBoundaryId]: error
2935
3172
  }
2936
3173
  };
2937
- return newContext;
2938
3174
  }
2939
3175
  function throwStaticHandlerAbortedError(request, isRouteRequest) {
2940
3176
  if (request.signal.reason !== void 0) {
@@ -3327,20 +3563,143 @@ async function loadLazyRouteModule(route, mapRouteProperties2, manifest) {
3327
3563
  lazy: void 0
3328
3564
  });
3329
3565
  }
3330
- async function defaultDataStrategy({
3331
- matches
3332
- }) {
3333
- let matchesToLoad = matches.filter((m) => m.shouldLoad);
3566
+ async function defaultDataStrategy(args) {
3567
+ let matchesToLoad = args.matches.filter((m) => m.shouldLoad);
3568
+ let keyedResults = {};
3334
3569
  let results = await Promise.all(matchesToLoad.map((m) => m.resolve()));
3335
- return results.reduce(
3336
- (acc, result, i) => Object.assign(acc, { [matchesToLoad[i].route.id]: result }),
3337
- {}
3570
+ results.forEach((result, i) => {
3571
+ keyedResults[matchesToLoad[i].route.id] = result;
3572
+ });
3573
+ return keyedResults;
3574
+ }
3575
+ async function defaultDataStrategyWithMiddleware(args) {
3576
+ if (!args.matches.some((m) => m.route.unstable_middleware)) {
3577
+ return defaultDataStrategy(args);
3578
+ }
3579
+ let lastIndex = args.matches.length - 1;
3580
+ for (let i = lastIndex; i >= 0; i--) {
3581
+ if (args.matches[i].shouldLoad) {
3582
+ lastIndex = i;
3583
+ break;
3584
+ }
3585
+ }
3586
+ let results = await runMiddlewarePipeline(
3587
+ args,
3588
+ lastIndex,
3589
+ false,
3590
+ async (keyedResults) => {
3591
+ Object.assign(keyedResults, await defaultDataStrategy(args));
3592
+ },
3593
+ (e, keyedResults) => {
3594
+ Object.assign(keyedResults, {
3595
+ [e.routeId]: { type: "error", result: e.error }
3596
+ });
3597
+ }
3338
3598
  );
3599
+ return results;
3339
3600
  }
3340
- async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties2, requestContext) {
3601
+ async function runMiddlewarePipeline({
3602
+ request,
3603
+ params,
3604
+ context,
3605
+ matches
3606
+ }, lastIndex, propagateResult, handler, errorHandler) {
3607
+ let middlewareState = {
3608
+ keyedResults: {},
3609
+ propagateResult
3610
+ };
3611
+ try {
3612
+ let result = await callRouteMiddleware(
3613
+ matches.slice(0, lastIndex + 1).flatMap(
3614
+ (m) => m.route.unstable_middleware ? m.route.unstable_middleware.map((fn) => [m.route.id, fn]) : []
3615
+ ),
3616
+ 0,
3617
+ { request, params, context },
3618
+ middlewareState,
3619
+ handler
3620
+ );
3621
+ return middlewareState.propagateResult ? result : middlewareState.keyedResults;
3622
+ } catch (e) {
3623
+ if (!(e instanceof MiddlewareError)) {
3624
+ throw e;
3625
+ }
3626
+ let result = await errorHandler(e, middlewareState.keyedResults);
3627
+ return middlewareState.propagateResult ? result : middlewareState.keyedResults;
3628
+ }
3629
+ }
3630
+ var MiddlewareError = class {
3631
+ constructor(routeId, error) {
3632
+ this.routeId = routeId;
3633
+ this.error = error;
3634
+ }
3635
+ };
3636
+ async function callRouteMiddleware(middlewares, idx, args, middlewareState, handler) {
3637
+ let { request } = args;
3638
+ if (request.signal.aborted) {
3639
+ if (request.signal.reason) {
3640
+ throw request.signal.reason;
3641
+ }
3642
+ throw new Error(
3643
+ `Request aborted without an \`AbortSignal.reason\`: ${request.method} ${request.url}`
3644
+ );
3645
+ }
3646
+ let tuple = middlewares[idx];
3647
+ if (!tuple) {
3648
+ let result = await handler(middlewareState.keyedResults);
3649
+ return result;
3650
+ }
3651
+ let [routeId, middleware] = tuple;
3652
+ let nextCalled = false;
3653
+ let nextResult = void 0;
3654
+ let next = async () => {
3655
+ if (nextCalled) {
3656
+ throw new Error("You may only call `next()` once per middleware");
3657
+ }
3658
+ nextCalled = true;
3659
+ let result = await callRouteMiddleware(
3660
+ middlewares,
3661
+ idx + 1,
3662
+ args,
3663
+ middlewareState,
3664
+ handler
3665
+ );
3666
+ if (middlewareState.propagateResult) {
3667
+ nextResult = result;
3668
+ return nextResult;
3669
+ }
3670
+ };
3671
+ try {
3672
+ let result = await middleware(
3673
+ {
3674
+ request: args.request,
3675
+ params: args.params,
3676
+ context: args.context
3677
+ },
3678
+ next
3679
+ );
3680
+ if (nextCalled) {
3681
+ if (result === void 0) {
3682
+ return nextResult;
3683
+ } else {
3684
+ return result;
3685
+ }
3686
+ } else {
3687
+ return next();
3688
+ }
3689
+ } catch (e) {
3690
+ if (e instanceof MiddlewareError) {
3691
+ throw e;
3692
+ }
3693
+ throw new MiddlewareError(routeId, e);
3694
+ }
3695
+ }
3696
+ async function callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties2, scopedContext, enableMiddleware) {
3341
3697
  let loadRouteDefinitionsPromises = matches.map(
3342
3698
  (m) => m.route.lazy ? loadLazyRouteModule(m.route, mapRouteProperties2, manifest) : void 0
3343
3699
  );
3700
+ if (enableMiddleware) {
3701
+ await Promise.all(loadRouteDefinitionsPromises);
3702
+ }
3344
3703
  let dsMatches = matches.map((match, i) => {
3345
3704
  let loadRoutePromise = loadRouteDefinitionsPromises[i];
3346
3705
  let shouldLoad = matchesToLoad.some((m) => m.route.id === match.route.id);
@@ -3354,7 +3713,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
3354
3713
  match,
3355
3714
  loadRoutePromise,
3356
3715
  handlerOverride,
3357
- requestContext
3716
+ scopedContext
3358
3717
  ) : Promise.resolve({ type: "data" /* data */, result: void 0 });
3359
3718
  };
3360
3719
  return {
@@ -3368,7 +3727,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
3368
3727
  request,
3369
3728
  params: matches[0].params,
3370
3729
  fetcherKey,
3371
- context: requestContext
3730
+ context: scopedContext
3372
3731
  });
3373
3732
  try {
3374
3733
  await Promise.all(loadRouteDefinitionsPromises);
@@ -3376,7 +3735,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
3376
3735
  }
3377
3736
  return results;
3378
3737
  }
3379
- async function callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, staticContext) {
3738
+ async function callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, scopedContext) {
3380
3739
  let result;
3381
3740
  let onReject;
3382
3741
  let runHandler = (handler) => {
@@ -3396,7 +3755,7 @@ async function callLoaderOrAction(type, request, match, loadRoutePromise, handle
3396
3755
  {
3397
3756
  request,
3398
3757
  params: match.params,
3399
- context: staticContext
3758
+ context: scopedContext
3400
3759
  },
3401
3760
  ...ctx !== void 0 ? [ctx] : []
3402
3761
  );
@@ -4709,6 +5068,7 @@ function mapRouteProperties(route) {
4709
5068
  function createMemoryRouter(routes, opts) {
4710
5069
  return createRouter({
4711
5070
  basename: opts?.basename,
5071
+ unstable_getContext: opts?.unstable_getContext,
4712
5072
  future: opts?.future,
4713
5073
  history: createMemoryHistory({
4714
5074
  initialEntries: opts?.initialEntries,
@@ -5664,55 +6024,103 @@ function StreamTransfer({
5664
6024
  )));
5665
6025
  }
5666
6026
  }
5667
- function getSingleFetchDataStrategy(manifest, routeModules, ssr, getRouter) {
5668
- return async ({ request, matches, fetcherKey }) => {
6027
+ function middlewareErrorHandler(e, keyedResults) {
6028
+ Object.assign(keyedResults, {
6029
+ [e.routeId]: { type: "error", result: e.error }
6030
+ });
6031
+ }
6032
+ function getSingleFetchDataStrategy(manifest, routeModules, ssr, basename, getRouter) {
6033
+ return async (args) => {
6034
+ let { request, matches, fetcherKey } = args;
5669
6035
  if (request.method !== "GET") {
5670
- return singleFetchActionStrategy(request, matches);
6036
+ return runMiddlewarePipeline(
6037
+ args,
6038
+ matches.findIndex((m) => m.shouldLoad),
6039
+ false,
6040
+ async (keyedResults) => {
6041
+ let results = await singleFetchActionStrategy(
6042
+ request,
6043
+ matches,
6044
+ basename
6045
+ );
6046
+ Object.assign(keyedResults, results);
6047
+ },
6048
+ middlewareErrorHandler
6049
+ );
5671
6050
  }
5672
6051
  if (!ssr) {
5673
6052
  let foundRevalidatingServerLoader = matches.some(
5674
6053
  (m) => m.shouldLoad && manifest.routes[m.route.id]?.hasLoader && !manifest.routes[m.route.id]?.hasClientLoader
5675
6054
  );
5676
6055
  if (!foundRevalidatingServerLoader) {
5677
- let matchesToLoad = matches.filter((m) => m.shouldLoad);
5678
- let url = stripIndexParam(singleFetchUrl(request.url));
5679
- let init = await createRequestInit(request);
5680
- let results = {};
5681
- await Promise.all(
5682
- matchesToLoad.map(
5683
- (m) => m.resolve(async (handler) => {
5684
- try {
5685
- let result = manifest.routes[m.route.id]?.hasClientLoader ? await fetchSingleLoader(handler, url, init, m.route.id) : await handler();
5686
- results[m.route.id] = { type: "data", result };
5687
- } catch (e) {
5688
- results[m.route.id] = { type: "error", result: e };
5689
- }
5690
- })
5691
- )
6056
+ let tailIdx = [...matches].reverse().findIndex((m) => m.shouldLoad);
6057
+ let lowestLoadingIndex2 = tailIdx < 0 ? 0 : matches.length - 1 - tailIdx;
6058
+ return runMiddlewarePipeline(
6059
+ args,
6060
+ lowestLoadingIndex2,
6061
+ false,
6062
+ async (keyedResults) => {
6063
+ let results = await nonSsrStrategy(
6064
+ manifest,
6065
+ request,
6066
+ matches,
6067
+ basename
6068
+ );
6069
+ Object.assign(keyedResults, results);
6070
+ },
6071
+ middlewareErrorHandler
5692
6072
  );
5693
- return results;
5694
6073
  }
5695
6074
  }
5696
6075
  if (fetcherKey) {
5697
- return singleFetchLoaderFetcherStrategy(request, matches);
6076
+ return runMiddlewarePipeline(
6077
+ args,
6078
+ matches.findIndex((m) => m.shouldLoad),
6079
+ false,
6080
+ async (keyedResults) => {
6081
+ let results = await singleFetchLoaderFetcherStrategy(
6082
+ request,
6083
+ matches,
6084
+ basename
6085
+ );
6086
+ Object.assign(keyedResults, results);
6087
+ },
6088
+ middlewareErrorHandler
6089
+ );
5698
6090
  }
5699
- return singleFetchLoaderNavigationStrategy(
6091
+ let lowestLoadingIndex = getLowestLoadingIndex(
5700
6092
  manifest,
5701
6093
  routeModules,
5702
- ssr,
5703
6094
  getRouter(),
5704
- request,
5705
6095
  matches
5706
6096
  );
6097
+ return runMiddlewarePipeline(
6098
+ args,
6099
+ lowestLoadingIndex,
6100
+ false,
6101
+ async (keyedResults) => {
6102
+ let results = await singleFetchLoaderNavigationStrategy(
6103
+ manifest,
6104
+ routeModules,
6105
+ ssr,
6106
+ getRouter(),
6107
+ request,
6108
+ matches,
6109
+ basename
6110
+ );
6111
+ Object.assign(keyedResults, results);
6112
+ },
6113
+ middlewareErrorHandler
6114
+ );
5707
6115
  };
5708
6116
  }
5709
- async function singleFetchActionStrategy(request, matches) {
6117
+ async function singleFetchActionStrategy(request, matches, basename) {
5710
6118
  let actionMatch = matches.find((m) => m.shouldLoad);
5711
6119
  invariant2(actionMatch, "No action match found");
5712
6120
  let actionStatus = void 0;
5713
6121
  let result = await actionMatch.resolve(async (handler) => {
5714
6122
  let result2 = await handler(async () => {
5715
- let url = singleFetchUrl(request.url);
6123
+ let url = singleFetchUrl(request.url, basename);
5716
6124
  let init = await createRequestInit(request);
5717
6125
  let { data: data2, status } = await fetchAndDecode(url, init);
5718
6126
  actionStatus = status;
@@ -5733,13 +6141,46 @@ async function singleFetchActionStrategy(request, matches) {
5733
6141
  }
5734
6142
  };
5735
6143
  }
5736
- async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr, router, request, matches) {
6144
+ async function nonSsrStrategy(manifest, request, matches, basename) {
6145
+ let matchesToLoad = matches.filter((m) => m.shouldLoad);
6146
+ let url = stripIndexParam(singleFetchUrl(request.url, basename));
6147
+ let init = await createRequestInit(request);
6148
+ let results = {};
6149
+ await Promise.all(
6150
+ matchesToLoad.map(
6151
+ (m) => m.resolve(async (handler) => {
6152
+ try {
6153
+ let result = manifest.routes[m.route.id]?.hasClientLoader ? await fetchSingleLoader(handler, url, init, m.route.id) : await handler();
6154
+ results[m.route.id] = { type: "data", result };
6155
+ } catch (e) {
6156
+ results[m.route.id] = { type: "error", result: e };
6157
+ }
6158
+ })
6159
+ )
6160
+ );
6161
+ return results;
6162
+ }
6163
+ function isOptedOut(manifestRoute, routeModule, match, router) {
6164
+ return match.route.id in router.state.loaderData && manifestRoute && manifestRoute.hasLoader && routeModule && routeModule.shouldRevalidate;
6165
+ }
6166
+ function getLowestLoadingIndex(manifest, routeModules, router, matches) {
6167
+ let tailIdx = [...matches].reverse().findIndex(
6168
+ (m) => m.shouldLoad || !isOptedOut(
6169
+ manifest.routes[m.route.id],
6170
+ routeModules[m.route.id],
6171
+ m,
6172
+ router
6173
+ )
6174
+ );
6175
+ return tailIdx < 0 ? 0 : matches.length - 1 - tailIdx;
6176
+ }
6177
+ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr, router, request, matches, basename) {
5737
6178
  let routesParams = /* @__PURE__ */ new Set();
5738
6179
  let foundOptOutRoute = false;
5739
6180
  let routeDfds = matches.map(() => createDeferred2());
5740
6181
  let routesLoadedPromise = Promise.all(routeDfds.map((d) => d.promise));
5741
6182
  let singleFetchDfd = createDeferred2();
5742
- let url = stripIndexParam(singleFetchUrl(request.url));
6183
+ let url = stripIndexParam(singleFetchUrl(request.url, basename));
5743
6184
  let init = await createRequestInit(request);
5744
6185
  let results = {};
5745
6186
  let resolvePromise = Promise.all(
@@ -5751,7 +6192,7 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr,
5751
6192
  if (!router.state.initialized) {
5752
6193
  return;
5753
6194
  }
5754
- if (m.route.id in router.state.loaderData && manifestRoute && manifestRoute.hasLoader && routeModules[m.route.id]?.shouldRevalidate) {
6195
+ if (isOptedOut(manifestRoute, routeModules[m.route.id], m, router)) {
5755
6196
  foundOptOutRoute = true;
5756
6197
  return;
5757
6198
  }
@@ -5814,11 +6255,11 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr,
5814
6255
  await resolvePromise;
5815
6256
  return results;
5816
6257
  }
5817
- async function singleFetchLoaderFetcherStrategy(request, matches) {
6258
+ async function singleFetchLoaderFetcherStrategy(request, matches, basename) {
5818
6259
  let fetcherMatch = matches.find((m) => m.shouldLoad);
5819
6260
  invariant2(fetcherMatch, "No fetcher match found");
5820
6261
  let result = await fetcherMatch.resolve(async (handler) => {
5821
- let url = stripIndexParam(singleFetchUrl(request.url));
6262
+ let url = stripIndexParam(singleFetchUrl(request.url, basename));
5822
6263
  let init = await createRequestInit(request);
5823
6264
  return fetchSingleLoader(handler, url, init, fetcherMatch.route.id);
5824
6265
  });
@@ -5846,7 +6287,7 @@ function stripIndexParam(url) {
5846
6287
  }
5847
6288
  return url;
5848
6289
  }
5849
- function singleFetchUrl(reqUrl) {
6290
+ function singleFetchUrl(reqUrl, basename) {
5850
6291
  let url = typeof reqUrl === "string" ? new URL(
5851
6292
  reqUrl,
5852
6293
  // This can be called during the SSR flow via PrefetchPageLinksImpl so
@@ -5855,6 +6296,8 @@ function singleFetchUrl(reqUrl) {
5855
6296
  ) : reqUrl;
5856
6297
  if (url.pathname === "/") {
5857
6298
  url.pathname = "_root.data";
6299
+ } else if (basename && stripBasename(url.pathname, basename) === "/") {
6300
+ url.pathname = `${basename.replace(/\/$/, "")}/_root.data`;
5858
6301
  } else {
5859
6302
  url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
5860
6303
  }
@@ -6151,8 +6594,8 @@ function createServerRoutes(manifest, routeModules, future, isSpaMode, parentId
6151
6594
  // render, so just give it a no-op function so we can render down to the
6152
6595
  // proper fallback
6153
6596
  loader: route.hasLoader || route.hasClientLoader ? () => null : void 0
6154
- // We don't need action/shouldRevalidate on these routes since they're
6155
- // for a static render
6597
+ // We don't need middleware/action/shouldRevalidate on these routes since
6598
+ // they're for a static render
6156
6599
  };
6157
6600
  let children = createServerRoutes(
6158
6601
  manifest,
@@ -6246,6 +6689,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6246
6689
  Object.assign(dataRoute, {
6247
6690
  ...dataRoute,
6248
6691
  ...getRouteComponents(route, routeModule, isSpaMode),
6692
+ unstable_middleware: routeModule.unstable_clientMiddleware,
6249
6693
  handle: routeModule.handle,
6250
6694
  shouldRevalidate: getShouldRevalidateFunction(
6251
6695
  routeModule,
@@ -6259,7 +6703,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6259
6703
  let hasInitialError = initialState && initialState.errors && route.id in initialState.errors;
6260
6704
  let initialError = hasInitialError ? initialState?.errors?.[route.id] : void 0;
6261
6705
  let isHydrationRequest = needsRevalidation == null && (routeModule.clientLoader?.hydrate === true || !route.hasLoader);
6262
- dataRoute.loader = async ({ request, params }, singleFetch) => {
6706
+ dataRoute.loader = async ({ request, params, context }, singleFetch) => {
6263
6707
  try {
6264
6708
  let result = await prefetchStylesAndCallHandler(async () => {
6265
6709
  invariant2(
@@ -6272,6 +6716,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6272
6716
  return routeModule.clientLoader({
6273
6717
  request,
6274
6718
  params,
6719
+ context,
6275
6720
  async serverLoader() {
6276
6721
  preventInvalidServerHandlerCall("loader", route);
6277
6722
  if (isHydrationRequest) {
@@ -6296,7 +6741,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6296
6741
  routeModule,
6297
6742
  isSpaMode
6298
6743
  );
6299
- dataRoute.action = ({ request, params }, singleFetch) => {
6744
+ dataRoute.action = ({ request, params, context }, singleFetch) => {
6300
6745
  return prefetchStylesAndCallHandler(async () => {
6301
6746
  invariant2(
6302
6747
  routeModule,
@@ -6311,6 +6756,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6311
6756
  return routeModule.clientAction({
6312
6757
  request,
6313
6758
  params,
6759
+ context,
6314
6760
  async serverAction() {
6315
6761
  preventInvalidServerHandlerCall("action", route);
6316
6762
  return fetchServerAction(singleFetch);
@@ -6320,7 +6766,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6320
6766
  };
6321
6767
  } else {
6322
6768
  if (!route.hasClientLoader) {
6323
- dataRoute.loader = ({ request }, singleFetch) => prefetchStylesAndCallHandler(() => {
6769
+ dataRoute.loader = (_, singleFetch) => prefetchStylesAndCallHandler(() => {
6324
6770
  return fetchServerLoader(singleFetch);
6325
6771
  });
6326
6772
  } else if (route.clientLoaderModule) {
@@ -6341,7 +6787,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6341
6787
  };
6342
6788
  }
6343
6789
  if (!route.hasClientAction) {
6344
- dataRoute.action = ({ request }, singleFetch) => prefetchStylesAndCallHandler(() => {
6790
+ dataRoute.action = (_, singleFetch) => prefetchStylesAndCallHandler(() => {
6345
6791
  if (isSpaMode) {
6346
6792
  throw noActionDefinedError("clientAction", route.id);
6347
6793
  }
@@ -6399,6 +6845,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6399
6845
  return {
6400
6846
  ...lazyRoute.loader ? { loader: lazyRoute.loader } : {},
6401
6847
  ...lazyRoute.action ? { action: lazyRoute.action } : {},
6848
+ unstable_middleware: mod.unstable_clientMiddleware,
6402
6849
  hasErrorBoundary: lazyRoute.hasErrorBoundary,
6403
6850
  shouldRevalidate: getShouldRevalidateFunction(
6404
6851
  lazyRoute,
@@ -6471,6 +6918,7 @@ async function loadRouteModuleWithBlockingLinks(route, routeModules) {
6471
6918
  return {
6472
6919
  Component: getRouteModuleComponent(routeModule),
6473
6920
  ErrorBoundary: routeModule.ErrorBoundary,
6921
+ unstable_clientMiddleware: routeModule.unstable_clientMiddleware,
6474
6922
  clientAction: routeModule.clientAction,
6475
6923
  clientLoader: routeModule.clientLoader,
6476
6924
  handle: routeModule.handle,
@@ -6526,12 +6974,13 @@ function getPatchRoutesOnNavigationFunction(manifest, routeModules, ssr, isSpaMo
6526
6974
  if (!isFogOfWarEnabled(ssr)) {
6527
6975
  return void 0;
6528
6976
  }
6529
- return async ({ path, patch, signal }) => {
6977
+ return async ({ path, patch, signal, fetcherKey }) => {
6530
6978
  if (discoveredPaths.has(path)) {
6531
6979
  return;
6532
6980
  }
6533
6981
  await fetchAndApplyManifestPatches(
6534
6982
  [path],
6983
+ fetcherKey ? window.location.href : path,
6535
6984
  manifest,
6536
6985
  routeModules,
6537
6986
  ssr,
@@ -6572,6 +7021,7 @@ function useFogOFWarDiscovery(router, manifest, routeModules, ssr, isSpaMode) {
6572
7021
  try {
6573
7022
  await fetchAndApplyManifestPatches(
6574
7023
  lazyPaths,
7024
+ null,
6575
7025
  manifest,
6576
7026
  routeModules,
6577
7027
  ssr,
@@ -6595,7 +7045,8 @@ function useFogOFWarDiscovery(router, manifest, routeModules, ssr, isSpaMode) {
6595
7045
  return () => observer.disconnect();
6596
7046
  }, [ssr, isSpaMode, manifest, routeModules, router]);
6597
7047
  }
6598
- async function fetchAndApplyManifestPatches(paths, manifest, routeModules, ssr, isSpaMode, basename, patchRoutes, signal) {
7048
+ var MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version";
7049
+ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, patchRoutes, signal) {
6599
7050
  let manifestPath = `${basename != null ? basename : "/"}/__manifest`.replace(
6600
7051
  /\/+/g,
6601
7052
  "/"
@@ -6612,9 +7063,26 @@ async function fetchAndApplyManifestPatches(paths, manifest, routeModules, ssr,
6612
7063
  let res = await fetch(url, { signal });
6613
7064
  if (!res.ok) {
6614
7065
  throw new Error(`${res.status} ${res.statusText}`);
7066
+ } else if (res.status === 204 && res.headers.has("X-Remix-Reload-Document")) {
7067
+ if (!errorReloadPath) {
7068
+ console.warn(
7069
+ "Detected a manifest version mismatch during eager route discovery. The next navigation/fetch to an undiscovered route will result in a new document navigation to sync up with the latest manifest."
7070
+ );
7071
+ return;
7072
+ }
7073
+ if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) {
7074
+ console.error(
7075
+ "Unable to discover routes due to manifest version mismatch."
7076
+ );
7077
+ return;
7078
+ }
7079
+ sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version);
7080
+ window.location.href = errorReloadPath;
7081
+ throw new Error("Detected manifest version mismatch, reloading...");
6615
7082
  } else if (res.status >= 400) {
6616
7083
  throw new Error(await res.text());
6617
7084
  }
7085
+ sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);
6618
7086
  serverPatches = await res.json();
6619
7087
  } catch (e) {
6620
7088
  if (signal?.aborted) return;
@@ -6768,7 +7236,7 @@ function Links() {
6768
7236
  () => getKeyedLinksForMatches(matches, routeModules, manifest),
6769
7237
  [matches, routeModules, manifest]
6770
7238
  );
6771
- return /* @__PURE__ */ React9.createElement(React9.Fragment, null, criticalCss ? /* @__PURE__ */ React9.createElement("style", { dangerouslySetInnerHTML: { __html: criticalCss } }) : null, keyedLinks.map(
7239
+ return /* @__PURE__ */ React9.createElement(React9.Fragment, null, typeof criticalCss === "string" ? /* @__PURE__ */ React9.createElement("style", { dangerouslySetInnerHTML: { __html: criticalCss } }) : null, typeof criticalCss === "object" ? /* @__PURE__ */ React9.createElement("link", { rel: "stylesheet", href: criticalCss.href }) : null, keyedLinks.map(
6772
7240
  ({ key, link }) => isPageLinkDescriptor(link) ? /* @__PURE__ */ React9.createElement(PrefetchPageLinks, { key, ...link }) : /* @__PURE__ */ React9.createElement("link", { key, ...link })
6773
7241
  ));
6774
7242
  }
@@ -6811,6 +7279,7 @@ function PrefetchPageLinksImpl({
6811
7279
  }) {
6812
7280
  let location = useLocation();
6813
7281
  let { manifest, routeModules } = useFrameworkContext();
7282
+ let { basename } = useDataRouterContext2();
6814
7283
  let { loaderData, matches } = useDataRouterStateContext();
6815
7284
  let newMatchesForData = React9.useMemo(
6816
7285
  () => getNewMatchesForLinks(
@@ -6856,7 +7325,7 @@ function PrefetchPageLinksImpl({
6856
7325
  if (routesParams.size === 0) {
6857
7326
  return [];
6858
7327
  }
6859
- let url = singleFetchUrl(page);
7328
+ let url = singleFetchUrl(page, basename);
6860
7329
  if (foundOptOutRoute && routesParams.size > 0) {
6861
7330
  url.searchParams.set(
6862
7331
  "_routes",
@@ -6865,6 +7334,7 @@ function PrefetchPageLinksImpl({
6865
7334
  }
6866
7335
  return [url.pathname + url.search];
6867
7336
  }, [
7337
+ basename,
6868
7338
  loaderData,
6869
7339
  location,
6870
7340
  manifest,
@@ -7118,13 +7588,14 @@ function mergeRefs(...refs) {
7118
7588
  var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
7119
7589
  try {
7120
7590
  if (isBrowser) {
7121
- window.__reactRouterVersion = "7.2.0";
7591
+ window.__reactRouterVersion = "7.3.0-pre.0";
7122
7592
  }
7123
7593
  } catch (e) {
7124
7594
  }
7125
7595
  function createBrowserRouter(routes, opts) {
7126
7596
  return createRouter({
7127
7597
  basename: opts?.basename,
7598
+ unstable_getContext: opts?.unstable_getContext,
7128
7599
  future: opts?.future,
7129
7600
  history: createBrowserHistory({ window: opts?.window }),
7130
7601
  hydrationData: opts?.hydrationData || parseHydrationData(),
@@ -7138,6 +7609,7 @@ function createBrowserRouter(routes, opts) {
7138
7609
  function createHashRouter(routes, opts) {
7139
7610
  return createRouter({
7140
7611
  basename: opts?.basename,
7612
+ unstable_getContext: opts?.unstable_getContext,
7141
7613
  future: opts?.future,
7142
7614
  history: createHashHistory({ window: opts?.window }),
7143
7615
  hydrationData: opts?.hydrationData || parseHydrationData(),
@@ -8096,6 +8568,7 @@ function createStaticRouter(routes, context, opts = {}) {
8096
8568
  },
8097
8569
  get future() {
8098
8570
  return {
8571
+ unstable_middleware: false,
8099
8572
  ...opts?.future
8100
8573
  };
8101
8574
  },
@@ -8258,7 +8731,7 @@ function ServerRouter({
8258
8731
 
8259
8732
  // lib/dom/ssr/routes-test-stub.tsx
8260
8733
  import * as React13 from "react";
8261
- function createRoutesStub(routes, context = {}) {
8734
+ function createRoutesStub(routes, unstable_getContext) {
8262
8735
  return function RoutesTestStub({
8263
8736
  initialEntries,
8264
8737
  initialIndex,
@@ -8269,7 +8742,9 @@ function createRoutesStub(routes, context = {}) {
8269
8742
  let remixContextRef = React13.useRef();
8270
8743
  if (routerRef.current == null) {
8271
8744
  remixContextRef.current = {
8272
- future: {},
8745
+ future: {
8746
+ unstable_middleware: future?.unstable_middleware === true
8747
+ },
8273
8748
  manifest: {
8274
8749
  routes: {},
8275
8750
  entry: { imports: [], module: "" },
@@ -8281,13 +8756,14 @@ function createRoutesStub(routes, context = {}) {
8281
8756
  isSpaMode: false
8282
8757
  };
8283
8758
  let patched = processRoutes(
8284
- // @ts-expect-error loader/action context types don't match :/
8759
+ // @ts-expect-error `StubRouteObject` is stricter about `loader`/`action`
8760
+ // types compared to `AgnosticRouteObject`
8285
8761
  convertRoutesToDataRoutes(routes, (r) => r),
8286
- context,
8287
8762
  remixContextRef.current.manifest,
8288
8763
  remixContextRef.current.routeModules
8289
8764
  );
8290
8765
  routerRef.current = createMemoryRouter(patched, {
8766
+ unstable_getContext,
8291
8767
  initialEntries,
8292
8768
  initialIndex,
8293
8769
  hydrationData
@@ -8296,14 +8772,13 @@ function createRoutesStub(routes, context = {}) {
8296
8772
  return /* @__PURE__ */ React13.createElement(FrameworkContext.Provider, { value: remixContextRef.current }, /* @__PURE__ */ React13.createElement(RouterProvider, { router: routerRef.current }));
8297
8773
  };
8298
8774
  }
8299
- function processRoutes(routes, context, manifest, routeModules, parentId) {
8775
+ function processRoutes(routes, manifest, routeModules, parentId) {
8300
8776
  return routes.map((route) => {
8301
8777
  if (!route.id) {
8302
8778
  throw new Error(
8303
8779
  "Expected a route.id in @remix-run/testing processRoutes() function"
8304
8780
  );
8305
8781
  }
8306
- let { loader, action } = route;
8307
8782
  let newRoute = {
8308
8783
  id: route.id,
8309
8784
  path: route.path,
@@ -8311,8 +8786,8 @@ function processRoutes(routes, context, manifest, routeModules, parentId) {
8311
8786
  Component: route.Component,
8312
8787
  HydrateFallback: route.HydrateFallback,
8313
8788
  ErrorBoundary: route.ErrorBoundary,
8314
- action: action ? (args) => action({ ...args, context }) : void 0,
8315
- loader: loader ? (args) => loader({ ...args, context }) : void 0,
8789
+ action: route.action,
8790
+ loader: route.loader,
8316
8791
  handle: route.handle,
8317
8792
  shouldRevalidate: route.shouldRevalidate
8318
8793
  };
@@ -8347,7 +8822,6 @@ function processRoutes(routes, context, manifest, routeModules, parentId) {
8347
8822
  if (route.children) {
8348
8823
  newRoute.children = processRoutes(
8349
8824
  route.children,
8350
- context,
8351
8825
  manifest,
8352
8826
  routeModules,
8353
8827
  newRoute.id
@@ -8708,6 +9182,7 @@ function createStaticHandlerDataRoutes(manifest, future, parentId = "", routesBy
8708
9182
  hasErrorBoundary: route.id === "root" || route.module.ErrorBoundary != null,
8709
9183
  id: route.id,
8710
9184
  path: route.path,
9185
+ unstable_middleware: route.module.unstable_middleware,
8711
9186
  // Need to use RR's version in the param typed here to permit the optional
8712
9187
  // context even though we know it'll always be provided in remix
8713
9188
  loader: route.module.loader ? async (args) => {
@@ -8853,27 +9328,46 @@ function prependCookies(parentHeaders, childHeaders) {
8853
9328
  }
8854
9329
 
8855
9330
  // lib/server-runtime/single-fetch.ts
9331
+ var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([100, 101, 204, 205, 304]);
8856
9332
  var SINGLE_FETCH_REDIRECT_STATUS = 202;
8857
- function getSingleFetchDataStrategy2({
8858
- isActionDataRequest,
8859
- loadRouteIds
8860
- } = {}) {
8861
- return async ({ request, matches }) => {
8862
- if (isActionDataRequest && request.method === "GET") {
8863
- return {};
8864
- }
8865
- let matchesToLoad = loadRouteIds ? matches.filter((m) => loadRouteIds.includes(m.route.id)) : matches;
8866
- let results = await Promise.all(
8867
- matchesToLoad.map((match) => match.resolve())
8868
- );
8869
- return results.reduce(
8870
- (acc, result, i) => Object.assign(acc, { [matchesToLoad[i].route.id]: result }),
8871
- {}
8872
- );
8873
- };
8874
- }
8875
9333
  async function singleFetchAction(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError) {
8876
9334
  try {
9335
+ let respond2 = function(context) {
9336
+ let headers = getDocumentHeaders(build, context);
9337
+ if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
9338
+ return generateSingleFetchResponse(request, build, serverMode, {
9339
+ result: getSingleFetchRedirect(
9340
+ context.statusCode,
9341
+ headers,
9342
+ build.basename
9343
+ ),
9344
+ headers,
9345
+ status: SINGLE_FETCH_REDIRECT_STATUS
9346
+ });
9347
+ }
9348
+ if (context.errors) {
9349
+ Object.values(context.errors).forEach((err) => {
9350
+ if (!isRouteErrorResponse(err) || err.error) {
9351
+ handleError(err);
9352
+ }
9353
+ });
9354
+ context.errors = sanitizeErrors(context.errors, serverMode);
9355
+ }
9356
+ let singleFetchResult;
9357
+ if (context.errors) {
9358
+ singleFetchResult = { error: Object.values(context.errors)[0] };
9359
+ } else {
9360
+ singleFetchResult = {
9361
+ data: Object.values(context.actionData || {})[0]
9362
+ };
9363
+ }
9364
+ return generateSingleFetchResponse(request, build, serverMode, {
9365
+ result: singleFetchResult,
9366
+ headers,
9367
+ status: context.statusCode
9368
+ });
9369
+ };
9370
+ var respond = respond2;
8877
9371
  let handlerRequest = new Request(handlerUrl, {
8878
9372
  method: request.method,
8879
9373
  body: request.body,
@@ -8884,12 +9378,14 @@ async function singleFetchAction(build, serverMode, staticHandler, request, hand
8884
9378
  let result = await staticHandler.query(handlerRequest, {
8885
9379
  requestContext: loadContext,
8886
9380
  skipLoaderErrorBubbling: true,
8887
- dataStrategy: getSingleFetchDataStrategy2({
8888
- isActionDataRequest: true
8889
- })
9381
+ skipRevalidation: true,
9382
+ unstable_respond: respond2
8890
9383
  });
8891
- if (isResponse(result)) {
8892
- return {
9384
+ if (!isResponse(result)) {
9385
+ result = respond2(result);
9386
+ }
9387
+ if (isRedirectResponse(result)) {
9388
+ return generateSingleFetchResponse(request, build, serverMode, {
8893
9389
  result: getSingleFetchRedirect(
8894
9390
  result.status,
8895
9391
  result.headers,
@@ -8897,65 +9393,83 @@ async function singleFetchAction(build, serverMode, staticHandler, request, hand
8897
9393
  ),
8898
9394
  headers: result.headers,
8899
9395
  status: SINGLE_FETCH_REDIRECT_STATUS
8900
- };
8901
- }
8902
- let context = result;
8903
- let headers = getDocumentHeaders(build, context);
8904
- if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
8905
- return {
8906
- result: getSingleFetchRedirect(
8907
- context.statusCode,
8908
- headers,
8909
- build.basename
8910
- ),
8911
- headers,
8912
- status: SINGLE_FETCH_REDIRECT_STATUS
8913
- };
8914
- }
8915
- if (context.errors) {
8916
- Object.values(context.errors).forEach((err) => {
8917
- if (!isRouteErrorResponse(err) || err.error) {
8918
- handleError(err);
8919
- }
8920
9396
  });
8921
- context.errors = sanitizeErrors(context.errors, serverMode);
8922
9397
  }
8923
- let singleFetchResult;
8924
- if (context.errors) {
8925
- singleFetchResult = { error: Object.values(context.errors)[0] };
8926
- } else {
8927
- singleFetchResult = { data: Object.values(context.actionData || {})[0] };
8928
- }
8929
- return {
8930
- result: singleFetchResult,
8931
- headers,
8932
- status: context.statusCode
8933
- };
9398
+ return result;
8934
9399
  } catch (error) {
8935
9400
  handleError(error);
8936
- return {
9401
+ return generateSingleFetchResponse(request, build, serverMode, {
8937
9402
  result: { error },
8938
9403
  headers: new Headers(),
8939
9404
  status: 500
8940
- };
9405
+ });
8941
9406
  }
8942
9407
  }
8943
9408
  async function singleFetchLoaders(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError) {
8944
9409
  try {
9410
+ let respond2 = function(context) {
9411
+ let headers = getDocumentHeaders(build, context);
9412
+ if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
9413
+ return generateSingleFetchResponse(request, build, serverMode, {
9414
+ result: {
9415
+ [SingleFetchRedirectSymbol]: getSingleFetchRedirect(
9416
+ context.statusCode,
9417
+ headers,
9418
+ build.basename
9419
+ )
9420
+ },
9421
+ headers,
9422
+ status: SINGLE_FETCH_REDIRECT_STATUS
9423
+ });
9424
+ }
9425
+ if (context.errors) {
9426
+ Object.values(context.errors).forEach((err) => {
9427
+ if (!isRouteErrorResponse(err) || err.error) {
9428
+ handleError(err);
9429
+ }
9430
+ });
9431
+ context.errors = sanitizeErrors(context.errors, serverMode);
9432
+ }
9433
+ let results = {};
9434
+ let loadedMatches = new Set(
9435
+ context.matches.filter(
9436
+ (m) => loadRouteIds ? loadRouteIds.has(m.route.id) : m.route.loader != null
9437
+ ).map((m) => m.route.id)
9438
+ );
9439
+ if (context.errors) {
9440
+ for (let [id, error] of Object.entries(context.errors)) {
9441
+ results[id] = { error };
9442
+ }
9443
+ }
9444
+ for (let [id, data2] of Object.entries(context.loaderData)) {
9445
+ if (!(id in results) && loadedMatches.has(id)) {
9446
+ results[id] = { data: data2 };
9447
+ }
9448
+ }
9449
+ return generateSingleFetchResponse(request, build, serverMode, {
9450
+ result: results,
9451
+ headers,
9452
+ status: context.statusCode
9453
+ });
9454
+ };
9455
+ var respond = respond2;
8945
9456
  let handlerRequest = new Request(handlerUrl, {
8946
9457
  headers: request.headers,
8947
9458
  signal: request.signal
8948
9459
  });
8949
- let loadRouteIds = new URL(request.url).searchParams.get("_routes")?.split(",") || void 0;
9460
+ let routesParam = new URL(request.url).searchParams.get("_routes");
9461
+ let loadRouteIds = routesParam ? new Set(routesParam.split(",")) : null;
8950
9462
  let result = await staticHandler.query(handlerRequest, {
8951
9463
  requestContext: loadContext,
9464
+ filterMatchesToLoad: (m) => !loadRouteIds || loadRouteIds.has(m.route.id),
8952
9465
  skipLoaderErrorBubbling: true,
8953
- dataStrategy: getSingleFetchDataStrategy2({
8954
- loadRouteIds
8955
- })
9466
+ unstable_respond: respond2
8956
9467
  });
8957
- if (isResponse(result)) {
8958
- return {
9468
+ if (!isResponse(result)) {
9469
+ result = respond2(result);
9470
+ }
9471
+ if (isRedirectResponse(result)) {
9472
+ return generateSingleFetchResponse(request, build, serverMode, {
8959
9473
  result: {
8960
9474
  [SingleFetchRedirectSymbol]: getSingleFetchRedirect(
8961
9475
  result.status,
@@ -8965,57 +9479,42 @@ async function singleFetchLoaders(build, serverMode, staticHandler, request, han
8965
9479
  },
8966
9480
  headers: result.headers,
8967
9481
  status: SINGLE_FETCH_REDIRECT_STATUS
8968
- };
8969
- }
8970
- let context = result;
8971
- let headers = getDocumentHeaders(build, context);
8972
- if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
8973
- return {
8974
- result: {
8975
- [SingleFetchRedirectSymbol]: getSingleFetchRedirect(
8976
- context.statusCode,
8977
- headers,
8978
- build.basename
8979
- )
8980
- },
8981
- headers,
8982
- status: SINGLE_FETCH_REDIRECT_STATUS
8983
- };
8984
- }
8985
- if (context.errors) {
8986
- Object.values(context.errors).forEach((err) => {
8987
- if (!isRouteErrorResponse(err) || err.error) {
8988
- handleError(err);
8989
- }
8990
9482
  });
8991
- context.errors = sanitizeErrors(context.errors, serverMode);
8992
9483
  }
8993
- let results = {};
8994
- let loadedMatches = loadRouteIds ? context.matches.filter(
8995
- (m) => m.route.loader && loadRouteIds.includes(m.route.id)
8996
- ) : context.matches;
8997
- loadedMatches.forEach((m) => {
8998
- let { id } = m.route;
8999
- if (context.errors && context.errors.hasOwnProperty(id)) {
9000
- results[id] = { error: context.errors[id] };
9001
- } else if (context.loaderData.hasOwnProperty(id)) {
9002
- results[id] = { data: context.loaderData[id] };
9003
- }
9004
- });
9005
- return {
9006
- result: results,
9007
- headers,
9008
- status: context.statusCode
9009
- };
9484
+ return result;
9010
9485
  } catch (error) {
9011
9486
  handleError(error);
9012
- return {
9487
+ return generateSingleFetchResponse(request, build, serverMode, {
9013
9488
  result: { root: { error } },
9014
9489
  headers: new Headers(),
9015
9490
  status: 500
9016
- };
9491
+ });
9017
9492
  }
9018
9493
  }
9494
+ function generateSingleFetchResponse(request, build, serverMode, {
9495
+ result,
9496
+ headers,
9497
+ status
9498
+ }) {
9499
+ let resultHeaders = new Headers(headers);
9500
+ resultHeaders.set("X-Remix-Response", "yes");
9501
+ if (NO_BODY_STATUS_CODES.has(status)) {
9502
+ return new Response(null, { status, headers: resultHeaders });
9503
+ }
9504
+ resultHeaders.set("Content-Type", "text/x-script");
9505
+ return new Response(
9506
+ encodeViaTurboStream(
9507
+ result,
9508
+ request.signal,
9509
+ build.entry.module.streamTimeout,
9510
+ serverMode
9511
+ ),
9512
+ {
9513
+ status: status || 200,
9514
+ headers: resultHeaders
9515
+ }
9516
+ );
9517
+ }
9019
9518
  function getSingleFetchRedirect(status, headers, basename) {
9020
9519
  let redirect2 = headers.get("Location");
9021
9520
  if (basename) {
@@ -9077,7 +9576,6 @@ function encodeViaTurboStream(data2, requestSignal, streamTimeout, serverMode) {
9077
9576
  }
9078
9577
 
9079
9578
  // lib/server-runtime/server.ts
9080
- var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([100, 101, 204, 205, 304]);
9081
9579
  function derive(build, mode) {
9082
9580
  let routes = createRoutes(build.routes);
9083
9581
  let dataRoutes = createStaticHandlerDataRoutes(build.routes, build.future);
@@ -9107,8 +9605,11 @@ var createRequestHandler = (build, mode) => {
9107
9605
  let serverMode;
9108
9606
  let staticHandler;
9109
9607
  let errorHandler;
9110
- return async function requestHandler(request, loadContext = {}) {
9608
+ return async function requestHandler(request, initialContext) {
9111
9609
  _build = typeof build === "function" ? await build() : build;
9610
+ let loadContext = _build.future.unstable_middleware ? new unstable_RouterContextProvider(
9611
+ initialContext
9612
+ ) : initialContext || {};
9112
9613
  if (typeof build === "function") {
9113
9614
  let derived = derive(_build, mode);
9114
9615
  routes = derived.routes;
@@ -9123,8 +9624,14 @@ var createRequestHandler = (build, mode) => {
9123
9624
  errorHandler = derived.errorHandler;
9124
9625
  }
9125
9626
  let url = new URL(request.url);
9126
- let normalizedPath = url.pathname.replace(/\.data$/, "").replace(/^\/_root$/, "/");
9127
- if (normalizedPath !== "/" && normalizedPath.endsWith("/")) {
9627
+ let normalizedBasename = _build.basename || "/";
9628
+ let normalizedPath = url.pathname;
9629
+ if (stripBasename(normalizedPath, normalizedBasename) === "/_root.data") {
9630
+ normalizedPath = normalizedBasename;
9631
+ } else if (normalizedPath.endsWith(".data")) {
9632
+ normalizedPath = normalizedPath.replace(/\.data$/, "");
9633
+ }
9634
+ if (stripBasename(normalizedPath, normalizedBasename) !== "/" && normalizedPath.endsWith("/")) {
9128
9635
  normalizedPath = normalizedPath.slice(0, -1);
9129
9636
  }
9130
9637
  let params = {};
@@ -9164,10 +9671,7 @@ var createRequestHandler = (build, mode) => {
9164
9671
  }
9165
9672
  }
9166
9673
  }
9167
- let manifestUrl = `${_build.basename ?? "/"}/__manifest`.replace(
9168
- /\/+/g,
9169
- "/"
9170
- );
9674
+ let manifestUrl = `${normalizedBasename}/__manifest`.replace(/\/+/g, "/");
9171
9675
  if (url.pathname === manifestUrl) {
9172
9676
  try {
9173
9677
  let res = await handleManifestRequest(_build, routes, url);
@@ -9232,9 +9736,10 @@ var createRequestHandler = (build, mode) => {
9232
9736
  );
9233
9737
  }
9234
9738
  }
9235
- } else if (matches && matches[matches.length - 1].route.module.default == null && matches[matches.length - 1].route.module.ErrorBoundary == null) {
9739
+ } else if (!request.headers.has("X-React-Router-SPA-Mode") && matches && matches[matches.length - 1].route.module.default == null && matches[matches.length - 1].route.module.ErrorBoundary == null) {
9236
9740
  response = await handleResourceRequest(
9237
9741
  serverMode,
9742
+ _build,
9238
9743
  staticHandler,
9239
9744
  matches.slice(-1)[0].route.id,
9240
9745
  request,
@@ -9242,7 +9747,13 @@ var createRequestHandler = (build, mode) => {
9242
9747
  handleError
9243
9748
  );
9244
9749
  } else {
9245
- let criticalCss = mode === "development" /* Development */ ? await getDevServerHooks()?.getCriticalCss?.(_build, url.pathname) : void 0;
9750
+ let { pathname } = url;
9751
+ let criticalCss = void 0;
9752
+ if (_build.getCriticalCss) {
9753
+ criticalCss = await _build.getCriticalCss({ pathname });
9754
+ } else if (mode === "development" /* Development */ && getDevServerHooks()?.getCriticalCss) {
9755
+ criticalCss = await getDevServerHooks()?.getCriticalCss?.(pathname);
9756
+ }
9246
9757
  response = await handleDocumentRequest(
9247
9758
  serverMode,
9248
9759
  _build,
@@ -9264,6 +9775,14 @@ var createRequestHandler = (build, mode) => {
9264
9775
  };
9265
9776
  };
9266
9777
  async function handleManifestRequest(build, routes, url) {
9778
+ if (build.assets.version !== url.searchParams.get("version")) {
9779
+ return new Response(null, {
9780
+ status: 204,
9781
+ headers: {
9782
+ "X-Remix-Reload-Document": "true"
9783
+ }
9784
+ });
9785
+ }
9267
9786
  let patches = {};
9268
9787
  if (url.searchParams.has("p")) {
9269
9788
  for (let path of url.searchParams.getAll("p")) {
@@ -9287,7 +9806,7 @@ async function handleManifestRequest(build, routes, url) {
9287
9806
  return new Response("Invalid Request", { status: 400 });
9288
9807
  }
9289
9808
  async function handleSingleFetchRequest(serverMode, build, staticHandler, request, handlerUrl, loadContext, handleError) {
9290
- let { result, headers, status } = request.method !== "GET" ? await singleFetchAction(
9809
+ let response = request.method !== "GET" ? await singleFetchAction(
9291
9810
  build,
9292
9811
  serverMode,
9293
9812
  staticHandler,
@@ -9304,133 +9823,66 @@ async function handleSingleFetchRequest(serverMode, build, staticHandler, reques
9304
9823
  loadContext,
9305
9824
  handleError
9306
9825
  );
9307
- let resultHeaders = new Headers(headers);
9308
- resultHeaders.set("X-Remix-Response", "yes");
9309
- if (NO_BODY_STATUS_CODES.has(status)) {
9310
- return new Response(null, { status, headers: resultHeaders });
9311
- }
9312
- resultHeaders.set("Content-Type", "text/x-script");
9313
- return new Response(
9314
- encodeViaTurboStream(
9315
- result,
9316
- request.signal,
9317
- build.entry.module.streamTimeout,
9318
- serverMode
9319
- ),
9320
- {
9321
- status: status || 200,
9322
- headers: resultHeaders
9323
- }
9324
- );
9826
+ return response;
9325
9827
  }
9326
9828
  async function handleDocumentRequest(serverMode, build, staticHandler, request, loadContext, handleError, criticalCss) {
9327
9829
  let isSpaMode = request.headers.has("X-React-Router-SPA-Mode");
9328
- let context;
9329
9830
  try {
9330
- context = await staticHandler.query(request, {
9331
- requestContext: loadContext
9831
+ let response = await staticHandler.query(request, {
9832
+ requestContext: loadContext,
9833
+ unstable_respond: build.future.unstable_middleware ? (ctx) => renderHtml(ctx, isSpaMode) : void 0
9332
9834
  });
9835
+ return isResponse(response) ? response : renderHtml(response, isSpaMode);
9333
9836
  } catch (error) {
9334
9837
  handleError(error);
9335
9838
  return new Response(null, { status: 500 });
9336
9839
  }
9337
- if (isResponse(context)) {
9338
- return context;
9339
- }
9340
- let headers = getDocumentHeaders(build, context);
9341
- if (NO_BODY_STATUS_CODES.has(context.statusCode)) {
9342
- return new Response(null, { status: context.statusCode, headers });
9343
- }
9344
- if (context.errors) {
9345
- Object.values(context.errors).forEach((err) => {
9346
- if (!isRouteErrorResponse(err) || err.error) {
9347
- handleError(err);
9348
- }
9349
- });
9350
- context.errors = sanitizeErrors(context.errors, serverMode);
9351
- }
9352
- let state = {
9353
- loaderData: context.loaderData,
9354
- actionData: context.actionData,
9355
- errors: serializeErrors2(context.errors, serverMode)
9356
- };
9357
- let entryContext = {
9358
- manifest: build.assets,
9359
- routeModules: createEntryRouteModules(build.routes),
9360
- staticHandlerContext: context,
9361
- criticalCss,
9362
- serverHandoffString: createServerHandoffString({
9363
- basename: build.basename,
9364
- criticalCss,
9365
- future: build.future,
9366
- ssr: build.ssr,
9367
- isSpaMode
9368
- }),
9369
- serverHandoffStream: encodeViaTurboStream(
9370
- state,
9371
- request.signal,
9372
- build.entry.module.streamTimeout,
9373
- serverMode
9374
- ),
9375
- renderMeta: {},
9376
- future: build.future,
9377
- ssr: build.ssr,
9378
- isSpaMode,
9379
- serializeError: (err) => serializeError(err, serverMode)
9380
- };
9381
- let handleDocumentRequestFunction = build.entry.module.default;
9382
- try {
9383
- return await handleDocumentRequestFunction(
9384
- request,
9385
- context.statusCode,
9386
- headers,
9387
- entryContext,
9388
- loadContext
9389
- );
9390
- } catch (error) {
9391
- handleError(error);
9392
- let errorForSecondRender = error;
9393
- if (isResponse(error)) {
9394
- try {
9395
- let data2 = await unwrapResponse(error);
9396
- errorForSecondRender = new ErrorResponseImpl(
9397
- error.status,
9398
- error.statusText,
9399
- data2
9400
- );
9401
- } catch (e) {
9402
- }
9840
+ async function renderHtml(context, isSpaMode2) {
9841
+ if (isResponse(context)) {
9842
+ return context;
9843
+ }
9844
+ let headers = getDocumentHeaders(build, context);
9845
+ if (NO_BODY_STATUS_CODES.has(context.statusCode)) {
9846
+ return new Response(null, { status: context.statusCode, headers });
9403
9847
  }
9404
- context = getStaticContextFromError(
9405
- staticHandler.dataRoutes,
9406
- context,
9407
- errorForSecondRender
9408
- );
9409
9848
  if (context.errors) {
9849
+ Object.values(context.errors).forEach((err) => {
9850
+ if (!isRouteErrorResponse(err) || err.error) {
9851
+ handleError(err);
9852
+ }
9853
+ });
9410
9854
  context.errors = sanitizeErrors(context.errors, serverMode);
9411
9855
  }
9412
- let state2 = {
9856
+ let state = {
9413
9857
  loaderData: context.loaderData,
9414
9858
  actionData: context.actionData,
9415
9859
  errors: serializeErrors2(context.errors, serverMode)
9416
9860
  };
9417
- entryContext = {
9418
- ...entryContext,
9861
+ let entryContext = {
9862
+ manifest: build.assets,
9863
+ routeModules: createEntryRouteModules(build.routes),
9419
9864
  staticHandlerContext: context,
9865
+ criticalCss,
9420
9866
  serverHandoffString: createServerHandoffString({
9421
9867
  basename: build.basename,
9868
+ criticalCss,
9422
9869
  future: build.future,
9423
9870
  ssr: build.ssr,
9424
- isSpaMode
9871
+ isSpaMode: isSpaMode2
9425
9872
  }),
9426
9873
  serverHandoffStream: encodeViaTurboStream(
9427
- state2,
9874
+ state,
9428
9875
  request.signal,
9429
9876
  build.entry.module.streamTimeout,
9430
9877
  serverMode
9431
9878
  ),
9432
- renderMeta: {}
9879
+ renderMeta: {},
9880
+ future: build.future,
9881
+ ssr: build.ssr,
9882
+ isSpaMode: isSpaMode2,
9883
+ serializeError: (err) => serializeError(err, serverMode)
9433
9884
  };
9885
+ let handleDocumentRequestFunction = build.entry.module.default;
9434
9886
  try {
9435
9887
  return await handleDocumentRequestFunction(
9436
9888
  request,
@@ -9439,17 +9891,71 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
9439
9891
  entryContext,
9440
9892
  loadContext
9441
9893
  );
9442
- } catch (error2) {
9443
- handleError(error2);
9444
- return returnLastResortErrorResponse(error2, serverMode);
9894
+ } catch (error) {
9895
+ handleError(error);
9896
+ let errorForSecondRender = error;
9897
+ if (isResponse(error)) {
9898
+ try {
9899
+ let data2 = await unwrapResponse(error);
9900
+ errorForSecondRender = new ErrorResponseImpl(
9901
+ error.status,
9902
+ error.statusText,
9903
+ data2
9904
+ );
9905
+ } catch (e) {
9906
+ }
9907
+ }
9908
+ context = getStaticContextFromError(
9909
+ staticHandler.dataRoutes,
9910
+ context,
9911
+ errorForSecondRender
9912
+ );
9913
+ if (context.errors) {
9914
+ context.errors = sanitizeErrors(context.errors, serverMode);
9915
+ }
9916
+ let state2 = {
9917
+ loaderData: context.loaderData,
9918
+ actionData: context.actionData,
9919
+ errors: serializeErrors2(context.errors, serverMode)
9920
+ };
9921
+ entryContext = {
9922
+ ...entryContext,
9923
+ staticHandlerContext: context,
9924
+ serverHandoffString: createServerHandoffString({
9925
+ basename: build.basename,
9926
+ future: build.future,
9927
+ ssr: build.ssr,
9928
+ isSpaMode: isSpaMode2
9929
+ }),
9930
+ serverHandoffStream: encodeViaTurboStream(
9931
+ state2,
9932
+ request.signal,
9933
+ build.entry.module.streamTimeout,
9934
+ serverMode
9935
+ ),
9936
+ renderMeta: {}
9937
+ };
9938
+ try {
9939
+ return await handleDocumentRequestFunction(
9940
+ request,
9941
+ context.statusCode,
9942
+ headers,
9943
+ entryContext,
9944
+ loadContext
9945
+ );
9946
+ } catch (error2) {
9947
+ handleError(error2);
9948
+ return returnLastResortErrorResponse(error2, serverMode);
9949
+ }
9445
9950
  }
9446
9951
  }
9447
9952
  }
9448
- async function handleResourceRequest(serverMode, staticHandler, routeId, request, loadContext, handleError) {
9953
+ async function handleResourceRequest(serverMode, build, staticHandler, routeId, request, loadContext, handleError) {
9449
9954
  try {
9450
9955
  let response = await staticHandler.queryRoute(request, {
9451
9956
  routeId,
9452
- requestContext: loadContext
9957
+ requestContext: loadContext,
9958
+ unstable_respond: build.future.unstable_middleware ? (ctx) => ctx : void 0
9453
9959
  });
9454
9960
  if (isResponse(response)) {
9455
9961
  return response;
@@ -9469,6 +9975,13 @@ async function handleResourceRequest(serverMode, staticHandler, routeId, request
9469
9975
  }
9470
9976
  return errorResponseToJson(error, serverMode);
9471
9977
  }
9978
+ if (error instanceof Error && error.message === "Expected a response from queryRoute") {
9979
+ let newError = new Error(
9980
+ "Expected a Response to be returned from resource route handler"
9981
+ );
9982
+ handleError(newError);
9983
+ return returnLastResortErrorResponse(newError, serverMode);
9984
+ }
9472
9985
  handleError(error);
9473
9986
  return returnLastResortErrorResponse(error, serverMode);
9474
9987
  }
@@ -9709,6 +10222,8 @@ export {
9709
10222
  invariant,
9710
10223
  createPath,
9711
10224
  parsePath,
10225
+ unstable_createContext,
10226
+ unstable_RouterContextProvider,
9712
10227
  matchRoutes,
9713
10228
  generatePath,
9714
10229
  matchPath,