@ordojs/dev-tools
Version:
Advanced developer tools for OrdoJS with component inspector, AST explorer, and performance profiling
228 lines (225 loc) • 6.31 kB
JavaScript
'use strict';
var events = require('events');
// src/profiler/index.ts
var PerformanceProfiler = class extends events.EventEmitter {
profiles;
activeProfiles;
measurements;
isRunning;
port;
/**
* Create a new PerformanceProfiler instance
*
* @param port - WebSocket port for profiler
*/
constructor(port = 24680) {
super();
this.profiles = /* @__PURE__ */ new Map();
this.activeProfiles = /* @__PURE__ */ new Map();
this.measurements = /* @__PURE__ */ new Map();
this.isRunning = false;
this.port = port;
}
/**
* Start the performance profiler
*/
async start() {
if (this.isRunning) {
console.warn("Performance profiler is already running");
return;
}
try {
await this.startWebSocketServer();
this.isRunning = true;
console.log(`Performance profiler started on port ${this.port}`);
this.emit("started");
} catch (error) {
console.error("Failed to start performance profiler:", error);
this.emit("error", error);
throw error;
}
}
/**
* Stop the performance profiler
*/
async stop() {
if (!this.isRunning) {
console.warn("Performance profiler is not running");
return;
}
try {
for (const [name, profile] of this.activeProfiles) {
await this.stopProfile(name);
}
await this.stopWebSocketServer();
this.isRunning = false;
console.log("Performance profiler stopped");
this.emit("stopped");
} catch (error) {
console.error("Failed to stop performance profiler:", error);
this.emit("error", error);
throw error;
}
}
/**
* Start a performance profile
*
* @param name - Profile name
* @param metadata - Profile metadata
* @returns Profile instance
*/
startProfile(name, metadata = {}) {
if (this.activeProfiles.has(name)) {
throw new Error(`Profile '${name}' is already active`);
}
const profile = {
name,
startTime: performance.now(),
endTime: 0,
duration: 0,
measurements: [],
metadata
};
this.activeProfiles.set(name, profile);
this.emit("profileStarted", profile);
return profile;
}
/**
* Stop a performance profile
*
* @param name - Profile name
* @returns Completed profile
*/
stopProfile(name) {
const profile = this.activeProfiles.get(name);
if (!profile) {
throw new Error(`Profile '${name}' is not active`);
}
profile.endTime = performance.now();
profile.duration = profile.endTime - profile.startTime;
this.activeProfiles.delete(name);
this.profiles.set(name, profile);
this.emit("profileStopped", profile);
return profile;
}
/**
* Add a performance measurement
*
* @param profileName - Profile name
* @param measurementName - Measurement name
* @param category - Measurement category
* @param metadata - Measurement metadata
* @returns Measurement instance
*/
addMeasurement(profileName, measurementName, category = "general", metadata = {}) {
const profile = this.activeProfiles.get(profileName);
if (!profile) {
throw new Error(`Profile '${profileName}' is not active`);
}
const measurement = {
name: measurementName,
startTime: performance.now(),
endTime: 0,
duration: 0,
category,
metadata
};
if (!this.measurements.has(profileName)) {
this.measurements.set(profileName, []);
}
this.measurements.get(profileName).push(measurement);
profile.measurements.push(measurement);
this.emit("measurementAdded", measurement);
return measurement;
}
/**
* End a performance measurement
*
* @param profileName - Profile name
* @param measurementName - Measurement name
* @returns Completed measurement
*/
endMeasurement(profileName, measurementName) {
const profile = this.activeProfiles.get(profileName);
if (!profile) {
throw new Error(`Profile '${profileName}' is not active`);
}
const measurements = this.measurements.get(profileName);
if (!measurements) {
throw new Error(`No measurements found for profile '${profileName}'`);
}
const measurement = measurements.find((m) => m.name === measurementName);
if (!measurement) {
throw new Error(`Measurement '${measurementName}' not found in profile '${profileName}'`);
}
measurement.endTime = performance.now();
measurement.duration = measurement.endTime - measurement.startTime;
this.emit("measurementEnded", measurement);
return measurement;
}
/**
* Get a profile by name
*
* @param name - Profile name
* @returns Profile or undefined
*/
getProfile(name) {
return this.profiles.get(name) || this.activeProfiles.get(name);
}
/**
* Get all profiles
*
* @returns Array of all profiles
*/
getAllProfiles() {
return Array.from(this.profiles.values());
}
/**
* Get active profiles
*
* @returns Array of active profiles
*/
getActiveProfiles() {
return Array.from(this.activeProfiles.values());
}
/**
* Clear all profiles
*/
clearProfiles() {
this.profiles.clear();
this.activeProfiles.clear();
this.measurements.clear();
this.emit("profilesCleared");
}
/**
* Get profiler statistics
*
* @returns Profiler statistics
*/
getStats() {
const allProfiles = Array.from(this.profiles.values());
const totalMeasurements = allProfiles.reduce((sum, profile) => sum + profile.measurements.length, 0);
const averageProfileDuration = allProfiles.reduce((sum, profile) => sum + profile.duration, 0) / allProfiles.length || 0;
return {
totalProfiles: allProfiles.length,
activeProfiles: this.activeProfiles.size,
totalMeasurements,
averageProfileDuration
};
}
/**
* Start WebSocket server for profiler communication
*/
async startWebSocketServer() {
console.log("Starting WebSocket server for performance profiler...");
}
/**
* Stop WebSocket server
*/
async stopWebSocketServer() {
console.log("Stopping WebSocket server for performance profiler...");
}
};
exports.PerformanceProfiler = PerformanceProfiler;
//# sourceMappingURL=index.js.map
//# sourceMappingURL=index.js.map