@farm.js/core 0.1.0-beta.46 → 0.1.0-beta.48

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 (38) hide show
  1. package/dist/{chunk-W2O6SKJU.mjs → chunk-3P63LWDM.mjs} +2 -2
  2. package/dist/{chunk-V7VDW7IY.mjs → chunk-HEZHCCMF.mjs} +2 -2
  3. package/dist/{chunk-LGCIIMFR.mjs → chunk-NKIHYEWC.mjs} +2 -2
  4. package/dist/{chunk-LGCIIMFR.mjs.map → chunk-NKIHYEWC.mjs.map} +1 -1
  5. package/dist/{chunk-TQJMU5BP.mjs → chunk-VZKOMD6C.mjs} +113 -4
  6. package/dist/chunk-VZKOMD6C.mjs.map +1 -0
  7. package/dist/client/lifecycle.mjs +2 -2
  8. package/dist/client-plugins.cjs +1 -1
  9. package/dist/client-plugins.cjs.map +1 -1
  10. package/dist/client-plugins.mjs +2 -2
  11. package/dist/client.cjs +1 -1
  12. package/dist/client.cjs.map +1 -1
  13. package/dist/client.mjs +2 -2
  14. package/dist/index.cjs +117 -4
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.mjs +4 -4
  17. package/dist/internal/build-runtime.cjs +117 -4
  18. package/dist/internal/build-runtime.cjs.map +1 -1
  19. package/dist/internal/build-runtime.mjs +3 -3
  20. package/dist/internal/client-runtime.cjs +1 -1
  21. package/dist/internal/client-runtime.cjs.map +1 -1
  22. package/dist/internal/client-runtime.mjs +2 -2
  23. package/dist/plugin.cjs +112 -3
  24. package/dist/plugin.cjs.map +1 -1
  25. package/dist/plugin.mjs +2 -2
  26. package/dist/server.cjs +112 -3
  27. package/dist/server.cjs.map +1 -1
  28. package/dist/server.mjs +2 -2
  29. package/dist/version.cjs +1 -1
  30. package/dist/version.cjs.map +1 -1
  31. package/dist/version.mjs +1 -1
  32. package/dist/vite.cjs +112 -3
  33. package/dist/vite.cjs.map +1 -1
  34. package/dist/vite.mjs +2 -2
  35. package/package.json +1 -1
  36. package/dist/chunk-TQJMU5BP.mjs.map +0 -1
  37. /package/dist/{chunk-W2O6SKJU.mjs.map → chunk-3P63LWDM.mjs.map} +0 -0
  38. /package/dist/{chunk-V7VDW7IY.mjs.map → chunk-HEZHCCMF.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-5ZGPRGWV.mjs";
10
10
  import {
11
11
  build
12
- } from "./chunk-V7VDW7IY.mjs";
12
+ } from "./chunk-HEZHCCMF.mjs";
13
13
  import "./chunk-SL6HTIOK.mjs";
14
14
  import "./chunk-4S3ORGFA.mjs";
15
15
  import {
@@ -208,7 +208,7 @@ import {
208
208
  createClientPluginManager,
209
209
  installChunkErrorRecovery,
210
210
  isChunkLoadError
211
- } from "./chunk-W2O6SKJU.mjs";
211
+ } from "./chunk-3P63LWDM.mjs";
212
212
  import {
213
213
  analyzeStaticRouteCandidate,
214
214
  collectSSGPages,
@@ -227,7 +227,7 @@ import {
227
227
  parseRouteRenderingDirective,
228
228
  resolveRouteRenderingConfig,
229
229
  resolveRouteRenderingConfigFromFile
230
- } from "./chunk-TQJMU5BP.mjs";
230
+ } from "./chunk-VZKOMD6C.mjs";
231
231
  import {
232
232
  APITypeGenerator
233
233
  } from "./chunk-XJTDE4L4.mjs";
@@ -567,7 +567,7 @@ import {
567
567
  runWithFarmSpan
568
568
  } from "./chunk-7ZMKVETU.mjs";
