@decentnetwork/beagle 0.1.125 → 0.1.126
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/desktop/app.js +1 -1
- package/dist/global-prefix.d.ts +13 -0
- package/dist/global-prefix.js +25 -0
- package/dist/server.js +36 -10
- package/package.json +1 -1
package/dist/desktop/app.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The npm global prefix a file inside a globally installed package lives
|
|
3
|
+
* under — the value `npm i -g --prefix` needs to replace THAT copy.
|
|
4
|
+
*
|
|
5
|
+
* /Users/x/.nvm/versions/node/v24.2.0/lib/node_modules/@decentnetwork/beagle → /Users/x/.nvm/versions/node/v24.2.0
|
|
6
|
+
* /usr/local/lib/node_modules/@decentnetwork/lan/dist/cli/index.js → /usr/local
|
|
7
|
+
* C:\Users\x\AppData\Roaming\npm\node_modules\@decentnetwork\beagle → C:\Users\x\AppData\Roaming\npm
|
|
8
|
+
*
|
|
9
|
+
* Empty when the path is not inside a global node_modules (dev checkout, npx).
|
|
10
|
+
* The FIRST match is the global root; a nested dependency's node_modules
|
|
11
|
+
* sits below it.
|
|
12
|
+
*/
|
|
13
|
+
export declare function globalPrefixOf(path: string, s?: string): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { sep } from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* The npm global prefix a file inside a globally installed package lives
|
|
4
|
+
* under — the value `npm i -g --prefix` needs to replace THAT copy.
|
|
5
|
+
*
|
|
6
|
+
* /Users/x/.nvm/versions/node/v24.2.0/lib/node_modules/@decentnetwork/beagle → /Users/x/.nvm/versions/node/v24.2.0
|
|
7
|
+
* /usr/local/lib/node_modules/@decentnetwork/lan/dist/cli/index.js → /usr/local
|
|
8
|
+
* C:\Users\x\AppData\Roaming\npm\node_modules\@decentnetwork\beagle → C:\Users\x\AppData\Roaming\npm
|
|
9
|
+
*
|
|
10
|
+
* Empty when the path is not inside a global node_modules (dev checkout, npx).
|
|
11
|
+
* The FIRST match is the global root; a nested dependency's node_modules
|
|
12
|
+
* sits below it.
|
|
13
|
+
*/
|
|
14
|
+
export function globalPrefixOf(path, s = sep) {
|
|
15
|
+
const posix = `${s}lib${s}node_modules${s}`;
|
|
16
|
+
const i = path.indexOf(posix);
|
|
17
|
+
if (i > 0)
|
|
18
|
+
return path.slice(0, i);
|
|
19
|
+
if (s === "\\") {
|
|
20
|
+
const w = path.indexOf(`${s}node_modules${s}`);
|
|
21
|
+
if (w > 0)
|
|
22
|
+
return path.slice(0, w);
|
|
23
|
+
}
|
|
24
|
+
return "";
|
|
25
|
+
}
|
package/dist/server.js
CHANGED
|
@@ -30,6 +30,7 @@ import { desktopRequestRow } from "./pending-requests.js";
|
|
|
30
30
|
import { createDiscoverFetch } from "./discover-cache.js";
|
|
31
31
|
import { applyWalletBind } from "@decentnetwork/beagle-ui/wallet-proof";
|
|
32
32
|
import { settleUpload } from "./upload-settle.js";
|
|
33
|
+
import { globalPrefixOf } from "./global-prefix.js";
|
|
33
34
|
// Directory holding the built desktop UI bundle (index.html, app.js, vendor/).
|
|
34
35
|
// scripts/build-ui.mjs emits it next to this compiled module at dist/ui/desktop/.
|
|
35
36
|
const DESKTOP_DIR = join(dirname(fileURLToPath(import.meta.url)), "desktop");
|
|
@@ -345,9 +346,15 @@ function verLt(a, b) {
|
|
|
345
346
|
* different node than this app (nvm: launchd starts v24.2.0 while the shell's
|
|
346
347
|
* npm is v24.3.0), and a global install lands in the prefix of whichever npm
|
|
347
348
|
* ran it — the wrong one leaves the daemon on the old code with no error. */
|
|
348
|
-
|
|
349
|
+
/** `targetPrefix` is the global prefix the RUNNING copy lives in. Pinning node
|
|
350
|
+
* is not enough: an nvm npm-cli.js runs under whatever node its caller picks,
|
|
351
|
+
* and npm on PATH (pm2's PATH on mac-dev: v24.3.0) installs into its own
|
|
352
|
+
* prefix — beagle 0.1.124 ran from v24.2.0 while every click of Update put
|
|
353
|
+
* the new version into v24.3.0, reported success, and restarted onto the old
|
|
354
|
+
* code. An explicit --prefix puts the files where the restart will load them. */
|
|
355
|
+
async function npmGlobalInstall(pkg, nodePath, targetPrefix) {
|
|
349
356
|
const { spawn } = await import("node:child_process");
|
|
350
|
-
const args = ["i", "-g", `${pkg}@latest
|
|
357
|
+
const args = ["i", "-g", `${pkg}@latest`, ...(targetPrefix ? ["--prefix", targetPrefix] : [])];
|
|
351
358
|
const cliFor = (node) => join(dirname(node), "..", "lib", "node_modules", "npm", "bin", "npm-cli.js");
|
|
352
359
|
const npmCli = cliFor(process.execPath);
|
|
353
360
|
const pinned = nodePath && existsSync(nodePath) && existsSync(cliFor(nodePath)) ? cliFor(nodePath) : "";
|
|
@@ -386,10 +393,10 @@ async function npmGlobalInstall(pkg, nodePath) {
|
|
|
386
393
|
const npmCmd = a.cmd === "npm" ? resolveNpmOnPath(npmCli) : [a.cmd, a.args[0]];
|
|
387
394
|
if (npmCmd.length) {
|
|
388
395
|
const [exe, ...pre0] = npmCmd;
|
|
389
|
-
const pre = await runOnce(exe, [...pre0, "prefix", "-g"], 15_000);
|
|
390
|
-
const prefix = pre
|
|
396
|
+
const pre = targetPrefix ? undefined : await runOnce(exe, [...pre0, "prefix", "-g"], 15_000);
|
|
397
|
+
const prefix = targetPrefix || (pre?.code === 0 ? pre.out.trim().split("\n").pop()?.trim() : "");
|
|
391
398
|
if (prefix) {
|
|
392
|
-
const s = await runOnce("sudo", ["-n", "-H", ...npmCmd, ...args, "--prefix", prefix]);
|
|
399
|
+
const s = await runOnce("sudo", ["-n", "-H", ...npmCmd, ...args, ...(targetPrefix ? [] : ["--prefix", prefix])]);
|
|
393
400
|
if (s.code === 0)
|
|
394
401
|
return { ok: true, log: s.out.slice(-2000) };
|
|
395
402
|
return { ok: false, error: `sudo -n npm exited ${s.code}`, log: s.out.slice(-2000) };
|
|
@@ -555,13 +562,31 @@ async function npmQuery(args) {
|
|
|
555
562
|
/** The node binary the running daemon was started with, from its pid's
|
|
556
563
|
* command line (`/…/bin/node /…/bin/agentnet up …`). Empty when unknown. */
|
|
557
564
|
async function daemonNodePath(dataDir) {
|
|
565
|
+
const first = (await daemonCommand(dataDir))[0] ?? "";
|
|
566
|
+
return /(^|\/)node(\.exe)?$/.test(first) && existsSync(first) ? first : "";
|
|
567
|
+
}
|
|
568
|
+
/** The global prefix the running daemon's lan was loaded from: its script
|
|
569
|
+
* (`/…/bin/agentnet`, a symlink into `<prefix>/lib/node_modules/…`) resolved.
|
|
570
|
+
* Empty when unknown — the install then falls back to npm's own prefix. */
|
|
571
|
+
async function daemonLanPrefix(dataDir) {
|
|
572
|
+
const script = (await daemonCommand(dataDir))[1] ?? "";
|
|
573
|
+
if (!script || !existsSync(script))
|
|
574
|
+
return "";
|
|
575
|
+
try {
|
|
576
|
+
return globalPrefixOf(realpathSync(script));
|
|
577
|
+
}
|
|
578
|
+
catch {
|
|
579
|
+
return "";
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
/** The daemon's command line split on whitespace, from its pidfile's pid. */
|
|
583
|
+
async function daemonCommand(dataDir) {
|
|
558
584
|
const pid = dataDir ? readDaemonPid(dataDir) : "";
|
|
559
585
|
if (!/^\d+$/.test(pid) || process.platform === "win32")
|
|
560
|
-
return
|
|
586
|
+
return [];
|
|
561
587
|
const { execFile } = await import("node:child_process");
|
|
562
588
|
const cmd = await new Promise((res) => execFile("ps", ["-o", "command=", "-p", pid], { timeout: 5000 }, (err, out) => res(err ? "" : String(out).trim())));
|
|
563
|
-
|
|
564
|
-
return /(^|\/)node(\.exe)?$/.test(first) && existsSync(first) ? first : "";
|
|
589
|
+
return cmd ? cmd.split(/\s+/) : [];
|
|
565
590
|
}
|
|
566
591
|
async function agentnetRestart(dataDir) {
|
|
567
592
|
const pidBefore = dataDir ? readDaemonPid(dataDir) : "";
|
|
@@ -1895,7 +1920,7 @@ export function startBeagleServer(opts) {
|
|
|
1895
1920
|
// lan (the agentnet daemon) updates independently of beagle's own
|
|
1896
1921
|
// install mode: global reinstall, then ask the daemon to re-exec.
|
|
1897
1922
|
if (body.pkg === "lan") {
|
|
1898
|
-
const inst = await npmGlobalInstall("@decentnetwork/lan", await daemonNodePath(opts.lanHost?.dataDir));
|
|
1923
|
+
const inst = await npmGlobalInstall("@decentnetwork/lan", await daemonNodePath(opts.lanHost?.dataDir), await daemonLanPrefix(opts.lanHost?.dataDir));
|
|
1899
1924
|
if (!inst.ok) {
|
|
1900
1925
|
sendJson(res, 502, inst);
|
|
1901
1926
|
return;
|
|
@@ -1919,7 +1944,8 @@ export function startBeagleServer(opts) {
|
|
|
1919
1944
|
sendJson(res, 200, { ok: true, npx: true });
|
|
1920
1945
|
return;
|
|
1921
1946
|
}
|
|
1922
|
-
|
|
1947
|
+
// Into the prefix THIS copy runs from, with this node's npm — see npmGlobalInstall.
|
|
1948
|
+
const r = await npmGlobalInstall(BEAGLE_PKG, process.execPath, globalPrefixOf(BEAGLE_ROOT) || undefined);
|
|
1923
1949
|
updateCache = null; // next check reflects the new install
|
|
1924
1950
|
sendJson(res, r.ok ? 200 : 502, r);
|
|
1925
1951
|
return;
|
package/package.json
CHANGED