@oxog/delay
Version:
A comprehensive, zero-dependency delay/timeout utility library with advanced timing features
118 lines • 4.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createBasicDelay = createBasicDelay;
exports.createProgressiveDelay = createProgressiveDelay;
exports.msDelay = msDelay;
exports.secondsDelay = secondsDelay;
exports.minutesDelay = minutesDelay;
exports.hoursDelay = hoursDelay;
exports.daysDelay = daysDelay;
const index_js_1 = require("../types/index.js");
const validation_js_1 = require("../utils/validation.js");
const time_js_1 = require("../utils/time.js");
function createBasicDelay(ms, options = {}) {
(0, validation_js_1.validateDelay)(ms);
return new Promise((resolve, reject) => {
const { signal, onProgress, progressInterval = 100 } = options;
// Check if already aborted
if (signal?.aborted) {
reject(new index_js_1.DelayError('Delay was aborted', index_js_1.DelayErrorCode.CANCELLED));
return;
}
// Handle immediate resolve for zero delay (but still check for cancellation)
if (ms === 0) {
// Use setTimeout to allow for cancellation even on zero delay
const timeoutId = setTimeout(() => {
if (!signal?.aborted) {
resolve();
}
}, 0);
signal?.addEventListener('abort', () => {
clearTimeout(timeoutId);
reject(new index_js_1.DelayError('Delay was cancelled', index_js_1.DelayErrorCode.CANCELLED));
});
return;
}
const startTime = (0, time_js_1.getHighResolutionTime)();
let timeoutId;
let progressIntervalId;
let isResolved = false;
const cleanup = () => {
if (typeof timeoutId === 'number') {
clearTimeout(timeoutId);
}
else {
clearTimeout(timeoutId);
}
if (progressIntervalId !== undefined) {
if (typeof progressIntervalId === 'number') {
clearInterval(progressIntervalId);
}
else {
clearInterval(progressIntervalId);
}
}
};
const handleAbort = () => {
if (!isResolved) {
isResolved = true;
cleanup();
reject(new index_js_1.DelayError('Delay was cancelled', index_js_1.DelayErrorCode.CANCELLED));
}
};
const handleResolve = () => {
if (!isResolved) {
isResolved = true;
cleanup();
signal?.removeEventListener('abort', handleAbort);
resolve();
}
};
// Set up abort handling
signal?.addEventListener('abort', handleAbort);
// Set up progress tracking
if (onProgress && ms > progressInterval) {
const updateProgress = () => {
if (!isResolved) {
const elapsed = (0, time_js_1.getHighResolutionTime)() - startTime;
const clampedElapsed = Math.min(elapsed, ms);
onProgress(clampedElapsed, ms);
if (elapsed >= ms) {
if (progressIntervalId !== undefined) {
if (typeof progressIntervalId === 'number') {
clearInterval(progressIntervalId);
}
else {
clearInterval(progressIntervalId);
}
}
}
}
};
progressIntervalId = setInterval(updateProgress, progressInterval);
// Call immediately for initial progress
updateProgress();
}
// Set the main timeout
timeoutId = setTimeout(handleResolve, ms);
});
}
function createProgressiveDelay(ms, onProgress, progressInterval = 100) {
return createBasicDelay(ms, { onProgress, progressInterval });
}
function msDelay(milliseconds, options) {
return createBasicDelay(milliseconds, options);
}
function secondsDelay(seconds, options) {
return createBasicDelay(seconds * 1000, options);
}
function minutesDelay(minutes, options) {
return createBasicDelay(minutes * 60 * 1000, options);
}
function hoursDelay(hours, options) {
return createBasicDelay(hours * 60 * 60 * 1000, options);
}
function daysDelay(days, options) {
return createBasicDelay(days * 24 * 60 * 60 * 1000, options);
}
//# sourceMappingURL=delay.js.map