react-router 7.0.0-pre.1 → 7.0.0-pre.2

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 (45) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/dist/dom-export.mjs +10 -2
  3. package/dist/dom-export.mjs.map +1 -1
  4. package/dist/index.d.ts +2 -3
  5. package/dist/index.mjs +1375 -219
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/lib/components.d.ts +6 -6
  8. package/dist/lib/dom/lib.d.ts +3 -2
  9. package/dist/lib/dom/ssr/components.d.ts +0 -1
  10. package/dist/lib/dom/ssr/data.d.ts +0 -5
  11. package/dist/lib/dom/ssr/entry.d.ts +2 -1
  12. package/dist/lib/dom/ssr/routeModules.d.ts +64 -22
  13. package/dist/lib/dom/ssr/routes.d.ts +2 -5
  14. package/dist/lib/hooks.d.ts +4 -3
  15. package/dist/lib/router/router.d.ts +4 -0
  16. package/dist/lib/router/utils.d.ts +1 -9
  17. package/dist/lib/server-runtime/build.d.ts +1 -1
  18. package/dist/lib/server-runtime/cookies.d.ts +5 -5
  19. package/dist/lib/server-runtime/data.d.ts +1 -5
  20. package/dist/lib/server-runtime/routeModules.d.ts +3 -175
  21. package/dist/lib/server-runtime/routes.d.ts +2 -22
  22. package/dist/lib/server-runtime/sessions.d.ts +4 -4
  23. package/dist/lib/types.d.ts +17 -10
  24. package/dist/lib/types.mjs +1 -1
  25. package/dist/main-dom-export.js +1 -1
  26. package/dist/main.js +1 -1
  27. package/dist/react-router-dom.development.js +2 -2
  28. package/dist/react-router-dom.development.js.map +1 -1
  29. package/dist/react-router-dom.production.min.js +2 -2
  30. package/dist/react-router-dom.production.min.js.map +1 -1
  31. package/dist/react-router.development.js +196 -171
  32. package/dist/react-router.development.js.map +1 -1
  33. package/dist/react-router.production.min.js +2 -2
  34. package/dist/react-router.production.min.js.map +1 -1
  35. package/dist/umd/react-router-dom.development.js +2 -2
  36. package/dist/umd/react-router-dom.development.js.map +1 -1
  37. package/dist/umd/react-router-dom.production.min.js +2 -2
  38. package/dist/umd/react-router-dom.production.min.js.map +1 -1
  39. package/dist/umd/react-router.development.js +195 -179
  40. package/dist/umd/react-router.development.js.map +1 -1
  41. package/dist/umd/react-router.production.min.js +2 -2
  42. package/dist/umd/react-router.production.min.js.map +1 -1
  43. package/package.json +4 -4
  44. package/dist/lib/server-runtime/jsonify.d.ts +0 -33
  45. package/dist/lib/server-runtime/responses.d.ts +0 -37
@@ -1,5 +1,5 @@
1
1
  /**
2
- * React Router v7.0.0-pre.1
2
+ * React Router v7.0.0-pre.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -250,7 +250,7 @@ function createHashHistory(options = {}) {
250
250
  pathname = "/",
251
251
  search = "",
252
252
  hash = ""
253
- } = parsePath(window.location.hash.substr(1));
253
+ } = parsePath(window.location.hash.substring(1));
254
254
 
255
255
  // Hash URL should always have a leading / just like window.location.pathname
256
256
  // does, so if an app ends up at a route like /#something then we add a
@@ -313,7 +313,7 @@ function warning(cond, message) {
313
313
  }
314
314
  }
315
315
  function createKey$1() {
316
- return Math.random().toString(36).substr(2, 8);
316
+ return Math.random().toString(36).substring(2, 10);
317
317
  }
318
318
 
319
319
  /**
@@ -371,13 +371,13 @@ function parsePath(path) {
371
371
  if (path) {
372
372
  let hashIndex = path.indexOf("#");
373
373
  if (hashIndex >= 0) {
374
- parsedPath.hash = path.substr(hashIndex);
375
- path = path.substr(0, hashIndex);
374
+ parsedPath.hash = path.substring(hashIndex);
375
+ path = path.substring(0, hashIndex);
376
376
  }
377
377
  let searchIndex = path.indexOf("?");
378
378
  if (searchIndex >= 0) {
379
- parsedPath.search = path.substr(searchIndex);
380
- path = path.substr(0, searchIndex);
379
+ parsedPath.search = path.substring(searchIndex);
380
+ path = path.substring(0, searchIndex);
381
381
  }
382
382
  if (path) {
383
383
  parsedPath.pathname = path;
@@ -1237,26 +1237,6 @@ const normalizeSearch = search => !search || search === "?" ? "" : search.starts
1237
1237
  * @private
1238
1238
  */
1239
1239
  const normalizeHash = hash => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
1240
-
1241
- /**
1242
- * This is a shortcut for creating `application/json` responses. Converts `data`
1243
- * to JSON and sets the `Content-Type` header.
1244
- *
1245
- * @category Utils
1246
- */
1247
- const json$1 = (data, init = {}) => {
1248
- let responseInit = typeof init === "number" ? {
1249
- status: init
1250
- } : init;
1251
- let headers = new Headers(responseInit.headers);
1252
- if (!headers.has("Content-Type")) {
1253
- headers.set("Content-Type", "application/json; charset=utf-8");
1254
- }
1255
- return new Response(JSON.stringify(data), {
1256
- ...responseInit,
1257
- headers
1258
- });
1259
- };
1260
1240
  class DataWithResponseInit {
1261
1241
  type = "DataWithResponseInit";
1262
1242
  constructor(data, init) {
@@ -1276,6 +1256,10 @@ function data(data, init) {
1276
1256
  status: init
1277
1257
  } : init);
1278
1258
  }
