@webtypen/webframez-react 0.0.34 → 0.0.36

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.
@@ -29,16 +29,21 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  // src/webframez-core.ts
30
30
  var webframez_core_exports = {};
31
31
  __export(webframez_core_exports, {
32
+ clearRegisteredReactBuildTargets: () => clearRegisteredReactBuildTargets,
33
+ getRegisteredReactBuildTargets: () => getRegisteredReactBuildTargets,
32
34
  initWebframezReact: () => initWebframezReact,
35
+ resolveWebframezReactRouteOptions: () => resolveWebframezReactRouteOptions,
33
36
  setupWebframezCoreReactRoute: () => setupWebframezCoreReactRoute
34
37
  });
35
38
  module.exports = __toCommonJS(webframez_core_exports);
39
+ var import_node_path4 = __toESM(require("node:path"), 1);
36
40
 
37
41
  // src/http.ts
38
42
  var import_node_fs2 = __toESM(require("node:fs"), 1);
39
43
  var import_node_path3 = __toESM(require("node:path"), 1);
40
44
  var import_node_url = require("node:url");
41
45
  var import_node_child_process = require("node:child_process");
46
+ var import_node_zlib = require("node:zlib");
42
47
 
43
48
  // src/server.ts
44
49
  var import_node_path = __toESM(require("node:path"), 1);
