@webtypen/webframez-react 0.0.1 → 0.0.2

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/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  React Server Components (RSC) extension for `@webtypen/webframez-core`.
4
4
 
5
5
  `webframez-react` provides:
6
+
6
7
  - seamless `webframez-core` integration via `initWebframezReact(Route)`
7
8
  - file-based routing for `pages/**/index.tsx`
8
9
  - layout/error handling with `RouteChildren`
@@ -19,28 +20,135 @@ React Server Components (RSC) extension for `@webtypen/webframez-core`.
19
20
 
20
21
  ```bash
21
22
  npm i @webtypen/webframez-react @webtypen/webframez-core react react-dom react-server-dom-webpack
23
+ npm i -D typescript webpack webpack-cli ts-loader
22
24
  ```
23
25
 
24
26
  ## Quick Start with webframez-core
25
27
 
26
28
  ```ts
27
29
  // server.ts
28
- import { WebApplication, Route } from "@webtypen/webframez-core";
30
+ import { BaseKernelWeb, Route, WebApplication } from "@webtypen/webframez-core";
29
31
  import { initWebframezReact } from "@webtypen/webframez-react/webframez-core";
30
32
 
33
+ class Kernel extends BaseKernelWeb {
34
+ static controller = {};
35
+ static middleware = {};
36
+ }
37
+
31
38
  initWebframezReact(Route);
32
39
 
33
- Route.renderReact("/react", {
34
- distRootDir: `${process.cwd()}/dist`,
40
+ const app = new WebApplication();
41
+ app.boot({
42
+ kernel: Kernel,
43
+ routesFunction: () => {
44
+ Route.renderReact("/react", {
45
+ distRootDir: `${process.cwd()}/dist`,
46
+ });
47
+ },
35
48
  });
36
-
37
- WebApplication.boot();
38
49
  ```
39
50
 
40
51
  Notes:
52
+
41
53
  - `"/react"` is automatically registered as a catch-all route (`/react/*`).
42
54
  - `basePath`, `assetsPrefix`, `rscPath`, and `clientScriptUrl` are derived automatically from the mount path.
43
55
 
56
+ ## Add to an Existing webframez-core Project
57
+
58
+ If you already have a running `@webtypen/webframez-core` app, this is the smallest setup to mount React and return a first JSX page.
59
+
60
+ 1. Install dependencies:
61
+
62
+ ```bash
63
+ npm i @webtypen/webframez-react react react-dom react-server-dom-webpack
64
+ npm i -D typescript webpack webpack-cli ts-loader
65
+ ```
66
+
67
+ 2. Extend `Route` and mount React inside your existing `routesFunction`:
68
+
69
+ ```ts
70
+ // server.ts
71
+ import path from "node:path";
72
+ import { BaseKernelWeb, Route, WebApplication } from "@webtypen/webframez-core";
73
+ import { initWebframezReact } from "@webtypen/webframez-react/webframez-core";
74
+
75
+ class Kernel extends BaseKernelWeb {
76
+ static controller = {};
77
+ static middleware = {};
78
+ }
79
+
80
+ initWebframezReact(Route);
81
+
82
+ const app = new WebApplication();
83
+ app.boot({
84
+ kernel: Kernel,
85
+ port: 3000,
86
+ routesFunction: () => {
87
+ // Your existing core routes can stay here.
88
+ Route.renderReact("/app", {
89
+ distRootDir: path.resolve(process.cwd(), "dist"),
90
+ });
91
+ },
92
+ });
93
+ ```
94
+
95
+ 3. Create a minimal file-router page setup:
96
+
97
+ ```tsx
98
+ // pages/layout.tsx
99
+ "use server";
100
+
101
+ import React from "react";
102
+ import { RouteChildren } from "@webtypen/webframez-react/router";
103
+
104
+ export default function Layout() {
105
+ return (
106
+ <main>
107
+ <RouteChildren />
108
+ </main>
109
+ );
110
+ }
111
+ ```
112
+
113
+ ```tsx
114
+ // pages/index.tsx
115
+ "use server";
116
+
117
+ import React from "react";
118
+
119
+ export default function HomePage() {
120
+ return <h1>Hello from webframez-react + JSX</h1>;
121
+ }
122
+ ```
123
+
124
+ 4. Create the client entry:
125
+
126
+ ```tsx
127
+ // src/client.tsx
128
+ import { mountWebframezClient } from "@webtypen/webframez-react/client";
129
+
130
+ mountWebframezClient();
131
+ ```
132
+
133
+ 5. Add build scripts (with automatic config fallback):
134
+
135
+ ```json
136
+ {
137
+ "scripts": {
138
+ "build:server": "webframez-react build:server",
139
+ "build:client": "webframez-react build:client",
140
+ "build": "npm run build:server && npm run build:client",
141
+ "watch:server": "webframez-react watch:server",
142
+ "watch:client": "webframez-react watch:client",
143
+ "serve:watch": "node --watch --conditions react-server start-server.cjs",
144
+ "watch": "sh -c 'npm run watch:server & npm run watch:client & npm run serve:watch & wait'",
145
+ "dev": "sh -c 'npm run watch:server & npm run watch:client & npm run serve:watch & wait'"
146
+ }
147
+ }
148
+ ```
149
+
150
+ After build, your first page is available at `http://localhost:3000/app`.
151
+
44
152
  ## Page Structure (File-Based Routing)
