const DEFAULT_THROTTLE_MS = 250; /** * Creates a throttled version of a progress callback that ensures it's not called * more frequently than the specified interval (default: 250ms) */ export const createThrottledProgressCallback = (callback, throttleMs = DEFAULT_THROTTLE_MS) => { if (!callback) { return null; } let lastCallTime = 0; let pendingUpdate = null; let timeoutId = null; const throttled = (progress) => { const now = Date.now(); const timeSinceLastCall = now - lastCallTime; // Always store the latest progress pendingUpdate = progress; // If enough time has passed, call immediately if (timeSinceLastCall >= throttleMs) { lastCallTime = now; callback(progress); pendingUpdate = null; // Clear any pending timeout if (timeoutId !== null) { clearTimeout(timeoutId); timeoutId = null; } } else if (timeoutId === null) { // Schedule a call for when the throttle period expires const remainingTime = throttleMs - timeSinceLastCall; timeoutId = setTimeout(() => { if (pendingUpdate !== null) { lastCallTime = Date.now(); callback(pendingUpdate); pendingUpdate = null; } timeoutId = null; }, remainingTime); } }; return throttled; };