@oxog/delay
Version:
A comprehensive, zero-dependency delay/timeout utility library with advanced timing features
90 lines • 3.28 kB
JavaScript
import { DelayError, DelayErrorCode } from '../types/index.js';
import { createBasicDelay } from '../core/delay.js';
export async function raceWithTimeout(promises, timeoutMs, timeoutError) {
const timeoutPromise = createTimeoutPromise(timeoutMs, timeoutError);
try {
const result = await Promise.race([...promises, timeoutPromise]);
return result;
}
catch (error) {
throw error;
}
}
export function createTimeoutPromise(ms, error) {
return new Promise((_, reject) => {
setTimeout(() => {
const timeoutError = error || new DelayError(`Operation timed out after ${ms}ms`, DelayErrorCode.TIMEOUT, { timeout: ms });
reject(timeoutError);
}, ms);
});
}
export async function minimumDelay(promise, minMs) {
const [result] = await Promise.all([
promise,
createBasicDelay(minMs),
]);
return result;
}
export async function raceArray(promises, options = {}) {
const { timeout, timeoutError, failFast = true } = options;
if (promises.length === 0) {
throw new DelayError('Cannot race empty array of promises', DelayErrorCode.INVALID_OPTIONS, { promises: [] });
}
const racePromises = [...promises];
if (timeout !== undefined) {
racePromises.push(createTimeoutPromise(timeout, timeoutError));
}
if (failFast) {
return Promise.race(racePromises);
}
// If not fail-fast, wait for the first successful result
return new Promise((resolve, reject) => {
let rejectionCount = 0;
const errors = [];
racePromises.forEach((promise, index) => {
promise
.then(result => resolve(result))
.catch(error => {
errors[index] = error;
rejectionCount++;
if (rejectionCount === racePromises.length) {
reject(new DelayError('All promises rejected', DelayErrorCode.RETRY_EXHAUSTED, { errors }));
}
});
});
});
}
export function createDelayedPromise(factory, delayMs) {
return createBasicDelay(delayMs).then(() => factory());
}
export async function sequential(factories, delayBetween = 0) {
const results = [];
for (let i = 0; i < factories.length; i++) {
if (i > 0 && delayBetween > 0) {
await createBasicDelay(delayBetween);
}
const result = await factories[i]();
results.push(result);
}
return results;
}
export async function parallel(factories, concurrency = Infinity) {
if (concurrency <= 0) {
throw new DelayError('Concurrency must be positive', DelayErrorCode.INVALID_OPTIONS, { concurrency });
}
if (concurrency >= factories.length) {
return Promise.all(factories.map(factory => factory()));
}
const results = new Array(factories.length);
let index = 0;
const worker = async () => {
while (index < factories.length) {
const currentIndex = index++;
results[currentIndex] = await factories[currentIndex]();
}
};
const workers = Array.from({ length: Math.min(concurrency, factories.length) }, worker);
await Promise.all(workers);
return results;
}
//# sourceMappingURL=promise.js.map