mslxdff 0.1.19 → 0.1.21

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.
Files changed (2) hide show
  1. package/bin/mslxdff.js +73 -26
  2. package/package.json +1 -1
package/bin/mslxdff.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { execFile } from "node:child_process";
3
- import { readFileSync, existsSync, statSync } from "node:fs";
3
+ import { readFileSync, existsSync, statSync, rmSync } from "node:fs";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { dirname, join, basename } from "node:path";
6
6
  import { startServer, resolvePort } from "../src/server.js";
7
- import { DEFAULT_PORT } from "../src/state.js";
7
+ import { DEFAULT_PORT, defaultStateFile } from "../src/state.js";
8
8
  import { createRouter } from "../src/routes.js";
9
9
  import { createUpstreamClient } from "../src/upstream.js";
10
10
  import { createModelsService } from "../src/models.js";
@@ -54,6 +54,37 @@ if (args.includes("-stop") || args.includes("--stop")) {
54
54
  process.exit(0);
55
55
  }
56
56
 
57
+ if (args.includes("-uninstall") || args.includes("--uninstall")) {
58
+ const { stopped, pid } = stopDaemon();
59
+ if (stopped) console.log(`mslxdff daemon stopped (pid ${pid})`);
60
+ else console.log("mslxdff daemon not running");
61
+
62
+ const stateFile = defaultStateFile();
63
+ const dir = dirname(stateFile);
64
+ const removed = [];
65
+ for (const f of [
66
+ stateFile,
67
+ pidFile(),
68
+ logFile(),
69
+ join(dir, "calls.log"),
70
+ join(dir, "errors.log"),
71
+ join(dir, "events.log"),
72
+ ]) {
73
+ try {
74
+ rmSync(f, { force: true });
75
+ removed.push(f);
76
+ } catch {
77
+ // already gone, fine
78
+ }
79
+ }
80
+ if (removed.length) console.log(`removed ${removed.length} file(s):\n ${removed.join("\n ")}`);
81
+ else console.log("no state/log files to remove");
82
+
83
+ console.log("\npackage still installed — finish with:");
84
+ console.log(" npm uninstall -g mslxdff");
85
+ process.exit(0);
86
+ }
87
+
57
88
  if (args.includes("-status") || args.includes("--status") || args.includes("-s")) {
58
89
  await printStatus();
59
90
  process.exit(0);
@@ -196,33 +227,48 @@ if (groupCmd && groupCmd !== "create") {
196
227
  const removed = peers.removeByGroup(a);
197
228
  console.log(before ? `left group "${a}" (${removed} member(s) removed)` : `not a member of group "${a}"`);
198
229
  } else if (action === "list") {
199
- const all = groups.list();
200
- const names = Object.keys(all);
201
- if (names.length) {
202
- for (const n of names) {
203
- console.log(`${n} (${Object.keys(all[n].members || {}).length} members)`);
204
- // probe every member endpoint concurrently to show reachability + latency
205
- const probes = Object.entries(all[n].members || {}).map(([id, m]) => ({
206
- id, url: m?.url,
207
- }));
208
- const joined = loadGroupsJoined().find((g) => g.name === n);
209
- if (joined?.leaderUrl) probes.push({ id: "leader", url: joined.leaderUrl });
210
- const results = await Promise.all(probes.map(probeHealth));
211
- const rows = results.sort((a, b) => (a.rank ?? 9) - (b.rank ?? 9));
212
- for (const r of rows) {
213
- const state = r.fail ? `fail ${r.fail}` : `ok ${r.ms}ms`;
214
- const label = r.id && r.id !== r.url ? r.id + " " : "";
215
- console.log(` ${label}${r.url} ${state}`);
216
- }
217
- }
218
- } else {
230
+ const joinedList = loadGroupsJoined();
231
+ if (!joinedList.length) {
219
232
  console.log("no groups on this node");
233
+ process.exit(0);
220
234
  }
221
- const joined = loadGroupsJoined();
222
- if (joined.length) {
223
- console.log(`\njoined groups (${joined.length}):`);
224
- for (const g of joined) console.log(` ${g.name} ${g.leaderUrl || "(this node is the leader)"}`);
235
+ const { token } = await loadToken();
236
+ const fetchImpl = (url, opts) => fetch(url, { ...opts, signal: AbortSignal.timeout(1500) });
237
+ for (const g of joinedList) {
238
+ const isLeader = !g.leaderUrl;
239
+ let members;
240
+ if (isLeader) {
241
+ members = groups.list()[g.name]?.members || {};
242
+ } else {
243
+ try {
244
+ members = await refreshGroupMembers(g.name, {
245
+ leaderUrl: g.leaderUrl,
246
+ memberName: g.memberName,
247
+ url: g.myUrl,
248
+ token,
249
+ fetchImpl,
250
+ });
251
+ } catch (err) {
252
+ console.log(`${g.name} (members unavailable — leader unreachable: ${errMsg(err)})`);
253
+ continue;
254
+ }
255
+ }
256
+ console.log(`${g.name} (${Object.keys(members).length} members)`);
257
+ // probe every member endpoint concurrently for reachability + latency
258
+ const probes = Object.entries(members).map(([id, m]) => ({ id, url: m?.url || id }));
259
+ if (!isLeader && g.leaderUrl && !probes.some((p) => p.url === g.leaderUrl)) {
260
+ probes.push({ id: "leader", url: g.leaderUrl });
261
+ }
262
+ const results = await Promise.all(probes.map(probeHealth));
263
+ const rows = results.sort((a, b) => (a.rank ?? 9) - (b.rank ?? 9));
264
+ for (const r of rows) {
265
+ const state = r.fail ? `fail ${r.fail}` : `ok ${r.ms}ms`;
266
+ const label = r.id && r.id !== r.url ? r.id + " " : "";
267
+ console.log(` ${label}${r.url} ${state}`);
268
+ }
225
269
  }
270
+ console.log(`\njoined groups (${joinedList.length}):`);
271
+ for (const g of joinedList) console.log(` ${g.name} ${g.leaderUrl || "(this node is the leader)"}`);
226
272
  } else {
227
273
  console.error("usage: mslxdff -creategroup <name> | -group sync | -group leave <name> | -group list");
228
274
  }
@@ -589,6 +635,7 @@ Usage:
589
635
  mslxdff -model refresh force-refresh the model cache from the upstream
590
636
  mslxdff -debug live-follow the daemon event stream (requests, errors, peer forwards)
591
637
  mslxdff -stop stop the running daemon
638
+ mslxdff -uninstall stop the daemon and delete all state/log files
592
639
  mslxdff -port N persist the listen port (restarts the daemon on it if running)
593
640
  mslxdff -update update mslxdff to the latest published version
594
641
  mslxdff -showtoken print the current auth token
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mslxdff",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "description": "测试项目,请勿使用。",
5
5
  "type": "module",
6
6
  "bin": {