@react-router/dev 0.0.0-experimental-3fe27584d → 0.0.0-experimental-e067e5e52

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.
package/dist/vite.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v0.0.0-experimental-3fe27584d
2
+ * @react-router/dev v0.0.0-experimental-e067e5e52
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -48,11 +48,10 @@ module.exports = __toCommonJS(vite_exports);
48
48
  // vite/plugin.ts
49
49
  var import_node_crypto = require("crypto");
50
50
  var import_node_fs2 = require("fs");
51
- var import_promises2 = require("fs/promises");
52
- var path6 = __toESM(require("path"));
51
+ var import_promises3 = require("fs/promises");
52
+ var path7 = __toESM(require("path"));
53
53
  var url = __toESM(require("url"));
54
54
  var babel = __toESM(require("@babel/core"));
55
- var import_node_fetch_server2 = require("@remix-run/node-fetch-server");
56
55
  var import_react_router2 = require("react-router");
57
56
  var import_es_module_lexer = require("es-module-lexer");
58
57
  var import_pick3 = __toESM(require("lodash/pick"));
@@ -247,7 +246,7 @@ function validateRouteConfig({
247
246
  `Route config in "${routeConfigFile}" is invalid.`,
248
247
  root ? `${root}` : [],
249
248
  nested ? Object.entries(nested).map(
250
- ([path9, message]) => `Path: routes.${path9}
249
+ ([path10, message]) => `Path: routes.${path10}
251
250
  ${message}`
252
251
  ) : []
253
252
  ].flat().join("\n\n")
@@ -432,7 +431,7 @@ async function resolveConfig({
432
431
  basename: basename3,
433
432
  buildDirectory: userBuildDirectory,
434
433
  buildEnd,
435
- prerender,
434
+ prerender: prerender2,
436
435
  routeDiscovery: userRouteDiscovery,
437
436
  serverBuildFile,
438
437
  serverBundles,
@@ -446,15 +445,15 @@ async function resolveConfig({
446
445
  if (!ssr && serverBundles) {
447
446
  serverBundles = void 0;
448
447
  }
449
- if (prerender) {
448
+ if (prerender2) {
450
449
  let isValidPrerenderPathsConfig = (p) => typeof p === "boolean" || typeof p === "function" || Array.isArray(p);
451
- let isValidPrerenderConfig = isValidPrerenderPathsConfig(prerender) || typeof prerender === "object" && "paths" in prerender && isValidPrerenderPathsConfig(prerender.paths);
450
+ let isValidPrerenderConfig = isValidPrerenderPathsConfig(prerender2) || typeof prerender2 === "object" && "paths" in prerender2 && isValidPrerenderPathsConfig(prerender2.paths);
452
451
  if (!isValidPrerenderConfig) {
453
452
  return err(
454
453
  "The `prerender`/`prerender.paths` config must be a boolean, an array of string paths, or a function returning a boolean or array of string paths."
455
454
  );
456
455
  }
457
- let isValidConcurrencyConfig = typeof prerender != "object" || !("unstable_concurrency" in prerender) || typeof prerender.unstable_concurrency === "number" && Number.isInteger(prerender.unstable_concurrency) && prerender.unstable_concurrency > 0;
456
+ let isValidConcurrencyConfig = typeof prerender2 != "object" || !("unstable_concurrency" in prerender2) || typeof prerender2.unstable_concurrency === "number" && Number.isInteger(prerender2.unstable_concurrency) && prerender2.unstable_concurrency > 0;
458
457
  if (!isValidConcurrencyConfig) {
459
458
  return err(
460
459
  "The `prerender.unstable_concurrency` config must be a positive integer if specified."
@@ -563,23 +562,26 @@ async function resolveConfig({
563
562
  unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
564
563
  unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
565
564
  unstable_trailingSlashAwareDataRequests: userAndPresetConfigs.future?.unstable_trailingSlashAwareDataRequests ?? false,
565
+ unstable_previewServerPrerendering: userAndPresetConfigs.future?.unstable_previewServerPrerendering ?? false,
566
566
  v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
567
567
  v8_splitRouteModules: userAndPresetConfigs.future?.v8_splitRouteModules ?? false,
568
568
  v8_viteEnvironmentApi: userAndPresetConfigs.future?.v8_viteEnvironmentApi ?? false
569
569
  };
570
+ let allowedActionOrigins = userAndPresetConfigs.allowedActionOrigins ?? false;
570
571
  let reactRouterConfig = deepFreeze({
571
572
  appDirectory,
572
573
  basename: basename3,
573
574
  buildDirectory,
574
575
  buildEnd,
575
576
  future,
576
- prerender,
577
+ prerender: prerender2,
577
578
  routes,
578
579
  routeDiscovery,
579
580
  serverBuildFile,
580
581
  serverBundles,
581
582
  serverModuleFormat,
582
583
  ssr,
584
+ allowedActionOrigins,
583
585
  unstable_routeConfig: routeConfig
584
586
  });
585
587
  for (let preset of reactRouterUserConfig.presets ?? []) {
@@ -639,11 +641,11 @@ async function createConfigLoader({
639
641
  if (!fsWatcher) {
640
642
  fsWatcher = import_chokidar.default.watch([root, appDirectory], {
641
643
  ignoreInitial: true,
642
- ignored: (path9) => {
643
- let dirname4 = import_pathe3.default.dirname(path9);
644
+ ignored: (path10) => {
645
+ let dirname4 = import_pathe3.default.dirname(path10);
644
646
  return !dirname4.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
645
647
  // that are at the root level, not nested in subdirectories
646
- path9 !== root && // Watch the root directory itself
648
+ path10 !== root && // Watch the root directory itself
647
649
  dirname4 !== root;
648
650
  }
649
651
  });
@@ -927,7 +929,7 @@ function fullpath(lineage2) {
927
929
  if (lineage2.length === 1 && route?.id === "root") return "/";
928
930
  const isLayout = route && route.index !== true && route.path === void 0;
929
931
  if (isLayout) return void 0;
930
- return "/" + lineage2.map((route2) => route2.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path9) => path9 !== void 0 && path9 !== "").join("/");
932
+ return "/" + lineage2.map((route2) => route2.path?.replace(/^\//, "")?.replace(/\/$/, "")).filter((path10) => path10 !== void 0 && path10 !== "").join("/");
931
933
  }
932
934
 
933
935
  // typegen/generate.ts
@@ -967,6 +969,7 @@ function generateServerBuild(ctx) {
967
969
  export const routeDiscovery: ServerBuild["routeDiscovery"];
968
970
  export const routes: ServerBuild["routes"];
969
971
  export const ssr: ServerBuild["ssr"];
972
+ export const allowedActionOrigins: ServerBuild["allowedActionOrigins"];
970
973
  export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"];
971
974
  }
972
975
  `;
@@ -1106,8 +1109,8 @@ function routeModulesType(ctx) {
1106
1109
  );
1107
1110
  }
1108
1111
  function isInAppDirectory(ctx, routeFile) {
1109
- const path9 = Path3.resolve(ctx.config.appDirectory, routeFile);
1110
- return path9.startsWith(ctx.config.appDirectory);
1112
+ const path10 = Path3.resolve(ctx.config.appDirectory, routeFile);
1113
+ return path10.startsWith(ctx.config.appDirectory);
1111
1114
  }
1112
1115
  function getRouteAnnotations({
1113
1116
  ctx,
@@ -1219,21 +1222,21 @@ function getRouteAnnotations({
1219
1222
  return { filename: filename2, content };
1220
1223
  }
1221
1224
  function relativeImportSource(from, to) {
1222
- let path9 = Path3.relative(Path3.dirname(from), to);
1223
- let extension = Path3.extname(path9);
1224
- path9 = Path3.join(Path3.dirname(path9), Pathe.filename(path9));
1225
- if (!path9.startsWith("../")) path9 = "./" + path9;
1225
+ let path10 = Path3.relative(Path3.dirname(from), to);
1226
+ let extension = Path3.extname(path10);
1227
+ path10 = Path3.join(Path3.dirname(path10), Pathe.filename(path10));
1228
+ if (!path10.startsWith("../")) path10 = "./" + path10;
1226
1229
  if (!extension || /\.(js|ts)x?$/.test(extension)) {
1227
1230
  extension = ".js";
1228
1231
  }
1229
- return path9 + extension;
1232
+ return path10 + extension;
1230
1233
  }
1231
1234
  function rootDirsPath(ctx, typesPath) {
1232
1235
  const rel = Path3.relative(typesDirectory(ctx), typesPath);
1233
1236
  return Path3.join(ctx.rootDirectory, rel);
1234
1237
  }
1235
- function paramsType(path9) {
1236
- const params = parse2(path9);
1238
+ function paramsType(path10) {
1239
+ const params = parse2(path10);
1237
1240
  return t2.tsTypeLiteral(
1238
1241
  Object.entries(params).map(([param, isRequired]) => {
1239
1242
  const property = t2.tsPropertySignature(
@@ -1322,14 +1325,14 @@ async function watch(rootDirectory, { mode, logger, rsc }) {
1322
1325
  }
1323
1326
 
1324
1327
  // vite/node-adapter.ts
1325
- var import_node_fetch_server = require("@remix-run/node-fetch-server");
1326
- function fromNodeRequest(nodeReq, nodeRes) {
1328
+ async function fromNodeRequest(nodeReq, nodeRes) {
1327
1329
  invariant(
1328
1330
  nodeReq.originalUrl,
1329
1331
  "Expected `nodeReq.originalUrl` to be defined"
1330
1332
  );
1331
1333
  nodeReq.url = nodeReq.originalUrl;
1332
- return (0, import_node_fetch_server.createRequest)(nodeReq, nodeRes);
1334
+ const { createRequest } = await import("@remix-run/node-fetch-server");
1335
+ return createRequest(nodeReq, nodeRes);
1333
1336
  }
1334
1337
 
1335
1338
  // vite/styles.ts
@@ -1502,11 +1505,11 @@ var getCssStringFromViteDevModuleCode = (code) => {
1502
1505
  let cssContent = void 0;
1503
1506
  const ast = import_parser.parse(code, { sourceType: "module" });
1504
1507
  traverse(ast, {
1505
- VariableDeclaration(path9) {
1506
- const declaration = path9.node.declarations[0];
1508
+ VariableDeclaration(path10) {
1509
+ const declaration = path10.node.declarations[0];
1507
1510
  if (declaration?.id?.type === "Identifier" && declaration.id.name === "__vite__css" && declaration.init?.type === "StringLiteral") {
1508
1511
  cssContent = declaration.init.value;
1509
- path9.stop();
1512
+ path10.stop();
1510
1513
  }
1511
1514
  }
1512
1515
  });
@@ -1545,10 +1548,10 @@ var removeExports = (ast, exportsToRemove) => {
1545
1548
  let markedForRemoval = /* @__PURE__ */ new Set();
1546
1549
  let removedExportLocalNames = /* @__PURE__ */ new Set();
1547
1550
  traverse(ast, {
1548
- ExportDeclaration(path9) {
1549
- if (path9.node.type === "ExportNamedDeclaration") {
1550
- if (path9.node.specifiers.length) {
1551
- path9.node.specifiers = path9.node.specifiers.filter((specifier) => {
1551
+ ExportDeclaration(path10) {
1552
+ if (path10.node.type === "ExportNamedDeclaration") {
1553
+ if (path10.node.specifiers.length) {
1554
+ path10.node.specifiers = path10.node.specifiers.filter((specifier) => {
1552
1555
  if (specifier.type === "ExportSpecifier" && specifier.exported.type === "Identifier") {
1553
1556
  if (exportsToRemove.includes(specifier.exported.name)) {
1554
1557
  exportsFiltered = true;
@@ -1560,12 +1563,12 @@ var removeExports = (ast, exportsToRemove) => {
1560
1563
  }
1561
1564
  return true;
1562
1565
  });
1563
- if (path9.node.specifiers.length === 0) {
1564
- markedForRemoval.add(path9);
1566
+ if (path10.node.specifiers.length === 0) {
1567
+ markedForRemoval.add(path10);
1565
1568
  }
1566
1569
  }
1567
- if (path9.node.declaration?.type === "VariableDeclaration") {
1568
- let declaration = path9.node.declaration;
1570
+ if (path10.node.declaration?.type === "VariableDeclaration") {
1571
+ let declaration = path10.node.declaration;
1569
1572
  declaration.declarations = declaration.declarations.filter(
1570
1573
  (declaration2) => {
1571
1574
  if (declaration2.id.type === "Identifier" && exportsToRemove.includes(declaration2.id.name)) {
@@ -1579,30 +1582,30 @@ var removeExports = (ast, exportsToRemove) => {
1579
1582
  }
1580
1583
  );
1581
1584
  if (declaration.declarations.length === 0) {
1582
- markedForRemoval.add(path9);
1585
+ markedForRemoval.add(path10);
1583
1586
  }
1584
1587
  }
1585
- if (path9.node.declaration?.type === "FunctionDeclaration") {
1586
- let id = path9.node.declaration.id;
1588
+ if (path10.node.declaration?.type === "FunctionDeclaration") {
1589
+ let id = path10.node.declaration.id;
1587
1590
  if (id && exportsToRemove.includes(id.name)) {
1588
- markedForRemoval.add(path9);
1591
+ markedForRemoval.add(path10);
1589
1592
  }
1590
1593
  }
1591
- if (path9.node.declaration?.type === "ClassDeclaration") {
1592
- let id = path9.node.declaration.id;
1594
+ if (path10.node.declaration?.type === "ClassDeclaration") {
1595
+ let id = path10.node.declaration.id;
1593
1596
  if (id && exportsToRemove.includes(id.name)) {
1594
- markedForRemoval.add(path9);
1597
+ markedForRemoval.add(path10);
1595
1598
  }
1596
1599
  }
1597
1600
  }
1598
- if (path9.node.type === "ExportDefaultDeclaration") {
1601
+ if (path10.node.type === "ExportDefaultDeclaration") {
1599
1602
  if (exportsToRemove.includes("default")) {
1600
- markedForRemoval.add(path9);
1601
- if (path9.node.declaration) {
1602
- if (path9.node.declaration.type === "Identifier") {
1603
- removedExportLocalNames.add(path9.node.declaration.name);
1604
- } else if ((path9.node.declaration.type === "FunctionDeclaration" || path9.node.declaration.type === "ClassDeclaration") && path9.node.declaration.id) {
1605
- removedExportLocalNames.add(path9.node.declaration.id.name);
1603
+ markedForRemoval.add(path10);
1604
+ if (path10.node.declaration) {
1605
+ if (path10.node.declaration.type === "Identifier") {
1606
+ removedExportLocalNames.add(path10.node.declaration.name);
1607
+ } else if ((path10.node.declaration.type === "FunctionDeclaration" || path10.node.declaration.type === "ClassDeclaration") && path10.node.declaration.id) {
1608
+ removedExportLocalNames.add(path10.node.declaration.id.name);
1606
1609
  }
1607
1610
  }
1608
1611
  }
@@ -1610,21 +1613,21 @@ var removeExports = (ast, exportsToRemove) => {
1610
1613
  }
1611
1614
  });
1612
1615
  traverse(ast, {
1613
- ExpressionStatement(path9) {
1614
- if (!path9.parentPath.isProgram()) {
1616
+ ExpressionStatement(path10) {
1617
+ if (!path10.parentPath.isProgram()) {
1615
1618
  return;
1616
1619
  }
1617
- if (path9.node.expression.type === "AssignmentExpression") {
1618
- const left = path9.node.expression.left;
1620
+ if (path10.node.expression.type === "AssignmentExpression") {
1621
+ const left = path10.node.expression.left;
1619
1622
  if (left.type === "MemberExpression" && left.object.type === "Identifier" && (exportsToRemove.includes(left.object.name) || removedExportLocalNames.has(left.object.name))) {
1620
- markedForRemoval.add(path9);
1623
+ markedForRemoval.add(path10);
1621
1624
  }
1622
1625
  }
1623
1626
  }
1624
1627
  });
1625
1628
  if (markedForRemoval.size > 0 || exportsFiltered) {
1626
- for (let path9 of markedForRemoval) {
1627
- path9.remove();
1629
+ for (let path10 of markedForRemoval) {
1630
+ path10.remove();
1628
1631
  }
1629
1632
  (0, import_babel_dead_code_elimination.deadCodeElimination)(ast, previouslyReferencedIdentifiers);
1630
1633
  }
@@ -1707,28 +1710,28 @@ function codeToAst(code, cache, cacheKey) {
1707
1710
  )
1708
1711
  );
1709
1712
  }
1710
- function assertNodePath(path9) {
1713
+ function assertNodePath(path10) {
1711
1714
  invariant(
1712
- path9 && !Array.isArray(path9),
1713
- `Expected a Path, but got ${Array.isArray(path9) ? "an array" : path9}`
1715
+ path10 && !Array.isArray(path10),
1716
+ `Expected a Path, but got ${Array.isArray(path10) ? "an array" : path10}`
1714
1717
  );
1715
1718
  }
1716
- function assertNodePathIsStatement(path9) {
1719
+ function assertNodePathIsStatement(path10) {
1717
1720
  invariant(
1718
- path9 && !Array.isArray(path9) && t.isStatement(path9.node),
1719
- `Expected a Statement path, but got ${Array.isArray(path9) ? "an array" : path9?.node?.type}`
1721
+ path10 && !Array.isArray(path10) && t.isStatement(path10.node),
1722
+ `Expected a Statement path, but got ${Array.isArray(path10) ? "an array" : path10?.node?.type}`
1720
1723
  );
1721
1724
  }
1722
- function assertNodePathIsVariableDeclarator(path9) {
1725
+ function assertNodePathIsVariableDeclarator(path10) {
1723
1726
  invariant(
1724
- path9 && !Array.isArray(path9) && t.isVariableDeclarator(path9.node),
1725
- `Expected an Identifier path, but got ${Array.isArray(path9) ? "an array" : path9?.node?.type}`
1727
+ path10 && !Array.isArray(path10) && t.isVariableDeclarator(path10.node),
1728
+ `Expected an Identifier path, but got ${Array.isArray(path10) ? "an array" : path10?.node?.type}`
1726
1729
  );
1727
1730
  }
1728
- function assertNodePathIsPattern(path9) {
1731
+ function assertNodePathIsPattern(path10) {
1729
1732
  invariant(
1730
- path9 && !Array.isArray(path9) && t.isPattern(path9.node),
1731
- `Expected a Pattern path, but got ${Array.isArray(path9) ? "an array" : path9?.node?.type}`
1733
+ path10 && !Array.isArray(path10) && t.isPattern(path10.node),
1734
+ `Expected a Pattern path, but got ${Array.isArray(path10) ? "an array" : path10?.node?.type}`
1732
1735
  );
1733
1736
  }
1734
1737
  function getExportDependencies(code, cache, cacheKey) {
@@ -1764,8 +1767,8 @@ function getExportDependencies(code, cache, cacheKey) {
1764
1767
  }
1765
1768
  let isWithinExportDestructuring = Boolean(
1766
1769
  identifier.findParent(
1767
- (path9) => Boolean(
1768
- path9.isPattern() && path9.parentPath?.isVariableDeclarator() && path9.parentPath.parentPath?.parentPath?.isExportNamedDeclaration()
1770
+ (path10) => Boolean(
1771
+ path10.isPattern() && path10.parentPath?.isVariableDeclarator() && path10.parentPath.parentPath?.parentPath?.isExportNamedDeclaration()
1769
1772
  )
1770
1773
  )
1771
1774
  );
@@ -1843,7 +1846,7 @@ function getExportDependencies(code, cache, cacheKey) {
1843
1846
  for (let specifier of node.specifiers) {
1844
1847
  if (t.isIdentifier(specifier.exported)) {
1845
1848
  let name = specifier.exported.name;
1846
- let specifierPath = exportPath.get("specifiers").find((path9) => path9.node === specifier);
1849
+ let specifierPath = exportPath.get("specifiers").find((path10) => path10.node === specifier);
1847
1850
  invariant(
1848
1851
  specifierPath,
1849
1852
  `Expected to find specifier path for ${name}`
@@ -1860,22 +1863,22 @@ function getExportDependencies(code, cache, cacheKey) {
1860
1863
  }
1861
1864
  );
1862
1865
  }
1863
- function getDependentIdentifiersForPath(path9, state) {
1866
+ function getDependentIdentifiersForPath(path10, state) {
1864
1867
  let { visited, identifiers } = state ?? {
1865
1868
  visited: /* @__PURE__ */ new Set(),
1866
1869
  identifiers: /* @__PURE__ */ new Set()
1867
1870
  };
1868
- if (visited.has(path9)) {
1871
+ if (visited.has(path10)) {
1869
1872
  return identifiers;
1870
1873
  }
1871
- visited.add(path9);
1872
- path9.traverse({
1873
- Identifier(path10) {
1874
- if (identifiers.has(path10)) {
1874
+ visited.add(path10);
1875
+ path10.traverse({
1876
+ Identifier(path11) {
1877
+ if (identifiers.has(path11)) {
1875
1878
  return;
1876
1879
  }
1877
- identifiers.add(path10);
1878
- let binding = path10.scope.getBinding(path10.node.name);
1880
+ identifiers.add(path11);
1881
+ let binding = path11.scope.getBinding(path11.node.name);
1879
1882
  if (!binding) {
1880
1883
  return;
1881
1884
  }
@@ -1897,7 +1900,7 @@ function getDependentIdentifiersForPath(path9, state) {
1897
1900
  }
1898
1901
  }
1899
1902
  });
1900
- let topLevelStatement = getTopLevelStatementPathForPath(path9);
1903
+ let topLevelStatement = getTopLevelStatementPathForPath(path10);
1901
1904
  let withinImportStatement = topLevelStatement.isImportDeclaration();
1902
1905
  let withinExportStatement = topLevelStatement.isExportDeclaration();
1903
1906
  if (!withinImportStatement && !withinExportStatement) {
@@ -1906,9 +1909,9 @@ function getDependentIdentifiersForPath(path9, state) {
1906
1909
  identifiers
1907
1910
  });
1908
1911
  }
1909
- if (withinExportStatement && path9.isIdentifier() && (t.isPattern(path9.parentPath.node) || // [foo]
1910
- t.isPattern(path9.parentPath.parentPath?.node))) {
1911
- let variableDeclarator = path9.findParent((p) => p.isVariableDeclarator());
1912
+ if (withinExportStatement && path10.isIdentifier() && (t.isPattern(path10.parentPath.node) || // [foo]
1913
+ t.isPattern(path10.parentPath.parentPath?.node))) {
1914
+ let variableDeclarator = path10.findParent((p) => p.isVariableDeclarator());
1912
1915
  assertNodePath(variableDeclarator);
1913
1916
  getDependentIdentifiersForPath(variableDeclarator, {
1914
1917
  visited,
@@ -1917,16 +1920,16 @@ function getDependentIdentifiersForPath(path9, state) {
1917
1920
  }
1918
1921
  return identifiers;
1919
1922
  }
1920
- function getTopLevelStatementPathForPath(path9) {
1921
- let ancestry = path9.getAncestry();
1923
+ function getTopLevelStatementPathForPath(path10) {
1924
+ let ancestry = path10.getAncestry();
1922
1925
  let topLevelStatement = ancestry[ancestry.length - 2];
1923
1926
  assertNodePathIsStatement(topLevelStatement);
1924
1927
  return topLevelStatement;
1925
1928
  }
1926
1929
  function getTopLevelStatementsForPaths(paths) {
1927
1930
  let topLevelStatements = /* @__PURE__ */ new Set();
1928
- for (let path9 of paths) {
1929
- let topLevelStatement = getTopLevelStatementPathForPath(path9);
1931
+ for (let path10 of paths) {
1932
+ let topLevelStatement = getTopLevelStatementPathForPath(path10);
1930
1933
  topLevelStatements.add(topLevelStatement.node);
1931
1934
  }
1932
1935
  return topLevelStatements;
@@ -2320,24 +2323,24 @@ function isNamedComponentExport(name) {
2320
2323
  }
2321
2324
  var decorateComponentExportsWithProps = (ast) => {
2322
2325
  const hocs = [];
2323
- function getHocUid(path9, hocName) {
2324
- const uid = path9.scope.generateUidIdentifier(hocName);
2326
+ function getHocUid(path10, hocName) {
2327
+ const uid = path10.scope.generateUidIdentifier(hocName);
2325
2328
  hocs.push([hocName, uid]);
2326
2329
  return uid;
2327
2330
  }
2328
2331
  traverse(ast, {
2329
- ExportDeclaration(path9) {
2330
- if (path9.isExportDefaultDeclaration()) {
2331
- const declaration = path9.get("declaration");
2332
+ ExportDeclaration(path10) {
2333
+ if (path10.isExportDefaultDeclaration()) {
2334
+ const declaration = path10.get("declaration");
2332
2335
  const expr = declaration.isExpression() ? declaration.node : declaration.isFunctionDeclaration() ? toFunctionExpression(declaration.node) : void 0;
2333
2336
  if (expr) {
2334
- const uid = getHocUid(path9, "UNSAFE_withComponentProps");
2337
+ const uid = getHocUid(path10, "UNSAFE_withComponentProps");
2335
2338
  declaration.replaceWith(t.callExpression(uid, [expr]));
2336
2339
  }
2337
2340
  return;
2338
2341
  }
2339
- if (path9.isExportNamedDeclaration()) {
2340
- const decl = path9.get("declaration");
2342
+ if (path10.isExportNamedDeclaration()) {
2343
+ const decl = path10.get("declaration");
2341
2344
  if (decl.isVariableDeclaration()) {
2342
2345
  decl.get("declarations").forEach((varDeclarator) => {
2343
2346
  const id = varDeclarator.get("id");
@@ -2347,7 +2350,7 @@ var decorateComponentExportsWithProps = (ast) => {
2347
2350
  if (!id.isIdentifier()) return;
2348
2351
  const { name } = id.node;
2349
2352
  if (!isNamedComponentExport(name)) return;
2350
- const uid = getHocUid(path9, `UNSAFE_with${name}Props`);
2353
+ const uid = getHocUid(path10, `UNSAFE_with${name}Props`);
2351
2354
  init.replaceWith(t.callExpression(uid, [expr]));
2352
2355
  });
2353
2356
  return;
@@ -2357,7 +2360,7 @@ var decorateComponentExportsWithProps = (ast) => {
2357
2360
  if (!id) return;
2358
2361
  const { name } = id;
2359
2362
  if (!isNamedComponentExport(name)) return;
2360
- const uid = getHocUid(path9, `UNSAFE_with${name}Props`);
2363
+ const uid = getHocUid(path10, `UNSAFE_with${name}Props`);
2361
2364
  decl.replaceWith(
2362
2365
  t.variableDeclaration("const", [
2363
2366
  t.variableDeclarator(
@@ -2478,6 +2481,222 @@ function warnOnClientSourceMaps() {
2478
2481
  };
2479
2482
  }
2480
2483
 
2484
+ // vite/plugins/prerender.ts
2485
+ var import_promises2 = require("fs/promises");
2486
+ var import_node_path = __toESM(require("path"));
2487
+ function normalizePrerenderRequest(input) {
2488
+ if (typeof input === "string" || input instanceof Request) {
2489
+ return { request: input, metadata: void 0 };
2490
+ }
2491
+ return { request: input.request, metadata: input.metadata };
2492
+ }
2493
+ function normalizePostProcessResult(result) {
2494
+ if (Array.isArray(result)) {
2495
+ return { files: result, requests: [] };
2496
+ }
2497
+ return { files: result.files, requests: result.requests ?? [] };
2498
+ }
2499
+ function prerender(options) {
2500
+ const {
2501
+ config,
2502
+ requests,
2503
+ postProcess = defaultPostProcess,
2504
+ handleError = defaultHandleError,
2505
+ logFile,
2506
+ finalize
2507
+ } = options;
2508
+ let viteConfig;
2509
+ return {
2510
+ name: "prerender",
2511
+ configResolved(resolvedConfig) {
2512
+ viteConfig = resolvedConfig;
2513
+ },
2514
+ writeBundle: {
2515
+ async handler() {
2516
+ const pluginContext = this;
2517
+ const rawRequests = typeof requests === "function" ? await requests.call(pluginContext) : requests;
2518
+ const prerenderRequests = rawRequests.map(normalizePrerenderRequest);
2519
+ if (prerenderRequests.length === 0) {
2520
+ return;
2521
+ }
2522
+ const prerenderConfig = typeof config === "function" ? await config.call(pluginContext) : config;
2523
+ const {
2524
+ buildDirectory = viteConfig.environments.client.build.outDir,
2525
+ concurrency = 1,
2526
+ retryCount = 0,
2527
+ retryDelay = 500,
2528
+ maxRedirects = 0,
2529
+ timeout = 1e4
2530
+ } = prerenderConfig ?? {};
2531
+ const previewServer = await startPreviewServer(viteConfig);
2532
+ try {
2533
+ const baseUrl = getResolvedUrl(previewServer);
2534
+ async function prerenderRequest(input, metadata) {
2535
+ let attemptCount = 0;
2536
+ let redirectCount = 0;
2537
+ const request = new Request(input);
2538
+ const url2 = new URL(request.url);
2539
+ if (url2.origin !== baseUrl.origin) {
2540
+ url2.hostname = baseUrl.hostname;
2541
+ url2.protocol = baseUrl.protocol;
2542
+ url2.port = baseUrl.port;
2543
+ }
2544
+ async function attempt(url3) {
2545
+ try {
2546
+ const signal = AbortSignal.timeout(timeout);
2547
+ const prerenderReq = new Request(url3, request);
2548
+ const response = await fetch(prerenderReq, {
2549
+ redirect: "manual",
2550
+ signal
2551
+ });
2552
+ if (response.status >= 300 && response.status < 400 && response.headers.has("location") && ++redirectCount <= maxRedirects) {
2553
+ const location = response.headers.get("location");
2554
+ const responseURL = new URL(response.url);
2555
+ const locationUrl = new URL(location, response.url);
2556
+ if (responseURL.origin !== locationUrl.origin) {
2557
+ return await postProcess.call(
2558
+ pluginContext,
2559
+ request,
2560
+ response,
2561
+ metadata
2562
+ );
2563
+ }
2564
+ const redirectUrl = new URL(location, url3);
2565
+ return await attempt(redirectUrl);
2566
+ }
2567
+ if (response.status >= 500 && ++attemptCount <= retryCount) {
2568
+ await new Promise(
2569
+ (resolve6) => setTimeout(resolve6, retryDelay)
2570
+ );
2571
+ return attempt(url3);
2572
+ }
2573
+ return await postProcess.call(
2574
+ pluginContext,
2575
+ request,
2576
+ response,
2577
+ metadata
2578
+ );
2579
+ } catch (error) {
2580
+ if (++attemptCount <= retryCount) {
2581
+ await new Promise(
2582
+ (resolve6) => setTimeout(resolve6, retryDelay)
2583
+ );
2584
+ return attempt(url3);
2585
+ }
2586
+ handleError.call(
2587
+ pluginContext,
2588
+ request,
2589
+ error instanceof Error ? error : new Error(error?.toString() ?? "Unknown error"),
2590
+ metadata
2591
+ );
2592
+ return [];
2593
+ }
2594
+ }
2595
+ return attempt(url2);
2596
+ }
2597
+ async function prerender2(input, metadata) {
2598
+ const result = await prerenderRequest(input, metadata);
2599
+ const { files, requests: requests2 } = normalizePostProcessResult(result);
2600
+ for (const file of files) {
2601
+ await writePrerenderFile(file, metadata);
2602
+ }
2603
+ for (const followUp of requests2) {
2604
+ const normalized = normalizePrerenderRequest(followUp);
2605
+ await prerender2(normalized.request, normalized.metadata);
2606
+ }
2607
+ }
2608
+ async function writePrerenderFile(file, metadata) {
2609
+ const normalizedPath = file.path.startsWith("/") ? file.path.slice(1) : file.path;
2610
+ const outputPath = import_node_path.default.join(
2611
+ buildDirectory,
2612
+ ...normalizedPath.split("/")
2613
+ );
2614
+ await (0, import_promises2.mkdir)(import_node_path.default.dirname(outputPath), { recursive: true });
2615
+ await (0, import_promises2.writeFile)(outputPath, file.contents);
2616
+ const relativePath = import_node_path.default.relative(viteConfig.root, outputPath);
2617
+ if (logFile) {
2618
+ logFile.call(pluginContext, relativePath, metadata);
2619
+ }
2620
+ return relativePath;
2621
+ }
2622
+ const pMap = await import("p-map");
2623
+ await pMap.default(
2624
+ prerenderRequests,
2625
+ async ({ request, metadata }) => {
2626
+ await prerender2(request, metadata);
2627
+ },
2628
+ { concurrency }
2629
+ );
2630
+ if (finalize) {
2631
+ await finalize.call(pluginContext, buildDirectory);
2632
+ }
2633
+ } finally {
2634
+ await new Promise((resolve6, reject) => {
2635
+ previewServer.httpServer.close((err2) => {
2636
+ if (err2) {
2637
+ reject(err2);
2638
+ } else {
2639
+ resolve6();
2640
+ }
2641
+ });
2642
+ });
2643
+ }
2644
+ }
2645
+ }
2646
+ };
2647
+ }
2648
+ async function defaultPostProcess(request, response) {
2649
+ const prerenderPath = new URL(request.url).pathname;
2650
+ if (!response.ok) {
2651
+ throw new Error(
2652
+ `Prerender: Request failed for ${prerenderPath}: ${response.status} ${response.statusText}`
2653
+ );
2654
+ }
2655
+ return [
2656
+ {
2657
+ path: `${prerenderPath}/index.html`,
2658
+ contents: await response.text()
2659
+ }
2660
+ ];
2661
+ }
2662
+ function defaultHandleError(request, error) {
2663
+ const prerenderPath = new URL(request.url).pathname;
2664
+ if (request.signal?.aborted) {
2665
+ throw new Error(
2666
+ `Prerender: Request timed out for ${prerenderPath}: ${error.message}`
2667
+ );
2668
+ }
2669
+ throw new Error(
2670
+ `Prerender: Request failed for ${prerenderPath}: ${error.message}`
2671
+ );
2672
+ }
2673
+ async function startPreviewServer(viteConfig) {
2674
+ const vite2 = await import("vite");
2675
+ try {
2676
+ return await vite2.preview({
2677
+ configFile: viteConfig.configFile,
2678
+ logLevel: "silent",
2679
+ preview: {
2680
+ port: 0,
2681
+ open: false
2682
+ }
2683
+ });
2684
+ } catch (error) {
2685
+ throw new Error("Prerender: Failed to start Vite preview server", {
2686
+ cause: error
2687
+ });
2688
+ }
2689
+ }
2690
+ function getResolvedUrl(previewServer) {
2691
+ const baseUrl = previewServer.resolvedUrls?.local[0];
2692
+ if (!baseUrl) {
2693
+ throw new Error(
2694
+ "Prerender: No resolved URL is available from the Vite preview server"
2695
+ );
2696
+ }
2697
+ return new URL(baseUrl);
2698
+ }
2699
+
2481
2700
  // vite/plugin.ts
2482
2701
  function extractPluginContext(viteConfig) {
2483
2702
  return viteConfig["__reactRouterPluginContext"];
@@ -2539,8 +2758,8 @@ var virtualHmrRuntime = create("hmr-runtime");
2539
2758
  var virtualInjectHmrRuntime = create("inject-hmr-runtime");
2540
2759
  var normalizeRelativeFilePath = (file, reactRouterConfig) => {
2541
2760
  let vite2 = getVite();
2542
- let fullPath = path6.resolve(reactRouterConfig.appDirectory, file);
2543
- let relativePath = path6.relative(reactRouterConfig.appDirectory, fullPath);
2761
+ let fullPath = path7.resolve(reactRouterConfig.appDirectory, file);
2762
+ let relativePath = path7.relative(reactRouterConfig.appDirectory, fullPath);
2544
2763
  return vite2.normalizePath(relativePath).split("?")[0];
2545
2764
  };
2546
2765
  var virtual = {
@@ -2563,7 +2782,7 @@ var getHash = (source, maxLength) => {
2563
2782
  var resolveChunk = (ctx, viteManifest, absoluteFilePath) => {
2564
2783
  let vite2 = getVite();
2565
2784
  let rootRelativeFilePath = vite2.normalizePath(
2566
- path6.relative(ctx.rootDirectory, absoluteFilePath)
2785
+ path7.relative(ctx.rootDirectory, absoluteFilePath)
2567
2786
  );
2568
2787
  let entryChunk = viteManifest[rootRelativeFilePath];
2569
2788
  if (!entryChunk) {
@@ -2654,7 +2873,7 @@ function resolveDependantChunks(viteManifest, entryChunks) {
2654
2873
  function getAllDynamicCssFiles(ctx, viteManifest) {
2655
2874
  let allDynamicCssFiles = /* @__PURE__ */ new Set();
2656
2875
  for (let route of Object.values(ctx.reactRouterConfig.routes)) {
2657
- let routeFile = path6.join(ctx.reactRouterConfig.appDirectory, route.file);
2876
+ let routeFile = path7.join(ctx.reactRouterConfig.appDirectory, route.file);
2658
2877
  let entryChunk = resolveChunk(
2659
2878
  ctx,
2660
2879
  viteManifest,
@@ -2693,8 +2912,8 @@ function dedupe(array2) {
2693
2912
  return [...new Set(array2)];
2694
2913
  }
2695
2914
  var writeFileSafe = async (file, contents) => {
2696
- await (0, import_promises2.mkdir)(path6.dirname(file), { recursive: true });
2697
- await (0, import_promises2.writeFile)(file, contents);
2915
+ await (0, import_promises3.mkdir)(path7.dirname(file), { recursive: true });
2916
+ await (0, import_promises3.writeFile)(file, contents);
2698
2917
  };
2699
2918
  var getExportNames = (code) => {
2700
2919
  let [, exportSpecifiers] = (0, import_es_module_lexer.parse)(code);
@@ -2719,7 +2938,7 @@ var compileRouteFile = async (viteChildCompiler, ctx, routeFile, readRouteFile)
2719
2938
  }
2720
2939
  let ssr = true;
2721
2940
  let { pluginContainer, moduleGraph } = viteChildCompiler;
2722
- let routePath = path6.resolve(ctx.reactRouterConfig.appDirectory, routeFile);
2941
+ let routePath = path7.resolve(ctx.reactRouterConfig.appDirectory, routeFile);
2723
2942
  let url2 = resolveFileUrl(ctx, routePath);
2724
2943
  let resolveId = async () => {
2725
2944
  let result = await pluginContainer.resolveId(url2, void 0, { ssr });
@@ -2728,7 +2947,7 @@ var compileRouteFile = async (viteChildCompiler, ctx, routeFile, readRouteFile)
2728
2947
  };
2729
2948
  let [id, code] = await Promise.all([
2730
2949
  resolveId(),
2731
- readRouteFile?.() ?? (0, import_promises2.readFile)(routePath, "utf-8"),
2950
+ readRouteFile?.() ?? (0, import_promises3.readFile)(routePath, "utf-8"),
2732
2951
  // pluginContainer.transform(...) fails if we don't do this first:
2733
2952
  moduleGraph.ensureEntryFromUrl(url2, ssr)
2734
2953
  ]);
@@ -2761,12 +2980,12 @@ var resolveEnvironmentBuildContext = ({
2761
2980
  };
2762
2981
  return resolvedBuildContext;
2763
2982
  };
2764
- var getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path6.join(
2983
+ var getServerBuildDirectory = (reactRouterConfig, { serverBundleId } = {}) => path7.join(
2765
2984
  reactRouterConfig.buildDirectory,
2766
2985
  "server",
2767
2986
  ...serverBundleId ? [serverBundleId] : []
2768
2987
  );
2769
- var getClientBuildDirectory = (reactRouterConfig) => path6.join(reactRouterConfig.buildDirectory, "client");
2988
+ var getClientBuildDirectory = (reactRouterConfig) => path7.join(reactRouterConfig.buildDirectory, "client");
2770
2989
  var getServerBundleRouteIds = (vitePluginContext, ctx) => {
2771
2990
  if (!ctx.buildManifest) {
2772
2991
  return void 0;
@@ -2784,14 +3003,14 @@ var getServerBundleRouteIds = (vitePluginContext, ctx) => {
2784
3003
  );
2785
3004
  return Object.keys(serverBundleRoutes);
2786
3005
  };
2787
- var defaultEntriesDir = path6.resolve(
2788
- path6.dirname(require.resolve("@react-router/dev/package.json")),
3006
+ var defaultEntriesDir = path7.resolve(
3007
+ path7.dirname(require.resolve("@react-router/dev/package.json")),
2789
3008
  "dist",
2790
3009
  "config",
2791
3010
  "defaults"
2792
3011
  );
2793
3012
  var defaultEntries = (0, import_node_fs2.readdirSync)(defaultEntriesDir).map(
2794
- (filename2) => path6.join(defaultEntriesDir, filename2)
3013
+ (filename2) => path7.join(defaultEntriesDir, filename2)
2795
3014
  );
2796
3015
  invariant(defaultEntries.length > 0, "No default entries found");
2797
3016
  var reactRouterDevLoadContext = () => void 0;
@@ -2841,6 +3060,8 @@ var reactRouterVitePlugin = () => {
2841
3060
  firstLoad = false;
2842
3061
  ctx = {
2843
3062
  environmentBuildContext,
3063
+ reactRouterManifest: null,
3064
+ prerenderPaths: null,
2844
3065
  reactRouterConfig,
2845
3066
  rootDirectory,
2846
3067
  entryClientFilePath,
@@ -2865,6 +3086,12 @@ var reactRouterVitePlugin = () => {
2865
3086
  ctx.reactRouterConfig.ssr,
2866
3087
  routes
2867
3088
  );
3089
+ if (!ctx.prerenderPaths) {
3090
+ ctx.prerenderPaths = /* @__PURE__ */ new Set();
3091
+ }
3092
+ for (let path10 of prerenderPaths) {
3093
+ ctx.prerenderPaths.add(path10);
3094
+ }
2868
3095
  let isSpaMode = isSpaModeEnabled(ctx.reactRouterConfig);
2869
3096
  return `
2870
3097
  import * as entryServer from ${JSON.stringify(
@@ -2887,7 +3114,7 @@ var reactRouterVitePlugin = () => {
2887
3114
  virtual.serverManifest.id
2888
3115
  )};
2889
3116
  export const assetsBuildDirectory = ${JSON.stringify(
2890
- path6.relative(
3117
+ path7.relative(
2891
3118
  ctx.rootDirectory,
2892
3119
  getClientBuildDirectory(ctx.reactRouterConfig)
2893
3120
  )
@@ -2922,11 +3149,13 @@ var reactRouterVitePlugin = () => {
2922
3149
  href: "${ctx.publicPath}@react-router/critical.css?pathname=" + pathname,
2923
3150
  };
2924
3151
  }
2925
- ` : ""}`;
3152
+ ` : ""}
3153
+ export const allowedActionOrigins = ${JSON.stringify(ctx.reactRouterConfig.allowedActionOrigins)};
3154
+ `;
2926
3155
  };
2927
3156
  let loadViteManifest = async (directory) => {
2928
- let manifestContents = await (0, import_promises2.readFile)(
2929
- path6.resolve(directory, ".vite", "manifest.json"),
3157
+ let manifestContents = await (0, import_promises3.readFile)(
3158
+ path7.resolve(directory, ".vite", "manifest.json"),
2930
3159
  "utf-8"
2931
3160
  );
2932
3161
  return JSON.parse(manifestContents);
@@ -2950,8 +3179,8 @@ var reactRouterVitePlugin = () => {
2950
3179
  const entryNormalizedPath = "parentPath" in entry && typeof entry.parentPath === "string" ? entry.parentPath : entry.path;
2951
3180
  let contents;
2952
3181
  try {
2953
- contents = await (0, import_promises2.readFile)(
2954
- path6.join(entryNormalizedPath, entry.name),
3182
+ contents = await (0, import_promises3.readFile)(
3183
+ path7.join(entryNormalizedPath, entry.name),
2955
3184
  "utf-8"
2956
3185
  );
2957
3186
  } catch (e) {
@@ -2960,9 +3189,9 @@ var reactRouterVitePlugin = () => {
2960
3189
  }
2961
3190
  let hash = (0, import_node_crypto.createHash)("sha384").update(contents).digest().toString("base64");
2962
3191
  let filepath = getVite().normalizePath(
2963
- path6.relative(
3192
+ path7.relative(
2964
3193
  clientBuildDirectory,
2965
- path6.join(entryNormalizedPath, entry.name)
3194
+ path7.join(entryNormalizedPath, entry.name)
2966
3195
  )
2967
3196
  );
2968
3197
  sriManifest[`${ctx2.publicPath}${filepath}`] = `sha384-${hash}`;
@@ -2995,7 +3224,7 @@ var reactRouterVitePlugin = () => {
2995
3224
  );
2996
3225
  let enforceSplitRouteModules = ctx.reactRouterConfig.future.v8_splitRouteModules === "enforce";
2997
3226
  for (let route of Object.values(ctx.reactRouterConfig.routes)) {
2998
- let routeFile = path6.join(ctx.reactRouterConfig.appDirectory, route.file);
3227
+ let routeFile = path7.join(ctx.reactRouterConfig.appDirectory, route.file);
2999
3228
  let sourceExports = routeManifestExports[route.id];
3000
3229
  let hasClientAction = sourceExports.includes("clientAction");
3001
3230
  let hasClientLoader = sourceExports.includes("clientLoader");
@@ -3030,6 +3259,7 @@ var reactRouterVitePlugin = () => {
3030
3259
  hasClientAction,
3031
3260
  hasClientLoader,
3032
3261
  hasClientMiddleware,
3262
+ hasDefaultExport: sourceExports.includes("default"),
3033
3263
  hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
3034
3264
  ...getReactRouterManifestBuildAssets(
3035
3265
  ctx,
@@ -3067,7 +3297,7 @@ var reactRouterVitePlugin = () => {
3067
3297
  }
3068
3298
  let fingerprintedValues = { entry, routes: browserRoutes };
3069
3299
  let version = getHash(JSON.stringify(fingerprintedValues), 8);
3070
- let manifestPath = path6.posix.join(
3300
+ let manifestPath = path7.posix.join(
3071
3301
  viteConfig2.build.assetsDir,
3072
3302
  `manifest-${version}.js`
3073
3303
  );
@@ -3079,7 +3309,7 @@ var reactRouterVitePlugin = () => {
3079
3309
  sri: void 0
3080
3310
  };
3081
3311
  await writeFileSafe(
3082
- path6.join(getClientBuildDirectory(ctx.reactRouterConfig), manifestPath),
3312
+ path7.join(getClientBuildDirectory(ctx.reactRouterConfig), manifestPath),
3083
3313
  `window.__reactRouterManifest=${JSON.stringify(
3084
3314
  reactRouterBrowserManifest
3085
3315
  )};`
@@ -3155,6 +3385,7 @@ var reactRouterVitePlugin = () => {
3155
3385
  hasClientAction,
3156
3386
  hasClientLoader,
3157
3387
  hasClientMiddleware,
3388
+ hasDefaultExport: sourceExports.includes("default"),
3158
3389
  hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
3159
3390
  imports: []
3160
3391
  };
@@ -3520,12 +3751,13 @@ var reactRouterVitePlugin = () => {
3520
3751
  }
3521
3752
  let handler = (0, import_react_router2.createRequestHandler)(build, "development");
3522
3753
  let nodeHandler = async (nodeReq, nodeRes) => {
3523
- let req2 = fromNodeRequest(nodeReq, nodeRes);
3754
+ let req2 = await fromNodeRequest(nodeReq, nodeRes);
3524
3755
  let res2 = await handler(
3525
3756
  req2,
3526
3757
  await reactRouterDevLoadContext(req2)
3527
3758
  );
3528
- await (0, import_node_fetch_server2.sendResponse)(nodeRes, res2);
3759
+ const { sendResponse } = await import("@remix-run/node-fetch-server");
3760
+ await sendResponse(nodeRes, res2);
3529
3761
  };
3530
3762
  await nodeHandler(req, res);
3531
3763
  } catch (error) {
@@ -3536,30 +3768,61 @@ var reactRouterVitePlugin = () => {
3536
3768
  };
3537
3769
  },
3538
3770
  configurePreviewServer(previewServer) {
3771
+ let cachedHandler = null;
3772
+ async function getHandler() {
3773
+ if (cachedHandler) return cachedHandler;
3774
+ let serverBuildFiles = [];
3775
+ let buildManifest = ctx.buildManifest ?? (ctx.reactRouterConfig.serverBundles ? await getBuildManifest({
3776
+ reactRouterConfig: ctx.reactRouterConfig,
3777
+ rootDirectory: ctx.rootDirectory
3778
+ }) : null);
3779
+ if (buildManifest?.serverBundles) {
3780
+ for (let bundle of Object.values(buildManifest.serverBundles)) {
3781
+ serverBuildFiles.push(
3782
+ path7.resolve(ctx.rootDirectory, bundle.file)
3783
+ );
3784
+ }
3785
+ } else {
3786
+ let serverEntryPath = path7.resolve(
3787
+ getServerBuildDirectory(ctx.reactRouterConfig),
3788
+ "index.js"
3789
+ );
3790
+ serverBuildFiles.push(serverEntryPath);
3791
+ }
3792
+ let handlers = [];
3793
+ for (let file of serverBuildFiles) {
3794
+ let build = await import(url.pathToFileURL(file).href);
3795
+ handlers.push((0, import_react_router2.createRequestHandler)(build, "production"));
3796
+ }
3797
+ cachedHandler = async (request, loadContext) => {
3798
+ let response;
3799
+ for (let handler of handlers) {
3800
+ response = await handler(request, loadContext);
3801
+ if (response.status !== 404) {
3802
+ return response;
3803
+ }
3804
+ }
3805
+ if (response) {
3806
+ return response;
3807
+ }
3808
+ throw new Error("No handlers were found for the request.");
3809
+ };
3810
+ return cachedHandler;
3811
+ }
3539
3812
  return () => {
3540
3813
  if (!ctx.reactRouterConfig.ssr) {
3541
3814
  return;
3542
3815
  }
3543
3816
  previewServer.middlewares.use(async (req, res, next) => {
3544
3817
  try {
3545
- let serverBuildDirectory = getServerBuildDirectory(
3546
- ctx.reactRouterConfig
3547
- );
3548
- let serverBuildFile = path6.resolve(
3549
- serverBuildDirectory,
3550
- "index.js"
3818
+ let handler = await getHandler();
3819
+ let request = await fromNodeRequest(req, res);
3820
+ let response = await handler(
3821
+ request,
3822
+ await reactRouterDevLoadContext(request)
3551
3823
  );
3552
- let build = await import(url.pathToFileURL(serverBuildFile).href);
3553
- let handler = (0, import_react_router2.createRequestHandler)(build, "production");
3554
- let nodeHandler = async (nodeReq, nodeRes) => {
3555
- let req2 = fromNodeRequest(nodeReq, nodeRes);
3556
- let res2 = await handler(
3557
- req2,
3558
- await reactRouterDevLoadContext(req2)
3559
- );
3560
- await (0, import_node_fetch_server2.sendResponse)(nodeRes, res2);
3561
- };
3562
- await nodeHandler(req, res);
3824
+ const { sendResponse } = await import("@remix-run/node-fetch-server");
3825
+ await sendResponse(res, response);
3563
3826
  } catch (error) {
3564
3827
  next(error);
3565
3828
  }
@@ -3586,19 +3849,19 @@ var reactRouterVitePlugin = () => {
3586
3849
  let removedAssetPaths = [];
3587
3850
  let copiedAssetPaths = [];
3588
3851
  for (let ssrAssetPath of ssrAssetPaths) {
3589
- let src = path6.join(serverBuildDirectory, ssrAssetPath);
3590
- let dest = path6.join(clientBuildDirectory, ssrAssetPath);
3852
+ let src = path7.join(serverBuildDirectory, ssrAssetPath);
3853
+ let dest = path7.join(clientBuildDirectory, ssrAssetPath);
3591
3854
  if (!userSsrEmitAssets) {
3592
3855
  if (!(0, import_node_fs2.existsSync)(dest)) {
3593
- await (0, import_promises2.mkdir)(path6.dirname(dest), { recursive: true });
3594
- await (0, import_promises2.rename)(src, dest);
3856
+ await (0, import_promises3.mkdir)(path7.dirname(dest), { recursive: true });
3857
+ await (0, import_promises3.rename)(src, dest);
3595
3858
  movedAssetPaths.push(dest);
3596
3859
  } else {
3597
- await (0, import_promises2.rm)(src, { force: true, recursive: true });
3860
+ await (0, import_promises3.rm)(src, { force: true, recursive: true });
3598
3861
  removedAssetPaths.push(dest);
3599
3862
  }
3600
3863
  } else if (!(0, import_node_fs2.existsSync)(dest)) {
3601
- await (0, import_promises2.cp)(src, dest, { recursive: true });
3864
+ await (0, import_promises3.cp)(src, dest, { recursive: true });
3602
3865
  copiedAssetPaths.push(dest);
3603
3866
  }
3604
3867
  }
@@ -3608,21 +3871,21 @@ var reactRouterVitePlugin = () => {
3608
3871
  );
3609
3872
  await Promise.all(
3610
3873
  ssrCssPaths.map(async (cssPath) => {
3611
- let src = path6.join(serverBuildDirectory, cssPath);
3612
- await (0, import_promises2.rm)(src, { force: true, recursive: true });
3874
+ let src = path7.join(serverBuildDirectory, cssPath);
3875
+ await (0, import_promises3.rm)(src, { force: true, recursive: true });
3613
3876
  removedAssetPaths.push(src);
3614
3877
  })
3615
3878
  );
3616
3879
  }
3617
3880
  let cleanedAssetPaths = [...removedAssetPaths, ...movedAssetPaths];
3618
3881
  let handledAssetPaths = [...cleanedAssetPaths, ...copiedAssetPaths];
3619
- let cleanedAssetDirs = new Set(cleanedAssetPaths.map(path6.dirname));
3882
+ let cleanedAssetDirs = new Set(cleanedAssetPaths.map(path7.dirname));
3620
3883
  await Promise.all(
3621
3884
  Array.from(cleanedAssetDirs).map(async (dir) => {
3622
3885
  try {
3623
- const files = await (0, import_promises2.readdir)(dir, { recursive: true });
3886
+ const files = await (0, import_promises3.readdir)(dir, { recursive: true });
3624
3887
  if (files.length === 0) {
3625
- await (0, import_promises2.rm)(dir, { force: true, recursive: true });
3888
+ await (0, import_promises3.rm)(dir, { force: true, recursive: true });
3626
3889
  }
3627
3890
  } catch {
3628
3891
  }
@@ -3638,7 +3901,7 @@ var reactRouterVitePlugin = () => {
3638
3901
  [
3639
3902
  `${import_picocolors4.default.green("\u2713")} ${message}`,
3640
3903
  ...paths.map(
3641
- (assetPath) => import_picocolors4.default.dim(path6.relative(ctx.rootDirectory, assetPath))
3904
+ (assetPath) => import_picocolors4.default.dim(path7.relative(ctx.rootDirectory, assetPath))
3642
3905
  )
3643
3906
  ].join("\n")
3644
3907
  );
@@ -3659,6 +3922,9 @@ var reactRouterVitePlugin = () => {
3659
3922
  if (handledAssetPaths.length) {
3660
3923
  viteConfig.logger.info("");
3661
3924
  }
3925
+ if (future.unstable_previewServerPrerendering) {
3926
+ return;
3927
+ }
3662
3928
  process.env.IS_RR_BUILD_REQUEST = "yes";
3663
3929
  if (isPrerenderingEnabled(ctx.reactRouterConfig)) {
3664
3930
  await handlePrerender(
@@ -3732,7 +3998,7 @@ var reactRouterVitePlugin = () => {
3732
3998
  );
3733
3999
  let isMainChunkExport = (name) => !chunkedExports.includes(name);
3734
4000
  let mainChunkReexports = sourceExports.filter(isMainChunkExport).join(", ");
3735
- let chunkBasePath = `./${path6.basename(id)}`;
4001
+ let chunkBasePath = `./${path7.basename(id)}`;
3736
4002
  return [
3737
4003
  `export { ${mainChunkReexports} } from "${getRouteChunkModuleId(
3738
4004
  chunkBasePath,
@@ -3752,7 +4018,7 @@ var reactRouterVitePlugin = () => {
3752
4018
  async transform(code, id, options) {
3753
4019
  if (!id.endsWith(BUILD_CLIENT_ROUTE_QUERY_STRING)) return;
3754
4020
  let routeModuleId = id.replace(BUILD_CLIENT_ROUTE_QUERY_STRING, "");
3755
- let routeFileName = path6.basename(routeModuleId);
4021
+ let routeFileName = path7.basename(routeModuleId);
3756
4022
  let sourceExports = await getRouteModuleExports(
3757
4023
  viteChildCompiler,
3758
4024
  ctx,
@@ -3832,6 +4098,7 @@ var reactRouterVitePlugin = () => {
3832
4098
  viteConfig,
3833
4099
  routeIds
3834
4100
  })).reactRouterServerManifest : await getReactRouterManifestForDev();
4101
+ ctx.reactRouterManifest = reactRouterManifest;
3835
4102
  if (!ctx.reactRouterConfig.ssr) {
3836
4103
  invariant(viteConfig);
3837
4104
  validateSsrFalsePrerenderExports(
@@ -3879,7 +4146,7 @@ var reactRouterVitePlugin = () => {
3879
4146
  }
3880
4147
  let vite2 = getVite();
3881
4148
  let importerShort = vite2.normalizePath(
3882
- path6.relative(ctx.rootDirectory, importer)
4149
+ path7.relative(ctx.rootDirectory, importer)
3883
4150
  );
3884
4151
  if (isRoute(ctx.reactRouterConfig, importer)) {
3885
4152
  let serverOnlyExports = SERVER_ONLY_ROUTE_EXPORTS.map(
@@ -4001,17 +4268,17 @@ var reactRouterVitePlugin = () => {
4001
4268
  },
4002
4269
  async load(id) {
4003
4270
  if (id !== virtualHmrRuntime.resolvedId) return;
4004
- let reactRefreshDir = path6.dirname(
4271
+ let reactRefreshDir = path7.dirname(
4005
4272
  require.resolve("react-refresh/package.json")
4006
4273
  );
4007
- let reactRefreshRuntimePath = path6.join(
4274
+ let reactRefreshRuntimePath = path7.join(
4008
4275
  reactRefreshDir,
4009
4276
  "cjs/react-refresh-runtime.development.js"
4010
4277
  );
4011
4278
  return [
4012
4279
  "const exports = {}",
4013
- await (0, import_promises2.readFile)(reactRefreshRuntimePath, "utf8"),
4014
- await (0, import_promises2.readFile)(require.resolve("./static/refresh-utils.mjs"), "utf8"),
4280
+ await (0, import_promises3.readFile)(reactRefreshRuntimePath, "utf8"),
4281
+ await (0, import_promises3.readFile)(require.resolve("./static/refresh-utils.mjs"), "utf8"),
4015
4282
  "export default exports"
4016
4283
  ].join("\n");
4017
4284
  }
@@ -4111,6 +4378,223 @@ var reactRouterVitePlugin = () => {
4111
4378
  }
4112
4379
  }
4113
4380
  },
4381
+ prerender({
4382
+ config() {
4383
+ process.env.IS_RR_BUILD_REQUEST = "yes";
4384
+ return {
4385
+ // Required as viteConfig.environments.client.build.outDir is only available in Vite v6+
4386
+ buildDirectory: getClientBuildDirectory(ctx.reactRouterConfig),
4387
+ concurrency: getPrerenderConcurrencyConfig(ctx.reactRouterConfig)
4388
+ };
4389
+ },
4390
+ async requests() {
4391
+ invariant(viteConfig);
4392
+ let { future } = ctx.reactRouterConfig;
4393
+ if (future.v8_viteEnvironmentApi ? this.environment.name === "client" : !viteConfigEnv.isSsrBuild) {
4394
+ return [];
4395
+ }
4396
+ if (!future.unstable_previewServerPrerendering) {
4397
+ return [];
4398
+ }
4399
+ let requests = [];
4400
+ if (isPrerenderingEnabled(ctx.reactRouterConfig)) {
4401
+ invariant(ctx.prerenderPaths !== null, "Prerender paths missing");
4402
+ invariant(
4403
+ ctx.reactRouterManifest !== null,
4404
+ "Prerender manifest missing"
4405
+ );
4406
+ let { reactRouterConfig, reactRouterManifest, prerenderPaths } = ctx;
4407
+ assertPrerenderPathsMatchRoutes(
4408
+ reactRouterConfig,
4409
+ Array.from(prerenderPaths)
4410
+ );
4411
+ let buildRoutes = createPrerenderRoutes(reactRouterManifest.routes);
4412
+ for (let prerenderPath of prerenderPaths) {
4413
+ let matches = (0, import_react_router2.matchRoutes)(
4414
+ buildRoutes,
4415
+ `/${prerenderPath}/`.replace(/^\/\/+/, "/")
4416
+ );
4417
+ if (!matches) {
4418
+ continue;
4419
+ }
4420
+ let leafRoute = matches[matches.length - 1].route;
4421
+ let manifestRoute = reactRouterManifest.routes[leafRoute.id];
4422
+ let isResourceRoute = manifestRoute && !manifestRoute.hasDefaultExport && !manifestRoute.hasErrorBoundary;
4423
+ if (isResourceRoute) {
4424
+ if (manifestRoute?.hasLoader) {
4425
+ requests.push(
4426
+ // Prerender a .data file for turbo-stream consumption
4427
+ createDataRequest(
4428
+ prerenderPath,
4429
+ reactRouterConfig,
4430
+ [leafRoute.id],
4431
+ true
4432
+ ),
4433
+ // Prerender a raw file for external consumption
4434
+ createResourceRouteRequest(prerenderPath, reactRouterConfig)
4435
+ );
4436
+ } else {
4437
+ viteConfig.logger.warn(
4438
+ `\u26A0\uFE0F Skipping prerendering for resource route without a loader: ${leafRoute.id}`
4439
+ );
4440
+ }
4441
+ } else {
4442
+ let hasLoaders = matches.some(
4443
+ (m) => reactRouterManifest.routes[m.route.id]?.hasLoader
4444
+ );
4445
+ if (hasLoaders) {
4446
+ requests.push(
4447
+ createDataRequest(prerenderPath, reactRouterConfig, null)
4448
+ );
4449
+ } else {
4450
+ requests.push(
4451
+ createRouteRequest(prerenderPath, reactRouterConfig)
4452
+ );
4453
+ }
4454
+ }
4455
+ }
4456
+ }
4457
+ if (!ctx.reactRouterConfig.ssr) {
4458
+ requests.push(createSpaModeRequest(ctx.reactRouterConfig));
4459
+ }
4460
+ return requests;
4461
+ },
4462
+ async postProcess(request, response, metadata) {
4463
+ invariant(metadata);
4464
+ if (metadata.type === "data") {
4465
+ let pathname2 = new URL(request.url).pathname;
4466
+ if (response.status !== 200 && response.status !== 202) {
4467
+ throw new Error(
4468
+ `Prerender (data): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${metadata.path}\` path.
4469
+ ${pathname2}`,
4470
+ { cause: response }
4471
+ );
4472
+ }
4473
+ let data = await response.text();
4474
+ return {
4475
+ files: [
4476
+ {
4477
+ path: pathname2,
4478
+ contents: data
4479
+ }
4480
+ ],
4481
+ // After saving the .data file, request the HTML page.
4482
+ // The data is passed along to be embedded in the response header.
4483
+ requests: !metadata.isResourceRoute ? [createRouteRequest(metadata.path, ctx.reactRouterConfig, data)] : []
4484
+ };
4485
+ }
4486
+ if (metadata.type === "resource") {
4487
+ let pathname2 = new URL(request.url).pathname;
4488
+ let contents = new Uint8Array(await response.arrayBuffer());
4489
+ if (response.status !== 200) {
4490
+ throw new Error(
4491
+ `Prerender (resource): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${pathname2}\` path.
4492
+ ${new TextDecoder().decode(contents)}`
4493
+ );
4494
+ }
4495
+ return [
4496
+ {
4497
+ path: pathname2,
4498
+ contents
4499
+ }
4500
+ ];
4501
+ }
4502
+ let html = await response.text();
4503
+ if (metadata.type === "spa") {
4504
+ if (response.status !== 200) {
4505
+ throw new Error(
4506
+ `SPA Mode: Received a ${response.status} status code from \`entry.server.tsx\` while prerendering your SPA Fallback HTML file.
4507
+ ` + html
4508
+ );
4509
+ }
4510
+ if (!html.includes("window.__reactRouterContext =") || !html.includes("window.__reactRouterRouteModules =")) {
4511
+ throw new Error(
4512
+ "SPA Mode: Did you forget to include `<Scripts/>` in your root route? Your pre-rendered HTML cannot hydrate without `<Scripts />`."
4513
+ );
4514
+ }
4515
+ return [
4516
+ {
4517
+ path: "/__spa-fallback.html",
4518
+ contents: html
4519
+ }
4520
+ ];
4521
+ }
4522
+ let pathname = new URL(request.url).pathname;
4523
+ if (redirectStatusCodes.has(response.status)) {
4524
+ let location = response.headers.get("Location");
4525
+ let delay = response.status === 302 ? 2 : 0;
4526
+ html = `<!doctype html>
4527
+ <head>
4528
+ <title>Redirecting to: ${location}</title>
4529
+ <meta http-equiv="refresh" content="${delay};url=${location}">
4530
+ <meta name="robots" content="noindex">
4531
+ </head>
4532
+ <body>
4533
+ <a href="${location}">
4534
+ Redirecting from <code>${pathname}</code> to <code>${location}</code>
4535
+ </a>
4536
+ </body>
4537
+ </html>`;
4538
+ } else if (response.status !== 200) {
4539
+ throw new Error(
4540
+ `Prerender (html): Received a ${response.status} status code from \`entry.server.tsx\` while prerendering the \`${pathname}\` path.
4541
+ ${html}`
4542
+ );
4543
+ }
4544
+ return [
4545
+ {
4546
+ path: `${pathname}/index.html`,
4547
+ contents: html
4548
+ }
4549
+ ];
4550
+ },
4551
+ logFile(outputPath, metadata) {
4552
+ invariant(viteConfig);
4553
+ invariant(metadata);
4554
+ if (metadata.type === "spa") {
4555
+ return;
4556
+ }
4557
+ viteConfig.logger.info(
4558
+ `Prerender (${metadata.type}): ${metadata.path} -> ${import_picocolors4.default.bold(outputPath)}`
4559
+ );
4560
+ },
4561
+ async finalize(buildDirectory) {
4562
+ invariant(viteConfig);
4563
+ let { ssr, future } = ctx.reactRouterConfig;
4564
+ if (!ssr) {
4565
+ let spaFallback = path7.join(buildDirectory, "__spa-fallback.html");
4566
+ let index = path7.join(buildDirectory, "index.html");
4567
+ let finalSpaPath;
4568
+ if ((0, import_node_fs2.existsSync)(spaFallback) && !(0, import_node_fs2.existsSync)(index)) {
4569
+ await (0, import_promises3.rename)(spaFallback, index);
4570
+ finalSpaPath = index;
4571
+ } else if ((0, import_node_fs2.existsSync)(spaFallback)) {
4572
+ finalSpaPath = spaFallback;
4573
+ }
4574
+ if (finalSpaPath) {
4575
+ let prettyPath = path7.relative(viteConfig.root, finalSpaPath);
4576
+ if (ctx.prerenderPaths && ctx.prerenderPaths.size > 0) {
4577
+ viteConfig.logger.info(
4578
+ `Prerender (html): SPA Fallback -> ${import_picocolors4.default.bold(prettyPath)}`
4579
+ );
4580
+ } else {
4581
+ viteConfig.logger.info(
4582
+ `SPA Mode: Generated ${import_picocolors4.default.bold(prettyPath)}`
4583
+ );
4584
+ }
4585
+ }
4586
+ let serverBuildDirectory = future.v8_viteEnvironmentApi ? this.environment.config?.build?.outDir : ctx.environmentBuildContext?.options.build?.outDir ?? getServerBuildDirectory(ctx.reactRouterConfig);
4587
+ viteConfig.logger.info(
4588
+ [
4589
+ "Removing the server build in",
4590
+ import_picocolors4.default.green(serverBuildDirectory),
4591
+ "due to ssr:false"
4592
+ ].join(" ")
4593
+ );
4594
+ (0, import_node_fs2.rmSync)(serverBuildDirectory, { force: true, recursive: true });
4595
+ }
4596
+ }
4597
+ }),
4114
4598
  validatePluginOrder(),
4115
4599
  warnOnClientSourceMaps()
4116
4600
  ];
@@ -4174,7 +4658,7 @@ if (import.meta.hot && !inWebWorker) {
4174
4658
  function getRoute(pluginConfig, file) {
4175
4659
  let vite2 = getVite();
4176
4660
  let routePath = vite2.normalizePath(
4177
- path6.relative(pluginConfig.appDirectory, file)
4661
+ path7.relative(pluginConfig.appDirectory, file)
4178
4662
  );
4179
4663
  let route = Object.values(pluginConfig.routes).find(
4180
4664
  (r) => vite2.normalizePath(r.file) === routePath
@@ -4213,7 +4697,7 @@ async function getRouteMetadata(cache, ctx, viteChildCompiler, route, readRouteF
4213
4697
  caseSensitive: route.caseSensitive,
4214
4698
  url: combineURLs(
4215
4699
  ctx.publicPath,
4216
- "/" + path6.relative(
4700
+ "/" + path7.relative(
4217
4701
  ctx.rootDirectory,
4218
4702
  resolveRelativeRouteFilePath(route, ctx.reactRouterConfig)
4219
4703
  )
@@ -4229,6 +4713,7 @@ async function getRouteMetadata(cache, ctx, viteChildCompiler, route, readRouteF
4229
4713
  hasLoader: sourceExports.includes("loader"),
4230
4714
  hasClientLoader: sourceExports.includes("clientLoader"),
4231
4715
  hasClientMiddleware: sourceExports.includes("clientMiddleware"),
4716
+ hasDefaultExport: sourceExports.includes("default"),
4232
4717
  hasErrorBoundary: sourceExports.includes("ErrorBoundary"),
4233
4718
  imports: []
4234
4719
  };
@@ -4241,7 +4726,7 @@ function isSpaModeEnabled(reactRouterConfig) {
4241
4726
  return reactRouterConfig.ssr === false && !isPrerenderingEnabled(reactRouterConfig);
4242
4727
  }
4243
4728
  async function getPrerenderBuildAndHandler(viteConfig, serverBuildDirectory, serverBuildFile) {
4244
- let serverBuildPath = path6.join(serverBuildDirectory, serverBuildFile);
4729
+ let serverBuildPath = path7.join(serverBuildDirectory, serverBuildFile);
4245
4730
  let build = await import(url.pathToFileURL(serverBuildPath).toString());
4246
4731
  let { createRequestHandler: createHandler } = await import("react-router");
4247
4732
  return {
@@ -4283,9 +4768,9 @@ async function handleSpaMode(viteConfig, reactRouterConfig, serverBuildDirectory
4283
4768
  "SPA Mode: Did you forget to include `<Scripts/>` in your root route? Your pre-rendered HTML cannot hydrate without `<Scripts />`."
4284
4769
  );
4285
4770
  }
4286
- await (0, import_promises2.writeFile)(path6.join(clientBuildDirectory, filename2), html);
4287
- let prettyDir = path6.relative(viteConfig.root, clientBuildDirectory);
4288
- let prettyPath = path6.join(prettyDir, filename2);
4771
+ await (0, import_promises3.writeFile)(path7.join(clientBuildDirectory, filename2), html);
4772
+ let prettyDir = path7.relative(viteConfig.root, clientBuildDirectory);
4773
+ let prettyPath = path7.join(prettyDir, filename2);
4289
4774
  if (build.prerender.length > 0) {
4290
4775
  viteConfig.logger.info(
4291
4776
  `Prerender (html): SPA Fallback -> ${import_picocolors4.default.bold(prettyPath)}`
@@ -4301,17 +4786,17 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4301
4786
  serverBuildPath
4302
4787
  );
4303
4788
  let routes = createPrerenderRoutes(reactRouterConfig.routes);
4304
- for (let path9 of build.prerender) {
4305
- let matches = (0, import_react_router2.matchRoutes)(routes, `/${path9}/`.replace(/^\/\/+/, "/"));
4789
+ for (let path10 of build.prerender) {
4790
+ let matches = (0, import_react_router2.matchRoutes)(routes, `/${path10}/`.replace(/^\/\/+/, "/"));
4306
4791
  if (!matches) {
4307
4792
  throw new Error(
4308
- `Unable to prerender path because it does not match any routes: ${path9}`
4793
+ `Unable to prerender path because it does not match any routes: ${path10}`
4309
4794
  );
4310
4795
  }
4311
4796
  }
4312
4797
  let buildRoutes = createPrerenderRoutes(build.routes);
4313
- let prerenderSinglePath = async (path9) => {
4314
- let matches = (0, import_react_router2.matchRoutes)(buildRoutes, `/${path9}/`.replace(/^\/\/+/, "/"));
4798
+ let prerenderSinglePath = async (path10) => {
4799
+ let matches = (0, import_react_router2.matchRoutes)(buildRoutes, `/${path10}/`.replace(/^\/\/+/, "/"));
4315
4800
  if (!matches) {
4316
4801
  return;
4317
4802
  }
@@ -4324,7 +4809,7 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4324
4809
  if (manifestRoute.loader) {
4325
4810
  await prerenderData(
4326
4811
  handler,
4327
- path9,
4812
+ path10,
4328
4813
  [leafRoute.id],
4329
4814
  clientBuildDirectory,
4330
4815
  reactRouterConfig,
@@ -4332,7 +4817,7 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4332
4817
  );
4333
4818
  await prerenderResourceRoute(
4334
4819
  handler,
4335
- path9,
4820
+ path10,
4336
4821
  clientBuildDirectory,
4337
4822
  reactRouterConfig,
4338
4823
  viteConfig
@@ -4350,7 +4835,7 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4350
4835
  if (!isResourceRoute && hasLoaders) {
4351
4836
  data = await prerenderData(
4352
4837
  handler,
4353
- path9,
4838
+ path10,
4354
4839
  null,
4355
4840
  clientBuildDirectory,
4356
4841
  reactRouterConfig,
@@ -4359,7 +4844,7 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4359
4844
  }
4360
4845
  await prerenderRoute(
4361
4846
  handler,
4362
- path9,
4847
+ path10,
4363
4848
  clientBuildDirectory,
4364
4849
  reactRouterConfig,
4365
4850
  viteConfig,
@@ -4372,9 +4857,9 @@ async function handlePrerender(viteConfig, reactRouterConfig, serverBuildDirecto
4372
4857
  }
4373
4858
  };
4374
4859
  let concurrency = 1;
4375
- let { prerender } = reactRouterConfig;
4376
- if (typeof prerender === "object" && "unstable_concurrency" in prerender) {
4377
- concurrency = prerender.unstable_concurrency ?? 1;
4860
+ let { prerender: prerender2 } = reactRouterConfig;
4861
+ if (typeof prerender2 === "object" && "unstable_concurrency" in prerender2) {
4862
+ concurrency = prerender2.unstable_concurrency ?? 1;
4378
4863
  }
4379
4864
  const pMap = await import("p-map");
4380
4865
  await pMap.default(build.prerender, prerenderSinglePath, { concurrency });
@@ -4433,12 +4918,12 @@ async function prerenderData(handler, prerenderPath, onlyRoutes, clientBuildDire
4433
4918
  ${normalizedPath}`
4434
4919
  );
4435
4920
  }
4436
- let outfile = path6.join(clientBuildDirectory, ...normalizedPath.split("/"));
4437
- await (0, import_promises2.mkdir)(path6.dirname(outfile), { recursive: true });
4438
- await (0, import_promises2.writeFile)(outfile, data);
4921
+ let outfile = path7.join(clientBuildDirectory, ...normalizedPath.split("/"));
4922
+ await (0, import_promises3.mkdir)(path7.dirname(outfile), { recursive: true });
4923
+ await (0, import_promises3.writeFile)(outfile, data);
4439
4924
  viteConfig.logger.info(
4440
4925
  `Prerender (data): ${prerenderPath} -> ${import_picocolors4.default.bold(
4441
- path6.relative(viteConfig.root, outfile)
4926
+ path7.relative(viteConfig.root, outfile)
4442
4927
  )}`
4443
4928
  );
4444
4929
  return data;
@@ -4473,16 +4958,16 @@ async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reac
4473
4958
  ${html}`
4474
4959
  );
4475
4960
  }
4476
- let outfile = path6.join(
4961
+ let outfile = path7.join(
4477
4962
  clientBuildDirectory,
4478
4963
  ...normalizedPath.split("/"),
4479
4964
  "index.html"
4480
4965
  );
4481
- await (0, import_promises2.mkdir)(path6.dirname(outfile), { recursive: true });
4482
- await (0, import_promises2.writeFile)(outfile, html);
4966
+ await (0, import_promises3.mkdir)(path7.dirname(outfile), { recursive: true });
4967
+ await (0, import_promises3.writeFile)(outfile, html);
4483
4968
  viteConfig.logger.info(
4484
4969
  `Prerender (html): ${prerenderPath} -> ${import_picocolors4.default.bold(
4485
- path6.relative(viteConfig.root, outfile)
4970
+ path7.relative(viteConfig.root, outfile)
4486
4971
  )}`
4487
4972
  );
4488
4973
  }
@@ -4497,24 +4982,24 @@ async function prerenderResourceRoute(handler, prerenderPath, clientBuildDirecto
4497
4982
  ${content.toString("utf8")}`
4498
4983
  );
4499
4984
  }
4500
- let outfile = path6.join(clientBuildDirectory, ...normalizedPath.split("/"));
4501
- await (0, import_promises2.mkdir)(path6.dirname(outfile), { recursive: true });
4502
- await (0, import_promises2.writeFile)(outfile, content);
4985
+ let outfile = path7.join(clientBuildDirectory, ...normalizedPath.split("/"));
4986
+ await (0, import_promises3.mkdir)(path7.dirname(outfile), { recursive: true });
4987
+ await (0, import_promises3.writeFile)(outfile, content);
4503
4988
  viteConfig.logger.info(
4504
4989
  `Prerender (resource): ${prerenderPath} -> ${import_picocolors4.default.bold(
4505
- path6.relative(viteConfig.root, outfile)
4990
+ path7.relative(viteConfig.root, outfile)
4506
4991
  )}`
4507
4992
  );
4508
4993
  }
4509
- async function getPrerenderPaths(prerender, ssr, routes, logWarning = false) {
4510
- if (prerender == null || prerender === false) {
4994
+ async function getPrerenderPaths(prerender2, ssr, routes, logWarning = false) {
4995
+ if (prerender2 == null || prerender2 === false) {
4511
4996
  return [];
4512
4997
  }
4513
4998
  let pathsConfig;
4514
- if (typeof prerender === "object" && "paths" in prerender) {
4515
- pathsConfig = prerender.paths;
4999
+ if (typeof prerender2 === "object" && "paths" in prerender2) {
5000
+ pathsConfig = prerender2.paths;
4516
5001
  } else {
4517
- pathsConfig = prerender;
5002
+ pathsConfig = prerender2;
4518
5003
  }
4519
5004
  if (pathsConfig === false) {
4520
5005
  return [];
@@ -4585,14 +5070,14 @@ async function validateSsrFalsePrerenderExports(viteConfig, ctx, manifest, viteC
4585
5070
  }
4586
5071
  let prerenderRoutes = createPrerenderRoutes(manifest.routes);
4587
5072
  let prerenderedRoutes = /* @__PURE__ */ new Set();
4588
- for (let path9 of prerenderPaths) {
5073
+ for (let path10 of prerenderPaths) {
4589
5074
  let matches = (0, import_react_router2.matchRoutes)(
4590
5075
  prerenderRoutes,
4591
- `/${path9}/`.replace(/^\/\/+/, "/")
5076
+ `/${path10}/`.replace(/^\/\/+/, "/")
4592
5077
  );
4593
5078
  invariant(
4594
5079
  matches,
4595
- `Unable to prerender path because it does not match any routes: ${path9}`
5080
+ `Unable to prerender path because it does not match any routes: ${path10}`
4596
5081
  );
4597
5082
  matches.forEach((m) => prerenderedRoutes.add(m.route.id));
4598
5083
  }
@@ -4759,11 +5244,11 @@ function validateRouteChunks({
4759
5244
  async function cleanBuildDirectory(viteConfig, ctx) {
4760
5245
  let buildDirectory = ctx.reactRouterConfig.buildDirectory;
4761
5246
  let isWithinRoot = () => {
4762
- let relativePath = path6.relative(ctx.rootDirectory, buildDirectory);
4763
- return !relativePath.startsWith("..") && !path6.isAbsolute(relativePath);
5247
+ let relativePath = path7.relative(ctx.rootDirectory, buildDirectory);
5248
+ return !relativePath.startsWith("..") && !path7.isAbsolute(relativePath);
4764
5249
  };
4765
5250
  if (viteConfig.build.emptyOutDir ?? isWithinRoot()) {
4766
- await (0, import_promises2.rm)(buildDirectory, { force: true, recursive: true });
5251
+ await (0, import_promises3.rm)(buildDirectory, { force: true, recursive: true });
4767
5252
  }
4768
5253
  }
4769
5254
  async function cleanViteManifests(environmentsOptions, ctx) {
@@ -4771,7 +5256,7 @@ async function cleanViteManifests(environmentsOptions, ctx) {
4771
5256
  ([environmentName, options]) => {
4772
5257
  let outDir = options.build?.outDir;
4773
5258
  invariant(outDir, `Expected build.outDir for ${environmentName}`);
4774
- return path6.join(outDir, ".vite/manifest.json");
5259
+ return path7.join(outDir, ".vite/manifest.json");
4775
5260
  }
4776
5261
  );
4777
5262
  await Promise.all(
@@ -4779,12 +5264,12 @@ async function cleanViteManifests(environmentsOptions, ctx) {
4779
5264
  let manifestExists = (0, import_node_fs2.existsSync)(viteManifestPath);
4780
5265
  if (!manifestExists) return;
4781
5266
  if (!ctx.viteManifestEnabled) {
4782
- await (0, import_promises2.rm)(viteManifestPath, { force: true, recursive: true });
5267
+ await (0, import_promises3.rm)(viteManifestPath, { force: true, recursive: true });
4783
5268
  }
4784
- let viteDir = path6.dirname(viteManifestPath);
4785
- let viteDirFiles = await (0, import_promises2.readdir)(viteDir, { recursive: true });
5269
+ let viteDir = path7.dirname(viteManifestPath);
5270
+ let viteDirFiles = await (0, import_promises3.readdir)(viteDir, { recursive: true });
4786
5271
  if (viteDirFiles.length === 0) {
4787
- await (0, import_promises2.rm)(viteDir, { force: true, recursive: true });
5272
+ await (0, import_promises3.rm)(viteDir, { force: true, recursive: true });
4788
5273
  }
4789
5274
  })
4790
5275
  );
@@ -4799,12 +5284,12 @@ async function getBuildManifest({
4799
5284
  }
4800
5285
  let { normalizePath } = await import("vite");
4801
5286
  let serverBuildDirectory = getServerBuildDirectory(reactRouterConfig);
4802
- let resolvedAppDirectory = path6.resolve(rootDirectory, appDirectory);
5287
+ let resolvedAppDirectory = path7.resolve(rootDirectory, appDirectory);
4803
5288
  let rootRelativeRoutes = Object.fromEntries(
4804
5289
  Object.entries(routes).map(([id, route]) => {
4805
- let filePath = path6.join(resolvedAppDirectory, route.file);
5290
+ let filePath = path7.join(resolvedAppDirectory, route.file);
4806
5291
  let rootRelativeFilePath = normalizePath(
4807
- path6.relative(rootDirectory, filePath)
5292
+ path7.relative(rootDirectory, filePath)
4808
5293
  );
4809
5294
  return [id, { ...route, file: rootRelativeFilePath }];
4810
5295
  })
@@ -4822,7 +5307,7 @@ async function getBuildManifest({
4822
5307
  (route2) => configRouteToBranchRoute({
4823
5308
  ...route2,
4824
5309
  // Ensure absolute paths are passed to the serverBundles function
4825
- file: path6.join(resolvedAppDirectory, route2.file)
5310
+ file: path7.join(resolvedAppDirectory, route2.file)
4826
5311
  })
4827
5312
  )
4828
5313
  });
@@ -4846,10 +5331,10 @@ async function getBuildManifest({
4846
5331
  buildManifest.serverBundles[serverBundleId] ??= {
4847
5332
  id: serverBundleId,
4848
5333
  file: normalizePath(
4849
- path6.join(
4850
- path6.relative(
5334
+ path7.join(
5335
+ path7.relative(
4851
5336
  rootDirectory,
4852
- path6.join(serverBuildDirectory, serverBundleId)
5337
+ path7.join(serverBuildDirectory, serverBundleId)
4853
5338
  ),
4854
5339
  reactRouterConfig.serverBuildFile
4855
5340
  )
@@ -4868,10 +5353,10 @@ function mergeEnvironmentOptions(base, ...overrides) {
4868
5353
  }
4869
5354
  async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4870
5355
  let { serverBuildFile, serverModuleFormat } = ctx.reactRouterConfig;
4871
- let packageRoot = path6.dirname(
5356
+ let packageRoot = path7.dirname(
4872
5357
  require.resolve("@react-router/dev/package.json")
4873
5358
  );
4874
- let { moduleSyncEnabled } = await import(`file:///${path6.join(packageRoot, "module-sync-enabled/index.mjs")}`);
5359
+ let { moduleSyncEnabled } = await import(`file:///${path7.join(packageRoot, "module-sync-enabled/index.mjs")}`);
4875
5360
  let vite2 = getVite();
4876
5361
  function getBaseOptions({
4877
5362
  viteUserConfig
@@ -4950,7 +5435,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4950
5435
  ctx.entryClientFilePath,
4951
5436
  ...Object.values(ctx.reactRouterConfig.routes).flatMap(
4952
5437
  (route) => {
4953
- let routeFilePath = path6.resolve(
5438
+ let routeFilePath = path7.resolve(
4954
5439
  ctx.reactRouterConfig.appDirectory,
4955
5440
  route.file
4956
5441
  );
@@ -4974,7 +5459,7 @@ async function getEnvironmentOptionsResolvers(ctx, viteCommand) {
4974
5459
  ) : null;
4975
5460
  let routeChunkSuffix = routeChunkName ? `-${(0, import_kebabCase.default)(routeChunkName)}` : "";
4976
5461
  let assetsDir = (ctx.reactRouterConfig.future.v8_viteEnvironmentApi ? viteUserConfig?.environments?.client?.build?.assetsDir : null) ?? viteUserConfig?.build?.assetsDir ?? "assets";
4977
- return path6.posix.join(
5462
+ return path7.posix.join(
4978
5463
  assetsDir,
4979
5464
  `[name]${routeChunkSuffix}-[hash].js`
4980
5465
  );
@@ -5040,13 +5525,78 @@ async function asyncFlatten(arr) {
5040
5525
  } while (arr.some((v2) => v2?.then));
5041
5526
  return arr;
5042
5527
  }
5528
+ function assertPrerenderPathsMatchRoutes(config, prerenderPaths) {
5529
+ let routes = createPrerenderRoutes(config.routes);
5530
+ for (let path10 of prerenderPaths) {
5531
+ let matches = (0, import_react_router2.matchRoutes)(routes, `/${path10}/`.replace(/^\/\/+/, "/"));
5532
+ if (!matches) {
5533
+ throw new Error(
5534
+ `Unable to prerender path because it does not match any routes: ${path10}`
5535
+ );
5536
+ }
5537
+ }
5538
+ }
5539
+ function getPrerenderConcurrencyConfig(reactRouterConfig) {
5540
+ let concurrency = 1;
5541
+ let { prerender: prerender2 } = reactRouterConfig;
5542
+ if (typeof prerender2 === "object" && "unstable_concurrency" in prerender2) {
5543
+ concurrency = prerender2.unstable_concurrency ?? 1;
5544
+ }
5545
+ return concurrency;
5546
+ }
5547
+ function createDataRequest(prerenderPath, reactRouterConfig, onlyRoutes, isResourceRoute) {
5548
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath === "/" ? "/_root.data" : `${prerenderPath.replace(/\/$/, "")}.data`}`.replace(/\/\/+/g, "/");
5549
+ let url2 = new URL(`http://localhost${normalizedPath}`);
5550
+ if (onlyRoutes?.length) {
5551
+ url2.searchParams.set("_routes", onlyRoutes.join(","));
5552
+ }
5553
+ return {
5554
+ request: new Request(url2),
5555
+ metadata: { type: "data", path: prerenderPath, isResourceRoute }
5556
+ };
5557
+ }
5558
+ function createRouteRequest(prerenderPath, reactRouterConfig, data) {
5559
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(
5560
+ /\/\/+/g,
5561
+ "/"
5562
+ );
5563
+ let headers = new Headers();
5564
+ if (data) {
5565
+ let encodedData = encodeURI(data);
5566
+ if (encodedData.length < 8 * 1024) {
5567
+ headers.set("X-React-Router-Prerender-Data", encodedData);
5568
+ }
5569
+ }
5570
+ return {
5571
+ request: new Request(`http://localhost${normalizedPath}`, { headers }),
5572
+ metadata: { type: "html", path: prerenderPath }
5573
+ };
5574
+ }
5575
+ function createResourceRouteRequest(prerenderPath, reactRouterConfig, requestInit) {
5576
+ let normalizedPath = `${reactRouterConfig.basename}${prerenderPath}/`.replace(/\/\/+/g, "/").replace(/\/$/g, "");
5577
+ return {
5578
+ request: new Request(`http://localhost${normalizedPath}`, requestInit),
5579
+ metadata: { type: "resource", path: prerenderPath }
5580
+ };
5581
+ }
5582
+ function createSpaModeRequest(reactRouterConfig) {
5583
+ return {
5584
+ request: new Request(`http://localhost${reactRouterConfig.basename}`, {
5585
+ headers: {
5586
+ // Enable SPA mode in the server runtime and only render down to the root
5587
+ "X-React-Router-SPA-Mode": "yes"
5588
+ }
5589
+ }),
5590
+ metadata: { type: "spa", path: "/" }
5591
+ };
5592
+ }
5043
5593
 
5044
5594
  // vite/rsc/plugin.ts
5045
5595
  var import_es_module_lexer3 = require("es-module-lexer");
5046
5596
  var Path5 = __toESM(require("pathe"));
5047
5597
  var babel2 = __toESM(require("@babel/core"));
5048
5598
  var import_picocolors5 = __toESM(require("picocolors"));
5049
- var import_promises3 = require("fs/promises");
5599
+ var import_promises4 = require("fs/promises");
5050
5600
  var import_pathe6 = __toESM(require("pathe"));
5051
5601
 
5052
5602
  // vite/rsc/virtual-route-config.ts
@@ -5757,8 +6307,8 @@ ${errors.map((x) => ` - ${x}`).join("\n")}
5757
6307
  );
5758
6308
  return [
5759
6309
  "const exports = {}",
5760
- await (0, import_promises3.readFile)(reactRefreshRuntimePath, "utf8"),
5761
- await (0, import_promises3.readFile)(
6310
+ await (0, import_promises4.readFile)(reactRefreshRuntimePath, "utf8"),
6311
+ await (0, import_promises4.readFile)(
5762
6312
  require.resolve("./static/rsc-refresh-utils.mjs"),
5763
6313
  "utf8"
5764
6314
  ),
@@ -5820,7 +6370,7 @@ ${errors.map((x) => ` - ${x}`).join("\n")}
5820
6370
  const normalizedPath = import_pathe6.default.normalize(mod.file);
5821
6371
  const routeId = routeIdByFile?.get(normalizedPath);
5822
6372
  if (routeId !== void 0) {
5823
- const routeSource = await (0, import_promises3.readFile)(normalizedPath, "utf8");
6373
+ const routeSource = await (0, import_promises4.readFile)(normalizedPath, "utf8");
5824
6374
  const virtualRouteModuleCode = (await server.environments.rsc.pluginContainer.transform(
5825
6375
  routeSource,
5826
6376
  `${normalizedPath}?route-module`