@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
@@ -7,7 +7,7 @@ import {
7
7
  memoryRateLimitStorage,
8
8
  middleware,
9
9
  unwrapMiddleware
10
- } from "./chunk-IRYMQRYJ.mjs";
10
+ } from "./chunk-ECLWCE4H.mjs";
11
11
  import {
12
12
  applyProductionMiddlewareHeaders,
13
13
  createProductionMiddlewareRunner
@@ -15,7 +15,7 @@ import {
15
15
  import {
16
16
  MiddlewareManager,
17
17
  createContext
18
- } from "./chunk-VHYARVB7.mjs";
18
+ } from "./chunk-TIESOJ7Z.mjs";
19
19
  import {
20
20
  _runWithMiddlewareContext,
21
21
  _runWithMiddlewareData,
@@ -24,7 +24,7 @@ import {
24
24
  getMiddlewareValue
25
25
  } from "./chunk-P7QDS5AT.mjs";
26
26
  import "./chunk-GIELMNBG.mjs";
27
- import "./chunk-KEPCW6EI.mjs";
27
+ import "./chunk-U5SPS2HR.mjs";
28
28
  import "./chunk-QGOHVJ6J.mjs";
29
29
  import "./chunk-RHIFZZUI.mjs";
30
30
  import "./chunk-LM2YNO4U.mjs";
package/dist/plugin.cjs CHANGED
@@ -12766,6 +12766,14 @@ function resolveAppPath(root, ...paths) {
12766
12766
  return import_path.default.resolve(root, ...paths);
12767
12767
  }
12768
12768
  __name(resolveAppPath, "resolveAppPath");
12769
+ function toRootRelativeUrlPath(absolutePath, projectRoot) {
12770
+ if (absolutePath === projectRoot) return "";
12771
+ if (absolutePath.startsWith(`${projectRoot}/`) || absolutePath.startsWith(`${projectRoot}\\`)) {
12772
+ return absolutePath.slice(projectRoot.length).replace(/\\/g, "/");
12773
+ }
12774
+ return void 0;
12775
+ }
12776
+ __name(toRootRelativeUrlPath, "toRootRelativeUrlPath");
12769
12777
  function toViteModuleId(filePath, root) {
12770
12778
  if (!import_path.default.isAbsolute(filePath)) return filePath;
12771
12779
  const relativePath2 = import_path.default.relative(root, filePath);
@@ -14915,9 +14923,8 @@ var _RouteManager = class _RouteManager {
14915
14923
  return this.clientManifestCache.manifest;
14916
14924
  }
14917
14925
  const toUrlPath = /* @__PURE__ */ __name((absolutePath) => {
14918
- if (absolutePath === normalizedProjectRoot || absolutePath.startsWith(`${normalizedProjectRoot}${import_path5.default.sep}`)) {
14919
- return absolutePath.slice(normalizedProjectRoot.length);
14920
- }
14926
+ const rootRelative = toRootRelativeUrlPath(absolutePath, normalizedProjectRoot);
14927
+ if (rootRelative !== void 0) return rootRelative;
14921
14928
  if (import_path5.default.isAbsolute(absolutePath)) {
14922
14929
  const normalized = absolutePath.replace(/\\/g, "/");
14923
14930
  return normalized.startsWith("/") ? `/@fs${normalized}` : `/@fs/${normalized}`;
@@ -15613,6 +15620,57 @@ __name(safeGlobFiles, "safeGlobFiles");
15613
15620
  // src/server/renderer.ts
15614
15621
  var fs3 = __toESM(require("fs"));
15615
15622
  var path11 = __toESM(require("path"));
15623
+
15624
+ // src/server/full-document.ts
15625
+ function stripContentsWrappers(markup) {
15626
+ let out = markup.replace(/^\s+/, "");
15627
+ const opener = /^<div\b[^>]*style="display\s*:\s*contents"[^>]*>/i;
15628
+ let match;
15629
+ while (match = opener.exec(out)) {
15630
+ out = out.slice(match[0].length).replace(/^\s+/, "");
15631
+ }
15632
+ return out;
15633
+ }
15634
+ __name(stripContentsWrappers, "stripContentsWrappers");
15635
+ function extractFarmFullDocument(markup) {
15636
+ const inner = stripContentsWrappers(markup);
15637
+ if (!/^<!doctype/i.test(inner) && !/^<html[\s>]/i.test(inner)) return null;
15638
+ const start = markup.search(/<!doctype|<html[\s>]/i);
15639
+ const closeIndex = markup.toLowerCase().lastIndexOf("</html>");
15640
+ if (start < 0 || closeIndex < 0) return null;
15641
+ return markup.slice(start, closeIndex + "</html>".length);
15642
+ }
15643
+ __name(extractFarmFullDocument, "extractFarmFullDocument");
15644
+ function opensFarmFullDocument(markup) {
15645
+ const inner = stripContentsWrappers(markup);
15646
+ return /^<!doctype/i.test(inner) || /^<html[\s>]/i.test(inner);
15647
+ }
15648
+ __name(opensFarmFullDocument, "opensFarmFullDocument");
15649
+ function composeFarmFullDocument(documentHtml, assets) {
15650
+ let html = documentHtml;
15651
+ if (assets.htmlAttributes) {
15652
+ html = html.replace(
15653
+ /<html\b([^>]*)>/i,
15654
+ (_match, attrs) => `<html${attrs}${assets.htmlAttributes}>`
15655
+ );
15656
+ }
15657
+ if (!/\sid=["']root["']/i.test(html)) {
15658
+ html = html.replace(/<body\b([^>]*)>/i, '<body$1><div id="root">').replace(/<\/body>/i, "</div></body>");
15659
+ }
15660
+ if (assets.headAssets) {
15661
+ html = html.replace(/<\/head>/i, () => ` ${assets.headAssets}
15662
+ </head>`);
15663
+ }
15664
+ if (assets.bodyFooter) {
15665
+ html = html.replace(/<\/body>/i, () => ` ${assets.bodyFooter}
15666
+ </body>`);
15667
+ }
15668
+ return /^\s*<!doctype/i.test(html) ? html : `<!DOCTYPE html>
15669
+ ${html}`;
15670
+ }
15671
+ __name(composeFarmFullDocument, "composeFarmFullDocument");
15672
+
15673
+ // src/server/renderer.ts
15616
15674
  var import_stream = require("stream");
15617
15675
 
15618
15676
  // src/middleware/server.ts
@@ -18963,7 +19021,7 @@ _setFarmThemeServerSnapshotResolver(() => {
18963
19021
  });
18964
19022
 
18965
19023
  // package.json
18966
- var version = "0.1.0-beta.45";
19024
+ var version = "0.1.0-beta.47";
18967
19025
 
18968
19026
  // src/version.ts
18969
19027
  var FARM_VERSION = version;
@@ -19072,6 +19130,16 @@ function warnSuppressedAsyncHydrationOnce(modulePath) {
19072
19130
  );
19073
19131
  }
19074
19132
  __name(warnSuppressedAsyncHydrationOnce, "warnSuppressedAsyncHydrationOnce");
19133
+ var fullDocumentRoutes = /* @__PURE__ */ new Set();
19134
+ var warnedFullDocumentLayout = false;
19135
+ function warnFarmFullDocumentLayout() {
19136
+ if (warnedFullDocumentLayout) return;
19137
+ warnedFullDocumentLayout = true;
19138
+ logger.warn(
19139
+ `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.`
19140
+ );
19141
+ }
19142
+ __name(warnFarmFullDocumentLayout, "warnFarmFullDocumentLayout");
19075
19143
  function hasRequestHeader(req, name2) {
19076
19144
  const value = req.headers[name2.toLowerCase()];
19077
19145
  return Array.isArray(value) ? value.length > 0 : Boolean(value);
@@ -19907,7 +19975,7 @@ var _ServerRenderer = class _ServerRenderer {
19907
19975
  );
19908
19976
  const clientLayouts = layouts.map((layout2, index) => ({
19909
19977
  pattern: layout2.pattern,
19910
- modulePath: layout2.modulePath.startsWith(this.config.root) ? layout2.modulePath.slice(this.config.root.length) : layout2.modulePath,
19978
+ modulePath: toRootRelativeUrlPath(layout2.modulePath, this.config.root) ?? layout2.modulePath,
19911
19979
  shouldHydrate: layoutHydrationMetadata[index]?.shouldHydrate === true,
19912
19980
  islandStrategy: layoutHydrationMetadata[index]?.islandStrategy ?? null
19913
19981
  }));
@@ -20483,7 +20551,7 @@ var _ServerRenderer = class _ServerRenderer {
20483
20551
  const routeSlots = (req.__FARM_ROUTE_SLOTS__ || []).map(
20484
20552
  (slot) => ({
20485
20553
  ...slot,
20486
- modulePath: typeof slot.modulePath === "string" && slot.modulePath.startsWith(this.config.root) ? slot.modulePath.slice(this.config.root.length) : slot.modulePath
20554
+ modulePath: typeof slot.modulePath === "string" ? toRootRelativeUrlPath(slot.modulePath, this.config.root) ?? slot.modulePath : slot.modulePath
20487
20555
  })
20488
20556
  );
20489
20557
  const deferredProps = prepareDeferredData({
@@ -20491,7 +20559,7 @@ var _ServerRenderer = class _ServerRenderer {
20491
20559
  slots: routeSlots
20492
20560
  });
20493
20561
  const pagePath = req.__FARM_PAGE_PATH__;
20494
- const relativePath2 = pagePath ? pagePath.startsWith(this.config.root) ? pagePath.slice(this.config.root.length) : pagePath : "/src/app/page.tsx";
20562
+ const relativePath2 = pagePath ? toRootRelativeUrlPath(pagePath, this.config.root) ?? pagePath : "/src/app/page.tsx";
20495
20563
  const deploymentId = this.getDeploymentId();
20496
20564
  const bootstrapScript = `<script>
20497
20565
  window.__FARM_PROPS__ = ${serializeInlineValue2(deferredProps.data.page)};
@@ -20525,7 +20593,27 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20525
20593
  this.config.basePath,
20526
20594
  getTheme()
20527
20595
  );
20528
- const html = `<!DOCTYPE html>
20596
+ const fullDocument = extractFarmFullDocument(content);
20597
+ let html;
20598
+ if (fullDocument) {
20599
+ warnFarmFullDocumentLayout();
20600
+ html = composeFarmFullDocument(fullDocument, {
20601
+ htmlAttributes: `${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}`,
20602
+ headAssets: [
20603
+ themeDocument.head,
20604
+ `<meta name="farm-deployment-id" content="${escapeHtmlAttribute2(deploymentId)}">`,
20605
+ metaTags,
20606
+ alternateTags,
20607
+ renderFarmFontDevHead(this.config.root || process.cwd()),
20608
+ `<link rel="stylesheet" href="/src/app/globals.css">`,
20609
+ `<script type="module" src="/@vite/client"></script>`,
20610
+ rendererHydrationScript,
20611
+ bootstrapScript
20612
+ ].filter(Boolean).join("\n "),
20613
+ bodyFooter: [deferredScript, `<script type="module" src="/@farm/client.js"></script>`].filter(Boolean).join("\n ")
20614
+ });
20615
+ } else {
20616
+ html = `<!DOCTYPE html>
20529
20617
  <html lang="${escapeHtmlAttribute2(i18nSnapshot?.locale || "en")}"${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}>
20530
20618
  <head>
20531
20619
  ${themeDocument.head}
@@ -20546,6 +20634,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20546
20634
  <script type="module" src="/@farm/client.js"></script>
20547
20635
  </body>
20548
20636
  </html>`;
20637
+ }
20549
20638
  emitFarmEvent({
20550
20639
  type: "render.stream.shellReady",
20551
20640
  route,
@@ -20568,7 +20657,8 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20568
20657
  }
20569
20658
  async renderWithSSR(element, req, res, clearMiddlewareData, options = {}) {
20570
20659
  const renderToPipeableStream2 = this.rendererRuntime.renderToPipeableStream;
20571
- if (!renderToPipeableStream2) {
20660
+ const fullDocumentRouteKey = options.observabilityRoute || req.__FARM_ROUTE__ || req.url || "/";
20661
+ if (!renderToPipeableStream2 || fullDocumentRoutes.has(fullDocumentRouteKey)) {
20572
20662
  return this.renderBufferedSSR(element, req, res, clearMiddlewareData, options);
20573
20663
  }
20574
20664
  return new Promise((resolve8, reject) => {
@@ -20587,7 +20677,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20587
20677
  let didError = false;
20588
20678
  const pagePath = req.__FARM_PAGE_PATH__;
20589
20679
  const isClientComponent = req.__FARM_IS_CLIENT_COMPONENT__ === true;
20590
- const relativePath2 = pagePath ? pagePath.startsWith(this.config.root) ? pagePath.slice(this.config.root.length) : pagePath : "/src/app/page.tsx";
20680
+ const relativePath2 = pagePath ? toRootRelativeUrlPath(pagePath, this.config.root) ?? pagePath : "/src/app/page.tsx";
20591
20681
  const manifest = options.routeManifest ?? this.routeManager.generateClientManifest(this.config.root);
20592
20682
  const clientManifest = {
20593
20683
  clientEntry: "/@farm/client.js",
@@ -20635,7 +20725,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20635
20725
  const routeSlotPayload = (req.__FARM_ROUTE_SLOTS__ || []).map(
20636
20726
  (slot) => ({
20637
20727
  ...slot,
20638
- modulePath: typeof slot.modulePath === "string" && slot.modulePath.startsWith(this.config.root) ? slot.modulePath.slice(this.config.root.length) : slot.modulePath
20728
+ modulePath: typeof slot.modulePath === "string" ? toRootRelativeUrlPath(slot.modulePath, this.config.root) ?? slot.modulePath : slot.modulePath
20639
20729
  })
20640
20730
  );
20641
20731
  const deferredProps = prepareDeferredData({
@@ -20715,6 +20805,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20715
20805
  htmlParts.push(shell);
20716
20806
  staticShellParts?.push(shell);
20717
20807
  let firstChunk = true;
20808
+ let checkedFullDocument = false;
20718
20809
  const writableStream = new import_stream.Writable({
20719
20810
  write(chunk, encoding, callback) {
20720
20811
  if (firstChunk && process.env.FARM_VERBOSE) {
@@ -20722,6 +20813,13 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
20722
20813
  firstChunk = false;
20723
20814
  }
20724
20815
  const chunkText = Buffer.isBuffer(chunk) ? chunk.toString() : String(chunk);
20816
+ if (!checkedFullDocument) {
20817
+ checkedFullDocument = true;
20818
+ if (opensFarmFullDocument(chunkText)) {
20819
+ fullDocumentRoutes.add(fullDocumentRouteKey);
20820
+ warnFarmFullDocumentLayout();
20821
+ }
20822
+ }
20725
20823
  htmlParts.push(chunkText);
20726
20824
  if (staticShellParts && !staticShellClosed) {
20727
20825
  const dynamicIndex = findPPRDynamicChunkIndex(chunkText);
@@ -20920,6 +21018,24 @@ ${i18nSnapshot ? `window.__FARM_I18N__ = ${serializeInlineValue2(i18nSnapshot)};
20920
21018
  getTheme()
20921
21019
  );
20922
21020
  const rendererHydrationScript = this.rendererRuntime.generateHydrationScript?.() || "";
21021
+ const fullDocument = extractFarmFullDocument(content);
21022
+ if (fullDocument) {
21023
+ warnFarmFullDocumentLayout();
21024
+ return composeFarmFullDocument(fullDocument, {
21025
+ htmlAttributes: `${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}`,
21026
+ headAssets: [
21027
+ themeDocument.head,
21028
+ `<meta name="farm-deployment-id" content="${escapeHtmlAttribute2(this.getDeploymentId())}">`,
21029
+ alternateLinks,
21030
+ fontHead,
21031
+ `<link rel="stylesheet" href="/src/app/globals.css" />`,
21032
+ `<script type="module" src="/@vite/client"></script>`,
21033
+ rendererHydrationScript,
21034
+ integrationManifestScript
21035
+ ].filter(Boolean).join("\n "),
21036
+ bodyFooter: clientScript.trim()
21037
+ });
21038
+ }
20923
21039
  return `<!DOCTYPE html>
20924
21040
  <html lang="${escapeHtmlAttribute2(i18nSnapshot?.locale || "en")}"${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}>
20925
21041
  <head>