react-router 7.2.0 → 7.3.0-pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +266 -0
  2. package/dist/development/{chunk-HA7DTUK3.mjs → chunk-3XNZT7XE.mjs} +782 -340
  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 +306 -83
  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 +784 -340
  14. package/dist/development/index.mjs +6 -2
  15. package/dist/development/lib/types/route-module.d.mts +25 -6
  16. package/dist/development/lib/types/route-module.d.ts +25 -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-ZGBK665M.mjs} +782 -340
  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 +306 -83
  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 +784 -340
  33. package/dist/production/index.mjs +6 -2
  34. package/dist/production/lib/types/route-module.d.mts +25 -6
  35. package/dist/production/lib/types/route-module.d.ts +25 -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.1
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
  // dom-export.ts
41
47
  var dom_export_exports = {};
@@ -245,6 +251,30 @@ function getUrlBasedHistory(getLocation, createHref, validateLocation, options =
245
251
  }
246
252
 
247
253
  // lib/router/utils.ts
254
+ var _map;
255
+ var unstable_RouterContextProvider = class {
256
+ constructor(init) {
257
+ __privateAdd(this, _map, /* @__PURE__ */ new Map());
258
+ if (init) {
259
+ for (let [context, value] of init) {
260
+ this.set(context, value);
261
+ }
262
+ }
263
+ }
264
+ get(context) {
265
+ if (__privateGet(this, _map).has(context)) {
266
+ return __privateGet(this, _map).get(context);
267
+ }
268
+ if (context.defaultValue !== void 0) {
269
+ return context.defaultValue;
270
+ }
271
+ throw new Error("No value found for context");
272
+ }
273
+ set(context, value) {
274
+ __privateGet(this, _map).set(context, value);
275
+ }
276
+ };
277
+ _map = new WeakMap();
248
278
  var immutableRouteKeys = /* @__PURE__ */ new Set([
249
279
  "lazy",
250
280
  "caseSensitive",
@@ -764,9 +794,9 @@ function createRouter(init) {
764
794
  );
765
795
  let inFlightDataRoutes;
766
796
  let basename = init.basename || "/";
767
- let dataStrategyImpl = init.dataStrategy || defaultDataStrategy;
768
- let patchRoutesOnNavigationImpl = init.patchRoutesOnNavigation;
797
+ let dataStrategyImpl = init.dataStrategy || defaultDataStrategyWithMiddleware;
769
798
  let future = {
799
+ unstable_middleware: false,
770
800
  ...init.future
771
801
  };
772
802
  let unlistenHistory = null;
@@ -778,7 +808,7 @@ function createRouter(init) {
778
808
  let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);
779
809
  let initialMatchesIsFOW = false;
780
810
  let initialErrors = null;
781
- if (initialMatches == null && !patchRoutesOnNavigationImpl) {
811
+ if (initialMatches == null && !init.patchRoutesOnNavigation) {
782
812
  let error = getInternalRouterError(404, {
783
813
  pathname: init.history.location.pathname
784
814
  });
@@ -1209,6 +1239,9 @@ function createRouter(init) {
1209
1239
  pendingNavigationController.signal,
1210
1240
  opts && opts.submission
1211
1241
  );
1242
+ let scopedContext = new unstable_RouterContextProvider(
1243
+ init.unstable_getContext ? await init.unstable_getContext() : void 0
1244
+ );
1212
1245
  let pendingActionResult;
1213
1246
  if (opts && opts.pendingError) {
1214
1247
  pendingActionResult = [
@@ -1221,6 +1254,7 @@ function createRouter(init) {
1221
1254
  location,
1222
1255
  opts.submission,
1223
1256
  matches,
1257
+ scopedContext,
1224
1258
  fogOfWar.active,
1225
1259
  { replace: opts.replace, flushSync: flushSync2 }
1226
1260
  );
@@ -1261,6 +1295,7 @@ function createRouter(init) {
1261
1295
  request,
1262
1296
  location,
1263
1297
  matches,
1298
+ scopedContext,
1264
1299
  fogOfWar.active,
1265
1300
  loadingNavigation,
1266
1301
  opts && opts.submission,
@@ -1281,7 +1316,7 @@ function createRouter(init) {
1281
1316
  errors
1282
1317
  });
1283
1318
  }
1284
- async function handleAction(request, location, submission, matches, isFogOfWar, opts = {}) {
1319
+ async function handleAction(request, location, submission, matches, scopedContext, isFogOfWar, opts = {}) {
1285
1320
  interruptActiveLoads();
1286
1321
  let navigation = getSubmittingNavigation(location, submission);
1287
1322
  updateState({ navigation }, { flushSync: opts.flushSync === true });
@@ -1337,13 +1372,21 @@ function createRouter(init) {
1337
1372
  } else {
1338
1373
  let results = await callDataStrategy(
1339
1374
  "action",
1340
- state,
1341
1375
  request,
1342
1376
  [actionMatch],
1343
1377
  matches,
1378
+ scopedContext,
1344
1379
  null
1345
1380
  );
1346
1381
  result = results[actionMatch.route.id];
1382
+ if (!result) {
1383
+ for (let match of matches) {
1384
+ if (results[match.route.id]) {
1385
+ result = results[match.route.id];
1386
+ break;
1387
+ }
1388
+ }
1389
+ }
1347
1390
  if (request.signal.aborted) {
1348
1391
  return { shortCircuited: true };
1349
1392
  }
@@ -1381,7 +1424,7 @@ function createRouter(init) {
1381
1424
  pendingActionResult: [actionMatch.route.id, result]
1382
1425
  };
1383
1426
  }
1384
- async function handleLoaders(request, location, matches, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync2, pendingActionResult) {
1427
+ async function handleLoaders(request, location, matches, scopedContext, isFogOfWar, overrideNavigation, submission, fetcherSubmission, replace2, initialHydration, flushSync2, pendingActionResult) {
1385
1428
  let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission);
1386
1429
  let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);
1387
1430
  let shouldUpdateNavigationState = !isUninterruptedRevalidation && !initialHydration;
@@ -1491,11 +1534,11 @@ function createRouter(init) {
1491
1534
  );
1492
1535
  }
1493
1536
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
1494
- state,
1495
1537
  matches,
1496
1538
  matchesToLoad,
1497
1539
  revalidatingFetchers,
1498
- request
1540
+ request,
1541
+ scopedContext
1499
1542
  );
1500
1543
  if (request.signal.aborted) {
1501
1544
  return { shortCircuited: true };
@@ -1603,6 +1646,9 @@ function createRouter(init) {
1603
1646
  return;
1604
1647
  }
1605
1648
  let match = getTargetMatch(matches, path);
1649
+ let scopedContext = new unstable_RouterContextProvider(
1650
+ init.unstable_getContext ? await init.unstable_getContext() : void 0
1651
+ );
1606
1652
  let preventScrollReset = (opts && opts.preventScrollReset) === true;
1607
1653
  if (submission && isMutationMethod(submission.formMethod)) {
1608
1654
  await handleFetcherAction(
@@ -1611,6 +1657,7 @@ function createRouter(init) {
1611
1657
  path,
1612
1658
  match,
1613
1659
  matches,
1660
+ scopedContext,
1614
1661
  fogOfWar.active,
1615
1662
  flushSync2,
1616
1663
  preventScrollReset,
@@ -1625,13 +1672,14 @@ function createRouter(init) {
1625
1672
  path,
1626
1673
  match,
1627
1674
  matches,
1675
+ scopedContext,
1628
1676
  fogOfWar.active,
1629
1677
  flushSync2,
1630
1678
  preventScrollReset,
1631
1679
  submission
1632
1680
  );
1633
1681
  }
1634
- async function handleFetcherAction(key, routeId, path, match, requestMatches, isFogOfWar, flushSync2, preventScrollReset, submission) {
1682
+ async function handleFetcherAction(key, routeId, path, match, requestMatches, scopedContext, isFogOfWar, flushSync2, preventScrollReset, submission) {
1635
1683
  interruptActiveLoads();
1636
1684
  fetchLoadMatches.delete(key);
1637
1685
  function detectAndHandle405Error(m) {
@@ -1664,7 +1712,8 @@ function createRouter(init) {
1664
1712
  let discoverResult = await discoverRoutes(
1665
1713
  requestMatches,
1666
1714
  path,
1667
- fetchRequest.signal
1715
+ fetchRequest.signal,
1716
+ key
1668
1717
  );
1669
1718
  if (discoverResult.type === "aborted") {
1670
1719
  return;
@@ -1691,10 +1740,10 @@ function createRouter(init) {
1691
1740
  let originatingLoadId = incrementingLoadId;
1692
1741
  let actionResults = await callDataStrategy(
1693
1742
  "action",
1694
- state,
1695
1743
  fetchRequest,
1696
1744
  [match],
1697
1745
  requestMatches,
1746
+ scopedContext,
1698
1747
  key
1699
1748
  );
1700
1749
  let actionResult = actionResults[match.route.id];
@@ -1778,11 +1827,11 @@ function createRouter(init) {
1778
1827
  abortPendingFetchRevalidations
1779
1828
  );
1780
1829
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
1781
- state,
1782
1830
  matches,
1783
1831
  matchesToLoad,
1784
1832
  revalidatingFetchers,
1785
- revalidationRequest
1833
+ revalidationRequest,
1834
+ scopedContext
1786
1835
  );
1787
1836
  if (abortController.signal.aborted) {
1788
1837
  return;
@@ -1849,7 +1898,7 @@ function createRouter(init) {
1849
1898
  isRevalidationRequired = false;
1850
1899
  }
1851
1900
  }
1852
- async function handleFetcherLoader(key, routeId, path, match, matches, isFogOfWar, flushSync2, preventScrollReset, submission) {
1901
+ async function handleFetcherLoader(key, routeId, path, match, matches, scopedContext, isFogOfWar, flushSync2, preventScrollReset, submission) {
1853
1902
  let existingFetcher = state.fetchers.get(key);
1854
1903
  updateFetcherState(
1855
1904
  key,
@@ -1869,7 +1918,8 @@ function createRouter(init) {
1869
1918
  let discoverResult = await discoverRoutes(
1870
1919
  matches,
1871
1920
  path,
1872
- fetchRequest.signal
1921
+ fetchRequest.signal,
1922
+ key
1873
1923
  );
1874
1924
  if (discoverResult.type === "aborted") {
1875
1925
  return;
@@ -1893,10 +1943,10 @@ function createRouter(init) {
1893
1943
  let originatingLoadId = incrementingLoadId;
1894
1944
  let results = await callDataStrategy(
1895
1945
  "loader",
1896
- state,
1897
1946
  fetchRequest,
1898
1947
  [match],
1899
1948
  matches,
1949
+ scopedContext,
1900
1950
  key
1901
1951
  );
1902
1952
  let result = results[match.route.id];
@@ -1998,20 +2048,21 @@ function createRouter(init) {
1998
2048
  });
1999
2049
  }
2000
2050
  }
2001
- async function callDataStrategy(type, state2, request, matchesToLoad, matches, fetcherKey) {
2051
+ async function callDataStrategy(type, request, matchesToLoad, matches, scopedContext, fetcherKey) {
2002
2052
  let results;
2003
2053
  let dataResults = {};
2004
2054
  try {
2005
2055
  results = await callDataStrategyImpl(
2006
2056
  dataStrategyImpl,
2007
2057
  type,
2008
- state2,
2009
2058
  request,
2010
2059
  matchesToLoad,
2011
2060
  matches,
2012
2061
  fetcherKey,
2013
2062
  manifest,
2014
- mapRouteProperties2
2063
+ mapRouteProperties2,
2064
+ scopedContext,
2065
+ future.unstable_middleware
2015
2066
  );
2016
2067
  } catch (e) {
2017
2068
  matchesToLoad.forEach((m) => {
@@ -2043,13 +2094,13 @@ function createRouter(init) {
2043
2094
  }
2044
2095
  return dataResults;
2045
2096
  }
2046
- async function callLoadersAndMaybeResolveData(state2, matches, matchesToLoad, fetchersToLoad, request) {
2097
+ async function callLoadersAndMaybeResolveData(matches, matchesToLoad, fetchersToLoad, request, scopedContext) {
2047
2098
  let loaderResultsPromise = callDataStrategy(
2048
2099
  "loader",
2049
- state2,
2050
2100
  request,
2051
2101
  matchesToLoad,
2052
2102
  matches,
2103
+ scopedContext,
2053
2104
  null
2054
2105
  );
2055
2106
  let fetcherResultsPromise = Promise.all(
@@ -2057,10 +2108,10 @@ function createRouter(init) {
2057
2108
  if (f.matches && f.match && f.controller) {
2058
2109
  let results = await callDataStrategy(
2059
2110
  "loader",
2060
- state2,
2061
2111
  createClientSideRequest(init.history, f.path, f.controller.signal),
2062
2112
  [f.match],
2063
2113
  f.matches,
2114
+ scopedContext,
2064
2115
  f.key
2065
2116
  );
2066
2117
  let result = results[f.match.route.id];
@@ -2282,7 +2333,7 @@ function createRouter(init) {
2282
2333
  return null;
2283
2334
  }
2284
2335
  function checkFogOfWar(matches, routesToUse, pathname) {
2285
- if (patchRoutesOnNavigationImpl) {
2336
+ if (init.patchRoutesOnNavigation) {
2286
2337
  if (!matches) {
2287
2338
  let fogMatches = matchRoutesImpl(
2288
2339
  routesToUse,
@@ -2305,8 +2356,8 @@ function createRouter(init) {
2305
2356
  }
2306
2357
  return { active: false, matches: null };
2307
2358
  }
2308
- async function discoverRoutes(matches, pathname, signal) {
2309
- if (!patchRoutesOnNavigationImpl) {
2359
+ async function discoverRoutes(matches, pathname, signal, fetcherKey) {
2360
+ if (!init.patchRoutesOnNavigation) {
2310
2361
  return { type: "success", matches };
2311
2362
  }
2312
2363
  let partialMatches = matches;
@@ -2315,10 +2366,11 @@ function createRouter(init) {
2315
2366
  let routesToUse = inFlightDataRoutes || dataRoutes;
2316
2367
  let localManifest = manifest;
2317
2368
  try {
2318
- await patchRoutesOnNavigationImpl({
2369
+ await init.patchRoutesOnNavigation({
2319
2370
  signal,
2320
2371
  path: pathname,
2321
2372
  matches: partialMatches,
2373
+ fetcherKey,
2322
2374
  patch: (routeId, children) => {
2323
2375
  if (signal.aborted) return;
2324
2376
  patchRoutesImpl(
@@ -2803,20 +2855,127 @@ async function loadLazyRouteModule(route, mapRouteProperties2, manifest) {
2803
2855
  lazy: void 0
2804
2856
  });
2805
2857
  }
2806
- async function defaultDataStrategy({
2807
- matches
2808
- }) {
2809
- let matchesToLoad = matches.filter((m) => m.shouldLoad);
2858
+ async function defaultDataStrategy(args) {
2859
+ let matchesToLoad = args.matches.filter((m) => m.shouldLoad);
2860
+ let keyedResults = {};
2810
2861
  let results = await Promise.all(matchesToLoad.map((m) => m.resolve()));
2811
- return results.reduce(
2812
- (acc, result, i) => Object.assign(acc, { [matchesToLoad[i].route.id]: result }),
2813
- {}
2862
+ results.forEach((result, i) => {
2863
+ keyedResults[matchesToLoad[i].route.id] = result;
2864
+ });
2865
+ return keyedResults;
2866
+ }
2867
+ async function defaultDataStrategyWithMiddleware(args) {
2868
+ if (!args.matches.some((m) => m.route.unstable_middleware)) {
2869
+ return defaultDataStrategy(args);
2870
+ }
2871
+ return runMiddlewarePipeline(
2872
+ args,
2873
+ false,
2874
+ () => defaultDataStrategy(args),
2875
+ (e) => ({ [e.routeId]: { type: "error", result: e.error } })
2814
2876
  );
2815
2877
  }
2816
- async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties2, requestContext) {
2878
+ async function runMiddlewarePipeline(args, propagateResult, handler, errorHandler) {
2879
+ let { matches, request, params, context } = args;
2880
+ let middlewareState = {
2881
+ handlerResult: void 0,
2882
+ propagateResult
2883
+ };
2884
+ try {
2885
+ let tuples = matches.flatMap(
2886
+ (m) => m.route.unstable_middleware ? m.route.unstable_middleware.map((fn) => [m.route.id, fn]) : []
2887
+ );
2888
+ let result = await callRouteMiddleware(
2889
+ { request, params, context },
2890
+ tuples,
2891
+ middlewareState,
2892
+ handler
2893
+ );
2894
+ return middlewareState.propagateResult ? result : middlewareState.handlerResult;
2895
+ } catch (e) {
2896
+ if (!(e instanceof MiddlewareError)) {
2897
+ throw e;
2898
+ }
2899
+ let result = await errorHandler(e);
2900
+ if (propagateResult || !middlewareState.handlerResult) {
2901
+ return result;
2902
+ }
2903
+ return Object.assign(middlewareState.handlerResult, result);
2904
+ }
2905
+ }
2906
+ var MiddlewareError = class {
2907
+ constructor(routeId, error) {
2908
+ this.routeId = routeId;
2909
+ this.error = error;
2910
+ }
2911
+ };
2912
+ async function callRouteMiddleware(args, middlewares, middlewareState, handler, idx = 0) {
2913
+ let { request } = args;
2914
+ if (request.signal.aborted) {
2915
+ if (request.signal.reason) {
2916
+ throw request.signal.reason;
2917
+ }
2918
+ throw new Error(
2919
+ `Request aborted without an \`AbortSignal.reason\`: ${request.method} ${request.url}`
2920
+ );
2921
+ }
2922
+ let tuple = middlewares[idx];
2923
+ if (!tuple) {
2924
+ middlewareState.handlerResult = await handler();
2925
+ return middlewareState.handlerResult;
2926
+ }
2927
+ let [routeId, middleware] = tuple;
2928
+ let nextCalled = false;
2929
+ let nextResult = void 0;
2930
+ let next = async () => {
2931
+ if (nextCalled) {
2932
+ throw new Error("You may only call `next()` once per middleware");
2933
+ }
2934
+ nextCalled = true;
2935
+ let result = await callRouteMiddleware(
2936
+ args,
2937
+ middlewares,
2938
+ middlewareState,
2939
+ handler,
2940
+ idx + 1
2941
+ );
2942
+ if (middlewareState.propagateResult) {
2943
+ nextResult = result;
2944
+ return nextResult;
2945
+ }
2946
+ };
2947
+ try {
2948
+ let result = await middleware(
2949
+ {
2950
+ request: args.request,
2951
+ params: args.params,
2952
+ context: args.context
2953
+ },
2954
+ next
2955
+ );
2956
+ if (nextCalled) {
2957
+ if (result === void 0) {
2958
+ return nextResult;
2959
+ } else {
2960
+ return result;
2961
+ }
2962
+ } else {
2963
+ return next();
2964
+ }
2965
+ } catch (e) {
2966
+ if (e instanceof MiddlewareError) {
2967
+ throw e;
2968
+ }
2969
+ throw new MiddlewareError(routeId, e);
2970
+ }
2971
+ }
2972
+ async function callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties2, scopedContext, enableMiddleware) {
2817
2973
  let loadRouteDefinitionsPromises = matches.map(
2818
2974
  (m) => m.route.lazy ? loadLazyRouteModule(m.route, mapRouteProperties2, manifest) : void 0
2819
2975
  );
2976
+ if (enableMiddleware) {
2977
+ await Promise.all(loadRouteDefinitionsPromises);
2978
+ }
2820
2979
  let dsMatches = matches.map((match, i) => {
2821
2980
  let loadRoutePromise = loadRouteDefinitionsPromises[i];
2822
2981
  let shouldLoad = matchesToLoad.some((m) => m.route.id === match.route.id);
@@ -2830,7 +2989,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
2830
2989
  match,
2831
2990
  loadRoutePromise,
2832
2991
  handlerOverride,
2833
- requestContext
2992
+ scopedContext
2834
2993
  ) : Promise.resolve({ type: "data" /* data */, result: void 0 });
2835
2994
  };
2836
2995
  return {
@@ -2844,7 +3003,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
2844
3003
  request,
2845
3004
  params: matches[0].params,
2846
3005
  fetcherKey,
2847
- context: requestContext
3006
+ context: scopedContext
2848
3007
  });
2849
3008
  try {
2850
3009
  await Promise.all(loadRouteDefinitionsPromises);
@@ -2852,7 +3011,7 @@ async function callDataStrategyImpl(dataStrategyImpl, type, state, request, matc
2852
3011
  }
2853
3012
  return results;
2854
3013
  }
2855
- async function callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, staticContext) {
3014
+ async function callLoaderOrAction(type, request, match, loadRoutePromise, handlerOverride, scopedContext) {
2856
3015
  let result;
2857
3016
  let onReject;
2858
3017
  let runHandler = (handler) => {
@@ -2872,7 +3031,7 @@ async function callLoaderOrAction(type, request, match, loadRoutePromise, handle
2872
3031
  {
2873
3032
  request,
2874
3033
  params: match.params,
2875
- context: staticContext
3034
+ context: scopedContext
2876
3035
  },
2877
3036
  ...ctx !== void 0 ? [ctx] : []
2878
3037
  );
@@ -4353,55 +4512,61 @@ async function createRequestInit(request) {
4353
4512
 
4354
4513
  // lib/dom/ssr/single-fetch.tsx
4355
4514
  var SingleFetchRedirectSymbol = Symbol("SingleFetchRedirect");
4356
- function getSingleFetchDataStrategy(manifest, routeModules, ssr, getRouter) {
4357
- return async ({ request, matches, fetcherKey }) => {
4515
+ function getSingleFetchDataStrategy(manifest, routeModules, ssr, basename, getRouter) {
4516
+ return async (args) => {
4517
+ let { request, matches, fetcherKey } = args;
4358
4518
  if (request.method !== "GET") {
4359
- return singleFetchActionStrategy(request, matches);
4519
+ return runMiddlewarePipeline(
4520
+ args,
4521
+ false,
4522
+ () => singleFetchActionStrategy(request, matches, basename),
4523
+ (e) => ({ [e.routeId]: { type: "error", result: e.error } })
4524
+ );
4360
4525
  }
4361
4526
  if (!ssr) {
4362
4527
  let foundRevalidatingServerLoader = matches.some(
4363
4528
  (m) => m.shouldLoad && manifest.routes[m.route.id]?.hasLoader && !manifest.routes[m.route.id]?.hasClientLoader
4364
4529
  );
4365
4530
  if (!foundRevalidatingServerLoader) {
4366
- let matchesToLoad = matches.filter((m) => m.shouldLoad);
4367
- let url = stripIndexParam(singleFetchUrl(request.url));
4368
- let init = await createRequestInit(request);
4369
- let results = {};
4370
- await Promise.all(
4371
- matchesToLoad.map(
4372
- (m) => m.resolve(async (handler) => {
4373
- try {
4374
- let result = manifest.routes[m.route.id]?.hasClientLoader ? await fetchSingleLoader(handler, url, init, m.route.id) : await handler();
4375
- results[m.route.id] = { type: "data", result };
4376
- } catch (e) {
4377
- results[m.route.id] = { type: "error", result: e };
4378
- }
4379
- })
4380
- )
4531
+ return runMiddlewarePipeline(
4532
+ args,
4533
+ false,
4534
+ () => nonSsrStrategy(manifest, request, matches, basename),
4535
+ (e) => ({ [e.routeId]: { type: "error", result: e.error } })
4381
4536
  );
4382
- return results;
4383
4537
  }
4384
4538
  }
4385
4539
  if (fetcherKey) {
4386
- return singleFetchLoaderFetcherStrategy(request, matches);
4540
+ return runMiddlewarePipeline(
4541
+ args,
4542
+ false,
4543
+ () => singleFetchLoaderFetcherStrategy(request, matches, basename),
4544
+ (e) => ({ [e.routeId]: { type: "error", result: e.error } })
4545
+ );
4387
4546
  }
4388
- return singleFetchLoaderNavigationStrategy(
4389
- manifest,
4390
- routeModules,
4391
- ssr,
4392
- getRouter(),
4393
- request,
4394
- matches
4547
+ return runMiddlewarePipeline(
4548
+ args,
4549
+ false,
4550
+ () => singleFetchLoaderNavigationStrategy(
4551
+ manifest,
4552
+ routeModules,
4553
+ ssr,
4554
+ getRouter(),
4555
+ request,
4556
+ matches,
4557
+ basename
4558
+ ),
4559
+ (e) => ({ [e.routeId]: { type: "error", result: e.error } })
4395
4560
  );
4396
4561
  };
4397
4562
  }
4398
- async function singleFetchActionStrategy(request, matches) {
4563
+ async function singleFetchActionStrategy(request, matches, basename) {
4399
4564
  let actionMatch = matches.find((m) => m.shouldLoad);
4400
4565
  invariant2(actionMatch, "No action match found");
4401
4566
  let actionStatus = void 0;
4402
4567
  let result = await actionMatch.resolve(async (handler) => {
4403
4568
  let result2 = await handler(async () => {
4404
- let url = singleFetchUrl(request.url);
4569
+ let url = singleFetchUrl(request.url, basename);
4405
4570
  let init = await createRequestInit(request);
4406
4571
  let { data: data2, status } = await fetchAndDecode(url, init);
4407
4572
  actionStatus = status;
@@ -4422,13 +4587,35 @@ async function singleFetchActionStrategy(request, matches) {
4422
4587
  }
4423
4588
  };
4424
4589
  }
4425
- async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr, router2, request, matches) {
4590
+ async function nonSsrStrategy(manifest, request, matches, basename) {
4591
+ let matchesToLoad = matches.filter((m) => m.shouldLoad);
4592
+ let url = stripIndexParam(singleFetchUrl(request.url, basename));
4593
+ let init = await createRequestInit(request);
4594
+ let results = {};
4595
+ await Promise.all(
4596
+ matchesToLoad.map(
4597
+ (m) => m.resolve(async (handler) => {
4598
+ try {
4599
+ let result = manifest.routes[m.route.id]?.hasClientLoader ? await fetchSingleLoader(handler, url, init, m.route.id) : await handler();
4600
+ results[m.route.id] = { type: "data", result };
4601
+ } catch (e) {
4602
+ results[m.route.id] = { type: "error", result: e };
4603
+ }
4604
+ })
4605
+ )
4606
+ );
4607
+ return results;
4608
+ }
4609
+ function isOptedOut(manifestRoute, routeModule, match, router2) {
4610
+ return match.route.id in router2.state.loaderData && manifestRoute && manifestRoute.hasLoader && routeModule && routeModule.shouldRevalidate;
4611
+ }
4612
+ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr, router2, request, matches, basename) {
4426
4613
  let routesParams = /* @__PURE__ */ new Set();
4427
4614
  let foundOptOutRoute = false;
4428
4615
  let routeDfds = matches.map(() => createDeferred2());
4429
4616
  let routesLoadedPromise = Promise.all(routeDfds.map((d) => d.promise));
4430
4617
  let singleFetchDfd = createDeferred2();
4431
- let url = stripIndexParam(singleFetchUrl(request.url));
4618
+ let url = stripIndexParam(singleFetchUrl(request.url, basename));
4432
4619
  let init = await createRequestInit(request);
4433
4620
  let results = {};
4434
4621
  let resolvePromise = Promise.all(
@@ -4440,7 +4627,7 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr,
4440
4627
  if (!router2.state.initialized) {
4441
4628
  return;
4442
4629
  }
4443
- if (m.route.id in router2.state.loaderData && manifestRoute && manifestRoute.hasLoader && routeModules[m.route.id]?.shouldRevalidate) {
4630
+ if (isOptedOut(manifestRoute, routeModules[m.route.id], m, router2)) {
4444
4631
  foundOptOutRoute = true;
4445
4632
  return;
4446
4633
  }
@@ -4503,11 +4690,11 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr,
4503
4690
  await resolvePromise;
4504
4691
  return results;
4505
4692
  }
4506
- async function singleFetchLoaderFetcherStrategy(request, matches) {
4693
+ async function singleFetchLoaderFetcherStrategy(request, matches, basename) {
4507
4694
  let fetcherMatch = matches.find((m) => m.shouldLoad);
4508
4695
  invariant2(fetcherMatch, "No fetcher match found");
4509
4696
  let result = await fetcherMatch.resolve(async (handler) => {
4510
- let url = stripIndexParam(singleFetchUrl(request.url));
4697
+ let url = stripIndexParam(singleFetchUrl(request.url, basename));
4511
4698
  let init = await createRequestInit(request);
4512
4699
  return fetchSingleLoader(handler, url, init, fetcherMatch.route.id);
4513
4700
  });
@@ -4535,7 +4722,7 @@ function stripIndexParam(url) {
4535
4722
  }
4536
4723
  return url;
4537
4724
  }
4538
- function singleFetchUrl(reqUrl) {
4725
+ function singleFetchUrl(reqUrl, basename) {
4539
4726
  let url = typeof reqUrl === "string" ? new URL(
4540
4727
  reqUrl,
4541
4728
  // This can be called during the SSR flow via PrefetchPageLinksImpl so
@@ -4544,6 +4731,8 @@ function singleFetchUrl(reqUrl) {
4544
4731
  ) : reqUrl;
4545
4732
  if (url.pathname === "/") {
4546
4733
  url.pathname = "_root.data";
4734
+ } else if (basename && stripBasename(url.pathname, basename) === "/") {
4735
+ url.pathname = `${basename.replace(/\/$/, "")}/_root.data`;
4547
4736
  } else {
4548
4737
  url.pathname = `${url.pathname.replace(/\/$/, "")}.data`;
4549
4738
  }
@@ -4895,6 +5084,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
4895
5084
  Object.assign(dataRoute, {
4896
5085
  ...dataRoute,
4897
5086
  ...getRouteComponents(route, routeModule, isSpaMode),
5087
+ unstable_middleware: routeModule.unstable_clientMiddleware,
4898
5088
  handle: routeModule.handle,
4899
5089
  shouldRevalidate: getShouldRevalidateFunction(
4900
5090
  routeModule,
@@ -4908,7 +5098,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
4908
5098
  let hasInitialError = initialState && initialState.errors && route.id in initialState.errors;
4909
5099
  let initialError = hasInitialError ? initialState?.errors?.[route.id] : void 0;
4910
5100
  let isHydrationRequest = needsRevalidation == null && (routeModule.clientLoader?.hydrate === true || !route.hasLoader);
4911
- dataRoute.loader = async ({ request, params }, singleFetch) => {
5101
+ dataRoute.loader = async ({ request, params, context }, singleFetch) => {
4912
5102
  try {
4913
5103
  let result = await prefetchStylesAndCallHandler(async () => {
4914
5104
  invariant2(
@@ -4921,6 +5111,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
4921
5111
  return routeModule.clientLoader({
4922
5112
  request,
4923
5113
  params,
5114
+ context,
4924
5115
  async serverLoader() {
4925
5116
  preventInvalidServerHandlerCall("loader", route);
4926
5117
  if (isHydrationRequest) {
@@ -4945,7 +5136,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
4945
5136
  routeModule,
4946
5137
  isSpaMode
4947
5138
  );
4948
- dataRoute.action = ({ request, params }, singleFetch) => {
5139
+ dataRoute.action = ({ request, params, context }, singleFetch) => {
4949
5140
  return prefetchStylesAndCallHandler(async () => {
4950
5141
  invariant2(
4951
5142
  routeModule,
@@ -4960,6 +5151,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
4960
5151
  return routeModule.clientAction({
4961
5152
  request,
4962
5153
  params,
5154
+ context,
4963
5155
  async serverAction() {
4964
5156
  preventInvalidServerHandlerCall("action", route);
4965
5157
  return fetchServerAction(singleFetch);
@@ -4969,7 +5161,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
4969
5161
  };
4970
5162
  } else {
4971
5163
  if (!route.hasClientLoader) {
4972
- dataRoute.loader = ({ request }, singleFetch) => prefetchStylesAndCallHandler(() => {
5164
+ dataRoute.loader = (_, singleFetch) => prefetchStylesAndCallHandler(() => {
4973
5165
  return fetchServerLoader(singleFetch);
4974
5166
  });
4975
5167
  } else if (route.clientLoaderModule) {
@@ -4990,7 +5182,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
4990
5182
  };
4991
5183
  }
4992
5184
  if (!route.hasClientAction) {
4993
- dataRoute.action = ({ request }, singleFetch) => prefetchStylesAndCallHandler(() => {
5185
+ dataRoute.action = (_, singleFetch) => prefetchStylesAndCallHandler(() => {
4994
5186
  if (isSpaMode) {
4995
5187
  throw noActionDefinedError("clientAction", route.id);
4996
5188
  }
@@ -5048,6 +5240,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
5048
5240
  return {
5049
5241
  ...lazyRoute.loader ? { loader: lazyRoute.loader } : {},
5050
5242
  ...lazyRoute.action ? { action: lazyRoute.action } : {},
5243
+ unstable_middleware: mod.unstable_clientMiddleware,
5051
5244
  hasErrorBoundary: lazyRoute.hasErrorBoundary,
5052
5245
  shouldRevalidate: getShouldRevalidateFunction(
5053
5246
  lazyRoute,
@@ -5120,6 +5313,7 @@ async function loadRouteModuleWithBlockingLinks(route, routeModules) {
5120
5313
  return {
5121
5314
  Component: getRouteModuleComponent(routeModule),
5122
5315
  ErrorBoundary: routeModule.ErrorBoundary,
5316
+ unstable_clientMiddleware: routeModule.unstable_clientMiddleware,
5123
5317
  clientAction: routeModule.clientAction,
5124
5318
  clientLoader: routeModule.clientLoader,
5125
5319
  handle: routeModule.handle,
@@ -5175,12 +5369,13 @@ function getPatchRoutesOnNavigationFunction(manifest, routeModules, ssr, isSpaMo
5175
5369
  if (!isFogOfWarEnabled(ssr)) {
5176
5370
  return void 0;
5177
5371
  }
5178
- return async ({ path, patch, signal }) => {
5372
+ return async ({ path, patch, signal, fetcherKey }) => {
5179
5373
  if (discoveredPaths.has(path)) {
5180
5374
  return;
5181
5375
  }
5182
5376
  await fetchAndApplyManifestPatches(
5183
5377
  [path],
5378
+ fetcherKey ? window.location.href : path,
5184
5379
  manifest,
5185
5380
  routeModules,
5186
5381
  ssr,
@@ -5221,6 +5416,7 @@ function useFogOFWarDiscovery(router2, manifest, routeModules, ssr, isSpaMode) {
5221
5416
  try {
5222
5417
  await fetchAndApplyManifestPatches(
5223
5418
  lazyPaths,
5419
+ null,
5224
5420
  manifest,
5225
5421
  routeModules,
5226
5422
  ssr,
@@ -5244,7 +5440,8 @@ function useFogOFWarDiscovery(router2, manifest, routeModules, ssr, isSpaMode) {
5244
5440
  return () => observer.disconnect();
5245
5441
  }, [ssr, isSpaMode, manifest, routeModules, router2]);
5246
5442
  }
5247
- async function fetchAndApplyManifestPatches(paths, manifest, routeModules, ssr, isSpaMode, basename, patchRoutes, signal) {
5443
+ var MANIFEST_VERSION_STORAGE_KEY = "react-router-manifest-version";
5444
+ async function fetchAndApplyManifestPatches(paths, errorReloadPath, manifest, routeModules, ssr, isSpaMode, basename, patchRoutes, signal) {
5248
5445
  let manifestPath = `${basename != null ? basename : "/"}/__manifest`.replace(
5249
5446
  /\/+/g,
5250
5447
  "/"
@@ -5261,9 +5458,26 @@ async function fetchAndApplyManifestPatches(paths, manifest, routeModules, ssr,
5261
5458
  let res = await fetch(url, { signal });
5262
5459
  if (!res.ok) {
5263
5460
  throw new Error(`${res.status} ${res.statusText}`);
5461
+ } else if (res.status === 204 && res.headers.has("X-Remix-Reload-Document")) {
5462
+ if (!errorReloadPath) {
5463
+ console.warn(
5464
+ "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."
5465
+ );
5466
+ return;
5467
+ }
5468
+ if (sessionStorage.getItem(MANIFEST_VERSION_STORAGE_KEY) === manifest.version) {
5469
+ console.error(
5470
+ "Unable to discover routes due to manifest version mismatch."
5471
+ );
5472
+ return;
5473
+ }
5474
+ sessionStorage.setItem(MANIFEST_VERSION_STORAGE_KEY, manifest.version);
5475
+ window.location.href = errorReloadPath;
5476
+ throw new Error("Detected manifest version mismatch, reloading...");
5264
5477
  } else if (res.status >= 400) {
5265
5478
  throw new Error(await res.text());
5266
5479
  }
5480
+ sessionStorage.removeItem(MANIFEST_VERSION_STORAGE_KEY);
5267
5481
  serverPatches = await res.json();
5268
5482
  } catch (e) {
5269
5483
  if (signal?.aborted) return;
@@ -5519,7 +5733,9 @@ function initSsrInfo() {
5519
5733
  };
5520
5734
  }
5521
5735
  }
5522
- function createHydratedRouter() {
5736
+ function createHydratedRouter({
5737
+ unstable_getContext
5738
+ }) {
5523
5739
  initSsrInfo();
5524
5740
  if (!ssrInfo) {
5525
5741
  throw new Error(
@@ -5589,12 +5805,17 @@ function createHydratedRouter() {
5589
5805
  routes,
5590
5806
  history: createBrowserHistory(),
5591
5807
  basename: ssrInfo.context.basename,
5808
+ unstable_getContext,
5592
5809
  hydrationData,
5593
5810
  mapRouteProperties,
5811
+ future: {
5812
+ unstable_middleware: ssrInfo.context.future.unstable_middleware
5813
+ },
5594
5814
  dataStrategy: getSingleFetchDataStrategy(
5595
5815
  ssrInfo.manifest,
5596
5816
  ssrInfo.routeModules,
5597
5817
  ssrInfo.context.ssr,
5818
+ ssrInfo.context.basename,
5598
5819
  () => router2
5599
5820
  ),
5600
5821
  patchRoutesOnNavigation: getPatchRoutesOnNavigationFunction(
@@ -5615,9 +5836,11 @@ function createHydratedRouter() {
5615
5836
  window.__reactRouterDataRouter = router2;
5616
5837
  return router2;
5617
5838
  }
5618
- function HydratedRouter() {
5839
+ function HydratedRouter(props) {
5619
5840
  if (!router) {
5620
- router = createHydratedRouter();
5841
+ router = createHydratedRouter({
5842
+ unstable_getContext: props.unstable_getContext
5843
+ });
5621
5844
  }
5622
5845
  let [criticalCss, setCriticalCss] = React11.useState(
5623
5846
  process.env.NODE_ENV === "development" ? ssrInfo?.context.criticalCss : void 0