@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.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/core/monitor.ts
2
- import { app as app2 } from "electron";
3
- import * as path3 from "path";
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 = path2.join(__dirname, "dashboard-preload.js");
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 uiPath = path2.join(__dirname, "ui", "index.html");
1109
- this.window.loadFile(uiPath);
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 (!app2.isReady()) {
1292
- await app2.whenReady();
1361
+ if (!app3.isReady()) {
1362
+ await app3.whenReady();
1293
1363
  }
1294
- const storageDir = this.config.storage.directory || path3.join(app2.getPath("userData"), "memory-monitor");
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 = path3.join(this.persister.getStorageDir(), completedSession.id, "report.json");
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 = path3.join(this.persister.getStorageDir(), sessionId, "report.json");
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((resolve) => setTimeout(resolve, 100));
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 || path3.join(
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