@appzung/react-native-code-push
Version:
React Native plugin for the CodePush service
55 lines (54 loc) • 1.65 kB
JavaScript
export async function fetchRetry(url, options = {}, attempt = 0) {
const {
maxRetries = 3,
initialBackoff = 1000,
backoffMultiplier = 2,
maxRetryDelay = 30000,
...fetchOptions
} = options;
try {
const response = await fetch(url, fetchOptions);
if (response.ok || !(response.status === 429 || response.status >= 500)) {
return response;
}
if (attempt >= maxRetries) {
return response;
}
const retryAfter = parseRetryAfterHeader(response);
if (retryAfter && retryAfter > maxRetryDelay) {
return response;
}
const delay = retryAfter ?? addJitter(initialBackoff * Math.pow(backoffMultiplier, attempt));
await new Promise(resolve => setTimeout(resolve, delay));
return fetchRetry(url, options, attempt + 1);
} catch (error) {
if (attempt >= maxRetries) {
throw error;
}
const delay = addJitter(initialBackoff * Math.pow(backoffMultiplier, attempt));
await new Promise(resolve => setTimeout(resolve, delay));
return fetchRetry(url, options, attempt + 1);
}
}
function parseRetryAfterHeader(response) {
const retryAfter = response.headers.get('Retry-After');
if (!retryAfter) {
return null;
}
if (!isNaN(Number(retryAfter))) {
return parseInt(retryAfter, 10) * 1000;
}
try {
const retryDate = new Date(retryAfter).getTime();
const now = Date.now();
return retryDate > now ? retryDate - now : 0;
} catch (e) {
return null;
}
}
function addJitter(delay) {
const jitterFactor = 0.5 + Math.random() * 0.5;
return Math.floor(delay * jitterFactor);
}
//# sourceMappingURL=fetchRetry.js.map
;