@webtypen/webframez-react 0.0.29 → 0.0.31

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.
package/dist/index.js CHANGED
@@ -8,10 +8,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
8
8
 
9
9
  // src/server.ts
10
10
  import path from "node:path";
11
- import { Writable } from "node:stream";
11
+ import { Readable, Writable } from "node:stream";
12
12
  import { createRequire } from "node:module";
13
13
  import { renderToPipeableStream } from "react-server-dom-webpack/server";
14
- import { createFromReadableStream } from "react-server-dom-webpack/client.node";
14
+ import * as reactServerDomClientNode from "react-server-dom-webpack/client.node";
15
15
  function defaultOnError(err) {
16
16
  console.error("[webframez-react] RSC render error", err);
17
17
  }
@@ -24,6 +24,7 @@ function createHTMLShell(options = {}) {
24
24
  rootHtml = "",
25
25
  initialFlightData = "",
26
26
  basename = "",
27
+ routeBasePath = "",
27
28
  liveReloadPath,
28
29
  liveReloadServerId
29
30
  } = options;
@@ -72,6 +73,7 @@ function createHTMLShell(options = {}) {
72
73
  <div id="root">${rootHtml}</div>
73
74
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
74
75
  <script>window.__RSC_BASENAME = "${basename}";</script>
76
+ <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
75
77
  <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
76
78
  <script type="module" src="${clientScriptUrl}"></script>
77
79
  ${liveReloadScript}
@@ -150,12 +152,12 @@ import path2 from "node:path";
150
152
  // src/head.ts
151
153
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
152
154
  function normalizeHeadBasename(value) {
153
- const trimmed = value?.trim();
154
- if (!trimmed) {
155
+ if (typeof value !== "string") {
155
156
  return void 0;
156
157
  }
157
- if (trimmed === "/") {
158
- return "/";
158
+ const trimmed = value.trim();
159
+ if (!trimmed || trimmed === "/") {
160
+ return "";
159
161
  }
160
162
  return trimmed.replace(/\/+$/, "");
161
163
  }
@@ -168,6 +170,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
168
170
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
169
171
  return normalizedAssetUrl;
170
172
  }
173
+ if (normalizedAssetUrl.startsWith("/")) {
174
+ return normalizedAssetUrl;
175
+ }
171
176
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
172
177
  return normalizedAssetUrl;
173
178
  }
@@ -184,9 +189,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
184
189
  return void 0;
185
190
  }
186
191
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
192
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
193
+ const normalizedTransportBasePath = normalizeHeadBasename(
194
+ head.transportBasePath
195
+ );
187
196
  const normalizedHead = {
188
197
  ...head,
189
- ...effectiveBasename ? { basename: effectiveBasename } : {}
198
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
199
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
200
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
190
201
  };
