UNPKG

@oxog/delay

Version:

A comprehensive, zero-dependency delay/timeout utility library with advanced timing features

129 lines 4.71 kB
import { DelayError, DelayErrorCode } from '../types/index.js'; export function nextFrame() { if (typeof requestAnimationFrame === 'undefined') { throw new DelayError('requestAnimationFrame is not available in this environment', DelayErrorCode.UNSUPPORTED_ENVIRONMENT, { feature: 'requestAnimationFrame' }); } return new Promise((resolve) => { requestAnimationFrame(resolve); }); } export function nextFrames(count) { if (count <= 0) { throw new DelayError('Frame count must be positive', DelayErrorCode.INVALID_OPTIONS, { count }); } if (count === 1) { return nextFrame(); } return new Promise((resolve) => { let remaining = count; const tick = (timestamp) => { remaining--; if (remaining <= 0) { resolve(timestamp); } else { requestAnimationFrame(tick); } }; requestAnimationFrame(tick); }); } export function idle(options = {}) { if (typeof requestIdleCallback === 'undefined') { // Fallback for environments without requestIdleCallback return new Promise((resolve) => { setTimeout(() => { resolve({ didTimeout: false, timeRemaining() { return 50; // Assume 50ms remaining }, }); }, 0); }); } return new Promise((resolve, reject) => { const id = requestIdleCallback(resolve, options); // Optional timeout handling if (options.timeout) { setTimeout(() => { if (typeof cancelIdleCallback !== 'undefined') { cancelIdleCallback(id); } reject(new DelayError(`Idle callback timed out after ${options.timeout}ms`, DelayErrorCode.TIMEOUT, { timeout: options.timeout })); }, options.timeout); } }); } export function waitForDOMReady() { if (typeof document === 'undefined') { throw new DelayError('DOM is not available in this environment', DelayErrorCode.UNSUPPORTED_ENVIRONMENT, { feature: 'document' }); } if (document.readyState === 'complete' || document.readyState === 'interactive') { return Promise.resolve(); } return new Promise((resolve) => { const handler = () => { document.removeEventListener('DOMContentLoaded', handler); resolve(); }; document.addEventListener('DOMContentLoaded', handler); }); } export function waitForWindowLoad() { if (typeof window === 'undefined') { throw new DelayError('Window is not available in this environment', DelayErrorCode.UNSUPPORTED_ENVIRONMENT, { feature: 'window' }); } if (document.readyState === 'complete') { return Promise.resolve(); } return new Promise((resolve) => { const handler = () => { window.removeEventListener('load', handler); resolve(); }; window.addEventListener('load', handler); }); } export function waitForVisibilityChange(visible) { if (typeof document === 'undefined') { throw new DelayError('Document is not available in this environment', DelayErrorCode.UNSUPPORTED_ENVIRONMENT, { feature: 'document' }); } // Check current state const isCurrentlyVisible = !document.hidden; if (isCurrentlyVisible === visible) { return Promise.resolve(); } return new Promise((resolve) => { const handler = () => { const isVisible = !document.hidden; if (isVisible === visible) { document.removeEventListener('visibilitychange', handler); resolve(); } }; document.addEventListener('visibilitychange', handler); }); } export function createFrameBasedDelay(frames) { return nextFrames(frames); } export function createIdleDelay(maxWait = 5000) { return idle({ timeout: maxWait }); } export function isRequestAnimationFrameAvailable() { return typeof requestAnimationFrame !== 'undefined'; } export function isRequestIdleCallbackAvailable() { return typeof requestIdleCallback !== 'undefined'; } export function getEnvironmentCapabilities() { return { hasRequestAnimationFrame: isRequestAnimationFrameAvailable(), hasRequestIdleCallback: isRequestIdleCallbackAvailable(), hasPerformanceNow: typeof performance !== 'undefined' && !!performance.now, hasDocument: typeof document !== 'undefined', hasWindow: typeof window !== 'undefined', }; } //# sourceMappingURL=browser.js.map