summarizely-cli
Version:
YouTube summarizer that respects your existing subscriptions. No API keys required.
183 lines • 5.71 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.profileOps = exports.PerformanceProfiler = void 0;
exports.profile = profile;
exports.profileAsync = profileAsync;
exports.startProfile = startProfile;
exports.endProfile = endProfile;
exports.Profiled = Profiled;
exports.enableAutoProfile = enableAutoProfile;
const config_1 = require("./config");
const perf_hooks_1 = require("perf_hooks");
class PerformanceProfiler {
static initialize() {
const config = (0, config_1.getConfig)();
this.enabled = config.performance.profiling || process.env.SUMMARIZELY_PROFILE === 'true';
}
static start(name, metadata) {
if (!this.enabled)
return;
const startTime = perf_hooks_1.performance.now();
this.marks.set(name, startTime);
if (metadata) {
this.profiles.set(name, {
name,
duration: 0,
startTime,
endTime: 0,
metadata
});
}
}
static end(name) {
if (!this.enabled)
return null;
const startTime = this.marks.get(name);
if (!startTime) {
console.error(`[PROFILE] No start mark found for: ${name}`);
return null;
}
const endTime = perf_hooks_1.performance.now();
const duration = endTime - startTime;
const result = {
name,
duration,
startTime,
endTime,
...this.profiles.get(name)
};
this.profiles.set(name, result);
this.marks.delete(name);
console.error(`[PROFILE] ${name}: ${duration.toFixed(2)}ms`);
return result;
}
static measure(name, fn) {
if (!this.enabled)
return fn();
this.start(name);
try {
return fn();
}
finally {
this.end(name);
}
}
static async measureAsync(name, fn) {
if (!this.enabled)
return fn();
this.start(name);
try {
return await fn();
}
finally {
this.end(name);
}
}
static getProfile(name) {
return this.profiles.get(name);
}
static getAllProfiles() {
return Array.from(this.profiles.values());
}
static clear() {
this.profiles.clear();
this.marks.clear();
}
static report() {
if (!this.enabled)
return 'Profiling disabled';
const profiles = this.getAllProfiles();
if (profiles.length === 0)
return 'No profiles recorded';
const sorted = profiles.sort((a, b) => b.duration - a.duration);
const total = sorted.reduce((sum, p) => sum + p.duration, 0);
const lines = [
'\n========== Performance Report ==========',
`Total time: ${total.toFixed(2)}ms`,
''
];
sorted.forEach(p => {
const percent = (p.duration / total * 100).toFixed(1);
lines.push(`${p.name}: ${p.duration.toFixed(2)}ms (${percent}%)`);
if (p.metadata) {
Object.entries(p.metadata).forEach(([key, value]) => {
lines.push(` ${key}: ${value}`);
});
}
});
lines.push('========================================\n');
return lines.join('\n');
}
static setEnabled(enabled) {
this.enabled = enabled;
}
static isEnabled() {
return this.enabled;
}
}
exports.PerformanceProfiler = PerformanceProfiler;
_a = PerformanceProfiler;
PerformanceProfiler.enabled = false;
PerformanceProfiler.profiles = new Map();
PerformanceProfiler.marks = new Map();
(() => {
_a.initialize();
})();
// Convenience functions
function profile(name, fn) {
return PerformanceProfiler.measure(name, fn);
}
async function profileAsync(name, fn) {
return PerformanceProfiler.measureAsync(name, fn);
}
function startProfile(name, metadata) {
PerformanceProfiler.start(name, metadata);
}
function endProfile(name) {
return PerformanceProfiler.end(name);
}
// Decorator for profiling methods
function Profiled(name) {
return function (target, propertyKey, descriptor) {
const originalMethod = descriptor.value;
const profileName = name || `${target.constructor.name}.${propertyKey}`;
descriptor.value = async function (...args) {
if (!PerformanceProfiler.isEnabled()) {
return originalMethod.apply(this, args);
}
return profileAsync(profileName, () => originalMethod.apply(this, args));
};
return descriptor;
};
}
// Profile specific operations
exports.profileOps = {
fetchCaptions: (url) => {
startProfile('fetch-captions', { url });
},
summarize: (provider, model) => {
startProfile('summarize', { provider, model });
},
writeFile: (path, size) => {
startProfile('write-file', { path, size });
},
cacheOperation: (operation, key) => {
startProfile(`cache-${operation}`, { key });
},
batchItem: (index, total, url) => {
startProfile(`batch-item-${index}`, { index, total, url });
}
};
// Auto-profile common Node.js operations
function enableAutoProfile() {
if (!PerformanceProfiler.isEnabled())
return;
// Profile require calls
const Module = require('module');
const originalRequire = Module.prototype.require;
Module.prototype.require = function (id) {
return profile(`require:${id}`, () => originalRequire.apply(this, [id]));
};
}
//# sourceMappingURL=performance.js.map