569
569
  import "./chunk-FXG2PS27.mjs";
570
- import "./chunk-LGCIIMFR.mjs";
570
+ import "./chunk-NKIHYEWC.mjs";
571
571
  import {
572
572
  createCompressionPlugin,
573
573
  createEnvPlugin,
@@ -11400,6 +11400,60 @@ var init_route_manager = __esm({
11400
11400
  }
11401
11401
  });
11402
11402
 
11403
+ // src/server/full-document.ts
11404
+ function stripContentsWrappers(markup) {
11405
+ let out = markup.replace(/^\s+/, "");
11406
+ const opener = /^<div\b[^>]*style="display\s*:\s*contents"[^>]*>/i;
11407
+ let match;
11408
+ while (match = opener.exec(out)) {
11409
+ out = out.slice(match[0].length).replace(/^\s+/, "");
11410
+ }
11411
+ return out;
11412
+ }
11413
+ function extractFarmFullDocument(markup) {
11414
+ const inner = stripContentsWrappers(markup);
11415
+ if (!/^<!doctype/i.test(inner) && !/^<html[\s>]/i.test(inner)) return null;
11416
+ const start = markup.search(/<!doctype|<html[\s>]/i);
11417
+ const closeIndex = markup.toLowerCase().lastIndexOf("</html>");
11418
+ if (start < 0 || closeIndex < 0) return null;
11419
+ return markup.slice(start, closeIndex + "</html>".length);
11420
+ }
11421
+ function opensFarmFullDocument(markup) {
11422
+ const inner = stripContentsWrappers(markup);
11423
+ return /^<!doctype/i.test(inner) || /^<html[\s>]/i.test(inner);
11424
+ }
11425
+ function composeFarmFullDocument(documentHtml, assets) {
11426
+ let html = documentHtml;
11427
+ if (assets.htmlAttributes) {
11428
+ html = html.replace(
11429
+ /<html\b([^>]*)>/i,
11430
+ (_match, attrs) => `<html${attrs}${assets.htmlAttributes}>`
11431
+ );
11432
+ }
11433
+ if (!/\sid=["']root["']/i.test(html)) {
11434
+ html = html.replace(/<body\b([^>]*)>/i, '<body$1><div id="root">').replace(/<\/body>/i, "</div></body>");
11435
+ }
11436
+ if (assets.headAssets) {
11437
+ html = html.replace(/<\/head>/i, () => ` ${assets.headAssets}
11438
+ </head>`);
11439
+ }
11440
+ if (assets.bodyFooter) {
11441
+ html = html.replace(/<\/body>/i, () => ` ${assets.bodyFooter}
11442
+ </body>`);
11443
+ }
11444
+ return /^\s*<!doctype/i.test(html) ? html : `<!DOCTYPE html>
11445
+ ${html}`;
11446
+ }
11447
+ var init_full_document = __esm({
11448
+ "src/server/full-document.ts"() {
11449
+ "use strict";
11450
+ __name(stripContentsWrappers, "stripContentsWrappers");
11451
+ __name(extractFarmFullDocument, "extractFarmFullDocument");
11452
+ __name(opensFarmFullDocument, "opensFarmFullDocument");
11453
+ __name(composeFarmFullDocument, "composeFarmFullDocument");
11454
+ }
11455
+ });
11456
+
11403
11457
  // src/middleware/server.ts
11404
11458
  function getGlobalMiddlewareStore(key) {
11405
11459
  const state = globalThis;
@@ -14858,7 +14912,7 @@ var init_server3 = __esm({
14858
14912
  var version;
14859
14913
  var init_package = __esm({
14860
14914
  "package.json"() {
14861
- version = "0.1.0-beta.46";
14915
+ version = "0.1.0-beta.48";
14862
14916
  }
14863
14917
  });
14864
14918
 
@@ -15030,6 +15084,13 @@ function warnSuppressedAsyncHydrationOnce(modulePath) {
15030
15084
  `${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.`
15031
15085
  );
15032
15086
  }
15087
+ function warnFarmFullDocumentLayout() {
15088
+ if (warnedFullDocumentLayout) return;
15089
+ warnedFullDocumentLayout = true;
15090
+ logger.warn(
15091
+ `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.`
15092
+ );
15093
+ }
15033
15094
  function hasRequestHeader(req, name2) {
15034
15095
  const value = req.headers[name2.toLowerCase()];
15035
15096
  return Array.isArray(value) ? value.length > 0 : Boolean(value);
@@ -15168,13 +15229,14 @@ function createRouteStateProps(input) {
15168
15229
  context: input.pluginExposedContext.size > 0 ? { data: input.pluginExposedContext } : void 0
15169
15230
  };
15170
15231
  }
15171
- var fs3, path13, import_stream, import_node_url6, cachedClerkProvider, importRuntimeModule, warnedSuppressedAsyncHydrationModules, _ServerRenderer, ServerRenderer;
15232
+ var fs3, path13, import_stream, import_node_url6, cachedClerkProvider, importRuntimeModule, warnedSuppressedAsyncHydrationModules, fullDocumentRoutes, warnedFullDocumentLayout, _ServerRenderer, ServerRenderer;
15172
15233
  var init_renderer2 = __esm({
15173
15234
  "src/server/renderer.ts"() {
15174
15235
  "use strict";
15175
15236
  fs3 = __toESM(require("fs"));
15176
15237
  path13 = __toESM(require("path"));
15177
15238
  init_utils();
15239
+ init_full_document();
15178
15240
  init_client_component();
15179
15241
  import_stream = require("stream");
15180
15242
  init_server();
@@ -15209,6 +15271,9 @@ var init_renderer2 = __esm({
15209
15271
  importRuntimeModule = new Function("specifier", "return import(specifier);");
15210
15272
  warnedSuppressedAsyncHydrationModules = /* @__PURE__ */ new Set();
15211
15273
  __name(warnSuppressedAsyncHydrationOnce, "warnSuppressedAsyncHydrationOnce");
15274
+ fullDocumentRoutes = /* @__PURE__ */ new Set();
15275
+ warnedFullDocumentLayout = false;
15276
+ __name(warnFarmFullDocumentLayout, "warnFarmFullDocumentLayout");
15212
15277
  __name(hasRequestHeader, "hasRequestHeader");
15213
15278
  __name(serializeInlineValue2, "serializeInlineValue");
15214
15279
  __name(escapeHtmlAttribute2, "escapeHtmlAttribute");
@@ -16524,7 +16589,27 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
16524
16589
  this.config.basePath,
16525
16590
  getTheme()
16526
16591
  );
16527
- const html = `<!DOCTYPE html>
16592
+ const fullDocument = extractFarmFullDocument(content);
16593
+ let html;
16594
+ if (fullDocument) {
16595
+ warnFarmFullDocumentLayout();
16596
+ html = composeFarmFullDocument(fullDocument, {
16597
+ htmlAttributes: `${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}`,
16598
+ headAssets: [
16599
+ themeDocument.head,
16600
+ `<meta name="farm-deployment-id" content="${escapeHtmlAttribute2(deploymentId)}">`,
16601
+ metaTags,
16602
+ alternateTags,
16603
+ renderFarmFontDevHead(this.config.root || process.cwd()),
16604
+ `<link rel="stylesheet" href="/src/app/globals.css">`,
16605
+ `<script type="module" src="/@vite/client"></script>`,
16606
+ rendererHydrationScript,
16607
+ bootstrapScript
16608
+ ].filter(Boolean).join("\n "),
16609
+ bodyFooter: [deferredScript, `<script type="module" src="/@farm/client.js"></script>`].filter(Boolean).join("\n ")
16610
+ });
16611
+ } else {
16612
+ html = `<!DOCTYPE html>
16528
16613
  <html lang="${escapeHtmlAttribute2(i18nSnapshot?.locale || "en")}"${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}>
16529
16614
  <head>
16530
16615
  ${themeDocument.head}
@@ -16545,6 +16630,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
16545
16630
  <script type="module" src="/@farm/client.js"></script>
16546
16631
  </body>
16547
16632
  </html>`;
16633
+ }
16548
16634
  emitFarmEvent({
16549
16635
  type: "render.stream.shellReady",
16550
16636
  route,
@@ -16567,7 +16653,8 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
16567
16653
  }
16568
16654
  async renderWithSSR(element, req, res, clearMiddlewareData, options = {}) {
16569
16655
  const renderToPipeableStream2 = this.rendererRuntime.renderToPipeableStream;
16570
- if (!renderToPipeableStream2) {
16656
+ const fullDocumentRouteKey = options.observabilityRoute || req.__FARM_ROUTE__ || req.url || "/";
16657
+ if (!renderToPipeableStream2 || fullDocumentRoutes.has(fullDocumentRouteKey)) {
16571
16658
  return this.renderBufferedSSR(element, req, res, clearMiddlewareData, options);
16572
16659
  }
16573
16660
  return new Promise((resolve8, reject) => {
@@ -16714,6 +16801,7 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
16714
16801
  htmlParts.push(shell);
16715
16802
  staticShellParts?.push(shell);
16716
16803
  let firstChunk = true;
16804
+ let checkedFullDocument = false;
16717
16805
  const writableStream = new import_stream.Writable({
16718
16806
  write(chunk, encoding, callback) {
16719
16807
  if (firstChunk && process.env.FARM_VERBOSE) {
@@ -16721,6 +16809,13 @@ ${getFarmI18nClientSnapshot() ? `window.__FARM_I18N__ = ${serializeInlineValue2(
16721
16809
  firstChunk = false;
16722
16810
  }
16723
16811
  const chunkText = Buffer.isBuffer(chunk) ? chunk.toString() : String(chunk);
16812
+ if (!checkedFullDocument) {
16813
+ checkedFullDocument = true;
16814
+ if (opensFarmFullDocument(chunkText)) {
16815
+ fullDocumentRoutes.add(fullDocumentRouteKey);
16816
+ warnFarmFullDocumentLayout();
16817
+ }
16818
+ }
16724
16819
  htmlParts.push(chunkText);
16725
16820
  if (staticShellParts && !staticShellClosed) {
16726
16821
  const dynamicIndex = findPPRDynamicChunkIndex(chunkText);
@@ -16919,6 +17014,24 @@ ${i18nSnapshot ? `window.__FARM_I18N__ = ${serializeInlineValue2(i18nSnapshot)};
16919
17014
  getTheme()
16920
17015
  );
16921
17016
  const rendererHydrationScript = this.rendererRuntime.generateHydrationScript?.() || "";
17017
+ const fullDocument = extractFarmFullDocument(content);
17018
+ if (fullDocument) {
17019
+ warnFarmFullDocumentLayout();
17020
+ return composeFarmFullDocument(fullDocument, {
17021
+ htmlAttributes: `${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}`,
17022
+ headAssets: [
17023
+ themeDocument.head,
17024
+ `<meta name="farm-deployment-id" content="${escapeHtmlAttribute2(this.getDeploymentId())}">`,
17025
+ alternateLinks,
17026
+ fontHead,
17027
+ `<link rel="stylesheet" href="/src/app/globals.css" />`,
17028
+ `<script type="module" src="/@vite/client"></script>`,
17029
+ rendererHydrationScript,
17030
+ integrationManifestScript
17031
+ ].filter(Boolean).join("\n "),
17032
+ bodyFooter: clientScript.trim()
17033
+ });
17034
+ }
16922
17035
  return `<!DOCTYPE html>
16923
17036
  <html lang="${escapeHtmlAttribute2(i18nSnapshot?.locale || "en")}"${i18nSnapshot ? ` dir="${i18nSnapshot.direction}"` : ""}${themeDocument.attributes}>
16924
17037
  <head>