@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/http.cjs +159 -45
- package/dist/http.js +159 -45
- package/dist/index.cjs +159 -45
- package/dist/index.js +159 -45
- package/dist/router.cjs +47 -0
- package/dist/router.js +47 -0
- package/dist/webframez-core.cjs +159 -45
- package/dist/webframez-core.js +159 -45
- package/package.json +1 -1
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");
|
package/dist/webframez-core.cjs
CHANGED
|
@@ -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
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
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 (
|
|
632
|
-
return
|
|
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
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
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
|
-
|
|
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;
|
package/dist/webframez-core.js
CHANGED
|
@@ -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
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
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 (
|
|
604
|
-
return
|
|
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
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
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
|
-
|
|
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;
|