@hangox/mg-cli 1.0.6 → 1.0.8
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/cli.js +172 -94
- package/dist/cli.js.map +1 -1
- package/dist/daemon-runner.js +46 -35
- package/dist/daemon-runner.js.map +1 -1
- package/dist/{index-BCd-mD-X.d.ts → index-DmySkKst.d.ts} +149 -5
- package/dist/index.d.ts +64 -5
- package/dist/index.js +333 -49
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +46 -35
- package/dist/server.js.map +1 -1
- package/package.json +2 -3
- package/VERSION +0 -1
package/dist/index.js
CHANGED
|
@@ -34,6 +34,7 @@ var MessageType = /* @__PURE__ */ ((MessageType2) => {
|
|
|
34
34
|
MessageType2["REGISTER"] = "register";
|
|
35
35
|
MessageType2["REGISTER_ACK"] = "register_ack";
|
|
36
36
|
MessageType2["GET_NODE_BY_ID"] = "get_node_by_id";
|
|
37
|
+
MessageType2["GET_PAGE_BY_ID"] = "get_page_by_id";
|
|
37
38
|
MessageType2["GET_ALL_NODES"] = "get_all_nodes";
|
|
38
39
|
MessageType2["GET_SELECTION"] = "get_selection";
|
|
39
40
|
MessageType2["EXPORT_IMAGE"] = "export_image";
|
|
@@ -225,27 +226,44 @@ function parseMgpLink(link) {
|
|
|
225
226
|
const queryString = urlPart.slice(questionMarkIndex + 1);
|
|
226
227
|
const params = new URLSearchParams(queryString);
|
|
227
228
|
const encodedNodeId = params.get("nodeId");
|
|
228
|
-
|
|
229
|
+
const encodedPageId = params.get("pageId");
|
|
230
|
+
if (!encodedNodeId && !encodedPageId) {
|
|
229
231
|
return null;
|
|
230
232
|
}
|
|
231
|
-
|
|
232
|
-
if (!/^(\d+:\d+)(\/\d+:\d+)*$/.test(nodeId)) {
|
|
233
|
+
if (encodedNodeId && encodedPageId) {
|
|
233
234
|
return null;
|
|
234
235
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const decodedNodePath = decodeURIComponent(encodedNodePath);
|
|
239
|
-
nodePath = decodedNodePath.split("/").filter(Boolean);
|
|
240
|
-
if (!nodePath.every((segment) => /^\d+:\d+$/.test(segment))) {
|
|
236
|
+
if (encodedNodeId) {
|
|
237
|
+
const nodeId = decodeURIComponent(encodedNodeId);
|
|
238
|
+
if (!/^(\d+:\d+)(\/\d+:\d+)*$/.test(nodeId)) {
|
|
241
239
|
return null;
|
|
242
240
|
}
|
|
241
|
+
const encodedNodePath = params.get("nodePath");
|
|
242
|
+
let nodePath;
|
|
243
|
+
if (encodedNodePath) {
|
|
244
|
+
const decodedNodePath = decodeURIComponent(encodedNodePath);
|
|
245
|
+
nodePath = decodedNodePath.split("/").filter(Boolean);
|
|
246
|
+
if (!nodePath.every((segment) => /^\d+:\d+$/.test(segment))) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return {
|
|
251
|
+
pageUrl,
|
|
252
|
+
nodeId,
|
|
253
|
+
nodePath
|
|
254
|
+
};
|
|
243
255
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
256
|
+
if (encodedPageId) {
|
|
257
|
+
const pageId = decodeURIComponent(encodedPageId);
|
|
258
|
+
if (!/^\d+:\d+$/.test(pageId)) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
pageUrl,
|
|
263
|
+
pageId
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
return null;
|
|
249
267
|
} catch {
|
|
250
268
|
return null;
|
|
251
269
|
}
|
|
@@ -260,6 +278,11 @@ function generateMgpLink(pageUrl, nodeId, nodePath) {
|
|
|
260
278
|
}
|
|
261
279
|
return link;
|
|
262
280
|
}
|
|
281
|
+
function generatePageLink(pageUrl, pageId) {
|
|
282
|
+
const normalizedUrl = normalizePageUrl(pageUrl);
|
|
283
|
+
const encodedPageId = encodeURIComponent(pageId);
|
|
284
|
+
return `mgp://${normalizedUrl}?pageId=${encodedPageId}`;
|
|
285
|
+
}
|
|
263
286
|
function formatFileSize(bytes) {
|
|
264
287
|
if (bytes < 1024) {
|
|
265
288
|
return `${bytes} \u5B57\u8282`;
|
|
@@ -557,7 +580,7 @@ function createLogger(options) {
|
|
|
557
580
|
// src/server/connection-manager.ts
|
|
558
581
|
var ConnectionManager = class {
|
|
559
582
|
logger;
|
|
560
|
-
/** Provider 连接(按页面 URL
|
|
583
|
+
/** Provider 连接(按页面 URL 索引,支持同 URL 多个连接) */
|
|
561
584
|
providers = /* @__PURE__ */ new Map();
|
|
562
585
|
/** Consumer 连接 */
|
|
563
586
|
consumers = /* @__PURE__ */ new Map();
|
|
@@ -593,7 +616,8 @@ var ConnectionManager = class {
|
|
|
593
616
|
*/
|
|
594
617
|
checkHeartbeats() {
|
|
595
618
|
const now = Date.now();
|
|
596
|
-
|
|
619
|
+
const entries = Array.from(this.allConnections.entries());
|
|
620
|
+
for (const [id, ws] of entries) {
|
|
597
621
|
const lastActive = ws.connectionInfo.lastActiveAt.getTime();
|
|
598
622
|
const elapsed = now - lastActive;
|
|
599
623
|
if (elapsed > HEARTBEAT_TIMEOUT) {
|
|
@@ -623,14 +647,10 @@ var ConnectionManager = class {
|
|
|
623
647
|
managedWs.isAlive = true;
|
|
624
648
|
this.allConnections.set(connectionId, managedWs);
|
|
625
649
|
if (type === "provider" /* PROVIDER */ && pageUrl) {
|
|
626
|
-
const existing = this.providers.get(pageUrl);
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
existing.close();
|
|
631
|
-
}
|
|
632
|
-
this.providers.set(pageUrl, managedWs);
|
|
633
|
-
this.logger.info(`Provider \u8FDE\u63A5: ${pageUrl}`);
|
|
650
|
+
const existing = this.providers.get(pageUrl) || [];
|
|
651
|
+
existing.push(managedWs);
|
|
652
|
+
this.providers.set(pageUrl, existing);
|
|
653
|
+
this.logger.info(`Provider \u8FDE\u63A5: ${pageUrl} (\u5F53\u524D\u8BE5\u9875\u9762\u8FDE\u63A5\u6570: ${existing.length})`);
|
|
634
654
|
} else if (type === "consumer" /* CONSUMER */) {
|
|
635
655
|
this.consumers.set(connectionId, managedWs);
|
|
636
656
|
this.logger.info(`Consumer \u8FDE\u63A5: ${connectionId}`);
|
|
@@ -644,8 +664,17 @@ var ConnectionManager = class {
|
|
|
644
664
|
const { connectionId, connectionInfo } = ws;
|
|
645
665
|
this.allConnections.delete(connectionId);
|
|
646
666
|
if (connectionInfo.type === "provider" /* PROVIDER */ && connectionInfo.pageUrl) {
|
|
647
|
-
this.providers.
|
|
648
|
-
|
|
667
|
+
const connections = this.providers.get(connectionInfo.pageUrl);
|
|
668
|
+
if (connections) {
|
|
669
|
+
const index = connections.findIndex((c) => c.connectionId === connectionId);
|
|
670
|
+
if (index !== -1) {
|
|
671
|
+
connections.splice(index, 1);
|
|
672
|
+
if (connections.length === 0) {
|
|
673
|
+
this.providers.delete(connectionInfo.pageUrl);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
this.logger.info(`Provider \u65AD\u5F00: ${connectionInfo.pageUrl} (\u8FDE\u63A5ID: ${connectionId})`);
|
|
649
678
|
} else if (connectionInfo.type === "consumer" /* CONSUMER */) {
|
|
650
679
|
this.consumers.delete(connectionId);
|
|
651
680
|
this.logger.info(`Consumer \u65AD\u5F00: ${connectionId}`);
|
|
@@ -659,31 +688,48 @@ var ConnectionManager = class {
|
|
|
659
688
|
ws.isAlive = true;
|
|
660
689
|
}
|
|
661
690
|
/**
|
|
662
|
-
* 根据页面 URL 查找 Provider
|
|
691
|
+
* 根据页面 URL 查找 Provider(返回第一个可用的连接)
|
|
663
692
|
*/
|
|
664
693
|
findProviderByPageUrl(pageUrl) {
|
|
665
|
-
|
|
694
|
+
const connections = this.providers.get(pageUrl);
|
|
695
|
+
return connections?.[0];
|
|
666
696
|
}
|
|
667
697
|
/**
|
|
668
698
|
* 获取第一个可用的 Provider
|
|
669
699
|
*/
|
|
670
700
|
getFirstProvider() {
|
|
671
|
-
const
|
|
672
|
-
const
|
|
673
|
-
|
|
701
|
+
const allConnections = Array.from(this.providers.values());
|
|
702
|
+
for (const connections of allConnections) {
|
|
703
|
+
if (connections.length > 0) {
|
|
704
|
+
return connections[0];
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
return void 0;
|
|
674
708
|
}
|
|
675
709
|
/**
|
|
676
710
|
* 获取所有 Provider 信息
|
|
677
711
|
*/
|
|
678
712
|
getAllProviders() {
|
|
679
|
-
|
|
713
|
+
const result = [];
|
|
714
|
+
const allConnections = Array.from(this.providers.values());
|
|
715
|
+
for (const connections of allConnections) {
|
|
716
|
+
for (const ws of connections) {
|
|
717
|
+
result.push(ws.connectionInfo);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
return result;
|
|
680
721
|
}
|
|
681
722
|
/**
|
|
682
723
|
* 获取连接统计
|
|
683
724
|
*/
|
|
684
725
|
getStats() {
|
|
726
|
+
let providerCount = 0;
|
|
727
|
+
const allConnections = Array.from(this.providers.values());
|
|
728
|
+
for (const connections of allConnections) {
|
|
729
|
+
providerCount += connections.length;
|
|
730
|
+
}
|
|
685
731
|
return {
|
|
686
|
-
providers:
|
|
732
|
+
providers: providerCount,
|
|
687
733
|
consumers: this.consumers.size,
|
|
688
734
|
total: this.allConnections.size
|
|
689
735
|
};
|
|
@@ -699,7 +745,8 @@ var ConnectionManager = class {
|
|
|
699
745
|
*/
|
|
700
746
|
closeAll() {
|
|
701
747
|
this.stopHeartbeatCheck();
|
|
702
|
-
|
|
748
|
+
const allWs = Array.from(this.allConnections.values());
|
|
749
|
+
for (const ws of allWs) {
|
|
703
750
|
ws.close();
|
|
704
751
|
}
|
|
705
752
|
this.providers.clear();
|
|
@@ -853,24 +900,11 @@ function getVersion() {
|
|
|
853
900
|
try {
|
|
854
901
|
const currentFile = fileURLToPath(import.meta.url);
|
|
855
902
|
const currentDir = dirname3(currentFile);
|
|
856
|
-
const versionFilePaths = [
|
|
857
|
-
join2(currentDir, "..", "VERSION"),
|
|
858
|
-
// dist/xxx.js -> ../VERSION
|
|
859
|
-
join2(currentDir, "..", "..", "VERSION")
|
|
860
|
-
// src/shared/version.ts -> ../../VERSION
|
|
861
|
-
];
|
|
862
|
-
for (const versionFilePath of versionFilePaths) {
|
|
863
|
-
if (existsSync3(versionFilePath)) {
|
|
864
|
-
const version = readFileSync2(versionFilePath, "utf-8").trim();
|
|
865
|
-
if (version) {
|
|
866
|
-
cachedVersion = version;
|
|
867
|
-
return cachedVersion;
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
903
|
const packageJsonPaths = [
|
|
872
904
|
join2(currentDir, "..", "package.json"),
|
|
905
|
+
// dist/xxx.js -> ../package.json
|
|
873
906
|
join2(currentDir, "..", "..", "package.json")
|
|
907
|
+
// src/shared/version.ts -> ../../package.json
|
|
874
908
|
];
|
|
875
909
|
for (const packageJsonPath of packageJsonPaths) {
|
|
876
910
|
if (existsSync3(packageJsonPath)) {
|
|
@@ -888,6 +922,13 @@ function getVersion() {
|
|
|
888
922
|
return cachedVersion;
|
|
889
923
|
}
|
|
890
924
|
}
|
|
925
|
+
var DEV_VERSION = "9.9.9";
|
|
926
|
+
function isVersionMatch(version1, version2) {
|
|
927
|
+
if (version1 === DEV_VERSION || version2 === DEV_VERSION) {
|
|
928
|
+
return true;
|
|
929
|
+
}
|
|
930
|
+
return version1 === version2;
|
|
931
|
+
}
|
|
891
932
|
|
|
892
933
|
// src/server/websocket-server.ts
|
|
893
934
|
var MGServer = class {
|
|
@@ -1134,6 +1175,247 @@ var MGServer = class {
|
|
|
1134
1175
|
function createServer(options) {
|
|
1135
1176
|
return new MGServer(options);
|
|
1136
1177
|
}
|
|
1178
|
+
|
|
1179
|
+
// src/cli/client.ts
|
|
1180
|
+
import WebSocket2 from "ws";
|
|
1181
|
+
|
|
1182
|
+
// src/server/daemon.ts
|
|
1183
|
+
import { spawn } from "child_process";
|
|
1184
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1185
|
+
import { dirname as dirname4, join as join3 } from "path";
|
|
1186
|
+
function isServerRunning() {
|
|
1187
|
+
const info = readServerInfo();
|
|
1188
|
+
if (!info) {
|
|
1189
|
+
return { running: false, info: null };
|
|
1190
|
+
}
|
|
1191
|
+
if (!isProcessRunning(info.pid)) {
|
|
1192
|
+
deleteServerInfo();
|
|
1193
|
+
return { running: false, info: null };
|
|
1194
|
+
}
|
|
1195
|
+
return { running: true, info };
|
|
1196
|
+
}
|
|
1197
|
+
async function startServerDaemon(port) {
|
|
1198
|
+
const { running, info } = isServerRunning();
|
|
1199
|
+
if (running && info) {
|
|
1200
|
+
throw new MGError(
|
|
1201
|
+
"E016" /* SERVER_ALREADY_RUNNING */,
|
|
1202
|
+
`Server \u5DF2\u5728\u8FD0\u884C\u4E2D (PID: ${info.pid}, \u7AEF\u53E3: ${info.port})`
|
|
1203
|
+
);
|
|
1204
|
+
}
|
|
1205
|
+
ensureConfigDir();
|
|
1206
|
+
const currentFile = fileURLToPath2(import.meta.url);
|
|
1207
|
+
const currentDir = dirname4(currentFile);
|
|
1208
|
+
const serverScript = join3(currentDir, "daemon-runner.js");
|
|
1209
|
+
const args = ["--foreground"];
|
|
1210
|
+
if (port) {
|
|
1211
|
+
args.push("--port", String(port));
|
|
1212
|
+
}
|
|
1213
|
+
const child = spawn(process.execPath, [serverScript, ...args], {
|
|
1214
|
+
detached: true,
|
|
1215
|
+
stdio: "ignore",
|
|
1216
|
+
env: {
|
|
1217
|
+
...process.env,
|
|
1218
|
+
MG_DAEMON: "1"
|
|
1219
|
+
}
|
|
1220
|
+
});
|
|
1221
|
+
child.unref();
|
|
1222
|
+
const startTime = Date.now();
|
|
1223
|
+
while (Date.now() - startTime < SERVER_START_TIMEOUT) {
|
|
1224
|
+
await new Promise((resolve2) => setTimeout(resolve2, 200));
|
|
1225
|
+
const { running: running2, info: info2 } = isServerRunning();
|
|
1226
|
+
if (running2 && info2) {
|
|
1227
|
+
return info2;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
throw new MGError("E015" /* SERVER_START_FAILED */, "Server \u542F\u52A8\u8D85\u65F6");
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
// src/cli/client.ts
|
|
1234
|
+
var MGClient = class {
|
|
1235
|
+
ws = null;
|
|
1236
|
+
options;
|
|
1237
|
+
constructor(options = {}) {
|
|
1238
|
+
this.options = options;
|
|
1239
|
+
}
|
|
1240
|
+
/**
|
|
1241
|
+
* 连接到 Server
|
|
1242
|
+
*/
|
|
1243
|
+
async connect() {
|
|
1244
|
+
const serverInfo = readServerInfo();
|
|
1245
|
+
if (serverInfo) {
|
|
1246
|
+
if (isProcessRunning(serverInfo.pid)) {
|
|
1247
|
+
const currentVersion = getVersion();
|
|
1248
|
+
if (!isVersionMatch(currentVersion, serverInfo.version)) {
|
|
1249
|
+
console.warn(`\u26A0\uFE0F \u7248\u672C\u4E0D\u5339\u914D: CLI ${currentVersion} vs Server ${serverInfo.version}`);
|
|
1250
|
+
console.warn("\u63D0\u793A: \u5982\u9700\u5BF9\u9F50\u7248\u672C\uFF0C\u8BF7\u624B\u52A8\u8FD0\u884C `npx -y @hangox/mg-cli@latest server restart`");
|
|
1251
|
+
}
|
|
1252
|
+
try {
|
|
1253
|
+
await this.tryConnect(serverInfo.port);
|
|
1254
|
+
return;
|
|
1255
|
+
} catch {
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
for (let port = PORT_RANGE_START; port <= PORT_RANGE_END; port++) {
|
|
1260
|
+
try {
|
|
1261
|
+
await this.tryConnect(port);
|
|
1262
|
+
return;
|
|
1263
|
+
} catch {
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
if (!this.options.noAutoStart) {
|
|
1267
|
+
console.log("Server \u672A\u8FD0\u884C\uFF0C\u6B63\u5728\u81EA\u52A8\u542F\u52A8...");
|
|
1268
|
+
try {
|
|
1269
|
+
const info = await startServerDaemon();
|
|
1270
|
+
console.log(`Server \u5DF2\u542F\u52A8\uFF0C\u7AEF\u53E3: ${info.port}`);
|
|
1271
|
+
await this.waitForServer(info.port);
|
|
1272
|
+
return;
|
|
1273
|
+
} catch (error) {
|
|
1274
|
+
throw new MGError(
|
|
1275
|
+
"E015" /* SERVER_START_FAILED */,
|
|
1276
|
+
`\u81EA\u52A8\u542F\u52A8 Server \u5931\u8D25: ${error instanceof Error ? error.message : error}`
|
|
1277
|
+
);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
throw new MGError("E001" /* CONNECTION_FAILED */, ErrorMessages["E001" /* CONNECTION_FAILED */]);
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* 尝试连接指定端口
|
|
1284
|
+
*/
|
|
1285
|
+
tryConnect(port) {
|
|
1286
|
+
return new Promise((resolve2, reject) => {
|
|
1287
|
+
const ws = new WebSocket2(`ws://localhost:${port}`);
|
|
1288
|
+
const timer = setTimeout(() => {
|
|
1289
|
+
ws.close();
|
|
1290
|
+
reject(new Error("\u8FDE\u63A5\u8D85\u65F6"));
|
|
1291
|
+
}, PORT_SCAN_TIMEOUT);
|
|
1292
|
+
ws.on("open", () => {
|
|
1293
|
+
clearTimeout(timer);
|
|
1294
|
+
this.ws = ws;
|
|
1295
|
+
this.register();
|
|
1296
|
+
resolve2();
|
|
1297
|
+
});
|
|
1298
|
+
ws.on("error", (error) => {
|
|
1299
|
+
clearTimeout(timer);
|
|
1300
|
+
reject(error);
|
|
1301
|
+
});
|
|
1302
|
+
});
|
|
1303
|
+
}
|
|
1304
|
+
/**
|
|
1305
|
+
* 等待 Server 就绪
|
|
1306
|
+
*/
|
|
1307
|
+
async waitForServer(port) {
|
|
1308
|
+
const startTime = Date.now();
|
|
1309
|
+
const interval = 500;
|
|
1310
|
+
while (Date.now() - startTime < SERVER_START_TIMEOUT) {
|
|
1311
|
+
try {
|
|
1312
|
+
await this.tryConnect(port);
|
|
1313
|
+
return;
|
|
1314
|
+
} catch {
|
|
1315
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
throw new Error("\u7B49\u5F85 Server \u542F\u52A8\u8D85\u65F6");
|
|
1319
|
+
}
|
|
1320
|
+
/**
|
|
1321
|
+
* 注册为 Consumer
|
|
1322
|
+
*/
|
|
1323
|
+
register() {
|
|
1324
|
+
if (!this.ws) return;
|
|
1325
|
+
const message = {
|
|
1326
|
+
type: "register" /* REGISTER */,
|
|
1327
|
+
data: {
|
|
1328
|
+
connectionType: "consumer" /* CONSUMER */
|
|
1329
|
+
},
|
|
1330
|
+
timestamp: Date.now()
|
|
1331
|
+
};
|
|
1332
|
+
this.ws.send(JSON.stringify(message));
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* 发送请求并等待响应
|
|
1336
|
+
*/
|
|
1337
|
+
async request(type, params, pageUrl) {
|
|
1338
|
+
if (!this.ws) {
|
|
1339
|
+
throw new MGError("E001" /* CONNECTION_FAILED */, "\u672A\u8FDE\u63A5\u5230 Server");
|
|
1340
|
+
}
|
|
1341
|
+
const requestId = generateId();
|
|
1342
|
+
const message = {
|
|
1343
|
+
id: requestId,
|
|
1344
|
+
type,
|
|
1345
|
+
params,
|
|
1346
|
+
pageUrl,
|
|
1347
|
+
timestamp: Date.now()
|
|
1348
|
+
};
|
|
1349
|
+
return new Promise((resolve2, reject) => {
|
|
1350
|
+
const timer = setTimeout(() => {
|
|
1351
|
+
reject(new MGError("E012" /* REQUEST_TIMEOUT */, ErrorMessages["E012" /* REQUEST_TIMEOUT */]));
|
|
1352
|
+
}, REQUEST_TIMEOUT);
|
|
1353
|
+
const messageHandler = (data) => {
|
|
1354
|
+
try {
|
|
1355
|
+
const response = JSON.parse(data.toString());
|
|
1356
|
+
if (response.id === requestId) {
|
|
1357
|
+
clearTimeout(timer);
|
|
1358
|
+
this.ws?.off("message", messageHandler);
|
|
1359
|
+
if (response.success) {
|
|
1360
|
+
resolve2(response.data);
|
|
1361
|
+
} else {
|
|
1362
|
+
const error = response.error;
|
|
1363
|
+
reject(
|
|
1364
|
+
new MGError(
|
|
1365
|
+
error?.code || "E099" /* UNKNOWN_ERROR */,
|
|
1366
|
+
error?.message || "\u672A\u77E5\u9519\u8BEF"
|
|
1367
|
+
)
|
|
1368
|
+
);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
} catch {
|
|
1372
|
+
}
|
|
1373
|
+
};
|
|
1374
|
+
this.ws.on("message", messageHandler);
|
|
1375
|
+
this.ws.send(JSON.stringify(message));
|
|
1376
|
+
});
|
|
1377
|
+
}
|
|
1378
|
+
/**
|
|
1379
|
+
* 带重试的请求
|
|
1380
|
+
*/
|
|
1381
|
+
async requestWithRetry(type, params, pageUrl) {
|
|
1382
|
+
if (this.options.noRetry) {
|
|
1383
|
+
return this.request(type, params, pageUrl);
|
|
1384
|
+
}
|
|
1385
|
+
let lastError = null;
|
|
1386
|
+
for (let attempt = 0; attempt <= MAX_RETRY_COUNT; attempt++) {
|
|
1387
|
+
try {
|
|
1388
|
+
return await this.request(type, params, pageUrl);
|
|
1389
|
+
} catch (error) {
|
|
1390
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
1391
|
+
if (error instanceof MGError) {
|
|
1392
|
+
const retryable = ["E017" /* CONNECTION_LOST */, "E012" /* REQUEST_TIMEOUT */];
|
|
1393
|
+
if (!retryable.includes(error.code)) {
|
|
1394
|
+
throw error;
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
if (attempt < MAX_RETRY_COUNT) {
|
|
1398
|
+
const delay = RETRY_INTERVALS[attempt] || RETRY_INTERVALS[RETRY_INTERVALS.length - 1];
|
|
1399
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
1400
|
+
try {
|
|
1401
|
+
await this.connect();
|
|
1402
|
+
} catch {
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
throw lastError || new MGError("E099" /* UNKNOWN_ERROR */, "\u8BF7\u6C42\u5931\u8D25");
|
|
1408
|
+
}
|
|
1409
|
+
/**
|
|
1410
|
+
* 关闭连接
|
|
1411
|
+
*/
|
|
1412
|
+
close() {
|
|
1413
|
+
if (this.ws) {
|
|
1414
|
+
this.ws.close();
|
|
1415
|
+
this.ws = null;
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
};
|
|
1137
1419
|
export {
|
|
1138
1420
|
CONFIG_DIR,
|
|
1139
1421
|
ConnectionManager,
|
|
@@ -1153,6 +1435,7 @@ export {
|
|
|
1153
1435
|
Logger,
|
|
1154
1436
|
MAX_PORT_ATTEMPTS,
|
|
1155
1437
|
MAX_RETRY_COUNT,
|
|
1438
|
+
MGClient,
|
|
1156
1439
|
MGError,
|
|
1157
1440
|
MGServer,
|
|
1158
1441
|
MessageType,
|
|
@@ -1185,6 +1468,7 @@ export {
|
|
|
1185
1468
|
formatLogTime,
|
|
1186
1469
|
generateId,
|
|
1187
1470
|
generateMgpLink,
|
|
1471
|
+
generatePageLink,
|
|
1188
1472
|
getCurrentISOTime,
|
|
1189
1473
|
isDesignPageUrl,
|
|
1190
1474
|
isProcessRunning,
|