@mt0926/node-network-devtools 0.2.0 → 0.3.10

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 (56) hide show
  1. package/README.md +134 -109
  2. package/README.zh-CN.md +62 -108
  3. package/dist/cjs/adapters/axios.js +2 -0
  4. package/dist/cjs/adapters/axios.js.map +1 -0
  5. package/dist/cjs/adapters/nextjs.js +133 -0
  6. package/dist/cjs/adapters/nextjs.js.map +1 -0
  7. package/dist/cjs/config.js +150 -0
  8. package/dist/cjs/config.js.map +1 -0
  9. package/dist/cjs/context/context-manager.js +139 -0
  10. package/dist/cjs/context/context-manager.js.map +1 -0
  11. package/dist/cjs/gui/browser-detector.js +263 -0
  12. package/dist/cjs/gui/browser-detector.js.map +1 -0
  13. package/dist/cjs/gui/browser-launcher.js +365 -0
  14. package/dist/cjs/gui/browser-launcher.js.map +1 -0
  15. package/dist/cjs/gui/event-bridge.js +197 -0
  16. package/dist/cjs/gui/event-bridge.js.map +1 -0
  17. package/dist/cjs/gui/port-utils.js +85 -0
  18. package/dist/cjs/gui/port-utils.js.map +1 -0
  19. package/dist/cjs/gui/server.js +267 -0
  20. package/dist/cjs/gui/server.js.map +1 -0
  21. package/dist/cjs/gui/websocket-hub.js +336 -0
  22. package/dist/cjs/gui/websocket-hub.js.map +1 -0
  23. package/dist/cjs/index.js +170 -0
  24. package/dist/cjs/index.js.map +1 -0
  25. package/dist/cjs/interceptors/http-patcher.js +275 -0
  26. package/dist/cjs/interceptors/http-patcher.js.map +1 -0
  27. package/dist/cjs/interceptors/undici-patcher.js +362 -0
  28. package/dist/cjs/interceptors/undici-patcher.js.map +1 -0
  29. package/dist/cjs/package.json +3 -0
  30. package/dist/cjs/register.js +95 -0
  31. package/dist/cjs/register.js.map +1 -0
  32. package/dist/cjs/store/ring-buffer.js +241 -0
  33. package/dist/cjs/store/ring-buffer.js.map +1 -0
  34. package/dist/cjs/test-setup.js +8 -0
  35. package/dist/cjs/test-setup.js.map +1 -0
  36. package/dist/cjs/utils/module-compat.js +83 -0
  37. package/dist/cjs/utils/module-compat.js.map +1 -0
  38. package/dist/esm/gui/server.js +41 -6
  39. package/dist/esm/gui/server.js.map +1 -1
  40. package/dist/esm/index.js +1 -1
  41. package/dist/esm/interceptors/undici-patcher.js +9 -4
  42. package/dist/esm/interceptors/undici-patcher.js.map +1 -1
  43. package/dist/esm/utils/module-compat.js +78 -0
  44. package/dist/esm/utils/module-compat.js.map +1 -0
  45. package/dist/gui/assets/index.css +1 -1
  46. package/dist/gui/assets/index.js +10 -10
  47. package/dist/types/gui/server.d.ts.map +1 -1
  48. package/dist/types/index.d.ts +1 -1
  49. package/dist/types/interceptors/undici-patcher.d.ts.map +1 -1
  50. package/dist/types/utils/module-compat.d.ts +34 -0
  51. package/dist/types/utils/module-compat.d.ts.map +1 -0
  52. package/package.json +42 -35
  53. package/dist/esm/cli.js +0 -203
  54. package/dist/esm/cli.js.map +0 -1
  55. package/dist/types/cli.d.ts +0 -8
  56. package/dist/types/cli.d.ts.map +0 -1