1259
+
1260
+ // This is now only used by the Await component and will eventually probably
1261
+ // go away in favor of the format used by `React.use`
1262
+
1279
1263
  /**
1280
1264
  * A redirect response. Sets the status code and the `Location` header.
1281
1265
  * Defaults to "302 Found".
@@ -1459,7 +1443,7 @@ const validMutationMethodsArr = ["POST", "PUT", "PATCH", "DELETE"];
1459
1443
  const validMutationMethods = new Set(validMutationMethodsArr);
1460
1444
  const validRequestMethodsArr = ["GET", ...validMutationMethodsArr];
1461
1445
  const validRequestMethods = new Set(validRequestMethodsArr);
1462
- const redirectStatusCodes$1 = new Set([301, 302, 303, 307, 308]);
1446
+ const redirectStatusCodes = new Set([301, 302, 303, 307, 308]);
1463
1447
  const redirectPreserveMethodStatusCodes = new Set([307, 308]);
1464
1448
  const IDLE_NAVIGATION = {
1465
1449
  state: "idle",
@@ -2985,7 +2969,7 @@ function createRouter(init) {
2985
2969
  return dataResults;
2986
2970
  }
2987
2971
  for (let [routeId, result] of Object.entries(results)) {
2988
- if (isRedirectDataStrategyResultResult(result)) {
2972
+ if (isRedirectDataStrategyResult(result)) {
2989
2973
  let response = result.result;
2990
2974
  dataResults[routeId] = {
2991
2975
  type: ResultType.redirect,
@@ -2998,8 +2982,6 @@ function createRouter(init) {
2998
2982
  return dataResults;
2999
2983
  }
3000
2984
  async function callLoadersAndMaybeResolveData(state, matches, matchesToLoad, fetchersToLoad, request) {
3001
- state.matches;
3002
-
3003
2985
  // Kick off loaders and fetchers in parallel
3004
2986
  let loaderResultsPromise = callDataStrategy("loader", state, request, matchesToLoad, matches, null);
3005
2987
  let fetcherResultsPromise = Promise.all(fetchersToLoad.map(async f => {
@@ -3503,7 +3485,7 @@ function createStaticHandler$1(routes, opts) {
3503
3485
  };
3504
3486
  }
3505
3487
  let result = await queryImpl(request, location, matches, requestContext, dataStrategy || null, skipLoaderErrorBubbling === true, null);
3506
- if (isResponse$2(result)) {
3488
+ if (isResponse(result)) {
3507
3489
  return result;
3508
3490
  }
3509
3491
 
@@ -3576,7 +3558,7 @@ function createStaticHandler$1(routes, opts) {
3576
3558
  });
3577
3559
  }
3578
3560
  let result = await queryImpl(request, location, matches, requestContext, dataStrategy || null, false, match);
3579
- if (isResponse$2(result)) {
3561
+ if (isResponse(result)) {
3580
3562
  return result;
3581
3563
  }
3582
3564
  let error = result.errors ? Object.values(result.errors)[0] : undefined;
@@ -3605,7 +3587,7 @@ function createStaticHandler$1(routes, opts) {
3605
3587
  return _result;
3606
3588
  }
3607
3589
  let result = await loadRouteData(request, matches, requestContext, dataStrategy, skipLoaderErrorBubbling, routeMatch);
3608
- return isResponse$2(result) ? result : {
3590
+ return isResponse(result) ? result : {
3609
3591
  ...result,
3610
3592
  actionData: null,
3611
3593
  actionHeaders: {}
@@ -3614,7 +3596,7 @@ function createStaticHandler$1(routes, opts) {
3614
3596
  // If the user threw/returned a Response in callLoaderOrAction for a
3615
3597
  // `queryRoute` call, we throw the `DataStrategyResult` to bail out early
3616
3598
  // and then return or throw the raw Response here accordingly
3617
- if (isDataStrategyResult(e) && isResponse$2(e.result)) {
3599
+ if (isDataStrategyResult(e) && isResponse(e.result)) {
3618
3600
  if (e.type === ResultType.error) {
3619
3601
  throw e.result;
3620
3602
  }
@@ -3622,7 +3604,7 @@ function createStaticHandler$1(routes, opts) {
3622
3604
  }
3623
3605
  // Redirects are always returned since they don't propagate to catch
3624
3606
  // boundaries
3625
- if (isRedirectResponse$1(e)) {
3607
+ if (isRedirectResponse(e)) {
3626
3608
  return e;
3627
3609
  }
3628
3610
  throw e;
@@ -3782,12 +3764,12 @@ function createStaticHandler$1(routes, opts) {
3782
3764
  return;
3783
3765
  }
3784
3766
  let result = results[match.route.id];
3785
- if (isRedirectDataStrategyResultResult(result)) {
3767
+ if (isRedirectDataStrategyResult(result)) {
3786
3768
  let response = result.result;
3787
3769
  // Throw redirects and let the server handle them with an HTTP redirect
3788
3770
  throw normalizeRelativeRoutingRedirectResponse(response, request, match.route.id, matches, basename);
3789
3771
  }
3790
- if (isResponse$2(result.result) && isRouteRequest) {
3772
+ if (isResponse(result.result) && isRouteRequest) {
3791
3773
  // For SSR single-route requests, we want to hand Responses back
3792
3774
  // directly without unwrapping
3793
3775
  throw result;
@@ -4493,7 +4475,7 @@ async function convertDataStrategyResultToDataResult(dataStrategyResult) {
4493
4475
  result,
4494
4476
  type
4495
4477
  } = dataStrategyResult;
4496
- if (isResponse$2(result)) {
4478
+ if (isResponse(result)) {
4497
4479
  let data;
4498
4480
  try {
4499
4481
  let contentType = result.headers.get("Content-Type");
@@ -4893,8 +4875,8 @@ function isHashChangeOnly(a, b) {
4893
4875
  function isDataStrategyResult(result) {
4894
4876
  return result != null && typeof result === "object" && "type" in result && "result" in result && (result.type === ResultType.data || result.type === ResultType.error);
4895
4877
  }
4896
- function isRedirectDataStrategyResultResult(result) {
4897
- return isResponse$2(result.result) && redirectStatusCodes$1.has(result.result.status);
4878
+ function isRedirectDataStrategyResult(result) {
4879
+ return isResponse(result.result) && redirectStatusCodes.has(result.result.status);
4898
4880
  }
4899
4881
  function isErrorResult(result) {
4900
4882
  return result.type === ResultType.error;
@@ -4905,16 +4887,14 @@ function isRedirectResult(result) {
4905
4887
  function isDataWithResponseInit(value) {
4906
4888
  return typeof value === "object" && value != null && "type" in value && "data" in value && "init" in value && value.type === "DataWithResponseInit";
4907
4889
  }
4908
- function isResponse$2(value) {
4890
+ function isResponse(value) {
4909
4891
  return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
4910
4892
  }
4911
- function isRedirectResponse$1(result) {
4912
- if (!isResponse$2(result)) {
4913
- return false;
4914
- }
4915
- let status = result.status;
4916
- let location = result.headers.get("Location");
4917
- return status >= 300 && status <= 399 && location != null;
4893
+ function isRedirectStatusCode(statusCode) {
4894
+ return redirectStatusCodes.has(statusCode);
4895
+ }
4896
+ function isRedirectResponse(result) {
4897
+ return isResponse(result) && isRedirectStatusCode(result.status) && result.headers.has("Location");
4918
4898
  }
4919
4899
  function isValidMethod(method) {
4920
4900
  return validRequestMethods.has(method.toUpperCase());
@@ -6347,8 +6327,8 @@ function RouterProvider({
6347
6327
  let fetcherData = React.useRef(new Map());
6348
6328
  let setState = React.useCallback((newState, {
6349
6329
  deletedFetchers,
6350
- flushSync: flushSync,
6351
- viewTransitionOpts: viewTransitionOpts
6330
+ flushSync,
6331
+ viewTransitionOpts
6352
6332
  }) => {
6353
6333
  deletedFetchers.forEach(key => fetcherData.current.delete(key));
6354
6334
  newState.fetchers.forEach((fetcher, key) => {
@@ -7238,7 +7218,56 @@ function invariant$1(value, message) {
7238
7218
  * @see https://remix.run/route/meta
7239
7219
  */
