Files
arcum42-ComfyUI_SageUtils/js/shared/performanceUtils.js
T
2026-06-20 21:09:30 -07:00

121 lines
3.1 KiB
JavaScript

/**
* Performance Utilities
*
* Provides debouncing, throttling, and rate limiting utilities
* to optimize performance and prevent overwhelming the system
*/
/**
* Debounce function - delays execution until after wait time has elapsed since last call
* @param {Function} func - Function to debounce
* @param {number} wait - Wait time in milliseconds
* @param {boolean} immediate - Execute on leading edge instead of trailing
* @returns {Function} Debounced function
*/
export function debounce(func, wait, immediate = false) {
let timeout;
return function executedFunction(...args) {
const context = this;
const later = () => {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
/**
* Throttle function - limits execution to once per wait period
* @param {Function} func - Function to throttle
* @param {number} wait - Wait time in milliseconds
* @returns {Function} Throttled function
*/
export function throttle(func, wait) {
let inThrottle;
let lastFunc;
let lastRan;
return function(...args) {
const context = this;
if (!inThrottle) {
func.apply(context, args);
lastRan = Date.now();
inThrottle = true;
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(() => {
if ((Date.now() - lastRan) >= wait) {
func.apply(context, args);
lastRan = Date.now();
}
}, Math.max(wait - (Date.now() - lastRan), 0));
}
};
}
/**
* Rate Limiter class - limits calls to a function over time
*/
export class RateLimiter {
constructor(maxCalls, timeWindow) {
this.maxCalls = maxCalls;
this.timeWindow = timeWindow; // in milliseconds
this.calls = [];
}
/**
* Check if a call is allowed
* @returns {boolean} True if call is allowed
*/
allowCall() {
const now = Date.now();
// Remove calls outside the time window
this.calls = this.calls.filter(time => now - time < this.timeWindow);
// Check if we're under the limit
if (this.calls.length < this.maxCalls) {
this.calls.push(now);
return true;
}
return false;
}
/**
* Get time until next call is allowed
* @returns {number} Milliseconds until next call allowed, or 0 if allowed now
*/
getWaitTime() {
if (this.calls.length < this.maxCalls) {
return 0;
}
const now = Date.now();
const oldestCall = this.calls[0];
return Math.max(0, this.timeWindow - (now - oldestCall));
}
/**
* Reset the rate limiter
*/
reset() {
this.calls = [];
}
}
export default {
debounce,
throttle,
RateLimiter
};