rwsdk 0.1.23 → 0.1.25

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.
@@ -15,7 +15,8 @@ const getPackageManagerInfo = (targetDir) => {
15
15
  if (existsSync(path.join(targetDir, "yarn.lock"))) {
16
16
  return { name: "yarn", lockFile: "yarn.lock", command: "add" };
17
17
  }
18
- if (existsSync(path.join(targetDir, "pnpm-lock.yaml"))) {
18
+ if (existsSync(path.join(targetDir, "pnpm-lock.yaml")) ||
19
+ existsSync(path.join(targetDir, "node_modules", ".pnpm"))) {
19
20
  return pnpmResult;
20
21
  }
21
22
  if (existsSync(path.join(targetDir, "package-lock.json"))) {
@@ -23,51 +24,75 @@ const getPackageManagerInfo = (targetDir) => {
23
24
  }
24
25
  return pnpmResult;
25
26
  };
26
- const performFullSync = async (sdkDir, targetDir) => {
27
- console.log("📦 Packing SDK...");
28
- const packResult = await $ `npm pack`;
29
- const tarballName = packResult.stdout?.trim() ?? "";
30
- if (!tarballName) {
31
- console.error("❌ Failed to get tarball name from npm pack.");
32
- return;
33
- }
34
- const tarballPath = path.resolve(sdkDir, tarballName);
35
- console.log(`💿 Installing ${tarballName} in ${targetDir}...`);
36
- const pm = getPackageManagerInfo(targetDir);
37
- const packageJsonPath = path.join(targetDir, "package.json");
38
- const lockfilePath = path.join(targetDir, pm.lockFile);
39
- const originalPackageJson = await fs
40
- .readFile(packageJsonPath, "utf-8")
41
- .catch(() => null);
42
- const originalLockfile = await fs
43
- .readFile(lockfilePath, "utf-8")
44
- .catch(() => null);
27
+ const performFullSync = async (sdkDir, targetDir, cacheBust = false) => {
28
+ const sdkPackageJsonPath = path.join(sdkDir, "package.json");
29
+ let originalSdkPackageJson = null;
30
+ let tarballPath = "";
31
+ let tarballName = "";
45
32
  try {
46
- const cmd = pm.name;
47
- const args = [pm.command];
48
- if (pm.name === "yarn") {
49
- args.push(`file:${tarballPath}`);
33
+ if (cacheBust) {
34
+ console.log("💥 Cache-busting version for full sync...");
35
+ originalSdkPackageJson = await fs.readFile(sdkPackageJsonPath, "utf-8");
36
+ const packageJson = JSON.parse(originalSdkPackageJson);
37
+ const now = Date.now();
38
+ // This is a temporary version used for cache busting
39
+ packageJson.version = `${packageJson.version}-dev.${now}`;
40
+ await fs.writeFile(sdkPackageJsonPath, JSON.stringify(packageJson, null, 2));
41
+ }
42
+ console.log("📦 Packing SDK...");
43
+ const packResult = await $({ cwd: sdkDir }) `npm pack`;
44
+ tarballName = packResult.stdout?.trim() ?? "";
45
+ if (!tarballName) {
46
+ console.error("❌ Failed to get tarball name from npm pack.");
47
+ return;
50
48
  }
51
- else {
52
- args.push(tarballPath);
49
+ tarballPath = path.resolve(sdkDir, tarballName);
50
+ console.log(`💿 Installing ${tarballName} in ${targetDir}...`);
51
+ const pm = getPackageManagerInfo(targetDir);
52
+ const packageJsonPath = path.join(targetDir, "package.json");
53
+ const lockfilePath = path.join(targetDir, pm.lockFile);
54
+ const originalPackageJson = await fs
55
+ .readFile(packageJsonPath, "utf-8")
56
+ .catch(() => null);
57
+ const originalLockfile = await fs
58
+ .readFile(lockfilePath, "utf-8")
59
+ .catch(() => null);
60
+ try {
61
+ const cmd = pm.name;
62
+ const args = [pm.command];
63
+ if (pm.name === "yarn") {
64
+ args.push(`file:${tarballPath}`);
65
+ }
66
+ else {
67
+ args.push(tarballPath);
68
+ }
69
+ await $(cmd, args, {
70
+ cwd: targetDir,
71
+ stdio: "inherit",
72
+ });
73
+ }
74
+ finally {
75
+ if (originalPackageJson) {
76
+ console.log("Restoring package.json...");
77
+ await fs.writeFile(packageJsonPath, originalPackageJson);
78
+ }
79
+ if (originalLockfile) {
80
+ console.log(`Restoring ${pm.lockFile}...`);
81
+ await fs.writeFile(lockfilePath, originalLockfile);
82
+ }
53
83
  }
54
- await $(cmd, args, {
55
- cwd: targetDir,
56
- stdio: "inherit",
57
- });
58
84
  }
59
85
  finally {
60
- if (originalPackageJson) {
86
+ if (originalSdkPackageJson) {
61
87
  console.log("Restoring package.json...");
62
- await fs.writeFile(packageJsonPath, originalPackageJson);
88
+ await fs.writeFile(sdkPackageJsonPath, originalSdkPackageJson);
63
89
  }
64
- if (originalLockfile) {
65
- console.log(`Restoring ${pm.lockFile}...`);
66
- await fs.writeFile(lockfilePath, originalLockfile);
90
+ if (tarballPath) {
91
+ console.log("Removing tarball...");
92
+ await fs.unlink(tarballPath).catch(() => {
93
+ // ignore if deletion fails
94
+ });
67
95
  }
68
- await fs.unlink(tarballPath).catch(() => {
69
- // ignore if deletion fails
70
- });
71
96
  }
72
97
  };
73
98
  const performFastSync = async (sdkDir, targetDir) => {
@@ -87,6 +112,13 @@ const performFastSync = async (sdkDir, targetDir) => {
87
112
  const performSync = async (sdkDir, targetDir) => {
88
113
  console.log("🏗️ Rebuilding SDK...");
89
114
  await $ `pnpm build`;
115
+ const forceFullSync = Boolean(process.env.RWSDK_FORCE_FULL_SYNC);
116
+ if (forceFullSync) {
117
+ console.log("🏃 Force full sync mode is enabled.");
118
+ await performFullSync(sdkDir, targetDir, true);
119
+ console.log("✅ Done syncing");
120
+ return;
121
+ }
90
122
  const sdkPackageJsonPath = path.join(sdkDir, "package.json");
91
123
  const installedSdkPackageJsonPath = path.join(targetDir, "node_modules/rwsdk/package.json");
92
124
  let packageJsonChanged = true;
@@ -166,8 +198,21 @@ export const debugSync = async (opts) => {
166
198
  ignoreInitial: true,
167
199
  cwd: sdkDir,
168
200
  });
169
- watcher.on("all", async () => {
170
- console.log("\nDetected change, re-syncing...");
201
+ let syncing = false;
202
+ // todo(justinvdm, 2025-07-22): Figure out wtf makes the full sync
203
+ // cause chokidar to find out about package.json after sync has resolved
204
+ let expectingFileChanges = Boolean(process.env.RWSDK_FORCE_FULL_SYNC);
205
+ watcher.on("all", async (_event, filePath) => {
206
+ if (syncing || filePath.endsWith(".tgz")) {
207
+ return;
208
+ }
209
+ if (expectingFileChanges && process.env.RWSDK_FORCE_FULL_SYNC) {
210
+ expectingFileChanges = false;
211
+ return;
212
+ }
213
+ syncing = true;
214
+ expectingFileChanges = true;
215
+ console.log(`\nDetected change, re-syncing... (file: ${filePath})`);
171
216
  if (childProc && !childProc.killed) {
172
217
  console.log("Stopping running process...");
173
218
  childProc.kill();
@@ -176,6 +221,7 @@ export const debugSync = async (opts) => {
176
221
  });
177
222
  }
178
223
  try {
224
+ watcher.unwatch(filesToWatch);
179
225
  await performSync(sdkDir, targetDir);
180
226
  runWatchedCommand();
181
227
  }
@@ -183,6 +229,10 @@ export const debugSync = async (opts) => {
183
229
  console.error("❌ Sync failed:", error);
184
230
  console.log(" Still watching for changes...");
185
231
  }
232
+ finally {
233
+ syncing = false;
234
+ watcher.add(filesToWatch);
235
+ }
186
236
  });
187
237
  const cleanup = async () => {
188
238
  console.log("\nCleaning up...");
@@ -2,7 +2,7 @@ import MagicString from "magic-string";
2
2
  import path from "path";
3
3
  import { readFile } from "fs/promises";
4
4
  import debug from "debug";
5
- import { normalizeModulePath } from "./normalizeModulePath.mjs";
5
+ import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
6
6
  import { pathExists } from "fs-extra";
7
7
  import { stat } from "fs/promises";
8
8
  import { getSrcPaths } from "../lib/getSrcPaths.js";
@@ -22,7 +22,7 @@ export const findFilesContainingDirective = async ({ projectRootDir, files, dire
22
22
  process.env.VERBOSE && log("Scanning file: %s", file);
23
23
  const content = await readFile(file, "utf-8");
24
24
  if (hasDirective(content, directive)) {
25
- const normalizedPath = normalizeModulePath(projectRootDir, file);
25
+ const normalizedPath = normalizeModulePath(file, projectRootDir);
26
26
  log("Found '%s' directive in file: %s -> %s", directive, file, normalizedPath);
27
27
  files.add(normalizedPath);
28
28
  }
@@ -3,7 +3,7 @@ import fs from "node:fs/promises";
3
3
  import debug from "debug";
4
4
  import { transformClientComponents } from "./transformClientComponents.mjs";
5
5
  import { transformServerFunctions } from "./transformServerFunctions.mjs";
6
- import { normalizeModulePath } from "./normalizeModulePath.mjs";
6
+ import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
7
7
  const log = debug("rwsdk:vite:rsc-directives-plugin");
8
8
  const getLoader = (filePath) => {
9
9
  const ext = path.extname(filePath).slice(1);
@@ -31,9 +31,10 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
31
31
  const addModule = (kind, environment, id) => {
32
32
  const files = kind === "client" ? clientFiles : serverFiles;
33
33
  const rawId = id.split("?")[0];
34
- const resolvedId = rawId;
35
- const relativePath = rawId.slice("/".length);
36
- const fullPath = path.resolve(projectRootDir, relativePath);
34
+ const resolvedId = normalizeModulePath(rawId, projectRootDir);
35
+ const fullPath = normalizeModulePath(rawId, projectRootDir, {
36
+ absolute: true,
37
+ });
37
38
  const isNodeModule = id.includes("node_modules");
38
39
  const hadFile = files.has(id);
39
40
  log("Adding %s module to %s and invalidating cache: id=%s", kind, files, resolvedId);
@@ -77,7 +78,7 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
77
78
  async transform(code, id) {
78
79
  process.env.VERBOSE &&
79
80
  log("Transform called for id=%s, environment=%s", id, this.environment.name);
80
- const normalizedId = normalizeModulePath(projectRootDir, id);
81
+ const normalizedId = normalizeModulePath(id, projectRootDir);
81
82
  const clientResult = await transformClientComponents(code, normalizedId, {
82
83
  environmentName: this.environment.name,
83
84
  clientFiles,
@@ -112,7 +113,7 @@ export const directivesPlugin = ({ projectRootDir, clientFiles, serverFiles, })
112
113
  build.onLoad({ filter: /\.(js|ts|jsx|tsx|mts|mjs|cjs)$/ }, async (args) => {
113
114
  process.env.VERBOSE &&
114
115
  log("Esbuild onLoad called for environment=%s, path=%s", env, args.path);
115
- const normalizedPath = normalizeModulePath(projectRootDir, args.path);
116
+ const normalizedPath = normalizeModulePath(args.path, projectRootDir);
116
117
  // context(justinvdm,2025-06-15): If we're in app code,
117
118
  // we will be doing the transform work in the vite plugin hooks,
118
119
  // the only reason we're in esbuild land for app code is for
@@ -3,7 +3,7 @@ import colors from "picocolors";
3
3
  import { readFile } from "node:fs/promises";
4
4
  import debug from "debug";
5
5
  import { VIRTUAL_SSR_PREFIX } from "./ssrBridgePlugin.mjs";
6
- import { normalizeModulePath } from "./normalizeModulePath.mjs";
6
+ import { normalizeModulePath } from "../lib/normalizeModulePath.mjs";
7
7
  import { hasDirective as sourceHasDirective } from "./hasDirective.mjs";
8
8
  import { isJsFile } from "./isJsFile.mjs";
9
9
  import { invalidateModule } from "./invalidateModule.mjs";
@@ -33,7 +33,7 @@ const hasEntryAsAncestor = (module, entryFile, seen = new Set()) => {
33
33
  return false;
34
34
  };
35
35
  const isInUseClientGraph = ({ file, clientFiles, server, }) => {
36
- const id = normalizeModulePath(server.config.root, file);
36
+ const id = normalizeModulePath(file, server.config.root);
37
37
  if (clientFiles.has(id)) {
38
38
  return true;
39
39
  }
@@ -74,7 +74,7 @@ export const miniflareHMRPlugin = (givenOptions) => [
74
74
  }
75
75
  invalidateModule(ctx.server, "ssr", ctx.file);
76
76
  invalidateModule(ctx.server, environment, VIRTUAL_SSR_PREFIX +
77
- normalizeModulePath(givenOptions.rootDir, ctx.file));
77
+ normalizeModulePath(ctx.file, givenOptions.rootDir));
78
78
  return [];
79
79
  }
80
80
  if (!["client", environment].includes(this.environment.name)) {
@@ -159,7 +159,7 @@ export const miniflareHMRPlugin = (givenOptions) => [
159
159
  invalidateModule(ctx.server, environment, m);
160
160
  }
161
161
  const virtualSSRModule = ctx.server.environments[environment].moduleGraph.idToModuleMap.get(VIRTUAL_SSR_PREFIX +
162
- normalizeModulePath(givenOptions.rootDir, ctx.file));
162
+ normalizeModulePath(ctx.file, givenOptions.rootDir));
163
163
  if (virtualSSRModule) {
164
164
  invalidateModule(ctx.server, environment, virtualSSRModule);
165
165
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rwsdk",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "description": "Build fast, server-driven webapps on Cloudflare with SSR, RSC, and realtime",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- export declare const normalizeModulePath: (projectRootDir: string, modulePath: string) => string;
@@ -1,13 +0,0 @@
1
- import path from "node:path";
2
- export const normalizeModulePath = (projectRootDir, modulePath) => {
3
- // /Users/path/to/project/src/foo/bar.ts -> /src/foo/bar.ts
4
- if (modulePath.startsWith(projectRootDir)) {
5
- return "/" + path.relative(projectRootDir, modulePath);
6
- }
7
- // /src/foo/bar.ts -> /src/foo/bar.ts
8
- if (modulePath.startsWith("/")) {
9
- return modulePath;
10
- }
11
- // src/foo/bar.ts -> /src/foo/bar.ts
12
- return "/" + modulePath;
13
- };