UNPKG

@tuanltntu/n8n-nodes-bitrix24

Version:

Comprehensive n8n community node for Bitrix24 API integration with CRM, Tasks, Chat, Telephony, and more

250 lines 7.58 kB
"use strict"; /** * Performance Optimizer for n8n-nodes-bitrix24 * This file provides utilities to monitor and improve performance */ Object.defineProperty(exports, "__esModule", { value: true }); exports.performanceOptimizer = exports.debouncer = exports.smartCache = exports.performanceMonitor = exports.PerformanceOptimizer = exports.Debouncer = exports.SmartCache = exports.PerformanceMonitor = void 0; // Performance monitoring class PerformanceMonitor { /** * Start timing an operation */ static startTimer(operation) { const startTime = performance.now(); return () => { const endTime = performance.now(); const duration = endTime - startTime; this.recordMetric(operation, duration); }; } /** * Record performance metric */ static recordMetric(operation, duration) { const existing = this.metrics.get(operation) || { count: 0, totalTime: 0, avgTime: 0 }; existing.count++; existing.totalTime += duration; existing.avgTime = existing.totalTime / existing.count; this.metrics.set(operation, existing); } /** * Record cache hit */ static recordCacheHit() { this.cacheHits++; } /** * Record cache miss */ static recordCacheMiss() { this.cacheMisses++; } /** * Get performance statistics */ static getStats() { const totalRequests = this.cacheHits + this.cacheMisses; const cacheHitRate = totalRequests > 0 ? (this.cacheHits / totalRequests) * 100 : 0; return { operations: new Map(this.metrics), cacheHitRate, totalCacheHits: this.cacheHits, totalCacheMisses: this.cacheMisses, }; } /** * Reset all metrics */ static reset() { this.metrics.clear(); this.cacheHits = 0; this.cacheMisses = 0; } } exports.PerformanceMonitor = PerformanceMonitor; PerformanceMonitor.metrics = new Map(); PerformanceMonitor.cacheHits = 0; PerformanceMonitor.cacheMisses = 0; // Enhanced caching with TTL and size limits class SmartCache { constructor(maxSize = 100, ttl = 5 * 60 * 1000) { this.cache = new Map(); this.maxSize = maxSize; this.ttl = ttl; } /** * Get item from cache */ get(key) { const item = this.cache.get(key); if (!item) { PerformanceMonitor.recordCacheMiss(); return null; } // Check if expired if (Date.now() - item.timestamp > this.ttl) { this.cache.delete(key); PerformanceMonitor.recordCacheMiss(); return null; } // Update access count and timestamp item.accessCount++; this.cache.set(key, item); PerformanceMonitor.recordCacheHit(); return item.data; } /** * Set item in cache */ set(key, data) { // Check if we need to evict items if (this.cache.size >= this.maxSize) { this.evictLeastUsed(); } this.cache.set(key, { data, timestamp: Date.now(), accessCount: 1, }); } /** * Evict least used items when cache is full */ evictLeastUsed() { let leastUsedKey = ''; let lowestAccessCount = Infinity; for (const [key, item] of this.cache.entries()) { if (item.accessCount < lowestAccessCount) { lowestAccessCount = item.accessCount; leastUsedKey = key; } } if (leastUsedKey) { this.cache.delete(leastUsedKey); } } /** * Clear expired items */ clearExpired() { const now = Date.now(); for (const [key, item] of this.cache.entries()) { if (now - item.timestamp > this.ttl) { this.cache.delete(key); } } } /** * Get cache statistics */ getStats() { return { size: this.cache.size, maxSize: this.maxSize, ttl: this.ttl, }; } /** * Clear all cache */ clear() { this.cache.clear(); } } exports.SmartCache = SmartCache; // Debounce utility for input fields class Debouncer { constructor() { this.timers = new Map(); } /** * Debounce a function call */ debounce(key, func, delay) { return (...args) => { if (this.timers.has(key)) { clearTimeout(this.timers.get(key)); } this.timers.set(key, setTimeout(() => { func(...args); this.timers.delete(key); }, delay)); }; } /** * Cancel a debounced function */ cancel(key) { if (this.timers.has(key)) { clearTimeout(this.timers.get(key)); this.timers.delete(key); } } /** * Clear all timers */ clear() { for (const timer of this.timers.values()) { clearTimeout(timer); } this.timers.clear(); } } exports.Debouncer = Debouncer; // Performance optimization recommendations class PerformanceOptimizer { /** * Get optimization recommendations based on current metrics */ static getRecommendations() { const stats = PerformanceMonitor.getStats(); const recommendations = []; // Check cache hit rate if (stats.cacheHitRate < 50) { recommendations.push("Consider increasing cache TTL or implementing better caching strategies"); } // Check operation performance for (const [operation, metrics] of stats.operations.entries()) { if (metrics.avgTime > 1000) { // More than 1 second recommendations.push(`Operation '${operation}' is slow (${metrics.avgTime.toFixed(2)}ms avg). Consider optimization.`); } } // General recommendations if (recommendations.length === 0) { recommendations.push("Performance is good! Keep up the good work."); } return recommendations; } /** * Generate performance report */ static generateReport() { const stats = PerformanceMonitor.getStats(); const recommendations = this.getRecommendations(); let report = "=== n8n-nodes-bitrix24 Performance Report ===\n\n"; // Cache statistics report += `Cache Performance:\n`; report += `- Hit Rate: ${stats.cacheHitRate.toFixed(2)}%\n`; report += `- Total Hits: ${stats.totalCacheHits}\n`; report += `- Total Misses: ${stats.totalCacheMisses}\n\n`; // Operation statistics report += `Operation Performance:\n`; for (const [operation, metrics] of stats.operations.entries()) { report += `- ${operation}: ${metrics.count} calls, ${metrics.avgTime.toFixed(2)}ms avg\n`; } // Recommendations report += `\nOptimization Recommendations:\n`; recommendations.forEach((rec, index) => { report += `${index + 1}. ${rec}\n`; }); return report; } } exports.PerformanceOptimizer = PerformanceOptimizer; // Export default instance exports.performanceMonitor = new PerformanceMonitor(); exports.smartCache = new SmartCache(); exports.debouncer = new Debouncer(); exports.performanceOptimizer = new PerformanceOptimizer(); //# sourceMappingURL=performance-optimizer.js.map