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
  *
@@ -15,6 +15,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
15
15
  var __getOwnPropNames = Object.getOwnPropertyNames;
16
16
  var __getProtoOf = Object.getPrototypeOf;
17
17
  var __hasOwnProp = Object.prototype.hasOwnProperty;
18
+ var __typeError = (msg) => {
19
+ throw TypeError(msg);
20
+ };
18
21
  var __export = (target, all) => {
19
22
  for (var name in all)
20
23
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -36,6 +39,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
36
39
  mod
37
40
  ));
38
41
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
42
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
43
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
44
+ 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);
39
45
 
40
46
  // index.ts
41
47
  var react_router_exports = {};
@@ -121,6 +127,8 @@ __export(react_router_exports, {
121
127
  replace: () => replace,
122
128
  resolvePath: () => resolvePath,
123
129
  unstable_HistoryRouter: () => HistoryRouter,
130
+ unstable_RouterContextProvider: () => unstable_RouterContextProvider,
131
+ unstable_createContext: () => unstable_createContext,
124
132
  unstable_setDevServerHooks: () => setDevServerHooks,
125
133
  unstable_usePrompt: () => usePrompt,
126
134
  useActionData: () => useActionData,
@@ -496,6 +504,33 @@ function getUrlBasedHistory(getLocation, createHref2, validateLocation, options
496
504
  }
497
505
 
498
506
  // lib/router/utils.ts
507
+ function unstable_createContext(defaultValue) {
508
+ return { defaultValue };
509
+ }
510
+ var _map;
511
+ var unstable_RouterContextProvider = class {
512
+ constructor(init) {
513
+ __privateAdd(this, _map, /* @__PURE__ */ new Map());
514
+ if (init) {
515
+ for (let [context, value] of init) {
516
+ this.set(context, value);
517
+ }
518
+ }
519
+ }
520
+ get(context) {
521
+ if (__privateGet(this, _map).has(context)) {
522
+ return __privateGet(this, _map).get(context);
523
+ }
524
+ if (context.defaultValue !== void 0) {
525
+ return context.defaultValue;
526
+ }
527
+ throw new Error("No value found for context");
528
+ }
529
+ set(context, value) {
530
+ __privateGet(this, _map).set(context, value);
531
+ }
532
+ };
533
+ _map = new WeakMap();
499
534
  var immutableRouteKeys = /* @__PURE__ */ new Set([
500
535
  "lazy",
501
536
  "caseSensitive",
@@ -1053,9 +1088,9 @@ function createRouter(init) {
1053
1088
  );
1054
1089
  let inFlightDataRoutes;
1055
1090
  let basename = init.basename || "/";
1056
- let dataStrategyImpl = init.dataStrategy || defaultDataStrategy;
1057
- let patchRoutesOnNavigationImpl = init.patchRoutesOnNavigation;
1091
+ let dataStrategyImpl = init.dataStrategy || defaultDataStrategyWithMiddleware;
1058
1092
  let future = {
1093
+ unstable_middleware: false,
1059
1094
  ...init.future
1060
1095
  };
1061
1096
  let unlistenHistory = null;
@@ -1067,7 +1102,7 @@ function createRouter(init) {
1067
1102
  let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);
1068
1103
  let initialMatchesIsFOW = false;
1069
1104
  let initialErrors = null;
1070
- if (initialMatches == null && !patchRoutesOnNavigationImpl) {
1105
+ if (initialMatches == null && !init.patchRoutesOnNavigation) {
1071
1106
  let error = getInternalRouterError(404, {
1072
1107
  pathname: init.history.location.pathname
1073
1108
  });
@@ -1498,6 +1533,9 @@ function createRouter(init) {
1498
1533
  pendingNavigationController.signal,
1499
1534
  opts && opts.submission
1500
1535
  );
1536
+ let scopedContext = new unstable_RouterContextProvider(
1537
+ init.unstable_getContext ? await init.unstable_getContext() : void 0
1538
+ );
1501
1539
  let pendingActionResult;
1502
1540
  if (opts && opts.pendingError) {
1503
1541
  pendingActionResult = [
@@ -1510,6 +1548,7 @@ function createRouter(init) {
1510
1548
  location,
1511
1549
  opts.submission,
1512
1550
  matches,
1551
+ scopedContext,
1513
1552
  fogOfWar.active,
1514
1553
  { replace: opts.replace, flushSync }
1515
1554
  );
@@ -1550,6 +1589,7 @@ function createRouter(init) {
1550
1589
  request,
1551
1590
  location,
1552
1591
  matches,
1592
+ scopedContext,
1553
1593
  fogOfWar.active,
1554
1594
  loadingNavigation,
1555
1595
  opts && opts.submission,
@@ -1570,7 +1610,7 @@ function createRouter(init) {
1570
1610
  errors
1571
1611
  });
1572
1612
  }
1573
- async function handleAction(request, location, submission, matches, isFogOfWar, opts = {}) {
1613
+ async function handleAction(request, location, submission, matches, scopedContext, isFogOfWar, opts = {}) {
1574
1614
  interruptActiveLoads();
1575
1615
  let navigation = getSubmittingNavigation(location, submission);
1576
1616
  updateState({ navigation }, { flushSync: opts.flushSync === true });
@@ -1626,13 +1666,21 @@ function createRouter(init) {
1626
1666
  } else {
1627
1667
  let results = await callDataStrategy(
1628
1668
  "action",
1629
- state,
1630
1669
  request,
1631
1670
  [actionMatch],
1632
1671
  matches,
1672
+ scopedContext,
1633
1673
  null
1634
1674
  );
1635
1675
  result = results[actionMatch.route.id];
1676
+ if (!result) {
1677
+ for (let match of matches) {
1678
+ if (results[match.route.id]) {
1679
+ result = results[match.route.id];
1680
+ break;
1681
+ }
1682
+ }
1683
+ }
1636
1684
  if (request.signal.aborted) {
1637
1685
  return { shortCircuited: true };
1638
1686
  }
@@ -1670,7 +1718,7 @@ function createRouter(init) {
1670
1718
  pendingActionResult: [actionMatch.route.id, result]
1671
1719
  };
1672
1720
  }
1673
- async function handleLoaders(request, location, matches, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync, pendingActionResult) {
1721
+ async function handleLoaders(request, location, matches, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync, pendingActionResult) {
1674
1722
  let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission);
1675
1723
  let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);
1676
1724
  let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration;
@@ -1780,11 +1828,11 @@ function createRouter(init) {
1780
1828
  );
1781
1829
  }
1782
1830
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
1783
- state,
1784
1831
  matches,
1785
1832
  matchesToLoad,
1786
1833
  revalidatingFetchers,
1787
- request
1834
+ request,
1835
+ scopedContext
1788
1836
  );
1789
1837
  if (request.signal.aborted) {
1790
1838
  return { shortCircuited: true };
@@ -1892,6 +1940,9 @@ function createRouter(init) {
1892
1940
  return;
1893
1941
  }
1894
1942
  let match = getTargetMatch(matches, path);
1943
+ let scopedContext = new unstable_RouterContextProvider(
1944
+ init.unstable_getContext ? await init.unstable_getContext() : void 0
1945
+ );
1895
1946
  let preventScrollReset = (opts && opts.preventScrollReset) === true;
1896
1947
  if (submission && isMutationMethod(submission.formMethod)) {
1897
1948
  await handleFetcherAction(
@@ -1900,6 +1951,7 @@ function createRouter(init) {
1900
1951
  path,
1901
1952
  match,
1902
1953
  matches,
1954
+ scopedContext,
1903
1955
  fogOfWar.active,
1904
1956
  flushSync,
1905
1957
  preventScrollReset,
@@ -1914,13 +1966,14 @@ function createRouter(init) {
1914
1966
  path,
1915
1967
  match,
1916
1968
  matches,
1969
+ scopedContext,
1917
1970
  fogOfWar.active,
1918
1971
  flushSync,
1919
1972
  preventScrollReset,
1920
1973
  submission
1921
1974
  );
1922
1975
  }
1923
- async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync, preventScrollReset, submission) {
1976
+ async function handleFetcherAction(key, routeId, path, match, requestMatches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission) {
1924
1977
  interruptActiveLoads();
1925
1978
  fetchLoadMatches.delete(key);
1926
1979
  function detectAndHandle405Error(m) {
@@ -1953,7 +2006,8 @@ function createRouter(init) {
1953
2006
  let discoverResult = await discoverRoutes(
1954
2007
  requestMatches,
1955
2008
  path,
1956
- fetchRequest.signal
2009
+ fetchRequest.signal,
2010
+ key
1957
2011
  );
1958
2012
  if (discoverResult.type === "aborted") {
1959
2013
  return;
@@ -1980,10 +2034,10 @@ function createRouter(init) {
1980
2034
  let originatingLoadId = incrementingLoadId;
1981
2035
  let actionResults = await callDataStrategy(
1982
2036
  "action",
1983
- state,
1984
2037
  fetchRequest,
1985
2038
  [match],
1986
2039
  requestMatches,
2040
+ scopedContext,
1987
2041
  key
1988
2042
  );
1989
2043
  let actionResult = actionResults[match.route.id];
@@ -2067,11 +2121,11 @@ function createRouter(init) {
2067
2121
  abortPendingFetchRevalidations
2068
2122
  );
2069
2123
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
2070
- state,
2071
2124
  matches,
2072
2125
  matchesToLoad,
2073
2126
  revalidatingFetchers,
2074
- revalidationRequest
2127
+ revalidationRequest,
2128
+ scopedContext
2075
2129
  );
2076
2130
  if (abortController.signal.aborted) {
2077
2131
  return;
@@ -2138,7 +2192,7 @@ function createRouter(init) {
2138
2192
  isRevalidationRequired = false;
2139
2193
  }
2140
2194
  }
2141
- async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync, preventScrollReset, submission) {
2195
+ async function handleFetcherLoader(key, routeId, path, match, matches, scopedContext, isFogOfWar, flushSync, preventScrollReset, submission) {
2142
2196
  let existingFetcher = state.fetchers.get(key);
2143
2197
  updateFetcherState(
2144
2198
  key,
@@ -2158,7 +2212,8 @@ function createRouter(init) {
2158
2212
  let discoverResult = await discoverRoutes(
2159
2213
  matches,
2160
2214
  path,
2161
- fetchRequest.signal
2215
+ fetchRequest.signal,
2216
+ key
2162
2217
  );
2163
2218
  if (discoverResult.type === "aborted") {
2164
2219
  return;
@@ -2182,10 +2237,10 @@ function createRouter(init) {
2182
2237
  let originatingLoadId = incrementingLoadId;
2183
2238
  let results = await callDataStrategy(
2184
2239
  "loader",
2185
- state,
2186
2240
  fetchRequest,
2187
2241
  [match],
2188
2242
  matches,
2243
+ scopedContext,
2189
2244
  key
2190
2245
  );
2191
2246
  let result = results[match.route.id];
@@ -2287,20 +2342,21 @@ function createRouter(init) {
2287
2342
  });
2288
2343
  }
2289
2344
  }
2290
- async function callDataStrategy(type, state2, request, matchesToLoad, matches, fetcherKey) {
2345
+ async function callDataStrategy(type, request, matchesToLoad, matches, scopedContext, fetcherKey) {
2291
2346
  let results;
2292
2347
  let dataResults = {};
2293
2348
  try {
2294
2349
  results = await callDataStrategyImpl(
2295
2350
  dataStrategyImpl,
2296
2351
  type,
2297
- state2,
2298
2352
  request,
2299
2353
  matchesToLoad,
2300
2354
  matches,
2301
2355
  fetcherKey,
2302
2356
  manifest,
2303
- mapRouteProperties2
2357
+ mapRouteProperties2,
2358
+ scopedContext,
2359
+ future.unstable_middleware
2304
2360
  );
2305
2361
  } catch (e) {
2306
2362
  matchesToLoad.forEach((m) => {
@@ -2332,13 +2388,13 @@ function createRouter(init) {
2332
2388
  }
2333
2389
  return dataResults;
2334
2390
  }
2335
- async function callLoadersAndMaybeResolveData(state2, matches, matchesToLoad, fetchersToLoad, request) {
2391
+ async function callLoadersAndMaybeResolveData(matches, matchesToLoad, fetchersToLoad, request, scopedContext) {
2336
2392
  let loaderResultsPromise = callDataStrategy(
2337
2393
  "loader",
2338
- state2,
2339
2394
  request,
2340
2395
  matchesToLoad,
2341
2396
  matches,
2397
+ scopedContext,
2342
2398
  null
2343
2399
  );
2344
2400
  let fetcherResultsPromise = Promise.all(
@@ -2346,10 +2402,10 @@ function createRouter(init) {
2346
2402
  if (f.matches && f.match && f.controller) {
2347
2403
  let results = await callDataStrategy(
2348
2404
  "loader",
2349
- state2,
2350
2405
  createClientSideRequest(init.history, f.path, f.controller.signal),
2351
2406
  [f.match],
2352
2407
  f.matches,
2408
+ scopedContext,
2353
2409
  f.key
2354
2410
  );
2355
2411
  let result = results[f.match.route.id];
@@ -2571,7 +2627,7 @@ function createRouter(init) {
2571
2627
  return null;
2572
2628
  }
2573
2629
  function checkFogOfWar(matches, routesToUse, pathname) {
2574
- if (patchRoutesOnNavigationImpl) {
2630
+ if (init.patchRoutesOnNavigation) {
2575
2631
  if (!matches) {
2576
2632
  let fogMatches = matchRoutesImpl(
2577
2633
  routesToUse,
@@ -2594,8 +2650,8 @@ function createRouter(init) {
2594
2650
  }
2595
2651
  return { active: false, matches: null };
2596
2652
  }
2597
- async function discoverRoutes(matches, pathname, signal) {
2598
- if (!patchRoutesOnNavigationImpl) {
2653
+ async function discoverRoutes(matches, pathname, signal, fetcherKey) {
2654
+ if (!init.patchRoutesOnNavigation) {
2599
2655
  return { type: "success", matches };
2600
2656
  }
2601
2657
  let partialMatches = matches;
@@ -2604,10 +2660,11 @@ function createRouter(init) {
2604
2660
  let routesToUse = inFlightDataRoutes || dataRoutes;
2605
2661
  let localManifest = manifest;
2606
2662
  try {
2607
- await patchRoutesOnNavigationImpl({
2663
+ await init.patchRoutesOnNavigation({
2608
2664
  signal,
2609
2665
  path: pathname,
2610
2666
  matches: partialMatches,
2667
+ fetcherKey,
2611
2668
  patch: (routeId, children) => {
2612
2669
  if (signal.aborted) return;
2613
2670
  patchRoutesImpl(
@@ -2726,17 +2783,21 @@ function createStaticHandler(routes, opts) {
2726
2783
  );
2727
2784
  async function query(request, {
2728
2785
  requestContext,
2786
+ filterMatchesToLoad,
2729
2787
  skipLoaderErrorBubbling,
2730
- dataStrategy
2788
+ skipRevalidation,
2789
+ dataStrategy,
2790
+ unstable_respond: respond
2731
2791
  } = {}) {
2732
2792
  let url = new URL(request.url);
2733
2793
  let method = request.method;
2734
2794
  let location = createLocation("", createPath(url), null, "default");
2735
2795
  let matches = matchRoutes(dataRoutes, location, basename);
2796
+ requestContext = requestContext != null ? requestContext : new unstable_RouterContextProvider();
2736
2797
  if (!isValidMethod(method) && method !== "HEAD") {
2737
2798
  let error = getInternalRouterError(405, { method });
2738
2799
  let { matches: methodNotAllowedMatches, route } = getShortCircuitMatches(dataRoutes);
2739
- return {
2800
+ let staticContext = {
2740
2801
  basename,
2741
2802
  location,
2742
2803
  matches: methodNotAllowedMatches,
@@ -2749,10 +2810,11 @@ function createStaticHandler(routes, opts) {
2749
2810
  loaderHeaders: {},
2750
2811
  actionHeaders: {}
2751
2812
  };
2813
+ return respond ? respond(staticContext) : staticContext;
2752
2814
  } else if (!matches) {
2753
2815
  let error = getInternalRouterError(404, { pathname: location.pathname });
2754
2816
  let { matches: notFoundMatches, route } = getShortCircuitMatches(dataRoutes);
2755
- return {
2817
+ let staticContext = {
2756
2818
  basename,
2757
2819
  location,
2758
2820
  matches: notFoundMatches,
@@ -2765,6 +2827,90 @@ function createStaticHandler(routes, opts) {
2765
2827
  loaderHeaders: {},
2766
2828
  actionHeaders: {}
2767
2829
  };
2830
+ return respond ? respond(staticContext) : staticContext;
2831
+ }
2832
+ if (respond && matches.some((m) => m.route.unstable_middleware)) {
2833
+ invariant(
2834
+ requestContext instanceof unstable_RouterContextProvider,
2835
+ "When using middleware in `staticHandler.query()`, any provided `requestContext` must bean instance of `unstable_RouterContextProvider`"
2836
+ );
2837
+ try {
2838
+ let tailIdx = [...matches].reverse().findIndex((m) => !filterMatchesToLoad || filterMatchesToLoad(m));
2839
+ let lowestLoadingIdx = tailIdx < 0 ? 0 : matches.length - 1 - tailIdx;
2840
+ let renderedStaticContext;
2841
+ let response = await runMiddlewarePipeline(
2842
+ {
2843
+ request,
2844
+ matches,
2845
+ params: matches[0].params,
2846
+ // If we're calling middleware then it must be enabled so we can cast
2847
+ // this to the proper type knowing it's not an `AppLoadContext`
2848
+ context: requestContext
2849
+ },
2850
+ lowestLoadingIdx,
2851
+ true,
2852
+ async () => {
2853
+ let result2 = await queryImpl(
2854
+ request,
2855
+ location,
2856
+ matches,
2857
+ requestContext,
2858
+ dataStrategy || null,
2859
+ skipLoaderErrorBubbling === true,
2860
+ null,
2861
+ filterMatchesToLoad || null,
2862
+ skipRevalidation === true
2863
+ );
2864
+ if (isResponse(result2)) {
2865
+ return result2;
2866
+ }
2867
+ renderedStaticContext = { location, basename, ...result2 };
2868
+ let res = await respond(renderedStaticContext);
2869
+ return res;
2870
+ },
2871
+ async (e) => {
2872
+ if (isResponse(e.error)) {
2873
+ return e.error;
2874
+ }
2875
+ if (renderedStaticContext) {
2876
+ if (e.routeId in renderedStaticContext.loaderData) {
2877
+ renderedStaticContext.loaderData[e.routeId] = void 0;
2878
+ }
2879
+ return respond(
2880
+ getStaticContextFromError(
2881
+ dataRoutes,
2882
+ renderedStaticContext,
2883
+ e.error,
2884
+ findNearestBoundary(matches, e.routeId).route.id
2885
+ )
2886
+ );
2887
+ } else {
2888
+ let loaderIdx = matches.findIndex((m) => m.route.loader);
2889
+ let boundary = loaderIdx >= 0 ? findNearestBoundary(matches, matches[loaderIdx].route.id) : findNearestBoundary(matches);
2890
+ return respond({
2891
+ matches,
2892
+ location,
2893
+ basename,
2894
+ loaderData: {},
2895
+ actionData: null,
2896
+ errors: {
2897
+ [boundary.route.id]: e.error
2898
+ },
2899
+ statusCode: isRouteErrorResponse(e.error) ? e.error.status : 500,
2900
+ actionHeaders: {},
2901
+ loaderHeaders: {}
2902
+ });
2903
+ }
2904
+ }
2905
+ );
2906
+ invariant(isResponse(response), "Expected a response in query()");
2907
+ return response;
2908
+ } catch (e) {
2909
+ if (isResponse(e)) {
2910
+ return e;
2911
+ }
2912
+ throw e;
2913
+ }
2768
2914
  }
2769
2915
  let result = await queryImpl(
2770
2916
  request,
@@ -2773,7 +2919,9 @@ function createStaticHandler(routes, opts) {
2773
2919
  requestContext,
2774
2920
  dataStrategy || null,
2775
2921
  skipLoaderErrorBubbling === true,
2776
- null
2922
+ null,
2923
+ filterMatchesToLoad || null,
2924
+ skipRevalidation === true
2777
2925
  );
2778
2926
  if (isResponse(result)) {
2779
2927
  return result;
@@ -2783,12 +2931,14 @@ function createStaticHandler(routes, opts) {
2783
2931
  async function queryRoute(request, {
2784
2932
  routeId,
2785
2933
  requestContext,
2786
- dataStrategy
2934
+ dataStrategy,
2935
+ unstable_respond: respond
2787
2936
  } = {}) {
2788
2937
  let url = new URL(request.url);
2789
2938
  let method = request.method;
2790
2939
  let location = createLocation("", createPath(url), null, "default");
2791
2940
  let matches = matchRoutes(dataRoutes, location, basename);
2941
+ requestContext = requestContext != null ? requestContext : new unstable_RouterContextProvider();
2792
2942
  if (!isValidMethod(method) && method !== "HEAD" && method !== "OPTIONS") {
2793
2943
  throw getInternalRouterError(405, { method });
2794
2944
  } else if (!matches) {
@@ -2803,6 +2953,56 @@ function createStaticHandler(routes, opts) {
2803
2953
  } else if (!match) {
2804
2954
  throw getInternalRouterError(404, { pathname: location.pathname });
2805
2955
  }
2956
+ if (respond && matches.some((m) => m.route.unstable_middleware)) {
2957
+ invariant(
2958
+ requestContext instanceof unstable_RouterContextProvider,
2959
+ "When using middleware in `staticHandler.queryRoute()`, any provided `requestContext` must bean instance of `unstable_RouterContextProvider`"
2960
+ );
2961
+ let response = await runMiddlewarePipeline(
2962
+ {
2963
+ request,
2964
+ matches,
2965
+ params: matches[0].params,
2966
+ // If we're calling middleware then it must be enabled so we can cast
2967
+ // this to the proper type knowing it's not an `AppLoadContext`
2968
+ context: requestContext
2969
+ },
2970
+ matches.length - 1,
2971
+ true,
2972
+ async () => {
2973
+ let result2 = await queryImpl(
2974
+ request,
2975
+ location,
2976
+ matches,
2977
+ requestContext,
2978
+ dataStrategy || null,
2979
+ false,
2980
+ match,
2981
+ null,
2982
+ false
2983
+ );
2984
+ if (isResponse(result2)) {
2985
+ return respond(result2);
2986
+ }
2987
+ let error2 = result2.errors ? Object.values(result2.errors)[0] : void 0;
2988
+ if (error2 !== void 0) {
2989
+ throw error2;
2990
+ }
2991
+ let value = result2.actionData ? Object.values(result2.actionData)[0] : Object.values(result2.loaderData)[0];
2992
+ return typeof value === "string" ? new Response(value) : Response.json(value);
2993
+ },
2994
+ (e) => {
2995
+ if (isResponse(e.error)) {
2996
+ return respond(e.error);
2997
+ }
2998
+ return new Response(String(e.error), {
2999
+ status: 500,
3000
+ statusText: "Unexpected Server Error"
3001
+ });
3002
+ }
3003
+ );
3004
+ return response;
3005
+ }
2806
3006
  let result = await queryImpl(
2807
3007
  request,
2808
3008
  location,
@@ -2810,7 +3010,9 @@ function createStaticHandler(routes, opts) {
2810
3010
  requestContext,
2811
3011
  dataStrategy || null,
2812
3012
  false,
2813
- match
3013
+ match,
3014
+ null,
3015
+ false
2814
3016
  );
2815
3017
  if (isResponse(result)) {
2816
3018
  return result;
@@ -2827,7 +3029,7 @@ function createStaticHandler(routes, opts) {
2827
3029
  }
2828
3030
  return void 0;
2829
3031
  }
2830
- async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch) {
3032
+ async function queryImpl(request, location, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, skipRevalidation) {
2831
3033
  invariant(
2832
3034
  request.signal,
2833
3035
  "query()/queryRoute() requests must contain an AbortController signal"
@@ -2841,7 +3043,9 @@ function createStaticHandler(routes, opts) {
2841
3043
  requestContext,
2842
3044
  dataStrategy,
2843
3045
  skipLoaderErrorBubbling,
2844
- routeMatch != null
3046
+ routeMatch != null,
3047
+ filterMatchesToLoad,
3048
+ skipRevalidation
2845
3049
  );
2846
3050
  return result2;
2847
3051
  }
@@ -2851,7 +3055,8 @@ function createStaticHandler(routes, opts) {
2851
3055
  requestContext,
2852
3056
  dataStrategy,
2853
3057
  skipLoaderErrorBubbling,
2854
- routeMatch
3058
+ routeMatch,
3059
+ filterMatchesToLoad
2855
3060
  );
2856
3061
  return isResponse(result) ? result : {
2857
3062
  ...result,
@@ -2871,7 +3076,7 @@ function createStaticHandler(routes, opts) {
2871
3076
  throw e;
2872
3077
  }
2873
3078
  }
2874
- async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest) {
3079
+ async function submit(request, matches, actionMatch, requestContext, dataStrategy, skipLoaderErrorBubbling, isRouteRequest, filterMatchesToLoad, skipRevalidation) {
2875
3080
  let result;
2876
3081
  if (!actionMatch.route.action && !actionMatch.route.lazy) {
2877
3082
  let error = getInternalRouterError(405, {
@@ -2925,6 +3130,36 @@ function createStaticHandler(routes, opts) {
2925
3130
  actionHeaders: {}
2926
3131
  };
2927
3132
  }
3133
+ if (skipRevalidation) {
3134
+ if (isErrorResult(result)) {
3135
+ let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
3136
+ return {
3137
+ statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
3138
+ actionData: null,
3139
+ actionHeaders: {
3140
+ ...result.headers ? { [actionMatch.route.id]: result.headers } : {}
3141
+ },
3142
+ matches,
3143
+ loaderData: {},
3144
+ errors: {
3145
+ [boundaryMatch.route.id]: result.error
3146
+ },
3147
+ loaderHeaders: {}
3148
+ };
3149
+ } else {
3150
+ return {
3151
+ actionData: {
3152
+ [actionMatch.route.id]: result.data
3153
+ },
3154
+ actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {},
3155
+ matches,
3156
+ loaderData: {},
3157
+ errors: null,
3158
+ statusCode: result.statusCode || 200,
3159
+ loaderHeaders: {}
3160
+ };
3161
+ }
3162
+ }
2928
3163
  let loaderRequest = new Request(request.url, {
2929
3164
  headers: request.headers,
2930
3165
  redirect: request.redirect,
@@ -2932,17 +3167,18 @@ function createStaticHandler(routes, opts) {
2932
3167
  });
2933
3168
  if (isErrorResult(result)) {
2934
3169
  let boundaryMatch = skipLoaderErrorBubbling ? actionMatch : findNearestBoundary(matches, actionMatch.route.id);
2935
- let context2 = await loadRouteData(
3170
+ let handlerContext2 = await loadRouteData(
2936
3171
  loaderRequest,
2937
3172
  matches,
2938
3173
  requestContext,
2939
3174
  dataStrategy,
2940
3175
  skipLoaderErrorBubbling,
2941
3176
  null,
3177
+ filterMatchesToLoad,
2942
3178
  [boundaryMatch.route.id, result]
2943
3179
  );
2944
3180
  return {
2945
- ...context2,
3181
+ ...handlerContext2,
2946
3182
  statusCode: isRouteErrorResponse(result.error) ? result.error.status : result.statusCode != null ? result.statusCode : 500,
2947
3183
  actionData: null,
2948
3184
  actionHeaders: {
@@ -2950,16 +3186,17 @@ function createStaticHandler(routes, opts) {
2950
3186
  }
2951
3187
  };
2952
3188
  }
2953
- let context = await loadRouteData(
3189
+ let handlerContext = await loadRouteData(
2954
3190
  loaderRequest,
2955
3191
  matches,
2956
3192
  requestContext,
2957
3193
  dataStrategy,
2958
3194
  skipLoaderErrorBubbling,
2959
- null
3195
+ null,
3196
+ filterMatchesToLoad
2960
3197
  );
2961
3198
  return {
2962
- ...context,
3199
+ ...handlerContext,
2963
3200
  actionData: {
2964
3201
  [actionMatch.route.id]: result.data
2965
3202
  },
@@ -2968,7 +3205,7 @@ function createStaticHandler(routes, opts) {
2968
3205
  actionHeaders: result.headers ? { [actionMatch.route.id]: result.headers } : {}
2969
3206
  };
2970
3207
  }
2971
- async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, pendingActionResult) {
3208
+ async function loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch, filterMatchesToLoad, pendingActionResult) {
2972
3209
  let isRouteRequest = routeMatch != null;
2973
3210
  if (isRouteRequest && !routeMatch?.route.loader && !routeMatch?.route.lazy) {
2974
3211
  throw getInternalRouterError(400, {
@@ -2979,7 +3216,7 @@ function createStaticHandler(routes, opts) {
2979
3216
  }
2980
3217
  let requestMatches = routeMatch ? [routeMatch] : pendingActionResult && isErrorResult(pendingActionResult[1]) ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]) : matches;
2981
3218
  let matchesToLoad = requestMatches.filter(
2982
- (m) => m.route.loader || m.route.lazy
3219
+ (m) => (m.route.loader || m.route.lazy) && (!filterMatchesToLoad || filterMatchesToLoad(m))
2983
3220
  );
2984
3221
  if (matchesToLoad.length === 0) {
2985
3222
  return {
@@ -3008,7 +3245,7 @@ function createStaticHandler(routes, opts) {
3008
3245
  if (request.signal.aborted) {
3009
3246
  throwStaticHandlerAbortedError(request, isRouteRequest);
3010
3247
  }
3011
- let context = processRouteLoaderData(
3248
+ let handlerContext = processRouteLoaderData(
3012
3249
  matches,
3013
3250
  results,
3014
3251
  pendingActionResult,
@@ -3020,11 +3257,11 @@ function createStaticHandler(routes, opts) {
3020
3257
  );
3021
3258
  matches.forEach((match) => {
3022
3259
  if (!executedLoaders.has(match.route.id)) {
3023
- context.loaderData[match.route.id] = null;
3260
+ handlerContext.loaderData[match.route.id] = null;
3024
3261
  }
3025
3262
  });
3026
3263
  return {
3027
- ...context,
3264
+ ...handlerContext,
3028
3265
  matches
3029
3266
  };
3030
3267
  }
@@ -3032,14 +3269,15 @@ function createStaticHandler(routes, opts) {
3032
3269
  let results = await callDataStrategyImpl(
3033
3270
  dataStrategy || defaultDataStrategy,
3034
3271
  type,
3035
- null,
3036
3272
  request,
3037
3273
  matchesToLoad,
3038
3274
  matches,
3039
3275
  null,
3040
3276
  manifest,
3041
3277
  mapRouteProperties2,
3042
- requestContext
3278
+ requestContext,
3279
+ false
3280
+ // middleware not done via dataStrategy in the static handler
3043
3281
  );
3044
3282
  let dataResults = {};
3045
3283
  await Promise.all(
@@ -3072,15 +3310,15 @@ function createStaticHandler(routes, opts) {
3072
3310
  queryRoute
3073
3311
  };
3074
3312
  }
3075
- function getStaticContextFromError(routes, context, error) {
3076
- let newContext = {
3077
- ...context,
3313
+ function getStaticContextFromError(routes, handlerContext, error, boundaryId) {
3314
+ let errorBoundaryId = boundaryId || handlerContext._deepestRenderedBoundaryId || routes[0].id;
3315
+ return {
3316
+ ...handlerContext,
3078
3317
  statusCode: isRouteErrorResponse(error) ? error.status : 500,
3079
3318
  errors: {
3080
- [context._deepestRenderedBoundaryId || routes[0].id]: error
3319
+ [errorBoundaryId]: error
3081
3320
  }
3082
3321
  };
3083
- return newContext;
3084
3322
  }
3085
3323
  function throwStaticHandlerAbortedError(request, isRouteRequest) {
3086
3324
  if (request.signal.reason !== void 0) {
@@ -3473,20 +3711,143 @@ async function loadLazyRouteModule(route, mapRouteProperties2, manifest) {
3473
3711
  lazy: void 0
3474
3712
  });
3475
3713
  }
3476
- async function defaultDataStrategy({
3477
- matches
3478
- }) {
3479
- let matchesToLoad = matches.filter((m) => m.shouldLoad);
3714
+ async function defaultDataStrategy(args) {
3715
+ let matchesToLoad = args.matches.filter((m) => m.shouldLoad);
3716
+ let keyedResults = {};
3480
3717
  let results = await Promise.all(matchesToLoad.map((m) => m.resolve()));
3481
- return results.reduce(
3482
- (acc, result, i) => Object.assign(acc, { [matchesToLoad[i].route.id]: result }),
3483
- {}
3718
+ results.forEach((result, i) => {
3719
+ keyedResults[matchesToLoad[i].route.id] = result;
3720
+ });
3721
+ return keyedResults;
3722
+ }
3723
+ async function defaultDataStrategyWithMiddleware(args) {
3724
+ if (!args.matches.some((m) => m.route.unstable_middleware)) {
3725
+ return defaultDataStrategy(args);
3726
+ }
3727
+ let lastIndex = args.matches.length - 1;
3728
+ for (let i = lastIndex; i >= 0; i--) {
3729
+ if (args.matches[i].shouldLoad) {
3730
+ lastIndex = i;
3731
+ break;
3732
+ }
3733
+ }
3734
+ let results = await runMiddlewarePipeline(
3735
+ args,
3736
+ lastIndex,
3737
+ false,
3738
+ async (keyedResults) => {
3739
+ Object.assign(keyedResults, await defaultDataStrategy(args));
3740
+ },
3741
+ (e, keyedResults) => {
3742
+ Object.assign(keyedResults, {
3743
+ [e.routeId]: { type: "error", result: e.error }
3744
+ });
3745
+ }
3484
3746
  );
3747
+ return results;
3485
3748
  }
3486
- async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties2, requestContext) {
3749
+ async function runMiddlewarePipeline({
3750
+ request,
3751
+ params,
3752
+ context,
3753
+ matches
3754
+ }, lastIndex, propagateResult, handler, errorHandler) {
3755
+ let middlewareState = {
3756
+ keyedResults: {},
3757
+ propagateResult
3758
+ };
3759
+ try {
3760
+ let result = await callRouteMiddleware(
3761
+ matches.slice(0, lastIndex + 1).flatMap(
3762
+ (m) => m.route.unstable_middleware ? m.route.unstable_middleware.map((fn) => [m.route.id, fn]) : []
3763
+ ),
3764
+ 0,
3765
+ { request, params, context },
3766
+ middlewareState,
3767
+ handler
3768
+ );
3769
+ return middlewareState.propagateResult ? result : middlewareState.keyedResults;
3770
+ } catch (e) {
3771
+ if (!(e instanceof MiddlewareError)) {
3772
+ throw e;
3773
+ }
3774
+ let result = await errorHandler(e, middlewareState.keyedResults);
3775
+ return middlewareState.propagateResult ? result : middlewareState.keyedResults;
3776
+ }
3777
+ }
3778
+ var MiddlewareError = class {
3779
+ constructor(routeId, error) {
3780
+ this.routeId = routeId;
3781
+ this.error = error;
3782
+ }
3783
+ };
3784
+ async function callRouteMiddleware(middlewares, idx, args, middlewareState, handler) {
3785
+ let { request } = args;
3786
+ if (request.signal.aborted) {
3787
+ if (request.signal.reason) {
3788
+ throw request.signal.reason;
3789
+ }
3790
+ throw new Error(
3791
+ `Request aborted without an \`AbortSignal.reason\`: ${request.method} ${request.url}`
3792
+ );
3793
+ }
3794
+ let tuple = middlewares[idx];
3795
+ if (!tuple) {
3796
+ let result = await handler(middlewareState.keyedResults);
3797
+ return result;
3798
+ }
3799
+ let [routeId, middleware] = tuple;
3800
+ let nextCalled = false;
3801
+ let nextResult = void 0;
3802
+ let next = async () => {
3803
+ if (nextCalled) {
3804
+ throw new Error("You may only call `next()` once per middleware");
3805
+ }
3806
+ nextCalled = true;
3807
+ let result = await callRouteMiddleware(
3808
+ middlewares,
3809
+ idx + 1,
3810
+ args,
3811
+ middlewareState,
3812
+ handler
3813
+ );
3814
+ if (middlewareState.propagateResult) {
3815
+ nextResult = result;
3816
+ return nextResult;
3817
+ }
3818
+ };
3819
+ try {
3820
+ let result = await middleware(
3821
+ {
3822
+ request: args.request,
3823
+ params: args.params,
3824
+ context: args.context
3825
+ },
3826
+ next
3827
+ );
3828
+ if (nextCalled) {
3829
+ if (result === void 0) {
3830
+ return nextResult;
3831
+ } else {
3832
+ return result;
3833
+ }
3834
+ } else {
3835
+ return next();
3836
+ }
3837
+ } catch (e) {
3838
+ if (e instanceof MiddlewareError) {
3839
+ throw e;
3840
+ }
3841
+ throw new MiddlewareError(routeId, e);
3842
+ }
3843
+ }
3844
+ async function callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties2, scopedContext, enableMiddleware) {
3487
3845
  let loadRouteDefinitionsPromises = matches.map(
3488
3846
  (m) => m.route.lazy ? loadLazyRouteModule(m.route, mapRouteProperties2, manifest) : void 0
3489
3847
  );
3848
+ if (enableMiddleware) {
3849
+ await Promise.all(loadRouteDefinitionsPromises);
3850
+ }
3490
3851
  let dsMatches = matches.map((match, i) => {
3491
3852
  let loadRoutePromise = loadRouteDefinitionsPromises[i];
3492
3853
  let shouldLoad = matchesToLoad.some((m) => m.route.id === match.route.id);
@@ -3500,7 +3861,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
3500
3861
  match,
3501
3862
  loadRoutePromise,
3502
3863
  handlerOverride,
3503
- requestContext
3864
+ scopedContext
3504
3865
  ) : Promise.resolve({ type: "data" /* data */, result: void 0 });
3505
3866
  };
3506
3867
  return {
@@ -3514,7 +3875,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
3514
3875
  request,
3515
3876
  params: matches[0].params,
3516
3877
  fetcherKey,
3517
- context: requestContext
3878
+ context: scopedContext
3518
3879
  });
3519
3880
  try {
3520
3881
  await Promise.all(loadRouteDefinitionsPromises);
@@ -3522,7 +3883,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
3522
3883
  }
3523
3884
  return results;
3524
3885
  }
3525
- async function callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, staticContext) {
3886
+ async function callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, scopedContext) {
3526
3887
  let result;
3527
3888
  let onReject;
3528
3889
  let runHandler = (handler) => {
@@ -3542,7 +3903,7 @@ async function callLoaderOrAction(type, request, match, loadRoutePromise, handle
3542
3903
  {
3543
3904
  request,
3544
3905
  params: match.params,
3545
- context: staticContext
3906
+ context: scopedContext
3546
3907
  },
3547
3908
  ...ctx !== void 0 ? [ctx] : []
3548
3909
  );
@@ -4855,6 +5216,7 @@ function mapRouteProperties(route) {
4855
5216
  function createMemoryRouter(routes, opts) {
4856
5217
  return createRouter({
4857
5218
  basename: opts?.basename,
5219
+ unstable_getContext: opts?.unstable_getContext,
4858
5220
  future: opts?.future,
4859
5221
  history: createMemoryHistory({
4860
5222
  initialEntries: opts?.initialEntries,
@@ -5810,55 +6172,103 @@ function StreamTransfer({
5810
6172
  )));
5811
6173
  }
5812
6174
  }
5813
- function getSingleFetchDataStrategy(manifest, routeModules, ssr, getRouter) {
5814
- return async ({ request, matches, fetcherKey }) => {
6175
+ function middlewareErrorHandler(e, keyedResults) {
6176
+ Object.assign(keyedResults, {
6177
+ [e.routeId]: { type: "error", result: e.error }
6178
+ });
6179
+ }
6180
+ function getSingleFetchDataStrategy(manifest, routeModules, ssr, basename, getRouter) {
6181
+ return async (args) => {
6182
+ let { request, matches, fetcherKey } = args;
5815
6183
  if (request.method !== "GET") {
5816
- return singleFetchActionStrategy(request, matches);
6184
+ return runMiddlewarePipeline(
6185
+ args,
6186
+ matches.findIndex((m) => m.shouldLoad),
6187
+ false,
6188
+ async (keyedResults) => {
6189
+ let results = await singleFetchActionStrategy(
6190
+ request,
6191
+ matches,
6192
+ basename
6193
+ );
6194
+ Object.assign(keyedResults, results);
6195
+ },
6196
+ middlewareErrorHandler
6197
+ );
5817
6198
  }
5818
6199
  if (!ssr) {
5819
6200
  let foundRevalidatingServerLoader = matches.some(
5820
6201
  (m) => m.shouldLoad && manifest.routes[m.route.id]?.hasLoader && !manifest.routes[m.route.id]?.hasClientLoader
5821
6202
  );
5822
6203
  if (!foundRevalidatingServerLoader) {
5823
- let matchesToLoad = matches.filter((m) => m.shouldLoad);
5824
- let url = stripIndexParam(singleFetchUrl(request.url));
5825
- let init = await createRequestInit(request);
5826
- let results = {};
5827
- await Promise.all(
5828
- matchesToLoad.map(
5829
- (m) => m.resolve(async (handler) => {
5830
- try {
5831
- let result = manifest.routes[m.route.id]?.hasClientLoader ? await fetchSingleLoader(handler, url, init, m.route.id) : await handler();
5832
- results[m.route.id] = { type: "data", result };
5833
- } catch (e) {
5834
- results[m.route.id] = { type: "error", result: e };
5835
- }
5836
- })
5837
- )
6204
+ let tailIdx = [...matches].reverse().findIndex((m) => m.shouldLoad);
6205
+ let lowestLoadingIndex2 = tailIdx < 0 ? 0 : matches.length - 1 - tailIdx;
6206
+ return runMiddlewarePipeline(
6207
+ args,
6208
+ lowestLoadingIndex2,
6209
+ false,
6210
+ async (keyedResults) => {
6211
+ let results = await nonSsrStrategy(
6212
+ manifest,
6213
+ request,
6214
+ matches,
6215
+ basename
6216
+ );
6217
+ Object.assign(keyedResults, results);
6218
+ },
6219
+ middlewareErrorHandler
5838
6220
  );
5839
- return results;
5840
6221
  }
5841
6222
  }
5842
6223
  if (fetcherKey) {
5843
- return singleFetchLoaderFetcherStrategy(request, matches);
6224
+ return runMiddlewarePipeline(
6225
+ args,
6226
+ matches.findIndex((m) => m.shouldLoad),
6227
+ false,
6228
+ async (keyedResults) => {
6229
+ let results = await singleFetchLoaderFetcherStrategy(
6230
+ request,
6231
+ matches,
6232
+ basename
6233
+ );
6234
+ Object.assign(keyedResults, results);
6235
+ },
6236
+ middlewareErrorHandler
6237
+ );
5844
6238
  }
5845
- return singleFetchLoaderNavigationStrategy(
6239
+ let lowestLoadingIndex = getLowestLoadingIndex(
5846
6240
  manifest,
5847
6241
  routeModules,
5848
- ssr,
5849
6242
  getRouter(),
5850
- request,
5851
6243
  matches
5852
6244
  );
6245
+ return runMiddlewarePipeline(
6246
+ args,
6247
+ lowestLoadingIndex,
6248
+ false,
6249
+ async (keyedResults) => {
6250
+ let results = await singleFetchLoaderNavigationStrategy(
6251
+ manifest,
6252
+ routeModules,
6253
+ ssr,
6254
+ getRouter(),
6255
+ request,
6256
+ matches,
6257
+ basename
6258
+ );
6259
+ Object.assign(keyedResults, results);
6260
+ },
6261
+ middlewareErrorHandler
6262
+ );
5853
6263
  };
5854
6264
  }
5855
- async function singleFetchActionStrategy(request, matches) {
6265
+ async function singleFetchActionStrategy(request, matches, basename) {
5856
6266
  let actionMatch = matches.find((m) => m.shouldLoad);
5857
6267
  invariant2(actionMatch, "No action match found");
5858
6268
  let actionStatus = void 0;
5859
6269
  let result = await actionMatch.resolve(async (handler) => {
5860
6270
  let result2 = await handler(async () => {
5861
- let url = singleFetchUrl(request.url);
6271
+ let url = singleFetchUrl(request.url, basename);
5862
6272
  let init = await createRequestInit(request);
5863
6273
  let { data: data2, status } = await fetchAndDecode(url, init);
5864
6274
  actionStatus = status;
@@ -5879,13 +6289,46 @@ async function singleFetchActionStrategy(request, matches) {
5879
6289
  }
5880
6290
  };
5881
6291
  }
5882
- async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr, router, request, matches) {
6292
+ async function nonSsrStrategy(manifest, request, matches, basename) {
6293
+ let matchesToLoad = matches.filter((m) => m.shouldLoad);
6294
+ let url = stripIndexParam(singleFetchUrl(request.url, basename));
6295
+ let init = await createRequestInit(request);
6296
+ let results = {};
6297
+ await Promise.all(
6298
+ matchesToLoad.map(
6299
+ (m) => m.resolve(async (handler) => {
6300
+ try {
6301
+ let result = manifest.routes[m.route.id]?.hasClientLoader ? await fetchSingleLoader(handler, url, init, m.route.id) : await handler();
6302
+ results[m.route.id] = { type: "data", result };
6303
+ } catch (e) {
6304
+ results[m.route.id] = { type: "error", result: e };
6305
+ }
6306
+ })
6307
+ )
6308
+ );
6309
+ return results;
6310
+ }
6311
+ function isOptedOut(manifestRoute, routeModule, match, router) {
6312
+ return match.route.id in router.state.loaderData && manifestRoute && manifestRoute.hasLoader && routeModule && routeModule.shouldRevalidate;
6313
+ }
6314
+ function getLowestLoadingIndex(manifest, routeModules, router, matches) {
6315
+ let tailIdx = [...matches].reverse().findIndex(
6316
+ (m) => m.shouldLoad || !isOptedOut(
6317
+ manifest.routes[m.route.id],
6318
+ routeModules[m.route.id],
6319
+ m,
6320
+ router
6321
+ )
6322
+ );
6323
+ return tailIdx < 0 ? 0 : matches.length - 1 - tailIdx;
6324
+ }
6325
+ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr, router, request, matches, basename) {
5883
6326
  let routesParams = /* @__PURE__ */ new Set();
5884
6327
  let foundOptOutRoute = false;
5885
6328
  let routeDfds = matches.map(() => createDeferred2());
5886
6329
  let routesLoadedPromise = Promise.all(routeDfds.map((d) => d.promise));
5887
6330
  let singleFetchDfd = createDeferred2();
5888
- let url = stripIndexParam(singleFetchUrl(request.url));
6331
+ let url = stripIndexParam(singleFetchUrl(request.url, basename));
5889
6332
  let init = await createRequestInit(request);
5890
6333
  let results = {};
5891
6334
  let resolvePromise = Promise.all(
@@ -5897,7 +6340,7 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr,
5897
6340
  if (!router.state.initialized) {
5898
6341
  return;
5899
6342
  }
5900
- if (m.route.id in router.state.loaderData && manifestRoute && manifestRoute.hasLoader && routeModules[m.route.id]?.shouldRevalidate) {
6343
+ if (isOptedOut(manifestRoute, routeModules[m.route.id], m, router)) {
5901
6344
  foundOptOutRoute = true;
5902
6345
  return;
5903
6346
  }
@@ -5960,11 +6403,11 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr,
5960
6403
  await resolvePromise;
5961
6404
  return results;
5962
6405
  }
5963
- async function singleFetchLoaderFetcherStrategy(request, matches) {
6406
+ async function singleFetchLoaderFetcherStrategy(request, matches, basename) {
5964
6407
  let fetcherMatch = matches.find((m) => m.shouldLoad);
5965
6408
  invariant2(fetcherMatch, "No fetcher match found");
5966
6409
  let result = await fetcherMatch.resolve(async (handler) => {
5967
- let url = stripIndexParam(singleFetchUrl(request.url));
6410
+ let url = stripIndexParam(singleFetchUrl(request.url, basename));
5968
6411
  let init = await createRequestInit(request);
5969
6412
  return fetchSingleLoader(handler, url, init, fetcherMatch.route.id);
5970
6413
  });
@@ -5992,7 +6435,7 @@ function stripIndexParam(url) {
5992
6435
  }
5993
6436
  return url;
5994
6437
  }
5995
- function singleFetchUrl(reqUrl) {
6438
+ function singleFetchUrl(reqUrl, basename) {
5996
6439
  let url = typeof reqUrl === "string" ? new URL(
5997
6440
  reqUrl,
5998
6441
  // This can be called during the SSR flow via PrefetchPageLinksImpl so
@@ -6001,6 +6444,8 @@ function singleFetchUrl(reqUrl) {
6001
6444
  ) : reqUrl;
6002
6445
  if (url.pathname === "/") {
6003
6446
  url.pathname = "_root.data";
6447
+ } else if (basename && stripBasename(url.pathname, basename) === "/") {
6448
+ url.pathname = `${basename.replace(/\/$/, "")}/_root.data`;
6004
6449
  } else {
6005
6450
  url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
6006
6451
  }
@@ -6297,8 +6742,8 @@ function createServerRoutes(manifest, routeModules, future, isSpaMode, parentId
6297
6742
  // render, so just give it a no-op function so we can render down to the
6298
6743
  // proper fallback
6299
6744
  loader: route.hasLoader || route.hasClientLoader ? () => null : void 0
6300
- // We don't need action/shouldRevalidate on these routes since they're
6301
- // for a static render
6745
+ // We don't need middleware/action/shouldRevalidate on these routes since
6746
+ // they're for a static render
6302
6747
  };
6303
6748
  let children = createServerRoutes(
6304
6749
  manifest,
@@ -6392,6 +6837,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6392
6837
  Object.assign(dataRoute, {
6393
6838
  ...dataRoute,
6394
6839
  ...getRouteComponents(route, routeModule, isSpaMode),
6840
+ unstable_middleware: routeModule.unstable_clientMiddleware,
6395
6841
  handle: routeModule.handle,
6396
6842
  shouldRevalidate: getShouldRevalidateFunction(
6397
6843
  routeModule,
@@ -6405,7 +6851,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6405
6851
  let hasInitialError = initialState && initialState.errors && route.id in initialState.errors;
6406
6852
  let initialError = hasInitialError ? initialState?.errors?.[route.id] : void 0;
6407
6853
  let isHydrationRequest = needsRevalidation == null && (routeModule.clientLoader?.hydrate === true || !route.hasLoader);
6408
- dataRoute.loader = async ({ request, params }, singleFetch) => {
6854
+ dataRoute.loader = async ({ request, params, context }, singleFetch) => {
6409
6855
  try {
6410
6856
  let result = await prefetchStylesAndCallHandler(async () => {
6411
6857
  invariant2(
@@ -6418,6 +6864,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6418
6864
  return routeModule.clientLoader({
6419
6865
  request,
6420
6866
  params,
6867
+ context,
6421
6868
  async serverLoader() {
6422
6869
  preventInvalidServerHandlerCall("loader", route);
6423
6870
  if (isHydrationRequest) {
@@ -6442,7 +6889,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6442
6889
  routeModule,
6443
6890
  isSpaMode
6444
6891
  );
6445
- dataRoute.action = ({ request, params }, singleFetch) => {
6892
+ dataRoute.action = ({ request, params, context }, singleFetch) => {
6446
6893
  return prefetchStylesAndCallHandler(async () => {
6447
6894
  invariant2(
6448
6895
  routeModule,
@@ -6457,6 +6904,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6457
6904
  return routeModule.clientAction({
6458
6905
  request,
6459
6906
  params,
6907
+ context,
6460
6908
  async serverAction() {
6461
6909
  preventInvalidServerHandlerCall("action", route);
6462
6910
  return fetchServerAction(singleFetch);
@@ -6466,7 +6914,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6466
6914
  };
6467
6915
  } else {
6468
6916
  if (!route.hasClientLoader) {
6469
- dataRoute.loader = ({ request }, singleFetch) => prefetchStylesAndCallHandler(() => {
6917
+ dataRoute.loader = (_, singleFetch) => prefetchStylesAndCallHandler(() => {
6470
6918
  return fetchServerLoader(singleFetch);
6471
6919
  });
6472
6920
  } else if (route.clientLoaderModule) {
@@ -6487,7 +6935,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6487
6935
  };
6488
6936
  }
6489
6937
  if (!route.hasClientAction) {
6490
- dataRoute.action = ({ request }, singleFetch) => prefetchStylesAndCallHandler(() => {
6938
+ dataRoute.action = (_, singleFetch) => prefetchStylesAndCallHandler(() => {
6491
6939
  if (isSpaMode) {
6492
6940
  throw noActionDefinedError("clientAction", route.id);
6493
6941
  }
@@ -6545,6 +6993,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6545
6993
  return {
6546
6994
  ...lazyRoute.loader ? { loader: lazyRoute.loader } : {},
6547
6995
  ...lazyRoute.action ? { action: lazyRoute.action } : {},
6996
+ unstable_middleware: mod.unstable_clientMiddleware,
6548
6997
  hasErrorBoundary: lazyRoute.hasErrorBoundary,
6549
6998
  shouldRevalidate: getShouldRevalidateFunction(
6550
6999
  lazyRoute,
@@ -6617,6 +7066,7 @@ async function loadRouteModuleWithBlockingLinks(route, routeModules) {
6617
7066
  return {
6618
7067
  Component: getRouteModuleComponent(routeModule),
6619
7068
  ErrorBoundary: routeModule.ErrorBoundary,
7069
+ unstable_clientMiddleware: routeModule.unstable_clientMiddleware,
6620
7070
  clientAction: routeModule.clientAction,
6621
7071
  clientLoader: routeModule.clientLoader,
6622
7072
  handle: routeModule.handle,
@@ -6672,12 +7122,13 @@ function getPatchRoutesOnNavigationFunction(manifest, routeModules, ssr, isSpaMo
6672
7122
  if (!isFogOfWarEnabled(ssr)) {
6673
7123
  return void 0;
6674
7124
  }
6675
- return async ({ path, patch, signal }) => {
7125
+ return async ({ path, patch, signal, fetcherKey }) => {
6676
7126
  if (discoveredPaths.has(path)) {
6677
7127
  return;
6678
7128
  }
6679
7129
  await fetchAndApplyManifestPatches(
6680
7130
  [path],
7131
+ fetcherKey ? window.location.href : path,
6681
7132
  manifest,
6682
7133
  routeModules,
6683
7134
  ssr,
@@ -6718,6 +7169,7 @@ function useFogOFWarDiscovery(router, manifest, routeModules, ssr, isSpaMode) {
6718
7169
  try {
6719
7170
  await fetchAndApplyManifestPatches(
6720
7171
  lazyPaths,
7172
+ null,
6721
7173
  manifest,
6722
7174
  routeModules,
6723
7175
  ssr,
@@ -6741,7 +7193,8 @@ function useFogOFWarDiscovery(router, manifest, routeModules, ssr, isSpaMode) {
6741
7193
  return () => observer.disconnect();
6742
7194
  }, [ssr, isSpaMode, manifest, routeModules, router]);
6743
7195
  }
6744
- async function fetchAndApplyManifestPatches(paths, manifest, routeModules, ssr, isSpaMode, basename, patchRoutes, signal) {
7196
+ var MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version";
7197
+ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, patchRoutes, signal) {
6745
7198
  let manifestPath = `${basename != null ? basename : "/"}/__manifest`.replace(
6746
7199
  /\/+/g,
6747
7200
  "/"
@@ -6758,9 +7211,26 @@ async function fetchAndApplyManifestPatches(paths, manifest, routeModules, ssr,
6758
7211
  let res = await fetch(url, { signal });
6759
7212
  if (!res.ok) {
6760
7213
  throw new Error(`${res.status} ${res.statusText}`);
7214
+ } else if (res.status === 204 && res.headers.has("X-Remix-Reload-Document")) {
7215
+ if (!errorReloadPath) {
7216
+ console.warn(
7217
+ "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."
7218
+ );
7219
+ return;
7220
+ }
7221
+ if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) {
7222
+ console.error(
7223
+ "Unable to discover routes due to manifest version mismatch."
7224
+ );
7225
+ return;
7226
+ }
7227
+ sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version);
7228
+ window.location.href = errorReloadPath;
7229
+ throw new Error("Detected manifest version mismatch, reloading...");
6761
7230
  } else if (res.status >= 400) {
6762
7231
  throw new Error(await res.text());
6763
7232
  }
7233
+ sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);
6764
7234
  serverPatches = await res.json();
6765
7235
  } catch (e) {
6766
7236
  if (signal?.aborted) return;
@@ -6914,7 +7384,7 @@ function Links() {
6914
7384
  () => getKeyedLinksForMatches(matches, routeModules, manifest),
6915
7385
  [matches, routeModules, manifest]
6916
7386
  );
6917
- return /* @__PURE__ */ React9.createElement(React9.Fragment, null, criticalCss ? /* @__PURE__ */ React9.createElement("style", { dangerouslySetInnerHTML: { __html: criticalCss } }) : null, keyedLinks.map(
7387
+ 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(
6918
7388
  ({ key, link }) => isPageLinkDescriptor(link) ? /* @__PURE__ */ React9.createElement(PrefetchPageLinks, { key, ...link }) : /* @__PURE__ */ React9.createElement("link", { key, ...link })
6919
7389
  ));
6920
7390
  }
@@ -6957,6 +7427,7 @@ function PrefetchPageLinksImpl({
6957
7427
  }) {
6958
7428
  let location = useLocation();
6959
7429
  let { manifest, routeModules } = useFrameworkContext();
7430
+ let { basename } = useDataRouterContext2();
6960
7431
  let { loaderData, matches } = useDataRouterStateContext();
6961
7432
  let newMatchesForData = React9.useMemo(
6962
7433
  () => getNewMatchesForLinks(
@@ -7002,7 +7473,7 @@ function PrefetchPageLinksImpl({
7002
7473
  if (routesParams.size === 0) {
7003
7474
  return [];
7004
7475
  }
7005
- let url = singleFetchUrl(page);
7476
+ let url = singleFetchUrl(page, basename);
7006
7477
  if (foundOptOutRoute && routesParams.size > 0) {
7007
7478
  url.searchParams.set(
7008
7479
  "_routes",
@@ -7011,6 +7482,7 @@ function PrefetchPageLinksImpl({
7011
7482
  }
7012
7483
  return [url.pathname + url.search];
7013
7484
  }, [
7485
+ basename,
7014
7486
  loaderData,
7015
7487
  location,
7016
7488
  manifest,
@@ -7264,13 +7736,14 @@ function mergeRefs(...refs) {
7264
7736
  var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
7265
7737
  try {
7266
7738
  if (isBrowser) {
7267
- window.__reactRouterVersion = "7.2.0";
7739
+ window.__reactRouterVersion = "7.3.0-pre.0";
7268
7740
  }
7269
7741
  } catch (e) {
7270
7742
  }
7271
7743
  function createBrowserRouter(routes, opts) {
7272
7744
  return createRouter({
7273
7745
  basename: opts?.basename,
7746
+ unstable_getContext: opts?.unstable_getContext,
7274
7747
  future: opts?.future,
7275
7748
  history: createBrowserHistory({ window: opts?.window }),
7276
7749
  hydrationData: opts?.hydrationData || parseHydrationData(),
@@ -7284,6 +7757,7 @@ function createBrowserRouter(routes, opts) {
7284
7757
  function createHashRouter(routes, opts) {
7285
7758
  return createRouter({
7286
7759
  basename: opts?.basename,
7760
+ unstable_getContext: opts?.unstable_getContext,
7287
7761
  future: opts?.future,
7288
7762
  history: createHashHistory({ window: opts?.window }),
7289
7763
  hydrationData: opts?.hydrationData || parseHydrationData(),
@@ -8242,6 +8716,7 @@ function createStaticRouter(routes, context, opts = {}) {
8242
8716
  },
8243
8717
  get future() {
8244
8718
  return {
8719
+ unstable_middleware: false,
8245
8720
  ...opts?.future
8246
8721
  };
8247
8722
  },
@@ -8404,7 +8879,7 @@ function ServerRouter({
8404
8879
 
8405
8880
  // lib/dom/ssr/routes-test-stub.tsx
8406
8881
  var React13 = __toESM(require("react"));
8407
- function createRoutesStub(routes, context = {}) {
8882
+ function createRoutesStub(routes, unstable_getContext) {
8408
8883
  return function RoutesTestStub({
8409
8884
  initialEntries,
8410
8885
  initialIndex,
@@ -8415,7 +8890,9 @@ function createRoutesStub(routes, context = {}) {
8415
8890
  let remixContextRef = React13.useRef();
8416
8891
  if (routerRef.current == null) {
8417
8892
  remixContextRef.current = {
8418
- future: {},
8893
+ future: {
8894
+ unstable_middleware: future?.unstable_middleware === true
8895
+ },
8419
8896
  manifest: {
8420
8897
  routes: {},
8421
8898
  entry: { imports: [], module: "" },
@@ -8427,13 +8904,14 @@ function createRoutesStub(routes, context = {}) {
8427
8904
  isSpaMode: false
8428
8905
  };
8429
8906
  let patched = processRoutes(
8430
- // @ts-expect-error loader/action context types don't match :/
8907
+ // @ts-expect-error `StubRouteObject` is stricter about `loader`/`action`
8908
+ // types compared to `AgnosticRouteObject`
8431
8909
  convertRoutesToDataRoutes(routes, (r) => r),
8432
- context,
8433
8910
  remixContextRef.current.manifest,
8434
8911
  remixContextRef.current.routeModules
8435
8912
  );
8436
8913
  routerRef.current = createMemoryRouter(patched, {
8914
+ unstable_getContext,
8437
8915
  initialEntries,
8438
8916
  initialIndex,
8439
8917
  hydrationData
@@ -8442,14 +8920,13 @@ function createRoutesStub(routes, context = {}) {
8442
8920
  return /* @__PURE__ */ React13.createElement(FrameworkContext.Provider, { value: remixContextRef.current }, /* @__PURE__ */ React13.createElement(RouterProvider, { router: routerRef.current }));
8443
8921
  };
8444
8922
  }
8445
- function processRoutes(routes, context, manifest, routeModules, parentId) {
8923
+ function processRoutes(routes, manifest, routeModules, parentId) {
8446
8924
  return routes.map((route) => {
8447
8925
  if (!route.id) {
8448
8926
  throw new Error(
8449
8927
  "Expected a route.id in @remix-run/testing processRoutes() function"
8450
8928
  );
8451
8929
  }
8452
- let { loader, action } = route;
8453
8930
  let newRoute = {
8454
8931
  id: route.id,
8455
8932
  path: route.path,
@@ -8457,8 +8934,8 @@ function processRoutes(routes, context, manifest, routeModules, parentId) {
8457
8934
  Component: route.Component,
8458
8935
  HydrateFallback: route.HydrateFallback,
8459
8936
  ErrorBoundary: route.ErrorBoundary,
8460
- action: action ? (args) => action({ ...args, context }) : void 0,
8461
- loader: loader ? (args) => loader({ ...args, context }) : void 0,
8937
+ action: route.action,
8938
+ loader: route.loader,
8462
8939
  handle: route.handle,
8463
8940
  shouldRevalidate: route.shouldRevalidate
8464
8941
  };
@@ -8493,7 +8970,6 @@ function processRoutes(routes, context, manifest, routeModules, parentId) {
8493
8970
  if (route.children) {
8494
8971
  newRoute.children = processRoutes(
8495
8972
  route.children,
8496
- context,
8497
8973
  manifest,
8498
8974
  routeModules,
8499
8975
  newRoute.id
@@ -8854,6 +9330,7 @@ function createStaticHandlerDataRoutes(manifest, future, parentId = "", routesBy
8854
9330
  hasErrorBoundary: route.id === "root" || route.module.ErrorBoundary != null,
8855
9331
  id: route.id,
8856
9332
  path: route.path,
9333
+ unstable_middleware: route.module.unstable_middleware,
8857
9334
  // Need to use RR's version in the param typed here to permit the optional
8858
9335
  // context even though we know it'll always be provided in remix
8859
9336
  loader: route.module.loader ? async (args) => {
@@ -8999,27 +9476,46 @@ function prependCookies(parentHeaders, childHeaders) {
8999
9476
  }
9000
9477
 
9001
9478
  // lib/server-runtime/single-fetch.ts
9479
+ var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([100, 101, 204, 205, 304]);
9002
9480
  var SINGLE_FETCH_REDIRECT_STATUS = 202;
9003
- function getSingleFetchDataStrategy2({
9004
- isActionDataRequest,
9005
- loadRouteIds
9006
- } = {}) {
9007
- return async ({ request, matches }) => {
9008
- if (isActionDataRequest && request.method === "GET") {
9009
- return {};
9010
- }
9011
- let matchesToLoad = loadRouteIds ? matches.filter((m) => loadRouteIds.includes(m.route.id)) : matches;
9012
- let results = await Promise.all(
9013
- matchesToLoad.map((match) => match.resolve())
9014
- );
9015
- return results.reduce(
9016
- (acc, result, i) => Object.assign(acc, { [matchesToLoad[i].route.id]: result }),
9017
- {}
9018
- );
9019
- };
9020
- }
9021
9481
  async function singleFetchAction(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError) {
9022
9482
  try {
9483
+ let respond2 = function(context) {
9484
+ let headers = getDocumentHeaders(build, context);
9485
+ if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
9486
+ return generateSingleFetchResponse(request, build, serverMode, {
9487
+ result: getSingleFetchRedirect(
9488
+ context.statusCode,
9489
+ headers,
9490
+ build.basename
9491
+ ),
9492
+ headers,
9493
+ status: SINGLE_FETCH_REDIRECT_STATUS
9494
+ });
9495
+ }
9496
+ if (context.errors) {
9497
+ Object.values(context.errors).forEach((err) => {
9498
+ if (!isRouteErrorResponse(err) || err.error) {
9499
+ handleError(err);
9500
+ }
9501
+ });
9502
+ context.errors = sanitizeErrors(context.errors, serverMode);
9503
+ }
9504
+ let singleFetchResult;
9505
+ if (context.errors) {
9506
+ singleFetchResult = { error: Object.values(context.errors)[0] };
9507
+ } else {
9508
+ singleFetchResult = {
9509
+ data: Object.values(context.actionData || {})[0]
9510
+ };
9511
+ }
9512
+ return generateSingleFetchResponse(request, build, serverMode, {
9513
+ result: singleFetchResult,
9514
+ headers,
9515
+ status: context.statusCode
9516
+ });
9517
+ };
9518
+ var respond = respond2;
9023
9519
  let handlerRequest = new Request(handlerUrl, {
9024
9520
  method: request.method,
9025
9521
  body: request.body,
@@ -9030,12 +9526,14 @@ async function singleFetchAction(build, serverMode, staticHandler, request, hand
9030
9526
  let result = await staticHandler.query(handlerRequest, {
9031
9527
  requestContext: loadContext,
9032
9528
  skipLoaderErrorBubbling: true,
9033
- dataStrategy: getSingleFetchDataStrategy2({
9034
- isActionDataRequest: true
9035
- })
9529
+ skipRevalidation: true,
9530
+ unstable_respond: respond2
9036
9531
  });
9037
- if (isResponse(result)) {
9038
- return {
9532
+ if (!isResponse(result)) {
9533
+ result = respond2(result);
9534
+ }
9535
+ if (isRedirectResponse(result)) {
9536
+ return generateSingleFetchResponse(request, build, serverMode, {
9039
9537
  result: getSingleFetchRedirect(
9040
9538
  result.status,
9041
9539
  result.headers,
@@ -9043,65 +9541,83 @@ async function singleFetchAction(build, serverMode, staticHandler, request, hand
9043
9541
  ),
9044
9542
  headers: result.headers,
9045
9543
  status: SINGLE_FETCH_REDIRECT_STATUS
9046
- };
9047
- }
9048
- let context = result;
9049
- let headers = getDocumentHeaders(build, context);
9050
- if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
9051
- return {
9052
- result: getSingleFetchRedirect(
9053
- context.statusCode,
9054
- headers,
9055
- build.basename
9056
- ),
9057
- headers,
9058
- status: SINGLE_FETCH_REDIRECT_STATUS
9059
- };
9060
- }
9061
- if (context.errors) {
9062
- Object.values(context.errors).forEach((err) => {
9063
- if (!isRouteErrorResponse(err) || err.error) {
9064
- handleError(err);
9065
- }
9066
9544
  });
9067
- context.errors = sanitizeErrors(context.errors, serverMode);
9068
9545
  }
9069
- let singleFetchResult;
9070
- if (context.errors) {
9071
- singleFetchResult = { error: Object.values(context.errors)[0] };
9072
- } else {
9073
- singleFetchResult = { data: Object.values(context.actionData || {})[0] };
9074
- }
9075
- return {
9076
- result: singleFetchResult,
9077
- headers,
9078
- status: context.statusCode
9079
- };
9546
+ return result;
9080
9547
  } catch (error) {
9081
9548
  handleError(error);
9082
- return {
9549
+ return generateSingleFetchResponse(request, build, serverMode, {
9083
9550
  result: { error },
9084
9551
  headers: new Headers(),
9085
9552
  status: 500
9086
- };
9553
+ });
9087
9554
  }
9088
9555
  }
9089
9556
  async function singleFetchLoaders(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError) {
9090
9557
  try {
9558
+ let respond2 = function(context) {
9559
+ let headers = getDocumentHeaders(build, context);
9560
+ if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
9561
+ return generateSingleFetchResponse(request, build, serverMode, {
9562
+ result: {
9563
+ [SingleFetchRedirectSymbol]: getSingleFetchRedirect(
9564
+ context.statusCode,
9565
+ headers,
9566
+ build.basename
9567
+ )
9568
+ },
9569
+ headers,
9570
+ status: SINGLE_FETCH_REDIRECT_STATUS
9571
+ });
9572
+ }
9573
+ if (context.errors) {
9574
+ Object.values(context.errors).forEach((err) => {
9575
+ if (!isRouteErrorResponse(err) || err.error) {
9576
+ handleError(err);
9577
+ }
9578
+ });
9579
+ context.errors = sanitizeErrors(context.errors, serverMode);
9580
+ }
9581
+ let results = {};
9582
+ let loadedMatches = new Set(
9583
+ context.matches.filter(
9584
+ (m) => loadRouteIds ? loadRouteIds.has(m.route.id) : m.route.loader != null
9585
+ ).map((m) => m.route.id)
9586
+ );
9587
+ if (context.errors) {
9588
+ for (let [id, error] of Object.entries(context.errors)) {
9589
+ results[id] = { error };
9590
+ }
9591
+ }
9592
+ for (let [id, data2] of Object.entries(context.loaderData)) {
9593
+ if (!(id in results) && loadedMatches.has(id)) {
9594
+ results[id] = { data: data2 };
9595
+ }
9596
+ }
9597
+ return generateSingleFetchResponse(request, build, serverMode, {
9598
+ result: results,
9599
+ headers,
9600
+ status: context.statusCode
9601
+ });
9602
+ };
9603
+ var respond = respond2;
9091
9604
  let handlerRequest = new Request(handlerUrl, {
9092
9605
  headers: request.headers,
9093
9606
  signal: request.signal
9094
9607
  });
9095
- let loadRouteIds = new URL(request.url).searchParams.get("_routes")?.split(",") || void 0;
9608
+ let routesParam = new URL(request.url).searchParams.get("_routes");
9609
+ let loadRouteIds = routesParam ? new Set(routesParam.split(",")) : null;
9096
9610
  let result = await staticHandler.query(handlerRequest, {
9097
9611
  requestContext: loadContext,
9612
+ filterMatchesToLoad: (m) => !loadRouteIds || loadRouteIds.has(m.route.id),
9098
9613
  skipLoaderErrorBubbling: true,
9099
- dataStrategy: getSingleFetchDataStrategy2({
9100
- loadRouteIds
9101
- })
9614
+ unstable_respond: respond2
9102
9615
  });
9103
- if (isResponse(result)) {
9104
- return {
9616
+ if (!isResponse(result)) {
9617
+ result = respond2(result);
9618
+ }
9619
+ if (isRedirectResponse(result)) {
9620
+ return generateSingleFetchResponse(request, build, serverMode, {
9105
9621
  result: {
9106
9622
  [SingleFetchRedirectSymbol]: getSingleFetchRedirect(
9107
9623
  result.status,
@@ -9111,57 +9627,42 @@ async function singleFetchLoaders(build, serverMode, staticHandler, request, han
9111
9627
  },
9112
9628
  headers: result.headers,
9113
9629
  status: SINGLE_FETCH_REDIRECT_STATUS
9114
- };
9115
- }
9116
- let context = result;
9117
- let headers = getDocumentHeaders(build, context);
9118
- if (isRedirectStatusCode(context.statusCode) && headers.has("Location")) {
9119
- return {
9120
- result: {
9121
- [SingleFetchRedirectSymbol]: getSingleFetchRedirect(
9122
- context.statusCode,
9123
- headers,
9124
- build.basename
9125
- )
9126
- },
9127
- headers,
9128
- status: SINGLE_FETCH_REDIRECT_STATUS
9129
- };
9130
- }
9131
- if (context.errors) {
9132
- Object.values(context.errors).forEach((err) => {
9133
- if (!isRouteErrorResponse(err) || err.error) {
9134
- handleError(err);
9135
- }
9136
9630
  });
9137
- context.errors = sanitizeErrors(context.errors, serverMode);
9138
9631
  }
9139
- let results = {};
9140
- let loadedMatches = loadRouteIds ? context.matches.filter(
9141
- (m) => m.route.loader && loadRouteIds.includes(m.route.id)
9142
- ) : context.matches;
9143
- loadedMatches.forEach((m) => {
9144
- let { id } = m.route;
9145
- if (context.errors && context.errors.hasOwnProperty(id)) {
9146
- results[id] = { error: context.errors[id] };
9147
- } else if (context.loaderData.hasOwnProperty(id)) {
9148
- results[id] = { data: context.loaderData[id] };
9149
- }
9150
- });
9151
- return {
9152
- result: results,
9153
- headers,
9154
- status: context.statusCode
9155
- };
9632
+ return result;
9156
9633
  } catch (error) {
9157
9634
  handleError(error);
9158
- return {
9635
+ return generateSingleFetchResponse(request, build, serverMode, {
9159
9636
  result: { root: { error } },
9160
9637
  headers: new Headers(),
9161
9638
  status: 500
9162
- };
9639
+ });
9163
9640
  }
9164
9641
  }
9642
+ function generateSingleFetchResponse(request, build, serverMode, {
9643
+ result,
9644
+ headers,
9645
+ status
9646
+ }) {
9647
+ let resultHeaders = new Headers(headers);
9648
+ resultHeaders.set("X-Remix-Response", "yes");
9649
+ if (NO_BODY_STATUS_CODES.has(status)) {
9650
+ return new Response(null, { status, headers: resultHeaders });
9651
+ }
9652
+ resultHeaders.set("Content-Type", "text/x-script");
9653
+ return new Response(
9654
+ encodeViaTurboStream(
9655
+ result,
9656
+ request.signal,
9657
+ build.entry.module.streamTimeout,
9658
+ serverMode
9659
+ ),
9660
+ {
9661
+ status: status || 200,
9662
+ headers: resultHeaders
9663
+ }
9664
+ );
9665
+ }
9165
9666
  function getSingleFetchRedirect(status, headers, basename) {
9166
9667
  let redirect2 = headers.get("Location");
9167
9668
  if (basename) {
@@ -9223,7 +9724,6 @@ function encodeViaTurboStream(data2, requestSignal, streamTimeout, serverMode) {
9223
9724
  }
9224
9725
 
9225
9726
  // lib/server-runtime/server.ts
9226
- var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([100, 101, 204, 205, 304]);
9227
9727
  function derive(build, mode) {
9228
9728
  let routes = createRoutes(build.routes);
9229
9729
  let dataRoutes = createStaticHandlerDataRoutes(build.routes, build.future);
@@ -9253,8 +9753,11 @@ var createRequestHandler = (build, mode) => {
9253
9753
  let serverMode;
9254
9754
  let staticHandler;
9255
9755
  let errorHandler;
9256
- return async function requestHandler(request, loadContext = {}) {
9756
+ return async function requestHandler(request, initialContext) {
9257
9757
  _build = typeof build === "function" ? await build() : build;
9758
+ let loadContext = _build.future.unstable_middleware ? new unstable_RouterContextProvider(
9759
+ initialContext
9760
+ ) : initialContext || {};
9258
9761
  if (typeof build === "function") {
9259
9762
  let derived = derive(_build, mode);
9260
9763
  routes = derived.routes;
@@ -9269,8 +9772,14 @@ var createRequestHandler = (build, mode) => {
9269
9772
  errorHandler = derived.errorHandler;
9270
9773
  }
9271
9774
  let url = new URL(request.url);
9272
- let normalizedPath = url.pathname.replace(/\.data$/, "").replace(/^\/_root$/, "/");
9273
- if (normalizedPath !== "/" && normalizedPath.endsWith("/")) {
9775
+ let normalizedBasename = _build.basename || "/";
9776
+ let normalizedPath = url.pathname;
9777
+ if (stripBasename(normalizedPath, normalizedBasename) === "/_root.data") {
9778
+ normalizedPath = normalizedBasename;
9779
+ } else if (normalizedPath.endsWith(".data")) {
9780
+ normalizedPath = normalizedPath.replace(/\.data$/, "");
9781
+ }
9782
+ if (stripBasename(normalizedPath, normalizedBasename) !== "/" && normalizedPath.endsWith("/")) {
9274
9783
  normalizedPath = normalizedPath.slice(0, -1);
9275
9784
  }
9276
9785
  let params = {};
@@ -9310,10 +9819,7 @@ var createRequestHandler = (build, mode) => {
9310
9819
  }
9311
9820
  }
9312
9821
  }
9313
- let manifestUrl = `${_build.basename ?? "/"}/__manifest`.replace(
9314
- /\/+/g,
9315
- "/"
9316
- );
9822
+ let manifestUrl = `${normalizedBasename}/__manifest`.replace(/\/+/g, "/");
9317
9823
  if (url.pathname === manifestUrl) {
9318
9824
  try {
9319
9825
  let res = await handleManifestRequest(_build, routes, url);
@@ -9378,9 +9884,10 @@ var createRequestHandler = (build, mode) => {
9378
9884
  );
9379
9885
  }
9380
9886
  }
9381
- } else if (matches && matches[matches.length - 1].route.module.default == null && matches[matches.length - 1].route.module.ErrorBoundary == null) {
9887
+ } 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) {
9382
9888
  response = await handleResourceRequest(
9383
9889
  serverMode,
9890
+ _build,
9384
9891
  staticHandler,
9385
9892
  matches.slice(-1)[0].route.id,
9386
9893
  request,
@@ -9388,7 +9895,13 @@ var createRequestHandler = (build, mode) => {
9388
9895
  handleError
9389
9896
  );
9390
9897
  } else {
9391
- let criticalCss = mode === "development" /* Development */ ? await getDevServerHooks()?.getCriticalCss?.(_build, url.pathname) : void 0;
9898
+ let { pathname } = url;
9899
+ let criticalCss = void 0;
9900
+ if (_build.getCriticalCss) {
9901
+ criticalCss = await _build.getCriticalCss({ pathname });
9902
+ } else if (mode === "development" /* Development */ && getDevServerHooks()?.getCriticalCss) {
9903
+ criticalCss = await getDevServerHooks()?.getCriticalCss?.(pathname);
9904
+ }
9392
9905
  response = await handleDocumentRequest(
9393
9906
  serverMode,
9394
9907
  _build,
@@ -9410,6 +9923,14 @@ var createRequestHandler = (build, mode) => {
9410
9923
  };
9411
9924
  };
9412
9925
  async function handleManifestRequest(build, routes, url) {
9926
+ if (build.assets.version !== url.searchParams.get("version")) {
9927
+ return new Response(null, {
9928
+ status: 204,
9929
+ headers: {
9930
+ "X-Remix-Reload-Document": "true"
9931
+ }
9932
+ });
9933
+ }
9413
9934
  let patches = {};
9414
9935
  if (url.searchParams.has("p")) {
9415
9936
  for (let path of url.searchParams.getAll("p")) {
@@ -9433,7 +9954,7 @@ async function handleManifestRequest(build, routes, url) {
9433
9954
  return new Response("Invalid Request", { status: 400 });
9434
9955
  }
9435
9956
  async function handleSingleFetchRequest(serverMode, build, staticHandler, request, handlerUrl, loadContext, handleError) {
9436
- let { result, headers, status } = request.method !== "GET" ? await singleFetchAction(
9957
+ let response = request.method !== "GET" ? await singleFetchAction(
9437
9958
  build,
9438
9959
  serverMode,
9439
9960
  staticHandler,
@@ -9450,133 +9971,66 @@ async function handleSingleFetchRequest(serverMode, build, staticHandler, reques
9450
9971
  loadContext,
9451
9972
  handleError
9452
9973
  );
9453
- let resultHeaders = new Headers(headers);
9454
- resultHeaders.set("X-Remix-Response", "yes");
9455
- if (NO_BODY_STATUS_CODES.has(status)) {
9456
- return new Response(null, { status, headers: resultHeaders });
9457
- }
9458
- resultHeaders.set("Content-Type", "text/x-script");
9459
- return new Response(
9460
- encodeViaTurboStream(
9461
- result,
9462
- request.signal,
9463
- build.entry.module.streamTimeout,
9464
- serverMode
9465
- ),
9466
- {
9467
- status: status || 200,
9468
- headers: resultHeaders
9469
- }
9470
- );
9974
+ return response;
9471
9975
  }
9472
9976
  async function handleDocumentRequest(serverMode, build, staticHandler, request, loadContext, handleError, criticalCss) {
9473
9977
  let isSpaMode = request.headers.has("X-React-Router-SPA-Mode");
9474
- let context;
9475
9978
  try {
9476
- context = await staticHandler.query(request, {
9477
- requestContext: loadContext
9979
+ let response = await staticHandler.query(request, {
9980
+ requestContext: loadContext,
9981
+ unstable_respond: build.future.unstable_middleware ? (ctx) => renderHtml(ctx, isSpaMode) : void 0
9478
9982
  });
9983
+ return isResponse(response) ? response : renderHtml(response, isSpaMode);
9479
9984
  } catch (error) {
9480
9985
  handleError(error);
9481
9986
  return new Response(null, { status: 500 });
9482
9987
  }
9483
- if (isResponse(context)) {
9484
- return context;
9485
- }
9486
- let headers = getDocumentHeaders(build, context);
9487
- if (NO_BODY_STATUS_CODES.has(context.statusCode)) {
9488
- return new Response(null, { status: context.statusCode, headers });
9489
- }
9490
- if (context.errors) {
9491
- Object.values(context.errors).forEach((err) => {
9492
- if (!isRouteErrorResponse(err) || err.error) {
9493
- handleError(err);
9494
- }
9495
- });
9496
- context.errors = sanitizeErrors(context.errors, serverMode);
9497
- }
9498
- let state = {
9499
- loaderData: context.loaderData,
9500
- actionData: context.actionData,
9501
- errors: serializeErrors2(context.errors, serverMode)
9502
- };
9503
- let entryContext = {
9504
- manifest: build.assets,
9505
- routeModules: createEntryRouteModules(build.routes),
9506
- staticHandlerContext: context,
9507
- criticalCss,
9508
- serverHandoffString: createServerHandoffString({
9509
- basename: build.basename,
9510
- criticalCss,
9511
- future: build.future,
9512
- ssr: build.ssr,
9513
- isSpaMode
9514
- }),
9515
- serverHandoffStream: encodeViaTurboStream(
9516
- state,
9517
- request.signal,
9518
- build.entry.module.streamTimeout,
9519
- serverMode
9520
- ),
9521
- renderMeta: {},
9522
- future: build.future,
9523
- ssr: build.ssr,
9524
- isSpaMode,
9525
- serializeError: (err) => serializeError(err, serverMode)
9526
- };
9527
- let handleDocumentRequestFunction = build.entry.module.default;
9528
- try {
9529
- return await handleDocumentRequestFunction(
9530
- request,
9531
- context.statusCode,
9532
- headers,
9533
- entryContext,
9534
- loadContext
9535
- );
9536
- } catch (error) {
9537
- handleError(error);
9538
- let errorForSecondRender = error;
9539
- if (isResponse(error)) {
9540
- try {
9541
- let data2 = await unwrapResponse(error);
9542
- errorForSecondRender = new ErrorResponseImpl(
9543
- error.status,
9544
- error.statusText,
9545
- data2
9546
- );
9547
- } catch (e) {
9548
- }
9988
+ async function renderHtml(context, isSpaMode2) {
9989
+ if (isResponse(context)) {
9990
+ return context;
9991
+ }
9992
+ let headers = getDocumentHeaders(build, context);
9993
+ if (NO_BODY_STATUS_CODES.has(context.statusCode)) {
9994
+ return new Response(null, { status: context.statusCode, headers });
9549
9995
  }
9550
- context = getStaticContextFromError(
9551
- staticHandler.dataRoutes,
9552
- context,
9553
- errorForSecondRender
9554
- );
9555
9996
  if (context.errors) {
9997
+ Object.values(context.errors).forEach((err) => {
9998
+ if (!isRouteErrorResponse(err) || err.error) {
9999
+ handleError(err);
10000
+ }
10001
+ });
9556
10002
  context.errors = sanitizeErrors(context.errors, serverMode);
9557
10003
  }
9558
- let state2 = {
10004
+ let state = {
9559
10005
  loaderData: context.loaderData,
9560
10006
  actionData: context.actionData,
9561
10007
  errors: serializeErrors2(context.errors, serverMode)
9562
10008
  };
9563
- entryContext = {
9564
- ...entryContext,
10009
+ let entryContext = {
10010
+ manifest: build.assets,
10011
+ routeModules: createEntryRouteModules(build.routes),
9565
10012
  staticHandlerContext: context,
10013
+ criticalCss,
9566
10014
  serverHandoffString: createServerHandoffString({
9567
10015
  basename: build.basename,
10016
+ criticalCss,
9568
10017
  future: build.future,
9569
10018
  ssr: build.ssr,
9570
- isSpaMode
10019
+ isSpaMode: isSpaMode2
9571
10020
  }),
9572
10021
  serverHandoffStream: encodeViaTurboStream(
9573
- state2,
10022
+ state,
9574
10023
  request.signal,
9575
10024
  build.entry.module.streamTimeout,
9576
10025
  serverMode
9577
10026
  ),
9578
- renderMeta: {}
10027
+ renderMeta: {},
10028
+ future: build.future,
10029
+ ssr: build.ssr,
10030
+ isSpaMode: isSpaMode2,
10031
+ serializeError: (err) => serializeError(err, serverMode)
9579
10032
  };
10033
+ let handleDocumentRequestFunction = build.entry.module.default;
9580
10034
  try {
9581
10035
  return await handleDocumentRequestFunction(
9582
10036
  request,
@@ -9585,17 +10039,71 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
9585
10039
  entryContext,
9586
10040
  loadContext
9587
10041
  );
9588
- } catch (error2) {
9589
- handleError(error2);
9590
- return returnLastResortErrorResponse(error2, serverMode);
10042
+ } catch (error) {
10043
+ handleError(error);
10044
+ let errorForSecondRender = error;
10045
+ if (isResponse(error)) {
10046
+ try {
10047
+ let data2 = await unwrapResponse(error);
10048
+ errorForSecondRender = new ErrorResponseImpl(
10049
+ error.status,
10050
+ error.statusText,
10051
+ data2
10052
+ );
10053
+ } catch (e) {
10054
+ }
10055
+ }
10056
+ context = getStaticContextFromError(
10057
+ staticHandler.dataRoutes,
10058
+ context,
10059
+ errorForSecondRender
10060
+ );
10061
+ if (context.errors) {
10062
+ context.errors = sanitizeErrors(context.errors, serverMode);
10063
+ }
10064
+ let state2 = {
10065
+ loaderData: context.loaderData,
10066
+ actionData: context.actionData,
10067
+ errors: serializeErrors2(context.errors, serverMode)
10068
+ };
10069
+ entryContext = {
10070
+ ...entryContext,
10071
+ staticHandlerContext: context,
10072
+ serverHandoffString: createServerHandoffString({
10073
+ basename: build.basename,
10074
+ future: build.future,
10075
+ ssr: build.ssr,
10076
+ isSpaMode: isSpaMode2
10077
+ }),
10078
+ serverHandoffStream: encodeViaTurboStream(
10079
+ state2,
10080
+ request.signal,
10081
+ build.entry.module.streamTimeout,
10082
+ serverMode
10083
+ ),
10084
+ renderMeta: {}
10085
+ };
10086
+ try {
10087
+ return await handleDocumentRequestFunction(
10088
+ request,
10089
+ context.statusCode,
10090
+ headers,
10091
+ entryContext,
10092
+ loadContext
10093
+ );
10094
+ } catch (error2) {
10095
+ handleError(error2);
10096
+ return returnLastResortErrorResponse(error2, serverMode);
10097
+ }
9591
10098
  }
9592
10099
  }
9593
10100
  }
9594
- async function handleResourceRequest(serverMode, staticHandler, routeId, request, loadContext, handleError) {
10101
+ async function handleResourceRequest(serverMode, build, staticHandler, routeId, request, loadContext, handleError) {
9595
10102
  try {
9596
10103
  let response = await staticHandler.queryRoute(request, {
9597
10104
  routeId,
9598
- requestContext: loadContext
10105
+ requestContext: loadContext,
10106
+ unstable_respond: build.future.unstable_middleware ? (ctx) => ctx : void 0
9599
10107
  });
9600
10108
  if (isResponse(response)) {
9601
10109
  return response;
@@ -9615,6 +10123,13 @@ async function handleResourceRequest(serverMode, staticHandler, routeId, request
9615
10123
  }
9616
10124
  return errorResponseToJson(error, serverMode);
9617
10125
  }
10126
+ if (error instanceof Error && error.message === "Expected a response from queryRoute") {
10127
+ let newError = new Error(
10128
+ "Expected a Response to be returned from resource route handler"
10129
+ );
10130
+ handleError(newError);
10131
+ return returnLastResortErrorResponse(newError, serverMode);
10132
+ }
9618
10133
  handleError(error);
9619
10134
  return returnLastResortErrorResponse(error, serverMode);
9620
10135
  }
@@ -9931,6 +10446,8 @@ function deserializeErrors2(errors) {
9931
10446
  replace,
9932
10447
  resolvePath,
9933
10448
  unstable_HistoryRouter,
10449
+ unstable_RouterContextProvider,
10450
+ unstable_createContext,
9934
10451
  unstable_setDevServerHooks,
9935
10452
  unstable_usePrompt,
9936
10453
  useActionData,