@farm.js/core 0.1.0-beta.45 → 0.1.0-beta.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/api/route-manager.cjs.map +1 -1
  2. package/dist/api/route-manager.mjs +2 -2
  3. package/dist/api.cjs.map +1 -1
  4. package/dist/api.mjs +3 -3
  5. package/dist/{chunk-EPBXX44K.mjs → chunk-3UUEBVR3.mjs} +3 -3
  6. package/dist/{chunk-IRYMQRYJ.mjs → chunk-ECLWCE4H.mjs} +2 -2
  7. package/dist/{chunk-IWPBMZGE.mjs → chunk-IHYFDXKQ.mjs} +4 -4
  8. package/dist/{chunk-FLGRRGVU.mjs → chunk-KTV3UWGE.mjs} +2 -2
  9. package/dist/{chunk-FLGRRGVU.mjs.map → chunk-KTV3UWGE.mjs.map} +1 -1
  10. package/dist/{chunk-MU2QKVYL.mjs → chunk-MP2SDRRB.mjs} +2 -2
  11. package/dist/{chunk-6NCLVPI7.mjs → chunk-MWYVMV3T.mjs} +124 -15
  12. package/dist/chunk-MWYVMV3T.mjs.map +1 -0
  13. package/dist/{chunk-QLCUQD3U.mjs → chunk-SHZF3DEB.mjs} +2 -2
  14. package/dist/{chunk-VHYARVB7.mjs → chunk-TIESOJ7Z.mjs} +2 -2
  15. package/dist/{chunk-KEPCW6EI.mjs → chunk-U5SPS2HR.mjs} +10 -1
  16. package/dist/chunk-U5SPS2HR.mjs.map +1 -0
  17. package/dist/client/lifecycle.mjs +2 -2
  18. package/dist/client-plugins.cjs +1 -1
  19. package/dist/client-plugins.cjs.map +1 -1
  20. package/dist/client-plugins.mjs +2 -2
  21. package/dist/client.cjs +1 -1
  22. package/dist/client.cjs.map +1 -1
  23. package/dist/client.mjs +2 -2
  24. package/dist/index.cjs +134 -12
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.mts +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.mjs +11 -9
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/internal/build-runtime.cjs +132 -12
  31. package/dist/internal/build-runtime.cjs.map +1 -1
  32. package/dist/internal/build-runtime.d.mts +1 -1
  33. package/dist/internal/build-runtime.d.ts +1 -1
  34. package/dist/internal/build-runtime.mjs +6 -6
  35. package/dist/internal/client-runtime.cjs +1 -1
  36. package/dist/internal/client-runtime.cjs.map +1 -1
  37. package/dist/internal/client-runtime.mjs +2 -2
  38. package/dist/internal/config-runtime.cjs.map +1 -1
  39. package/dist/internal/config-runtime.d.mts +1 -1
  40. package/dist/internal/config-runtime.d.ts +1 -1
  41. package/dist/internal/config-runtime.mjs +1 -1
  42. package/dist/middleware.cjs.map +1 -1
  43. package/dist/middleware.mjs +3 -3
  44. package/dist/plugin.cjs +127 -11
  45. package/dist/plugin.cjs.map +1 -1
  46. package/dist/plugin.mjs +5 -5
  47. package/dist/server.cjs +129 -11
  48. package/dist/server.cjs.map +1 -1
  49. package/dist/server.d.mts +1 -1
  50. package/dist/server.d.ts +1 -1
  51. package/dist/server.mjs +7 -5
  52. package/dist/server.mjs.map +1 -1
  53. package/dist/testing.mjs +2 -2
  54. package/dist/{utils-CjZRiq-l.d.mts → utils-9OPxcT1T.d.mts} +9 -1
  55. package/dist/{utils-_LOF-V9f.d.ts → utils-CIIoLfn9.d.ts} +9 -1
  56. package/dist/version.cjs +1 -1
  57. package/dist/version.cjs.map +1 -1
  58. package/dist/version.mjs +1 -1
  59. package/dist/vite.cjs +127 -11
  60. package/dist/vite.cjs.map +1 -1
  61. package/dist/vite.mjs +5 -5
  62. package/package.json +3 -3
  63. package/dist/chunk-6NCLVPI7.mjs.map +0 -1
  64. package/dist/chunk-KEPCW6EI.mjs.map +0 -1
  65. /package/dist/{chunk-EPBXX44K.mjs.map → chunk-3UUEBVR3.mjs.map} +0 -0
  66. /package/dist/{chunk-IRYMQRYJ.mjs.map → chunk-ECLWCE4H.mjs.map} +0 -0
  67. /package/dist/{chunk-IWPBMZGE.mjs.map → chunk-IHYFDXKQ.mjs.map} +0 -0
  68. /package/dist/{chunk-MU2QKVYL.mjs.map → chunk-MP2SDRRB.mjs.map} +0 -0
  69. /package/dist/{chunk-QLCUQD3U.mjs.map → chunk-SHZF3DEB.mjs.map} +0 -0
  70. /package/dist/{chunk-VHYARVB7.mjs.map → chunk-TIESOJ7Z.mjs.map} +0 -0