45
153
 
46
154
  Example:
@@ -60,7 +168,7 @@ pages/
60
168
  "use server";
61
169
 
62
170
  import React from "react";
63
- import { RouteChildren } from "webframez-react/router";
171
+ import { RouteChildren } from "@webtypen/webframez-react/router";
64
172
 
65
173
  export default function Layout() {
66
174
  return (
@@ -81,7 +189,7 @@ Every server page gets `abort()` via `RouteContext`.
81
189
  ```tsx
82
190
  "use server";
83
191
 
84
- import type { PageProps } from "webframez-react/types";
192
+ import type { PageProps } from "@webtypen/webframez-react/types";
85
193
 
86
194
  export default function AccountPage({ params, abort }: PageProps) {
87
195
  if (params.username !== "jane") {
@@ -97,6 +205,7 @@ export default function AccountPage({ params, abort }: PageProps) {
97
205
  ```
98
206
 
99
207
  Behavior:
208
+
100
209
  - default without options: `404` + `"Page not found"`
101
210
  - rendered through `pages/errors.tsx` (same behavior as unmatched routes)
102
211
  - `pathname` is provided automatically by context
@@ -106,7 +215,7 @@ Behavior:
106
215
 
107
216
  ```tsx
108
217
  // src/client.tsx
109
- import { mountWebframezClient } from "webframez-react/client";
218
+ import { mountWebframezClient } from "@webtypen/webframez-react/client";
110
219
 
111
220
  mountWebframezClient();
112
221
  ```
@@ -126,7 +235,7 @@ mountWebframezClient({
126
235
  "use client";
127
236
 
128
237
  import React from "react";
129
- import { Link, Redirect } from "webframez-react/navigation";
238
+ import { Link, Redirect } from "@webtypen/webframez-react/navigation";
130
239
 
131
240
  export function Nav() {
132
241
  return (
@@ -147,6 +256,7 @@ export function Guard({ loggedIn }: { loggedIn: boolean }) {
147
256
  ```
148
257
 
149
258
  Note:
259
+
150
260
  - `Link` and `Redirect` automatically use the basename from `Route.renderReact()`.
151
261
  - You can override it per usage via `basename`.
152
262
 
@@ -156,7 +266,7 @@ Note:
156
266
  "use client";
157
267
 
158
268
  import React from "react";
159
- import { useCookie, useRouter } from "webframez-react/client";
269
+ import { useCookie, useRouter } from "@webtypen/webframez-react/client";
160
270
 
161
271
  export default function LoginAction() {
162
272
  const cookie = useCookie();
@@ -177,17 +287,17 @@ export default function LoginAction() {
177
287
 
178
288
  ## Public Entrypoints
179
289
 
180
- - `webframez-react`
290
+ - `@webtypen/webframez-react`
181
291
  - `createNodeRequestHandler`, `createFileRouter`, `createHTMLShell`, `sendRSC`, `createRSCHandler`
182
- - `webframez-react/webframez-core`
292
+ - `@webtypen/webframez-react/webframez-core`
183
293
  - `initWebframezReact`
184
- - `webframez-react/router`
294
+ - `@webtypen/webframez-react/router`
185
295
  - `RouteChildren`
186
- - `webframez-react/client`
296
+ - `@webtypen/webframez-react/client`
187
297
  - `mountWebframezClient`, `useRouter`, `useCookie`
188
- - `webframez-react/navigation`
298
+ - `@webtypen/webframez-react/navigation`
189
299
  - `Link`, `Redirect`
190
- - `webframez-react/types`
300
+ - `@webtypen/webframez-react/types`
191
301
  - all public types (`RouteContext`, `PageProps`, `ErrorPageProps`, ...)
192
302
 
193
303
  ## package.json Scripts
@@ -197,22 +307,31 @@ Example scripts for a `webframez-react` app:
197
307
  ```json
198
308
  {
199
309
  "scripts": {
200
- "build:server": "tsc -p tsconfig.server.json",
201
- "build:client": "webpack --config webpack.client.cjs",
310
+ "build:server": "webframez-react build:server",
311
+ "build:client": "webframez-react build:client",
202
312
  "build": "npm run build:server && npm run build:client",
203
313
  "start": "node --conditions react-server start-server.cjs",
204
- "watch:server": "tsc -p tsconfig.server.json --watch --preserveWatchOutput",
205
- "watch:client": "webpack --config webpack.client.cjs --watch",
314
+ "watch:server": "webframez-react watch:server",
315
+ "watch:client": "webframez-react watch:client",
206
316
  "serve:watch": "node --watch --conditions react-server start-server.cjs",
317
+ "watch": "sh -c 'npm run watch:server & npm run watch:client & npm run serve:watch & wait'",
207
318
  "dev": "sh -c 'npm run watch:server & npm run watch:client & npm run serve:watch & wait'"
208
319
  }
209
320
  }
210
321
  ```
211
322
 
212
323
  Notes:
324
+
325
+ - `webframez-react` CLI first checks project overrides and falls back to package defaults:
326
+ - `tsconfig.server.json`
327
+ - `webpack.client.cjs`
328
+ - `webpack.server.cjs`
329
+ - `webpack.server.cjs` is optional. Default flow compiles server with `tsc`. Use webpack-server only if you explicitly want a bundled server build:
330
+ - `webframez-react build:server:webpack`
331
+ - `webframez-react watch:server:webpack`
213
332
  - `build` compiles server output (`pages`, `server.ts`) and client output (`client.tsx` bundle + RSC manifests).
214
333
  - `start` runs the built app in React Server mode.
215
- - `dev` enables watch mode for TypeScript and webpack and restarts Node automatically on server output changes.
334
+ - `watch` and `dev` run the same full watch pipeline and restart Node automatically on server output changes.
216
335
 
217
336
  ## Build
218
337
 
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { spawn } from "node:child_process";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ const binFilePath = fileURLToPath(import.meta.url);
9
+ const packageRoot = path.resolve(path.dirname(binFilePath), "..");
10
+ const projectRoot = process.cwd();
11
+
12
+ const command = process.argv[2];
13
+ const passthroughStart = process.argv[3] === "--" ? 4 : 3;
14
+ const passthroughArgs = process.argv.slice(passthroughStart);
15
+
16
+ function printHelp() {
17
+ console.log(
18
+ [
19
+ "webframez-react CLI",
20
+ "",
21
+ "Usage:",
22
+ " webframez-react build:server",
23
+ " webframez-react watch:server",
24
+ " webframez-react build:client",
25
+ " webframez-react watch:client",
26
+ " webframez-react build:server:webpack",
27
+ " webframez-react watch:server:webpack",
28
+ "",
29
+ "Config fallback order:",
30
+ " 1) project root override file",
31
+ " 2) package default in @webtypen/webframez-react/defaults",
32
+ "",
33
+ "Override file names:",
34
+ " - tsconfig.server.json",
35
+ " - webpack.client.cjs",
36
+ " - webpack.server.cjs",
37
+ ].join("\n"),
38
+ );
39
+ }
40
+
41
+ function hasFlag(flag) {
42
+ return passthroughArgs.includes(flag);
43
+ }
44
+
45
+ function resolveConfig(localFileName, fallbackFileName) {
46
+ const localPath = path.resolve(projectRoot, localFileName);
47
+ if (fs.existsSync(localPath)) {
48
+ return {
49
+ path: localPath,
50
+ source: "project",
51
+ name: localFileName,
52
+ };
53
+ }
54
+
55
+ return {
56
+ path: path.resolve(packageRoot, "defaults", fallbackFileName),
57
+ source: "package",
58
+ name: fallbackFileName,
59
+ };
60
+ }
61
+
62
+ function resolveBinary(name) {
63
+ const extension = process.platform === "win32" ? ".cmd" : "";
64
+ const localBinary = path.resolve(projectRoot, "node_modules", ".bin", `${name}${extension}`);
65
+ if (fs.existsSync(localBinary)) {
66
+ return localBinary;
67
+ }
68
+
69
+ return name;
70
+ }
71
+
72
+ function run(binaryName, args) {
73
+ const binary = resolveBinary(binaryName);
74
+
75
+ return new Promise((resolve, reject) => {
76
+ const child = spawn(binary, args, {
77
+ cwd: projectRoot,
78
+ stdio: "inherit",
79
+ shell: false,
80
+ });
81
+
82
+ child.on("error", (error) => {
83
+ reject(error);
84
+ });
85
+
86
+ child.on("close", (code) => {
87
+ resolve(code || 0);
88
+ });
89
+ });
90
+ }
91
+
92
+ async function main() {
93
+ if (!command || command === "--help" || command === "-h") {
94
+ printHelp();
95
+ return;
96
+ }
97
+
98
+ if (command === "build:server" || command === "watch:server") {
99
+ const config = resolveConfig("tsconfig.server.json", "tsconfig.server.json");
100
+ console.log(`[webframez-react] tsc config (${config.source}): ${config.path}`);
101
+
102
+ const args = ["-p", config.path, ...passthroughArgs];
103
+ if (command === "watch:server") {
104
+ if (!hasFlag("--watch")) {
105
+ args.push("--watch");
106
+ }
107
+ if (!hasFlag("--preserveWatchOutput")) {
108
+ args.push("--preserveWatchOutput");
109
+ }
110
+ }
111
+
112
+ const code = await run("tsc", args);
113
+ process.exit(code);
114
+ return;
115
+ }
116
+
117
+ if (command === "build:client" || command === "watch:client") {
118
+ const config = resolveConfig("webpack.client.cjs", "webpack.client.cjs");
119
+ console.log(`[webframez-react] webpack config (${config.source}): ${config.path}`);
120
+
121
+ const args = ["--config", config.path, ...passthroughArgs];
122
+ if (command === "watch:client" && !hasFlag("--watch")) {
123
+ args.push("--watch");
124
+ }
125
+
126
+ const code = await run("webpack", args);
127
+ process.exit(code);
128
+ return;
129
+ }
130
+
131
+ if (command === "build:server:webpack" || command === "watch:server:webpack") {
132
+ const config = resolveConfig("webpack.server.cjs", "webpack.server.cjs");
133
+ console.log(`[webframez-react] webpack server config (${config.source}): ${config.path}`);
134
+
135
+ const args = ["--config", config.path, ...passthroughArgs];
136
+ if (command === "watch:server:webpack" && !hasFlag("--watch")) {
137
+ args.push("--watch");
138
+ }
139
+
140
+ const code = await run("webpack", args);
141
+ process.exit(code);
142
+ return;
143
+ }
144
+
145
+ console.error(`[webframez-react] Unknown command: ${command}`);
146
+ printHelp();
147
+ process.exit(1);
148
+ }
149
+
150
+ main().catch((error) => {
151
+ console.error("[webframez-react] Build command failed.");
152
+ if (error && typeof error === "object" && "message" in error) {
153
+ console.error(String(error.message));
154
+ } else {
155
+ console.error(error);
156
+ }
157
+ process.exit(1);
158
+ });
@@ -0,0 +1,51 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "CommonJS",
5
+ "moduleResolution": "Node",
6
+ "baseUrl": ".",
7
+ "paths": {
8
+ "@webtypen/webframez-react/types": [
9
+ "./node_modules/@webtypen/webframez-react/dist/types.d.ts"
10
+ ],
11
+ "@webtypen/webframez-react/router": [
12
+ "./node_modules/@webtypen/webframez-react/dist/router.d.ts"
13
+ ],
14
+ "@webtypen/webframez-react/client": [
15
+ "./node_modules/@webtypen/webframez-react/dist/client.d.ts"
16
+ ],
17
+ "@webtypen/webframez-react/navigation": [
18
+ "./node_modules/@webtypen/webframez-react/dist/navigation.d.ts"
19
+ ],
20
+ "webframez-react/types": [
21
+ "./node_modules/@webtypen/webframez-react/dist/types.d.ts"
22
+ ],
23
+ "webframez-react/router": [
24
+ "./node_modules/@webtypen/webframez-react/dist/router.d.ts"
25
+ ],
26
+ "webframez-react/client": [
27
+ "./node_modules/@webtypen/webframez-react/dist/client.d.ts"
28
+ ],
29
+ "webframez-react/navigation": [
30
+ "./node_modules/@webtypen/webframez-react/dist/navigation.d.ts"
31
+ ]
32
+ },
33
+ "jsx": "react-jsx",
34
+ "strict": true,
35
+ "esModuleInterop": true,
36
+ "skipLibCheck": true,
37
+ "outDir": "dist",
38
+ "rootDir": "."
39
+ },
40
+ "include": [
41
+ "src/server.ts",
42
+ "src/components/**/*.tsx",
43
+ "pages/**/*.tsx",
44
+ "src/types.d.ts"
45
+ ],
46
+ "exclude": [
47
+ "src/client.tsx",
48
+ "dist",
49
+ "node_modules"
50
+ ]
51
+ }
@@ -0,0 +1,61 @@
1
+ const path = require("path");
2
+ const ReactFlightWebpackPlugin = require("react-server-dom-webpack/plugin");
3
+
4
+ const projectRoot = process.cwd();
5
+ const frameworkDistDir = path.resolve(__dirname, "..", "dist");
6
+
7
+ module.exports = {
8
+ mode: process.env.NODE_ENV === "production" ? "production" : "development",
9
+ entry: {
10
+ client: path.resolve(projectRoot, "src/client.tsx"),
11
+ },
12
+ output: {
13
+ path: path.resolve(projectRoot, "dist"),
14
+ filename: "[name].js",
15
+ chunkFilename: "chunks/[name]-[contenthash].js",
16
+ publicPath: "auto",
17
+ },
18
+ resolve: {
19
+ extensions: [".tsx", ".ts", ".js"],
20
+ },
21
+ module: {
22
+ rules: [
23
+ {
24
+ test: /\.[tj]sx?$/,
25
+ exclude: /node_modules/,
26
+ use: {
27
+ loader: "ts-loader",
28
+ options: {
29
+ transpileOnly: true,
30
+ },
31
+ },
32
+ },
33
+ ],
34
+ },
35
+ optimization: {
36
+ splitChunks: false,
37
+ runtimeChunk: false,
38
+ },
39
+ plugins: [
40
+ new ReactFlightWebpackPlugin({
41
+ isServer: false,
42
+ clientReferences: [
43
+ {
44
+ directory: path.resolve(projectRoot, "dist/pages"),
45
+ recursive: true,
46
+ include: /\.js$/,
47
+ },
48
+ {
49
+ directory: path.resolve(projectRoot, "dist/src/components"),
50
+ recursive: true,
51
+ include: /\.js$/,
52
+ },
53
+ {
54
+ directory: frameworkDistDir,
55
+ recursive: false,
56
+ include: /navigation\.(js|cjs)$/,
57
+ },
58
+ ],
59
+ }),
60
+ ],
61
+ };
@@ -0,0 +1,33 @@
1
+ const path = require("path");
2
+
3
+ const projectRoot = process.cwd();
4
+
5
+ module.exports = {
6
+ mode: process.env.NODE_ENV === "production" ? "production" : "development",
7
+ target: "node",
8
+ entry: path.resolve(projectRoot, "src/server.ts"),
9
+ output: {
10
+ path: path.resolve(projectRoot, "dist"),
11
+ filename: "server.cjs",
12
+ libraryTarget: "commonjs2",
13
+ },
14
+ resolve: {
15
+ extensions: [".tsx", ".ts", ".js"],
16
+ conditionNames: ["react-server", "node", "import", "require", "default"],
17
+ },
18
+ module: {
19
+ rules: [
20
+ {
21
+ test: /\.[tj]sx?$/,
22
+ exclude: /node_modules/,
23
+ use: {
24
+ loader: "ts-loader",
25
+ options: {
26
+ transpileOnly: true,
27
+ },
28
+ },
29
+ },
30
+ ],
31
+ },
32
+ externalsPresets: { node: true },
33
+ };
package/dist/http.cjs CHANGED
@@ -493,8 +493,23 @@ async function renderInitialHtmlInWorker(options) {
493
493
  const payload = Buffer.from(JSON.stringify(options), "utf8").toString("base64url");
494
494
  const script = `
495
495
  const path = require("node:path");
496
+ const Module = require("node:module");
496
497
  const input = JSON.parse(Buffer.from(process.argv[1], "base64url").toString("utf8"));
497
498
  globalThis.__RSC_BASENAME = input.basename || "";
499
+ const appRequire = Module.createRequire(path.join(input.pagesDir, "__webframez_react_worker__.js"));
500
+ const originalResolveFilename = Module._resolveFilename;
501
+ const forcedResolutions = new Map([
502
+ ["react", appRequire.resolve("react")],
503
+ ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
504
+ ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
505
+ ["react-dom/client", appRequire.resolve("react-dom/client")]
506
+ ]);
507
+ Module._resolveFilename = function(request, parent, isMain, options) {
508
+ if (forcedResolutions.has(request)) {
509
+ return forcedResolutions.get(request);
510
+ }
511
+ return originalResolveFilename.call(this, request, parent, isMain, options);
512
+ };
498
513
  const { createFileRouter } = require("webframez-react/router");
499
514
  const reactDomPkg = require.resolve("react-dom/package.json", {
500
515
  paths: [process.cwd(), input.pagesDir]
package/dist/http.js CHANGED
@@ -468,8 +468,23 @@ async function renderInitialHtmlInWorker(options) {
468
468
  const payload = Buffer.from(JSON.stringify(options), "utf8").toString("base64url");
469
469
  const script = `
470
470
  const path = require("node:path");
471
+ const Module = require("node:module");
471
472
  const input = JSON.parse(Buffer.from(process.argv[1], "base64url").toString("utf8"));
472
473
  globalThis.__RSC_BASENAME = input.basename || "";
474
+ const appRequire = Module.createRequire(path.join(input.pagesDir, "__webframez_react_worker__.js"));
475
+ const originalResolveFilename = Module._resolveFilename;
476
+ const forcedResolutions = new Map([
477
+ ["react", appRequire.resolve("react")],
478
+ ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
479
+ ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
480
+ ["react-dom/client", appRequire.resolve("react-dom/client")]
481
+ ]);
482
+ Module._resolveFilename = function(request, parent, isMain, options) {
483
+ if (forcedResolutions.has(request)) {
484
+ return forcedResolutions.get(request);
485
+ }
486
+ return originalResolveFilename.call(this, request, parent, isMain, options);
487
+ };
473
488
  const { createFileRouter } = require("webframez-react/router");
474
489
  const reactDomPkg = require.resolve("react-dom/package.json", {
475
490
  paths: [process.cwd(), input.pagesDir]
package/dist/index.cjs CHANGED
@@ -530,8 +530,23 @@ async function renderInitialHtmlInWorker(options) {
530
530
  const payload = Buffer.from(JSON.stringify(options), "utf8").toString("base64url");
531
531
  const script = `
532
532
  const path = require("node:path");
533
+ const Module = require("node:module");
533
534
  const input = JSON.parse(Buffer.from(process.argv[1], "base64url").toString("utf8"));
534
535
  globalThis.__RSC_BASENAME = input.basename || "";
536
+ const appRequire = Module.createRequire(path.join(input.pagesDir, "__webframez_react_worker__.js"));
537
+ const originalResolveFilename = Module._resolveFilename;
538
+ const forcedResolutions = new Map([
539
+ ["react", appRequire.resolve("react")],
540
+ ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
541
+ ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
542
+ ["react-dom/client", appRequire.resolve("react-dom/client")]
543
+ ]);
544
+ Module._resolveFilename = function(request, parent, isMain, options) {
545
+ if (forcedResolutions.has(request)) {
546
+ return forcedResolutions.get(request);
547
+ }
548
+ return originalResolveFilename.call(this, request, parent, isMain, options);
549
+ };
535
550
  const { createFileRouter } = require("webframez-react/router");
536
551
  const reactDomPkg = require.resolve("react-dom/package.json", {
537
552
  paths: [process.cwd(), input.pagesDir]
package/dist/index.js CHANGED
@@ -494,8 +494,23 @@ async function renderInitialHtmlInWorker(options) {
494
494
  const payload = Buffer.from(JSON.stringify(options), "utf8").toString("base64url");
495
495
  const script = `
496
496
  const path = require("node:path");
497
+ const Module = require("node:module");
497
498
  const input = JSON.parse(Buffer.from(process.argv[1], "base64url").toString("utf8"));
498
499
  globalThis.__RSC_BASENAME = input.basename || "";
500
+ const appRequire = Module.createRequire(path.join(input.pagesDir, "__webframez_react_worker__.js"));
501
+ const originalResolveFilename = Module._resolveFilename;
502
+ const forcedResolutions = new Map([
503
+ ["react", appRequire.resolve("react")],
504
+ ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
505
+ ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
506
+ ["react-dom/client", appRequire.resolve("react-dom/client")]
507
+ ]);
508
+ Module._resolveFilename = function(request, parent, isMain, options) {
509
+ if (forcedResolutions.has(request)) {
510
+ return forcedResolutions.get(request);
511
+ }
512
+ return originalResolveFilename.call(this, request, parent, isMain, options);
513
+ };
499
514
  const { createFileRouter } = require("webframez-react/router");
500
515
  const reactDomPkg = require.resolve("react-dom/package.json", {
501
516
  paths: [process.cwd(), input.pagesDir]
@@ -496,8 +496,23 @@ async function renderInitialHtmlInWorker(options) {
496
496
  const payload = Buffer.from(JSON.stringify(options), "utf8").toString("base64url");
497
497
  const script = `
498
498
  const path = require("node:path");
499
+ const Module = require("node:module");
499
500
  const input = JSON.parse(Buffer.from(process.argv[1], "base64url").toString("utf8"));
500
501
  globalThis.__RSC_BASENAME = input.basename || "";
502
+ const appRequire = Module.createRequire(path.join(input.pagesDir, "__webframez_react_worker__.js"));
503
+ const originalResolveFilename = Module._resolveFilename;
504
+ const forcedResolutions = new Map([
505
+ ["react", appRequire.resolve("react")],
506
+ ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
507
+ ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
508
+ ["react-dom/client", appRequire.resolve("react-dom/client")]
509
+ ]);
510
+ Module._resolveFilename = function(request, parent, isMain, options) {
511
+ if (forcedResolutions.has(request)) {
512
+ return forcedResolutions.get(request);
513
+ }
514
+ return originalResolveFilename.call(this, request, parent, isMain, options);
515
+ };
501
516
  const { createFileRouter } = require("webframez-react/router");
502
517
  const reactDomPkg = require.resolve("react-dom/package.json", {
503
518
  paths: [process.cwd(), input.pagesDir]
@@ -468,8 +468,23 @@ async function renderInitialHtmlInWorker(options) {
468
468
  const payload = Buffer.from(JSON.stringify(options), "utf8").toString("base64url");
469
469
  const script = `
470
470
  const path = require("node:path");
471
+ const Module = require("node:module");
471
472
  const input = JSON.parse(Buffer.from(process.argv[1], "base64url").toString("utf8"));
472
473
  globalThis.__RSC_BASENAME = input.basename || "";
474
+ const appRequire = Module.createRequire(path.join(input.pagesDir, "__webframez_react_worker__.js"));
475
+ const originalResolveFilename = Module._resolveFilename;
476
+ const forcedResolutions = new Map([
477
+ ["react", appRequire.resolve("react")],
478
+ ["react/jsx-runtime", appRequire.resolve("react/jsx-runtime")],
479
+ ["react/jsx-dev-runtime", appRequire.resolve("react/jsx-dev-runtime")],
480
+ ["react-dom/client", appRequire.resolve("react-dom/client")]
481
+ ]);
482
+ Module._resolveFilename = function(request, parent, isMain, options) {
483
+ if (forcedResolutions.has(request)) {
484
+ return forcedResolutions.get(request);
485
+ }
486
+ return originalResolveFilename.call(this, request, parent, isMain, options);
487
+ };
473
488
  const { createFileRouter } = require("webframez-react/router");
474
489
  const reactDomPkg = require.resolve("react-dom/package.json", {
475
490
  paths: [process.cwd(), input.pagesDir]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webtypen/webframez-react",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "TypeScript React RSC addition for @webtypen/webframez-core",
5
5
  "homepage": "https://webtypen.de/",
6
6
  "author": {
@@ -19,6 +19,9 @@
19
19
  "main": "./dist/index.cjs",
20
20
  "module": "./dist/index.js",
21
21
  "types": "./dist/index.d.ts",
22
+ "bin": {
23
+ "webframez-react": "./bin/webframez-react.mjs"
24
+ },
22
25
  "exports": {
23
26
  ".": {
24
27
  "types": "./dist/index.d.ts",
@@ -54,10 +57,16 @@
54
57
  "types": "./dist/webframez-core.d.ts",
55
58
  "import": "./dist/webframez-core.js",
56
59
  "require": "./dist/webframez-core.cjs"
57
- }
60
+ },
61
+ "./defaults/webpack.client": "./defaults/webpack.client.cjs",
62
+ "./defaults/webpack.server": "./defaults/webpack.server.cjs",
63
+ "./defaults/tsconfig.server": "./defaults/tsconfig.server.json",
64
+ "./cli": "./bin/webframez-react.mjs"
58
65
  },
59
66
  "files": [
60
- "dist"
67
+ "dist",
68
+ "defaults",
69
+ "bin"
61
70
  ],
62
71
  "scripts": {
63
72
  "clean": "rm -rf dist",