7240
7220
 
7241
- // Loose copy from @react-router/server-runtime to avoid circular imports
7221
+ /**
7222
+ * A function that returns an array of data objects to use for rendering
7223
+ * metadata HTML tags in a route. These tags are not rendered on descendant
7224
+ * routes in the route hierarchy. In other words, they will only be rendered on
7225
+ * the route in which they are exported.
7226
+ *
7227
+ * @param Loader - The type of the current route's loader function
7228
+ * @param MatchLoaders - Mapping from a parent route's filepath to its loader
7229
+ * function type
7230
+ *
7231
+ * Note that parent route filepaths are relative to the `app/` directory.
7232
+ *
7233
+ * For example, if this meta function is for `/sales/customers/$customerId`:
7234
+ *
7235
+ * ```ts
7236
+ * // app/root.tsx
7237
+ * const loader = () => ({ hello: "world" })
7238
+ * export type Loader = typeof loader
7239
+ *
7240
+ * // app/routes/sales.tsx
7241
+ * const loader = () => ({ salesCount: 1074 })
7242
+ * export type Loader = typeof loader
7243
+ *
7244
+ * // app/routes/sales/customers.tsx
7245
+ * const loader = () => ({ customerCount: 74 })
7246
+ * export type Loader = typeof loader
7247
+ *
7248
+ * // app/routes/sales/customers/$customersId.tsx
7249
+ * import type { Loader as RootLoader } from "../../../root"
7250
+ * import type { Loader as SalesLoader } from "../../sales"
7251
+ * import type { Loader as CustomersLoader } from "../../sales/customers"
7252
+ *
7253
+ * const loader = () => ({ name: "Customer name" })
7254
+ *
7255
+ * const meta: MetaFunction<typeof loader, {
7256
+ * "root": RootLoader,
7257
+ * "routes/sales": SalesLoader,
7258
+ * "routes/sales/customers": CustomersLoader,
7259
+ * }> = ({ data, matches }) => {
7260
+ * const { name } = data
7261
+ * // ^? string
7262
+ * const { customerCount } = matches.find((match) => match.id === "routes/sales/customers").data
7263
+ * // ^? number
7264
+ * const { salesCount } = matches.find((match) => match.id === "routes/sales").data
7265
+ * // ^? number
7266
+ * const { hello } = matches.find((match) => match.id === "root").data
7267
+ * // ^? "world"
7268
+ * }
7269
+ * ```
7270
+ */
7242
7271
 
