UNPKG

axios-retryer

Version:

TypeScript-first Axios retry library with concurrency limits, request priority, token refresh, response caching, and circuit breaker plugins.

2 lines (1 loc) 7.54 kB
"use strict";const e=new Set(["retryAttempt","requestRetries","requestMode","requestId","correlationId","isRetrying","priority","timestamp","backoffType","retryableStatuses","extra","isRetryRefreshRequest","manualReplayAttempt","retryAfterMs","silentlyCancelled","cachingOptions"]);function t(t){return e.has(t)&&"__proto__"!==t&&"constructor"!==t&&"prototype"!==t}function r(e){const r={};if(Object.defineProperty(r,"toJSON",{value:()=>{},enumerable:!1,writable:!1,configurable:!1}),e)for(const s of Object.keys(e))t(s)&&(r[s]=e[s]);return r}function s(e){const t=e;return t.__axiosRetryer?"function"!=typeof t.__axiosRetryer.toJSON&&(t.__axiosRetryer=r(t.__axiosRetryer)):t.__axiosRetryer=r(),t.__axiosRetryer}function o(e){if(e)return e.__axiosRetryer}function n(e,t,r){const o=s(e);return void 0===r?delete o[t]:o[t]=r,o}class i{constructor(e=200,t){this.maxStoreSize=e,this.emit=t,this.requests=[]}add(e){if(s(e),this.requests.push(e),this.requests.length>this.maxStoreSize){const e=this.requests.shift();e&&this.emit("onRequestRemovedFromStore",e)}}remove(e){var t;const r=null===(t=o(e))||void 0===t?void 0:t.requestId;this.requests=this.requests.filter(e=>{var t;return(null===(t=o(e))||void 0===t?void 0:t.requestId)!==r})}getAll(){return this.requests.slice()}clear(){this.requests=[]}}const a={maxRequestsToStore:200,manualRetryMaxAge:3e5,storeNonIdempotent:!1,storeAuthRequests:!1};function u(e,t=new WeakMap){if(null===e||"object"!=typeof e)return e;if(e instanceof Date)return new Date(e.getTime());if("undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams)return new URLSearchParams(e.toString());if("undefined"!=typeof ArrayBuffer){if(e instanceof ArrayBuffer)return e.slice(0);if(ArrayBuffer.isView(e))return function(e){const t="undefined"!=typeof globalThis?globalThis.Buffer:void 0;return(null==t?void 0:t.isBuffer(e))?t.from(e):e instanceof DataView?new DataView(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength)):"function"==typeof e.slice?e.slice():new Uint8Array(e.buffer.slice(e.byteOffset,e.byteOffset+e.byteLength))}(e)}if("undefined"!=typeof Blob&&e instanceof Blob)return e.slice(0,e.size,e.type);const r=t.get(e);if(void 0!==r)return r;if(Array.isArray(e)){const r=[];return t.set(e,r),e.forEach((e,s)=>{r[s]=u(e,t)}),r}if(e instanceof Map){const r=new Map;return t.set(e,r),e.forEach((e,s)=>{r.set(u(s,t),u(e,t))}),r}if(e instanceof Set){const r=new Set;return t.set(e,r),e.forEach(e=>{r.add(u(e,t))}),r}let s=e;if(function(e){return"object"==typeof e&&null!==e&&"function"==typeof e.toJSON}(e))try{s=e.toJSON()}catch{}if(s!==e)return u(s,t);const o=Object.getPrototypeOf(e),n=Object.create(null===o?null:o);return t.set(e,n),Reflect.ownKeys(e).forEach(r=>{const s=Object.getOwnPropertyDescriptor(e,r);(null==s?void 0:s.enumerable)&&(n[r]=u(e[r],t))}),n}function l(e){if("function"==typeof structuredClone)try{return structuredClone(e)}catch(e){}return u(e)}const c=new Set(["get","head","options"]),d=["authorization","proxy-authorization","cookie","set-cookie","x-auth-token","x-api-key","api-key","apikey","token","refresh-token","x-refresh-token","x-csrf-token","x-xsrf-token"],f=new Set(d);class h{constructor(e={}){this.name="ManualRetryPlugin",this.version="1.0.0";const t=function(e={}){return{...a,...e}}(e);this.maxRequestsToStore=t.maxRequestsToStore,this.maxAge=t.manualRetryMaxAge,this.storeNonIdempotent=t.storeNonIdempotent,this.storeAuthRequests=t.storeAuthRequests,this.beforeRetryCallback=t.beforeRetry,this.prepareRequestForStoreCallback=t.prepareRequestForStore,this.rehydrateAuthCallback=t.rehydrateAuth,this.customStore=t.requestStore}initialize(e){var t;this.context=e,this.store=null!==(t=this.customStore)&&void 0!==t?t:new i(this.maxRequestsToStore,e.triggerAndEmit),this.onFailureHandler=e=>{const t=this.prepareStoredRequest(e);t&&this.store.add(t)},e.on("onFailure",this.onFailureHandler)}onBeforeDestroyed(e){var t;e.off("onFailure",this.onFailureHandler),null===(t=this.store)||void 0===t||t.clear()}async retryFailedRequests(){var e,t,r,s,i;const a=this.store.getAll();this.store.clear();const u=Date.now(),l=a.filter(e=>{var t,r,s;const n=u-((null===(t=o(e))||void 0===t?void 0:t.timestamp)||0);return!(n>this.maxAge&&(null===(r=this.context.getLogger())||void 0===r||r.debug("[ManualRetryPlugin] Discarding expired stored request",{requestId:null===(s=o(e))||void 0===s?void 0:s.requestId,ageMs:n,maxAgeMs:this.maxAge}),1))});if(0===l.length)return[];null===(e=this.context.getLogger())||void 0===e||e.debug("[ManualRetryPlugin] Starting manual retry process",{count:l.length,discarded:a.length-l.length}),this.context.triggerAndEmit("onManualRetryProcessStarted");const c=[];for(let e=0;e<l.length;e++){const a=l[e],u=this.beforeRetryCallback?this.beforeRetryCallback(a):a;if(!u){null===(t=this.context.getLogger())||void 0===t||t.debug("[ManualRetryPlugin] Request skipped by beforeRetry callback",{requestId:null===(r=o(a))||void 0===r?void 0:r.requestId});continue}if(this.rehydrateAuthCallback){if(!this.rehydrateAuthCallback(u)){null===(s=this.context.getLogger())||void 0===s||s.debug("[ManualRetryPlugin] Request skipped by rehydrateAuth callback",{requestId:null===(i=o(a))||void 0===i?void 0:i.requestId});continue}}else this.neutralizeDefaultAuthHeaders(u);delete u.signal,n(u,"retryAttempt",0),n(u,"isRetrying",!1),n(u,"manualReplayAttempt",!0),e>0&&await new Promise(t=>setTimeout(t,Math.min(200*e,2e3)));const d=await this.context.axiosInstance.request(u);c.push(d)}return c}getStoredRequests(){return this.store.getAll()}clearStoredRequests(){this.store.clear()}isEligible(e){return function(e,t){if(t)return!0;const r=(e.method||"get").toLowerCase();return!!c.has(r)||function(e){var t;const r="Idempotency-Key".toLowerCase();return Object.keys(null!==(t=e.headers)&&void 0!==t?t:{}).some(e=>e.toLowerCase()===r)}(e)}(e,this.storeNonIdempotent)}prepareStoredRequest(e){var t,r,s,n,i,a,u;if(null===(t=o(e))||void 0===t?void 0:t.manualReplayAttempt)return null===(r=this.context.getLogger())||void 0===r||r.debug("[ManualRetryPlugin] Skipping replay failure to avoid re-storing it",{requestId:null===(s=o(e))||void 0===s?void 0:s.requestId}),null;if(!this.isEligible(e))return null;if(function(e){var t;return!!e.auth||Object.keys(null!==(t=e.headers)&&void 0!==t?t:{}).some(e=>f.has(e.toLowerCase()))}(e)&&!this.storeAuthRequests)return null===(n=this.context.getLogger())||void 0===n||n.debug("[ManualRetryPlugin] Skipping storage for auth-bearing request",{requestId:null===(i=o(e))||void 0===i?void 0:i.requestId}),null;const c=function(e){const t={...e,data:l(e.data),headers:e.headers?{...e.headers}:{},params:l(e.params)};return function(e){if(e.headers){for(const t of Object.keys(e.headers))f.has(t.toLowerCase())&&delete e.headers[t];delete e.auth}}(t),t}(e);if(!this.prepareRequestForStoreCallback)return c;const d=this.prepareRequestForStoreCallback(c);return d||null===(a=this.context.getLogger())||void 0===a||a.debug("[ManualRetryPlugin] Request skipped by prepareRequestForStore",{requestId:null===(u=o(e))||void 0===u?void 0:u.requestId}),d}neutralizeDefaultAuthHeaders(e){const t=this.context.axiosInstance.defaults;!function(e,t,r){var s;const o=null!==(s=null==t?void 0:t.common)&&void 0!==s?s:{};e.headers=e.headers||{};for(const r of d){const s=r.toLowerCase(),n=Object.keys(o).some(e=>e.toLowerCase()===s),i=!!t&&Object.keys(t).some(e=>e.toLowerCase()===s);(n||i)&&(e.headers[r]=void 0)}r&&(e.auth=void 0)}(e,t.headers,Boolean(t.auth))}}exports.ManualRetryPlugin=h,exports.createManualRetryPlugin=function(e){return new h(e)};