react-router 7.5.0 → 7.5.1-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 +36 -0
  2. package/dist/development/{chunk-KNED5TY2.mjs → chunk-QP2GE2RJ.mjs} +586 -346
  3. package/dist/development/{future-ldDp5FKH.d.ts → data-CQbyyGzl.d.mts} +1 -11
  4. package/dist/{production/future-ldDp5FKH.d.mts → development/data-CQbyyGzl.d.ts} +1 -11
  5. package/dist/development/dom-export.d.mts +2 -2
  6. package/dist/development/dom-export.d.ts +2 -2
  7. package/dist/development/dom-export.js +479 -311
  8. package/dist/development/dom-export.mjs +18 -6
  9. package/dist/{production/fog-of-war-1hWhK5ey.d.mts → development/fog-of-war-CyHis97d.d.mts} +3 -2
  10. package/dist/development/{fog-of-war-oa9CGk10.d.ts → fog-of-war-D4x86-Xc.d.ts} +3 -2
  11. package/dist/development/index.d.mts +12 -8
  12. package/dist/development/index.d.ts +12 -8
  13. package/dist/development/index.js +587 -346
  14. package/dist/development/index.mjs +4 -2
  15. package/dist/development/lib/types/route-module.d.mts +2 -2
  16. package/dist/development/lib/types/route-module.d.ts +2 -2
  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/development/{route-data-5OzAzQtT.d.mts → route-data-OcOrqK13.d.mts} +30 -7
  20. package/dist/{production/route-data-5OzAzQtT.d.mts → development/route-data-OcOrqK13.d.ts} +30 -7
  21. package/dist/production/{chunk-ZIM7OIE3.mjs → chunk-TOAG3JKW.mjs} +586 -346
  22. package/dist/production/{future-ldDp5FKH.d.ts → data-CQbyyGzl.d.mts} +1 -11
  23. package/dist/{development/future-ldDp5FKH.d.mts → production/data-CQbyyGzl.d.ts} +1 -11
  24. package/dist/production/dom-export.d.mts +2 -2
  25. package/dist/production/dom-export.d.ts +2 -2
  26. package/dist/production/dom-export.js +479 -311
  27. package/dist/production/dom-export.mjs +18 -6
  28. package/dist/{development/fog-of-war-1hWhK5ey.d.mts → production/fog-of-war-CyHis97d.d.mts} +3 -2
  29. package/dist/production/{fog-of-war-oa9CGk10.d.ts → fog-of-war-D4x86-Xc.d.ts} +3 -2
  30. package/dist/production/index.d.mts +12 -8
  31. package/dist/production/index.d.ts +12 -8
  32. package/dist/production/index.js +587 -346
  33. package/dist/production/index.mjs +4 -2
  34. package/dist/production/lib/types/route-module.d.mts +2 -2
  35. package/dist/production/lib/types/route-module.d.ts +2 -2
  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/production/{route-data-5OzAzQtT.d.ts → route-data-OcOrqK13.d.mts} +30 -7
  39. package/dist/{development/route-data-5OzAzQtT.d.ts → production/route-data-OcOrqK13.d.ts} +30 -7
  40. package/package.json +1 -2
@@ -1,5 +1,5 @@
1
1
  /**
2
- * react-router v7.5.0
2
+ * react-router v7.5.1-pre.0
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -949,6 +949,7 @@ function createRouter(init) {
949
949
  init.routes.length > 0,
950
950
  "You must provide a non-empty routes array to createRouter"
951
951
  );
952
+ let hydrationRouteProperties2 = init.hydrationRouteProperties || [];
952
953
  let mapRouteProperties2 = init.mapRouteProperties || defaultMapRouteProperties;
953
954
  let manifest = {};
954
955
  let dataRoutes = convertRoutesToDataRoutes(
@@ -1421,6 +1422,7 @@ function createRouter(init) {
1421
1422
  matches,
1422
1423
  scopedContext,
1423
1424
  fogOfWar.active,
1425
+ opts && opts.initialHydration === true,
1424
1426
  { replace: opts.replace, flushSync }
1425
1427
  );
1426
1428
  if (actionResult.shortCircuited) {
@@ -1481,7 +1483,7 @@ function createRouter(init) {
1481
1483
  errors
1482
1484
  });
1483
1485
  }
1484
- async function handleAction(request, location, submission, matches, scopedContext, isFogOfWar, opts = {}) {
1486
+ async function handleAction(request, location, submission, matches, scopedContext, isFogOfWar, initialHydration, opts = {}) {
1485
1487
  interruptActiveLoads();
1486
1488
  let navigation = getSubmittingNavigation(location, submission);
1487
1489
  updateState({ navigation }, { flushSync: opts.flushSync === true });
@@ -1535,11 +1537,18 @@ function createRouter(init) {
1535
1537
  })
1536
1538
  };
1537
1539
  } else {
1538
- let results = await callDataStrategy(
1539
- "action",
1540
+ let dsMatches = getTargetedDataStrategyMatches(
1541
+ mapRouteProperties2,
1542
+ manifest,
1540
1543
  request,
1541
- [actionMatch],
1542
1544
  matches,
1545
+ actionMatch,
1546
+ initialHydration ? [] : hydrationRouteProperties2,
1547
+ scopedContext
1548
+ );
1549
+ let results = await callDataStrategy(
1550
+ request,
1551
+ dsMatches,
1543
1552
  scopedContext,
1544
1553
  null
1545
1554
  );
@@ -1638,12 +1647,17 @@ function createRouter(init) {
1638
1647
  }
1639
1648
  }
1640
1649
  let routesToUse = inFlightDataRoutes || dataRoutes;
1641
- let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(
1650
+ let { dsMatches, revalidatingFetchers } = getMatchesToLoad(
1651
+ request,
1652
+ scopedContext,
1653
+ mapRouteProperties2,
1654
+ manifest,
1642
1655
  init.history,
1643
1656
  state,
1644
1657
  matches,
1645
1658
  activeSubmission,
1646
1659
  location,
1660
+ initialHydration ? [] : hydrationRouteProperties2,
1647
1661
  initialHydration === true,
1648
1662
  isRevalidationRequired,
1649
1663
  cancelledFetcherLoads,
@@ -1655,7 +1669,7 @@ function createRouter(init) {
1655
1669
  pendingActionResult
1656
1670
  );
1657
1671
  pendingNavigationLoadId = ++incrementingLoadId;
1658
- if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {
1672
+ if (!init.dataStrategy && !dsMatches.some((m) => m.shouldLoad) && revalidatingFetchers.length === 0) {
1659
1673
  let updatedFetchers2 = markFetchRedirectsDone();
1660
1674
  completeNavigation(
1661
1675
  location,
@@ -1699,8 +1713,7 @@ function createRouter(init) {
1699
1713
  );
1700
1714
  }
1701
1715
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
1702
- matches,
1703
- matchesToLoad,
1716
+ dsMatches,
1704
1717
  revalidatingFetchers,
1705
1718
  request,
1706
1719
  scopedContext
@@ -1903,11 +1916,18 @@ function createRouter(init) {
1903
1916
  }
1904
1917
  fetchControllers.set(key, abortController);
1905
1918
  let originatingLoadId = incrementingLoadId;
1906
- let actionResults = await callDataStrategy(
1907
- "action",
1919
+ let fetchMatches = getTargetedDataStrategyMatches(
1920
+ mapRouteProperties2,
1921
+ manifest,
1908
1922
  fetchRequest,
1909
- [match],
1910
1923
  requestMatches,
1924
+ match,
1925
+ hydrationRouteProperties2,
1926
+ scopedContext
1927
+ );
1928
+ let actionResults = await callDataStrategy(
1929
+ fetchRequest,
1930
+ fetchMatches,
1911
1931
  scopedContext,
1912
1932
  key
1913
1933
  );
@@ -1956,12 +1976,17 @@ function createRouter(init) {
1956
1976
  fetchReloadIds.set(key, loadId);
1957
1977
  let loadFetcher = getLoadingFetcher(submission, actionResult.data);
1958
1978
  state.fetchers.set(key, loadFetcher);
1959
- let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(
1979
+ let { dsMatches, revalidatingFetchers } = getMatchesToLoad(
1980
+ revalidationRequest,
1981
+ scopedContext,
1982
+ mapRouteProperties2,
1983
+ manifest,
1960
1984
  init.history,
1961
1985
  state,
1962
1986
  matches,
1963
1987
  submission,
1964
1988
  nextLocation,
1989
+ hydrationRouteProperties2,
1965
1990
  false,
1966
1991
  isRevalidationRequired,
1967
1992
  cancelledFetcherLoads,
@@ -1992,8 +2017,7 @@ function createRouter(init) {
1992
2017
  abortPendingFetchRevalidations
1993
2018
  );
1994
2019
  let { loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(
1995
- matches,
1996
- matchesToLoad,
2020
+ dsMatches,
1997
2021
  revalidatingFetchers,
1998
2022
  revalidationRequest,
1999
2023
  scopedContext
@@ -2106,11 +2130,18 @@ function createRouter(init) {
2106
2130
  }
2107
2131
  fetchControllers.set(key, abortController);
2108
2132
  let originatingLoadId = incrementingLoadId;
2109
- let results = await callDataStrategy(
2110
- "loader",
2133
+ let dsMatches = getTargetedDataStrategyMatches(
2134
+ mapRouteProperties2,
2135
+ manifest,
2111
2136
  fetchRequest,
2112
- [match],
2113
2137
  matches,
2138
+ match,
2139
+ hydrationRouteProperties2,
2140
+ scopedContext
2141
+ );
2142
+ let results = await callDataStrategy(
2143
+ fetchRequest,
2144
+ dsMatches,
2114
2145
  scopedContext,
2115
2146
  key
2116
2147
  );
@@ -2213,23 +2244,20 @@ function createRouter(init) {
2213
2244
  });
2214
2245
  }
2215
2246
  }
2216
- async function callDataStrategy(type, request, matchesToLoad, matches, scopedContext, fetcherKey) {
2247
+ async function callDataStrategy(request, matches, scopedContext, fetcherKey) {
2217
2248
  let results;
2218
2249
  let dataResults = {};
2219
2250
  try {
2220
2251
  results = await callDataStrategyImpl(
2221
2252
  dataStrategyImpl,
2222
- type,
2223
2253
  request,
2224
- matchesToLoad,
2225
2254
  matches,
2226
2255
  fetcherKey,
2227
- manifest,
2228
- mapRouteProperties2,
2229
- scopedContext
2256
+ scopedContext,
2257
+ false
2230
2258
  );
2231
2259
  } catch (e) {
2232
- matchesToLoad.forEach((m) => {
2260
+ matches.filter((m) => m.shouldLoad).forEach((m) => {
2233
2261
  dataResults[m.route.id] = {
2234
2262
  type: "error" /* error */,
