@electron-memory/monitor 0.1.0 → 0.2.0
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/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +105 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +84 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/core/monitor.ts
|
|
2
|
-
import { app as
|
|
3
|
-
import * as
|
|
2
|
+
import { app as app3 } from "electron";
|
|
3
|
+
import * as path4 from "path";
|
|
4
4
|
import * as v82 from "v8";
|
|
5
5
|
import { EventEmitter as EventEmitter3 } from "events";
|
|
6
6
|
|
|
@@ -1070,7 +1070,75 @@ var Analyzer = class {
|
|
|
1070
1070
|
|
|
1071
1071
|
// src/core/dashboard.ts
|
|
1072
1072
|
import { BrowserWindow as BrowserWindow2 } from "electron";
|
|
1073
|
+
import * as path3 from "path";
|
|
1074
|
+
|
|
1075
|
+
// src/core/dashboard-protocol.ts
|
|
1076
|
+
import { app as app2, net, protocol } from "electron";
|
|
1073
1077
|
import * as path2 from "path";
|
|
1078
|
+
import { pathToFileURL } from "url";
|
|
1079
|
+
var SCHEME = "emm-dashboard";
|
|
1080
|
+
var privilegedRegistered = false;
|
|
1081
|
+
var handlerRegistered = false;
|
|
1082
|
+
function isPathInsideRoot(filePath, root) {
|
|
1083
|
+
const f = path2.resolve(filePath);
|
|
1084
|
+
const r = path2.resolve(root);
|
|
1085
|
+
if (f === r) {
|
|
1086
|
+
return true;
|
|
1087
|
+
}
|
|
1088
|
+
const sep2 = r.endsWith(path2.sep) ? r : `${r}${path2.sep}`;
|
|
1089
|
+
return f.startsWith(sep2);
|
|
1090
|
+
}
|
|
1091
|
+
function registerDashboardSchemePrivileged() {
|
|
1092
|
+
if (privilegedRegistered) {
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
privilegedRegistered = true;
|
|
1096
|
+
protocol.registerSchemesAsPrivileged([
|
|
1097
|
+
{
|
|
1098
|
+
scheme: SCHEME,
|
|
1099
|
+
privileges: {
|
|
1100
|
+
standard: true,
|
|
1101
|
+
secure: true,
|
|
1102
|
+
supportFetchAPI: true,
|
|
1103
|
+
corsEnabled: true,
|
|
1104
|
+
stream: true
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
]);
|
|
1108
|
+
}
|
|
1109
|
+
function ensureDashboardProtocolHandler(uiRoot) {
|
|
1110
|
+
if (handlerRegistered) {
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1113
|
+
if (!app2.isReady()) {
|
|
1114
|
+
throw new Error(
|
|
1115
|
+
"[@electron-memory/monitor] ensureDashboardProtocolHandler: app must be ready before opening dashboard"
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
handlerRegistered = true;
|
|
1119
|
+
const base = path2.resolve(uiRoot);
|
|
1120
|
+
protocol.handle(SCHEME, (request) => {
|
|
1121
|
+
try {
|
|
1122
|
+
const { pathname } = new URL(request.url);
|
|
1123
|
+
let rel = pathname.startsWith("/") ? pathname.slice(1) : pathname;
|
|
1124
|
+
if (!rel) {
|
|
1125
|
+
rel = "index.html";
|
|
1126
|
+
}
|
|
1127
|
+
const filePath = path2.resolve(path2.join(base, rel));
|
|
1128
|
+
if (!isPathInsideRoot(filePath, base)) {
|
|
1129
|
+
return new Response("Forbidden", { status: 403 });
|
|
1130
|
+
}
|
|
1131
|
+
return net.fetch(pathToFileURL(filePath).href);
|
|
1132
|
+
} catch {
|
|
1133
|
+
return new Response("Bad Request", { status: 400 });
|
|
1134
|
+
}
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
function getDashboardPageURL() {
|
|
1138
|
+
return `${SCHEME}://electron/index.html`;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
// src/core/dashboard.ts
|
|
1074
1142
|
var DashboardManager = class {
|
|
1075
1143
|
constructor(config) {
|
|
1076
1144
|
this.window = null;
|
|
@@ -1093,7 +1161,7 @@ var DashboardManager = class {
|
|
|
1093
1161
|
this.window.focus();
|
|
1094
1162
|
return;
|
|
1095
1163
|
}
|
|
1096
|
-
const preloadPath =
|
|
1164
|
+
const preloadPath = path3.join(__dirname, "dashboard-preload.js");
|
|
1097
1165
|
this.window = new BrowserWindow2({
|
|
1098
1166
|
width: this.config.dashboard.width,
|
|
1099
1167
|
height: this.config.dashboard.height,
|
|
@@ -1105,8 +1173,9 @@ var DashboardManager = class {
|
|
|
1105
1173
|
nodeIntegration: false
|
|
1106
1174
|
}
|
|
1107
1175
|
});
|
|
1108
|
-
const
|
|
1109
|
-
|
|
1176
|
+
const uiRoot = path3.join(__dirname, "ui");
|
|
1177
|
+
ensureDashboardProtocolHandler(uiRoot);
|
|
1178
|
+
this.window.loadURL(getDashboardPageURL());
|
|
1110
1179
|
this.window.on("closed", () => {
|
|
1111
1180
|
this.window = null;
|
|
1112
1181
|
});
|
|
@@ -1276,6 +1345,7 @@ var ElectronMemoryMonitor = class extends EventEmitter3 {
|
|
|
1276
1345
|
this.dashboard = null;
|
|
1277
1346
|
return;
|
|
1278
1347
|
}
|
|
1348
|
+
registerDashboardSchemePrivileged();
|
|
1279
1349
|
this.collector = new MemoryCollector(this.config);
|
|
1280
1350
|
this.anomalyDetector = new AnomalyDetector(this.config);
|
|
1281
1351
|
this.analyzer = new Analyzer();
|
|
@@ -1288,10 +1358,10 @@ var ElectronMemoryMonitor = class extends EventEmitter3 {
|
|
|
1288
1358
|
/** 启动监控 */
|
|
1289
1359
|
async start() {
|
|
1290
1360
|
if (!this.config.enabled || this.started) return;
|
|
1291
|
-
if (!
|
|
1292
|
-
await
|
|
1361
|
+
if (!app3.isReady()) {
|
|
1362
|
+
await app3.whenReady();
|
|
1293
1363
|
}
|
|
1294
|
-
const storageDir = this.config.storage.directory ||
|
|
1364
|
+
const storageDir = this.config.storage.directory || path4.join(app3.getPath("userData"), "memory-monitor");
|
|
1295
1365
|
this.persister = new DataPersister(this.config, storageDir);
|
|
1296
1366
|
this.sessionManager = new SessionManager(this.persister);
|
|
1297
1367
|
this.ipcHandler = new IPCMainHandler(this);
|
|
@@ -1363,7 +1433,7 @@ var ElectronMemoryMonitor = class extends EventEmitter3 {
|
|
|
1363
1433
|
anomalies,
|
|
1364
1434
|
completedSession.dataFile
|
|
1365
1435
|
);
|
|
1366
|
-
const reportPath =
|
|
1436
|
+
const reportPath = path4.join(this.persister.getStorageDir(), completedSession.id, "report.json");
|
|
1367
1437
|
const fs2 = await import("fs");
|
|
1368
1438
|
fs2.writeFileSync(reportPath, JSON.stringify(report, null, 2), "utf-8");
|
|
1369
1439
|
this.emit("session-end", report);
|
|
@@ -1393,7 +1463,7 @@ var ElectronMemoryMonitor = class extends EventEmitter3 {
|
|
|
1393
1463
|
/** 获取指定会话报告 */
|
|
1394
1464
|
async getSessionReport(sessionId) {
|
|
1395
1465
|
const fs2 = await import("fs");
|
|
1396
|
-
const reportPath =
|
|
1466
|
+
const reportPath = path4.join(this.persister.getStorageDir(), sessionId, "report.json");
|
|
1397
1467
|
try {
|
|
1398
1468
|
const content = fs2.readFileSync(reportPath, "utf-8");
|
|
1399
1469
|
return JSON.parse(content);
|
|
@@ -1524,7 +1594,7 @@ var ElectronMemoryMonitor = class extends EventEmitter3 {
|
|
|
1524
1594
|
} catch {
|
|
1525
1595
|
}
|
|
1526
1596
|
}
|
|
1527
|
-
await new Promise((
|
|
1597
|
+
await new Promise((resolve2) => setTimeout(resolve2, 100));
|
|
1528
1598
|
const afterMem = process.memoryUsage();
|
|
1529
1599
|
const freed = beforeMem.heapUsed - afterMem.heapUsed;
|
|
1530
1600
|
return {
|
|
@@ -1537,7 +1607,7 @@ var ElectronMemoryMonitor = class extends EventEmitter3 {
|
|
|
1537
1607
|
}
|
|
1538
1608
|
/** 导出堆快照 */
|
|
1539
1609
|
async takeHeapSnapshot(filePath) {
|
|
1540
|
-
const snapshotPath = filePath ||
|
|
1610
|
+
const snapshotPath = filePath || path4.join(
|
|
1541
1611
|
this.persister.getStorageDir(),
|
|
1542
1612
|
`heap-${Date.now()}.heapsnapshot`
|
|
1543
1613
|
);
|
|
@@ -1597,6 +1667,7 @@ var ElectronMemoryMonitor = class extends EventEmitter3 {
|
|
|
1597
1667
|
};
|
|
1598
1668
|
export {
|
|
1599
1669
|
ElectronMemoryMonitor,
|
|
1600
|
-
IPC_CHANNELS
|
|
1670
|
+
IPC_CHANNELS,
|
|
1671
|
+
registerDashboardSchemePrivileged
|
|
1601
1672
|
};
|
|
1602
1673
|
//# sourceMappingURL=index.mjs.map
|