@farm.js/core 0.1.0-beta.23 → 0.1.0-beta.24

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.
@@ -142,6 +142,7 @@ declare class RouteManager {
142
142
  shouldHydrate: boolean;
143
143
  isClientComponent: boolean;
144
144
  islandStrategy: FarmIslandStrategy | null;
145
+ suppressedAsyncHydration?: true;
145
146
  search?: ProgrammaticRouteSearchClientOptions;
146
147
  segments: Array<{
147
148
  segment: string;
@@ -142,6 +142,7 @@ declare class RouteManager {
142
142
  shouldHydrate: boolean;
143
143
  isClientComponent: boolean;
144
144
  islandStrategy: FarmIslandStrategy | null;
145
+ suppressedAsyncHydration?: true;
145
146
  search?: ProgrammaticRouteSearchClientOptions;
146
147
  segments: Array<{
147
148
  segment: string;
@@ -178,7 +178,7 @@ import {
178
178
  } from "./chunk-RHIFZZUI.mjs";
179
179
  import {
180
180
  FARM_VERSION
181
- } from "./chunk-5NOVWCFL.mjs";
181
+ } from "./chunk-WO466YX5.mjs";
182
182
  import {
183
183
  FARM_DEPLOYMENT_ID_HEADER,
184
184
  createFarmDeploymentCookie,
@@ -1114,6 +1114,37 @@ function stripUseClientDirective(content) {
1114
1114
  return content.replace(/^\s*(["'])use client\1\s*;?\s*/, "");
1115
1115
  }
1116
1116
  __name(stripUseClientDirective, "stripUseClientDirective");
1117
+ function hasAsyncDefaultExport(content) {
1118
+ if (!content) return false;
1119
+ const tokens = tokenizeModuleSource(content);
1120
+ for (let index = 0; index < tokens.length - 2; index++) {
1121
+ const token = tokens[index];
1122
+ if (token.kind !== "identifier" || token.value !== "export") continue;
1123
+ if (tokens[index - 1]?.value === ".") continue;
1124
+ if (tokens[index + 1]?.value !== "default") continue;
1125
+ const exported = tokens[index + 2];
1126
+ if (exported.kind === "identifier" && exported.value === "async") {
1127
+ return true;
1128
+ }
1129
+ if (exported.kind === "identifier" && !["function", "class"].includes(exported.value) && tokens[index + 3]?.value !== "(" && isAsyncLocalDeclaration(tokens, exported.value)) {
1130
+ return true;
1131
+ }
1132
+ }
1133
+ return false;
1134
+ }
1135
+ __name(hasAsyncDefaultExport, "hasAsyncDefaultExport");
1136
+ function isAsyncLocalDeclaration(tokens, name) {
1137
+ for (let index = 0; index < tokens.length - 2; index++) {
1138
+ if (tokens[index].value === "async" && tokens[index + 1]?.value === "function" && tokens[index + 2]?.value === name) {
1139
+ return true;
1140
+ }
1141
+ if (tokens[index].value === name && tokens[index + 1]?.value === "=" && tokens[index + 2]?.value === "async") {
1142
+ return true;
1143
+ }
1144
+ }
1145
+ return false;
1146
+ }
1147
+ __name(isAsyncLocalDeclaration, "isAsyncLocalDeclaration");
1117
1148
  function parseClientModuleMetadata(content, inspectIslandExport) {
1118
1149
  if (!content) {
1119
1150
  return {
@@ -1169,6 +1200,14 @@ function inspectClientModuleMetadata(resolvedPath, root, visited, inspectIslandE
1169
1200
  }
1170
1201
  }
1171
1202
  const shouldHydrate = parsed.hasHydrateExport || importsClientBoundary;
1203
+ if (shouldHydrate && hasAsyncDefaultExport(content)) {
1204
+ return {
1205
+ isClientComponent: false,
1206
+ shouldHydrate: false,
1207
+ islandStrategy: null,
1208
+ suppressedAsyncHydration: true
1209
+ };
1210
+ }
1172
1211
  return {
1173
1212
  isClientComponent: false,
1174
1213
  shouldHydrate,
@@ -1806,6 +1845,7 @@ var _RouteManager = class _RouteManager {
1806
1845
  shouldHydrate: metadata.shouldHydrate,
1807
1846
  isClientComponent: metadata.isClientComponent,
1808
1847
  islandStrategy: metadata.islandStrategy,
1848
+ suppressedAsyncHydration: metadata.suppressedAsyncHydration,
1809
1849
  search: getProgrammaticRouteSearchClientOptions(programmaticPage?.search),
1810
1850
  segments: entry.route.segments.map((seg) => ({
1811
1851
  segment: seg.segment,
@@ -3639,6 +3679,15 @@ __name(DefaultNotFoundPage, "DefaultNotFoundPage");
3639
3679
  // src/server/renderer.ts
3640
3680
  var cachedClerkProvider = null;
3641
3681
  var importRuntimeModule = new Function("specifier", "return import(specifier);");
3682
+ var warnedSuppressedAsyncHydrationModules = /* @__PURE__ */ new Set();
3683
+ function warnSuppressedAsyncHydrationOnce(modulePath) {
3684
+ if (warnedSuppressedAsyncHydrationModules.has(modulePath)) return;
3685
+ warnedSuppressedAsyncHydrationModules.add(modulePath);
3686
+ logger.warn(
3687
+ `${modulePath} is an async server component that imports client components. React cannot hydrate async components in the browser, so this route stays server-rendered and its client imports are not interactive. Move the interactive UI into a "use client" child rendered by a synchronous page, or enable experimental server components support.`
3688
+ );
3689
+ }
3690
+ __name(warnSuppressedAsyncHydrationOnce, "warnSuppressedAsyncHydrationOnce");
3642
3691
  function hasRequestHeader(req, name) {
3643
3692
  const value = req.headers[name.toLowerCase()];
3644
3693
  return Array.isArray(value) ? value.length > 0 : Boolean(value);
@@ -4313,6 +4362,9 @@ var _ServerRenderer = class _ServerRenderer {
4313
4362
  })
4314
4363
  );
4315
4364
  const shouldHydrate = moduleMetadata.shouldHydrate;
4365
+ if (moduleMetadata.suppressedAsyncHydration) {
4366
+ warnSuppressedAsyncHydrationOnce(route.modulePath);
4367
+ }
4316
4368
  const layoutHydrationMetadata = layouts.map((layout) => {
4317
4369
  const manifestEntry = routeManifest.layouts.find(
4318
4370
  (entry) => entry.pattern === layout.pattern
@@ -4810,7 +4862,7 @@ var _ServerRenderer = class _ServerRenderer {
4810
4862
  }
4811
4863
  }
4812
4864
  async renderWithSSR(element, req, res, clearMiddlewareData, options = {}) {
4813
- return new Promise((resolve5, reject) => {
4865
+ return new Promise((resolve6, reject) => {
4814
4866
  const streamStartTime = Date.now();
4815
4867
  const observabilityRoute = options.observabilityRoute || req.__FARM_ROUTE__ || req.url || "/";
4816
4868
  const deploymentId = this.getDeploymentId();
@@ -5010,7 +5062,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue(g
5010
5062
  route: observabilityRoute,
5011
5063
  durationMs: Date.now() - streamStartTime
5012
5064
  });
5013
- resolve5();
5065
+ resolve6();
5014
5066
  }
5015
5067
  });
5016
5068
  res.write(shell);
@@ -6029,12 +6081,40 @@ function collectLegacyTypeArtifacts(root, srcDir, stalePaths) {
6029
6081
  __name(collectLegacyTypeArtifacts, "collectLegacyTypeArtifacts");
6030
6082
 
6031
6083
  // src/vite.ts
6084
+ import * as fs5 from "fs";
6085
+ import * as path12 from "path";
6086
+
6087
+ // src/dev-static.ts
6032
6088
  import * as fs4 from "fs";
6033
- import * as path11 from "path";
6089
+ import * as path9 from "path";
6090
+ function devServableFileExists(pathname, baseDirs) {
6091
+ let decodedPathname;
6092
+ try {
6093
+ decodedPathname = decodeURIComponent(pathname);
6094
+ } catch {
6095
+ return false;
6096
+ }
6097
+ const relativePathname = decodedPathname.replace(/^\/+/, "");
6098
+ if (!relativePathname) return false;
6099
+ for (const baseDir of baseDirs) {
6100
+ if (typeof baseDir !== "string" || baseDir.length === 0) continue;
6101
+ const resolvedBase = path9.resolve(baseDir);
6102
+ const candidate = path9.resolve(resolvedBase, relativePathname);
6103
+ if (!candidate.startsWith(resolvedBase + path9.sep)) continue;
6104
+ try {
6105
+ if (fs4.existsSync(candidate) && fs4.statSync(candidate).isFile()) {
6106
+ return true;
6107
+ }
6108
+ } catch {
6109
+ }
6110
+ }
6111
+ return false;
6112
+ }
6113
+ __name(devServableFileExists, "devServableFileExists");
6034
6114
 
6035
6115
  // src/image-vite.ts
6036
6116
  import { readFile as readFile4 } from "fs/promises";
6037
- import path9 from "path";
6117
+ import path10 from "path";
6038
6118
  import { imageSize as imageSize2 } from "image-size";
6039
6119
  var FARM_IMAGE_ID_PREFIX = "\0farm:image:";
6040
6120
  var STATIC_IMAGE_RE = /\.(?:avif|gif|jpe?g|png|webp)$/i;
@@ -6102,7 +6182,7 @@ async function createBlurDataURL(bytes) {
6102
6182
  __name(createBlurDataURL, "createBlurDataURL");
6103
6183
 
6104
6184
  // src/server/vite-config.ts
6105
- import path10 from "path";
6185
+ import path11 from "path";
6106
6186
  var FARM_CLIENT_ENTRY_PATTERN = "**/{page,layout,loading,error,not-found,default}.{js,jsx,ts,tsx}";
6107
6187
  var FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE = [
6108
6188
  "react",
@@ -6120,9 +6200,9 @@ var FARM_CLIENT_OPTIMIZE_DEPS_INCLUDE = [
6120
6200
  "@farm.js/core/server-query/client"
6121
6201
  ];
6122
6202
  function createFarmClientOptimizeDepsEntries(projectRoot, appDirectories) {
6123
- const resolvedProjectRoot = path10.resolve(projectRoot);
6203
+ const resolvedProjectRoot = path11.resolve(projectRoot);
6124
6204
  return appDirectories.map((appDirectory) => {
6125
- const relativeAppDirectory = path10.relative(resolvedProjectRoot, path10.resolve(appDirectory)).replace(/\\/g, "/");
6205
+ const relativeAppDirectory = path11.relative(resolvedProjectRoot, path11.resolve(appDirectory)).replace(/\\/g, "/");
6126
6206
  const prefix = relativeAppDirectory || ".";
6127
6207
  return `${prefix}/${FARM_CLIENT_ENTRY_PATTERN}`;
6128
6208
  });
@@ -6146,7 +6226,7 @@ function createFarmClientOptimizeDepsConfig(entries) {
6146
6226
  __name(createFarmClientOptimizeDepsConfig, "createFarmClientOptimizeDepsConfig");
6147
6227
  function createFarmSourceAlias(projectRoot, srcDir = "src") {
6148
6228
  return {
6149
- "@": path10.resolve(projectRoot, srcDir)
6229
+ "@": path11.resolve(projectRoot, srcDir)
6150
6230
  };
6151
6231
  }
6152
6232
  __name(createFarmSourceAlias, "createFarmSourceAlias");
@@ -6454,11 +6534,11 @@ function isPotentialProgrammaticRouteSourceFile(normalizedFile, srcDirSlug) {
6454
6534
  }
6455
6535
  __name(isPotentialProgrammaticRouteSourceFile, "isPotentialProgrammaticRouteSourceFile");
6456
6536
  function fileContainsProgrammaticPageRoute(file) {
6457
- if (!fs4.existsSync(file)) {
6537
+ if (!fs5.existsSync(file)) {
6458
6538
  return false;
6459
6539
  }
6460
6540
  try {
6461
- return scanProgrammaticPagePaths(fs4.readFileSync(file, "utf8")).length > 0;
6541
+ return scanProgrammaticPagePaths(fs5.readFileSync(file, "utf8")).length > 0;
6462
6542
  } catch {
6463
6543
  return false;
6464
6544
  }
@@ -6466,7 +6546,7 @@ function fileContainsProgrammaticPageRoute(file) {
6466
6546
  __name(fileContainsProgrammaticPageRoute, "fileContainsProgrammaticPageRoute");
6467
6547
  function rewriteEarlySsrRelativeImports(options) {
6468
6548
  const cleanId = options.id.split("?", 1)[0];
6469
- if (!path11.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
6549
+ if (!path12.isAbsolute(cleanId) || cleanId.replace(/\\/g, "/").includes("/node_modules/")) {
6470
6550
  return null;
6471
6551
  }
6472
6552
  const replacements = [];
@@ -6486,7 +6566,7 @@ function rewriteEarlySsrRelativeImports(options) {
6486
6566
  const suffixIndex = source.value.search(/[?#]/);
6487
6567
  const sourcePath = suffixIndex === -1 ? source.value : source.value.slice(0, suffixIndex);
6488
6568
  const suffix = suffixIndex === -1 ? "" : source.value.slice(suffixIndex);
6489
- const resolvedPath = path11.resolve(path11.dirname(cleanId), sourcePath);
6569
+ const resolvedPath = path12.resolve(path12.dirname(cleanId), sourcePath);
6490
6570
  replacements.push({
6491
6571
  start: source.start,
6492
6572
  end: source.end,
@@ -6565,7 +6645,7 @@ function farmPlugin(options = {}, initialPluginManager) {
6565
6645
  ...layerRoots.length ? {
6566
6646
  server: {
6567
6647
  fs: {
6568
- allow: [path11.resolve(options.root || process.cwd()), ...layerRoots]
6648
+ allow: [path12.resolve(options.root || process.cwd()), ...layerRoots]
6569
6649
  }
6570
6650
  }
6571
6651
  } : {}
@@ -6596,13 +6676,13 @@ function farmPlugin(options = {}, initialPluginManager) {
6596
6676
  },
6597
6677
  server
6598
6678
  );
6599
- const globalsCSSPath = path11.join(server.config.root, "src/app/globals.css");
6600
- if (!fs4.existsSync(globalsCSSPath)) {
6601
- const appDir = path11.join(server.config.root, "src/app");
6602
- if (!fs4.existsSync(appDir)) {
6603
- fs4.mkdirSync(appDir, { recursive: true });
6679
+ const globalsCSSPath = path12.join(server.config.root, "src/app/globals.css");
6680
+ if (!fs5.existsSync(globalsCSSPath)) {
6681
+ const appDir = path12.join(server.config.root, "src/app");
6682
+ if (!fs5.existsSync(appDir)) {
6683
+ fs5.mkdirSync(appDir, { recursive: true });
6604
6684
  }
6605
- fs4.writeFileSync(globalsCSSPath, defaultGlobalCSS);
6685
+ fs5.writeFileSync(globalsCSSPath, defaultGlobalCSS);
6606
6686
  }
6607
6687
  await farmApp.initialize();
6608
6688
  const farmConfig = farmApp.getConfig();
@@ -6621,10 +6701,10 @@ function farmPlugin(options = {}, initialPluginManager) {
6621
6701
  });
6622
6702
  }
6623
6703
  const sourceRoots = getFarmSourceRoots(farmConfig);
6624
- server.watcher.add(sourceRoots.map((source) => path11.join(source.root, source.srcDir)));
6704
+ server.watcher.add(sourceRoots.map((source) => path12.join(source.root, source.srcDir)));
6625
6705
  if (farmConfig.i18n.enabled) {
6626
6706
  server.watcher.add(
6627
- farmConfig.i18n.messages.includes("{locale}") ? path11.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
6707
+ farmConfig.i18n.messages.includes("{locale}") ? path12.dirname(farmConfig.i18n.messages) : farmConfig.i18n.messages
6628
6708
  );
6629
6709
  }
6630
6710
  const workflowConfig = farmConfig.workflows;
@@ -6634,7 +6714,7 @@ function farmPlugin(options = {}, initialPluginManager) {
6634
6714
  ...farmDocsDevRuntime?.getFarmDocsRouteTypeEntries(farmConfig.docs) ?? []
6635
6715
  ], "getExtraRouteTypes");
6636
6716
  const appDirSlugs = sourceRoots.map(
6637
- (source) => path11.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
6717
+ (source) => path12.join(source.root, source.srcDir, "app").replace(/\\/g, "/")
6638
6718
  );
6639
6719
  const generateTypeArtifacts = /* @__PURE__ */ __name(async (reason, selection = ALL_TYPE_ARTIFACTS, log = false) => {
6640
6720
  try {
@@ -6674,7 +6754,7 @@ function farmPlugin(options = {}, initialPluginManager) {
6674
6754
  }, "generateTypeArtifacts");
6675
6755
  await generateTypeArtifacts("startup");
6676
6756
  const srcDirSlugs = sourceRoots.map(
6677
- (source) => path11.join(source.root, source.srcDir).replace(/\\/g, "/")
6757
+ (source) => path12.join(source.root, source.srcDir).replace(/\\/g, "/")
6678
6758
  );
6679
6759
  const layerConfigFiles = new Set(
6680
6760
  farmConfig.layers.map((layer) => layer.configFile?.replace(/\\/g, "/")).filter((file) => Boolean(file))
@@ -6792,7 +6872,7 @@ function farmPlugin(options = {}, initialPluginManager) {
6792
6872
  await apiRouteManager.discoverRoutes();
6793
6873
  let discoveredWorkflows = [];
6794
6874
  const hasWorkflowDirectory = workflowConfig.enabled && workflowConfig.dirs.some(
6795
- (dir) => fs4.existsSync(path11.isAbsolute(dir) ? dir : path11.join(farmConfig.root, dir))
6875
+ (dir) => fs5.existsSync(path12.isAbsolute(dir) ? dir : path12.join(farmConfig.root, dir))
6796
6876
  );
6797
6877
  if (hasWorkflowDirectory) {
6798
6878
  const { createFarmWorkflowRequestHandler, discoverFarmWorkflows } = await loadFarmWorkflowsDevRuntime();
@@ -7026,12 +7106,12 @@ window.__FARM_MANIFEST__ = ${inlineValue({
7026
7106
  }
7027
7107
  }
7028
7108
  const farmDocsFontPath = farmDocsFontAssets.get(requestPathname);
7029
- if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs4.existsSync(farmDocsFontPath)) {
7109
+ if ((requestMethod === "GET" || requestMethod === "HEAD") && farmDocsFontPath && fs5.existsSync(farmDocsFontPath)) {
7030
7110
  res.statusCode = 200;
7031
7111
  res.setHeader("Content-Type", "font/woff2");
7032
7112
  res.setHeader("Cache-Control", "public, max-age=31536000, immutable");
7033
7113
  if (requestMethod === "HEAD") res.end();
7034
- else fs4.createReadStream(farmDocsFontPath).pipe(res);
7114
+ else fs5.createReadStream(farmDocsFontPath).pipe(res);
7035
7115
  return;
7036
7116
  }
7037
7117
  if (requestMethod === "GET" && (requestPathname === FARM_DEVTOOLS_PATH || requestPathname === `${FARM_DEVTOOLS_PATH}.json`)) {
@@ -7129,7 +7209,7 @@ window.__FARM_MANIFEST__ = ${inlineValue({
7129
7209
  return null;
7130
7210
  }
7131
7211
  return {
7132
- source: await fs4.promises.readFile(sourcePath, "utf8"),
7212
+ source: await fs5.promises.readFile(sourcePath, "utf8"),
7133
7213
  filePath: sourcePath
7134
7214
  };
7135
7215
  }, "resolveSource")
@@ -7464,9 +7544,17 @@ window.__FARM_MANIFEST__ = ${inlineValue({
7464
7544
  res.end(JSON.stringify({ error: "API route not found", pathname: pathname2 }));
7465
7545
  return;
7466
7546
  }
7467
- if (req.url?.startsWith("/@") || req.url?.startsWith("/node_modules") || requestPathname.includes(".") && !requestPathname.endsWith(".html")) {
7547
+ if (req.url?.startsWith("/@") || req.url?.startsWith("/node_modules")) {
7468
7548
  return next();
7469
7549
  }
7550
+ if (requestPathname.includes(".") && !requestPathname.endsWith(".html")) {
7551
+ const matchesAppRoute = Boolean(
7552
+ farmApp?.getRouteManager()?.matchRoute(requestPathname)?.route
7553
+ );
7554
+ if (!matchesAppRoute || devServableFileExists(requestPathname, [server.config.publicDir, server.config.root])) {
7555
+ return next();
7556
+ }
7557
+ }
7470
7558
  if (req.url?.startsWith("/__farm/page-data")) {
7471
7559
  const urlObj = new URL(req.url, `http://${req.headers.host || "localhost:3000"}`);
7472
7560
  const targetPath = urlObj.searchParams.get("path") || "/";
@@ -8172,8 +8260,8 @@ if (import.meta.hot) {
8172
8260
  }
8173
8261
  logger.info(`Found ${ssgPages.length} SSG pages, ${ssrRoutes.length} SSR routes`);
8174
8262
  logger.info("Pre-rendering SSG pages...");
8175
- const outDir = path11.join(server?.config.root || process.cwd(), options.outDir || "dist");
8176
- const clientDir = path11.join(outDir, "client");
8263
+ const outDir = path12.join(server?.config.root || process.cwd(), options.outDir || "dist");
8264
+ const clientDir = path12.join(outDir, "client");
8177
8265
  for (const page of ssgPages) {
8178
8266
  try {
8179
8267
  const staticRequest = new Request(new URL(page.urlPath, "http://farm.static"));
@@ -8225,9 +8313,9 @@ if (import.meta.hot) {
8225
8313
  <script type="module" src="/assets/client.js"></script>
8226
8314
  </body>
8227
8315
  </html>`;
8228
- const outputPath = page.urlPath === "/" ? path11.join(clientDir, "index.html") : path11.join(clientDir, page.urlPath + ".html");
8229
- fs4.mkdirSync(path11.dirname(outputPath), { recursive: true });
8230
- fs4.writeFileSync(outputPath, fullHtml);
8316
+ const outputPath = page.urlPath === "/" ? path12.join(clientDir, "index.html") : path12.join(clientDir, page.urlPath + ".html");
8317
+ fs5.mkdirSync(path12.dirname(outputPath), { recursive: true });
8318
+ fs5.writeFileSync(outputPath, fullHtml);
8231
8319
  const revalidateInfo = page.revalidate ? ` (revalidate: ${page.revalidate}s)` : "";
8232
8320
  logger.success(` \u2713 ${page.urlPath}${revalidateInfo}`);
8233
8321
  });
@@ -8235,8 +8323,8 @@ if (import.meta.hot) {
8235
8323
  logger.error(` \u2717 ${page.urlPath}: ${error}`);
8236
8324
  }
8237
8325
  }
8238
- const manifestPath = path11.join(outDir, "__ssg_manifest.json");
8239
- fs4.writeFileSync(
8326
+ const manifestPath = path12.join(outDir, "__ssg_manifest.json");
8327
+ fs5.writeFileSync(
8240
8328
  manifestPath,
8241
8329
  JSON.stringify(
8242
8330
  ssgPages.map((p) => ({
@@ -8271,9 +8359,9 @@ if (import.meta.hot) {
8271
8359
  }
8272
8360
  const currentFarmConfig = farmApp?.getConfig();
8273
8361
  const normalizedFile = file.replace(/\\/g, "/");
8274
- const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path11.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
8362
+ const currentSrcRoot = currentFarmConfig ? getFarmSourceRoots(currentFarmConfig).map((source) => path12.join(source.root, source.srcDir).replace(/\\/g, "/")).find((sourceRoot) => normalizedFile.startsWith(`${sourceRoot}/`)) || null : null;
8275
8363
  if (currentSrcRoot && normalizedFile.startsWith(`${currentSrcRoot}/`) && isProgrammaticRoutesFileName(normalizedFile)) {
8276
- logUpdate("PAGE", `updated ${path11.basename(file)}`);
8364
+ logUpdate("PAGE", `updated ${path12.basename(file)}`);
8277
8365
  for (const mod of modules) {
8278
8366
  server2.moduleGraph.invalidateModule(mod);
8279
8367
  }
@@ -9459,6 +9547,19 @@ async function tryHydrateImportedPage(
9459
9547
  const PageComponent = pageModule?.default;
9460
9548
  if (!PageComponent) return false;
9461
9549
 
9550
+ if (
9551
+ typeof PageComponent === 'function' &&
9552
+ PageComponent.constructor &&
9553
+ PageComponent.constructor.name === 'AsyncFunction'
9554
+ ) {
9555
+ console.warn(
9556
+ '[Farm.js] Skipping hydration for ' + modulePath +
9557
+ ': async server components cannot run in the browser. ' +
9558
+ 'Server-rendered HTML is preserved; move interactive UI into a "use client" child of a synchronous page.'
9559
+ );
9560
+ return false;
9561
+ }
9562
+
9462
9563
  currentPageComponent = PageComponent;
9463
9564
  currentPageProps = await buildRouteComponentProps(
9464
9565
  pageModule,
@@ -10012,7 +10113,7 @@ function generateClientManifest(bundle) {
10012
10113
  __name(generateClientManifest, "generateClientManifest");
10013
10114
  async function defineConfig(config = {}) {
10014
10115
  const tailwindcss = (await import("@tailwindcss/vite")).default;
10015
- const appRoot = path11.resolve(config.root || process.cwd());
10116
+ const appRoot = path12.resolve(config.root || process.cwd());
10016
10117
  if (config.extends?.length) {
10017
10118
  const { config: layeredConfig } = await import("./layers-VWVDTPUZ.mjs").then(
10018
10119
  ({ resolveFarmLayers }) => resolveFarmLayers(config, {
@@ -10257,4 +10358,4 @@ export {
10257
10358
  farmPlugin,
10258
10359
  defineConfig
10259
10360
  };
10260
- //# sourceMappingURL=chunk-TX54PXAJ.mjs.map
10361
+ //# sourceMappingURL=chunk-HVJHNKSP.mjs.map