191
202
  if (normalizedHead.favicon) {
192
203
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -747,8 +758,8 @@ function createInitialHtmlErrorMarkup(message) {
747
758
  var INITIAL_HTML_WORKER_SCRIPT = `
748
759
  const path = require("node:path");
749
760
  const Module = require("node:module");
750
- const { Writable } = require("node:stream");
751
- const { createFromReadableStream } = require("react-server-dom-webpack/client.node");
761
+ const { Readable, Writable } = require("node:stream");
762
+ const reactServerDomClientNode = require("react-server-dom-webpack/client.node");
752
763
 
753
764
  const originalResolveFilename = Module._resolveFilename;
754
765
  const rootParent = {
@@ -866,14 +877,34 @@ function createReadableStreamFromString(value) {
866
877
  });
867
878
  }
868
879
 
880
+ async function decodeFlightPayloadFromString(flightData, moduleMap) {
881
+ const serverConsumerManifest = {
882
+ moduleMap: moduleMap || {},
883
+ serverModuleMap: null,
884
+ moduleLoading: null
885
+ };
886
+
887
+ if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
888
+ return await reactServerDomClientNode.createFromNodeStream(
889
+ Readable.from([flightData]),
890
+ serverConsumerManifest
891
+ );
892
+ }
893
+
894
+ if (typeof reactServerDomClientNode.createFromReadableStream === "function") {
895
+ return await reactServerDomClientNode.createFromReadableStream(
896
+ createReadableStreamFromString(flightData),
897
+ { serverConsumerManifest }
898
+ );
899
+ }
900
+
901
+ throw new Error(
902
+ "react-server-dom-webpack/client.node does not provide createFromNodeStream or createFromReadableStream."
903
+ );
904
+ }
905
+
869
906
  async function renderHtmlFromFlightData(flightData, moduleMap) {
870
- const payload = await createFromReadableStream(createReadableStreamFromString(flightData), {
871
- serverConsumerManifest: {
872
- moduleMap: moduleMap || {},
873
- serverModuleMap: null,
874
- moduleLoading: null
875
- }
876
- });
907
+ const payload = await decodeFlightPayloadFromString(flightData, moduleMap);
877
908
 
878
909
  const model =
879
910
  payload && typeof payload === "object" && "model" in payload
@@ -980,6 +1011,23 @@ function stripBasePath(pathname, basePath) {
980
1011
  }
981
1012
  return pathname;
982
1013
  }
1014
+ function normalizeRuntimeBasePath(value) {
1015
+ if (typeof value !== "string") {
1016
+ return void 0;
1017
+ }
1018
+ const trimmed = value.trim();
1019
+ if (!trimmed || trimmed === "/") {
1020
+ return "";
1021
+ }
1022
+ return trimmed.replace(/\/+$/, "");
1023
+ }
1024
+ function joinRuntimeBasePath(basePath, pathname) {
1025
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1026
+ if (!basePath) {
1027
+ return normalizedPath;
1028
+ }
1029
+ return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1030
+ }
983
1031
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
984
1032
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
985
1033
  return "";
@@ -1380,6 +1428,14 @@ function createNodeRequestHandler(options) {
1380
1428
  const initialFlightData = await renderRSCToString(initialPayload, {
1381
1429
  moduleMap
1382
1430
  });
1431
+ const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1432
+ const shellClientScriptUrl = joinRuntimeBasePath(
1433
+ transportBasePath,
1434
+ "/assets/client.js"
1435
+ );
1436
+ const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1437
+ const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1438
+ const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1383
1439
  let rootHtml = "";
1384
1440
  try {
1385
1441
  rootHtml = await initialHtmlWorker.renderFromFlightData({
@@ -1410,11 +1466,12 @@ function createNodeRequestHandler(options) {
1410
1466
  createHTMLShell({
1411
1467
  title: "500 - Initial HTML render failed",
1412
1468
  headTags: "",
1413
- clientScriptUrl,
1414
- rscEndpoint: rscPath,
1469
+ clientScriptUrl: shellClientScriptUrl,
1470
+ rscEndpoint: shellRscEndpoint,
1415
1471
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1416
1472
  initialFlightData,
1417
- basename: resolved?.head?.basename ?? basePath,
1473
+ basename: shellBasename,
1474
+ routeBasePath: shellRouteBasePath,
1418
1475
  liveReloadPath: liveReloadPath || void 0,
1419
1476
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1420
1477
  })
@@ -1429,11 +1486,12 @@ function createNodeRequestHandler(options) {
1429
1486
  createHTMLShell({
1430
1487
  title: resolved.head.title || "Webframez React",
1431
1488
  headTags: renderHeadToString(resolved.head),
1432
- clientScriptUrl,
1433
- rscEndpoint: rscPath,
1489
+ clientScriptUrl: shellClientScriptUrl,
1490
+ rscEndpoint: shellRscEndpoint,
1434
1491
  rootHtml,
1435
1492
  initialFlightData,
1436
- basename: resolved.head.basename ?? basePath,
1493
+ basename: shellBasename,
1494
+ routeBasePath: shellRouteBasePath,
1437
1495
  liveReloadPath: liveReloadPath || void 0,
1438
1496
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1439
1497
  })
package/dist/router.cjs CHANGED
@@ -44,12 +44,12 @@ var import_node_path = __toESM(require("node:path"), 1);
44
44
  // src/head.ts
45
45
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
46
46
  function normalizeHeadBasename(value) {
47
- const trimmed = value?.trim();
48
- if (!trimmed) {
47
+ if (typeof value !== "string") {
49
48
  return void 0;
50
49
  }
51
- if (trimmed === "/") {
52
- return "/";
50
+ const trimmed = value.trim();
51
+ if (!trimmed || trimmed === "/") {
52
+ return "";
53
53
  }
54
54
  return trimmed.replace(/\/+$/, "");
55
55
  }
@@ -62,6 +62,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
62
62
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
63
63
  return normalizedAssetUrl;
64
64
  }
65
+ if (normalizedAssetUrl.startsWith("/")) {
66
+ return normalizedAssetUrl;
67
+ }
65
68
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
66
69
  return normalizedAssetUrl;
67
70
  }
@@ -78,9 +81,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
78
81
  return void 0;
79
82
  }
80
83
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
84
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
85
+ const normalizedTransportBasePath = normalizeHeadBasename(
86
+ head.transportBasePath
87
+ );
81
88
  const normalizedHead = {
82
89
  ...head,
83
- ...effectiveBasename ? { basename: effectiveBasename } : {}
90
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
91
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
92
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
84
93
  };
85
94
  if (normalizedHead.favicon) {
86
95
  normalizedHead.favicon = resolveHeadAssetUrl(
package/dist/router.js CHANGED
@@ -14,12 +14,12 @@ import path from "node:path";
14
14
  // src/head.ts
15
15
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
16
16
  function normalizeHeadBasename(value) {
17
- const trimmed = value?.trim();
18
- if (!trimmed) {
17
+ if (typeof value !== "string") {
19
18
  return void 0;
20
19
  }
21
- if (trimmed === "/") {
22
- return "/";
20
+ const trimmed = value.trim();
21
+ if (!trimmed || trimmed === "/") {
22
+ return "";
23
23
  }
24
24
  return trimmed.replace(/\/+$/, "");
25
25
  }
@@ -32,6 +32,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
32
32
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
33
33
  return normalizedAssetUrl;
34
34
  }
35
+ if (normalizedAssetUrl.startsWith("/")) {
36
+ return normalizedAssetUrl;
37
+ }
35
38
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
36
39
  return normalizedAssetUrl;
37
40
  }
@@ -48,9 +51,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
48
51
  return void 0;
49
52
  }
50
53
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
54
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
55
+ const normalizedTransportBasePath = normalizeHeadBasename(
56
+ head.transportBasePath
57
+ );
51
58
  const normalizedHead = {
52
59
  ...head,
53
- ...effectiveBasename ? { basename: effectiveBasename } : {}
60
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
61
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
62
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
54
63
  };
55
64
  if (normalizedHead.favicon) {
56
65
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -45,7 +45,7 @@ var import_node_path = __toESM(require("node:path"), 1);
45
45
  var import_node_stream = require("node:stream");
46
46
  var import_node_module = require("node:module");
47
47
  var import_server = require("react-server-dom-webpack/server");
48
- var import_client = require("react-server-dom-webpack/client.node");
48
+ var reactServerDomClientNode = __toESM(require("react-server-dom-webpack/client.node"), 1);
49
49
  function defaultOnError(err) {
50
50
  console.error("[webframez-react] RSC render error", err);
51
51
  }
@@ -58,6 +58,7 @@ function createHTMLShell(options = {}) {
58
58
  rootHtml = "",
59
59
  initialFlightData = "",
60
60
  basename = "",
61
+ routeBasePath = "",
61
62
  liveReloadPath,
62
63
  liveReloadServerId
63
64
  } = options;
@@ -106,6 +107,7 @@ function createHTMLShell(options = {}) {
106
107
  <div id="root">${rootHtml}</div>
107
108
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
108
109
  <script>window.__RSC_BASENAME = "${basename}";</script>
110
+ <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
109
111
  <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
110
112
  <script type="module" src="${clientScriptUrl}"></script>
111
113
  ${liveReloadScript}
@@ -156,12 +158,12 @@ var import_node_path2 = __toESM(require("node:path"), 1);
156
158
  // src/head.ts
157
159
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
158
160
  function normalizeHeadBasename(value) {
159
- const trimmed = value?.trim();
160
- if (!trimmed) {
161
+ if (typeof value !== "string") {
161
162
  return void 0;
162
163
  }
163
- if (trimmed === "/") {
164
- return "/";
164
+ const trimmed = value.trim();
165
+ if (!trimmed || trimmed === "/") {
166
+ return "";
165
167
  }
166
168
  return trimmed.replace(/\/+$/, "");
167
169
  }
@@ -174,6 +176,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
174
176
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
175
177
  return normalizedAssetUrl;
176
178
  }
179
+ if (normalizedAssetUrl.startsWith("/")) {
180
+ return normalizedAssetUrl;
181
+ }
177
182
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
178
183
  return normalizedAssetUrl;
179
184
  }
@@ -190,9 +195,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
190
195
  return void 0;
191
196
  }
192
197
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
198
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
199
+ const normalizedTransportBasePath = normalizeHeadBasename(
200
+ head.transportBasePath
201
+ );
193
202
  const normalizedHead = {
194
203
  ...head,
195
- ...effectiveBasename ? { basename: effectiveBasename } : {}
204
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
205
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
206
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
196
207
  };
197
208
  if (normalizedHead.favicon) {
198
209
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -749,8 +760,8 @@ function createInitialHtmlErrorMarkup(message) {
749
760
  var INITIAL_HTML_WORKER_SCRIPT = `
750
761
  const path = require("node:path");
751
762
  const Module = require("node:module");
752
- const { Writable } = require("node:stream");
753
- const { createFromReadableStream } = require("react-server-dom-webpack/client.node");
763
+ const { Readable, Writable } = require("node:stream");
764
+ const reactServerDomClientNode = require("react-server-dom-webpack/client.node");
754
765
 
755
766
  const originalResolveFilename = Module._resolveFilename;
756
767
  const rootParent = {
@@ -868,14 +879,34 @@ function createReadableStreamFromString(value) {
868
879
  });
869
880
  }
870
881
 
882
+ async function decodeFlightPayloadFromString(flightData, moduleMap) {
883
+ const serverConsumerManifest = {
884
+ moduleMap: moduleMap || {},
885
+ serverModuleMap: null,
886
+ moduleLoading: null
887
+ };
888
+
889
+ if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
890
+ return await reactServerDomClientNode.createFromNodeStream(
891
+ Readable.from([flightData]),
892
+ serverConsumerManifest
893
+ );
894
+ }
895
+
896
+ if (typeof reactServerDomClientNode.createFromReadableStream === "function") {
897
+ return await reactServerDomClientNode.createFromReadableStream(
898
+ createReadableStreamFromString(flightData),
899
+ { serverConsumerManifest }
900
+ );
901
+ }
902
+
903
+ throw new Error(
904
+ "react-server-dom-webpack/client.node does not provide createFromNodeStream or createFromReadableStream."
905
+ );
906
+ }
907
+
871
908
  async function renderHtmlFromFlightData(flightData, moduleMap) {
872
- const payload = await createFromReadableStream(createReadableStreamFromString(flightData), {
873
- serverConsumerManifest: {
874
- moduleMap: moduleMap || {},
875
- serverModuleMap: null,
876
- moduleLoading: null
877
- }
878
- });
909
+ const payload = await decodeFlightPayloadFromString(flightData, moduleMap);
879
910
 
880
911
  const model =
881
912
  payload && typeof payload === "object" && "model" in payload
@@ -982,6 +1013,23 @@ function stripBasePath(pathname, basePath) {
982
1013
  }
983
1014
  return pathname;
984
1015
  }
