UNPKG

@hirosystems/api-toolkit

Version:
121 lines 3.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.timeout = timeout; exports.time = time; exports.resolveOrTimeout = resolveOrTimeout; exports.stopwatch = stopwatch; exports.waiter = waiter; const promises_1 = require("node:timers/promises"); /** * Wait a set amount of milliseconds or until the timer is aborted. * @param ms - Number of milliseconds to wait * @param abort - Abort controller * @returns Promise */ function timeout(ms, abort) { const signal = abort && (abort instanceof AbortSignal ? abort : abort.signal); return (0, promises_1.setTimeout)(ms, undefined, { signal }); } /** * Time the execution of an async function. * @param fn - Async function * @param onFinish - Callback with elapsed milliseconds * @returns Promise */ async function time(fn, onFinish) { const watch = stopwatch(); try { return await fn(); } finally { onFinish(watch.getElapsed()); } } /** * Set an execution time limit for a promise. * @param promise - The promise being capped to `timeoutMs` max execution time * @param timeoutMs - Timeout limit in milliseconds * @param wait - If we should wait another `timeoutMs` period for `promise` to resolve * @param waitHandler - If `wait` is `true`, this closure will be executed before waiting another * `timeoutMs` cycle * @returns `true` if `promise` ended gracefully, `false` if timeout was reached */ async function resolveOrTimeout(promise, timeoutMs, wait = false, waitHandler) { let timer; const result = await Promise.race([ new Promise((resolve, reject) => { promise .then(() => resolve(true)) .catch(error => reject(error)) .finally(() => clearTimeout(timer)); }), new Promise((resolve, _) => { timer = setInterval(() => { if (!wait) { clearTimeout(timer); resolve(false); return; } if (waitHandler) { waitHandler(); } }, timeoutMs); }), ]); return result; } /** * Start a `Stopwatch` that measures elapsed time based on `process.hrtime`. * @returns Stopwatch */ function stopwatch() { let start = process.hrtime.bigint(); const result = { getElapsedSeconds: () => { const elapsedMs = result.getElapsed(); return elapsedMs / 1000; }, getElapsed: () => { const end = process.hrtime.bigint(); return Number((end - start) / 1000000n); }, getElapsedAndRestart: () => { const end = process.hrtime.bigint(); const result = Number((end - start) / 1000000n); start = process.hrtime.bigint(); return result; }, restart: () => { start = process.hrtime.bigint(); }, }; return result; } /** * Creates a `Waiter` promise that can be resolved or rejected at a later time. * @returns Waiter */ function waiter() { let resolveFn; let rejectFn; const promise = new Promise((resolve, reject) => { resolveFn = resolve; rejectFn = reject; }); const completer = { finish: (result) => completer.resolve(result), resolve: (result) => { void Object.assign(promise, { isFinished: true, isResolved: true }); resolveFn(result); }, reject: (error) => { void Object.assign(promise, { isFinished: true, isRejected: true }); rejectFn(error); }, isFinished: false, isResolved: false, isRejected: false, }; return Object.assign(promise, completer); } //# sourceMappingURL=time.js.map