@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
JavaScript
"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