rwsdk 0.2.0-alpha.6 → 0.2.0-alpha.6-test.20250806102744
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/runtime/lib/db/createDb.js +13 -15
- package/dist/scripts/debug-sync.mjs +24 -137
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Kysely } from "kysely";
|
|
2
|
-
import { requestInfo
|
|
2
|
+
import { requestInfo } from "../../requestInfo/worker.js";
|
|
3
3
|
import { DOWorkerDialect } from "./DOWorkerDialect.js";
|
|
4
|
+
const moduleLevelDbCache = new Map();
|
|
4
5
|
const createDurableObjectDb = (durableObjectBinding, name = "main") => {
|
|
5
6
|
const durableObjectId = durableObjectBinding.idFromName(name);
|
|
6
7
|
const stub = durableObjectBinding.get(durableObjectId);
|
|
@@ -10,26 +11,23 @@ const createDurableObjectDb = (durableObjectBinding, name = "main") => {
|
|
|
10
11
|
});
|
|
11
12
|
};
|
|
12
13
|
export function createDb(durableObjectBinding, name = "main") {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
if (!requestInfo.rw) {
|
|
16
|
-
throw new Error(`
|
|
17
|
-
rwsdk: A database created using createDb() was accessed before requestInfo was available.
|
|
18
|
-
|
|
19
|
-
Please make sure database access is happening in a request handler or action handler.
|
|
20
|
-
`);
|
|
21
|
-
}
|
|
22
|
-
let db = requestInfo.rw.databases.get(cacheKey);
|
|
14
|
+
const getDb = () => {
|
|
15
|
+
let db = moduleLevelDbCache.get(name);
|
|
23
16
|
if (!db) {
|
|
24
17
|
db = createDurableObjectDb(durableObjectBinding, name);
|
|
25
|
-
|
|
18
|
+
moduleLevelDbCache.set(name, db);
|
|
19
|
+
}
|
|
20
|
+
if (requestInfo.rw) {
|
|
21
|
+
if (!requestInfo.rw.databases) {
|
|
22
|
+
requestInfo.rw.databases = new Map();
|
|
23
|
+
}
|
|
24
|
+
requestInfo.rw.databases.set(name, db);
|
|
26
25
|
}
|
|
27
26
|
return db;
|
|
28
27
|
};
|
|
29
|
-
waitForRequestInfo().then(() => doCreateDb());
|
|
30
28
|
return new Proxy({}, {
|
|
31
|
-
get(target, prop
|
|
32
|
-
const db =
|
|
29
|
+
get(target, prop) {
|
|
30
|
+
const db = getDb();
|
|
33
31
|
const value = db[prop];
|
|
34
32
|
if (typeof value === "function") {
|
|
35
33
|
return value.bind(db);
|
|
@@ -24,108 +24,12 @@ const getPackageManagerInfo = (targetDir) => {
|
|
|
24
24
|
}
|
|
25
25
|
return pnpmResult;
|
|
26
26
|
};
|
|
27
|
-
|
|
28
|
-
* @summary Workaround for pnpm's local tarball dependency resolution.
|
|
29
|
-
*
|
|
30
|
-
* @description
|
|
31
|
-
* When installing a new version of the SDK from a local tarball (e.g., during
|
|
32
|
-
* development with `rwsync`), pnpm creates a new, uniquely-named directory in
|
|
33
|
-
* the `.pnpm` store (e.g., `rwsdk@file+...`).
|
|
34
|
-
*
|
|
35
|
-
* A challenge arises when other packages list `rwsdk` as a peer dependency.
|
|
36
|
-
* pnpm may not consistently update the symlinks for these peer dependencies
|
|
37
|
-
* to point to the newest `rwsdk` instance. This can result in a state where
|
|
38
|
-
* multiple versions of `rwsdk` coexist in `node_modules`, with some parts of
|
|
39
|
-
* the application using a stale version.
|
|
40
|
-
*
|
|
41
|
-
* This function addresses the issue by:
|
|
42
|
-
* 1. Identifying the most recently installed `rwsdk` instance in the `.pnpm`
|
|
43
|
-
* store after a `pnpm install` run.
|
|
44
|
-
* 2. Forcefully updating the top-level `node_modules/rwsdk` symlink to point
|
|
45
|
-
* to this new instance.
|
|
46
|
-
* 3. Traversing all other `rwsdk`-related directories in the `.pnpm` store
|
|
47
|
-
* and updating their internal `rwsdk` symlinks to also point to the correct
|
|
48
|
-
* new instance.
|
|
49
|
-
*
|
|
50
|
-
* I am sorry for this ugly hack, I am sure there is a better way, and that it is me
|
|
51
|
-
* doing something wrong. The aim is not to go down this rabbit hole right now
|
|
52
|
-
* -- @justinvdm
|
|
53
|
-
*/
|
|
54
|
-
const hackyPnpmSymlinkFix = async (targetDir) => {
|
|
55
|
-
console.log("💣 Performing pnpm symlink fix...");
|
|
56
|
-
const pnpmDir = path.join(targetDir, "node_modules", ".pnpm");
|
|
57
|
-
if (!existsSync(pnpmDir)) {
|
|
58
|
-
console.log(" 🤔 No .pnpm directory found.");
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
try {
|
|
62
|
-
const entries = await fs.readdir(pnpmDir);
|
|
63
|
-
// Find ALL rwsdk directories, not just file-based ones, to handle
|
|
64
|
-
// all kinds of stale peer dependencies.
|
|
65
|
-
const rwsdkDirs = entries.filter((e) => e.startsWith("rwsdk@"));
|
|
66
|
-
console.log(" Found rwsdk directories:", rwsdkDirs);
|
|
67
|
-
if (rwsdkDirs.length === 0) {
|
|
68
|
-
console.log(" 🤔 No rwsdk directories found to hack.");
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
let latestDir = "";
|
|
72
|
-
let latestMtime = new Date(0);
|
|
73
|
-
for (const dir of rwsdkDirs) {
|
|
74
|
-
const fullPath = path.join(pnpmDir, dir);
|
|
75
|
-
const stats = await fs.stat(fullPath);
|
|
76
|
-
if (stats.mtime > latestMtime) {
|
|
77
|
-
latestMtime = stats.mtime;
|
|
78
|
-
latestDir = dir;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
console.log(" Latest rwsdk directory:", latestDir);
|
|
82
|
-
if (!latestDir) {
|
|
83
|
-
console.log(" 🤔 Could not determine the latest rwsdk directory.");
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const goldenSourcePath = path.join(pnpmDir, latestDir, "node_modules", "rwsdk");
|
|
87
|
-
if (!existsSync(goldenSourcePath)) {
|
|
88
|
-
console.error(` ❌ Golden source path does not exist: ${goldenSourcePath}`);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
console.log(` 🎯 Golden rwsdk path is: ${goldenSourcePath}`);
|
|
92
|
-
// 1. Fix top-level symlink
|
|
93
|
-
const topLevelSymlink = path.join(targetDir, "node_modules", "rwsdk");
|
|
94
|
-
await fs.rm(topLevelSymlink, { recursive: true, force: true });
|
|
95
|
-
await fs.symlink(goldenSourcePath, topLevelSymlink, "dir");
|
|
96
|
-
console.log(` ✅ Symlinked ${topLevelSymlink} -> ${goldenSourcePath}`);
|
|
97
|
-
// 2. Fix peer dependency symlinks
|
|
98
|
-
const allPnpmDirs = await fs.readdir(pnpmDir);
|
|
99
|
-
for (const dir of allPnpmDirs) {
|
|
100
|
-
if (dir === latestDir || !dir.includes("rwsdk"))
|
|
101
|
-
continue;
|
|
102
|
-
const peerSymlink = path.join(pnpmDir, dir, "node_modules", "rwsdk");
|
|
103
|
-
if (existsSync(peerSymlink)) {
|
|
104
|
-
await fs.rm(peerSymlink, { recursive: true, force: true });
|
|
105
|
-
await fs.symlink(goldenSourcePath, peerSymlink, "dir");
|
|
106
|
-
console.log(` ✅ Hijacked symlink in ${dir}`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
console.error(" ❌ Failed during hacky pnpm symlink fix:", error);
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
const performFullSync = async (sdkDir, targetDir, cacheBust = false) => {
|
|
27
|
+
const performFullSync = async (sdkDir, targetDir) => {
|
|
115
28
|
const sdkPackageJsonPath = path.join(sdkDir, "package.json");
|
|
116
29
|
let originalSdkPackageJson = null;
|
|
117
30
|
let tarballPath = "";
|
|
118
31
|
let tarballName = "";
|
|
119
32
|
try {
|
|
120
|
-
if (cacheBust) {
|
|
121
|
-
console.log("💥 Cache-busting version for full sync...");
|
|
122
|
-
originalSdkPackageJson = await fs.readFile(sdkPackageJsonPath, "utf-8");
|
|
123
|
-
const packageJson = JSON.parse(originalSdkPackageJson);
|
|
124
|
-
const now = Date.now();
|
|
125
|
-
// This is a temporary version used for cache busting
|
|
126
|
-
packageJson.version = `${packageJson.version}-dev.${now}`;
|
|
127
|
-
await fs.writeFile(sdkPackageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
128
|
-
}
|
|
129
33
|
console.log("📦 Packing SDK...");
|
|
130
34
|
const packResult = await $({ cwd: sdkDir }) `npm pack`;
|
|
131
35
|
tarballName = packResult.stdout?.trim() ?? "";
|
|
@@ -145,47 +49,25 @@ const performFullSync = async (sdkDir, targetDir, cacheBust = false) => {
|
|
|
145
49
|
.readFile(lockfilePath, "utf-8")
|
|
146
50
|
.catch(() => null);
|
|
147
51
|
try {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
targetPackageJson.pnpm = targetPackageJson.pnpm || {};
|
|
153
|
-
targetPackageJson.pnpm.overrides =
|
|
154
|
-
targetPackageJson.pnpm.overrides || {};
|
|
155
|
-
targetPackageJson.pnpm.overrides.rwsdk = `file:${tarballPath}`;
|
|
156
|
-
await fs.writeFile(packageJsonPath, JSON.stringify(targetPackageJson, null, 2));
|
|
157
|
-
}
|
|
158
|
-
// We use install here, which respects the overrides.
|
|
159
|
-
// We also don't want to fail if the lockfile is out of date.
|
|
160
|
-
await $("pnpm", ["install", "--no-frozen-lockfile"], {
|
|
161
|
-
cwd: targetDir,
|
|
162
|
-
stdio: "inherit",
|
|
163
|
-
});
|
|
164
|
-
if (process.env.RWSDK_PNPM_SYMLINK_FIX) {
|
|
165
|
-
await hackyPnpmSymlinkFix(targetDir);
|
|
166
|
-
}
|
|
52
|
+
const cmd = pm.name;
|
|
53
|
+
const args = [pm.command];
|
|
54
|
+
if (pm.name === "yarn") {
|
|
55
|
+
args.push(`file:${tarballPath}`);
|
|
167
56
|
}
|
|
168
57
|
else {
|
|
169
|
-
|
|
170
|
-
const args = [pm.command];
|
|
171
|
-
if (pm.name === "yarn") {
|
|
172
|
-
args.push(`file:${tarballPath}`);
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
args.push(tarballPath);
|
|
176
|
-
}
|
|
177
|
-
await $(cmd, args, {
|
|
178
|
-
cwd: targetDir,
|
|
179
|
-
stdio: "inherit",
|
|
180
|
-
});
|
|
58
|
+
args.push(tarballPath);
|
|
181
59
|
}
|
|
60
|
+
await $(cmd, args, {
|
|
61
|
+
cwd: targetDir,
|
|
62
|
+
stdio: "inherit",
|
|
63
|
+
});
|
|
182
64
|
}
|
|
183
65
|
finally {
|
|
184
66
|
if (originalPackageJson) {
|
|
185
67
|
console.log("Restoring package.json...");
|
|
186
68
|
await fs.writeFile(packageJsonPath, originalPackageJson);
|
|
187
69
|
}
|
|
188
|
-
if (originalLockfile
|
|
70
|
+
if (originalLockfile) {
|
|
189
71
|
console.log(`Restoring ${pm.lockFile}...`);
|
|
190
72
|
await fs.writeFile(lockfilePath, originalLockfile);
|
|
191
73
|
}
|
|
@@ -218,13 +100,17 @@ const performFastSync = async (sdkDir, targetDir) => {
|
|
|
218
100
|
// Always copy package.json
|
|
219
101
|
await fs.copyFile(path.join(sdkDir, "package.json"), path.join(targetDir, "node_modules/rwsdk/package.json"));
|
|
220
102
|
};
|
|
103
|
+
const areDependenciesEqual = (deps1, deps2) => {
|
|
104
|
+
// Simple string comparison for this use case is sufficient
|
|
105
|
+
return JSON.stringify(deps1 ?? {}) === JSON.stringify(deps2 ?? {});
|
|
106
|
+
};
|
|
221
107
|
const performSync = async (sdkDir, targetDir) => {
|
|
222
108
|
console.log("🏗️ Rebuilding SDK...");
|
|
223
109
|
await $ `pnpm build`;
|
|
224
110
|
const forceFullSync = Boolean(process.env.RWSDK_FORCE_FULL_SYNC);
|
|
225
111
|
if (forceFullSync) {
|
|
226
112
|
console.log("🏃 Force full sync mode is enabled.");
|
|
227
|
-
await performFullSync(sdkDir, targetDir
|
|
113
|
+
await performFullSync(sdkDir, targetDir);
|
|
228
114
|
console.log("✅ Done syncing");
|
|
229
115
|
return;
|
|
230
116
|
}
|
|
@@ -234,15 +120,17 @@ const performSync = async (sdkDir, targetDir) => {
|
|
|
234
120
|
if (existsSync(installedSdkPackageJsonPath)) {
|
|
235
121
|
const sdkPackageJsonContent = await fs.readFile(sdkPackageJsonPath, "utf-8");
|
|
236
122
|
const installedSdkPackageJsonContent = await fs.readFile(installedSdkPackageJsonPath, "utf-8");
|
|
237
|
-
|
|
123
|
+
const sdkPkg = JSON.parse(sdkPackageJsonContent);
|
|
124
|
+
const installedPkg = JSON.parse(installedSdkPackageJsonContent);
|
|
125
|
+
if (areDependenciesEqual(sdkPkg.dependencies, installedPkg.dependencies) &&
|
|
126
|
+
areDependenciesEqual(sdkPkg.devDependencies, installedPkg.devDependencies) &&
|
|
127
|
+
areDependenciesEqual(sdkPkg.peerDependencies, installedPkg.peerDependencies)) {
|
|
238
128
|
packageJsonChanged = false;
|
|
239
129
|
}
|
|
240
130
|
}
|
|
241
131
|
if (packageJsonChanged) {
|
|
242
132
|
console.log("📦 package.json changed, performing full sync...");
|
|
243
|
-
|
|
244
|
-
// see a new version and the hacky symlink fix runs on a clean slate.
|
|
245
|
-
await performFullSync(sdkDir, targetDir, true);
|
|
133
|
+
await performFullSync(sdkDir, targetDir);
|
|
246
134
|
}
|
|
247
135
|
else {
|
|
248
136
|
await performFastSync(sdkDir, targetDir);
|
|
@@ -261,8 +149,7 @@ export const debugSync = async (opts) => {
|
|
|
261
149
|
return;
|
|
262
150
|
}
|
|
263
151
|
// --- Watch Mode Logic ---
|
|
264
|
-
|
|
265
|
-
const lockfilePath = path.join(sdkDir, ".rwsync.lock");
|
|
152
|
+
const lockfilePath = path.join(targetDir, "node_modules", ".rwsync.lock");
|
|
266
153
|
let release;
|
|
267
154
|
// Ensure the directory for the lockfile exists
|
|
268
155
|
await fs.mkdir(path.dirname(lockfilePath), { recursive: true });
|
|
@@ -273,7 +160,7 @@ export const debugSync = async (opts) => {
|
|
|
273
160
|
}
|
|
274
161
|
catch (e) {
|
|
275
162
|
if (e.code === "ELOCKED") {
|
|
276
|
-
console.error(`❌ Another rwsync process is already
|
|
163
|
+
console.error(`❌ Another rwsync process is already watching ${targetDir}.`);
|
|
277
164
|
console.error(` If this is not correct, please remove the lockfile at ${lockfilePath}`);
|
|
278
165
|
process.exit(1);
|
|
279
166
|
}
|