ms-vite-plugin 1.0.2 → 1.0.4
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 +297 -12
- package/dist/device.d.ts +32 -0
- package/dist/device.js +325 -0
- package/dist/project.d.ts +34 -0
- package/dist/project.js +474 -0
- package/dist/ws-manager.d.ts +125 -0
- package/dist/ws-manager.js +392 -0
- package/package.json +9 -3
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.WebSocketServerManager = exports.WSManager = void 0;
|
|
37
|
+
const os = __importStar(require("os"));
|
|
38
|
+
const uuid_1 = require("uuid");
|
|
39
|
+
const ws_1 = require("ws");
|
|
40
|
+
/**
|
|
41
|
+
* 选择当前机器最合适的局域网 IP
|
|
42
|
+
* @returns 返回可用的 IPv4 地址,兜底 127.0.0.1
|
|
43
|
+
* @example
|
|
44
|
+
* const ip = detectHostIp()
|
|
45
|
+
*/
|
|
46
|
+
function detectHostIp() {
|
|
47
|
+
const nets = os.networkInterfaces();
|
|
48
|
+
const entries = [];
|
|
49
|
+
for (const name of Object.keys(nets)) {
|
|
50
|
+
for (const info of nets[name] || []) {
|
|
51
|
+
const i = info;
|
|
52
|
+
const addr = String(i.address || "");
|
|
53
|
+
const bad = /(awdl|utun|llw|bridge|vmnet|vbox|docker)/i.test(name);
|
|
54
|
+
const linkLocal = /^169\.254\./.test(addr);
|
|
55
|
+
if (i.family === "IPv4" && !i.internal && !bad && !linkLocal) {
|
|
56
|
+
entries.push({ name, addr });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const score = (e) => {
|
|
61
|
+
let s = 0;
|
|
62
|
+
if (process.platform === "darwin" && e.name === "en0") {
|
|
63
|
+
s += 60;
|
|
64
|
+
}
|
|
65
|
+
if (/(wi-?fi|wlan|wlp|wl)/i.test(e.name)) {
|
|
66
|
+
s += 50;
|
|
67
|
+
}
|
|
68
|
+
if (/^(en|eth)\d+$/i.test(e.name)) {
|
|
69
|
+
s += 40;
|
|
70
|
+
}
|
|
71
|
+
if (/^192\.168\./.test(e.addr)) {
|
|
72
|
+
s += 30;
|
|
73
|
+
}
|
|
74
|
+
else if (/^10\./.test(e.addr)) {
|
|
75
|
+
s += 25;
|
|
76
|
+
}
|
|
77
|
+
else if (/^172\.(1[6-9]|2[0-9]|3[0-1])\./.test(e.addr)) {
|
|
78
|
+
s += 20;
|
|
79
|
+
}
|
|
80
|
+
return s;
|
|
81
|
+
};
|
|
82
|
+
entries.sort((a, b) => score(b) - score(a));
|
|
83
|
+
return entries[0]?.addr ?? "127.0.0.1";
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* CLI 版 WebSocket 管理器
|
|
87
|
+
*/
|
|
88
|
+
class WSManager {
|
|
89
|
+
constructor() {
|
|
90
|
+
Object.defineProperty(this, "wss", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
configurable: true,
|
|
93
|
+
writable: true,
|
|
94
|
+
value: null
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(this, "client", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
configurable: true,
|
|
99
|
+
writable: true,
|
|
100
|
+
value: null
|
|
101
|
+
});
|
|
102
|
+
Object.defineProperty(this, "checkInterval", {
|
|
103
|
+
enumerable: true,
|
|
104
|
+
configurable: true,
|
|
105
|
+
writable: true,
|
|
106
|
+
value: null
|
|
107
|
+
});
|
|
108
|
+
Object.defineProperty(this, "connectedClientIp", {
|
|
109
|
+
enumerable: true,
|
|
110
|
+
configurable: true,
|
|
111
|
+
writable: true,
|
|
112
|
+
value: null
|
|
113
|
+
});
|
|
114
|
+
Object.defineProperty(this, "hostIp", {
|
|
115
|
+
enumerable: true,
|
|
116
|
+
configurable: true,
|
|
117
|
+
writable: true,
|
|
118
|
+
value: detectHostIp()
|
|
119
|
+
});
|
|
120
|
+
Object.defineProperty(this, "port", {
|
|
121
|
+
enumerable: true,
|
|
122
|
+
configurable: true,
|
|
123
|
+
writable: true,
|
|
124
|
+
value: 31111
|
|
125
|
+
});
|
|
126
|
+
Object.defineProperty(this, "pending", {
|
|
127
|
+
enumerable: true,
|
|
128
|
+
configurable: true,
|
|
129
|
+
writable: true,
|
|
130
|
+
value: new Map()
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 获取 WS 管理器单例
|
|
135
|
+
* @returns 返回单例实例
|
|
136
|
+
* @example
|
|
137
|
+
* const ws = WSManager.get()
|
|
138
|
+
*/
|
|
139
|
+
static get() {
|
|
140
|
+
if (!this.instance) {
|
|
141
|
+
this.instance = new WSManager();
|
|
142
|
+
}
|
|
143
|
+
return this.instance;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 判断是否已有设备连接
|
|
147
|
+
* @returns 已连接返回 true,否则 false
|
|
148
|
+
* @example
|
|
149
|
+
* WSManager.isConnected()
|
|
150
|
+
*/
|
|
151
|
+
static isConnected() {
|
|
152
|
+
return this.get().client !== null;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 静态请求入口
|
|
156
|
+
* @param type 请求类型
|
|
157
|
+
* @param message 请求参数
|
|
158
|
+
* @param timeoutMs 超时时间(毫秒)
|
|
159
|
+
* @returns 返回设备响应
|
|
160
|
+
* @example
|
|
161
|
+
* await WSManager.request("runtime_status", {}, 5000)
|
|
162
|
+
*/
|
|
163
|
+
static request(type, message = {}, timeoutMs = 60000) {
|
|
164
|
+
return this.get().request(type, message, timeoutMs);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* 获取监听地址
|
|
168
|
+
* @returns 返回 ws 地址
|
|
169
|
+
* @example
|
|
170
|
+
* ws.getAddress()
|
|
171
|
+
*/
|
|
172
|
+
getAddress() {
|
|
173
|
+
return `ws://${this.hostIp}:${this.port}`;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* 判断服务器是否已启动
|
|
177
|
+
* @returns 已启动返回 true,否则 false
|
|
178
|
+
* @example
|
|
179
|
+
* ws.isStarted()
|
|
180
|
+
*/
|
|
181
|
+
isStarted() {
|
|
182
|
+
return this.wss !== null;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 获取设备连接状态
|
|
186
|
+
* @returns 已连接返回 true,否则 false
|
|
187
|
+
* @example
|
|
188
|
+
* ws.isClientConnected()
|
|
189
|
+
*/
|
|
190
|
+
isClientConnected() {
|
|
191
|
+
return this.client !== null;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* 获取当前连接设备 IP
|
|
195
|
+
* @returns 返回设备 IP,未连接时返回 null
|
|
196
|
+
* @example
|
|
197
|
+
* ws.getConnectedClientIp()
|
|
198
|
+
*/
|
|
199
|
+
getConnectedClientIp() {
|
|
200
|
+
return this.connectedClientIp;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* 启动 WS 服务
|
|
204
|
+
* @param port 指定端口,默认 31111
|
|
205
|
+
* @returns 启动完成后返回 Promise<void>
|
|
206
|
+
* @example
|
|
207
|
+
* await ws.start(31111)
|
|
208
|
+
*/
|
|
209
|
+
async start(port = 31111) {
|
|
210
|
+
if (this.wss) {
|
|
211
|
+
console.log(`服务已开启,地址 ${this.getAddress()}`);
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
this.port = port;
|
|
215
|
+
this.wss = new ws_1.WebSocketServer({ port: this.port, host: "0.0.0.0" });
|
|
216
|
+
this.wss.on("connection", (ws) => {
|
|
217
|
+
if (this.client) {
|
|
218
|
+
ws.send(JSON.stringify({ type: "reject", reason: "only-one-client" }));
|
|
219
|
+
ws.close(1013, "Only one client allowed");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
this.client = ws;
|
|
223
|
+
const socket = ws;
|
|
224
|
+
this.connectedClientIp = socket._socket?.remoteAddress || null;
|
|
225
|
+
ws.on("close", () => {
|
|
226
|
+
if (this.client === ws) {
|
|
227
|
+
console.log(`设备已断开,设备IP: ${this.connectedClientIp || "unknown"}`);
|
|
228
|
+
this.stopStatusInterval();
|
|
229
|
+
this.client = null;
|
|
230
|
+
this.connectedClientIp = null;
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
ws.on("message", (data) => {
|
|
234
|
+
let message = null;
|
|
235
|
+
try {
|
|
236
|
+
message = JSON.parse(data.toString());
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (message.type === "log") {
|
|
242
|
+
console.log("[device-log]", JSON.stringify(message));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const id = message.requestId;
|
|
246
|
+
if (id && this.pending.has(id)) {
|
|
247
|
+
const p = this.pending.get(id);
|
|
248
|
+
clearTimeout(p.timer);
|
|
249
|
+
this.pending.delete(id);
|
|
250
|
+
p.resolve(message);
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
console.log(`设备已连接,设备IP: ${this.connectedClientIp || "unknown"}`);
|
|
254
|
+
this.startStatusInterval();
|
|
255
|
+
});
|
|
256
|
+
await new Promise((resolve, reject) => {
|
|
257
|
+
this.wss.once("listening", () => {
|
|
258
|
+
console.log(`服务已开启,地址 ${this.getAddress()}`);
|
|
259
|
+
resolve();
|
|
260
|
+
});
|
|
261
|
+
this.wss.once("error", (err) => {
|
|
262
|
+
this.wss = null;
|
|
263
|
+
console.error(`服务启动失败: ${String(err)}`);
|
|
264
|
+
reject(err);
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 等待设备连接
|
|
270
|
+
* @param timeoutMs 超时时间(毫秒)
|
|
271
|
+
* @returns 成功连接后返回 Promise<void>
|
|
272
|
+
* @example
|
|
273
|
+
* await ws.waitForClient(30000)
|
|
274
|
+
*/
|
|
275
|
+
async waitForClient(timeoutMs = 30000) {
|
|
276
|
+
if (this.client) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
await new Promise((resolve, reject) => {
|
|
280
|
+
const start = Date.now();
|
|
281
|
+
const timer = setInterval(() => {
|
|
282
|
+
if (this.client) {
|
|
283
|
+
clearInterval(timer);
|
|
284
|
+
resolve();
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (Date.now() - start > timeoutMs) {
|
|
288
|
+
clearInterval(timer);
|
|
289
|
+
reject(new Error("等待设备连接超时"));
|
|
290
|
+
}
|
|
291
|
+
}, 200);
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* 发送请求并等待响应
|
|
296
|
+
* @param type 请求类型
|
|
297
|
+
* @param message 请求消息
|
|
298
|
+
* @param timeoutMs 超时时间(毫秒)
|
|
299
|
+
* @returns 返回设备响应
|
|
300
|
+
* @example
|
|
301
|
+
* await ws.request("files", {}, 60000)
|
|
302
|
+
*/
|
|
303
|
+
async request(type, message = {}, timeoutMs = 5000) {
|
|
304
|
+
if (!this.client || this.client.readyState !== this.client.OPEN) {
|
|
305
|
+
throw new Error("no-client");
|
|
306
|
+
}
|
|
307
|
+
const id = (0, uuid_1.v4)();
|
|
308
|
+
const payload = JSON.stringify({ ...message, type, requestId: id });
|
|
309
|
+
return new Promise((resolve, reject) => {
|
|
310
|
+
const timer = setTimeout(() => {
|
|
311
|
+
this.pending.delete(id);
|
|
312
|
+
reject(new Error("timeout"));
|
|
313
|
+
}, timeoutMs);
|
|
314
|
+
this.pending.set(id, { resolve, reject, timer });
|
|
315
|
+
try {
|
|
316
|
+
this.client.send(payload);
|
|
317
|
+
}
|
|
318
|
+
catch (e) {
|
|
319
|
+
clearTimeout(timer);
|
|
320
|
+
this.pending.delete(id);
|
|
321
|
+
reject(e);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* 停止 WS 服务
|
|
327
|
+
* @returns 停止完成后返回 Promise<void>
|
|
328
|
+
* @example
|
|
329
|
+
* await ws.stop()
|
|
330
|
+
*/
|
|
331
|
+
async stop() {
|
|
332
|
+
if (!this.wss) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
if (this.client) {
|
|
336
|
+
this.client.close(1000);
|
|
337
|
+
}
|
|
338
|
+
for (const [, p] of this.pending) {
|
|
339
|
+
clearTimeout(p.timer);
|
|
340
|
+
p.reject(new Error("server-stopped"));
|
|
341
|
+
}
|
|
342
|
+
this.pending.clear();
|
|
343
|
+
await new Promise((resolve) => this.wss.close(() => resolve()));
|
|
344
|
+
this.wss = null;
|
|
345
|
+
this.stopStatusInterval();
|
|
346
|
+
console.log("服务已停止");
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* 启动运行状态轮询
|
|
350
|
+
* @returns 无返回值
|
|
351
|
+
* @example
|
|
352
|
+
* ws.startStatusInterval()
|
|
353
|
+
*/
|
|
354
|
+
startStatusInterval() {
|
|
355
|
+
this.stopStatusInterval();
|
|
356
|
+
this.checkInterval = setInterval(async () => {
|
|
357
|
+
try {
|
|
358
|
+
const data = await this.request("runtime_status");
|
|
359
|
+
if (data.success) {
|
|
360
|
+
const status = (data.data || {});
|
|
361
|
+
console.log(`[runtime] memory=${status.memory ?? "unknown"}, isRunning=${status.isRunning ?? "unknown"}`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
catch {
|
|
365
|
+
// ignore
|
|
366
|
+
}
|
|
367
|
+
}, 2000);
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* 停止运行状态轮询
|
|
371
|
+
* @returns 无返回值
|
|
372
|
+
* @example
|
|
373
|
+
* ws.stopStatusInterval()
|
|
374
|
+
*/
|
|
375
|
+
stopStatusInterval() {
|
|
376
|
+
if (this.checkInterval) {
|
|
377
|
+
clearInterval(this.checkInterval);
|
|
378
|
+
this.checkInterval = null;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
exports.WSManager = WSManager;
|
|
383
|
+
Object.defineProperty(WSManager, "instance", {
|
|
384
|
+
enumerable: true,
|
|
385
|
+
configurable: true,
|
|
386
|
+
writable: true,
|
|
387
|
+
value: null
|
|
388
|
+
});
|
|
389
|
+
/**
|
|
390
|
+
* 对齐原有命名导出
|
|
391
|
+
*/
|
|
392
|
+
exports.WebSocketServerManager = WSManager;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ms-vite-plugin",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -19,16 +19,22 @@
|
|
|
19
19
|
"prepublishOnly": "npm run build"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
+
"archiver": "^7.0.1",
|
|
22
23
|
"commander": "^14.0.3",
|
|
24
|
+
"crc": "^4.3.2",
|
|
23
25
|
"fs-extra": "^11.3.4",
|
|
26
|
+
"uuid": "^14.0.0",
|
|
24
27
|
"vite": "^8.0.9",
|
|
25
28
|
"vite-plugin-bundle-obfuscator": "^1.11.0",
|
|
26
|
-
"
|
|
29
|
+
"ws": "^8.20.0"
|
|
27
30
|
},
|
|
28
31
|
"devDependencies": {
|
|
32
|
+
"@types/archiver": "^7.0.0",
|
|
33
|
+
"@types/crc": "^4.0.0",
|
|
29
34
|
"@types/fs-extra": "^11.0.4",
|
|
30
35
|
"@types/node": "^25.6.0",
|
|
31
|
-
"@types/
|
|
36
|
+
"@types/uuid": "^11.0.0",
|
|
37
|
+
"@types/ws": "^8.18.1",
|
|
32
38
|
"typescript": "~6.0.3"
|
|
33
39
|
}
|
|
34
40
|
}
|