2235
2263
  error: e
@@ -2258,22 +2286,18 @@ function createRouter(init) {
2258
2286
  }
2259
2287
  return dataResults;
2260
2288
  }
2261
- async function callLoadersAndMaybeResolveData(matches, matchesToLoad, fetchersToLoad, request, scopedContext) {
2289
+ async function callLoadersAndMaybeResolveData(matches, fetchersToLoad, request, scopedContext) {
2262
2290
  let loaderResultsPromise = callDataStrategy(
2263
- "loader",
2264
2291
  request,
2265
- matchesToLoad,
2266
2292
  matches,
2267
2293
  scopedContext,
2268
2294
  null
2269
2295
  );
2270
2296
  let fetcherResultsPromise = Promise.all(
2271
2297
  fetchersToLoad.map(async (f) => {
2272
- if (f.matches && f.match && f.controller) {
2298
+ if (f.matches && f.match && f.request && f.controller) {
2273
2299
  let results = await callDataStrategy(
2274
- "loader",
2275
- createClientSideRequest(init.history, f.path, f.controller.signal),
2276
- [f.match],
2300
+ f.request,
2277
2301
  f.matches,
2278
2302
  scopedContext,
2279
2303
  f.key
@@ -2968,11 +2992,18 @@ function createStaticHandler(routes, opts) {
2968
2992
  error
2969
2993
  };
2970
2994
  } else {
2971
- let results = await callDataStrategy(
2972
- "action",
2995
+ let dsMatches = getTargetedDataStrategyMatches(
2996
+ mapRouteProperties2,
2997
+ manifest,
2973
2998
  request,
2974
- [actionMatch],
2975
2999
  matches,
3000
+ actionMatch,
3001
+ [],
3002
+ requestContext
3003
+ );
3004
+ let results = await callDataStrategy(
3005
+ request,
3006
+ dsMatches,
2976
3007
  isRouteRequest,
2977
3008
  requestContext,
2978
3009
  dataStrategy
@@ -3090,18 +3121,49 @@ function createStaticHandler(routes, opts) {
3090
3121
  routeId: routeMatch?.route.id
3091
3122
  });
3092
3123
  }
3093
- let requestMatches = routeMatch ? [routeMatch] : pendingActionResult && isErrorResult(pendingActionResult[1]) ? getLoaderMatchesUntilBoundary(matches, pendingActionResult[0]) : matches;
3094
- let matchesToLoad = requestMatches.filter(
3095
- (m) => (m.route.loader || m.route.lazy) && (!filterMatchesToLoad || filterMatchesToLoad(m))
3096
- );
3097
- if (matchesToLoad.length === 0) {
3124
+ let dsMatches;
3125
+ if (routeMatch) {
3126
+ dsMatches = getTargetedDataStrategyMatches(
3127
+ mapRouteProperties2,
3128
+ manifest,
3129
+ request,
3130
+ matches,
3131
+ routeMatch,
3132
+ [],
3133
+ requestContext
3134
+ );
3135
+ } else {
3136
+ let maxIdx = pendingActionResult && isErrorResult(pendingActionResult[1]) ? (
3137
+ // Up to but not including the boundary
3138
+ matches.findIndex((m) => m.route.id === pendingActionResult[0]) - 1
3139
+ ) : void 0;
3140
+ dsMatches = matches.map((match, index) => {
3141
+ if (maxIdx != null && index > maxIdx) {
3142
+ return getDataStrategyMatch(
3143
+ mapRouteProperties2,
3144
+ manifest,
3145
+ request,
3146
+ match,
3147
+ [],
3148
+ requestContext,
3149
+ false
3150
+ );
3151
+ }
3152
+ return getDataStrategyMatch(
3153
+ mapRouteProperties2,
3154
+ manifest,
3155
+ request,
3156
+ match,
3157
+ [],
3158
+ requestContext,
3159
+ (match.route.loader || match.route.lazy) != null && (!filterMatchesToLoad || filterMatchesToLoad(match))
3160
+ );
3161
+ });
3162
+ }
3163
+ if (!dataStrategy && !dsMatches.some((m) => m.shouldLoad)) {
3098
3164
  return {
3099
3165
  matches,
3100
- // Add a null for all matched routes for proper revalidation on the client
3101
- loaderData: matches.reduce(
3102
- (acc, m) => Object.assign(acc, { [m.route.id]: null }),
3103
- {}
3104
- ),
3166
+ loaderData: {},
3105
3167
  errors: pendingActionResult && isErrorResult(pendingActionResult[1]) ? {
3106
3168
  [pendingActionResult[0]]: pendingActionResult[1].error
3107
3169
  } : null,
@@ -3110,10 +3172,8 @@ function createStaticHandler(routes, opts) {
3110
3172
  };
3111
3173
  }
3112
3174
  let results = await callDataStrategy(
3113
- "loader",
3114
3175
  request,
3115
- matchesToLoad,
3116
- matches,
3176
+ dsMatches,
3117
3177
  isRouteRequest,
3118
3178
  requestContext,
3119
3179
  dataStrategy
@@ -3128,30 +3188,19 @@ function createStaticHandler(routes, opts) {
3128
3188
  true,
3129
3189
  skipLoaderErrorBubbling
3130
3190
  );
3131
- let executedLoaders = new Set(
3132
- matchesToLoad.map((match) => match.route.id)
3133
- );
3134
- matches.forEach((match) => {
3135
- if (!executedLoaders.has(match.route.id)) {
3136
- handlerContext.loaderData[match.route.id] = null;
3137
- }
3138
- });
3139
3191
  return {
3140
3192
  ...handlerContext,
3141
3193
  matches
3142
3194
  };
3143
3195
  }
3144
- async function callDataStrategy(type, request, matchesToLoad, matches, isRouteRequest, requestContext, dataStrategy) {
3196
+ async function callDataStrategy(request, matches, isRouteRequest, requestContext, dataStrategy) {
3145
3197
  let results = await callDataStrategyImpl(
3146
3198
  dataStrategy || defaultDataStrategy,
3147
- type,
3148
3199
  request,
3149
- matchesToLoad,
3150
3200
  matches,
3151
3201
  null,
3152
- manifest,
3153
- mapRouteProperties2,
3154
- requestContext
3202
+ requestContext,
3203
+ true
3155
3204
  );
3156
3205
  let dataResults = {};
3157
3206
  await Promise.all(
@@ -3357,62 +3406,78 @@ function normalizeNavigateOptions(isFetcher, path, opts) {
3357
3406
  parsedPath.search = `?${searchParams}`;
3358
3407
  return { path: createPath(parsedPath), submission };
3359
3408
  }
3360
- function getLoaderMatchesUntilBoundary(matches, boundaryId, includeBoundary = false) {
3361
- let index = matches.findIndex((m) => m.route.id === boundaryId);
3362
- if (index >= 0) {
3363
- return matches.slice(0, includeBoundary ? index + 1 : index);
3364
- }
3365
- return matches;
3366
- }
3367
- function getMatchesToLoad(history, state, matches, submission, location, initialHydration, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult) {
3409
+ function getMatchesToLoad(request, scopedContext, mapRouteProperties2, manifest, history, state, matches, submission, location, lazyRoutePropertiesToSkip, initialHydration, isRevalidationRequired, cancelledFetcherLoads, fetchersQueuedForDeletion, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionResult) {
3368
3410
  let actionResult = pendingActionResult ? isErrorResult(pendingActionResult[1]) ? pendingActionResult[1].error : pendingActionResult[1].data : void 0;
3369
3411
  let currentUrl = history.createURL(state.location);
3370
3412
  let nextUrl = history.createURL(location);
3371
- let boundaryMatches = matches;
3413
+ let maxIdx;
3372
3414
  if (initialHydration && state.errors) {
3373
- boundaryMatches = getLoaderMatchesUntilBoundary(
3374
- matches,
3375
- Object.keys(state.errors)[0],
3376
- true
3377
- );
3415
+ let boundaryId = Object.keys(state.errors)[0];
3416
+ maxIdx = matches.findIndex((m) => m.route.id === boundaryId);
3378
3417
  } else if (pendingActionResult && isErrorResult(pendingActionResult[1])) {
3379
- boundaryMatches = getLoaderMatchesUntilBoundary(
3380
- matches,
3381
- pendingActionResult[0]
3382
- );
3418
+ let boundaryId = pendingActionResult[0];
3419
+ maxIdx = matches.findIndex((m) => m.route.id === boundaryId) - 1;
3383
3420
  }
3384
3421
  let actionStatus = pendingActionResult ? pendingActionResult[1].statusCode : void 0;
3385
3422
  let shouldSkipRevalidation = actionStatus && actionStatus >= 400;
3386
- let navigationMatches = boundaryMatches.filter((match, index) => {
3423
+ let baseShouldRevalidateArgs = {
3424
+ currentUrl,
3425
+ currentParams: state.matches[0]?.params || {},
3426
+ nextUrl,
3427
+ nextParams: matches[0].params,
3428
+ ...submission,
3429
+ actionResult,
3430
+ actionStatus
3431
+ };
3432
+ let dsMatches = matches.map((match, index) => {
3387
3433
  let { route } = match;
3388
- if (route.lazy) {
3389
- return true;
3390
- }
3391
- if (route.loader == null) {
3392
- return false;
3393
- }
3394
- if (initialHydration) {
3395
- return shouldLoadRouteOnHydration(route, state.loaderData, state.errors);
3434
+ let forceShouldLoad = null;
3435
+ if (maxIdx != null && index > maxIdx) {
3436
+ forceShouldLoad = false;
3437
+ } else if (route.lazy) {
3438
+ forceShouldLoad = true;
3439
+ } else if (route.loader == null) {
3440
+ forceShouldLoad = false;
3441
+ } else if (initialHydration) {
3442
+ forceShouldLoad = shouldLoadRouteOnHydration(
3443
+ route,
3444
+ state.loaderData,
3445
+ state.errors
3446
+ );
3447
+ } else if (isNewLoader(state.loaderData, state.matches[index], match)) {
3448
+ forceShouldLoad = true;
3396
3449
  }
3397
- if (isNewLoader(state.loaderData, state.matches[index], match)) {
3398
- return true;
3450
+ if (forceShouldLoad !== null) {
3451
+ return getDataStrategyMatch(
3452
+ mapRouteProperties2,
3453
+ manifest,
3454
+ request,
3455
+ match,
3456
+ lazyRoutePropertiesToSkip,
3457
+ scopedContext,
3458
+ forceShouldLoad
3459
+ );
3399
3460
  }
3400
- let currentRouteMatch = state.matches[index];
3401
- let nextRouteMatch = match;
3402
- return shouldRevalidateLoader(match, {
3403
- currentUrl,
3404
- currentParams: currentRouteMatch.params,
3405
- nextUrl,
3406
- nextParams: nextRouteMatch.params,
3407
- ...submission,
3408
- actionResult,
3409
- actionStatus,
3410
- defaultShouldRevalidate: shouldSkipRevalidation ? false : (
3411
- // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate
3412
- isRevalidationRequired || currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search || // Search params affect all loaders
3413
- currentUrl.search !== nextUrl.search || isNewRouteInstance(currentRouteMatch, nextRouteMatch)
3414
- )
3415
- });
3461
+ let defaultShouldRevalidate = shouldSkipRevalidation ? false : (
3462
+ // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate
3463
+ isRevalidationRequired || currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search || // Search params affect all loaders
3464
+ currentUrl.search !== nextUrl.search || isNewRouteInstance(state.matches[index], match)
3465
+ );
3466
+ let shouldRevalidateArgs = {
3467
+ ...baseShouldRevalidateArgs,
3468
+ defaultShouldRevalidate
3469
+ };
3470
+ let shouldLoad = shouldRevalidateLoader(match, shouldRevalidateArgs);
3471
+ return getDataStrategyMatch(
3472
+ mapRouteProperties2,
3473
+ manifest,
3474
+ request,
3475
+ match,
3476
+ lazyRoutePropertiesToSkip,
3477
+ scopedContext,
3478
+ shouldLoad,
3479
+ shouldRevalidateArgs
3480
+ );
3416
3481
  });
3417
3482
  let revalidatingFetchers = [];
3418
3483
  fetchLoadMatches.forEach((f, key) => {
@@ -3427,44 +3492,77 @@ function getMatchesToLoad(history, state, matches, submission, location, initial
3427
3492
  path: f.path,
3428
3493
  matches: null,
3429
3494
  match: null,
3495
+ request: null,
3430
3496
  controller: null
3431
3497
  });
3432
3498
  return;
3433
3499
  }
3500
+ if (fetchRedirectIds.has(key)) {
3501
+ return;
3502
+ }
3434
3503
  let fetcher = state.fetchers.get(key);
3435
3504
  let fetcherMatch = getTargetMatch(fetcherMatches, f.path);
3436
- let shouldRevalidate = false;
3437
- if (fetchRedirectIds.has(key)) {
3438
- shouldRevalidate = false;
3439
- } else if (cancelledFetcherLoads.has(key)) {
3505
+ let fetchController = new AbortController();
3506
+ let fetchRequest = createClientSideRequest(
3507
+ history,
3508
+ f.path,
3509
+ fetchController.signal
3510
+ );
3511
+ let fetcherDsMatches = null;
3512
+ if (cancelledFetcherLoads.has(key)) {
3440
3513
  cancelledFetcherLoads.delete(key);
3441
- shouldRevalidate = true;
3514
+ fetcherDsMatches = getTargetedDataStrategyMatches(
3515
+ mapRouteProperties2,
3516
+ manifest,
3517
+ fetchRequest,
3518
+ fetcherMatches,
3519
+ fetcherMatch,
3520
+ lazyRoutePropertiesToSkip,
3521
+ scopedContext
3522
+ );
3442
3523
  } else if (fetcher && fetcher.state !== "idle" && fetcher.data === void 0) {
3443
- shouldRevalidate = isRevalidationRequired;
3524
+ if (isRevalidationRequired) {
3525
+ fetcherDsMatches = getTargetedDataStrategyMatches(
3526
+ mapRouteProperties2,
3527
+ manifest,
3528
+ fetchRequest,
3529
+ fetcherMatches,
3530
+ fetcherMatch,
3531
+ lazyRoutePropertiesToSkip,
3532
+ scopedContext
3533
+ );
3534
+ }
3444
3535
  } else {
3445
- shouldRevalidate = shouldRevalidateLoader(fetcherMatch, {
3446
- currentUrl,
3447
- currentParams: state.matches[state.matches.length - 1].params,
3448
- nextUrl,
3449
- nextParams: matches[matches.length - 1].params,
3450
- ...submission,
3451
- actionResult,
3452
- actionStatus,
3536
+ let shouldRevalidateArgs = {
3537
+ ...baseShouldRevalidateArgs,
3453
3538
  defaultShouldRevalidate: shouldSkipRevalidation ? false : isRevalidationRequired
3454
- });
3539
+ };
3540
+ if (shouldRevalidateLoader(fetcherMatch, shouldRevalidateArgs)) {
3541
+ fetcherDsMatches = getTargetedDataStrategyMatches(
3542
+ mapRouteProperties2,
3543
+ manifest,
3544
+ fetchRequest,
3545
+ fetcherMatches,
3546
+ fetcherMatch,
3547
+ lazyRoutePropertiesToSkip,
3548
+ scopedContext,
3549
+ shouldRevalidateArgs
3550
+ );
3551
+ }
3455
3552
  }
3456
- if (shouldRevalidate) {
3553
+ if (fetcherDsMatches) {
3457
3554
  revalidatingFetchers.push({
3458
3555
  key,
3459
3556
  routeId: f.routeId,
3460
3557
  path: f.path,
3461
- matches: fetcherMatches,
3558
+ matches: fetcherDsMatches,
3462
3559
  match: fetcherMatch,
3463
- controller: new AbortController()
3560
+ request: fetchRequest,
3561
+ controller: fetchController
3464
3562
  });
3465
3563
  }
3466
3564
  });
3467
- return [navigationMatches, revalidatingFetchers];
3565
+ return { dsMatches, revalidatingFetchers };
3468
3566
  }
3469
3567
  function shouldLoadRouteOnHydration(route, loaderData, errors) {
3470
3568
  if (route.lazy) {
@@ -3610,7 +3708,7 @@ var loadLazyRouteProperty = ({
3610
3708
  return propertyPromise;
3611
3709
  };
3612
3710
  var lazyRouteFunctionCache = /* @__PURE__ */ new WeakMap();
3613
- function loadLazyRoute(route, type, manifest, mapRouteProperties2) {
3711
+ function loadLazyRoute(route, type, manifest, mapRouteProperties2, lazyRoutePropertiesToSkip) {
3614
3712
  let routeToUpdate = manifest[route.id];
3615
3713
  invariant(routeToUpdate, "No route found in manifest");
3616
3714
  if (!route.lazy) {
@@ -3668,6 +3766,8 @@ function loadLazyRoute(route, type, manifest, mapRouteProperties2) {
3668
3766
  });
3669
3767
  })();
3670
3768
  lazyRouteFunctionCache.set(routeToUpdate, lazyRoutePromise2);
3769
+ lazyRoutePromise2.catch(() => {
3770
+ });
3671
3771
  return {
3672
3772
  lazyRoutePromise: lazyRoutePromise2,
3673
3773
  lazyHandlerPromise: lazyRoutePromise2
@@ -3677,6 +3777,9 @@ function loadLazyRoute(route, type, manifest, mapRouteProperties2) {
3677
3777
  let lazyPropertyPromises = [];
3678
3778
  let lazyHandlerPromise = void 0;
3679
3779
  for (let key of lazyKeys) {
3780
+ if (lazyRoutePropertiesToSkip && lazyRoutePropertiesToSkip.includes(key)) {
3781
+ continue;
3782
+ }
3680
3783
  let promise = loadLazyRouteProperty({
3681
3784
  key,
3682
3785
  route,
@@ -3690,7 +3793,11 @@ function loadLazyRoute(route, type, manifest, mapRouteProperties2) {
3690
3793
  }
3691
3794
  }
3692
3795
  }
3693
- let lazyRoutePromise = Promise.all(lazyPropertyPromises).then(() => {
3796
+ let lazyRoutePromise = lazyPropertyPromises.length > 0 ? Promise.all(lazyPropertyPromises).then(() => {
3797
+ }) : void 0;
3798
+ lazyRoutePromise?.catch(() => {
3799
+ });
3800
+ lazyHandlerPromise?.catch(() => {
3694
3801
  });
3695
3802
  return {
3696
3803
  lazyRoutePromise,
@@ -3828,59 +3935,145 @@ async function callRouteMiddleware(args, middlewares, propagateResult, middlewar
3828
3935
  throw error;
3829
3936
  }
3830
3937
  }
3831
- async function callDataStrategyImpl(dataStrategyImpl, type, request, matchesToLoad, matches, fetcherKey, manifest, mapRouteProperties2, scopedContext) {
3832
- let loadMiddlewarePromise = loadLazyMiddlewareForMatches(
3833
- matches,
3938
+ function getDataStrategyMatchLazyPromises(mapRouteProperties2, manifest, request, match, lazyRoutePropertiesToSkip) {
3939
+ let lazyMiddlewarePromise = loadLazyRouteProperty({
3940
+ key: "unstable_middleware",
3941
+ route: match.route,
3834
3942
  manifest,
3835
- mapRouteProperties2
3943
+ mapRouteProperties: mapRouteProperties2
3944
+ });
3945
+ let lazyRoutePromises = loadLazyRoute(
3946
+ match.route,
3947
+ isMutationMethod(request.method) ? "action" : "loader",
3948
+ manifest,
3949
+ mapRouteProperties2,
3950
+ lazyRoutePropertiesToSkip
3836
3951
  );
3837
- let lazyRoutePromises = matches.map(
3838
- (m) => loadLazyRoute(m.route, type, manifest, mapRouteProperties2)
3952
+ return {
3953
+ middleware: lazyMiddlewarePromise,
3954
+ route: lazyRoutePromises.lazyRoutePromise,
3955
+ handler: lazyRoutePromises.lazyHandlerPromise
3956
+ };
3957
+ }
3958
+ function getDataStrategyMatch(mapRouteProperties2, manifest, request, match, lazyRoutePropertiesToSkip, scopedContext, shouldLoad, unstable_shouldRevalidateArgs = null) {
3959
+ let isUsingNewApi = false;
3960
+ let _lazyPromises = getDataStrategyMatchLazyPromises(
3961
+ mapRouteProperties2,
3962
+ manifest,
3963
+ request,
3964
+ match,
3965
+ lazyRoutePropertiesToSkip
3839
3966
  );
3840
- if (loadMiddlewarePromise) {
3841
- await loadMiddlewarePromise;
3842
- }
3843
- let dsMatches = matches.map((match, i) => {
3844
- let { lazyRoutePromise, lazyHandlerPromise } = lazyRoutePromises[i];
3845
- let shouldLoad = matchesToLoad.some((m) => m.route.id === match.route.id);
3846
- let resolve = async (handlerOverride) => {
3847
- if (handlerOverride && request.method === "GET" && (match.route.lazy || match.route.loader)) {
3848
- shouldLoad = true;
3849
- }
3850
- return shouldLoad ? callLoaderOrAction({
3851
- type,
3852
- request,
3853
- match,
3854
- lazyHandlerPromise,
3855
- lazyRoutePromise,
3856
- handlerOverride,
3857
- scopedContext
3858
- }) : Promise.resolve({ type: "data" /* data */, result: void 0 });
3859
- };
3860
- return {
3861
- ...match,
3862
- shouldLoad,
3863
- resolve
3864
- };
3967
+ return {
3968
+ ...match,
3969
+ _lazyPromises,
3970
+ shouldLoad,
3971
+ unstable_shouldRevalidateArgs,
3972
+ unstable_shouldCallHandler(defaultShouldRevalidate) {
3973
+ isUsingNewApi = true;
3974
+ if (!unstable_shouldRevalidateArgs) {
3975
+ return shouldLoad;
3976
+ }
3977
+ if (typeof defaultShouldRevalidate === "boolean") {
3978
+ return shouldRevalidateLoader(match, {
3979
+ ...unstable_shouldRevalidateArgs,
3980
+ defaultShouldRevalidate
3981
+ });
3982
+ }
3983
+ return shouldRevalidateLoader(match, unstable_shouldRevalidateArgs);
3984
+ },
3985
+ resolve(handlerOverride) {
3986
+ if (isUsingNewApi || shouldLoad || handlerOverride && request.method === "GET" && (match.route.lazy || match.route.loader)) {
3987
+ return callLoaderOrAction({
3988
+ request,
3989
+ match,
3990
+ lazyHandlerPromise: _lazyPromises?.handler,
3991
+ lazyRoutePromise: _lazyPromises?.route,
3992
+ handlerOverride,
3993
+ scopedContext
3994
+ });
3995
+ }
3996
+ return Promise.resolve({ type: "data" /* data */, result: void 0 });
3997
+ }
3998
+ };
3999
+ }
4000
+ function getTargetedDataStrategyMatches(mapRouteProperties2, manifest, request, matches, targetMatch, lazyRoutePropertiesToSkip, scopedContext, shouldRevalidateArgs = null) {
4001
+ return matches.map((match) => {
4002
+ if (match.route.id !== targetMatch.route.id) {
4003
+ return {
4004
+ ...match,
4005
+ shouldLoad: false,
4006
+ unstable_shouldRevalidateArgs: shouldRevalidateArgs,
4007
+ unstable_shouldCallHandler: () => false,
4008
+ _lazyPromises: getDataStrategyMatchLazyPromises(
4009
+ mapRouteProperties2,
4010
+ manifest,
4011
+ request,
4012
+ match,
4013
+ lazyRoutePropertiesToSkip
4014
+ ),
4015
+ resolve: () => Promise.resolve({ type: "data", result: void 0 })
4016
+ };
4017
+ }
4018
+ return getDataStrategyMatch(
4019
+ mapRouteProperties2,
4020
+ manifest,
4021
+ request,
4022
+ match,
4023
+ lazyRoutePropertiesToSkip,
4024
+ scopedContext,
4025
+ true,
4026
+ shouldRevalidateArgs
4027
+ );
3865
4028
  });
3866
- let results = await dataStrategyImpl({
3867
- matches: dsMatches,
4029
+ }
4030
+ async function callDataStrategyImpl(dataStrategyImpl, request, matches, fetcherKey, scopedContext, isStaticHandler) {
4031
+ if (matches.some((m) => m._lazyPromises?.middleware)) {
4032
+ await Promise.all(matches.map((m) => m._lazyPromises?.middleware));
4033
+ }
4034
+ let dataStrategyArgs = {
3868
4035
  request,
3869
4036
  params: matches[0].params,
4037
+ context: scopedContext,
4038
+ matches
4039
+ };
4040
+ let unstable_runClientMiddleware = isStaticHandler ? () => {
4041
+ throw new Error(
4042
+ "You cannot call `unstable_runClientMiddleware()` from a static handler `dataStrategy`. Middleware is run outside of `dataStrategy` during SSR in order to bubble up the Response. You can enable middleware via the `respond` API in `query`/`queryRoute`"
4043
+ );
4044
+ } : (cb) => {
4045
+ let typedDataStrategyArgs = dataStrategyArgs;
4046
+ return runMiddlewarePipeline(
4047
+ typedDataStrategyArgs,
4048
+ false,
4049
+ () => cb({
4050
+ ...typedDataStrategyArgs,
4051
+ fetcherKey,
4052
+ unstable_runClientMiddleware: () => {
4053
+ throw new Error(
4054
+ "Cannot call `unstable_runClientMiddleware()` from within an `unstable_runClientMiddleware` handler"
4055
+ );
4056
+ }
4057
+ }),
4058
+ (error, routeId) => ({
4059
+ [routeId]: { type: "error", result: error }
4060
+ })
4061
+ );
4062
+ };
4063
+ let results = await dataStrategyImpl({
4064
+ ...dataStrategyArgs,
3870
4065
  fetcherKey,
3871
- context: scopedContext
4066
+ unstable_runClientMiddleware
3872
4067
  });
3873
- let allLazyRoutePromises = lazyRoutePromises.flatMap(
3874
- (promiseMap) => Object.values(promiseMap).filter(isNonNullable)
3875
- );
3876
4068
  try {
3877
- await Promise.all(allLazyRoutePromises);
4069
+ await Promise.all(
4070
+ matches.flatMap((m) => [m._lazyPromises?.handler, m._lazyPromises?.route])
4071
+ );
3878
4072
  } catch (e) {
3879
4073
  }
3880
4074
  return results;
3881
4075
  }
3882
4076
  async function callLoaderOrAction({
3883
- type,
3884
4077
  request,
3885
4078
  match,
3886
4079
  lazyHandlerPromise,
@@ -3890,6 +4083,8 @@ async function callLoaderOrAction({
3890
4083
  }) {
3891
4084
  let result;
3892
4085
  let onReject;
4086
+ let isAction = isMutationMethod(request.method);
4087
+ let type = isAction ? "action" : "loader";
3893
4088
  let runHandler = (handler) => {
3894
4089
  let reject;
3895
4090
  let abortPromise = new Promise((_, r) => reject = r);
@@ -3923,7 +4118,7 @@ async function callLoaderOrAction({
3923
4118
  return Promise.race([handlerPromise, abortPromise]);
3924
4119
  };
3925
4120
  try {
3926
- let handler = match.route[type];
4121
+ let handler = isAction ? match.route.action : match.route.loader;
3927
4122
  if (lazyHandlerPromise || lazyRoutePromise) {
3928
4123
  if (handler) {
3929
4124
  let handlerError;
@@ -3944,9 +4139,9 @@ async function callLoaderOrAction({
3944
4139
  result = value;
3945
4140
  } else {
3946
4141
  await lazyHandlerPromise;
3947
- handler = match.route[type];
3948
- if (handler) {
3949
- [result] = await Promise.all([runHandler(handler), lazyRoutePromise]);
4142
+ let handler2 = isAction ? match.route.action : match.route.loader;
4143
+ if (handler2) {
4144
+ [result] = await Promise.all([runHandler(handler2), lazyRoutePromise]);
3950
4145
  } else if (type === "action") {
3951
4146
  let url = new URL(request.url);
3952
4147
  let pathname = url.pathname + url.search;
@@ -4181,7 +4376,7 @@ function processLoaderData(state, matches, results, pendingActionResult, revalid
4181
4376
  results,
4182
4377
  pendingActionResult
4183
4378
  );
4184
- revalidatingFetchers.forEach((rf) => {
4379
+ revalidatingFetchers.filter((f) => !f.matches || f.matches.some((m) => m.shouldLoad)).forEach((rf) => {
4185
4380
  let { key, match, controller } = rf;
4186
4381
  let result = fetcherResults[key];
4187
4382
  invariant(result, "Did not find corresponding fetcher result");
@@ -5219,6 +5414,10 @@ function mapRouteProperties(route) {
5219
5414
  }
5220
5415
  return updates;
5221
5416
  }
5417
+ var hydrationRouteProperties = [
5418
+ "HydrateFallback",
5419
+ "hydrateFallbackElement"
5420
+ ];
5222
5421
  function createMemoryRouter(routes, opts) {
5223
5422
  return createRouter({
5224
5423
  basename: opts?.basename,
@@ -5230,6 +5429,7 @@ function createMemoryRouter(routes, opts) {
5230
5429
  }),
5231
5430
  hydrationData: opts?.hydrationData,
5232
5431
  routes,
5432
+ hydrationRouteProperties,
5233
5433
  mapRouteProperties,
5234
5434
  dataStrategy: opts?.dataStrategy,
5235
5435
  patchRoutesOnNavigation: opts?.patchRoutesOnNavigation
@@ -6112,6 +6312,7 @@ async function createRequestInit(request) {
6112
6312
 
6113
6313
  // lib/dom/ssr/single-fetch.tsx
6114
6314
  var SingleFetchRedirectSymbol = Symbol("SingleFetchRedirect");
6315
+ var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([100, 101, 204, 205]);
6115
6316
  function StreamTransfer({
6116
6317
  context,
6117
6318
  identifier,
@@ -6178,71 +6379,54 @@ function StreamTransfer({
6178
6379
  )));
6179
6380
  }
6180
6381
  }
6181
- function handleMiddlewareError(error, routeId) {
6182
- return { [routeId]: { type: "error", result: error } };
6382
+ function getSingleFetchDataStrategy(getRouter, getRouteInfo, ssr, basename) {
6383
+ let dataStrategy = getSingleFetchDataStrategyImpl(
6384
+ getRouter,
6385
+ getRouteInfo,
6386
+ fetchAndDecodeViaTurboStream,
6387
+ ssr,
6388
+ basename
6389
+ );
6390
+ return async (args) => args.unstable_runClientMiddleware(dataStrategy);
6183
6391
  }
6184
- function getSingleFetchDataStrategy(manifest, routeModules, ssr, basename, getRouter) {
6392
+ function getSingleFetchDataStrategyImpl(getRouter, getRouteInfo, fetchAndDecode, ssr, basename) {
6185
6393
  return async (args) => {
6186
6394
  let { request, matches, fetcherKey } = args;
6395
+ let router = getRouter();
6187
6396
  if (request.method !== "GET") {
6188
- return runMiddlewarePipeline(
6189
- args,
6190
- false,
6191
- () => singleFetchActionStrategy(request, matches, basename),
6192
- handleMiddlewareError
6193
- );
6397
+ return singleFetchActionStrategy(args, fetchAndDecode, basename);
6194
6398
  }
6195
- if (!ssr) {
6196
- let foundRevalidatingServerLoader = matches.some(
6197
- (m) => m.shouldLoad && manifest.routes[m.route.id]?.hasLoader && !manifest.routes[m.route.id]?.hasClientLoader
6198
- );
6199
- if (!foundRevalidatingServerLoader) {
6200
- return runMiddlewarePipeline(
6201
- args,
6202
- false,
6203
- () => nonSsrStrategy(manifest, request, matches, basename),
6204
- handleMiddlewareError
6205
- );
6206
- }
6399
+ let foundRevalidatingServerLoader = matches.some((m) => {
6400
+ let { hasLoader, hasClientLoader } = getRouteInfo(m.route.id);
6401
+ return m.unstable_shouldCallHandler() && hasLoader && !hasClientLoader;
6402
+ });
6403
+ if (!ssr && !foundRevalidatingServerLoader) {
6404
+ return nonSsrStrategy(args, getRouteInfo, fetchAndDecode, basename);
6207
6405
  }
6208
6406
  if (fetcherKey) {
6209
- return runMiddlewarePipeline(
6210
- args,
6211
- false,
6212
- () => singleFetchLoaderFetcherStrategy(request, matches, basename),
6213
- handleMiddlewareError
6214
- );
6407
+ return singleFetchLoaderFetcherStrategy(args, fetchAndDecode, basename);
6215
6408
  }
6216
- return runMiddlewarePipeline(
6409
+ return singleFetchLoaderNavigationStrategy(
6217
6410
  args,
6218
- false,
6219
- () => singleFetchLoaderNavigationStrategy(
6220
- manifest,
6221
- routeModules,
6222
- ssr,
6223
- getRouter(),
6224
- request,
6225
- matches,
6226
- basename
6227
- ),
6228
- handleMiddlewareError
6411
+ router,
6412
+ getRouteInfo,
6413
+ fetchAndDecode,
6414
+ ssr,
6415
+ basename
6229
6416
  );
6230
6417
  };
6231
6418
  }
6232
- async function singleFetchActionStrategy(request, matches, basename) {
6233
- let actionMatch = matches.find((m) => m.shouldLoad);
6419
+ async function singleFetchActionStrategy(args, fetchAndDecode, basename) {
6420
+ let actionMatch = args.matches.find((m) => m.unstable_shouldCallHandler());
6234
6421
  invariant2(actionMatch, "No action match found");
6235
6422
  let actionStatus = void 0;
6236
6423
  let result = await actionMatch.resolve(async (handler) => {
6237
6424
  let result2 = await handler(async () => {
6238
- let url = singleFetchUrl(request.url, basename);
6239
- let init = await createRequestInit(request);
6240
- let { data: data2, status } = await fetchAndDecode(url, init);
6241
- actionStatus = status;
6242
- return unwrapSingleFetchResult(
6243
- data2,
6425
+ let { data: data2, status } = await fetchAndDecode(args, basename, [
6244
6426
  actionMatch.route.id
6245
- );
6427
+ ]);
6428
+ actionStatus = status;
6429
+ return unwrapSingleFetchResult(data2, actionMatch.route.id);
6246
6430
  });
6247
6431
  return result2;
6248
6432
  });
@@ -6256,16 +6440,21 @@ async function singleFetchActionStrategy(request, matches, basename) {
6256
6440
  }
6257
6441
  };
6258
6442
  }
6259
- async function nonSsrStrategy(manifest, request, matches, basename) {
6260
- let matchesToLoad = matches.filter((m) => m.shouldLoad);
6261
- let url = stripIndexParam(singleFetchUrl(request.url, basename));
6262
- let init = await createRequestInit(request);
6443
+ async function nonSsrStrategy(args, getRouteInfo, fetchAndDecode, basename) {
6444
+ let matchesToLoad = args.matches.filter(
6445
+ (m) => m.unstable_shouldCallHandler()
6446
+ );
6263
6447
  let results = {};
6264
6448
  await Promise.all(
6265
6449
  matchesToLoad.map(
6266
6450
  (m) => m.resolve(async (handler) => {
6267
6451
  try {
6268
- let result = manifest.routes[m.route.id]?.hasClientLoader ? await fetchSingleLoader(handler, url, init, m.route.id) : await handler();
6452
+ let { hasClientLoader } = getRouteInfo(m.route.id);
6453
+ let routeId = m.route.id;
6454
+ let result = hasClientLoader ? await handler(async () => {
6455
+ let { data: data2 } = await fetchAndDecode(args, basename, [routeId]);
6456
+ return unwrapSingleFetchResult(data2, routeId);
6457
+ }) : await handler();
6269
6458
  results[m.route.id] = { type: "data", result };
6270
6459
  } catch (e) {
6271
6460
  results[m.route.id] = { type: "error", result: e };
@@ -6275,81 +6464,63 @@ async function nonSsrStrategy(manifest, request, matches, basename) {
6275
6464
  );
6276
6465
  return results;
6277
6466
  }
6278
- async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr, router, request, matches, basename) {
6467
+ async function singleFetchLoaderNavigationStrategy(args, router, getRouteInfo, fetchAndDecode, ssr, basename) {
6279
6468
  let routesParams = /* @__PURE__ */ new Set();
6280
6469
  let foundOptOutRoute = false;
6281
- let routeDfds = matches.map(() => createDeferred2());
6282
- let routesLoadedPromise = Promise.all(routeDfds.map((d) => d.promise));
6470
+ let routeDfds = args.matches.map(() => createDeferred2());
6283
6471
  let singleFetchDfd = createDeferred2();
6284
- let url = stripIndexParam(singleFetchUrl(request.url, basename));
6285
- let init = await createRequestInit(request);
6286
6472
  let results = {};
6287
6473
  let resolvePromise = Promise.all(
6288
- matches.map(
6474
+ args.matches.map(
6289
6475
  async (m, i) => m.resolve(async (handler) => {
6290
6476
  routeDfds[i].resolve();
6291
- let manifestRoute = manifest.routes[m.route.id];
6292
- if (!m.shouldLoad) {
6293
- if (!router.state.initialized) {
6294
- return;
6295
- }
6296
- if (m.route.id in router.state.loaderData && manifestRoute && m.route.shouldRevalidate) {
6297
- if (manifestRoute.hasLoader) {
6298
- foundOptOutRoute = true;
6299
- }
6300
- return;
6301
- }
6477
+ let routeId = m.route.id;
6478
+ let { hasLoader, hasClientLoader, hasShouldRevalidate } = getRouteInfo(routeId);
6479
+ let defaultShouldRevalidate = !m.unstable_shouldRevalidateArgs || m.unstable_shouldRevalidateArgs.actionStatus == null || m.unstable_shouldRevalidateArgs.actionStatus < 400;
6480
+ let shouldCall = m.unstable_shouldCallHandler(defaultShouldRevalidate);
6481
+ if (!shouldCall) {
6482
+ foundOptOutRoute || (foundOptOutRoute = m.unstable_shouldRevalidateArgs != null && // This is a revalidation,
6483
+ hasLoader && // for a route with a server loader,
6484
+ hasShouldRevalidate === true);
6485
+ return;
6302
6486
  }
6303
- if (manifestRoute && manifestRoute.hasClientLoader) {
6304
- if (manifestRoute.hasLoader) {
6487
+ if (hasClientLoader) {
6488
+ if (hasLoader) {
6305
6489
  foundOptOutRoute = true;
6306
6490
  }
6307
6491
  try {
6308
- let result = await fetchSingleLoader(
6309
- handler,
6310
- url,
6311
- init,
6312
- m.route.id
6313
- );
6314
- results[m.route.id] = { type: "data", result };
6492
+ let result = await handler(async () => {
6493
+ let { data: data2 } = await fetchAndDecode(args, basename, [routeId]);
6494
+ return unwrapSingleFetchResult(data2, routeId);
6495
+ });
6496
+ results[routeId] = { type: "data", result };
6315
6497
  } catch (e) {
6316
- results[m.route.id] = { type: "error", result: e };
6498
+ results[routeId] = { type: "error", result: e };
6317
6499
  }
6318
6500
  return;
6319
6501
  }
6320
- if (manifestRoute && manifestRoute.hasLoader) {
6321
- routesParams.add(m.route.id);
6502
+ if (hasLoader) {
6503
+ routesParams.add(routeId);
6322
6504
  }
6323
6505
  try {
6324
6506
  let result = await handler(async () => {
6325
6507
  let data2 = await singleFetchDfd.promise;
6326
- return unwrapSingleFetchResults(data2, m.route.id);
6508
+ return unwrapSingleFetchResult(data2, routeId);
6327
6509
  });
6328
- results[m.route.id] = {
6329
- type: "data",
6330
- result
6331
- };
6510
+ results[routeId] = { type: "data", result };
6332
6511
  } catch (e) {
6333
- results[m.route.id] = {
6334
- type: "error",
6335
- result: e
6336
- };
6512
+ results[routeId] = { type: "error", result: e };
6337
6513
  }
6338
6514
  })
6339
6515
  )
6340
6516
  );
6341
- await routesLoadedPromise;
6517
+ await Promise.all(routeDfds.map((d) => d.promise));
6342
6518
  if ((!router.state.initialized || routesParams.size === 0) && !window.__reactRouterHdrActive) {
6343
6519
  singleFetchDfd.resolve({});
6344
6520
  } else {
6521
+ let targetRoutes = ssr && foundOptOutRoute && routesParams.size > 0 ? [...routesParams.keys()] : void 0;
6345
6522
  try {
6346
- if (ssr && foundOptOutRoute && routesParams.size > 0) {
6347
- url.searchParams.set(
6348
- "_routes",
6349
- matches.filter((m) => routesParams.has(m.route.id)).map((m) => m.route.id).join(",")
6350
- );
6351
- }
6352
- let data2 = await fetchAndDecode(url, init);
6523
+ let data2 = await fetchAndDecode(args, basename, targetRoutes);
6353
6524
  singleFetchDfd.resolve(data2.data);
6354
6525
  } catch (e) {
6355
6526
  singleFetchDfd.reject(e);
@@ -6358,24 +6529,18 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, ssr,
6358
6529
  await resolvePromise;
6359
6530
  return results;
6360
6531
  }
6361
- async function singleFetchLoaderFetcherStrategy(request, matches, basename) {
6362
- let fetcherMatch = matches.find((m) => m.shouldLoad);
6532
+ async function singleFetchLoaderFetcherStrategy(args, fetchAndDecode, basename) {
6533
+ let fetcherMatch = args.matches.find((m) => m.unstable_shouldCallHandler());
6363
6534
  invariant2(fetcherMatch, "No fetcher match found");
6364
- let result = await fetcherMatch.resolve(async (handler) => {
6365
- let url = stripIndexParam(singleFetchUrl(request.url, basename));
6366
- let init = await createRequestInit(request);
6367
- return fetchSingleLoader(handler, url, init, fetcherMatch.route.id);
6368
- });
6535
+ let routeId = fetcherMatch.route.id;
6536
+ let result = await fetcherMatch.resolve(
6537
+ async (handler) => handler(async () => {
6538
+ let { data: data2 } = await fetchAndDecode(args, basename, [routeId]);
6539
+ return unwrapSingleFetchResult(data2, routeId);
6540
+ })
6541
+ );
6369
6542
  return { [fetcherMatch.route.id]: result };
6370
6543
  }
6371
- function fetchSingleLoader(handler, url, init, routeId) {
6372
- return handler(async () => {
6373
- let singleLoaderUrl = new URL(url);
6374
- singleLoaderUrl.searchParams.set("_routes", routeId);
6375
- let { data: data2 } = await fetchAndDecode(singleLoaderUrl, init);
6376
- return unwrapSingleFetchResults(data2, routeId);
6377
- });
6378
- }
6379
6544
  function stripIndexParam(url) {
6380
6545
  let indexValues = url.searchParams.getAll("index");
6381
6546
  url.searchParams.delete("index");
@@ -6406,23 +6571,51 @@ function singleFetchUrl(reqUrl, basename) {
6406
6571
  }
6407
6572
  return url;
6408
6573
  }
6409
- async function fetchAndDecode(url, init) {
6410
- let res = await fetch(url, init);
6574
+ async function fetchAndDecodeViaTurboStream(args, basename, targetRoutes) {
6575
+ let { request } = args;
6576
+ let url = singleFetchUrl(request.url, basename);
6577
+ if (request.method === "GET") {
6578
+ url = stripIndexParam(url);
6579
+ if (targetRoutes) {
6580
+ url.searchParams.set("_routes", targetRoutes.join(","));
6581
+ }
6582
+ }
6583
+ let res = await fetch(url, await createRequestInit(request));
6411
6584
  if (res.status === 404 && !res.headers.has("X-Remix-Response")) {
6412
6585
  throw new ErrorResponseImpl(404, "Not Found", true);
6413
6586
  }
6414
- const NO_BODY_STATUS_CODES2 = /* @__PURE__ */ new Set([100, 101, 204, 205]);
6415
- if (NO_BODY_STATUS_CODES2.has(res.status)) {
6416
- if (!init.method || init.method === "GET") {
6417
- return { status: res.status, data: {} };
6418
- } else {
6419
- return { status: res.status, data: { data: void 0 } };
6587
+ if (NO_BODY_STATUS_CODES.has(res.status)) {
6588
+ let routes = {};
6589
+ if (targetRoutes && request.method !== "GET") {
6590
+ routes[targetRoutes[0]] = { data: void 0 };
6420
6591
  }
6592
+ return {
6593
+ status: res.status,
6594
+ data: { routes }
6595
+ };
6421
6596
  }
6422
6597
  invariant2(res.body, "No response body to decode");
6423
6598
  try {
6424
6599
  let decoded = await decodeViaTurboStream(res.body, window);
6425
- return { status: res.status, data: decoded.value };
6600
+ let data2;
6601
+ if (request.method === "GET") {
6602
+ let typed = decoded.value;
6603
+ if (SingleFetchRedirectSymbol in typed) {
6604
+ data2 = { redirect: typed[SingleFetchRedirectSymbol] };
6605
+ } else {
6606
+ data2 = { routes: typed };
6607
+ }
6608
+ } else {
6609
+ let typed = decoded.value;
6610
+ let routeId = targetRoutes?.[0];
6611
+ invariant2(routeId, "No routeId found for single fetch call decoding");
6612
+ if ("redirect" in typed) {
6613
+ data2 = { redirect: typed };
6614
+ } else {
6615
+ data2 = { routes: { [routeId]: typed } };
6616
+ }
6617
+ }
6618
+ return { status: res.status, data: data2 };
6426
6619
  } catch (e) {
6427
6620
  throw new Error("Unable to decode turbo-stream response");
6428
6621
  }
@@ -6460,30 +6653,30 @@ function decodeViaTurboStream(body, global2) {
6460
6653
  ]
6461
6654
  });
6462
6655
  }
6463
- function unwrapSingleFetchResults(results, routeId) {
6464
- let redirect2 = results[SingleFetchRedirectSymbol];
6465
- if (redirect2) {
6466
- return unwrapSingleFetchResult(redirect2, routeId);
6467
- }
6468
- return results[routeId] !== void 0 ? unwrapSingleFetchResult(results[routeId], routeId) : null;
6469
- }
6470
6656
  function unwrapSingleFetchResult(result, routeId) {
6471
- if ("error" in result) {
6472
- throw result.error;
6473
- } else if ("redirect" in result) {
6474
- let headers = {};
6475
- if (result.revalidate) {
6476
- headers["X-Remix-Revalidate"] = "yes";
6477
- }
6478
- if (result.reload) {
6479
- headers["X-Remix-Reload-Document"] = "yes";
6480
- }
6481
- if (result.replace) {
6482
- headers["X-Remix-Replace"] = "yes";
6483
- }
6484
- throw redirect(result.redirect, { status: result.status, headers });
6485
- } else if ("data" in result) {
6486
- return result.data;
6657
+ if ("redirect" in result) {
6658
+ let {
6659
+ redirect: location,
6660
+ revalidate,
6661
+ reload,
6662
+ replace: replace2,
6663
+ status
6664
+ } = result.redirect;
6665
+ throw redirect(location, {
6666
+ status,
6667
+ headers: {
6668
+ // Three R's of redirecting (lol Veep)
6669
+ ...revalidate ? { "X-Remix-Revalidate": "yes" } : null,
6670
+ ...reload ? { "X-Remix-Reload-Document": "yes" } : null,
6671
+ ...replace2 ? { "X-Remix-Replace": "yes" } : null
6672
+ }
6673
+ });
6674
+ }
6675
+ let routeResult = result.routes[routeId];
6676
+ if ("error" in routeResult) {
6677
+ throw routeResult.error;
6678
+ } else if ("data" in routeResult) {
6679
+ return routeResult.data;
6487
6680
  } else {
6488
6681
  throw new Error(`No response found for routeId "${routeId}"`);
6489
6682
  }
@@ -6795,6 +6988,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6795
6988
  unstable_middleware: routeModule.unstable_clientMiddleware,
6796
6989
  handle: routeModule.handle,
6797
6990
  shouldRevalidate: getShouldRevalidateFunction(
6991
+ dataRoute.path,
6798
6992
  routeModule,
6799
6993
  route,
6800
6994
  ssr,
@@ -6947,6 +7141,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6947
7141
  shouldRevalidate: async () => {
6948
7142
  let lazyRoute = await getLazyRoute();
6949
7143
  return getShouldRevalidateFunction(
7144
+ dataRoute.path,
6950
7145
  lazyRoute,
6951
7146
  route,
6952
7147
  ssr,
@@ -6974,7 +7169,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, ssr, isSp
6974
7169
  return dataRoute;
6975
7170
  });
6976
7171
  }
6977
- function getShouldRevalidateFunction(route, manifestRoute, ssr, needsRevalidation) {
7172
+ function getShouldRevalidateFunction(path, route, manifestRoute, ssr, needsRevalidation) {
6978
7173
  if (needsRevalidation) {
6979
7174
  return wrapShouldRevalidateForHdr(
6980
7175
  manifestRoute.id,
@@ -6983,11 +7178,16 @@ function getShouldRevalidateFunction(route, manifestRoute, ssr, needsRevalidatio
6983
7178
  );
6984
7179
  }
6985
7180
  if (!ssr && manifestRoute.hasLoader && !manifestRoute.hasClientLoader) {
7181
+ let myParams = path ? compilePath(path)[1].map((p) => p.paramName) : [];
7182
+ const didParamsChange = (opts) => myParams.some((p) => opts.currentParams[p] !== opts.nextParams[p]);
6986
7183
  if (route.shouldRevalidate) {
6987
7184
  let fn = route.shouldRevalidate;
6988
- return (opts) => fn({ ...opts, defaultShouldRevalidate: false });
7185
+ return (opts) => fn({
7186
+ ...opts,
7187
+ defaultShouldRevalidate: didParamsChange(opts)
7188
+ });
6989
7189
  } else {
6990
- return () => false;
7190
+ return (opts) => didParamsChange(opts);
6991
7191
  }
6992
7192
  }
6993
7193
  if (ssr && route.shouldRevalidate) {
@@ -7716,7 +7916,7 @@ function mergeRefs(...refs) {
7716
7916
  var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
7717
7917
  try {
7718
7918
  if (isBrowser) {
7719
- window.__reactRouterVersion = "7.5.0";
7919
+ window.__reactRouterVersion = "7.5.1-pre.0";
7720
7920
  }
7721
7921
  } catch (e) {
7722
7922
  }
@@ -7729,6 +7929,7 @@ function createBrowserRouter(routes, opts) {
7729
7929
  hydrationData: opts?.hydrationData || parseHydrationData(),
7730
7930
  routes,
7731
7931
  mapRouteProperties,
7932
+ hydrationRouteProperties,
7732
7933
  dataStrategy: opts?.dataStrategy,
7733
7934
  patchRoutesOnNavigation: opts?.patchRoutesOnNavigation,
7734
7935
  window: opts?.window
@@ -7743,6 +7944,7 @@ function createHashRouter(routes, opts) {
7743
7944
  hydrationData: opts?.hydrationData || parseHydrationData(),
7744
7945
  routes,
7745
7946
  mapRouteProperties,
7947
+ hydrationRouteProperties,
7746
7948
  dataStrategy: opts?.dataStrategy,
7747
7949
  patchRoutesOnNavigation: opts?.patchRoutesOnNavigation,
7748
7950
  window: opts?.window
@@ -9332,13 +9534,28 @@ function createStaticHandlerDataRoutes(manifest, future, parentId = "", routesBy
9332
9534
  });
9333
9535
  let decoded = await decodeViaTurboStream(stream, global);
9334
9536
  let data2 = decoded.value;
9335
- invariant3(
9336
- data2 && route.id in data2,
9337
- "Unable to decode prerendered data"
9338
- );
9339
- let result = data2[route.id];
9340
- invariant3("data" in result, "Unable to process prerendered data");
9341
- return result.data;
9537
+ if (data2 && SingleFetchRedirectSymbol in data2) {
9538
+ let result = data2[SingleFetchRedirectSymbol];
9539
+ let init = { status: result.status };
9540
+ if (result.reload) {
9541
+ throw redirectDocument(result.redirect, init);
9542
+ } else if (result.replace) {
9543
+ throw replace(result.redirect, init);
9544
+ } else {
9545
+ throw redirect(result.redirect, init);
9546
+ }
9547
+ } else {
9548
+ invariant3(
9549
+ data2 && route.id in data2,
9550
+ "Unable to decode prerendered data"
9551
+ );
9552
+ let result = data2[route.id];
9553
+ invariant3(
9554
+ "data" in result,
9555
+ "Unable to process prerendered data"
9556
+ );
9557
+ return result.data;
9558
+ }
9342
9559
  }
9343
9560
  let val = await callRouteHandler(route.module.loader, args);
9344
9561
  return val;
@@ -9459,8 +9676,11 @@ function prependCookies(parentHeaders, childHeaders) {
9459
9676
  }
9460
9677
 
9461
9678
  // lib/server-runtime/single-fetch.ts
9462
- var NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([100, 101, 204, 205, 304]);
9463
9679
  var SINGLE_FETCH_REDIRECT_STATUS = 202;
9680
+ var SERVER_NO_BODY_STATUS_CODES = /* @__PURE__ */ new Set([
9681
+ ...NO_BODY_STATUS_CODES,
9682
+ 304
9683
+ ]);
9464
9684
  async function singleFetchAction(build, serverMode, staticHandler, request, handlerUrl, loadContext, handleError) {
9465
9685
  try {
9466
9686
  let respond2 = function(context) {
@@ -9629,7 +9849,7 @@ function generateSingleFetchResponse(request, build, serverMode, {
9629
9849
  }) {
9630
9850
  let resultHeaders = new Headers(headers);
9631
9851
  resultHeaders.set("X-Remix-Response", "yes");
9632
- if (NO_BODY_STATUS_CODES.has(status)) {
9852
+ if (SERVER_NO_BODY_STATUS_CODES.has(status)) {
9633
9853
  return new Response(null, { status, headers: resultHeaders });
9634
9854
  }
9635
9855
  resultHeaders.set("Content-Type", "text/x-script");
@@ -9738,9 +9958,6 @@ var createRequestHandler = (build, mode) => {
9738
9958
  let errorHandler;
9739
9959
  return async function requestHandler(request, initialContext) {
9740
9960
  _build = typeof build === "function" ? await build() : build;
9741
- let loadContext = _build.future.unstable_middleware ? new unstable_RouterContextProvider(
9742
- initialContext
9743
- ) : initialContext || {};
9744
9961
  if (typeof build === "function") {
9745
9962
  let derived = derive(_build, mode);
9746
9963
  routes = derived.routes;
@@ -9754,18 +9971,8 @@ var createRequestHandler = (build, mode) => {
9754
9971
  staticHandler = derived.staticHandler;
9755
9972
  errorHandler = derived.errorHandler;
9756
9973
  }
9757
- let url = new URL(request.url);
9758
- let normalizedBasename = _build.basename || "/";
9759
- let normalizedPath = url.pathname;
9760
- if (stripBasename(normalizedPath, normalizedBasename) === "/_root.data") {
9761
- normalizedPath = normalizedBasename;
9762
- } else if (normalizedPath.endsWith(".data")) {
9763
- normalizedPath = normalizedPath.replace(/\.data$/, "");
9764
- }
9765
- if (stripBasename(normalizedPath, normalizedBasename) !== "/" && normalizedPath.endsWith("/")) {
9766
- normalizedPath = normalizedPath.slice(0, -1);
9767
- }
9768
9974
  let params = {};
9975
+ let loadContext;
9769
9976
  let handleError = (error) => {
9770
9977
  if (mode === "development" /* Development */) {
9771
9978
  getDevServerHooks()?.processRequestError?.(error);
@@ -9776,6 +9983,38 @@ var createRequestHandler = (build, mode) => {
9776
9983
  request
9777
9984
  });
9778
9985
  };
9986
+ if (_build.future.unstable_middleware) {
9987
+ if (initialContext == null) {
9988
+ loadContext = new unstable_RouterContextProvider();
9989
+ } else {
9990
+ try {
9991
+ loadContext = new unstable_RouterContextProvider(
9992
+ initialContext
9993
+ );
9994
+ } catch (e) {
9995
+ let error = new Error(
9996
+ `Unable to create initial \`unstable_RouterContextProvider\` instance. Please confirm you are returning an instance of \`Map<unstable_routerContext, unknown>\` from your \`getLoadContext\` function.
9997
+
9998
+ Error: ${e instanceof Error ? e.toString() : e}`
9999
+ );
10000
+ handleError(error);
10001
+ return returnLastResortErrorResponse(error, serverMode);
10002
+ }
10003
+ }
10004
+ } else {
10005
+ loadContext = initialContext || {};
10006
+ }
10007
+ let url = new URL(request.url);
10008
+ let normalizedBasename = _build.basename || "/";
10009
+ let normalizedPath = url.pathname;
10010
+ if (stripBasename(normalizedPath, normalizedBasename) === "/_root.data") {
10011
+ normalizedPath = normalizedBasename;
10012
+ } else if (normalizedPath.endsWith(".data")) {
10013
+ normalizedPath = normalizedPath.replace(/\.data$/, "");
10014
+ }
10015
+ if (stripBasename(normalizedPath, normalizedBasename) !== "/" && normalizedPath.endsWith("/")) {
10016
+ normalizedPath = normalizedPath.slice(0, -1);
10017
+ }
9779
10018
  if (!_build.ssr) {
9780
10019
  if (_build.prerender.length === 0) {
9781
10020
  request.headers.set("X-React-Router-SPA-Mode", "yes");
@@ -9984,7 +10223,7 @@ async function handleDocumentRequest(serverMode, build, staticHandler, request,
9984
10223
  return context;
9985
10224
  }
9986
10225
  let headers = getDocumentHeaders(build, context);
9987
- if (NO_BODY_STATUS_CODES.has(context.statusCode)) {
10226
+ if (SERVER_NO_BODY_STATUS_CODES.has(context.statusCode)) {
9988
10227
  return new Response(null, { status: context.statusCode, headers });
9989
10228
  }
9990
10229
  if (context.errors) {
@@ -10409,6 +10648,7 @@ export {
10409
10648
  useAsyncError,
10410
10649
  useBlocker,
10411
10650
  mapRouteProperties,
10651
+ hydrationRouteProperties,
10412
10652
  createMemoryRouter,
10413
10653
  RouterProvider,
10414
10654
  MemoryRouter,