1016
+ function normalizeRuntimeBasePath(value) {
1017
+ if (typeof value !== "string") {
1018
+ return void 0;
1019
+ }
1020
+ const trimmed = value.trim();
1021
+ if (!trimmed || trimmed === "/") {
1022
+ return "";
1023
+ }
1024
+ return trimmed.replace(/\/+$/, "");
1025
+ }
1026
+ function joinRuntimeBasePath(basePath, pathname) {
1027
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1028
+ if (!basePath) {
1029
+ return normalizedPath;
1030
+ }
1031
+ return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1032
+ }
985
1033
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
986
1034
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
987
1035
  return "";
@@ -1382,6 +1430,14 @@ function createNodeRequestHandler(options) {
1382
1430
  const initialFlightData = await renderRSCToString(initialPayload, {
1383
1431
  moduleMap
1384
1432
  });
1433
+ const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1434
+ const shellClientScriptUrl = joinRuntimeBasePath(
1435
+ transportBasePath,
1436
+ "/assets/client.js"
1437
+ );
1438
+ const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1439
+ const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1440
+ const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1385
1441
  let rootHtml = "";
1386
1442
  try {
1387
1443
  rootHtml = await initialHtmlWorker.renderFromFlightData({
@@ -1412,11 +1468,12 @@ function createNodeRequestHandler(options) {
1412
1468
  createHTMLShell({
1413
1469
  title: "500 - Initial HTML render failed",
1414
1470
  headTags: "",
1415
- clientScriptUrl,
1416
- rscEndpoint: rscPath,
1471
+ clientScriptUrl: shellClientScriptUrl,
1472
+ rscEndpoint: shellRscEndpoint,
1417
1473
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1418
1474
  initialFlightData,
1419
- basename: resolved?.head?.basename ?? basePath,
1475
+ basename: shellBasename,
1476
+ routeBasePath: shellRouteBasePath,
1420
1477
  liveReloadPath: liveReloadPath || void 0,
1421
1478
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1422
1479
  })
@@ -1431,11 +1488,12 @@ function createNodeRequestHandler(options) {
1431
1488
  createHTMLShell({
1432
1489
  title: resolved.head.title || "Webframez React",
1433
1490
  headTags: renderHeadToString(resolved.head),
1434
- clientScriptUrl,
1435
- rscEndpoint: rscPath,
1491
+ clientScriptUrl: shellClientScriptUrl,
1492
+ rscEndpoint: shellRscEndpoint,
1436
1493
  rootHtml,
1437
1494
  initialFlightData,
1438
- basename: resolved.head.basename ?? basePath,
1495
+ basename: shellBasename,
1496
+ routeBasePath: shellRouteBasePath,
1439
1497
  liveReloadPath: liveReloadPath || void 0,
1440
1498
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1441
1499
  })
@@ -14,10 +14,10 @@ import { spawn } from "node:child_process";
14
14
 
15
15
  // src/server.ts
16
16
  import path from "node:path";
17
- import { Writable } from "node:stream";
17
+ import { Readable, Writable } from "node:stream";
18
18
  import { createRequire } from "node:module";
19
19
  import { renderToPipeableStream } from "react-server-dom-webpack/server";
20
- import { createFromReadableStream } from "react-server-dom-webpack/client.node";
20
+ import * as reactServerDomClientNode from "react-server-dom-webpack/client.node";
21
21
  function defaultOnError(err) {
22
22
  console.error("[webframez-react] RSC render error", err);
23
23
  }
@@ -30,6 +30,7 @@ function createHTMLShell(options = {}) {
30
30
  rootHtml = "",
31
31
  initialFlightData = "",
32
32
  basename = "",
33
+ routeBasePath = "",
33
34
  liveReloadPath,
34
35
  liveReloadServerId
35
36
  } = options;
@@ -78,6 +79,7 @@ function createHTMLShell(options = {}) {
78
79
  <div id="root">${rootHtml}</div>
79
80
  <script>window.__RSC_ENDPOINT = "${rscEndpoint}";</script>
80
81
  <script>window.__RSC_BASENAME = "${basename}";</script>
82
+ <script>window.__RSC_ROUTE_BASE_PATH = "${routeBasePath}";</script>
81
83
  <script>window.__RSC_INITIAL_PAYLOAD = ${escapedInitialFlightData};</script>
82
84
  <script type="module" src="${clientScriptUrl}"></script>
83
85
  ${liveReloadScript}
@@ -128,12 +130,12 @@ import path2 from "node:path";
128
130
  // src/head.ts
129
131
  var ABSOLUTE_ASSET_URL_PATTERN = /^(?:[a-zA-Z][a-zA-Z\d+\-.]*:|\/\/|#)/;
130
132
  function normalizeHeadBasename(value) {
131
- const trimmed = value?.trim();
132
- if (!trimmed) {
133
+ if (typeof value !== "string") {
133
134
  return void 0;
134
135
  }
135
- if (trimmed === "/") {
136
- return "/";
136
+ const trimmed = value.trim();
137
+ if (!trimmed || trimmed === "/") {
138
+ return "";
137
139
  }
138
140
  return trimmed.replace(/\/+$/, "");
139
141
  }
@@ -146,6 +148,9 @@ function resolveHeadAssetUrl(assetUrl, basename) {
146
148
  if (ABSOLUTE_ASSET_URL_PATTERN.test(normalizedAssetUrl)) {
147
149
  return normalizedAssetUrl;
148
150
  }
151
+ if (normalizedAssetUrl.startsWith("/")) {
152
+ return normalizedAssetUrl;
153
+ }
149
154
  if (normalizedBasename !== "/" && (normalizedAssetUrl === normalizedBasename || normalizedAssetUrl.startsWith(`${normalizedBasename}/`))) {
150
155
  return normalizedAssetUrl;
151
156
  }
@@ -162,9 +167,15 @@ function normalizeHeadConfig(head, inheritedBasename) {
162
167
  return void 0;
163
168
  }
164
169
  const effectiveBasename = normalizeHeadBasename(head.basename) ?? normalizeHeadBasename(inheritedBasename);
170
+ const normalizedRouteBasePath = normalizeHeadBasename(head.routeBasePath);
171
+ const normalizedTransportBasePath = normalizeHeadBasename(
172
+ head.transportBasePath
173
+ );
165
174
  const normalizedHead = {
166
175
  ...head,
167
- ...effectiveBasename ? { basename: effectiveBasename } : {}
176
+ ...effectiveBasename !== void 0 ? { basename: effectiveBasename } : {},
177
+ ...normalizedRouteBasePath !== void 0 ? { routeBasePath: normalizedRouteBasePath } : {},
178
+ ...normalizedTransportBasePath !== void 0 ? { transportBasePath: normalizedTransportBasePath } : {}
168
179
  };
169
180
  if (normalizedHead.favicon) {
170
181
  normalizedHead.favicon = resolveHeadAssetUrl(
@@ -721,8 +732,8 @@ function createInitialHtmlErrorMarkup(message) {
721
732
  var INITIAL_HTML_WORKER_SCRIPT = `
722
733
  const path = require("node:path");
723
734
  const Module = require("node:module");
724
- const { Writable } = require("node:stream");
725
- const { createFromReadableStream } = require("react-server-dom-webpack/client.node");
735
+ const { Readable, Writable } = require("node:stream");
736
+ const reactServerDomClientNode = require("react-server-dom-webpack/client.node");
726
737
 
727
738
  const originalResolveFilename = Module._resolveFilename;
728
739
  const rootParent = {
@@ -840,14 +851,34 @@ function createReadableStreamFromString(value) {
840
851
  });
841
852
  }
842
853
 
854
+ async function decodeFlightPayloadFromString(flightData, moduleMap) {
855
+ const serverConsumerManifest = {
856
+ moduleMap: moduleMap || {},
857
+ serverModuleMap: null,
858
+ moduleLoading: null
859
+ };
860
+
861
+ if (typeof reactServerDomClientNode.createFromNodeStream === "function") {
862
+ return await reactServerDomClientNode.createFromNodeStream(
863
+ Readable.from([flightData]),
864
+ serverConsumerManifest
865
+ );
866
+ }
867
+
868
+ if (typeof reactServerDomClientNode.createFromReadableStream === "function") {
869
+ return await reactServerDomClientNode.createFromReadableStream(
870
+ createReadableStreamFromString(flightData),
871
+ { serverConsumerManifest }
872
+ );
873
+ }
874
+
875
+ throw new Error(
876
+ "react-server-dom-webpack/client.node does not provide createFromNodeStream or createFromReadableStream."
877
+ );
878
+ }
879
+
843
880
  async function renderHtmlFromFlightData(flightData, moduleMap) {
844
- const payload = await createFromReadableStream(createReadableStreamFromString(flightData), {
845
- serverConsumerManifest: {
846
- moduleMap: moduleMap || {},
847
- serverModuleMap: null,
848
- moduleLoading: null
849
- }
850
- });
881
+ const payload = await decodeFlightPayloadFromString(flightData, moduleMap);
851
882
 
852
883
  const model =
853
884
  payload && typeof payload === "object" && "model" in payload
@@ -954,6 +985,23 @@ function stripBasePath(pathname, basePath) {
954
985
  }
955
986
  return pathname;
956
987
  }
988
+ function normalizeRuntimeBasePath(value) {
989
+ if (typeof value !== "string") {
990
+ return void 0;
991
+ }
992
+ const trimmed = value.trim();
993
+ if (!trimmed || trimmed === "/") {
994
+ return "";
995
+ }
996
+ return trimmed.replace(/\/+$/, "");
997
+ }
998
+ function joinRuntimeBasePath(basePath, pathname) {
999
+ const normalizedPath = !pathname || pathname === "/" ? "/" : pathname.startsWith("/") ? pathname : `/${pathname}`;
1000
+ if (!basePath) {
1001
+ return normalizedPath;
1002
+ }
1003
+ return normalizedPath === "/" ? basePath : `${basePath}${normalizedPath}`;
1004
+ }
957
1005
  function sanitizeInitialHtmlWorkerNodeOptions(rawNodeOptions) {
958
1006
  if (!rawNodeOptions || rawNodeOptions.trim() === "") {
959
1007
  return "";
@@ -1354,6 +1402,14 @@ function createNodeRequestHandler(options) {
1354
1402
  const initialFlightData = await renderRSCToString(initialPayload, {
1355
1403
  moduleMap
1356
1404
  });
1405
+ const transportBasePath = normalizeRuntimeBasePath(resolved.head.transportBasePath) ?? normalizeRuntimeBasePath(basePath) ?? "";
1406
+ const shellClientScriptUrl = joinRuntimeBasePath(
1407
+ transportBasePath,
1408
+ "/assets/client.js"
1409
+ );
1410
+ const shellRscEndpoint = joinRuntimeBasePath(transportBasePath, "/rsc");
1411
+ const shellBasename = normalizeRuntimeBasePath(resolved.head.basename) ?? normalizeRuntimeBasePath(basePath) ?? "";
1412
+ const shellRouteBasePath = normalizeRuntimeBasePath(resolved.head.routeBasePath) ?? "";
1357
1413
  let rootHtml = "";
1358
1414
  try {
1359
1415
  rootHtml = await initialHtmlWorker.renderFromFlightData({
@@ -1384,11 +1440,12 @@ function createNodeRequestHandler(options) {
1384
1440
  createHTMLShell({
1385
1441
  title: "500 - Initial HTML render failed",
1386
1442
  headTags: "",
1387
- clientScriptUrl,
1388
- rscEndpoint: rscPath,
1443
+ clientScriptUrl: shellClientScriptUrl,
1444
+ rscEndpoint: shellRscEndpoint,
1389
1445
  rootHtml: createInitialHtmlErrorMarkup("Initial HTML render failed."),
1390
1446
  initialFlightData,
1391
- basename: resolved?.head?.basename ?? basePath,
1447
+ basename: shellBasename,
1448
+ routeBasePath: shellRouteBasePath,
1392
1449
  liveReloadPath: liveReloadPath || void 0,
1393
1450
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1394
1451
  })
@@ -1403,11 +1460,12 @@ function createNodeRequestHandler(options) {
1403
1460
  createHTMLShell({
1404
1461
  title: resolved.head.title || "Webframez React",
1405
1462
  headTags: renderHeadToString(resolved.head),
1406
- clientScriptUrl,
1407
- rscEndpoint: rscPath,
1463
+ clientScriptUrl: shellClientScriptUrl,
1464
+ rscEndpoint: shellRscEndpoint,
1408
1465
  rootHtml,
1409
1466
  initialFlightData,
1410
- basename: resolved.head.basename ?? basePath,
1467
+ basename: shellBasename,
1468
+ routeBasePath: shellRouteBasePath,
1411
1469
  liveReloadPath: liveReloadPath || void 0,
1412
1470
  liveReloadServerId: liveReloadPath ? devServerId : void 0
1413
1471
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webtypen/webframez-react",
3
- "version": "0.0.29",
3
+ "version": "0.0.31",
4
4
  "description": "TypeScript React RSC addition for @webtypen/webframez-core",
5
5
  "homepage": "https://webtypen.de/",
6
6
  "author": {