async-states
Version:
Core of async-states
88 lines (85 loc) • 2.75 kB
JavaScript
import { isPromise, cloneProducerProps, isFunction } from './utils.js';
import { pending, success, error } from './enums.js';
function run(producer, props, indicators, onSettled, retryConfig, callbacks) {
let pendingPromise;
let executionValue;
try {
executionValue = producer(props);
// when producer runs, it can decide to bailout everything
// by calling props.abort(reason?) as early as possible
if (indicators.aborted) {
return;
}
}
catch (e) {
// same, you can props.abort(); throw "Ignored error";
if (indicators.aborted) {
return;
}
onFail(e);
return;
}
if (isPromise(executionValue)) {
pendingPromise = executionValue;
}
else {
// final value
onSuccess(executionValue);
return;
}
pendingPromise = pendingPromise.then(onSuccess, onFail);
pendingPromise.status = pending;
return pendingPromise;
function onSuccess(data) {
if (pendingPromise) {
pendingPromise.status = "fulfilled";
pendingPromise.value = data;
}
if (!indicators.aborted) {
indicators.done = true;
onSettled(data, success, cloneProducerProps(props), callbacks);
}
return data;
}
function onFail(error$1) {
if (pendingPromise) {
pendingPromise.status = "rejected";
pendingPromise.reason = error$1;
}
if (indicators.aborted) {
return;
}
if (retryConfig?.enabled &&
shouldRetry(indicators.index, retryConfig, error$1)) {
let backoff = getRetryBackoff(indicators.index, retryConfig, error$1);
indicators.index += 1;
let id = setTimeout(() => {
run(producer, props, indicators, onSettled, retryConfig, callbacks);
}, backoff);
props.onAbort(() => {
clearTimeout(id);
});
return;
}
indicators.done = true;
onSettled(error$1, error, cloneProducerProps(props), callbacks);
}
}
function shouldRetry(attempt, retryConfig, error) {
let { retry, maxAttempts } = retryConfig;
let canRetry = !!maxAttempts && attempt <= maxAttempts;
let shouldRetry = retry === undefined ? true : !!retry;
if (isFunction(retry)) {
shouldRetry = retry(attempt, error);
}
return canRetry && shouldRetry;
}
function getRetryBackoff(attempt, retryConfig, error) {
let { backoff } = retryConfig;
if (isFunction(backoff)) {
return backoff(attempt, error);
}
return backoff || 0;
}
export { run };
//# sourceMappingURL=wrapper.js.map