@clerk/shared
Version:
Internal package utils used by the Clerk SDKs
58 lines (57 loc) • 1.67 kB
JavaScript
//#region src/retry.ts
const defaultOptions = {
initialDelay: 125,
maxDelayBetweenRetries: 0,
factor: 2,
shouldRetry: (_, iteration) => iteration < 5,
retryImmediately: false,
jitter: true
};
const RETRY_IMMEDIATELY_DELAY = 100;
const sleep = async (ms) => new Promise((s) => setTimeout(s, ms));
const applyJitter = (delay, jitter) => {
return jitter ? delay * (1 + Math.random()) : delay;
};
const createExponentialDelayAsyncFn = (opts) => {
let timesCalled = 0;
const calculateDelayInMs = () => {
const constant = opts.initialDelay;
const base = opts.factor;
let delay = constant * Math.pow(base, timesCalled);
delay = applyJitter(delay, opts.jitter);
return Math.min(opts.maxDelayBetweenRetries || delay, delay);
};
return async () => {
await sleep(calculateDelayInMs());
timesCalled++;
};
};
/**
* Retries a callback until it succeeds or the shouldRetry function returns false.
* See {@link RetryOptions} for the available options.
*/
const retry = async (callback, options = {}) => {
let iterations = 0;
const { shouldRetry, initialDelay, maxDelayBetweenRetries, factor, retryImmediately, jitter, onBeforeRetry } = {
...defaultOptions,
...options
};
const delay = createExponentialDelayAsyncFn({
initialDelay,
maxDelayBetweenRetries,
factor,
jitter
});
while (true) try {
return await callback();
} catch (e) {
iterations++;
if (!shouldRetry(e, iterations)) throw e;
if (onBeforeRetry) await onBeforeRetry(iterations);
if (retryImmediately && iterations === 1) await sleep(applyJitter(RETRY_IMMEDIATELY_DELAY, jitter));
else await delay();
}
};
//#endregion
export { retry };
//# sourceMappingURL=retry.mjs.map