rwsdk 1.0.0-beta.20 → 1.0.0-beta.22
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/lib/constants.mjs +6 -4
- package/dist/lib/e2e/dev.mjs +21 -33
- package/dist/lib/e2e/testHarness.mjs +4 -3
- package/dist/runtime/entries/routerClient.d.ts +1 -0
- package/dist/runtime/entries/routerClient.js +1 -0
- package/dist/runtime/render/renderToStream.js +35 -25
- package/dist/scripts/worker-run.mjs +3 -1
- package/dist/vite/configPlugin.mjs +1 -0
- package/dist/vite/getViteEsbuild.mjs +2 -1
- package/dist/vite/moveStaticAssetsPlugin.mjs +14 -4
- package/dist/vite/runDirectivesScan.mjs +2 -2
- package/package.json +3 -2
package/dist/lib/constants.mjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { fileURLToPath } from "url";
|
|
2
|
+
import { dirname, resolve } from "path";
|
|
3
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = dirname(__filename);
|
|
3
5
|
export const ROOT_DIR = resolve(__dirname, "..", "..");
|
|
4
6
|
export const SRC_DIR = resolve(ROOT_DIR, "src");
|
|
5
7
|
export const DIST_DIR = resolve(ROOT_DIR, "dist");
|
|
6
8
|
export const VITE_DIR = resolve(ROOT_DIR, "src", "vite");
|
|
7
9
|
export const INTERMEDIATES_OUTPUT_DIR = resolve(DIST_DIR, "__intermediate_builds");
|
|
8
|
-
export const VENDOR_CLIENT_BARREL_PATH =
|
|
9
|
-
export const VENDOR_SERVER_BARREL_PATH =
|
|
10
|
+
export const VENDOR_CLIENT_BARREL_PATH = resolve(INTERMEDIATES_OUTPUT_DIR, "rwsdk-vendor-client-barrel.js");
|
|
11
|
+
export const VENDOR_SERVER_BARREL_PATH = resolve(INTERMEDIATES_OUTPUT_DIR, "rwsdk-vendor-server-barrel.js");
|
|
10
12
|
export const VENDOR_CLIENT_BARREL_EXPORT_PATH = "rwsdk/__vendor_client_barrel";
|
|
11
13
|
export const VENDOR_SERVER_BARREL_EXPORT_PATH = "rwsdk/__vendor_server_barrel";
|
|
12
14
|
export const RW_STATE_EXPORT_PATH = "rwsdk/__state";
|
package/dist/lib/e2e/dev.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import debug from "debug";
|
|
2
2
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
3
|
-
import { $ } from "../../lib/$.mjs";
|
|
3
|
+
import { $, $sh } from "../../lib/$.mjs";
|
|
4
4
|
import { poll } from "./poll.mjs";
|
|
5
5
|
const DEV_SERVER_CHECK_TIMEOUT = process.env.RWSDK_DEV_SERVER_CHECK_TIMEOUT
|
|
6
6
|
? parseInt(process.env.RWSDK_DEV_SERVER_CHECK_TIMEOUT, 10)
|
|
@@ -21,43 +21,30 @@ export async function runDevServer(packageManager = "pnpm", cwd) {
|
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
console.log("Stopping development server...");
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// Wait for the process to terminate with a timeout
|
|
32
|
-
const terminationTimeout = 5000; // 5 seconds
|
|
33
|
-
const processExitPromise = devProcess.catch(() => {
|
|
34
|
-
// We expect this promise to reject when the process is killed,
|
|
35
|
-
// so we catch and ignore the error.
|
|
36
|
-
});
|
|
37
|
-
const timeoutPromise = new Promise((resolve) => setTimeout(() => resolve(undefined), terminationTimeout));
|
|
38
|
-
await Promise.race([processExitPromise, timeoutPromise]);
|
|
39
|
-
// Check if the process is still alive. We can't reliably check exitCode
|
|
40
|
-
// on a detached process, so we try sending a signal 0, which errors
|
|
41
|
-
// if the process doesn't exist.
|
|
42
|
-
let isAlive = true;
|
|
43
|
-
try {
|
|
44
|
-
// Sending signal 0 doesn't kill the process, but checks if it exists
|
|
45
|
-
process.kill(-devProcess.pid, 0);
|
|
46
|
-
}
|
|
47
|
-
catch (e) {
|
|
48
|
-
isAlive = false;
|
|
24
|
+
if (process.platform === "win32") {
|
|
25
|
+
try {
|
|
26
|
+
await $sh(`taskkill /pid ${devProcess.pid} /f /t`);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
log("Failed to kill process tree with taskkill:", err);
|
|
30
|
+
}
|
|
49
31
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
32
|
+
else {
|
|
33
|
+
// On Unix-like systems, we kill the entire process group by sending a signal
|
|
34
|
+
// to the negative PID. This is the equivalent of the `/t` flag for `taskkill` on Windows.
|
|
35
|
+
// This relies on `detached: true` being set in the execa options, which makes
|
|
36
|
+
// the child process the leader of a new process group.
|
|
54
37
|
try {
|
|
55
38
|
process.kill(-devProcess.pid, "SIGKILL");
|
|
56
39
|
}
|
|
57
40
|
catch (e) {
|
|
58
|
-
log("
|
|
41
|
+
log("Failed to kill process group. This may happen if the process already exited. %O", e);
|
|
59
42
|
}
|
|
60
43
|
}
|
|
44
|
+
await devProcess.catch(() => {
|
|
45
|
+
// We expect this promise to reject when the process is killed,
|
|
46
|
+
// so we catch and ignore the error.
|
|
47
|
+
});
|
|
61
48
|
console.log("Development server stopped");
|
|
62
49
|
};
|
|
63
50
|
try {
|
|
@@ -88,8 +75,9 @@ export async function runDevServer(packageManager = "pnpm", cwd) {
|
|
|
88
75
|
// Use the provided cwd if available
|
|
89
76
|
devProcess = $({
|
|
90
77
|
all: true,
|
|
91
|
-
detached: true, //
|
|
92
|
-
cleanup:
|
|
78
|
+
detached: true, // Re-enable for reliable process cleanup
|
|
79
|
+
cleanup: true, // Let execa handle cleanup
|
|
80
|
+
forceKillAfterTimeout: 2000, // Force kill if graceful shutdown fails
|
|
93
81
|
cwd: cwd || process.cwd(), // Use provided directory or current directory
|
|
94
82
|
env, // Pass the updated environment variables
|
|
95
83
|
stdio: "pipe", // Ensure streams are piped
|
|
@@ -9,6 +9,7 @@ import { runDevServer } from "./dev.mjs";
|
|
|
9
9
|
import { poll, pollValue } from "./poll.mjs";
|
|
10
10
|
import { deleteD1Database, deleteWorker, isRelatedToTest, runRelease, } from "./release.mjs";
|
|
11
11
|
import { setupTarballEnvironment } from "./tarball.mjs";
|
|
12
|
+
import { fileURLToPath } from "url";
|
|
12
13
|
export { DEPLOYMENT_CHECK_TIMEOUT, DEPLOYMENT_MIN_TRIES, DEPLOYMENT_TIMEOUT, DEV_SERVER_MIN_TRIES, DEV_SERVER_TIMEOUT, HYDRATION_TIMEOUT, INSTALL_DEPENDENCIES_RETRIES, PUPPETEER_TIMEOUT, SETUP_PLAYGROUND_ENV_TIMEOUT, SETUP_WAIT_TIMEOUT, TEST_MAX_RETRIES, TEST_MAX_RETRIES_PER_CODE, };
|
|
13
14
|
// Environment variable flags for skipping tests
|
|
14
15
|
const SKIP_DEV_SERVER_TESTS = process.env.RWSDK_SKIP_DEV === "1";
|
|
@@ -64,11 +65,11 @@ function getProjectDirectory() {
|
|
|
64
65
|
* Derive the playground directory from import.meta.url by finding the nearest package.json
|
|
65
66
|
*/
|
|
66
67
|
function getPlaygroundDirFromImportMeta(importMetaUrl) {
|
|
67
|
-
const
|
|
68
|
-
const testFilePath = url.pathname;
|
|
68
|
+
const testFilePath = fileURLToPath(importMetaUrl);
|
|
69
69
|
let currentDir = dirname(testFilePath);
|
|
70
70
|
// Walk up the tree from the test file's directory
|
|
71
|
-
|
|
71
|
+
// Stop when the parent directory is the same as the current directory (we've reached the root)
|
|
72
|
+
while (dirname(currentDir) !== currentDir) {
|
|
72
73
|
// Check if a package.json exists in the current directory
|
|
73
74
|
if (fs.existsSync(pathJoin(currentDir, "package.json"))) {
|
|
74
75
|
return currentDir;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { defineLinks } from "../lib/links.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { defineLinks } from "../lib/links.js";
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { injectRSCPayload } from "rsc-html-stream/server";
|
|
3
|
+
import { ssrWebpackRequire } from "../imports/worker.js";
|
|
3
4
|
import { constructWithDefaultRequestInfo } from "../requestInfo/utils";
|
|
4
|
-
import { getRequestInfo } from "../requestInfo/worker";
|
|
5
|
+
import { getRequestInfo, runWithRequestInfo } from "../requestInfo/worker";
|
|
5
6
|
import { renderDocumentHtmlStream } from "./renderDocumentHtmlStream";
|
|
6
7
|
import { renderToRscStream } from "./renderToRscStream";
|
|
7
8
|
export const IdentityDocument = ({ children }) => (_jsx(_Fragment, { children: children }));
|
|
8
9
|
export const renderToStream = async (element, { ssr: shouldSSR = true, Document = IdentityDocument, injectRSCPayload: shouldInjectRSCPayload = true, requestInfo: givenRequestInfo, onError = () => { }, } = {}) => {
|
|
10
|
+
if (!globalThis.__webpack_require__) {
|
|
11
|
+
globalThis.__webpack_require__ = ssrWebpackRequire;
|
|
12
|
+
}
|
|
9
13
|
// Try to get the context requestInfo from the async store.
|
|
10
14
|
let contextRequestInfo;
|
|
11
15
|
try {
|
|
@@ -24,30 +28,36 @@ export const renderToStream = async (element, { ssr: shouldSSR = true, Document
|
|
|
24
28
|
...givenRequestInfo?.rw,
|
|
25
29
|
},
|
|
26
30
|
});
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
injectRSCStream = injectRSCPayload(rscPayloadStream2, {
|
|
39
|
-
nonce: requestInfo.rw.nonce,
|
|
31
|
+
// context(gching, 2025-10-29): We wrap the following with context to the requestInfo
|
|
32
|
+
// due to `ssrWebpackRequire` needing to reference the `requestInfo` in context.
|
|
33
|
+
// Therefore, we need to wrap + also pass in the requestInfo in their independent
|
|
34
|
+
// function calls
|
|
35
|
+
return runWithRequestInfo(requestInfo, async () => {
|
|
36
|
+
let rscStream = renderToRscStream({
|
|
37
|
+
input: {
|
|
38
|
+
node: element,
|
|
39
|
+
actionResult: undefined,
|
|
40
|
+
},
|
|
41
|
+
onError,
|
|
40
42
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
43
|
+
let injectRSCStream;
|
|
44
|
+
if (shouldInjectRSCPayload) {
|
|
45
|
+
const [rscPayloadStream1, rscPayloadStream2] = rscStream.tee();
|
|
46
|
+
rscStream = rscPayloadStream1;
|
|
47
|
+
injectRSCStream = injectRSCPayload(rscPayloadStream2, {
|
|
48
|
+
nonce: requestInfo.rw.nonce,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
let htmlStream = await renderDocumentHtmlStream({
|
|
52
|
+
rscPayloadStream: rscStream,
|
|
53
|
+
Document,
|
|
54
|
+
requestInfo,
|
|
55
|
+
shouldSSR,
|
|
56
|
+
onError,
|
|
57
|
+
});
|
|
58
|
+
if (injectRSCStream) {
|
|
59
|
+
htmlStream = htmlStream.pipeThrough(injectRSCStream);
|
|
60
|
+
}
|
|
61
|
+
return htmlStream;
|
|
48
62
|
});
|
|
49
|
-
if (injectRSCStream) {
|
|
50
|
-
htmlStream = htmlStream.pipeThrough(injectRSCStream);
|
|
51
|
-
}
|
|
52
|
-
return htmlStream;
|
|
53
63
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import dbg from "debug";
|
|
2
2
|
import getPort from "get-port";
|
|
3
3
|
import path from "path";
|
|
4
|
+
import { pathToFileURL } from "url";
|
|
4
5
|
import * as vite from "vite";
|
|
5
6
|
import { createLogger } from "vite";
|
|
6
7
|
const debug = dbg("rwsdk:worker-run");
|
|
@@ -42,7 +43,8 @@ const main = async () => {
|
|
|
42
43
|
},
|
|
43
44
|
});
|
|
44
45
|
await server.listen();
|
|
45
|
-
const
|
|
46
|
+
const fileUrl = pathToFileURL(scriptPath).href;
|
|
47
|
+
const url = `http://localhost:${port}/__worker-run?script=${encodeURIComponent(fileUrl)}`;
|
|
46
48
|
debug("Fetching %s", url);
|
|
47
49
|
const response = await fetch(url);
|
|
48
50
|
debug("Response from worker: %s", response);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
3
4
|
const require = createRequire(import.meta.url);
|
|
4
5
|
export async function getViteEsbuild(projectRootDir) {
|
|
5
6
|
const vitePath = require.resolve("vite/package.json", {
|
|
@@ -7,6 +8,6 @@ export async function getViteEsbuild(projectRootDir) {
|
|
|
7
8
|
});
|
|
8
9
|
const viteDir = path.dirname(vitePath);
|
|
9
10
|
const esbuildPath = require.resolve("esbuild", { paths: [viteDir] });
|
|
10
|
-
const esbuildModule = await import(esbuildPath);
|
|
11
|
+
const esbuildModule = await import(pathToFileURL(esbuildPath).href);
|
|
11
12
|
return esbuildModule.default || esbuildModule;
|
|
12
13
|
}
|
|
@@ -1,13 +1,23 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import { glob } from "glob";
|
|
2
4
|
export const moveStaticAssetsPlugin = ({ rootDir, }) => ({
|
|
3
5
|
name: "rwsdk:move-static-assets",
|
|
4
6
|
apply: "build",
|
|
5
7
|
async closeBundle() {
|
|
6
8
|
if (this.environment.name === "worker" &&
|
|
7
9
|
process.env.RWSDK_BUILD_PASS === "linker") {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
const sourceDir = path.join(rootDir, "dist", "worker", "assets");
|
|
11
|
+
const destDir = path.join(rootDir, "dist", "client", "assets");
|
|
12
|
+
const cssFiles = await glob("*.css", { cwd: sourceDir });
|
|
13
|
+
if (cssFiles.length > 0) {
|
|
14
|
+
await fs.ensureDir(destDir);
|
|
15
|
+
for (const file of cssFiles) {
|
|
16
|
+
const sourceFile = path.join(sourceDir, file);
|
|
17
|
+
const destFile = path.join(destDir, file);
|
|
18
|
+
await fs.move(sourceFile, destFile, { overwrite: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
11
21
|
}
|
|
12
22
|
},
|
|
13
23
|
});
|
|
@@ -210,11 +210,11 @@ export const runDirectivesScan = async ({ rootConfig, environments, clientFiles,
|
|
|
210
210
|
});
|
|
211
211
|
build.onLoad({ filter: /\.(m|c)?[jt]sx?$|\.mdx$/ }, async (args) => {
|
|
212
212
|
log("onLoad called for:", args.path);
|
|
213
|
-
if (!args.path
|
|
213
|
+
if (!path.isAbsolute(args.path) ||
|
|
214
214
|
args.path.includes("virtual:") ||
|
|
215
215
|
isExternalUrl(args.path)) {
|
|
216
216
|
log("Skipping file due to filter:", args.path, {
|
|
217
|
-
|
|
217
|
+
isAbsolute: path.isAbsolute(args.path),
|
|
218
218
|
hasVirtual: args.path.includes("virtual:"),
|
|
219
219
|
isExternal: isExternalUrl(args.path),
|
|
220
220
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rwsdk",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.22",
|
|
4
4
|
"description": "Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -58,7 +58,8 @@
|
|
|
58
58
|
},
|
|
59
59
|
"./router": {
|
|
60
60
|
"types": "./dist/runtime/entries/router.d.ts",
|
|
61
|
-
"
|
|
61
|
+
"workerd": "./dist/runtime/entries/router.js",
|
|
62
|
+
"default": "./dist/runtime/entries/routerClient.js"
|
|
62
63
|
},
|
|
63
64
|
"./auth": {
|
|
64
65
|
"types": "./dist/runtime/entries/auth.d.ts",
|