package/dist/vite.cjs CHANGED
@@ -13193,6 +13193,14 @@ function resolveAppPath(root, ...paths) {
13193
13193
  return import_path.default.resolve(root, ...paths);
13194
13194
  }
13195
13195
  __name(resolveAppPath, "resolveAppPath");
13196
+ function toRootRelativeUrlPath(absolutePath, projectRoot) {
13197
+ if (absolutePath === projectRoot) return "";
13198
+ if (absolutePath.startsWith(`${projectRoot}/`) || absolutePath.startsWith(`${projectRoot}\\`)) {
13199
+ return absolutePath.slice(projectRoot.length).replace(/\\/g, "/");
13200
+ }
13201
+ return void 0;
13202
+ }
13203
+ __name(toRootRelativeUrlPath, "toRootRelativeUrlPath");
13196
13204
  function toViteModuleId(filePath, root) {
13197
13205
  if (!import_path.default.isAbsolute(filePath)) return filePath;
13198
13206
  const relativePath2 = import_path.default.relative(root, filePath);
@@ -15342,9 +15350,8 @@ var _RouteManager = class _RouteManager {
15342
15350
  return this.clientManifestCache.manifest;
15343
15351
  }
15344
15352
  const toUrlPath = /* @__PURE__ */ __name((absolutePath) => {
15345
- if (absolutePath === normalizedProjectRoot || absolutePath.startsWith(`${normalizedProjectRoot}${import_path5.default.sep}`)) {
15346
- return absolutePath.slice(normalizedProjectRoot.length);
15347
- }
15353
+ const rootRelative = toRootRelativeUrlPath(absolutePath, normalizedProjectRoot);
15354
+ if (rootRelative !== void 0) return rootRelative;
15348
15355
  if (import_path5.default.isAbsolute(absolutePath)) {
15349
15356
  const normalized = absolutePath.replace(/\\/g, "/");
15350
15357
  return normalized.startsWith("/") ? `/@fs${normalized}` : `/@fs/${normalized}`;
@@ -16040,6 +16047,57 @@ __name(safeGlobFiles, "safeGlobFiles");
16040
16047
  // src/server/renderer.ts
16041
16048
  var fs3 = __toESM(require("fs"));
16042
16049
  var path11 = __toESM(require("path"));
16050
+
16051
+ // src/server/full-document.ts
16052
+ function stripContentsWrappers(markup) {
16053
+ let out = markup.replace(/^\s+/, "");
16054
+ const opener = /^<div\b[^>]*style="display\s*:\s*contents"[^>]*>/i;
16055
+ let match;
16056
+ while (match = opener.exec(out)) {
16057
+ out = out.slice(match[0].length).replace(/^\s+/, "");
16058
+ }
16059
+ return out;
16060
+ }
16061
+ __name(stripContentsWrappers, "stripContentsWrappers");
16062
+ function extractFarmFullDocument(markup) {
16063
+ const inner = stripContentsWrappers(markup);
16064
+ if (!/^<!doctype/i.test(inner) && !/^<html[\s>]/i.test(inner)) return null;
16065
+ const start = markup.search(/<!doctype|<html[\s>]/i);
16066
+ const closeIndex = markup.toLowerCase().lastIndexOf("</html>");
16067
+ if (start < 0 || closeIndex < 0) return null;
16068
+ return markup.slice(start, closeIndex + "</html>".length);
16069
+ }
16070
+ __name(extractFarmFullDocument, "extractFarmFullDocument");
16071
+ function opensFarmFullDocument(markup) {
16072
+ const inner = stripContentsWrappers(markup);
16073
+ return /^<!doctype/i.test(inner) || /^<html[\s>]/i.test(inner);
16074
+ }
16075
+ __name(opensFarmFullDocument, "opensFarmFullDocument");
16076
+ function composeFarmFullDocument(documentHtml, assets) {
16077
+ let html = documentHtml;
16078
+ if (assets.htmlAttributes) {
16079
+ html = html.replace(
16080
+ /<html\b([^>]*)>/i,
16081
+ (_match, attrs) => `<html${attrs}${assets.htmlAttributes}>`
16082
+ );
16083
+ }
16084
+ if (!/\sid=["']root["']/i.test(html)) {
16085
+ html = html.replace(/<body\b([^>]*)>/i, '<body$1><div id="root">').replace(/<\/body>/i, "</div></body>");
16086
+ }
16087
+ if (assets.headAssets) {
16088
+ html = html.replace(/<\/head>/i, () => ` ${assets.headAssets}
16089
+ </head>`);
16090
+ }
16091
+ if (assets.bodyFooter) {
16092
+ html = html.replace(/<\/body>/i, () => ` ${assets.bodyFooter}
16093
+ </body>`);
16094
+ }
16095
+ return /^\s*<!doctype/i.test(html) ? html : `<!DOCTYPE html>
16096
+ ${html}`;
16097
+ }
16098
+ __name(composeFarmFullDocument, "composeFarmFullDocument");
16099
+
16100
+ // src/server/renderer.ts
16043
16101
  var import_stream = require("stream");
16044
16102
 
16045
16103
  // src/middleware/server.ts
@@ -19390,7 +19448,7 @@ _setFarmThemeServerSnapshotResolver(() => {
19390
19448
  });
19391
19449
 
19392
19450
  // package.json
19393
- var version = "0.1.0-beta.45";
19451
+ var version = "0.1.0-beta.47";
19394
19452
 
19395
19453
  // src/version.ts
19396
19454
  var FARM_VERSION = version;
@@ -19499,6 +19557,16 @@ function warnSuppressedAsyncHydrationOnce(modulePath) {
19499
19557
  );
19500
19558
  }
19501
19559
  __name(warnSuppressedAsyncHydrationOnce, "warnSuppressedAsyncHydrationOnce");
19560
+ var fullDocumentRoutes = /* @__PURE__ */ new Set();
19561
+ var warnedFullDocumentLayout = false;
19562
+ function warnFarmFullDocumentLayout() {
19563
+ if (warnedFullDocumentLayout) return;
19564
+ warnedFullDocumentLayout = true;
19565
+ logger.warn(
19566
+ `A root layout returned a full <html> document. Farm.js owns the document shell, so a layout should return a fragment (its children) \u2014 like the docs example \u2014 and let the framework provide <html>/<head>/<body>. The document has been composed into the response, but returning a fragment avoids the ambiguity and keeps dev and production identical.`
19567
+ );
19568
+ }
19569
+ __name(warnFarmFullDocumentLayout, "warnFarmFullDocumentLayout");
19502
19570
  function hasRequestHeader(req, name2) {
19503
19571
  const value = req.headers[name2.toLowerCase()];
19504
19572
  return Array.isArray(value) ? value.length > 0 : Boolean(value);
@@ -20334,7 +20402,7 @@ var _ServerRenderer = class _ServerRenderer {
20334
20402
  );
20335
20403
  const clientLayouts = layouts.map((layout2, index) => ({
20336
20404
  pattern: layout2.pattern,
20337
- modulePath: layout2.modulePath.startsWith(this.config.root) ? layout2.modulePath.slice(this.config.root.length) : layout2.modulePath,
20405
+ modulePath: toRootRelativeUrlPath(layout2.modulePath, this.config.root) ?? layout2.modulePath,
20338
20406
  shouldHydrate: layoutHydrationMetadata[index]?.shouldHydrate === true,
20339
20407
  islandStrategy: layoutHydrationMetadata[index]?.islandStrategy ?? null
20340
20408
  }));
@@ -20910,7 +20978,7 @@ var _ServerRenderer = class _ServerRenderer {
20910
20978
  const routeSlots = (req.__FARM_ROUTE_SLOTS__ || []).map(
20911
20979
  (slot) => ({
20912
20980
  ...slot,
20913
- modulePath: typeof slot.modulePath === "string" && slot.modulePath.startsWith(this.config.root) ? slot.modulePath.slice(this.config.root.length) : slot.modulePath
20981
+ modulePath: typeof slot.modulePath === "string" ? toRootRelativeUrlPath(slot.modulePath, this.config.root) ?? slot.modulePath : slot.modulePath
20914
20982
  })
20915
20983
  );
20916
20984
  const deferredProps = prepareDeferredData({
@@ -20918,7 +20986,7 @@ var _ServerRenderer = class _ServerRenderer {
20918
20986
  slots: routeSlots
20919
20987
  });
20920
20988
  const pagePath = req.__FARM_PAGE_PATH__;
20921
- const relativePath2 = pagePath ? pagePath.startsWith(this.config.root) ? pagePath.slice(this.config.root.length) : pagePath : "/src/app/page.tsx";
20989
+ const relativePath2 = pagePath ? toRootRelativeUrlPath(pagePath, this.config.root) ?? pagePath : "/src/app/page.tsx";
20922
20990
  const deploymentId = this.getDeploymentId();
20923
20991
  const bootstrapScript = `<script>
20924
20992
  window.__FARM_PROPS__ = ${serializeInlineValue2(deferredProps.data.page)};
@@ -20952,7 +21020,27 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20952
21020
  this.config.basePath,
20953
21021
  getTheme()
20954
21022
  );
20955
- const html = `<!DOCTYPE html>
21023
+ const fullDocument = extractFarmFullDocument(content);
21024
+ let html;
21025
+ if (fullDocument) {
21026
+ warnFarmFullDocumentLayout();
21027
+ html = composeFarmFullDocument(fullDocument, {
21028
+ htmlAttributes: `${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}`,
21029
+ headAssets: [
21030
+ themeDocument.head,
21031
+ `<meta name="farm-deployment-id" content="${escapeHtmlAttribute2(deploymentId)}">`,
21032
+ metaTags,
21033
+ alternateTags,
21034
+ renderFarmFontDevHead(this.config.root || process.cwd()),
21035
+ `<link rel="stylesheet" href="/src/app/globals.css">`,
21036
+ `<script type="module" src="/@vite/client"></script>`,
21037
+ rendererHydrationScript,
21038
+ bootstrapScript
21039
+ ].filter(Boolean).join("\n "),
21040
+ bodyFooter: [deferredScript, `<script type="module" src="/@farm/client.js"></script>`].filter(Boolean).join("\n ")
21041
+ });
21042
+ } else {
21043
+ html = `<!DOCTYPE html>
20956
21044
  <html lang="${escapeHtmlAttribute2(i18nSnapshot?.locale || "en")}"${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}>
20957
21045
  <head>
20958
21046
  ${themeDocument.head}
@@ -20973,6 +21061,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20973
21061
  <script type="module" src="/@farm/client.js"></script>
20974
21062
  </body>
20975
21063
  </html>`;
21064
+ }
20976
21065
  emitFarmEvent({
20977
21066
  type: "render.stream.shellReady",
20978
21067
  route,
@@ -20995,7 +21084,8 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20995
21084
  }
20996
21085
  async renderWithSSR(element, req, res, clearMiddlewareData, options = {}) {
20997
21086
  const renderToPipeableStream2 = this.rendererRuntime.renderToPipeableStream;
20998
- if (!renderToPipeableStream2) {
21087
+ const fullDocumentRouteKey = options.observabilityRoute || req.__FARM_ROUTE__ || req.url || "/";
21088
+ if (!renderToPipeableStream2 || fullDocumentRoutes.has(fullDocumentRouteKey)) {
20999
21089
  return this.renderBufferedSSR(element, req, res, clearMiddlewareData, options);
21000
21090
  }
21001
21091
  return new Promise((resolve8, reject) => {
@@ -21014,7 +21104,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
21014
21104
  let didError = false;
21015
21105
  const pagePath = req.__FARM_PAGE_PATH__;
21016
21106
  const isClientComponent = req.__FARM_IS_CLIENT_COMPONENT__ === true;
21017
- const relativePath2 = pagePath ? pagePath.startsWith(this.config.root) ? pagePath.slice(this.config.root.length) : pagePath : "/src/app/page.tsx";
21107
+ const relativePath2 = pagePath ? toRootRelativeUrlPath(pagePath, this.config.root) ?? pagePath : "/src/app/page.tsx";
21018
21108
  const manifest = options.routeManifest ?? this.routeManager.generateClientManifest(this.config.root);
21019
21109
  const clientManifest = {
21020
21110
  clientEntry: "/@farm/client.js",
@@ -21062,7 +21152,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
21062
21152
  const routeSlotPayload = (req.__FARM_ROUTE_SLOTS__ || []).map(
21063
21153
  (slot) => ({
21064
21154
  ...slot,
21065
- modulePath: typeof slot.modulePath === "string" && slot.modulePath.startsWith(this.config.root) ? slot.modulePath.slice(this.config.root.length) : slot.modulePath
21155
+ modulePath: typeof slot.modulePath === "string" ? toRootRelativeUrlPath(slot.modulePath, this.config.root) ?? slot.modulePath : slot.modulePath
21066
21156
  })
21067
21157
  );
21068
21158
  const deferredProps = prepareDeferredData({
@@ -21142,6 +21232,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
21142
21232
  htmlParts.push(shell);
21143
21233
  staticShellParts?.push(shell);
21144
21234
  let firstChunk = true;
21235
+ let checkedFullDocument = false;
21145
21236
  const writableStream = new import_stream.Writable({
21146
21237
  write(chunk, encoding, callback) {
21147
21238
  if (firstChunk && process.env.FARM_VERBOSE) {
@@ -21149,6 +21240,13 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
21149
21240
  firstChunk = false;
21150
21241
  }
21151
21242
  const chunkText = Buffer.isBuffer(chunk) ? chunk.toString() : String(chunk);
21243
+ if (!checkedFullDocument) {
21244
+ checkedFullDocument = true;
21245
+ if (opensFarmFullDocument(chunkText)) {
21246
+ fullDocumentRoutes.add(fullDocumentRouteKey);
21247
+ warnFarmFullDocumentLayout();
21248
+ }
21249
+ }
21152
21250
  htmlParts.push(chunkText);
21153
21251
  if (staticShellParts && !staticShellClosed) {
21154
21252
  const dynamicIndex = findPPRDynamicChunkIndex(chunkText);
@@ -21347,6 +21445,24 @@ ${i18nSnapshot ? `window.__FARM_I18N__ = ${serializeInlineValue2(i18nSnapshot)};
21347
21445
  getTheme()
21348
21446
  );
21349
21447
  const rendererHydrationScript = this.rendererRuntime.generateHydrationScript?.() || "";
21448
+ const fullDocument = extractFarmFullDocument(content);
21449
+ if (fullDocument) {
21450
+ warnFarmFullDocumentLayout();
21451
+ return composeFarmFullDocument(fullDocument, {
21452
+ htmlAttributes: `${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}`,
21453
+ headAssets: [
21454
+ themeDocument.head,
21455
+ `<meta name="farm-deployment-id" content="${escapeHtmlAttribute2(this.getDeploymentId())}">`,
21456
+ alternateLinks,
21457
+ fontHead,
21458
+ `<link rel="stylesheet" href="/src/app/globals.css" />`,
21459
+ `<script type="module" src="/@vite/client"></script>`,
21460
+ rendererHydrationScript,
21461
+ integrationManifestScript
21462
+ ].filter(Boolean).join("\n "),
21463
+ bodyFooter: clientScript.trim()
21464
+ });
21465
+ }
21350
21466
  return `<!DOCTYPE html>
21351
21467
  <html lang="${escapeHtmlAttribute2(i18nSnapshot?.locale || "en")}"${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}>
21352
21468
  <head>