7243
7272
  /**
7244
7273
  * A React component that is rendered for a route.
@@ -7295,7 +7324,7 @@ function getKeyedLinksForMatches(matches, routeModules, manifest) {
7295
7324
  let descriptors = matches.map(match => {
7296
7325
  let module = routeModules[match.route.id];
7297
7326
  let route = manifest.routes[match.route.id];
7298
- return [route.css ? route.css.map(href => ({
7327
+ return [route && route.css ? route.css.map(href => ({
7299
7328
  rel: "stylesheet",
7300
7329
  href
7301
7330
  })) : [], module?.links?.() || []];
@@ -7375,8 +7404,12 @@ function isHtmlLinkDescriptor(object) {
7375
7404
  }
7376
7405
  async function getKeyedPrefetchLinks(matches, manifest, routeModules) {
7377
7406
  let links = await Promise.all(matches.map(async match => {
7378
- let mod = await loadRouteModule(manifest.routes[match.route.id], routeModules);
7379
- return mod.links ? mod.links() : [];
7407
+ let route = manifest.routes[match.route.id];
7408
+ if (route) {
7409
+ let mod = await loadRouteModule(route, routeModules);
7410
+ return mod.links ? mod.links() : [];
7411
+ }
7412
+ return [];
7380
7413
  }));
7381
7414
  return dedupeLinkDescriptors(links.flat(1).filter(isHtmlLinkDescriptor).filter(link => link.rel === "stylesheet" || link.rel === "preload").map(link => link.rel === "stylesheet" ? {
7382
7415
  ...link,
@@ -7390,7 +7423,6 @@ async function getKeyedPrefetchLinks(matches, manifest, routeModules) {
7390
7423
 
7391
7424
  // This is ridiculously identical to transition.ts `filterMatchesToLoad`
7392
7425
  function getNewMatchesForLinks(page, nextMatches, currentMatches, manifest, location, mode) {
7393
- let path = parsePathPatch(page);
7394
7426
  let isNew = (match, index) => {
7395
7427
  if (!currentMatches[index]) return true;
7396
7428
  return match.route.id !== currentMatches[index].route.id;
@@ -7404,42 +7436,44 @@ function getNewMatchesForLinks(page, nextMatches, currentMatches, manifest, loca
7404
7436
  currentMatches[index].route.path?.endsWith("*") && currentMatches[index].params["*"] !== match.params["*"]
7405
7437
  );
7406
7438
  };
7439
+ if (mode === "assets") {
7440
+ return nextMatches.filter((match, index) => isNew(match, index) || matchPathChanged(match, index));
7441
+ }
7407
7442
 
7408
- // NOTE: keep this mostly up-to-date w/ the transition data diff, but this
7443
+ // NOTE: keep this mostly up-to-date w/ the router data diff, but this
7409
7444
  // version doesn't care about submissions
7410
- let newMatches = mode === "data" && location.search !== path.search ?
7411
- // this is really similar to stuff in transition.ts, maybe somebody smarter
7445
+ // TODO: this is really similar to stuff in router.ts, maybe somebody smarter
7412
7446
  // than me (or in less of a hurry) can share some of it. You're the best.
7413
- nextMatches.filter((match, index) => {
7414
- let manifestRoute = manifest.routes[match.route.id];
7415
- if (!manifestRoute.hasLoader) {
7416
- return false;
7417
- }
7418
- if (isNew(match, index) || matchPathChanged(match, index)) {
7419
- return true;
7420
- }
7421
- if (match.route.shouldRevalidate) {
7422
- let routeChoice = match.route.shouldRevalidate({
7423
- currentUrl: new URL(location.pathname + location.search + location.hash, window.origin),
7424
- currentParams: currentMatches[0]?.params || {},
7425
- nextUrl: new URL(page, window.origin),
7426
- nextParams: match.params,
7427
- defaultShouldRevalidate: true
7428
- });
7429
- if (typeof routeChoice === "boolean") {
7430
- return routeChoice;
7447
+ if (mode === "data") {
7448
+ return nextMatches.filter((match, index) => {
7449
+ let manifestRoute = manifest.routes[match.route.id];
7450
+ if (!manifestRoute || !manifestRoute.hasLoader) {
7451
+ return false;
7431
7452
  }
7432
- }
7433
- return true;
7434
- }) : nextMatches.filter((match, index) => {
7435
- let manifestRoute = manifest.routes[match.route.id];
7436
- return (mode === "assets" || manifestRoute.hasLoader) && (isNew(match, index) || matchPathChanged(match, index));
7437
- });
7438
- return newMatches;
7453
+ if (isNew(match, index) || matchPathChanged(match, index)) {
7454
+ return true;
7455
+ }
7456
+ if (match.route.shouldRevalidate) {
7457
+ let routeChoice = match.route.shouldRevalidate({
7458
+ currentUrl: new URL(location.pathname + location.search + location.hash, window.origin),
7459
+ currentParams: currentMatches[0]?.params || {},
7460
+ nextUrl: new URL(page, window.origin),
7461
+ nextParams: match.params,
7462
+ defaultShouldRevalidate: true
7463
+ });
7464
+ if (typeof routeChoice === "boolean") {
7465
+ return routeChoice;
7466
+ }
7467
+ }
7468
+ return true;
7469
+ });
7470
+ }
7471
+ return [];
7439
7472
  }
7440
7473
  function getModuleLinkHrefs(matches, manifestPatch) {
7441
7474
  return dedupeHrefs(matches.map(match => {
7442
7475
  let route = manifestPatch.routes[match.route.id];
7476
+ if (!route) return [];
7443
7477
  let hrefs = [route.module];
7444
7478
  if (route.imports) {
7445
7479
  hrefs = hrefs.concat(route.imports);
@@ -7454,6 +7488,7 @@ function getModuleLinkHrefs(matches, manifestPatch) {
7454
7488
  function getCurrentPageModulePreloadHrefs(matches, manifest) {
7455
7489
  return dedupeHrefs(matches.map(match => {
7456
7490
  let route = manifest.routes[match.route.id];
7491
+ if (!route) return [];
7457
7492
  let hrefs = [route.module];
7458
7493
  if (route.imports) {
7459
7494
  hrefs = hrefs.concat(route.imports);
@@ -7492,13 +7527,6 @@ function dedupeLinkDescriptors(descriptors, preloads) {
7492
7527
  }, []);
7493
7528
  }
7494
7529
 
7495
- // https://github.com/remix-run/history/issues/897
7496
- function parsePathPatch(href) {
7497
- let path = parsePath(href);
7498
- if (path.search === undefined) path.search = "";
7499
- return path;
7500
- }
7501
-
7502
7530
  // Detect if this browser supports <link rel="preload"> (or has it enabled).
7503
7531
  // Originally added to handle the firefox `network.preload` config:
7504
7532
  // https://bugzilla.mozilla.org/show_bug.cgi?id=1847811
@@ -7536,13 +7564,6 @@ function createHtml(html) {
7536
7564
  };
7537
7565
  }
7538
7566
 
7539
- /**
7540
- * Data for a route that was returned from a `loader()`.
7541
- */
7542
-
7543
- function isResponse$1(value) {
7544
- return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
7545
- }
7546
7567
  async function createRequestInit(request) {
7547
7568
  let init = {
7548
7569
  signal: request.signal
@@ -7679,7 +7700,7 @@ async function singleFetchActionStrategy(request, matches) {
7679
7700
  });
7680
7701
  return result;
7681
7702
  });