@@ -0,0 +1,267 @@
1
+ "use strict";
2
+ /**
3
+ * GUI Server 模块
4
+ *
5
+ * 提供 HTTP 静态文件服务和 WebSocket 实时通信
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.getGUIServer = getGUIServer;
9
+ exports.resetGUIServer = resetGUIServer;
10
+ exports.createGUIServer = createGUIServer;
11
+ const node_http_1 = require("node:http");
12
+ const promises_1 = require("node:fs/promises");
13
+ const node_fs_1 = require("node:fs");
14
+ const node_path_1 = require("node:path");
15
+ const node_url_1 = require("node:url");
16
+ const config_js_1 = require("../config.js");
17
+ const port_utils_js_1 = require("./port-utils.js");
18
+ const websocket_hub_js_1 = require("./websocket-hub.js");
19
+ const event_bridge_js_1 = require("./event-bridge.js");
20
+ // 获取当前模块目录
21
+ // 在 CommonJS 中,__dirname 是全局可用的
22
+ // 在 ESM 中,需要使用 import.meta.url
23
+ // 为了避免在 CJS 构建中出现 import.meta 引用,我们使用 eval 来延迟求值
24
+ let currentDirname;
25
+ // @ts-ignore - __dirname 在 CommonJS 中可用
26
+ if (typeof __dirname !== 'undefined') {
27
+ // CommonJS 环境
28
+ // @ts-ignore
29
+ currentDirname = __dirname;
30
+ }
31
+ else {
32
+ // ESM 环境 - 使用 eval 来避免 TypeScript 编译器处理 import.meta
33
+ try {
34
+ // eslint-disable-next-line no-eval
35
+ const importMetaUrl = eval('import.meta.url');
36
+ currentDirname = (0, node_path_1.dirname)((0, node_url_1.fileURLToPath)(importMetaUrl));
37
+ }
38
+ catch (error) {
39
+ // 后备方案:尝试从 module 路径推断
40
+ // 这种情况不应该发生,但作为最后的后备
41
+ console.error('[GUI Server] 无法确定模块目录,使用 process.cwd() 作为后备:', error);
42
+ currentDirname = process.cwd();
43
+ }
44
+ }
45
+ /**
46
+ * MIME 类型映射
47
+ */
48
+ const MIME_TYPES = {
49
+ '.html': 'text/html; charset=utf-8',
50
+ '.css': 'text/css; charset=utf-8',
51
+ '.js': 'application/javascript; charset=utf-8',
52
+ '.mjs': 'application/javascript; charset=utf-8',
53
+ '.json': 'application/json; charset=utf-8',
54
+ '.png': 'image/png',
55
+ '.jpg': 'image/jpeg',
56
+ '.jpeg': 'image/jpeg',
57
+ '.gif': 'image/gif',
58
+ '.svg': 'image/svg+xml',
59
+ '.ico': 'image/x-icon',
60
+ '.woff': 'font/woff',
61
+ '.woff2': 'font/woff2',
62
+ '.ttf': 'font/ttf',
63
+ '.eot': 'application/vnd.ms-fontobject',
64
+ };
65
+ /**
66
+ * GUI Server 实现
67
+ */
68
+ class GUIServerImpl {
69
+ server = null;
70
+ wsHub;
71
+ eventBridge;
72
+ guiPort = null;
73
+ wsPort = null;
74
+ host;
75
+ staticDir;
76
+ constructor(wsHub, eventBridge, host = '127.0.0.1') {
77
+ this.wsHub = wsHub ?? (0, websocket_hub_js_1.getWebSocketHub)();
78
+ this.eventBridge = eventBridge ?? (0, event_bridge_js_1.getEventBridge)();
79
+ this.host = host;
80
+ // 静态文件目录:dist/gui(构建后的前端文件)
81
+ // 我们需要确保在不同环境下都能找到该目录:
82
+ // 1. 开发环境运行 tsx: currentDirname 是 src/gui,路径应为 ../../dist/gui
83
+ // 2. 编译后运行: currentDirname 是 dist/esm/gui 或 dist/cjs/gui,路径应为 ../../gui
84
+ const possiblePaths = [
85
+ (0, node_path_1.join)(currentDirname, '../../gui'), // 编译后路径
86
+ (0, node_path_1.join)(currentDirname, '../../../dist/gui'), // 开发环境(tsx)路径
87
+ (0, node_path_1.join)(process.cwd(), 'dist/gui'), // 后备路径
88
+ ];
89
+ this.staticDir = possiblePaths[0];
90
+ for (const p of possiblePaths) {
91
+ if ((0, node_fs_1.existsSync)(p) && (0, node_fs_1.existsSync)((0, node_path_1.join)(p, 'index.html'))) {
92
+ this.staticDir = p;
93
+ break;
94
+ }
95
+ }
96
+ }
97
+ /**
98
+ * 启动 GUI 服务器
99
+ */
100
+ async start(options) {
101
+ if (this.server) {
102
+ throw new Error('GUI Server 已经在运行');
103
+ }
104
+ const config = (0, config_js_1.getConfig)();
105
+ // 使用传入的选项或配置中的值
106
+ const guiPortConfig = options?.guiPort ?? config.guiPort;
107
+ const wsPortConfig = options?.wsPort ?? config.wsPort;
108
+ const hostConfig = options?.host ?? config.guiHost;
109
+ // 更新 host
110
+ this.host = hostConfig;
111
+ // 获取可用端口
112
+ this.guiPort = await (0, port_utils_js_1.getAvailablePort)(guiPortConfig, this.host);
113
+ this.wsPort = await (0, port_utils_js_1.getAvailablePort)(wsPortConfig, this.host);
114
+ // 启动 WebSocket Hub
115
+ await this.wsHub.start(this.wsPort, this.host);
116
+ // 启动 Event Bridge
117
+ this.eventBridge.start();
118
+ // 创建 HTTP 服务器
119
+ this.server = (0, node_http_1.createServer)((req, res) => {
120
+ this.handleRequest(req, res);
121
+ });
122
+ // 启动 HTTP 服务器
123
+ await new Promise((resolve, reject) => {
124
+ this.server.once('error', reject);
125
+ this.server.listen(this.guiPort, this.host, () => {
126
+ resolve();
127
+ });
128
+ });
129
+ const url = this.getUrl();
130
+ console.log(`[node-network-devtools] GUI 服务器已启动: ${url}`);
131
+ return {
132
+ guiPort: this.guiPort,
133
+ wsPort: this.wsPort,
134
+ url,
135
+ };
136
+ }
137
+ /**
138
+ * 处理 HTTP 请求
139
+ */
140
+ async handleRequest(req, res) {
141
+ const url = new URL(req.url || '/', `http://${this.host}:${this.guiPort}`);
142
+ let pathname = url.pathname;
143
+ console.log(`[GUI Server] 请求: ${pathname}, 静态目录: ${this.staticDir}`);
144
+ // 默认路径指向 index.html
145
+ if (pathname === '/') {
146
+ pathname = '/index.html';
147
+ }
148
+ // 构建文件路径
149
+ const filePath = (0, node_path_1.join)(this.staticDir, pathname);
150
+ console.log(`[GUI Server] 文件路径: ${filePath}`);
151
+ try {
152
+ // 检查文件是否存在
153
+ const fileStat = await (0, promises_1.stat)(filePath);
154
+ if (!fileStat.isFile()) {
155
+ // 如果不是文件,尝试返回 index.html(SPA 路由支持)
156
+ await this.serveFile((0, node_path_1.join)(this.staticDir, 'index.html'), res);
157
+ return;
158
+ }
159
+ await this.serveFile(filePath, res);
160
+ }
161
+ catch (err) {
162
+ console.log(`[GUI Server] 文件不存在: ${filePath}, 错误:`, err);
163
+ // 文件不存在,尝试返回 index.html(SPA 路由支持)
164
+ try {
165
+ await this.serveFile((0, node_path_1.join)(this.staticDir, 'index.html'), res);
166
+ }
167
+ catch (indexErr) {
168
+ console.log(`[GUI Server] index.html 也不存在:`, indexErr);
169
+ this.sendError(res, 404, 'Not Found');
170
+ }
171
+ }
172
+ }
173
+ /**
174
+ * 提供静态文件
175
+ */
176
+ async serveFile(filePath, res) {
177
+ const ext = (0, node_path_1.extname)(filePath).toLowerCase();
178
+ const contentType = MIME_TYPES[ext] || 'application/octet-stream';
179
+ const content = await (0, promises_1.readFile)(filePath);
180
+ res.writeHead(200, {
181
+ 'Content-Type': contentType,
182
+ 'Content-Length': content.length,
183
+ 'Cache-Control': 'no-cache',
184
+ });
185
+ res.end(content);
186
+ }
187
+ /**
188
+ * 发送错误响应
189
+ */
190
+ sendError(res, statusCode, message) {
191
+ res.writeHead(statusCode, { 'Content-Type': 'text/plain; charset=utf-8' });
192
+ res.end(message);
193
+ }
194
+ /**
195
+ * 停止 GUI 服务器
196
+ */
197
+ async stop() {
198
+ // 停止 Event Bridge
199
+ this.eventBridge.stop();
200
+ // 停止 WebSocket Hub
201
+ await this.wsHub.stop();
202
+ // 停止 HTTP 服务器
203
+ if (this.server) {
204
+ await new Promise((resolve) => {
205
+ this.server.close(() => {
206
+ resolve();
207
+ });
208
+ });
209
+ this.server = null;
210
+ }
211
+ this.guiPort = null;
212
+ this.wsPort = null;
213
+ }
214
+ /**
215
+ * 检查是否正在运行
216
+ */
217
+ isRunning() {
218
+ return this.server !== null;
219
+ }
220
+ /**
221
+ * 获取 GUI URL
222
+ */
223
+ getUrl() {
224
+ if (!this.guiPort || !this.wsPort)
225
+ return null;
226
+ return `http://${this.host}:${this.guiPort}?wsPort=${this.wsPort}`;
227
+ }
228
+ /**
229
+ * 获取 GUI 端口
230
+ */
231
+ getGuiPort() {
232
+ return this.guiPort;
233
+ }
234
+ /**
235
+ * 获取 WebSocket 端口
236
+ */
237
+ getWsPort() {
238
+ return this.wsPort;
239
+ }
240
+ }
241
+ // 全局单例
242
+ let globalServer = null;
243
+ /**
244
+ * 获取全局 GUI Server 实例
245
+ */
246
+ function getGUIServer() {
247
+ if (!globalServer) {
248
+ globalServer = new GUIServerImpl();
249
+ }
250
+ return globalServer;
251
+ }
252
+ /**
253
+ * 重置全局 GUI Server(用于测试)
254
+ */
255
+ async function resetGUIServer() {
256
+ if (globalServer) {
257
+ await globalServer.stop();
258
+ }
259
+ globalServer = null;
260
+ }
261
+ /**
262
+ * 创建新的 GUI Server 实例(用于测试)
263
+ */
264
+ function createGUIServer(wsHub, eventBridge, host) {
265
+ return new GUIServerImpl(wsHub, eventBridge, host);
266
+ }
267
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/gui/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,336 @@
1
+ "use strict";
2
+ /**
3
+ * WebSocket Hub 模块
4
+ *
5
+ * 管理 WebSocket 客户端连接,广播消息到所有连接的客户端
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.getWebSocketHub = getWebSocketHub;
9
+ exports.resetWebSocketHub = resetWebSocketHub;
10
+ exports.createWebSocketHub = createWebSocketHub;
11
+ exports.createRequestStartMessage = createRequestStartMessage;
12
+ exports.createRequestCompleteMessage = createRequestCompleteMessage;
13
+ exports.createRequestErrorMessage = createRequestErrorMessage;
14
+ exports.createInitialDataMessage = createInitialDataMessage;
15
+ exports.createClearMessage = createClearMessage;
16
+ const ws_1 = require("ws");
17
+ const nanoid_1 = require("nanoid");
18
+ /**
19
+ * WebSocket Hub 实现
20
+ */
21
+ class WebSocketHubImpl {
22
+ wss = null;
23
+ clients = new Map();
24
+ port = null;
25
+ // 事件回调
26
+ connectCallbacks = [];
27
+ disconnectCallbacks = [];
28
+ messageCallbacks = [];
29
+ /**
30
+ * 启动 WebSocket 服务器
31
+ */
32
+ async start(port, host = '127.0.0.1') {
33
+ if (this.wss) {
34
+ throw new Error('WebSocket Hub 已经在运行');
35
+ }
36
+ return new Promise((resolve, reject) => {
37
+ this.wss = new ws_1.WebSocketServer({ port, host });
38
+ this.wss.on('listening', () => {
39
+ const address = this.wss?.address();
40
+ if (address && typeof address === 'object') {
41
+ this.port = address.port;
42
+ resolve(this.port);
43
+ }
44
+ else {
45
+ reject(new Error('无法获取 WebSocket 端口'));
46
+ }
47
+ });
48
+ this.wss.on('error', (err) => {
49
+ reject(err);
50
+ });
51
+ this.wss.on('connection', (ws) => {
52
+ this.handleConnection(ws);
53
+ });
54
+ });
55
+ }
56
+ /**
57
+ * 处理新连接
58
+ */
59
+ handleConnection(ws) {
60
+ const clientId = (0, nanoid_1.nanoid)();
61
+ const clientInfo = {
62
+ id: clientId,
63
+ ws,
64
+ connectedAt: Date.now(),
65
+ };
66
+ this.clients.set(clientId, clientInfo);
67
+ // 触发连接回调
68
+ for (const callback of this.connectCallbacks) {
69
+ try {
70
+ callback(clientId);
71
+ }
72
+ catch {
73
+ // 忽略回调错误
74
+ }
75
+ }
76
+ // 处理消息
77
+ ws.on('message', (data) => {
78
+ try {
79
+ const message = JSON.parse(data.toString());
80
+ for (const callback of this.messageCallbacks) {
81
+ try {
82
+ callback(clientId, message);
83
+ }
84
+ catch {
85
+ // 忽略回调错误
86
+ }
87
+ }
88
+ }
89
+ catch {
90
+ // 忽略解析错误
91
+ }
92
+ });
93
+ // 处理断开连接
94
+ ws.on('close', () => {
95
+ this.clients.delete(clientId);
96
+ for (const callback of this.disconnectCallbacks) {
97
+ try {
98
+ callback(clientId);
99
+ }
100
+ catch {
101
+ // 忽略回调错误
102
+ }
103
+ }
104
+ });
105
+ // 处理错误
106
+ ws.on('error', () => {
107
+ // 错误时也移除客户端
108
+ if (this.clients.has(clientId)) {
109
+ this.clients.delete(clientId);
110
+ for (const callback of this.disconnectCallbacks) {
111
+ try {
112
+ callback(clientId);
113
+ }
114
+ catch {
115
+ // 忽略回调错误
116
+ }
117
+ }
118
+ }
119
+ });
120
+ }
121
+ /**
122
+ * 停止 WebSocket 服务器
123
+ */
124
+ async stop() {
125
+ if (!this.wss)
126
+ return;
127
+ return new Promise((resolve) => {
128
+ // 关闭所有客户端连接
129
+ for (const client of this.clients.values()) {
130
+ try {
131
+ client.ws.close();
132
+ }
133
+ catch {
134
+ // 忽略关闭错误
135
+ }
136
+ }
137
+ this.clients.clear();
138
+ // 关闭服务器
139
+ this.wss?.close(() => {
140
+ this.wss = null;
141
+ this.port = null;
142
+ resolve();
143
+ });
144
+ });
145
+ }
146
+ /**
147
+ * 广播消息到所有客户端
148
+ */
149
+ broadcast(message) {
150
+ const data = JSON.stringify(message);
151
+ for (const client of this.clients.values()) {
152
+ if (client.ws.readyState === ws_1.WebSocket.OPEN) {
153
+ try {
154
+ client.ws.send(data);
155
+ }
156
+ catch {
157
+ // 忽略发送错误
158
+ }
159
+ }
160
+ }
161
+ }
162
+ /**
163
+ * 发送消息到指定客户端
164
+ */
165
+ send(clientId, message) {
166
+ const client = this.clients.get(clientId);
167
+ if (!client)
168
+ return;
169
+ if (client.ws.readyState === ws_1.WebSocket.OPEN) {
170
+ const data = JSON.stringify(message);
171
+ try {
172
+ client.ws.send(data);
173
+ }
174
+ catch {
175
+ // 忽略发送错误
176
+ }
177
+ }
178
+ }
179
+ /**
180
+ * 获取连接的客户端数量
181
+ */
182
+ getClientCount() {
183
+ return this.clients.size;
184
+ }
185
+ /**
186
+ * 获取所有客户端 ID
187
+ */
188
+ getClientIds() {
189
+ return Array.from(this.clients.keys());
190
+ }
191
+ /**
192
+ * 检查是否正在运行
193
+ */
194
+ isRunning() {
195
+ return this.wss !== null;
196
+ }
197
+ /**
198
+ * 获取端口号
199
+ */
200
+ getPort() {
201
+ return this.port;
202
+ }
203
+ /**
204
+ * 注册客户端连接回调
205
+ */
206
+ onClientConnect(callback) {
207
+ this.connectCallbacks.push(callback);
208
+ }
209
+ /**
210
+ * 注册客户端断开回调
211
+ */
212
+ onClientDisconnect(callback) {
213
+ this.disconnectCallbacks.push(callback);
214
+ }
215
+ /**
216
+ * 注册客户端消息回调
217
+ */
218
+ onClientMessage(callback) {
219
+ this.messageCallbacks.push(callback);
220
+ }
221
+ }
222
+ // 全局单例
223
+ let globalHub = null;
224
+ /**
225
+ * 获取全局 WebSocket Hub 实例
226
+ */
227
+ function getWebSocketHub() {
228
+ if (!globalHub) {
229
+ globalHub = new WebSocketHubImpl();
230
+ }
231
+ return globalHub;
232
+ }
233
+ /**
234
+ * 重置全局 WebSocket Hub(用于测试)
235
+ */
236
+ async function resetWebSocketHub() {
237
+ if (globalHub) {
238
+ await globalHub.stop();
239
+ }
240
+ globalHub = null;
241
+ }
242
+ /**
243
+ * 创建新的 WebSocket Hub 实例(用于测试)
244
+ */
245
+ function createWebSocketHub() {
246
+ return new WebSocketHubImpl();
247
+ }
248
+ /**
249
+ * 创建请求开始消息
250
+ */
251
+ function createRequestStartMessage(request) {
252
+ return {
253
+ type: 'request:start',
254
+ payload: {
255
+ id: request.id,
256
+ url: request.url,
257
+ method: request.method,
258
+ headers: request.headers,
259
+ body: request.body ? (Buffer.isBuffer(request.body) ? request.body.toString('utf-8') : request.body) : undefined,
260
+ timestamp: request.timestamp,
261
+ traceId: request.traceId,
262
+ stackTrace: request.stackTrace,
263
+ },
264
+ timestamp: Date.now(),
265
+ };
266
+ }
267
+ /**
268
+ * 创建请求完成消息
269
+ */
270
+ function createRequestCompleteMessage(requestId, response) {
271
+ return {
272
+ type: 'request:complete',
273
+ payload: {
274
+ id: requestId,
275
+ statusCode: response.statusCode,
276
+ statusMessage: response.statusMessage,
277
+ headers: response.headers,
278
+ body: response.body ? (Buffer.isBuffer(response.body) ? response.body.toString('utf-8') : response.body) : undefined,
279
+ bodyTruncated: response.bodyTruncated,
280
+ },
281
+ timestamp: Date.now(),
282
+ };
283
+ }
284
+ /**
285
+ * 创建请求错误消息
286
+ */
287
+ function createRequestErrorMessage(requestId, error) {
288
+ return {
289
+ type: 'request:error',
290
+ payload: {
291
+ id: requestId,
292
+ code: error.code,
293
+ message: error.message,
294
+ },
295
+ timestamp: Date.now(),
296
+ };
297
+ }
298
+ /**
299
+ * 创建初始数据消息
300
+ */
301
+ function createInitialDataMessage(requests) {
302
+ return {
303
+ type: 'requests:initial',
304
+ payload: requests.map(req => ({
305
+ id: req.id,
306
+ url: req.url,
307
+ method: req.method,
308
+ headers: req.headers,
309
+ body: req.body ? (Buffer.isBuffer(req.body) ? req.body.toString('utf-8') : req.body) : undefined,
310
+ timestamp: req.timestamp,
311
+ traceId: req.traceId,
312
+ stackTrace: req.stackTrace,
313
+ response: req.response ? {
314
+ statusCode: req.response.statusCode,
315
+ statusMessage: req.response.statusMessage,
316
+ headers: req.response.headers,
317
+ body: req.response.body ? (Buffer.isBuffer(req.response.body) ? req.response.body.toString('utf-8') : req.response.body) : undefined,
318
+ bodyTruncated: req.response.bodyTruncated,
319
+ } : undefined,
320
+ error: req.error,
321
+ timing: req.timing,
322
+ })),
323
+ timestamp: Date.now(),
324
+ };
325
+ }
326
+ /**
327
+ * 创建清空请求消息
328
+ */
329
+ function createClearMessage() {
330
+ return {
331
+ type: 'requests:clear',
332
+ payload: null,
333
+ timestamp: Date.now(),
334
+ };
335
+ }
336
+ //# sourceMappingURL=websocket-hub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-hub.js","sourceRoot":"","sources":["../../../src/gui/websocket-hub.ts"],"names":[],"mappings":"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"}