rwsdk 0.1.8 → 0.1.9
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/bin/rwsync
CHANGED
|
@@ -1,2 +1,12 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
|
-
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
# This script is a lightweight wrapper that passes all arguments to the underlying
|
|
5
|
+
# debug:sync Node.js script.
|
|
6
|
+
# The RWSDK_REPO env var should point to the root of the sdk repo.
|
|
7
|
+
|
|
8
|
+
# Capture the current directory *before* changing it
|
|
9
|
+
TARGET_DIR=$PWD
|
|
10
|
+
|
|
11
|
+
cd "${RWSDK_REPO}/sdk"
|
|
12
|
+
pnpm debug:sync "$TARGET_DIR" "$@"
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { initClient } from "../../client";
|
|
2
2
|
import { createFromReadableStream } from "react-server-dom-webpack/client.browser";
|
|
3
|
-
import { IS_DEV } from "../../constants";
|
|
4
3
|
import { MESSAGE_TYPE } from "./shared";
|
|
5
4
|
const DEFAULT_KEY = "default";
|
|
6
5
|
export const initRealtimeClient = ({ key = DEFAULT_KEY, } = {}) => {
|
|
@@ -12,12 +11,13 @@ export const realtimeTransport = ({ key = DEFAULT_KEY }) => (transportContext) =
|
|
|
12
11
|
let isConnected = false;
|
|
13
12
|
const clientId = crypto.randomUUID();
|
|
14
13
|
const clientUrl = new URL(window.location.href);
|
|
14
|
+
const isHttps = clientUrl.protocol === "https:";
|
|
15
15
|
clientUrl.protocol = "";
|
|
16
16
|
clientUrl.host = "";
|
|
17
17
|
const setupWebSocket = () => {
|
|
18
18
|
if (ws)
|
|
19
19
|
return;
|
|
20
|
-
const protocol =
|
|
20
|
+
const protocol = isHttps ? "wss" : "ws";
|
|
21
21
|
ws = new WebSocket(`${protocol}://${window.location.host}/__realtime?` +
|
|
22
22
|
`key=${encodeURIComponent(key)}&` +
|
|
23
23
|
`url=${encodeURIComponent(clientUrl.toString())}&` +
|
|
@@ -1,26 +1,38 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
-
import { $ } from "
|
|
3
|
+
import { $ } from "execa";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
|
+
import chokidar from "chokidar";
|
|
7
|
+
import { lock } from "proper-lockfile";
|
|
6
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
9
|
const getPackageManagerInfo = (targetDir) => {
|
|
10
|
+
const pnpmResult = {
|
|
11
|
+
name: "pnpm",
|
|
12
|
+
lockFile: "pnpm-lock.yaml",
|
|
13
|
+
command: "add",
|
|
14
|
+
};
|
|
8
15
|
if (existsSync(path.join(targetDir, "yarn.lock"))) {
|
|
9
16
|
return { name: "yarn", lockFile: "yarn.lock", command: "add" };
|
|
10
17
|
}
|
|
11
18
|
if (existsSync(path.join(targetDir, "pnpm-lock.yaml"))) {
|
|
12
|
-
return
|
|
19
|
+
return pnpmResult;
|
|
13
20
|
}
|
|
14
|
-
|
|
21
|
+
if (existsSync(path.join(targetDir, "package-lock.json"))) {
|
|
22
|
+
return { name: "npm", lockFile: "package-lock.json", command: "install" };
|
|
23
|
+
}
|
|
24
|
+
return pnpmResult;
|
|
15
25
|
};
|
|
16
|
-
const
|
|
17
|
-
console.log("
|
|
18
|
-
|
|
19
|
-
console.log("📦 packing sdk...");
|
|
20
|
-
const packResult = await $({ cwd: sdkDir, shell: true }) `npm pack`;
|
|
26
|
+
const performFullSync = async (sdkDir, targetDir) => {
|
|
27
|
+
console.log("📦 Packing SDK...");
|
|
28
|
+
const packResult = await $ `npm pack`;
|
|
21
29
|
const tarballName = packResult.stdout?.trim() ?? "";
|
|
30
|
+
if (!tarballName) {
|
|
31
|
+
console.error("❌ Failed to get tarball name from npm pack.");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
22
34
|
const tarballPath = path.resolve(sdkDir, tarballName);
|
|
23
|
-
console.log(
|
|
35
|
+
console.log(`💿 Installing ${tarballName} in ${targetDir}...`);
|
|
24
36
|
const pm = getPackageManagerInfo(targetDir);
|
|
25
37
|
const packageJsonPath = path.join(targetDir, "package.json");
|
|
26
38
|
const lockfilePath = path.join(targetDir, pm.lockFile);
|
|
@@ -31,15 +43,18 @@ const performSync = async (sdkDir, targetDir) => {
|
|
|
31
43
|
.readFile(lockfilePath, "utf-8")
|
|
32
44
|
.catch(() => null);
|
|
33
45
|
try {
|
|
34
|
-
|
|
46
|
+
const cmd = pm.name;
|
|
47
|
+
const args = [pm.command];
|
|
35
48
|
if (pm.name === "yarn") {
|
|
36
|
-
|
|
49
|
+
args.push(`file:${tarballPath}`);
|
|
37
50
|
}
|
|
38
|
-
|
|
51
|
+
else {
|
|
52
|
+
args.push(tarballPath);
|
|
53
|
+
}
|
|
54
|
+
await $(cmd, args, {
|
|
39
55
|
cwd: targetDir,
|
|
40
56
|
stdio: "inherit",
|
|
41
|
-
|
|
42
|
-
}) `${installCommand}`;
|
|
57
|
+
});
|
|
43
58
|
}
|
|
44
59
|
finally {
|
|
45
60
|
if (originalPackageJson) {
|
|
@@ -54,67 +69,140 @@ const performSync = async (sdkDir, targetDir) => {
|
|
|
54
69
|
// ignore if deletion fails
|
|
55
70
|
});
|
|
56
71
|
}
|
|
57
|
-
|
|
72
|
+
};
|
|
73
|
+
const performFastSync = async (sdkDir, targetDir) => {
|
|
74
|
+
console.log("⚡️ No dependency changes, performing fast sync...");
|
|
75
|
+
const sdkPackageJson = JSON.parse(await fs.readFile(path.join(sdkDir, "package.json"), "utf-8"));
|
|
76
|
+
const filesToSync = sdkPackageJson.files || [];
|
|
77
|
+
for (const file of filesToSync) {
|
|
78
|
+
const source = path.join(sdkDir, file);
|
|
79
|
+
const destination = path.join(targetDir, "node_modules/rwsdk", file);
|
|
80
|
+
if (existsSync(source)) {
|
|
81
|
+
await fs.cp(source, destination, { recursive: true, force: true });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Always copy package.json
|
|
85
|
+
await fs.copyFile(path.join(sdkDir, "package.json"), path.join(targetDir, "node_modules/rwsdk/package.json"));
|
|
86
|
+
};
|
|
87
|
+
const performSync = async (sdkDir, targetDir) => {
|
|
88
|
+
console.log("🏗️ Rebuilding SDK...");
|
|
89
|
+
await $ `pnpm build`;
|
|
90
|
+
const sdkPackageJsonPath = path.join(sdkDir, "package.json");
|
|
91
|
+
const installedSdkPackageJsonPath = path.join(targetDir, "node_modules/rwsdk/package.json");
|
|
92
|
+
let packageJsonChanged = true;
|
|
93
|
+
if (existsSync(installedSdkPackageJsonPath)) {
|
|
94
|
+
const sdkPackageJsonContent = await fs.readFile(sdkPackageJsonPath, "utf-8");
|
|
95
|
+
const installedSdkPackageJsonContent = await fs.readFile(installedSdkPackageJsonPath, "utf-8");
|
|
96
|
+
if (sdkPackageJsonContent === installedSdkPackageJsonContent) {
|
|
97
|
+
packageJsonChanged = false;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (packageJsonChanged) {
|
|
101
|
+
console.log("📦 package.json changed, performing full sync...");
|
|
102
|
+
await performFullSync(sdkDir, targetDir);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
await performFastSync(sdkDir, targetDir);
|
|
106
|
+
}
|
|
107
|
+
console.log("✅ Done syncing");
|
|
58
108
|
};
|
|
59
109
|
export const debugSync = async (opts) => {
|
|
60
|
-
const { targetDir, sdkDir = process.cwd(),
|
|
110
|
+
const { targetDir, sdkDir = process.cwd(), watch } = opts;
|
|
61
111
|
if (!targetDir) {
|
|
62
112
|
console.error("❌ Please provide a target directory as an argument.");
|
|
63
113
|
process.exit(1);
|
|
64
114
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
if (!process.env.NO_CLEAN_VITE) {
|
|
70
|
-
console.log("🧹 Cleaning Vite cache...");
|
|
71
|
-
await $({
|
|
72
|
-
stdio: "inherit",
|
|
73
|
-
shell: true,
|
|
74
|
-
cwd: targetDir,
|
|
75
|
-
}) `rm -rf ${targetDir}/node_modules/.vite*`;
|
|
76
|
-
}
|
|
77
|
-
// If dev flag is present, clean vite cache and start dev server
|
|
78
|
-
if (dev) {
|
|
79
|
-
console.log("🚀 Starting dev server...");
|
|
80
|
-
await $({ stdio: "inherit", shell: true, cwd: targetDir }) `npm run dev`;
|
|
115
|
+
// If not in watch mode, just do a one-time sync and exit.
|
|
116
|
+
if (!watch) {
|
|
117
|
+
await performSync(sdkDir, targetDir);
|
|
118
|
+
return;
|
|
81
119
|
}
|
|
82
|
-
//
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
120
|
+
// --- Watch Mode Logic ---
|
|
121
|
+
const lockfilePath = path.join(targetDir, "node_modules", ".rwsync.lock");
|
|
122
|
+
let release;
|
|
123
|
+
// Ensure the directory for the lockfile exists
|
|
124
|
+
await fs.mkdir(path.dirname(lockfilePath), { recursive: true });
|
|
125
|
+
// "Touch" the file to ensure it exists before locking
|
|
126
|
+
await fs.appendFile(lockfilePath, "").catch(() => { });
|
|
127
|
+
try {
|
|
128
|
+
release = await lock(lockfilePath, { retries: 0 });
|
|
90
129
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
130
|
+
catch (e) {
|
|
131
|
+
if (e.code === "ELOCKED") {
|
|
132
|
+
console.error(`❌ Another rwsync process is already watching ${targetDir}.`);
|
|
133
|
+
console.error(` If this is not correct, please remove the lockfile at ${lockfilePath}`);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
throw e;
|
|
98
137
|
}
|
|
138
|
+
// Initial sync for watch mode. We do it *after* acquiring the lock.
|
|
139
|
+
await performSync(sdkDir, targetDir);
|
|
140
|
+
const filesToWatch = [
|
|
141
|
+
path.join(sdkDir, "src"),
|
|
142
|
+
path.join(sdkDir, "types"),
|
|
143
|
+
path.join(sdkDir, "bin"),
|
|
144
|
+
path.join(sdkDir, "package.json"),
|
|
145
|
+
];
|
|
146
|
+
console.log("👀 Watching for changes...");
|
|
147
|
+
let childProc = null;
|
|
148
|
+
const runWatchedCommand = () => {
|
|
149
|
+
if (typeof watch === "string") {
|
|
150
|
+
console.log(`\n> ${watch}\n`);
|
|
151
|
+
childProc = $({
|
|
152
|
+
stdio: "inherit",
|
|
153
|
+
shell: true,
|
|
154
|
+
cwd: targetDir,
|
|
155
|
+
reject: false,
|
|
156
|
+
}) `${watch}`;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
const watcher = chokidar.watch(filesToWatch, {
|
|
160
|
+
ignoreInitial: true,
|
|
161
|
+
cwd: sdkDir,
|
|
162
|
+
});
|
|
163
|
+
watcher.on("all", async () => {
|
|
164
|
+
console.log("\nDetected change, re-syncing...");
|
|
165
|
+
if (childProc && !childProc.killed) {
|
|
166
|
+
console.log("Stopping running process...");
|
|
167
|
+
childProc.kill();
|
|
168
|
+
await childProc.catch(() => {
|
|
169
|
+
/* ignore kill errors */
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
await performSync(sdkDir, targetDir);
|
|
173
|
+
runWatchedCommand();
|
|
174
|
+
});
|
|
175
|
+
const cleanup = async () => {
|
|
176
|
+
console.log("\nCleaning up...");
|
|
177
|
+
if (childProc && !childProc.killed) {
|
|
178
|
+
childProc.kill();
|
|
179
|
+
}
|
|
180
|
+
await release();
|
|
181
|
+
process.exit();
|
|
182
|
+
};
|
|
183
|
+
process.on("SIGINT", cleanup);
|
|
184
|
+
process.on("SIGTERM", cleanup);
|
|
185
|
+
runWatchedCommand();
|
|
99
186
|
};
|
|
100
187
|
if (import.meta.url === new URL(process.argv[1], import.meta.url).href) {
|
|
101
188
|
const args = process.argv.slice(2);
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
? path.resolve(__dirname, process.env.RWSDK_REPO, "sdk")
|
|
114
|
-
: path.resolve(__dirname, "..", ".."),
|
|
115
|
-
dev: flags.has("--dev"),
|
|
116
|
-
watch: flags.has("--watch"),
|
|
117
|
-
build: flags.has("--build"),
|
|
118
|
-
});
|
|
189
|
+
const watchFlagIndex = args.indexOf("--watch");
|
|
190
|
+
let watchCmd = watchFlagIndex !== -1;
|
|
191
|
+
let cmdArgs = args;
|
|
192
|
+
if (watchFlagIndex !== -1) {
|
|
193
|
+
if (watchFlagIndex + 1 < args.length &&
|
|
194
|
+
!args[watchFlagIndex + 1].startsWith("--")) {
|
|
195
|
+
watchCmd = args[watchFlagIndex + 1];
|
|
196
|
+
}
|
|
197
|
+
// remove --watch and its potential command from args
|
|
198
|
+
const watchArgCount = typeof watchCmd === "string" ? 2 : 1;
|
|
199
|
+
cmdArgs = args.filter((_, i) => i < watchFlagIndex || i >= watchFlagIndex + watchArgCount);
|
|
119
200
|
}
|
|
201
|
+
const targetDir = cmdArgs[0] ?? process.cwd();
|
|
202
|
+
const sdkDir = path.resolve(__dirname, "..", "..");
|
|
203
|
+
debugSync({
|
|
204
|
+
targetDir,
|
|
205
|
+
sdkDir,
|
|
206
|
+
watch: watchCmd,
|
|
207
|
+
});
|
|
120
208
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rwsdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -120,6 +120,7 @@
|
|
|
120
120
|
"@types/react-dom": "^19.1.2",
|
|
121
121
|
"@types/react-is": "^19.0.0",
|
|
122
122
|
"@vitejs/plugin-react": "^4.3.4",
|
|
123
|
+
"chokidar": "^3.6.0",
|
|
123
124
|
"debug": "^4.4.0",
|
|
124
125
|
"enhanced-resolve": "^5.18.1",
|
|
125
126
|
"eventsource-parser": "^3.0.0",
|
|
@@ -134,6 +135,7 @@
|
|
|
134
135
|
"magic-string": "^0.30.17",
|
|
135
136
|
"miniflare": "^4.20250405.0",
|
|
136
137
|
"picocolors": "^1.1.1",
|
|
138
|
+
"proper-lockfile": "^4.1.2",
|
|
137
139
|
"puppeteer-core": "^22.8.1",
|
|
138
140
|
"react": "19.2.0-canary-39cad7af-20250411",
|
|
139
141
|
"react-dom": "19.2.0-canary-39cad7af-20250411",
|
|
@@ -154,6 +156,7 @@
|
|
|
154
156
|
"@types/debug": "^4.1.12",
|
|
155
157
|
"@types/lodash": "^4.17.16",
|
|
156
158
|
"@types/node": "^22.14.0",
|
|
159
|
+
"@types/proper-lockfile": "^4.1.4",
|
|
157
160
|
"semver": "^7.7.1",
|
|
158
161
|
"tsx": "^4.19.4",
|
|
159
162
|
"typescript": "^5.8.3",
|