7682
- if (isResponse$1(result.result) || isRouteErrorResponse(result.result)) {
7703
+ if (isResponse(result.result) || isRouteErrorResponse(result.result)) {
7683
7704
  return {
7684
7705
  [actionMatch.route.id]: result
7685
7706
  };
@@ -7724,6 +7745,7 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, route
7724
7745
  let results = {};
7725
7746
  let resolvePromise = Promise.all(matches.map(async (m, i) => m.resolve(async handler => {
7726
7747
  routeDfds[i].resolve();
7748
+ let manifestRoute = manifest.routes[m.route.id];
7727
7749
  if (!m.shouldLoad) {
7728
7750
  // If we're not yet initialized and this is the initial load, respect
7729
7751
  // `shouldLoad` because we're only dealing with `clientLoader.hydrate`
@@ -7735,7 +7757,7 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, route
7735
7757
  // Otherwise, we opt out if we currently have data, a `loader`, and a
7736
7758
  // `shouldRevalidate` function. This implies that the user opted out
7737
7759
  // via `shouldRevalidate`
7738
- if (m.route.id in router.state.loaderData && manifest.routes[m.route.id].hasLoader && routeModules[m.route.id]?.shouldRevalidate) {
7760
+ if (m.route.id in router.state.loaderData && manifestRoute && manifestRoute.hasLoader && routeModules[m.route.id]?.shouldRevalidate) {
7739
7761
  foundOptOutRoute = true;
7740
7762
  return;
7741
7763
  }
@@ -7743,8 +7765,8 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, route
7743
7765
 
7744
7766
  // When a route has a client loader, it opts out of the singular call and
7745
7767
  // calls it's server loader via `serverLoader()` using a `?_routes` param
7746
- if (manifest.routes[m.route.id].hasClientLoader) {
7747
- if (manifest.routes[m.route.id].hasLoader) {
7768
+ if (manifestRoute && manifestRoute.hasClientLoader) {
7769
+ if (manifestRoute.hasLoader) {
7748
7770
  foundOptOutRoute = true;
7749
7771
  }
7750
7772
  try {
@@ -7763,7 +7785,7 @@ async function singleFetchLoaderNavigationStrategy(manifest, routeModules, route
7763
7785
  }
7764
7786
 
7765
7787
  // Load this route on the server if it has a loader
7766
- if (manifest.routes[m.route.id].hasLoader) {
7788
+ if (manifestRoute && manifestRoute.hasLoader) {
7767
7789
  routesParams.add(m.route.id);
7768
7790
  }
7769
7791
 
@@ -8160,20 +8182,18 @@ function RemixRootDefaultHydrateFallback() {
8160
8182
  }));
8161
8183
  }
8162
8184
 
8163
- // NOTE: make sure to change the Route in server-runtime if you change this
8164
-
8165
- // NOTE: make sure to change the EntryRoute in server-runtime if you change this
8166
-
8167
8185
  // Create a map of routes by parentId to use recursively instead of
8168
8186
  // repeatedly filtering the manifest.
8169
8187
  function groupRoutesByParentId$1(manifest) {
8170
8188
  let routes = {};
8171
8189
  Object.values(manifest).forEach(route => {
8172
- let parentId = route.parentId || "";
8173
- if (!routes[parentId]) {
8174
- routes[parentId] = [];
8190
+ if (route) {
8191
+ let parentId = route.parentId || "";
8192
+ if (!routes[parentId]) {
8193
+ routes[parentId] = [];
8194
+ }
8195
+ routes[parentId].push(route);
8175
8196
  }
8176
- routes[parentId].push(route);
8177
8197
  });
8178
8198
  return routes;
8179
8199
  }
@@ -8304,7 +8324,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
8304
8324
  ...dataRoute,
8305
8325
  ...getRouteComponents(route, routeModule, isSpaMode),
8306
8326
  handle: routeModule.handle,
8307
- shouldRevalidate: needsRevalidation ? wrapShouldRevalidateForHdr(route.id, routeModule.shouldRevalidate, needsRevalidation) : routeModule.shouldRevalidate
8327
+ shouldRevalidate: getShouldRevalidateFunction(routeModule, route.id, needsRevalidation)
8308
8328
  });
8309
8329
  let hasInitialData = initialState && initialState.loaderData && route.id in initialState.loaderData;
8310
8330
  let initialData = hasInitialData ? initialState?.loaderData?.[route.id] : undefined;
@@ -8425,9 +8445,6 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
8425
8445
  }
8426
8446
  });
8427
8447
  }
8428
- if (needsRevalidation) {
8429
- lazyRoute.shouldRevalidate = wrapShouldRevalidateForHdr(route.id, mod.shouldRevalidate, needsRevalidation);
8430
- }
8431
8448
  return {
8432
8449
  ...(lazyRoute.loader ? {
8433
8450
  loader: lazyRoute.loader
@@ -8436,7 +8453,7 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
8436
8453
  action: lazyRoute.action
8437
8454
  } : {}),
8438
8455
  hasErrorBoundary: lazyRoute.hasErrorBoundary,
8439
- shouldRevalidate: lazyRoute.shouldRevalidate,
8456
+ shouldRevalidate: getShouldRevalidateFunction(lazyRoute, route.id, needsRevalidation),
8440
8457
  handle: lazyRoute.handle,
8441
8458
  // No need to wrap these in layout since the root route is never
8442
8459
  // loaded via route.lazy()
@@ -8450,6 +8467,23 @@ function createClientRoutes(manifest, routeModulesCache, initialState, isSpaMode
8450
8467
  return dataRoute;
8451
8468
  });
8452
8469
  }
8470
+ function getShouldRevalidateFunction(route, routeId, needsRevalidation) {
8471
+ // During HDR we force revalidation for updated routes
8472
+ if (needsRevalidation) {
8473
+ return wrapShouldRevalidateForHdr(routeId, route.shouldRevalidate, needsRevalidation);
8474
+ }
8475
+
8476
+ // Single fetch revalidates by default, so override the RR default value which
8477
+ // matches the multi-fetch behavior with `true`
8478
+ if (route.shouldRevalidate) {
8479
+ let fn = route.shouldRevalidate;
8480
+ return opts => fn({
8481
+ ...opts,
8482
+ defaultShouldRevalidate: true
8483
+ });
8484
+ }
8485
+ return route.shouldRevalidate;
8486
+ }
8453
8487
 
8454
8488
  // When an HMR / HDR update happens we opt out of all user-defined
8455
8489
  // revalidation logic and force a revalidation on the first call
@@ -8650,9 +8684,12 @@ async function fetchAndApplyManifestPatches(paths, manifest, routeModules, isSpa
8650
8684
 
8651
8685
  // Patch routes we don't know about yet into the manifest
8652
8686
  let knownRoutes = new Set(Object.keys(manifest.routes));
8653
- let patches = Object.values(serverPatches).reduce((acc, route) => !knownRoutes.has(route.id) ? Object.assign(acc, {
8654
- [route.id]: route
8655
- }) : acc, {});
8687
+ let patches = Object.values(serverPatches).reduce((acc, route) => {
8688
+ if (route && !knownRoutes.has(route.id)) {
8689
+ acc[route.id] = route;
8690
+ }
8691
+ return acc;
8692
+ }, {});
8656
8693
  Object.assign(manifest.routes, patches);
8657
8694
 
8658
8695
  // Track discovered paths so we don't have to fetch them again
@@ -8662,7 +8699,7 @@ async function fetchAndApplyManifestPatches(paths, manifest, routeModules, isSpa
8662
8699
  // in their new children
8663
8700
  let parentIds = new Set();
8664
8701
  Object.values(patches).forEach(patch => {
8665
- if (!patch.parentId || !patches[patch.parentId]) {
8702
+ if (patch && (!patch.parentId || !patches[patch.parentId])) {
8666
8703
  parentIds.add(patch.parentId);
8667
8704
  }
8668
8705
  });
@@ -8686,8 +8723,6 @@ function debounce(callback, wait) {
8686
8723
  };
8687
8724
  }
8688
8725
 
8689
- // TODO: Temporary shim until we figure out the way to handle typings in v7
8690
-
8691
8726
  function useDataRouterContext$1() {
8692
8727
  let context = React.useContext(DataRouterContext);
8693
8728
  !context ? invariant$1(false, "You must render this element inside a <DataRouterContext.Provider> element") : void 0;
@@ -8944,12 +8979,13 @@ function PrefetchPageLinksImpl({
8944
8979
  let routesParams = new Set();
8945
8980
  let foundOptOutRoute = false;
8946
8981
  nextMatches.forEach(m => {
8947
- if (!manifest.routes[m.route.id].hasLoader) {
8982
+ let manifestRoute = manifest.routes[m.route.id];
8983
+ if (!manifestRoute || !manifestRoute.hasLoader) {
8948
8984
  return;
8949
8985
  }
8950
8986
  if (!newMatchesForData.some(m2 => m2.route.id === m.route.id) && m.route.id in loaderData && routeModules[m.route.id]?.shouldRevalidate) {
8951
8987
  foundOptOutRoute = true;
8952
- } else if (manifest.routes[m.route.id].hasClientLoader) {
8988
+ } else if (manifestRoute.hasClientLoader) {
8953
8989
  foundOptOutRoute = true;
8954
8990
  } else {
8955
8991
  routesParams.add(m.route.id);
@@ -9220,7 +9256,7 @@ import(${JSON.stringify(manifest.entry.module)});`;
9220
9256
  }, []);
9221
9257
  let routePreloads = matches.map(match => {
9222
9258
  let route = manifest.routes[match.route.id];
9223
- return (route.imports || []).concat([route.module]);
9259
+ return route ? (route.imports || []).concat([route.module]) : [];
9224
9260
  }).flat(1);
9225
9261
  let preloads = isHydrated ? [] : manifest.entry.imports.concat(routePreloads);
9226
9262
  return isHydrated ? null : /*#__PURE__*/React.createElement(React.Fragment, null, !enableFogOfWar ? /*#__PURE__*/React.createElement("link", {
@@ -10915,7 +10951,7 @@ function ServerRouter({
10915
10951
  // route opted into clientLoader hydration and either:
10916
10952
  // * gave us a HydrateFallback
10917
10953
  // * or doesn't have a server loader and we have no data to render
10918
- if (route && shouldHydrateRouteLoader(manifestRoute, route, context.isSpaMode) && (route.HydrateFallback || !manifestRoute.hasLoader)) {
10954
+ if (route && manifestRoute && shouldHydrateRouteLoader(manifestRoute, route, context.isSpaMode) && (route.HydrateFallback || !manifestRoute.hasLoader)) {
10919
10955
  delete context.staticHandlerContext.loaderData[routeId];
10920
10956
  }
10921
10957
  }
@@ -11128,7 +11164,17 @@ const createCookie = (name, cookieOptions = {}) => {
11128
11164
  ...options,
11129
11165
  ...parseOptions
11130
11166
  });
11131
- return name in cookies ? cookies[name] === "" ? "" : await decodeCookieValue(cookies[name], secrets) : null;
11167
+ if (name in cookies) {
11168
+ let value = cookies[name];
11169
+ if (typeof value === "string" && value !== "") {
11170
+ let decoded = await decodeCookieValue(value, secrets);
11171
+ return decoded;
11172
+ } else {
11173
+ return "";
11174
+ }
11175
+ } else {
11176
+ return null;
11177
+ }
11132
11178
  },
11133
11179
  async serialize(value, serializeOptions) {
11134
11180
  return serialize(name, value === "" ? "" : await encodeCookieValue(value, secrets), {
@@ -11238,7 +11284,10 @@ function warnOnceAboutExpiresCookie(name, expires) {
11238
11284
 
11239
11285
  function createEntryRouteModules(manifest) {
11240
11286
  return Object.keys(manifest).reduce((memo, routeId) => {
11241
- memo[routeId] = manifest[routeId].module;
11287
+ let route = manifest[routeId];
11288
+ if (route) {
11289
+ memo[routeId] = route.module;
11290
+ }
11242
11291
  return memo;
11243
11292
  }, {});
11244
11293
  }
@@ -11367,29 +11416,6 @@ function matchServerRoutes(routes, pathname, basename) {
11367
11416
  }));
11368
11417
  }
11369
11418
 
11370
- // must be a type since this is a subtype of response
11371
- // interfaces must conform to the types they extend
11372
-
11373
- /**
11374
- * This is a shortcut for creating `application/json` responses. Converts `data`
11375
- * to JSON and sets the `Content-Type` header.
11376
- *
11377
- * @see https://remix.run/utils/json
11378
- */
11379
- const json = (data, init = {}) => {
11380
- return json$1(data, init);
11381
- };
11382
- function isResponse(value) {
11383
- return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
11384
- }
11385
- const redirectStatusCodes = new Set([301, 302, 303, 307, 308]);
11386
- function isRedirectStatusCode(statusCode) {
11387
- return redirectStatusCodes.has(statusCode);
11388
- }
11389
- function isRedirectResponse(response) {
11390
- return isRedirectStatusCode(response.status);
11391
- }
11392
-
11393
11419
  /**
11394
11420
  * An object of unknown type for route loaders and actions provided by the
11395
11421
  * server's `getLoadContext()` function. This is defined as an empty interface
@@ -11397,10 +11423,6 @@ function isRedirectResponse(response) {
11397
11423
  * globally: https://www.typescriptlang.org/docs/handbook/declaration-merging.html
11398
11424
  */
11399
11425
 
11400
- /**
11401
- * Data for a route that was returned from a `loader()`.
11402
- */
11403
-
11404
11426
  // Need to use RR's version here to permit the optional context even
11405
11427
  // though we know it'll always be provided in remix
11406
11428
  async function callRouteHandler(handler, args) {
@@ -11463,23 +11485,21 @@ function stripRoutesParam(request) {
11463
11485
 
11464
11486
  function invariant(value, message) {
11465
11487
  if (value === false || value === null || typeof value === "undefined") {
11466
- console.error("The following error is a bug in Remix; please open an issue! https://github.com/remix-run/remix/issues/new");
11488
+ console.error("The following error is a bug in React Router; please open an issue! https://github.com/remix-run/react-router/issues/new/choose");
11467
11489
  throw new Error(message);
11468
11490
  }
11469
11491
  }
11470
11492
 
11471
- // NOTE: make sure to change the Route in remix-react/react-router-dev if you change this
11472
-
11473
- // NOTE: make sure to change the EntryRoute in react-router/react-router-dev if you change this
11474
-
11475
11493
  function groupRoutesByParentId(manifest) {
11476
11494
  let routes = {};
11477
11495
  Object.values(manifest).forEach(route => {
11478
- let parentId = route.parentId || "";
11479
- if (!routes[parentId]) {
11480
- routes[parentId] = [];
11496
+ if (route) {
11497
+ let parentId = route.parentId || "";
11498
+ if (!routes[parentId]) {
11499
+ routes[parentId] = [];
11500
+ }
11501
+ routes[parentId].push(route);
11481
11502
  }
11482
- routes[parentId].push(route);
11483
11503
  });
11484
11504
  return routes;
11485
11505
  }
@@ -11603,13 +11623,15 @@ function getDocumentHeaders(build, context) {
11603
11623
  let {
11604
11624
  id
11605
11625
  } = match.route;
11606
- let routeModule = build.routes[id].module;
11626
+ let route = build.routes[id];
11627
+ !route ? invariant(false, `Route with id "${id}" not found in build`) : void 0;
11628
+ let routeModule = route.module;
11607
11629
  let loaderHeaders = context.loaderHeaders[id] || new Headers();
11608
11630
  let actionHeaders = context.actionHeaders[id] || new Headers();
11609
11631
 
11610
11632
  // Only expose errorHeaders to the leaf headers() function to
11611
11633
  // avoid duplication via parentHeaders
11612
- let includeErrorHeaders = errorHeaders != undefined && idx === matches.length - 1;
11634
+ let includeErrorHeaders = errorHeaders != null && idx === matches.length - 1;
11613
11635
  // Only prepend cookies from errorHeaders at the leaf renderable route
11614
11636
  // when it's not the same as loaderHeaders/actionHeaders to avoid
11615
11637
  // duplicate cookies
@@ -12032,15 +12054,18 @@ async function handleManifestRequest(build, routes, url) {
12032
12054
  if (matches) {
12033
12055
  for (let match of matches) {
12034
12056
  let routeId = match.route.id;
12035
- patches[routeId] = build.assets.routes[routeId];
12057
+ let route = build.assets.routes[routeId];
12058
+ if (route) {
12059
+ patches[routeId] = route;
12060
+ }
12036
12061
  }
12037
12062
  }
12038
12063
  }
12039
- return json(patches, {
12064
+ return Response.json(patches, {
12040
12065
  headers: {
12041
12066
  "Cache-Control": "public, max-age=31536000, immutable"
12042
12067
  }
12043
- }); // Override the TypedResponse stuff from json()
12068
+ });
12044
12069
  }
12045
12070
  return new Response("Invalid Request", {
12046
12071
  status: 400
@@ -12220,7 +12245,7 @@ async function handleResourceRequest(serverMode, build, staticHandler, routeId,
12220
12245
  }
12221
12246
  }
12222
12247
  function errorResponseToJson(errorResponse, serverMode) {
12223
- return json$1(serializeError(
12248
+ return Response.json(serializeError(
12224
12249
  // @ts-expect-error This is "private" from users but intended for internal use
12225
12250
  errorResponse.error || new Error("Unexpected Server Error"), serverMode), {
12226
12251
  status: errorResponse.status,
@@ -12499,5 +12524,5 @@ function deserializeErrors(errors) {
12499
12524
  return serialized;
12500
12525
  }
12501
12526
 
12502
- export { Await, BrowserRouter, Form, HashRouter, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, Link, Links, MemoryRouter, Meta, NavLink, Navigate, Action as NavigationType, Outlet, PrefetchPageLinks, Route, Router, RouterProvider, Routes, Scripts, ScrollRestoration, ServerRouter, StaticRouter, StaticRouterProvider, DataRouterContext as UNSAFE_DataRouterContext, DataRouterStateContext as UNSAFE_DataRouterStateContext, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, FetchersContext as UNSAFE_FetchersContext, FrameworkContext as UNSAFE_FrameworkContext, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RemixErrorBoundary as UNSAFE_RemixErrorBoundary, RouteContext as UNSAFE_RouteContext, ServerMode as UNSAFE_ServerMode, SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol, ViewTransitionContext as UNSAFE_ViewTransitionContext, createBrowserHistory as UNSAFE_createBrowserHistory, createClientRoutes as UNSAFE_createClientRoutes, createClientRoutesWithHMRRevalidationOptOut as UNSAFE_createClientRoutesWithHMRRevalidationOptOut, createRouter as UNSAFE_createRouter, decodeViaTurboStream as UNSAFE_decodeViaTurboStream, deserializeErrors as UNSAFE_deserializeErrors, getPatchRoutesOnNavigationFunction as UNSAFE_getPatchRoutesOnNavigationFunction, getSingleFetchDataStrategy$1 as UNSAFE_getSingleFetchDataStrategy, invariant$2 as UNSAFE_invariant, mapRouteProperties as UNSAFE_mapRouteProperties, shouldHydrateRouteLoader as UNSAFE_shouldHydrateRouteLoader, useFogOFWarDiscovery as UNSAFE_useFogOFWarDiscovery, useScrollRestoration as UNSAFE_useScrollRestoration, createBrowserRouter, createCookie, createCookieSessionStorage, createHashRouter, createMemoryRouter, createMemorySessionStorage, createPath, createRequestHandler, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, createRoutesStub, createSearchParams, createSession, createSessionStorage, createStaticHandler, createStaticRouter, data, generatePath, isCookie, isRouteErrorResponse, isSession, json$1 as json, matchPath, matchRoutes, parsePath, redirect, redirectDocument, renderMatches, replace, resolvePath, HistoryRouter as unstable_HistoryRouter, setDevServerHooks as unstable_setDevServerHooks, usePrompt as unstable_usePrompt, useActionData, useAsyncError, useAsyncValue, useBeforeUnload, useBlocker, useFetcher, useFetchers, useFormAction, useHref, useInRouterContext, useLinkClickHandler, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes, useSearchParams, useSubmit, useViewTransitionState };
12527
+ export { Await, BrowserRouter, Form, HashRouter, IDLE_BLOCKER, IDLE_FETCHER, IDLE_NAVIGATION, Link, Links, MemoryRouter, Meta, NavLink, Navigate, Action as NavigationType, Outlet, PrefetchPageLinks, Route, Router, RouterProvider, Routes, Scripts, ScrollRestoration, ServerRouter, StaticRouter, StaticRouterProvider, DataRouterContext as UNSAFE_DataRouterContext, DataRouterStateContext as UNSAFE_DataRouterStateContext, ErrorResponseImpl as UNSAFE_ErrorResponseImpl, FetchersContext as UNSAFE_FetchersContext, FrameworkContext as UNSAFE_FrameworkContext, LocationContext as UNSAFE_LocationContext, NavigationContext as UNSAFE_NavigationContext, RemixErrorBoundary as UNSAFE_RemixErrorBoundary, RouteContext as UNSAFE_RouteContext, ServerMode as UNSAFE_ServerMode, SingleFetchRedirectSymbol as UNSAFE_SingleFetchRedirectSymbol, ViewTransitionContext as UNSAFE_ViewTransitionContext, createBrowserHistory as UNSAFE_createBrowserHistory, createClientRoutes as UNSAFE_createClientRoutes, createClientRoutesWithHMRRevalidationOptOut as UNSAFE_createClientRoutesWithHMRRevalidationOptOut, createRouter as UNSAFE_createRouter, decodeViaTurboStream as UNSAFE_decodeViaTurboStream, deserializeErrors as UNSAFE_deserializeErrors, getPatchRoutesOnNavigationFunction as UNSAFE_getPatchRoutesOnNavigationFunction, getSingleFetchDataStrategy$1 as UNSAFE_getSingleFetchDataStrategy, invariant$2 as UNSAFE_invariant, mapRouteProperties as UNSAFE_mapRouteProperties, shouldHydrateRouteLoader as UNSAFE_shouldHydrateRouteLoader, useFogOFWarDiscovery as UNSAFE_useFogOFWarDiscovery, useScrollRestoration as UNSAFE_useScrollRestoration, createBrowserRouter, createCookie, createCookieSessionStorage, createHashRouter, createMemoryRouter, createMemorySessionStorage, createPath, createRequestHandler, createRoutesFromChildren, createRoutesFromChildren as createRoutesFromElements, createRoutesStub, createSearchParams, createSession, createSessionStorage, createStaticHandler, createStaticRouter, data, generatePath, isCookie, isRouteErrorResponse, isSession, matchPath, matchRoutes, parsePath, redirect, redirectDocument, renderMatches, replace, resolvePath, HistoryRouter as unstable_HistoryRouter, setDevServerHooks as unstable_setDevServerHooks, usePrompt as unstable_usePrompt, useActionData, useAsyncError, useAsyncValue, useBeforeUnload, useBlocker, useFetcher, useFetchers, useFormAction, useHref, useInRouterContext, useLinkClickHandler, useLoaderData, useLocation, useMatch, useMatches, useNavigate, useNavigation, useNavigationType, useOutlet, useOutletContext, useParams, useResolvedPath, useRevalidator, useRouteError, useRouteLoaderData, useRoutes, useSearchParams, useSubmit, useViewTransitionState };
12503
12528
  //# sourceMappingURL=react-router.development.js.map