UNPKG

summarizely-cli

Version:

YouTube summarizer that respects your existing subscriptions. No API keys required.

183 lines 5.71 kB
"use strict"; 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