fcr-core
Version:
Core APIs for building online scenes
61 lines (60 loc) • 2.02 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.abortableRetry = void 0;
require("core-js/modules/web.dom-exception.stack.js");
var _imports = require("../imports");
/**
* Creates an abortable retry operation that can be cancelled at any time.
*
* The handler function will be retried up to `retriesMax` times if it fails.
* The operation can be cancelled by calling the returned abort function,
* which will cause the promise to reject with an AbortError.
*
* @example
* ```typescript
* const [abort, promise] = abortableRetry(async (signal) => {
* await asyncFunction1();
* // Check if aborted after each async operation
* signal.throwIfAborted();
*
* await asyncFunction2();
* signal.throwIfAborted();
*
* return result;
* }, { retriesMax: 10 });
*
* // Cancel the operation at any time
* setTimeout(() => abort(), 5000);
*
* const [err, result] = await promise;
* if (err?.name === 'AbortError') {
* console.log('Operation was cancelled');
* }
* ```
*
* @param handler - Async function that receives an AbortSignal.
* Should call `signal.throwIfAborted()` periodically to check for cancellation.
* @param options - Retry configuration
* @returns Tuple of [abort function, result promise]. The promise resolves to [error, result].
*/
const abortableRetry = (handler, options) => {
const abortController = new AbortController();
const promise = (0, _imports.to)((0, _imports.retryAttempt)(async () => {
abortController.signal.throwIfAborted();
const result = await handler(abortController.signal);
abortController.signal.throwIfAborted();
return result;
}, [], {
retriesMax: options.retriesMax
}).fail(async options => {
if (abortController.signal.aborted) {
throw new DOMException('Operation aborted', 'AbortError');
}
await options.timeFn();
return true;
}).exec());
return [() => abortController.abort(), promise];
};
exports.abortableRetry = abortableRetry;