@@ -795,7 +800,77 @@ function parseSearchParams(query) {
795
800
  function createInitialHtmlErrorMarkup(message) {
796
801
  return `<main style="font-family:system-ui,sans-serif;padding:24px"><h1 style="margin:0 0 12px">500</h1><p style="margin:0">${message}</p></main>`;
797
802
  }
803
+ function createClientAssetVersion(distRootDir) {
804
+ try {
805
+ const stat = import_node_fs2.default.statSync(import_node_path3.default.join(distRootDir, "client.js"));
806
+ return `${Math.floor(stat.mtimeMs)}-${stat.size}`;
807
+ } catch {
808
+ return "";
809
+ }
810
+ }
811
+ function appendAssetVersion(url, version) {
812
+ if (!version) {
813
+ return url;
814
+ }
815
+ const separator = url.includes("?") ? "&" : "?";
816
+ return `${url}${separator}v=${encodeURIComponent(version)}`;
817
+ }
818
+ function isWithinDirectory(filePath, directory) {
819
+ return filePath === directory || filePath.startsWith(`${directory}${import_node_path3.default.sep}`);
820
+ }
821
+ function isCompressibleAsset(ext) {
822
+ return [".js", ".mjs", ".json", ".css", ".svg", ".txt", ".html"].includes(ext);
823
+ }
824
+ function isHashedAssetPath(filePath) {
825
+ return /-[a-f0-9]{12,}\.[cm]?js$/i.test(import_node_path3.default.basename(filePath));
826
+ }
827
+ function setAssetContentType(res, ext) {
828
+ if (ext === ".js" || ext === ".mjs") {
829
+ res.setHeader("Content-Type", "text/javascript; charset=utf-8");
830
+ } else if (ext === ".json") {
831
+ res.setHeader("Content-Type", "application/json; charset=utf-8");
832
+ } else if (ext === ".css") {
833
+ res.setHeader("Content-Type", "text/css; charset=utf-8");
834
+ } else if (ext === ".svg") {
835
+ res.setHeader("Content-Type", "image/svg+xml; charset=utf-8");
836
+ }
837
+ }
838
+ function getPreferredContentEncoding(req, ext, fileSize) {
839
+ if (!isCompressibleAsset(ext) || fileSize < 1024) {
840
+ return "";
841
+ }
842
+ const acceptEncoding = String(req.headers["accept-encoding"] || "");
843
+ if (/\bbr\b/.test(acceptEncoding)) {
844
+ return "br";
845
+ }
846
+ if (/\bgzip\b/.test(acceptEncoding)) {
847
+ return "gzip";
848
+ }
849
+ return "";
850
+ }
851
+ function sendTextResponse(req, res, body, options) {
852
+ const bodyBuffer = Buffer.from(body);
853
+ const contentEncoding = options.compress === false ? "" : getPreferredContentEncoding(req, ".html", bodyBuffer.length);
854
+ res.statusCode = options.statusCode ?? 200;
855
+ res.setHeader("Content-Type", options.contentType);
856
+ if (options.cacheControl) {
857
+ res.setHeader("Cache-Control", options.cacheControl);
858
+ }
859
+ res.setHeader("Vary", "Accept-Encoding");
860
+ if (contentEncoding === "br") {
861
+ res.setHeader("Content-Encoding", "br");
862
+ res.end((0, import_node_zlib.brotliCompressSync)(bodyBuffer));
863
+ return;
864
+ }
865
+ if (contentEncoding === "gzip") {
866
+ res.setHeader("Content-Encoding", "gzip");
867
+ res.end((0, import_node_zlib.gzipSync)(bodyBuffer));
868
+ return;
869
+ }
870
+ res.end(bodyBuffer);
871
+ }
798
872
  var INITIAL_HTML_WORKER_SCRIPT = `
873
+ const fs = require("node:fs");
799
874
  const path = require("node:path");
800
875
  const Module = require("node:module");
801
876
  const { Readable, Writable } = require("node:stream");
@@ -845,11 +920,42 @@ const reactDomServer = require(path.join(path.dirname(reactDomPkg), "server.node
845
920
  globalThis.__webpack_chunk_load__ = function __webframezNoopChunkLoad() {
846
921
  return Promise.resolve();
847
922
  };
923
+ function normalizeWebframezRequireCandidate(candidate) {
924
+ const stagingMarker = path.join(".webframez-build", "");
925
+ const appMarker = path.join("app", "");
926
+ const stagingIndex = candidate.indexOf(stagingMarker);
927
+ const appIndex = candidate.indexOf(appMarker, stagingIndex >= 0 ? stagingIndex : 0);
928
+ if (stagingIndex >= 0 && appIndex >= 0) {
929
+ const runtimeCandidate = path.resolve(process.cwd(), candidate.slice(appIndex));
930
+ if (fs.existsSync(runtimeCandidate)) {
931
+ return runtimeCandidate;
932
+ }
933
+ }
934
+
935
+ const frameworkDistDir = path.join("node_modules", "@webtypen", "webframez-react", "dist");
936
+ const shouldUseCjs =
937
+ candidate.includes(frameworkDistDir) &&
938
+ (candidate.endsWith(path.join("dist", "navigation.js")) ||
939
+ candidate.endsWith(path.join("dist", "route-slot.js")));
940
+
941
+ if (!shouldUseCjs) {
942
+ return candidate;
943
+ }
944
+
945
+ const cjsCandidate = candidate.slice(0, -3) + ".cjs";
946
+ return fs.existsSync(cjsCandidate) ? cjsCandidate : candidate;
947
+ }
948
+
848
949
  globalThis.__webpack_require__ = function __webframezNodeRequire(id) {
849
950
  if (typeof id !== "string") {
850
951
  return require(id);
851
952
  }
852
953
 
954
+ const directRequireTarget = normalizeWebframezRequireCandidate(id);
955
+ if (directRequireTarget !== id) {
956
+ return require(directRequireTarget);
957
+ }
958
+
853
959
  if (id.startsWith("./")) {
854
960
  const relativeId = id.slice(2);
855
961
  const candidates = [
@@ -857,10 +963,16 @@ globalThis.__webpack_require__ = function __webframezNodeRequire(id) {
857
963
  path.resolve(process.cwd(), "..", relativeId)
858
964
  ];
859
965
  for (const candidate of candidates) {
966
+ const requireTarget = normalizeWebframezRequireCandidate(candidate);
860
967
  try {
861
- return require(candidate);
968
+ return require(requireTarget);
862
969
  } catch (error) {
863
- const missingCandidate = error && error.code === "MODULE_NOT_FOUND" && typeof error.message === "string" && error.message.includes("'" + candidate + "'");
970
+ const missingCandidate =
971
+ error &&
972
+ error.code === "MODULE_NOT_FOUND" &&
973
+ typeof error.message === "string" &&
974
+ (error.message.includes("'" + candidate + "'") ||
975
+ error.message.includes("'" + requireTarget + "'"));
864
976
  if (!missingCandidate) {
865
977
  throw error;
866
978
  }
@@ -1082,6 +1194,14 @@ function joinRuntimeBasePath(basePath, pathname) {
1082
1194
  }
1083
1195
  return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1084
1196
  }
1197
+ function joinRuntimeAssetPath(basePath, pathname) {
1198
+ const normalizedBasePath = normalizeRuntimeBasePath(basePath) ?? "";
1199
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1200
+ if (normalizedBasePath && (normalizedPath === normalizedBasePath || normalizedPath.startsWith(`${normalizedBasePath}/`))) {
1201
+ return normalizedPath;
1202
+ }
1203
+ return joinRuntimeBasePath(normalizedBasePath, normalizedPath);
1204
+ }
1085
1205
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
1086
1206
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
1087
1207
  return "";
@@ -1276,6 +1396,18 @@ function createServerConsumerManifest(manifest) {
1276
1396
  const consumerManifest = {};
1277
1397
  const normalizeWorkerModuleId = (requestKey, rawModuleId) => {
1278
1398
  if (typeof rawModuleId === "string" && rawModuleId.trim() !== "") {
1399
+ const isStagingModuleId = rawModuleId.startsWith("./.webframez-build/") || rawModuleId.includes(`${import_node_path3.default.sep}.webframez-build${import_node_path3.default.sep}`);
1400
+ const isRuntimeBuildKey = requestKey.startsWith("file://") || requestKey.startsWith("/") && requestKey.includes(`${import_node_path3.default.sep}build${import_node_path3.default.sep}app${import_node_path3.default.sep}`);
1401
+ if (isStagingModuleId && isRuntimeBuildKey) {
1402
+ if (requestKey.startsWith("file://")) {
1403
+ try {
1404
+ return (0, import_node_url.fileURLToPath)(requestKey);
1405
+ } catch {
1406
+ return rawModuleId;
1407
+ }
1408
+ }
1409
+ return requestKey;
1410
+ }
1279
1411
  return rawModuleId;
1280
1412
  }
1281
1413
  if (typeof rawModuleId !== "number" || !Number.isFinite(rawModuleId)) {
@@ -1357,6 +1489,14 @@ function createServerConsumerManifest(manifest) {
1357
1489
  name: exportName
1358
1490
  });
1359
1491
  }
1492
+ } else if (typeof entry.id === "string" && entry.id.trim() !== "") {
1493
+ addReference(entry.id, "*", reference);
1494
+ for (const exportName of exportNames) {
1495
+ addReference(entry.id, exportName, {
1496
+ ...reference,
1497
+ name: exportName
1498
+ });
1499
+ }
1360
1500
  }
1361
1501
  }
1362
1502
  return consumerManifest;
@@ -1471,24 +1611,49 @@ function createNodeRequestHandler(options) {
1471
1611
  if (url.pathname.startsWith(assetsPrefix)) {
1472
1612
  const relative = url.pathname.slice(assetsPrefix.length);
1473
1613
  const filePath = import_node_path3.default.resolve(distRootDir, relative);
1474
- if (!filePath.startsWith(distRootDir)) {
1614
+ if (!isWithinDirectory(filePath, distRootDir)) {
1475
1615
  res.statusCode = 400;
1476
1616
  res.end("Invalid path");
1477
1617
  return;
1478
1618
  }
1479
1619
  const ext = import_node_path3.default.extname(filePath);
1480
- if (ext === ".js" || ext === ".mjs") {
1481
- res.setHeader("Content-Type", "text/javascript; charset=utf-8");
1482
- } else if (ext === ".json") {
1483
- res.setHeader("Content-Type", "application/json; charset=utf-8");
1620
+ let stat;
1621
+ try {
1622
+ stat = import_node_fs2.default.statSync(filePath);
1623
+ if (!stat.isFile()) {
1624
+ throw new Error("Asset path is not a file");
1625
+ }
1626
+ } catch {
1627
+ res.statusCode = 404;
1628
+ res.end("Not found");
1629
+ return;
1484
1630
  }
1485
- res.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
1631
+ setAssetContentType(res, ext);
1632
+ const isDevelopmentAsset = nodeEnv !== "production";
1633
+ const isVersionedClientAsset = import_node_path3.default.basename(filePath) === "client.js" && url.searchParams.has("v");
1634
+ const canCacheLongTerm = !isDevelopmentAsset && (isHashedAssetPath(filePath) || isVersionedClientAsset);
1635
+ res.setHeader(
1636
+ "Cache-Control",
1637
+ canCacheLongTerm ? "public, max-age=31536000, immutable" : "no-store, no-cache, must-revalidate, proxy-revalidate"
1638
+ );
1639
+ res.setHeader("Vary", "Accept-Encoding");
1640
+ const contentEncoding = !isDevelopmentAsset ? getPreferredContentEncoding(req, ext, stat.size) : "";
1486
1641
  const stream = import_node_fs2.default.createReadStream(filePath);
1487
1642
  stream.on("error", () => {
1488
- res.statusCode = 404;
1643
+ if (!res.headersSent) {
1644
+ res.statusCode = 404;
1645
+ }
1489
1646
  res.end("Not found");
1490
1647
  });
1491
- stream.pipe(res);
1648
+ if (contentEncoding === "br") {
1649
+ res.setHeader("Content-Encoding", "br");
1650
+ stream.pipe((0, import_node_zlib.createBrotliCompress)()).pipe(res);
1651
+ } else if (contentEncoding === "gzip") {
1652
+ res.setHeader("Content-Encoding", "gzip");
1653
+ stream.pipe((0, import_node_zlib.createGzip)()).pipe(res);
1654
+ } else {
1655
+ stream.pipe(res);
1656
+ }
1492
1657
  return;
1493
1658
  }
1494
1659
  const resolved = await withRequestBasename(
@@ -1506,22 +1671,23 @@ function createNodeRequestHandler(options) {
1506
1671
  );
1507
1672
  const initialPayload = {
1508
1673
  model: resolved.model,
1509
- contextModel: resolved.contextModel,
1510
- pageModel: resolved.pageModel,
1511
1674
  head: resolved.head
1512
1675
  };
1513
1676
  const initialFlightData = await renderRSCToString(initialPayload, {
1514
1677
  moduleMap
1515
1678
  });
1516
1679
  const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1517
- const shellClientScriptUrl = joinRuntimeBasePath(
1518
- transportBasePath,
1519
- "/assets/client.js"
1680
+ const shellClientScriptUrl = appendAssetVersion(
1681
+ joinRuntimeAssetPath(
1682
+ transportBasePath,
1683
+ clientScriptUrl
1684
+ ),
1685
+ createClientAssetVersion(distRootDir)
1520
1686
  );
1521
1687
  const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1522
1688
  const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1523
1689
  const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1524
- let rootHtml = "";
1690
+ let rootHtml;
1525
1691
  try {
1526
1692
  rootHtml = await initialHtmlWorker.renderFromFlightData({
1527
1693
  flightData: initialFlightData,
@@ -1545,29 +1711,23 @@ function createNodeRequestHandler(options) {
1545
1711
  });
1546
1712
  } catch (flightRenderError) {
1547
1713
  console.error("[webframez-react] Flight-to-HTML render failed", flightRenderError);
1548
- res.statusCode = 500;
1549
- res.setHeader("Content-Type", "text/html");
1550
- res.end(
1551
- createHTMLShell({
1552
- title: "500 - Initial HTML render failed",
1553
- headTags: "",
1554
- clientScriptUrl: shellClientScriptUrl,
1555
- rscEndpoint: shellRscEndpoint,
1556
- rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1557
- initialFlightData,
1558
- basename: shellBasename,
1559
- routeBasePath: shellRouteBasePath,
1560
- liveReloadPath: liveReloadPath || void 0,
1561
- liveReloadServerId: liveReloadPath ? devServerId : void 0
1562
- })
1714
+ sendTextResponse(
1715
+ req,
1716
+ res,
1717
+ createInitialHtmlErrorMarkup("Failed to render initial React HTML."),
1718
+ {
1719
+ statusCode: 500,
1720
+ contentType: "text/html; charset=utf-8",
1721
+ compress: nodeEnv === "production"
1722
+ }
1563
1723
  );
1564
1724
  return;
1565
1725
  }
1566
1726
  }
1567
1727
  }
1568
- res.statusCode = resolved.statusCode;
1569
- res.setHeader("Content-Type", "text/html");
1570
- res.end(
1728
+ sendTextResponse(
1729
+ req,
1730
+ res,
1571
1731
  createHTMLShell({
1572
1732
  title: resolved.head.title || "Webframez React",
1573
1733
  headTags: renderHeadToString(resolved.head),
@@ -1579,14 +1739,20 @@ function createNodeRequestHandler(options) {
1579
1739
  routeBasePath: shellRouteBasePath,
1580
1740
  liveReloadPath: liveReloadPath || void 0,
1581
1741
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1582
- })
1742
+ }),
1743
+ {
1744
+ statusCode: resolved.statusCode,
1745
+ contentType: "text/html; charset=utf-8",
1746
+ cacheControl: "no-store, no-cache, must-revalidate, proxy-revalidate",
1747
+ compress: nodeEnv === "production"
1748
+ }
1583
1749
  );
1584
1750
  };
1585
1751
  }
1586
1752
 
1587
1753
  // src/webframez-core.ts
1588
- function normalizeMountPath(path4) {
1589
- const trimmed = (path4 || "").trim();
1754
+ function normalizeMountPath(path5) {
1755
+ const trimmed = (path5 || "").trim();
1590
1756
  let normalized = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
1591
1757
  if (normalized.endsWith("/**")) {
1592
1758
  normalized = normalized.slice(0, -3);
@@ -1598,12 +1764,57 @@ function normalizeMountPath(path4) {
1598
1764
  }
1599
1765
  return normalized || "/";
1600
1766
  }
1601
- function buildRenderDefaults(path4) {
1602
- const mountPath = normalizeMountPath(path4);
1767
+ var REGISTRY_KEY = "__WEBFRAMEZ_REACT_BUILD_TARGETS__";
1768
+ function getBuildTargetsRegistry() {
1769
+ const globalWithRegistry = globalThis;
1770
+ if (!globalWithRegistry[REGISTRY_KEY]) {
1771
+ globalWithRegistry[REGISTRY_KEY] = [];
1772
+ }
1773
+ return globalWithRegistry[REGISTRY_KEY];
1774
+ }
1775
+ function toRouteKey(mountPath) {
1776
+ const trimmed = mountPath.replace(/^\/+|\/+$/g, "");
1777
+ return trimmed || "root";
1778
+ }
1779
+ function toPascalCase(value) {
1780
+ return value.split(/[^A-Za-z0-9]+/).filter(Boolean).map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`).join("");
1781
+ }
1782
+ function getOutputRoot() {
1783
+ const configured = process.env.WEBFRAMEZ_REACT_OUT_DIR;
1784
+ if (configured) {
1785
+ return import_node_path4.default.resolve(process.cwd(), configured);
1786
+ }
1787
+ const isTsNodeRuntime = process.execArgv.some((arg) => arg.includes("ts-node/register")) || process.env.TS_NODE_FILES === "true" || typeof require !== "undefined" && typeof require.extensions[".ts"] === "function";
1788
+ if (isTsNodeRuntime && import_node_path4.default.basename(process.cwd()) !== "build") {
1789
+ return import_node_path4.default.resolve(process.cwd(), "build");
1790
+ }
1791
+ return process.cwd();
1792
+ }
1793
+ function resolveFromProjectRoot(value) {
1794
+ return import_node_path4.default.resolve(process.cwd(), value);
1795
+ }
1796
+ function resolveFromOutputRoot(value) {
1797
+ return import_node_path4.default.resolve(getOutputRoot(), value);
1798
+ }
1799
+ function buildRenderDefaults(routePathValue) {
1800
+ const mountPath = normalizeMountPath(routePathValue);
1801
+ const routeKey = toRouteKey(mountPath);
1802
+ const routeDirName = toPascalCase(routeKey) || routeKey;
1603
1803
  const routePath = mountPath === "/" ? "/*" : `${mountPath}/*`;
1804
+ const srcPath = import_node_path4.default.join("app", routeDirName, "react");
1805
+ const pagesDir = srcPath;
1806
+ const distRootDir = import_node_path4.default.join("webframez-react", routeKey);
1807
+ const styleSrcPath = import_node_path4.default.join("app", routeDirName, "assets", "scss");
1604
1808
  if (mountPath === "/") {
1605
1809
  return {
1810
+ path: mountPath,
1606
1811
  routePath,
1812
+ routeKey,
1813
+ srcPath: resolveFromProjectRoot(srcPath),
1814
+ distRootDir: resolveFromOutputRoot(distRootDir),
1815
+ pagesDir: resolveFromOutputRoot(pagesDir),
1816
+ manifestPath: resolveFromOutputRoot(import_node_path4.default.join(distRootDir, "react-client-manifest.json")),
1817
+ styleSrcPath: resolveFromProjectRoot(styleSrcPath),
1607
1818
  basePath: void 0,
1608
1819
  assetsPrefix: void 0,
1609
1820
  rscPath: void 0,
@@ -1611,7 +1822,14 @@ function buildRenderDefaults(path4) {
1611
1822
  };
1612
1823
  }
1613
1824
  return {
1825
+ path: mountPath,
1614
1826
  routePath,
1827
+ routeKey,
1828
+ srcPath: resolveFromProjectRoot(srcPath),
1829
+ distRootDir: resolveFromOutputRoot(distRootDir),
1830
+ pagesDir: resolveFromOutputRoot(pagesDir),
1831
+ manifestPath: resolveFromOutputRoot(import_node_path4.default.join(distRootDir, "react-client-manifest.json")),
1832
+ styleSrcPath: resolveFromProjectRoot(styleSrcPath),
1615
1833
  basePath: mountPath,
1616
1834
  assetsPrefix: `${mountPath}/assets/`,
1617
1835
  rscPath: `${mountPath}/rsc`,
@@ -1651,41 +1869,66 @@ function normalizeMethods(method) {
1651
1869
  }
1652
1870
  return Array.isArray(method) ? method : [method];
1653
1871
  }
1654
- function registerByMethod(route, method, path4, component, routeOptions) {
1872
+ function registerByMethod(route, method, path5, component, routeOptions) {
1655
1873
  if (method === "GET") {
1656
- route.get(path4, component, routeOptions);
1874
+ route.get(path5, component, routeOptions);
1657
1875
  return;
1658
1876
  }
1659
1877
  if (method === "POST") {
1660
- route.post(path4, component, routeOptions);
1878
+ route.post(path5, component, routeOptions);
1661
1879
  return;
1662
1880
  }
1663
1881
  if (method === "PUT") {
1664
- route.put(path4, component, routeOptions);
1882
+ route.put(path5, component, routeOptions);
1665
1883
  return;
1666
1884
  }
1667
- route.delete(path4, component, routeOptions);
1885
+ route.delete(path5, component, routeOptions);
1668
1886
  }
1669
1887
  function registerRouteRenderer(route, methodName) {
1670
1888
  route.extend(methodName, () => {
1671
- return (path4, options) => {
1672
- if (!options || !options.distRootDir) {
1673
- throw new Error(
1674
- `Route.${methodName} requires at least { distRootDir }`
1675
- );
1676
- }
1677
- const defaults = buildRenderDefaults(path4);
1889
+ return (routePathValue, options = {}) => {
1890
+ const defaults = buildRenderDefaults(routePathValue);
1678
1891
  const {
1679
1892
  method,
1680
1893
  routeOptions,
1894
+ srcPath,
1895
+ distRootDir,
1896
+ pagesDir,
1897
+ manifestPath,
1681
1898
  basePath,
1682
1899
  assetsPrefix,
1683
1900
  rscPath,
1684
1901
  clientScriptUrl,
1902
+ clientEntryPath,
1903
+ styleSrcPath,
1685
1904
  ...nodeHandlerOptions
1686
1905
  } = options;
1906
+ const resolvedDistRootDir = distRootDir ?? defaults.distRootDir;
1907
+ const resolvedPagesDir = pagesDir ?? defaults.pagesDir;
1908
+ const resolvedManifestPath = manifestPath ?? import_node_path4.default.join(resolvedDistRootDir, "react-client-manifest.json");
1909
+ const resolvedTarget = {
1910
+ path: defaults.path,
1911
+ routePath: defaults.routePath,
1912
+ routeKey: defaults.routeKey,
1913
+ srcPath: srcPath ? resolveFromProjectRoot(srcPath) : defaults.srcPath,
1914
+ distRootDir: resolvedDistRootDir,
1915
+ pagesDir: resolvedPagesDir,
1916
+ manifestPath: resolvedManifestPath,
1917
+ assetsPrefix: assetsPrefix ?? defaults.assetsPrefix,
1918
+ rscPath: rscPath ?? defaults.rscPath,
1919
+ clientScriptUrl: clientScriptUrl ?? defaults.clientScriptUrl,
1920
+ clientEntryPath: clientEntryPath ? resolveFromProjectRoot(clientEntryPath) : void 0,
1921
+ styleSrcPath: styleSrcPath ? resolveFromProjectRoot(styleSrcPath) : defaults.styleSrcPath
1922
+ };
1923
+ getBuildTargetsRegistry().push(resolvedTarget);
1924
+ if (process.env.WEBFRAMEZ_REACT_CAPTURE_ROUTES === "1") {
1925
+ return;
1926
+ }
1687
1927
  const handleNodeRequest = createNodeRequestHandler({
1688
1928
  ...nodeHandlerOptions,
1929
+ distRootDir: resolvedTarget.distRootDir,
1930
+ pagesDir: resolvedTarget.pagesDir,
1931
+ manifestPath: resolvedTarget.manifestPath,
1689
1932
  basePath: basePath ?? defaults.basePath,
1690
1933
  assetsPrefix: assetsPrefix ?? defaults.assetsPrefix,
1691
1934
  rscPath: rscPath ?? defaults.rscPath,
@@ -1712,6 +1955,34 @@ function registerRouteRenderer(route, methodName) {
1712
1955
  };
1713
1956
  });
1714
1957
  }
1958
+ function resolveWebframezReactRouteOptions(routePathValue, options = {}) {
1959
+ const defaults = buildRenderDefaults(routePathValue);
1960
+ const distRootDir = options.distRootDir ?? defaults.distRootDir;
1961
+ const pagesDir = options.pagesDir ?? defaults.pagesDir;
1962
+ const manifestPath = options.manifestPath ?? import_node_path4.default.join(distRootDir, "react-client-manifest.json");
1963
+ return {
1964
+ path: defaults.path,
1965
+ routePath: defaults.routePath,
1966
+ routeKey: defaults.routeKey,
1967
+ srcPath: options.srcPath ? resolveFromProjectRoot(options.srcPath) : defaults.srcPath,
1968
+ distRootDir,
1969
+ pagesDir,
1970
+ manifestPath,
1971
+ assetsPrefix: options.assetsPrefix ?? defaults.assetsPrefix,
1972
+ rscPath: options.rscPath ?? defaults.rscPath,
1973
+ clientScriptUrl: options.clientScriptUrl ?? defaults.clientScriptUrl,
1974
+ clientEntryPath: options.clientEntryPath ? resolveFromProjectRoot(options.clientEntryPath) : void 0,
1975
+ styleSrcPath: options.styleSrcPath ? resolveFromProjectRoot(options.styleSrcPath) : defaults.styleSrcPath,
1976
+ basePath: options.basePath ?? defaults.basePath,
1977
+ liveReloadPath: options.liveReloadPath
1978
+ };
1979
+ }
1980
+ function getRegisteredReactBuildTargets() {
1981
+ return [...getBuildTargetsRegistry()];
1982
+ }
1983
+ function clearRegisteredReactBuildTargets() {
1984
+ getBuildTargetsRegistry().length = 0;
1985
+ }
1715
1986
  function initWebframezReact(route) {
1716
1987
  if (!route || typeof route.extend !== "function") {
1717
1988
  throw new Error(
@@ -1729,6 +2000,9 @@ function initWebframezReact(route) {
1729
2000
  var setupWebframezCoreReactRoute = initWebframezReact;
1730
2001
  // Annotate the CommonJS export names for ESM import in node:
1731
2002
  0 && (module.exports = {
2003
+ clearRegisteredReactBuildTargets,
2004
+ getRegisteredReactBuildTargets,
1732
2005
  initWebframezReact,
2006
+ resolveWebframezReactRouteOptions,
1733
2007
  setupWebframezCoreReactRoute
1734
2008
  });
@@ -11,14 +11,32 @@ export interface WebframezCoreRouteRegistrationOptions {
11
11
  }
12
12
 
13
13
  export interface WebframezCoreReactRenderRouteOptions
14
- extends CreateNodeHandlerOptions {
14
+ extends Partial<CreateNodeHandlerOptions> {
15
+ srcPath?: string;
16
+ clientEntryPath?: string;
17
+ styleSrcPath?: string;
15
18
  method?: WebframezCoreRouteMethod | WebframezCoreRouteMethod[];
16
19
  routeOptions?: WebframezCoreRouteRegistrationOptions;
17
20
  }
18
21
 
22
+ export type WebframezReactBuildTarget = {
23
+ path: string;
24
+ routePath: string;
25
+ routeKey: string;
26
+ srcPath: string;
27
+ distRootDir: string;
28
+ pagesDir: string;
29
+ manifestPath: string;
30
+ assetsPrefix?: string;
31
+ rscPath?: string;
32
+ clientScriptUrl?: string;
33
+ clientEntryPath?: string;
34
+ styleSrcPath?: string;
35
+ };
36
+
19
37
  export interface WebframezCoreRouteFacadeExtensions {
20
- renderReact(path: string, options: WebframezCoreReactRenderRouteOptions): void;
21
- reactRender(path: string, options: WebframezCoreReactRenderRouteOptions): void;
38
+ renderReact(path: string, options?: WebframezCoreReactRenderRouteOptions): void;
39
+ reactRender(path: string, options?: WebframezCoreReactRenderRouteOptions): void;
22
40
  }
23
41
 
24
42
  declare module "@webtypen/webframez-core" {
@@ -41,3 +59,9 @@ export function initWebframezReact<T extends RouteFacade>(
41
59
  route: T,
42
60
  ): T & WebframezCoreRouteFacadeExtensions;
43
61
  export const setupWebframezCoreReactRoute: typeof initWebframezReact;
62
+ export function resolveWebframezReactRouteOptions(
63
+ path: string,
64
+ options?: WebframezCoreReactRenderRouteOptions,
65
+ ): CreateNodeHandlerOptions & WebframezReactBuildTarget;
66
+ export function getRegisteredReactBuildTargets(): WebframezReactBuildTarget[];
67
+ export function clearRegisteredReactBuildTargets(): void;