@webtypen/webframez-react 0.0.15 → 0.0.17

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/router.js CHANGED
@@ -8,6 +8,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
8
8
 
9
9
  // src/file-router.tsx
10
10
  import fs from "node:fs";
11
+ import Module from "node:module";
11
12
  import path from "node:path";
12
13
 
13
14
  // src/router-runtime.tsx
@@ -70,6 +71,23 @@ function injectRouteChildren(node, routeChildren) {
70
71
 
71
72
  // src/file-router.tsx
72
73
  import { jsx, jsxs } from "react/jsx-runtime";
74
+ var FORCED_PACKAGE_REQUESTS = [
75
+ "@webtypen/webframez-core",
76
+ "@webtypen/webframez-react",
77
+ "react",
78
+ "react/jsx-runtime",
79
+ "react/jsx-dev-runtime",
80
+ "react-dom",
81
+ "react-dom/client",
82
+ "react-dom/server",
83
+ "react-dom/server.node",
84
+ "react-server-dom-webpack",
85
+ "react-server-dom-webpack/server",
86
+ "react-server-dom-webpack/client",
87
+ "react-server-dom-webpack/client.node",
88
+ "scheduler"
89
+ ];
90
+ var forcedPackageResolutionInstalled = false;
73
91
  function normalizePathname(pathname) {
74
92
  const trimmed = pathname.replace(/\/+$/, "") || "/";
75
93
  return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
@@ -118,6 +136,34 @@ var MANAGED_HEAD_ATTR = "data-webframez-head";
118
136
  function createManagedAttributes() {
119
137
  return `${MANAGED_HEAD_ATTR}="true"`;
120
138
  }
139
+ function shouldForcePackageResolution(request) {
140
+ return FORCED_PACKAGE_REQUESTS.some(
141
+ (candidate) => request === candidate || request.startsWith(`${candidate}/`)
142
+ );
143
+ }
144
+ function installForcedPackageResolution() {
145
+ if (forcedPackageResolutionInstalled) {
146
+ return;
147
+ }
148
+ const moduleWithPrivateResolver = Module;
149
+ const originalResolveFilename = moduleWithPrivateResolver._resolveFilename;
150
+ const rootParent = {
151
+ id: "__webframez_react_runtime__",
152
+ filename: path.join(process.cwd(), "__webframez_react_runtime__.js"),
153
+ path: process.cwd(),
154
+ paths: moduleWithPrivateResolver._nodeModulePaths(process.cwd())
155
+ };
156
+ moduleWithPrivateResolver._resolveFilename = function patchedResolveFilename(request, parent, isMain, options) {
157
+ if (typeof request === "string" && shouldForcePackageResolution(request)) {
158
+ try {
159
+ return originalResolveFilename.call(this, request, rootParent, false, options);
160
+ } catch {
161
+ }
162
+ }
163
+ return originalResolveFilename.call(this, request, parent, isMain, options);
164
+ };
165
+ forcedPackageResolutionInstalled = true;
166
+ }
121
167
  function toRouteEntry(pagesDir, filePath) {
122
168
  const normalized = filePath.replace(/\\/g, "/");
123
169
  if (!normalized.endsWith("/index.js")) {
@@ -265,6 +311,7 @@ function isRouteAbort(value) {
265
311
  }
266
312
  }
267
313
  function createFileRouter(options) {
314
+ installForcedPackageResolution();
268
315
  const pagesDir = options.pagesDir;
269
316
  const layoutPath = path.join(pagesDir, "layout.js");
270
317
  const errorPath = path.join(pagesDir, "errors.js");
@@ -134,28 +134,6 @@ function renderRSCToString(payload, options = {}) {
134
134
  stream.pipe(writable);
135
135
  });
136
136
  }
137
- function createReadableStreamFromString(value) {
138
- const encoder = new TextEncoder();
139
- return new ReadableStream({
140
- start(controller) {
141
- controller.enqueue(encoder.encode(value));
142
- controller.close();
143
- }
144
- });
145
- }
146
- async function renderHtmlFromFlightData(flightData, options) {
147
- const appRequire = (0, import_node_module.createRequire)(import_node_path.default.join(process.cwd(), "__webframez_react_server__.js"));
148
- const reactDomPkg = appRequire.resolve("react-dom/package.json");
149
- const { renderToString } = appRequire(import_node_path.default.join(import_node_path.default.dirname(reactDomPkg), "server.node.js"));
150
- const model = await (0, import_client.createFromReadableStream)(createReadableStreamFromString(flightData), {
151
- serverConsumerManifest: {
152
- moduleMap: options.moduleMap ?? {},
153
- serverModuleMap: null,
154
- moduleLoading: null
155
- }
156
- });
157
- return renderToString(model);
158
- }
159
137
  function sendRSC(res, model, options = {}) {
160
138
  const {
161
139
  moduleMap = {},
@@ -172,6 +150,7 @@ function sendRSC(res, model, options = {}) {
172
150
 
173
151
  // src/file-router.tsx
174
152
  var import_node_fs = __toESM(require("node:fs"), 1);
153
+ var import_node_module2 = __toESM(require("node:module"), 1);
175
154
  var import_node_path2 = __toESM(require("node:path"), 1);
176
155
 
177
156
  // src/router-runtime.tsx
@@ -234,6 +213,23 @@ function injectRouteChildren(node, routeChildren) {
234
213
 
235
214
  // src/file-router.tsx
236
215
  var import_jsx_runtime = require("react/jsx-runtime");
216
+ var FORCED_PACKAGE_REQUESTS = [
217
+ "@webtypen/webframez-core",
218
+ "@webtypen/webframez-react",
219
+ "react",
220
+ "react/jsx-runtime",
221
+ "react/jsx-dev-runtime",
222
+ "react-dom",
223
+ "react-dom/client",
224
+ "react-dom/server",
225
+ "react-dom/server.node",
226
+ "react-server-dom-webpack",
227
+ "react-server-dom-webpack/server",
228
+ "react-server-dom-webpack/client",
229
+ "react-server-dom-webpack/client.node",
230
+ "scheduler"
231
+ ];
232
+ var forcedPackageResolutionInstalled = false;
237
233
  function normalizePathname(pathname) {
238
234
  const trimmed = pathname.replace(/\/+$/, "") || "/";
239
235
  return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
@@ -282,6 +278,34 @@ var MANAGED_HEAD_ATTR = "data-webframez-head";
282
278
  function createManagedAttributes() {
283
279
  return `${MANAGED_HEAD_ATTR}="true"`;
284
280
  }
281
+ function shouldForcePackageResolution(request) {
282
+ return FORCED_PACKAGE_REQUESTS.some(
283
+ (candidate) => request === candidate || request.startsWith(`${candidate}/`)
284
+ );
285
+ }
286
+ function installForcedPackageResolution() {
287
+ if (forcedPackageResolutionInstalled) {
288
+ return;
289
+ }
290
+ const moduleWithPrivateResolver = import_node_module2.default;
291
+ const originalResolveFilename = moduleWithPrivateResolver._resolveFilename;
292
+ const rootParent = {
293
+ id: "__webframez_react_runtime__",
294
+ filename: import_node_path2.default.join(process.cwd(), "__webframez_react_runtime__.js"),
295
+ path: process.cwd(),
296
+ paths: moduleWithPrivateResolver._nodeModulePaths(process.cwd())
297
+ };
298
+ moduleWithPrivateResolver._resolveFilename = function patchedResolveFilename(request, parent, isMain, options) {
299
+ if (typeof request === "string" && shouldForcePackageResolution(request)) {
300
+ try {
301
+ return originalResolveFilename.call(this, request, rootParent, false, options);
302
+ } catch {
303
+ }
304
+ }
305
+ return originalResolveFilename.call(this, request, parent, isMain, options);
306
+ };
307
+ forcedPackageResolutionInstalled = true;
308
+ }
285
309
  function toRouteEntry(pagesDir, filePath) {
286
310
  const normalized = filePath.replace(/\\/g, "/");
287
311
  if (!normalized.endsWith("/index.js")) {
@@ -429,6 +453,7 @@ function isRouteAbort(value) {
429
453
  }
430
454
  }
431
455
  function createFileRouter(options) {
456
+ installForcedPackageResolution();
432
457
  const pagesDir = options.pagesDir;
433
458
  const layoutPath = import_node_path2.default.join(pagesDir, "layout.js");
434
459
  const errorPath = import_node_path2.default.join(pagesDir, "errors.js");
@@ -612,24 +637,46 @@ var INITIAL_HTML_WORKER_SCRIPT = `
612
637
  const path = require("node:path");
613
638
  const Module = require("node:module");
614
639
  const { Writable } = require("node:stream");
640
+ const { createFromReadableStream } = require("react-server-dom-webpack/client.node");
615
641
 
616
642
  const pagesDir = process.env.WEBFRAMEZ_REACT_PAGES_DIR || "";
617
643
  if (!pagesDir) {
618
644
  throw new Error("Missing WEBFRAMEZ_REACT_PAGES_DIR");
619
645
  }
620
646
 
621
- const appRequire = Module.createRequire(path.join(pagesDir, "__webframez_react_worker__.js"));
622
647
  const originalResolveFilename = Module._resolveFilename;
623
- const forcedResolutions = new Map([
624
- ["react", appRequire.resolve("react")],
625
- ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
626
- ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
627
- ["react-dom/client", appRequire.resolve("react-dom/client")]
628
- ]);
648
+ const rootParent = {
649
+ id: "__webframez_react_worker__",
650
+ filename: path.join(process.cwd(), "__webframez_react_worker__.js"),
651
+ path: process.cwd(),
652
+ paths: Module._nodeModulePaths(process.cwd()),
653
+ };
654
+ const forcedPackageRequests = [
655
+ "@webtypen/webframez-core",
656
+ "@webtypen/webframez-react",
657
+ "react",
658
+ "react/jsx-runtime",
659
+ "react/jsx-dev-runtime",
660
+ "react-dom",
661
+ "react-dom/client",
662
+ "react-dom/server",
663
+ "react-dom/server.node",
664
+ "react-server-dom-webpack",
665
+ "react-server-dom-webpack/server",
666
+ "react-server-dom-webpack/client",
667
+ "react-server-dom-webpack/client.node",
668
+ "scheduler"
669
+ ];
670
+
671
+ function shouldForcePackageResolution(request) {
672
+ return forcedPackageRequests.some((candidate) =>
673
+ request === candidate || request.startsWith(candidate + "/")
674
+ );
675
+ }
629
676
 
630
677
  Module._resolveFilename = function(request, parent, isMain, options) {
631
- if (forcedResolutions.has(request)) {
632
- return forcedResolutions.get(request);
678
+ if (typeof request === "string" && shouldForcePackageResolution(request)) {
679
+ return originalResolveFilename.call(this, request, rootParent, false, options);
633
680
  }
634
681
  return originalResolveFilename.call(this, request, parent, isMain, options);
635
682
  };
@@ -676,21 +723,58 @@ function renderHtml(model) {
676
723
  });
677
724
  }
678
725
 
726
+ function createReadableStreamFromString(value) {
727
+ const encoder = new TextEncoder();
728
+
729
+ return new ReadableStream({
730
+ start(controller) {
731
+ controller.enqueue(encoder.encode(value));
732
+ controller.close();
733
+ }
734
+ });
735
+ }
736
+
737
+ async function renderHtmlFromFlightData(flightData, moduleMap) {
738
+ const model = await createFromReadableStream(createReadableStreamFromString(flightData), {
739
+ serverConsumerManifest: {
740
+ moduleMap: moduleMap || {},
741
+ serverModuleMap: null,
742
+ moduleLoading: null
743
+ }
744
+ });
745
+
746
+ return renderHtml(model);
747
+ }
748
+
679
749
  process.on("message", async (message) => {
680
- if (!message || message.type !== "render") {
750
+ if (!message || (message.type !== "render-route" && message.type !== "render-flight")) {
681
751
  return;
682
752
  }
683
753
 
684
- const previousBasename = globalThis.__RSC_BASENAME;
685
- globalThis.__RSC_BASENAME = message.payload.basename || "";
686
-
687
754
  try {
688
- const resolved = await router.resolve({
689
- pathname: message.payload.pathname,
690
- searchParams: message.payload.searchParams || {},
691
- cookies: message.payload.cookies || {},
692
- });
693
- const html = await renderHtml(resolved.model);
755
+ let html = "";
756
+
757
+ if (message.type === "render-route") {
758
+ const previousBasename = globalThis.__RSC_BASENAME;
759
+ globalThis.__RSC_BASENAME = message.payload.basename || "";
760
+
761
+ try {
762
+ const resolved = await router.resolve({
763
+ pathname: message.payload.pathname,
764
+ searchParams: message.payload.searchParams || {},
765
+ cookies: message.payload.cookies || {},
766
+ });
767
+ html = await renderHtml(resolved.model);
768
+ } finally {
769
+ globalThis.__RSC_BASENAME = previousBasename;
770
+ }
771
+ } else {
772
+ html = await renderHtmlFromFlightData(
773
+ message.payload.flightData || "",
774
+ message.payload.moduleMap || {},
775
+ );
776
+ }
777
+
694
778
  if (typeof process.send === "function") {
695
779
  process.send({ id: message.id, ok: true, html });
696
780
  }
@@ -701,8 +785,6 @@ process.on("message", async (message) => {
701
785
  if (typeof process.send === "function") {
702
786
  process.send({ id: message.id, ok: false, error: formatted });
703
787
  }
704
- } finally {
705
- globalThis.__RSC_BASENAME = previousBasename;
706
788
  }
707
789
  });
708
790
  `;
@@ -814,7 +896,35 @@ ${stderrBuffer.trim()}` : "";
814
896
  pending.set(requestId, { resolve, reject, timeout });
815
897
  const request = {
816
898
  id: requestId,
817
- type: "render",
899
+ type: "render-route",
900
+ payload
901
+ };
902
+ activeChild.send(request, (error) => {
903
+ if (!error) {
904
+ return;
905
+ }
906
+ const entry = pending.get(requestId);
907
+ if (!entry) {
908
+ return;
909
+ }
910
+ pending.delete(requestId);
911
+ clearTimeout(entry.timeout);
912
+ entry.reject(error instanceof Error ? error : new Error(String(error)));
913
+ });
914
+ });
915
+ },
916
+ renderFromFlightData(payload) {
917
+ const activeChild = startWorker();
918
+ const requestId = nextRequestId++;
919
+ return new Promise((resolve, reject) => {
920
+ const timeout = setTimeout(() => {
921
+ rejectPending(new Error("[webframez-react] Initial HTML worker timed out"));
922
+ stopWorker();
923
+ }, 1e4);
924
+ pending.set(requestId, { resolve, reject, timeout });
925
+ const request = {
926
+ id: requestId,
927
+ type: "render-flight",
818
928
  payload
819
929
  };
820
930
  activeChild.send(request, (error) => {
@@ -1065,7 +1175,11 @@ function createNodeRequestHandler(options) {
1065
1175
  } catch (retryError) {
1066
1176
  console.error("[webframez-react] Retry for initial HTML failed", retryError);
1067
1177
  try {
1068
- rootHtml = await renderHtmlFromFlightData(initialFlightData, { moduleMap });
1178
+ initialHtmlWorker.dispose();
1179
+ rootHtml = await initialHtmlWorker.renderFromFlightData({
1180
+ flightData: initialFlightData,
1181
+ moduleMap
1182
+ });
1069
1183
  } catch (flightRenderError) {
1070
1184
  console.error("[webframez-react] Flight-to-HTML render failed", flightRenderError);
1071
1185
  res.statusCode = 500;
@@ -106,28 +106,6 @@ function renderRSCToString(payload, options = {}) {
106
106
  stream.pipe(writable);
107
107
  });
108
108
  }
109
- function createReadableStreamFromString(value) {
110
- const encoder = new TextEncoder();
111
- return new ReadableStream({
112
- start(controller) {
113
- controller.enqueue(encoder.encode(value));
114
- controller.close();
115
- }
116
- });
117
- }
118
- async function renderHtmlFromFlightData(flightData, options) {
119
- const appRequire = createRequire(path.join(process.cwd(), "__webframez_react_server__.js"));
120
- const reactDomPkg = appRequire.resolve("react-dom/package.json");
121
- const { renderToString } = appRequire(path.join(path.dirname(reactDomPkg), "server.node.js"));
122
- const model = await createFromReadableStream(createReadableStreamFromString(flightData), {
123
- serverConsumerManifest: {
124
- moduleMap: options.moduleMap ?? {},
125
- serverModuleMap: null,
126
- moduleLoading: null
127
- }
128
- });
129
- return renderToString(model);
130
- }
131
109
  function sendRSC(res, model, options = {}) {
132
110
  const {
133
111
  moduleMap = {},
@@ -144,6 +122,7 @@ function sendRSC(res, model, options = {}) {
144
122
 
145
123
  // src/file-router.tsx
146
124
  import fs from "node:fs";
125
+ import Module from "node:module";
147
126
  import path2 from "node:path";
148
127
 
149
128
  // src/router-runtime.tsx
@@ -206,6 +185,23 @@ function injectRouteChildren(node, routeChildren) {
206
185
 
207
186
  // src/file-router.tsx
208
187
  import { jsx, jsxs } from "react/jsx-runtime";
188
+ var FORCED_PACKAGE_REQUESTS = [
189
+ "@webtypen/webframez-core",
190
+ "@webtypen/webframez-react",
191
+ "react",
192
+ "react/jsx-runtime",
193
+ "react/jsx-dev-runtime",
194
+ "react-dom",
195
+ "react-dom/client",
196
+ "react-dom/server",
197
+ "react-dom/server.node",
198
+ "react-server-dom-webpack",
199
+ "react-server-dom-webpack/server",
200
+ "react-server-dom-webpack/client",
201
+ "react-server-dom-webpack/client.node",
202
+ "scheduler"
203
+ ];
204
+ var forcedPackageResolutionInstalled = false;
209
205
  function normalizePathname(pathname) {
210
206
  const trimmed = pathname.replace(/\/+$/, "") || "/";
211
207
  return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
@@ -254,6 +250,34 @@ var MANAGED_HEAD_ATTR = "data-webframez-head";
254
250
  function createManagedAttributes() {
255
251
  return `${MANAGED_HEAD_ATTR}="true"`;
256
252
  }
253
+ function shouldForcePackageResolution(request) {
254
+ return FORCED_PACKAGE_REQUESTS.some(
255
+ (candidate) => request === candidate || request.startsWith(`${candidate}/`)
256
+ );
257
+ }
258
+ function installForcedPackageResolution() {
259
+ if (forcedPackageResolutionInstalled) {
260
+ return;
261
+ }
262
+ const moduleWithPrivateResolver = Module;
263
+ const originalResolveFilename = moduleWithPrivateResolver._resolveFilename;
264
+ const rootParent = {
265
+ id: "__webframez_react_runtime__",
266
+ filename: path2.join(process.cwd(), "__webframez_react_runtime__.js"),
267
+ path: process.cwd(),
268
+ paths: moduleWithPrivateResolver._nodeModulePaths(process.cwd())
269
+ };
270
+ moduleWithPrivateResolver._resolveFilename = function patchedResolveFilename(request, parent, isMain, options) {
271
+ if (typeof request === "string" && shouldForcePackageResolution(request)) {
272
+ try {
273
+ return originalResolveFilename.call(this, request, rootParent, false, options);
274
+ } catch {
275
+ }
276
+ }
277
+ return originalResolveFilename.call(this, request, parent, isMain, options);
278
+ };
279
+ forcedPackageResolutionInstalled = true;
280
+ }
257
281
  function toRouteEntry(pagesDir, filePath) {
258
282
  const normalized = filePath.replace(/\\/g, "/");
259
283
  if (!normalized.endsWith("/index.js")) {
@@ -401,6 +425,7 @@ function isRouteAbort(value) {
401
425
  }
402
426
  }
403
427
  function createFileRouter(options) {
428
+ installForcedPackageResolution();
404
429
  const pagesDir = options.pagesDir;
405
430
  const layoutPath = path2.join(pagesDir, "layout.js");
406
431
  const errorPath = path2.join(pagesDir, "errors.js");
@@ -584,24 +609,46 @@ var INITIAL_HTML_WORKER_SCRIPT = `
584
609
  const path = require("node:path");
585
610
  const Module = require("node:module");
586
611
  const { Writable } = require("node:stream");
612
+ const { createFromReadableStream } = require("react-server-dom-webpack/client.node");
587
613
 
588
614
  const pagesDir = process.env.WEBFRAMEZ_REACT_PAGES_DIR || "";
589
615
  if (!pagesDir) {
590
616
  throw new Error("Missing WEBFRAMEZ_REACT_PAGES_DIR");
591
617
  }
592
618
 
593
- const appRequire = Module.createRequire(path.join(pagesDir, "__webframez_react_worker__.js"));
594
619
  const originalResolveFilename = Module._resolveFilename;
595
- const forcedResolutions = new Map([
596
- ["react", appRequire.resolve("react")],
597
- ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
598
- ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
599
- ["react-dom/client", appRequire.resolve("react-dom/client")]
600
- ]);
620
+ const rootParent = {
621
+ id: "__webframez_react_worker__",
622
+ filename: path.join(process.cwd(), "__webframez_react_worker__.js"),
623
+ path: process.cwd(),
624
+ paths: Module._nodeModulePaths(process.cwd()),
625
+ };
626
+ const forcedPackageRequests = [
627
+ "@webtypen/webframez-core",
628
+ "@webtypen/webframez-react",
629
+ "react",
630
+ "react/jsx-runtime",
631
+ "react/jsx-dev-runtime",
632
+ "react-dom",
633
+ "react-dom/client",
634
+ "react-dom/server",
635
+ "react-dom/server.node",
636
+ "react-server-dom-webpack",
637
+ "react-server-dom-webpack/server",
638
+ "react-server-dom-webpack/client",
639
+ "react-server-dom-webpack/client.node",
640
+ "scheduler"
641
+ ];
642
+
643
+ function shouldForcePackageResolution(request) {
644
+ return forcedPackageRequests.some((candidate) =>
645
+ request === candidate || request.startsWith(candidate + "/")
646
+ );
647
+ }
601
648
 
602
649
  Module._resolveFilename = function(request, parent, isMain, options) {
603
- if (forcedResolutions.has(request)) {
604
- return forcedResolutions.get(request);
650
+ if (typeof request === "string" && shouldForcePackageResolution(request)) {
651
+ return originalResolveFilename.call(this, request, rootParent, false, options);
605
652
  }
606
653
  return originalResolveFilename.call(this, request, parent, isMain, options);
607
654
  };
@@ -648,21 +695,58 @@ function renderHtml(model) {
648
695
  });
649
696
  }
650
697
 
698
+ function createReadableStreamFromString(value) {
699
+ const encoder = new TextEncoder();
700
+
701
+ return new ReadableStream({
702
+ start(controller) {
703
+ controller.enqueue(encoder.encode(value));
704
+ controller.close();
705
+ }
706
+ });
707
+ }
708
+
709
+ async function renderHtmlFromFlightData(flightData, moduleMap) {
710
+ const model = await createFromReadableStream(createReadableStreamFromString(flightData), {
711
+ serverConsumerManifest: {
712
+ moduleMap: moduleMap || {},
713
+ serverModuleMap: null,
714
+ moduleLoading: null
715
+ }
716
+ });
717
+
718
+ return renderHtml(model);
719
+ }
720
+
651
721
  process.on("message", async (message) => {
652
- if (!message || message.type !== "render") {
722
+ if (!message || (message.type !== "render-route" && message.type !== "render-flight")) {
653
723
  return;
654
724
  }
655
725
 
656
- const previousBasename = globalThis.__RSC_BASENAME;
657
- globalThis.__RSC_BASENAME = message.payload.basename || "";
658
-
659
726
  try {
660
- const resolved = await router.resolve({
661
- pathname: message.payload.pathname,
662
- searchParams: message.payload.searchParams || {},
663
- cookies: message.payload.cookies || {},
664
- });
665
- const html = await renderHtml(resolved.model);
727
+ let html = "";
728
+
729
+ if (message.type === "render-route") {
730
+ const previousBasename = globalThis.__RSC_BASENAME;
731
+ globalThis.__RSC_BASENAME = message.payload.basename || "";
732
+
733
+ try {
734
+ const resolved = await router.resolve({
735
+ pathname: message.payload.pathname,
736
+ searchParams: message.payload.searchParams || {},
737
+ cookies: message.payload.cookies || {},
738
+ });
739
+ html = await renderHtml(resolved.model);
740
+ } finally {
741
+ globalThis.__RSC_BASENAME = previousBasename;
742
+ }
743
+ } else {
744
+ html = await renderHtmlFromFlightData(
745
+ message.payload.flightData || "",
746
+ message.payload.moduleMap || {},
747
+ );
748
+ }
749
+
666
750
  if (typeof process.send === "function") {
667
751
  process.send({ id: message.id, ok: true, html });
668
752
  }
@@ -673,8 +757,6 @@ process.on("message", async (message) => {
673
757
  if (typeof process.send === "function") {
674
758
  process.send({ id: message.id, ok: false, error: formatted });
675
759
  }
676
- } finally {
677
- globalThis.__RSC_BASENAME = previousBasename;
678
760
  }
679
761
  });
680
762
  `;
@@ -786,7 +868,35 @@ ${stderrBuffer.trim()}` : "";
786
868
  pending.set(requestId, { resolve, reject, timeout });
787
869
  const request = {
788
870
  id: requestId,
789
- type: "render",
871
+ type: "render-route",
872
+ payload
873
+ };
874
+ activeChild.send(request, (error) => {
875
+ if (!error) {
876
+ return;
877
+ }
878
+ const entry = pending.get(requestId);
879
+ if (!entry) {
880
+ return;
881
+ }
882
+ pending.delete(requestId);
883
+ clearTimeout(entry.timeout);
884
+ entry.reject(error instanceof Error ? error : new Error(String(error)));
885
+ });
886
+ });
887
+ },
888
+ renderFromFlightData(payload) {
889
+ const activeChild = startWorker();
890
+ const requestId = nextRequestId++;
891
+ return new Promise((resolve, reject) => {
892
+ const timeout = setTimeout(() => {
893
+ rejectPending(new Error("[webframez-react] Initial HTML worker timed out"));
894
+ stopWorker();
895
+ }, 1e4);
896
+ pending.set(requestId, { resolve, reject, timeout });
897
+ const request = {
898
+ id: requestId,
899
+ type: "render-flight",
790
900
  payload
791
901
  };
792
902
  activeChild.send(request, (error) => {
@@ -1037,7 +1147,11 @@ function createNodeRequestHandler(options) {
1037
1147
  } catch (retryError) {
1038
1148
  console.error("[webframez-react] Retry for initial HTML failed", retryError);
1039
1149
  try {
1040
- rootHtml = await renderHtmlFromFlightData(initialFlightData, { moduleMap });
1150
+ initialHtmlWorker.dispose();
1151
+ rootHtml = await initialHtmlWorker.renderFromFlightData({
1152
+ flightData: initialFlightData,
1153
+ moduleMap
1154
+ });
1041
1155
  } catch (flightRenderError) {
1042
1156
  console.error("[webframez-react] Flight-to-HTML render failed", flightRenderError);
1043
1157
  res.statusCode = 500;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webtypen/webframez-react",
3
- "version": "0.0.15",
3
+ "version": "0.0.17",
4
4
  "description": "TypeScript React RSC addition for @webtypen/webframez-core",
5
5
  "homepage": "https://webtypen.de/",
6
6
  "author": {