@pinia/colada-plugin-retry
Version:
Retry failed requests with Pinia Colada
89 lines • 2.87 kB
JavaScript
// src/index.ts
var RETRY_OPTIONS_DEFAULTS = {
delay: (attempt) => {
const time = Math.min(
2 ** attempt * 1e3,
// never more than 30 seconds
3e4
);
console.log(`\u23F2\uFE0F delaying attempt #${attempt + 1} by ${time}ms`);
return time;
},
retry: (count) => {
console.log(`\u{1F504} Retrying ${"\u{1F7E8}".repeat(count + 1)}${"\u2B1C\uFE0F".repeat(2 - count)}`);
return count < 2;
}
};
function PiniaColadaRetry(globalOptions) {
const defaults = { ...RETRY_OPTIONS_DEFAULTS, ...globalOptions };
return ({ queryCache }) => {
const retryMap = /* @__PURE__ */ new Map();
let isInternalCall = false;
queryCache.$onAction(({ name, args, after, onError }) => {
if (name === "remove") {
const [cacheEntry] = args;
const key2 = cacheEntry.key.join("/");
const entry = retryMap.get(key2);
if (entry) {
clearTimeout(entry.timeoutId);
retryMap.delete(key2);
}
}
if (name !== "fetch") return;
const [queryEntry] = args;
const localOptions = queryEntry.options?.retry;
const options = {
...typeof localOptions === "object" ? localOptions : {
retry: localOptions
}
};
const retry = options.retry ?? defaults.retry;
const delay = options.delay ?? defaults.delay;
if (retry === 0) return;
const key = queryEntry.key.join("/");
clearTimeout(retryMap.get(key)?.timeoutId);
if (!isInternalCall) {
retryMap.delete(key);
}
const retryFetch = () => {
if (queryEntry.state.value.status === "error") {
const error = queryEntry.state.value.error;
let entry = retryMap.get(key);
if (!entry) {
entry = { retryCount: 0 };
retryMap.set(key, entry);
}
const shouldRetry = typeof retry === "number" ? retry > entry.retryCount : retry(entry.retryCount, error);
if (shouldRetry) {
const delayTime = typeof delay === "function" ? delay(entry.retryCount) : delay;
entry.timeoutId = setTimeout(() => {
if (!queryEntry.active) {
retryMap.delete(key);
return;
}
isInternalCall = true;
Promise.resolve(queryCache.fetch(queryEntry)).catch(
process.env.NODE_ENV !== "test" ? console.error : () => {
}
);
isInternalCall = false;
if (entry) {
entry.retryCount++;
}
}, delayTime);
} else {
retryMap.delete(key);
}
} else {
retryMap.delete(key);
}
};
onError(retryFetch);
after(retryFetch);
});
};
}
export {
PiniaColadaRetry
};
//# sourceMappingURL=index.js.map