@naturalcycles/js-lib
Version:
Standard library for universal (browser + Node.js) javascript
69 lines (68 loc) • 2.39 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.pTimeoutFn = pTimeoutFn;
exports.pTimeout = pTimeout;
const error_util_1 = require("../error/error.util");
const types_1 = require("../types");
/**
* Decorates a Function with a timeout.
* Returns a decorated Function.
*
* Throws an Error if the Function is not resolved in a certain time.
* If the Function rejects - passes this rejection further.
*/
function pTimeoutFn(fn, opt) {
opt.name ||= fn.name;
if (!opt.timeout) {
return fn;
}
return async function pTimeoutInternalFn(...args) {
return await pTimeout(() => fn.apply(this, args), opt);
};
}
/**
* Decorates a Function with a timeout and immediately calls it.
*
* Throws an Error if the Function is not resolved in a certain time.
* If the Function rejects - passes this rejection further.
*/
async function pTimeout(fn, opt) {
if (!opt.timeout) {
// short-circuit to direct execution if 0 timeout is passed
return await fn();
}
const { timeout, name = fn.name || 'pTimeout function', onTimeout } = opt;
const fakeError = opt.fakeError || new Error('TimeoutError');
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: ok
return await new Promise(async (resolve, reject) => {
// Prepare the timeout timer
const timer = setTimeout(() => {
const err = new error_util_1.TimeoutError(`"${name}" timed out after ${timeout} ms`, opt.errorData);
// keep original stack
err.stack = fakeError.stack.replace('Error: TimeoutError', 'TimeoutError: ' + err.message);
if (onTimeout) {
try {
resolve(onTimeout(err));
}
catch (err) {
(0, types_1._typeCast)(err);
// keep original stack
err.stack = fakeError.stack.replace('Error: TimeoutError', err.name + ': ' + err.message);
reject((0, error_util_1._errorDataAppend)(err, opt.errorData));
}
return;
}
reject(err);
}, timeout);
// Execute the Function
try {
resolve(await fn());
}
catch (err) {
reject(err);
}
finally {
clearTimeout(timer);
}
});
}