diff --git a/dist/browser/index.global.js b/dist/browser/index.global.js index 46d7b80..10c75a5 100644 --- a/dist/browser/index.global.js +++ b/dist/browser/index.global.js @@ -1,3 +1,3 @@ -var fetchff=(function(exports){'use strict';var z="application/",te=z+"json",et="charset=utf-8",_="Content-Type",D="undefined",Ie="object",x="string",b="function",k="AbortError",tt="TimeoutError",O="GET",re="HEAD",pe="reject",ye=2147483647;var st=10,S=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);function J(e){return e instanceof URLSearchParams}function g(e){return e!==null&&typeof e===Ie}function B(e){let t=S(e,"__proto__"),r=S(e,"constructor"),s=S(e,"prototype");if(!t&&!r&&!s)return e;let n={};for(let a of Object.keys(e))a!=="__proto__"&&a!=="constructor"&&a!=="prototype"&&(n[a]=e[a]);return n}function at(e){let t=Object.create(null);return Object.keys(e).sort().forEach(r=>t[r]=e[r]),t}function rt(e,t){return t?e+(e.includes("?")?"&":"?")+t:e}function nt(e,t){if(!t)return e;if(J(t)){let u=t.toString();return rt(e,u)}let r=[],s=encodeURIComponent,n=(u,c)=>{c=typeof c===b?c():c,c=c==null?"":c,r[r.length]=s(u)+"="+s(c);},a=(u,c,f=0)=>{if(f>=st)return r;let l,p,m;if(u)if(Array.isArray(c))for(l=0,p=c.length;l{let o=n||a;if(S(r,o)){let i=r[o];if(i!=null){let u=encodeURIComponent(String(i));if(u==="."||u==="..")throw new Error('Path params "." and ".." not allowed.');return u}}return s})}function it(e){return /^[a-z][a-z\d+\-.]*:\/\//i.test(e)}var h=()=>Date.now(),C=()=>{};function se(e){let t=typeof e;return e==null?false:t===x||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==D&&typeof globalThis.Buffer!==D&&globalThis.Buffer.isBuffer(e)||e instanceof Date||J(e)?false:!!(g(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===b))}var ae=(e,t)=>new Promise(r=>{let s=()=>{clearTimeout(n),t&&t.removeEventListener("abort",s),r(true);},n=setTimeout(s,Math.min(e,ye));t&&(t.aborted?s():t.addEventListener("abort",s));});function ve(e,t=0){return t>=st?e:e&&g(e)&&typeof e.data!==D?ve(e.data,t+1):e}function E(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,s)=>{t[s.toLowerCase()]=r;});else for(let r in e)S(e,r)&&r!=="__proto__"&&(t[r.toLowerCase()]=e[r]);return t}function ut(){return typeof window!==D&&typeof window.addEventListener===b}function W(e,t){if(typeof DOMException!==D)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Se=()=>{let e=typeof navigator!==D&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)},ct=()=>typeof document!==D&&document.visibilityState==="hidden",lt=()=>typeof navigator!==D&&navigator.onLine===false;async function F(e,t,...r){if(!e)return;let s=n=>n&&g(t)&&g(n)&&Object.assign(t,B(n));if(typeof e===b)s(await e(t,...r));else if(Array.isArray(e))for(let n of e)s(await n(t,...r));}var Re=class extends Error{constructor(t,r,s){super(t),this.request=r,this.response=s,this.status=s?s.status:0,this.statusText=s?s.statusText:"",this.config=r,this.isCancelled=false,this.name="FetchError";}};var he=class extends Re{constructor(t,r,s){super(t,r,s),this.name="ResponseError";}};var be=600,Pe=1e3,Qe=Array(be).fill(0).map(()=>[]),U=new Map,ge=0,Fe=0,A=null,ft=([e,t])=>{U.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(C);}catch(r){}},M=(e,t,r)=>{Y(e);let s=r/Pe+(A&&h()!==Fe?1:0);if(r=be||r%Pe!==0){U.set(e,[setTimeout(ft.bind(null,[e,t]),Math.min(r,ye))]);return}let n=(ge+s)%be;Qe[n].push([e,t]),U.set(e,n),A||(Fe=h(),A=setInterval(()=>{ge=(ge+1)%be,Fe=h();let a=Qe[ge];for(let o=0;o{let t=U.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Qe[t];for(let s=0;s{mt(e,W(t+" aborted due to timeout",tt));},r),c}async function mt(e,t=null){if(e){let r=G.get(e);r&&(t&&r[0].abort(t),De(e));}}function De(e){Y(e),G.delete(e);}function pt(e,t){let r=G.get(e);r&&(r[4]=t);}function He(e,t){if(!e)return null;let r=G.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!a[s]||r&&n-a[1]{r[t]&&Kt(s);});}function Ne(e){if(V.has(e))return;let t=Rt.bind(null,e,true,e==="focus"),r=yt.get(e);if(r){let s=r(t);V.set(e,s);return}ut()&&(window.addEventListener(e,t),V.set(e,()=>window.removeEventListener(e,t)));}function ht(e){let t=V.get(e);t&&(t(),V.delete(e));}function Pt(e,t,r,s,n,a,o,i){let u=Z.get(e)||[];u[0]=t,u[1]=h(),u[2]=Mt,u[3]=s,u[4]=n,u[5]=a,u[6]=o,u[7]=i,Z.set(e,u),a&&Ne("focus"),o&&Ne("online"),s&&M("s:"+e,Ee.bind(null,e,true),s*1e3);}function Kt(e){Z.delete(e),Y("s:"+e);}var ne=new Map;function zt(e,t){let r=ne.get(e);r||ne.set(e,r=new Set),r.add(t);}function kt(e,t){let r=ne.get(e);r&&(r.delete(t),r.size===0&&ne.delete(e));}function L(e,t){let r=ne.get(e);if(r)if(r.size===1){let s=r.values().next().value;s(t);}else r.forEach(s=>s(t));}function Jt(e,t){return e?(zt(e,t),()=>{kt(e,t);}):C}var Te=(Se()?60:30)*1e3,j={strategy:pe,timeout:Te,loadingTimeout:Te/10,focusThrottleInterval:5e3,headers:{Accept:te+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:Te/30,maxDelay:Te,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504],methods:[O,re,"PUT","DELETE","OPTIONS","TRACE"]}};function Wt(e){let t=B(e);return $({retry:j.retry,headers:j.headers},t,j)}function Yt(){return {...j}}function _e(e,t){let r=$(j,t?B(t):{});return Gt(e,r)}function Gt(e,t){var f;let r=t.method;r=r?r.toUpperCase():O;let s;r!==O&&r!==re&&(s=(f=t.body)!=null?f:t.data,s&&typeof s!==x&&se(s)&&(s=JSON.stringify(s))),Xt(t.headers,s);let n=t.withCredentials?"include":t.credentials,a=ot(e,t.urlPathParams),o=nt(a,t.params),u=it(e)?"":t.baseURL||t.apiUrl||"",c=u&&o&&!u.endsWith("/")&&!/^[/?#]/.test(o)?"/":"";return t.url=u+c+o,t.method=r,t.credentials=n,t.body=s,t}function Xt(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==D&&t instanceof Blob||typeof ReadableStream!==D&&t instanceof ReadableStream)return;let r;if(J(t))r=z+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=z+"octet-stream";else if(se(t))r=te+";"+et;else return;e instanceof Headers?e.has(_)||e.set(_,r):g(e)&&!Array.isArray(e)&&!E(e)[_.toLowerCase()]&&(e[_]=r);}var Vt=["onRequest","onResponse","onError","onLoadingSlow"];function $(e,t,r={}){Object.assign(r,e,t),gt("retry",e,t,r),gt("headers",e,t,r);for(let s of Vt)Zt(s,e,t,r);return r}function Zt(e,t,r,s){let n=t[e],a=r[e];n&&a?s[e]=e==="onResponse"?[].concat(a,n):[].concat(n,a):(n||a)&&(s[e]=n||a);}function gt(e,t,r,s){let n=t[e],a=r[e];if(a)if(e==="headers"){let o=n instanceof Headers||a instanceof Headers,i=o?E(n):{...n},u=o?E(a):B(a);for(let c of Object.keys(u)){let f=c.toLowerCase();for(let l in i)l.toLowerCase()===f&&delete i[l];i[c]=u[c];}s[e]=i;}else s[e]={...n,...B(a)};else a===void 0&&g(n)&&!(n instanceof Headers)&&(s[e]={...n});}var Q=new Map,ie=new Map,oe="|",Ue=64,$t=/[^\w\-_|/:@.?=&~%#]/g,er=/[^\w\-_|/:@.?=&~%#]/,tr=/^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;function ue(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===x?r:r(e);let{url:s="",method:n=O,headers:a=null,body:o=null,credentials:i="same-origin"}=e,u="";if(a){let l;a instanceof Headers?l=E(a):l=a;let p=Object.keys(l),m=p.length;m>1&&p.sort();let q="";for(let T=0;T{f+=p+"="+(typeof l===x?l:"F"+Dt(l))+"&";}),f.length>Ue&&(f=X(f));else if(g(o)&&!se(o))f="B"+Dt(o);else {let l=g(o)?JSON.stringify(at(o)):String(o);f=l.length>Ue?X(l):l;}return Et(c+oe+f)}var bt=new WeakMap,rr=0;function Dt(e){let t=bt.get(e);return t||bt.set(e,t=++rr),t}function Et(e){return er.test(e)?e.replace($t,"")+oe+X(e):e}function Me(e){return e.expiry?h()>e.expiry:false}function Le(e){if(!e)return null;let t=Q.get(e);return t?t.data:null}function ce(e){return Q.get(e)}function we(e,t,r,s){if(r===0){le(e);return}let n=h(),a=r?r*1e3:0,o=s?s*1e3:0;Q.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+a}),a>0&&Tt(e,a);}function Tt(e,t){M("c:"+e,()=>le(e,true),t);}function le(e,t=false){if(t){let s=ce(e);if(!s||!Me(s))return}Q.delete(e);let r=ie.get(e);r&&(ie.delete(e),je(()=>r.delete(e)));}function je(e){try{Promise.resolve(e()).catch(C);}catch(t){}}function wt(e,t){let r=Q.get(e);if(t&&r){let{data:s,status:n,statusText:a,headers:o}=r.data;ie.set(e,t),je(()=>t.set(e,{...r,data:{data:s,status:n,statusText:a,headers:o}}));}}async function xt(e,t){let r=t.cacheStore;if(!r||xe(t))return null;let s;try{s=await r.get(e);}catch(n){return null}return !s||Q.has(e)?null:Me(s)?(je(()=>r.delete(e)),null):s}function Ct(e,t,r){return Q.set(e,t),ie.set(e,r),t.expiry&&Tt(e,t.expiry-h()),L(e,t.data),!t.stale||h(){let s=t.defaultResponse,n=t.cacheKey,a=Ke.bind(null,n);if(!e)return {ok:false,error:r,data:s!=null?s:null,headers:null,config:t,mutate:a,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===b&&e instanceof Response,i=e.data;s!==void 0&&(i==null||/^\[object (Object|Array)\]$/.test(Object.prototype.toString.call(i))&&Object.keys(i).length===0)&&(e.data=i=s),t.flattenResponse&&(e.data=i=ve(i)),t.select&&(e.data=i=t.select(i));let u=E(e.headers);if(o){let c={body:e.body,bodyUsed:e.bodyUsed,ok:e.ok,redirected:e.redirected,type:e.type,url:e.url,status:e.status,statusText:e.statusText,blob:async()=>i instanceof ArrayBuffer?new Blob([i]):new Blob,json:async()=>i,text:async()=>i,clone:()=>({...c}),arrayBuffer:async()=>i instanceof ArrayBuffer?i:new ArrayBuffer(0),formData:async()=>i instanceof FormData?i:new FormData,bytes:async()=>new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),error:r,data:i,headers:u,config:t,mutate:a,isFetching:false,isSuccess:e.ok&&!r,isError:!!r};return c}return g(e)&&Object.assign(e,{error:r,headers:u,isFetching:false,mutate:a,isSuccess:e.ok&&!r,isError:!!r}),e};function Ot(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function sr(e){if(!e)return null;let t=e.headers||{},r=t["retry-after"];if(r){let o=Number(r);if(!isNaN(o)&&o>=0)return o*1e3;let i=Ot(r);if(i!==null)return i}let s="ratelimit-reset",n=t[s+"-after"]||t["x-"+s+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let a=t[s+"-at"]||t["x-"+s+"-at"];return a?Ot(a):null}async function Bt(e,t){let{retries:r=0,delay:s=0,backoff:n=1,maxDelay:a,retryOn:o=[],shouldRetry:i,jitter:u,methods:c}=t,f=0,l=s,p=r>0?r:0,m;for(;f<=p;){if(f>0&&m){let d=m.config,H=d.onRetry;H&&(await F(H,m,f),d._isAutoKey&&(d._prevKey=d.cacheKey,d.cacheKey=ue(d,false)));}m=await e(f>0,f);let q=m.error;if(q?await ar(m,f,p,i,o,c):!(i&&fc.toUpperCase()===e.config.method)))}function nr(e,t){return typeof t===b?t(e):t?Math.random()*e:e}async function At(e,t,r,s=0,n=0,a=false,o=false,i){if(!t)return e();let u=0,c;for(;(s===0||u0&&await ae(n,i),c=await e(),u++,!(s>0&&u>=s||!t||r&&r(c,u)));)do if(await ae(t,i),i&&i.aborted)return c;while(!a&&ct()||!o&<());return c}var or=[204,205,304],ir=/^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/,It=e=>typeof ReadableStream!==D&&e instanceof ReadableStream,qe=(e,t)=>({loaded:e,total:t,progress:t?e/t:void 0});function vt(e,t){let r=t.body;return typeof XMLHttpRequest!==D&&!It(r)?ur(e,t,r):cr(e,t,r)}function ur(e,t,r){return new Promise((s,n)=>{let a=new XMLHttpRequest,o=t.signal,i=()=>a.abort(),u=f=>{o.removeEventListener("abort",i);try{f();}catch(l){n(l);}};a.open(t.method,e),a.responseType="blob",a.withCredentials=t.credentials==="include",new Headers(t.headers).forEach((f,l)=>ir.test(l)||a.setRequestHeader(l,f)),a.upload.onprogress=f=>t.onUploadProgress(qe(f.loaded,f.lengthComputable?f.total:void 0)),a.onload=()=>u(()=>{let f=new Headers;for(let p of a.getAllResponseHeaders().split(/\r?\n/)){let m=p.indexOf(":");m>0&&f.append(p.slice(0,m),p.slice(m+1).trim());}let l=new Response(or.includes(a.status)?null:a.response,{status:a.status,statusText:a.statusText,headers:f});Object.defineProperty(l,"url",{value:a.responseURL}),s(l);}),a.onerror=()=>u(()=>n(new TypeError("Network request failed")));let c=()=>u(()=>n(o.reason||W("The request was aborted",k)));if(a.onabort=c,o.aborted)return c();o.addEventListener("abort",i),a.send(r);})}async function cr(e,t,r){let s=new Headers(t.headers),n=r,a;if(!It(r)){let i=r instanceof Blob?r:await new Response(r).blob();a=i.size,n=i.stream(),i.type&&!s.has("content-type")&&s.set("content-type",i.type);}let o=0;return fetch(e,{...t,headers:s,body:n.pipeThrough(new TransformStream({transform(i,u){o+=i.byteLength,t.onUploadProgress(qe(o,a)),u.enqueue(i);}})),duplex:"half"})}function St(e,t){if(!t||typeof Response!==b||!(e instanceof Response)||!e.body)return e;let r=e.headers,s=r.has("content-encoding")?void 0:Number(r.get("content-length"))||void 0,n=0,a=new Response(e.body.pipeThrough(new TransformStream({transform(o,i){n+=o.byteLength,t(qe(n,s&&Math.max(s,n))),i.enqueue(o);}})),e);for(let o of ["url","redirected","type"])Object.defineProperty(a,o,{value:e[o]});return a}async function Ft(e,t,r){var u;let s=await t(e),n=s.error;if(!n)return ze(s,r),s;r.onError&&await F(r.onError,n);let a=n.isCancelled,o=r.logger;if(!a&&o&&o.warn&&o.warn("FETCH ERROR",fr(n)),r.strategy==="defaultResponse"&&(s.data=(u=r.defaultResponse)!=null?u:null),ze(s,r,true),!a||r.rejectCancelled){let c=r.strategy;if(c===pe)throw n;c==="silent"&&await new Promise(()=>null);}return s}var lr=["authorization","proxy-authorization","cookie","x-api-key"];function fr(e){let t={...e.config,body:void 0,data:void 0,cacheKey:void 0,_prevKey:void 0,headers:E(e.config.headers)};for(let s of lr)t.headers[s]&&(t.headers[s]="[REDACTED]");let r=Object.assign(new Error(e.message),e,{config:t,request:t,response:e.response&&{...e.response,config:t}});return r.name=e.name,r.stack=e.stack,r}function Qt(e,t,r){e.status=e.status||t&&t.status||0,e.statusText=e.statusText||t&&t.statusText||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===k;}var ke=Object.freeze({isFetching:true});async function Oe(e,t=null){var Ve;if(t&&typeof t.cacheKey=="string"){let R=fe(t.cacheKey,t.cacheTime,t);if(R)return R}let r=_e(e,t),{timeout:s,cancellable:n,cacheKey:a,dedupeTime:o,cacheTime:i,staleTime:u,refetchOnFocus:c,refetchOnReconnect:f,pollingInterval:l=0}=r,p=i!==void 0||u!==void 0,m=r.method,q=p&&(m===O||m===re)&&((Ve=r.etag)!=null?Ve:!r.fetcher),T=!!(a||s||o||p||n||c||f),d=null;T&&(d=ue(r));let H=null;if(d&&p){let R=fe(d,i,r);if(R)return R;if(r.cacheStore){let w=await xt(d,r),I=w&&Ht(w.data,d,r);if(I&&Ct(d,{...w,data:I},r.cacheStore))return I}r.initialData!==void 0&&!Le(d)&&!xe(r)&&(H=Ht({data:r.initialData,status:200,statusText:"",headers:{}},d,r));}if(d&&o){let R=He(d,o);if(R)return R}let Je=r.retry||{},{retries:Nt=0,resetTimeout:_t}=Je,N=r.signal,We=async(R,w=0)=>{let I=q&&Le(d);if(!w){if(H){let v=H;return H=null,v}d&&!R&&(u?fe(d,i,r)||(we(d,ke,i,u),L(d,ke)):L(d,ke)),r.cacheKey=d;}let ee=r.url,Ze=dt(d,ee,s,o||0,!!n,!!(s&&(!w||_t))),P=r;P.signal=Ze.signal;let Ae=()=>Ze.abort(N.reason);N&&(N.aborted?Ae():N.addEventListener("abort",Ae));let me,y=null;try{r.onRequest&&(d&&o&&!w&&await null,await F(r.onRequest,P));let v=r.fetcher,K=dr(P,I);if(y=v?await v(ee,K):await(P.onUploadProgress&&P.body?vt(ee,P):fetch(ee,K)),y=St(y,P.onDownloadProgress),g(y)){if(K!==P&&y.status===304)return I;if(typeof Response===b&&y instanceof Response?y.data=P.parser?await P.parser(y):await qt(y,P.responseType):v&&("data"in y&&"body"in y||(y={data:y})),y.config=P,y.ok!==void 0&&!y.ok)throw new he(P.method+" to "+ee+" failed! Status: "+(y.status||null),P,y)}me=Ce(y,P);let $e=r.onResponse;$e&&await F($e,me);}catch(v){let K=v;Qt(K,y,P),me=Ce(y,P,K);}finally{N&&N.removeEventListener("abort",Ae);}return me},Be=Nt>0?R=>Bt((w,I)=>We(R,I),Je):We,{onLoadingSlow:Ye,loadingTimeout:Ge}=r,Ut=Ye&&Ge?async R=>{if(R)return Be(R);let w=setTimeout(()=>F(Ye,r).catch(C),Ge);try{return await Be(R)}finally{clearTimeout(w);}}:Be,de=(R=false)=>Ft(R,Ut,r),Xe=l?At(de,l,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay,r.refreshWhenHidden,r.refreshWhenOffline,N):de();return d&&(o&&pt(d,Xe),(u||c||f)&&Pt(d,de,void 0,u,de,!!c,!!f,r.focusThrottleInterval)),Xe}function Ht(e,t,r){try{let s=typeof Response===b?new Response(null,e):{ok:!0,status:e.status,statusText:e.statusText,headers:e.headers};s.data=e.data,r.cacheKey=t;let n=Ce(s,{...r,select:void 0,flattenResponse:!1,defaultResponse:void 0});return n.config=r,n}catch(s){return null}}function dr(e,t){let r=t&&!t.error&&t.headers&&t.headers.etag,s=r&&E(e.headers);return s&&!s["if-none-match"]?{...e,headers:{...s,"if-none-match":r}}:e}function mr(e){let t=e.endpoints;async function r(n){return console.error("Add "+n+" to 'endpoints'."),null}let s={config:e,endpoints:t,async request(n,a={}){let o=S(t,n)?t[n]:void 0,i=o||{url:String(n)},u=i.url,c=u.replace(/[\t\n\r]/g,"").replace(/^[\x00-\x20]+/,"");if(/^[/\\]{2}/.test(c))throw new Error("Protocol-relative URLs not allowed.");let f=/^[a-z][a-z\d+\-.]*:/i.test(c)?o&&o.url===u?$(i,a):a:$($(e,i),a);return Oe(u,f)}};return new Proxy(s,{get(n,a){if(a in s)return s[a];if(!(typeof a=="symbol"||a==="then"))return S(t,a)?s.request.bind(null,a):r.bind(null,a)}})} +var fetchff=(function(exports){'use strict';var z="application/",te=z+"json",et="charset=utf-8",_="Content-Type",D="undefined",Ie="object",x="string",b="function",k="AbortError",tt="TimeoutError",O="GET",re="HEAD",pe="reject",ye=2147483647;var st=10,S=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);function J(e){return e instanceof URLSearchParams}function g(e){return e!==null&&typeof e===Ie}function B(e){let t=S(e,"__proto__"),r=S(e,"constructor"),s=S(e,"prototype");if(!t&&!r&&!s)return e;let n={};for(let a of Object.keys(e))a!=="__proto__"&&a!=="constructor"&&a!=="prototype"&&(n[a]=e[a]);return n}function at(e){let t=Object.create(null);return Object.keys(e).sort().forEach(r=>t[r]=e[r]),t}function rt(e,t){return t?e+(e.includes("?")?"&":"?")+t:e}function nt(e,t){if(!t)return e;if(J(t)){let u=t.toString();return rt(e,u)}let r=[],s=encodeURIComponent,n=(u,c)=>{c=typeof c===b?c():c,c=c==null?"":c,r[r.length]=s(u)+"="+s(c);},a=(u,c,f=0)=>{if(f>=st)return r;let l,p,m;if(u)if(Array.isArray(c))for(l=0,p=c.length;l{let o=n||a;if(S(r,o)){let i=r[o];if(i!=null){let u=encodeURIComponent(String(i));if(u==="."||u==="..")throw new Error('Path params "." and ".." not allowed.');return u}}return s})}function it(e){return /^[a-z][a-z\d+\-.]*:\/\//i.test(e)}var h=()=>Date.now(),C=()=>{};function se(e){let t=typeof e;return e==null?false:t===x||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==D&&typeof globalThis.Buffer!==D&&globalThis.Buffer.isBuffer(e)||e instanceof Date||J(e)?false:!!(g(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===b))}var ae=(e,t)=>new Promise(r=>{let s=()=>{clearTimeout(n),t&&t.removeEventListener("abort",s),r(true);},n=setTimeout(s,Math.min(e,ye));t&&(t.aborted?s():t.addEventListener("abort",s));});function ve(e,t=0){return t>=st?e:e&&g(e)&&typeof e.data!==D?ve(e.data,t+1):e}function E(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,s)=>{t[s.toLowerCase()]=r;});else for(let r in e)S(e,r)&&r!=="__proto__"&&(t[r.toLowerCase()]=e[r]);return t}function ut(){return typeof window!==D&&typeof window.addEventListener===b}function W(e,t){if(typeof DOMException!==D)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Se=()=>{let e=typeof navigator!==D&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)},ct=()=>typeof document!==D&&document.visibilityState==="hidden",lt=()=>typeof navigator!==D&&navigator.onLine===false;async function F(e,t,...r){if(!e)return;let s=n=>n&&g(t)&&g(n)&&Object.assign(t,B(n));if(typeof e===b)s(await e(t,...r));else if(Array.isArray(e))for(let n of e)s(await n(t,...r));}var Re=class extends Error{constructor(t,r,s){super(t),this.request=r,this.response=s,this.status=s?s.status:0,this.statusText=s?s.statusText:"",this.config=r,this.isCancelled=false,this.name="FetchError";}};var he=class extends Re{constructor(t,r,s){super(t,r,s),this.name="ResponseError";}};var be=600,Pe=1e3,Qe=Array(be).fill(0).map(()=>[]),U=new Map,ge=0,Fe=0,A=null,ft=([e,t])=>{U.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(C);}catch(r){}},M=(e,t,r)=>{Y(e);let s=r/Pe+(A&&h()!==Fe?1:0);if(r=be||r%Pe!==0){U.set(e,[setTimeout(ft.bind(null,[e,t]),Math.min(r,ye))]);return}let n=(ge+s)%be;Qe[n].push([e,t]),U.set(e,n),A||(Fe=h(),A=setInterval(()=>{ge=(ge+1)%be,Fe=h();let a=Qe[ge];for(let o=0;o{let t=U.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Qe[t];for(let s=0;s{mt(e,W(t+" aborted due to timeout",tt));},r),c}async function mt(e,t=null){if(e){let r=G.get(e);r&&(t&&r[0].abort(t),De(e));}}function De(e){Y(e),G.delete(e);}function pt(e,t){let r=G.get(e);r&&(r[4]=t);}function He(e,t){if(!e)return null;let r=G.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!a[s]||r&&n-a[1]{r[t]&&Kt(s);});}function Ne(e){if(V.has(e))return;let t=Rt.bind(null,e,true,e==="focus"),r=yt.get(e);if(r){let s=r(t);V.set(e,s);return}ut()&&(window.addEventListener(e,t),V.set(e,()=>window.removeEventListener(e,t)));}function ht(e){let t=V.get(e);t&&(t(),V.delete(e));}function Pt(e,t,r,s,n,a,o,i){let u=Z.get(e)||[];u[0]=t,u[1]=h(),u[2]=Mt,u[3]=s,u[4]=n,u[5]=a,u[6]=o,u[7]=i,Z.set(e,u),a&&Ne("focus"),o&&Ne("online"),s&&M("s:"+e,Ee.bind(null,e,true),s*1e3);}function Kt(e){Z.delete(e),Y("s:"+e);}var ne=new Map;function zt(e,t){let r=ne.get(e);r||ne.set(e,r=new Set),r.add(t);}function kt(e,t){let r=ne.get(e);r&&(r.delete(t),r.size===0&&ne.delete(e));}function L(e,t){let r=ne.get(e);if(r)if(r.size===1){let s=r.values().next().value;s(t);}else r.forEach(s=>s(t));}function Jt(e,t){return e?(zt(e,t),()=>{kt(e,t);}):C}var Te=(Se()?60:30)*1e3,j={strategy:pe,timeout:Te,loadingTimeout:Te/10,focusThrottleInterval:5e3,headers:{Accept:te+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:Te/30,maxDelay:Te,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504],methods:[O,re,"PUT","DELETE","OPTIONS","TRACE"]}};function Wt(e){let t=B(e);return $({retry:j.retry,headers:j.headers},t,j)}function Yt(){return {...j}}function _e(e,t){let r=$(j,t?B(t):{});return Gt(e,r)}function Gt(e,t){var f;let r=t.method;r=r?r.toUpperCase():O;let s;r!==O&&r!==re&&(s=(f=t.body)!=null?f:t.data,s&&typeof s!==x&&se(s)&&(s=JSON.stringify(s))),Xt(t.headers,s);let n=t.withCredentials?"include":t.credentials,a=ot(e,t.urlPathParams),o=nt(a,t.params),u=it(e)?"":t.baseURL||t.apiUrl||"",c=u&&o&&!u.endsWith("/")&&!/^[/?#]/.test(o)?"/":"";return t.url=u+c+o,t.method=r,t.credentials=n,t.body=s,t}function Xt(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==D&&t instanceof Blob||typeof ReadableStream!==D&&t instanceof ReadableStream)return;let r;if(J(t))r=z+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=z+"octet-stream";else if(se(t))r=te+";"+et;else return;e instanceof Headers?e.has(_)||e.set(_,r):g(e)&&!Array.isArray(e)&&!E(e)[_.toLowerCase()]&&(e[_]=r);}var Vt=["onRequest","onResponse","onError","onLoadingSlow"];function $(e,t,r={}){Object.assign(r,e,t),gt("retry",e,t,r),gt("headers",e,t,r);for(let s of Vt)Zt(s,e,t,r);return r}function Zt(e,t,r,s){let n=t[e],a=r[e];n&&a?s[e]=e==="onResponse"?[].concat(a,n):[].concat(n,a):(n||a)&&(s[e]=n||a);}function gt(e,t,r,s){let n=t[e],a=r[e];if(a)if(e==="headers"){let o=n instanceof Headers||a instanceof Headers,i=o?E(n):{...n},u=o?E(a):B(a);for(let c of Object.keys(u)){let f=c.toLowerCase();for(let l in i)l.toLowerCase()===f&&delete i[l];i[c]=u[c];}s[e]=i;}else s[e]={...n,...B(a)};else a===void 0&&g(n)&&!(n instanceof Headers)&&(s[e]={...n});}var Q=new Map,ie=new Map,oe="|",Ue=64,$t=/[^\w\-_|/:@.?=&~%#]/g,er=/[^\w\-_|/:@.?=&~%#]/,tr=/^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;function ue(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===x?r:r(e);let{url:s="",method:n=O,headers:a=null,body:o=null,credentials:i="same-origin"}=e,u="";if(a){let l;a instanceof Headers?l=E(a):l=a;let p=Object.keys(l),m=p.length;m>1&&p.sort();let q="";for(let T=0;T{f+=p+"="+(typeof l===x?l:"F"+Dt(l))+"&";}),f.length>Ue&&(f=X(f));else if(g(o)&&!se(o))f="B"+Dt(o);else {let l=g(o)?JSON.stringify(at(o)):String(o);f=l.length>Ue?X(l):l;}return Et(c+oe+f)}var bt=new WeakMap,rr=0;function Dt(e){let t=bt.get(e);return t||bt.set(e,t=++rr),t}function Et(e){return er.test(e)?e.replace($t,"")+oe+X(e):e}function Me(e){return e.expiry?h()>e.expiry:false}function Le(e){if(!e)return null;let t=Q.get(e);return t?t.data:null}function ce(e){return Q.get(e)}function we(e,t,r,s){if(r===0){le(e);return}let n=h(),a=r?r*1e3:0,o=s?s*1e3:0;Q.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+a}),a>0&&Tt(e,a);}function Tt(e,t){M("c:"+e,()=>le(e,true),t);}function le(e,t=false){if(t){let s=ce(e);if(!s||!Me(s))return}Q.delete(e);let r=ie.get(e);r&&(ie.delete(e),je(()=>r.delete(e)));}function je(e){try{Promise.resolve(e()).catch(C);}catch(t){}}function wt(e,t){let r=Q.get(e);if(t&&r){let{data:s,status:n,statusText:a,headers:o}=r.data;ie.set(e,t),je(()=>t.set(e,{...r,data:{data:s,status:n,statusText:a,headers:o}}));}}async function xt(e,t){let r=t.cacheStore;if(!r||xe(t))return null;let s;try{s=await r.get(e);}catch(n){return null}return !s||Q.has(e)?null:Me(s)?(je(()=>r.delete(e)),null):s}function Ct(e,t,r){return Q.set(e,t),ie.set(e,r),t.expiry&&Tt(e,t.expiry-h()),L(e,t.data),!t.stale||h(){let s=t.defaultResponse,n=t.cacheKey,a=Ke.bind(null,n);if(!e)return {ok:false,error:r,data:s!=null?s:null,headers:null,config:t,mutate:a,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===b&&e instanceof Response,i=e.data;s!==void 0&&(i==null||/^\[object (Object|Array)\]$/.test(Object.prototype.toString.call(i))&&Object.keys(i).length===0)&&(e.data=i=s),t.flattenResponse&&(e.data=i=ve(i)),t.select&&(e.data=i=t.select(i));let u=E(e.headers);if(o){let c={body:e.body,bodyUsed:e.bodyUsed,ok:e.ok,redirected:e.redirected,type:e.type,url:e.url,status:e.status,statusText:e.statusText,blob:async()=>i instanceof ArrayBuffer?new Blob([i]):new Blob,json:async()=>i,text:async()=>i,clone:()=>({...c}),arrayBuffer:async()=>i instanceof ArrayBuffer?i:new ArrayBuffer(0),formData:async()=>i instanceof FormData?i:new FormData,bytes:async()=>new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),error:r,data:i,headers:u,config:t,mutate:a,isFetching:false,isSuccess:e.ok&&!r,isError:!!r};return c}return g(e)&&(e.error=r,e.headers=u,e.isFetching=false,e.mutate=a,e.isSuccess=e.ok&&!r,e.isError=!!r),e};function Ot(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function sr(e){if(!e)return null;let t=e.headers||{},r=t["retry-after"];if(r){let o=Number(r);if(!isNaN(o)&&o>=0)return o*1e3;let i=Ot(r);if(i!==null)return i}let s="ratelimit-reset",n=t[s+"-after"]||t["x-"+s+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let a=t[s+"-at"]||t["x-"+s+"-at"];return a?Ot(a):null}async function Bt(e,t){let{retries:r=0,delay:s=0,backoff:n=1,maxDelay:a,retryOn:o=[],shouldRetry:i,jitter:u,methods:c}=t,f=0,l=s,p=r>0?r:0,m;for(;f<=p;){if(f>0&&m){let d=m.config,H=d.onRetry;H&&(await F(H,m,f),d._isAutoKey&&(d._prevKey=d.cacheKey,d.cacheKey=ue(d,false)));}m=await e(f>0,f);let q=m.error;if(q?await ar(m,f,p,i,o,c):!(i&&fc.toUpperCase()===e.config.method)))}function nr(e,t){return typeof t===b?t(e):t?Math.random()*e:e}async function At(e,t,r,s=0,n=0,a=false,o=false,i){if(!t)return e();let u=0,c;for(;(s===0||u0&&await ae(n,i),c=await e(),u++,!(s>0&&u>=s||!t||r&&r(c,u)));)do if(await ae(t,i),i&&i.aborted)return c;while(!a&&ct()||!o&<());return c}var or=[204,205,304],ir=/^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/,It=e=>typeof ReadableStream!==D&&e instanceof ReadableStream,qe=(e,t)=>({loaded:e,total:t,progress:t?e/t:void 0});function vt(e,t){let r=t.body;return typeof XMLHttpRequest!==D&&!It(r)?ur(e,t,r):cr(e,t,r)}function ur(e,t,r){return new Promise((s,n)=>{let a=new XMLHttpRequest,o=t.signal,i=()=>a.abort(),u=f=>{o.removeEventListener("abort",i);try{f();}catch(l){n(l);}};a.open(t.method,e),a.responseType="blob",a.withCredentials=t.credentials==="include",new Headers(t.headers).forEach((f,l)=>ir.test(l)||a.setRequestHeader(l,f)),a.upload.onprogress=f=>t.onUploadProgress(qe(f.loaded,f.lengthComputable?f.total:void 0)),a.onload=()=>u(()=>{let f=new Headers;for(let p of a.getAllResponseHeaders().split(/\r?\n/)){let m=p.indexOf(":");m>0&&f.append(p.slice(0,m),p.slice(m+1).trim());}let l=new Response(or.includes(a.status)?null:a.response,{status:a.status,statusText:a.statusText,headers:f});Object.defineProperty(l,"url",{value:a.responseURL}),s(l);}),a.onerror=()=>u(()=>n(new TypeError("Network request failed")));let c=()=>u(()=>n(o.reason||W("The request was aborted",k)));if(a.onabort=c,o.aborted)return c();o.addEventListener("abort",i),a.send(r);})}async function cr(e,t,r){let s=new Headers(t.headers),n=r,a;if(!It(r)){let i=r instanceof Blob?r:await new Response(r).blob();a=i.size,n=i.stream(),i.type&&!s.has("content-type")&&s.set("content-type",i.type);}let o=0;return fetch(e,{...t,headers:s,body:n.pipeThrough(new TransformStream({transform(i,u){o+=i.byteLength,t.onUploadProgress(qe(o,a)),u.enqueue(i);}})),duplex:"half"})}function St(e,t){if(!t||typeof Response!==b||!(e instanceof Response)||!e.body)return e;let r=e.headers,s=r.has("content-encoding")?void 0:Number(r.get("content-length"))||void 0,n=0,a=new Response(e.body.pipeThrough(new TransformStream({transform(o,i){n+=o.byteLength,t(qe(n,s&&Math.max(s,n))),i.enqueue(o);}})),e);for(let o of ["url","redirected","type"])Object.defineProperty(a,o,{value:e[o]});return a}async function Ft(e,t,r){var u;let s=await t(e),n=s.error;if(!n)return ze(s,r),s;r.onError&&await F(r.onError,n);let a=n.isCancelled,o=r.logger;if(!a&&o&&o.warn&&o.warn("FETCH ERROR",fr(n)),r.strategy==="defaultResponse"&&(s.data=(u=r.defaultResponse)!=null?u:null),ze(s,r,true),!a||r.rejectCancelled){let c=r.strategy;if(c===pe)throw n;c==="silent"&&await new Promise(()=>null);}return s}var lr=["authorization","proxy-authorization","cookie","x-api-key"];function fr(e){let t={...e.config,body:void 0,data:void 0,cacheKey:void 0,_prevKey:void 0,headers:E(e.config.headers)};for(let s of lr)t.headers[s]&&(t.headers[s]="[REDACTED]");let r=Object.assign(new Error(e.message),e,{config:t,request:t,response:e.response&&{...e.response,config:t}});return r.name=e.name,r.stack=e.stack,r}function Qt(e,t,r){e.status=e.status||t&&t.status||0,e.statusText=e.statusText||t&&t.statusText||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===k;}var ke=Object.freeze({isFetching:true});async function Oe(e,t=null){var Ve;if(t&&typeof t.cacheKey=="string"){let R=fe(t.cacheKey,t.cacheTime,t);if(R)return R}let r=_e(e,t),{timeout:s,cancellable:n,cacheKey:a,dedupeTime:o,cacheTime:i,staleTime:u,refetchOnFocus:c,refetchOnReconnect:f,pollingInterval:l=0}=r,p=i!==void 0||u!==void 0,m=r.method,q=p&&(m===O||m===re)&&((Ve=r.etag)!=null?Ve:!r.fetcher),T=!!(a||s||o||p||n||c||f),d=null;T&&(d=ue(r));let H=null;if(d&&p){let R=fe(d,i,r);if(R)return R;if(r.cacheStore){let w=await xt(d,r),I=w&&Ht(w.data,d,r);if(I&&Ct(d,{...w,data:I},r.cacheStore))return I}r.initialData!==void 0&&!Le(d)&&!xe(r)&&(H=Ht({data:r.initialData,status:200,statusText:"",headers:{}},d,r));}if(d&&o){let R=He(d,o);if(R)return R}let Je=r.retry||{},{retries:Nt=0,resetTimeout:_t}=Je,N=r.signal,We=async(R,w=0)=>{let I=q&&Le(d);if(!w){if(H){let v=H;return H=null,v}d&&!R&&(u?fe(d,i,r)||(we(d,ke,i,u),L(d,ke)):L(d,ke)),r.cacheKey=d;}let ee=r.url,Ze=dt(d,ee,s,o||0,!!n,!!(s&&(!w||_t))),P=r;P.signal=Ze.signal;let Ae=()=>Ze.abort(N.reason);N&&(N.aborted?Ae():N.addEventListener("abort",Ae));let me,y=null;try{r.onRequest&&(d&&o&&!w&&await null,await F(r.onRequest,P));let v=r.fetcher,K=dr(P,I);if(y=v?await v(ee,K):await(P.onUploadProgress&&P.body?vt(ee,P):fetch(ee,K)),y=St(y,P.onDownloadProgress),g(y)){if(K!==P&&y.status===304)return I;if(typeof Response===b&&y instanceof Response?y.data=P.parser?await P.parser(y):await qt(y,P.responseType):v&&("data"in y&&"body"in y||(y={data:y})),y.config=P,y.ok!==void 0&&!y.ok)throw new he(P.method+" to "+ee+" failed! Status: "+(y.status||null),P,y)}me=Ce(y,P);let $e=r.onResponse;$e&&await F($e,me);}catch(v){let K=v;Qt(K,y,P),me=Ce(y,P,K);}finally{N&&N.removeEventListener("abort",Ae);}return me},Be=Nt>0?R=>Bt((w,I)=>We(R,I),Je):We,{onLoadingSlow:Ye,loadingTimeout:Ge}=r,Ut=Ye&&Ge?async R=>{if(R)return Be(R);let w=setTimeout(()=>F(Ye,r).catch(C),Ge);try{return await Be(R)}finally{clearTimeout(w);}}:Be,de=(R=false)=>Ft(R,Ut,r),Xe=l?At(de,l,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay,r.refreshWhenHidden,r.refreshWhenOffline,N):de();return d&&(o&&pt(d,Xe),(u||c||f)&&Pt(d,de,void 0,u,de,!!c,!!f,r.focusThrottleInterval)),Xe}function Ht(e,t,r){try{let s=typeof Response===b?new Response(null,e):{ok:!0,status:e.status,statusText:e.statusText,headers:e.headers};s.data=e.data,r.cacheKey=t;let n=Ce(s,{...r,select:void 0,flattenResponse:!1,defaultResponse:void 0});return n.config=r,n}catch(s){return null}}function dr(e,t){let r=t&&!t.error&&t.headers&&t.headers.etag,s=r&&E(e.headers);return s&&!s["if-none-match"]?{...e,headers:{...s,"if-none-match":r}}:e}function mr(e){let t=e.endpoints;async function r(n){return console.error("Add "+n+" to 'endpoints'."),null}let s={config:e,endpoints:t,async request(n,a={}){let o=S(t,n)?t[n]:void 0,i=o||{url:String(n)},u=i.url,c=u.replace(/[\t\n\r]/g,"").replace(/^[\x00-\x20]+/,"");if(/^[/\\]{2}/.test(c))throw new Error("Protocol-relative URLs not allowed.");let f=/^[a-z][a-z\d+\-.]*:/i.test(c)?o&&o.url===u?$(i,a):a:$($(e,i),a);return Oe(u,f)}};return new Proxy(s,{get(n,a){if(a in s)return s[a];if(!(typeof a=="symbol"||a==="then"))return S(t,a)?s.request.bind(null,a):r.bind(null,a)}})} exports.abortRequest=mt;exports.addTimeout=M;exports.buildConfig=_e;exports.createAbortError=W;exports.createApiFetcher=mr;exports.deleteCache=le;exports.fetchf=Oe;exports.fetchff=Oe;exports.generateCacheKey=ue;exports.getCache=ce;exports.getCachedResponse=fe;exports.getDefaultConfig=Yt;exports.getInFlightPromise=He;exports.isSlowConnection=Se;exports.mutate=Ke;exports.removeRevalidators=jt;exports.revalidate=Ee;exports.revalidateAll=Rt;exports.setCache=we;exports.setDefaultConfig=Wt;exports.setEventProvider=Lt;exports.subscribe=Jt;return exports;})({});//# sourceMappingURL=index.global.js.map //# sourceMappingURL=index.global.js.map \ No newline at end of file diff --git a/dist/browser/index.global.js.map b/dist/browser/index.global.js.map index 2658fa7..8a34cdb 100644 --- a/dist/browser/index.global.js.map +++ b/dist/browser/index.global.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../src/constants.ts","../../src/utils.ts","../../src/interceptor-manager.ts","../../src/errors/fetch-error.ts","../../src/errors/response-error.ts","../../src/timeout-wheel.ts","../../src/inflight-manager.ts","../../src/hash.ts","../../src/revalidator-manager.ts","../../src/pubsub-manager.ts","../../src/config-handler.ts","../../src/cache-manager.ts","../../src/response-parser.ts","../../src/retry-handler.ts","../../src/polling-handler.ts","../../src/upload-progress.ts","../../src/download-progress.ts","../../src/error-handler.ts","../../src/request-handler.ts","../../src/api-handler.ts"],"names":["APPLICATION_CONTENT_TYPE","APPLICATION_JSON","CHARSET_UTF_8","CONTENT_TYPE","UNDEFINED","OBJECT","STRING","FUNCTION","ABORT_ERROR","TIMEOUT_ERROR","GET","HEAD","REJECT","MAX_DELAY_MS","MAX_DEPTH","hasOwn","o","k","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","key","sortObject","sortedObj","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","v","buildParams","prefix","depth","i","len","replaceUrlPathParams","urlPathParams","match","colonKey","braceKey","encoded","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","signal","resolve","done","timer","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","isPageHidden","isOffline","applyInterceptors","interceptors","args","merge","interceptor","FetchError","request","response","ResponseError","WHEEL_SIZE","SECOND","wheel","keyMap","position","lastTick","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","inFlight","markInFlight","timeout","dedupeTime","isCancellable","isTimeoutEnabled","now","item","prevPromise","prevController","prevIsCancellable","controller","abortRequest","removeInFlight","setInFlightPromise","promise","getInFlightPromise","prevReq","hash","str","char","DEFAULT_TTL","revalidators","eventHandlers","customEventProviders","setEventProvider","type","provider","removeEventHandler","addEventHandler","revalidateAll","isStaleRevalidation","isThrottled","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","focusThrottleInterval","listeners","addListener","fn","set","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","merged","buildFetcherConfig","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","separator","contentTypeValue","INTERCEPTORS","baseConfig","overrideConfig","targetConfig","mergeConfig","property","mergeInterceptors","baseInterceptor","newInterceptor","base","override","isInstance","overrides","lowerKey","existingKey","_cache","stores","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADERS","generateCacheKey","config","cacheKeyCheck","headersString","keys","cacheStr","sanitizeCacheKey","bodyString","getObjectId","objectIds","lastObjectId","id","isCacheExpired","getCacheData","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","scheduleExpiry","removeExpired","store","callStore","persistCache","status","statusText","getStoredCache","isCacheBypassed","restoreCache","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","buster","getCachedResponse","cacheKey","cacheTime","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","responseType","contentType","mimeType","trimmed","_error","prepareResponse","defaultResponse","mutatator","isNativeResponse","getMsFromHttpDate","dateString","getRetryAfterMs","extendedResponse","retryAfter","RATELIMIT_RESET","rateLimitResetAfter","rateLimitResetAt","withRetry","requestFn","retries","delay","backoff","maxDelay","retryOn","shouldRetry","jitter","methods","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryDelay","withJitter","retryAfterMs","_b","_c","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","refreshWhenHidden","refreshWhenOffline","pollingAttempt","NULL_BODY_STATUSES","FORBIDDEN_HEADERS","isStream","toProgress","loaded","total","fetchWithUploadProgress","sendWithXhr","sendStreamed","reject","xhr","abort","settle","line","index","onAbort","stream","blob","chunk","withDownloadProgress","onDownloadProgress","counted","withErrorHandling","isCancelled","logger","redactError","strategy","SENSITIVE_HEADERS","copy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","isETagEnabled","needsCacheKey","_cacheKey","initialResponse","stored","restored","toResponse","inflight","retryConfig","resetTimeout","userSignal","doRequestOnce","init","withETag","onResponse","baseRequest","_","onLoadingSlow","loadingTimeout","requestWithErrorHandling","doRequestPromise","etag","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","resolvedUrl","mergedConfig","_target","prop"],"mappings":"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","file":"index.global.js","sourcesContent":["export const APPLICATION_CONTENT_TYPE = 'application/';\n\nexport const APPLICATION_JSON = APPLICATION_CONTENT_TYPE + 'json';\nexport const CHARSET_UTF_8 = 'charset=utf-8';\nexport const CONTENT_TYPE = 'Content-Type';\n\nexport const UNDEFINED = 'undefined';\nexport const OBJECT = 'object';\nexport const STRING = 'string';\nexport const FUNCTION = 'function';\n\nexport const ABORT_ERROR = 'AbortError';\nexport const TIMEOUT_ERROR = 'TimeoutError';\n\nexport const GET = 'GET';\nexport const HEAD = 'HEAD';\n\nexport const REJECT = 'reject';\n\n// Larger timer delays overflow and fire immediately in browsers and Node.js (~24.8 days)\nexport const MAX_DELAY_MS = 2147483647;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, MAX_DELAY_MS, OBJECT, STRING, UNDEFINED } from './constants';\nimport type {\n DefaultUrlParams,\n HeadersObject,\n QueryParams,\n UrlPathParams,\n} from './types';\n\n// Prevent stack overflow with recursion depth limit\nconst MAX_DEPTH = 10;\n\nexport const hasOwn = (o: any, k: string) =>\n Object.prototype.hasOwnProperty.call(o, k);\n\nexport function isSearchParams(data: unknown): boolean {\n return data instanceof URLSearchParams;\n}\n\n/**\n * Determines if a value is a non-null object.\n *\n * @param {any} value - The value to check.\n * @returns {boolean} - True if the value is a non-null object.\n */\nexport function isObject(value: any): value is Record {\n return value !== null && typeof value === OBJECT;\n}\n\n/**\n * Shallowly serializes an object by converting its key-value pairs into a string representation.\n * This function does not recursively serialize nested objects.\n *\n * @param obj - The object to serialize.\n * @returns A string representation of the object's top-level properties.\n */\nexport function shallowSerialize(obj: Record): string {\n let result = '';\n\n for (const key in obj) {\n if (hasOwn(obj, key)) {\n result += key + ':' + obj[key];\n }\n }\n\n return result;\n}\n\n/**\n * Removes properties that could lead to prototype pollution from an object.\n *\n * This function checks for dangerous properties like '__proto__', 'constructor',\n * and 'prototype'. If none are present, the object is returned as-is (zero-copy fast path).\n * Otherwise, a shallow copy is created with the dangerous properties removed.\n *\n * @param obj - The object to sanitize\n * @returns A safe object without dangerous properties\n */\nexport function sanitizeObject>(obj: T): T {\n const hasProto = hasOwn(obj, '__proto__');\n const hasCtor = hasOwn(obj, 'constructor');\n const hasPrototype = hasOwn(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n // Copy key by key, as a spread compiled to assignments would let \"__proto__\" set the prototype\n const safeObj = {} as Record;\n\n for (const key of Object.keys(obj)) {\n if (key !== '__proto__' && key !== 'constructor' && key !== 'prototype') {\n safeObj[key] = obj[key];\n }\n }\n\n return safeObj as T;\n}\n\n/**\n * Sorts the keys of an object and returns a new object with sorted keys.\n *\n * This function is optimized for performance by minimizing the number of object operations\n * and using a single pass to create the sorted object.\n *\n * @param {Object} obj - The object to be sorted by keys.\n * @returns {Object} - A new object with keys sorted in ascending order.\n */\nexport function sortObject(obj: Record): object {\n // Without a prototype, a \"__proto__\" key is kept as a regular property instead of setting the prototype\n const sortedObj = Object.create(null) as Record;\n\n Object.keys(obj)\n .sort()\n .forEach((k) => (sortedObj[k] = obj[k]));\n\n return sortedObj;\n}\n\n/**\n * Appends a query string to a URL, ensuring proper handling of existing query parameters.\n *\n * @param baseUrl - The base URL to which the query string will be appended.\n * @param queryString - The encoded query string to append.\n * @returns The URL with the appended query string, or the original URL if no query string is provided.\n */\nfunction appendQueryStringToUrl(baseUrl: string, queryString: string): string {\n if (!queryString) {\n return baseUrl;\n }\n\n return baseUrl + (baseUrl.includes('?') ? '&' : '?') + queryString;\n}\n\n/**\n * Appends query parameters to a given URL.\n *\n * @param {string} url - The base URL to which query parameters will be appended.\n * @param {QueryParams} params - An object containing the query parameters to append.\n * @returns {string} - The URL with the appended query parameters.\n */\nexport function appendQueryParams(url: string, params: QueryParams): string {\n if (!params) {\n return url;\n }\n\n // Check if `params` is an instance of URLSearchParams and bail early if it is\n if (isSearchParams(params)) {\n const encodedQueryString = params.toString();\n\n return appendQueryStringToUrl(url, encodedQueryString);\n }\n\n // This is exact copy of what JQ used to do. It works much better than URLSearchParams\n const s: string[] = [];\n const encode = encodeURIComponent;\n const add = (k: string, v: any) => {\n v = typeof v === FUNCTION ? v() : v;\n v = v === null || v === undefined ? '' : v;\n s[s.length] = encode(k) + '=' + encode(v);\n };\n\n const buildParams = (prefix: string, obj: any, depth = 0) => {\n // Stop recursion if maximum depth is reached\n if (depth >= MAX_DEPTH) {\n return s;\n }\n\n let i: number, len: number, key: string;\n\n if (prefix) {\n if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n buildParams(\n prefix + '[' + (typeof obj[i] === OBJECT && obj[i] ? i : '') + ']',\n obj[i],\n depth + 1,\n );\n }\n } else if (isObject(obj)) {\n for (key in obj) {\n buildParams(prefix + '[' + key + ']', obj[key], depth + 1);\n }\n } else {\n add(prefix, obj);\n }\n } else if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n add(obj[i].name, obj[i].value);\n }\n } else {\n for (key in obj) {\n buildParams(key, obj[key], depth + 1);\n }\n }\n return s;\n };\n\n const queryStringParts = buildParams('', params).join('&');\n\n // Encode special characters as per RFC 3986, https://datatracker.ietf.org/doc/html/rfc3986\n // This is for compatibility with server frameworks that expect the literal notation\n const encodedQueryString = queryStringParts.replace(/%5B%5D/g, '[]'); // Keep '[]' for arrays\n\n return appendQueryStringToUrl(url, encodedQueryString);\n}\n\n/**\n * Replaces dynamic URI parameters in a URL string with values from the provided `urlPathParams` object.\n * Parameters in the URL are denoted by `:` or `{}` (like in OpenAPI paths), where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:` or `{}`.\n * @param {Object} urlPathParams - An object containing the parameter values to replace placeholders.\n * @param {string} urlPathParams.paramName - The value to replace the placeholder `:` in the URL.\n * @returns {string} - The URL string with placeholders replaced by corresponding values from `urlPathParams`.\n */\nexport function replaceUrlPathParams(\n url: string,\n urlPathParams: UrlPathParams,\n): string {\n if (!urlPathParams || (url.indexOf(':') === -1 && url.indexOf('{') === -1)) {\n return url;\n }\n\n // Use a single RegExp and avoid unnecessary casts and function calls\n // Precompute keys for faster lookup\n const params = urlPathParams as DefaultUrlParams;\n\n // Use a replacer function that avoids extra work\n return url.replace(/:(\\w+)|\\{(\\w+)\\}/g, (match, colonKey, braceKey) => {\n const key = colonKey || braceKey;\n\n // Use hasOwnProperty for strict key existence check\n if (hasOwn(params, key)) {\n const value = params[key];\n\n // Only replace if value is not undefined or null\n if (value !== undefined && value !== null) {\n const encoded = encodeURIComponent(String(value));\n\n // These can't be encoded, and URL parsers would move the request to another path\n if (encoded === '.' || encoded === '..') {\n throw new Error('Path params \".\" and \"..\" not allowed.');\n }\n\n return encoded;\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL starts with a scheme (e.g., \"http://\", \"https://\").\n * A \"://\" appearing later, e.g. in a query string, does not make the URL absolute.\n *\n * @param url - The URL string to check.\n * @returns `true` if the URL is absolute, otherwise `false`.\n */\nexport function isAbsoluteUrl(url: string): boolean {\n return /^[a-z][a-z\\d+\\-.]*:\\/\\//i.test(url);\n}\n\nexport const timeNow = () => Date.now();\n\nexport const noop = () => {};\n\n/**\n * Checks if a value is JSON serializable.\n *\n * JSON serializable values include:\n * - Primitive types: string, number, boolean, null\n * - Arrays\n * - Plain objects (i.e., objects without special methods)\n * - Values with a `toJSON` method\n *\n * @param {any} value - The value to check for JSON serializability.\n * @returns {boolean} - Returns `true` if the value is JSON serializable, otherwise `false`.\n */\nexport function isJSONSerializable(value: any): boolean {\n const t = typeof value;\n\n if (value === undefined || value === null) {\n return false;\n }\n\n if (t === STRING || t === 'number' || t === 'boolean') {\n return true;\n }\n\n if (Array.isArray(value)) {\n return true;\n }\n\n if (\n typeof globalThis !== UNDEFINED &&\n typeof globalThis.Buffer !== UNDEFINED &&\n globalThis.Buffer.isBuffer(value)\n ) {\n return false;\n }\n\n if (value instanceof Date || isSearchParams(value)) {\n return false;\n }\n\n if (isObject(value)) {\n const proto = Object.getPrototypeOf(value);\n\n // Check if the prototype is `Object.prototype` (plain object)\n if (proto === Object.prototype) {\n return true;\n }\n\n // Check if the object has a toJSON method\n if (typeof value.toJSON === FUNCTION) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Waits for the given time. When a signal is passed, the wait ends early once it is aborted.\n *\n * @param {number} ms - The time to wait in milliseconds.\n * @param {AbortSignal} [signal] - An optional signal that ends the wait when aborted.\n * @returns {Promise} - A promise that resolves with `true` once the wait is over.\n */\nexport const delayInvocation = (\n ms: number,\n signal?: AbortSignal,\n): Promise =>\n new Promise((resolve) => {\n const done = () => {\n clearTimeout(timer);\n if (signal) {\n signal.removeEventListener('abort', done);\n }\n resolve(true);\n };\n const timer = setTimeout(done, Math.min(ms, MAX_DELAY_MS));\n\n if (signal) {\n if (signal.aborted) {\n done();\n } else {\n signal.addEventListener('abort', done);\n }\n }\n });\n\n/**\n * Recursively flattens the data object if it meets specific criteria.\n *\n * The method checks if the provided `data` is an object with exactly one property named `data`.\n * If so, it recursively flattens the `data` property. Otherwise, it returns the `data` as-is.\n *\n * @param {any} data - The data to be flattened. Can be of any type, including objects, arrays, or primitives.\n * @returns {any} - The flattened data if the criteria are met; otherwise, the original `data`.\n */\nexport function flattenData(data: any, depth = 0): any {\n if (depth >= MAX_DEPTH) {\n return data;\n }\n\n if (data && isObject(data) && typeof data.data !== UNDEFINED) {\n return flattenData(data.data, depth + 1);\n }\n\n return data;\n}\n\n/**\n * Processes headers and returns them as a normalized object.\n *\n * Handles both `Headers` instances and plain objects. Normalizes header keys to lowercase\n * as per RFC 2616 section 4.2.\n *\n * @param headers - The headers to process. Can be an instance of `Headers`, a plain object,\n * or `null`. If `null`, an empty object is returned.\n * @returns {HeadersObject} - A normalized headers object with lowercase keys.\n */\nexport function processHeaders(\n headers?: (HeadersObject & HeadersInit) | null | Headers,\n): HeadersObject {\n if (!headers) {\n return {};\n }\n\n const headersObject: HeadersObject = {};\n\n // Normalize keys to lowercase as per RFC 2616 4.2\n // https://datatracker.ietf.org/doc/html/rfc2616#section-4.2\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n headersObject[key.toLowerCase()] = value;\n });\n } else {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n // Assigning \"__proto__\" would set the prototype of the result\n if (hasOwn(headers, key) && key !== '__proto__') {\n headersObject[key.toLowerCase()] = headers[key];\n }\n }\n }\n\n return headersObject;\n}\n\n/**\n * Determines if the current environment is a browser.\n *\n * @returns {boolean} - True if running in a browser environment, false otherwise.\n */\nexport function isBrowser(): boolean {\n // For node and some mobile frameworks like React Native, `add/removeEventListener` doesn't exist on window!\n return (\n typeof window !== UNDEFINED && typeof window.addEventListener === FUNCTION\n );\n}\n\n/**\n * Creates an abort/timeout error compatible with all JS runtimes.\n * Falls back to a plain Error with the correct `name` when DOMException is unavailable (e.g. React Native).\n *\n * @param {string} message - The error message.\n * @param {string} name - The error name (e.g. 'AbortError', 'TimeoutError').\n * @returns {DOMException | Error} - An error object with the specified name.\n */\nexport function createAbortError(\n message: string,\n name: string,\n): DOMException | Error {\n if (typeof DOMException !== UNDEFINED) {\n return new DOMException(message, name);\n }\n\n const error = new Error(message);\n error.name = name;\n\n return error;\n}\n\n/**\n * Detects if the user is on a slow network connection\n * @returns {boolean} True if connection is slow, false otherwise or if detection unavailable\n */\nexport const isSlowConnection = (): boolean => {\n const conn = typeof navigator !== UNDEFINED && (navigator as any).connection;\n\n return conn && ['slow-2g', '2g', '3g'].includes(conn.effectiveType);\n};\n\n/**\n * Detects if the page is hidden, e.g. when its tab is in the background or the window is minimized\n * @returns {boolean} True if the page is hidden, false otherwise or outside browsers\n */\nexport const isPageHidden = (): boolean =>\n typeof document !== UNDEFINED && document.visibilityState === 'hidden';\n\n/**\n * Detects if the browser is offline\n * @returns {boolean} True if the browser is offline, false otherwise or if the connection state is unknown\n */\nexport const isOffline = (): boolean =>\n typeof navigator !== UNDEFINED && navigator.onLine === false;\n","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject, sanitizeObject } from './utils';\n\n/**\n * Applies interceptors to the object. Interceptors can be a single function or an array of functions.\n *\n * @template T - Type of the object.\n * @template Args - Type of additional arguments.\n * @template I - Type of interceptors.\n *\n * @param {InterceptorFunction | InterceptorFunction[]} [interceptors] - Interceptor function(s).\n * @param {T} data - The data object to process.\n * @param {...Args} args - Additional arguments to pass to interceptors.\n *\n * @returns {Promise} - Nothing as the function is non-idempotent.\n */\nexport async function applyInterceptors<\n T extends object,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Args extends any[] = any[],\n I = InterceptorFunction | InterceptorFunction[],\n>(interceptors: I | undefined, data: T, ...args: Args): Promise {\n if (!interceptors) {\n return;\n }\n\n const merge = (v: unknown) =>\n v &&\n isObject(data) &&\n isObject(v) &&\n Object.assign(data, sanitizeObject(v));\n\n if (typeof interceptors === FUNCTION) {\n merge(await (interceptors as InterceptorFunction)(data, ...args));\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n merge(await interceptor(data, ...args));\n }\n }\n}\n","import type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\n/**\n * This is a base error class\n */\nexport class FetchError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends Error {\n // Declared only, and set in the constructor, as class fields would need a helper in the ES2018 bundle\n declare status: number;\n declare statusText: string;\n declare config: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare isCancelled: boolean;\n declare request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null;\n\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.request = request;\n this.response = response;\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\n this.name = 'FetchError';\n }\n}\n","import { FetchError } from './fetch-error';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\nexport class ResponseError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends FetchError {\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message, request, response);\n\n this.name = 'ResponseError';\n }\n}\n","/**\n * @module timeout-wheel\n * @description\n * Ultra-minimal timing wheel implementation optimized for max performance & many requests.\n * For most of the cases it's 4-100x faster than setTimeout and setInterval alone.\n * Provides efficient scheduling and cancellation of timeouts using a circular array.\n *\n * Position 0 → 1 → 2 → ... → 599 → 0 → 1 → 2 ...\n * Time: 0s 1s 2s 599s 600s 601s 602s\n *\n * The timing wheel consists of 600 slots (one per second for 10 min).\n * Each slot contains a list of timeout items, each associated with a unique key and callback.\n * Timeouts are scheduled by placing them in the appropriate slot based on the delay in seconds.\n * The wheel advances every second, executing and removing callbacks as their timeouts expire.\n * Defaults to setTimeout if the delay doesn't fit in the wheel (~10 minutes) or is not divisible by 1000.\n *\n * @remarks\n * - Designed for minimal footprint and simplicity.\n * - Only supports second-level granularity (minimum timeout: 1 second).\n * - Timeouts never fire early, but may fire up to 1 second late.\n * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { MAX_DELAY_MS } from './constants';\nimport { noop, timeNow } from './utils';\n\ntype TimeoutCallback = () => unknown | Promise;\ntype TimeoutItem = [string, TimeoutCallback]; // [key, callback]\n\nconst WHEEL_SIZE = 600; // 600 slots for 10 min (1 slot per second)\nconst SECOND = 1000; // 1 second in milliseconds\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\nlet lastTick = 0; // Time when the wheel last advanced (or started)\nlet timer: NodeJS.Timeout | null = null;\n\nconst handleCallback = ([key, callback]: TimeoutItem): void => {\n keyMap.delete(key);\n\n try {\n const result = callback();\n if (result && result instanceof Promise) {\n // Silently ignore async errors to prevent wheel from stopping\n result.catch(noop);\n }\n } catch {\n // Ignore callback errors to prevent wheel from stopping\n }\n};\n\nexport const addTimeout = (\n key: string,\n cb: TimeoutCallback,\n ms: number,\n): void => {\n removeTimeout(key);\n\n // A running wheel is already part-way through its current second, so the timeout\n // waits one more slot to never fire early. A new wheel starts its first second now.\n const seconds = ms / SECOND + (timer && timeNow() !== lastTick ? 1 : 0);\n\n // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || seconds >= WHEEL_SIZE || ms % SECOND !== 0) {\n keyMap.set(key, [\n setTimeout(\n handleCallback.bind(null, [key, cb]),\n Math.min(ms, MAX_DELAY_MS),\n ),\n ]); // Store timeout ID instead of slot\n\n return;\n }\n\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n lastTick = timeNow();\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\n lastTick = timeNow();\n const slot = wheel[position];\n\n // Use slot.length directly (not cached) so mid-iteration mutations\n // from callbacks (e.g. removeTimeout) are handled correctly\n for (let i = 0; i < slot.length; i++) {\n handleCallback(slot[i]);\n }\n\n slot.length = 0; // Reuse array, avoid GC allocation\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }, SECOND);\n }\n};\n\nexport const removeTimeout = (key: string): void => {\n const slotOrTimeout = keyMap.get(key);\n\n if (slotOrTimeout !== undefined) {\n // It's a Timeout object from setTimeout\n if (Array.isArray(slotOrTimeout)) {\n clearTimeout(slotOrTimeout[0]);\n } else {\n const slotArr = wheel[slotOrTimeout];\n\n for (let i = 0; i < slotArr.length; i++) {\n if (slotArr[i][0] === key) {\n slotArr.splice(i, 1);\n break;\n }\n }\n }\n\n keyMap.delete(key);\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }\n};\n\nexport const clearAllTimeouts = () => {\n // Clear native setTimeout timeouts first!\n keyMap.forEach((value) => {\n if (Array.isArray(value)) {\n clearTimeout(value[0]);\n }\n });\n\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n\n keyMap.clear();\n\n for (let i = 0; i < WHEEL_SIZE; i++) {\n wheel[i].length = 0;\n }\n\n position = 0;\n};\n","/**\n * @module inflight-manager\n *\n * Manages in-flight asynchronous requests using unique keys to enable deduplication and cancellation.\n *\n * Provides utilities for:\n * - Deduplication of requests within a configurable time window (`dedupeTime`)\n * - Timeout management and automatic request abortion\n * - AbortController lifecycle and cancellation logic\n * - Concurrency control and request state tracking\n * - In-flight promise deduplication to prevent duplicate network calls\n *\n * @remarks\n * - Requests with the same key within the deduplication interval share the same AbortController and in-flight promise.\n * - Supports cancellation of previous requests when a new one with the same key is issued, if `isCancellable` is enabled.\n * - Timeout logic ensures requests are aborted after a specified duration, if enabled.\n * - Internal queue state is managed via a Map, keyed by request identifier.\n * - Polled requests are also marked as \"in-flight\" to prevent duplicate requests.\n */\n\nimport { ABORT_ERROR, TIMEOUT_ERROR } from './constants';\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { createAbortError, timeNow } from './utils';\n\nexport type InFlightItem = [\n AbortController, // AbortController for the request\n boolean, // Whether timeout is enabled for the request\n number, // Timestamp when the request was marked in-flight\n boolean, // isCancellable - whether the request can be cancelled\n Promise | null, // Optional in-flight promise for deduplication\n];\n\nconst inFlight: Map = new Map();\n\n/**\n * Adds a request to the queue if it's not already being processed within the dedupeTime interval.\n *\n * @param {string | null} key - Unique key for the request (e.g. cache key).\n * @param {string} url - The request URL (for error messages/timeouts).\n * @param {number} timeout - Timeout in milliseconds for the request.\n * @param {number} dedupeTime - Deduplication time in milliseconds.\n * @param {boolean} isCancellable - If true, then the previous request with same configuration should be aborted.\n * @param {boolean} isTimeoutEnabled - Whether timeout is enabled.\n * @returns {AbortController} - A promise that resolves to an AbortController.\n */\nexport function markInFlight(\n key: string | null,\n url: string,\n timeout: number | undefined,\n dedupeTime: number,\n isCancellable: boolean,\n isTimeoutEnabled: boolean,\n): AbortController {\n if (!key) {\n return new AbortController();\n }\n\n const now = timeNow();\n const item = inFlight.get(key);\n let prevPromise: Promise | null = null;\n\n // Previous request is in-flight, check if we can reuse it\n if (item) {\n const prevController = item[0];\n const prevIsCancellable = item[3];\n\n // If the request is already in the queue and within the dedupeTime, reuse the existing controller\n if (\n !prevIsCancellable &&\n now - item[2] < dedupeTime &&\n !prevController.signal.aborted\n ) {\n return prevController;\n }\n\n // If the request is too old, remove it and proceed to add a new one\n // Abort previous request, if applicable, and continue as usual\n if (prevIsCancellable) {\n prevController.abort(\n createAbortError('Aborted due to new request', ABORT_ERROR),\n );\n }\n\n removeTimeout(key);\n prevPromise = item[4];\n }\n\n const controller = new AbortController();\n\n inFlight.set(key, [\n controller,\n isTimeoutEnabled,\n now,\n isCancellable,\n prevPromise,\n ]);\n\n if (isTimeoutEnabled) {\n addTimeout(\n key,\n () => {\n abortRequest(\n key,\n createAbortError(url + ' aborted due to timeout', TIMEOUT_ERROR),\n );\n },\n timeout as number,\n );\n }\n\n return controller;\n}\n\n/**\n * Removes a request from the queue and clears its timeout.\n *\n * @param key - Unique key for the request.\n * @param {boolean} error - Optional error to abort the request with. If null, the request is simply removed but no abort sent.\n * @returns {Promise} - A promise that resolves when the request is aborted and removed.\n */\nexport async function abortRequest(\n key: string | null,\n error: DOMException | Error | null | string = null,\n): Promise {\n // If the key is not in the queue, there's nothing to remove\n if (key) {\n const item = inFlight.get(key);\n\n if (item) {\n // If the request is not yet aborted, abort it with the provided error\n if (error) {\n const controller = item[0];\n controller.abort(error);\n }\n\n removeInFlight(key);\n }\n }\n}\n\n/**\n * Removes a request from the in-flight queue without aborting or clearing timeout.\n *\n * @param key - Unique key for the request.\n */\nexport function removeInFlight(key: string | null): void {\n removeTimeout(key!);\n inFlight.delete(key!);\n}\n\n/**\n * Gets the AbortController for a request key.\n *\n * @param key - Unique key for the request.\n * @returns {AbortController | undefined} - The AbortController or undefined.\n */\nexport async function getController(\n key: string,\n): Promise {\n const item = inFlight.get(key);\n\n return item && item[0];\n}\n\n/**\n * Adds helpers for in-flight promise deduplication.\n *\n * @param key - Unique key for the request.\n * @param promise - The promise to store.\n */\nexport function setInFlightPromise(\n key: string,\n promise: Promise,\n): void {\n const item = inFlight.get(key);\n if (item) {\n // store the promise at index 4 — item is already the Map's reference, no need to re-set\n item[4] = promise;\n }\n}\n\n/**\n * Retrieves the in-flight promise for a request key if it exists and is within the dedupeTime interval.\n *\n * @param key - Unique key for the request.\n * @param dedupeTime - Deduplication time in milliseconds.\n * @returns {Promise | null} - The in-flight promise or null.\n */\nexport function getInFlightPromise(\n key: string | null,\n dedupeTime: number,\n): Promise | null {\n if (!key) {\n return null;\n }\n\n const prevReq = inFlight.get(key);\n\n if (\n prevReq &&\n // If the request is in-flight and has a promise\n prevReq[4] &&\n // If the request is cancellable, we will not reuse it\n !prevReq[3] &&\n // If the request is within the dedupeTime\n timeNow() - prevReq[2] < dedupeTime &&\n // If one request is cancelled, ALL deduped requests get cancelled\n !prevReq[0].signal.aborted\n ) {\n return prevReq[4] as Promise;\n }\n\n return null;\n}\n","const PRIME_MULTIPLIER = 31;\n\n/**\n * Computes a hash value for a given string using the variant of djb2 hash function.\n * This hash function is non-cryptographic and designed for speed.\n * @author Daniel J. Bernstein (of djb2)\n *\n * @param str Input string to hash\n * @returns {string} Hash\n */\nexport function hash(str: string): string {\n let hash = 0;\n\n for (let i = 0, len = str.length; i < len; i++) {\n const char = str.charCodeAt(i);\n hash = (hash * PRIME_MULTIPLIER + char) | 0;\n }\n\n return String(hash);\n}\n","/**\n * @module revalidator-manager\n *\n * Provides utilities for managing cache revalidation functions, including:\n * - Registering and unregistering revalidators for specific cache keys.\n * - Triggering revalidation for a given key.\n * - Enabling or disabling automatic revalidation on window focus and if user comes back online for specific keys.\n * - Attaching and removing global focus and online event handlers to trigger revalidation.\n *\n * Revalidators are functions that can be registered to revalidate cache entries when needed.\n * They are typically used to refresh data in the cache when the window gains focus or when specific actions occur.\n * @performance O(1) lookup by key makes it blazing fast to register, unregister, and revalidate cache entries.\n * - Designed for high performance: minimizes unnecessary re-renders and leverages fast cache key generation.\n * - Integrates with a global cache and pub/sub system for efficient state updates across contexts.\n * - Handles automatic revalidation, deduplication, retries, and cache management out of the box.\n * @remarks\n * - Designed to be used in various environments (Deno, Node.js, Bun, Browser, etc.) to ensure cache consistency and freshness.\n */\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { FetchResponse } from './types';\nimport { isBrowser, noop, timeNow } from './utils';\n\nexport type RevalidatorFn = (\n isStaleRevalidation?: boolean,\n) => Promise;\n\ntype EventType = 'focus' | 'online';\n\ntype RevalidatorEntry = [\n RevalidatorFn, // main revalidator\n number, // lastUsed\n number, // ttl\n number?, // staleTime\n RevalidatorFn?, // bgRevalidator\n boolean?, // refetchOnFocus\n boolean?, // refetchOnReconnect\n number?, // focusThrottleInterval\n];\n\nconst DEFAULT_TTL = 3 * 60 * 1000; // Default TTL of 3 minutes\nconst revalidators = new Map();\n\n/**\n * Stores cleanup functions for active event handlers (browser or custom providers).\n * Each entry removes the corresponding event listener when called.\n * @remarks\n * - Improves performance by reducing the number of event listeners.\n * - Enables efficient O(1) lookup and management of event handlers for revalidation.\n */\nconst eventHandlers = new Map void>();\n\n/** Subscribe to an event and return a cleanup function */\nexport type EventProvider = (handler: () => void) => () => void;\n\nconst customEventProviders = new Map();\n\n/**\n * Registers a custom event provider for 'focus' or 'online' events.\n * Useful for non-browser environments like React Native.\n *\n * @param type - The event type ('focus' or 'online').\n * @param provider - A function that subscribes to the event and returns a cleanup function.\n */\nexport function setEventProvider(\n type: EventType,\n provider: EventProvider,\n): void {\n customEventProviders.set(type, provider);\n\n // Re-register if already active\n if (eventHandlers.has(type)) {\n removeEventHandler(type);\n addEventHandler(type);\n }\n}\n\n/**\n * Triggers revalidation for all registered entries based on the given event type.\n * For example, if it's a 'focus' event, it will revalidate entries that have the `refetchOnFocus` flag set.\n * Updates the timestamp and invokes the revalidator function for each applicable entry.\n *\n * @param type - The type of event that caused the revalidation (e.g., 'focus' or 'online').\n * @param isStaleRevalidation - If `true`, uses background revalidator and doesn't mark as in-flight.\n * @param isThrottled - If `true`, skips entries that were requested or revalidated within their `focusThrottleInterval`.\n */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n isThrottled: boolean = false,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex] || (isThrottled && now - entry[1] < entry[7]!)) {\n return;\n }\n\n entry[1] = now;\n\n // If it's a stale revalidation, use the background revalidator function\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n if (revalidator) {\n Promise.resolve(revalidator(isStaleRevalidation)).catch(noop);\n }\n });\n}\n\n/**\n * Revalidates an entry by executing the registered revalidation function.\n *\n * @param key The unique identifier for the cache entry to revalidate. If `null`, no revalidation occurs.\n * @param isStaleRevalidation - If `true`, it does not mark revalidated requests as in-flight.\n * @returns A promise that resolves to the result of the revalidator function, or\n * `null` if no key or revalidator is found, or a `FetchResponse` if applicable.\n */\nexport async function revalidate(\n key: string | null,\n isStaleRevalidation: boolean = false,\n): Promise {\n // If no key is provided, no revalidation occurs\n if (!key) {\n return null;\n }\n\n const entry = revalidators.get(key);\n\n if (entry) {\n // Update only the lastUsed timestamp without resetting the whole array\n entry[1] = timeNow();\n\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n // If no revalidator function is registered, return null\n if (revalidator) {\n return await revalidator(isStaleRevalidation);\n }\n }\n\n // If no revalidator is registered for the key, return null\n return null;\n}\n\n/**\n * Removes all revalidators associated with the specified event type.\n *\n * @param type - The event type whose revalidators should be removed.\n */\nexport function removeRevalidators(type: EventType) {\n removeEventHandler(type);\n\n const flagIndex = type === 'focus' ? 5 : 6;\n\n // Clear all revalidators with this flag\n revalidators.forEach((entry, key) => {\n if (entry[flagIndex]) {\n removeRevalidator(key);\n }\n });\n}\n\n/**\n * Registers a generic revalidation event handler for the specified event type.\n * Supports browser window events and custom event providers (e.g. for React Native).\n * Ensures the handler is only added once.\n *\n * @param event - The type of event to listen for (e.g., 'focus', 'online').\n */\nfunction addEventHandler(event: EventType) {\n if (eventHandlers.has(event)) {\n return;\n }\n\n // Focus events are throttled, so that e.g. switching between tabs quickly doesn't revalidate every time\n const handler = revalidateAll.bind(null, event, true, event === 'focus');\n\n // Priority 1: Custom event provider (works in any environment including React Native)\n const customProvider = customEventProviders.get(event);\n\n if (customProvider) {\n const cleanup = customProvider(handler);\n\n eventHandlers.set(event, cleanup);\n\n return;\n }\n\n // Priority 2: Browser window events\n if (isBrowser()) {\n window.addEventListener(event, handler);\n\n eventHandlers.set(event, () => window.removeEventListener(event, handler));\n }\n}\n\n/**\n * Removes the event handler for the specified event type.\n *\n * @param event - The type of event whose handler should be removed.\n */\nfunction removeEventHandler(event: EventType) {\n const cleanup = eventHandlers.get(event);\n\n if (cleanup) {\n cleanup();\n eventHandlers.delete(event);\n }\n}\n\n/**\n * Registers a revalidation functions for a specific cache key.\n *\n * @param {string} key Cache key to utilize\n * @param {RevalidatorFn} revalidatorFn Main revalidation function (marks in-flight requests)\n * @param {number} [ttl] Time to live in milliseconds (default: 3 minutes)\n * @param {number} [staleTime] Time (in seconds) after which the cache entry is considered stale\n * @param {RevalidatorFn} [bgRevalidatorFn] For stale revalidation (does not mark in-flight requests)\n * @param {boolean} [refetchOnFocus] Whether to revalidate on window focus\n * @param {boolean} [refetchOnReconnect] Whether to revalidate on network reconnect\n * @param {number} [focusThrottleInterval] Time (in milliseconds) after a request or revalidation during which focus events don't revalidate it\n */\nexport function addRevalidator(\n key: string,\n revalidatorFn: RevalidatorFn, // Main revalidation function (marks in-flight requests)\n ttl?: number,\n staleTime?: number,\n bgRevalidatorFn?: RevalidatorFn, // For stale revalidation (does not mark in-flight requests)\n refetchOnFocus?: boolean,\n refetchOnReconnect?: boolean,\n focusThrottleInterval?: number,\n) {\n // Existing entries are updated in place\n const entry = revalidators.get(key) || ([] as unknown as RevalidatorEntry);\n\n entry[0] = revalidatorFn;\n entry[1] = timeNow();\n entry[2] = ttl ?? DEFAULT_TTL;\n entry[3] = staleTime;\n entry[4] = bgRevalidatorFn;\n entry[5] = refetchOnFocus;\n entry[6] = refetchOnReconnect;\n entry[7] = focusThrottleInterval;\n\n revalidators.set(key, entry);\n\n if (refetchOnFocus) {\n addEventHandler('focus');\n }\n\n if (refetchOnReconnect) {\n addEventHandler('online');\n }\n\n if (staleTime) {\n addTimeout('s:' + key, revalidate.bind(null, key, true), staleTime * 1000);\n }\n}\n\nexport function removeRevalidator(key: string) {\n revalidators.delete(key);\n\n // Clean up stale timer\n removeTimeout('s:' + key);\n}\n\n/**\n * Periodically cleans up expired revalidators from the registry.\n * Removes any revalidator whose TTL has expired.\n *\n * @param {number} intervalMs How often to run cleanup (default: 3 minutes)\n * @returns {() => void} A function to stop the periodic cleanup\n */\nexport function startRevalidatorCleanup(\n intervalMs: number = DEFAULT_TTL,\n): () => void {\n const intervalId = setInterval(() => {\n const now = timeNow();\n\n revalidators.forEach(\n ([, lastUsed, ttl, , , refetchOnFocus, refetchOnReconnect], key) => {\n // Skip focus-only or reconnect-only revalidators to keep them alive\n if (refetchOnFocus || refetchOnReconnect) {\n return;\n }\n\n if (ttl > 0 && now - lastUsed > ttl) {\n removeRevalidator(key);\n }\n },\n );\n }, intervalMs);\n\n return () => clearInterval(intervalId);\n}\n","/**\n * Manages a set of listeners (subscribers) for arbitrary string keys, allowing cross-context or cross-component\n * cache updates and synchronization. Provides functions to add, remove, and notify listeners, as well as a\n * convenient subscribe/unsubscribe API.\n *\n * @template T - The type of the response object passed to listeners.\n *\n * @remarks\n * - Listeners are grouped by a string key, which typically represents a cache key or resource identifier.\n * - When `notifySubscribers` is called for a key, all listeners registered for that key are invoked with the provided response.\n * - The `subscribe` function returns an unsubscribe function for convenient cleanup.\n *\n * @example\n * ```ts\n * const unsubscribe = subscribe('user:123', (response) => {\n * // handle updated data\n * });\n * // Later, to stop listening:\n * unsubscribe();\n * ```\n */\n\nimport { noop } from './utils';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Listener = (response: T) => void;\n\nconst listeners = new Map>();\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n let set = listeners.get(key);\n\n if (!set) {\n listeners.set(key, (set = new Set()));\n }\n\n set.add(fn);\n}\n\nexport function removeListener(key: string, fn: Listener) {\n const set = listeners.get(key);\n\n if (set) {\n set.delete(fn);\n\n // If the set is empty, remove the key from the listeners map\n if (set.size === 0) {\n listeners.delete(key);\n }\n }\n}\n\nexport function notifySubscribers(key: string, response: T) {\n const fns = listeners.get(key);\n\n if (fns) {\n if (fns.size === 1) {\n // If there's only one listener, call it directly\n const fn = fns.values().next().value;\n fn!(response);\n } else {\n fns.forEach((fn) => fn(response));\n }\n }\n}\n\nexport function subscribe(key: string | null, fn: (response: T) => void) {\n if (!key) {\n // No op if no key is provided\n return noop;\n }\n\n addListener(key, fn);\n\n // Return an unsubscribe function\n return () => {\n removeListener(key, fn);\n };\n}\n","import { processHeaders } from './utils';\nimport {\n GET,\n APPLICATION_JSON,\n HEAD,\n STRING,\n CHARSET_UTF_8,\n CONTENT_TYPE,\n REJECT,\n UNDEFINED,\n APPLICATION_CONTENT_TYPE,\n} from './constants';\nimport type {\n HeadersObject,\n Method,\n RequestConfig,\n} from './types/request-handler';\nimport {\n replaceUrlPathParams,\n appendQueryParams,\n isSearchParams,\n isJSONSerializable,\n isSlowConnection,\n isAbsoluteUrl,\n sanitizeObject,\n isObject,\n} from './utils';\n\nconst defaultTimeoutMs = (isSlowConnection() ? 60 : 30) * 1000;\n\nexport const defaultConfig: RequestConfig = {\n strategy: REJECT,\n timeout: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n loadingTimeout: defaultTimeoutMs / 10, // 3 seconds (6 on slow connections)\n focusThrottleInterval: 5000, // 5 seconds\n headers: {\n Accept: APPLICATION_JSON + ', text/plain, */*',\n 'Accept-Encoding': 'gzip, deflate, br',\n },\n retry: {\n delay: defaultTimeoutMs / 30, // 1 second (2 on slow connections)\n maxDelay: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n resetTimeout: true,\n backoff: 1.5,\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n retryOn: [\n 408, // Request Timeout\n 409, // Conflict\n 425, // Too Early\n 429, // Too Many Requests\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n ],\n\n // Idempotent methods, which can be repeated safely, unlike e.g. POST requests that create resources\n methods: [GET, HEAD, 'PUT', 'DELETE', 'OPTIONS', 'TRACE'],\n },\n};\n\n/**\n * Overwrites the default configuration with the provided custom configuration.\n *\n * @param {Partial} customConfig - The custom configuration to merge into the default config.\n * @returns {Partial} - The updated default configuration object.\n */\nexport function setDefaultConfig(\n customConfig: Partial,\n): Partial {\n const sanitized = sanitizeObject(customConfig);\n\n // Merge nested retry and headers settings into the current defaults instead of replacing them\n return mergeConfigs(\n { retry: defaultConfig.retry, headers: defaultConfig.headers },\n sanitized,\n defaultConfig,\n );\n}\n\n/**\n * Returns a shallow copy of the current default configuration.\n *\n * @returns {RequestConfig} - The current default configuration.\n */\nexport function getDefaultConfig(): RequestConfig {\n return { ...defaultConfig };\n}\n\n/**\n * Build request configuration from defaults and overrides.\n * This function merges the default configuration with the provided request configuration,\n * @param {string} url - Request url\n * @param {RequestConfig | null | undefined} reqConfig - Request configuration\n * @return {RequestConfig} - Merged request configuration\n */\nexport function buildConfig(\n url: string,\n reqConfig?: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null,\n): RequestConfig {\n // Merging gives the request its own copies of nested objects like headers, so that\n // mutations (e.g. by interceptors) never leak into the global defaults\n const merged = mergeConfigs(\n defaultConfig,\n reqConfig ? sanitizeObject(reqConfig) : {},\n );\n\n return buildFetcherConfig(url, merged);\n}\n\n/**\n * Builds the fetcher configuration by setting the method, body, headers, and URL.\n * It also handles query parameters and path parameters. This fn mutates the passed `requestConfig` object.\n * @param {string} url - The endpoint URL to which the request will be sent.\n * @param {RequestConfig} requestConfig - The request configuration object containing method, body, headers, and other options.\n * @return {RequestConfig} - The modified request configuration object with the URL, method, body, and headers set appropriately.\n **/\nexport function buildFetcherConfig(\n url: string,\n requestConfig: RequestConfig,\n): RequestConfig {\n let method = requestConfig.method as Method;\n method = method ? (method.toUpperCase() as Method) : GET;\n\n let body: RequestConfig['data'] | undefined;\n\n // Only applicable for request methods 'PUT', 'POST', 'DELETE', and 'PATCH'\n if (method !== GET && method !== HEAD) {\n body = requestConfig.body ?? requestConfig.data;\n\n // Automatically stringify request body, if possible and when not dealing with strings\n if (body && typeof body !== STRING && isJSONSerializable(body)) {\n body = JSON.stringify(body);\n }\n }\n\n setContentTypeIfNeeded(requestConfig.headers, body);\n\n // Native fetch compatible settings\n const credentials = requestConfig.withCredentials\n ? 'include'\n : requestConfig.credentials;\n\n // The explicitly passed query params\n const dynamicUrl = replaceUrlPathParams(url, requestConfig.urlPathParams);\n const urlPath = appendQueryParams(dynamicUrl, requestConfig.params);\n const isFullUrl = isAbsoluteUrl(url);\n const baseURL = isFullUrl\n ? ''\n : requestConfig.baseURL || requestConfig.apiUrl || '';\n\n // Join as a path, as plain concatenation could extend the host of the baseURL,\n // e.g. \"https://api.example.com\" + \".evil.com\" would point to another host\n const separator =\n baseURL && urlPath && !baseURL.endsWith('/') && !/^[/?#]/.test(urlPath)\n ? '/'\n : '';\n\n requestConfig.url = baseURL + separator + urlPath;\n requestConfig.method = method;\n requestConfig.credentials = credentials;\n requestConfig.body = body;\n\n return requestConfig;\n}\n\n/**\n * Ensures the `Content-Type` header is set to `application/json; charset=utf-8`\n * if it is not already present and the request method and body meet specific conditions.\n *\n * @param headers - The headers object to modify. Can be an instance of `Headers`\n * or a plain object conforming to `HeadersInit`.\n * @param body - The optional body of the request. If no body is provided and the\n * method is 'GET' or 'HEAD', the function exits without modifying headers.\n */\nfunction setContentTypeIfNeeded(\n headers?: HeadersInit | HeadersObject,\n body?: unknown,\n): void {\n // If no headers are provided, or if the body is not set and the method is PUT or DELETE, do nothing\n if (!headers || !body) {\n return;\n }\n\n // Types that should not have Content-Type set (browser handles these)\n if (\n body instanceof FormData || // Browser automatically sets multipart/form-data with boundary\n (typeof Blob !== UNDEFINED && body instanceof Blob) || // Blob/File (a File is a Blob) already have their own MIME types, don't override\n (typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream) // Stream type should be determined by the stream source\n ) {\n return;\n }\n\n let contentTypeValue: string;\n\n if (isSearchParams(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded';\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'octet-stream';\n } else if (isJSONSerializable(body)) {\n contentTypeValue = APPLICATION_JSON + ';' + CHARSET_UTF_8;\n } else {\n // Do not set Content-Type if content is not recognizable\n return;\n }\n\n if (headers instanceof Headers) {\n if (!headers.has(CONTENT_TYPE)) {\n headers.set(CONTENT_TYPE, contentTypeValue);\n }\n } else if (\n isObject(headers) &&\n !Array.isArray(headers) &&\n // Header names are case-insensitive, so check the normalized (lowercase) headers\n !processHeaders(headers as HeadersObject)[CONTENT_TYPE.toLowerCase()]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\n\n// The interceptors that are merged instead of replaced\nconst INTERCEPTORS = [\n 'onRequest',\n 'onResponse',\n 'onError',\n 'onLoadingSlow',\n] as const;\n\n/**\n * Merges two request configurations, applying overrides from the second config to the first.\n * Handles special merging for nested properties like 'retry' and 'headers' (deep merge),\n * and concatenates interceptor arrays for 'onRequest', 'onResponse', 'onError' and 'onLoadingSlow'.\n * If a target config is provided, it mutates that object; otherwise, creates a new one.\n *\n * @param {RequestConfig} baseConfig - The base configuration object to merge from.\n * @param {RequestConfig} overrideConfig - The override configuration object to apply on top of the base.\n * @param {RequestConfig} [targetConfig={}] - Optional target configuration object to merge into (mutated in place).\n * @returns {RequestConfig} The merged configuration object.\n *\n * @example\n * const base = { timeout: 5000, headers: { 'Accept': 'application/json' } };\n * const override = { timeout: 10000, headers: { 'Authorization': 'Bearer token' } };\n * const merged = mergeConfigs(base, override);\n * // Result: { timeout: 10000, headers: { Accept: 'application/json', Authorization: 'Bearer token' } }\n */\nexport function mergeConfigs(\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig = {},\n): RequestConfig {\n Object.assign(targetConfig, baseConfig, overrideConfig);\n\n // Ensure that retry and headers are merged correctly\n mergeConfig('retry', baseConfig, overrideConfig, targetConfig);\n mergeConfig('headers', baseConfig, overrideConfig, targetConfig);\n\n // Merge interceptors efficiently\n for (const property of INTERCEPTORS) {\n mergeInterceptors(property, baseConfig, overrideConfig, targetConfig);\n }\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends\n 'onRequest' | 'onResponse' | 'onError' | 'onRetry' | 'onLoadingSlow',\n>(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const baseInterceptor = baseConfig[property];\n const newInterceptor = overrideConfig[property];\n\n if (baseInterceptor && newInterceptor) {\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] = (\n property === 'onResponse'\n ? [].concat(newInterceptor as never, baseInterceptor as never)\n : [].concat(baseInterceptor as never, newInterceptor as never)\n ) as RequestConfig[K];\n } else if (baseInterceptor || newInterceptor) {\n targetConfig[property] = baseInterceptor || newInterceptor;\n }\n}\n\n/**\n * Merges the specified property from the base configuration and the override configuration into the target configuration.\n *\n * @param {K} property - The property key to merge from the base and override configurations. Must be a key of RequestConfig.\n * @param {RequestConfig} baseConfig - The base configuration object that provides default values.\n * @param {RequestConfig} overrideConfig - The override configuration object that contains user-specific settings to merge.\n * @param {RequestConfig} targetConfig - The configuration object that will receive the merged properties.\n */\nexport function mergeConfig(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n if (override) {\n if (property === 'headers') {\n // Handle Headers instances which don't expose entries as own enumerable properties\n const isInstance =\n (base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers;\n const merged: HeadersObject = isInstance\n ? processHeaders(base)\n : { ...(base as HeadersObject) };\n const overrides: HeadersObject = isInstance\n ? processHeaders(override)\n : sanitizeObject(override as HeadersObject);\n\n // Header names are case-insensitive, so replace existing entries instead of duplicating them\n for (const key of Object.keys(overrides)) {\n const lowerKey = key.toLowerCase();\n\n for (const existingKey in merged) {\n if (existingKey.toLowerCase() === lowerKey) {\n delete merged[existingKey];\n }\n }\n\n merged[key] = overrides[key];\n }\n\n targetConfig[property] = merged as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...sanitizeObject(override as Record),\n } as RequestConfig[K];\n }\n } else if (\n override === undefined &&\n isObject(base) &&\n !((base as Headers | HeadersObject) instanceof Headers)\n ) {\n // Copy so that mutating the merged config never changes the base config\n targetConfig[property] = { ...base } as RequestConfig[K];\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { hash } from './hash';\nimport type {\n CacheKeyFunction,\n DefaultResponse,\n FetchResponse,\n MutationSettings,\n RequestConfig,\n} from './types/request-handler';\nimport type {\n CacheEntry,\n CacheStore,\n StoredResponse,\n} from './types/cache-manager';\nimport { GET, STRING } from './constants';\nimport {\n isJSONSerializable,\n isObject,\n isSearchParams,\n noop,\n sanitizeObject,\n sortObject,\n timeNow,\n} from './utils';\nimport { revalidate } from './revalidator-manager';\nimport { notifySubscribers } from './pubsub-manager';\nimport type { DefaultPayload, DefaultParams, DefaultUrlParams } from './types';\nimport { removeInFlight } from './inflight-manager';\nimport { addTimeout } from './timeout-wheel';\nimport { defaultConfig } from './config-handler';\nimport { processHeaders } from './utils';\n\nexport const IMMEDIATE_DISCARD_CACHE_TIME = 0; // Use it for cache entries that need to be persistent until unused by components or manually deleted\n\nconst _cache = new Map>();\n// The cache stores that keep copies of cache entries, by cache key\nconst stores = new Map();\nconst DELIMITER = '|';\nconst MIN_LENGTH_TO_HASH = 64;\nconst CACHE_KEY_SANITIZE_PATTERN = /[^\\w\\-_|/:@.?=&~%#]/g;\nconst CACHE_KEY_NEEDS_SANITIZE = /[^\\w\\-_|/:@.?=&~%#]/; // Non-global for fast test\n\n/**\n * Headers that may affect HTTP response content and should be included in cache key generation.\n * Header names are matched case-insensitively.\n *\n * - Content negotiation: accept (response format, e.g. JSON or HTML), accept-language (localization), accept-encoding (compression)\n * - Authentication: authorization (access to protected resources)\n * - Request body metadata: content-type (how the request body is interpreted)\n * - Optional: referer (may influence behavior in some APIs), origin (CORS or tenant-specific APIs),\n * user-agent (if the server returns client-specific content), cookie (session-based responses; can fragment the cache heavily)\n * - Custom headers that may affect response content: x-api-key (token-based access), x-requested-with (AJAX requests),\n * x-client-id (per-client/partner identity), x-tenant-id (multi-tenant segmentation), x-user-id (explicit user context),\n * x-app-version (version-specific behavior), x-feature-flag (feature rollout), x-device-id (per device/app instance),\n * x-platform (e.g. 'ios', 'android', 'web'), x-session-id (if it affects the response directly), x-locale (like accept-language)\n */\nconst CACHE_KEY_HEADERS =\n /^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;\n\n/**\n * Generates a unique cache key for a given URL and fetch options, ensuring that key factors\n * like method, headers, body, and other options are included in the cache key.\n * Headers and other objects are sorted by key to ensure consistent cache keys.\n *\n * @param {RequestConfig} config - The fetch options that may affect the request. The most important are:\n * @property {string} [method=\"GET\"] - The HTTP method (GET, POST, etc.).\n * @property {HeadersInit} [headers={}] - The request headers.\n * @property {BodyInit | null} [body=\"\"] - The body of the request (only for methods like POST, PUT).\n * @property {RequestCredentials} [credentials=\"same-origin\"] - Whether to include credentials (include, same-origin, omit).\n * @property {RequestCache} [cache=\"default\"] - The cache mode (e.g., default, no-store, reload).\n * @returns {string} - A unique cache key string based on the provided options.\n *\n * @example\n * const cacheKey = generateCacheKey({\n * url: 'https://api.example.com/data',\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'Alice' }),\n * mode: 'cors',\n * credentials: 'include',\n * });\n * console.log(cacheKey);\n */\nexport function generateCacheKey(\n config: RequestConfig,\n cacheKeyCheck = true,\n): string {\n // This is super fast. Effectively a no-op if cacheKey is\n // a string or a function that returns a string.\n const key = config.cacheKey;\n\n if (key && cacheKeyCheck) {\n return typeof key === STRING\n ? (key as string)\n : (key as CacheKeyFunction)(config);\n }\n\n const {\n url = '',\n method = GET,\n headers = null,\n body = null,\n credentials = 'same-origin',\n } = config;\n\n // Sort headers and body + convert sorted to strings for hashing purposes\n // Native serializer is on avg. 3.5x faster than a Fast Hash or FNV-1a\n let headersString = '';\n if (headers) {\n let obj: Record;\n\n if (headers instanceof Headers) {\n obj = processHeaders(headers);\n } else {\n obj = headers as Record;\n }\n\n // Filter headers to only include those that affect request identity\n // Include only headers that affect request identity, not execution behavior\n const keys = Object.keys(obj);\n const len = keys.length;\n\n // Sort keys manually for fastest deterministic output\n if (len > 1) {\n keys.sort();\n }\n\n let str = '';\n for (let i = 0; i < len; ++i) {\n if (CACHE_KEY_HEADERS.test(keys[i])) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // Concatenate all key parts into a cache key string\n // Template literals are apparently slower\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n return sanitizeCacheKey(cacheStr);\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING || isSearchParams(body)) {\n const str = String(body);\n\n bodyString = str.length < MIN_LENGTH_TO_HASH ? str : hash(str); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Files can't be read synchronously, so they are identified by their object\n bodyString +=\n key +\n '=' +\n (typeof value === STRING ? value : 'F' + getObjectId(value as File)) +\n '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (isObject(body) && !isJSONSerializable(body)) {\n // Blobs, buffers, streams etc. can't be read synchronously, so they are identified by their object.\n // Two different bodies never share a key, while the same body object is still deduplicated.\n bodyString = 'B' + getObjectId(body);\n } else {\n const o = isObject(body)\n ? JSON.stringify(sortObject(body))\n : String(body);\n\n bodyString = o.length > MIN_LENGTH_TO_HASH ? hash(o) : o;\n }\n }\n\n return sanitizeCacheKey(cacheStr + DELIMITER + bodyString);\n}\n\nconst objectIds = new WeakMap();\nlet lastObjectId = 0;\n\n/**\n * Returns a unique id for an object, e.g. a request body that can't be serialized.\n *\n * @param {object} obj - The object to identify.\n * @returns {number} - The id of the object.\n */\nfunction getObjectId(obj: object): number {\n let id = objectIds.get(obj);\n\n if (!id) {\n objectIds.set(obj, (id = ++lastObjectId));\n }\n\n return id;\n}\n\n/**\n * Prevents cache poisoning by removal of control chars and unusual characters.\n * When anything is removed, a hash of the original key is appended so that keys\n * differing only in the removed characters (e.g. `?a[]=1` and `?a=1`) don't collide.\n *\n * @param {string} cacheStr - The raw cache key.\n * @returns {string} - The sanitized cache key.\n */\nfunction sanitizeCacheKey(cacheStr: string): string {\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '') +\n DELIMITER +\n hash(cacheStr)\n : cacheStr;\n}\n\n/**\n * Checks if the cache entry is expired based on its timestamp and the expiry time.\n *\n * @param {CacheEntry} entry - The cache entry to check.\n * @returns {boolean} - Returns true if the cache entry is expired, false otherwise.\n */\nfunction isCacheExpired(entry: CacheEntry): boolean {\n // No expiry time means the entry never expires\n if (!entry.expiry) {\n return false;\n }\n\n return timeNow() > entry.expiry;\n}\n\n/**\n * Retrieves a cached response from the internal cache using the provided key.\n *\n * @param key - The unique key identifying the cached entry. If null, returns null.\n * @returns The cached {@link FetchResponse} if found, otherwise null.\n */\nexport function getCacheData<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n key: string | null,\n): FetchResponse | null {\n if (!key) {\n return null;\n }\n\n const entry = _cache.get(key);\n\n return entry ? entry.data : null;\n}\n\n/**\n * Retrieves a cache entry if it exists and is not expired.\n *\n * @param {string} key Cache key to utilize\n * @returns {CacheEntry | null} - The cache entry if it exists and is not expired, null otherwise.\n */\nexport function getCache(\n key: string | null,\n):\n | CacheEntry<\n FetchResponse\n >\n | null\n | undefined {\n return _cache.get(key as string);\n}\n\n/**\n * Sets a new cache entry or updates an existing one, with optional TTL (time-to-live).\n *\n * @param {string} key Cache key to utilize\n * @param {T} data - The data to be cached.\n * @param {number} [ttl] - Optional TTL in seconds. If not provided, the cache entry will not expire.\n * @param {number} [staleTime] - Optional stale time in seconds. If provided, the cache entry will be considered stale after this time.\n */\nexport function setCache(\n key: string,\n data: T,\n ttl?: number,\n staleTime?: number,\n): void {\n if (ttl === 0) {\n deleteCache(key);\n return;\n }\n\n const time = timeNow();\n const ttlMs = ttl ? ttl * 1000 : 0;\n const staleTimeMs = staleTime ? staleTime * 1000 : 0; // Ensure default value for staleTime\n\n _cache.set(key, {\n data,\n time,\n stale: staleTimeMs > 0 ? time + staleTimeMs : undefined, // Use undefined if staleTime is not set\n expiry: ttl === -1 ? undefined : time + ttlMs,\n });\n\n if (ttlMs > 0) {\n scheduleExpiry(key, ttlMs);\n }\n}\n\n/**\n * Deletes a cache entry once it expires.\n *\n * @param {string} key Cache key to utilize\n * @param {number} ms - The time until the entry expires, in milliseconds.\n */\nfunction scheduleExpiry(key: string, ms: number): void {\n addTimeout('c:' + key, () => deleteCache(key, true), ms);\n}\n\n/**\n * Invalidates (deletes) a cache entry.\n *\n * @param {string} key Cache key to utilize\n * @param {boolean} [removeExpired=false] - If true, only deletes the cache entry if it is expired or stale.\n */\nexport function deleteCache(key: string, removeExpired: boolean = false): void {\n if (removeExpired) {\n const entry = getCache(key);\n\n // If the entry does not exist, or it is neither expired nor stale, do not delete\n if (!entry || !isCacheExpired(entry)) {\n return;\n }\n }\n\n _cache.delete(key);\n\n const store = stores.get(key);\n\n if (store) {\n stores.delete(key);\n callStore(() => store.delete(key));\n }\n}\n\n/**\n * Prunes the cache by removing entries that have expired based on the provided cache time.\n */\nexport function pruneCache(): void {\n _cache.clear();\n stores.clear();\n}\n\n/**\n * Calls a cache store method. Store errors, e.g. of a full localStorage, are ignored so that they can't break requests.\n *\n * @param {() => unknown} fn - The function calling the store.\n */\nfunction callStore(fn: () => unknown): void {\n try {\n Promise.resolve(fn()).catch(noop);\n } catch {\n // Ignored\n }\n}\n\n/**\n * Saves a copy of a cached response in a cache store, so that it can be restored later, e.g. after a page reload.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheStore} [store] - The cache store. If not provided, nothing is saved.\n */\nfunction persistCache(key: string, store?: CacheStore): void {\n const entry = _cache.get(key);\n\n if (store && entry) {\n const { data, status, statusText, headers } = entry.data as FetchResponse;\n\n stores.set(key, store);\n callStore(() =>\n store.set(key, { ...entry, data: { data, status, statusText, headers } }),\n );\n }\n}\n\n/**\n * Reads the entry of a cache key from the cache store of a request, e.g. one saved during a previous page load.\n * Expired entries are deleted from the store.\n *\n * @param {string} key Cache key to utilize\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {Promise | null>} - The stored entry, or null if there is no valid one or the in-memory cache has an entry already.\n */\nexport async function getStoredCache(\n key: string,\n requestConfig: RequestConfig,\n): Promise | null> {\n const store = requestConfig.cacheStore;\n\n if (!store || isCacheBypassed(requestConfig)) {\n return null;\n }\n\n let entry: CacheEntry | null | undefined;\n\n try {\n entry = await store.get(key);\n } catch {\n // A failing store is treated like an empty one\n return null;\n }\n\n // Another request may have cached a response in the meantime\n if (!entry || _cache.has(key)) {\n return null;\n }\n\n if (isCacheExpired(entry)) {\n callStore(() => store.delete(key));\n\n return null;\n }\n\n return entry;\n}\n\n/**\n * Caches a response restored from a cache store in memory, keeping its original stale and expiry times.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheEntry} entry - The cache entry with the restored response.\n * @param {CacheStore} store - The cache store that the response was restored from.\n * @returns {boolean} - True if the restored response is fresh, false if it's stale.\n */\nexport function restoreCache(\n key: string,\n entry: CacheEntry,\n store: CacheStore,\n): boolean {\n _cache.set(key, entry);\n stores.set(key, store);\n\n if (entry.expiry) {\n scheduleExpiry(key, entry.expiry - timeNow());\n }\n\n notifySubscribers(key, entry.data);\n\n return !entry.stale || timeNow() < entry.stale;\n}\n\n/**\n * Mutates a cache entry with new data and optionally revalidates it.\n *\n * @param {string | null} key Cache key to utilize. If null, no mutation occurs.\n * @param {ResponseData} newData - The new data to be cached.\n * @param {MutationSettings|undefined} settings - Mutation settings.\n */\nexport async function mutate<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n key: string | null,\n newData: ResponseData,\n settings?: MutationSettings,\n): Promise | null> {\n // If no key is provided, do nothing\n if (!key) {\n return null;\n }\n\n const entry = getCache(\n key,\n );\n\n if (!entry) {\n return null;\n }\n\n const updatedData = isObject(newData) ? sanitizeObject(newData) : newData;\n\n const updatedResponse = {\n ...entry.data,\n data: updatedData,\n };\n\n // The ETag belongs to the original data, so the changed data must not be revalidated with it\n const headers = updatedResponse.headers;\n\n if (headers && headers.etag) {\n updatedResponse.headers = { ...headers };\n delete updatedResponse.headers.etag;\n }\n\n const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n persistCache(key, stores.get(key));\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\n}\n\n/**\n * Checks whether a request should bypass the cache, because of its cache buster or `cache: 'reload'`.\n *\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {boolean} - True if the cache should be bypassed.\n */\nexport function isCacheBypassed(requestConfig: RequestConfig): boolean {\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n\n return (\n !!(buster && buster(requestConfig)) || requestConfig.cache === 'reload'\n );\n}\n\n/**\n * Retrieves a cached response if available and valid, otherwise returns null.\n *\n * @template ResponseData - The type of the response data.\n * @template RequestBody - The type of the request body.\n * @template QueryParams - The type of the query parameters.\n * @template PathParams - The type of the path parameters.\n * @param {string | null} cacheKey - The cache key to look up.\n * @param {number | undefined} cacheTime - The maximum time to cache entry.\n * @param {RequestConfig} requestConfig - The fetcher configuration.\n * @returns {FetchResponse | null} - The cached response or null.\n */\nexport function getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n cacheKey: string | null,\n cacheTime: number | undefined,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): FetchResponse | null {\n // If cache key or time is not provided, return null\n if (!cacheKey || cacheTime === undefined || cacheTime === null) {\n return null;\n }\n\n if (isCacheBypassed(requestConfig)) {\n return null;\n }\n\n // Retrieve the cached entry\n const entry = getCache(\n cacheKey,\n );\n\n if (!entry) {\n return null;\n }\n\n const isExpired = isCacheExpired(entry);\n\n // If completely expired, delete and return null\n if (isExpired) {\n deleteCache(cacheKey);\n return null;\n }\n\n const data = entry.data;\n\n // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n // The placeholder stored while a request is in flight is not a response, so treat it as a miss\n return data && data.isFetching ? null : data;\n}\n\n/**\n * Sets or deletes the response cache based on cache settings and notifies subscribers.\n *\n * @param {FetchResponse} output - The response to cache.\n * @param {RequestConfig} requestConfig - The request configuration.\n * @param {boolean} [isError=false] - Whether the response is an error.\n */\nexport function handleResponseCache<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n output: FetchResponse,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n isError: boolean = false,\n): void {\n // It is string as it is called once request is made\n const cacheKey = requestConfig.cacheKey as string;\n\n if (cacheKey) {\n const cacheTime = requestConfig.cacheTime;\n const skipCache = requestConfig.skipCache;\n\n // Fast path: only set cache if cacheTime is positive and not skipping cache\n if (\n cacheTime &&\n (!isError || requestConfig.cacheErrors) &&\n !(skipCache && skipCache(output, requestConfig))\n ) {\n setCache(cacheKey, output, cacheTime, requestConfig.staleTime);\n\n // Error responses are only cached in memory\n if (!isError) {\n persistCache(cacheKey, requestConfig.cacheStore);\n }\n } else {\n const entry = getCache(cacheKey);\n\n // Don't let the in-flight placeholder outlive a request whose result isn't cached\n if (entry && entry.data && entry.data.isFetching) {\n deleteCache(cacheKey);\n }\n }\n\n notifySubscribers(cacheKey, output);\n removeInFlight(cacheKey);\n\n const prevCacheKey = requestConfig._prevKey;\n\n if (prevCacheKey) {\n removeInFlight(prevCacheKey);\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { mutate } from './cache-manager';\nimport {\n APPLICATION_CONTENT_TYPE,\n APPLICATION_JSON,\n CONTENT_TYPE,\n FUNCTION,\n STRING,\n} from './constants';\nimport {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n ResponseError,\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n} from './types';\nimport { flattenData, isObject, processHeaders } from './utils';\n\n/**\n * Parses the response data based on the Content-Type header, or reads it as the given response type.\n *\n * @param response - The Response object to parse.\n * @param responseType - How to read the body regardless of its Content-Type, e.g. as a Blob, or `'stream'` to leave it unread.\n * @returns A Promise that resolves to the parsed data.\n */\nexport async function parseResponseData<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse,\n responseType?: RequestConfig['responseType'],\n): Promise {\n // Bail early if response is null or undefined\n if (!response) {\n return null;\n }\n\n // Get the content-type header once\n const headers = (response as Response).headers;\n let contentType = headers && headers.get(CONTENT_TYPE);\n\n if (contentType) {\n // Lowercase and trim for consistent matching\n contentType = contentType.toLowerCase().trim();\n } else {\n contentType = '';\n }\n\n // Split for mime type without charset\n const mimeType = contentType.split(';', 1)[0];\n\n let data;\n\n try {\n if (responseType) {\n // The body is read as requested, or left unread as a stream to be read by the caller\n data =\n responseType === 'stream'\n ? response.body\n : await response[responseType]();\n } else if (\n mimeType.includes(APPLICATION_JSON) ||\n mimeType.includes('+json')\n ) {\n data = await response.json(); // Parse JSON response\n } else if (\n (mimeType.includes('multipart/form-data') || // Parse as FormData\n mimeType.includes(\n APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded', // Handle URL-encoded forms\n )) &&\n typeof response.formData === FUNCTION\n ) {\n data = await response.formData();\n } else if (/^(image|video|audio)\\/|octet-stream|pdf|zip/.test(mimeType)) {\n data = await response.arrayBuffer(); // Parse as ArrayBuffer for binary types\n } else {\n data = await response.text();\n\n if (typeof data === STRING) {\n const trimmed = data.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n data = JSON.parse(trimmed);\n } catch {\n // leave as text if parsing fails\n }\n }\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (_error) {\n // Parsing failed, fallback to null\n data = null;\n }\n\n return data;\n}\n\n/**\n * Prepare response object with additional information.\n *\n * @param Response. It may be \"null\" in case of request being aborted.\n * @param {RequestConfig} config - Request config\n * @param error - whether the response is erroneous\n * @returns {FetchResponse} Response data\n */\nexport const prepareResponse = <\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n config: RequestConfig,\n error: ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null,\n): FetchResponse => {\n const defaultResponse = config.defaultResponse;\n const cacheKey = config.cacheKey;\n const mutatator = mutate.bind(null, cacheKey as string) as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >['mutate'];\n\n // This may happen when request is cancelled.\n if (!response) {\n return {\n ok: false,\n // Enhance the response with extra information\n error,\n data: defaultResponse ?? null,\n headers: null,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: false,\n isError: true,\n } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n const isNativeResponse =\n typeof Response === FUNCTION && response instanceof Response;\n\n let data = response.data;\n\n // Set the default response if the provided data is an empty object or array\n // Other objects, e.g. Blobs, buffers and streams, have no keys either, but aren't empty\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (/^\\[object (Object|Array)\\]$/.test(\n Object.prototype.toString.call(data),\n ) &&\n Object.keys(data).length === 0))\n ) {\n response.data = data = defaultResponse;\n }\n\n if (config.flattenResponse) {\n response.data = data = flattenData(data);\n }\n\n if (config.select) {\n response.data = data = config.select(data);\n }\n\n const headers = processHeaders(response.headers);\n\n // Native fetch Response extended by extra information\n if (isNativeResponse) {\n const output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > = {\n body: response.body,\n bodyUsed: response.bodyUsed,\n ok: response.ok,\n redirected: response.redirected,\n type: response.type,\n url: response.url,\n status: response.status,\n statusText: response.statusText,\n\n // Convert methods to use arrow functions to preserve correct return types\n // Lazily construct Blob from ArrayBuffer\n blob: async () =>\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n json: async () => data as ResponseData, // Return the already parsed JSON data\n text: async () => data as string, // Return the already parsed text data\n // The body was already read, so a copy of this response is returned instead of Response.clone()\n clone: () => ({ ...output }),\n arrayBuffer: async () =>\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0), // Return the ArrayBuffer directly\n formData: async () => (data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: async () =>\n new Uint8Array(data instanceof ArrayBuffer ? data : new ArrayBuffer(0)),\n // Enhance the response with extra information\n error,\n data,\n headers,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: response.ok && !error,\n isError: !!error,\n };\n\n return output;\n }\n\n // If it's a custom fetcher, and it does not return any Response instance, it may have its own internal handler\n if (isObject(response)) {\n Object.assign(response, {\n error,\n headers,\n isFetching: false,\n mutate: mutatator,\n isSuccess: response.ok && !error,\n isError: !!error,\n });\n }\n\n return response;\n};\n","import { applyInterceptors } from './interceptor-manager';\nimport type { FetchResponse, RetryConfig, RetryFunction } from './types';\nimport { delayInvocation, timeNow } from './utils';\nimport { generateCacheKey } from './cache-manager';\nimport { FUNCTION } from './constants';\n\nfunction getMsFromHttpDate(dateString: string): number | null {\n const ms = Date.parse(dateString) - timeNow();\n\n if (!isNaN(ms)) {\n return Math.max(0, Math.floor(ms));\n }\n return null;\n}\n\n/**\n * Calculates the number of milliseconds to wait before retrying a request,\n * based on the `Retry-After` HTTP header in the provided response.\n *\n * The function supports both numeric (seconds) and HTTP-date formats for the `Retry-After` header.\n * - If the header is a number, it is interpreted as seconds and converted to milliseconds.\n * - If the header is a date, the function calculates the difference between the date and the current time.\n *\n * @param extendedResponse - The response object containing headers, or `null`.\n * @returns The number of milliseconds to wait before retrying, or `null` if the header is not present or invalid.\n */\nexport function getRetryAfterMs(\n extendedResponse: FetchResponse | null,\n): number | null {\n if (!extendedResponse) {\n return null;\n }\n\n const headers = extendedResponse.headers || {};\n const retryAfter = headers['retry-after'];\n\n if (retryAfter) {\n // Try parsing as seconds\n const seconds = Number(retryAfter);\n\n if (!isNaN(seconds) && seconds >= 0) {\n return seconds * 1000;\n }\n\n const ms = getMsFromHttpDate(retryAfter);\n\n if (ms !== null) {\n return ms;\n }\n }\n\n // Headers are already in lowercase\n const RATELIMIT_RESET = 'ratelimit-reset';\n\n // Unix timestamp when the rate limit window resets (relative to current time)\n // Fallback to checking 'ratelimit-reset-after' OR 'x-ratelimit-reset-after' headers\n const rateLimitResetAfter =\n headers[RATELIMIT_RESET + '-after'] ||\n headers['x-' + RATELIMIT_RESET + '-after'];\n\n if (rateLimitResetAfter) {\n const seconds = Number(rateLimitResetAfter);\n\n if (!isNaN(seconds)) {\n return seconds * 1000;\n }\n }\n\n // ISO 8601 datetime when the rate limit resets\n // Fallback to checking 'ratelimit-reset-at' 'x-ratelimit-reset-at' headers\n const rateLimitResetAt =\n headers[RATELIMIT_RESET + '-at'] || headers['x-' + RATELIMIT_RESET + '-at'];\n\n if (rateLimitResetAt) {\n return getMsFromHttpDate(rateLimitResetAt);\n }\n\n return null;\n}\n\n/**\n * Executes a request function with retry logic according to the provided configuration.\n *\n * The function attempts the request up to the specified number of retries, applying delay and backoff strategies.\n * Retries can be triggered based on response status codes, custom logic, or the presence of a `Retry-After` header.\n * Optionally, an `onRetry` interceptor can be invoked before each retry attempt.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param requestFn - The function that performs the request. Receives `isStaleRevalidation` and `attempt` as arguments.\n * @param config - The retry configuration, including retry count, delay, backoff, retry conditions, and hooks.\n * @returns A promise resolving to the fetch response, or rejecting if all retries are exhausted.\n * @throws Error if the maximum number of retries is exceeded or a non-retriable error occurs.\n */\nexport async function withRetry<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation: boolean,\n attempt: number,\n ) => Promise<\n FetchResponse\n >,\n config: RetryConfig,\n): Promise> {\n const {\n retries = 0,\n delay = 0,\n backoff = 1,\n maxDelay,\n retryOn = [],\n shouldRetry,\n jitter,\n methods,\n } = config;\n\n let attempt = 0;\n let waitTime = delay;\n const maxRetries = retries > 0 ? retries : 0;\n let output: FetchResponse;\n\n while (attempt <= maxRetries) {\n // Subsequent attempts will have output defined, but the first attempt may not.\n // Let's apply onRetry interceptor and regenerate cache key if ot really changes.\n if (attempt > 0 && output!) {\n const cfg = output.config;\n const onRetry = cfg.onRetry;\n\n if (onRetry) {\n await applyInterceptors(onRetry, output, attempt);\n\n // If the key was automatically generated, we need to regenerate it as config may change.\n // We don't detect whether config changed for performance reasons.\n if (cfg._isAutoKey) {\n cfg._prevKey = cfg.cacheKey as string;\n cfg.cacheKey = generateCacheKey(cfg, false);\n }\n }\n }\n\n // Performance optimization: Call the request function with the current attempt number\n // If this is the first attempt, we pass `isStaleRevalidation` as `false`,\n // otherwise we pass `true` to indicate that this is a stale revalidation (no cache hit).\n output = await requestFn(attempt > 0, attempt);\n const error = output.error;\n\n // Stop unless a failed response should be retried according to the retry settings,\n // or a successful one according to shouldRetry\n if (\n error\n ? await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n methods,\n )\n : !(\n shouldRetry &&\n attempt < maxRetries &&\n (await shouldRetry(output, attempt))\n )\n ) {\n break;\n }\n\n // The delay before the next retry, randomized with jitter unless the server asks for one below\n let retryDelay = withJitter(waitTime, jitter);\n\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (error && (error.status === 429 || error.status === 503)) {\n // Try to extract the \"Retry-After\" value from the response headers\n const retryAfterMs = getRetryAfterMs(output);\n\n // If a valid retry-after value is found, override the wait time before next retry\n // Cap it with maxDelay so that a server can't make the client wait indefinitely\n if (retryAfterMs !== null) {\n retryDelay = waitTime = Math.min(\n retryAfterMs,\n maxDelay || retryAfterMs,\n );\n }\n }\n\n await delayInvocation(retryDelay);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n }\n\n return output!;\n}\n\n/**\n * Determines whether to stop retrying based on the error, current attempt count, and retry configuration.\n *\n * This function checks:\n * - If the maximum number of retries has been reached.\n * - If the request was aborted, e.g. with its signal or by a newer request. Aborted requests are never retried.\n * - If a custom `shouldRetry` callback is provided, its result is used to decide.\n * - If no custom logic is provided, falls back to checking if the error status is included in the `retryOn` list,\n * and the request method in the `methods` list, if any.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param output - The response object containing the error and request configuration.\n * @param attempt - The current retry attempt number.\n * @param maxRetries - The maximum number of retry attempts allowed.\n * @param shouldRetry - Optional custom function to determine if a retry should occur.\n * @param retryOn - Optional list of HTTP status codes that should trigger a retry.\n * @param methods - Optional list of request methods that are retried on the `retryOn` statuses. All methods are retried without it.\n * @returns A promise resolving to `true` if retrying should stop, or `false` to continue retrying.\n */\nexport async function getShouldStopRetrying<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n output: FetchResponse,\n attempt: number,\n maxRetries: number,\n shouldRetry?: RetryFunction<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n retryOn: number[] = [],\n methods?: string[],\n): Promise {\n // Safety first: always respect max retries\n // We check retries provided regardless of the shouldRetry being provided so to avoid infinite loops.\n // It is a fail-safe so to prevent excessive retry attempts even if custom retry logic suggests a retry.\n if (attempt === maxRetries) {\n return true;\n }\n\n // Aborted requests are never retried, as e.g. a retry of one cancelled by a newer request would cancel the newer one\n if (output.error?.isCancelled) {\n return true;\n }\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n\n if (result !== null) {\n return !result;\n }\n }\n\n return !(\n (retryOn || []).includes(output.error?.status ?? 0) &&\n (!methods ||\n methods.some((method) => method.toUpperCase() === output.config.method))\n );\n}\n\n/**\n * Randomizes a retry delay with jitter, so that clients that failed at the same time, e.g. during an outage, don't retry all at once.\n *\n * @param delay - The delay computed from the `delay`, `backoff` and `maxDelay` settings, in milliseconds.\n * @param jitter - `true` for a random delay between 0 and the computed one (\"full jitter\"), or a function that returns the delay to use.\n * @returns The delay to wait before the retry, in milliseconds.\n */\nfunction withJitter(delay: number, jitter: RetryConfig['jitter']): number {\n return typeof jitter === FUNCTION\n ? (jitter as (delay: number) => number)(delay)\n : jitter\n ? Math.random() * delay\n : delay;\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation, isOffline, isPageHidden } from './utils';\n\n/**\n * Executes a request function with polling, stopping when shouldStopPolling returns true,\n * pollingInterval is not set, or maxAttempts is reached.\n * Polling pauses while the page is hidden or the browser is offline, unless allowed by refreshWhenHidden or refreshWhenOffline.\n *\n * @template Output The type of the output returned by the request function.\n * @param requestFn - The function that performs a single request (with retries).\n * @param pollingInterval - Interval in ms between polling attempts.\n * @param shouldStopPolling - Function to determine if polling should stop.\n * @param maxAttempts - Maximum number of polling attempts, default: 0 (unlimited).\n * @param pollingDelay - Delay in ms before each polling attempt, default: 0.\n * @param refreshWhenHidden - Whether to keep polling while the page is hidden, default: false.\n * @param refreshWhenOffline - Whether to keep polling while the browser is offline, default: false.\n * @param signal - The signal passed to the request. Polling stops once it is aborted.\n * @returns The final output from the last request.\n */\nexport async function withPolling<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation?: boolean,\n attempt?: number,\n ) => Promise<\n FetchResponse\n >,\n pollingInterval?: RequestConfig['pollingInterval'],\n shouldStopPolling?: RequestConfig['shouldStopPolling'],\n maxAttempts = 0,\n pollingDelay = 0,\n refreshWhenHidden = false,\n refreshWhenOffline = false,\n signal?: AbortSignal,\n): Promise> {\n if (!pollingInterval) {\n return requestFn();\n }\n\n let pollingAttempt = 0;\n let output: FetchResponse;\n\n while (maxAttempts === 0 || pollingAttempt < maxAttempts) {\n if (pollingDelay > 0) {\n await delayInvocation(pollingDelay, signal);\n }\n\n output = await requestFn();\n\n pollingAttempt++;\n\n if (\n (maxAttempts > 0 && pollingAttempt >= maxAttempts) ||\n !pollingInterval ||\n (shouldStopPolling && shouldStopPolling(output, pollingAttempt))\n ) {\n break;\n }\n\n // Wait for the next attempt, and keep waiting while polling is paused\n do {\n await delayInvocation(pollingInterval, signal);\n\n // Aborting the signal of the request stops polling\n if (signal && signal.aborted) {\n return output;\n }\n } while (\n (!refreshWhenHidden && isPageHidden()) ||\n (!refreshWhenOffline && isOffline())\n );\n }\n\n return output!;\n}\n","import { ABORT_ERROR, UNDEFINED } from './constants';\nimport type { RequestConfig, UploadProgress } from './types';\nimport { createAbortError } from './utils';\n\n// Responses with these statuses can't have a body\nconst NULL_BODY_STATUSES = [204, 205, 304];\n\n// Headers that browsers don't let requests set. fetch() skips them silently, while\n// XMLHttpRequest logs errors for them, so they are skipped before sending.\nconst FORBIDDEN_HEADERS =\n /^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/;\n\n// ReadableStream is missing in some environments, e.g. React Native\nconst isStream = (body: unknown): body is ReadableStream =>\n typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream;\n\nexport const toProgress = (loaded: number, total?: number): UploadProgress => ({\n loaded,\n total,\n progress: total ? loaded / total : undefined,\n});\n\n/**\n * Sends a request and reports the upload progress of its body to `onUploadProgress`.\n * Browsers and React Native don't report the upload progress of fetch(), so XMLHttpRequest is used there.\n * Elsewhere, e.g. in Node.js, the body is streamed with fetch() and counted while it is sent.\n *\n * @param {string} url - The request URL.\n * @param {RequestConfig} config - The request configuration, with a body and `onUploadProgress`.\n * @returns {Promise} - The response.\n */\nexport function fetchWithUploadProgress(\n url: string,\n config: RequestConfig,\n): Promise {\n const body = config.body as BodyInit;\n\n return typeof XMLHttpRequest !== UNDEFINED && !isStream(body)\n ? sendWithXhr(url, config, body)\n : sendStreamed(url, config, body);\n}\n\nfunction sendWithXhr(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n // fetchf() always sets the signal, as it handles timeouts and cancellation with it\n const signal = config.signal!;\n const abort = () => xhr.abort();\n\n const settle = (fn: () => void) => {\n signal.removeEventListener('abort', abort);\n\n try {\n fn();\n } catch (error) {\n reject(error);\n }\n };\n\n xhr.open(config.method as string, url);\n xhr.responseType = 'blob';\n xhr.withCredentials = config.credentials === 'include';\n\n new Headers(config.headers).forEach(\n (value, name) =>\n FORBIDDEN_HEADERS.test(name) || xhr.setRequestHeader(name, value),\n );\n\n xhr.upload.onprogress = (event) =>\n config.onUploadProgress!(\n toProgress(\n event.loaded,\n event.lengthComputable ? event.total : undefined,\n ),\n );\n\n xhr.onload = () =>\n settle(() => {\n const headers = new Headers();\n\n for (const line of xhr.getAllResponseHeaders().split(/\\r?\\n/)) {\n const index = line.indexOf(':');\n\n if (index > 0) {\n headers.append(line.slice(0, index), line.slice(index + 1).trim());\n }\n }\n\n const response = new Response(\n NULL_BODY_STATUSES.includes(xhr.status) ? null : xhr.response,\n { status: xhr.status, statusText: xhr.statusText, headers },\n );\n\n // Like fetch(), the response tells its final URL, e.g. after redirects\n Object.defineProperty(response, 'url', { value: xhr.responseURL });\n\n resolve(response);\n });\n\n xhr.onerror = () =>\n settle(() => reject(new TypeError('Network request failed')));\n\n // Like fetch(), aborted requests reject with the reason of the abort signal\n const onAbort = () =>\n settle(() =>\n reject(\n signal.reason ||\n createAbortError('The request was aborted', ABORT_ERROR),\n ),\n );\n\n xhr.onabort = onAbort;\n\n if (signal.aborted) {\n return onAbort();\n }\n\n signal.addEventListener('abort', abort);\n\n xhr.send(body as XMLHttpRequestBodyInit);\n });\n}\n\nasync function sendStreamed(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n const headers = new Headers(config.headers);\n let stream = body as ReadableStream;\n let total: number | undefined;\n\n if (!isStream(body)) {\n // Serialize the body like fetch() would, to know its size and content type\n const blob = body instanceof Blob ? body : await new Response(body).blob();\n\n total = blob.size;\n stream = blob.stream();\n\n if (blob.type && !headers.has('content-type')) {\n headers.set('content-type', blob.type);\n }\n }\n\n let loaded = 0;\n\n return fetch(url, {\n ...config,\n headers,\n body: stream.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n config.onUploadProgress!(toProgress(loaded, total));\n controller.enqueue(chunk);\n },\n }),\n ),\n // Required by fetch() to send a stream\n duplex: 'half',\n } as RequestInit);\n}\n","import { FUNCTION } from './constants';\nimport type { DownloadProgress } from './types';\nimport { toProgress } from './upload-progress';\n\n/**\n * Reports the download progress of a response body to `onDownloadProgress` while the body is read.\n * The body is counted as it arrives, so the progress follows the download.\n *\n * @param {T} response - The response. Other than native responses with a body, e.g. responses of HEAD requests or custom fetchers, are returned as they are.\n * @param {Function} [onDownloadProgress] - The function called with the progress. Without it, the response is returned as it is.\n * @returns {T} - A copy of the response, whose body is counted while it's read.\n */\nexport function withDownloadProgress(\n response: T,\n onDownloadProgress?: (progress: DownloadProgress) => void,\n): T {\n // Response is missing in some environments, and response bodies e.g. in React Native\n if (\n !onDownloadProgress ||\n typeof Response !== FUNCTION ||\n !(response instanceof Response) ||\n !response.body\n ) {\n return response;\n }\n\n const headers = response.headers;\n // Content-Length is the size of the compressed body, so the size of a compressed one is unknown\n const total = headers.has('content-encoding')\n ? undefined\n : Number(headers.get('content-length')) || undefined;\n let loaded = 0;\n\n const counted = new Response(\n response.body.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n // Browsers may hide the Content-Encoding header of cross-origin responses, so the progress is capped at 1\n onDownloadProgress(\n toProgress(loaded, total && Math.max(total, loaded)),\n );\n controller.enqueue(chunk);\n },\n }),\n ),\n response,\n );\n\n // Like the original response, the copy tells its final URL, whether it was redirected and its type\n for (const key of ['url', 'redirected', 'type'] as const) {\n Object.defineProperty(counted, key, { value: response[key] });\n }\n\n return counted as T;\n}\n","import type { ResponseError } from './errors/response-error';\nimport type {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n} from './types/request-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { handleResponseCache } from './cache-manager';\nimport { ABORT_ERROR, REJECT } from './constants';\nimport {\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n HeadersObject,\n} from './types';\nimport { processHeaders } from './utils';\n\n/**\n * Handles final processing for both success and error responses\n * Applies error interceptors, caching, notifications, and error strategy\n */\nexport async function withErrorHandling<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n isStaleRevalidation: boolean,\n requestFn: (\n isStaleRevalidation: boolean,\n ) => Promise<\n FetchResponse\n >,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): Promise> {\n const output = await requestFn(isStaleRevalidation);\n const error = output.error;\n\n if (!error) {\n // SUCCESS PATH\n handleResponseCache(output, requestConfig);\n\n return output;\n }\n\n // ERROR PATH\n\n if (requestConfig.onError) {\n await applyInterceptors(requestConfig.onError, error);\n }\n\n // Timeouts and request cancellations using AbortController do not throw any errors unless rejectCancelled is true.\n // Only handle the error if the request was not cancelled, or if it was cancelled and rejectCancelled is true.\n const isCancelled = error.isCancelled;\n\n const logger = requestConfig.logger;\n\n if (!isCancelled && logger && logger.warn) {\n logger.warn('FETCH ERROR', redactError(error as ResponseError));\n }\n\n // The defaultResponse strategy returns the default response in place of the error data.\n // The original data stays available through error.response.\n if (requestConfig.strategy === 'defaultResponse') {\n output.data = (requestConfig.defaultResponse ?? null) as typeof output.data;\n }\n\n // Handle cache and notifications FIRST (before strategy)\n handleResponseCache(output, requestConfig, true);\n\n // handle error strategy as the last part\n const shouldHandleError = !isCancelled || requestConfig.rejectCancelled;\n\n if (shouldHandleError) {\n const strategy = requestConfig.strategy;\n // Reject the promise\n if (strategy === REJECT) {\n throw error;\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\n}\n\n// Credential headers that must not end up in logs\nconst SENSITIVE_HEADERS = [\n 'authorization',\n 'proxy-authorization',\n 'cookie',\n 'x-api-key',\n];\n\n/**\n * Creates a copy of the error for logging, with credential headers masked and the request body removed.\n * The error itself is left untouched.\n */\nfunction redactError(error: ResponseError): ResponseError {\n // Cache keys are dropped too, as they can contain short request bodies\n const config = {\n ...error.config,\n body: undefined,\n data: undefined,\n cacheKey: undefined,\n _prevKey: undefined,\n headers: processHeaders(error.config.headers as HeadersObject),\n };\n\n for (const name of SENSITIVE_HEADERS) {\n if (config.headers[name]) {\n config.headers[name] = '[REDACTED]';\n }\n }\n\n const copy = Object.assign(new Error(error.message), error, {\n config,\n request: config,\n response: error.response && { ...error.response, config },\n });\n\n copy.name = error.name;\n copy.stack = error.stack;\n\n return copy;\n}\n\nexport function enhanceError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): void {\n error.status = error.status || (response && response.status) || 0;\n error.statusText =\n error.statusText || (response && response.statusText) || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n HeadersObject,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport type { StoredResponse } from './types/cache-manager';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject, noop, processHeaders } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport {\n generateCacheKey,\n getCacheData,\n getCachedResponse,\n getStoredCache,\n isCacheBypassed,\n restoreCache,\n setCache,\n} from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { fetchWithUploadProgress } from './upload-progress';\nimport { withDownloadProgress } from './download-progress';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION, GET, HEAD } from './constants';\nimport { buildConfig } from './config-handler';\n\nconst inFlightResponse = Object.freeze({\n isFetching: true,\n});\n\n/**\n * Sends an HTTP request to the specified URL using the provided configuration and returns a typed response.\n *\n * @typeParam ResponseData - The expected shape of the response data. Defaults to `DefaultResponse`.\n * @typeParam RequestBody - The type of the request payload/body. Defaults to `DefaultPayload`.\n * @typeParam QueryParams - The type of the query parameters. Defaults to `DefaultParams`.\n * @typeParam PathParams - The type of the path parameters. Defaults to `DefaultUrlParams`.\n *\n * @param url - The endpoint URL to which the request will be sent.\n * @param config - Optional configuration object for the request, including headers, method, body, query, and path parameters.\n *\n * @returns A promise that resolves to a `FetchResponse` containing the typed response data and request metadata.\n *\n * @example\n * ```typescript\n * const { data } = await fetchf('/api/user', { method: 'GET' });\n * console.log(data);\n * ```\n */\nexport async function fetchf<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n url: string,\n reqConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null = null,\n): Promise> {\n // Ultra-fast early cache check if cacheKey is provided as a string\n // For workloads dominated by repeated requests, this string caching optimization\n // can potentially support millions of requests per second with minimal CPU overhead\n if (reqConfig && typeof reqConfig.cacheKey === 'string') {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(reqConfig.cacheKey, reqConfig.cacheTime, reqConfig);\n\n if (cached) {\n return cached;\n }\n }\n\n const fetcherConfig = buildConfig<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(url, reqConfig);\n\n const {\n timeout,\n cancellable,\n cacheKey,\n dedupeTime,\n cacheTime,\n staleTime,\n refetchOnFocus,\n refetchOnReconnect,\n pollingInterval = 0,\n } = fetcherConfig;\n const isCacheEnabled = cacheTime !== undefined || staleTime !== undefined;\n const method = fetcherConfig.method;\n\n // Cached responses of GET and HEAD requests are revalidated with their ETag.\n // Custom fetchers may not handle 304 responses, so they only send it when it's enabled for them.\n const isETagEnabled =\n isCacheEnabled &&\n (method === GET || method === HEAD) &&\n (fetcherConfig.etag ?? !fetcherConfig.fetcher);\n\n const needsCacheKey = !!(\n cacheKey ||\n timeout ||\n dedupeTime ||\n isCacheEnabled ||\n cancellable ||\n refetchOnFocus ||\n refetchOnReconnect\n );\n\n let _cacheKey: string | null = null;\n\n // Generate cache key if required\n if (needsCacheKey) {\n _cacheKey = generateCacheKey(fetcherConfig);\n }\n\n // The initial data, which is used as the first response instead of sending the request\n let initialResponse: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n // Cache handling logic\n if (_cacheKey && isCacheEnabled) {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(_cacheKey, cacheTime, fetcherConfig);\n\n if (cached) {\n return cached;\n }\n\n // Restore the response from the cache store, e.g. one saved during a previous page load\n if (fetcherConfig.cacheStore) {\n const stored = await getStoredCache(_cacheKey, fetcherConfig);\n const restored =\n stored &&\n toResponse(\n stored.data,\n _cacheKey,\n fetcherConfig,\n );\n\n // A stale response is shown until the request below revalidates it\n if (\n restored &&\n restoreCache(\n _cacheKey,\n { ...stored, data: restored },\n fetcherConfig.cacheStore,\n )\n ) {\n return restored;\n }\n }\n\n // While there's no cached response, the initial data, e.g. data rendered on the server, is cached as the response\n if (\n fetcherConfig.initialData !== undefined &&\n !getCacheData(_cacheKey) &&\n !isCacheBypassed(fetcherConfig)\n ) {\n initialResponse = toResponse(\n {\n data: fetcherConfig.initialData,\n status: 200,\n statusText: '',\n headers: {},\n },\n _cacheKey,\n fetcherConfig,\n );\n }\n }\n\n // Deduplication logic\n if (_cacheKey && dedupeTime) {\n const inflight = getInFlightPromise<\n FetchResponse\n >(_cacheKey, dedupeTime);\n\n if (inflight) {\n return inflight;\n }\n }\n\n const retryConfig = fetcherConfig.retry || {};\n const { retries = 0, resetTimeout } = retryConfig;\n\n // The signal passed to the request. Each attempt replaces it in the config with a signal of its own.\n const userSignal = fetcherConfig.signal;\n\n // The actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation: boolean, attempt = 0) => {\n // The cached response to revalidate. It's read before the cache is marked as fetching below.\n const cached =\n isETagEnabled &&\n getCacheData(\n _cacheKey,\n );\n\n // If cache key is specified, we will handle optimistic updates\n // and mark the request as in-flight, so to catch \"fetching\" state.\n // This is useful for Optimistic UI updates (e.g., showing loading spinners).\n if (!attempt) {\n // The initial data is only used once, as the first response\n if (initialResponse) {\n const response = initialResponse;\n\n initialResponse = null;\n\n return response;\n }\n\n if (_cacheKey && !isStaleRevalidation) {\n if (staleTime) {\n const existingCache = getCachedResponse(\n _cacheKey,\n cacheTime,\n fetcherConfig,\n );\n\n // Don't notify subscribers when cache exists\n // Let them continue showing stale data during background revalidation\n if (!existingCache) {\n setCache(_cacheKey, inFlightResponse, cacheTime, staleTime);\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n } else {\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n }\n\n // Attach cache key so that it can be reused in interceptors or in the final response\n fetcherConfig.cacheKey = _cacheKey;\n }\n\n const url = fetcherConfig.url as string;\n\n // Add the request to the queue. Make sure to handle deduplication, cancellation, timeouts in accordance to retry settings\n const controller = markInFlight(\n _cacheKey,\n url,\n timeout,\n dedupeTime || 0,\n !!cancellable,\n // Enable timeout either by default or when retries & resetTimeout are enabled\n !!(timeout && (!attempt || resetTimeout)),\n );\n\n // Do not create a shallow copy to maintain idempotency here.\n // This ensures the original object is mutated by interceptors whenever needed, including retry logic.\n const requestConfig = fetcherConfig;\n\n requestConfig.signal = controller.signal;\n\n // The request is aborted along with the signal passed to it, which may have been aborted already\n const abort = () => controller.abort(userSignal!.reason);\n\n if (userSignal) {\n if (userSignal.aborted) {\n abort();\n } else {\n userSignal.addEventListener('abort', abort);\n }\n }\n\n let output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n let response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n try {\n if (fetcherConfig.onRequest) {\n // Zero-allocation yield to microtask queue so the outer fetchf() can call setInFlightPromise()\n // before onRequest interceptors run. This ensures that if onRequest triggers\n // another fetchf() with the same cacheKey, getInFlightPromise() finds item[4].\n // On retries (attempt > 0), setInFlightPromise() was already called during the first attempt.\n // The promise stored in item[4] is the outer doRequestPromise which covers all retries.\n // So the race only matters on the very first attempt when the outer scope hasn't had a chance to call setInFlightPromise() yet.\n if (_cacheKey && dedupeTime && !attempt) {\n await null;\n }\n\n await applyInterceptors(fetcherConfig.onRequest, requestConfig);\n }\n\n // Custom fetcher\n const fn = fetcherConfig.fetcher;\n const init = withETag(requestConfig, cached);\n\n response = (fn\n ? await fn(\n url,\n init,\n )\n : // Uploads with onUploadProgress are sent in a way that reports their progress\n await (requestConfig.onUploadProgress && requestConfig.body\n ? fetchWithUploadProgress(url, requestConfig)\n : fetch(url, init as RequestInit))) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Reports the download progress while the body is read\n response = withDownloadProgress(\n response,\n requestConfig.onDownloadProgress,\n );\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\n // The server answered that the cached response is still valid, so it's reused instead of being sent again.\n // Like other cached responses, it has been parsed and transformed already.\n if (init !== requestConfig && response.status === 304) {\n return cached as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n // Case 1: Native Response instance\n if (typeof Response === FUNCTION && response instanceof Response) {\n response.data = requestConfig.parser\n ? await requestConfig.parser(response)\n : await parseResponseData(response, requestConfig.responseType);\n } else if (fn) {\n // Case 2: Custom fetcher that returns a response object\n if (!('data' in response && 'body' in response)) {\n // Case 3: Raw data, wrap it\n response = { data: response } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n }\n\n // Attach config and data to the response\n // This is useful for custom fetchers that do not return a Response instance\n // and for interceptors that may need to access the request config\n response.config = requestConfig;\n\n // Check if the response status is not outside the range 200-299 and if so, output error\n // This is the pattern for fetch responses as per spec, but custom fetchers may not follow it so we check for `ok` property\n if (response.ok !== undefined && !response.ok) {\n throw new ResponseError(\n requestConfig.method +\n ' to ' +\n url +\n ' failed! Status: ' +\n (response.status || null),\n requestConfig,\n response,\n );\n }\n }\n\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig);\n\n const onResponse = fetcherConfig.onResponse;\n\n if (onResponse) {\n await applyInterceptors(onResponse, output);\n }\n } catch (_error) {\n const error = _error as ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Append additional information to Network, CORS or any other fetch() errors\n enhanceError(\n error,\n response,\n requestConfig,\n );\n\n // Prepare Extended Response\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig, error);\n } finally {\n if (userSignal) {\n userSignal.removeEventListener('abort', abort);\n }\n }\n\n return output;\n };\n\n // Inline and minimize function wrappers for performance\n // When retries are enabled, forward isStaleRevalidation so the first attempt\n // of a background SWR revalidation doesn't incorrectly mark the request as in-flight\n const baseRequest =\n retries > 0\n ? (isStaleRevalidation: boolean) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const { onLoadingSlow, loadingTimeout } = fetcherConfig;\n\n // Calls onLoadingSlow once a request, including its retries, is still pending after loadingTimeout.\n // Background revalidations don't show a loading state, so they are never considered slow.\n const request =\n onLoadingSlow && loadingTimeout\n ? async (isStaleRevalidation: boolean) => {\n if (isStaleRevalidation) {\n return baseRequest(isStaleRevalidation);\n }\n\n const timer = setTimeout(\n () => applyInterceptors(onLoadingSlow, fetcherConfig).catch(noop),\n loadingTimeout,\n );\n\n try {\n return await baseRequest(isStaleRevalidation);\n } finally {\n clearTimeout(timer);\n }\n }\n : baseRequest;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n request,\n fetcherConfig,\n );\n\n // Avoid unnecessary function wrapping if polling is not enabled\n const doRequestPromise = pollingInterval\n ? withPolling(\n requestWithErrorHandling,\n pollingInterval,\n fetcherConfig.shouldStopPolling,\n fetcherConfig.maxPollingAttempts,\n fetcherConfig.pollingDelay,\n fetcherConfig.refreshWhenHidden,\n fetcherConfig.refreshWhenOffline,\n userSignal,\n )\n : requestWithErrorHandling();\n\n // If deduplication is enabled, store the in-flight promise immediately\n if (_cacheKey) {\n if (dedupeTime) {\n setInFlightPromise(_cacheKey, doRequestPromise);\n }\n\n // Only register revalidator when revalidation features are actually requested\n if (staleTime || refetchOnFocus || refetchOnReconnect) {\n addRevalidator(\n _cacheKey,\n requestWithErrorHandling,\n undefined,\n staleTime,\n requestWithErrorHandling,\n !!refetchOnFocus,\n !!refetchOnReconnect,\n fetcherConfig.focusThrottleInterval,\n );\n }\n }\n\n return doRequestPromise;\n}\n\n/**\n * Recreates a response from its copy in a cache store.\n * The data was transformed before it was stored, so it isn't transformed again.\n *\n * @param stored - The stored copy of the response.\n * @param cacheKey - The cache key of the request.\n * @param config - The request configuration.\n * @returns The response, or null if the stored copy is invalid, e.g. has an unknown status.\n */\nfunction toResponse(\n stored: StoredResponse,\n cacheKey: string,\n config: RequestConfig,\n): FetchResponse | null {\n try {\n // Without the Fetch API (e.g. with a custom fetcher in tests), a plain response object is used\n const response = (typeof Response === FUNCTION\n ? new Response(null, stored)\n : {\n ok: true,\n status: stored.status,\n statusText: stored.statusText,\n headers: stored.headers,\n }) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n response.data = stored.data as typeof response.data;\n config.cacheKey = cacheKey;\n\n const output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, {\n ...config,\n select: undefined,\n flattenResponse: false,\n defaultResponse: undefined,\n });\n\n output.config = config;\n\n return output;\n } catch {\n return null;\n }\n}\n\n/**\n * Asks the server whether a cached response is still valid, by sending its ETag in the If-None-Match header.\n * Then the server can answer 304 Not Modified instead of sending the response again.\n * Requests with an If-None-Match header of their own are sent as they are.\n *\n * @param config - The request configuration.\n * @param cached - The cached response of the request, if any.\n * @returns A copy of the configuration with the If-None-Match header, or the configuration itself if the cached response has no ETag.\n */\nfunction withETag(\n config: RequestConfig,\n cached: FetchResponse | null | false,\n): RequestConfig {\n const etag = cached && !cached.error && cached.headers && cached.headers.etag;\n const headers = etag && processHeaders(config.headers as HeadersObject);\n\n return headers && !headers['if-none-match']\n ? { ...config, headers: { ...headers, 'if-none-match': etag } }\n : config;\n}\n","import type {\n ApiHandlerConfig,\n ApiHandlerDefaultMethods,\n ApiHandlerMethods,\n RequestConfigUrlRequired,\n} from './types/api-handler';\nimport { fetchf } from '.';\nimport { mergeConfigs } from './config-handler';\nimport { hasOwn } from './utils';\n\n/**\n * Creates an instance of API Handler.\n * It creates an API fetcher function using native fetch() or a custom fetcher if passed as \"fetcher\".\n * @see https://github.com/MattCCC/fetchff#configuration\n *\n * @param {Object} config - Configuration object for the API fetcher (see link above for full options).\n * @param {Object} config.endpoints - An object containing endpoint definitions.\n * @param {string} [config.baseURL] - The base URL for the API.\n * @param {Object} [config.headers] - Optional default headers to include in every request.\n * @param {Function} [config.onError] - Optional callback function for handling errors.\n * @returns API handler functions and endpoints to call\n *\n * @example\n * // Define endpoint paths\n * const endpoints = {\n * getUser: '/user',\n * createPost: '/post',\n * };\n *\n * // Create the API fetcher with configuration\n * const api = createApiFetcher({\n * endpoints,\n * apiUrl: 'https://example.com/api',\n * onError(error) {\n * console.log('Request failed', error);\n * },\n * headers: {\n * 'my-auth-key': 'example-auth-key-32rjjfa',\n * },\n * });\n *\n * // Fetch user data\n * const response = await api.getUser({ userId: 1, ratings: [1, 2] })\n */\nfunction createApiFetcher<\n EndpointTypes extends object,\n EndpointsSettings = never,\n>(config: ApiHandlerConfig) {\n const endpoints = config.endpoints;\n\n /**\n * Triggered when trying to use non-existent endpoints\n *\n * @param endpointName Endpoint Name\n * @returns {Promise}\n */\n async function handleNonImplemented(endpointName: string): Promise {\n console.error('Add ' + endpointName + \" to 'endpoints'.\");\n\n return null;\n }\n\n const apiHandler: ApiHandlerDefaultMethods = {\n config,\n endpoints,\n /**\n * Handle Single API Request\n * It considers settings in following order: per-request settings, global per-endpoint settings, global settings.\n *\n * @param endpointName - The name of the API endpoint to call.\n * @param requestConfig - Additional configuration for the request.\n * @returns A promise that resolves with the response from the API provider.\n */\n async request(endpointName, requestConfig = {}) {\n // Use global and per-endpoint settings\n // Only own properties are endpoints, not ones inherited like \"constructor\"\n const endpointConfig = hasOwn(endpoints, endpointName as string)\n ? endpoints[endpointName]\n : undefined;\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // URL parsers ignore leading control characters and spaces, drop tabs and newlines,\n // and treat backslashes like slashes, so check the URL the way it will be resolved\n const resolvedUrl = url\n .replace(/[\\t\\n\\r]/g, '')\n // eslint-disable-next-line no-control-regex -- matching control characters is the point\n .replace(/^[\\x00-\\x20]+/, '');\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (/^[/\\\\]{2}/.test(resolvedUrl)) {\n throw new Error('Protocol-relative URLs not allowed.');\n }\n\n // Prevent potential Server-Side Request Forgery attack and leakage of credentials when same instance is used for external requests\n // Any scheme counts here, as e.g. \"http:\\\\host\" or \"http:host\" can also point to another host\n const mergedConfig = /^[a-z][a-z\\d+\\-.]*:/i.test(resolvedUrl)\n ? // Merge endpoints configs for absolute URLs only if urls match\n endpointConfig && endpointConfig.url === url\n ? mergeConfigs(_endpointConfig, requestConfig)\n : requestConfig\n : mergeConfigs(mergeConfigs(config, _endpointConfig), requestConfig);\n\n // We prevent potential Server-Side Request Forgery attack and leakage of credentials as the same instance is not used for external requests\n // Retrigger fetch to ensure completely new instance of handler being triggered for external URLs\n return fetchf(url, mergedConfig);\n },\n };\n\n /**\n * Maps all API requests using native Proxy\n *\n * @param {*} prop Caller\n */\n return new Proxy>(\n apiHandler as ApiHandlerMethods,\n {\n get(_target, prop: string | symbol) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Symbols (e.g. inspection hooks) are never endpoints, and returning a function\n // for \"then\" would make the instance a thenable that never settles when awaited\n if (typeof prop === 'symbol' || prop === 'then') {\n return undefined;\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (hasOwn(endpoints, prop)) {\n return apiHandler.request.bind(null, prop);\n }\n\n return handleNonImplemented.bind(null, prop);\n },\n },\n );\n}\n\nexport { createApiFetcher };\n"]} \ No newline at end of file +{"version":3,"sources":["../../src/constants.ts","../../src/utils.ts","../../src/interceptor-manager.ts","../../src/errors/fetch-error.ts","../../src/errors/response-error.ts","../../src/timeout-wheel.ts","../../src/inflight-manager.ts","../../src/hash.ts","../../src/revalidator-manager.ts","../../src/pubsub-manager.ts","../../src/config-handler.ts","../../src/cache-manager.ts","../../src/response-parser.ts","../../src/retry-handler.ts","../../src/polling-handler.ts","../../src/upload-progress.ts","../../src/download-progress.ts","../../src/error-handler.ts","../../src/request-handler.ts","../../src/api-handler.ts"],"names":["APPLICATION_CONTENT_TYPE","APPLICATION_JSON","CHARSET_UTF_8","CONTENT_TYPE","UNDEFINED","OBJECT","STRING","FUNCTION","ABORT_ERROR","TIMEOUT_ERROR","GET","HEAD","REJECT","MAX_DELAY_MS","MAX_DEPTH","hasOwn","o","k","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","key","sortObject","sortedObj","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","v","buildParams","prefix","depth","i","len","replaceUrlPathParams","urlPathParams","match","colonKey","braceKey","encoded","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","signal","resolve","done","timer","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","isPageHidden","isOffline","applyInterceptors","interceptors","args","merge","interceptor","FetchError","request","response","ResponseError","WHEEL_SIZE","SECOND","wheel","keyMap","position","lastTick","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","inFlight","markInFlight","timeout","dedupeTime","isCancellable","isTimeoutEnabled","now","item","prevPromise","prevController","prevIsCancellable","controller","abortRequest","removeInFlight","setInFlightPromise","promise","getInFlightPromise","prevReq","hash","str","char","DEFAULT_TTL","revalidators","eventHandlers","customEventProviders","setEventProvider","type","provider","removeEventHandler","addEventHandler","revalidateAll","isStaleRevalidation","isThrottled","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","focusThrottleInterval","listeners","addListener","fn","set","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","merged","buildFetcherConfig","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","separator","contentTypeValue","INTERCEPTORS","baseConfig","overrideConfig","targetConfig","mergeConfig","property","mergeInterceptors","baseInterceptor","newInterceptor","base","override","isInstance","overrides","lowerKey","existingKey","_cache","stores","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADERS","generateCacheKey","config","cacheKeyCheck","headersString","keys","cacheStr","sanitizeCacheKey","bodyString","getObjectId","objectIds","lastObjectId","id","isCacheExpired","getCacheData","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","scheduleExpiry","removeExpired","store","callStore","persistCache","status","statusText","getStoredCache","isCacheBypassed","restoreCache","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","buster","getCachedResponse","cacheKey","cacheTime","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","responseType","contentType","mimeType","trimmed","_error","prepareResponse","defaultResponse","mutatator","isNativeResponse","getMsFromHttpDate","dateString","getRetryAfterMs","extendedResponse","retryAfter","RATELIMIT_RESET","rateLimitResetAfter","rateLimitResetAt","withRetry","requestFn","retries","delay","backoff","maxDelay","retryOn","shouldRetry","jitter","methods","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryDelay","withJitter","retryAfterMs","_b","_c","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","refreshWhenHidden","refreshWhenOffline","pollingAttempt","NULL_BODY_STATUSES","FORBIDDEN_HEADERS","isStream","toProgress","loaded","total","fetchWithUploadProgress","sendWithXhr","sendStreamed","reject","xhr","abort","settle","line","index","onAbort","stream","blob","chunk","withDownloadProgress","onDownloadProgress","counted","withErrorHandling","isCancelled","logger","redactError","strategy","SENSITIVE_HEADERS","copy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","isETagEnabled","needsCacheKey","_cacheKey","initialResponse","stored","restored","toResponse","inflight","retryConfig","resetTimeout","userSignal","doRequestOnce","init","withETag","onResponse","baseRequest","_","onLoadingSlow","loadingTimeout","requestWithErrorHandling","doRequestPromise","etag","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","resolvedUrl","mergedConfig","_target","prop"],"mappings":"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","file":"index.global.js","sourcesContent":["export const APPLICATION_CONTENT_TYPE = 'application/';\n\nexport const APPLICATION_JSON = APPLICATION_CONTENT_TYPE + 'json';\nexport const CHARSET_UTF_8 = 'charset=utf-8';\nexport const CONTENT_TYPE = 'Content-Type';\n\nexport const UNDEFINED = 'undefined';\nexport const OBJECT = 'object';\nexport const STRING = 'string';\nexport const FUNCTION = 'function';\n\nexport const ABORT_ERROR = 'AbortError';\nexport const TIMEOUT_ERROR = 'TimeoutError';\n\nexport const GET = 'GET';\nexport const HEAD = 'HEAD';\n\nexport const REJECT = 'reject';\n\n// Larger timer delays overflow and fire immediately in browsers and Node.js (~24.8 days)\nexport const MAX_DELAY_MS = 2147483647;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, MAX_DELAY_MS, OBJECT, STRING, UNDEFINED } from './constants';\nimport type {\n DefaultUrlParams,\n HeadersObject,\n QueryParams,\n UrlPathParams,\n} from './types';\n\n// Prevent stack overflow with recursion depth limit\nconst MAX_DEPTH = 10;\n\nexport const hasOwn = (o: any, k: string) =>\n Object.prototype.hasOwnProperty.call(o, k);\n\nexport function isSearchParams(data: unknown): boolean {\n return data instanceof URLSearchParams;\n}\n\n/**\n * Determines if a value is a non-null object.\n *\n * @param {any} value - The value to check.\n * @returns {boolean} - True if the value is a non-null object.\n */\nexport function isObject(value: any): value is Record {\n return value !== null && typeof value === OBJECT;\n}\n\n/**\n * Shallowly serializes an object by converting its key-value pairs into a string representation.\n * This function does not recursively serialize nested objects.\n *\n * @param obj - The object to serialize.\n * @returns A string representation of the object's top-level properties.\n */\nexport function shallowSerialize(obj: Record): string {\n let result = '';\n\n for (const key in obj) {\n if (hasOwn(obj, key)) {\n result += key + ':' + obj[key];\n }\n }\n\n return result;\n}\n\n/**\n * Removes properties that could lead to prototype pollution from an object.\n *\n * This function checks for dangerous properties like '__proto__', 'constructor',\n * and 'prototype'. If none are present, the object is returned as-is (zero-copy fast path).\n * Otherwise, a shallow copy is created with the dangerous properties removed.\n *\n * @param obj - The object to sanitize\n * @returns A safe object without dangerous properties\n */\nexport function sanitizeObject>(obj: T): T {\n const hasProto = hasOwn(obj, '__proto__');\n const hasCtor = hasOwn(obj, 'constructor');\n const hasPrototype = hasOwn(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n // Copy key by key, as a spread compiled to assignments would let \"__proto__\" set the prototype\n const safeObj = {} as Record;\n\n for (const key of Object.keys(obj)) {\n if (key !== '__proto__' && key !== 'constructor' && key !== 'prototype') {\n safeObj[key] = obj[key];\n }\n }\n\n return safeObj as T;\n}\n\n/**\n * Sorts the keys of an object and returns a new object with sorted keys.\n *\n * This function is optimized for performance by minimizing the number of object operations\n * and using a single pass to create the sorted object.\n *\n * @param {Object} obj - The object to be sorted by keys.\n * @returns {Object} - A new object with keys sorted in ascending order.\n */\nexport function sortObject(obj: Record): object {\n // Without a prototype, a \"__proto__\" key is kept as a regular property instead of setting the prototype\n const sortedObj = Object.create(null) as Record;\n\n Object.keys(obj)\n .sort()\n .forEach((k) => (sortedObj[k] = obj[k]));\n\n return sortedObj;\n}\n\n/**\n * Appends a query string to a URL, ensuring proper handling of existing query parameters.\n *\n * @param baseUrl - The base URL to which the query string will be appended.\n * @param queryString - The encoded query string to append.\n * @returns The URL with the appended query string, or the original URL if no query string is provided.\n */\nfunction appendQueryStringToUrl(baseUrl: string, queryString: string): string {\n if (!queryString) {\n return baseUrl;\n }\n\n return baseUrl + (baseUrl.includes('?') ? '&' : '?') + queryString;\n}\n\n/**\n * Appends query parameters to a given URL.\n *\n * @param {string} url - The base URL to which query parameters will be appended.\n * @param {QueryParams} params - An object containing the query parameters to append.\n * @returns {string} - The URL with the appended query parameters.\n */\nexport function appendQueryParams(url: string, params: QueryParams): string {\n if (!params) {\n return url;\n }\n\n // Check if `params` is an instance of URLSearchParams and bail early if it is\n if (isSearchParams(params)) {\n const encodedQueryString = params.toString();\n\n return appendQueryStringToUrl(url, encodedQueryString);\n }\n\n // This is exact copy of what JQ used to do. It works much better than URLSearchParams\n const s: string[] = [];\n const encode = encodeURIComponent;\n const add = (k: string, v: any) => {\n v = typeof v === FUNCTION ? v() : v;\n v = v === null || v === undefined ? '' : v;\n s[s.length] = encode(k) + '=' + encode(v);\n };\n\n const buildParams = (prefix: string, obj: any, depth = 0) => {\n // Stop recursion if maximum depth is reached\n if (depth >= MAX_DEPTH) {\n return s;\n }\n\n let i: number, len: number, key: string;\n\n if (prefix) {\n if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n buildParams(\n prefix + '[' + (typeof obj[i] === OBJECT && obj[i] ? i : '') + ']',\n obj[i],\n depth + 1,\n );\n }\n } else if (isObject(obj)) {\n for (key in obj) {\n buildParams(prefix + '[' + key + ']', obj[key], depth + 1);\n }\n } else {\n add(prefix, obj);\n }\n } else if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n add(obj[i].name, obj[i].value);\n }\n } else {\n for (key in obj) {\n buildParams(key, obj[key], depth + 1);\n }\n }\n return s;\n };\n\n const queryStringParts = buildParams('', params).join('&');\n\n // Encode special characters as per RFC 3986, https://datatracker.ietf.org/doc/html/rfc3986\n // This is for compatibility with server frameworks that expect the literal notation\n const encodedQueryString = queryStringParts.replace(/%5B%5D/g, '[]'); // Keep '[]' for arrays\n\n return appendQueryStringToUrl(url, encodedQueryString);\n}\n\n/**\n * Replaces dynamic URI parameters in a URL string with values from the provided `urlPathParams` object.\n * Parameters in the URL are denoted by `:` or `{}` (like in OpenAPI paths), where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:` or `{}`.\n * @param {Object} urlPathParams - An object containing the parameter values to replace placeholders.\n * @param {string} urlPathParams.paramName - The value to replace the placeholder `:` in the URL.\n * @returns {string} - The URL string with placeholders replaced by corresponding values from `urlPathParams`.\n */\nexport function replaceUrlPathParams(\n url: string,\n urlPathParams: UrlPathParams,\n): string {\n if (!urlPathParams || (url.indexOf(':') === -1 && url.indexOf('{') === -1)) {\n return url;\n }\n\n // Use a single RegExp and avoid unnecessary casts and function calls\n // Precompute keys for faster lookup\n const params = urlPathParams as DefaultUrlParams;\n\n // Use a replacer function that avoids extra work\n return url.replace(/:(\\w+)|\\{(\\w+)\\}/g, (match, colonKey, braceKey) => {\n const key = colonKey || braceKey;\n\n // Use hasOwnProperty for strict key existence check\n if (hasOwn(params, key)) {\n const value = params[key];\n\n // Only replace if value is not undefined or null\n if (value !== undefined && value !== null) {\n const encoded = encodeURIComponent(String(value));\n\n // These can't be encoded, and URL parsers would move the request to another path\n if (encoded === '.' || encoded === '..') {\n throw new Error('Path params \".\" and \"..\" not allowed.');\n }\n\n return encoded;\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL starts with a scheme (e.g., \"http://\", \"https://\").\n * A \"://\" appearing later, e.g. in a query string, does not make the URL absolute.\n *\n * @param url - The URL string to check.\n * @returns `true` if the URL is absolute, otherwise `false`.\n */\nexport function isAbsoluteUrl(url: string): boolean {\n return /^[a-z][a-z\\d+\\-.]*:\\/\\//i.test(url);\n}\n\nexport const timeNow = () => Date.now();\n\nexport const noop = () => {};\n\n/**\n * Checks if a value is JSON serializable.\n *\n * JSON serializable values include:\n * - Primitive types: string, number, boolean, null\n * - Arrays\n * - Plain objects (i.e., objects without special methods)\n * - Values with a `toJSON` method\n *\n * @param {any} value - The value to check for JSON serializability.\n * @returns {boolean} - Returns `true` if the value is JSON serializable, otherwise `false`.\n */\nexport function isJSONSerializable(value: any): boolean {\n const t = typeof value;\n\n if (value === undefined || value === null) {\n return false;\n }\n\n if (t === STRING || t === 'number' || t === 'boolean') {\n return true;\n }\n\n if (Array.isArray(value)) {\n return true;\n }\n\n if (\n typeof globalThis !== UNDEFINED &&\n typeof globalThis.Buffer !== UNDEFINED &&\n globalThis.Buffer.isBuffer(value)\n ) {\n return false;\n }\n\n if (value instanceof Date || isSearchParams(value)) {\n return false;\n }\n\n if (isObject(value)) {\n const proto = Object.getPrototypeOf(value);\n\n // Check if the prototype is `Object.prototype` (plain object)\n if (proto === Object.prototype) {\n return true;\n }\n\n // Check if the object has a toJSON method\n if (typeof value.toJSON === FUNCTION) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Waits for the given time. When a signal is passed, the wait ends early once it is aborted.\n *\n * @param {number} ms - The time to wait in milliseconds.\n * @param {AbortSignal} [signal] - An optional signal that ends the wait when aborted.\n * @returns {Promise} - A promise that resolves with `true` once the wait is over.\n */\nexport const delayInvocation = (\n ms: number,\n signal?: AbortSignal,\n): Promise =>\n new Promise((resolve) => {\n const done = () => {\n clearTimeout(timer);\n if (signal) {\n signal.removeEventListener('abort', done);\n }\n resolve(true);\n };\n const timer = setTimeout(done, Math.min(ms, MAX_DELAY_MS));\n\n if (signal) {\n if (signal.aborted) {\n done();\n } else {\n signal.addEventListener('abort', done);\n }\n }\n });\n\n/**\n * Recursively flattens the data object if it meets specific criteria.\n *\n * The method checks if the provided `data` is an object with exactly one property named `data`.\n * If so, it recursively flattens the `data` property. Otherwise, it returns the `data` as-is.\n *\n * @param {any} data - The data to be flattened. Can be of any type, including objects, arrays, or primitives.\n * @returns {any} - The flattened data if the criteria are met; otherwise, the original `data`.\n */\nexport function flattenData(data: any, depth = 0): any {\n if (depth >= MAX_DEPTH) {\n return data;\n }\n\n if (data && isObject(data) && typeof data.data !== UNDEFINED) {\n return flattenData(data.data, depth + 1);\n }\n\n return data;\n}\n\n/**\n * Processes headers and returns them as a normalized object.\n *\n * Handles both `Headers` instances and plain objects. Normalizes header keys to lowercase\n * as per RFC 2616 section 4.2.\n *\n * @param headers - The headers to process. Can be an instance of `Headers`, a plain object,\n * or `null`. If `null`, an empty object is returned.\n * @returns {HeadersObject} - A normalized headers object with lowercase keys.\n */\nexport function processHeaders(\n headers?: (HeadersObject & HeadersInit) | null | Headers,\n): HeadersObject {\n if (!headers) {\n return {};\n }\n\n const headersObject: HeadersObject = {};\n\n // Normalize keys to lowercase as per RFC 2616 4.2\n // https://datatracker.ietf.org/doc/html/rfc2616#section-4.2\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n headersObject[key.toLowerCase()] = value;\n });\n } else {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n // Assigning \"__proto__\" would set the prototype of the result\n if (hasOwn(headers, key) && key !== '__proto__') {\n headersObject[key.toLowerCase()] = headers[key];\n }\n }\n }\n\n return headersObject;\n}\n\n/**\n * Determines if the current environment is a browser.\n *\n * @returns {boolean} - True if running in a browser environment, false otherwise.\n */\nexport function isBrowser(): boolean {\n // For node and some mobile frameworks like React Native, `add/removeEventListener` doesn't exist on window!\n return (\n typeof window !== UNDEFINED && typeof window.addEventListener === FUNCTION\n );\n}\n\n/**\n * Creates an abort/timeout error compatible with all JS runtimes.\n * Falls back to a plain Error with the correct `name` when DOMException is unavailable (e.g. React Native).\n *\n * @param {string} message - The error message.\n * @param {string} name - The error name (e.g. 'AbortError', 'TimeoutError').\n * @returns {DOMException | Error} - An error object with the specified name.\n */\nexport function createAbortError(\n message: string,\n name: string,\n): DOMException | Error {\n if (typeof DOMException !== UNDEFINED) {\n return new DOMException(message, name);\n }\n\n const error = new Error(message);\n error.name = name;\n\n return error;\n}\n\n/**\n * Detects if the user is on a slow network connection\n * @returns {boolean} True if connection is slow, false otherwise or if detection unavailable\n */\nexport const isSlowConnection = (): boolean => {\n const conn = typeof navigator !== UNDEFINED && (navigator as any).connection;\n\n return conn && ['slow-2g', '2g', '3g'].includes(conn.effectiveType);\n};\n\n/**\n * Detects if the page is hidden, e.g. when its tab is in the background or the window is minimized\n * @returns {boolean} True if the page is hidden, false otherwise or outside browsers\n */\nexport const isPageHidden = (): boolean =>\n typeof document !== UNDEFINED && document.visibilityState === 'hidden';\n\n/**\n * Detects if the browser is offline\n * @returns {boolean} True if the browser is offline, false otherwise or if the connection state is unknown\n */\nexport const isOffline = (): boolean =>\n typeof navigator !== UNDEFINED && navigator.onLine === false;\n","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject, sanitizeObject } from './utils';\n\n/**\n * Applies interceptors to the object. Interceptors can be a single function or an array of functions.\n *\n * @template T - Type of the object.\n * @template Args - Type of additional arguments.\n * @template I - Type of interceptors.\n *\n * @param {InterceptorFunction | InterceptorFunction[]} [interceptors] - Interceptor function(s).\n * @param {T} data - The data object to process.\n * @param {...Args} args - Additional arguments to pass to interceptors.\n *\n * @returns {Promise} - Nothing as the function is non-idempotent.\n */\nexport async function applyInterceptors<\n T extends object,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Args extends any[] = any[],\n I = InterceptorFunction | InterceptorFunction[],\n>(interceptors: I | undefined, data: T, ...args: Args): Promise {\n if (!interceptors) {\n return;\n }\n\n const merge = (v: unknown) =>\n v &&\n isObject(data) &&\n isObject(v) &&\n Object.assign(data, sanitizeObject(v));\n\n if (typeof interceptors === FUNCTION) {\n merge(await (interceptors as InterceptorFunction)(data, ...args));\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n merge(await interceptor(data, ...args));\n }\n }\n}\n","import type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\n/**\n * This is a base error class\n */\nexport class FetchError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends Error {\n // Declared only, and set in the constructor, as class fields would need a helper in the ES2018 bundle\n declare status: number;\n declare statusText: string;\n declare config: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare isCancelled: boolean;\n declare request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null;\n\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.request = request;\n this.response = response;\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\n this.name = 'FetchError';\n }\n}\n","import { FetchError } from './fetch-error';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\nexport class ResponseError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends FetchError {\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message, request, response);\n\n this.name = 'ResponseError';\n }\n}\n","/**\n * @module timeout-wheel\n * @description\n * Ultra-minimal timing wheel implementation optimized for max performance & many requests.\n * For most of the cases it's 4-100x faster than setTimeout and setInterval alone.\n * Provides efficient scheduling and cancellation of timeouts using a circular array.\n *\n * Position 0 → 1 → 2 → ... → 599 → 0 → 1 → 2 ...\n * Time: 0s 1s 2s 599s 600s 601s 602s\n *\n * The timing wheel consists of 600 slots (one per second for 10 min).\n * Each slot contains a list of timeout items, each associated with a unique key and callback.\n * Timeouts are scheduled by placing them in the appropriate slot based on the delay in seconds.\n * The wheel advances every second, executing and removing callbacks as their timeouts expire.\n * Defaults to setTimeout if the delay doesn't fit in the wheel (~10 minutes) or is not divisible by 1000.\n *\n * @remarks\n * - Designed for minimal footprint and simplicity.\n * - Only supports second-level granularity (minimum timeout: 1 second).\n * - Timeouts never fire early, but may fire up to 1 second late.\n * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { MAX_DELAY_MS } from './constants';\nimport { noop, timeNow } from './utils';\n\ntype TimeoutCallback = () => unknown | Promise;\ntype TimeoutItem = [string, TimeoutCallback]; // [key, callback]\n\nconst WHEEL_SIZE = 600; // 600 slots for 10 min (1 slot per second)\nconst SECOND = 1000; // 1 second in milliseconds\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\nlet lastTick = 0; // Time when the wheel last advanced (or started)\nlet timer: NodeJS.Timeout | null = null;\n\nconst handleCallback = ([key, callback]: TimeoutItem): void => {\n keyMap.delete(key);\n\n try {\n const result = callback();\n if (result && result instanceof Promise) {\n // Silently ignore async errors to prevent wheel from stopping\n result.catch(noop);\n }\n } catch {\n // Ignore callback errors to prevent wheel from stopping\n }\n};\n\nexport const addTimeout = (\n key: string,\n cb: TimeoutCallback,\n ms: number,\n): void => {\n removeTimeout(key);\n\n // A running wheel is already part-way through its current second, so the timeout\n // waits one more slot to never fire early. A new wheel starts its first second now.\n const seconds = ms / SECOND + (timer && timeNow() !== lastTick ? 1 : 0);\n\n // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || seconds >= WHEEL_SIZE || ms % SECOND !== 0) {\n keyMap.set(key, [\n setTimeout(\n handleCallback.bind(null, [key, cb]),\n Math.min(ms, MAX_DELAY_MS),\n ),\n ]); // Store timeout ID instead of slot\n\n return;\n }\n\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n lastTick = timeNow();\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\n lastTick = timeNow();\n const slot = wheel[position];\n\n // Use slot.length directly (not cached) so mid-iteration mutations\n // from callbacks (e.g. removeTimeout) are handled correctly\n for (let i = 0; i < slot.length; i++) {\n handleCallback(slot[i]);\n }\n\n slot.length = 0; // Reuse array, avoid GC allocation\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }, SECOND);\n }\n};\n\nexport const removeTimeout = (key: string): void => {\n const slotOrTimeout = keyMap.get(key);\n\n if (slotOrTimeout !== undefined) {\n // It's a Timeout object from setTimeout\n if (Array.isArray(slotOrTimeout)) {\n clearTimeout(slotOrTimeout[0]);\n } else {\n const slotArr = wheel[slotOrTimeout];\n\n for (let i = 0; i < slotArr.length; i++) {\n if (slotArr[i][0] === key) {\n slotArr.splice(i, 1);\n break;\n }\n }\n }\n\n keyMap.delete(key);\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }\n};\n\nexport const clearAllTimeouts = () => {\n // Clear native setTimeout timeouts first!\n keyMap.forEach((value) => {\n if (Array.isArray(value)) {\n clearTimeout(value[0]);\n }\n });\n\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n\n keyMap.clear();\n\n for (let i = 0; i < WHEEL_SIZE; i++) {\n wheel[i].length = 0;\n }\n\n position = 0;\n};\n","/**\n * @module inflight-manager\n *\n * Manages in-flight asynchronous requests using unique keys to enable deduplication and cancellation.\n *\n * Provides utilities for:\n * - Deduplication of requests within a configurable time window (`dedupeTime`)\n * - Timeout management and automatic request abortion\n * - AbortController lifecycle and cancellation logic\n * - Concurrency control and request state tracking\n * - In-flight promise deduplication to prevent duplicate network calls\n *\n * @remarks\n * - Requests with the same key within the deduplication interval share the same AbortController and in-flight promise.\n * - Supports cancellation of previous requests when a new one with the same key is issued, if `isCancellable` is enabled.\n * - Timeout logic ensures requests are aborted after a specified duration, if enabled.\n * - Internal queue state is managed via a Map, keyed by request identifier.\n * - Polled requests are also marked as \"in-flight\" to prevent duplicate requests.\n */\n\nimport { ABORT_ERROR, TIMEOUT_ERROR } from './constants';\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { createAbortError, timeNow } from './utils';\n\nexport type InFlightItem = [\n AbortController, // AbortController for the request\n boolean, // Whether timeout is enabled for the request\n number, // Timestamp when the request was marked in-flight\n boolean, // isCancellable - whether the request can be cancelled\n Promise | null, // Optional in-flight promise for deduplication\n];\n\nconst inFlight: Map = new Map();\n\n/**\n * Adds a request to the queue if it's not already being processed within the dedupeTime interval.\n *\n * @param {string | null} key - Unique key for the request (e.g. cache key).\n * @param {string} url - The request URL (for error messages/timeouts).\n * @param {number} timeout - Timeout in milliseconds for the request.\n * @param {number} dedupeTime - Deduplication time in milliseconds.\n * @param {boolean} isCancellable - If true, then the previous request with same configuration should be aborted.\n * @param {boolean} isTimeoutEnabled - Whether timeout is enabled.\n * @returns {AbortController} - A promise that resolves to an AbortController.\n */\nexport function markInFlight(\n key: string | null,\n url: string,\n timeout: number | undefined,\n dedupeTime: number,\n isCancellable: boolean,\n isTimeoutEnabled: boolean,\n): AbortController {\n if (!key) {\n return new AbortController();\n }\n\n const now = timeNow();\n const item = inFlight.get(key);\n let prevPromise: Promise | null = null;\n\n // Previous request is in-flight, check if we can reuse it\n if (item) {\n const prevController = item[0];\n const prevIsCancellable = item[3];\n\n // If the request is already in the queue and within the dedupeTime, reuse the existing controller\n if (\n !prevIsCancellable &&\n now - item[2] < dedupeTime &&\n !prevController.signal.aborted\n ) {\n return prevController;\n }\n\n // If the request is too old, remove it and proceed to add a new one\n // Abort previous request, if applicable, and continue as usual\n if (prevIsCancellable) {\n prevController.abort(\n createAbortError('Aborted due to new request', ABORT_ERROR),\n );\n }\n\n removeTimeout(key);\n prevPromise = item[4];\n }\n\n const controller = new AbortController();\n\n inFlight.set(key, [\n controller,\n isTimeoutEnabled,\n now,\n isCancellable,\n prevPromise,\n ]);\n\n if (isTimeoutEnabled) {\n addTimeout(\n key,\n () => {\n abortRequest(\n key,\n createAbortError(url + ' aborted due to timeout', TIMEOUT_ERROR),\n );\n },\n timeout as number,\n );\n }\n\n return controller;\n}\n\n/**\n * Removes a request from the queue and clears its timeout.\n *\n * @param key - Unique key for the request.\n * @param {boolean} error - Optional error to abort the request with. If null, the request is simply removed but no abort sent.\n * @returns {Promise} - A promise that resolves when the request is aborted and removed.\n */\nexport async function abortRequest(\n key: string | null,\n error: DOMException | Error | null | string = null,\n): Promise {\n // If the key is not in the queue, there's nothing to remove\n if (key) {\n const item = inFlight.get(key);\n\n if (item) {\n // If the request is not yet aborted, abort it with the provided error\n if (error) {\n const controller = item[0];\n controller.abort(error);\n }\n\n removeInFlight(key);\n }\n }\n}\n\n/**\n * Removes a request from the in-flight queue without aborting or clearing timeout.\n *\n * @param key - Unique key for the request.\n */\nexport function removeInFlight(key: string | null): void {\n removeTimeout(key!);\n inFlight.delete(key!);\n}\n\n/**\n * Gets the AbortController for a request key.\n *\n * @param key - Unique key for the request.\n * @returns {AbortController | undefined} - The AbortController or undefined.\n */\nexport async function getController(\n key: string,\n): Promise {\n const item = inFlight.get(key);\n\n return item && item[0];\n}\n\n/**\n * Adds helpers for in-flight promise deduplication.\n *\n * @param key - Unique key for the request.\n * @param promise - The promise to store.\n */\nexport function setInFlightPromise(\n key: string,\n promise: Promise,\n): void {\n const item = inFlight.get(key);\n if (item) {\n // store the promise at index 4 — item is already the Map's reference, no need to re-set\n item[4] = promise;\n }\n}\n\n/**\n * Retrieves the in-flight promise for a request key if it exists and is within the dedupeTime interval.\n *\n * @param key - Unique key for the request.\n * @param dedupeTime - Deduplication time in milliseconds.\n * @returns {Promise | null} - The in-flight promise or null.\n */\nexport function getInFlightPromise(\n key: string | null,\n dedupeTime: number,\n): Promise | null {\n if (!key) {\n return null;\n }\n\n const prevReq = inFlight.get(key);\n\n if (\n prevReq &&\n // If the request is in-flight and has a promise\n prevReq[4] &&\n // If the request is cancellable, we will not reuse it\n !prevReq[3] &&\n // If the request is within the dedupeTime\n timeNow() - prevReq[2] < dedupeTime &&\n // If one request is cancelled, ALL deduped requests get cancelled\n !prevReq[0].signal.aborted\n ) {\n return prevReq[4] as Promise;\n }\n\n return null;\n}\n","const PRIME_MULTIPLIER = 31;\n\n/**\n * Computes a hash value for a given string using the variant of djb2 hash function.\n * This hash function is non-cryptographic and designed for speed.\n * @author Daniel J. Bernstein (of djb2)\n *\n * @param str Input string to hash\n * @returns {string} Hash\n */\nexport function hash(str: string): string {\n let hash = 0;\n\n for (let i = 0, len = str.length; i < len; i++) {\n const char = str.charCodeAt(i);\n hash = (hash * PRIME_MULTIPLIER + char) | 0;\n }\n\n return String(hash);\n}\n","/**\n * @module revalidator-manager\n *\n * Provides utilities for managing cache revalidation functions, including:\n * - Registering and unregistering revalidators for specific cache keys.\n * - Triggering revalidation for a given key.\n * - Enabling or disabling automatic revalidation on window focus and if user comes back online for specific keys.\n * - Attaching and removing global focus and online event handlers to trigger revalidation.\n *\n * Revalidators are functions that can be registered to revalidate cache entries when needed.\n * They are typically used to refresh data in the cache when the window gains focus or when specific actions occur.\n * @performance O(1) lookup by key makes it blazing fast to register, unregister, and revalidate cache entries.\n * - Designed for high performance: minimizes unnecessary re-renders and leverages fast cache key generation.\n * - Integrates with a global cache and pub/sub system for efficient state updates across contexts.\n * - Handles automatic revalidation, deduplication, retries, and cache management out of the box.\n * @remarks\n * - Designed to be used in various environments (Deno, Node.js, Bun, Browser, etc.) to ensure cache consistency and freshness.\n */\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { FetchResponse } from './types';\nimport { isBrowser, noop, timeNow } from './utils';\n\nexport type RevalidatorFn = (\n isStaleRevalidation?: boolean,\n) => Promise;\n\ntype EventType = 'focus' | 'online';\n\ntype RevalidatorEntry = [\n RevalidatorFn, // main revalidator\n number, // lastUsed\n number, // ttl\n number?, // staleTime\n RevalidatorFn?, // bgRevalidator\n boolean?, // refetchOnFocus\n boolean?, // refetchOnReconnect\n number?, // focusThrottleInterval\n];\n\nconst DEFAULT_TTL = 3 * 60 * 1000; // Default TTL of 3 minutes\nconst revalidators = new Map();\n\n/**\n * Stores cleanup functions for active event handlers (browser or custom providers).\n * Each entry removes the corresponding event listener when called.\n * @remarks\n * - Improves performance by reducing the number of event listeners.\n * - Enables efficient O(1) lookup and management of event handlers for revalidation.\n */\nconst eventHandlers = new Map void>();\n\n/** Subscribe to an event and return a cleanup function */\nexport type EventProvider = (handler: () => void) => () => void;\n\nconst customEventProviders = new Map();\n\n/**\n * Registers a custom event provider for 'focus' or 'online' events.\n * Useful for non-browser environments like React Native.\n *\n * @param type - The event type ('focus' or 'online').\n * @param provider - A function that subscribes to the event and returns a cleanup function.\n */\nexport function setEventProvider(\n type: EventType,\n provider: EventProvider,\n): void {\n customEventProviders.set(type, provider);\n\n // Re-register if already active\n if (eventHandlers.has(type)) {\n removeEventHandler(type);\n addEventHandler(type);\n }\n}\n\n/**\n * Triggers revalidation for all registered entries based on the given event type.\n * For example, if it's a 'focus' event, it will revalidate entries that have the `refetchOnFocus` flag set.\n * Updates the timestamp and invokes the revalidator function for each applicable entry.\n *\n * @param type - The type of event that caused the revalidation (e.g., 'focus' or 'online').\n * @param isStaleRevalidation - If `true`, uses background revalidator and doesn't mark as in-flight.\n * @param isThrottled - If `true`, skips entries that were requested or revalidated within their `focusThrottleInterval`.\n */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n isThrottled: boolean = false,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex] || (isThrottled && now - entry[1] < entry[7]!)) {\n return;\n }\n\n entry[1] = now;\n\n // If it's a stale revalidation, use the background revalidator function\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n if (revalidator) {\n Promise.resolve(revalidator(isStaleRevalidation)).catch(noop);\n }\n });\n}\n\n/**\n * Revalidates an entry by executing the registered revalidation function.\n *\n * @param key The unique identifier for the cache entry to revalidate. If `null`, no revalidation occurs.\n * @param isStaleRevalidation - If `true`, it does not mark revalidated requests as in-flight.\n * @returns A promise that resolves to the result of the revalidator function, or\n * `null` if no key or revalidator is found, or a `FetchResponse` if applicable.\n */\nexport async function revalidate(\n key: string | null,\n isStaleRevalidation: boolean = false,\n): Promise {\n // If no key is provided, no revalidation occurs\n if (!key) {\n return null;\n }\n\n const entry = revalidators.get(key);\n\n if (entry) {\n // Update only the lastUsed timestamp without resetting the whole array\n entry[1] = timeNow();\n\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n // If no revalidator function is registered, return null\n if (revalidator) {\n return await revalidator(isStaleRevalidation);\n }\n }\n\n // If no revalidator is registered for the key, return null\n return null;\n}\n\n/**\n * Removes all revalidators associated with the specified event type.\n *\n * @param type - The event type whose revalidators should be removed.\n */\nexport function removeRevalidators(type: EventType) {\n removeEventHandler(type);\n\n const flagIndex = type === 'focus' ? 5 : 6;\n\n // Clear all revalidators with this flag\n revalidators.forEach((entry, key) => {\n if (entry[flagIndex]) {\n removeRevalidator(key);\n }\n });\n}\n\n/**\n * Registers a generic revalidation event handler for the specified event type.\n * Supports browser window events and custom event providers (e.g. for React Native).\n * Ensures the handler is only added once.\n *\n * @param event - The type of event to listen for (e.g., 'focus', 'online').\n */\nfunction addEventHandler(event: EventType) {\n if (eventHandlers.has(event)) {\n return;\n }\n\n // Focus events are throttled, so that e.g. switching between tabs quickly doesn't revalidate every time\n const handler = revalidateAll.bind(null, event, true, event === 'focus');\n\n // Priority 1: Custom event provider (works in any environment including React Native)\n const customProvider = customEventProviders.get(event);\n\n if (customProvider) {\n const cleanup = customProvider(handler);\n\n eventHandlers.set(event, cleanup);\n\n return;\n }\n\n // Priority 2: Browser window events\n if (isBrowser()) {\n window.addEventListener(event, handler);\n\n eventHandlers.set(event, () => window.removeEventListener(event, handler));\n }\n}\n\n/**\n * Removes the event handler for the specified event type.\n *\n * @param event - The type of event whose handler should be removed.\n */\nfunction removeEventHandler(event: EventType) {\n const cleanup = eventHandlers.get(event);\n\n if (cleanup) {\n cleanup();\n eventHandlers.delete(event);\n }\n}\n\n/**\n * Registers a revalidation functions for a specific cache key.\n *\n * @param {string} key Cache key to utilize\n * @param {RevalidatorFn} revalidatorFn Main revalidation function (marks in-flight requests)\n * @param {number} [ttl] Time to live in milliseconds (default: 3 minutes)\n * @param {number} [staleTime] Time (in seconds) after which the cache entry is considered stale\n * @param {RevalidatorFn} [bgRevalidatorFn] For stale revalidation (does not mark in-flight requests)\n * @param {boolean} [refetchOnFocus] Whether to revalidate on window focus\n * @param {boolean} [refetchOnReconnect] Whether to revalidate on network reconnect\n * @param {number} [focusThrottleInterval] Time (in milliseconds) after a request or revalidation during which focus events don't revalidate it\n */\nexport function addRevalidator(\n key: string,\n revalidatorFn: RevalidatorFn, // Main revalidation function (marks in-flight requests)\n ttl?: number,\n staleTime?: number,\n bgRevalidatorFn?: RevalidatorFn, // For stale revalidation (does not mark in-flight requests)\n refetchOnFocus?: boolean,\n refetchOnReconnect?: boolean,\n focusThrottleInterval?: number,\n) {\n // Existing entries are updated in place\n const entry = revalidators.get(key) || ([] as unknown as RevalidatorEntry);\n\n entry[0] = revalidatorFn;\n entry[1] = timeNow();\n entry[2] = ttl ?? DEFAULT_TTL;\n entry[3] = staleTime;\n entry[4] = bgRevalidatorFn;\n entry[5] = refetchOnFocus;\n entry[6] = refetchOnReconnect;\n entry[7] = focusThrottleInterval;\n\n revalidators.set(key, entry);\n\n if (refetchOnFocus) {\n addEventHandler('focus');\n }\n\n if (refetchOnReconnect) {\n addEventHandler('online');\n }\n\n if (staleTime) {\n addTimeout('s:' + key, revalidate.bind(null, key, true), staleTime * 1000);\n }\n}\n\nexport function removeRevalidator(key: string) {\n revalidators.delete(key);\n\n // Clean up stale timer\n removeTimeout('s:' + key);\n}\n\n/**\n * Periodically cleans up expired revalidators from the registry.\n * Removes any revalidator whose TTL has expired.\n *\n * @param {number} intervalMs How often to run cleanup (default: 3 minutes)\n * @returns {() => void} A function to stop the periodic cleanup\n */\nexport function startRevalidatorCleanup(\n intervalMs: number = DEFAULT_TTL,\n): () => void {\n const intervalId = setInterval(() => {\n const now = timeNow();\n\n revalidators.forEach(\n ([, lastUsed, ttl, , , refetchOnFocus, refetchOnReconnect], key) => {\n // Skip focus-only or reconnect-only revalidators to keep them alive\n if (refetchOnFocus || refetchOnReconnect) {\n return;\n }\n\n if (ttl > 0 && now - lastUsed > ttl) {\n removeRevalidator(key);\n }\n },\n );\n }, intervalMs);\n\n return () => clearInterval(intervalId);\n}\n","/**\n * Manages a set of listeners (subscribers) for arbitrary string keys, allowing cross-context or cross-component\n * cache updates and synchronization. Provides functions to add, remove, and notify listeners, as well as a\n * convenient subscribe/unsubscribe API.\n *\n * @template T - The type of the response object passed to listeners.\n *\n * @remarks\n * - Listeners are grouped by a string key, which typically represents a cache key or resource identifier.\n * - When `notifySubscribers` is called for a key, all listeners registered for that key are invoked with the provided response.\n * - The `subscribe` function returns an unsubscribe function for convenient cleanup.\n *\n * @example\n * ```ts\n * const unsubscribe = subscribe('user:123', (response) => {\n * // handle updated data\n * });\n * // Later, to stop listening:\n * unsubscribe();\n * ```\n */\n\nimport { noop } from './utils';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Listener = (response: T) => void;\n\nconst listeners = new Map>();\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n let set = listeners.get(key);\n\n if (!set) {\n listeners.set(key, (set = new Set()));\n }\n\n set.add(fn);\n}\n\nexport function removeListener(key: string, fn: Listener) {\n const set = listeners.get(key);\n\n if (set) {\n set.delete(fn);\n\n // If the set is empty, remove the key from the listeners map\n if (set.size === 0) {\n listeners.delete(key);\n }\n }\n}\n\nexport function notifySubscribers(key: string, response: T) {\n const fns = listeners.get(key);\n\n if (fns) {\n if (fns.size === 1) {\n // If there's only one listener, call it directly\n const fn = fns.values().next().value;\n fn!(response);\n } else {\n fns.forEach((fn) => fn(response));\n }\n }\n}\n\nexport function subscribe(key: string | null, fn: (response: T) => void) {\n if (!key) {\n // No op if no key is provided\n return noop;\n }\n\n addListener(key, fn);\n\n // Return an unsubscribe function\n return () => {\n removeListener(key, fn);\n };\n}\n","import { processHeaders } from './utils';\nimport {\n GET,\n APPLICATION_JSON,\n HEAD,\n STRING,\n CHARSET_UTF_8,\n CONTENT_TYPE,\n REJECT,\n UNDEFINED,\n APPLICATION_CONTENT_TYPE,\n} from './constants';\nimport type {\n HeadersObject,\n Method,\n RequestConfig,\n} from './types/request-handler';\nimport {\n replaceUrlPathParams,\n appendQueryParams,\n isSearchParams,\n isJSONSerializable,\n isSlowConnection,\n isAbsoluteUrl,\n sanitizeObject,\n isObject,\n} from './utils';\n\nconst defaultTimeoutMs = (isSlowConnection() ? 60 : 30) * 1000;\n\nexport const defaultConfig: RequestConfig = {\n strategy: REJECT,\n timeout: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n loadingTimeout: defaultTimeoutMs / 10, // 3 seconds (6 on slow connections)\n focusThrottleInterval: 5000, // 5 seconds\n headers: {\n Accept: APPLICATION_JSON + ', text/plain, */*',\n 'Accept-Encoding': 'gzip, deflate, br',\n },\n retry: {\n delay: defaultTimeoutMs / 30, // 1 second (2 on slow connections)\n maxDelay: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n resetTimeout: true,\n backoff: 1.5,\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n retryOn: [\n 408, // Request Timeout\n 409, // Conflict\n 425, // Too Early\n 429, // Too Many Requests\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n ],\n\n // Idempotent methods, which can be repeated safely, unlike e.g. POST requests that create resources\n methods: [GET, HEAD, 'PUT', 'DELETE', 'OPTIONS', 'TRACE'],\n },\n};\n\n/**\n * Overwrites the default configuration with the provided custom configuration.\n *\n * @param {Partial} customConfig - The custom configuration to merge into the default config.\n * @returns {Partial} - The updated default configuration object.\n */\nexport function setDefaultConfig(\n customConfig: Partial,\n): Partial {\n const sanitized = sanitizeObject(customConfig);\n\n // Merge nested retry and headers settings into the current defaults instead of replacing them\n return mergeConfigs(\n { retry: defaultConfig.retry, headers: defaultConfig.headers },\n sanitized,\n defaultConfig,\n );\n}\n\n/**\n * Returns a shallow copy of the current default configuration.\n *\n * @returns {RequestConfig} - The current default configuration.\n */\nexport function getDefaultConfig(): RequestConfig {\n return { ...defaultConfig };\n}\n\n/**\n * Build request configuration from defaults and overrides.\n * This function merges the default configuration with the provided request configuration,\n * @param {string} url - Request url\n * @param {RequestConfig | null | undefined} reqConfig - Request configuration\n * @return {RequestConfig} - Merged request configuration\n */\nexport function buildConfig(\n url: string,\n reqConfig?: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null,\n): RequestConfig {\n // Merging gives the request its own copies of nested objects like headers, so that\n // mutations (e.g. by interceptors) never leak into the global defaults\n const merged = mergeConfigs(\n defaultConfig,\n reqConfig ? sanitizeObject(reqConfig) : {},\n );\n\n return buildFetcherConfig(url, merged);\n}\n\n/**\n * Builds the fetcher configuration by setting the method, body, headers, and URL.\n * It also handles query parameters and path parameters. This fn mutates the passed `requestConfig` object.\n * @param {string} url - The endpoint URL to which the request will be sent.\n * @param {RequestConfig} requestConfig - The request configuration object containing method, body, headers, and other options.\n * @return {RequestConfig} - The modified request configuration object with the URL, method, body, and headers set appropriately.\n **/\nexport function buildFetcherConfig(\n url: string,\n requestConfig: RequestConfig,\n): RequestConfig {\n let method = requestConfig.method as Method;\n method = method ? (method.toUpperCase() as Method) : GET;\n\n let body: RequestConfig['data'] | undefined;\n\n // Only applicable for request methods 'PUT', 'POST', 'DELETE', and 'PATCH'\n if (method !== GET && method !== HEAD) {\n body = requestConfig.body ?? requestConfig.data;\n\n // Automatically stringify request body, if possible and when not dealing with strings\n if (body && typeof body !== STRING && isJSONSerializable(body)) {\n body = JSON.stringify(body);\n }\n }\n\n setContentTypeIfNeeded(requestConfig.headers, body);\n\n // Native fetch compatible settings\n const credentials = requestConfig.withCredentials\n ? 'include'\n : requestConfig.credentials;\n\n // The explicitly passed query params\n const dynamicUrl = replaceUrlPathParams(url, requestConfig.urlPathParams);\n const urlPath = appendQueryParams(dynamicUrl, requestConfig.params);\n const isFullUrl = isAbsoluteUrl(url);\n const baseURL = isFullUrl\n ? ''\n : requestConfig.baseURL || requestConfig.apiUrl || '';\n\n // Join as a path, as plain concatenation could extend the host of the baseURL,\n // e.g. \"https://api.example.com\" + \".evil.com\" would point to another host\n const separator =\n baseURL && urlPath && !baseURL.endsWith('/') && !/^[/?#]/.test(urlPath)\n ? '/'\n : '';\n\n requestConfig.url = baseURL + separator + urlPath;\n requestConfig.method = method;\n requestConfig.credentials = credentials;\n requestConfig.body = body;\n\n return requestConfig;\n}\n\n/**\n * Ensures the `Content-Type` header is set to `application/json; charset=utf-8`\n * if it is not already present and the request method and body meet specific conditions.\n *\n * @param headers - The headers object to modify. Can be an instance of `Headers`\n * or a plain object conforming to `HeadersInit`.\n * @param body - The optional body of the request. If no body is provided and the\n * method is 'GET' or 'HEAD', the function exits without modifying headers.\n */\nfunction setContentTypeIfNeeded(\n headers?: HeadersInit | HeadersObject,\n body?: unknown,\n): void {\n // If no headers are provided, or if the body is not set and the method is PUT or DELETE, do nothing\n if (!headers || !body) {\n return;\n }\n\n // Types that should not have Content-Type set (browser handles these)\n if (\n body instanceof FormData || // Browser automatically sets multipart/form-data with boundary\n (typeof Blob !== UNDEFINED && body instanceof Blob) || // Blob/File (a File is a Blob) already have their own MIME types, don't override\n (typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream) // Stream type should be determined by the stream source\n ) {\n return;\n }\n\n let contentTypeValue: string;\n\n if (isSearchParams(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded';\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'octet-stream';\n } else if (isJSONSerializable(body)) {\n contentTypeValue = APPLICATION_JSON + ';' + CHARSET_UTF_8;\n } else {\n // Do not set Content-Type if content is not recognizable\n return;\n }\n\n if (headers instanceof Headers) {\n if (!headers.has(CONTENT_TYPE)) {\n headers.set(CONTENT_TYPE, contentTypeValue);\n }\n } else if (\n isObject(headers) &&\n !Array.isArray(headers) &&\n // Header names are case-insensitive, so check the normalized (lowercase) headers\n !processHeaders(headers as HeadersObject)[CONTENT_TYPE.toLowerCase()]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\n\n// The interceptors that are merged instead of replaced\nconst INTERCEPTORS = [\n 'onRequest',\n 'onResponse',\n 'onError',\n 'onLoadingSlow',\n] as const;\n\n/**\n * Merges two request configurations, applying overrides from the second config to the first.\n * Handles special merging for nested properties like 'retry' and 'headers' (deep merge),\n * and concatenates interceptor arrays for 'onRequest', 'onResponse', 'onError' and 'onLoadingSlow'.\n * If a target config is provided, it mutates that object; otherwise, creates a new one.\n *\n * @param {RequestConfig} baseConfig - The base configuration object to merge from.\n * @param {RequestConfig} overrideConfig - The override configuration object to apply on top of the base.\n * @param {RequestConfig} [targetConfig={}] - Optional target configuration object to merge into (mutated in place).\n * @returns {RequestConfig} The merged configuration object.\n *\n * @example\n * const base = { timeout: 5000, headers: { 'Accept': 'application/json' } };\n * const override = { timeout: 10000, headers: { 'Authorization': 'Bearer token' } };\n * const merged = mergeConfigs(base, override);\n * // Result: { timeout: 10000, headers: { Accept: 'application/json', Authorization: 'Bearer token' } }\n */\nexport function mergeConfigs(\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig = {},\n): RequestConfig {\n Object.assign(targetConfig, baseConfig, overrideConfig);\n\n // Ensure that retry and headers are merged correctly\n mergeConfig('retry', baseConfig, overrideConfig, targetConfig);\n mergeConfig('headers', baseConfig, overrideConfig, targetConfig);\n\n // Merge interceptors efficiently\n for (const property of INTERCEPTORS) {\n mergeInterceptors(property, baseConfig, overrideConfig, targetConfig);\n }\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends\n 'onRequest' | 'onResponse' | 'onError' | 'onRetry' | 'onLoadingSlow',\n>(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const baseInterceptor = baseConfig[property];\n const newInterceptor = overrideConfig[property];\n\n if (baseInterceptor && newInterceptor) {\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] = (\n property === 'onResponse'\n ? [].concat(newInterceptor as never, baseInterceptor as never)\n : [].concat(baseInterceptor as never, newInterceptor as never)\n ) as RequestConfig[K];\n } else if (baseInterceptor || newInterceptor) {\n targetConfig[property] = baseInterceptor || newInterceptor;\n }\n}\n\n/**\n * Merges the specified property from the base configuration and the override configuration into the target configuration.\n *\n * @param {K} property - The property key to merge from the base and override configurations. Must be a key of RequestConfig.\n * @param {RequestConfig} baseConfig - The base configuration object that provides default values.\n * @param {RequestConfig} overrideConfig - The override configuration object that contains user-specific settings to merge.\n * @param {RequestConfig} targetConfig - The configuration object that will receive the merged properties.\n */\nexport function mergeConfig(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n if (override) {\n if (property === 'headers') {\n // Handle Headers instances which don't expose entries as own enumerable properties\n const isInstance =\n (base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers;\n const merged: HeadersObject = isInstance\n ? processHeaders(base)\n : { ...(base as HeadersObject) };\n const overrides: HeadersObject = isInstance\n ? processHeaders(override)\n : sanitizeObject(override as HeadersObject);\n\n // Header names are case-insensitive, so replace existing entries instead of duplicating them\n for (const key of Object.keys(overrides)) {\n const lowerKey = key.toLowerCase();\n\n for (const existingKey in merged) {\n if (existingKey.toLowerCase() === lowerKey) {\n delete merged[existingKey];\n }\n }\n\n merged[key] = overrides[key];\n }\n\n targetConfig[property] = merged as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...sanitizeObject(override as Record),\n } as RequestConfig[K];\n }\n } else if (\n override === undefined &&\n isObject(base) &&\n !((base as Headers | HeadersObject) instanceof Headers)\n ) {\n // Copy so that mutating the merged config never changes the base config\n targetConfig[property] = { ...base } as RequestConfig[K];\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { hash } from './hash';\nimport type {\n CacheKeyFunction,\n DefaultResponse,\n FetchResponse,\n MutationSettings,\n RequestConfig,\n} from './types/request-handler';\nimport type {\n CacheEntry,\n CacheStore,\n StoredResponse,\n} from './types/cache-manager';\nimport { GET, STRING } from './constants';\nimport {\n isJSONSerializable,\n isObject,\n isSearchParams,\n noop,\n sanitizeObject,\n sortObject,\n timeNow,\n} from './utils';\nimport { revalidate } from './revalidator-manager';\nimport { notifySubscribers } from './pubsub-manager';\nimport type { DefaultPayload, DefaultParams, DefaultUrlParams } from './types';\nimport { removeInFlight } from './inflight-manager';\nimport { addTimeout } from './timeout-wheel';\nimport { defaultConfig } from './config-handler';\nimport { processHeaders } from './utils';\n\nexport const IMMEDIATE_DISCARD_CACHE_TIME = 0; // Use it for cache entries that need to be persistent until unused by components or manually deleted\n\nconst _cache = new Map>();\n// The cache stores that keep copies of cache entries, by cache key\nconst stores = new Map();\nconst DELIMITER = '|';\nconst MIN_LENGTH_TO_HASH = 64;\nconst CACHE_KEY_SANITIZE_PATTERN = /[^\\w\\-_|/:@.?=&~%#]/g;\nconst CACHE_KEY_NEEDS_SANITIZE = /[^\\w\\-_|/:@.?=&~%#]/; // Non-global for fast test\n\n/**\n * Headers that may affect HTTP response content and should be included in cache key generation.\n * Header names are matched case-insensitively.\n *\n * - Content negotiation: accept (response format, e.g. JSON or HTML), accept-language (localization), accept-encoding (compression)\n * - Authentication: authorization (access to protected resources)\n * - Request body metadata: content-type (how the request body is interpreted)\n * - Optional: referer (may influence behavior in some APIs), origin (CORS or tenant-specific APIs),\n * user-agent (if the server returns client-specific content), cookie (session-based responses; can fragment the cache heavily)\n * - Custom headers that may affect response content: x-api-key (token-based access), x-requested-with (AJAX requests),\n * x-client-id (per-client/partner identity), x-tenant-id (multi-tenant segmentation), x-user-id (explicit user context),\n * x-app-version (version-specific behavior), x-feature-flag (feature rollout), x-device-id (per device/app instance),\n * x-platform (e.g. 'ios', 'android', 'web'), x-session-id (if it affects the response directly), x-locale (like accept-language)\n */\nconst CACHE_KEY_HEADERS =\n /^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;\n\n/**\n * Generates a unique cache key for a given URL and fetch options, ensuring that key factors\n * like method, headers, body, and other options are included in the cache key.\n * Headers and other objects are sorted by key to ensure consistent cache keys.\n *\n * @param {RequestConfig} config - The fetch options that may affect the request. The most important are:\n * @property {string} [method=\"GET\"] - The HTTP method (GET, POST, etc.).\n * @property {HeadersInit} [headers={}] - The request headers.\n * @property {BodyInit | null} [body=\"\"] - The body of the request (only for methods like POST, PUT).\n * @property {RequestCredentials} [credentials=\"same-origin\"] - Whether to include credentials (include, same-origin, omit).\n * @property {RequestCache} [cache=\"default\"] - The cache mode (e.g., default, no-store, reload).\n * @returns {string} - A unique cache key string based on the provided options.\n *\n * @example\n * const cacheKey = generateCacheKey({\n * url: 'https://api.example.com/data',\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'Alice' }),\n * mode: 'cors',\n * credentials: 'include',\n * });\n * console.log(cacheKey);\n */\nexport function generateCacheKey(\n config: RequestConfig,\n cacheKeyCheck = true,\n): string {\n // This is super fast. Effectively a no-op if cacheKey is\n // a string or a function that returns a string.\n const key = config.cacheKey;\n\n if (key && cacheKeyCheck) {\n return typeof key === STRING\n ? (key as string)\n : (key as CacheKeyFunction)(config);\n }\n\n const {\n url = '',\n method = GET,\n headers = null,\n body = null,\n credentials = 'same-origin',\n } = config;\n\n // Sort headers and body + convert sorted to strings for hashing purposes\n // Native serializer is on avg. 3.5x faster than a Fast Hash or FNV-1a\n let headersString = '';\n if (headers) {\n let obj: Record;\n\n if (headers instanceof Headers) {\n obj = processHeaders(headers);\n } else {\n obj = headers as Record;\n }\n\n // Filter headers to only include those that affect request identity\n // Include only headers that affect request identity, not execution behavior\n const keys = Object.keys(obj);\n const len = keys.length;\n\n // Sort keys manually for fastest deterministic output\n if (len > 1) {\n keys.sort();\n }\n\n let str = '';\n for (let i = 0; i < len; ++i) {\n if (CACHE_KEY_HEADERS.test(keys[i])) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // Concatenate all key parts into a cache key string\n // Template literals are apparently slower\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n return sanitizeCacheKey(cacheStr);\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING || isSearchParams(body)) {\n const str = String(body);\n\n bodyString = str.length < MIN_LENGTH_TO_HASH ? str : hash(str); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Files can't be read synchronously, so they are identified by their object\n bodyString +=\n key +\n '=' +\n (typeof value === STRING ? value : 'F' + getObjectId(value as File)) +\n '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (isObject(body) && !isJSONSerializable(body)) {\n // Blobs, buffers, streams etc. can't be read synchronously, so they are identified by their object.\n // Two different bodies never share a key, while the same body object is still deduplicated.\n bodyString = 'B' + getObjectId(body);\n } else {\n const o = isObject(body)\n ? JSON.stringify(sortObject(body))\n : String(body);\n\n bodyString = o.length > MIN_LENGTH_TO_HASH ? hash(o) : o;\n }\n }\n\n return sanitizeCacheKey(cacheStr + DELIMITER + bodyString);\n}\n\nconst objectIds = new WeakMap();\nlet lastObjectId = 0;\n\n/**\n * Returns a unique id for an object, e.g. a request body that can't be serialized.\n *\n * @param {object} obj - The object to identify.\n * @returns {number} - The id of the object.\n */\nfunction getObjectId(obj: object): number {\n let id = objectIds.get(obj);\n\n if (!id) {\n objectIds.set(obj, (id = ++lastObjectId));\n }\n\n return id;\n}\n\n/**\n * Prevents cache poisoning by removal of control chars and unusual characters.\n * When anything is removed, a hash of the original key is appended so that keys\n * differing only in the removed characters (e.g. `?a[]=1` and `?a=1`) don't collide.\n *\n * @param {string} cacheStr - The raw cache key.\n * @returns {string} - The sanitized cache key.\n */\nfunction sanitizeCacheKey(cacheStr: string): string {\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '') +\n DELIMITER +\n hash(cacheStr)\n : cacheStr;\n}\n\n/**\n * Checks if the cache entry is expired based on its timestamp and the expiry time.\n *\n * @param {CacheEntry} entry - The cache entry to check.\n * @returns {boolean} - Returns true if the cache entry is expired, false otherwise.\n */\nfunction isCacheExpired(entry: CacheEntry): boolean {\n // No expiry time means the entry never expires\n if (!entry.expiry) {\n return false;\n }\n\n return timeNow() > entry.expiry;\n}\n\n/**\n * Retrieves a cached response from the internal cache using the provided key.\n *\n * @param key - The unique key identifying the cached entry. If null, returns null.\n * @returns The cached {@link FetchResponse} if found, otherwise null.\n */\nexport function getCacheData<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n key: string | null,\n): FetchResponse | null {\n if (!key) {\n return null;\n }\n\n const entry = _cache.get(key);\n\n return entry ? entry.data : null;\n}\n\n/**\n * Retrieves a cache entry if it exists and is not expired.\n *\n * @param {string} key Cache key to utilize\n * @returns {CacheEntry | null} - The cache entry if it exists and is not expired, null otherwise.\n */\nexport function getCache(\n key: string | null,\n):\n | CacheEntry<\n FetchResponse\n >\n | null\n | undefined {\n return _cache.get(key as string);\n}\n\n/**\n * Sets a new cache entry or updates an existing one, with optional TTL (time-to-live).\n *\n * @param {string} key Cache key to utilize\n * @param {T} data - The data to be cached.\n * @param {number} [ttl] - Optional TTL in seconds. If not provided, the cache entry will not expire.\n * @param {number} [staleTime] - Optional stale time in seconds. If provided, the cache entry will be considered stale after this time.\n */\nexport function setCache(\n key: string,\n data: T,\n ttl?: number,\n staleTime?: number,\n): void {\n if (ttl === 0) {\n deleteCache(key);\n return;\n }\n\n const time = timeNow();\n const ttlMs = ttl ? ttl * 1000 : 0;\n const staleTimeMs = staleTime ? staleTime * 1000 : 0; // Ensure default value for staleTime\n\n _cache.set(key, {\n data,\n time,\n stale: staleTimeMs > 0 ? time + staleTimeMs : undefined, // Use undefined if staleTime is not set\n expiry: ttl === -1 ? undefined : time + ttlMs,\n });\n\n if (ttlMs > 0) {\n scheduleExpiry(key, ttlMs);\n }\n}\n\n/**\n * Deletes a cache entry once it expires.\n *\n * @param {string} key Cache key to utilize\n * @param {number} ms - The time until the entry expires, in milliseconds.\n */\nfunction scheduleExpiry(key: string, ms: number): void {\n addTimeout('c:' + key, () => deleteCache(key, true), ms);\n}\n\n/**\n * Invalidates (deletes) a cache entry.\n *\n * @param {string} key Cache key to utilize\n * @param {boolean} [removeExpired=false] - If true, only deletes the cache entry if it is expired or stale.\n */\nexport function deleteCache(key: string, removeExpired: boolean = false): void {\n if (removeExpired) {\n const entry = getCache(key);\n\n // If the entry does not exist, or it is neither expired nor stale, do not delete\n if (!entry || !isCacheExpired(entry)) {\n return;\n }\n }\n\n _cache.delete(key);\n\n const store = stores.get(key);\n\n if (store) {\n stores.delete(key);\n callStore(() => store.delete(key));\n }\n}\n\n/**\n * Prunes the cache by removing entries that have expired based on the provided cache time.\n */\nexport function pruneCache(): void {\n _cache.clear();\n stores.clear();\n}\n\n/**\n * Calls a cache store method. Store errors, e.g. of a full localStorage, are ignored so that they can't break requests.\n *\n * @param {() => unknown} fn - The function calling the store.\n */\nfunction callStore(fn: () => unknown): void {\n try {\n Promise.resolve(fn()).catch(noop);\n } catch {\n // Ignored\n }\n}\n\n/**\n * Saves a copy of a cached response in a cache store, so that it can be restored later, e.g. after a page reload.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheStore} [store] - The cache store. If not provided, nothing is saved.\n */\nfunction persistCache(key: string, store?: CacheStore): void {\n const entry = _cache.get(key);\n\n if (store && entry) {\n const { data, status, statusText, headers } = entry.data as FetchResponse;\n\n stores.set(key, store);\n callStore(() =>\n store.set(key, { ...entry, data: { data, status, statusText, headers } }),\n );\n }\n}\n\n/**\n * Reads the entry of a cache key from the cache store of a request, e.g. one saved during a previous page load.\n * Expired entries are deleted from the store.\n *\n * @param {string} key Cache key to utilize\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {Promise | null>} - The stored entry, or null if there is no valid one or the in-memory cache has an entry already.\n */\nexport async function getStoredCache(\n key: string,\n requestConfig: RequestConfig,\n): Promise | null> {\n const store = requestConfig.cacheStore;\n\n if (!store || isCacheBypassed(requestConfig)) {\n return null;\n }\n\n let entry: CacheEntry | null | undefined;\n\n try {\n entry = await store.get(key);\n } catch {\n // A failing store is treated like an empty one\n return null;\n }\n\n // Another request may have cached a response in the meantime\n if (!entry || _cache.has(key)) {\n return null;\n }\n\n if (isCacheExpired(entry)) {\n callStore(() => store.delete(key));\n\n return null;\n }\n\n return entry;\n}\n\n/**\n * Caches a response restored from a cache store in memory, keeping its original stale and expiry times.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheEntry} entry - The cache entry with the restored response.\n * @param {CacheStore} store - The cache store that the response was restored from.\n * @returns {boolean} - True if the restored response is fresh, false if it's stale.\n */\nexport function restoreCache(\n key: string,\n entry: CacheEntry,\n store: CacheStore,\n): boolean {\n _cache.set(key, entry);\n stores.set(key, store);\n\n if (entry.expiry) {\n scheduleExpiry(key, entry.expiry - timeNow());\n }\n\n notifySubscribers(key, entry.data);\n\n return !entry.stale || timeNow() < entry.stale;\n}\n\n/**\n * Mutates a cache entry with new data and optionally revalidates it.\n *\n * @param {string | null} key Cache key to utilize. If null, no mutation occurs.\n * @param {ResponseData} newData - The new data to be cached.\n * @param {MutationSettings|undefined} settings - Mutation settings.\n */\nexport async function mutate<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n key: string | null,\n newData: ResponseData,\n settings?: MutationSettings,\n): Promise | null> {\n // If no key is provided, do nothing\n if (!key) {\n return null;\n }\n\n const entry = getCache(\n key,\n );\n\n if (!entry) {\n return null;\n }\n\n const updatedData = isObject(newData) ? sanitizeObject(newData) : newData;\n\n const updatedResponse = {\n ...entry.data,\n data: updatedData,\n };\n\n // The ETag belongs to the original data, so the changed data must not be revalidated with it\n const headers = updatedResponse.headers;\n\n if (headers && headers.etag) {\n updatedResponse.headers = { ...headers };\n delete updatedResponse.headers.etag;\n }\n\n const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n persistCache(key, stores.get(key));\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\n}\n\n/**\n * Checks whether a request should bypass the cache, because of its cache buster or `cache: 'reload'`.\n *\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {boolean} - True if the cache should be bypassed.\n */\nexport function isCacheBypassed(requestConfig: RequestConfig): boolean {\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n\n return (\n !!(buster && buster(requestConfig)) || requestConfig.cache === 'reload'\n );\n}\n\n/**\n * Retrieves a cached response if available and valid, otherwise returns null.\n *\n * @template ResponseData - The type of the response data.\n * @template RequestBody - The type of the request body.\n * @template QueryParams - The type of the query parameters.\n * @template PathParams - The type of the path parameters.\n * @param {string | null} cacheKey - The cache key to look up.\n * @param {number | undefined} cacheTime - The maximum time to cache entry.\n * @param {RequestConfig} requestConfig - The fetcher configuration.\n * @returns {FetchResponse | null} - The cached response or null.\n */\nexport function getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n cacheKey: string | null,\n cacheTime: number | undefined,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): FetchResponse | null {\n // If cache key or time is not provided, return null\n if (!cacheKey || cacheTime === undefined || cacheTime === null) {\n return null;\n }\n\n if (isCacheBypassed(requestConfig)) {\n return null;\n }\n\n // Retrieve the cached entry\n const entry = getCache(\n cacheKey,\n );\n\n if (!entry) {\n return null;\n }\n\n const isExpired = isCacheExpired(entry);\n\n // If completely expired, delete and return null\n if (isExpired) {\n deleteCache(cacheKey);\n return null;\n }\n\n const data = entry.data;\n\n // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n // The placeholder stored while a request is in flight is not a response, so treat it as a miss\n return data && data.isFetching ? null : data;\n}\n\n/**\n * Sets or deletes the response cache based on cache settings and notifies subscribers.\n *\n * @param {FetchResponse} output - The response to cache.\n * @param {RequestConfig} requestConfig - The request configuration.\n * @param {boolean} [isError=false] - Whether the response is an error.\n */\nexport function handleResponseCache<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n output: FetchResponse,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n isError: boolean = false,\n): void {\n // It is string as it is called once request is made\n const cacheKey = requestConfig.cacheKey as string;\n\n if (cacheKey) {\n const cacheTime = requestConfig.cacheTime;\n const skipCache = requestConfig.skipCache;\n\n // Fast path: only set cache if cacheTime is positive and not skipping cache\n if (\n cacheTime &&\n (!isError || requestConfig.cacheErrors) &&\n !(skipCache && skipCache(output, requestConfig))\n ) {\n setCache(cacheKey, output, cacheTime, requestConfig.staleTime);\n\n // Error responses are only cached in memory\n if (!isError) {\n persistCache(cacheKey, requestConfig.cacheStore);\n }\n } else {\n const entry = getCache(cacheKey);\n\n // Don't let the in-flight placeholder outlive a request whose result isn't cached\n if (entry && entry.data && entry.data.isFetching) {\n deleteCache(cacheKey);\n }\n }\n\n notifySubscribers(cacheKey, output);\n removeInFlight(cacheKey);\n\n const prevCacheKey = requestConfig._prevKey;\n\n if (prevCacheKey) {\n removeInFlight(prevCacheKey);\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { mutate } from './cache-manager';\nimport {\n APPLICATION_CONTENT_TYPE,\n APPLICATION_JSON,\n CONTENT_TYPE,\n FUNCTION,\n STRING,\n} from './constants';\nimport {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n ResponseError,\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n} from './types';\nimport { flattenData, isObject, processHeaders } from './utils';\n\n/**\n * Parses the response data based on the Content-Type header, or reads it as the given response type.\n *\n * @param response - The Response object to parse.\n * @param responseType - How to read the body regardless of its Content-Type, e.g. as a Blob, or `'stream'` to leave it unread.\n * @returns A Promise that resolves to the parsed data.\n */\nexport async function parseResponseData<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse,\n responseType?: RequestConfig['responseType'],\n): Promise {\n // Bail early if response is null or undefined\n if (!response) {\n return null;\n }\n\n // Get the content-type header once\n const headers = (response as Response).headers;\n let contentType = headers && headers.get(CONTENT_TYPE);\n\n if (contentType) {\n // Lowercase and trim for consistent matching\n contentType = contentType.toLowerCase().trim();\n } else {\n contentType = '';\n }\n\n // Split for mime type without charset\n const mimeType = contentType.split(';', 1)[0];\n\n let data;\n\n try {\n if (responseType) {\n // The body is read as requested, or left unread as a stream to be read by the caller\n data =\n responseType === 'stream'\n ? response.body\n : await response[responseType]();\n } else if (\n mimeType.includes(APPLICATION_JSON) ||\n mimeType.includes('+json')\n ) {\n data = await response.json(); // Parse JSON response\n } else if (\n (mimeType.includes('multipart/form-data') || // Parse as FormData\n mimeType.includes(\n APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded', // Handle URL-encoded forms\n )) &&\n typeof response.formData === FUNCTION\n ) {\n data = await response.formData();\n } else if (/^(image|video|audio)\\/|octet-stream|pdf|zip/.test(mimeType)) {\n data = await response.arrayBuffer(); // Parse as ArrayBuffer for binary types\n } else {\n data = await response.text();\n\n if (typeof data === STRING) {\n const trimmed = data.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n data = JSON.parse(trimmed);\n } catch {\n // leave as text if parsing fails\n }\n }\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (_error) {\n // Parsing failed, fallback to null\n data = null;\n }\n\n return data;\n}\n\n/**\n * Prepare response object with additional information.\n *\n * @param Response. It may be \"null\" in case of request being aborted.\n * @param {RequestConfig} config - Request config\n * @param error - whether the response is erroneous\n * @returns {FetchResponse} Response data\n */\nexport const prepareResponse = <\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n config: RequestConfig,\n error: ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null,\n): FetchResponse => {\n const defaultResponse = config.defaultResponse;\n const cacheKey = config.cacheKey;\n const mutatator = mutate.bind(null, cacheKey as string) as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >['mutate'];\n\n // This may happen when request is cancelled.\n if (!response) {\n return {\n ok: false,\n // Enhance the response with extra information\n error,\n data: defaultResponse ?? null,\n headers: null,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: false,\n isError: true,\n } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n const isNativeResponse =\n typeof Response === FUNCTION && response instanceof Response;\n\n let data = response.data;\n\n // Set the default response if the provided data is an empty object or array\n // Other objects, e.g. Blobs, buffers and streams, have no keys either, but aren't empty\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (/^\\[object (Object|Array)\\]$/.test(\n Object.prototype.toString.call(data),\n ) &&\n Object.keys(data).length === 0))\n ) {\n response.data = data = defaultResponse;\n }\n\n if (config.flattenResponse) {\n response.data = data = flattenData(data);\n }\n\n if (config.select) {\n response.data = data = config.select(data);\n }\n\n const headers = processHeaders(response.headers);\n\n // Native fetch Response extended by extra information\n if (isNativeResponse) {\n const output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > = {\n body: response.body,\n bodyUsed: response.bodyUsed,\n ok: response.ok,\n redirected: response.redirected,\n type: response.type,\n url: response.url,\n status: response.status,\n statusText: response.statusText,\n\n // Convert methods to use arrow functions to preserve correct return types\n // Lazily construct Blob from ArrayBuffer\n blob: async () =>\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n json: async () => data as ResponseData, // Return the already parsed JSON data\n text: async () => data as string, // Return the already parsed text data\n // The body was already read, so a copy of this response is returned instead of Response.clone()\n clone: () => ({ ...output }),\n arrayBuffer: async () =>\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0), // Return the ArrayBuffer directly\n formData: async () => (data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: async () =>\n new Uint8Array(data instanceof ArrayBuffer ? data : new ArrayBuffer(0)),\n // Enhance the response with extra information\n error,\n data,\n headers,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: response.ok && !error,\n isError: !!error,\n };\n\n return output;\n }\n\n // If it's a custom fetcher, and it does not return any Response instance, it may have its own internal handler\n if (isObject(response)) {\n // Assigned one by one, as Object.assign() with an object literal is measurably slower here\n response.error = error;\n response.headers = headers;\n response.isFetching = false;\n response.mutate = mutatator;\n response.isSuccess = response.ok && !error;\n response.isError = !!error;\n }\n\n return response;\n};\n","import { applyInterceptors } from './interceptor-manager';\nimport type { FetchResponse, RetryConfig, RetryFunction } from './types';\nimport { delayInvocation, timeNow } from './utils';\nimport { generateCacheKey } from './cache-manager';\nimport { FUNCTION } from './constants';\n\nfunction getMsFromHttpDate(dateString: string): number | null {\n const ms = Date.parse(dateString) - timeNow();\n\n if (!isNaN(ms)) {\n return Math.max(0, Math.floor(ms));\n }\n return null;\n}\n\n/**\n * Calculates the number of milliseconds to wait before retrying a request,\n * based on the `Retry-After` HTTP header in the provided response.\n *\n * The function supports both numeric (seconds) and HTTP-date formats for the `Retry-After` header.\n * - If the header is a number, it is interpreted as seconds and converted to milliseconds.\n * - If the header is a date, the function calculates the difference between the date and the current time.\n *\n * @param extendedResponse - The response object containing headers, or `null`.\n * @returns The number of milliseconds to wait before retrying, or `null` if the header is not present or invalid.\n */\nexport function getRetryAfterMs(\n extendedResponse: FetchResponse | null,\n): number | null {\n if (!extendedResponse) {\n return null;\n }\n\n const headers = extendedResponse.headers || {};\n const retryAfter = headers['retry-after'];\n\n if (retryAfter) {\n // Try parsing as seconds\n const seconds = Number(retryAfter);\n\n if (!isNaN(seconds) && seconds >= 0) {\n return seconds * 1000;\n }\n\n const ms = getMsFromHttpDate(retryAfter);\n\n if (ms !== null) {\n return ms;\n }\n }\n\n // Headers are already in lowercase\n const RATELIMIT_RESET = 'ratelimit-reset';\n\n // Unix timestamp when the rate limit window resets (relative to current time)\n // Fallback to checking 'ratelimit-reset-after' OR 'x-ratelimit-reset-after' headers\n const rateLimitResetAfter =\n headers[RATELIMIT_RESET + '-after'] ||\n headers['x-' + RATELIMIT_RESET + '-after'];\n\n if (rateLimitResetAfter) {\n const seconds = Number(rateLimitResetAfter);\n\n if (!isNaN(seconds)) {\n return seconds * 1000;\n }\n }\n\n // ISO 8601 datetime when the rate limit resets\n // Fallback to checking 'ratelimit-reset-at' 'x-ratelimit-reset-at' headers\n const rateLimitResetAt =\n headers[RATELIMIT_RESET + '-at'] || headers['x-' + RATELIMIT_RESET + '-at'];\n\n if (rateLimitResetAt) {\n return getMsFromHttpDate(rateLimitResetAt);\n }\n\n return null;\n}\n\n/**\n * Executes a request function with retry logic according to the provided configuration.\n *\n * The function attempts the request up to the specified number of retries, applying delay and backoff strategies.\n * Retries can be triggered based on response status codes, custom logic, or the presence of a `Retry-After` header.\n * Optionally, an `onRetry` interceptor can be invoked before each retry attempt.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param requestFn - The function that performs the request. Receives `isStaleRevalidation` and `attempt` as arguments.\n * @param config - The retry configuration, including retry count, delay, backoff, retry conditions, and hooks.\n * @returns A promise resolving to the fetch response, or rejecting if all retries are exhausted.\n * @throws Error if the maximum number of retries is exceeded or a non-retriable error occurs.\n */\nexport async function withRetry<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation: boolean,\n attempt: number,\n ) => Promise<\n FetchResponse\n >,\n config: RetryConfig,\n): Promise> {\n const {\n retries = 0,\n delay = 0,\n backoff = 1,\n maxDelay,\n retryOn = [],\n shouldRetry,\n jitter,\n methods,\n } = config;\n\n let attempt = 0;\n let waitTime = delay;\n const maxRetries = retries > 0 ? retries : 0;\n let output: FetchResponse;\n\n while (attempt <= maxRetries) {\n // Subsequent attempts will have output defined, but the first attempt may not.\n // Let's apply onRetry interceptor and regenerate cache key if ot really changes.\n if (attempt > 0 && output!) {\n const cfg = output.config;\n const onRetry = cfg.onRetry;\n\n if (onRetry) {\n await applyInterceptors(onRetry, output, attempt);\n\n // If the key was automatically generated, we need to regenerate it as config may change.\n // We don't detect whether config changed for performance reasons.\n if (cfg._isAutoKey) {\n cfg._prevKey = cfg.cacheKey as string;\n cfg.cacheKey = generateCacheKey(cfg, false);\n }\n }\n }\n\n // Performance optimization: Call the request function with the current attempt number\n // If this is the first attempt, we pass `isStaleRevalidation` as `false`,\n // otherwise we pass `true` to indicate that this is a stale revalidation (no cache hit).\n output = await requestFn(attempt > 0, attempt);\n const error = output.error;\n\n // Stop unless a failed response should be retried according to the retry settings,\n // or a successful one according to shouldRetry\n if (\n error\n ? await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n methods,\n )\n : !(\n shouldRetry &&\n attempt < maxRetries &&\n (await shouldRetry(output, attempt))\n )\n ) {\n break;\n }\n\n // The delay before the next retry, randomized with jitter unless the server asks for one below\n let retryDelay = withJitter(waitTime, jitter);\n\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (error && (error.status === 429 || error.status === 503)) {\n // Try to extract the \"Retry-After\" value from the response headers\n const retryAfterMs = getRetryAfterMs(output);\n\n // If a valid retry-after value is found, override the wait time before next retry\n // Cap it with maxDelay so that a server can't make the client wait indefinitely\n if (retryAfterMs !== null) {\n retryDelay = waitTime = Math.min(\n retryAfterMs,\n maxDelay || retryAfterMs,\n );\n }\n }\n\n await delayInvocation(retryDelay);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n }\n\n return output!;\n}\n\n/**\n * Determines whether to stop retrying based on the error, current attempt count, and retry configuration.\n *\n * This function checks:\n * - If the maximum number of retries has been reached.\n * - If the request was aborted, e.g. with its signal or by a newer request. Aborted requests are never retried.\n * - If a custom `shouldRetry` callback is provided, its result is used to decide.\n * - If no custom logic is provided, falls back to checking if the error status is included in the `retryOn` list,\n * and the request method in the `methods` list, if any.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param output - The response object containing the error and request configuration.\n * @param attempt - The current retry attempt number.\n * @param maxRetries - The maximum number of retry attempts allowed.\n * @param shouldRetry - Optional custom function to determine if a retry should occur.\n * @param retryOn - Optional list of HTTP status codes that should trigger a retry.\n * @param methods - Optional list of request methods that are retried on the `retryOn` statuses. All methods are retried without it.\n * @returns A promise resolving to `true` if retrying should stop, or `false` to continue retrying.\n */\nexport async function getShouldStopRetrying<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n output: FetchResponse,\n attempt: number,\n maxRetries: number,\n shouldRetry?: RetryFunction<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n retryOn: number[] = [],\n methods?: string[],\n): Promise {\n // Safety first: always respect max retries\n // We check retries provided regardless of the shouldRetry being provided so to avoid infinite loops.\n // It is a fail-safe so to prevent excessive retry attempts even if custom retry logic suggests a retry.\n if (attempt === maxRetries) {\n return true;\n }\n\n // Aborted requests are never retried, as e.g. a retry of one cancelled by a newer request would cancel the newer one\n if (output.error?.isCancelled) {\n return true;\n }\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n\n if (result !== null) {\n return !result;\n }\n }\n\n return !(\n (retryOn || []).includes(output.error?.status ?? 0) &&\n (!methods ||\n methods.some((method) => method.toUpperCase() === output.config.method))\n );\n}\n\n/**\n * Randomizes a retry delay with jitter, so that clients that failed at the same time, e.g. during an outage, don't retry all at once.\n *\n * @param delay - The delay computed from the `delay`, `backoff` and `maxDelay` settings, in milliseconds.\n * @param jitter - `true` for a random delay between 0 and the computed one (\"full jitter\"), or a function that returns the delay to use.\n * @returns The delay to wait before the retry, in milliseconds.\n */\nfunction withJitter(delay: number, jitter: RetryConfig['jitter']): number {\n return typeof jitter === FUNCTION\n ? (jitter as (delay: number) => number)(delay)\n : jitter\n ? Math.random() * delay\n : delay;\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation, isOffline, isPageHidden } from './utils';\n\n/**\n * Executes a request function with polling, stopping when shouldStopPolling returns true,\n * pollingInterval is not set, or maxAttempts is reached.\n * Polling pauses while the page is hidden or the browser is offline, unless allowed by refreshWhenHidden or refreshWhenOffline.\n *\n * @template Output The type of the output returned by the request function.\n * @param requestFn - The function that performs a single request (with retries).\n * @param pollingInterval - Interval in ms between polling attempts.\n * @param shouldStopPolling - Function to determine if polling should stop.\n * @param maxAttempts - Maximum number of polling attempts, default: 0 (unlimited).\n * @param pollingDelay - Delay in ms before each polling attempt, default: 0.\n * @param refreshWhenHidden - Whether to keep polling while the page is hidden, default: false.\n * @param refreshWhenOffline - Whether to keep polling while the browser is offline, default: false.\n * @param signal - The signal passed to the request. Polling stops once it is aborted.\n * @returns The final output from the last request.\n */\nexport async function withPolling<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation?: boolean,\n attempt?: number,\n ) => Promise<\n FetchResponse\n >,\n pollingInterval?: RequestConfig['pollingInterval'],\n shouldStopPolling?: RequestConfig['shouldStopPolling'],\n maxAttempts = 0,\n pollingDelay = 0,\n refreshWhenHidden = false,\n refreshWhenOffline = false,\n signal?: AbortSignal,\n): Promise> {\n if (!pollingInterval) {\n return requestFn();\n }\n\n let pollingAttempt = 0;\n let output: FetchResponse;\n\n while (maxAttempts === 0 || pollingAttempt < maxAttempts) {\n if (pollingDelay > 0) {\n await delayInvocation(pollingDelay, signal);\n }\n\n output = await requestFn();\n\n pollingAttempt++;\n\n if (\n (maxAttempts > 0 && pollingAttempt >= maxAttempts) ||\n !pollingInterval ||\n (shouldStopPolling && shouldStopPolling(output, pollingAttempt))\n ) {\n break;\n }\n\n // Wait for the next attempt, and keep waiting while polling is paused\n do {\n await delayInvocation(pollingInterval, signal);\n\n // Aborting the signal of the request stops polling\n if (signal && signal.aborted) {\n return output;\n }\n } while (\n (!refreshWhenHidden && isPageHidden()) ||\n (!refreshWhenOffline && isOffline())\n );\n }\n\n return output!;\n}\n","import { ABORT_ERROR, UNDEFINED } from './constants';\nimport type { RequestConfig, UploadProgress } from './types';\nimport { createAbortError } from './utils';\n\n// Responses with these statuses can't have a body\nconst NULL_BODY_STATUSES = [204, 205, 304];\n\n// Headers that browsers don't let requests set. fetch() skips them silently, while\n// XMLHttpRequest logs errors for them, so they are skipped before sending.\nconst FORBIDDEN_HEADERS =\n /^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/;\n\n// ReadableStream is missing in some environments, e.g. React Native\nconst isStream = (body: unknown): body is ReadableStream =>\n typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream;\n\nexport const toProgress = (loaded: number, total?: number): UploadProgress => ({\n loaded,\n total,\n progress: total ? loaded / total : undefined,\n});\n\n/**\n * Sends a request and reports the upload progress of its body to `onUploadProgress`.\n * Browsers and React Native don't report the upload progress of fetch(), so XMLHttpRequest is used there.\n * Elsewhere, e.g. in Node.js, the body is streamed with fetch() and counted while it is sent.\n *\n * @param {string} url - The request URL.\n * @param {RequestConfig} config - The request configuration, with a body and `onUploadProgress`.\n * @returns {Promise} - The response.\n */\nexport function fetchWithUploadProgress(\n url: string,\n config: RequestConfig,\n): Promise {\n const body = config.body as BodyInit;\n\n return typeof XMLHttpRequest !== UNDEFINED && !isStream(body)\n ? sendWithXhr(url, config, body)\n : sendStreamed(url, config, body);\n}\n\nfunction sendWithXhr(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n // fetchf() always sets the signal, as it handles timeouts and cancellation with it\n const signal = config.signal!;\n const abort = () => xhr.abort();\n\n const settle = (fn: () => void) => {\n signal.removeEventListener('abort', abort);\n\n try {\n fn();\n } catch (error) {\n reject(error);\n }\n };\n\n xhr.open(config.method as string, url);\n xhr.responseType = 'blob';\n xhr.withCredentials = config.credentials === 'include';\n\n new Headers(config.headers).forEach(\n (value, name) =>\n FORBIDDEN_HEADERS.test(name) || xhr.setRequestHeader(name, value),\n );\n\n xhr.upload.onprogress = (event) =>\n config.onUploadProgress!(\n toProgress(\n event.loaded,\n event.lengthComputable ? event.total : undefined,\n ),\n );\n\n xhr.onload = () =>\n settle(() => {\n const headers = new Headers();\n\n for (const line of xhr.getAllResponseHeaders().split(/\\r?\\n/)) {\n const index = line.indexOf(':');\n\n if (index > 0) {\n headers.append(line.slice(0, index), line.slice(index + 1).trim());\n }\n }\n\n const response = new Response(\n NULL_BODY_STATUSES.includes(xhr.status) ? null : xhr.response,\n { status: xhr.status, statusText: xhr.statusText, headers },\n );\n\n // Like fetch(), the response tells its final URL, e.g. after redirects\n Object.defineProperty(response, 'url', { value: xhr.responseURL });\n\n resolve(response);\n });\n\n xhr.onerror = () =>\n settle(() => reject(new TypeError('Network request failed')));\n\n // Like fetch(), aborted requests reject with the reason of the abort signal\n const onAbort = () =>\n settle(() =>\n reject(\n signal.reason ||\n createAbortError('The request was aborted', ABORT_ERROR),\n ),\n );\n\n xhr.onabort = onAbort;\n\n if (signal.aborted) {\n return onAbort();\n }\n\n signal.addEventListener('abort', abort);\n\n xhr.send(body as XMLHttpRequestBodyInit);\n });\n}\n\nasync function sendStreamed(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n const headers = new Headers(config.headers);\n let stream = body as ReadableStream;\n let total: number | undefined;\n\n if (!isStream(body)) {\n // Serialize the body like fetch() would, to know its size and content type\n const blob = body instanceof Blob ? body : await new Response(body).blob();\n\n total = blob.size;\n stream = blob.stream();\n\n if (blob.type && !headers.has('content-type')) {\n headers.set('content-type', blob.type);\n }\n }\n\n let loaded = 0;\n\n return fetch(url, {\n ...config,\n headers,\n body: stream.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n config.onUploadProgress!(toProgress(loaded, total));\n controller.enqueue(chunk);\n },\n }),\n ),\n // Required by fetch() to send a stream\n duplex: 'half',\n } as RequestInit);\n}\n","import { FUNCTION } from './constants';\nimport type { DownloadProgress } from './types';\nimport { toProgress } from './upload-progress';\n\n/**\n * Reports the download progress of a response body to `onDownloadProgress` while the body is read.\n * The body is counted as it arrives, so the progress follows the download.\n *\n * @param {T} response - The response. Other than native responses with a body, e.g. responses of HEAD requests or custom fetchers, are returned as they are.\n * @param {Function} [onDownloadProgress] - The function called with the progress. Without it, the response is returned as it is.\n * @returns {T} - A copy of the response, whose body is counted while it's read.\n */\nexport function withDownloadProgress(\n response: T,\n onDownloadProgress?: (progress: DownloadProgress) => void,\n): T {\n // Response is missing in some environments, and response bodies e.g. in React Native\n if (\n !onDownloadProgress ||\n typeof Response !== FUNCTION ||\n !(response instanceof Response) ||\n !response.body\n ) {\n return response;\n }\n\n const headers = response.headers;\n // Content-Length is the size of the compressed body, so the size of a compressed one is unknown\n const total = headers.has('content-encoding')\n ? undefined\n : Number(headers.get('content-length')) || undefined;\n let loaded = 0;\n\n const counted = new Response(\n response.body.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n // Browsers may hide the Content-Encoding header of cross-origin responses, so the progress is capped at 1\n onDownloadProgress(\n toProgress(loaded, total && Math.max(total, loaded)),\n );\n controller.enqueue(chunk);\n },\n }),\n ),\n response,\n );\n\n // Like the original response, the copy tells its final URL, whether it was redirected and its type\n for (const key of ['url', 'redirected', 'type'] as const) {\n Object.defineProperty(counted, key, { value: response[key] });\n }\n\n return counted as T;\n}\n","import type { ResponseError } from './errors/response-error';\nimport type {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n} from './types/request-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { handleResponseCache } from './cache-manager';\nimport { ABORT_ERROR, REJECT } from './constants';\nimport {\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n HeadersObject,\n} from './types';\nimport { processHeaders } from './utils';\n\n/**\n * Handles final processing for both success and error responses\n * Applies error interceptors, caching, notifications, and error strategy\n */\nexport async function withErrorHandling<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n isStaleRevalidation: boolean,\n requestFn: (\n isStaleRevalidation: boolean,\n ) => Promise<\n FetchResponse\n >,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): Promise> {\n const output = await requestFn(isStaleRevalidation);\n const error = output.error;\n\n if (!error) {\n // SUCCESS PATH\n handleResponseCache(output, requestConfig);\n\n return output;\n }\n\n // ERROR PATH\n\n if (requestConfig.onError) {\n await applyInterceptors(requestConfig.onError, error);\n }\n\n // Timeouts and request cancellations using AbortController do not throw any errors unless rejectCancelled is true.\n // Only handle the error if the request was not cancelled, or if it was cancelled and rejectCancelled is true.\n const isCancelled = error.isCancelled;\n\n const logger = requestConfig.logger;\n\n if (!isCancelled && logger && logger.warn) {\n logger.warn('FETCH ERROR', redactError(error as ResponseError));\n }\n\n // The defaultResponse strategy returns the default response in place of the error data.\n // The original data stays available through error.response.\n if (requestConfig.strategy === 'defaultResponse') {\n output.data = (requestConfig.defaultResponse ?? null) as typeof output.data;\n }\n\n // Handle cache and notifications FIRST (before strategy)\n handleResponseCache(output, requestConfig, true);\n\n // handle error strategy as the last part\n const shouldHandleError = !isCancelled || requestConfig.rejectCancelled;\n\n if (shouldHandleError) {\n const strategy = requestConfig.strategy;\n // Reject the promise\n if (strategy === REJECT) {\n throw error;\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\n}\n\n// Credential headers that must not end up in logs\nconst SENSITIVE_HEADERS = [\n 'authorization',\n 'proxy-authorization',\n 'cookie',\n 'x-api-key',\n];\n\n/**\n * Creates a copy of the error for logging, with credential headers masked and the request body removed.\n * The error itself is left untouched.\n */\nfunction redactError(error: ResponseError): ResponseError {\n // Cache keys are dropped too, as they can contain short request bodies\n const config = {\n ...error.config,\n body: undefined,\n data: undefined,\n cacheKey: undefined,\n _prevKey: undefined,\n headers: processHeaders(error.config.headers as HeadersObject),\n };\n\n for (const name of SENSITIVE_HEADERS) {\n if (config.headers[name]) {\n config.headers[name] = '[REDACTED]';\n }\n }\n\n const copy = Object.assign(new Error(error.message), error, {\n config,\n request: config,\n response: error.response && { ...error.response, config },\n });\n\n copy.name = error.name;\n copy.stack = error.stack;\n\n return copy;\n}\n\nexport function enhanceError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): void {\n error.status = error.status || (response && response.status) || 0;\n error.statusText =\n error.statusText || (response && response.statusText) || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n HeadersObject,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport type { StoredResponse } from './types/cache-manager';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject, noop, processHeaders } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport {\n generateCacheKey,\n getCacheData,\n getCachedResponse,\n getStoredCache,\n isCacheBypassed,\n restoreCache,\n setCache,\n} from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { fetchWithUploadProgress } from './upload-progress';\nimport { withDownloadProgress } from './download-progress';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION, GET, HEAD } from './constants';\nimport { buildConfig } from './config-handler';\n\nconst inFlightResponse = Object.freeze({\n isFetching: true,\n});\n\n/**\n * Sends an HTTP request to the specified URL using the provided configuration and returns a typed response.\n *\n * @typeParam ResponseData - The expected shape of the response data. Defaults to `DefaultResponse`.\n * @typeParam RequestBody - The type of the request payload/body. Defaults to `DefaultPayload`.\n * @typeParam QueryParams - The type of the query parameters. Defaults to `DefaultParams`.\n * @typeParam PathParams - The type of the path parameters. Defaults to `DefaultUrlParams`.\n *\n * @param url - The endpoint URL to which the request will be sent.\n * @param config - Optional configuration object for the request, including headers, method, body, query, and path parameters.\n *\n * @returns A promise that resolves to a `FetchResponse` containing the typed response data and request metadata.\n *\n * @example\n * ```typescript\n * const { data } = await fetchf('/api/user', { method: 'GET' });\n * console.log(data);\n * ```\n */\nexport async function fetchf<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n url: string,\n reqConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null = null,\n): Promise> {\n // Ultra-fast early cache check if cacheKey is provided as a string\n // For workloads dominated by repeated requests, this string caching optimization\n // can potentially support millions of requests per second with minimal CPU overhead\n if (reqConfig && typeof reqConfig.cacheKey === 'string') {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(reqConfig.cacheKey, reqConfig.cacheTime, reqConfig);\n\n if (cached) {\n return cached;\n }\n }\n\n const fetcherConfig = buildConfig<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(url, reqConfig);\n\n const {\n timeout,\n cancellable,\n cacheKey,\n dedupeTime,\n cacheTime,\n staleTime,\n refetchOnFocus,\n refetchOnReconnect,\n pollingInterval = 0,\n } = fetcherConfig;\n const isCacheEnabled = cacheTime !== undefined || staleTime !== undefined;\n const method = fetcherConfig.method;\n\n // Cached responses of GET and HEAD requests are revalidated with their ETag.\n // Custom fetchers may not handle 304 responses, so they only send it when it's enabled for them.\n const isETagEnabled =\n isCacheEnabled &&\n (method === GET || method === HEAD) &&\n (fetcherConfig.etag ?? !fetcherConfig.fetcher);\n\n const needsCacheKey = !!(\n cacheKey ||\n timeout ||\n dedupeTime ||\n isCacheEnabled ||\n cancellable ||\n refetchOnFocus ||\n refetchOnReconnect\n );\n\n let _cacheKey: string | null = null;\n\n // Generate cache key if required\n if (needsCacheKey) {\n _cacheKey = generateCacheKey(fetcherConfig);\n }\n\n // The initial data, which is used as the first response instead of sending the request\n let initialResponse: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n // Cache handling logic\n if (_cacheKey && isCacheEnabled) {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(_cacheKey, cacheTime, fetcherConfig);\n\n if (cached) {\n return cached;\n }\n\n // Restore the response from the cache store, e.g. one saved during a previous page load\n if (fetcherConfig.cacheStore) {\n const stored = await getStoredCache(_cacheKey, fetcherConfig);\n const restored =\n stored &&\n toResponse(\n stored.data,\n _cacheKey,\n fetcherConfig,\n );\n\n // A stale response is shown until the request below revalidates it\n if (\n restored &&\n restoreCache(\n _cacheKey,\n { ...stored, data: restored },\n fetcherConfig.cacheStore,\n )\n ) {\n return restored;\n }\n }\n\n // While there's no cached response, the initial data, e.g. data rendered on the server, is cached as the response\n if (\n fetcherConfig.initialData !== undefined &&\n !getCacheData(_cacheKey) &&\n !isCacheBypassed(fetcherConfig)\n ) {\n initialResponse = toResponse(\n {\n data: fetcherConfig.initialData,\n status: 200,\n statusText: '',\n headers: {},\n },\n _cacheKey,\n fetcherConfig,\n );\n }\n }\n\n // Deduplication logic\n if (_cacheKey && dedupeTime) {\n const inflight = getInFlightPromise<\n FetchResponse\n >(_cacheKey, dedupeTime);\n\n if (inflight) {\n return inflight;\n }\n }\n\n const retryConfig = fetcherConfig.retry || {};\n const { retries = 0, resetTimeout } = retryConfig;\n\n // The signal passed to the request. Each attempt replaces it in the config with a signal of its own.\n const userSignal = fetcherConfig.signal;\n\n // The actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation: boolean, attempt = 0) => {\n // The cached response to revalidate. It's read before the cache is marked as fetching below.\n const cached =\n isETagEnabled &&\n getCacheData(\n _cacheKey,\n );\n\n // If cache key is specified, we will handle optimistic updates\n // and mark the request as in-flight, so to catch \"fetching\" state.\n // This is useful for Optimistic UI updates (e.g., showing loading spinners).\n if (!attempt) {\n // The initial data is only used once, as the first response\n if (initialResponse) {\n const response = initialResponse;\n\n initialResponse = null;\n\n return response;\n }\n\n if (_cacheKey && !isStaleRevalidation) {\n if (staleTime) {\n const existingCache = getCachedResponse(\n _cacheKey,\n cacheTime,\n fetcherConfig,\n );\n\n // Don't notify subscribers when cache exists\n // Let them continue showing stale data during background revalidation\n if (!existingCache) {\n setCache(_cacheKey, inFlightResponse, cacheTime, staleTime);\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n } else {\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n }\n\n // Attach cache key so that it can be reused in interceptors or in the final response\n fetcherConfig.cacheKey = _cacheKey;\n }\n\n const url = fetcherConfig.url as string;\n\n // Add the request to the queue. Make sure to handle deduplication, cancellation, timeouts in accordance to retry settings\n const controller = markInFlight(\n _cacheKey,\n url,\n timeout,\n dedupeTime || 0,\n !!cancellable,\n // Enable timeout either by default or when retries & resetTimeout are enabled\n !!(timeout && (!attempt || resetTimeout)),\n );\n\n // Do not create a shallow copy to maintain idempotency here.\n // This ensures the original object is mutated by interceptors whenever needed, including retry logic.\n const requestConfig = fetcherConfig;\n\n requestConfig.signal = controller.signal;\n\n // The request is aborted along with the signal passed to it, which may have been aborted already\n const abort = () => controller.abort(userSignal!.reason);\n\n if (userSignal) {\n if (userSignal.aborted) {\n abort();\n } else {\n userSignal.addEventListener('abort', abort);\n }\n }\n\n let output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n let response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n try {\n if (fetcherConfig.onRequest) {\n // Zero-allocation yield to microtask queue so the outer fetchf() can call setInFlightPromise()\n // before onRequest interceptors run. This ensures that if onRequest triggers\n // another fetchf() with the same cacheKey, getInFlightPromise() finds item[4].\n // On retries (attempt > 0), setInFlightPromise() was already called during the first attempt.\n // The promise stored in item[4] is the outer doRequestPromise which covers all retries.\n // So the race only matters on the very first attempt when the outer scope hasn't had a chance to call setInFlightPromise() yet.\n if (_cacheKey && dedupeTime && !attempt) {\n await null;\n }\n\n await applyInterceptors(fetcherConfig.onRequest, requestConfig);\n }\n\n // Custom fetcher\n const fn = fetcherConfig.fetcher;\n const init = withETag(requestConfig, cached);\n\n response = (fn\n ? await fn(\n url,\n init,\n )\n : // Uploads with onUploadProgress are sent in a way that reports their progress\n await (requestConfig.onUploadProgress && requestConfig.body\n ? fetchWithUploadProgress(url, requestConfig)\n : fetch(url, init as RequestInit))) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Reports the download progress while the body is read\n response = withDownloadProgress(\n response,\n requestConfig.onDownloadProgress,\n );\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\n // The server answered that the cached response is still valid, so it's reused instead of being sent again.\n // Like other cached responses, it has been parsed and transformed already.\n if (init !== requestConfig && response.status === 304) {\n return cached as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n // Case 1: Native Response instance\n if (typeof Response === FUNCTION && response instanceof Response) {\n response.data = requestConfig.parser\n ? await requestConfig.parser(response)\n : await parseResponseData(response, requestConfig.responseType);\n } else if (fn) {\n // Case 2: Custom fetcher that returns a response object\n if (!('data' in response && 'body' in response)) {\n // Case 3: Raw data, wrap it\n response = { data: response } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n }\n\n // Attach config and data to the response\n // This is useful for custom fetchers that do not return a Response instance\n // and for interceptors that may need to access the request config\n response.config = requestConfig;\n\n // Check if the response status is not outside the range 200-299 and if so, output error\n // This is the pattern for fetch responses as per spec, but custom fetchers may not follow it so we check for `ok` property\n if (response.ok !== undefined && !response.ok) {\n throw new ResponseError(\n requestConfig.method +\n ' to ' +\n url +\n ' failed! Status: ' +\n (response.status || null),\n requestConfig,\n response,\n );\n }\n }\n\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig);\n\n const onResponse = fetcherConfig.onResponse;\n\n if (onResponse) {\n await applyInterceptors(onResponse, output);\n }\n } catch (_error) {\n const error = _error as ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Append additional information to Network, CORS or any other fetch() errors\n enhanceError(\n error,\n response,\n requestConfig,\n );\n\n // Prepare Extended Response\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig, error);\n } finally {\n if (userSignal) {\n userSignal.removeEventListener('abort', abort);\n }\n }\n\n return output;\n };\n\n // Inline and minimize function wrappers for performance\n // When retries are enabled, forward isStaleRevalidation so the first attempt\n // of a background SWR revalidation doesn't incorrectly mark the request as in-flight\n const baseRequest =\n retries > 0\n ? (isStaleRevalidation: boolean) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const { onLoadingSlow, loadingTimeout } = fetcherConfig;\n\n // Calls onLoadingSlow once a request, including its retries, is still pending after loadingTimeout.\n // Background revalidations don't show a loading state, so they are never considered slow.\n const request =\n onLoadingSlow && loadingTimeout\n ? async (isStaleRevalidation: boolean) => {\n if (isStaleRevalidation) {\n return baseRequest(isStaleRevalidation);\n }\n\n const timer = setTimeout(\n () => applyInterceptors(onLoadingSlow, fetcherConfig).catch(noop),\n loadingTimeout,\n );\n\n try {\n return await baseRequest(isStaleRevalidation);\n } finally {\n clearTimeout(timer);\n }\n }\n : baseRequest;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n request,\n fetcherConfig,\n );\n\n // Avoid unnecessary function wrapping if polling is not enabled\n const doRequestPromise = pollingInterval\n ? withPolling(\n requestWithErrorHandling,\n pollingInterval,\n fetcherConfig.shouldStopPolling,\n fetcherConfig.maxPollingAttempts,\n fetcherConfig.pollingDelay,\n fetcherConfig.refreshWhenHidden,\n fetcherConfig.refreshWhenOffline,\n userSignal,\n )\n : requestWithErrorHandling();\n\n // If deduplication is enabled, store the in-flight promise immediately\n if (_cacheKey) {\n if (dedupeTime) {\n setInFlightPromise(_cacheKey, doRequestPromise);\n }\n\n // Only register revalidator when revalidation features are actually requested\n if (staleTime || refetchOnFocus || refetchOnReconnect) {\n addRevalidator(\n _cacheKey,\n requestWithErrorHandling,\n undefined,\n staleTime,\n requestWithErrorHandling,\n !!refetchOnFocus,\n !!refetchOnReconnect,\n fetcherConfig.focusThrottleInterval,\n );\n }\n }\n\n return doRequestPromise;\n}\n\n/**\n * Recreates a response from its copy in a cache store.\n * The data was transformed before it was stored, so it isn't transformed again.\n *\n * @param stored - The stored copy of the response.\n * @param cacheKey - The cache key of the request.\n * @param config - The request configuration.\n * @returns The response, or null if the stored copy is invalid, e.g. has an unknown status.\n */\nfunction toResponse(\n stored: StoredResponse,\n cacheKey: string,\n config: RequestConfig,\n): FetchResponse | null {\n try {\n // Without the Fetch API (e.g. with a custom fetcher in tests), a plain response object is used\n const response = (typeof Response === FUNCTION\n ? new Response(null, stored)\n : {\n ok: true,\n status: stored.status,\n statusText: stored.statusText,\n headers: stored.headers,\n }) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n response.data = stored.data as typeof response.data;\n config.cacheKey = cacheKey;\n\n const output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, {\n ...config,\n select: undefined,\n flattenResponse: false,\n defaultResponse: undefined,\n });\n\n output.config = config;\n\n return output;\n } catch {\n return null;\n }\n}\n\n/**\n * Asks the server whether a cached response is still valid, by sending its ETag in the If-None-Match header.\n * Then the server can answer 304 Not Modified instead of sending the response again.\n * Requests with an If-None-Match header of their own are sent as they are.\n *\n * @param config - The request configuration.\n * @param cached - The cached response of the request, if any.\n * @returns A copy of the configuration with the If-None-Match header, or the configuration itself if the cached response has no ETag.\n */\nfunction withETag(\n config: RequestConfig,\n cached: FetchResponse | null | false,\n): RequestConfig {\n const etag = cached && !cached.error && cached.headers && cached.headers.etag;\n const headers = etag && processHeaders(config.headers as HeadersObject);\n\n return headers && !headers['if-none-match']\n ? { ...config, headers: { ...headers, 'if-none-match': etag } }\n : config;\n}\n","import type {\n ApiHandlerConfig,\n ApiHandlerDefaultMethods,\n ApiHandlerMethods,\n RequestConfigUrlRequired,\n} from './types/api-handler';\nimport { fetchf } from '.';\nimport { mergeConfigs } from './config-handler';\nimport { hasOwn } from './utils';\n\n/**\n * Creates an instance of API Handler.\n * It creates an API fetcher function using native fetch() or a custom fetcher if passed as \"fetcher\".\n * @see https://github.com/MattCCC/fetchff#configuration\n *\n * @param {Object} config - Configuration object for the API fetcher (see link above for full options).\n * @param {Object} config.endpoints - An object containing endpoint definitions.\n * @param {string} [config.baseURL] - The base URL for the API.\n * @param {Object} [config.headers] - Optional default headers to include in every request.\n * @param {Function} [config.onError] - Optional callback function for handling errors.\n * @returns API handler functions and endpoints to call\n *\n * @example\n * // Define endpoint paths\n * const endpoints = {\n * getUser: '/user',\n * createPost: '/post',\n * };\n *\n * // Create the API fetcher with configuration\n * const api = createApiFetcher({\n * endpoints,\n * apiUrl: 'https://example.com/api',\n * onError(error) {\n * console.log('Request failed', error);\n * },\n * headers: {\n * 'my-auth-key': 'example-auth-key-32rjjfa',\n * },\n * });\n *\n * // Fetch user data\n * const response = await api.getUser({ userId: 1, ratings: [1, 2] })\n */\nfunction createApiFetcher<\n EndpointTypes extends object,\n EndpointsSettings = never,\n>(config: ApiHandlerConfig) {\n const endpoints = config.endpoints;\n\n /**\n * Triggered when trying to use non-existent endpoints\n *\n * @param endpointName Endpoint Name\n * @returns {Promise}\n */\n async function handleNonImplemented(endpointName: string): Promise {\n console.error('Add ' + endpointName + \" to 'endpoints'.\");\n\n return null;\n }\n\n const apiHandler: ApiHandlerDefaultMethods = {\n config,\n endpoints,\n /**\n * Handle Single API Request\n * It considers settings in following order: per-request settings, global per-endpoint settings, global settings.\n *\n * @param endpointName - The name of the API endpoint to call.\n * @param requestConfig - Additional configuration for the request.\n * @returns A promise that resolves with the response from the API provider.\n */\n async request(endpointName, requestConfig = {}) {\n // Use global and per-endpoint settings\n // Only own properties are endpoints, not ones inherited like \"constructor\"\n const endpointConfig = hasOwn(endpoints, endpointName as string)\n ? endpoints[endpointName]\n : undefined;\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // URL parsers ignore leading control characters and spaces, drop tabs and newlines,\n // and treat backslashes like slashes, so check the URL the way it will be resolved\n const resolvedUrl = url\n .replace(/[\\t\\n\\r]/g, '')\n // eslint-disable-next-line no-control-regex -- matching control characters is the point\n .replace(/^[\\x00-\\x20]+/, '');\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (/^[/\\\\]{2}/.test(resolvedUrl)) {\n throw new Error('Protocol-relative URLs not allowed.');\n }\n\n // Prevent potential Server-Side Request Forgery attack and leakage of credentials when same instance is used for external requests\n // Any scheme counts here, as e.g. \"http:\\\\host\" or \"http:host\" can also point to another host\n const mergedConfig = /^[a-z][a-z\\d+\\-.]*:/i.test(resolvedUrl)\n ? // Merge endpoints configs for absolute URLs only if urls match\n endpointConfig && endpointConfig.url === url\n ? mergeConfigs(_endpointConfig, requestConfig)\n : requestConfig\n : mergeConfigs(mergeConfigs(config, _endpointConfig), requestConfig);\n\n // We prevent potential Server-Side Request Forgery attack and leakage of credentials as the same instance is not used for external requests\n // Retrigger fetch to ensure completely new instance of handler being triggered for external URLs\n return fetchf(url, mergedConfig);\n },\n };\n\n /**\n * Maps all API requests using native Proxy\n *\n * @param {*} prop Caller\n */\n return new Proxy>(\n apiHandler as ApiHandlerMethods,\n {\n get(_target, prop: string | symbol) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Symbols (e.g. inspection hooks) are never endpoints, and returning a function\n // for \"then\" would make the instance a thenable that never settles when awaited\n if (typeof prop === 'symbol' || prop === 'then') {\n return undefined;\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (hasOwn(endpoints, prop)) {\n return apiHandler.request.bind(null, prop);\n }\n\n return handleNonImplemented.bind(null, prop);\n },\n },\n );\n}\n\nexport { createApiFetcher };\n"]} \ No newline at end of file diff --git a/dist/browser/index.mjs b/dist/browser/index.mjs index 1c43445..2e199a3 100644 --- a/dist/browser/index.mjs +++ b/dist/browser/index.mjs @@ -1,3 +1,3 @@ -var z="application/",te=z+"json",et="charset=utf-8",_="Content-Type",D="undefined",Ie="object",x="string",b="function",k="AbortError",tt="TimeoutError",O="GET",re="HEAD",pe="reject",ye=2147483647;var st=10,S=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);function J(e){return e instanceof URLSearchParams}function g(e){return e!==null&&typeof e===Ie}function B(e){let t=S(e,"__proto__"),r=S(e,"constructor"),s=S(e,"prototype");if(!t&&!r&&!s)return e;let n={};for(let a of Object.keys(e))a!=="__proto__"&&a!=="constructor"&&a!=="prototype"&&(n[a]=e[a]);return n}function at(e){let t=Object.create(null);return Object.keys(e).sort().forEach(r=>t[r]=e[r]),t}function rt(e,t){return t?e+(e.includes("?")?"&":"?")+t:e}function nt(e,t){if(!t)return e;if(J(t)){let u=t.toString();return rt(e,u)}let r=[],s=encodeURIComponent,n=(u,c)=>{c=typeof c===b?c():c,c=c==null?"":c,r[r.length]=s(u)+"="+s(c);},a=(u,c,f=0)=>{if(f>=st)return r;let l,p,m;if(u)if(Array.isArray(c))for(l=0,p=c.length;l{let o=n||a;if(S(r,o)){let i=r[o];if(i!=null){let u=encodeURIComponent(String(i));if(u==="."||u==="..")throw new Error('Path params "." and ".." not allowed.');return u}}return s})}function it(e){return /^[a-z][a-z\d+\-.]*:\/\//i.test(e)}var h=()=>Date.now(),C=()=>{};function se(e){let t=typeof e;return e==null?false:t===x||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==D&&typeof globalThis.Buffer!==D&&globalThis.Buffer.isBuffer(e)||e instanceof Date||J(e)?false:!!(g(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===b))}var ae=(e,t)=>new Promise(r=>{let s=()=>{clearTimeout(n),t&&t.removeEventListener("abort",s),r(true);},n=setTimeout(s,Math.min(e,ye));t&&(t.aborted?s():t.addEventListener("abort",s));});function ve(e,t=0){return t>=st?e:e&&g(e)&&typeof e.data!==D?ve(e.data,t+1):e}function E(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,s)=>{t[s.toLowerCase()]=r;});else for(let r in e)S(e,r)&&r!=="__proto__"&&(t[r.toLowerCase()]=e[r]);return t}function ut(){return typeof window!==D&&typeof window.addEventListener===b}function W(e,t){if(typeof DOMException!==D)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Se=()=>{let e=typeof navigator!==D&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)},ct=()=>typeof document!==D&&document.visibilityState==="hidden",lt=()=>typeof navigator!==D&&navigator.onLine===false;async function F(e,t,...r){if(!e)return;let s=n=>n&&g(t)&&g(n)&&Object.assign(t,B(n));if(typeof e===b)s(await e(t,...r));else if(Array.isArray(e))for(let n of e)s(await n(t,...r));}var Re=class extends Error{constructor(t,r,s){super(t),this.request=r,this.response=s,this.status=s?s.status:0,this.statusText=s?s.statusText:"",this.config=r,this.isCancelled=false,this.name="FetchError";}};var he=class extends Re{constructor(t,r,s){super(t,r,s),this.name="ResponseError";}};var be=600,Pe=1e3,Qe=Array(be).fill(0).map(()=>[]),U=new Map,ge=0,Fe=0,A=null,ft=([e,t])=>{U.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(C);}catch(r){}},M=(e,t,r)=>{Y(e);let s=r/Pe+(A&&h()!==Fe?1:0);if(r=be||r%Pe!==0){U.set(e,[setTimeout(ft.bind(null,[e,t]),Math.min(r,ye))]);return}let n=(ge+s)%be;Qe[n].push([e,t]),U.set(e,n),A||(Fe=h(),A=setInterval(()=>{ge=(ge+1)%be,Fe=h();let a=Qe[ge];for(let o=0;o{let t=U.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Qe[t];for(let s=0;s{mt(e,W(t+" aborted due to timeout",tt));},r),c}async function mt(e,t=null){if(e){let r=G.get(e);r&&(t&&r[0].abort(t),De(e));}}function De(e){Y(e),G.delete(e);}function pt(e,t){let r=G.get(e);r&&(r[4]=t);}function He(e,t){if(!e)return null;let r=G.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!a[s]||r&&n-a[1]{r[t]&&Kt(s);});}function Ne(e){if(V.has(e))return;let t=Rt.bind(null,e,true,e==="focus"),r=yt.get(e);if(r){let s=r(t);V.set(e,s);return}ut()&&(window.addEventListener(e,t),V.set(e,()=>window.removeEventListener(e,t)));}function ht(e){let t=V.get(e);t&&(t(),V.delete(e));}function Pt(e,t,r,s,n,a,o,i){let u=Z.get(e)||[];u[0]=t,u[1]=h(),u[2]=Mt,u[3]=s,u[4]=n,u[5]=a,u[6]=o,u[7]=i,Z.set(e,u),a&&Ne("focus"),o&&Ne("online"),s&&M("s:"+e,Ee.bind(null,e,true),s*1e3);}function Kt(e){Z.delete(e),Y("s:"+e);}var ne=new Map;function zt(e,t){let r=ne.get(e);r||ne.set(e,r=new Set),r.add(t);}function kt(e,t){let r=ne.get(e);r&&(r.delete(t),r.size===0&&ne.delete(e));}function L(e,t){let r=ne.get(e);if(r)if(r.size===1){let s=r.values().next().value;s(t);}else r.forEach(s=>s(t));}function Jt(e,t){return e?(zt(e,t),()=>{kt(e,t);}):C}var Te=(Se()?60:30)*1e3,j={strategy:pe,timeout:Te,loadingTimeout:Te/10,focusThrottleInterval:5e3,headers:{Accept:te+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:Te/30,maxDelay:Te,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504],methods:[O,re,"PUT","DELETE","OPTIONS","TRACE"]}};function Wt(e){let t=B(e);return $({retry:j.retry,headers:j.headers},t,j)}function Yt(){return {...j}}function _e(e,t){let r=$(j,t?B(t):{});return Gt(e,r)}function Gt(e,t){var f;let r=t.method;r=r?r.toUpperCase():O;let s;r!==O&&r!==re&&(s=(f=t.body)!=null?f:t.data,s&&typeof s!==x&&se(s)&&(s=JSON.stringify(s))),Xt(t.headers,s);let n=t.withCredentials?"include":t.credentials,a=ot(e,t.urlPathParams),o=nt(a,t.params),u=it(e)?"":t.baseURL||t.apiUrl||"",c=u&&o&&!u.endsWith("/")&&!/^[/?#]/.test(o)?"/":"";return t.url=u+c+o,t.method=r,t.credentials=n,t.body=s,t}function Xt(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==D&&t instanceof Blob||typeof ReadableStream!==D&&t instanceof ReadableStream)return;let r;if(J(t))r=z+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=z+"octet-stream";else if(se(t))r=te+";"+et;else return;e instanceof Headers?e.has(_)||e.set(_,r):g(e)&&!Array.isArray(e)&&!E(e)[_.toLowerCase()]&&(e[_]=r);}var Vt=["onRequest","onResponse","onError","onLoadingSlow"];function $(e,t,r={}){Object.assign(r,e,t),gt("retry",e,t,r),gt("headers",e,t,r);for(let s of Vt)Zt(s,e,t,r);return r}function Zt(e,t,r,s){let n=t[e],a=r[e];n&&a?s[e]=e==="onResponse"?[].concat(a,n):[].concat(n,a):(n||a)&&(s[e]=n||a);}function gt(e,t,r,s){let n=t[e],a=r[e];if(a)if(e==="headers"){let o=n instanceof Headers||a instanceof Headers,i=o?E(n):{...n},u=o?E(a):B(a);for(let c of Object.keys(u)){let f=c.toLowerCase();for(let l in i)l.toLowerCase()===f&&delete i[l];i[c]=u[c];}s[e]=i;}else s[e]={...n,...B(a)};else a===void 0&&g(n)&&!(n instanceof Headers)&&(s[e]={...n});}var Q=new Map,ie=new Map,oe="|",Ue=64,$t=/[^\w\-_|/:@.?=&~%#]/g,er=/[^\w\-_|/:@.?=&~%#]/,tr=/^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;function ue(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===x?r:r(e);let{url:s="",method:n=O,headers:a=null,body:o=null,credentials:i="same-origin"}=e,u="";if(a){let l;a instanceof Headers?l=E(a):l=a;let p=Object.keys(l),m=p.length;m>1&&p.sort();let q="";for(let T=0;T{f+=p+"="+(typeof l===x?l:"F"+Dt(l))+"&";}),f.length>Ue&&(f=X(f));else if(g(o)&&!se(o))f="B"+Dt(o);else {let l=g(o)?JSON.stringify(at(o)):String(o);f=l.length>Ue?X(l):l;}return Et(c+oe+f)}var bt=new WeakMap,rr=0;function Dt(e){let t=bt.get(e);return t||bt.set(e,t=++rr),t}function Et(e){return er.test(e)?e.replace($t,"")+oe+X(e):e}function Me(e){return e.expiry?h()>e.expiry:false}function Le(e){if(!e)return null;let t=Q.get(e);return t?t.data:null}function ce(e){return Q.get(e)}function we(e,t,r,s){if(r===0){le(e);return}let n=h(),a=r?r*1e3:0,o=s?s*1e3:0;Q.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+a}),a>0&&Tt(e,a);}function Tt(e,t){M("c:"+e,()=>le(e,true),t);}function le(e,t=false){if(t){let s=ce(e);if(!s||!Me(s))return}Q.delete(e);let r=ie.get(e);r&&(ie.delete(e),je(()=>r.delete(e)));}function je(e){try{Promise.resolve(e()).catch(C);}catch(t){}}function wt(e,t){let r=Q.get(e);if(t&&r){let{data:s,status:n,statusText:a,headers:o}=r.data;ie.set(e,t),je(()=>t.set(e,{...r,data:{data:s,status:n,statusText:a,headers:o}}));}}async function xt(e,t){let r=t.cacheStore;if(!r||xe(t))return null;let s;try{s=await r.get(e);}catch(n){return null}return !s||Q.has(e)?null:Me(s)?(je(()=>r.delete(e)),null):s}function Ct(e,t,r){return Q.set(e,t),ie.set(e,r),t.expiry&&Tt(e,t.expiry-h()),L(e,t.data),!t.stale||h(){let s=t.defaultResponse,n=t.cacheKey,a=Ke.bind(null,n);if(!e)return {ok:false,error:r,data:s!=null?s:null,headers:null,config:t,mutate:a,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===b&&e instanceof Response,i=e.data;s!==void 0&&(i==null||/^\[object (Object|Array)\]$/.test(Object.prototype.toString.call(i))&&Object.keys(i).length===0)&&(e.data=i=s),t.flattenResponse&&(e.data=i=ve(i)),t.select&&(e.data=i=t.select(i));let u=E(e.headers);if(o){let c={body:e.body,bodyUsed:e.bodyUsed,ok:e.ok,redirected:e.redirected,type:e.type,url:e.url,status:e.status,statusText:e.statusText,blob:async()=>i instanceof ArrayBuffer?new Blob([i]):new Blob,json:async()=>i,text:async()=>i,clone:()=>({...c}),arrayBuffer:async()=>i instanceof ArrayBuffer?i:new ArrayBuffer(0),formData:async()=>i instanceof FormData?i:new FormData,bytes:async()=>new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),error:r,data:i,headers:u,config:t,mutate:a,isFetching:false,isSuccess:e.ok&&!r,isError:!!r};return c}return g(e)&&Object.assign(e,{error:r,headers:u,isFetching:false,mutate:a,isSuccess:e.ok&&!r,isError:!!r}),e};function Ot(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function sr(e){if(!e)return null;let t=e.headers||{},r=t["retry-after"];if(r){let o=Number(r);if(!isNaN(o)&&o>=0)return o*1e3;let i=Ot(r);if(i!==null)return i}let s="ratelimit-reset",n=t[s+"-after"]||t["x-"+s+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let a=t[s+"-at"]||t["x-"+s+"-at"];return a?Ot(a):null}async function Bt(e,t){let{retries:r=0,delay:s=0,backoff:n=1,maxDelay:a,retryOn:o=[],shouldRetry:i,jitter:u,methods:c}=t,f=0,l=s,p=r>0?r:0,m;for(;f<=p;){if(f>0&&m){let d=m.config,H=d.onRetry;H&&(await F(H,m,f),d._isAutoKey&&(d._prevKey=d.cacheKey,d.cacheKey=ue(d,false)));}m=await e(f>0,f);let q=m.error;if(q?await ar(m,f,p,i,o,c):!(i&&fc.toUpperCase()===e.config.method)))}function nr(e,t){return typeof t===b?t(e):t?Math.random()*e:e}async function At(e,t,r,s=0,n=0,a=false,o=false,i){if(!t)return e();let u=0,c;for(;(s===0||u0&&await ae(n,i),c=await e(),u++,!(s>0&&u>=s||!t||r&&r(c,u)));)do if(await ae(t,i),i&&i.aborted)return c;while(!a&&ct()||!o&<());return c}var or=[204,205,304],ir=/^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/,It=e=>typeof ReadableStream!==D&&e instanceof ReadableStream,qe=(e,t)=>({loaded:e,total:t,progress:t?e/t:void 0});function vt(e,t){let r=t.body;return typeof XMLHttpRequest!==D&&!It(r)?ur(e,t,r):cr(e,t,r)}function ur(e,t,r){return new Promise((s,n)=>{let a=new XMLHttpRequest,o=t.signal,i=()=>a.abort(),u=f=>{o.removeEventListener("abort",i);try{f();}catch(l){n(l);}};a.open(t.method,e),a.responseType="blob",a.withCredentials=t.credentials==="include",new Headers(t.headers).forEach((f,l)=>ir.test(l)||a.setRequestHeader(l,f)),a.upload.onprogress=f=>t.onUploadProgress(qe(f.loaded,f.lengthComputable?f.total:void 0)),a.onload=()=>u(()=>{let f=new Headers;for(let p of a.getAllResponseHeaders().split(/\r?\n/)){let m=p.indexOf(":");m>0&&f.append(p.slice(0,m),p.slice(m+1).trim());}let l=new Response(or.includes(a.status)?null:a.response,{status:a.status,statusText:a.statusText,headers:f});Object.defineProperty(l,"url",{value:a.responseURL}),s(l);}),a.onerror=()=>u(()=>n(new TypeError("Network request failed")));let c=()=>u(()=>n(o.reason||W("The request was aborted",k)));if(a.onabort=c,o.aborted)return c();o.addEventListener("abort",i),a.send(r);})}async function cr(e,t,r){let s=new Headers(t.headers),n=r,a;if(!It(r)){let i=r instanceof Blob?r:await new Response(r).blob();a=i.size,n=i.stream(),i.type&&!s.has("content-type")&&s.set("content-type",i.type);}let o=0;return fetch(e,{...t,headers:s,body:n.pipeThrough(new TransformStream({transform(i,u){o+=i.byteLength,t.onUploadProgress(qe(o,a)),u.enqueue(i);}})),duplex:"half"})}function St(e,t){if(!t||typeof Response!==b||!(e instanceof Response)||!e.body)return e;let r=e.headers,s=r.has("content-encoding")?void 0:Number(r.get("content-length"))||void 0,n=0,a=new Response(e.body.pipeThrough(new TransformStream({transform(o,i){n+=o.byteLength,t(qe(n,s&&Math.max(s,n))),i.enqueue(o);}})),e);for(let o of ["url","redirected","type"])Object.defineProperty(a,o,{value:e[o]});return a}async function Ft(e,t,r){var u;let s=await t(e),n=s.error;if(!n)return ze(s,r),s;r.onError&&await F(r.onError,n);let a=n.isCancelled,o=r.logger;if(!a&&o&&o.warn&&o.warn("FETCH ERROR",fr(n)),r.strategy==="defaultResponse"&&(s.data=(u=r.defaultResponse)!=null?u:null),ze(s,r,true),!a||r.rejectCancelled){let c=r.strategy;if(c===pe)throw n;c==="silent"&&await new Promise(()=>null);}return s}var lr=["authorization","proxy-authorization","cookie","x-api-key"];function fr(e){let t={...e.config,body:void 0,data:void 0,cacheKey:void 0,_prevKey:void 0,headers:E(e.config.headers)};for(let s of lr)t.headers[s]&&(t.headers[s]="[REDACTED]");let r=Object.assign(new Error(e.message),e,{config:t,request:t,response:e.response&&{...e.response,config:t}});return r.name=e.name,r.stack=e.stack,r}function Qt(e,t,r){e.status=e.status||t&&t.status||0,e.statusText=e.statusText||t&&t.statusText||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===k;}var ke=Object.freeze({isFetching:true});async function Oe(e,t=null){var Ve;if(t&&typeof t.cacheKey=="string"){let R=fe(t.cacheKey,t.cacheTime,t);if(R)return R}let r=_e(e,t),{timeout:s,cancellable:n,cacheKey:a,dedupeTime:o,cacheTime:i,staleTime:u,refetchOnFocus:c,refetchOnReconnect:f,pollingInterval:l=0}=r,p=i!==void 0||u!==void 0,m=r.method,q=p&&(m===O||m===re)&&((Ve=r.etag)!=null?Ve:!r.fetcher),T=!!(a||s||o||p||n||c||f),d=null;T&&(d=ue(r));let H=null;if(d&&p){let R=fe(d,i,r);if(R)return R;if(r.cacheStore){let w=await xt(d,r),I=w&&Ht(w.data,d,r);if(I&&Ct(d,{...w,data:I},r.cacheStore))return I}r.initialData!==void 0&&!Le(d)&&!xe(r)&&(H=Ht({data:r.initialData,status:200,statusText:"",headers:{}},d,r));}if(d&&o){let R=He(d,o);if(R)return R}let Je=r.retry||{},{retries:Nt=0,resetTimeout:_t}=Je,N=r.signal,We=async(R,w=0)=>{let I=q&&Le(d);if(!w){if(H){let v=H;return H=null,v}d&&!R&&(u?fe(d,i,r)||(we(d,ke,i,u),L(d,ke)):L(d,ke)),r.cacheKey=d;}let ee=r.url,Ze=dt(d,ee,s,o||0,!!n,!!(s&&(!w||_t))),P=r;P.signal=Ze.signal;let Ae=()=>Ze.abort(N.reason);N&&(N.aborted?Ae():N.addEventListener("abort",Ae));let me,y=null;try{r.onRequest&&(d&&o&&!w&&await null,await F(r.onRequest,P));let v=r.fetcher,K=dr(P,I);if(y=v?await v(ee,K):await(P.onUploadProgress&&P.body?vt(ee,P):fetch(ee,K)),y=St(y,P.onDownloadProgress),g(y)){if(K!==P&&y.status===304)return I;if(typeof Response===b&&y instanceof Response?y.data=P.parser?await P.parser(y):await qt(y,P.responseType):v&&("data"in y&&"body"in y||(y={data:y})),y.config=P,y.ok!==void 0&&!y.ok)throw new he(P.method+" to "+ee+" failed! Status: "+(y.status||null),P,y)}me=Ce(y,P);let $e=r.onResponse;$e&&await F($e,me);}catch(v){let K=v;Qt(K,y,P),me=Ce(y,P,K);}finally{N&&N.removeEventListener("abort",Ae);}return me},Be=Nt>0?R=>Bt((w,I)=>We(R,I),Je):We,{onLoadingSlow:Ye,loadingTimeout:Ge}=r,Ut=Ye&&Ge?async R=>{if(R)return Be(R);let w=setTimeout(()=>F(Ye,r).catch(C),Ge);try{return await Be(R)}finally{clearTimeout(w);}}:Be,de=(R=false)=>Ft(R,Ut,r),Xe=l?At(de,l,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay,r.refreshWhenHidden,r.refreshWhenOffline,N):de();return d&&(o&&pt(d,Xe),(u||c||f)&&Pt(d,de,void 0,u,de,!!c,!!f,r.focusThrottleInterval)),Xe}function Ht(e,t,r){try{let s=typeof Response===b?new Response(null,e):{ok:!0,status:e.status,statusText:e.statusText,headers:e.headers};s.data=e.data,r.cacheKey=t;let n=Ce(s,{...r,select:void 0,flattenResponse:!1,defaultResponse:void 0});return n.config=r,n}catch(s){return null}}function dr(e,t){let r=t&&!t.error&&t.headers&&t.headers.etag,s=r&&E(e.headers);return s&&!s["if-none-match"]?{...e,headers:{...s,"if-none-match":r}}:e}function mr(e){let t=e.endpoints;async function r(n){return console.error("Add "+n+" to 'endpoints'."),null}let s={config:e,endpoints:t,async request(n,a={}){let o=S(t,n)?t[n]:void 0,i=o||{url:String(n)},u=i.url,c=u.replace(/[\t\n\r]/g,"").replace(/^[\x00-\x20]+/,"");if(/^[/\\]{2}/.test(c))throw new Error("Protocol-relative URLs not allowed.");let f=/^[a-z][a-z\d+\-.]*:/i.test(c)?o&&o.url===u?$(i,a):a:$($(e,i),a);return Oe(u,f)}};return new Proxy(s,{get(n,a){if(a in s)return s[a];if(!(typeof a=="symbol"||a==="then"))return S(t,a)?s.request.bind(null,a):r.bind(null,a)}})} +var z="application/",te=z+"json",et="charset=utf-8",_="Content-Type",D="undefined",Ie="object",x="string",b="function",k="AbortError",tt="TimeoutError",O="GET",re="HEAD",pe="reject",ye=2147483647;var st=10,S=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);function J(e){return e instanceof URLSearchParams}function g(e){return e!==null&&typeof e===Ie}function B(e){let t=S(e,"__proto__"),r=S(e,"constructor"),s=S(e,"prototype");if(!t&&!r&&!s)return e;let n={};for(let a of Object.keys(e))a!=="__proto__"&&a!=="constructor"&&a!=="prototype"&&(n[a]=e[a]);return n}function at(e){let t=Object.create(null);return Object.keys(e).sort().forEach(r=>t[r]=e[r]),t}function rt(e,t){return t?e+(e.includes("?")?"&":"?")+t:e}function nt(e,t){if(!t)return e;if(J(t)){let u=t.toString();return rt(e,u)}let r=[],s=encodeURIComponent,n=(u,c)=>{c=typeof c===b?c():c,c=c==null?"":c,r[r.length]=s(u)+"="+s(c);},a=(u,c,f=0)=>{if(f>=st)return r;let l,p,m;if(u)if(Array.isArray(c))for(l=0,p=c.length;l{let o=n||a;if(S(r,o)){let i=r[o];if(i!=null){let u=encodeURIComponent(String(i));if(u==="."||u==="..")throw new Error('Path params "." and ".." not allowed.');return u}}return s})}function it(e){return /^[a-z][a-z\d+\-.]*:\/\//i.test(e)}var h=()=>Date.now(),C=()=>{};function se(e){let t=typeof e;return e==null?false:t===x||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==D&&typeof globalThis.Buffer!==D&&globalThis.Buffer.isBuffer(e)||e instanceof Date||J(e)?false:!!(g(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===b))}var ae=(e,t)=>new Promise(r=>{let s=()=>{clearTimeout(n),t&&t.removeEventListener("abort",s),r(true);},n=setTimeout(s,Math.min(e,ye));t&&(t.aborted?s():t.addEventListener("abort",s));});function ve(e,t=0){return t>=st?e:e&&g(e)&&typeof e.data!==D?ve(e.data,t+1):e}function E(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,s)=>{t[s.toLowerCase()]=r;});else for(let r in e)S(e,r)&&r!=="__proto__"&&(t[r.toLowerCase()]=e[r]);return t}function ut(){return typeof window!==D&&typeof window.addEventListener===b}function W(e,t){if(typeof DOMException!==D)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Se=()=>{let e=typeof navigator!==D&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)},ct=()=>typeof document!==D&&document.visibilityState==="hidden",lt=()=>typeof navigator!==D&&navigator.onLine===false;async function F(e,t,...r){if(!e)return;let s=n=>n&&g(t)&&g(n)&&Object.assign(t,B(n));if(typeof e===b)s(await e(t,...r));else if(Array.isArray(e))for(let n of e)s(await n(t,...r));}var Re=class extends Error{constructor(t,r,s){super(t),this.request=r,this.response=s,this.status=s?s.status:0,this.statusText=s?s.statusText:"",this.config=r,this.isCancelled=false,this.name="FetchError";}};var he=class extends Re{constructor(t,r,s){super(t,r,s),this.name="ResponseError";}};var be=600,Pe=1e3,Qe=Array(be).fill(0).map(()=>[]),U=new Map,ge=0,Fe=0,A=null,ft=([e,t])=>{U.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(C);}catch(r){}},M=(e,t,r)=>{Y(e);let s=r/Pe+(A&&h()!==Fe?1:0);if(r=be||r%Pe!==0){U.set(e,[setTimeout(ft.bind(null,[e,t]),Math.min(r,ye))]);return}let n=(ge+s)%be;Qe[n].push([e,t]),U.set(e,n),A||(Fe=h(),A=setInterval(()=>{ge=(ge+1)%be,Fe=h();let a=Qe[ge];for(let o=0;o{let t=U.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Qe[t];for(let s=0;s{mt(e,W(t+" aborted due to timeout",tt));},r),c}async function mt(e,t=null){if(e){let r=G.get(e);r&&(t&&r[0].abort(t),De(e));}}function De(e){Y(e),G.delete(e);}function pt(e,t){let r=G.get(e);r&&(r[4]=t);}function He(e,t){if(!e)return null;let r=G.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!a[s]||r&&n-a[1]{r[t]&&Kt(s);});}function Ne(e){if(V.has(e))return;let t=Rt.bind(null,e,true,e==="focus"),r=yt.get(e);if(r){let s=r(t);V.set(e,s);return}ut()&&(window.addEventListener(e,t),V.set(e,()=>window.removeEventListener(e,t)));}function ht(e){let t=V.get(e);t&&(t(),V.delete(e));}function Pt(e,t,r,s,n,a,o,i){let u=Z.get(e)||[];u[0]=t,u[1]=h(),u[2]=Mt,u[3]=s,u[4]=n,u[5]=a,u[6]=o,u[7]=i,Z.set(e,u),a&&Ne("focus"),o&&Ne("online"),s&&M("s:"+e,Ee.bind(null,e,true),s*1e3);}function Kt(e){Z.delete(e),Y("s:"+e);}var ne=new Map;function zt(e,t){let r=ne.get(e);r||ne.set(e,r=new Set),r.add(t);}function kt(e,t){let r=ne.get(e);r&&(r.delete(t),r.size===0&&ne.delete(e));}function L(e,t){let r=ne.get(e);if(r)if(r.size===1){let s=r.values().next().value;s(t);}else r.forEach(s=>s(t));}function Jt(e,t){return e?(zt(e,t),()=>{kt(e,t);}):C}var Te=(Se()?60:30)*1e3,j={strategy:pe,timeout:Te,loadingTimeout:Te/10,focusThrottleInterval:5e3,headers:{Accept:te+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:Te/30,maxDelay:Te,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504],methods:[O,re,"PUT","DELETE","OPTIONS","TRACE"]}};function Wt(e){let t=B(e);return $({retry:j.retry,headers:j.headers},t,j)}function Yt(){return {...j}}function _e(e,t){let r=$(j,t?B(t):{});return Gt(e,r)}function Gt(e,t){var f;let r=t.method;r=r?r.toUpperCase():O;let s;r!==O&&r!==re&&(s=(f=t.body)!=null?f:t.data,s&&typeof s!==x&&se(s)&&(s=JSON.stringify(s))),Xt(t.headers,s);let n=t.withCredentials?"include":t.credentials,a=ot(e,t.urlPathParams),o=nt(a,t.params),u=it(e)?"":t.baseURL||t.apiUrl||"",c=u&&o&&!u.endsWith("/")&&!/^[/?#]/.test(o)?"/":"";return t.url=u+c+o,t.method=r,t.credentials=n,t.body=s,t}function Xt(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==D&&t instanceof Blob||typeof ReadableStream!==D&&t instanceof ReadableStream)return;let r;if(J(t))r=z+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=z+"octet-stream";else if(se(t))r=te+";"+et;else return;e instanceof Headers?e.has(_)||e.set(_,r):g(e)&&!Array.isArray(e)&&!E(e)[_.toLowerCase()]&&(e[_]=r);}var Vt=["onRequest","onResponse","onError","onLoadingSlow"];function $(e,t,r={}){Object.assign(r,e,t),gt("retry",e,t,r),gt("headers",e,t,r);for(let s of Vt)Zt(s,e,t,r);return r}function Zt(e,t,r,s){let n=t[e],a=r[e];n&&a?s[e]=e==="onResponse"?[].concat(a,n):[].concat(n,a):(n||a)&&(s[e]=n||a);}function gt(e,t,r,s){let n=t[e],a=r[e];if(a)if(e==="headers"){let o=n instanceof Headers||a instanceof Headers,i=o?E(n):{...n},u=o?E(a):B(a);for(let c of Object.keys(u)){let f=c.toLowerCase();for(let l in i)l.toLowerCase()===f&&delete i[l];i[c]=u[c];}s[e]=i;}else s[e]={...n,...B(a)};else a===void 0&&g(n)&&!(n instanceof Headers)&&(s[e]={...n});}var Q=new Map,ie=new Map,oe="|",Ue=64,$t=/[^\w\-_|/:@.?=&~%#]/g,er=/[^\w\-_|/:@.?=&~%#]/,tr=/^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;function ue(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===x?r:r(e);let{url:s="",method:n=O,headers:a=null,body:o=null,credentials:i="same-origin"}=e,u="";if(a){let l;a instanceof Headers?l=E(a):l=a;let p=Object.keys(l),m=p.length;m>1&&p.sort();let q="";for(let T=0;T{f+=p+"="+(typeof l===x?l:"F"+Dt(l))+"&";}),f.length>Ue&&(f=X(f));else if(g(o)&&!se(o))f="B"+Dt(o);else {let l=g(o)?JSON.stringify(at(o)):String(o);f=l.length>Ue?X(l):l;}return Et(c+oe+f)}var bt=new WeakMap,rr=0;function Dt(e){let t=bt.get(e);return t||bt.set(e,t=++rr),t}function Et(e){return er.test(e)?e.replace($t,"")+oe+X(e):e}function Me(e){return e.expiry?h()>e.expiry:false}function Le(e){if(!e)return null;let t=Q.get(e);return t?t.data:null}function ce(e){return Q.get(e)}function we(e,t,r,s){if(r===0){le(e);return}let n=h(),a=r?r*1e3:0,o=s?s*1e3:0;Q.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+a}),a>0&&Tt(e,a);}function Tt(e,t){M("c:"+e,()=>le(e,true),t);}function le(e,t=false){if(t){let s=ce(e);if(!s||!Me(s))return}Q.delete(e);let r=ie.get(e);r&&(ie.delete(e),je(()=>r.delete(e)));}function je(e){try{Promise.resolve(e()).catch(C);}catch(t){}}function wt(e,t){let r=Q.get(e);if(t&&r){let{data:s,status:n,statusText:a,headers:o}=r.data;ie.set(e,t),je(()=>t.set(e,{...r,data:{data:s,status:n,statusText:a,headers:o}}));}}async function xt(e,t){let r=t.cacheStore;if(!r||xe(t))return null;let s;try{s=await r.get(e);}catch(n){return null}return !s||Q.has(e)?null:Me(s)?(je(()=>r.delete(e)),null):s}function Ct(e,t,r){return Q.set(e,t),ie.set(e,r),t.expiry&&Tt(e,t.expiry-h()),L(e,t.data),!t.stale||h(){let s=t.defaultResponse,n=t.cacheKey,a=Ke.bind(null,n);if(!e)return {ok:false,error:r,data:s!=null?s:null,headers:null,config:t,mutate:a,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===b&&e instanceof Response,i=e.data;s!==void 0&&(i==null||/^\[object (Object|Array)\]$/.test(Object.prototype.toString.call(i))&&Object.keys(i).length===0)&&(e.data=i=s),t.flattenResponse&&(e.data=i=ve(i)),t.select&&(e.data=i=t.select(i));let u=E(e.headers);if(o){let c={body:e.body,bodyUsed:e.bodyUsed,ok:e.ok,redirected:e.redirected,type:e.type,url:e.url,status:e.status,statusText:e.statusText,blob:async()=>i instanceof ArrayBuffer?new Blob([i]):new Blob,json:async()=>i,text:async()=>i,clone:()=>({...c}),arrayBuffer:async()=>i instanceof ArrayBuffer?i:new ArrayBuffer(0),formData:async()=>i instanceof FormData?i:new FormData,bytes:async()=>new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),error:r,data:i,headers:u,config:t,mutate:a,isFetching:false,isSuccess:e.ok&&!r,isError:!!r};return c}return g(e)&&(e.error=r,e.headers=u,e.isFetching=false,e.mutate=a,e.isSuccess=e.ok&&!r,e.isError=!!r),e};function Ot(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function sr(e){if(!e)return null;let t=e.headers||{},r=t["retry-after"];if(r){let o=Number(r);if(!isNaN(o)&&o>=0)return o*1e3;let i=Ot(r);if(i!==null)return i}let s="ratelimit-reset",n=t[s+"-after"]||t["x-"+s+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let a=t[s+"-at"]||t["x-"+s+"-at"];return a?Ot(a):null}async function Bt(e,t){let{retries:r=0,delay:s=0,backoff:n=1,maxDelay:a,retryOn:o=[],shouldRetry:i,jitter:u,methods:c}=t,f=0,l=s,p=r>0?r:0,m;for(;f<=p;){if(f>0&&m){let d=m.config,H=d.onRetry;H&&(await F(H,m,f),d._isAutoKey&&(d._prevKey=d.cacheKey,d.cacheKey=ue(d,false)));}m=await e(f>0,f);let q=m.error;if(q?await ar(m,f,p,i,o,c):!(i&&fc.toUpperCase()===e.config.method)))}function nr(e,t){return typeof t===b?t(e):t?Math.random()*e:e}async function At(e,t,r,s=0,n=0,a=false,o=false,i){if(!t)return e();let u=0,c;for(;(s===0||u0&&await ae(n,i),c=await e(),u++,!(s>0&&u>=s||!t||r&&r(c,u)));)do if(await ae(t,i),i&&i.aborted)return c;while(!a&&ct()||!o&<());return c}var or=[204,205,304],ir=/^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/,It=e=>typeof ReadableStream!==D&&e instanceof ReadableStream,qe=(e,t)=>({loaded:e,total:t,progress:t?e/t:void 0});function vt(e,t){let r=t.body;return typeof XMLHttpRequest!==D&&!It(r)?ur(e,t,r):cr(e,t,r)}function ur(e,t,r){return new Promise((s,n)=>{let a=new XMLHttpRequest,o=t.signal,i=()=>a.abort(),u=f=>{o.removeEventListener("abort",i);try{f();}catch(l){n(l);}};a.open(t.method,e),a.responseType="blob",a.withCredentials=t.credentials==="include",new Headers(t.headers).forEach((f,l)=>ir.test(l)||a.setRequestHeader(l,f)),a.upload.onprogress=f=>t.onUploadProgress(qe(f.loaded,f.lengthComputable?f.total:void 0)),a.onload=()=>u(()=>{let f=new Headers;for(let p of a.getAllResponseHeaders().split(/\r?\n/)){let m=p.indexOf(":");m>0&&f.append(p.slice(0,m),p.slice(m+1).trim());}let l=new Response(or.includes(a.status)?null:a.response,{status:a.status,statusText:a.statusText,headers:f});Object.defineProperty(l,"url",{value:a.responseURL}),s(l);}),a.onerror=()=>u(()=>n(new TypeError("Network request failed")));let c=()=>u(()=>n(o.reason||W("The request was aborted",k)));if(a.onabort=c,o.aborted)return c();o.addEventListener("abort",i),a.send(r);})}async function cr(e,t,r){let s=new Headers(t.headers),n=r,a;if(!It(r)){let i=r instanceof Blob?r:await new Response(r).blob();a=i.size,n=i.stream(),i.type&&!s.has("content-type")&&s.set("content-type",i.type);}let o=0;return fetch(e,{...t,headers:s,body:n.pipeThrough(new TransformStream({transform(i,u){o+=i.byteLength,t.onUploadProgress(qe(o,a)),u.enqueue(i);}})),duplex:"half"})}function St(e,t){if(!t||typeof Response!==b||!(e instanceof Response)||!e.body)return e;let r=e.headers,s=r.has("content-encoding")?void 0:Number(r.get("content-length"))||void 0,n=0,a=new Response(e.body.pipeThrough(new TransformStream({transform(o,i){n+=o.byteLength,t(qe(n,s&&Math.max(s,n))),i.enqueue(o);}})),e);for(let o of ["url","redirected","type"])Object.defineProperty(a,o,{value:e[o]});return a}async function Ft(e,t,r){var u;let s=await t(e),n=s.error;if(!n)return ze(s,r),s;r.onError&&await F(r.onError,n);let a=n.isCancelled,o=r.logger;if(!a&&o&&o.warn&&o.warn("FETCH ERROR",fr(n)),r.strategy==="defaultResponse"&&(s.data=(u=r.defaultResponse)!=null?u:null),ze(s,r,true),!a||r.rejectCancelled){let c=r.strategy;if(c===pe)throw n;c==="silent"&&await new Promise(()=>null);}return s}var lr=["authorization","proxy-authorization","cookie","x-api-key"];function fr(e){let t={...e.config,body:void 0,data:void 0,cacheKey:void 0,_prevKey:void 0,headers:E(e.config.headers)};for(let s of lr)t.headers[s]&&(t.headers[s]="[REDACTED]");let r=Object.assign(new Error(e.message),e,{config:t,request:t,response:e.response&&{...e.response,config:t}});return r.name=e.name,r.stack=e.stack,r}function Qt(e,t,r){e.status=e.status||t&&t.status||0,e.statusText=e.statusText||t&&t.statusText||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===k;}var ke=Object.freeze({isFetching:true});async function Oe(e,t=null){var Ve;if(t&&typeof t.cacheKey=="string"){let R=fe(t.cacheKey,t.cacheTime,t);if(R)return R}let r=_e(e,t),{timeout:s,cancellable:n,cacheKey:a,dedupeTime:o,cacheTime:i,staleTime:u,refetchOnFocus:c,refetchOnReconnect:f,pollingInterval:l=0}=r,p=i!==void 0||u!==void 0,m=r.method,q=p&&(m===O||m===re)&&((Ve=r.etag)!=null?Ve:!r.fetcher),T=!!(a||s||o||p||n||c||f),d=null;T&&(d=ue(r));let H=null;if(d&&p){let R=fe(d,i,r);if(R)return R;if(r.cacheStore){let w=await xt(d,r),I=w&&Ht(w.data,d,r);if(I&&Ct(d,{...w,data:I},r.cacheStore))return I}r.initialData!==void 0&&!Le(d)&&!xe(r)&&(H=Ht({data:r.initialData,status:200,statusText:"",headers:{}},d,r));}if(d&&o){let R=He(d,o);if(R)return R}let Je=r.retry||{},{retries:Nt=0,resetTimeout:_t}=Je,N=r.signal,We=async(R,w=0)=>{let I=q&&Le(d);if(!w){if(H){let v=H;return H=null,v}d&&!R&&(u?fe(d,i,r)||(we(d,ke,i,u),L(d,ke)):L(d,ke)),r.cacheKey=d;}let ee=r.url,Ze=dt(d,ee,s,o||0,!!n,!!(s&&(!w||_t))),P=r;P.signal=Ze.signal;let Ae=()=>Ze.abort(N.reason);N&&(N.aborted?Ae():N.addEventListener("abort",Ae));let me,y=null;try{r.onRequest&&(d&&o&&!w&&await null,await F(r.onRequest,P));let v=r.fetcher,K=dr(P,I);if(y=v?await v(ee,K):await(P.onUploadProgress&&P.body?vt(ee,P):fetch(ee,K)),y=St(y,P.onDownloadProgress),g(y)){if(K!==P&&y.status===304)return I;if(typeof Response===b&&y instanceof Response?y.data=P.parser?await P.parser(y):await qt(y,P.responseType):v&&("data"in y&&"body"in y||(y={data:y})),y.config=P,y.ok!==void 0&&!y.ok)throw new he(P.method+" to "+ee+" failed! Status: "+(y.status||null),P,y)}me=Ce(y,P);let $e=r.onResponse;$e&&await F($e,me);}catch(v){let K=v;Qt(K,y,P),me=Ce(y,P,K);}finally{N&&N.removeEventListener("abort",Ae);}return me},Be=Nt>0?R=>Bt((w,I)=>We(R,I),Je):We,{onLoadingSlow:Ye,loadingTimeout:Ge}=r,Ut=Ye&&Ge?async R=>{if(R)return Be(R);let w=setTimeout(()=>F(Ye,r).catch(C),Ge);try{return await Be(R)}finally{clearTimeout(w);}}:Be,de=(R=false)=>Ft(R,Ut,r),Xe=l?At(de,l,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay,r.refreshWhenHidden,r.refreshWhenOffline,N):de();return d&&(o&&pt(d,Xe),(u||c||f)&&Pt(d,de,void 0,u,de,!!c,!!f,r.focusThrottleInterval)),Xe}function Ht(e,t,r){try{let s=typeof Response===b?new Response(null,e):{ok:!0,status:e.status,statusText:e.statusText,headers:e.headers};s.data=e.data,r.cacheKey=t;let n=Ce(s,{...r,select:void 0,flattenResponse:!1,defaultResponse:void 0});return n.config=r,n}catch(s){return null}}function dr(e,t){let r=t&&!t.error&&t.headers&&t.headers.etag,s=r&&E(e.headers);return s&&!s["if-none-match"]?{...e,headers:{...s,"if-none-match":r}}:e}function mr(e){let t=e.endpoints;async function r(n){return console.error("Add "+n+" to 'endpoints'."),null}let s={config:e,endpoints:t,async request(n,a={}){let o=S(t,n)?t[n]:void 0,i=o||{url:String(n)},u=i.url,c=u.replace(/[\t\n\r]/g,"").replace(/^[\x00-\x20]+/,"");if(/^[/\\]{2}/.test(c))throw new Error("Protocol-relative URLs not allowed.");let f=/^[a-z][a-z\d+\-.]*:/i.test(c)?o&&o.url===u?$(i,a):a:$($(e,i),a);return Oe(u,f)}};return new Proxy(s,{get(n,a){if(a in s)return s[a];if(!(typeof a=="symbol"||a==="then"))return S(t,a)?s.request.bind(null,a):r.bind(null,a)}})} export{mt as abortRequest,M as addTimeout,_e as buildConfig,W as createAbortError,mr as createApiFetcher,le as deleteCache,Oe as fetchf,Oe as fetchff,ue as generateCacheKey,ce as getCache,fe as getCachedResponse,Yt as getDefaultConfig,He as getInFlightPromise,Se as isSlowConnection,Ke as mutate,jt as removeRevalidators,Ee as revalidate,Rt as revalidateAll,we as setCache,Wt as setDefaultConfig,Lt as setEventProvider,Jt as subscribe};//# sourceMappingURL=index.mjs.map //# sourceMappingURL=index.mjs.map \ No newline at end of file diff --git a/dist/browser/index.mjs.map b/dist/browser/index.mjs.map index 923793f..dc38332 100644 --- a/dist/browser/index.mjs.map +++ b/dist/browser/index.mjs.map @@ -1 +1 @@ -{"version":3,"sources":["../../src/constants.ts","../../src/utils.ts","../../src/interceptor-manager.ts","../../src/errors/fetch-error.ts","../../src/errors/response-error.ts","../../src/timeout-wheel.ts","../../src/inflight-manager.ts","../../src/hash.ts","../../src/revalidator-manager.ts","../../src/pubsub-manager.ts","../../src/config-handler.ts","../../src/cache-manager.ts","../../src/response-parser.ts","../../src/retry-handler.ts","../../src/polling-handler.ts","../../src/upload-progress.ts","../../src/download-progress.ts","../../src/error-handler.ts","../../src/request-handler.ts","../../src/api-handler.ts"],"names":["APPLICATION_CONTENT_TYPE","APPLICATION_JSON","CHARSET_UTF_8","CONTENT_TYPE","UNDEFINED","OBJECT","STRING","FUNCTION","ABORT_ERROR","TIMEOUT_ERROR","GET","HEAD","REJECT","MAX_DELAY_MS","MAX_DEPTH","hasOwn","o","k","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","key","sortObject","sortedObj","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","v","buildParams","prefix","depth","i","len","replaceUrlPathParams","urlPathParams","match","colonKey","braceKey","encoded","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","signal","resolve","done","timer","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","isPageHidden","isOffline","applyInterceptors","interceptors","args","merge","interceptor","FetchError","request","response","ResponseError","WHEEL_SIZE","SECOND","wheel","keyMap","position","lastTick","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","inFlight","markInFlight","timeout","dedupeTime","isCancellable","isTimeoutEnabled","now","item","prevPromise","prevController","prevIsCancellable","controller","abortRequest","removeInFlight","setInFlightPromise","promise","getInFlightPromise","prevReq","hash","str","char","DEFAULT_TTL","revalidators","eventHandlers","customEventProviders","setEventProvider","type","provider","removeEventHandler","addEventHandler","revalidateAll","isStaleRevalidation","isThrottled","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","focusThrottleInterval","listeners","addListener","fn","set","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","merged","buildFetcherConfig","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","separator","contentTypeValue","INTERCEPTORS","baseConfig","overrideConfig","targetConfig","mergeConfig","property","mergeInterceptors","baseInterceptor","newInterceptor","base","override","isInstance","overrides","lowerKey","existingKey","_cache","stores","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADERS","generateCacheKey","config","cacheKeyCheck","headersString","keys","cacheStr","sanitizeCacheKey","bodyString","getObjectId","objectIds","lastObjectId","id","isCacheExpired","getCacheData","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","scheduleExpiry","removeExpired","store","callStore","persistCache","status","statusText","getStoredCache","isCacheBypassed","restoreCache","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","buster","getCachedResponse","cacheKey","cacheTime","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","responseType","contentType","mimeType","trimmed","_error","prepareResponse","defaultResponse","mutatator","isNativeResponse","getMsFromHttpDate","dateString","getRetryAfterMs","extendedResponse","retryAfter","RATELIMIT_RESET","rateLimitResetAfter","rateLimitResetAt","withRetry","requestFn","retries","delay","backoff","maxDelay","retryOn","shouldRetry","jitter","methods","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryDelay","withJitter","retryAfterMs","_b","_c","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","refreshWhenHidden","refreshWhenOffline","pollingAttempt","NULL_BODY_STATUSES","FORBIDDEN_HEADERS","isStream","toProgress","loaded","total","fetchWithUploadProgress","sendWithXhr","sendStreamed","reject","xhr","abort","settle","line","index","onAbort","stream","blob","chunk","withDownloadProgress","onDownloadProgress","counted","withErrorHandling","isCancelled","logger","redactError","strategy","SENSITIVE_HEADERS","copy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","isETagEnabled","needsCacheKey","_cacheKey","initialResponse","stored","restored","toResponse","inflight","retryConfig","resetTimeout","userSignal","doRequestOnce","init","withETag","onResponse","baseRequest","_","onLoadingSlow","loadingTimeout","requestWithErrorHandling","doRequestPromise","etag","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","resolvedUrl","mergedConfig","_target","prop"],"mappings":"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","file":"index.mjs","sourcesContent":["export const APPLICATION_CONTENT_TYPE = 'application/';\n\nexport const APPLICATION_JSON = APPLICATION_CONTENT_TYPE + 'json';\nexport const CHARSET_UTF_8 = 'charset=utf-8';\nexport const CONTENT_TYPE = 'Content-Type';\n\nexport const UNDEFINED = 'undefined';\nexport const OBJECT = 'object';\nexport const STRING = 'string';\nexport const FUNCTION = 'function';\n\nexport const ABORT_ERROR = 'AbortError';\nexport const TIMEOUT_ERROR = 'TimeoutError';\n\nexport const GET = 'GET';\nexport const HEAD = 'HEAD';\n\nexport const REJECT = 'reject';\n\n// Larger timer delays overflow and fire immediately in browsers and Node.js (~24.8 days)\nexport const MAX_DELAY_MS = 2147483647;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, MAX_DELAY_MS, OBJECT, STRING, UNDEFINED } from './constants';\nimport type {\n DefaultUrlParams,\n HeadersObject,\n QueryParams,\n UrlPathParams,\n} from './types';\n\n// Prevent stack overflow with recursion depth limit\nconst MAX_DEPTH = 10;\n\nexport const hasOwn = (o: any, k: string) =>\n Object.prototype.hasOwnProperty.call(o, k);\n\nexport function isSearchParams(data: unknown): boolean {\n return data instanceof URLSearchParams;\n}\n\n/**\n * Determines if a value is a non-null object.\n *\n * @param {any} value - The value to check.\n * @returns {boolean} - True if the value is a non-null object.\n */\nexport function isObject(value: any): value is Record {\n return value !== null && typeof value === OBJECT;\n}\n\n/**\n * Shallowly serializes an object by converting its key-value pairs into a string representation.\n * This function does not recursively serialize nested objects.\n *\n * @param obj - The object to serialize.\n * @returns A string representation of the object's top-level properties.\n */\nexport function shallowSerialize(obj: Record): string {\n let result = '';\n\n for (const key in obj) {\n if (hasOwn(obj, key)) {\n result += key + ':' + obj[key];\n }\n }\n\n return result;\n}\n\n/**\n * Removes properties that could lead to prototype pollution from an object.\n *\n * This function checks for dangerous properties like '__proto__', 'constructor',\n * and 'prototype'. If none are present, the object is returned as-is (zero-copy fast path).\n * Otherwise, a shallow copy is created with the dangerous properties removed.\n *\n * @param obj - The object to sanitize\n * @returns A safe object without dangerous properties\n */\nexport function sanitizeObject>(obj: T): T {\n const hasProto = hasOwn(obj, '__proto__');\n const hasCtor = hasOwn(obj, 'constructor');\n const hasPrototype = hasOwn(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n // Copy key by key, as a spread compiled to assignments would let \"__proto__\" set the prototype\n const safeObj = {} as Record;\n\n for (const key of Object.keys(obj)) {\n if (key !== '__proto__' && key !== 'constructor' && key !== 'prototype') {\n safeObj[key] = obj[key];\n }\n }\n\n return safeObj as T;\n}\n\n/**\n * Sorts the keys of an object and returns a new object with sorted keys.\n *\n * This function is optimized for performance by minimizing the number of object operations\n * and using a single pass to create the sorted object.\n *\n * @param {Object} obj - The object to be sorted by keys.\n * @returns {Object} - A new object with keys sorted in ascending order.\n */\nexport function sortObject(obj: Record): object {\n // Without a prototype, a \"__proto__\" key is kept as a regular property instead of setting the prototype\n const sortedObj = Object.create(null) as Record;\n\n Object.keys(obj)\n .sort()\n .forEach((k) => (sortedObj[k] = obj[k]));\n\n return sortedObj;\n}\n\n/**\n * Appends a query string to a URL, ensuring proper handling of existing query parameters.\n *\n * @param baseUrl - The base URL to which the query string will be appended.\n * @param queryString - The encoded query string to append.\n * @returns The URL with the appended query string, or the original URL if no query string is provided.\n */\nfunction appendQueryStringToUrl(baseUrl: string, queryString: string): string {\n if (!queryString) {\n return baseUrl;\n }\n\n return baseUrl + (baseUrl.includes('?') ? '&' : '?') + queryString;\n}\n\n/**\n * Appends query parameters to a given URL.\n *\n * @param {string} url - The base URL to which query parameters will be appended.\n * @param {QueryParams} params - An object containing the query parameters to append.\n * @returns {string} - The URL with the appended query parameters.\n */\nexport function appendQueryParams(url: string, params: QueryParams): string {\n if (!params) {\n return url;\n }\n\n // Check if `params` is an instance of URLSearchParams and bail early if it is\n if (isSearchParams(params)) {\n const encodedQueryString = params.toString();\n\n return appendQueryStringToUrl(url, encodedQueryString);\n }\n\n // This is exact copy of what JQ used to do. It works much better than URLSearchParams\n const s: string[] = [];\n const encode = encodeURIComponent;\n const add = (k: string, v: any) => {\n v = typeof v === FUNCTION ? v() : v;\n v = v === null || v === undefined ? '' : v;\n s[s.length] = encode(k) + '=' + encode(v);\n };\n\n const buildParams = (prefix: string, obj: any, depth = 0) => {\n // Stop recursion if maximum depth is reached\n if (depth >= MAX_DEPTH) {\n return s;\n }\n\n let i: number, len: number, key: string;\n\n if (prefix) {\n if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n buildParams(\n prefix + '[' + (typeof obj[i] === OBJECT && obj[i] ? i : '') + ']',\n obj[i],\n depth + 1,\n );\n }\n } else if (isObject(obj)) {\n for (key in obj) {\n buildParams(prefix + '[' + key + ']', obj[key], depth + 1);\n }\n } else {\n add(prefix, obj);\n }\n } else if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n add(obj[i].name, obj[i].value);\n }\n } else {\n for (key in obj) {\n buildParams(key, obj[key], depth + 1);\n }\n }\n return s;\n };\n\n const queryStringParts = buildParams('', params).join('&');\n\n // Encode special characters as per RFC 3986, https://datatracker.ietf.org/doc/html/rfc3986\n // This is for compatibility with server frameworks that expect the literal notation\n const encodedQueryString = queryStringParts.replace(/%5B%5D/g, '[]'); // Keep '[]' for arrays\n\n return appendQueryStringToUrl(url, encodedQueryString);\n}\n\n/**\n * Replaces dynamic URI parameters in a URL string with values from the provided `urlPathParams` object.\n * Parameters in the URL are denoted by `:` or `{}` (like in OpenAPI paths), where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:` or `{}`.\n * @param {Object} urlPathParams - An object containing the parameter values to replace placeholders.\n * @param {string} urlPathParams.paramName - The value to replace the placeholder `:` in the URL.\n * @returns {string} - The URL string with placeholders replaced by corresponding values from `urlPathParams`.\n */\nexport function replaceUrlPathParams(\n url: string,\n urlPathParams: UrlPathParams,\n): string {\n if (!urlPathParams || (url.indexOf(':') === -1 && url.indexOf('{') === -1)) {\n return url;\n }\n\n // Use a single RegExp and avoid unnecessary casts and function calls\n // Precompute keys for faster lookup\n const params = urlPathParams as DefaultUrlParams;\n\n // Use a replacer function that avoids extra work\n return url.replace(/:(\\w+)|\\{(\\w+)\\}/g, (match, colonKey, braceKey) => {\n const key = colonKey || braceKey;\n\n // Use hasOwnProperty for strict key existence check\n if (hasOwn(params, key)) {\n const value = params[key];\n\n // Only replace if value is not undefined or null\n if (value !== undefined && value !== null) {\n const encoded = encodeURIComponent(String(value));\n\n // These can't be encoded, and URL parsers would move the request to another path\n if (encoded === '.' || encoded === '..') {\n throw new Error('Path params \".\" and \"..\" not allowed.');\n }\n\n return encoded;\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL starts with a scheme (e.g., \"http://\", \"https://\").\n * A \"://\" appearing later, e.g. in a query string, does not make the URL absolute.\n *\n * @param url - The URL string to check.\n * @returns `true` if the URL is absolute, otherwise `false`.\n */\nexport function isAbsoluteUrl(url: string): boolean {\n return /^[a-z][a-z\\d+\\-.]*:\\/\\//i.test(url);\n}\n\nexport const timeNow = () => Date.now();\n\nexport const noop = () => {};\n\n/**\n * Checks if a value is JSON serializable.\n *\n * JSON serializable values include:\n * - Primitive types: string, number, boolean, null\n * - Arrays\n * - Plain objects (i.e., objects without special methods)\n * - Values with a `toJSON` method\n *\n * @param {any} value - The value to check for JSON serializability.\n * @returns {boolean} - Returns `true` if the value is JSON serializable, otherwise `false`.\n */\nexport function isJSONSerializable(value: any): boolean {\n const t = typeof value;\n\n if (value === undefined || value === null) {\n return false;\n }\n\n if (t === STRING || t === 'number' || t === 'boolean') {\n return true;\n }\n\n if (Array.isArray(value)) {\n return true;\n }\n\n if (\n typeof globalThis !== UNDEFINED &&\n typeof globalThis.Buffer !== UNDEFINED &&\n globalThis.Buffer.isBuffer(value)\n ) {\n return false;\n }\n\n if (value instanceof Date || isSearchParams(value)) {\n return false;\n }\n\n if (isObject(value)) {\n const proto = Object.getPrototypeOf(value);\n\n // Check if the prototype is `Object.prototype` (plain object)\n if (proto === Object.prototype) {\n return true;\n }\n\n // Check if the object has a toJSON method\n if (typeof value.toJSON === FUNCTION) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Waits for the given time. When a signal is passed, the wait ends early once it is aborted.\n *\n * @param {number} ms - The time to wait in milliseconds.\n * @param {AbortSignal} [signal] - An optional signal that ends the wait when aborted.\n * @returns {Promise} - A promise that resolves with `true` once the wait is over.\n */\nexport const delayInvocation = (\n ms: number,\n signal?: AbortSignal,\n): Promise =>\n new Promise((resolve) => {\n const done = () => {\n clearTimeout(timer);\n if (signal) {\n signal.removeEventListener('abort', done);\n }\n resolve(true);\n };\n const timer = setTimeout(done, Math.min(ms, MAX_DELAY_MS));\n\n if (signal) {\n if (signal.aborted) {\n done();\n } else {\n signal.addEventListener('abort', done);\n }\n }\n });\n\n/**\n * Recursively flattens the data object if it meets specific criteria.\n *\n * The method checks if the provided `data` is an object with exactly one property named `data`.\n * If so, it recursively flattens the `data` property. Otherwise, it returns the `data` as-is.\n *\n * @param {any} data - The data to be flattened. Can be of any type, including objects, arrays, or primitives.\n * @returns {any} - The flattened data if the criteria are met; otherwise, the original `data`.\n */\nexport function flattenData(data: any, depth = 0): any {\n if (depth >= MAX_DEPTH) {\n return data;\n }\n\n if (data && isObject(data) && typeof data.data !== UNDEFINED) {\n return flattenData(data.data, depth + 1);\n }\n\n return data;\n}\n\n/**\n * Processes headers and returns them as a normalized object.\n *\n * Handles both `Headers` instances and plain objects. Normalizes header keys to lowercase\n * as per RFC 2616 section 4.2.\n *\n * @param headers - The headers to process. Can be an instance of `Headers`, a plain object,\n * or `null`. If `null`, an empty object is returned.\n * @returns {HeadersObject} - A normalized headers object with lowercase keys.\n */\nexport function processHeaders(\n headers?: (HeadersObject & HeadersInit) | null | Headers,\n): HeadersObject {\n if (!headers) {\n return {};\n }\n\n const headersObject: HeadersObject = {};\n\n // Normalize keys to lowercase as per RFC 2616 4.2\n // https://datatracker.ietf.org/doc/html/rfc2616#section-4.2\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n headersObject[key.toLowerCase()] = value;\n });\n } else {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n // Assigning \"__proto__\" would set the prototype of the result\n if (hasOwn(headers, key) && key !== '__proto__') {\n headersObject[key.toLowerCase()] = headers[key];\n }\n }\n }\n\n return headersObject;\n}\n\n/**\n * Determines if the current environment is a browser.\n *\n * @returns {boolean} - True if running in a browser environment, false otherwise.\n */\nexport function isBrowser(): boolean {\n // For node and some mobile frameworks like React Native, `add/removeEventListener` doesn't exist on window!\n return (\n typeof window !== UNDEFINED && typeof window.addEventListener === FUNCTION\n );\n}\n\n/**\n * Creates an abort/timeout error compatible with all JS runtimes.\n * Falls back to a plain Error with the correct `name` when DOMException is unavailable (e.g. React Native).\n *\n * @param {string} message - The error message.\n * @param {string} name - The error name (e.g. 'AbortError', 'TimeoutError').\n * @returns {DOMException | Error} - An error object with the specified name.\n */\nexport function createAbortError(\n message: string,\n name: string,\n): DOMException | Error {\n if (typeof DOMException !== UNDEFINED) {\n return new DOMException(message, name);\n }\n\n const error = new Error(message);\n error.name = name;\n\n return error;\n}\n\n/**\n * Detects if the user is on a slow network connection\n * @returns {boolean} True if connection is slow, false otherwise or if detection unavailable\n */\nexport const isSlowConnection = (): boolean => {\n const conn = typeof navigator !== UNDEFINED && (navigator as any).connection;\n\n return conn && ['slow-2g', '2g', '3g'].includes(conn.effectiveType);\n};\n\n/**\n * Detects if the page is hidden, e.g. when its tab is in the background or the window is minimized\n * @returns {boolean} True if the page is hidden, false otherwise or outside browsers\n */\nexport const isPageHidden = (): boolean =>\n typeof document !== UNDEFINED && document.visibilityState === 'hidden';\n\n/**\n * Detects if the browser is offline\n * @returns {boolean} True if the browser is offline, false otherwise or if the connection state is unknown\n */\nexport const isOffline = (): boolean =>\n typeof navigator !== UNDEFINED && navigator.onLine === false;\n","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject, sanitizeObject } from './utils';\n\n/**\n * Applies interceptors to the object. Interceptors can be a single function or an array of functions.\n *\n * @template T - Type of the object.\n * @template Args - Type of additional arguments.\n * @template I - Type of interceptors.\n *\n * @param {InterceptorFunction | InterceptorFunction[]} [interceptors] - Interceptor function(s).\n * @param {T} data - The data object to process.\n * @param {...Args} args - Additional arguments to pass to interceptors.\n *\n * @returns {Promise} - Nothing as the function is non-idempotent.\n */\nexport async function applyInterceptors<\n T extends object,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Args extends any[] = any[],\n I = InterceptorFunction | InterceptorFunction[],\n>(interceptors: I | undefined, data: T, ...args: Args): Promise {\n if (!interceptors) {\n return;\n }\n\n const merge = (v: unknown) =>\n v &&\n isObject(data) &&\n isObject(v) &&\n Object.assign(data, sanitizeObject(v));\n\n if (typeof interceptors === FUNCTION) {\n merge(await (interceptors as InterceptorFunction)(data, ...args));\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n merge(await interceptor(data, ...args));\n }\n }\n}\n","import type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\n/**\n * This is a base error class\n */\nexport class FetchError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends Error {\n // Declared only, and set in the constructor, as class fields would need a helper in the ES2018 bundle\n declare status: number;\n declare statusText: string;\n declare config: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare isCancelled: boolean;\n declare request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null;\n\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.request = request;\n this.response = response;\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\n this.name = 'FetchError';\n }\n}\n","import { FetchError } from './fetch-error';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\nexport class ResponseError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends FetchError {\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message, request, response);\n\n this.name = 'ResponseError';\n }\n}\n","/**\n * @module timeout-wheel\n * @description\n * Ultra-minimal timing wheel implementation optimized for max performance & many requests.\n * For most of the cases it's 4-100x faster than setTimeout and setInterval alone.\n * Provides efficient scheduling and cancellation of timeouts using a circular array.\n *\n * Position 0 → 1 → 2 → ... → 599 → 0 → 1 → 2 ...\n * Time: 0s 1s 2s 599s 600s 601s 602s\n *\n * The timing wheel consists of 600 slots (one per second for 10 min).\n * Each slot contains a list of timeout items, each associated with a unique key and callback.\n * Timeouts are scheduled by placing them in the appropriate slot based on the delay in seconds.\n * The wheel advances every second, executing and removing callbacks as their timeouts expire.\n * Defaults to setTimeout if the delay doesn't fit in the wheel (~10 minutes) or is not divisible by 1000.\n *\n * @remarks\n * - Designed for minimal footprint and simplicity.\n * - Only supports second-level granularity (minimum timeout: 1 second).\n * - Timeouts never fire early, but may fire up to 1 second late.\n * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { MAX_DELAY_MS } from './constants';\nimport { noop, timeNow } from './utils';\n\ntype TimeoutCallback = () => unknown | Promise;\ntype TimeoutItem = [string, TimeoutCallback]; // [key, callback]\n\nconst WHEEL_SIZE = 600; // 600 slots for 10 min (1 slot per second)\nconst SECOND = 1000; // 1 second in milliseconds\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\nlet lastTick = 0; // Time when the wheel last advanced (or started)\nlet timer: NodeJS.Timeout | null = null;\n\nconst handleCallback = ([key, callback]: TimeoutItem): void => {\n keyMap.delete(key);\n\n try {\n const result = callback();\n if (result && result instanceof Promise) {\n // Silently ignore async errors to prevent wheel from stopping\n result.catch(noop);\n }\n } catch {\n // Ignore callback errors to prevent wheel from stopping\n }\n};\n\nexport const addTimeout = (\n key: string,\n cb: TimeoutCallback,\n ms: number,\n): void => {\n removeTimeout(key);\n\n // A running wheel is already part-way through its current second, so the timeout\n // waits one more slot to never fire early. A new wheel starts its first second now.\n const seconds = ms / SECOND + (timer && timeNow() !== lastTick ? 1 : 0);\n\n // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || seconds >= WHEEL_SIZE || ms % SECOND !== 0) {\n keyMap.set(key, [\n setTimeout(\n handleCallback.bind(null, [key, cb]),\n Math.min(ms, MAX_DELAY_MS),\n ),\n ]); // Store timeout ID instead of slot\n\n return;\n }\n\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n lastTick = timeNow();\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\n lastTick = timeNow();\n const slot = wheel[position];\n\n // Use slot.length directly (not cached) so mid-iteration mutations\n // from callbacks (e.g. removeTimeout) are handled correctly\n for (let i = 0; i < slot.length; i++) {\n handleCallback(slot[i]);\n }\n\n slot.length = 0; // Reuse array, avoid GC allocation\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }, SECOND);\n }\n};\n\nexport const removeTimeout = (key: string): void => {\n const slotOrTimeout = keyMap.get(key);\n\n if (slotOrTimeout !== undefined) {\n // It's a Timeout object from setTimeout\n if (Array.isArray(slotOrTimeout)) {\n clearTimeout(slotOrTimeout[0]);\n } else {\n const slotArr = wheel[slotOrTimeout];\n\n for (let i = 0; i < slotArr.length; i++) {\n if (slotArr[i][0] === key) {\n slotArr.splice(i, 1);\n break;\n }\n }\n }\n\n keyMap.delete(key);\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }\n};\n\nexport const clearAllTimeouts = () => {\n // Clear native setTimeout timeouts first!\n keyMap.forEach((value) => {\n if (Array.isArray(value)) {\n clearTimeout(value[0]);\n }\n });\n\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n\n keyMap.clear();\n\n for (let i = 0; i < WHEEL_SIZE; i++) {\n wheel[i].length = 0;\n }\n\n position = 0;\n};\n","/**\n * @module inflight-manager\n *\n * Manages in-flight asynchronous requests using unique keys to enable deduplication and cancellation.\n *\n * Provides utilities for:\n * - Deduplication of requests within a configurable time window (`dedupeTime`)\n * - Timeout management and automatic request abortion\n * - AbortController lifecycle and cancellation logic\n * - Concurrency control and request state tracking\n * - In-flight promise deduplication to prevent duplicate network calls\n *\n * @remarks\n * - Requests with the same key within the deduplication interval share the same AbortController and in-flight promise.\n * - Supports cancellation of previous requests when a new one with the same key is issued, if `isCancellable` is enabled.\n * - Timeout logic ensures requests are aborted after a specified duration, if enabled.\n * - Internal queue state is managed via a Map, keyed by request identifier.\n * - Polled requests are also marked as \"in-flight\" to prevent duplicate requests.\n */\n\nimport { ABORT_ERROR, TIMEOUT_ERROR } from './constants';\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { createAbortError, timeNow } from './utils';\n\nexport type InFlightItem = [\n AbortController, // AbortController for the request\n boolean, // Whether timeout is enabled for the request\n number, // Timestamp when the request was marked in-flight\n boolean, // isCancellable - whether the request can be cancelled\n Promise | null, // Optional in-flight promise for deduplication\n];\n\nconst inFlight: Map = new Map();\n\n/**\n * Adds a request to the queue if it's not already being processed within the dedupeTime interval.\n *\n * @param {string | null} key - Unique key for the request (e.g. cache key).\n * @param {string} url - The request URL (for error messages/timeouts).\n * @param {number} timeout - Timeout in milliseconds for the request.\n * @param {number} dedupeTime - Deduplication time in milliseconds.\n * @param {boolean} isCancellable - If true, then the previous request with same configuration should be aborted.\n * @param {boolean} isTimeoutEnabled - Whether timeout is enabled.\n * @returns {AbortController} - A promise that resolves to an AbortController.\n */\nexport function markInFlight(\n key: string | null,\n url: string,\n timeout: number | undefined,\n dedupeTime: number,\n isCancellable: boolean,\n isTimeoutEnabled: boolean,\n): AbortController {\n if (!key) {\n return new AbortController();\n }\n\n const now = timeNow();\n const item = inFlight.get(key);\n let prevPromise: Promise | null = null;\n\n // Previous request is in-flight, check if we can reuse it\n if (item) {\n const prevController = item[0];\n const prevIsCancellable = item[3];\n\n // If the request is already in the queue and within the dedupeTime, reuse the existing controller\n if (\n !prevIsCancellable &&\n now - item[2] < dedupeTime &&\n !prevController.signal.aborted\n ) {\n return prevController;\n }\n\n // If the request is too old, remove it and proceed to add a new one\n // Abort previous request, if applicable, and continue as usual\n if (prevIsCancellable) {\n prevController.abort(\n createAbortError('Aborted due to new request', ABORT_ERROR),\n );\n }\n\n removeTimeout(key);\n prevPromise = item[4];\n }\n\n const controller = new AbortController();\n\n inFlight.set(key, [\n controller,\n isTimeoutEnabled,\n now,\n isCancellable,\n prevPromise,\n ]);\n\n if (isTimeoutEnabled) {\n addTimeout(\n key,\n () => {\n abortRequest(\n key,\n createAbortError(url + ' aborted due to timeout', TIMEOUT_ERROR),\n );\n },\n timeout as number,\n );\n }\n\n return controller;\n}\n\n/**\n * Removes a request from the queue and clears its timeout.\n *\n * @param key - Unique key for the request.\n * @param {boolean} error - Optional error to abort the request with. If null, the request is simply removed but no abort sent.\n * @returns {Promise} - A promise that resolves when the request is aborted and removed.\n */\nexport async function abortRequest(\n key: string | null,\n error: DOMException | Error | null | string = null,\n): Promise {\n // If the key is not in the queue, there's nothing to remove\n if (key) {\n const item = inFlight.get(key);\n\n if (item) {\n // If the request is not yet aborted, abort it with the provided error\n if (error) {\n const controller = item[0];\n controller.abort(error);\n }\n\n removeInFlight(key);\n }\n }\n}\n\n/**\n * Removes a request from the in-flight queue without aborting or clearing timeout.\n *\n * @param key - Unique key for the request.\n */\nexport function removeInFlight(key: string | null): void {\n removeTimeout(key!);\n inFlight.delete(key!);\n}\n\n/**\n * Gets the AbortController for a request key.\n *\n * @param key - Unique key for the request.\n * @returns {AbortController | undefined} - The AbortController or undefined.\n */\nexport async function getController(\n key: string,\n): Promise {\n const item = inFlight.get(key);\n\n return item && item[0];\n}\n\n/**\n * Adds helpers for in-flight promise deduplication.\n *\n * @param key - Unique key for the request.\n * @param promise - The promise to store.\n */\nexport function setInFlightPromise(\n key: string,\n promise: Promise,\n): void {\n const item = inFlight.get(key);\n if (item) {\n // store the promise at index 4 — item is already the Map's reference, no need to re-set\n item[4] = promise;\n }\n}\n\n/**\n * Retrieves the in-flight promise for a request key if it exists and is within the dedupeTime interval.\n *\n * @param key - Unique key for the request.\n * @param dedupeTime - Deduplication time in milliseconds.\n * @returns {Promise | null} - The in-flight promise or null.\n */\nexport function getInFlightPromise(\n key: string | null,\n dedupeTime: number,\n): Promise | null {\n if (!key) {\n return null;\n }\n\n const prevReq = inFlight.get(key);\n\n if (\n prevReq &&\n // If the request is in-flight and has a promise\n prevReq[4] &&\n // If the request is cancellable, we will not reuse it\n !prevReq[3] &&\n // If the request is within the dedupeTime\n timeNow() - prevReq[2] < dedupeTime &&\n // If one request is cancelled, ALL deduped requests get cancelled\n !prevReq[0].signal.aborted\n ) {\n return prevReq[4] as Promise;\n }\n\n return null;\n}\n","const PRIME_MULTIPLIER = 31;\n\n/**\n * Computes a hash value for a given string using the variant of djb2 hash function.\n * This hash function is non-cryptographic and designed for speed.\n * @author Daniel J. Bernstein (of djb2)\n *\n * @param str Input string to hash\n * @returns {string} Hash\n */\nexport function hash(str: string): string {\n let hash = 0;\n\n for (let i = 0, len = str.length; i < len; i++) {\n const char = str.charCodeAt(i);\n hash = (hash * PRIME_MULTIPLIER + char) | 0;\n }\n\n return String(hash);\n}\n","/**\n * @module revalidator-manager\n *\n * Provides utilities for managing cache revalidation functions, including:\n * - Registering and unregistering revalidators for specific cache keys.\n * - Triggering revalidation for a given key.\n * - Enabling or disabling automatic revalidation on window focus and if user comes back online for specific keys.\n * - Attaching and removing global focus and online event handlers to trigger revalidation.\n *\n * Revalidators are functions that can be registered to revalidate cache entries when needed.\n * They are typically used to refresh data in the cache when the window gains focus or when specific actions occur.\n * @performance O(1) lookup by key makes it blazing fast to register, unregister, and revalidate cache entries.\n * - Designed for high performance: minimizes unnecessary re-renders and leverages fast cache key generation.\n * - Integrates with a global cache and pub/sub system for efficient state updates across contexts.\n * - Handles automatic revalidation, deduplication, retries, and cache management out of the box.\n * @remarks\n * - Designed to be used in various environments (Deno, Node.js, Bun, Browser, etc.) to ensure cache consistency and freshness.\n */\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { FetchResponse } from './types';\nimport { isBrowser, noop, timeNow } from './utils';\n\nexport type RevalidatorFn = (\n isStaleRevalidation?: boolean,\n) => Promise;\n\ntype EventType = 'focus' | 'online';\n\ntype RevalidatorEntry = [\n RevalidatorFn, // main revalidator\n number, // lastUsed\n number, // ttl\n number?, // staleTime\n RevalidatorFn?, // bgRevalidator\n boolean?, // refetchOnFocus\n boolean?, // refetchOnReconnect\n number?, // focusThrottleInterval\n];\n\nconst DEFAULT_TTL = 3 * 60 * 1000; // Default TTL of 3 minutes\nconst revalidators = new Map();\n\n/**\n * Stores cleanup functions for active event handlers (browser or custom providers).\n * Each entry removes the corresponding event listener when called.\n * @remarks\n * - Improves performance by reducing the number of event listeners.\n * - Enables efficient O(1) lookup and management of event handlers for revalidation.\n */\nconst eventHandlers = new Map void>();\n\n/** Subscribe to an event and return a cleanup function */\nexport type EventProvider = (handler: () => void) => () => void;\n\nconst customEventProviders = new Map();\n\n/**\n * Registers a custom event provider for 'focus' or 'online' events.\n * Useful for non-browser environments like React Native.\n *\n * @param type - The event type ('focus' or 'online').\n * @param provider - A function that subscribes to the event and returns a cleanup function.\n */\nexport function setEventProvider(\n type: EventType,\n provider: EventProvider,\n): void {\n customEventProviders.set(type, provider);\n\n // Re-register if already active\n if (eventHandlers.has(type)) {\n removeEventHandler(type);\n addEventHandler(type);\n }\n}\n\n/**\n * Triggers revalidation for all registered entries based on the given event type.\n * For example, if it's a 'focus' event, it will revalidate entries that have the `refetchOnFocus` flag set.\n * Updates the timestamp and invokes the revalidator function for each applicable entry.\n *\n * @param type - The type of event that caused the revalidation (e.g., 'focus' or 'online').\n * @param isStaleRevalidation - If `true`, uses background revalidator and doesn't mark as in-flight.\n * @param isThrottled - If `true`, skips entries that were requested or revalidated within their `focusThrottleInterval`.\n */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n isThrottled: boolean = false,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex] || (isThrottled && now - entry[1] < entry[7]!)) {\n return;\n }\n\n entry[1] = now;\n\n // If it's a stale revalidation, use the background revalidator function\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n if (revalidator) {\n Promise.resolve(revalidator(isStaleRevalidation)).catch(noop);\n }\n });\n}\n\n/**\n * Revalidates an entry by executing the registered revalidation function.\n *\n * @param key The unique identifier for the cache entry to revalidate. If `null`, no revalidation occurs.\n * @param isStaleRevalidation - If `true`, it does not mark revalidated requests as in-flight.\n * @returns A promise that resolves to the result of the revalidator function, or\n * `null` if no key or revalidator is found, or a `FetchResponse` if applicable.\n */\nexport async function revalidate(\n key: string | null,\n isStaleRevalidation: boolean = false,\n): Promise {\n // If no key is provided, no revalidation occurs\n if (!key) {\n return null;\n }\n\n const entry = revalidators.get(key);\n\n if (entry) {\n // Update only the lastUsed timestamp without resetting the whole array\n entry[1] = timeNow();\n\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n // If no revalidator function is registered, return null\n if (revalidator) {\n return await revalidator(isStaleRevalidation);\n }\n }\n\n // If no revalidator is registered for the key, return null\n return null;\n}\n\n/**\n * Removes all revalidators associated with the specified event type.\n *\n * @param type - The event type whose revalidators should be removed.\n */\nexport function removeRevalidators(type: EventType) {\n removeEventHandler(type);\n\n const flagIndex = type === 'focus' ? 5 : 6;\n\n // Clear all revalidators with this flag\n revalidators.forEach((entry, key) => {\n if (entry[flagIndex]) {\n removeRevalidator(key);\n }\n });\n}\n\n/**\n * Registers a generic revalidation event handler for the specified event type.\n * Supports browser window events and custom event providers (e.g. for React Native).\n * Ensures the handler is only added once.\n *\n * @param event - The type of event to listen for (e.g., 'focus', 'online').\n */\nfunction addEventHandler(event: EventType) {\n if (eventHandlers.has(event)) {\n return;\n }\n\n // Focus events are throttled, so that e.g. switching between tabs quickly doesn't revalidate every time\n const handler = revalidateAll.bind(null, event, true, event === 'focus');\n\n // Priority 1: Custom event provider (works in any environment including React Native)\n const customProvider = customEventProviders.get(event);\n\n if (customProvider) {\n const cleanup = customProvider(handler);\n\n eventHandlers.set(event, cleanup);\n\n return;\n }\n\n // Priority 2: Browser window events\n if (isBrowser()) {\n window.addEventListener(event, handler);\n\n eventHandlers.set(event, () => window.removeEventListener(event, handler));\n }\n}\n\n/**\n * Removes the event handler for the specified event type.\n *\n * @param event - The type of event whose handler should be removed.\n */\nfunction removeEventHandler(event: EventType) {\n const cleanup = eventHandlers.get(event);\n\n if (cleanup) {\n cleanup();\n eventHandlers.delete(event);\n }\n}\n\n/**\n * Registers a revalidation functions for a specific cache key.\n *\n * @param {string} key Cache key to utilize\n * @param {RevalidatorFn} revalidatorFn Main revalidation function (marks in-flight requests)\n * @param {number} [ttl] Time to live in milliseconds (default: 3 minutes)\n * @param {number} [staleTime] Time (in seconds) after which the cache entry is considered stale\n * @param {RevalidatorFn} [bgRevalidatorFn] For stale revalidation (does not mark in-flight requests)\n * @param {boolean} [refetchOnFocus] Whether to revalidate on window focus\n * @param {boolean} [refetchOnReconnect] Whether to revalidate on network reconnect\n * @param {number} [focusThrottleInterval] Time (in milliseconds) after a request or revalidation during which focus events don't revalidate it\n */\nexport function addRevalidator(\n key: string,\n revalidatorFn: RevalidatorFn, // Main revalidation function (marks in-flight requests)\n ttl?: number,\n staleTime?: number,\n bgRevalidatorFn?: RevalidatorFn, // For stale revalidation (does not mark in-flight requests)\n refetchOnFocus?: boolean,\n refetchOnReconnect?: boolean,\n focusThrottleInterval?: number,\n) {\n // Existing entries are updated in place\n const entry = revalidators.get(key) || ([] as unknown as RevalidatorEntry);\n\n entry[0] = revalidatorFn;\n entry[1] = timeNow();\n entry[2] = ttl ?? DEFAULT_TTL;\n entry[3] = staleTime;\n entry[4] = bgRevalidatorFn;\n entry[5] = refetchOnFocus;\n entry[6] = refetchOnReconnect;\n entry[7] = focusThrottleInterval;\n\n revalidators.set(key, entry);\n\n if (refetchOnFocus) {\n addEventHandler('focus');\n }\n\n if (refetchOnReconnect) {\n addEventHandler('online');\n }\n\n if (staleTime) {\n addTimeout('s:' + key, revalidate.bind(null, key, true), staleTime * 1000);\n }\n}\n\nexport function removeRevalidator(key: string) {\n revalidators.delete(key);\n\n // Clean up stale timer\n removeTimeout('s:' + key);\n}\n\n/**\n * Periodically cleans up expired revalidators from the registry.\n * Removes any revalidator whose TTL has expired.\n *\n * @param {number} intervalMs How often to run cleanup (default: 3 minutes)\n * @returns {() => void} A function to stop the periodic cleanup\n */\nexport function startRevalidatorCleanup(\n intervalMs: number = DEFAULT_TTL,\n): () => void {\n const intervalId = setInterval(() => {\n const now = timeNow();\n\n revalidators.forEach(\n ([, lastUsed, ttl, , , refetchOnFocus, refetchOnReconnect], key) => {\n // Skip focus-only or reconnect-only revalidators to keep them alive\n if (refetchOnFocus || refetchOnReconnect) {\n return;\n }\n\n if (ttl > 0 && now - lastUsed > ttl) {\n removeRevalidator(key);\n }\n },\n );\n }, intervalMs);\n\n return () => clearInterval(intervalId);\n}\n","/**\n * Manages a set of listeners (subscribers) for arbitrary string keys, allowing cross-context or cross-component\n * cache updates and synchronization. Provides functions to add, remove, and notify listeners, as well as a\n * convenient subscribe/unsubscribe API.\n *\n * @template T - The type of the response object passed to listeners.\n *\n * @remarks\n * - Listeners are grouped by a string key, which typically represents a cache key or resource identifier.\n * - When `notifySubscribers` is called for a key, all listeners registered for that key are invoked with the provided response.\n * - The `subscribe` function returns an unsubscribe function for convenient cleanup.\n *\n * @example\n * ```ts\n * const unsubscribe = subscribe('user:123', (response) => {\n * // handle updated data\n * });\n * // Later, to stop listening:\n * unsubscribe();\n * ```\n */\n\nimport { noop } from './utils';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Listener = (response: T) => void;\n\nconst listeners = new Map>();\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n let set = listeners.get(key);\n\n if (!set) {\n listeners.set(key, (set = new Set()));\n }\n\n set.add(fn);\n}\n\nexport function removeListener(key: string, fn: Listener) {\n const set = listeners.get(key);\n\n if (set) {\n set.delete(fn);\n\n // If the set is empty, remove the key from the listeners map\n if (set.size === 0) {\n listeners.delete(key);\n }\n }\n}\n\nexport function notifySubscribers(key: string, response: T) {\n const fns = listeners.get(key);\n\n if (fns) {\n if (fns.size === 1) {\n // If there's only one listener, call it directly\n const fn = fns.values().next().value;\n fn!(response);\n } else {\n fns.forEach((fn) => fn(response));\n }\n }\n}\n\nexport function subscribe(key: string | null, fn: (response: T) => void) {\n if (!key) {\n // No op if no key is provided\n return noop;\n }\n\n addListener(key, fn);\n\n // Return an unsubscribe function\n return () => {\n removeListener(key, fn);\n };\n}\n","import { processHeaders } from './utils';\nimport {\n GET,\n APPLICATION_JSON,\n HEAD,\n STRING,\n CHARSET_UTF_8,\n CONTENT_TYPE,\n REJECT,\n UNDEFINED,\n APPLICATION_CONTENT_TYPE,\n} from './constants';\nimport type {\n HeadersObject,\n Method,\n RequestConfig,\n} from './types/request-handler';\nimport {\n replaceUrlPathParams,\n appendQueryParams,\n isSearchParams,\n isJSONSerializable,\n isSlowConnection,\n isAbsoluteUrl,\n sanitizeObject,\n isObject,\n} from './utils';\n\nconst defaultTimeoutMs = (isSlowConnection() ? 60 : 30) * 1000;\n\nexport const defaultConfig: RequestConfig = {\n strategy: REJECT,\n timeout: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n loadingTimeout: defaultTimeoutMs / 10, // 3 seconds (6 on slow connections)\n focusThrottleInterval: 5000, // 5 seconds\n headers: {\n Accept: APPLICATION_JSON + ', text/plain, */*',\n 'Accept-Encoding': 'gzip, deflate, br',\n },\n retry: {\n delay: defaultTimeoutMs / 30, // 1 second (2 on slow connections)\n maxDelay: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n resetTimeout: true,\n backoff: 1.5,\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n retryOn: [\n 408, // Request Timeout\n 409, // Conflict\n 425, // Too Early\n 429, // Too Many Requests\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n ],\n\n // Idempotent methods, which can be repeated safely, unlike e.g. POST requests that create resources\n methods: [GET, HEAD, 'PUT', 'DELETE', 'OPTIONS', 'TRACE'],\n },\n};\n\n/**\n * Overwrites the default configuration with the provided custom configuration.\n *\n * @param {Partial} customConfig - The custom configuration to merge into the default config.\n * @returns {Partial} - The updated default configuration object.\n */\nexport function setDefaultConfig(\n customConfig: Partial,\n): Partial {\n const sanitized = sanitizeObject(customConfig);\n\n // Merge nested retry and headers settings into the current defaults instead of replacing them\n return mergeConfigs(\n { retry: defaultConfig.retry, headers: defaultConfig.headers },\n sanitized,\n defaultConfig,\n );\n}\n\n/**\n * Returns a shallow copy of the current default configuration.\n *\n * @returns {RequestConfig} - The current default configuration.\n */\nexport function getDefaultConfig(): RequestConfig {\n return { ...defaultConfig };\n}\n\n/**\n * Build request configuration from defaults and overrides.\n * This function merges the default configuration with the provided request configuration,\n * @param {string} url - Request url\n * @param {RequestConfig | null | undefined} reqConfig - Request configuration\n * @return {RequestConfig} - Merged request configuration\n */\nexport function buildConfig(\n url: string,\n reqConfig?: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null,\n): RequestConfig {\n // Merging gives the request its own copies of nested objects like headers, so that\n // mutations (e.g. by interceptors) never leak into the global defaults\n const merged = mergeConfigs(\n defaultConfig,\n reqConfig ? sanitizeObject(reqConfig) : {},\n );\n\n return buildFetcherConfig(url, merged);\n}\n\n/**\n * Builds the fetcher configuration by setting the method, body, headers, and URL.\n * It also handles query parameters and path parameters. This fn mutates the passed `requestConfig` object.\n * @param {string} url - The endpoint URL to which the request will be sent.\n * @param {RequestConfig} requestConfig - The request configuration object containing method, body, headers, and other options.\n * @return {RequestConfig} - The modified request configuration object with the URL, method, body, and headers set appropriately.\n **/\nexport function buildFetcherConfig(\n url: string,\n requestConfig: RequestConfig,\n): RequestConfig {\n let method = requestConfig.method as Method;\n method = method ? (method.toUpperCase() as Method) : GET;\n\n let body: RequestConfig['data'] | undefined;\n\n // Only applicable for request methods 'PUT', 'POST', 'DELETE', and 'PATCH'\n if (method !== GET && method !== HEAD) {\n body = requestConfig.body ?? requestConfig.data;\n\n // Automatically stringify request body, if possible and when not dealing with strings\n if (body && typeof body !== STRING && isJSONSerializable(body)) {\n body = JSON.stringify(body);\n }\n }\n\n setContentTypeIfNeeded(requestConfig.headers, body);\n\n // Native fetch compatible settings\n const credentials = requestConfig.withCredentials\n ? 'include'\n : requestConfig.credentials;\n\n // The explicitly passed query params\n const dynamicUrl = replaceUrlPathParams(url, requestConfig.urlPathParams);\n const urlPath = appendQueryParams(dynamicUrl, requestConfig.params);\n const isFullUrl = isAbsoluteUrl(url);\n const baseURL = isFullUrl\n ? ''\n : requestConfig.baseURL || requestConfig.apiUrl || '';\n\n // Join as a path, as plain concatenation could extend the host of the baseURL,\n // e.g. \"https://api.example.com\" + \".evil.com\" would point to another host\n const separator =\n baseURL && urlPath && !baseURL.endsWith('/') && !/^[/?#]/.test(urlPath)\n ? '/'\n : '';\n\n requestConfig.url = baseURL + separator + urlPath;\n requestConfig.method = method;\n requestConfig.credentials = credentials;\n requestConfig.body = body;\n\n return requestConfig;\n}\n\n/**\n * Ensures the `Content-Type` header is set to `application/json; charset=utf-8`\n * if it is not already present and the request method and body meet specific conditions.\n *\n * @param headers - The headers object to modify. Can be an instance of `Headers`\n * or a plain object conforming to `HeadersInit`.\n * @param body - The optional body of the request. If no body is provided and the\n * method is 'GET' or 'HEAD', the function exits without modifying headers.\n */\nfunction setContentTypeIfNeeded(\n headers?: HeadersInit | HeadersObject,\n body?: unknown,\n): void {\n // If no headers are provided, or if the body is not set and the method is PUT or DELETE, do nothing\n if (!headers || !body) {\n return;\n }\n\n // Types that should not have Content-Type set (browser handles these)\n if (\n body instanceof FormData || // Browser automatically sets multipart/form-data with boundary\n (typeof Blob !== UNDEFINED && body instanceof Blob) || // Blob/File (a File is a Blob) already have their own MIME types, don't override\n (typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream) // Stream type should be determined by the stream source\n ) {\n return;\n }\n\n let contentTypeValue: string;\n\n if (isSearchParams(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded';\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'octet-stream';\n } else if (isJSONSerializable(body)) {\n contentTypeValue = APPLICATION_JSON + ';' + CHARSET_UTF_8;\n } else {\n // Do not set Content-Type if content is not recognizable\n return;\n }\n\n if (headers instanceof Headers) {\n if (!headers.has(CONTENT_TYPE)) {\n headers.set(CONTENT_TYPE, contentTypeValue);\n }\n } else if (\n isObject(headers) &&\n !Array.isArray(headers) &&\n // Header names are case-insensitive, so check the normalized (lowercase) headers\n !processHeaders(headers as HeadersObject)[CONTENT_TYPE.toLowerCase()]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\n\n// The interceptors that are merged instead of replaced\nconst INTERCEPTORS = [\n 'onRequest',\n 'onResponse',\n 'onError',\n 'onLoadingSlow',\n] as const;\n\n/**\n * Merges two request configurations, applying overrides from the second config to the first.\n * Handles special merging for nested properties like 'retry' and 'headers' (deep merge),\n * and concatenates interceptor arrays for 'onRequest', 'onResponse', 'onError' and 'onLoadingSlow'.\n * If a target config is provided, it mutates that object; otherwise, creates a new one.\n *\n * @param {RequestConfig} baseConfig - The base configuration object to merge from.\n * @param {RequestConfig} overrideConfig - The override configuration object to apply on top of the base.\n * @param {RequestConfig} [targetConfig={}] - Optional target configuration object to merge into (mutated in place).\n * @returns {RequestConfig} The merged configuration object.\n *\n * @example\n * const base = { timeout: 5000, headers: { 'Accept': 'application/json' } };\n * const override = { timeout: 10000, headers: { 'Authorization': 'Bearer token' } };\n * const merged = mergeConfigs(base, override);\n * // Result: { timeout: 10000, headers: { Accept: 'application/json', Authorization: 'Bearer token' } }\n */\nexport function mergeConfigs(\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig = {},\n): RequestConfig {\n Object.assign(targetConfig, baseConfig, overrideConfig);\n\n // Ensure that retry and headers are merged correctly\n mergeConfig('retry', baseConfig, overrideConfig, targetConfig);\n mergeConfig('headers', baseConfig, overrideConfig, targetConfig);\n\n // Merge interceptors efficiently\n for (const property of INTERCEPTORS) {\n mergeInterceptors(property, baseConfig, overrideConfig, targetConfig);\n }\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends\n 'onRequest' | 'onResponse' | 'onError' | 'onRetry' | 'onLoadingSlow',\n>(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const baseInterceptor = baseConfig[property];\n const newInterceptor = overrideConfig[property];\n\n if (baseInterceptor && newInterceptor) {\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] = (\n property === 'onResponse'\n ? [].concat(newInterceptor as never, baseInterceptor as never)\n : [].concat(baseInterceptor as never, newInterceptor as never)\n ) as RequestConfig[K];\n } else if (baseInterceptor || newInterceptor) {\n targetConfig[property] = baseInterceptor || newInterceptor;\n }\n}\n\n/**\n * Merges the specified property from the base configuration and the override configuration into the target configuration.\n *\n * @param {K} property - The property key to merge from the base and override configurations. Must be a key of RequestConfig.\n * @param {RequestConfig} baseConfig - The base configuration object that provides default values.\n * @param {RequestConfig} overrideConfig - The override configuration object that contains user-specific settings to merge.\n * @param {RequestConfig} targetConfig - The configuration object that will receive the merged properties.\n */\nexport function mergeConfig(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n if (override) {\n if (property === 'headers') {\n // Handle Headers instances which don't expose entries as own enumerable properties\n const isInstance =\n (base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers;\n const merged: HeadersObject = isInstance\n ? processHeaders(base)\n : { ...(base as HeadersObject) };\n const overrides: HeadersObject = isInstance\n ? processHeaders(override)\n : sanitizeObject(override as HeadersObject);\n\n // Header names are case-insensitive, so replace existing entries instead of duplicating them\n for (const key of Object.keys(overrides)) {\n const lowerKey = key.toLowerCase();\n\n for (const existingKey in merged) {\n if (existingKey.toLowerCase() === lowerKey) {\n delete merged[existingKey];\n }\n }\n\n merged[key] = overrides[key];\n }\n\n targetConfig[property] = merged as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...sanitizeObject(override as Record),\n } as RequestConfig[K];\n }\n } else if (\n override === undefined &&\n isObject(base) &&\n !((base as Headers | HeadersObject) instanceof Headers)\n ) {\n // Copy so that mutating the merged config never changes the base config\n targetConfig[property] = { ...base } as RequestConfig[K];\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { hash } from './hash';\nimport type {\n CacheKeyFunction,\n DefaultResponse,\n FetchResponse,\n MutationSettings,\n RequestConfig,\n} from './types/request-handler';\nimport type {\n CacheEntry,\n CacheStore,\n StoredResponse,\n} from './types/cache-manager';\nimport { GET, STRING } from './constants';\nimport {\n isJSONSerializable,\n isObject,\n isSearchParams,\n noop,\n sanitizeObject,\n sortObject,\n timeNow,\n} from './utils';\nimport { revalidate } from './revalidator-manager';\nimport { notifySubscribers } from './pubsub-manager';\nimport type { DefaultPayload, DefaultParams, DefaultUrlParams } from './types';\nimport { removeInFlight } from './inflight-manager';\nimport { addTimeout } from './timeout-wheel';\nimport { defaultConfig } from './config-handler';\nimport { processHeaders } from './utils';\n\nexport const IMMEDIATE_DISCARD_CACHE_TIME = 0; // Use it for cache entries that need to be persistent until unused by components or manually deleted\n\nconst _cache = new Map>();\n// The cache stores that keep copies of cache entries, by cache key\nconst stores = new Map();\nconst DELIMITER = '|';\nconst MIN_LENGTH_TO_HASH = 64;\nconst CACHE_KEY_SANITIZE_PATTERN = /[^\\w\\-_|/:@.?=&~%#]/g;\nconst CACHE_KEY_NEEDS_SANITIZE = /[^\\w\\-_|/:@.?=&~%#]/; // Non-global for fast test\n\n/**\n * Headers that may affect HTTP response content and should be included in cache key generation.\n * Header names are matched case-insensitively.\n *\n * - Content negotiation: accept (response format, e.g. JSON or HTML), accept-language (localization), accept-encoding (compression)\n * - Authentication: authorization (access to protected resources)\n * - Request body metadata: content-type (how the request body is interpreted)\n * - Optional: referer (may influence behavior in some APIs), origin (CORS or tenant-specific APIs),\n * user-agent (if the server returns client-specific content), cookie (session-based responses; can fragment the cache heavily)\n * - Custom headers that may affect response content: x-api-key (token-based access), x-requested-with (AJAX requests),\n * x-client-id (per-client/partner identity), x-tenant-id (multi-tenant segmentation), x-user-id (explicit user context),\n * x-app-version (version-specific behavior), x-feature-flag (feature rollout), x-device-id (per device/app instance),\n * x-platform (e.g. 'ios', 'android', 'web'), x-session-id (if it affects the response directly), x-locale (like accept-language)\n */\nconst CACHE_KEY_HEADERS =\n /^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;\n\n/**\n * Generates a unique cache key for a given URL and fetch options, ensuring that key factors\n * like method, headers, body, and other options are included in the cache key.\n * Headers and other objects are sorted by key to ensure consistent cache keys.\n *\n * @param {RequestConfig} config - The fetch options that may affect the request. The most important are:\n * @property {string} [method=\"GET\"] - The HTTP method (GET, POST, etc.).\n * @property {HeadersInit} [headers={}] - The request headers.\n * @property {BodyInit | null} [body=\"\"] - The body of the request (only for methods like POST, PUT).\n * @property {RequestCredentials} [credentials=\"same-origin\"] - Whether to include credentials (include, same-origin, omit).\n * @property {RequestCache} [cache=\"default\"] - The cache mode (e.g., default, no-store, reload).\n * @returns {string} - A unique cache key string based on the provided options.\n *\n * @example\n * const cacheKey = generateCacheKey({\n * url: 'https://api.example.com/data',\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'Alice' }),\n * mode: 'cors',\n * credentials: 'include',\n * });\n * console.log(cacheKey);\n */\nexport function generateCacheKey(\n config: RequestConfig,\n cacheKeyCheck = true,\n): string {\n // This is super fast. Effectively a no-op if cacheKey is\n // a string or a function that returns a string.\n const key = config.cacheKey;\n\n if (key && cacheKeyCheck) {\n return typeof key === STRING\n ? (key as string)\n : (key as CacheKeyFunction)(config);\n }\n\n const {\n url = '',\n method = GET,\n headers = null,\n body = null,\n credentials = 'same-origin',\n } = config;\n\n // Sort headers and body + convert sorted to strings for hashing purposes\n // Native serializer is on avg. 3.5x faster than a Fast Hash or FNV-1a\n let headersString = '';\n if (headers) {\n let obj: Record;\n\n if (headers instanceof Headers) {\n obj = processHeaders(headers);\n } else {\n obj = headers as Record;\n }\n\n // Filter headers to only include those that affect request identity\n // Include only headers that affect request identity, not execution behavior\n const keys = Object.keys(obj);\n const len = keys.length;\n\n // Sort keys manually for fastest deterministic output\n if (len > 1) {\n keys.sort();\n }\n\n let str = '';\n for (let i = 0; i < len; ++i) {\n if (CACHE_KEY_HEADERS.test(keys[i])) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // Concatenate all key parts into a cache key string\n // Template literals are apparently slower\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n return sanitizeCacheKey(cacheStr);\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING || isSearchParams(body)) {\n const str = String(body);\n\n bodyString = str.length < MIN_LENGTH_TO_HASH ? str : hash(str); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Files can't be read synchronously, so they are identified by their object\n bodyString +=\n key +\n '=' +\n (typeof value === STRING ? value : 'F' + getObjectId(value as File)) +\n '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (isObject(body) && !isJSONSerializable(body)) {\n // Blobs, buffers, streams etc. can't be read synchronously, so they are identified by their object.\n // Two different bodies never share a key, while the same body object is still deduplicated.\n bodyString = 'B' + getObjectId(body);\n } else {\n const o = isObject(body)\n ? JSON.stringify(sortObject(body))\n : String(body);\n\n bodyString = o.length > MIN_LENGTH_TO_HASH ? hash(o) : o;\n }\n }\n\n return sanitizeCacheKey(cacheStr + DELIMITER + bodyString);\n}\n\nconst objectIds = new WeakMap();\nlet lastObjectId = 0;\n\n/**\n * Returns a unique id for an object, e.g. a request body that can't be serialized.\n *\n * @param {object} obj - The object to identify.\n * @returns {number} - The id of the object.\n */\nfunction getObjectId(obj: object): number {\n let id = objectIds.get(obj);\n\n if (!id) {\n objectIds.set(obj, (id = ++lastObjectId));\n }\n\n return id;\n}\n\n/**\n * Prevents cache poisoning by removal of control chars and unusual characters.\n * When anything is removed, a hash of the original key is appended so that keys\n * differing only in the removed characters (e.g. `?a[]=1` and `?a=1`) don't collide.\n *\n * @param {string} cacheStr - The raw cache key.\n * @returns {string} - The sanitized cache key.\n */\nfunction sanitizeCacheKey(cacheStr: string): string {\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '') +\n DELIMITER +\n hash(cacheStr)\n : cacheStr;\n}\n\n/**\n * Checks if the cache entry is expired based on its timestamp and the expiry time.\n *\n * @param {CacheEntry} entry - The cache entry to check.\n * @returns {boolean} - Returns true if the cache entry is expired, false otherwise.\n */\nfunction isCacheExpired(entry: CacheEntry): boolean {\n // No expiry time means the entry never expires\n if (!entry.expiry) {\n return false;\n }\n\n return timeNow() > entry.expiry;\n}\n\n/**\n * Retrieves a cached response from the internal cache using the provided key.\n *\n * @param key - The unique key identifying the cached entry. If null, returns null.\n * @returns The cached {@link FetchResponse} if found, otherwise null.\n */\nexport function getCacheData<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n key: string | null,\n): FetchResponse | null {\n if (!key) {\n return null;\n }\n\n const entry = _cache.get(key);\n\n return entry ? entry.data : null;\n}\n\n/**\n * Retrieves a cache entry if it exists and is not expired.\n *\n * @param {string} key Cache key to utilize\n * @returns {CacheEntry | null} - The cache entry if it exists and is not expired, null otherwise.\n */\nexport function getCache(\n key: string | null,\n):\n | CacheEntry<\n FetchResponse\n >\n | null\n | undefined {\n return _cache.get(key as string);\n}\n\n/**\n * Sets a new cache entry or updates an existing one, with optional TTL (time-to-live).\n *\n * @param {string} key Cache key to utilize\n * @param {T} data - The data to be cached.\n * @param {number} [ttl] - Optional TTL in seconds. If not provided, the cache entry will not expire.\n * @param {number} [staleTime] - Optional stale time in seconds. If provided, the cache entry will be considered stale after this time.\n */\nexport function setCache(\n key: string,\n data: T,\n ttl?: number,\n staleTime?: number,\n): void {\n if (ttl === 0) {\n deleteCache(key);\n return;\n }\n\n const time = timeNow();\n const ttlMs = ttl ? ttl * 1000 : 0;\n const staleTimeMs = staleTime ? staleTime * 1000 : 0; // Ensure default value for staleTime\n\n _cache.set(key, {\n data,\n time,\n stale: staleTimeMs > 0 ? time + staleTimeMs : undefined, // Use undefined if staleTime is not set\n expiry: ttl === -1 ? undefined : time + ttlMs,\n });\n\n if (ttlMs > 0) {\n scheduleExpiry(key, ttlMs);\n }\n}\n\n/**\n * Deletes a cache entry once it expires.\n *\n * @param {string} key Cache key to utilize\n * @param {number} ms - The time until the entry expires, in milliseconds.\n */\nfunction scheduleExpiry(key: string, ms: number): void {\n addTimeout('c:' + key, () => deleteCache(key, true), ms);\n}\n\n/**\n * Invalidates (deletes) a cache entry.\n *\n * @param {string} key Cache key to utilize\n * @param {boolean} [removeExpired=false] - If true, only deletes the cache entry if it is expired or stale.\n */\nexport function deleteCache(key: string, removeExpired: boolean = false): void {\n if (removeExpired) {\n const entry = getCache(key);\n\n // If the entry does not exist, or it is neither expired nor stale, do not delete\n if (!entry || !isCacheExpired(entry)) {\n return;\n }\n }\n\n _cache.delete(key);\n\n const store = stores.get(key);\n\n if (store) {\n stores.delete(key);\n callStore(() => store.delete(key));\n }\n}\n\n/**\n * Prunes the cache by removing entries that have expired based on the provided cache time.\n */\nexport function pruneCache(): void {\n _cache.clear();\n stores.clear();\n}\n\n/**\n * Calls a cache store method. Store errors, e.g. of a full localStorage, are ignored so that they can't break requests.\n *\n * @param {() => unknown} fn - The function calling the store.\n */\nfunction callStore(fn: () => unknown): void {\n try {\n Promise.resolve(fn()).catch(noop);\n } catch {\n // Ignored\n }\n}\n\n/**\n * Saves a copy of a cached response in a cache store, so that it can be restored later, e.g. after a page reload.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheStore} [store] - The cache store. If not provided, nothing is saved.\n */\nfunction persistCache(key: string, store?: CacheStore): void {\n const entry = _cache.get(key);\n\n if (store && entry) {\n const { data, status, statusText, headers } = entry.data as FetchResponse;\n\n stores.set(key, store);\n callStore(() =>\n store.set(key, { ...entry, data: { data, status, statusText, headers } }),\n );\n }\n}\n\n/**\n * Reads the entry of a cache key from the cache store of a request, e.g. one saved during a previous page load.\n * Expired entries are deleted from the store.\n *\n * @param {string} key Cache key to utilize\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {Promise | null>} - The stored entry, or null if there is no valid one or the in-memory cache has an entry already.\n */\nexport async function getStoredCache(\n key: string,\n requestConfig: RequestConfig,\n): Promise | null> {\n const store = requestConfig.cacheStore;\n\n if (!store || isCacheBypassed(requestConfig)) {\n return null;\n }\n\n let entry: CacheEntry | null | undefined;\n\n try {\n entry = await store.get(key);\n } catch {\n // A failing store is treated like an empty one\n return null;\n }\n\n // Another request may have cached a response in the meantime\n if (!entry || _cache.has(key)) {\n return null;\n }\n\n if (isCacheExpired(entry)) {\n callStore(() => store.delete(key));\n\n return null;\n }\n\n return entry;\n}\n\n/**\n * Caches a response restored from a cache store in memory, keeping its original stale and expiry times.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheEntry} entry - The cache entry with the restored response.\n * @param {CacheStore} store - The cache store that the response was restored from.\n * @returns {boolean} - True if the restored response is fresh, false if it's stale.\n */\nexport function restoreCache(\n key: string,\n entry: CacheEntry,\n store: CacheStore,\n): boolean {\n _cache.set(key, entry);\n stores.set(key, store);\n\n if (entry.expiry) {\n scheduleExpiry(key, entry.expiry - timeNow());\n }\n\n notifySubscribers(key, entry.data);\n\n return !entry.stale || timeNow() < entry.stale;\n}\n\n/**\n * Mutates a cache entry with new data and optionally revalidates it.\n *\n * @param {string | null} key Cache key to utilize. If null, no mutation occurs.\n * @param {ResponseData} newData - The new data to be cached.\n * @param {MutationSettings|undefined} settings - Mutation settings.\n */\nexport async function mutate<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n key: string | null,\n newData: ResponseData,\n settings?: MutationSettings,\n): Promise | null> {\n // If no key is provided, do nothing\n if (!key) {\n return null;\n }\n\n const entry = getCache(\n key,\n );\n\n if (!entry) {\n return null;\n }\n\n const updatedData = isObject(newData) ? sanitizeObject(newData) : newData;\n\n const updatedResponse = {\n ...entry.data,\n data: updatedData,\n };\n\n // The ETag belongs to the original data, so the changed data must not be revalidated with it\n const headers = updatedResponse.headers;\n\n if (headers && headers.etag) {\n updatedResponse.headers = { ...headers };\n delete updatedResponse.headers.etag;\n }\n\n const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n persistCache(key, stores.get(key));\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\n}\n\n/**\n * Checks whether a request should bypass the cache, because of its cache buster or `cache: 'reload'`.\n *\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {boolean} - True if the cache should be bypassed.\n */\nexport function isCacheBypassed(requestConfig: RequestConfig): boolean {\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n\n return (\n !!(buster && buster(requestConfig)) || requestConfig.cache === 'reload'\n );\n}\n\n/**\n * Retrieves a cached response if available and valid, otherwise returns null.\n *\n * @template ResponseData - The type of the response data.\n * @template RequestBody - The type of the request body.\n * @template QueryParams - The type of the query parameters.\n * @template PathParams - The type of the path parameters.\n * @param {string | null} cacheKey - The cache key to look up.\n * @param {number | undefined} cacheTime - The maximum time to cache entry.\n * @param {RequestConfig} requestConfig - The fetcher configuration.\n * @returns {FetchResponse | null} - The cached response or null.\n */\nexport function getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n cacheKey: string | null,\n cacheTime: number | undefined,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): FetchResponse | null {\n // If cache key or time is not provided, return null\n if (!cacheKey || cacheTime === undefined || cacheTime === null) {\n return null;\n }\n\n if (isCacheBypassed(requestConfig)) {\n return null;\n }\n\n // Retrieve the cached entry\n const entry = getCache(\n cacheKey,\n );\n\n if (!entry) {\n return null;\n }\n\n const isExpired = isCacheExpired(entry);\n\n // If completely expired, delete and return null\n if (isExpired) {\n deleteCache(cacheKey);\n return null;\n }\n\n const data = entry.data;\n\n // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n // The placeholder stored while a request is in flight is not a response, so treat it as a miss\n return data && data.isFetching ? null : data;\n}\n\n/**\n * Sets or deletes the response cache based on cache settings and notifies subscribers.\n *\n * @param {FetchResponse} output - The response to cache.\n * @param {RequestConfig} requestConfig - The request configuration.\n * @param {boolean} [isError=false] - Whether the response is an error.\n */\nexport function handleResponseCache<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n output: FetchResponse,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n isError: boolean = false,\n): void {\n // It is string as it is called once request is made\n const cacheKey = requestConfig.cacheKey as string;\n\n if (cacheKey) {\n const cacheTime = requestConfig.cacheTime;\n const skipCache = requestConfig.skipCache;\n\n // Fast path: only set cache if cacheTime is positive and not skipping cache\n if (\n cacheTime &&\n (!isError || requestConfig.cacheErrors) &&\n !(skipCache && skipCache(output, requestConfig))\n ) {\n setCache(cacheKey, output, cacheTime, requestConfig.staleTime);\n\n // Error responses are only cached in memory\n if (!isError) {\n persistCache(cacheKey, requestConfig.cacheStore);\n }\n } else {\n const entry = getCache(cacheKey);\n\n // Don't let the in-flight placeholder outlive a request whose result isn't cached\n if (entry && entry.data && entry.data.isFetching) {\n deleteCache(cacheKey);\n }\n }\n\n notifySubscribers(cacheKey, output);\n removeInFlight(cacheKey);\n\n const prevCacheKey = requestConfig._prevKey;\n\n if (prevCacheKey) {\n removeInFlight(prevCacheKey);\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { mutate } from './cache-manager';\nimport {\n APPLICATION_CONTENT_TYPE,\n APPLICATION_JSON,\n CONTENT_TYPE,\n FUNCTION,\n STRING,\n} from './constants';\nimport {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n ResponseError,\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n} from './types';\nimport { flattenData, isObject, processHeaders } from './utils';\n\n/**\n * Parses the response data based on the Content-Type header, or reads it as the given response type.\n *\n * @param response - The Response object to parse.\n * @param responseType - How to read the body regardless of its Content-Type, e.g. as a Blob, or `'stream'` to leave it unread.\n * @returns A Promise that resolves to the parsed data.\n */\nexport async function parseResponseData<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse,\n responseType?: RequestConfig['responseType'],\n): Promise {\n // Bail early if response is null or undefined\n if (!response) {\n return null;\n }\n\n // Get the content-type header once\n const headers = (response as Response).headers;\n let contentType = headers && headers.get(CONTENT_TYPE);\n\n if (contentType) {\n // Lowercase and trim for consistent matching\n contentType = contentType.toLowerCase().trim();\n } else {\n contentType = '';\n }\n\n // Split for mime type without charset\n const mimeType = contentType.split(';', 1)[0];\n\n let data;\n\n try {\n if (responseType) {\n // The body is read as requested, or left unread as a stream to be read by the caller\n data =\n responseType === 'stream'\n ? response.body\n : await response[responseType]();\n } else if (\n mimeType.includes(APPLICATION_JSON) ||\n mimeType.includes('+json')\n ) {\n data = await response.json(); // Parse JSON response\n } else if (\n (mimeType.includes('multipart/form-data') || // Parse as FormData\n mimeType.includes(\n APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded', // Handle URL-encoded forms\n )) &&\n typeof response.formData === FUNCTION\n ) {\n data = await response.formData();\n } else if (/^(image|video|audio)\\/|octet-stream|pdf|zip/.test(mimeType)) {\n data = await response.arrayBuffer(); // Parse as ArrayBuffer for binary types\n } else {\n data = await response.text();\n\n if (typeof data === STRING) {\n const trimmed = data.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n data = JSON.parse(trimmed);\n } catch {\n // leave as text if parsing fails\n }\n }\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (_error) {\n // Parsing failed, fallback to null\n data = null;\n }\n\n return data;\n}\n\n/**\n * Prepare response object with additional information.\n *\n * @param Response. It may be \"null\" in case of request being aborted.\n * @param {RequestConfig} config - Request config\n * @param error - whether the response is erroneous\n * @returns {FetchResponse} Response data\n */\nexport const prepareResponse = <\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n config: RequestConfig,\n error: ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null,\n): FetchResponse => {\n const defaultResponse = config.defaultResponse;\n const cacheKey = config.cacheKey;\n const mutatator = mutate.bind(null, cacheKey as string) as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >['mutate'];\n\n // This may happen when request is cancelled.\n if (!response) {\n return {\n ok: false,\n // Enhance the response with extra information\n error,\n data: defaultResponse ?? null,\n headers: null,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: false,\n isError: true,\n } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n const isNativeResponse =\n typeof Response === FUNCTION && response instanceof Response;\n\n let data = response.data;\n\n // Set the default response if the provided data is an empty object or array\n // Other objects, e.g. Blobs, buffers and streams, have no keys either, but aren't empty\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (/^\\[object (Object|Array)\\]$/.test(\n Object.prototype.toString.call(data),\n ) &&\n Object.keys(data).length === 0))\n ) {\n response.data = data = defaultResponse;\n }\n\n if (config.flattenResponse) {\n response.data = data = flattenData(data);\n }\n\n if (config.select) {\n response.data = data = config.select(data);\n }\n\n const headers = processHeaders(response.headers);\n\n // Native fetch Response extended by extra information\n if (isNativeResponse) {\n const output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > = {\n body: response.body,\n bodyUsed: response.bodyUsed,\n ok: response.ok,\n redirected: response.redirected,\n type: response.type,\n url: response.url,\n status: response.status,\n statusText: response.statusText,\n\n // Convert methods to use arrow functions to preserve correct return types\n // Lazily construct Blob from ArrayBuffer\n blob: async () =>\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n json: async () => data as ResponseData, // Return the already parsed JSON data\n text: async () => data as string, // Return the already parsed text data\n // The body was already read, so a copy of this response is returned instead of Response.clone()\n clone: () => ({ ...output }),\n arrayBuffer: async () =>\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0), // Return the ArrayBuffer directly\n formData: async () => (data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: async () =>\n new Uint8Array(data instanceof ArrayBuffer ? data : new ArrayBuffer(0)),\n // Enhance the response with extra information\n error,\n data,\n headers,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: response.ok && !error,\n isError: !!error,\n };\n\n return output;\n }\n\n // If it's a custom fetcher, and it does not return any Response instance, it may have its own internal handler\n if (isObject(response)) {\n Object.assign(response, {\n error,\n headers,\n isFetching: false,\n mutate: mutatator,\n isSuccess: response.ok && !error,\n isError: !!error,\n });\n }\n\n return response;\n};\n","import { applyInterceptors } from './interceptor-manager';\nimport type { FetchResponse, RetryConfig, RetryFunction } from './types';\nimport { delayInvocation, timeNow } from './utils';\nimport { generateCacheKey } from './cache-manager';\nimport { FUNCTION } from './constants';\n\nfunction getMsFromHttpDate(dateString: string): number | null {\n const ms = Date.parse(dateString) - timeNow();\n\n if (!isNaN(ms)) {\n return Math.max(0, Math.floor(ms));\n }\n return null;\n}\n\n/**\n * Calculates the number of milliseconds to wait before retrying a request,\n * based on the `Retry-After` HTTP header in the provided response.\n *\n * The function supports both numeric (seconds) and HTTP-date formats for the `Retry-After` header.\n * - If the header is a number, it is interpreted as seconds and converted to milliseconds.\n * - If the header is a date, the function calculates the difference between the date and the current time.\n *\n * @param extendedResponse - The response object containing headers, or `null`.\n * @returns The number of milliseconds to wait before retrying, or `null` if the header is not present or invalid.\n */\nexport function getRetryAfterMs(\n extendedResponse: FetchResponse | null,\n): number | null {\n if (!extendedResponse) {\n return null;\n }\n\n const headers = extendedResponse.headers || {};\n const retryAfter = headers['retry-after'];\n\n if (retryAfter) {\n // Try parsing as seconds\n const seconds = Number(retryAfter);\n\n if (!isNaN(seconds) && seconds >= 0) {\n return seconds * 1000;\n }\n\n const ms = getMsFromHttpDate(retryAfter);\n\n if (ms !== null) {\n return ms;\n }\n }\n\n // Headers are already in lowercase\n const RATELIMIT_RESET = 'ratelimit-reset';\n\n // Unix timestamp when the rate limit window resets (relative to current time)\n // Fallback to checking 'ratelimit-reset-after' OR 'x-ratelimit-reset-after' headers\n const rateLimitResetAfter =\n headers[RATELIMIT_RESET + '-after'] ||\n headers['x-' + RATELIMIT_RESET + '-after'];\n\n if (rateLimitResetAfter) {\n const seconds = Number(rateLimitResetAfter);\n\n if (!isNaN(seconds)) {\n return seconds * 1000;\n }\n }\n\n // ISO 8601 datetime when the rate limit resets\n // Fallback to checking 'ratelimit-reset-at' 'x-ratelimit-reset-at' headers\n const rateLimitResetAt =\n headers[RATELIMIT_RESET + '-at'] || headers['x-' + RATELIMIT_RESET + '-at'];\n\n if (rateLimitResetAt) {\n return getMsFromHttpDate(rateLimitResetAt);\n }\n\n return null;\n}\n\n/**\n * Executes a request function with retry logic according to the provided configuration.\n *\n * The function attempts the request up to the specified number of retries, applying delay and backoff strategies.\n * Retries can be triggered based on response status codes, custom logic, or the presence of a `Retry-After` header.\n * Optionally, an `onRetry` interceptor can be invoked before each retry attempt.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param requestFn - The function that performs the request. Receives `isStaleRevalidation` and `attempt` as arguments.\n * @param config - The retry configuration, including retry count, delay, backoff, retry conditions, and hooks.\n * @returns A promise resolving to the fetch response, or rejecting if all retries are exhausted.\n * @throws Error if the maximum number of retries is exceeded or a non-retriable error occurs.\n */\nexport async function withRetry<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation: boolean,\n attempt: number,\n ) => Promise<\n FetchResponse\n >,\n config: RetryConfig,\n): Promise> {\n const {\n retries = 0,\n delay = 0,\n backoff = 1,\n maxDelay,\n retryOn = [],\n shouldRetry,\n jitter,\n methods,\n } = config;\n\n let attempt = 0;\n let waitTime = delay;\n const maxRetries = retries > 0 ? retries : 0;\n let output: FetchResponse;\n\n while (attempt <= maxRetries) {\n // Subsequent attempts will have output defined, but the first attempt may not.\n // Let's apply onRetry interceptor and regenerate cache key if ot really changes.\n if (attempt > 0 && output!) {\n const cfg = output.config;\n const onRetry = cfg.onRetry;\n\n if (onRetry) {\n await applyInterceptors(onRetry, output, attempt);\n\n // If the key was automatically generated, we need to regenerate it as config may change.\n // We don't detect whether config changed for performance reasons.\n if (cfg._isAutoKey) {\n cfg._prevKey = cfg.cacheKey as string;\n cfg.cacheKey = generateCacheKey(cfg, false);\n }\n }\n }\n\n // Performance optimization: Call the request function with the current attempt number\n // If this is the first attempt, we pass `isStaleRevalidation` as `false`,\n // otherwise we pass `true` to indicate that this is a stale revalidation (no cache hit).\n output = await requestFn(attempt > 0, attempt);\n const error = output.error;\n\n // Stop unless a failed response should be retried according to the retry settings,\n // or a successful one according to shouldRetry\n if (\n error\n ? await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n methods,\n )\n : !(\n shouldRetry &&\n attempt < maxRetries &&\n (await shouldRetry(output, attempt))\n )\n ) {\n break;\n }\n\n // The delay before the next retry, randomized with jitter unless the server asks for one below\n let retryDelay = withJitter(waitTime, jitter);\n\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (error && (error.status === 429 || error.status === 503)) {\n // Try to extract the \"Retry-After\" value from the response headers\n const retryAfterMs = getRetryAfterMs(output);\n\n // If a valid retry-after value is found, override the wait time before next retry\n // Cap it with maxDelay so that a server can't make the client wait indefinitely\n if (retryAfterMs !== null) {\n retryDelay = waitTime = Math.min(\n retryAfterMs,\n maxDelay || retryAfterMs,\n );\n }\n }\n\n await delayInvocation(retryDelay);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n }\n\n return output!;\n}\n\n/**\n * Determines whether to stop retrying based on the error, current attempt count, and retry configuration.\n *\n * This function checks:\n * - If the maximum number of retries has been reached.\n * - If the request was aborted, e.g. with its signal or by a newer request. Aborted requests are never retried.\n * - If a custom `shouldRetry` callback is provided, its result is used to decide.\n * - If no custom logic is provided, falls back to checking if the error status is included in the `retryOn` list,\n * and the request method in the `methods` list, if any.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param output - The response object containing the error and request configuration.\n * @param attempt - The current retry attempt number.\n * @param maxRetries - The maximum number of retry attempts allowed.\n * @param shouldRetry - Optional custom function to determine if a retry should occur.\n * @param retryOn - Optional list of HTTP status codes that should trigger a retry.\n * @param methods - Optional list of request methods that are retried on the `retryOn` statuses. All methods are retried without it.\n * @returns A promise resolving to `true` if retrying should stop, or `false` to continue retrying.\n */\nexport async function getShouldStopRetrying<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n output: FetchResponse,\n attempt: number,\n maxRetries: number,\n shouldRetry?: RetryFunction<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n retryOn: number[] = [],\n methods?: string[],\n): Promise {\n // Safety first: always respect max retries\n // We check retries provided regardless of the shouldRetry being provided so to avoid infinite loops.\n // It is a fail-safe so to prevent excessive retry attempts even if custom retry logic suggests a retry.\n if (attempt === maxRetries) {\n return true;\n }\n\n // Aborted requests are never retried, as e.g. a retry of one cancelled by a newer request would cancel the newer one\n if (output.error?.isCancelled) {\n return true;\n }\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n\n if (result !== null) {\n return !result;\n }\n }\n\n return !(\n (retryOn || []).includes(output.error?.status ?? 0) &&\n (!methods ||\n methods.some((method) => method.toUpperCase() === output.config.method))\n );\n}\n\n/**\n * Randomizes a retry delay with jitter, so that clients that failed at the same time, e.g. during an outage, don't retry all at once.\n *\n * @param delay - The delay computed from the `delay`, `backoff` and `maxDelay` settings, in milliseconds.\n * @param jitter - `true` for a random delay between 0 and the computed one (\"full jitter\"), or a function that returns the delay to use.\n * @returns The delay to wait before the retry, in milliseconds.\n */\nfunction withJitter(delay: number, jitter: RetryConfig['jitter']): number {\n return typeof jitter === FUNCTION\n ? (jitter as (delay: number) => number)(delay)\n : jitter\n ? Math.random() * delay\n : delay;\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation, isOffline, isPageHidden } from './utils';\n\n/**\n * Executes a request function with polling, stopping when shouldStopPolling returns true,\n * pollingInterval is not set, or maxAttempts is reached.\n * Polling pauses while the page is hidden or the browser is offline, unless allowed by refreshWhenHidden or refreshWhenOffline.\n *\n * @template Output The type of the output returned by the request function.\n * @param requestFn - The function that performs a single request (with retries).\n * @param pollingInterval - Interval in ms between polling attempts.\n * @param shouldStopPolling - Function to determine if polling should stop.\n * @param maxAttempts - Maximum number of polling attempts, default: 0 (unlimited).\n * @param pollingDelay - Delay in ms before each polling attempt, default: 0.\n * @param refreshWhenHidden - Whether to keep polling while the page is hidden, default: false.\n * @param refreshWhenOffline - Whether to keep polling while the browser is offline, default: false.\n * @param signal - The signal passed to the request. Polling stops once it is aborted.\n * @returns The final output from the last request.\n */\nexport async function withPolling<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation?: boolean,\n attempt?: number,\n ) => Promise<\n FetchResponse\n >,\n pollingInterval?: RequestConfig['pollingInterval'],\n shouldStopPolling?: RequestConfig['shouldStopPolling'],\n maxAttempts = 0,\n pollingDelay = 0,\n refreshWhenHidden = false,\n refreshWhenOffline = false,\n signal?: AbortSignal,\n): Promise> {\n if (!pollingInterval) {\n return requestFn();\n }\n\n let pollingAttempt = 0;\n let output: FetchResponse;\n\n while (maxAttempts === 0 || pollingAttempt < maxAttempts) {\n if (pollingDelay > 0) {\n await delayInvocation(pollingDelay, signal);\n }\n\n output = await requestFn();\n\n pollingAttempt++;\n\n if (\n (maxAttempts > 0 && pollingAttempt >= maxAttempts) ||\n !pollingInterval ||\n (shouldStopPolling && shouldStopPolling(output, pollingAttempt))\n ) {\n break;\n }\n\n // Wait for the next attempt, and keep waiting while polling is paused\n do {\n await delayInvocation(pollingInterval, signal);\n\n // Aborting the signal of the request stops polling\n if (signal && signal.aborted) {\n return output;\n }\n } while (\n (!refreshWhenHidden && isPageHidden()) ||\n (!refreshWhenOffline && isOffline())\n );\n }\n\n return output!;\n}\n","import { ABORT_ERROR, UNDEFINED } from './constants';\nimport type { RequestConfig, UploadProgress } from './types';\nimport { createAbortError } from './utils';\n\n// Responses with these statuses can't have a body\nconst NULL_BODY_STATUSES = [204, 205, 304];\n\n// Headers that browsers don't let requests set. fetch() skips them silently, while\n// XMLHttpRequest logs errors for them, so they are skipped before sending.\nconst FORBIDDEN_HEADERS =\n /^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/;\n\n// ReadableStream is missing in some environments, e.g. React Native\nconst isStream = (body: unknown): body is ReadableStream =>\n typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream;\n\nexport const toProgress = (loaded: number, total?: number): UploadProgress => ({\n loaded,\n total,\n progress: total ? loaded / total : undefined,\n});\n\n/**\n * Sends a request and reports the upload progress of its body to `onUploadProgress`.\n * Browsers and React Native don't report the upload progress of fetch(), so XMLHttpRequest is used there.\n * Elsewhere, e.g. in Node.js, the body is streamed with fetch() and counted while it is sent.\n *\n * @param {string} url - The request URL.\n * @param {RequestConfig} config - The request configuration, with a body and `onUploadProgress`.\n * @returns {Promise} - The response.\n */\nexport function fetchWithUploadProgress(\n url: string,\n config: RequestConfig,\n): Promise {\n const body = config.body as BodyInit;\n\n return typeof XMLHttpRequest !== UNDEFINED && !isStream(body)\n ? sendWithXhr(url, config, body)\n : sendStreamed(url, config, body);\n}\n\nfunction sendWithXhr(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n // fetchf() always sets the signal, as it handles timeouts and cancellation with it\n const signal = config.signal!;\n const abort = () => xhr.abort();\n\n const settle = (fn: () => void) => {\n signal.removeEventListener('abort', abort);\n\n try {\n fn();\n } catch (error) {\n reject(error);\n }\n };\n\n xhr.open(config.method as string, url);\n xhr.responseType = 'blob';\n xhr.withCredentials = config.credentials === 'include';\n\n new Headers(config.headers).forEach(\n (value, name) =>\n FORBIDDEN_HEADERS.test(name) || xhr.setRequestHeader(name, value),\n );\n\n xhr.upload.onprogress = (event) =>\n config.onUploadProgress!(\n toProgress(\n event.loaded,\n event.lengthComputable ? event.total : undefined,\n ),\n );\n\n xhr.onload = () =>\n settle(() => {\n const headers = new Headers();\n\n for (const line of xhr.getAllResponseHeaders().split(/\\r?\\n/)) {\n const index = line.indexOf(':');\n\n if (index > 0) {\n headers.append(line.slice(0, index), line.slice(index + 1).trim());\n }\n }\n\n const response = new Response(\n NULL_BODY_STATUSES.includes(xhr.status) ? null : xhr.response,\n { status: xhr.status, statusText: xhr.statusText, headers },\n );\n\n // Like fetch(), the response tells its final URL, e.g. after redirects\n Object.defineProperty(response, 'url', { value: xhr.responseURL });\n\n resolve(response);\n });\n\n xhr.onerror = () =>\n settle(() => reject(new TypeError('Network request failed')));\n\n // Like fetch(), aborted requests reject with the reason of the abort signal\n const onAbort = () =>\n settle(() =>\n reject(\n signal.reason ||\n createAbortError('The request was aborted', ABORT_ERROR),\n ),\n );\n\n xhr.onabort = onAbort;\n\n if (signal.aborted) {\n return onAbort();\n }\n\n signal.addEventListener('abort', abort);\n\n xhr.send(body as XMLHttpRequestBodyInit);\n });\n}\n\nasync function sendStreamed(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n const headers = new Headers(config.headers);\n let stream = body as ReadableStream;\n let total: number | undefined;\n\n if (!isStream(body)) {\n // Serialize the body like fetch() would, to know its size and content type\n const blob = body instanceof Blob ? body : await new Response(body).blob();\n\n total = blob.size;\n stream = blob.stream();\n\n if (blob.type && !headers.has('content-type')) {\n headers.set('content-type', blob.type);\n }\n }\n\n let loaded = 0;\n\n return fetch(url, {\n ...config,\n headers,\n body: stream.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n config.onUploadProgress!(toProgress(loaded, total));\n controller.enqueue(chunk);\n },\n }),\n ),\n // Required by fetch() to send a stream\n duplex: 'half',\n } as RequestInit);\n}\n","import { FUNCTION } from './constants';\nimport type { DownloadProgress } from './types';\nimport { toProgress } from './upload-progress';\n\n/**\n * Reports the download progress of a response body to `onDownloadProgress` while the body is read.\n * The body is counted as it arrives, so the progress follows the download.\n *\n * @param {T} response - The response. Other than native responses with a body, e.g. responses of HEAD requests or custom fetchers, are returned as they are.\n * @param {Function} [onDownloadProgress] - The function called with the progress. Without it, the response is returned as it is.\n * @returns {T} - A copy of the response, whose body is counted while it's read.\n */\nexport function withDownloadProgress(\n response: T,\n onDownloadProgress?: (progress: DownloadProgress) => void,\n): T {\n // Response is missing in some environments, and response bodies e.g. in React Native\n if (\n !onDownloadProgress ||\n typeof Response !== FUNCTION ||\n !(response instanceof Response) ||\n !response.body\n ) {\n return response;\n }\n\n const headers = response.headers;\n // Content-Length is the size of the compressed body, so the size of a compressed one is unknown\n const total = headers.has('content-encoding')\n ? undefined\n : Number(headers.get('content-length')) || undefined;\n let loaded = 0;\n\n const counted = new Response(\n response.body.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n // Browsers may hide the Content-Encoding header of cross-origin responses, so the progress is capped at 1\n onDownloadProgress(\n toProgress(loaded, total && Math.max(total, loaded)),\n );\n controller.enqueue(chunk);\n },\n }),\n ),\n response,\n );\n\n // Like the original response, the copy tells its final URL, whether it was redirected and its type\n for (const key of ['url', 'redirected', 'type'] as const) {\n Object.defineProperty(counted, key, { value: response[key] });\n }\n\n return counted as T;\n}\n","import type { ResponseError } from './errors/response-error';\nimport type {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n} from './types/request-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { handleResponseCache } from './cache-manager';\nimport { ABORT_ERROR, REJECT } from './constants';\nimport {\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n HeadersObject,\n} from './types';\nimport { processHeaders } from './utils';\n\n/**\n * Handles final processing for both success and error responses\n * Applies error interceptors, caching, notifications, and error strategy\n */\nexport async function withErrorHandling<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n isStaleRevalidation: boolean,\n requestFn: (\n isStaleRevalidation: boolean,\n ) => Promise<\n FetchResponse\n >,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): Promise> {\n const output = await requestFn(isStaleRevalidation);\n const error = output.error;\n\n if (!error) {\n // SUCCESS PATH\n handleResponseCache(output, requestConfig);\n\n return output;\n }\n\n // ERROR PATH\n\n if (requestConfig.onError) {\n await applyInterceptors(requestConfig.onError, error);\n }\n\n // Timeouts and request cancellations using AbortController do not throw any errors unless rejectCancelled is true.\n // Only handle the error if the request was not cancelled, or if it was cancelled and rejectCancelled is true.\n const isCancelled = error.isCancelled;\n\n const logger = requestConfig.logger;\n\n if (!isCancelled && logger && logger.warn) {\n logger.warn('FETCH ERROR', redactError(error as ResponseError));\n }\n\n // The defaultResponse strategy returns the default response in place of the error data.\n // The original data stays available through error.response.\n if (requestConfig.strategy === 'defaultResponse') {\n output.data = (requestConfig.defaultResponse ?? null) as typeof output.data;\n }\n\n // Handle cache and notifications FIRST (before strategy)\n handleResponseCache(output, requestConfig, true);\n\n // handle error strategy as the last part\n const shouldHandleError = !isCancelled || requestConfig.rejectCancelled;\n\n if (shouldHandleError) {\n const strategy = requestConfig.strategy;\n // Reject the promise\n if (strategy === REJECT) {\n throw error;\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\n}\n\n// Credential headers that must not end up in logs\nconst SENSITIVE_HEADERS = [\n 'authorization',\n 'proxy-authorization',\n 'cookie',\n 'x-api-key',\n];\n\n/**\n * Creates a copy of the error for logging, with credential headers masked and the request body removed.\n * The error itself is left untouched.\n */\nfunction redactError(error: ResponseError): ResponseError {\n // Cache keys are dropped too, as they can contain short request bodies\n const config = {\n ...error.config,\n body: undefined,\n data: undefined,\n cacheKey: undefined,\n _prevKey: undefined,\n headers: processHeaders(error.config.headers as HeadersObject),\n };\n\n for (const name of SENSITIVE_HEADERS) {\n if (config.headers[name]) {\n config.headers[name] = '[REDACTED]';\n }\n }\n\n const copy = Object.assign(new Error(error.message), error, {\n config,\n request: config,\n response: error.response && { ...error.response, config },\n });\n\n copy.name = error.name;\n copy.stack = error.stack;\n\n return copy;\n}\n\nexport function enhanceError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): void {\n error.status = error.status || (response && response.status) || 0;\n error.statusText =\n error.statusText || (response && response.statusText) || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n HeadersObject,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport type { StoredResponse } from './types/cache-manager';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject, noop, processHeaders } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport {\n generateCacheKey,\n getCacheData,\n getCachedResponse,\n getStoredCache,\n isCacheBypassed,\n restoreCache,\n setCache,\n} from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { fetchWithUploadProgress } from './upload-progress';\nimport { withDownloadProgress } from './download-progress';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION, GET, HEAD } from './constants';\nimport { buildConfig } from './config-handler';\n\nconst inFlightResponse = Object.freeze({\n isFetching: true,\n});\n\n/**\n * Sends an HTTP request to the specified URL using the provided configuration and returns a typed response.\n *\n * @typeParam ResponseData - The expected shape of the response data. Defaults to `DefaultResponse`.\n * @typeParam RequestBody - The type of the request payload/body. Defaults to `DefaultPayload`.\n * @typeParam QueryParams - The type of the query parameters. Defaults to `DefaultParams`.\n * @typeParam PathParams - The type of the path parameters. Defaults to `DefaultUrlParams`.\n *\n * @param url - The endpoint URL to which the request will be sent.\n * @param config - Optional configuration object for the request, including headers, method, body, query, and path parameters.\n *\n * @returns A promise that resolves to a `FetchResponse` containing the typed response data and request metadata.\n *\n * @example\n * ```typescript\n * const { data } = await fetchf('/api/user', { method: 'GET' });\n * console.log(data);\n * ```\n */\nexport async function fetchf<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n url: string,\n reqConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null = null,\n): Promise> {\n // Ultra-fast early cache check if cacheKey is provided as a string\n // For workloads dominated by repeated requests, this string caching optimization\n // can potentially support millions of requests per second with minimal CPU overhead\n if (reqConfig && typeof reqConfig.cacheKey === 'string') {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(reqConfig.cacheKey, reqConfig.cacheTime, reqConfig);\n\n if (cached) {\n return cached;\n }\n }\n\n const fetcherConfig = buildConfig<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(url, reqConfig);\n\n const {\n timeout,\n cancellable,\n cacheKey,\n dedupeTime,\n cacheTime,\n staleTime,\n refetchOnFocus,\n refetchOnReconnect,\n pollingInterval = 0,\n } = fetcherConfig;\n const isCacheEnabled = cacheTime !== undefined || staleTime !== undefined;\n const method = fetcherConfig.method;\n\n // Cached responses of GET and HEAD requests are revalidated with their ETag.\n // Custom fetchers may not handle 304 responses, so they only send it when it's enabled for them.\n const isETagEnabled =\n isCacheEnabled &&\n (method === GET || method === HEAD) &&\n (fetcherConfig.etag ?? !fetcherConfig.fetcher);\n\n const needsCacheKey = !!(\n cacheKey ||\n timeout ||\n dedupeTime ||\n isCacheEnabled ||\n cancellable ||\n refetchOnFocus ||\n refetchOnReconnect\n );\n\n let _cacheKey: string | null = null;\n\n // Generate cache key if required\n if (needsCacheKey) {\n _cacheKey = generateCacheKey(fetcherConfig);\n }\n\n // The initial data, which is used as the first response instead of sending the request\n let initialResponse: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n // Cache handling logic\n if (_cacheKey && isCacheEnabled) {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(_cacheKey, cacheTime, fetcherConfig);\n\n if (cached) {\n return cached;\n }\n\n // Restore the response from the cache store, e.g. one saved during a previous page load\n if (fetcherConfig.cacheStore) {\n const stored = await getStoredCache(_cacheKey, fetcherConfig);\n const restored =\n stored &&\n toResponse(\n stored.data,\n _cacheKey,\n fetcherConfig,\n );\n\n // A stale response is shown until the request below revalidates it\n if (\n restored &&\n restoreCache(\n _cacheKey,\n { ...stored, data: restored },\n fetcherConfig.cacheStore,\n )\n ) {\n return restored;\n }\n }\n\n // While there's no cached response, the initial data, e.g. data rendered on the server, is cached as the response\n if (\n fetcherConfig.initialData !== undefined &&\n !getCacheData(_cacheKey) &&\n !isCacheBypassed(fetcherConfig)\n ) {\n initialResponse = toResponse(\n {\n data: fetcherConfig.initialData,\n status: 200,\n statusText: '',\n headers: {},\n },\n _cacheKey,\n fetcherConfig,\n );\n }\n }\n\n // Deduplication logic\n if (_cacheKey && dedupeTime) {\n const inflight = getInFlightPromise<\n FetchResponse\n >(_cacheKey, dedupeTime);\n\n if (inflight) {\n return inflight;\n }\n }\n\n const retryConfig = fetcherConfig.retry || {};\n const { retries = 0, resetTimeout } = retryConfig;\n\n // The signal passed to the request. Each attempt replaces it in the config with a signal of its own.\n const userSignal = fetcherConfig.signal;\n\n // The actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation: boolean, attempt = 0) => {\n // The cached response to revalidate. It's read before the cache is marked as fetching below.\n const cached =\n isETagEnabled &&\n getCacheData(\n _cacheKey,\n );\n\n // If cache key is specified, we will handle optimistic updates\n // and mark the request as in-flight, so to catch \"fetching\" state.\n // This is useful for Optimistic UI updates (e.g., showing loading spinners).\n if (!attempt) {\n // The initial data is only used once, as the first response\n if (initialResponse) {\n const response = initialResponse;\n\n initialResponse = null;\n\n return response;\n }\n\n if (_cacheKey && !isStaleRevalidation) {\n if (staleTime) {\n const existingCache = getCachedResponse(\n _cacheKey,\n cacheTime,\n fetcherConfig,\n );\n\n // Don't notify subscribers when cache exists\n // Let them continue showing stale data during background revalidation\n if (!existingCache) {\n setCache(_cacheKey, inFlightResponse, cacheTime, staleTime);\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n } else {\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n }\n\n // Attach cache key so that it can be reused in interceptors or in the final response\n fetcherConfig.cacheKey = _cacheKey;\n }\n\n const url = fetcherConfig.url as string;\n\n // Add the request to the queue. Make sure to handle deduplication, cancellation, timeouts in accordance to retry settings\n const controller = markInFlight(\n _cacheKey,\n url,\n timeout,\n dedupeTime || 0,\n !!cancellable,\n // Enable timeout either by default or when retries & resetTimeout are enabled\n !!(timeout && (!attempt || resetTimeout)),\n );\n\n // Do not create a shallow copy to maintain idempotency here.\n // This ensures the original object is mutated by interceptors whenever needed, including retry logic.\n const requestConfig = fetcherConfig;\n\n requestConfig.signal = controller.signal;\n\n // The request is aborted along with the signal passed to it, which may have been aborted already\n const abort = () => controller.abort(userSignal!.reason);\n\n if (userSignal) {\n if (userSignal.aborted) {\n abort();\n } else {\n userSignal.addEventListener('abort', abort);\n }\n }\n\n let output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n let response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n try {\n if (fetcherConfig.onRequest) {\n // Zero-allocation yield to microtask queue so the outer fetchf() can call setInFlightPromise()\n // before onRequest interceptors run. This ensures that if onRequest triggers\n // another fetchf() with the same cacheKey, getInFlightPromise() finds item[4].\n // On retries (attempt > 0), setInFlightPromise() was already called during the first attempt.\n // The promise stored in item[4] is the outer doRequestPromise which covers all retries.\n // So the race only matters on the very first attempt when the outer scope hasn't had a chance to call setInFlightPromise() yet.\n if (_cacheKey && dedupeTime && !attempt) {\n await null;\n }\n\n await applyInterceptors(fetcherConfig.onRequest, requestConfig);\n }\n\n // Custom fetcher\n const fn = fetcherConfig.fetcher;\n const init = withETag(requestConfig, cached);\n\n response = (fn\n ? await fn(\n url,\n init,\n )\n : // Uploads with onUploadProgress are sent in a way that reports their progress\n await (requestConfig.onUploadProgress && requestConfig.body\n ? fetchWithUploadProgress(url, requestConfig)\n : fetch(url, init as RequestInit))) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Reports the download progress while the body is read\n response = withDownloadProgress(\n response,\n requestConfig.onDownloadProgress,\n );\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\n // The server answered that the cached response is still valid, so it's reused instead of being sent again.\n // Like other cached responses, it has been parsed and transformed already.\n if (init !== requestConfig && response.status === 304) {\n return cached as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n // Case 1: Native Response instance\n if (typeof Response === FUNCTION && response instanceof Response) {\n response.data = requestConfig.parser\n ? await requestConfig.parser(response)\n : await parseResponseData(response, requestConfig.responseType);\n } else if (fn) {\n // Case 2: Custom fetcher that returns a response object\n if (!('data' in response && 'body' in response)) {\n // Case 3: Raw data, wrap it\n response = { data: response } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n }\n\n // Attach config and data to the response\n // This is useful for custom fetchers that do not return a Response instance\n // and for interceptors that may need to access the request config\n response.config = requestConfig;\n\n // Check if the response status is not outside the range 200-299 and if so, output error\n // This is the pattern for fetch responses as per spec, but custom fetchers may not follow it so we check for `ok` property\n if (response.ok !== undefined && !response.ok) {\n throw new ResponseError(\n requestConfig.method +\n ' to ' +\n url +\n ' failed! Status: ' +\n (response.status || null),\n requestConfig,\n response,\n );\n }\n }\n\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig);\n\n const onResponse = fetcherConfig.onResponse;\n\n if (onResponse) {\n await applyInterceptors(onResponse, output);\n }\n } catch (_error) {\n const error = _error as ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Append additional information to Network, CORS or any other fetch() errors\n enhanceError(\n error,\n response,\n requestConfig,\n );\n\n // Prepare Extended Response\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig, error);\n } finally {\n if (userSignal) {\n userSignal.removeEventListener('abort', abort);\n }\n }\n\n return output;\n };\n\n // Inline and minimize function wrappers for performance\n // When retries are enabled, forward isStaleRevalidation so the first attempt\n // of a background SWR revalidation doesn't incorrectly mark the request as in-flight\n const baseRequest =\n retries > 0\n ? (isStaleRevalidation: boolean) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const { onLoadingSlow, loadingTimeout } = fetcherConfig;\n\n // Calls onLoadingSlow once a request, including its retries, is still pending after loadingTimeout.\n // Background revalidations don't show a loading state, so they are never considered slow.\n const request =\n onLoadingSlow && loadingTimeout\n ? async (isStaleRevalidation: boolean) => {\n if (isStaleRevalidation) {\n return baseRequest(isStaleRevalidation);\n }\n\n const timer = setTimeout(\n () => applyInterceptors(onLoadingSlow, fetcherConfig).catch(noop),\n loadingTimeout,\n );\n\n try {\n return await baseRequest(isStaleRevalidation);\n } finally {\n clearTimeout(timer);\n }\n }\n : baseRequest;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n request,\n fetcherConfig,\n );\n\n // Avoid unnecessary function wrapping if polling is not enabled\n const doRequestPromise = pollingInterval\n ? withPolling(\n requestWithErrorHandling,\n pollingInterval,\n fetcherConfig.shouldStopPolling,\n fetcherConfig.maxPollingAttempts,\n fetcherConfig.pollingDelay,\n fetcherConfig.refreshWhenHidden,\n fetcherConfig.refreshWhenOffline,\n userSignal,\n )\n : requestWithErrorHandling();\n\n // If deduplication is enabled, store the in-flight promise immediately\n if (_cacheKey) {\n if (dedupeTime) {\n setInFlightPromise(_cacheKey, doRequestPromise);\n }\n\n // Only register revalidator when revalidation features are actually requested\n if (staleTime || refetchOnFocus || refetchOnReconnect) {\n addRevalidator(\n _cacheKey,\n requestWithErrorHandling,\n undefined,\n staleTime,\n requestWithErrorHandling,\n !!refetchOnFocus,\n !!refetchOnReconnect,\n fetcherConfig.focusThrottleInterval,\n );\n }\n }\n\n return doRequestPromise;\n}\n\n/**\n * Recreates a response from its copy in a cache store.\n * The data was transformed before it was stored, so it isn't transformed again.\n *\n * @param stored - The stored copy of the response.\n * @param cacheKey - The cache key of the request.\n * @param config - The request configuration.\n * @returns The response, or null if the stored copy is invalid, e.g. has an unknown status.\n */\nfunction toResponse(\n stored: StoredResponse,\n cacheKey: string,\n config: RequestConfig,\n): FetchResponse | null {\n try {\n // Without the Fetch API (e.g. with a custom fetcher in tests), a plain response object is used\n const response = (typeof Response === FUNCTION\n ? new Response(null, stored)\n : {\n ok: true,\n status: stored.status,\n statusText: stored.statusText,\n headers: stored.headers,\n }) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n response.data = stored.data as typeof response.data;\n config.cacheKey = cacheKey;\n\n const output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, {\n ...config,\n select: undefined,\n flattenResponse: false,\n defaultResponse: undefined,\n });\n\n output.config = config;\n\n return output;\n } catch {\n return null;\n }\n}\n\n/**\n * Asks the server whether a cached response is still valid, by sending its ETag in the If-None-Match header.\n * Then the server can answer 304 Not Modified instead of sending the response again.\n * Requests with an If-None-Match header of their own are sent as they are.\n *\n * @param config - The request configuration.\n * @param cached - The cached response of the request, if any.\n * @returns A copy of the configuration with the If-None-Match header, or the configuration itself if the cached response has no ETag.\n */\nfunction withETag(\n config: RequestConfig,\n cached: FetchResponse | null | false,\n): RequestConfig {\n const etag = cached && !cached.error && cached.headers && cached.headers.etag;\n const headers = etag && processHeaders(config.headers as HeadersObject);\n\n return headers && !headers['if-none-match']\n ? { ...config, headers: { ...headers, 'if-none-match': etag } }\n : config;\n}\n","import type {\n ApiHandlerConfig,\n ApiHandlerDefaultMethods,\n ApiHandlerMethods,\n RequestConfigUrlRequired,\n} from './types/api-handler';\nimport { fetchf } from '.';\nimport { mergeConfigs } from './config-handler';\nimport { hasOwn } from './utils';\n\n/**\n * Creates an instance of API Handler.\n * It creates an API fetcher function using native fetch() or a custom fetcher if passed as \"fetcher\".\n * @see https://github.com/MattCCC/fetchff#configuration\n *\n * @param {Object} config - Configuration object for the API fetcher (see link above for full options).\n * @param {Object} config.endpoints - An object containing endpoint definitions.\n * @param {string} [config.baseURL] - The base URL for the API.\n * @param {Object} [config.headers] - Optional default headers to include in every request.\n * @param {Function} [config.onError] - Optional callback function for handling errors.\n * @returns API handler functions and endpoints to call\n *\n * @example\n * // Define endpoint paths\n * const endpoints = {\n * getUser: '/user',\n * createPost: '/post',\n * };\n *\n * // Create the API fetcher with configuration\n * const api = createApiFetcher({\n * endpoints,\n * apiUrl: 'https://example.com/api',\n * onError(error) {\n * console.log('Request failed', error);\n * },\n * headers: {\n * 'my-auth-key': 'example-auth-key-32rjjfa',\n * },\n * });\n *\n * // Fetch user data\n * const response = await api.getUser({ userId: 1, ratings: [1, 2] })\n */\nfunction createApiFetcher<\n EndpointTypes extends object,\n EndpointsSettings = never,\n>(config: ApiHandlerConfig) {\n const endpoints = config.endpoints;\n\n /**\n * Triggered when trying to use non-existent endpoints\n *\n * @param endpointName Endpoint Name\n * @returns {Promise}\n */\n async function handleNonImplemented(endpointName: string): Promise {\n console.error('Add ' + endpointName + \" to 'endpoints'.\");\n\n return null;\n }\n\n const apiHandler: ApiHandlerDefaultMethods = {\n config,\n endpoints,\n /**\n * Handle Single API Request\n * It considers settings in following order: per-request settings, global per-endpoint settings, global settings.\n *\n * @param endpointName - The name of the API endpoint to call.\n * @param requestConfig - Additional configuration for the request.\n * @returns A promise that resolves with the response from the API provider.\n */\n async request(endpointName, requestConfig = {}) {\n // Use global and per-endpoint settings\n // Only own properties are endpoints, not ones inherited like \"constructor\"\n const endpointConfig = hasOwn(endpoints, endpointName as string)\n ? endpoints[endpointName]\n : undefined;\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // URL parsers ignore leading control characters and spaces, drop tabs and newlines,\n // and treat backslashes like slashes, so check the URL the way it will be resolved\n const resolvedUrl = url\n .replace(/[\\t\\n\\r]/g, '')\n // eslint-disable-next-line no-control-regex -- matching control characters is the point\n .replace(/^[\\x00-\\x20]+/, '');\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (/^[/\\\\]{2}/.test(resolvedUrl)) {\n throw new Error('Protocol-relative URLs not allowed.');\n }\n\n // Prevent potential Server-Side Request Forgery attack and leakage of credentials when same instance is used for external requests\n // Any scheme counts here, as e.g. \"http:\\\\host\" or \"http:host\" can also point to another host\n const mergedConfig = /^[a-z][a-z\\d+\\-.]*:/i.test(resolvedUrl)\n ? // Merge endpoints configs for absolute URLs only if urls match\n endpointConfig && endpointConfig.url === url\n ? mergeConfigs(_endpointConfig, requestConfig)\n : requestConfig\n : mergeConfigs(mergeConfigs(config, _endpointConfig), requestConfig);\n\n // We prevent potential Server-Side Request Forgery attack and leakage of credentials as the same instance is not used for external requests\n // Retrigger fetch to ensure completely new instance of handler being triggered for external URLs\n return fetchf(url, mergedConfig);\n },\n };\n\n /**\n * Maps all API requests using native Proxy\n *\n * @param {*} prop Caller\n */\n return new Proxy>(\n apiHandler as ApiHandlerMethods,\n {\n get(_target, prop: string | symbol) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Symbols (e.g. inspection hooks) are never endpoints, and returning a function\n // for \"then\" would make the instance a thenable that never settles when awaited\n if (typeof prop === 'symbol' || prop === 'then') {\n return undefined;\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (hasOwn(endpoints, prop)) {\n return apiHandler.request.bind(null, prop);\n }\n\n return handleNonImplemented.bind(null, prop);\n },\n },\n );\n}\n\nexport { createApiFetcher };\n"]} \ No newline at end of file +{"version":3,"sources":["../../src/constants.ts","../../src/utils.ts","../../src/interceptor-manager.ts","../../src/errors/fetch-error.ts","../../src/errors/response-error.ts","../../src/timeout-wheel.ts","../../src/inflight-manager.ts","../../src/hash.ts","../../src/revalidator-manager.ts","../../src/pubsub-manager.ts","../../src/config-handler.ts","../../src/cache-manager.ts","../../src/response-parser.ts","../../src/retry-handler.ts","../../src/polling-handler.ts","../../src/upload-progress.ts","../../src/download-progress.ts","../../src/error-handler.ts","../../src/request-handler.ts","../../src/api-handler.ts"],"names":["APPLICATION_CONTENT_TYPE","APPLICATION_JSON","CHARSET_UTF_8","CONTENT_TYPE","UNDEFINED","OBJECT","STRING","FUNCTION","ABORT_ERROR","TIMEOUT_ERROR","GET","HEAD","REJECT","MAX_DELAY_MS","MAX_DEPTH","hasOwn","o","k","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","key","sortObject","sortedObj","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","v","buildParams","prefix","depth","i","len","replaceUrlPathParams","urlPathParams","match","colonKey","braceKey","encoded","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","signal","resolve","done","timer","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","isPageHidden","isOffline","applyInterceptors","interceptors","args","merge","interceptor","FetchError","request","response","ResponseError","WHEEL_SIZE","SECOND","wheel","keyMap","position","lastTick","handleCallback","callback","result","e","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","inFlight","markInFlight","timeout","dedupeTime","isCancellable","isTimeoutEnabled","now","item","prevPromise","prevController","prevIsCancellable","controller","abortRequest","removeInFlight","setInFlightPromise","promise","getInFlightPromise","prevReq","hash","str","char","DEFAULT_TTL","revalidators","eventHandlers","customEventProviders","setEventProvider","type","provider","removeEventHandler","addEventHandler","revalidateAll","isStaleRevalidation","isThrottled","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","focusThrottleInterval","listeners","addListener","fn","set","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","merged","buildFetcherConfig","requestConfig","_a","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","separator","contentTypeValue","INTERCEPTORS","baseConfig","overrideConfig","targetConfig","mergeConfig","property","mergeInterceptors","baseInterceptor","newInterceptor","base","override","isInstance","overrides","lowerKey","existingKey","_cache","stores","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADERS","generateCacheKey","config","cacheKeyCheck","headersString","keys","cacheStr","sanitizeCacheKey","bodyString","getObjectId","objectIds","lastObjectId","id","isCacheExpired","getCacheData","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","scheduleExpiry","removeExpired","store","callStore","persistCache","status","statusText","getStoredCache","isCacheBypassed","restoreCache","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","buster","getCachedResponse","cacheKey","cacheTime","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","responseType","contentType","mimeType","trimmed","_error","prepareResponse","defaultResponse","mutatator","isNativeResponse","getMsFromHttpDate","dateString","getRetryAfterMs","extendedResponse","retryAfter","RATELIMIT_RESET","rateLimitResetAfter","rateLimitResetAt","withRetry","requestFn","retries","delay","backoff","maxDelay","retryOn","shouldRetry","jitter","methods","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryDelay","withJitter","retryAfterMs","_b","_c","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","refreshWhenHidden","refreshWhenOffline","pollingAttempt","NULL_BODY_STATUSES","FORBIDDEN_HEADERS","isStream","toProgress","loaded","total","fetchWithUploadProgress","sendWithXhr","sendStreamed","reject","xhr","abort","settle","line","index","onAbort","stream","blob","chunk","withDownloadProgress","onDownloadProgress","counted","withErrorHandling","isCancelled","logger","redactError","strategy","SENSITIVE_HEADERS","copy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","isETagEnabled","needsCacheKey","_cacheKey","initialResponse","stored","restored","toResponse","inflight","retryConfig","resetTimeout","userSignal","doRequestOnce","init","withETag","onResponse","baseRequest","_","onLoadingSlow","loadingTimeout","requestWithErrorHandling","doRequestPromise","etag","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","resolvedUrl","mergedConfig","_target","prop"],"mappings":"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","file":"index.mjs","sourcesContent":["export const APPLICATION_CONTENT_TYPE = 'application/';\n\nexport const APPLICATION_JSON = APPLICATION_CONTENT_TYPE + 'json';\nexport const CHARSET_UTF_8 = 'charset=utf-8';\nexport const CONTENT_TYPE = 'Content-Type';\n\nexport const UNDEFINED = 'undefined';\nexport const OBJECT = 'object';\nexport const STRING = 'string';\nexport const FUNCTION = 'function';\n\nexport const ABORT_ERROR = 'AbortError';\nexport const TIMEOUT_ERROR = 'TimeoutError';\n\nexport const GET = 'GET';\nexport const HEAD = 'HEAD';\n\nexport const REJECT = 'reject';\n\n// Larger timer delays overflow and fire immediately in browsers and Node.js (~24.8 days)\nexport const MAX_DELAY_MS = 2147483647;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, MAX_DELAY_MS, OBJECT, STRING, UNDEFINED } from './constants';\nimport type {\n DefaultUrlParams,\n HeadersObject,\n QueryParams,\n UrlPathParams,\n} from './types';\n\n// Prevent stack overflow with recursion depth limit\nconst MAX_DEPTH = 10;\n\nexport const hasOwn = (o: any, k: string) =>\n Object.prototype.hasOwnProperty.call(o, k);\n\nexport function isSearchParams(data: unknown): boolean {\n return data instanceof URLSearchParams;\n}\n\n/**\n * Determines if a value is a non-null object.\n *\n * @param {any} value - The value to check.\n * @returns {boolean} - True if the value is a non-null object.\n */\nexport function isObject(value: any): value is Record {\n return value !== null && typeof value === OBJECT;\n}\n\n/**\n * Shallowly serializes an object by converting its key-value pairs into a string representation.\n * This function does not recursively serialize nested objects.\n *\n * @param obj - The object to serialize.\n * @returns A string representation of the object's top-level properties.\n */\nexport function shallowSerialize(obj: Record): string {\n let result = '';\n\n for (const key in obj) {\n if (hasOwn(obj, key)) {\n result += key + ':' + obj[key];\n }\n }\n\n return result;\n}\n\n/**\n * Removes properties that could lead to prototype pollution from an object.\n *\n * This function checks for dangerous properties like '__proto__', 'constructor',\n * and 'prototype'. If none are present, the object is returned as-is (zero-copy fast path).\n * Otherwise, a shallow copy is created with the dangerous properties removed.\n *\n * @param obj - The object to sanitize\n * @returns A safe object without dangerous properties\n */\nexport function sanitizeObject>(obj: T): T {\n const hasProto = hasOwn(obj, '__proto__');\n const hasCtor = hasOwn(obj, 'constructor');\n const hasPrototype = hasOwn(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n // Copy key by key, as a spread compiled to assignments would let \"__proto__\" set the prototype\n const safeObj = {} as Record;\n\n for (const key of Object.keys(obj)) {\n if (key !== '__proto__' && key !== 'constructor' && key !== 'prototype') {\n safeObj[key] = obj[key];\n }\n }\n\n return safeObj as T;\n}\n\n/**\n * Sorts the keys of an object and returns a new object with sorted keys.\n *\n * This function is optimized for performance by minimizing the number of object operations\n * and using a single pass to create the sorted object.\n *\n * @param {Object} obj - The object to be sorted by keys.\n * @returns {Object} - A new object with keys sorted in ascending order.\n */\nexport function sortObject(obj: Record): object {\n // Without a prototype, a \"__proto__\" key is kept as a regular property instead of setting the prototype\n const sortedObj = Object.create(null) as Record;\n\n Object.keys(obj)\n .sort()\n .forEach((k) => (sortedObj[k] = obj[k]));\n\n return sortedObj;\n}\n\n/**\n * Appends a query string to a URL, ensuring proper handling of existing query parameters.\n *\n * @param baseUrl - The base URL to which the query string will be appended.\n * @param queryString - The encoded query string to append.\n * @returns The URL with the appended query string, or the original URL if no query string is provided.\n */\nfunction appendQueryStringToUrl(baseUrl: string, queryString: string): string {\n if (!queryString) {\n return baseUrl;\n }\n\n return baseUrl + (baseUrl.includes('?') ? '&' : '?') + queryString;\n}\n\n/**\n * Appends query parameters to a given URL.\n *\n * @param {string} url - The base URL to which query parameters will be appended.\n * @param {QueryParams} params - An object containing the query parameters to append.\n * @returns {string} - The URL with the appended query parameters.\n */\nexport function appendQueryParams(url: string, params: QueryParams): string {\n if (!params) {\n return url;\n }\n\n // Check if `params` is an instance of URLSearchParams and bail early if it is\n if (isSearchParams(params)) {\n const encodedQueryString = params.toString();\n\n return appendQueryStringToUrl(url, encodedQueryString);\n }\n\n // This is exact copy of what JQ used to do. It works much better than URLSearchParams\n const s: string[] = [];\n const encode = encodeURIComponent;\n const add = (k: string, v: any) => {\n v = typeof v === FUNCTION ? v() : v;\n v = v === null || v === undefined ? '' : v;\n s[s.length] = encode(k) + '=' + encode(v);\n };\n\n const buildParams = (prefix: string, obj: any, depth = 0) => {\n // Stop recursion if maximum depth is reached\n if (depth >= MAX_DEPTH) {\n return s;\n }\n\n let i: number, len: number, key: string;\n\n if (prefix) {\n if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n buildParams(\n prefix + '[' + (typeof obj[i] === OBJECT && obj[i] ? i : '') + ']',\n obj[i],\n depth + 1,\n );\n }\n } else if (isObject(obj)) {\n for (key in obj) {\n buildParams(prefix + '[' + key + ']', obj[key], depth + 1);\n }\n } else {\n add(prefix, obj);\n }\n } else if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n add(obj[i].name, obj[i].value);\n }\n } else {\n for (key in obj) {\n buildParams(key, obj[key], depth + 1);\n }\n }\n return s;\n };\n\n const queryStringParts = buildParams('', params).join('&');\n\n // Encode special characters as per RFC 3986, https://datatracker.ietf.org/doc/html/rfc3986\n // This is for compatibility with server frameworks that expect the literal notation\n const encodedQueryString = queryStringParts.replace(/%5B%5D/g, '[]'); // Keep '[]' for arrays\n\n return appendQueryStringToUrl(url, encodedQueryString);\n}\n\n/**\n * Replaces dynamic URI parameters in a URL string with values from the provided `urlPathParams` object.\n * Parameters in the URL are denoted by `:` or `{}` (like in OpenAPI paths), where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:` or `{}`.\n * @param {Object} urlPathParams - An object containing the parameter values to replace placeholders.\n * @param {string} urlPathParams.paramName - The value to replace the placeholder `:` in the URL.\n * @returns {string} - The URL string with placeholders replaced by corresponding values from `urlPathParams`.\n */\nexport function replaceUrlPathParams(\n url: string,\n urlPathParams: UrlPathParams,\n): string {\n if (!urlPathParams || (url.indexOf(':') === -1 && url.indexOf('{') === -1)) {\n return url;\n }\n\n // Use a single RegExp and avoid unnecessary casts and function calls\n // Precompute keys for faster lookup\n const params = urlPathParams as DefaultUrlParams;\n\n // Use a replacer function that avoids extra work\n return url.replace(/:(\\w+)|\\{(\\w+)\\}/g, (match, colonKey, braceKey) => {\n const key = colonKey || braceKey;\n\n // Use hasOwnProperty for strict key existence check\n if (hasOwn(params, key)) {\n const value = params[key];\n\n // Only replace if value is not undefined or null\n if (value !== undefined && value !== null) {\n const encoded = encodeURIComponent(String(value));\n\n // These can't be encoded, and URL parsers would move the request to another path\n if (encoded === '.' || encoded === '..') {\n throw new Error('Path params \".\" and \"..\" not allowed.');\n }\n\n return encoded;\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL starts with a scheme (e.g., \"http://\", \"https://\").\n * A \"://\" appearing later, e.g. in a query string, does not make the URL absolute.\n *\n * @param url - The URL string to check.\n * @returns `true` if the URL is absolute, otherwise `false`.\n */\nexport function isAbsoluteUrl(url: string): boolean {\n return /^[a-z][a-z\\d+\\-.]*:\\/\\//i.test(url);\n}\n\nexport const timeNow = () => Date.now();\n\nexport const noop = () => {};\n\n/**\n * Checks if a value is JSON serializable.\n *\n * JSON serializable values include:\n * - Primitive types: string, number, boolean, null\n * - Arrays\n * - Plain objects (i.e., objects without special methods)\n * - Values with a `toJSON` method\n *\n * @param {any} value - The value to check for JSON serializability.\n * @returns {boolean} - Returns `true` if the value is JSON serializable, otherwise `false`.\n */\nexport function isJSONSerializable(value: any): boolean {\n const t = typeof value;\n\n if (value === undefined || value === null) {\n return false;\n }\n\n if (t === STRING || t === 'number' || t === 'boolean') {\n return true;\n }\n\n if (Array.isArray(value)) {\n return true;\n }\n\n if (\n typeof globalThis !== UNDEFINED &&\n typeof globalThis.Buffer !== UNDEFINED &&\n globalThis.Buffer.isBuffer(value)\n ) {\n return false;\n }\n\n if (value instanceof Date || isSearchParams(value)) {\n return false;\n }\n\n if (isObject(value)) {\n const proto = Object.getPrototypeOf(value);\n\n // Check if the prototype is `Object.prototype` (plain object)\n if (proto === Object.prototype) {\n return true;\n }\n\n // Check if the object has a toJSON method\n if (typeof value.toJSON === FUNCTION) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Waits for the given time. When a signal is passed, the wait ends early once it is aborted.\n *\n * @param {number} ms - The time to wait in milliseconds.\n * @param {AbortSignal} [signal] - An optional signal that ends the wait when aborted.\n * @returns {Promise} - A promise that resolves with `true` once the wait is over.\n */\nexport const delayInvocation = (\n ms: number,\n signal?: AbortSignal,\n): Promise =>\n new Promise((resolve) => {\n const done = () => {\n clearTimeout(timer);\n if (signal) {\n signal.removeEventListener('abort', done);\n }\n resolve(true);\n };\n const timer = setTimeout(done, Math.min(ms, MAX_DELAY_MS));\n\n if (signal) {\n if (signal.aborted) {\n done();\n } else {\n signal.addEventListener('abort', done);\n }\n }\n });\n\n/**\n * Recursively flattens the data object if it meets specific criteria.\n *\n * The method checks if the provided `data` is an object with exactly one property named `data`.\n * If so, it recursively flattens the `data` property. Otherwise, it returns the `data` as-is.\n *\n * @param {any} data - The data to be flattened. Can be of any type, including objects, arrays, or primitives.\n * @returns {any} - The flattened data if the criteria are met; otherwise, the original `data`.\n */\nexport function flattenData(data: any, depth = 0): any {\n if (depth >= MAX_DEPTH) {\n return data;\n }\n\n if (data && isObject(data) && typeof data.data !== UNDEFINED) {\n return flattenData(data.data, depth + 1);\n }\n\n return data;\n}\n\n/**\n * Processes headers and returns them as a normalized object.\n *\n * Handles both `Headers` instances and plain objects. Normalizes header keys to lowercase\n * as per RFC 2616 section 4.2.\n *\n * @param headers - The headers to process. Can be an instance of `Headers`, a plain object,\n * or `null`. If `null`, an empty object is returned.\n * @returns {HeadersObject} - A normalized headers object with lowercase keys.\n */\nexport function processHeaders(\n headers?: (HeadersObject & HeadersInit) | null | Headers,\n): HeadersObject {\n if (!headers) {\n return {};\n }\n\n const headersObject: HeadersObject = {};\n\n // Normalize keys to lowercase as per RFC 2616 4.2\n // https://datatracker.ietf.org/doc/html/rfc2616#section-4.2\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n headersObject[key.toLowerCase()] = value;\n });\n } else {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n // Assigning \"__proto__\" would set the prototype of the result\n if (hasOwn(headers, key) && key !== '__proto__') {\n headersObject[key.toLowerCase()] = headers[key];\n }\n }\n }\n\n return headersObject;\n}\n\n/**\n * Determines if the current environment is a browser.\n *\n * @returns {boolean} - True if running in a browser environment, false otherwise.\n */\nexport function isBrowser(): boolean {\n // For node and some mobile frameworks like React Native, `add/removeEventListener` doesn't exist on window!\n return (\n typeof window !== UNDEFINED && typeof window.addEventListener === FUNCTION\n );\n}\n\n/**\n * Creates an abort/timeout error compatible with all JS runtimes.\n * Falls back to a plain Error with the correct `name` when DOMException is unavailable (e.g. React Native).\n *\n * @param {string} message - The error message.\n * @param {string} name - The error name (e.g. 'AbortError', 'TimeoutError').\n * @returns {DOMException | Error} - An error object with the specified name.\n */\nexport function createAbortError(\n message: string,\n name: string,\n): DOMException | Error {\n if (typeof DOMException !== UNDEFINED) {\n return new DOMException(message, name);\n }\n\n const error = new Error(message);\n error.name = name;\n\n return error;\n}\n\n/**\n * Detects if the user is on a slow network connection\n * @returns {boolean} True if connection is slow, false otherwise or if detection unavailable\n */\nexport const isSlowConnection = (): boolean => {\n const conn = typeof navigator !== UNDEFINED && (navigator as any).connection;\n\n return conn && ['slow-2g', '2g', '3g'].includes(conn.effectiveType);\n};\n\n/**\n * Detects if the page is hidden, e.g. when its tab is in the background or the window is minimized\n * @returns {boolean} True if the page is hidden, false otherwise or outside browsers\n */\nexport const isPageHidden = (): boolean =>\n typeof document !== UNDEFINED && document.visibilityState === 'hidden';\n\n/**\n * Detects if the browser is offline\n * @returns {boolean} True if the browser is offline, false otherwise or if the connection state is unknown\n */\nexport const isOffline = (): boolean =>\n typeof navigator !== UNDEFINED && navigator.onLine === false;\n","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject, sanitizeObject } from './utils';\n\n/**\n * Applies interceptors to the object. Interceptors can be a single function or an array of functions.\n *\n * @template T - Type of the object.\n * @template Args - Type of additional arguments.\n * @template I - Type of interceptors.\n *\n * @param {InterceptorFunction | InterceptorFunction[]} [interceptors] - Interceptor function(s).\n * @param {T} data - The data object to process.\n * @param {...Args} args - Additional arguments to pass to interceptors.\n *\n * @returns {Promise} - Nothing as the function is non-idempotent.\n */\nexport async function applyInterceptors<\n T extends object,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Args extends any[] = any[],\n I = InterceptorFunction | InterceptorFunction[],\n>(interceptors: I | undefined, data: T, ...args: Args): Promise {\n if (!interceptors) {\n return;\n }\n\n const merge = (v: unknown) =>\n v &&\n isObject(data) &&\n isObject(v) &&\n Object.assign(data, sanitizeObject(v));\n\n if (typeof interceptors === FUNCTION) {\n merge(await (interceptors as InterceptorFunction)(data, ...args));\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n merge(await interceptor(data, ...args));\n }\n }\n}\n","import type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\n/**\n * This is a base error class\n */\nexport class FetchError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends Error {\n // Declared only, and set in the constructor, as class fields would need a helper in the ES2018 bundle\n declare status: number;\n declare statusText: string;\n declare config: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare isCancelled: boolean;\n declare request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null;\n\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.request = request;\n this.response = response;\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\n this.name = 'FetchError';\n }\n}\n","import { FetchError } from './fetch-error';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\nexport class ResponseError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends FetchError {\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message, request, response);\n\n this.name = 'ResponseError';\n }\n}\n","/**\n * @module timeout-wheel\n * @description\n * Ultra-minimal timing wheel implementation optimized for max performance & many requests.\n * For most of the cases it's 4-100x faster than setTimeout and setInterval alone.\n * Provides efficient scheduling and cancellation of timeouts using a circular array.\n *\n * Position 0 → 1 → 2 → ... → 599 → 0 → 1 → 2 ...\n * Time: 0s 1s 2s 599s 600s 601s 602s\n *\n * The timing wheel consists of 600 slots (one per second for 10 min).\n * Each slot contains a list of timeout items, each associated with a unique key and callback.\n * Timeouts are scheduled by placing them in the appropriate slot based on the delay in seconds.\n * The wheel advances every second, executing and removing callbacks as their timeouts expire.\n * Defaults to setTimeout if the delay doesn't fit in the wheel (~10 minutes) or is not divisible by 1000.\n *\n * @remarks\n * - Designed for minimal footprint and simplicity.\n * - Only supports second-level granularity (minimum timeout: 1 second).\n * - Timeouts never fire early, but may fire up to 1 second late.\n * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { MAX_DELAY_MS } from './constants';\nimport { noop, timeNow } from './utils';\n\ntype TimeoutCallback = () => unknown | Promise;\ntype TimeoutItem = [string, TimeoutCallback]; // [key, callback]\n\nconst WHEEL_SIZE = 600; // 600 slots for 10 min (1 slot per second)\nconst SECOND = 1000; // 1 second in milliseconds\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\nlet lastTick = 0; // Time when the wheel last advanced (or started)\nlet timer: NodeJS.Timeout | null = null;\n\nconst handleCallback = ([key, callback]: TimeoutItem): void => {\n keyMap.delete(key);\n\n try {\n const result = callback();\n if (result && result instanceof Promise) {\n // Silently ignore async errors to prevent wheel from stopping\n result.catch(noop);\n }\n } catch {\n // Ignore callback errors to prevent wheel from stopping\n }\n};\n\nexport const addTimeout = (\n key: string,\n cb: TimeoutCallback,\n ms: number,\n): void => {\n removeTimeout(key);\n\n // A running wheel is already part-way through its current second, so the timeout\n // waits one more slot to never fire early. A new wheel starts its first second now.\n const seconds = ms / SECOND + (timer && timeNow() !== lastTick ? 1 : 0);\n\n // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || seconds >= WHEEL_SIZE || ms % SECOND !== 0) {\n keyMap.set(key, [\n setTimeout(\n handleCallback.bind(null, [key, cb]),\n Math.min(ms, MAX_DELAY_MS),\n ),\n ]); // Store timeout ID instead of slot\n\n return;\n }\n\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n lastTick = timeNow();\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\n lastTick = timeNow();\n const slot = wheel[position];\n\n // Use slot.length directly (not cached) so mid-iteration mutations\n // from callbacks (e.g. removeTimeout) are handled correctly\n for (let i = 0; i < slot.length; i++) {\n handleCallback(slot[i]);\n }\n\n slot.length = 0; // Reuse array, avoid GC allocation\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }, SECOND);\n }\n};\n\nexport const removeTimeout = (key: string): void => {\n const slotOrTimeout = keyMap.get(key);\n\n if (slotOrTimeout !== undefined) {\n // It's a Timeout object from setTimeout\n if (Array.isArray(slotOrTimeout)) {\n clearTimeout(slotOrTimeout[0]);\n } else {\n const slotArr = wheel[slotOrTimeout];\n\n for (let i = 0; i < slotArr.length; i++) {\n if (slotArr[i][0] === key) {\n slotArr.splice(i, 1);\n break;\n }\n }\n }\n\n keyMap.delete(key);\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }\n};\n\nexport const clearAllTimeouts = () => {\n // Clear native setTimeout timeouts first!\n keyMap.forEach((value) => {\n if (Array.isArray(value)) {\n clearTimeout(value[0]);\n }\n });\n\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n\n keyMap.clear();\n\n for (let i = 0; i < WHEEL_SIZE; i++) {\n wheel[i].length = 0;\n }\n\n position = 0;\n};\n","/**\n * @module inflight-manager\n *\n * Manages in-flight asynchronous requests using unique keys to enable deduplication and cancellation.\n *\n * Provides utilities for:\n * - Deduplication of requests within a configurable time window (`dedupeTime`)\n * - Timeout management and automatic request abortion\n * - AbortController lifecycle and cancellation logic\n * - Concurrency control and request state tracking\n * - In-flight promise deduplication to prevent duplicate network calls\n *\n * @remarks\n * - Requests with the same key within the deduplication interval share the same AbortController and in-flight promise.\n * - Supports cancellation of previous requests when a new one with the same key is issued, if `isCancellable` is enabled.\n * - Timeout logic ensures requests are aborted after a specified duration, if enabled.\n * - Internal queue state is managed via a Map, keyed by request identifier.\n * - Polled requests are also marked as \"in-flight\" to prevent duplicate requests.\n */\n\nimport { ABORT_ERROR, TIMEOUT_ERROR } from './constants';\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { createAbortError, timeNow } from './utils';\n\nexport type InFlightItem = [\n AbortController, // AbortController for the request\n boolean, // Whether timeout is enabled for the request\n number, // Timestamp when the request was marked in-flight\n boolean, // isCancellable - whether the request can be cancelled\n Promise | null, // Optional in-flight promise for deduplication\n];\n\nconst inFlight: Map = new Map();\n\n/**\n * Adds a request to the queue if it's not already being processed within the dedupeTime interval.\n *\n * @param {string | null} key - Unique key for the request (e.g. cache key).\n * @param {string} url - The request URL (for error messages/timeouts).\n * @param {number} timeout - Timeout in milliseconds for the request.\n * @param {number} dedupeTime - Deduplication time in milliseconds.\n * @param {boolean} isCancellable - If true, then the previous request with same configuration should be aborted.\n * @param {boolean} isTimeoutEnabled - Whether timeout is enabled.\n * @returns {AbortController} - A promise that resolves to an AbortController.\n */\nexport function markInFlight(\n key: string | null,\n url: string,\n timeout: number | undefined,\n dedupeTime: number,\n isCancellable: boolean,\n isTimeoutEnabled: boolean,\n): AbortController {\n if (!key) {\n return new AbortController();\n }\n\n const now = timeNow();\n const item = inFlight.get(key);\n let prevPromise: Promise | null = null;\n\n // Previous request is in-flight, check if we can reuse it\n if (item) {\n const prevController = item[0];\n const prevIsCancellable = item[3];\n\n // If the request is already in the queue and within the dedupeTime, reuse the existing controller\n if (\n !prevIsCancellable &&\n now - item[2] < dedupeTime &&\n !prevController.signal.aborted\n ) {\n return prevController;\n }\n\n // If the request is too old, remove it and proceed to add a new one\n // Abort previous request, if applicable, and continue as usual\n if (prevIsCancellable) {\n prevController.abort(\n createAbortError('Aborted due to new request', ABORT_ERROR),\n );\n }\n\n removeTimeout(key);\n prevPromise = item[4];\n }\n\n const controller = new AbortController();\n\n inFlight.set(key, [\n controller,\n isTimeoutEnabled,\n now,\n isCancellable,\n prevPromise,\n ]);\n\n if (isTimeoutEnabled) {\n addTimeout(\n key,\n () => {\n abortRequest(\n key,\n createAbortError(url + ' aborted due to timeout', TIMEOUT_ERROR),\n );\n },\n timeout as number,\n );\n }\n\n return controller;\n}\n\n/**\n * Removes a request from the queue and clears its timeout.\n *\n * @param key - Unique key for the request.\n * @param {boolean} error - Optional error to abort the request with. If null, the request is simply removed but no abort sent.\n * @returns {Promise} - A promise that resolves when the request is aborted and removed.\n */\nexport async function abortRequest(\n key: string | null,\n error: DOMException | Error | null | string = null,\n): Promise {\n // If the key is not in the queue, there's nothing to remove\n if (key) {\n const item = inFlight.get(key);\n\n if (item) {\n // If the request is not yet aborted, abort it with the provided error\n if (error) {\n const controller = item[0];\n controller.abort(error);\n }\n\n removeInFlight(key);\n }\n }\n}\n\n/**\n * Removes a request from the in-flight queue without aborting or clearing timeout.\n *\n * @param key - Unique key for the request.\n */\nexport function removeInFlight(key: string | null): void {\n removeTimeout(key!);\n inFlight.delete(key!);\n}\n\n/**\n * Gets the AbortController for a request key.\n *\n * @param key - Unique key for the request.\n * @returns {AbortController | undefined} - The AbortController or undefined.\n */\nexport async function getController(\n key: string,\n): Promise {\n const item = inFlight.get(key);\n\n return item && item[0];\n}\n\n/**\n * Adds helpers for in-flight promise deduplication.\n *\n * @param key - Unique key for the request.\n * @param promise - The promise to store.\n */\nexport function setInFlightPromise(\n key: string,\n promise: Promise,\n): void {\n const item = inFlight.get(key);\n if (item) {\n // store the promise at index 4 — item is already the Map's reference, no need to re-set\n item[4] = promise;\n }\n}\n\n/**\n * Retrieves the in-flight promise for a request key if it exists and is within the dedupeTime interval.\n *\n * @param key - Unique key for the request.\n * @param dedupeTime - Deduplication time in milliseconds.\n * @returns {Promise | null} - The in-flight promise or null.\n */\nexport function getInFlightPromise(\n key: string | null,\n dedupeTime: number,\n): Promise | null {\n if (!key) {\n return null;\n }\n\n const prevReq = inFlight.get(key);\n\n if (\n prevReq &&\n // If the request is in-flight and has a promise\n prevReq[4] &&\n // If the request is cancellable, we will not reuse it\n !prevReq[3] &&\n // If the request is within the dedupeTime\n timeNow() - prevReq[2] < dedupeTime &&\n // If one request is cancelled, ALL deduped requests get cancelled\n !prevReq[0].signal.aborted\n ) {\n return prevReq[4] as Promise;\n }\n\n return null;\n}\n","const PRIME_MULTIPLIER = 31;\n\n/**\n * Computes a hash value for a given string using the variant of djb2 hash function.\n * This hash function is non-cryptographic and designed for speed.\n * @author Daniel J. Bernstein (of djb2)\n *\n * @param str Input string to hash\n * @returns {string} Hash\n */\nexport function hash(str: string): string {\n let hash = 0;\n\n for (let i = 0, len = str.length; i < len; i++) {\n const char = str.charCodeAt(i);\n hash = (hash * PRIME_MULTIPLIER + char) | 0;\n }\n\n return String(hash);\n}\n","/**\n * @module revalidator-manager\n *\n * Provides utilities for managing cache revalidation functions, including:\n * - Registering and unregistering revalidators for specific cache keys.\n * - Triggering revalidation for a given key.\n * - Enabling or disabling automatic revalidation on window focus and if user comes back online for specific keys.\n * - Attaching and removing global focus and online event handlers to trigger revalidation.\n *\n * Revalidators are functions that can be registered to revalidate cache entries when needed.\n * They are typically used to refresh data in the cache when the window gains focus or when specific actions occur.\n * @performance O(1) lookup by key makes it blazing fast to register, unregister, and revalidate cache entries.\n * - Designed for high performance: minimizes unnecessary re-renders and leverages fast cache key generation.\n * - Integrates with a global cache and pub/sub system for efficient state updates across contexts.\n * - Handles automatic revalidation, deduplication, retries, and cache management out of the box.\n * @remarks\n * - Designed to be used in various environments (Deno, Node.js, Bun, Browser, etc.) to ensure cache consistency and freshness.\n */\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { FetchResponse } from './types';\nimport { isBrowser, noop, timeNow } from './utils';\n\nexport type RevalidatorFn = (\n isStaleRevalidation?: boolean,\n) => Promise;\n\ntype EventType = 'focus' | 'online';\n\ntype RevalidatorEntry = [\n RevalidatorFn, // main revalidator\n number, // lastUsed\n number, // ttl\n number?, // staleTime\n RevalidatorFn?, // bgRevalidator\n boolean?, // refetchOnFocus\n boolean?, // refetchOnReconnect\n number?, // focusThrottleInterval\n];\n\nconst DEFAULT_TTL = 3 * 60 * 1000; // Default TTL of 3 minutes\nconst revalidators = new Map();\n\n/**\n * Stores cleanup functions for active event handlers (browser or custom providers).\n * Each entry removes the corresponding event listener when called.\n * @remarks\n * - Improves performance by reducing the number of event listeners.\n * - Enables efficient O(1) lookup and management of event handlers for revalidation.\n */\nconst eventHandlers = new Map void>();\n\n/** Subscribe to an event and return a cleanup function */\nexport type EventProvider = (handler: () => void) => () => void;\n\nconst customEventProviders = new Map();\n\n/**\n * Registers a custom event provider for 'focus' or 'online' events.\n * Useful for non-browser environments like React Native.\n *\n * @param type - The event type ('focus' or 'online').\n * @param provider - A function that subscribes to the event and returns a cleanup function.\n */\nexport function setEventProvider(\n type: EventType,\n provider: EventProvider,\n): void {\n customEventProviders.set(type, provider);\n\n // Re-register if already active\n if (eventHandlers.has(type)) {\n removeEventHandler(type);\n addEventHandler(type);\n }\n}\n\n/**\n * Triggers revalidation for all registered entries based on the given event type.\n * For example, if it's a 'focus' event, it will revalidate entries that have the `refetchOnFocus` flag set.\n * Updates the timestamp and invokes the revalidator function for each applicable entry.\n *\n * @param type - The type of event that caused the revalidation (e.g., 'focus' or 'online').\n * @param isStaleRevalidation - If `true`, uses background revalidator and doesn't mark as in-flight.\n * @param isThrottled - If `true`, skips entries that were requested or revalidated within their `focusThrottleInterval`.\n */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n isThrottled: boolean = false,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex] || (isThrottled && now - entry[1] < entry[7]!)) {\n return;\n }\n\n entry[1] = now;\n\n // If it's a stale revalidation, use the background revalidator function\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n if (revalidator) {\n Promise.resolve(revalidator(isStaleRevalidation)).catch(noop);\n }\n });\n}\n\n/**\n * Revalidates an entry by executing the registered revalidation function.\n *\n * @param key The unique identifier for the cache entry to revalidate. If `null`, no revalidation occurs.\n * @param isStaleRevalidation - If `true`, it does not mark revalidated requests as in-flight.\n * @returns A promise that resolves to the result of the revalidator function, or\n * `null` if no key or revalidator is found, or a `FetchResponse` if applicable.\n */\nexport async function revalidate(\n key: string | null,\n isStaleRevalidation: boolean = false,\n): Promise {\n // If no key is provided, no revalidation occurs\n if (!key) {\n return null;\n }\n\n const entry = revalidators.get(key);\n\n if (entry) {\n // Update only the lastUsed timestamp without resetting the whole array\n entry[1] = timeNow();\n\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n // If no revalidator function is registered, return null\n if (revalidator) {\n return await revalidator(isStaleRevalidation);\n }\n }\n\n // If no revalidator is registered for the key, return null\n return null;\n}\n\n/**\n * Removes all revalidators associated with the specified event type.\n *\n * @param type - The event type whose revalidators should be removed.\n */\nexport function removeRevalidators(type: EventType) {\n removeEventHandler(type);\n\n const flagIndex = type === 'focus' ? 5 : 6;\n\n // Clear all revalidators with this flag\n revalidators.forEach((entry, key) => {\n if (entry[flagIndex]) {\n removeRevalidator(key);\n }\n });\n}\n\n/**\n * Registers a generic revalidation event handler for the specified event type.\n * Supports browser window events and custom event providers (e.g. for React Native).\n * Ensures the handler is only added once.\n *\n * @param event - The type of event to listen for (e.g., 'focus', 'online').\n */\nfunction addEventHandler(event: EventType) {\n if (eventHandlers.has(event)) {\n return;\n }\n\n // Focus events are throttled, so that e.g. switching between tabs quickly doesn't revalidate every time\n const handler = revalidateAll.bind(null, event, true, event === 'focus');\n\n // Priority 1: Custom event provider (works in any environment including React Native)\n const customProvider = customEventProviders.get(event);\n\n if (customProvider) {\n const cleanup = customProvider(handler);\n\n eventHandlers.set(event, cleanup);\n\n return;\n }\n\n // Priority 2: Browser window events\n if (isBrowser()) {\n window.addEventListener(event, handler);\n\n eventHandlers.set(event, () => window.removeEventListener(event, handler));\n }\n}\n\n/**\n * Removes the event handler for the specified event type.\n *\n * @param event - The type of event whose handler should be removed.\n */\nfunction removeEventHandler(event: EventType) {\n const cleanup = eventHandlers.get(event);\n\n if (cleanup) {\n cleanup();\n eventHandlers.delete(event);\n }\n}\n\n/**\n * Registers a revalidation functions for a specific cache key.\n *\n * @param {string} key Cache key to utilize\n * @param {RevalidatorFn} revalidatorFn Main revalidation function (marks in-flight requests)\n * @param {number} [ttl] Time to live in milliseconds (default: 3 minutes)\n * @param {number} [staleTime] Time (in seconds) after which the cache entry is considered stale\n * @param {RevalidatorFn} [bgRevalidatorFn] For stale revalidation (does not mark in-flight requests)\n * @param {boolean} [refetchOnFocus] Whether to revalidate on window focus\n * @param {boolean} [refetchOnReconnect] Whether to revalidate on network reconnect\n * @param {number} [focusThrottleInterval] Time (in milliseconds) after a request or revalidation during which focus events don't revalidate it\n */\nexport function addRevalidator(\n key: string,\n revalidatorFn: RevalidatorFn, // Main revalidation function (marks in-flight requests)\n ttl?: number,\n staleTime?: number,\n bgRevalidatorFn?: RevalidatorFn, // For stale revalidation (does not mark in-flight requests)\n refetchOnFocus?: boolean,\n refetchOnReconnect?: boolean,\n focusThrottleInterval?: number,\n) {\n // Existing entries are updated in place\n const entry = revalidators.get(key) || ([] as unknown as RevalidatorEntry);\n\n entry[0] = revalidatorFn;\n entry[1] = timeNow();\n entry[2] = ttl ?? DEFAULT_TTL;\n entry[3] = staleTime;\n entry[4] = bgRevalidatorFn;\n entry[5] = refetchOnFocus;\n entry[6] = refetchOnReconnect;\n entry[7] = focusThrottleInterval;\n\n revalidators.set(key, entry);\n\n if (refetchOnFocus) {\n addEventHandler('focus');\n }\n\n if (refetchOnReconnect) {\n addEventHandler('online');\n }\n\n if (staleTime) {\n addTimeout('s:' + key, revalidate.bind(null, key, true), staleTime * 1000);\n }\n}\n\nexport function removeRevalidator(key: string) {\n revalidators.delete(key);\n\n // Clean up stale timer\n removeTimeout('s:' + key);\n}\n\n/**\n * Periodically cleans up expired revalidators from the registry.\n * Removes any revalidator whose TTL has expired.\n *\n * @param {number} intervalMs How often to run cleanup (default: 3 minutes)\n * @returns {() => void} A function to stop the periodic cleanup\n */\nexport function startRevalidatorCleanup(\n intervalMs: number = DEFAULT_TTL,\n): () => void {\n const intervalId = setInterval(() => {\n const now = timeNow();\n\n revalidators.forEach(\n ([, lastUsed, ttl, , , refetchOnFocus, refetchOnReconnect], key) => {\n // Skip focus-only or reconnect-only revalidators to keep them alive\n if (refetchOnFocus || refetchOnReconnect) {\n return;\n }\n\n if (ttl > 0 && now - lastUsed > ttl) {\n removeRevalidator(key);\n }\n },\n );\n }, intervalMs);\n\n return () => clearInterval(intervalId);\n}\n","/**\n * Manages a set of listeners (subscribers) for arbitrary string keys, allowing cross-context or cross-component\n * cache updates and synchronization. Provides functions to add, remove, and notify listeners, as well as a\n * convenient subscribe/unsubscribe API.\n *\n * @template T - The type of the response object passed to listeners.\n *\n * @remarks\n * - Listeners are grouped by a string key, which typically represents a cache key or resource identifier.\n * - When `notifySubscribers` is called for a key, all listeners registered for that key are invoked with the provided response.\n * - The `subscribe` function returns an unsubscribe function for convenient cleanup.\n *\n * @example\n * ```ts\n * const unsubscribe = subscribe('user:123', (response) => {\n * // handle updated data\n * });\n * // Later, to stop listening:\n * unsubscribe();\n * ```\n */\n\nimport { noop } from './utils';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Listener = (response: T) => void;\n\nconst listeners = new Map>();\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n let set = listeners.get(key);\n\n if (!set) {\n listeners.set(key, (set = new Set()));\n }\n\n set.add(fn);\n}\n\nexport function removeListener(key: string, fn: Listener) {\n const set = listeners.get(key);\n\n if (set) {\n set.delete(fn);\n\n // If the set is empty, remove the key from the listeners map\n if (set.size === 0) {\n listeners.delete(key);\n }\n }\n}\n\nexport function notifySubscribers(key: string, response: T) {\n const fns = listeners.get(key);\n\n if (fns) {\n if (fns.size === 1) {\n // If there's only one listener, call it directly\n const fn = fns.values().next().value;\n fn!(response);\n } else {\n fns.forEach((fn) => fn(response));\n }\n }\n}\n\nexport function subscribe(key: string | null, fn: (response: T) => void) {\n if (!key) {\n // No op if no key is provided\n return noop;\n }\n\n addListener(key, fn);\n\n // Return an unsubscribe function\n return () => {\n removeListener(key, fn);\n };\n}\n","import { processHeaders } from './utils';\nimport {\n GET,\n APPLICATION_JSON,\n HEAD,\n STRING,\n CHARSET_UTF_8,\n CONTENT_TYPE,\n REJECT,\n UNDEFINED,\n APPLICATION_CONTENT_TYPE,\n} from './constants';\nimport type {\n HeadersObject,\n Method,\n RequestConfig,\n} from './types/request-handler';\nimport {\n replaceUrlPathParams,\n appendQueryParams,\n isSearchParams,\n isJSONSerializable,\n isSlowConnection,\n isAbsoluteUrl,\n sanitizeObject,\n isObject,\n} from './utils';\n\nconst defaultTimeoutMs = (isSlowConnection() ? 60 : 30) * 1000;\n\nexport const defaultConfig: RequestConfig = {\n strategy: REJECT,\n timeout: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n loadingTimeout: defaultTimeoutMs / 10, // 3 seconds (6 on slow connections)\n focusThrottleInterval: 5000, // 5 seconds\n headers: {\n Accept: APPLICATION_JSON + ', text/plain, */*',\n 'Accept-Encoding': 'gzip, deflate, br',\n },\n retry: {\n delay: defaultTimeoutMs / 30, // 1 second (2 on slow connections)\n maxDelay: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n resetTimeout: true,\n backoff: 1.5,\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n retryOn: [\n 408, // Request Timeout\n 409, // Conflict\n 425, // Too Early\n 429, // Too Many Requests\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n ],\n\n // Idempotent methods, which can be repeated safely, unlike e.g. POST requests that create resources\n methods: [GET, HEAD, 'PUT', 'DELETE', 'OPTIONS', 'TRACE'],\n },\n};\n\n/**\n * Overwrites the default configuration with the provided custom configuration.\n *\n * @param {Partial} customConfig - The custom configuration to merge into the default config.\n * @returns {Partial} - The updated default configuration object.\n */\nexport function setDefaultConfig(\n customConfig: Partial,\n): Partial {\n const sanitized = sanitizeObject(customConfig);\n\n // Merge nested retry and headers settings into the current defaults instead of replacing them\n return mergeConfigs(\n { retry: defaultConfig.retry, headers: defaultConfig.headers },\n sanitized,\n defaultConfig,\n );\n}\n\n/**\n * Returns a shallow copy of the current default configuration.\n *\n * @returns {RequestConfig} - The current default configuration.\n */\nexport function getDefaultConfig(): RequestConfig {\n return { ...defaultConfig };\n}\n\n/**\n * Build request configuration from defaults and overrides.\n * This function merges the default configuration with the provided request configuration,\n * @param {string} url - Request url\n * @param {RequestConfig | null | undefined} reqConfig - Request configuration\n * @return {RequestConfig} - Merged request configuration\n */\nexport function buildConfig(\n url: string,\n reqConfig?: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null,\n): RequestConfig {\n // Merging gives the request its own copies of nested objects like headers, so that\n // mutations (e.g. by interceptors) never leak into the global defaults\n const merged = mergeConfigs(\n defaultConfig,\n reqConfig ? sanitizeObject(reqConfig) : {},\n );\n\n return buildFetcherConfig(url, merged);\n}\n\n/**\n * Builds the fetcher configuration by setting the method, body, headers, and URL.\n * It also handles query parameters and path parameters. This fn mutates the passed `requestConfig` object.\n * @param {string} url - The endpoint URL to which the request will be sent.\n * @param {RequestConfig} requestConfig - The request configuration object containing method, body, headers, and other options.\n * @return {RequestConfig} - The modified request configuration object with the URL, method, body, and headers set appropriately.\n **/\nexport function buildFetcherConfig(\n url: string,\n requestConfig: RequestConfig,\n): RequestConfig {\n let method = requestConfig.method as Method;\n method = method ? (method.toUpperCase() as Method) : GET;\n\n let body: RequestConfig['data'] | undefined;\n\n // Only applicable for request methods 'PUT', 'POST', 'DELETE', and 'PATCH'\n if (method !== GET && method !== HEAD) {\n body = requestConfig.body ?? requestConfig.data;\n\n // Automatically stringify request body, if possible and when not dealing with strings\n if (body && typeof body !== STRING && isJSONSerializable(body)) {\n body = JSON.stringify(body);\n }\n }\n\n setContentTypeIfNeeded(requestConfig.headers, body);\n\n // Native fetch compatible settings\n const credentials = requestConfig.withCredentials\n ? 'include'\n : requestConfig.credentials;\n\n // The explicitly passed query params\n const dynamicUrl = replaceUrlPathParams(url, requestConfig.urlPathParams);\n const urlPath = appendQueryParams(dynamicUrl, requestConfig.params);\n const isFullUrl = isAbsoluteUrl(url);\n const baseURL = isFullUrl\n ? ''\n : requestConfig.baseURL || requestConfig.apiUrl || '';\n\n // Join as a path, as plain concatenation could extend the host of the baseURL,\n // e.g. \"https://api.example.com\" + \".evil.com\" would point to another host\n const separator =\n baseURL && urlPath && !baseURL.endsWith('/') && !/^[/?#]/.test(urlPath)\n ? '/'\n : '';\n\n requestConfig.url = baseURL + separator + urlPath;\n requestConfig.method = method;\n requestConfig.credentials = credentials;\n requestConfig.body = body;\n\n return requestConfig;\n}\n\n/**\n * Ensures the `Content-Type` header is set to `application/json; charset=utf-8`\n * if it is not already present and the request method and body meet specific conditions.\n *\n * @param headers - The headers object to modify. Can be an instance of `Headers`\n * or a plain object conforming to `HeadersInit`.\n * @param body - The optional body of the request. If no body is provided and the\n * method is 'GET' or 'HEAD', the function exits without modifying headers.\n */\nfunction setContentTypeIfNeeded(\n headers?: HeadersInit | HeadersObject,\n body?: unknown,\n): void {\n // If no headers are provided, or if the body is not set and the method is PUT or DELETE, do nothing\n if (!headers || !body) {\n return;\n }\n\n // Types that should not have Content-Type set (browser handles these)\n if (\n body instanceof FormData || // Browser automatically sets multipart/form-data with boundary\n (typeof Blob !== UNDEFINED && body instanceof Blob) || // Blob/File (a File is a Blob) already have their own MIME types, don't override\n (typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream) // Stream type should be determined by the stream source\n ) {\n return;\n }\n\n let contentTypeValue: string;\n\n if (isSearchParams(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded';\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'octet-stream';\n } else if (isJSONSerializable(body)) {\n contentTypeValue = APPLICATION_JSON + ';' + CHARSET_UTF_8;\n } else {\n // Do not set Content-Type if content is not recognizable\n return;\n }\n\n if (headers instanceof Headers) {\n if (!headers.has(CONTENT_TYPE)) {\n headers.set(CONTENT_TYPE, contentTypeValue);\n }\n } else if (\n isObject(headers) &&\n !Array.isArray(headers) &&\n // Header names are case-insensitive, so check the normalized (lowercase) headers\n !processHeaders(headers as HeadersObject)[CONTENT_TYPE.toLowerCase()]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\n\n// The interceptors that are merged instead of replaced\nconst INTERCEPTORS = [\n 'onRequest',\n 'onResponse',\n 'onError',\n 'onLoadingSlow',\n] as const;\n\n/**\n * Merges two request configurations, applying overrides from the second config to the first.\n * Handles special merging for nested properties like 'retry' and 'headers' (deep merge),\n * and concatenates interceptor arrays for 'onRequest', 'onResponse', 'onError' and 'onLoadingSlow'.\n * If a target config is provided, it mutates that object; otherwise, creates a new one.\n *\n * @param {RequestConfig} baseConfig - The base configuration object to merge from.\n * @param {RequestConfig} overrideConfig - The override configuration object to apply on top of the base.\n * @param {RequestConfig} [targetConfig={}] - Optional target configuration object to merge into (mutated in place).\n * @returns {RequestConfig} The merged configuration object.\n *\n * @example\n * const base = { timeout: 5000, headers: { 'Accept': 'application/json' } };\n * const override = { timeout: 10000, headers: { 'Authorization': 'Bearer token' } };\n * const merged = mergeConfigs(base, override);\n * // Result: { timeout: 10000, headers: { Accept: 'application/json', Authorization: 'Bearer token' } }\n */\nexport function mergeConfigs(\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig = {},\n): RequestConfig {\n Object.assign(targetConfig, baseConfig, overrideConfig);\n\n // Ensure that retry and headers are merged correctly\n mergeConfig('retry', baseConfig, overrideConfig, targetConfig);\n mergeConfig('headers', baseConfig, overrideConfig, targetConfig);\n\n // Merge interceptors efficiently\n for (const property of INTERCEPTORS) {\n mergeInterceptors(property, baseConfig, overrideConfig, targetConfig);\n }\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends\n 'onRequest' | 'onResponse' | 'onError' | 'onRetry' | 'onLoadingSlow',\n>(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const baseInterceptor = baseConfig[property];\n const newInterceptor = overrideConfig[property];\n\n if (baseInterceptor && newInterceptor) {\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] = (\n property === 'onResponse'\n ? [].concat(newInterceptor as never, baseInterceptor as never)\n : [].concat(baseInterceptor as never, newInterceptor as never)\n ) as RequestConfig[K];\n } else if (baseInterceptor || newInterceptor) {\n targetConfig[property] = baseInterceptor || newInterceptor;\n }\n}\n\n/**\n * Merges the specified property from the base configuration and the override configuration into the target configuration.\n *\n * @param {K} property - The property key to merge from the base and override configurations. Must be a key of RequestConfig.\n * @param {RequestConfig} baseConfig - The base configuration object that provides default values.\n * @param {RequestConfig} overrideConfig - The override configuration object that contains user-specific settings to merge.\n * @param {RequestConfig} targetConfig - The configuration object that will receive the merged properties.\n */\nexport function mergeConfig(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n if (override) {\n if (property === 'headers') {\n // Handle Headers instances which don't expose entries as own enumerable properties\n const isInstance =\n (base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers;\n const merged: HeadersObject = isInstance\n ? processHeaders(base)\n : { ...(base as HeadersObject) };\n const overrides: HeadersObject = isInstance\n ? processHeaders(override)\n : sanitizeObject(override as HeadersObject);\n\n // Header names are case-insensitive, so replace existing entries instead of duplicating them\n for (const key of Object.keys(overrides)) {\n const lowerKey = key.toLowerCase();\n\n for (const existingKey in merged) {\n if (existingKey.toLowerCase() === lowerKey) {\n delete merged[existingKey];\n }\n }\n\n merged[key] = overrides[key];\n }\n\n targetConfig[property] = merged as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...sanitizeObject(override as Record),\n } as RequestConfig[K];\n }\n } else if (\n override === undefined &&\n isObject(base) &&\n !((base as Headers | HeadersObject) instanceof Headers)\n ) {\n // Copy so that mutating the merged config never changes the base config\n targetConfig[property] = { ...base } as RequestConfig[K];\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { hash } from './hash';\nimport type {\n CacheKeyFunction,\n DefaultResponse,\n FetchResponse,\n MutationSettings,\n RequestConfig,\n} from './types/request-handler';\nimport type {\n CacheEntry,\n CacheStore,\n StoredResponse,\n} from './types/cache-manager';\nimport { GET, STRING } from './constants';\nimport {\n isJSONSerializable,\n isObject,\n isSearchParams,\n noop,\n sanitizeObject,\n sortObject,\n timeNow,\n} from './utils';\nimport { revalidate } from './revalidator-manager';\nimport { notifySubscribers } from './pubsub-manager';\nimport type { DefaultPayload, DefaultParams, DefaultUrlParams } from './types';\nimport { removeInFlight } from './inflight-manager';\nimport { addTimeout } from './timeout-wheel';\nimport { defaultConfig } from './config-handler';\nimport { processHeaders } from './utils';\n\nexport const IMMEDIATE_DISCARD_CACHE_TIME = 0; // Use it for cache entries that need to be persistent until unused by components or manually deleted\n\nconst _cache = new Map>();\n// The cache stores that keep copies of cache entries, by cache key\nconst stores = new Map();\nconst DELIMITER = '|';\nconst MIN_LENGTH_TO_HASH = 64;\nconst CACHE_KEY_SANITIZE_PATTERN = /[^\\w\\-_|/:@.?=&~%#]/g;\nconst CACHE_KEY_NEEDS_SANITIZE = /[^\\w\\-_|/:@.?=&~%#]/; // Non-global for fast test\n\n/**\n * Headers that may affect HTTP response content and should be included in cache key generation.\n * Header names are matched case-insensitively.\n *\n * - Content negotiation: accept (response format, e.g. JSON or HTML), accept-language (localization), accept-encoding (compression)\n * - Authentication: authorization (access to protected resources)\n * - Request body metadata: content-type (how the request body is interpreted)\n * - Optional: referer (may influence behavior in some APIs), origin (CORS or tenant-specific APIs),\n * user-agent (if the server returns client-specific content), cookie (session-based responses; can fragment the cache heavily)\n * - Custom headers that may affect response content: x-api-key (token-based access), x-requested-with (AJAX requests),\n * x-client-id (per-client/partner identity), x-tenant-id (multi-tenant segmentation), x-user-id (explicit user context),\n * x-app-version (version-specific behavior), x-feature-flag (feature rollout), x-device-id (per device/app instance),\n * x-platform (e.g. 'ios', 'android', 'web'), x-session-id (if it affects the response directly), x-locale (like accept-language)\n */\nconst CACHE_KEY_HEADERS =\n /^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;\n\n/**\n * Generates a unique cache key for a given URL and fetch options, ensuring that key factors\n * like method, headers, body, and other options are included in the cache key.\n * Headers and other objects are sorted by key to ensure consistent cache keys.\n *\n * @param {RequestConfig} config - The fetch options that may affect the request. The most important are:\n * @property {string} [method=\"GET\"] - The HTTP method (GET, POST, etc.).\n * @property {HeadersInit} [headers={}] - The request headers.\n * @property {BodyInit | null} [body=\"\"] - The body of the request (only for methods like POST, PUT).\n * @property {RequestCredentials} [credentials=\"same-origin\"] - Whether to include credentials (include, same-origin, omit).\n * @property {RequestCache} [cache=\"default\"] - The cache mode (e.g., default, no-store, reload).\n * @returns {string} - A unique cache key string based on the provided options.\n *\n * @example\n * const cacheKey = generateCacheKey({\n * url: 'https://api.example.com/data',\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'Alice' }),\n * mode: 'cors',\n * credentials: 'include',\n * });\n * console.log(cacheKey);\n */\nexport function generateCacheKey(\n config: RequestConfig,\n cacheKeyCheck = true,\n): string {\n // This is super fast. Effectively a no-op if cacheKey is\n // a string or a function that returns a string.\n const key = config.cacheKey;\n\n if (key && cacheKeyCheck) {\n return typeof key === STRING\n ? (key as string)\n : (key as CacheKeyFunction)(config);\n }\n\n const {\n url = '',\n method = GET,\n headers = null,\n body = null,\n credentials = 'same-origin',\n } = config;\n\n // Sort headers and body + convert sorted to strings for hashing purposes\n // Native serializer is on avg. 3.5x faster than a Fast Hash or FNV-1a\n let headersString = '';\n if (headers) {\n let obj: Record;\n\n if (headers instanceof Headers) {\n obj = processHeaders(headers);\n } else {\n obj = headers as Record;\n }\n\n // Filter headers to only include those that affect request identity\n // Include only headers that affect request identity, not execution behavior\n const keys = Object.keys(obj);\n const len = keys.length;\n\n // Sort keys manually for fastest deterministic output\n if (len > 1) {\n keys.sort();\n }\n\n let str = '';\n for (let i = 0; i < len; ++i) {\n if (CACHE_KEY_HEADERS.test(keys[i])) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // Concatenate all key parts into a cache key string\n // Template literals are apparently slower\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n return sanitizeCacheKey(cacheStr);\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING || isSearchParams(body)) {\n const str = String(body);\n\n bodyString = str.length < MIN_LENGTH_TO_HASH ? str : hash(str); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Files can't be read synchronously, so they are identified by their object\n bodyString +=\n key +\n '=' +\n (typeof value === STRING ? value : 'F' + getObjectId(value as File)) +\n '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (isObject(body) && !isJSONSerializable(body)) {\n // Blobs, buffers, streams etc. can't be read synchronously, so they are identified by their object.\n // Two different bodies never share a key, while the same body object is still deduplicated.\n bodyString = 'B' + getObjectId(body);\n } else {\n const o = isObject(body)\n ? JSON.stringify(sortObject(body))\n : String(body);\n\n bodyString = o.length > MIN_LENGTH_TO_HASH ? hash(o) : o;\n }\n }\n\n return sanitizeCacheKey(cacheStr + DELIMITER + bodyString);\n}\n\nconst objectIds = new WeakMap();\nlet lastObjectId = 0;\n\n/**\n * Returns a unique id for an object, e.g. a request body that can't be serialized.\n *\n * @param {object} obj - The object to identify.\n * @returns {number} - The id of the object.\n */\nfunction getObjectId(obj: object): number {\n let id = objectIds.get(obj);\n\n if (!id) {\n objectIds.set(obj, (id = ++lastObjectId));\n }\n\n return id;\n}\n\n/**\n * Prevents cache poisoning by removal of control chars and unusual characters.\n * When anything is removed, a hash of the original key is appended so that keys\n * differing only in the removed characters (e.g. `?a[]=1` and `?a=1`) don't collide.\n *\n * @param {string} cacheStr - The raw cache key.\n * @returns {string} - The sanitized cache key.\n */\nfunction sanitizeCacheKey(cacheStr: string): string {\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '') +\n DELIMITER +\n hash(cacheStr)\n : cacheStr;\n}\n\n/**\n * Checks if the cache entry is expired based on its timestamp and the expiry time.\n *\n * @param {CacheEntry} entry - The cache entry to check.\n * @returns {boolean} - Returns true if the cache entry is expired, false otherwise.\n */\nfunction isCacheExpired(entry: CacheEntry): boolean {\n // No expiry time means the entry never expires\n if (!entry.expiry) {\n return false;\n }\n\n return timeNow() > entry.expiry;\n}\n\n/**\n * Retrieves a cached response from the internal cache using the provided key.\n *\n * @param key - The unique key identifying the cached entry. If null, returns null.\n * @returns The cached {@link FetchResponse} if found, otherwise null.\n */\nexport function getCacheData<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n key: string | null,\n): FetchResponse | null {\n if (!key) {\n return null;\n }\n\n const entry = _cache.get(key);\n\n return entry ? entry.data : null;\n}\n\n/**\n * Retrieves a cache entry if it exists and is not expired.\n *\n * @param {string} key Cache key to utilize\n * @returns {CacheEntry | null} - The cache entry if it exists and is not expired, null otherwise.\n */\nexport function getCache(\n key: string | null,\n):\n | CacheEntry<\n FetchResponse\n >\n | null\n | undefined {\n return _cache.get(key as string);\n}\n\n/**\n * Sets a new cache entry or updates an existing one, with optional TTL (time-to-live).\n *\n * @param {string} key Cache key to utilize\n * @param {T} data - The data to be cached.\n * @param {number} [ttl] - Optional TTL in seconds. If not provided, the cache entry will not expire.\n * @param {number} [staleTime] - Optional stale time in seconds. If provided, the cache entry will be considered stale after this time.\n */\nexport function setCache(\n key: string,\n data: T,\n ttl?: number,\n staleTime?: number,\n): void {\n if (ttl === 0) {\n deleteCache(key);\n return;\n }\n\n const time = timeNow();\n const ttlMs = ttl ? ttl * 1000 : 0;\n const staleTimeMs = staleTime ? staleTime * 1000 : 0; // Ensure default value for staleTime\n\n _cache.set(key, {\n data,\n time,\n stale: staleTimeMs > 0 ? time + staleTimeMs : undefined, // Use undefined if staleTime is not set\n expiry: ttl === -1 ? undefined : time + ttlMs,\n });\n\n if (ttlMs > 0) {\n scheduleExpiry(key, ttlMs);\n }\n}\n\n/**\n * Deletes a cache entry once it expires.\n *\n * @param {string} key Cache key to utilize\n * @param {number} ms - The time until the entry expires, in milliseconds.\n */\nfunction scheduleExpiry(key: string, ms: number): void {\n addTimeout('c:' + key, () => deleteCache(key, true), ms);\n}\n\n/**\n * Invalidates (deletes) a cache entry.\n *\n * @param {string} key Cache key to utilize\n * @param {boolean} [removeExpired=false] - If true, only deletes the cache entry if it is expired or stale.\n */\nexport function deleteCache(key: string, removeExpired: boolean = false): void {\n if (removeExpired) {\n const entry = getCache(key);\n\n // If the entry does not exist, or it is neither expired nor stale, do not delete\n if (!entry || !isCacheExpired(entry)) {\n return;\n }\n }\n\n _cache.delete(key);\n\n const store = stores.get(key);\n\n if (store) {\n stores.delete(key);\n callStore(() => store.delete(key));\n }\n}\n\n/**\n * Prunes the cache by removing entries that have expired based on the provided cache time.\n */\nexport function pruneCache(): void {\n _cache.clear();\n stores.clear();\n}\n\n/**\n * Calls a cache store method. Store errors, e.g. of a full localStorage, are ignored so that they can't break requests.\n *\n * @param {() => unknown} fn - The function calling the store.\n */\nfunction callStore(fn: () => unknown): void {\n try {\n Promise.resolve(fn()).catch(noop);\n } catch {\n // Ignored\n }\n}\n\n/**\n * Saves a copy of a cached response in a cache store, so that it can be restored later, e.g. after a page reload.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheStore} [store] - The cache store. If not provided, nothing is saved.\n */\nfunction persistCache(key: string, store?: CacheStore): void {\n const entry = _cache.get(key);\n\n if (store && entry) {\n const { data, status, statusText, headers } = entry.data as FetchResponse;\n\n stores.set(key, store);\n callStore(() =>\n store.set(key, { ...entry, data: { data, status, statusText, headers } }),\n );\n }\n}\n\n/**\n * Reads the entry of a cache key from the cache store of a request, e.g. one saved during a previous page load.\n * Expired entries are deleted from the store.\n *\n * @param {string} key Cache key to utilize\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {Promise | null>} - The stored entry, or null if there is no valid one or the in-memory cache has an entry already.\n */\nexport async function getStoredCache(\n key: string,\n requestConfig: RequestConfig,\n): Promise | null> {\n const store = requestConfig.cacheStore;\n\n if (!store || isCacheBypassed(requestConfig)) {\n return null;\n }\n\n let entry: CacheEntry | null | undefined;\n\n try {\n entry = await store.get(key);\n } catch {\n // A failing store is treated like an empty one\n return null;\n }\n\n // Another request may have cached a response in the meantime\n if (!entry || _cache.has(key)) {\n return null;\n }\n\n if (isCacheExpired(entry)) {\n callStore(() => store.delete(key));\n\n return null;\n }\n\n return entry;\n}\n\n/**\n * Caches a response restored from a cache store in memory, keeping its original stale and expiry times.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheEntry} entry - The cache entry with the restored response.\n * @param {CacheStore} store - The cache store that the response was restored from.\n * @returns {boolean} - True if the restored response is fresh, false if it's stale.\n */\nexport function restoreCache(\n key: string,\n entry: CacheEntry,\n store: CacheStore,\n): boolean {\n _cache.set(key, entry);\n stores.set(key, store);\n\n if (entry.expiry) {\n scheduleExpiry(key, entry.expiry - timeNow());\n }\n\n notifySubscribers(key, entry.data);\n\n return !entry.stale || timeNow() < entry.stale;\n}\n\n/**\n * Mutates a cache entry with new data and optionally revalidates it.\n *\n * @param {string | null} key Cache key to utilize. If null, no mutation occurs.\n * @param {ResponseData} newData - The new data to be cached.\n * @param {MutationSettings|undefined} settings - Mutation settings.\n */\nexport async function mutate<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n key: string | null,\n newData: ResponseData,\n settings?: MutationSettings,\n): Promise | null> {\n // If no key is provided, do nothing\n if (!key) {\n return null;\n }\n\n const entry = getCache(\n key,\n );\n\n if (!entry) {\n return null;\n }\n\n const updatedData = isObject(newData) ? sanitizeObject(newData) : newData;\n\n const updatedResponse = {\n ...entry.data,\n data: updatedData,\n };\n\n // The ETag belongs to the original data, so the changed data must not be revalidated with it\n const headers = updatedResponse.headers;\n\n if (headers && headers.etag) {\n updatedResponse.headers = { ...headers };\n delete updatedResponse.headers.etag;\n }\n\n const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n persistCache(key, stores.get(key));\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\n}\n\n/**\n * Checks whether a request should bypass the cache, because of its cache buster or `cache: 'reload'`.\n *\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {boolean} - True if the cache should be bypassed.\n */\nexport function isCacheBypassed(requestConfig: RequestConfig): boolean {\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n\n return (\n !!(buster && buster(requestConfig)) || requestConfig.cache === 'reload'\n );\n}\n\n/**\n * Retrieves a cached response if available and valid, otherwise returns null.\n *\n * @template ResponseData - The type of the response data.\n * @template RequestBody - The type of the request body.\n * @template QueryParams - The type of the query parameters.\n * @template PathParams - The type of the path parameters.\n * @param {string | null} cacheKey - The cache key to look up.\n * @param {number | undefined} cacheTime - The maximum time to cache entry.\n * @param {RequestConfig} requestConfig - The fetcher configuration.\n * @returns {FetchResponse | null} - The cached response or null.\n */\nexport function getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n cacheKey: string | null,\n cacheTime: number | undefined,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): FetchResponse | null {\n // If cache key or time is not provided, return null\n if (!cacheKey || cacheTime === undefined || cacheTime === null) {\n return null;\n }\n\n if (isCacheBypassed(requestConfig)) {\n return null;\n }\n\n // Retrieve the cached entry\n const entry = getCache(\n cacheKey,\n );\n\n if (!entry) {\n return null;\n }\n\n const isExpired = isCacheExpired(entry);\n\n // If completely expired, delete and return null\n if (isExpired) {\n deleteCache(cacheKey);\n return null;\n }\n\n const data = entry.data;\n\n // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n // The placeholder stored while a request is in flight is not a response, so treat it as a miss\n return data && data.isFetching ? null : data;\n}\n\n/**\n * Sets or deletes the response cache based on cache settings and notifies subscribers.\n *\n * @param {FetchResponse} output - The response to cache.\n * @param {RequestConfig} requestConfig - The request configuration.\n * @param {boolean} [isError=false] - Whether the response is an error.\n */\nexport function handleResponseCache<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n output: FetchResponse,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n isError: boolean = false,\n): void {\n // It is string as it is called once request is made\n const cacheKey = requestConfig.cacheKey as string;\n\n if (cacheKey) {\n const cacheTime = requestConfig.cacheTime;\n const skipCache = requestConfig.skipCache;\n\n // Fast path: only set cache if cacheTime is positive and not skipping cache\n if (\n cacheTime &&\n (!isError || requestConfig.cacheErrors) &&\n !(skipCache && skipCache(output, requestConfig))\n ) {\n setCache(cacheKey, output, cacheTime, requestConfig.staleTime);\n\n // Error responses are only cached in memory\n if (!isError) {\n persistCache(cacheKey, requestConfig.cacheStore);\n }\n } else {\n const entry = getCache(cacheKey);\n\n // Don't let the in-flight placeholder outlive a request whose result isn't cached\n if (entry && entry.data && entry.data.isFetching) {\n deleteCache(cacheKey);\n }\n }\n\n notifySubscribers(cacheKey, output);\n removeInFlight(cacheKey);\n\n const prevCacheKey = requestConfig._prevKey;\n\n if (prevCacheKey) {\n removeInFlight(prevCacheKey);\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { mutate } from './cache-manager';\nimport {\n APPLICATION_CONTENT_TYPE,\n APPLICATION_JSON,\n CONTENT_TYPE,\n FUNCTION,\n STRING,\n} from './constants';\nimport {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n ResponseError,\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n} from './types';\nimport { flattenData, isObject, processHeaders } from './utils';\n\n/**\n * Parses the response data based on the Content-Type header, or reads it as the given response type.\n *\n * @param response - The Response object to parse.\n * @param responseType - How to read the body regardless of its Content-Type, e.g. as a Blob, or `'stream'` to leave it unread.\n * @returns A Promise that resolves to the parsed data.\n */\nexport async function parseResponseData<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse,\n responseType?: RequestConfig['responseType'],\n): Promise {\n // Bail early if response is null or undefined\n if (!response) {\n return null;\n }\n\n // Get the content-type header once\n const headers = (response as Response).headers;\n let contentType = headers && headers.get(CONTENT_TYPE);\n\n if (contentType) {\n // Lowercase and trim for consistent matching\n contentType = contentType.toLowerCase().trim();\n } else {\n contentType = '';\n }\n\n // Split for mime type without charset\n const mimeType = contentType.split(';', 1)[0];\n\n let data;\n\n try {\n if (responseType) {\n // The body is read as requested, or left unread as a stream to be read by the caller\n data =\n responseType === 'stream'\n ? response.body\n : await response[responseType]();\n } else if (\n mimeType.includes(APPLICATION_JSON) ||\n mimeType.includes('+json')\n ) {\n data = await response.json(); // Parse JSON response\n } else if (\n (mimeType.includes('multipart/form-data') || // Parse as FormData\n mimeType.includes(\n APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded', // Handle URL-encoded forms\n )) &&\n typeof response.formData === FUNCTION\n ) {\n data = await response.formData();\n } else if (/^(image|video|audio)\\/|octet-stream|pdf|zip/.test(mimeType)) {\n data = await response.arrayBuffer(); // Parse as ArrayBuffer for binary types\n } else {\n data = await response.text();\n\n if (typeof data === STRING) {\n const trimmed = data.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n data = JSON.parse(trimmed);\n } catch {\n // leave as text if parsing fails\n }\n }\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (_error) {\n // Parsing failed, fallback to null\n data = null;\n }\n\n return data;\n}\n\n/**\n * Prepare response object with additional information.\n *\n * @param Response. It may be \"null\" in case of request being aborted.\n * @param {RequestConfig} config - Request config\n * @param error - whether the response is erroneous\n * @returns {FetchResponse} Response data\n */\nexport const prepareResponse = <\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n config: RequestConfig,\n error: ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null,\n): FetchResponse => {\n const defaultResponse = config.defaultResponse;\n const cacheKey = config.cacheKey;\n const mutatator = mutate.bind(null, cacheKey as string) as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >['mutate'];\n\n // This may happen when request is cancelled.\n if (!response) {\n return {\n ok: false,\n // Enhance the response with extra information\n error,\n data: defaultResponse ?? null,\n headers: null,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: false,\n isError: true,\n } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n const isNativeResponse =\n typeof Response === FUNCTION && response instanceof Response;\n\n let data = response.data;\n\n // Set the default response if the provided data is an empty object or array\n // Other objects, e.g. Blobs, buffers and streams, have no keys either, but aren't empty\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (/^\\[object (Object|Array)\\]$/.test(\n Object.prototype.toString.call(data),\n ) &&\n Object.keys(data).length === 0))\n ) {\n response.data = data = defaultResponse;\n }\n\n if (config.flattenResponse) {\n response.data = data = flattenData(data);\n }\n\n if (config.select) {\n response.data = data = config.select(data);\n }\n\n const headers = processHeaders(response.headers);\n\n // Native fetch Response extended by extra information\n if (isNativeResponse) {\n const output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > = {\n body: response.body,\n bodyUsed: response.bodyUsed,\n ok: response.ok,\n redirected: response.redirected,\n type: response.type,\n url: response.url,\n status: response.status,\n statusText: response.statusText,\n\n // Convert methods to use arrow functions to preserve correct return types\n // Lazily construct Blob from ArrayBuffer\n blob: async () =>\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n json: async () => data as ResponseData, // Return the already parsed JSON data\n text: async () => data as string, // Return the already parsed text data\n // The body was already read, so a copy of this response is returned instead of Response.clone()\n clone: () => ({ ...output }),\n arrayBuffer: async () =>\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0), // Return the ArrayBuffer directly\n formData: async () => (data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: async () =>\n new Uint8Array(data instanceof ArrayBuffer ? data : new ArrayBuffer(0)),\n // Enhance the response with extra information\n error,\n data,\n headers,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: response.ok && !error,\n isError: !!error,\n };\n\n return output;\n }\n\n // If it's a custom fetcher, and it does not return any Response instance, it may have its own internal handler\n if (isObject(response)) {\n // Assigned one by one, as Object.assign() with an object literal is measurably slower here\n response.error = error;\n response.headers = headers;\n response.isFetching = false;\n response.mutate = mutatator;\n response.isSuccess = response.ok && !error;\n response.isError = !!error;\n }\n\n return response;\n};\n","import { applyInterceptors } from './interceptor-manager';\nimport type { FetchResponse, RetryConfig, RetryFunction } from './types';\nimport { delayInvocation, timeNow } from './utils';\nimport { generateCacheKey } from './cache-manager';\nimport { FUNCTION } from './constants';\n\nfunction getMsFromHttpDate(dateString: string): number | null {\n const ms = Date.parse(dateString) - timeNow();\n\n if (!isNaN(ms)) {\n return Math.max(0, Math.floor(ms));\n }\n return null;\n}\n\n/**\n * Calculates the number of milliseconds to wait before retrying a request,\n * based on the `Retry-After` HTTP header in the provided response.\n *\n * The function supports both numeric (seconds) and HTTP-date formats for the `Retry-After` header.\n * - If the header is a number, it is interpreted as seconds and converted to milliseconds.\n * - If the header is a date, the function calculates the difference between the date and the current time.\n *\n * @param extendedResponse - The response object containing headers, or `null`.\n * @returns The number of milliseconds to wait before retrying, or `null` if the header is not present or invalid.\n */\nexport function getRetryAfterMs(\n extendedResponse: FetchResponse | null,\n): number | null {\n if (!extendedResponse) {\n return null;\n }\n\n const headers = extendedResponse.headers || {};\n const retryAfter = headers['retry-after'];\n\n if (retryAfter) {\n // Try parsing as seconds\n const seconds = Number(retryAfter);\n\n if (!isNaN(seconds) && seconds >= 0) {\n return seconds * 1000;\n }\n\n const ms = getMsFromHttpDate(retryAfter);\n\n if (ms !== null) {\n return ms;\n }\n }\n\n // Headers are already in lowercase\n const RATELIMIT_RESET = 'ratelimit-reset';\n\n // Unix timestamp when the rate limit window resets (relative to current time)\n // Fallback to checking 'ratelimit-reset-after' OR 'x-ratelimit-reset-after' headers\n const rateLimitResetAfter =\n headers[RATELIMIT_RESET + '-after'] ||\n headers['x-' + RATELIMIT_RESET + '-after'];\n\n if (rateLimitResetAfter) {\n const seconds = Number(rateLimitResetAfter);\n\n if (!isNaN(seconds)) {\n return seconds * 1000;\n }\n }\n\n // ISO 8601 datetime when the rate limit resets\n // Fallback to checking 'ratelimit-reset-at' 'x-ratelimit-reset-at' headers\n const rateLimitResetAt =\n headers[RATELIMIT_RESET + '-at'] || headers['x-' + RATELIMIT_RESET + '-at'];\n\n if (rateLimitResetAt) {\n return getMsFromHttpDate(rateLimitResetAt);\n }\n\n return null;\n}\n\n/**\n * Executes a request function with retry logic according to the provided configuration.\n *\n * The function attempts the request up to the specified number of retries, applying delay and backoff strategies.\n * Retries can be triggered based on response status codes, custom logic, or the presence of a `Retry-After` header.\n * Optionally, an `onRetry` interceptor can be invoked before each retry attempt.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param requestFn - The function that performs the request. Receives `isStaleRevalidation` and `attempt` as arguments.\n * @param config - The retry configuration, including retry count, delay, backoff, retry conditions, and hooks.\n * @returns A promise resolving to the fetch response, or rejecting if all retries are exhausted.\n * @throws Error if the maximum number of retries is exceeded or a non-retriable error occurs.\n */\nexport async function withRetry<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation: boolean,\n attempt: number,\n ) => Promise<\n FetchResponse\n >,\n config: RetryConfig,\n): Promise> {\n const {\n retries = 0,\n delay = 0,\n backoff = 1,\n maxDelay,\n retryOn = [],\n shouldRetry,\n jitter,\n methods,\n } = config;\n\n let attempt = 0;\n let waitTime = delay;\n const maxRetries = retries > 0 ? retries : 0;\n let output: FetchResponse;\n\n while (attempt <= maxRetries) {\n // Subsequent attempts will have output defined, but the first attempt may not.\n // Let's apply onRetry interceptor and regenerate cache key if ot really changes.\n if (attempt > 0 && output!) {\n const cfg = output.config;\n const onRetry = cfg.onRetry;\n\n if (onRetry) {\n await applyInterceptors(onRetry, output, attempt);\n\n // If the key was automatically generated, we need to regenerate it as config may change.\n // We don't detect whether config changed for performance reasons.\n if (cfg._isAutoKey) {\n cfg._prevKey = cfg.cacheKey as string;\n cfg.cacheKey = generateCacheKey(cfg, false);\n }\n }\n }\n\n // Performance optimization: Call the request function with the current attempt number\n // If this is the first attempt, we pass `isStaleRevalidation` as `false`,\n // otherwise we pass `true` to indicate that this is a stale revalidation (no cache hit).\n output = await requestFn(attempt > 0, attempt);\n const error = output.error;\n\n // Stop unless a failed response should be retried according to the retry settings,\n // or a successful one according to shouldRetry\n if (\n error\n ? await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n methods,\n )\n : !(\n shouldRetry &&\n attempt < maxRetries &&\n (await shouldRetry(output, attempt))\n )\n ) {\n break;\n }\n\n // The delay before the next retry, randomized with jitter unless the server asks for one below\n let retryDelay = withJitter(waitTime, jitter);\n\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (error && (error.status === 429 || error.status === 503)) {\n // Try to extract the \"Retry-After\" value from the response headers\n const retryAfterMs = getRetryAfterMs(output);\n\n // If a valid retry-after value is found, override the wait time before next retry\n // Cap it with maxDelay so that a server can't make the client wait indefinitely\n if (retryAfterMs !== null) {\n retryDelay = waitTime = Math.min(\n retryAfterMs,\n maxDelay || retryAfterMs,\n );\n }\n }\n\n await delayInvocation(retryDelay);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n }\n\n return output!;\n}\n\n/**\n * Determines whether to stop retrying based on the error, current attempt count, and retry configuration.\n *\n * This function checks:\n * - If the maximum number of retries has been reached.\n * - If the request was aborted, e.g. with its signal or by a newer request. Aborted requests are never retried.\n * - If a custom `shouldRetry` callback is provided, its result is used to decide.\n * - If no custom logic is provided, falls back to checking if the error status is included in the `retryOn` list,\n * and the request method in the `methods` list, if any.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param output - The response object containing the error and request configuration.\n * @param attempt - The current retry attempt number.\n * @param maxRetries - The maximum number of retry attempts allowed.\n * @param shouldRetry - Optional custom function to determine if a retry should occur.\n * @param retryOn - Optional list of HTTP status codes that should trigger a retry.\n * @param methods - Optional list of request methods that are retried on the `retryOn` statuses. All methods are retried without it.\n * @returns A promise resolving to `true` if retrying should stop, or `false` to continue retrying.\n */\nexport async function getShouldStopRetrying<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n output: FetchResponse,\n attempt: number,\n maxRetries: number,\n shouldRetry?: RetryFunction<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n retryOn: number[] = [],\n methods?: string[],\n): Promise {\n // Safety first: always respect max retries\n // We check retries provided regardless of the shouldRetry being provided so to avoid infinite loops.\n // It is a fail-safe so to prevent excessive retry attempts even if custom retry logic suggests a retry.\n if (attempt === maxRetries) {\n return true;\n }\n\n // Aborted requests are never retried, as e.g. a retry of one cancelled by a newer request would cancel the newer one\n if (output.error?.isCancelled) {\n return true;\n }\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n\n if (result !== null) {\n return !result;\n }\n }\n\n return !(\n (retryOn || []).includes(output.error?.status ?? 0) &&\n (!methods ||\n methods.some((method) => method.toUpperCase() === output.config.method))\n );\n}\n\n/**\n * Randomizes a retry delay with jitter, so that clients that failed at the same time, e.g. during an outage, don't retry all at once.\n *\n * @param delay - The delay computed from the `delay`, `backoff` and `maxDelay` settings, in milliseconds.\n * @param jitter - `true` for a random delay between 0 and the computed one (\"full jitter\"), or a function that returns the delay to use.\n * @returns The delay to wait before the retry, in milliseconds.\n */\nfunction withJitter(delay: number, jitter: RetryConfig['jitter']): number {\n return typeof jitter === FUNCTION\n ? (jitter as (delay: number) => number)(delay)\n : jitter\n ? Math.random() * delay\n : delay;\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation, isOffline, isPageHidden } from './utils';\n\n/**\n * Executes a request function with polling, stopping when shouldStopPolling returns true,\n * pollingInterval is not set, or maxAttempts is reached.\n * Polling pauses while the page is hidden or the browser is offline, unless allowed by refreshWhenHidden or refreshWhenOffline.\n *\n * @template Output The type of the output returned by the request function.\n * @param requestFn - The function that performs a single request (with retries).\n * @param pollingInterval - Interval in ms between polling attempts.\n * @param shouldStopPolling - Function to determine if polling should stop.\n * @param maxAttempts - Maximum number of polling attempts, default: 0 (unlimited).\n * @param pollingDelay - Delay in ms before each polling attempt, default: 0.\n * @param refreshWhenHidden - Whether to keep polling while the page is hidden, default: false.\n * @param refreshWhenOffline - Whether to keep polling while the browser is offline, default: false.\n * @param signal - The signal passed to the request. Polling stops once it is aborted.\n * @returns The final output from the last request.\n */\nexport async function withPolling<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation?: boolean,\n attempt?: number,\n ) => Promise<\n FetchResponse\n >,\n pollingInterval?: RequestConfig['pollingInterval'],\n shouldStopPolling?: RequestConfig['shouldStopPolling'],\n maxAttempts = 0,\n pollingDelay = 0,\n refreshWhenHidden = false,\n refreshWhenOffline = false,\n signal?: AbortSignal,\n): Promise> {\n if (!pollingInterval) {\n return requestFn();\n }\n\n let pollingAttempt = 0;\n let output: FetchResponse;\n\n while (maxAttempts === 0 || pollingAttempt < maxAttempts) {\n if (pollingDelay > 0) {\n await delayInvocation(pollingDelay, signal);\n }\n\n output = await requestFn();\n\n pollingAttempt++;\n\n if (\n (maxAttempts > 0 && pollingAttempt >= maxAttempts) ||\n !pollingInterval ||\n (shouldStopPolling && shouldStopPolling(output, pollingAttempt))\n ) {\n break;\n }\n\n // Wait for the next attempt, and keep waiting while polling is paused\n do {\n await delayInvocation(pollingInterval, signal);\n\n // Aborting the signal of the request stops polling\n if (signal && signal.aborted) {\n return output;\n }\n } while (\n (!refreshWhenHidden && isPageHidden()) ||\n (!refreshWhenOffline && isOffline())\n );\n }\n\n return output!;\n}\n","import { ABORT_ERROR, UNDEFINED } from './constants';\nimport type { RequestConfig, UploadProgress } from './types';\nimport { createAbortError } from './utils';\n\n// Responses with these statuses can't have a body\nconst NULL_BODY_STATUSES = [204, 205, 304];\n\n// Headers that browsers don't let requests set. fetch() skips them silently, while\n// XMLHttpRequest logs errors for them, so they are skipped before sending.\nconst FORBIDDEN_HEADERS =\n /^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/;\n\n// ReadableStream is missing in some environments, e.g. React Native\nconst isStream = (body: unknown): body is ReadableStream =>\n typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream;\n\nexport const toProgress = (loaded: number, total?: number): UploadProgress => ({\n loaded,\n total,\n progress: total ? loaded / total : undefined,\n});\n\n/**\n * Sends a request and reports the upload progress of its body to `onUploadProgress`.\n * Browsers and React Native don't report the upload progress of fetch(), so XMLHttpRequest is used there.\n * Elsewhere, e.g. in Node.js, the body is streamed with fetch() and counted while it is sent.\n *\n * @param {string} url - The request URL.\n * @param {RequestConfig} config - The request configuration, with a body and `onUploadProgress`.\n * @returns {Promise} - The response.\n */\nexport function fetchWithUploadProgress(\n url: string,\n config: RequestConfig,\n): Promise {\n const body = config.body as BodyInit;\n\n return typeof XMLHttpRequest !== UNDEFINED && !isStream(body)\n ? sendWithXhr(url, config, body)\n : sendStreamed(url, config, body);\n}\n\nfunction sendWithXhr(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n // fetchf() always sets the signal, as it handles timeouts and cancellation with it\n const signal = config.signal!;\n const abort = () => xhr.abort();\n\n const settle = (fn: () => void) => {\n signal.removeEventListener('abort', abort);\n\n try {\n fn();\n } catch (error) {\n reject(error);\n }\n };\n\n xhr.open(config.method as string, url);\n xhr.responseType = 'blob';\n xhr.withCredentials = config.credentials === 'include';\n\n new Headers(config.headers).forEach(\n (value, name) =>\n FORBIDDEN_HEADERS.test(name) || xhr.setRequestHeader(name, value),\n );\n\n xhr.upload.onprogress = (event) =>\n config.onUploadProgress!(\n toProgress(\n event.loaded,\n event.lengthComputable ? event.total : undefined,\n ),\n );\n\n xhr.onload = () =>\n settle(() => {\n const headers = new Headers();\n\n for (const line of xhr.getAllResponseHeaders().split(/\\r?\\n/)) {\n const index = line.indexOf(':');\n\n if (index > 0) {\n headers.append(line.slice(0, index), line.slice(index + 1).trim());\n }\n }\n\n const response = new Response(\n NULL_BODY_STATUSES.includes(xhr.status) ? null : xhr.response,\n { status: xhr.status, statusText: xhr.statusText, headers },\n );\n\n // Like fetch(), the response tells its final URL, e.g. after redirects\n Object.defineProperty(response, 'url', { value: xhr.responseURL });\n\n resolve(response);\n });\n\n xhr.onerror = () =>\n settle(() => reject(new TypeError('Network request failed')));\n\n // Like fetch(), aborted requests reject with the reason of the abort signal\n const onAbort = () =>\n settle(() =>\n reject(\n signal.reason ||\n createAbortError('The request was aborted', ABORT_ERROR),\n ),\n );\n\n xhr.onabort = onAbort;\n\n if (signal.aborted) {\n return onAbort();\n }\n\n signal.addEventListener('abort', abort);\n\n xhr.send(body as XMLHttpRequestBodyInit);\n });\n}\n\nasync function sendStreamed(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n const headers = new Headers(config.headers);\n let stream = body as ReadableStream;\n let total: number | undefined;\n\n if (!isStream(body)) {\n // Serialize the body like fetch() would, to know its size and content type\n const blob = body instanceof Blob ? body : await new Response(body).blob();\n\n total = blob.size;\n stream = blob.stream();\n\n if (blob.type && !headers.has('content-type')) {\n headers.set('content-type', blob.type);\n }\n }\n\n let loaded = 0;\n\n return fetch(url, {\n ...config,\n headers,\n body: stream.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n config.onUploadProgress!(toProgress(loaded, total));\n controller.enqueue(chunk);\n },\n }),\n ),\n // Required by fetch() to send a stream\n duplex: 'half',\n } as RequestInit);\n}\n","import { FUNCTION } from './constants';\nimport type { DownloadProgress } from './types';\nimport { toProgress } from './upload-progress';\n\n/**\n * Reports the download progress of a response body to `onDownloadProgress` while the body is read.\n * The body is counted as it arrives, so the progress follows the download.\n *\n * @param {T} response - The response. Other than native responses with a body, e.g. responses of HEAD requests or custom fetchers, are returned as they are.\n * @param {Function} [onDownloadProgress] - The function called with the progress. Without it, the response is returned as it is.\n * @returns {T} - A copy of the response, whose body is counted while it's read.\n */\nexport function withDownloadProgress(\n response: T,\n onDownloadProgress?: (progress: DownloadProgress) => void,\n): T {\n // Response is missing in some environments, and response bodies e.g. in React Native\n if (\n !onDownloadProgress ||\n typeof Response !== FUNCTION ||\n !(response instanceof Response) ||\n !response.body\n ) {\n return response;\n }\n\n const headers = response.headers;\n // Content-Length is the size of the compressed body, so the size of a compressed one is unknown\n const total = headers.has('content-encoding')\n ? undefined\n : Number(headers.get('content-length')) || undefined;\n let loaded = 0;\n\n const counted = new Response(\n response.body.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n // Browsers may hide the Content-Encoding header of cross-origin responses, so the progress is capped at 1\n onDownloadProgress(\n toProgress(loaded, total && Math.max(total, loaded)),\n );\n controller.enqueue(chunk);\n },\n }),\n ),\n response,\n );\n\n // Like the original response, the copy tells its final URL, whether it was redirected and its type\n for (const key of ['url', 'redirected', 'type'] as const) {\n Object.defineProperty(counted, key, { value: response[key] });\n }\n\n return counted as T;\n}\n","import type { ResponseError } from './errors/response-error';\nimport type {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n} from './types/request-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { handleResponseCache } from './cache-manager';\nimport { ABORT_ERROR, REJECT } from './constants';\nimport {\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n HeadersObject,\n} from './types';\nimport { processHeaders } from './utils';\n\n/**\n * Handles final processing for both success and error responses\n * Applies error interceptors, caching, notifications, and error strategy\n */\nexport async function withErrorHandling<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n isStaleRevalidation: boolean,\n requestFn: (\n isStaleRevalidation: boolean,\n ) => Promise<\n FetchResponse\n >,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): Promise> {\n const output = await requestFn(isStaleRevalidation);\n const error = output.error;\n\n if (!error) {\n // SUCCESS PATH\n handleResponseCache(output, requestConfig);\n\n return output;\n }\n\n // ERROR PATH\n\n if (requestConfig.onError) {\n await applyInterceptors(requestConfig.onError, error);\n }\n\n // Timeouts and request cancellations using AbortController do not throw any errors unless rejectCancelled is true.\n // Only handle the error if the request was not cancelled, or if it was cancelled and rejectCancelled is true.\n const isCancelled = error.isCancelled;\n\n const logger = requestConfig.logger;\n\n if (!isCancelled && logger && logger.warn) {\n logger.warn('FETCH ERROR', redactError(error as ResponseError));\n }\n\n // The defaultResponse strategy returns the default response in place of the error data.\n // The original data stays available through error.response.\n if (requestConfig.strategy === 'defaultResponse') {\n output.data = (requestConfig.defaultResponse ?? null) as typeof output.data;\n }\n\n // Handle cache and notifications FIRST (before strategy)\n handleResponseCache(output, requestConfig, true);\n\n // handle error strategy as the last part\n const shouldHandleError = !isCancelled || requestConfig.rejectCancelled;\n\n if (shouldHandleError) {\n const strategy = requestConfig.strategy;\n // Reject the promise\n if (strategy === REJECT) {\n throw error;\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\n}\n\n// Credential headers that must not end up in logs\nconst SENSITIVE_HEADERS = [\n 'authorization',\n 'proxy-authorization',\n 'cookie',\n 'x-api-key',\n];\n\n/**\n * Creates a copy of the error for logging, with credential headers masked and the request body removed.\n * The error itself is left untouched.\n */\nfunction redactError(error: ResponseError): ResponseError {\n // Cache keys are dropped too, as they can contain short request bodies\n const config = {\n ...error.config,\n body: undefined,\n data: undefined,\n cacheKey: undefined,\n _prevKey: undefined,\n headers: processHeaders(error.config.headers as HeadersObject),\n };\n\n for (const name of SENSITIVE_HEADERS) {\n if (config.headers[name]) {\n config.headers[name] = '[REDACTED]';\n }\n }\n\n const copy = Object.assign(new Error(error.message), error, {\n config,\n request: config,\n response: error.response && { ...error.response, config },\n });\n\n copy.name = error.name;\n copy.stack = error.stack;\n\n return copy;\n}\n\nexport function enhanceError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): void {\n error.status = error.status || (response && response.status) || 0;\n error.statusText =\n error.statusText || (response && response.statusText) || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n HeadersObject,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport type { StoredResponse } from './types/cache-manager';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject, noop, processHeaders } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport {\n generateCacheKey,\n getCacheData,\n getCachedResponse,\n getStoredCache,\n isCacheBypassed,\n restoreCache,\n setCache,\n} from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { fetchWithUploadProgress } from './upload-progress';\nimport { withDownloadProgress } from './download-progress';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION, GET, HEAD } from './constants';\nimport { buildConfig } from './config-handler';\n\nconst inFlightResponse = Object.freeze({\n isFetching: true,\n});\n\n/**\n * Sends an HTTP request to the specified URL using the provided configuration and returns a typed response.\n *\n * @typeParam ResponseData - The expected shape of the response data. Defaults to `DefaultResponse`.\n * @typeParam RequestBody - The type of the request payload/body. Defaults to `DefaultPayload`.\n * @typeParam QueryParams - The type of the query parameters. Defaults to `DefaultParams`.\n * @typeParam PathParams - The type of the path parameters. Defaults to `DefaultUrlParams`.\n *\n * @param url - The endpoint URL to which the request will be sent.\n * @param config - Optional configuration object for the request, including headers, method, body, query, and path parameters.\n *\n * @returns A promise that resolves to a `FetchResponse` containing the typed response data and request metadata.\n *\n * @example\n * ```typescript\n * const { data } = await fetchf('/api/user', { method: 'GET' });\n * console.log(data);\n * ```\n */\nexport async function fetchf<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n url: string,\n reqConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null = null,\n): Promise> {\n // Ultra-fast early cache check if cacheKey is provided as a string\n // For workloads dominated by repeated requests, this string caching optimization\n // can potentially support millions of requests per second with minimal CPU overhead\n if (reqConfig && typeof reqConfig.cacheKey === 'string') {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(reqConfig.cacheKey, reqConfig.cacheTime, reqConfig);\n\n if (cached) {\n return cached;\n }\n }\n\n const fetcherConfig = buildConfig<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(url, reqConfig);\n\n const {\n timeout,\n cancellable,\n cacheKey,\n dedupeTime,\n cacheTime,\n staleTime,\n refetchOnFocus,\n refetchOnReconnect,\n pollingInterval = 0,\n } = fetcherConfig;\n const isCacheEnabled = cacheTime !== undefined || staleTime !== undefined;\n const method = fetcherConfig.method;\n\n // Cached responses of GET and HEAD requests are revalidated with their ETag.\n // Custom fetchers may not handle 304 responses, so they only send it when it's enabled for them.\n const isETagEnabled =\n isCacheEnabled &&\n (method === GET || method === HEAD) &&\n (fetcherConfig.etag ?? !fetcherConfig.fetcher);\n\n const needsCacheKey = !!(\n cacheKey ||\n timeout ||\n dedupeTime ||\n isCacheEnabled ||\n cancellable ||\n refetchOnFocus ||\n refetchOnReconnect\n );\n\n let _cacheKey: string | null = null;\n\n // Generate cache key if required\n if (needsCacheKey) {\n _cacheKey = generateCacheKey(fetcherConfig);\n }\n\n // The initial data, which is used as the first response instead of sending the request\n let initialResponse: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n // Cache handling logic\n if (_cacheKey && isCacheEnabled) {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(_cacheKey, cacheTime, fetcherConfig);\n\n if (cached) {\n return cached;\n }\n\n // Restore the response from the cache store, e.g. one saved during a previous page load\n if (fetcherConfig.cacheStore) {\n const stored = await getStoredCache(_cacheKey, fetcherConfig);\n const restored =\n stored &&\n toResponse(\n stored.data,\n _cacheKey,\n fetcherConfig,\n );\n\n // A stale response is shown until the request below revalidates it\n if (\n restored &&\n restoreCache(\n _cacheKey,\n { ...stored, data: restored },\n fetcherConfig.cacheStore,\n )\n ) {\n return restored;\n }\n }\n\n // While there's no cached response, the initial data, e.g. data rendered on the server, is cached as the response\n if (\n fetcherConfig.initialData !== undefined &&\n !getCacheData(_cacheKey) &&\n !isCacheBypassed(fetcherConfig)\n ) {\n initialResponse = toResponse(\n {\n data: fetcherConfig.initialData,\n status: 200,\n statusText: '',\n headers: {},\n },\n _cacheKey,\n fetcherConfig,\n );\n }\n }\n\n // Deduplication logic\n if (_cacheKey && dedupeTime) {\n const inflight = getInFlightPromise<\n FetchResponse\n >(_cacheKey, dedupeTime);\n\n if (inflight) {\n return inflight;\n }\n }\n\n const retryConfig = fetcherConfig.retry || {};\n const { retries = 0, resetTimeout } = retryConfig;\n\n // The signal passed to the request. Each attempt replaces it in the config with a signal of its own.\n const userSignal = fetcherConfig.signal;\n\n // The actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation: boolean, attempt = 0) => {\n // The cached response to revalidate. It's read before the cache is marked as fetching below.\n const cached =\n isETagEnabled &&\n getCacheData(\n _cacheKey,\n );\n\n // If cache key is specified, we will handle optimistic updates\n // and mark the request as in-flight, so to catch \"fetching\" state.\n // This is useful for Optimistic UI updates (e.g., showing loading spinners).\n if (!attempt) {\n // The initial data is only used once, as the first response\n if (initialResponse) {\n const response = initialResponse;\n\n initialResponse = null;\n\n return response;\n }\n\n if (_cacheKey && !isStaleRevalidation) {\n if (staleTime) {\n const existingCache = getCachedResponse(\n _cacheKey,\n cacheTime,\n fetcherConfig,\n );\n\n // Don't notify subscribers when cache exists\n // Let them continue showing stale data during background revalidation\n if (!existingCache) {\n setCache(_cacheKey, inFlightResponse, cacheTime, staleTime);\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n } else {\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n }\n\n // Attach cache key so that it can be reused in interceptors or in the final response\n fetcherConfig.cacheKey = _cacheKey;\n }\n\n const url = fetcherConfig.url as string;\n\n // Add the request to the queue. Make sure to handle deduplication, cancellation, timeouts in accordance to retry settings\n const controller = markInFlight(\n _cacheKey,\n url,\n timeout,\n dedupeTime || 0,\n !!cancellable,\n // Enable timeout either by default or when retries & resetTimeout are enabled\n !!(timeout && (!attempt || resetTimeout)),\n );\n\n // Do not create a shallow copy to maintain idempotency here.\n // This ensures the original object is mutated by interceptors whenever needed, including retry logic.\n const requestConfig = fetcherConfig;\n\n requestConfig.signal = controller.signal;\n\n // The request is aborted along with the signal passed to it, which may have been aborted already\n const abort = () => controller.abort(userSignal!.reason);\n\n if (userSignal) {\n if (userSignal.aborted) {\n abort();\n } else {\n userSignal.addEventListener('abort', abort);\n }\n }\n\n let output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n let response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n try {\n if (fetcherConfig.onRequest) {\n // Zero-allocation yield to microtask queue so the outer fetchf() can call setInFlightPromise()\n // before onRequest interceptors run. This ensures that if onRequest triggers\n // another fetchf() with the same cacheKey, getInFlightPromise() finds item[4].\n // On retries (attempt > 0), setInFlightPromise() was already called during the first attempt.\n // The promise stored in item[4] is the outer doRequestPromise which covers all retries.\n // So the race only matters on the very first attempt when the outer scope hasn't had a chance to call setInFlightPromise() yet.\n if (_cacheKey && dedupeTime && !attempt) {\n await null;\n }\n\n await applyInterceptors(fetcherConfig.onRequest, requestConfig);\n }\n\n // Custom fetcher\n const fn = fetcherConfig.fetcher;\n const init = withETag(requestConfig, cached);\n\n response = (fn\n ? await fn(\n url,\n init,\n )\n : // Uploads with onUploadProgress are sent in a way that reports their progress\n await (requestConfig.onUploadProgress && requestConfig.body\n ? fetchWithUploadProgress(url, requestConfig)\n : fetch(url, init as RequestInit))) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Reports the download progress while the body is read\n response = withDownloadProgress(\n response,\n requestConfig.onDownloadProgress,\n );\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\n // The server answered that the cached response is still valid, so it's reused instead of being sent again.\n // Like other cached responses, it has been parsed and transformed already.\n if (init !== requestConfig && response.status === 304) {\n return cached as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n // Case 1: Native Response instance\n if (typeof Response === FUNCTION && response instanceof Response) {\n response.data = requestConfig.parser\n ? await requestConfig.parser(response)\n : await parseResponseData(response, requestConfig.responseType);\n } else if (fn) {\n // Case 2: Custom fetcher that returns a response object\n if (!('data' in response && 'body' in response)) {\n // Case 3: Raw data, wrap it\n response = { data: response } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n }\n\n // Attach config and data to the response\n // This is useful for custom fetchers that do not return a Response instance\n // and for interceptors that may need to access the request config\n response.config = requestConfig;\n\n // Check if the response status is not outside the range 200-299 and if so, output error\n // This is the pattern for fetch responses as per spec, but custom fetchers may not follow it so we check for `ok` property\n if (response.ok !== undefined && !response.ok) {\n throw new ResponseError(\n requestConfig.method +\n ' to ' +\n url +\n ' failed! Status: ' +\n (response.status || null),\n requestConfig,\n response,\n );\n }\n }\n\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig);\n\n const onResponse = fetcherConfig.onResponse;\n\n if (onResponse) {\n await applyInterceptors(onResponse, output);\n }\n } catch (_error) {\n const error = _error as ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Append additional information to Network, CORS or any other fetch() errors\n enhanceError(\n error,\n response,\n requestConfig,\n );\n\n // Prepare Extended Response\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig, error);\n } finally {\n if (userSignal) {\n userSignal.removeEventListener('abort', abort);\n }\n }\n\n return output;\n };\n\n // Inline and minimize function wrappers for performance\n // When retries are enabled, forward isStaleRevalidation so the first attempt\n // of a background SWR revalidation doesn't incorrectly mark the request as in-flight\n const baseRequest =\n retries > 0\n ? (isStaleRevalidation: boolean) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const { onLoadingSlow, loadingTimeout } = fetcherConfig;\n\n // Calls onLoadingSlow once a request, including its retries, is still pending after loadingTimeout.\n // Background revalidations don't show a loading state, so they are never considered slow.\n const request =\n onLoadingSlow && loadingTimeout\n ? async (isStaleRevalidation: boolean) => {\n if (isStaleRevalidation) {\n return baseRequest(isStaleRevalidation);\n }\n\n const timer = setTimeout(\n () => applyInterceptors(onLoadingSlow, fetcherConfig).catch(noop),\n loadingTimeout,\n );\n\n try {\n return await baseRequest(isStaleRevalidation);\n } finally {\n clearTimeout(timer);\n }\n }\n : baseRequest;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n request,\n fetcherConfig,\n );\n\n // Avoid unnecessary function wrapping if polling is not enabled\n const doRequestPromise = pollingInterval\n ? withPolling(\n requestWithErrorHandling,\n pollingInterval,\n fetcherConfig.shouldStopPolling,\n fetcherConfig.maxPollingAttempts,\n fetcherConfig.pollingDelay,\n fetcherConfig.refreshWhenHidden,\n fetcherConfig.refreshWhenOffline,\n userSignal,\n )\n : requestWithErrorHandling();\n\n // If deduplication is enabled, store the in-flight promise immediately\n if (_cacheKey) {\n if (dedupeTime) {\n setInFlightPromise(_cacheKey, doRequestPromise);\n }\n\n // Only register revalidator when revalidation features are actually requested\n if (staleTime || refetchOnFocus || refetchOnReconnect) {\n addRevalidator(\n _cacheKey,\n requestWithErrorHandling,\n undefined,\n staleTime,\n requestWithErrorHandling,\n !!refetchOnFocus,\n !!refetchOnReconnect,\n fetcherConfig.focusThrottleInterval,\n );\n }\n }\n\n return doRequestPromise;\n}\n\n/**\n * Recreates a response from its copy in a cache store.\n * The data was transformed before it was stored, so it isn't transformed again.\n *\n * @param stored - The stored copy of the response.\n * @param cacheKey - The cache key of the request.\n * @param config - The request configuration.\n * @returns The response, or null if the stored copy is invalid, e.g. has an unknown status.\n */\nfunction toResponse(\n stored: StoredResponse,\n cacheKey: string,\n config: RequestConfig,\n): FetchResponse | null {\n try {\n // Without the Fetch API (e.g. with a custom fetcher in tests), a plain response object is used\n const response = (typeof Response === FUNCTION\n ? new Response(null, stored)\n : {\n ok: true,\n status: stored.status,\n statusText: stored.statusText,\n headers: stored.headers,\n }) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n response.data = stored.data as typeof response.data;\n config.cacheKey = cacheKey;\n\n const output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, {\n ...config,\n select: undefined,\n flattenResponse: false,\n defaultResponse: undefined,\n });\n\n output.config = config;\n\n return output;\n } catch {\n return null;\n }\n}\n\n/**\n * Asks the server whether a cached response is still valid, by sending its ETag in the If-None-Match header.\n * Then the server can answer 304 Not Modified instead of sending the response again.\n * Requests with an If-None-Match header of their own are sent as they are.\n *\n * @param config - The request configuration.\n * @param cached - The cached response of the request, if any.\n * @returns A copy of the configuration with the If-None-Match header, or the configuration itself if the cached response has no ETag.\n */\nfunction withETag(\n config: RequestConfig,\n cached: FetchResponse | null | false,\n): RequestConfig {\n const etag = cached && !cached.error && cached.headers && cached.headers.etag;\n const headers = etag && processHeaders(config.headers as HeadersObject);\n\n return headers && !headers['if-none-match']\n ? { ...config, headers: { ...headers, 'if-none-match': etag } }\n : config;\n}\n","import type {\n ApiHandlerConfig,\n ApiHandlerDefaultMethods,\n ApiHandlerMethods,\n RequestConfigUrlRequired,\n} from './types/api-handler';\nimport { fetchf } from '.';\nimport { mergeConfigs } from './config-handler';\nimport { hasOwn } from './utils';\n\n/**\n * Creates an instance of API Handler.\n * It creates an API fetcher function using native fetch() or a custom fetcher if passed as \"fetcher\".\n * @see https://github.com/MattCCC/fetchff#configuration\n *\n * @param {Object} config - Configuration object for the API fetcher (see link above for full options).\n * @param {Object} config.endpoints - An object containing endpoint definitions.\n * @param {string} [config.baseURL] - The base URL for the API.\n * @param {Object} [config.headers] - Optional default headers to include in every request.\n * @param {Function} [config.onError] - Optional callback function for handling errors.\n * @returns API handler functions and endpoints to call\n *\n * @example\n * // Define endpoint paths\n * const endpoints = {\n * getUser: '/user',\n * createPost: '/post',\n * };\n *\n * // Create the API fetcher with configuration\n * const api = createApiFetcher({\n * endpoints,\n * apiUrl: 'https://example.com/api',\n * onError(error) {\n * console.log('Request failed', error);\n * },\n * headers: {\n * 'my-auth-key': 'example-auth-key-32rjjfa',\n * },\n * });\n *\n * // Fetch user data\n * const response = await api.getUser({ userId: 1, ratings: [1, 2] })\n */\nfunction createApiFetcher<\n EndpointTypes extends object,\n EndpointsSettings = never,\n>(config: ApiHandlerConfig) {\n const endpoints = config.endpoints;\n\n /**\n * Triggered when trying to use non-existent endpoints\n *\n * @param endpointName Endpoint Name\n * @returns {Promise}\n */\n async function handleNonImplemented(endpointName: string): Promise {\n console.error('Add ' + endpointName + \" to 'endpoints'.\");\n\n return null;\n }\n\n const apiHandler: ApiHandlerDefaultMethods = {\n config,\n endpoints,\n /**\n * Handle Single API Request\n * It considers settings in following order: per-request settings, global per-endpoint settings, global settings.\n *\n * @param endpointName - The name of the API endpoint to call.\n * @param requestConfig - Additional configuration for the request.\n * @returns A promise that resolves with the response from the API provider.\n */\n async request(endpointName, requestConfig = {}) {\n // Use global and per-endpoint settings\n // Only own properties are endpoints, not ones inherited like \"constructor\"\n const endpointConfig = hasOwn(endpoints, endpointName as string)\n ? endpoints[endpointName]\n : undefined;\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // URL parsers ignore leading control characters and spaces, drop tabs and newlines,\n // and treat backslashes like slashes, so check the URL the way it will be resolved\n const resolvedUrl = url\n .replace(/[\\t\\n\\r]/g, '')\n // eslint-disable-next-line no-control-regex -- matching control characters is the point\n .replace(/^[\\x00-\\x20]+/, '');\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (/^[/\\\\]{2}/.test(resolvedUrl)) {\n throw new Error('Protocol-relative URLs not allowed.');\n }\n\n // Prevent potential Server-Side Request Forgery attack and leakage of credentials when same instance is used for external requests\n // Any scheme counts here, as e.g. \"http:\\\\host\" or \"http:host\" can also point to another host\n const mergedConfig = /^[a-z][a-z\\d+\\-.]*:/i.test(resolvedUrl)\n ? // Merge endpoints configs for absolute URLs only if urls match\n endpointConfig && endpointConfig.url === url\n ? mergeConfigs(_endpointConfig, requestConfig)\n : requestConfig\n : mergeConfigs(mergeConfigs(config, _endpointConfig), requestConfig);\n\n // We prevent potential Server-Side Request Forgery attack and leakage of credentials as the same instance is not used for external requests\n // Retrigger fetch to ensure completely new instance of handler being triggered for external URLs\n return fetchf(url, mergedConfig);\n },\n };\n\n /**\n * Maps all API requests using native Proxy\n *\n * @param {*} prop Caller\n */\n return new Proxy>(\n apiHandler as ApiHandlerMethods,\n {\n get(_target, prop: string | symbol) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Symbols (e.g. inspection hooks) are never endpoints, and returning a function\n // for \"then\" would make the instance a thenable that never settles when awaited\n if (typeof prop === 'symbol' || prop === 'then') {\n return undefined;\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (hasOwn(endpoints, prop)) {\n return apiHandler.request.bind(null, prop);\n }\n\n return handleNonImplemented.bind(null, prop);\n },\n },\n );\n}\n\nexport { createApiFetcher };\n"]} \ No newline at end of file diff --git a/dist/node/index.js b/dist/node/index.js index ba215b2..347fd11 100644 --- a/dist/node/index.js +++ b/dist/node/index.js @@ -1,3 +1,3 @@ -'use strict';var z="application/",te=z+"json",$e="charset=utf-8",_="Content-Type",D="undefined",Ie="object",x="string",b="function",k="AbortError",et="TimeoutError",O="GET",re="HEAD",me="reject",Re=2147483647;var rt=10,S=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);function J(e){return e instanceof URLSearchParams}function g(e){return e!==null&&typeof e===Ie}function B(e){let t=S(e,"__proto__"),r=S(e,"constructor"),s=S(e,"prototype");if(!t&&!r&&!s)return e;let n={};for(let a of Object.keys(e))a!=="__proto__"&&a!=="constructor"&&a!=="prototype"&&(n[a]=e[a]);return n}function st(e){let t=Object.create(null);return Object.keys(e).sort().forEach(r=>t[r]=e[r]),t}function tt(e,t){return t?e+(e.includes("?")?"&":"?")+t:e}function at(e,t){if(!t)return e;if(J(t)){let u=t.toString();return tt(e,u)}let r=[],s=encodeURIComponent,n=(u,c)=>{c=typeof c===b?c():c,c=c??"",r[r.length]=s(u)+"="+s(c);},a=(u,c,f=0)=>{if(f>=rt)return r;let l,m,p;if(u)if(Array.isArray(c))for(l=0,m=c.length;l{let o=n||a;if(S(r,o)){let i=r[o];if(i!=null){let u=encodeURIComponent(String(i));if(u==="."||u==="..")throw new Error('Path params "." and ".." not allowed.');return u}}return s})}function ot(e){return /^[a-z][a-z\d+\-.]*:\/\//i.test(e)}var h=()=>Date.now(),C=()=>{};function se(e){let t=typeof e;return e==null?false:t===x||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==D&&typeof globalThis.Buffer!==D&&globalThis.Buffer.isBuffer(e)||e instanceof Date||J(e)?false:!!(g(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===b))}var ae=(e,t)=>new Promise(r=>{let s=()=>{clearTimeout(n),t&&t.removeEventListener("abort",s),r(true);},n=setTimeout(s,Math.min(e,Re));t&&(t.aborted?s():t.addEventListener("abort",s));});function ve(e,t=0){return t>=rt?e:e&&g(e)&&typeof e.data!==D?ve(e.data,t+1):e}function E(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,s)=>{t[s.toLowerCase()]=r;});else for(let r in e)S(e,r)&&r!=="__proto__"&&(t[r.toLowerCase()]=e[r]);return t}function it(){return typeof window!==D&&typeof window.addEventListener===b}function W(e,t){if(typeof DOMException!==D)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Se=()=>{let e=typeof navigator!==D&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)},ut=()=>typeof document!==D&&document.visibilityState==="hidden",ct=()=>typeof navigator!==D&&navigator.onLine===false;async function F(e,t,...r){if(!e)return;let s=n=>n&&g(t)&&g(n)&&Object.assign(t,B(n));if(typeof e===b)s(await e(t,...r));else if(Array.isArray(e))for(let n of e)s(await n(t,...r));}var ye=class extends Error{constructor(t,r,s){super(t),this.request=r,this.response=s,this.status=s?s.status:0,this.statusText=s?s.statusText:"",this.config=r,this.isCancelled=false,this.name="FetchError";}};var he=class extends ye{constructor(t,r,s){super(t,r,s),this.name="ResponseError";}};var be=600,Pe=1e3,Qe=Array(be).fill(0).map(()=>[]),U=new Map,ge=0,Fe=0,A=null,lt=([e,t])=>{U.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(C);}catch{}},M=(e,t,r)=>{Y(e);let s=r/Pe+(A&&h()!==Fe?1:0);if(r=be||r%Pe!==0){U.set(e,[setTimeout(lt.bind(null,[e,t]),Math.min(r,Re))]);return}let n=(ge+s)%be;Qe[n].push([e,t]),U.set(e,n),A||(Fe=h(),A=setInterval(()=>{ge=(ge+1)%be,Fe=h();let a=Qe[ge];for(let o=0;o{let t=U.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Qe[t];for(let s=0;s{dt(e,W(t+" aborted due to timeout",et));},r),c}async function dt(e,t=null){if(e){let r=G.get(e);r&&(t&&r[0].abort(t),De(e));}}function De(e){Y(e),G.delete(e);}function pt(e,t){let r=G.get(e);r&&(r[4]=t);}function He(e,t){if(!e)return null;let r=G.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!a[s]||r&&n-a[1]{r[t]&&jt(s);});}function Ne(e){if(V.has(e))return;let t=Rt.bind(null,e,true,e==="focus"),r=mt.get(e);if(r){let s=r(t);V.set(e,s);return}it()&&(window.addEventListener(e,t),V.set(e,()=>window.removeEventListener(e,t)));}function yt(e){let t=V.get(e);t&&(t(),V.delete(e));}function ht(e,t,r,s,n,a,o,i){let u=Z.get(e)||[];u[0]=t,u[1]=h(),u[2]=Ut,u[3]=s,u[4]=n,u[5]=a,u[6]=o,u[7]=i,Z.set(e,u),a&&Ne("focus"),o&&Ne("online"),s&&M("s:"+e,Ee.bind(null,e,true),s*1e3);}function jt(e){Z.delete(e),Y("s:"+e);}var ne=new Map;function Kt(e,t){let r=ne.get(e);r||ne.set(e,r=new Set),r.add(t);}function zt(e,t){let r=ne.get(e);r&&(r.delete(t),r.size===0&&ne.delete(e));}function L(e,t){let r=ne.get(e);if(r)if(r.size===1){let s=r.values().next().value;s(t);}else r.forEach(s=>s(t));}function kt(e,t){return e?(Kt(e,t),()=>{zt(e,t);}):C}var Te=(Se()?60:30)*1e3,j={strategy:me,timeout:Te,loadingTimeout:Te/10,focusThrottleInterval:5e3,headers:{Accept:te+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:Te/30,maxDelay:Te,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504],methods:[O,re,"PUT","DELETE","OPTIONS","TRACE"]}};function Jt(e){let t=B(e);return $({retry:j.retry,headers:j.headers},t,j)}function Wt(){return {...j}}function _e(e,t){let r=$(j,t?B(t):{});return Yt(e,r)}function Yt(e,t){let r=t.method;r=r?r.toUpperCase():O;let s;r!==O&&r!==re&&(s=t.body??t.data,s&&typeof s!==x&&se(s)&&(s=JSON.stringify(s))),Gt(t.headers,s);let n=t.withCredentials?"include":t.credentials,a=nt(e,t.urlPathParams),o=at(a,t.params),u=ot(e)?"":t.baseURL||t.apiUrl||"",c=u&&o&&!u.endsWith("/")&&!/^[/?#]/.test(o)?"/":"";return t.url=u+c+o,t.method=r,t.credentials=n,t.body=s,t}function Gt(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==D&&t instanceof Blob||typeof ReadableStream!==D&&t instanceof ReadableStream)return;let r;if(J(t))r=z+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=z+"octet-stream";else if(se(t))r=te+";"+$e;else return;e instanceof Headers?e.has(_)||e.set(_,r):g(e)&&!Array.isArray(e)&&!E(e)[_.toLowerCase()]&&(e[_]=r);}var Xt=["onRequest","onResponse","onError","onLoadingSlow"];function $(e,t,r={}){Object.assign(r,e,t),Pt("retry",e,t,r),Pt("headers",e,t,r);for(let s of Xt)Vt(s,e,t,r);return r}function Vt(e,t,r,s){let n=t[e],a=r[e];n&&a?s[e]=e==="onResponse"?[].concat(a,n):[].concat(n,a):(n||a)&&(s[e]=n||a);}function Pt(e,t,r,s){let n=t[e],a=r[e];if(a)if(e==="headers"){let o=n instanceof Headers||a instanceof Headers,i=o?E(n):{...n},u=o?E(a):B(a);for(let c of Object.keys(u)){let f=c.toLowerCase();for(let l in i)l.toLowerCase()===f&&delete i[l];i[c]=u[c];}s[e]=i;}else s[e]={...n,...B(a)};else a===void 0&&g(n)&&!(n instanceof Headers)&&(s[e]={...n});}var Q=new Map,ie=new Map,oe="|",Ue=64,Zt=/[^\w\-_|/:@.?=&~%#]/g,$t=/[^\w\-_|/:@.?=&~%#]/,er=/^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;function ue(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===x?r:r(e);let{url:s="",method:n=O,headers:a=null,body:o=null,credentials:i="same-origin"}=e,u="";if(a){let l;a instanceof Headers?l=E(a):l=a;let m=Object.keys(l),p=m.length;p>1&&m.sort();let q="";for(let T=0;T{f+=m+"="+(typeof l===x?l:"F"+bt(l))+"&";}),f.length>Ue&&(f=X(f));else if(g(o)&&!se(o))f="B"+bt(o);else {let l=g(o)?JSON.stringify(st(o)):String(o);f=l.length>Ue?X(l):l;}return Dt(c+oe+f)}var gt=new WeakMap,tr=0;function bt(e){let t=gt.get(e);return t||gt.set(e,t=++tr),t}function Dt(e){return $t.test(e)?e.replace(Zt,"")+oe+X(e):e}function Me(e){return e.expiry?h()>e.expiry:false}function Le(e){if(!e)return null;let t=Q.get(e);return t?t.data:null}function ce(e){return Q.get(e)}function we(e,t,r,s){if(r===0){le(e);return}let n=h(),a=r?r*1e3:0,o=s?s*1e3:0;Q.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+a}),a>0&&Et(e,a);}function Et(e,t){M("c:"+e,()=>le(e,true),t);}function le(e,t=false){if(t){let s=ce(e);if(!s||!Me(s))return}Q.delete(e);let r=ie.get(e);r&&(ie.delete(e),je(()=>r.delete(e)));}function je(e){try{Promise.resolve(e()).catch(C);}catch{}}function Tt(e,t){let r=Q.get(e);if(t&&r){let{data:s,status:n,statusText:a,headers:o}=r.data;ie.set(e,t),je(()=>t.set(e,{...r,data:{data:s,status:n,statusText:a,headers:o}}));}}async function wt(e,t){let r=t.cacheStore;if(!r||xe(t))return null;let s;try{s=await r.get(e);}catch{return null}return !s||Q.has(e)?null:Me(s)?(je(()=>r.delete(e)),null):s}function xt(e,t,r){return Q.set(e,t),ie.set(e,r),t.expiry&&Et(e,t.expiry-h()),L(e,t.data),!t.stale||h(){let s=t.defaultResponse,n=t.cacheKey,a=Ke.bind(null,n);if(!e)return {ok:false,error:r,data:s??null,headers:null,config:t,mutate:a,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===b&&e instanceof Response,i=e.data;s!==void 0&&(i==null||/^\[object (Object|Array)\]$/.test(Object.prototype.toString.call(i))&&Object.keys(i).length===0)&&(e.data=i=s),t.flattenResponse&&(e.data=i=ve(i)),t.select&&(e.data=i=t.select(i));let u=E(e.headers);if(o){let c={body:e.body,bodyUsed:e.bodyUsed,ok:e.ok,redirected:e.redirected,type:e.type,url:e.url,status:e.status,statusText:e.statusText,blob:async()=>i instanceof ArrayBuffer?new Blob([i]):new Blob,json:async()=>i,text:async()=>i,clone:()=>({...c}),arrayBuffer:async()=>i instanceof ArrayBuffer?i:new ArrayBuffer(0),formData:async()=>i instanceof FormData?i:new FormData,bytes:async()=>new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),error:r,data:i,headers:u,config:t,mutate:a,isFetching:false,isSuccess:e.ok&&!r,isError:!!r};return c}return g(e)&&Object.assign(e,{error:r,headers:u,isFetching:false,mutate:a,isSuccess:e.ok&&!r,isError:!!r}),e};function qt(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function rr(e){if(!e)return null;let t=e.headers||{},r=t["retry-after"];if(r){let o=Number(r);if(!isNaN(o)&&o>=0)return o*1e3;let i=qt(r);if(i!==null)return i}let s="ratelimit-reset",n=t[s+"-after"]||t["x-"+s+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let a=t[s+"-at"]||t["x-"+s+"-at"];return a?qt(a):null}async function Ot(e,t){let{retries:r=0,delay:s=0,backoff:n=1,maxDelay:a,retryOn:o=[],shouldRetry:i,jitter:u,methods:c}=t,f=0,l=s,m=r>0?r:0,p;for(;f<=m;){if(f>0&&p){let d=p.config,H=d.onRetry;H&&(await F(H,p,f),d._isAutoKey&&(d._prevKey=d.cacheKey,d.cacheKey=ue(d,false)));}p=await e(f>0,f);let q=p.error;if(q?await sr(p,f,m,i,o,c):!(i&&fo.toUpperCase()===e.config.method)))}function ar(e,t){return typeof t===b?t(e):t?Math.random()*e:e}async function Bt(e,t,r,s=0,n=0,a=false,o=false,i){if(!t)return e();let u=0,c;for(;(s===0||u0&&await ae(n,i),c=await e(),u++,!(s>0&&u>=s||!t||r&&r(c,u)));)do if(await ae(t,i),i&&i.aborted)return c;while(!a&&ut()||!o&&ct());return c}var nr=[204,205,304],or=/^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/,At=e=>typeof ReadableStream!==D&&e instanceof ReadableStream,qe=(e,t)=>({loaded:e,total:t,progress:t?e/t:void 0});function It(e,t){let r=t.body;return typeof XMLHttpRequest!==D&&!At(r)?ir(e,t,r):ur(e,t,r)}function ir(e,t,r){return new Promise((s,n)=>{let a=new XMLHttpRequest,o=t.signal,i=()=>a.abort(),u=f=>{o.removeEventListener("abort",i);try{f();}catch(l){n(l);}};a.open(t.method,e),a.responseType="blob",a.withCredentials=t.credentials==="include",new Headers(t.headers).forEach((f,l)=>or.test(l)||a.setRequestHeader(l,f)),a.upload.onprogress=f=>t.onUploadProgress(qe(f.loaded,f.lengthComputable?f.total:void 0)),a.onload=()=>u(()=>{let f=new Headers;for(let m of a.getAllResponseHeaders().split(/\r?\n/)){let p=m.indexOf(":");p>0&&f.append(m.slice(0,p),m.slice(p+1).trim());}let l=new Response(nr.includes(a.status)?null:a.response,{status:a.status,statusText:a.statusText,headers:f});Object.defineProperty(l,"url",{value:a.responseURL}),s(l);}),a.onerror=()=>u(()=>n(new TypeError("Network request failed")));let c=()=>u(()=>n(o.reason||W("The request was aborted",k)));if(a.onabort=c,o.aborted)return c();o.addEventListener("abort",i),a.send(r);})}async function ur(e,t,r){let s=new Headers(t.headers),n=r,a;if(!At(r)){let i=r instanceof Blob?r:await new Response(r).blob();a=i.size,n=i.stream(),i.type&&!s.has("content-type")&&s.set("content-type",i.type);}let o=0;return fetch(e,{...t,headers:s,body:n.pipeThrough(new TransformStream({transform(i,u){o+=i.byteLength,t.onUploadProgress(qe(o,a)),u.enqueue(i);}})),duplex:"half"})}function vt(e,t){if(!t||typeof Response!==b||!(e instanceof Response)||!e.body)return e;let r=e.headers,s=r.has("content-encoding")?void 0:Number(r.get("content-length"))||void 0,n=0,a=new Response(e.body.pipeThrough(new TransformStream({transform(o,i){n+=o.byteLength,t(qe(n,s&&Math.max(s,n))),i.enqueue(o);}})),e);for(let o of ["url","redirected","type"])Object.defineProperty(a,o,{value:e[o]});return a}async function St(e,t,r){let s=await t(e),n=s.error;if(!n)return ze(s,r),s;r.onError&&await F(r.onError,n);let a=n.isCancelled,o=r.logger;if(!a&&o&&o.warn&&o.warn("FETCH ERROR",lr(n)),r.strategy==="defaultResponse"&&(s.data=r.defaultResponse??null),ze(s,r,true),!a||r.rejectCancelled){let u=r.strategy;if(u===me)throw n;u==="silent"&&await new Promise(()=>null);}return s}var cr=["authorization","proxy-authorization","cookie","x-api-key"];function lr(e){let t={...e.config,body:void 0,data:void 0,cacheKey:void 0,_prevKey:void 0,headers:E(e.config.headers)};for(let s of cr)t.headers[s]&&(t.headers[s]="[REDACTED]");let r=Object.assign(new Error(e.message),e,{config:t,request:t,response:e.response&&{...e.response,config:t}});return r.name=e.name,r.stack=e.stack,r}function Ft(e,t,r){e.status=e.status||t&&t.status||0,e.statusText=e.statusText||t&&t.statusText||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===k;}var ke=Object.freeze({isFetching:true});async function Oe(e,t=null){if(t&&typeof t.cacheKey=="string"){let y=fe(t.cacheKey,t.cacheTime,t);if(y)return y}let r=_e(e,t),{timeout:s,cancellable:n,cacheKey:a,dedupeTime:o,cacheTime:i,staleTime:u,refetchOnFocus:c,refetchOnReconnect:f,pollingInterval:l=0}=r,m=i!==void 0||u!==void 0,p=r.method,q=m&&(p===O||p===re)&&(r.etag??!r.fetcher),T=!!(a||s||o||m||n||c||f),d=null;T&&(d=ue(r));let H=null;if(d&&m){let y=fe(d,i,r);if(y)return y;if(r.cacheStore){let w=await wt(d,r),I=w&&Qt(w.data,d,r);if(I&&xt(d,{...w,data:I},r.cacheStore))return I}r.initialData!==void 0&&!Le(d)&&!xe(r)&&(H=Qt({data:r.initialData,status:200,statusText:"",headers:{}},d,r));}if(d&&o){let y=He(d,o);if(y)return y}let Je=r.retry||{},{retries:Ht=0,resetTimeout:Nt}=Je,N=r.signal,We=async(y,w=0)=>{let I=q&&Le(d);if(!w){if(H){let v=H;return H=null,v}d&&!y&&(u?fe(d,i,r)||(we(d,ke,i,u),L(d,ke)):L(d,ke)),r.cacheKey=d;}let ee=r.url,Ve=ft(d,ee,s,o||0,!!n,!!(s&&(!w||Nt))),P=r;P.signal=Ve.signal;let Ae=()=>Ve.abort(N.reason);N&&(N.aborted?Ae():N.addEventListener("abort",Ae));let pe,R=null;try{r.onRequest&&(d&&o&&!w&&await null,await F(r.onRequest,P));let v=r.fetcher,K=fr(P,I);if(R=v?await v(ee,K):await(P.onUploadProgress&&P.body?It(ee,P):fetch(ee,K)),R=vt(R,P.onDownloadProgress),g(R)){if(K!==P&&R.status===304)return I;if(typeof Response===b&&R instanceof Response?R.data=P.parser?await P.parser(R):await Ct(R,P.responseType):v&&("data"in R&&"body"in R||(R={data:R})),R.config=P,R.ok!==void 0&&!R.ok)throw new he(P.method+" to "+ee+" failed! Status: "+(R.status||null),P,R)}pe=Ce(R,P);let Ze=r.onResponse;Ze&&await F(Ze,pe);}catch(v){let K=v;Ft(K,R,P),pe=Ce(R,P,K);}finally{N&&N.removeEventListener("abort",Ae);}return pe},Be=Ht>0?y=>Ot((w,I)=>We(y,I),Je):We,{onLoadingSlow:Ye,loadingTimeout:Ge}=r,_t=Ye&&Ge?async y=>{if(y)return Be(y);let w=setTimeout(()=>F(Ye,r).catch(C),Ge);try{return await Be(y)}finally{clearTimeout(w);}}:Be,de=(y=false)=>St(y,_t,r),Xe=l?Bt(de,l,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay,r.refreshWhenHidden,r.refreshWhenOffline,N):de();return d&&(o&&pt(d,Xe),(u||c||f)&&ht(d,de,void 0,u,de,!!c,!!f,r.focusThrottleInterval)),Xe}function Qt(e,t,r){try{let s=typeof Response===b?new Response(null,e):{ok:!0,status:e.status,statusText:e.statusText,headers:e.headers};s.data=e.data,r.cacheKey=t;let n=Ce(s,{...r,select:void 0,flattenResponse:!1,defaultResponse:void 0});return n.config=r,n}catch{return null}}function fr(e,t){let r=t&&!t.error&&t.headers&&t.headers.etag,s=r&&E(e.headers);return s&&!s["if-none-match"]?{...e,headers:{...s,"if-none-match":r}}:e}function dr(e){let t=e.endpoints;async function r(n){return console.error("Add "+n+" to 'endpoints'."),null}let s={config:e,endpoints:t,async request(n,a={}){let o=S(t,n)?t[n]:void 0,i=o||{url:String(n)},u=i.url,c=u.replace(/[\t\n\r]/g,"").replace(/^[\x00-\x20]+/,"");if(/^[/\\]{2}/.test(c))throw new Error("Protocol-relative URLs not allowed.");let f=/^[a-z][a-z\d+\-.]*:/i.test(c)?o&&o.url===u?$(i,a):a:$($(e,i),a);return Oe(u,f)}};return new Proxy(s,{get(n,a){if(a in s)return s[a];if(!(typeof a=="symbol"||a==="then"))return S(t,a)?s.request.bind(null,a):r.bind(null,a)}})} +'use strict';var z="application/",te=z+"json",$e="charset=utf-8",_="Content-Type",D="undefined",Ie="object",x="string",b="function",k="AbortError",et="TimeoutError",O="GET",re="HEAD",pe="reject",Re=2147483647;var rt=10,S=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);function J(e){return e instanceof URLSearchParams}function g(e){return e!==null&&typeof e===Ie}function B(e){let t=S(e,"__proto__"),r=S(e,"constructor"),s=S(e,"prototype");if(!t&&!r&&!s)return e;let n={};for(let a of Object.keys(e))a!=="__proto__"&&a!=="constructor"&&a!=="prototype"&&(n[a]=e[a]);return n}function st(e){let t=Object.create(null);return Object.keys(e).sort().forEach(r=>t[r]=e[r]),t}function tt(e,t){return t?e+(e.includes("?")?"&":"?")+t:e}function at(e,t){if(!t)return e;if(J(t)){let u=t.toString();return tt(e,u)}let r=[],s=encodeURIComponent,n=(u,c)=>{c=typeof c===b?c():c,c=c??"",r[r.length]=s(u)+"="+s(c);},a=(u,c,f=0)=>{if(f>=rt)return r;let l,p,m;if(u)if(Array.isArray(c))for(l=0,p=c.length;l{let o=n||a;if(S(r,o)){let i=r[o];if(i!=null){let u=encodeURIComponent(String(i));if(u==="."||u==="..")throw new Error('Path params "." and ".." not allowed.');return u}}return s})}function ot(e){return /^[a-z][a-z\d+\-.]*:\/\//i.test(e)}var h=()=>Date.now(),C=()=>{};function se(e){let t=typeof e;return e==null?false:t===x||t==="number"||t==="boolean"||Array.isArray(e)?true:typeof globalThis!==D&&typeof globalThis.Buffer!==D&&globalThis.Buffer.isBuffer(e)||e instanceof Date||J(e)?false:!!(g(e)&&(Object.getPrototypeOf(e)===Object.prototype||typeof e.toJSON===b))}var ae=(e,t)=>new Promise(r=>{let s=()=>{clearTimeout(n),t&&t.removeEventListener("abort",s),r(true);},n=setTimeout(s,Math.min(e,Re));t&&(t.aborted?s():t.addEventListener("abort",s));});function ve(e,t=0){return t>=rt?e:e&&g(e)&&typeof e.data!==D?ve(e.data,t+1):e}function E(e){if(!e)return {};let t={};if(e instanceof Headers)e.forEach((r,s)=>{t[s.toLowerCase()]=r;});else for(let r in e)S(e,r)&&r!=="__proto__"&&(t[r.toLowerCase()]=e[r]);return t}function it(){return typeof window!==D&&typeof window.addEventListener===b}function W(e,t){if(typeof DOMException!==D)return new DOMException(e,t);let r=new Error(e);return r.name=t,r}var Se=()=>{let e=typeof navigator!==D&&navigator.connection;return e&&["slow-2g","2g","3g"].includes(e.effectiveType)},ut=()=>typeof document!==D&&document.visibilityState==="hidden",ct=()=>typeof navigator!==D&&navigator.onLine===false;async function F(e,t,...r){if(!e)return;let s=n=>n&&g(t)&&g(n)&&Object.assign(t,B(n));if(typeof e===b)s(await e(t,...r));else if(Array.isArray(e))for(let n of e)s(await n(t,...r));}var ye=class extends Error{constructor(t,r,s){super(t),this.request=r,this.response=s,this.status=s?s.status:0,this.statusText=s?s.statusText:"",this.config=r,this.isCancelled=false,this.name="FetchError";}};var he=class extends ye{constructor(t,r,s){super(t,r,s),this.name="ResponseError";}};var be=600,Pe=1e3,Qe=Array(be).fill(0).map(()=>[]),U=new Map,ge=0,Fe=0,A=null,lt=([e,t])=>{U.delete(e);try{let r=t();r&&r instanceof Promise&&r.catch(C);}catch{}},M=(e,t,r)=>{Y(e);let s=r/Pe+(A&&h()!==Fe?1:0);if(r=be||r%Pe!==0){U.set(e,[setTimeout(lt.bind(null,[e,t]),Math.min(r,Re))]);return}let n=(ge+s)%be;Qe[n].push([e,t]),U.set(e,n),A||(Fe=h(),A=setInterval(()=>{ge=(ge+1)%be,Fe=h();let a=Qe[ge];for(let o=0;o{let t=U.get(e);if(t!==void 0){if(Array.isArray(t))clearTimeout(t[0]);else {let r=Qe[t];for(let s=0;s{dt(e,W(t+" aborted due to timeout",et));},r),c}async function dt(e,t=null){if(e){let r=G.get(e);r&&(t&&r[0].abort(t),De(e));}}function De(e){Y(e),G.delete(e);}function mt(e,t){let r=G.get(e);r&&(r[4]=t);}function He(e,t){if(!e)return null;let r=G.get(e);return r&&r[4]&&!r[3]&&h()-r[2]{if(!a[s]||r&&n-a[1]{r[t]&&jt(s);});}function Ne(e){if(V.has(e))return;let t=Rt.bind(null,e,true,e==="focus"),r=pt.get(e);if(r){let s=r(t);V.set(e,s);return}it()&&(window.addEventListener(e,t),V.set(e,()=>window.removeEventListener(e,t)));}function yt(e){let t=V.get(e);t&&(t(),V.delete(e));}function ht(e,t,r,s,n,a,o,i){let u=Z.get(e)||[];u[0]=t,u[1]=h(),u[2]=Ut,u[3]=s,u[4]=n,u[5]=a,u[6]=o,u[7]=i,Z.set(e,u),a&&Ne("focus"),o&&Ne("online"),s&&M("s:"+e,Ee.bind(null,e,true),s*1e3);}function jt(e){Z.delete(e),Y("s:"+e);}var ne=new Map;function Kt(e,t){let r=ne.get(e);r||ne.set(e,r=new Set),r.add(t);}function zt(e,t){let r=ne.get(e);r&&(r.delete(t),r.size===0&&ne.delete(e));}function L(e,t){let r=ne.get(e);if(r)if(r.size===1){let s=r.values().next().value;s(t);}else r.forEach(s=>s(t));}function kt(e,t){return e?(Kt(e,t),()=>{zt(e,t);}):C}var Te=(Se()?60:30)*1e3,j={strategy:pe,timeout:Te,loadingTimeout:Te/10,focusThrottleInterval:5e3,headers:{Accept:te+", text/plain, */*","Accept-Encoding":"gzip, deflate, br"},retry:{delay:Te/30,maxDelay:Te,resetTimeout:true,backoff:1.5,retryOn:[408,409,425,429,500,502,503,504],methods:[O,re,"PUT","DELETE","OPTIONS","TRACE"]}};function Jt(e){let t=B(e);return $({retry:j.retry,headers:j.headers},t,j)}function Wt(){return {...j}}function _e(e,t){let r=$(j,t?B(t):{});return Yt(e,r)}function Yt(e,t){let r=t.method;r=r?r.toUpperCase():O;let s;r!==O&&r!==re&&(s=t.body??t.data,s&&typeof s!==x&&se(s)&&(s=JSON.stringify(s))),Gt(t.headers,s);let n=t.withCredentials?"include":t.credentials,a=nt(e,t.urlPathParams),o=at(a,t.params),u=ot(e)?"":t.baseURL||t.apiUrl||"",c=u&&o&&!u.endsWith("/")&&!/^[/?#]/.test(o)?"/":"";return t.url=u+c+o,t.method=r,t.credentials=n,t.body=s,t}function Gt(e,t){if(!e||!t||t instanceof FormData||typeof Blob!==D&&t instanceof Blob||typeof ReadableStream!==D&&t instanceof ReadableStream)return;let r;if(J(t))r=z+"x-www-form-urlencoded";else if(t instanceof ArrayBuffer||ArrayBuffer.isView(t))r=z+"octet-stream";else if(se(t))r=te+";"+$e;else return;e instanceof Headers?e.has(_)||e.set(_,r):g(e)&&!Array.isArray(e)&&!E(e)[_.toLowerCase()]&&(e[_]=r);}var Xt=["onRequest","onResponse","onError","onLoadingSlow"];function $(e,t,r={}){Object.assign(r,e,t),Pt("retry",e,t,r),Pt("headers",e,t,r);for(let s of Xt)Vt(s,e,t,r);return r}function Vt(e,t,r,s){let n=t[e],a=r[e];n&&a?s[e]=e==="onResponse"?[].concat(a,n):[].concat(n,a):(n||a)&&(s[e]=n||a);}function Pt(e,t,r,s){let n=t[e],a=r[e];if(a)if(e==="headers"){let o=n instanceof Headers||a instanceof Headers,i=o?E(n):{...n},u=o?E(a):B(a);for(let c of Object.keys(u)){let f=c.toLowerCase();for(let l in i)l.toLowerCase()===f&&delete i[l];i[c]=u[c];}s[e]=i;}else s[e]={...n,...B(a)};else a===void 0&&g(n)&&!(n instanceof Headers)&&(s[e]={...n});}var Q=new Map,ie=new Map,oe="|",Ue=64,Zt=/[^\w\-_|/:@.?=&~%#]/g,$t=/[^\w\-_|/:@.?=&~%#]/,er=/^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;function ue(e,t=true){let r=e.cacheKey;if(r&&t)return typeof r===x?r:r(e);let{url:s="",method:n=O,headers:a=null,body:o=null,credentials:i="same-origin"}=e,u="";if(a){let l;a instanceof Headers?l=E(a):l=a;let p=Object.keys(l),m=p.length;m>1&&p.sort();let q="";for(let T=0;T{f+=p+"="+(typeof l===x?l:"F"+bt(l))+"&";}),f.length>Ue&&(f=X(f));else if(g(o)&&!se(o))f="B"+bt(o);else {let l=g(o)?JSON.stringify(st(o)):String(o);f=l.length>Ue?X(l):l;}return Dt(c+oe+f)}var gt=new WeakMap,tr=0;function bt(e){let t=gt.get(e);return t||gt.set(e,t=++tr),t}function Dt(e){return $t.test(e)?e.replace(Zt,"")+oe+X(e):e}function Me(e){return e.expiry?h()>e.expiry:false}function Le(e){if(!e)return null;let t=Q.get(e);return t?t.data:null}function ce(e){return Q.get(e)}function we(e,t,r,s){if(r===0){le(e);return}let n=h(),a=r?r*1e3:0,o=s?s*1e3:0;Q.set(e,{data:t,time:n,stale:o>0?n+o:void 0,expiry:r===-1?void 0:n+a}),a>0&&Et(e,a);}function Et(e,t){M("c:"+e,()=>le(e,true),t);}function le(e,t=false){if(t){let s=ce(e);if(!s||!Me(s))return}Q.delete(e);let r=ie.get(e);r&&(ie.delete(e),je(()=>r.delete(e)));}function je(e){try{Promise.resolve(e()).catch(C);}catch{}}function Tt(e,t){let r=Q.get(e);if(t&&r){let{data:s,status:n,statusText:a,headers:o}=r.data;ie.set(e,t),je(()=>t.set(e,{...r,data:{data:s,status:n,statusText:a,headers:o}}));}}async function wt(e,t){let r=t.cacheStore;if(!r||xe(t))return null;let s;try{s=await r.get(e);}catch{return null}return !s||Q.has(e)?null:Me(s)?(je(()=>r.delete(e)),null):s}function xt(e,t,r){return Q.set(e,t),ie.set(e,r),t.expiry&&Et(e,t.expiry-h()),L(e,t.data),!t.stale||h(){let s=t.defaultResponse,n=t.cacheKey,a=Ke.bind(null,n);if(!e)return {ok:false,error:r,data:s??null,headers:null,config:t,mutate:a,isFetching:false,isSuccess:false,isError:true};let o=typeof Response===b&&e instanceof Response,i=e.data;s!==void 0&&(i==null||/^\[object (Object|Array)\]$/.test(Object.prototype.toString.call(i))&&Object.keys(i).length===0)&&(e.data=i=s),t.flattenResponse&&(e.data=i=ve(i)),t.select&&(e.data=i=t.select(i));let u=E(e.headers);if(o){let c={body:e.body,bodyUsed:e.bodyUsed,ok:e.ok,redirected:e.redirected,type:e.type,url:e.url,status:e.status,statusText:e.statusText,blob:async()=>i instanceof ArrayBuffer?new Blob([i]):new Blob,json:async()=>i,text:async()=>i,clone:()=>({...c}),arrayBuffer:async()=>i instanceof ArrayBuffer?i:new ArrayBuffer(0),formData:async()=>i instanceof FormData?i:new FormData,bytes:async()=>new Uint8Array(i instanceof ArrayBuffer?i:new ArrayBuffer(0)),error:r,data:i,headers:u,config:t,mutate:a,isFetching:false,isSuccess:e.ok&&!r,isError:!!r};return c}return g(e)&&(e.error=r,e.headers=u,e.isFetching=false,e.mutate=a,e.isSuccess=e.ok&&!r,e.isError=!!r),e};function qt(e){let t=Date.parse(e)-h();return isNaN(t)?null:Math.max(0,Math.floor(t))}function rr(e){if(!e)return null;let t=e.headers||{},r=t["retry-after"];if(r){let o=Number(r);if(!isNaN(o)&&o>=0)return o*1e3;let i=qt(r);if(i!==null)return i}let s="ratelimit-reset",n=t[s+"-after"]||t["x-"+s+"-after"];if(n){let o=Number(n);if(!isNaN(o))return o*1e3}let a=t[s+"-at"]||t["x-"+s+"-at"];return a?qt(a):null}async function Ot(e,t){let{retries:r=0,delay:s=0,backoff:n=1,maxDelay:a,retryOn:o=[],shouldRetry:i,jitter:u,methods:c}=t,f=0,l=s,p=r>0?r:0,m;for(;f<=p;){if(f>0&&m){let d=m.config,H=d.onRetry;H&&(await F(H,m,f),d._isAutoKey&&(d._prevKey=d.cacheKey,d.cacheKey=ue(d,false)));}m=await e(f>0,f);let q=m.error;if(q?await sr(m,f,p,i,o,c):!(i&&fo.toUpperCase()===e.config.method)))}function ar(e,t){return typeof t===b?t(e):t?Math.random()*e:e}async function Bt(e,t,r,s=0,n=0,a=false,o=false,i){if(!t)return e();let u=0,c;for(;(s===0||u0&&await ae(n,i),c=await e(),u++,!(s>0&&u>=s||!t||r&&r(c,u)));)do if(await ae(t,i),i&&i.aborted)return c;while(!a&&ut()||!o&&ct());return c}var nr=[204,205,304],or=/^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/,At=e=>typeof ReadableStream!==D&&e instanceof ReadableStream,qe=(e,t)=>({loaded:e,total:t,progress:t?e/t:void 0});function It(e,t){let r=t.body;return typeof XMLHttpRequest!==D&&!At(r)?ir(e,t,r):ur(e,t,r)}function ir(e,t,r){return new Promise((s,n)=>{let a=new XMLHttpRequest,o=t.signal,i=()=>a.abort(),u=f=>{o.removeEventListener("abort",i);try{f();}catch(l){n(l);}};a.open(t.method,e),a.responseType="blob",a.withCredentials=t.credentials==="include",new Headers(t.headers).forEach((f,l)=>or.test(l)||a.setRequestHeader(l,f)),a.upload.onprogress=f=>t.onUploadProgress(qe(f.loaded,f.lengthComputable?f.total:void 0)),a.onload=()=>u(()=>{let f=new Headers;for(let p of a.getAllResponseHeaders().split(/\r?\n/)){let m=p.indexOf(":");m>0&&f.append(p.slice(0,m),p.slice(m+1).trim());}let l=new Response(nr.includes(a.status)?null:a.response,{status:a.status,statusText:a.statusText,headers:f});Object.defineProperty(l,"url",{value:a.responseURL}),s(l);}),a.onerror=()=>u(()=>n(new TypeError("Network request failed")));let c=()=>u(()=>n(o.reason||W("The request was aborted",k)));if(a.onabort=c,o.aborted)return c();o.addEventListener("abort",i),a.send(r);})}async function ur(e,t,r){let s=new Headers(t.headers),n=r,a;if(!At(r)){let i=r instanceof Blob?r:await new Response(r).blob();a=i.size,n=i.stream(),i.type&&!s.has("content-type")&&s.set("content-type",i.type);}let o=0;return fetch(e,{...t,headers:s,body:n.pipeThrough(new TransformStream({transform(i,u){o+=i.byteLength,t.onUploadProgress(qe(o,a)),u.enqueue(i);}})),duplex:"half"})}function vt(e,t){if(!t||typeof Response!==b||!(e instanceof Response)||!e.body)return e;let r=e.headers,s=r.has("content-encoding")?void 0:Number(r.get("content-length"))||void 0,n=0,a=new Response(e.body.pipeThrough(new TransformStream({transform(o,i){n+=o.byteLength,t(qe(n,s&&Math.max(s,n))),i.enqueue(o);}})),e);for(let o of ["url","redirected","type"])Object.defineProperty(a,o,{value:e[o]});return a}async function St(e,t,r){let s=await t(e),n=s.error;if(!n)return ze(s,r),s;r.onError&&await F(r.onError,n);let a=n.isCancelled,o=r.logger;if(!a&&o&&o.warn&&o.warn("FETCH ERROR",lr(n)),r.strategy==="defaultResponse"&&(s.data=r.defaultResponse??null),ze(s,r,true),!a||r.rejectCancelled){let u=r.strategy;if(u===pe)throw n;u==="silent"&&await new Promise(()=>null);}return s}var cr=["authorization","proxy-authorization","cookie","x-api-key"];function lr(e){let t={...e.config,body:void 0,data:void 0,cacheKey:void 0,_prevKey:void 0,headers:E(e.config.headers)};for(let s of cr)t.headers[s]&&(t.headers[s]="[REDACTED]");let r=Object.assign(new Error(e.message),e,{config:t,request:t,response:e.response&&{...e.response,config:t}});return r.name=e.name,r.stack=e.stack,r}function Ft(e,t,r){e.status=e.status||t&&t.status||0,e.statusText=e.statusText||t&&t.statusText||"",e.config=e.request=r,e.response=t,e.isCancelled=e.name===k;}var ke=Object.freeze({isFetching:true});async function Oe(e,t=null){if(t&&typeof t.cacheKey=="string"){let y=fe(t.cacheKey,t.cacheTime,t);if(y)return y}let r=_e(e,t),{timeout:s,cancellable:n,cacheKey:a,dedupeTime:o,cacheTime:i,staleTime:u,refetchOnFocus:c,refetchOnReconnect:f,pollingInterval:l=0}=r,p=i!==void 0||u!==void 0,m=r.method,q=p&&(m===O||m===re)&&(r.etag??!r.fetcher),T=!!(a||s||o||p||n||c||f),d=null;T&&(d=ue(r));let H=null;if(d&&p){let y=fe(d,i,r);if(y)return y;if(r.cacheStore){let w=await wt(d,r),I=w&&Qt(w.data,d,r);if(I&&xt(d,{...w,data:I},r.cacheStore))return I}r.initialData!==void 0&&!Le(d)&&!xe(r)&&(H=Qt({data:r.initialData,status:200,statusText:"",headers:{}},d,r));}if(d&&o){let y=He(d,o);if(y)return y}let Je=r.retry||{},{retries:Ht=0,resetTimeout:Nt}=Je,N=r.signal,We=async(y,w=0)=>{let I=q&&Le(d);if(!w){if(H){let v=H;return H=null,v}d&&!y&&(u?fe(d,i,r)||(we(d,ke,i,u),L(d,ke)):L(d,ke)),r.cacheKey=d;}let ee=r.url,Ve=ft(d,ee,s,o||0,!!n,!!(s&&(!w||Nt))),P=r;P.signal=Ve.signal;let Ae=()=>Ve.abort(N.reason);N&&(N.aborted?Ae():N.addEventListener("abort",Ae));let me,R=null;try{r.onRequest&&(d&&o&&!w&&await null,await F(r.onRequest,P));let v=r.fetcher,K=fr(P,I);if(R=v?await v(ee,K):await(P.onUploadProgress&&P.body?It(ee,P):fetch(ee,K)),R=vt(R,P.onDownloadProgress),g(R)){if(K!==P&&R.status===304)return I;if(typeof Response===b&&R instanceof Response?R.data=P.parser?await P.parser(R):await Ct(R,P.responseType):v&&("data"in R&&"body"in R||(R={data:R})),R.config=P,R.ok!==void 0&&!R.ok)throw new he(P.method+" to "+ee+" failed! Status: "+(R.status||null),P,R)}me=Ce(R,P);let Ze=r.onResponse;Ze&&await F(Ze,me);}catch(v){let K=v;Ft(K,R,P),me=Ce(R,P,K);}finally{N&&N.removeEventListener("abort",Ae);}return me},Be=Ht>0?y=>Ot((w,I)=>We(y,I),Je):We,{onLoadingSlow:Ye,loadingTimeout:Ge}=r,_t=Ye&&Ge?async y=>{if(y)return Be(y);let w=setTimeout(()=>F(Ye,r).catch(C),Ge);try{return await Be(y)}finally{clearTimeout(w);}}:Be,de=(y=false)=>St(y,_t,r),Xe=l?Bt(de,l,r.shouldStopPolling,r.maxPollingAttempts,r.pollingDelay,r.refreshWhenHidden,r.refreshWhenOffline,N):de();return d&&(o&&mt(d,Xe),(u||c||f)&&ht(d,de,void 0,u,de,!!c,!!f,r.focusThrottleInterval)),Xe}function Qt(e,t,r){try{let s=typeof Response===b?new Response(null,e):{ok:!0,status:e.status,statusText:e.statusText,headers:e.headers};s.data=e.data,r.cacheKey=t;let n=Ce(s,{...r,select:void 0,flattenResponse:!1,defaultResponse:void 0});return n.config=r,n}catch{return null}}function fr(e,t){let r=t&&!t.error&&t.headers&&t.headers.etag,s=r&&E(e.headers);return s&&!s["if-none-match"]?{...e,headers:{...s,"if-none-match":r}}:e}function dr(e){let t=e.endpoints;async function r(n){return console.error("Add "+n+" to 'endpoints'."),null}let s={config:e,endpoints:t,async request(n,a={}){let o=S(t,n)?t[n]:void 0,i=o||{url:String(n)},u=i.url,c=u.replace(/[\t\n\r]/g,"").replace(/^[\x00-\x20]+/,"");if(/^[/\\]{2}/.test(c))throw new Error("Protocol-relative URLs not allowed.");let f=/^[a-z][a-z\d+\-.]*:/i.test(c)?o&&o.url===u?$(i,a):a:$($(e,i),a);return Oe(u,f)}};return new Proxy(s,{get(n,a){if(a in s)return s[a];if(!(typeof a=="symbol"||a==="then"))return S(t,a)?s.request.bind(null,a):r.bind(null,a)}})} exports.abortRequest=dt;exports.addTimeout=M;exports.buildConfig=_e;exports.createAbortError=W;exports.createApiFetcher=dr;exports.deleteCache=le;exports.fetchf=Oe;exports.fetchff=Oe;exports.generateCacheKey=ue;exports.getCache=ce;exports.getCachedResponse=fe;exports.getDefaultConfig=Wt;exports.getInFlightPromise=He;exports.isSlowConnection=Se;exports.mutate=Ke;exports.removeRevalidators=Lt;exports.revalidate=Ee;exports.revalidateAll=Rt;exports.setCache=we;exports.setDefaultConfig=Jt;exports.setEventProvider=Mt;exports.subscribe=kt;//# sourceMappingURL=index.js.map //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/node/index.js.map b/dist/node/index.js.map index 7ba8b70..6754a67 100644 --- a/dist/node/index.js.map +++ b/dist/node/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../../src/constants.ts","../../src/utils.ts","../../src/interceptor-manager.ts","../../src/errors/fetch-error.ts","../../src/errors/response-error.ts","../../src/timeout-wheel.ts","../../src/inflight-manager.ts","../../src/hash.ts","../../src/revalidator-manager.ts","../../src/pubsub-manager.ts","../../src/config-handler.ts","../../src/cache-manager.ts","../../src/response-parser.ts","../../src/retry-handler.ts","../../src/polling-handler.ts","../../src/upload-progress.ts","../../src/download-progress.ts","../../src/error-handler.ts","../../src/request-handler.ts","../../src/api-handler.ts"],"names":["APPLICATION_CONTENT_TYPE","APPLICATION_JSON","CHARSET_UTF_8","CONTENT_TYPE","UNDEFINED","OBJECT","STRING","FUNCTION","ABORT_ERROR","TIMEOUT_ERROR","GET","HEAD","REJECT","MAX_DELAY_MS","MAX_DEPTH","hasOwn","o","k","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","key","sortObject","sortedObj","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","v","buildParams","prefix","depth","i","len","replaceUrlPathParams","urlPathParams","match","colonKey","braceKey","encoded","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","signal","resolve","done","timer","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","isPageHidden","isOffline","applyInterceptors","interceptors","args","merge","interceptor","FetchError","request","response","ResponseError","WHEEL_SIZE","SECOND","wheel","keyMap","position","lastTick","handleCallback","callback","result","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","inFlight","markInFlight","timeout","dedupeTime","isCancellable","isTimeoutEnabled","now","item","prevPromise","prevController","prevIsCancellable","controller","abortRequest","removeInFlight","setInFlightPromise","promise","getInFlightPromise","prevReq","hash","str","char","DEFAULT_TTL","revalidators","eventHandlers","customEventProviders","setEventProvider","type","provider","removeEventHandler","addEventHandler","revalidateAll","isStaleRevalidation","isThrottled","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","focusThrottleInterval","listeners","addListener","fn","set","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","merged","buildFetcherConfig","requestConfig","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","separator","contentTypeValue","INTERCEPTORS","baseConfig","overrideConfig","targetConfig","mergeConfig","property","mergeInterceptors","baseInterceptor","newInterceptor","base","override","isInstance","overrides","lowerKey","existingKey","_cache","stores","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADERS","generateCacheKey","config","cacheKeyCheck","headersString","keys","cacheStr","sanitizeCacheKey","bodyString","getObjectId","objectIds","lastObjectId","id","isCacheExpired","getCacheData","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","scheduleExpiry","removeExpired","store","callStore","persistCache","status","statusText","getStoredCache","isCacheBypassed","restoreCache","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","buster","getCachedResponse","cacheKey","cacheTime","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","responseType","contentType","mimeType","trimmed","prepareResponse","defaultResponse","mutatator","isNativeResponse","getMsFromHttpDate","dateString","getRetryAfterMs","extendedResponse","retryAfter","RATELIMIT_RESET","rateLimitResetAfter","rateLimitResetAt","withRetry","requestFn","retries","delay","backoff","maxDelay","retryOn","shouldRetry","jitter","methods","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryDelay","withJitter","retryAfterMs","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","refreshWhenHidden","refreshWhenOffline","pollingAttempt","NULL_BODY_STATUSES","FORBIDDEN_HEADERS","isStream","toProgress","loaded","total","fetchWithUploadProgress","sendWithXhr","sendStreamed","reject","xhr","abort","settle","line","index","onAbort","stream","blob","chunk","withDownloadProgress","onDownloadProgress","counted","withErrorHandling","isCancelled","logger","redactError","strategy","SENSITIVE_HEADERS","copy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","isETagEnabled","needsCacheKey","_cacheKey","initialResponse","stored","restored","toResponse","inflight","retryConfig","resetTimeout","userSignal","doRequestOnce","init","withETag","onResponse","_error","baseRequest","_","onLoadingSlow","loadingTimeout","requestWithErrorHandling","doRequestPromise","etag","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","resolvedUrl","mergedConfig","_target","prop"],"mappings":"aAAO,IAAMA,EAA2B,cAAA,CAE3BC,EAAAA,CAAmBD,CAAAA,CAA2B,MAAA,CAC9CE,GAAgB,eAAA,CAChBC,CAAAA,CAAe,cAAA,CAEfC,CAAAA,CAAY,YACZC,EAAAA,CAAS,QAAA,CACTC,EAAS,QAAA,CACTC,CAAAA,CAAW,WAEXC,CAAAA,CAAc,YAAA,CACdC,EAAAA,CAAgB,cAAA,CAEhBC,EAAM,KAAA,CACNC,EAAAA,CAAO,MAAA,CAEPC,EAAAA,CAAS,SAGTC,EAAAA,CAAe,UAAA,CCV5B,IAAMC,EAAAA,CAAY,GAELC,CAAAA,CAAS,CAACC,EAAQC,CAAAA,GAC7B,MAAA,CAAO,UAAU,cAAA,CAAe,IAAA,CAAKD,CAAAA,CAAGC,CAAC,EAEpC,SAASC,CAAAA,CAAeC,CAAAA,CAAwB,CACrD,OAAOA,CAAAA,YAAgB,eACzB,CAQO,SAASC,EAASC,CAAAA,CAA0C,CACjE,OAAOA,CAAAA,GAAU,IAAA,EAAQ,OAAOA,CAAAA,GAAUhB,EAC5C,CA+BO,SAASiB,EAA8CC,CAAAA,CAAW,CACvE,IAAMC,CAAAA,CAAWT,EAAOQ,CAAAA,CAAK,WAAW,CAAA,CAClCE,CAAAA,CAAUV,EAAOQ,CAAAA,CAAK,aAAa,EACnCG,CAAAA,CAAeX,CAAAA,CAAOQ,EAAK,WAAW,CAAA,CAE5C,GAAI,CAACC,GAAY,CAACC,CAAAA,EAAW,CAACC,CAAAA,CAC5B,OAAOH,CAAAA,CAIT,IAAMI,CAAAA,CAAU,GAEhB,IAAA,IAAWC,CAAAA,IAAO,OAAO,IAAA,CAAKL,CAAG,EAC3BK,CAAAA,GAAQ,WAAA,EAAeA,CAAAA,GAAQ,aAAA,EAAiBA,IAAQ,WAAA,GAC1DD,CAAAA,CAAQC,CAAG,CAAA,CAAIL,EAAIK,CAAG,CAAA,CAAA,CAI1B,OAAOD,CACT,CAWO,SAASE,EAAAA,CAAWN,EAAkC,CAE3D,IAAMO,EAAY,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,CAEpC,cAAO,IAAA,CAAKP,CAAG,CAAA,CACZ,IAAA,GACA,OAAA,CAASN,CAAAA,EAAOa,CAAAA,CAAUb,CAAC,EAAIM,CAAAA,CAAIN,CAAC,CAAE,CAAA,CAElCa,CACT,CASA,SAASC,EAAAA,CAAuBC,CAAAA,CAAiBC,CAAAA,CAA6B,CAC5E,OAAKA,CAAAA,CAIED,GAAWA,CAAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,CAAI,GAAA,CAAM,GAAA,CAAA,CAAOC,CAAAA,CAH9CD,CAIX,CASO,SAASE,GAAkBC,CAAAA,CAAaC,CAAAA,CAA6B,CAC1E,GAAI,CAACA,CAAAA,CACH,OAAOD,EAIT,GAAIjB,CAAAA,CAAekB,CAAM,CAAA,CAAG,CAC1B,IAAMC,CAAAA,CAAqBD,CAAAA,CAAO,QAAA,GAElC,OAAOL,EAAAA,CAAuBI,EAAKE,CAAkB,CACvD,CAGA,IAAMC,CAAAA,CAAc,EAAC,CACfC,EAAS,kBAAA,CACTC,CAAAA,CAAM,CAACvB,CAAAA,CAAWwB,IAAW,CACjCA,CAAAA,CAAI,OAAOA,CAAAA,GAAMlC,EAAWkC,CAAAA,EAAE,CAAIA,EAClCA,CAAAA,CAAIA,CAAAA,EAAgC,GACpCH,CAAAA,CAAEA,CAAAA,CAAE,MAAM,CAAA,CAAIC,EAAOtB,CAAC,CAAA,CAAI,GAAA,CAAMsB,CAAAA,CAAOE,CAAC,EAC1C,CAAA,CAEMC,CAAAA,CAAc,CAACC,EAAgBpB,CAAAA,CAAUqB,CAAAA,CAAQ,IAAM,CAE3D,GAAIA,GAAS9B,EAAAA,CACX,OAAOwB,CAAAA,CAGT,IAAIO,EAAWC,CAAAA,CAAalB,CAAAA,CAE5B,GAAIe,CAAAA,CACF,GAAI,MAAM,OAAA,CAAQpB,CAAG,CAAA,CACnB,IAAKsB,EAAI,CAAA,CAAGC,CAAAA,CAAMvB,EAAI,MAAA,CAAQsB,CAAAA,CAAIC,EAAKD,CAAAA,EAAAA,CACrCH,CAAAA,CACEC,CAAAA,CAAS,GAAA,EAAO,OAAOpB,CAAAA,CAAIsB,CAAC,CAAA,GAAMxC,EAAAA,EAAUkB,EAAIsB,CAAC,CAAA,CAAIA,CAAAA,CAAI,EAAA,CAAA,CAAM,IAC/DtB,CAAAA,CAAIsB,CAAC,EACLD,CAAAA,CAAQ,CACV,UAEOxB,CAAAA,CAASG,CAAG,CAAA,CACrB,IAAKK,KAAOL,CAAAA,CACVmB,CAAAA,CAAYC,CAAAA,CAAS,GAAA,CAAMf,EAAM,GAAA,CAAKL,CAAAA,CAAIK,CAAG,CAAA,CAAGgB,EAAQ,CAAC,CAAA,CAAA,KAG3DJ,EAAIG,CAAAA,CAAQpB,CAAG,UAER,KAAA,CAAM,OAAA,CAAQA,CAAG,CAAA,CAC1B,IAAKsB,CAAAA,CAAI,CAAA,CAAGC,CAAAA,CAAMvB,CAAAA,CAAI,OAAQsB,CAAAA,CAAIC,CAAAA,CAAKD,CAAAA,EAAAA,CACrCL,CAAAA,CAAIjB,EAAIsB,CAAC,CAAA,CAAE,KAAMtB,CAAAA,CAAIsB,CAAC,EAAE,KAAK,CAAA,CAAA,KAG/B,IAAKjB,CAAAA,IAAOL,EACVmB,CAAAA,CAAYd,CAAAA,CAAKL,EAAIK,CAAG,CAAA,CAAGgB,EAAQ,CAAC,CAAA,CAGxC,OAAON,CACT,EAMMD,CAAAA,CAJmBK,CAAAA,CAAY,GAAIN,CAAM,CAAA,CAAE,KAAK,GAAG,CAAA,CAIb,OAAA,CAAQ,SAAA,CAAW,IAAI,CAAA,CAEnE,OAAOL,EAAAA,CAAuBI,CAAAA,CAAKE,CAAkB,CACvD,CAWO,SAASU,EAAAA,CACdZ,EACAa,CAAAA,CACQ,CACR,GAAI,CAACA,CAAAA,EAAkBb,EAAI,OAAA,CAAQ,GAAG,CAAA,GAAM,EAAA,EAAMA,EAAI,OAAA,CAAQ,GAAG,CAAA,GAAM,EAAA,CACrE,OAAOA,CAAAA,CAKT,IAAMC,CAAAA,CAASY,CAAAA,CAGf,OAAOb,CAAAA,CAAI,OAAA,CAAQ,oBAAqB,CAACc,CAAAA,CAAOC,EAAUC,CAAAA,GAAa,CACrE,IAAMvB,CAAAA,CAAMsB,GAAYC,CAAAA,CAGxB,GAAIpC,CAAAA,CAAOqB,CAAAA,CAAQR,CAAG,CAAA,CAAG,CACvB,IAAMP,CAAAA,CAAQe,EAAOR,CAAG,CAAA,CAGxB,GAA2BP,CAAAA,EAAU,IAAA,CAAM,CACzC,IAAM+B,CAAAA,CAAU,kBAAA,CAAmB,MAAA,CAAO/B,CAAK,CAAC,CAAA,CAGhD,GAAI+B,CAAAA,GAAY,GAAA,EAAOA,IAAY,IAAA,CACjC,MAAM,IAAI,KAAA,CAAM,uCAAuC,CAAA,CAGzD,OAAOA,CACT,CACF,CAEA,OAAOH,CACT,CAAC,CACH,CAWO,SAASI,EAAAA,CAAclB,CAAAA,CAAsB,CAClD,OAAO,2BAA2B,IAAA,CAAKA,CAAG,CAC5C,CAEO,IAAMmB,CAAAA,CAAU,IAAM,KAAK,GAAA,EAAI,CAEzBC,EAAO,IAAM,CAAC,CAAA,CAcpB,SAASC,GAAmBnC,CAAAA,CAAqB,CACtD,IAAM,CAAA,CAAI,OAAOA,CAAAA,CAEjB,OAA2BA,CAAAA,EAAU,IAAA,CAC5B,MAGL,CAAA,GAAMf,CAAAA,EAAU,IAAM,QAAA,EAAY,CAAA,GAAM,WAIxC,KAAA,CAAM,OAAA,CAAQe,CAAK,CAAA,CACd,KAIP,OAAO,UAAA,GAAejB,CAAAA,EACtB,OAAO,WAAW,MAAA,GAAWA,CAAAA,EAC7B,UAAA,CAAW,MAAA,CAAO,SAASiB,CAAK,CAAA,EAK9BA,aAAiB,IAAA,EAAQH,CAAAA,CAAeG,CAAK,CAAA,CACxC,KAAA,CAGL,CAAA,EAAAD,CAAAA,CAASC,CAAK,CAAA,GACF,MAAA,CAAO,eAAeA,CAAK,CAAA,GAG3B,OAAO,SAAA,EAKjB,OAAOA,CAAAA,CAAM,MAAA,GAAWd,GAMhC,CASO,IAAMkD,GAAkB,CAC7BC,CAAAA,CACAC,IAEA,IAAI,OAAA,CAASC,CAAAA,EAAY,CACvB,IAAMC,CAAAA,CAAO,IAAM,CACjB,YAAA,CAAaC,CAAK,CAAA,CACdH,CAAAA,EACFA,CAAAA,CAAO,mBAAA,CAAoB,QAASE,CAAI,CAAA,CAE1CD,EAAQ,IAAI,EACd,EACME,CAAAA,CAAQ,UAAA,CAAWD,CAAAA,CAAM,IAAA,CAAK,IAAIH,CAAAA,CAAI7C,EAAY,CAAC,CAAA,CAErD8C,IACEA,CAAAA,CAAO,OAAA,CACTE,CAAAA,EAAK,CAELF,EAAO,gBAAA,CAAiB,OAAA,CAASE,CAAI,CAAA,EAG3C,CAAC,EAWI,SAASE,EAAAA,CAAY5C,CAAAA,CAAWyB,CAAAA,CAAQ,EAAQ,CACrD,OAAIA,CAAAA,EAAS9B,EAAAA,CACJK,EAGLA,CAAAA,EAAQC,CAAAA,CAASD,CAAI,CAAA,EAAK,OAAOA,CAAAA,CAAK,IAAA,GAASf,EAC1C2D,EAAAA,CAAY5C,CAAAA,CAAK,KAAMyB,CAAAA,CAAQ,CAAC,CAAA,CAGlCzB,CACT,CAYO,SAAS6C,CAAAA,CACdC,EACe,CACf,GAAI,CAACA,CAAAA,CACH,OAAO,EAAC,CAGV,IAAMC,CAAAA,CAA+B,GAIrC,GAAID,CAAAA,YAAmB,QACrBA,CAAAA,CAAQ,OAAA,CAAQ,CAAC5C,CAAAA,CAAOO,IAAQ,CAC9BsC,CAAAA,CAActC,CAAAA,CAAI,WAAA,EAAa,CAAA,CAAIP,EACrC,CAAC,CAAA,CAAA,aAGUO,CAAAA,IAAOqC,CAAAA,CAEZlD,EAAOkD,CAAAA,CAASrC,CAAG,GAAKA,CAAAA,GAAQ,WAAA,GAClCsC,CAAAA,CAActC,CAAAA,CAAI,aAAa,CAAA,CAAIqC,CAAAA,CAAQrC,CAAG,GAKpD,OAAOsC,CACT,CAOO,SAASC,IAAqB,CAEnC,OACE,OAAO,MAAA,GAAW/D,CAAAA,EAAa,OAAO,MAAA,CAAO,gBAAA,GAAqBG,CAEtE,CAUO,SAAS6D,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACsB,CACtB,GAAI,OAAO,YAAA,GAAiBlE,CAAAA,CAC1B,OAAO,IAAI,YAAA,CAAaiE,CAAAA,CAASC,CAAI,CAAA,CAGvC,IAAMC,EAAQ,IAAI,KAAA,CAAMF,CAAO,CAAA,CAC/B,OAAAE,CAAAA,CAAM,IAAA,CAAOD,EAENC,CACT,KAMaC,EAAAA,CAAmB,IAAe,CAC7C,IAAMC,EAAO,OAAO,SAAA,GAAcrE,GAAc,SAAA,CAAkB,UAAA,CAElE,OAAOqE,CAAAA,EAAQ,CAAC,SAAA,CAAW,IAAA,CAAM,IAAI,CAAA,CAAE,QAAA,CAASA,CAAAA,CAAK,aAAa,CACpE,CAAA,CAMaC,EAAAA,CAAe,IAC1B,OAAO,WAAatE,CAAAA,EAAa,QAAA,CAAS,kBAAoB,QAAA,CAMnDuE,EAAAA,CAAY,IACvB,OAAO,SAAA,GAAcvE,CAAAA,EAAa,SAAA,CAAU,SAAW,MClbzD,eAAsBwE,CAAAA,CAKpBC,CAAAA,CAA6B1D,KAAY2D,CAAAA,CAA2B,CACpE,GAAI,CAACD,EACH,OAGF,IAAME,EAAStC,CAAAA,EACbA,CAAAA,EACArB,EAASD,CAAI,CAAA,EACbC,CAAAA,CAASqB,CAAC,GACV,MAAA,CAAO,MAAA,CAAOtB,CAAAA,CAAMG,CAAAA,CAAemB,CAAC,CAAC,CAAA,CAEvC,GAAI,OAAOoC,IAAiBtE,CAAAA,CAC1BwE,CAAAA,CAAM,MAAOF,CAAAA,CAA8C1D,CAAAA,CAAM,GAAG2D,CAAI,CAAC,CAAA,CAAA,KAAA,GAChE,KAAA,CAAM,QAAQD,CAAY,CAAA,CACnC,QAAWG,CAAAA,IAAeH,CAAAA,CACxBE,EAAM,MAAMC,CAAAA,CAAY7D,CAAAA,CAAM,GAAG2D,CAAI,CAAC,EAG5C,CC5BO,IAAMG,EAAAA,CAAN,cAKG,KAAM,CAwBd,WAAA,CACEZ,CAAAA,CACAa,EACAC,CAAAA,CAMA,CACA,KAAA,CAAMd,CAAO,EAEb,IAAA,CAAK,OAAA,CAAUa,CAAAA,CACf,IAAA,CAAK,SAAWC,CAAAA,CAChB,IAAA,CAAK,OAASA,CAAAA,CAAWA,CAAAA,CAAS,OAAS,CAAA,CAC3C,IAAA,CAAK,UAAA,CAAaA,CAAAA,CAAWA,EAAS,UAAA,CAAa,EAAA,CACnD,IAAA,CAAK,MAAA,CAASD,EACd,IAAA,CAAK,WAAA,CAAc,KAAA,CACnB,IAAA,CAAK,KAAO,aACd,CACF,ECnDO,IAAME,EAAAA,CAAN,cAKGH,EAA+D,CACvE,WAAA,CACEZ,CAAAA,CACAa,EACAC,CAAAA,CAMA,CACA,KAAA,CAAMd,CAAAA,CAASa,EAASC,CAAQ,CAAA,CAEhC,IAAA,CAAK,IAAA,CAAO,gBACd,CACF,CAAA,KCDME,EAAAA,CAAa,GAAA,CACbC,GAAS,GAAA,CACTC,EAAAA,CAAyB,KAAA,CAAMF,EAAU,EAC5C,IAAA,CAAK,CAAC,EACN,GAAA,CAAI,IAAM,EAAE,CAAA,CAETG,CAAAA,CAAS,IAAI,IACfC,EAAAA,CAAW,CAAA,CACXC,GAAW,CAAA,CACX5B,CAAAA,CAA+B,KAE7B6B,EAAAA,CAAiB,CAAC,CAAC/D,CAAAA,CAAKgE,CAAQ,CAAA,GAAyB,CAC7DJ,CAAAA,CAAO,MAAA,CAAO5D,CAAG,CAAA,CAEjB,GAAI,CACF,IAAMiE,EAASD,CAAAA,EAAS,CACpBC,GAAUA,CAAAA,YAAkB,OAAA,EAE9BA,EAAO,KAAA,CAAMtC,CAAI,EAErB,CAAA,KAAQ,CAER,CACF,CAAA,CAEauC,CAAAA,CAAa,CACxBlE,EACAmE,CAAAA,CACArC,CAAAA,GACS,CACTsC,CAAAA,CAAcpE,CAAG,CAAA,CAIjB,IAAMqE,EAAUvC,CAAAA,CAAK4B,EAAAA,EAAUxB,GAASR,CAAAA,EAAQ,GAAMoC,EAAAA,CAAW,CAAA,CAAI,GAGrE,GAAIhC,CAAAA,CAAK4B,EAAAA,EAAUW,CAAAA,EAAWZ,IAAc3B,CAAAA,CAAK4B,EAAAA,GAAW,CAAA,CAAG,CAC7DE,EAAO,GAAA,CAAI5D,CAAAA,CAAK,CACd,UAAA,CACE+D,EAAAA,CAAe,KAAK,IAAA,CAAM,CAAC/D,CAAAA,CAAKmE,CAAE,CAAC,CAAA,CACnC,IAAA,CAAK,IAAIrC,CAAAA,CAAI7C,EAAY,CAC3B,CACF,CAAC,CAAA,CAED,MACF,CAEA,IAAMqF,CAAAA,CAAAA,CAAQT,GAAWQ,CAAAA,EAAWZ,EAAAA,CAEpCE,GAAMW,CAAI,CAAA,CAAE,IAAA,CAAK,CAACtE,EAAKmE,CAAE,CAAC,CAAA,CAC1BP,CAAAA,CAAO,IAAI5D,CAAAA,CAAKsE,CAAI,CAAA,CAEfpC,CAAAA,GACH4B,GAAWpC,CAAAA,EAAQ,CACnBQ,EAAQ,WAAA,CAAY,IAAM,CACxB2B,EAAAA,CAAAA,CAAYA,EAAAA,CAAW,CAAA,EAAKJ,EAAAA,CAC5BK,GAAWpC,CAAAA,EAAQ,CACnB,IAAM4C,CAAAA,CAAOX,GAAME,EAAQ,CAAA,CAI3B,IAAA,IAAS5C,CAAAA,CAAI,EAAGA,CAAAA,CAAIqD,CAAAA,CAAK,OAAQrD,CAAAA,EAAAA,CAC/B8C,EAAAA,CAAeO,EAAKrD,CAAC,CAAC,CAAA,CAGxBqD,CAAAA,CAAK,OAAS,CAAA,CAEV,CAACV,CAAAA,CAAO,IAAA,EAAQ1B,IAClB,aAAA,CAAcA,CAAK,CAAA,CACnBA,CAAAA,CAAQ,MAEZ,CAAA,CAAGwB,EAAM,GAEb,CAAA,CAEaU,CAAAA,CAAiBpE,GAAsB,CAClD,IAAMuE,CAAAA,CAAgBX,CAAAA,CAAO,IAAI5D,CAAG,CAAA,CAEpC,GAAIuE,CAAAA,GAAkB,MAAA,CAAW,CAE/B,GAAI,KAAA,CAAM,OAAA,CAAQA,CAAa,EAC7B,YAAA,CAAaA,CAAAA,CAAc,CAAC,CAAC,CAAA,CAAA,KACxB,CACL,IAAMC,CAAAA,CAAUb,EAAAA,CAAMY,CAAa,EAEnC,IAAA,IAAStD,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIuD,EAAQ,MAAA,CAAQvD,CAAAA,EAAAA,CAClC,GAAIuD,CAAAA,CAAQvD,CAAC,CAAA,CAAE,CAAC,IAAMjB,CAAAA,CAAK,CACzBwE,EAAQ,MAAA,CAAOvD,CAAAA,CAAG,CAAC,CAAA,CACnB,KACF,CAEJ,CAEA2C,CAAAA,CAAO,MAAA,CAAO5D,CAAG,CAAA,CAEb,CAAC4D,CAAAA,CAAO,IAAA,EAAQ1B,IAClB,aAAA,CAAcA,CAAK,EACnBA,CAAAA,CAAQ,IAAA,EAEZ,CACF,EClGA,IAAMuC,CAAAA,CAAsC,IAAI,IAazC,SAASC,EAAAA,CACd1E,CAAAA,CACAO,CAAAA,CACAoE,EACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACiB,CACjB,GAAI,CAAC9E,CAAAA,CACH,OAAO,IAAI,eAAA,CAGb,IAAM+E,CAAAA,CAAMrD,CAAAA,EAAQ,CACdsD,CAAAA,CAAOP,EAAS,GAAA,CAAIzE,CAAG,EACzBiF,CAAAA,CAAuC,IAAA,CAG3C,GAAID,CAAAA,CAAM,CACR,IAAME,CAAAA,CAAiBF,EAAK,CAAC,CAAA,CACvBG,EAAoBH,CAAAA,CAAK,CAAC,EAGhC,GACE,CAACG,CAAAA,EACDJ,CAAAA,CAAMC,EAAK,CAAC,CAAA,CAAIJ,CAAAA,EAChB,CAACM,EAAe,MAAA,CAAO,OAAA,CAEvB,OAAOA,CAAAA,CAKLC,GACFD,CAAAA,CAAe,KAAA,CACb1C,EAAiB,4BAAA,CAA8B5D,CAAW,CAC5D,CAAA,CAGFwF,CAAAA,CAAcpE,CAAG,CAAA,CACjBiF,EAAcD,CAAAA,CAAK,CAAC,EACtB,CAEA,IAAMI,CAAAA,CAAa,IAAI,eAAA,CAEvB,OAAAX,EAAS,GAAA,CAAIzE,CAAAA,CAAK,CAChBoF,CAAAA,CACAN,CAAAA,CACAC,EACAF,CAAAA,CACAI,CACF,CAAC,CAAA,CAEGH,GACFZ,CAAAA,CACElE,CAAAA,CACA,IAAM,CACJqF,GACErF,CAAAA,CACAwC,CAAAA,CAAiBjC,CAAAA,CAAM,yBAAA,CAA2B1B,EAAa,CACjE,EACF,EACA8F,CACF,CAAA,CAGKS,CACT,CASA,eAAsBC,EAAAA,CACpBrF,CAAAA,CACA2C,EAA8C,IAAA,CAC/B,CAEf,GAAI3C,CAAAA,CAAK,CACP,IAAMgF,CAAAA,CAAOP,CAAAA,CAAS,GAAA,CAAIzE,CAAG,EAEzBgF,CAAAA,GAEErC,CAAAA,EACiBqC,EAAK,CAAC,CAAA,CACd,MAAMrC,CAAK,CAAA,CAGxB2C,EAAAA,CAAetF,CAAG,GAEtB,CACF,CAOO,SAASsF,EAAAA,CAAetF,EAA0B,CACvDoE,CAAAA,CAAcpE,CAAI,CAAA,CAClByE,EAAS,MAAA,CAAOzE,CAAI,EACtB,CAsBO,SAASuF,GACdvF,CAAAA,CACAwF,CAAAA,CACM,CACN,IAAMR,EAAOP,CAAAA,CAAS,GAAA,CAAIzE,CAAG,CAAA,CACzBgF,IAEFA,CAAAA,CAAK,CAAC,CAAA,CAAIQ,CAAAA,EAEd,CASO,SAASC,EAAAA,CACdzF,EACA4E,CAAAA,CACmB,CACnB,GAAI,CAAC5E,CAAAA,CACH,OAAO,IAAA,CAGT,IAAM0F,CAAAA,CAAUjB,CAAAA,CAAS,GAAA,CAAIzE,CAAG,EAEhC,OACE0F,CAAAA,EAEAA,CAAAA,CAAQ,CAAC,GAET,CAACA,CAAAA,CAAQ,CAAC,CAAA,EAEVhE,CAAAA,GAAYgE,CAAAA,CAAQ,CAAC,CAAA,CAAId,CAAAA,EAEzB,CAACc,CAAAA,CAAQ,CAAC,EAAE,MAAA,CAAO,OAAA,CAEZA,EAAQ,CAAC,CAAA,CAGX,IACT,CC3MO,SAASC,CAAAA,CAAKC,CAAAA,CAAqB,CACxC,IAAID,CAAAA,CAAO,EAEX,IAAA,IAAS1E,CAAAA,CAAI,CAAA,CAAGC,CAAAA,CAAM0E,EAAI,MAAA,CAAQ3E,CAAAA,CAAIC,CAAAA,CAAKD,CAAAA,EAAAA,CAAK,CAC9C,IAAM4E,CAAAA,CAAOD,CAAAA,CAAI,UAAA,CAAW3E,CAAC,CAAA,CAC7B0E,CAAAA,CAAQA,EAAO,EAAA,CAAmBE,CAAAA,CAAQ,EAC5C,CAEA,OAAO,MAAA,CAAOF,CAAI,CACpB,CCoBA,IAAMG,EAAAA,CAAc,GAAA,CAAS,IACvBC,CAAAA,CAAe,IAAI,GAAA,CASnBC,CAAAA,CAAgB,IAAI,GAAA,CAKpBC,EAAAA,CAAuB,IAAI,GAAA,CAS1B,SAASC,GACdC,CAAAA,CACAC,CAAAA,CACM,CACNH,EAAAA,CAAqB,IAAIE,CAAAA,CAAMC,CAAQ,CAAA,CAGnCJ,CAAAA,CAAc,IAAIG,CAAI,CAAA,GACxBE,EAAAA,CAAmBF,CAAI,EACvBG,EAAAA,CAAgBH,CAAI,GAExB,CAWO,SAASI,GACdJ,CAAAA,CACAK,CAAAA,CAA+B,IAAA,CAC/BC,CAAAA,CAAuB,MACvB,CACA,IAAMC,EAAYP,CAAAA,GAAS,OAAA,CAAU,EAAI,CAAA,CACnCpB,CAAAA,CAAMrD,CAAAA,EAAQ,CAEpBqE,EAAa,OAAA,CAASY,CAAAA,EAAU,CAC9B,GAAI,CAACA,EAAMD,CAAS,CAAA,EAAMD,CAAAA,EAAe1B,CAAAA,CAAM4B,EAAM,CAAC,CAAA,CAAIA,CAAAA,CAAM,CAAC,EAC/D,OAGFA,CAAAA,CAAM,CAAC,CAAA,CAAI5B,EAGX,IAAM6B,CAAAA,CAAcJ,EAAsBG,CAAAA,CAAM,CAAC,EAAIA,CAAAA,CAAM,CAAC,CAAA,CAExDC,CAAAA,EACF,QAAQ,OAAA,CAAQA,CAAAA,CAAYJ,CAAmB,CAAC,EAAE,KAAA,CAAM7E,CAAI,EAEhE,CAAC,EACH,CAUA,eAAsBkF,GACpB7G,CAAAA,CACAwG,CAAAA,CAA+B,MACI,CAEnC,GAAI,CAACxG,CAAAA,CACH,OAAO,IAAA,CAGT,IAAM2G,CAAAA,CAAQZ,CAAAA,CAAa,IAAI/F,CAAG,CAAA,CAElC,GAAI2G,CAAAA,CAAO,CAETA,CAAAA,CAAM,CAAC,EAAIjF,CAAAA,EAAQ,CAEnB,IAAMkF,CAAAA,CAAcJ,CAAAA,CAAsBG,CAAAA,CAAM,CAAC,EAAIA,CAAAA,CAAM,CAAC,EAG5D,GAAIC,CAAAA,CACF,OAAO,MAAMA,CAAAA,CAAYJ,CAAmB,CAEhD,CAGA,OAAO,IACT,CAOO,SAASM,EAAAA,CAAmBX,EAAiB,CAClDE,EAAAA,CAAmBF,CAAI,CAAA,CAEvB,IAAMO,CAAAA,CAAYP,CAAAA,GAAS,OAAA,CAAU,CAAA,CAAI,EAGzCJ,CAAAA,CAAa,OAAA,CAAQ,CAACY,CAAAA,CAAO3G,IAAQ,CAC/B2G,CAAAA,CAAMD,CAAS,CAAA,EACjBK,EAAAA,CAAkB/G,CAAG,EAEzB,CAAC,EACH,CASA,SAASsG,EAAAA,CAAgBU,CAAAA,CAAkB,CACzC,GAAIhB,EAAc,GAAA,CAAIgB,CAAK,CAAA,CACzB,OAIF,IAAMC,CAAAA,CAAUV,EAAAA,CAAc,KAAK,IAAA,CAAMS,CAAAA,CAAO,KAAMA,CAAAA,GAAU,OAAO,CAAA,CAGjEE,CAAAA,CAAiBjB,GAAqB,GAAA,CAAIe,CAAK,CAAA,CAErD,GAAIE,EAAgB,CAClB,IAAMC,CAAAA,CAAUD,CAAAA,CAAeD,CAAO,CAAA,CAEtCjB,CAAAA,CAAc,IAAIgB,CAAAA,CAAOG,CAAO,EAEhC,MACF,CAGI5E,EAAAA,EAAU,GACZ,OAAO,gBAAA,CAAiByE,CAAAA,CAAOC,CAAO,CAAA,CAEtCjB,CAAAA,CAAc,IAAIgB,CAAAA,CAAO,IAAM,MAAA,CAAO,mBAAA,CAAoBA,EAAOC,CAAO,CAAC,GAE7E,CAOA,SAASZ,GAAmBW,CAAAA,CAAkB,CAC5C,IAAMG,CAAAA,CAAUnB,EAAc,GAAA,CAAIgB,CAAK,CAAA,CAEnCG,CAAAA,GACFA,GAAQ,CACRnB,CAAAA,CAAc,MAAA,CAAOgB,CAAK,GAE9B,CAcO,SAASI,GACdpH,CAAAA,CACAqH,CAAAA,CACAC,EACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,CAAAA,CACAC,EACA,CAEA,IAAMhB,CAAAA,CAAQZ,CAAAA,CAAa,IAAI/F,CAAG,CAAA,EAAM,EAAC,CAEzC2G,EAAM,CAAC,CAAA,CAAIU,EACXV,CAAAA,CAAM,CAAC,EAAIjF,CAAAA,EAAQ,CACnBiF,CAAAA,CAAM,CAAC,EAAWb,EAAAA,CAClBa,CAAAA,CAAM,CAAC,EAAIY,CAAAA,CACXZ,CAAAA,CAAM,CAAC,CAAA,CAAIa,EACXb,CAAAA,CAAM,CAAC,EAAIc,CAAAA,CACXd,CAAAA,CAAM,CAAC,CAAA,CAAIe,CAAAA,CACXf,CAAAA,CAAM,CAAC,EAAIgB,CAAAA,CAEX5B,CAAAA,CAAa,IAAI/F,CAAAA,CAAK2G,CAAK,EAEvBc,CAAAA,EACFnB,EAAAA,CAAgB,OAAO,CAAA,CAGrBoB,GACFpB,EAAAA,CAAgB,QAAQ,EAGtBiB,CAAAA,EACFrD,CAAAA,CAAW,KAAOlE,CAAAA,CAAK6G,EAAAA,CAAW,IAAA,CAAK,IAAA,CAAM7G,EAAK,IAAI,CAAA,CAAGuH,CAAAA,CAAY,GAAI,EAE7E,CAEO,SAASR,EAAAA,CAAkB/G,CAAAA,CAAa,CAC7C+F,CAAAA,CAAa,MAAA,CAAO/F,CAAG,CAAA,CAGvBoE,CAAAA,CAAc,KAAOpE,CAAG,EAC1B,CC7OA,IAAM4H,GAAY,IAAI,GAAA,CAGf,SAASC,EAAAA,CAAqB7H,EAAa8H,CAAAA,CAAuB,CACvE,IAAIC,CAAAA,CAAMH,GAAU,GAAA,CAAI5H,CAAG,EAEtB+H,CAAAA,EACHH,EAAAA,CAAU,IAAI5H,CAAAA,CAAM+H,CAAAA,CAAM,IAAI,GAAM,EAGtCA,CAAAA,CAAI,GAAA,CAAID,CAAE,EACZ,CAEO,SAASE,EAAAA,CAAkBhI,CAAAA,CAAa8H,CAAAA,CAAiB,CAC9D,IAAMC,CAAAA,CAAMH,GAAU,GAAA,CAAI5H,CAAG,EAEzB+H,CAAAA,GACFA,CAAAA,CAAI,MAAA,CAAOD,CAAE,EAGTC,CAAAA,CAAI,IAAA,GAAS,GACfH,EAAAA,CAAU,MAAA,CAAO5H,CAAG,CAAA,EAG1B,CAEO,SAASiI,CAAAA,CAAqBjI,EAAauD,CAAAA,CAAa,CAC7D,IAAM2E,CAAAA,CAAMN,EAAAA,CAAU,IAAI5H,CAAG,CAAA,CAE7B,GAAIkI,CAAAA,CACF,GAAIA,CAAAA,CAAI,IAAA,GAAS,CAAA,CAAG,CAElB,IAAMJ,CAAAA,CAAKI,CAAAA,CAAI,MAAA,EAAO,CAAE,MAAK,CAAE,KAAA,CAC/BJ,EAAIvE,CAAQ,EACd,MACE2E,CAAAA,CAAI,OAAA,CAASJ,CAAAA,EAAOA,CAAAA,CAAGvE,CAAQ,CAAC,EAGtC,CAEO,SAAS4E,GAAanI,CAAAA,CAAoB8H,CAAAA,CAA2B,CAC1E,OAAK9H,GAKL6H,EAAAA,CAAe7H,CAAAA,CAAK8H,CAAE,CAAA,CAGf,IAAM,CACXE,EAAAA,CAAehI,CAAAA,CAAK8H,CAAE,EACxB,GARSnG,CASX,CCnDA,IAAMyG,EAAAA,CAAAA,CAAoBxF,IAAiB,CAAI,EAAA,CAAK,EAAA,EAAM,GAAA,CAE7CyF,EAA+B,CAC1C,QAAA,CAAUrJ,GACV,OAAA,CAASoJ,EAAAA,CACT,eAAgBA,EAAAA,CAAmB,EAAA,CACnC,qBAAA,CAAuB,GAAA,CACvB,QAAS,CACP,MAAA,CAAQ/J,GAAmB,mBAAA,CAC3B,iBAAA,CAAmB,mBACrB,CAAA,CACA,KAAA,CAAO,CACL,KAAA,CAAO+J,GAAmB,EAAA,CAC1B,QAAA,CAAUA,GACV,YAAA,CAAc,IAAA,CACd,QAAS,GAAA,CAGT,OAAA,CAAS,CACP,GAAA,CACA,IACA,GAAA,CACA,GAAA,CACA,GAAA,CACA,GAAA,CACA,IACA,GACF,CAAA,CAGA,OAAA,CAAS,CAACtJ,EAAKC,EAAAA,CAAM,KAAA,CAAO,SAAU,SAAA,CAAW,OAAO,CAC1D,CACF,CAAA,CAQO,SAASuJ,EAAAA,CACdC,EACwB,CACxB,IAAMC,CAAAA,CAAY9I,CAAAA,CAAe6I,CAAY,CAAA,CAG7C,OAAOE,CAAAA,CACL,CAAE,MAAOJ,CAAAA,CAAc,KAAA,CAAO,QAASA,CAAAA,CAAc,OAAQ,EAC7DG,CAAAA,CACAH,CACF,CACF,CAOO,SAASK,EAAAA,EAAkC,CAChD,OAAO,CAAE,GAAGL,CAAc,CAC5B,CASO,SAASM,GACdpI,CAAAA,CACAqI,CAAAA,CAMmE,CAGnE,IAAMC,CAAAA,CAASJ,EACbJ,CAAAA,CACAO,CAAAA,CAAYlJ,CAAAA,CAAekJ,CAAS,EAAI,EAC1C,EAEA,OAAOE,EAAAA,CAAmBvI,EAAKsI,CAAM,CACvC,CASO,SAASC,GACdvI,CAAAA,CACAwI,CAAAA,CACe,CACf,IAAIC,CAAAA,CAASD,EAAc,MAAA,CAC3BC,CAAAA,CAASA,CAAAA,CAAUA,CAAAA,CAAO,aAAY,CAAelK,CAAAA,CAErD,IAAImK,CAAAA,CAGAD,IAAWlK,CAAAA,EAAOkK,CAAAA,GAAWjK,EAAAA,GAC/BkK,CAAAA,CAAOF,EAAc,IAAA,EAAQA,CAAAA,CAAc,KAGvCE,CAAAA,EAAQ,OAAOA,IAASvK,CAAAA,EAAUkD,EAAAA,CAAmBqH,CAAI,CAAA,GAC3DA,EAAO,IAAA,CAAK,SAAA,CAAUA,CAAI,CAAA,CAAA,CAAA,CAI9BC,GAAuBH,CAAAA,CAAc,OAAA,CAASE,CAAI,CAAA,CAGlD,IAAME,CAAAA,CAAcJ,CAAAA,CAAc,gBAC9B,SAAA,CACAA,CAAAA,CAAc,YAGZK,CAAAA,CAAajI,EAAAA,CAAqBZ,CAAAA,CAAKwI,CAAAA,CAAc,aAAa,CAAA,CAClEM,CAAAA,CAAU/I,EAAAA,CAAkB8I,CAAAA,CAAYL,EAAc,MAAM,CAAA,CAE5DO,CAAAA,CADY7H,EAAAA,CAAclB,CAAG,CAAA,CAE/B,EAAA,CACAwI,EAAc,OAAA,EAAWA,CAAAA,CAAc,QAAU,EAAA,CAI/CQ,CAAAA,CACJD,CAAAA,EAAWD,CAAAA,EAAW,CAACC,CAAAA,CAAQ,QAAA,CAAS,GAAG,CAAA,EAAK,CAAC,SAAS,IAAA,CAAKD,CAAO,CAAA,CAClE,GAAA,CACA,GAEN,OAAAN,CAAAA,CAAc,IAAMO,CAAAA,CAAUC,CAAAA,CAAYF,EAC1CN,CAAAA,CAAc,MAAA,CAASC,CAAAA,CACvBD,CAAAA,CAAc,YAAcI,CAAAA,CAC5BJ,CAAAA,CAAc,IAAA,CAAOE,CAAAA,CAEdF,CACT,CAWA,SAASG,EAAAA,CACP7G,CAAAA,CACA4G,EACM,CAON,GALI,CAAC5G,CAAAA,EAAW,CAAC4G,GAMfA,CAAAA,YAAgB,QAAA,EACf,OAAO,IAAA,GAASzK,GAAayK,CAAAA,YAAgB,IAAA,EAC7C,OAAO,cAAA,GAAmBzK,GAAayK,CAAAA,YAAgB,cAAA,CAExD,OAGF,IAAIO,EAEJ,GAAIlK,CAAAA,CAAe2J,CAAI,CAAA,CACrBO,CAAAA,CAAmBpL,EAA2B,uBAAA,CAAA,KAAA,GACrC6K,CAAAA,YAAgB,WAAA,EAAe,WAAA,CAAY,OAAOA,CAAI,CAAA,CAC/DO,CAAAA,CAAmBpL,CAAAA,CAA2B,uBACrCwD,EAAAA,CAAmBqH,CAAI,CAAA,CAChCO,CAAAA,CAAmBnL,GAAmB,GAAA,CAAMC,EAAAA,CAAAA,YAM1C+D,CAAAA,YAAmB,OAAA,CAChBA,EAAQ,GAAA,CAAI9D,CAAY,CAAA,EAC3B8D,CAAAA,CAAQ,IAAI9D,CAAAA,CAAciL,CAAgB,EAG5ChK,CAAAA,CAAS6C,CAAO,GAChB,CAAC,KAAA,CAAM,OAAA,CAAQA,CAAO,GAEtB,CAACD,CAAAA,CAAeC,CAAwB,CAAA,CAAE9D,CAAAA,CAAa,aAAa,CAAA,GAEpE8D,CAAAA,CAAQ9D,CAAY,EAAIiL,CAAAA,EAE5B,CAGA,IAAMC,EAAAA,CAAe,CACnB,WAAA,CACA,YAAA,CACA,SAAA,CACA,eACF,EAmBO,SAAShB,CAAAA,CACdiB,EACAC,CAAAA,CACAC,CAAAA,CAA8B,EAAC,CAChB,CACf,MAAA,CAAO,MAAA,CAAOA,EAAcF,CAAAA,CAAYC,CAAc,CAAA,CAGtDE,EAAAA,CAAY,QAASH,CAAAA,CAAYC,CAAAA,CAAgBC,CAAY,CAAA,CAC7DC,GAAY,SAAA,CAAWH,CAAAA,CAAYC,EAAgBC,CAAY,CAAA,CAG/D,QAAWE,CAAAA,IAAYL,EAAAA,CACrBM,EAAAA,CAAkBD,CAAAA,CAAUJ,EAAYC,CAAAA,CAAgBC,CAAY,CAAA,CAGtE,OAAOA,CACT,CAKA,SAASG,EAAAA,CAIPD,CAAAA,CACAJ,EACAC,CAAAA,CACAC,CAAAA,CACM,CACN,IAAMI,CAAAA,CAAkBN,EAAWI,CAAQ,CAAA,CACrCG,CAAAA,CAAiBN,CAAAA,CAAeG,CAAQ,CAAA,CAE1CE,CAAAA,EAAmBC,EAErBL,CAAAA,CAAaE,CAAQ,EACnBA,CAAAA,GAAa,YAAA,CACT,EAAC,CAAE,OAAOG,CAAAA,CAAyBD,CAAwB,EAC3D,EAAC,CAAE,OAAOA,CAAAA,CAA0BC,CAAuB,CAAA,CAAA,CAExDD,CAAAA,EAAmBC,KAC5BL,CAAAA,CAAaE,CAAQ,CAAA,CAAIE,CAAAA,EAAmBC,GAEhD,CAUO,SAASJ,EAAAA,CACdC,CAAAA,CACAJ,EACAC,CAAAA,CACAC,CAAAA,CACM,CACN,IAAMM,CAAAA,CAAOR,EAAWI,CAAQ,CAAA,CAC1BK,CAAAA,CAAWR,CAAAA,CAAeG,CAAQ,CAAA,CAExC,GAAIK,CAAAA,CACF,GAAIL,IAAa,SAAA,CAAW,CAE1B,IAAMM,CAAAA,CACHF,aAA4D,OAAA,EAC5DC,CAAAA,YACC,QACEtB,CAAAA,CAAwBuB,CAAAA,CAC1BhI,EAAe8H,CAAI,CAAA,CACnB,CAAE,GAAIA,CAAuB,CAAA,CAC3BG,CAAAA,CAA2BD,CAAAA,CAC7BhI,CAAAA,CAAe+H,CAAQ,CAAA,CACvBzK,CAAAA,CAAeyK,CAAyB,CAAA,CAG5C,QAAWnK,CAAAA,IAAO,MAAA,CAAO,KAAKqK,CAAS,CAAA,CAAG,CACxC,IAAMC,CAAAA,CAAWtK,CAAAA,CAAI,WAAA,GAErB,IAAA,IAAWuK,CAAAA,IAAe1B,EACpB0B,CAAAA,CAAY,WAAA,KAAkBD,CAAAA,EAChC,OAAOzB,CAAAA,CAAO0B,CAAW,EAI7B1B,CAAAA,CAAO7I,CAAG,EAAIqK,CAAAA,CAAUrK,CAAG,EAC7B,CAEA4J,CAAAA,CAAaE,CAAQ,CAAA,CAAIjB,EAC3B,CAAA,KACEe,CAAAA,CAAaE,CAAQ,CAAA,CAAI,CACvB,GAAGI,CAAAA,CACH,GAAGxK,CAAAA,CAAeyK,CAAmC,CACvD,CAAA,CAAA,KAGFA,IAAa,MAAA,EACb3K,CAAAA,CAAS0K,CAAI,CAAA,EACb,EAAGA,CAAAA,YAA4C,OAAA,CAAA,GAG/CN,EAAaE,CAAQ,CAAA,CAAI,CAAE,GAAGI,CAAK,CAAA,EAEvC,CClUA,IAAMM,CAAAA,CAAS,IAAI,GAAA,CAEbC,EAAAA,CAAS,IAAI,GAAA,CACbC,EAAAA,CAAY,IACZC,EAAAA,CAAqB,EAAA,CACrBC,EAAAA,CAA6B,sBAAA,CAC7BC,GAA2B,qBAAA,CAgB3BC,EAAAA,CACJ,oNAAA,CA0BK,SAASC,GACdC,CAAAA,CACAC,CAAAA,CAAgB,IAAA,CACR,CAGR,IAAMjL,CAAAA,CAAMgL,CAAAA,CAAO,SAEnB,GAAIhL,CAAAA,EAAOiL,EACT,OAAO,OAAOjL,CAAAA,GAAQtB,CAAAA,CACjBsB,EACAA,CAAAA,CAAyBgL,CAAM,EAGtC,GAAM,CACJ,IAAAzK,CAAAA,CAAM,EAAA,CACN,MAAA,CAAAyI,CAAAA,CAASlK,EACT,OAAA,CAAAuD,CAAAA,CAAU,KACV,IAAA,CAAA4G,CAAAA,CAAO,KACP,WAAA,CAAAE,CAAAA,CAAc,aAChB,CAAA,CAAI6B,EAIAE,CAAAA,CAAgB,EAAA,CACpB,GAAI7I,CAAAA,CAAS,CACX,IAAI1C,CAAAA,CAEA0C,CAAAA,YAAmB,OAAA,CACrB1C,EAAMyC,CAAAA,CAAeC,CAAO,EAE5B1C,CAAAA,CAAM0C,CAAAA,CAKR,IAAM8I,CAAAA,CAAO,MAAA,CAAO,IAAA,CAAKxL,CAAG,EACtBuB,CAAAA,CAAMiK,CAAAA,CAAK,MAAA,CAGbjK,CAAAA,CAAM,GACRiK,CAAAA,CAAK,IAAA,EAAK,CAGZ,IAAIvF,EAAM,EAAA,CACV,IAAA,IAAS3E,EAAI,CAAA,CAAGA,CAAAA,CAAIC,EAAK,EAAED,CAAAA,CACrB6J,EAAAA,CAAkB,IAAA,CAAKK,EAAKlK,CAAC,CAAC,CAAA,GAChC2E,CAAAA,EAAOuF,EAAKlK,CAAC,CAAA,CAAI,GAAA,CAAMtB,CAAAA,CAAIwL,EAAKlK,CAAC,CAAC,EAAI,GAAA,CAAA,CAI1CiK,CAAAA,CAAgBvF,EAAKC,CAAG,EAC1B,CAIA,IAAMwF,EACJpC,CAAAA,CACA0B,EAAAA,CACAnK,EACAmK,EAAAA,CACAvB,CAAAA,CACAuB,GACAQ,CAAAA,CAGF,GAAIlC,CAAAA,GAAWlK,CAAAA,CACb,OAAOuM,EAAAA,CAAiBD,CAAQ,EAGlC,IAAIE,CAAAA,CAAa,GACjB,GAAIrC,CAAAA,CACF,GAAI,OAAOA,IAASvK,CAAAA,EAAUY,CAAAA,CAAe2J,CAAI,CAAA,CAAG,CAClD,IAAMrD,CAAAA,CAAM,MAAA,CAAOqD,CAAI,EAEvBqC,CAAAA,CAAa1F,CAAAA,CAAI,OAAS+E,EAAAA,CAAqB/E,CAAAA,CAAMD,EAAKC,CAAG,EAC/D,CAAA,KAAA,GAAWqD,CAAAA,YAAgB,SACzBA,CAAAA,CAAK,OAAA,CAAQ,CAACxJ,CAAAA,CAAOO,IAAQ,CAE3BsL,CAAAA,EACEtL,CAAAA,CACA,GAAA,EACC,OAAOP,CAAAA,GAAUf,CAAAA,CAASe,EAAQ,GAAA,CAAM8L,EAAAA,CAAY9L,CAAa,CAAA,CAAA,CAClE,IACJ,CAAC,CAAA,CAEG6L,EAAW,MAAA,CAASX,EAAAA,GACtBW,CAAAA,CAAa3F,CAAAA,CAAK2F,CAAU,CAAA,CAAA,CAAA,KAAA,GAErB9L,CAAAA,CAASyJ,CAAI,CAAA,EAAK,CAACrH,EAAAA,CAAmBqH,CAAI,EAGnDqC,CAAAA,CAAa,GAAA,CAAMC,GAAYtC,CAAI,CAAA,CAAA,KAC9B,CACL,IAAM7J,EAAII,CAAAA,CAASyJ,CAAI,EACnB,IAAA,CAAK,SAAA,CAAUhJ,GAAWgJ,CAAI,CAAC,CAAA,CAC/B,MAAA,CAAOA,CAAI,CAAA,CAEfqC,CAAAA,CAAalM,EAAE,MAAA,CAASuL,EAAAA,CAAqBhF,EAAKvG,CAAC,CAAA,CAAIA,EACzD,CAGF,OAAOiM,EAAAA,CAAiBD,CAAAA,CAAWV,EAAAA,CAAYY,CAAU,CAC3D,CAEA,IAAME,EAAAA,CAAY,IAAI,QAClBC,EAAAA,CAAe,CAAA,CAQnB,SAASF,EAAAA,CAAY5L,CAAAA,CAAqB,CACxC,IAAI+L,CAAAA,CAAKF,EAAAA,CAAU,GAAA,CAAI7L,CAAG,CAAA,CAE1B,OAAK+L,CAAAA,EACHF,EAAAA,CAAU,IAAI7L,CAAAA,CAAM+L,CAAAA,CAAK,EAAED,EAAa,EAGnCC,CACT,CAUA,SAASL,EAAAA,CAAiBD,CAAAA,CAA0B,CAClD,OAAOP,EAAAA,CAAyB,IAAA,CAAKO,CAAQ,EACzCA,CAAAA,CAAS,OAAA,CAAQR,EAAAA,CAA4B,EAAE,EAC7CF,EAAAA,CACA/E,CAAAA,CAAKyF,CAAQ,CAAA,CACfA,CACN,CAQA,SAASO,GAAehF,CAAAA,CAAiC,CAEvD,OAAKA,CAAAA,CAAM,MAAA,CAIJjF,CAAAA,EAAQ,CAAIiF,EAAM,MAAA,CAHhB,KAIX,CAQO,SAASiF,EAAAA,CAMd5L,EAC0E,CAC1E,GAAI,CAACA,CAAAA,CACH,OAAO,IAAA,CAGT,IAAM2G,EAAQ6D,CAAAA,CAAO,GAAA,CAAIxK,CAAG,CAAA,CAE5B,OAAO2G,CAAAA,CAAQA,CAAAA,CAAM,KAAO,IAC9B,CAQO,SAASkF,EAAAA,CACd7L,EAMY,CACZ,OAAOwK,CAAAA,CAAO,GAAA,CAAIxK,CAAa,CACjC,CAUO,SAAS8L,EAAAA,CACd9L,CAAAA,CACAT,EACA+H,CAAAA,CACAC,CAAAA,CACM,CACN,GAAID,IAAQ,CAAA,CAAG,CACbyE,EAAAA,CAAY/L,CAAG,EACf,MACF,CAEA,IAAMgM,CAAAA,CAAOtK,GAAQ,CACfuK,CAAAA,CAAQ3E,EAAMA,CAAAA,CAAM,GAAA,CAAO,EAC3B4E,CAAAA,CAAc3E,CAAAA,CAAYA,CAAAA,CAAY,GAAA,CAAO,EAEnDiD,CAAAA,CAAO,GAAA,CAAIxK,CAAAA,CAAK,CACd,KAAAT,CAAAA,CACA,IAAA,CAAAyM,CAAAA,CACA,KAAA,CAAOE,EAAc,CAAA,CAAIF,CAAAA,CAAOE,EAAc,MAAA,CAC9C,MAAA,CAAQ5E,IAAQ,EAAA,CAAK,MAAA,CAAY0E,CAAAA,CAAOC,CAC1C,CAAC,CAAA,CAEGA,CAAAA,CAAQ,GACVE,EAAAA,CAAenM,CAAAA,CAAKiM,CAAK,EAE7B,CAQA,SAASE,EAAAA,CAAenM,EAAa8B,CAAAA,CAAkB,CACrDoC,EAAW,IAAA,CAAOlE,CAAAA,CAAK,IAAM+L,EAAAA,CAAY/L,CAAAA,CAAK,IAAI,CAAA,CAAG8B,CAAE,EACzD,CAQO,SAASiK,EAAAA,CAAY/L,EAAaoM,CAAAA,CAAyB,KAAA,CAAa,CAC7E,GAAIA,EAAe,CACjB,IAAMzF,EAAQkF,EAAAA,CAAS7L,CAAG,EAG1B,GAAI,CAAC2G,CAAAA,EAAS,CAACgF,GAAehF,CAAK,CAAA,CACjC,MAEJ,CAEA6D,EAAO,MAAA,CAAOxK,CAAG,CAAA,CAEjB,IAAMqM,EAAQ5B,EAAAA,CAAO,GAAA,CAAIzK,CAAG,CAAA,CAExBqM,CAAAA,GACF5B,GAAO,MAAA,CAAOzK,CAAG,CAAA,CACjBsM,EAAAA,CAAU,IAAMD,CAAAA,CAAM,MAAA,CAAOrM,CAAG,CAAC,GAErC,CAeA,SAASsM,EAAAA,CAAUxE,CAAAA,CAAyB,CAC1C,GAAI,CACF,QAAQ,OAAA,CAAQA,CAAAA,EAAI,CAAA,CAAE,KAAA,CAAMnG,CAAI,EAClC,MAAQ,CAER,CACF,CAQA,SAAS4K,EAAAA,CAAavM,EAAaqM,CAAAA,CAA0B,CAC3D,IAAM1F,CAAAA,CAAQ6D,EAAO,GAAA,CAAIxK,CAAG,EAE5B,GAAIqM,CAAAA,EAAS1F,EAAO,CAClB,GAAM,CAAE,IAAA,CAAApH,EAAM,MAAA,CAAAiN,CAAAA,CAAQ,UAAA,CAAAC,CAAAA,CAAY,QAAApK,CAAQ,CAAA,CAAIsE,CAAAA,CAAM,IAAA,CAEpD8D,GAAO,GAAA,CAAIzK,CAAAA,CAAKqM,CAAK,CAAA,CACrBC,EAAAA,CAAU,IACRD,CAAAA,CAAM,GAAA,CAAIrM,CAAAA,CAAK,CAAE,GAAG2G,CAAAA,CAAO,IAAA,CAAM,CAAE,IAAA,CAAApH,EAAM,MAAA,CAAAiN,CAAAA,CAAQ,UAAA,CAAAC,CAAAA,CAAY,QAAApK,CAAQ,CAAE,CAAC,CAC1E,EACF,CACF,CAUA,eAAsBqK,EAAAA,CACpB1M,CAAAA,CACA+I,EAC4C,CAC5C,IAAMsD,CAAAA,CAAQtD,CAAAA,CAAc,WAE5B,GAAI,CAACsD,CAAAA,EAASM,EAAAA,CAAgB5D,CAAa,CAAA,CACzC,OAAO,KAGT,IAAIpC,CAAAA,CAEJ,GAAI,CACFA,CAAAA,CAAQ,MAAM0F,CAAAA,CAAM,IAAIrM,CAAG,EAC7B,MAAQ,CAEN,OAAO,IACT,CAGA,OAAI,CAAC2G,CAAAA,EAAS6D,EAAO,GAAA,CAAIxK,CAAG,EACnB,IAAA,CAGL2L,EAAAA,CAAehF,CAAK,CAAA,EACtB2F,EAAAA,CAAU,IAAMD,CAAAA,CAAM,OAAOrM,CAAG,CAAC,CAAA,CAE1B,IAAA,EAGF2G,CACT,CAUO,SAASiG,EAAAA,CACd5M,CAAAA,CACA2G,EACA0F,CAAAA,CACS,CACT,OAAA7B,CAAAA,CAAO,GAAA,CAAIxK,EAAK2G,CAAK,CAAA,CACrB8D,EAAAA,CAAO,GAAA,CAAIzK,EAAKqM,CAAK,CAAA,CAEjB1F,CAAAA,CAAM,MAAA,EACRwF,GAAenM,CAAAA,CAAK2G,CAAAA,CAAM,MAAA,CAASjF,CAAAA,EAAS,CAAA,CAG9CuG,CAAAA,CAAkBjI,EAAK2G,CAAAA,CAAM,IAAI,EAE1B,CAACA,CAAAA,CAAM,KAAA,EAASjF,CAAAA,GAAYiF,CAAAA,CAAM,KAC3C,CASA,eAAsBkG,GAMpB7M,CAAAA,CACA8M,CAAAA,CACAC,CAAAA,CAMQ,CAER,GAAI,CAAC/M,CAAAA,CACH,OAAO,IAAA,CAGT,IAAM2G,EAAQkF,EAAAA,CACZ7L,CACF,CAAA,CAEA,GAAI,CAAC2G,CAAAA,CACH,OAAO,KAGT,IAAMqG,CAAAA,CAAcxN,EAASsN,CAAO,CAAA,CAAIpN,CAAAA,CAAeoN,CAAO,EAAIA,CAAAA,CAE5DG,CAAAA,CAAkB,CACtB,GAAGtG,CAAAA,CAAM,KACT,IAAA,CAAMqG,CACR,CAAA,CAGM3K,CAAAA,CAAU4K,EAAgB,OAAA,CAE5B5K,CAAAA,EAAWA,CAAAA,CAAQ,IAAA,GACrB4K,EAAgB,OAAA,CAAU,CAAE,GAAG5K,CAAQ,EACvC,OAAO4K,CAAAA,CAAgB,QAAQ,IAAA,CAAA,CAGjC,IAAMC,EAAe,CACnB,GAAGvG,CAAAA,CACH,IAAA,CAAMsG,CACR,CAAA,CAMA,OAJAzC,CAAAA,CAAO,GAAA,CAAIxK,EAAKkN,CAAY,CAAA,CAC5BX,EAAAA,CAAavM,CAAAA,CAAKyK,GAAO,GAAA,CAAIzK,CAAG,CAAC,CAAA,CACjCiI,CAAAA,CAAkBjI,EAAKiN,CAAe,CAAA,CAElCF,CAAAA,EAAYA,CAAAA,CAAS,QAChB,MAAMlG,EAAAA,CAAW7G,CAAG,CAAA,CAGtB,IACT,CAQO,SAAS2M,EAAAA,CAAgB5D,CAAAA,CAAuC,CACrE,IAAMoE,CAAAA,CAASpE,EAAc,WAAA,EAAeV,CAAAA,CAAc,YAE1D,OACE,CAAC,EAAE8E,CAAAA,EAAUA,EAAOpE,CAAa,CAAA,CAAA,EAAMA,EAAc,KAAA,GAAU,QAEnE,CAcO,SAASqE,EAAAA,CAMdC,CAAAA,CACAC,CAAAA,CACAvE,EAM0E,CAM1E,GAJI,CAACsE,CAAAA,EAAYC,CAAAA,GAAc,QAAaA,CAAAA,GAAc,IAAA,EAItDX,EAAAA,CAAgB5D,CAAa,EAC/B,OAAO,IAAA,CAIT,IAAMpC,CAAAA,CAAQkF,GACZwB,CACF,CAAA,CAEA,GAAI,CAAC1G,EACH,OAAO,IAAA,CAMT,GAHkBgF,EAAAA,CAAehF,CAAK,EAIpC,OAAAoF,EAAAA,CAAYsB,CAAQ,CAAA,CACb,KAGT,IAAM9N,CAAAA,CAAOoH,CAAAA,CAAM,IAAA,CAInB,OAAOpH,CAAAA,EAAQA,CAAAA,CAAK,UAAA,CAAa,IAAA,CAAOA,CAC1C,CASO,SAASgO,GAMdC,CAAAA,CACAzE,CAAAA,CAMA0E,EAAmB,KAAA,CACb,CAEN,IAAMJ,CAAAA,CAAWtE,EAAc,QAAA,CAE/B,GAAIsE,CAAAA,CAAU,CACZ,IAAMC,CAAAA,CAAYvE,CAAAA,CAAc,SAAA,CAC1B2E,CAAAA,CAAY3E,EAAc,SAAA,CAGhC,GACEuE,IACC,CAACG,CAAAA,EAAW1E,EAAc,WAAA,CAAA,EAC3B,EAAE2E,CAAAA,EAAaA,CAAAA,CAAUF,EAAQzE,CAAa,CAAA,CAAA,CAE9C+C,GAASuB,CAAAA,CAAUG,CAAAA,CAAQF,EAAWvE,CAAAA,CAAc,SAAS,CAAA,CAGxD0E,CAAAA,EACHlB,GAAac,CAAAA,CAAUtE,CAAAA,CAAc,UAAU,CAAA,CAAA,KAE5C,CACL,IAAMpC,CAAAA,CAAQkF,EAAAA,CAASwB,CAAQ,CAAA,CAG3B1G,GAASA,CAAAA,CAAM,IAAA,EAAQA,CAAAA,CAAM,IAAA,CAAK,YACpCoF,EAAAA,CAAYsB,CAAQ,EAExB,CAEApF,EAAkBoF,CAAAA,CAAUG,CAAM,EAClClI,EAAAA,CAAe+H,CAAQ,EAEvB,IAAMM,CAAAA,CAAe5E,CAAAA,CAAc,QAAA,CAE/B4E,GACFrI,EAAAA,CAAeqI,CAAY,EAE/B,CACF,CCnnBA,eAAsBC,EAAAA,CAMpBrK,CAAAA,CACAsK,CAAAA,CACc,CAEd,GAAI,CAACtK,EACH,OAAO,IAAA,CAIT,IAAMlB,CAAAA,CAAWkB,CAAAA,CAAsB,OAAA,CACnCuK,CAAAA,CAAczL,GAAWA,CAAAA,CAAQ,GAAA,CAAI9D,CAAY,CAAA,CAEjDuP,EAEFA,CAAAA,CAAcA,CAAAA,CAAY,WAAA,EAAY,CAAE,MAAK,CAE7CA,CAAAA,CAAc,GAIhB,IAAMC,CAAAA,CAAWD,EAAY,KAAA,CAAM,GAAA,CAAK,CAAC,CAAA,CAAE,CAAC,CAAA,CAExCvO,CAAAA,CAEJ,GAAI,CACF,GAAIsO,EAEFtO,CAAAA,CACEsO,CAAAA,GAAiB,QAAA,CACbtK,CAAAA,CAAS,KACT,MAAMA,CAAAA,CAASsK,CAAY,CAAA,EAAE,CAAA,KAAA,GAEnCE,EAAS,QAAA,CAAS1P,EAAgB,CAAA,EAClC0P,CAAAA,CAAS,SAAS,OAAO,CAAA,CAEzBxO,CAAAA,CAAO,MAAMgE,EAAS,IAAA,EAAK,CAAA,KAAA,GAAA,CAE1BwK,CAAAA,CAAS,QAAA,CAAS,qBAAqB,CAAA,EACtCA,CAAAA,CAAS,SACP3P,CAAAA,CAA2B,uBAC7B,IACF,OAAOmF,CAAAA,CAAS,QAAA,GAAa5E,CAAAA,CAE7BY,EAAO,MAAMgE,CAAAA,CAAS,QAAA,EAAS,CAAA,KAAA,GACtB,8CAA8C,IAAA,CAAKwK,CAAQ,CAAA,CACpExO,CAAAA,CAAO,MAAMgE,CAAAA,CAAS,WAAA,WAEtBhE,CAAAA,CAAO,MAAMgE,EAAS,IAAA,EAAK,CAEvB,OAAOhE,CAAAA,GAASb,EAAQ,CAC1B,IAAMsP,CAAAA,CAAUzO,CAAAA,CAAK,MAAK,CAC1B,GACGyO,CAAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,EAAKA,CAAAA,CAAQ,SAAS,GAAG,CAAA,EAC/CA,EAAQ,UAAA,CAAW,GAAG,CAAA,EAAKA,CAAAA,CAAQ,SAAS,GAAG,CAAA,CAEhD,GAAI,CACFzO,CAAAA,CAAO,KAAK,KAAA,CAAMyO,CAAO,EAC3B,CAAA,KAAQ,CAER,CAEJ,CAGJ,MAAiB,CAEfzO,CAAAA,CAAO,KACT,CAEA,OAAOA,CACT,CAUO,IAAM0O,EAAAA,CAAkB,CAM7B1K,CAAAA,CAMAyH,CAAAA,CACArI,EAKW,IAAA,GAC2D,CACtE,IAAMuL,CAAAA,CAAkBlD,EAAO,eAAA,CACzBqC,CAAAA,CAAWrC,EAAO,QAAA,CAClBmD,CAAAA,CAAYtB,GAAO,IAAA,CAAK,IAAA,CAAMQ,CAAkB,CAAA,CAQtD,GAAI,CAAC9J,CAAAA,CACH,OAAO,CACL,GAAI,KAAA,CAEJ,KAAA,CAAAZ,CAAAA,CACA,IAAA,CAAMuL,GAAmB,IAAA,CACzB,OAAA,CAAS,KACT,MAAA,CAAAlD,CAAAA,CACA,OAAQmD,CAAAA,CACR,UAAA,CAAY,KAAA,CACZ,SAAA,CAAW,MACX,OAAA,CAAS,IACX,CAAA,CAQF,IAAMC,EACJ,OAAO,QAAA,GAAazP,CAAAA,EAAY4E,CAAAA,YAAoB,SAElDhE,CAAAA,CAAOgE,CAAAA,CAAS,KAKlB2K,CAAAA,GAAoB,MAAA,GAElB3O,GAAS,IAAA,EACR,6BAAA,CAA8B,IAAA,CAC7B,MAAA,CAAO,UAAU,QAAA,CAAS,IAAA,CAAKA,CAAI,CACrC,CAAA,EACE,OAAO,IAAA,CAAKA,CAAI,CAAA,CAAE,MAAA,GAAW,KAEjCgE,CAAAA,CAAS,IAAA,CAAOhE,EAAO2O,CAAAA,CAAAA,CAGrBlD,CAAAA,CAAO,kBACTzH,CAAAA,CAAS,IAAA,CAAOhE,CAAAA,CAAO4C,EAAAA,CAAY5C,CAAI,CAAA,CAAA,CAGrCyL,CAAAA,CAAO,MAAA,GACTzH,CAAAA,CAAS,KAAOhE,CAAAA,CAAOyL,CAAAA,CAAO,MAAA,CAAOzL,CAAI,GAG3C,IAAM8C,CAAAA,CAAUD,EAAemB,CAAAA,CAAS,OAAO,EAG/C,GAAI6K,CAAAA,CAAkB,CACpB,IAAMZ,EAKF,CACF,IAAA,CAAMjK,CAAAA,CAAS,IAAA,CACf,SAAUA,CAAAA,CAAS,QAAA,CACnB,EAAA,CAAIA,CAAAA,CAAS,GACb,UAAA,CAAYA,CAAAA,CAAS,WACrB,IAAA,CAAMA,CAAAA,CAAS,KACf,GAAA,CAAKA,CAAAA,CAAS,GAAA,CACd,MAAA,CAAQA,EAAS,MAAA,CACjB,UAAA,CAAYA,CAAAA,CAAS,UAAA,CAIrB,KAAM,SACJhE,CAAAA,YAAgB,WAAA,CAAc,IAAI,KAAK,CAACA,CAAI,CAAC,CAAA,CAAI,IAAI,KACvD,IAAA,CAAM,SAAYA,CAAAA,CAClB,IAAA,CAAM,SAAYA,CAAAA,CAElB,KAAA,CAAO,KAAO,CAAE,GAAGiO,CAAO,CAAA,CAAA,CAC1B,WAAA,CAAa,SACXjO,CAAAA,YAAgB,YAAcA,CAAAA,CAAO,IAAI,YAAY,CAAC,CAAA,CACxD,SAAU,SAAaA,CAAAA,YAAgB,QAAA,CAAWA,CAAAA,CAAO,IAAI,QAAA,CAC7D,KAAA,CAAO,SACL,IAAI,WAAWA,CAAAA,YAAgB,WAAA,CAAcA,CAAAA,CAAO,IAAI,YAAY,CAAC,CAAC,EAExE,KAAA,CAAAoD,CAAAA,CACA,KAAApD,CAAAA,CACA,OAAA,CAAA8C,CAAAA,CACA,MAAA,CAAA2I,EACA,MAAA,CAAQmD,CAAAA,CACR,UAAA,CAAY,KAAA,CACZ,UAAW5K,CAAAA,CAAS,EAAA,EAAM,CAACZ,CAAAA,CAC3B,QAAS,CAAC,CAACA,CACb,CAAA,CAEA,OAAO6K,CACT,CAGA,OAAIhO,CAAAA,CAAS+D,CAAQ,GACnB,MAAA,CAAO,MAAA,CAAOA,CAAAA,CAAU,CACtB,MAAAZ,CAAAA,CACA,OAAA,CAAAN,CAAAA,CACA,UAAA,CAAY,MACZ,MAAA,CAAQ8L,CAAAA,CACR,UAAW5K,CAAAA,CAAS,EAAA,EAAM,CAACZ,CAAAA,CAC3B,OAAA,CAAS,CAAC,CAACA,CACb,CAAC,CAAA,CAGIY,CACT,CAAA,CCnPA,SAAS8K,GAAkBC,CAAAA,CAAmC,CAC5D,IAAMxM,CAAAA,CAAK,KAAK,KAAA,CAAMwM,CAAU,EAAI5M,CAAAA,EAAQ,CAE5C,OAAK,KAAA,CAAMI,CAAE,CAAA,CAGN,IAAA,CAFE,KAAK,GAAA,CAAI,CAAA,CAAG,IAAA,CAAK,KAAA,CAAMA,CAAE,CAAC,CAGrC,CAaO,SAASyM,GACdC,CAAAA,CACe,CACf,GAAI,CAACA,CAAAA,CACH,OAAO,IAAA,CAGT,IAAMnM,CAAAA,CAAUmM,CAAAA,CAAiB,SAAW,EAAC,CACvCC,CAAAA,CAAapM,CAAAA,CAAQ,aAAa,CAAA,CAExC,GAAIoM,CAAAA,CAAY,CAEd,IAAMpK,CAAAA,CAAU,MAAA,CAAOoK,CAAU,CAAA,CAEjC,GAAI,CAAC,KAAA,CAAMpK,CAAO,CAAA,EAAKA,CAAAA,EAAW,EAChC,OAAOA,CAAAA,CAAU,GAAA,CAGnB,IAAMvC,EAAKuM,EAAAA,CAAkBI,CAAU,CAAA,CAEvC,GAAI3M,IAAO,IAAA,CACT,OAAOA,CAEX,CAGA,IAAM4M,EAAkB,iBAAA,CAIlBC,CAAAA,CACJtM,CAAAA,CAAQqM,CAAAA,CAAkB,QAAQ,CAAA,EAClCrM,CAAAA,CAAQ,KAAOqM,CAAAA,CAAkB,QAAQ,EAE3C,GAAIC,CAAAA,CAAqB,CACvB,IAAMtK,EAAU,MAAA,CAAOsK,CAAmB,EAE1C,GAAI,CAAC,MAAMtK,CAAO,CAAA,CAChB,OAAOA,CAAAA,CAAU,GAErB,CAIA,IAAMuK,CAAAA,CACJvM,CAAAA,CAAQqM,EAAkB,KAAK,CAAA,EAAKrM,CAAAA,CAAQ,IAAA,CAAOqM,EAAkB,KAAK,CAAA,CAE5E,OAAIE,CAAAA,CACKP,EAAAA,CAAkBO,CAAgB,CAAA,CAGpC,IACT,CAkBA,eAAsBC,GAMpBC,CAAAA,CAMA9D,CAAAA,CAC4E,CAC5E,GAAM,CACJ,OAAA,CAAA+D,CAAAA,CAAU,CAAA,CACV,KAAA,CAAAC,EAAQ,CAAA,CACR,OAAA,CAAAC,EAAU,CAAA,CACV,QAAA,CAAAC,EACA,OAAA,CAAAC,CAAAA,CAAU,EAAC,CACX,YAAAC,CAAAA,CACA,MAAA,CAAAC,CAAAA,CACA,OAAA,CAAAC,CACF,CAAA,CAAItE,CAAAA,CAEAuE,CAAAA,CAAU,CAAA,CACVC,EAAWR,CAAAA,CACTS,CAAAA,CAAaV,EAAU,CAAA,CAAIA,CAAAA,CAAU,EACvCvB,CAAAA,CAEJ,KAAO+B,CAAAA,EAAWE,CAAAA,EAAY,CAG5B,GAAIF,CAAAA,CAAU,GAAK/B,CAAAA,CAAS,CAC1B,IAAMkC,CAAAA,CAAMlC,CAAAA,CAAO,MAAA,CACbmC,CAAAA,CAAUD,EAAI,OAAA,CAEhBC,CAAAA,GACF,MAAM3M,CAAAA,CAAkB2M,CAAAA,CAASnC,EAAQ+B,CAAO,CAAA,CAI5CG,CAAAA,CAAI,UAAA,GACNA,EAAI,QAAA,CAAWA,CAAAA,CAAI,QAAA,CACnBA,CAAAA,CAAI,SAAW3E,EAAAA,CAAiB2E,CAAAA,CAAK,KAAK,CAAA,CAAA,EAGhD,CAKAlC,CAAAA,CAAS,MAAMsB,EAAUS,CAAAA,CAAU,CAAA,CAAGA,CAAO,CAAA,CAC7C,IAAM5M,CAAAA,CAAQ6K,CAAAA,CAAO,MAIrB,GACE7K,CAAAA,CACI,MAAMiN,EAAAA,CACJpC,EACA+B,CAAAA,CACAE,CAAAA,CACAL,CAAAA,CACAD,CAAAA,CACAG,CACF,CAAA,CACA,EACEF,GACAG,CAAAA,CAAUE,CAAAA,EACT,MAAML,CAAAA,CAAY5B,CAAAA,CAAQ+B,CAAO,CAAA,CAAA,CAGxC,MAIF,IAAIM,CAAAA,CAAaC,EAAAA,CAAWN,CAAAA,CAAUH,CAAM,CAAA,CAG5C,GAAI1M,CAAAA,GAAUA,CAAAA,CAAM,SAAW,GAAA,EAAOA,CAAAA,CAAM,SAAW,GAAA,CAAA,CAAM,CAE3D,IAAMoN,CAAAA,CAAexB,EAAAA,CAAgBf,CAAM,CAAA,CAIvCuC,IAAiB,IAAA,GACnBF,CAAAA,CAAaL,EAAW,IAAA,CAAK,GAAA,CAC3BO,EACAb,CAAAA,EAAYa,CACd,CAAA,EAEJ,CAEA,MAAMlO,EAAAA,CAAgBgO,CAAU,EAChCL,CAAAA,EAAYP,CAAAA,EAAW,EACvBO,CAAAA,CAAW,IAAA,CAAK,GAAA,CAAIA,CAAAA,CAAUN,GAAYM,CAAQ,CAAA,CAClDD,CAAAA,GACF,CAEA,OAAO/B,CACT,CAwBA,eAAsBoC,EAAAA,CAMpBpC,EACA+B,CAAAA,CACAE,CAAAA,CACAL,EAMAD,CAAAA,CAAoB,GACpBG,CAAAA,CACkB,CASlB,GALIC,CAAAA,GAAYE,GAKZjC,CAAAA,CAAO,KAAA,EAAO,WAAA,CAChB,OAAO,MAIT,GAAI4B,CAAAA,CAAa,CACf,IAAMnL,EAAS,MAAMmL,CAAAA,CAAY5B,EAAQ+B,CAAO,CAAA,CAEhD,GAAItL,CAAAA,GAAW,IAAA,CACb,OAAO,CAACA,CAEZ,CAEA,OAAO,EAAA,CACJkL,CAAAA,EAAW,EAAC,EAAG,QAAA,CAAS3B,CAAAA,CAAO,KAAA,EAAO,QAAU,CAAC,CAAA,GACjD,CAAC8B,CAAAA,EACAA,CAAAA,CAAQ,KAAMtG,CAAAA,EAAWA,CAAAA,CAAO,WAAA,EAAY,GAAMwE,EAAO,MAAA,CAAO,MAAM,GAE5E,CASA,SAASsC,GAAWd,CAAAA,CAAeK,CAAAA,CAAuC,CACxE,OAAO,OAAOA,CAAAA,GAAW1Q,CAAAA,CACpB0Q,EAAqCL,CAAK,CAAA,CAC3CK,EACE,IAAA,CAAK,MAAA,EAAO,CAAIL,CAAAA,CAChBA,CACR,CCrQA,eAAsBgB,EAAAA,CAMpBlB,CAAAA,CAMAmB,EACAC,CAAAA,CACAC,CAAAA,CAAc,CAAA,CACdC,CAAAA,CAAe,EACfC,CAAAA,CAAoB,KAAA,CACpBC,EAAqB,KAAA,CACrBvO,CAAAA,CAC4E,CAC5E,GAAI,CAACkO,CAAAA,CACH,OAAOnB,GAAU,CAGnB,IAAIyB,CAAAA,CAAiB,CAAA,CACjB/C,EAEJ,KAAA,CAAO2C,CAAAA,GAAgB,CAAA,EAAKI,CAAAA,CAAiBJ,KACvCC,CAAAA,CAAe,CAAA,EACjB,MAAMvO,EAAAA,CAAgBuO,CAAAA,CAAcrO,CAAM,CAAA,CAG5CyL,CAAAA,CAAS,MAAMsB,CAAAA,GAEfyB,CAAAA,EAAAA,CAGG,EAAAJ,CAAAA,CAAc,CAAA,EAAKI,GAAkBJ,CAAAA,EACtC,CAACF,CAAAA,EACAC,CAAAA,EAAqBA,EAAkB1C,CAAAA,CAAQ+C,CAAc,KAMhE,GAIE,GAHA,MAAM1O,EAAAA,CAAgBoO,CAAAA,CAAiBlO,CAAM,CAAA,CAGzCA,GAAUA,CAAAA,CAAO,OAAA,CACnB,OAAOyL,CAAAA,CAAAA,MAGR,CAAC6C,GAAqBvN,EAAAA,EAAa,EACnC,CAACwN,CAAAA,EAAsBvN,IAAU,EAItC,OAAOyK,CACT,CCzEA,IAAMgD,GAAqB,CAAC,GAAA,CAAK,GAAA,CAAK,GAAG,EAInCC,EAAAA,CACJ,iNAAA,CAGIC,EAAAA,CAAYzH,CAAAA,EAChB,OAAO,cAAA,GAAmBzK,CAAAA,EAAayK,CAAAA,YAAgB,cAAA,CAE5C0H,GAAa,CAACC,CAAAA,CAAgBC,KAAoC,CAC7E,MAAA,CAAAD,EACA,KAAA,CAAAC,CAAAA,CACA,QAAA,CAAUA,CAAAA,CAAQD,EAASC,CAAAA,CAAQ,MACrC,CAAA,CAAA,CAWO,SAASC,GACdvQ,CAAAA,CACAyK,CAAAA,CACmB,CACnB,IAAM/B,EAAO+B,CAAAA,CAAO,IAAA,CAEpB,OAAO,OAAO,cAAA,GAAmBxM,GAAa,CAACkS,EAAAA,CAASzH,CAAI,CAAA,CACxD8H,GAAYxQ,CAAAA,CAAKyK,CAAAA,CAAQ/B,CAAI,CAAA,CAC7B+H,GAAazQ,CAAAA,CAAKyK,CAAAA,CAAQ/B,CAAI,CACpC,CAEA,SAAS8H,EAAAA,CACPxQ,EACAyK,CAAAA,CACA/B,CAAAA,CACmB,CACnB,OAAO,IAAI,OAAA,CAAQ,CAACjH,EAASiP,CAAAA,GAAW,CACtC,IAAMC,CAAAA,CAAM,IAAI,eAEVnP,CAAAA,CAASiJ,CAAAA,CAAO,MAAA,CAChBmG,CAAAA,CAAQ,IAAMD,CAAAA,CAAI,KAAA,GAElBE,CAAAA,CAAUtJ,CAAAA,EAAmB,CACjC/F,CAAAA,CAAO,mBAAA,CAAoB,OAAA,CAASoP,CAAK,EAEzC,GAAI,CACFrJ,CAAAA,GACF,OAASnF,CAAAA,CAAO,CACdsO,CAAAA,CAAOtO,CAAK,EACd,CACF,CAAA,CAEAuO,EAAI,IAAA,CAAKlG,CAAAA,CAAO,OAAkBzK,CAAG,CAAA,CACrC2Q,CAAAA,CAAI,YAAA,CAAe,OACnBA,CAAAA,CAAI,eAAA,CAAkBlG,CAAAA,CAAO,WAAA,GAAgB,UAE7C,IAAI,OAAA,CAAQA,CAAAA,CAAO,OAAO,EAAE,OAAA,CAC1B,CAACvL,EAAOiD,CAAAA,GACN+N,EAAAA,CAAkB,KAAK/N,CAAI,CAAA,EAAKwO,CAAAA,CAAI,gBAAA,CAAiBxO,EAAMjD,CAAK,CACpE,CAAA,CAEAyR,CAAAA,CAAI,OAAO,UAAA,CAAclK,CAAAA,EACvBgE,CAAAA,CAAO,gBAAA,CACL2F,GACE3J,CAAAA,CAAM,MAAA,CACNA,EAAM,gBAAA,CAAmBA,CAAAA,CAAM,MAAQ,MACzC,CACF,CAAA,CAEFkK,CAAAA,CAAI,OAAS,IACXE,CAAAA,CAAO,IAAM,CACX,IAAM/O,EAAU,IAAI,OAAA,CAEpB,IAAA,IAAWgP,CAAAA,IAAQH,EAAI,qBAAA,EAAsB,CAAE,MAAM,OAAO,CAAA,CAAG,CAC7D,IAAMI,CAAAA,CAAQD,CAAAA,CAAK,OAAA,CAAQ,GAAG,CAAA,CAE1BC,CAAAA,CAAQ,CAAA,EACVjP,CAAAA,CAAQ,OAAOgP,CAAAA,CAAK,KAAA,CAAM,CAAA,CAAGC,CAAK,EAAGD,CAAAA,CAAK,KAAA,CAAMC,EAAQ,CAAC,CAAA,CAAE,MAAM,EAErE,CAEA,IAAM/N,EAAW,IAAI,QAAA,CACnBiN,EAAAA,CAAmB,QAAA,CAASU,EAAI,MAAM,CAAA,CAAI,IAAA,CAAOA,CAAAA,CAAI,SACrD,CAAE,MAAA,CAAQA,EAAI,MAAA,CAAQ,UAAA,CAAYA,EAAI,UAAA,CAAY,OAAA,CAAA7O,CAAQ,CAC5D,EAGA,MAAA,CAAO,cAAA,CAAekB,CAAAA,CAAU,KAAA,CAAO,CAAE,KAAA,CAAO2N,CAAAA,CAAI,WAAY,CAAC,EAEjElP,CAAAA,CAAQuB,CAAQ,EAClB,CAAC,CAAA,CAEH2N,EAAI,OAAA,CAAU,IACZE,CAAAA,CAAO,IAAMH,EAAO,IAAI,SAAA,CAAU,wBAAwB,CAAC,CAAC,EAG9D,IAAMM,CAAAA,CAAU,IACdH,CAAAA,CAAO,IACLH,CAAAA,CACElP,CAAAA,CAAO,QACLS,CAAAA,CAAiB,yBAAA,CAA2B5D,CAAW,CAC3D,CACF,CAAA,CAIF,GAFAsS,EAAI,OAAA,CAAUK,CAAAA,CAEVxP,CAAAA,CAAO,OAAA,CACT,OAAOwP,CAAAA,EAAQ,CAGjBxP,CAAAA,CAAO,gBAAA,CAAiB,QAASoP,CAAK,CAAA,CAEtCD,EAAI,IAAA,CAAKjI,CAA8B,EACzC,CAAC,CACH,CAEA,eAAe+H,GACbzQ,CAAAA,CACAyK,CAAAA,CACA/B,CAAAA,CACmB,CACnB,IAAM5G,CAAAA,CAAU,IAAI,OAAA,CAAQ2I,CAAAA,CAAO,OAAO,CAAA,CACtCwG,CAAAA,CAASvI,EACT4H,CAAAA,CAEJ,GAAI,CAACH,EAAAA,CAASzH,CAAI,CAAA,CAAG,CAEnB,IAAMwI,CAAAA,CAAOxI,CAAAA,YAAgB,IAAA,CAAOA,CAAAA,CAAO,MAAM,IAAI,QAAA,CAASA,CAAI,CAAA,CAAE,MAAK,CAEzE4H,CAAAA,CAAQY,EAAK,IAAA,CACbD,CAAAA,CAASC,EAAK,MAAA,EAAO,CAEjBA,CAAAA,CAAK,IAAA,EAAQ,CAACpP,CAAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,EAC1CA,CAAAA,CAAQ,IAAI,cAAA,CAAgBoP,CAAAA,CAAK,IAAI,EAEzC,CAEA,IAAIb,CAAAA,CAAS,EAEb,OAAO,KAAA,CAAMrQ,EAAK,CAChB,GAAGyK,CAAAA,CACH,OAAA,CAAA3I,EACA,IAAA,CAAMmP,CAAAA,CAAO,WAAA,CACX,IAAI,gBAAgB,CAClB,SAAA,CAAUE,CAAAA,CAAOtM,CAAAA,CAAY,CAC3BwL,CAAAA,EAAUc,CAAAA,CAAM,WAChB1G,CAAAA,CAAO,gBAAA,CAAkB2F,GAAWC,CAAAA,CAAQC,CAAK,CAAC,CAAA,CAClDzL,EAAW,OAAA,CAAQsM,CAAK,EAC1B,CACF,CAAC,CACH,CAAA,CAEA,MAAA,CAAQ,MACV,CAAgB,CAClB,CCzJO,SAASC,EAAAA,CACdpO,CAAAA,CACAqO,EACG,CAEH,GACE,CAACA,CAAAA,EACD,OAAO,QAAA,GAAajT,CAAAA,EACpB,EAAE4E,CAAAA,YAAoB,WACtB,CAACA,CAAAA,CAAS,IAAA,CAEV,OAAOA,EAGT,IAAMlB,CAAAA,CAAUkB,EAAS,OAAA,CAEnBsN,CAAAA,CAAQxO,EAAQ,GAAA,CAAI,kBAAkB,CAAA,CACxC,MAAA,CACA,OAAOA,CAAAA,CAAQ,GAAA,CAAI,gBAAgB,CAAC,CAAA,EAAK,OACzCuO,CAAAA,CAAS,CAAA,CAEPiB,CAAAA,CAAU,IAAI,SAClBtO,CAAAA,CAAS,IAAA,CAAK,YACZ,IAAI,eAAA,CAAgB,CAClB,SAAA,CAAUmO,CAAAA,CAAOtM,CAAAA,CAAY,CAC3BwL,GAAUc,CAAAA,CAAM,UAAA,CAEhBE,CAAAA,CACEjB,EAAAA,CAAWC,EAAQC,CAAAA,EAAS,IAAA,CAAK,GAAA,CAAIA,CAAAA,CAAOD,CAAM,CAAC,CACrD,EACAxL,CAAAA,CAAW,OAAA,CAAQsM,CAAK,EAC1B,CACF,CAAC,CACH,EACAnO,CACF,CAAA,CAGA,IAAA,IAAWvD,CAAAA,IAAO,CAAC,KAAA,CAAO,YAAA,CAAc,MAAM,CAAA,CAC5C,OAAO,cAAA,CAAe6R,CAAAA,CAAS7R,EAAK,CAAE,KAAA,CAAOuD,EAASvD,CAAG,CAAE,CAAC,CAAA,CAG9D,OAAO6R,CACT,CClCA,eAAsBC,EAAAA,CAMpBtL,EACAsI,CAAAA,CAKA/F,CAAAA,CAM4E,CAC5E,IAAMyE,EAAS,MAAMsB,CAAAA,CAAUtI,CAAmB,CAAA,CAC5C7D,CAAAA,CAAQ6K,EAAO,KAAA,CAErB,GAAI,CAAC7K,CAAAA,CAEH,OAAA4K,EAAAA,CAAoBC,CAAAA,CAAQzE,CAAa,CAAA,CAElCyE,CAAAA,CAKLzE,EAAc,OAAA,EAChB,MAAM/F,CAAAA,CAAkB+F,CAAAA,CAAc,QAASpG,CAAK,CAAA,CAKtD,IAAMoP,CAAAA,CAAcpP,CAAAA,CAAM,YAEpBqP,CAAAA,CAASjJ,CAAAA,CAAc,MAAA,CAkB7B,GAhBI,CAACgJ,CAAAA,EAAeC,CAAAA,EAAUA,CAAAA,CAAO,IAAA,EACnCA,EAAO,IAAA,CAAK,aAAA,CAAeC,EAAAA,CAAYtP,CAAsB,CAAC,CAAA,CAK5DoG,CAAAA,CAAc,WAAa,iBAAA,GAC7ByE,CAAAA,CAAO,KAAQzE,CAAAA,CAAc,eAAA,EAAmB,IAAA,CAAA,CAIlDwE,EAAAA,CAAoBC,EAAQzE,CAAAA,CAAe,IAAI,CAAA,CAGrB,CAACgJ,GAAehJ,CAAAA,CAAc,eAAA,CAEjC,CACrB,IAAMmJ,EAAWnJ,CAAAA,CAAc,QAAA,CAE/B,GAAImJ,CAAAA,GAAalT,EAAAA,CACf,MAAM2D,CAAAA,CAIJuP,CAAAA,GAAa,QAAA,EACf,MAAM,IAAI,OAAA,CAAQ,IAAM,IAAI,EAEhC,CAEA,OAAO1E,CACT,CAGA,IAAM2E,GAAoB,CACxB,eAAA,CACA,sBACA,QAAA,CACA,WACF,EAMA,SAASF,EAAAA,CAAYtP,CAAAA,CAAqC,CAExD,IAAMqI,CAAAA,CAAS,CACb,GAAGrI,CAAAA,CAAM,MAAA,CACT,KAAM,MAAA,CACN,IAAA,CAAM,MAAA,CACN,QAAA,CAAU,OACV,QAAA,CAAU,MAAA,CACV,QAASP,CAAAA,CAAeO,CAAAA,CAAM,OAAO,OAAwB,CAC/D,CAAA,CAEA,IAAA,IAAWD,KAAQyP,EAAAA,CACbnH,CAAAA,CAAO,OAAA,CAAQtI,CAAI,IACrBsI,CAAAA,CAAO,OAAA,CAAQtI,CAAI,CAAA,CAAI,cAI3B,IAAM0P,CAAAA,CAAO,OAAO,MAAA,CAAO,IAAI,MAAMzP,CAAAA,CAAM,OAAO,CAAA,CAAGA,CAAAA,CAAO,CAC1D,MAAA,CAAAqI,CAAAA,CACA,OAAA,CAASA,CAAAA,CACT,SAAUrI,CAAAA,CAAM,QAAA,EAAY,CAAE,GAAGA,EAAM,QAAA,CAAU,MAAA,CAAAqI,CAAO,CAC1D,CAAC,EAED,OAAAoH,CAAAA,CAAK,IAAA,CAAOzP,CAAAA,CAAM,KAClByP,CAAAA,CAAK,KAAA,CAAQzP,CAAAA,CAAM,KAAA,CAEZyP,CACT,CAEO,SAASC,EAAAA,CAOd1P,CAAAA,CACAY,EAMAwF,CAAAA,CAMM,CACNpG,EAAM,MAAA,CAASA,CAAAA,CAAM,QAAWY,CAAAA,EAAYA,CAAAA,CAAS,MAAA,EAAW,CAAA,CAChEZ,EAAM,UAAA,CACJA,CAAAA,CAAM,YAAeY,CAAAA,EAAYA,CAAAA,CAAS,YAAe,EAAA,CAC3DZ,CAAAA,CAAM,MAAA,CAASA,CAAAA,CAAM,QAAUoG,CAAAA,CAC/BpG,CAAAA,CAAM,SAAWY,CAAAA,CACjBZ,CAAAA,CAAM,YAAcA,CAAAA,CAAM,IAAA,GAAS/D,EACrC,CC1HA,IAAM0T,EAAAA,CAAmB,MAAA,CAAO,MAAA,CAAO,CACrC,WAAY,IACd,CAAC,CAAA,CAqBD,eAAsBC,GAMpBhS,CAAAA,CACAqI,CAAAA,CAKW,KACiE,CAI5E,GAAIA,GAAa,OAAOA,CAAAA,CAAU,QAAA,EAAa,QAAA,CAAU,CACvD,IAAM4J,CAAAA,CAASpF,EAAAA,CAKbxE,CAAAA,CAAU,SAAUA,CAAAA,CAAU,SAAA,CAAWA,CAAS,CAAA,CAEpD,GAAI4J,CAAAA,CACF,OAAOA,CAEX,CAEA,IAAMC,EAAgB9J,EAAAA,CAKpBpI,CAAAA,CAAKqI,CAAS,CAAA,CAEV,CACJ,OAAA,CAAAjE,CAAAA,CACA,WAAA,CAAA+N,CAAAA,CACA,SAAArF,CAAAA,CACA,UAAA,CAAAzI,CAAAA,CACA,SAAA,CAAA0I,EACA,SAAA,CAAA/F,CAAAA,CACA,eAAAE,CAAAA,CACA,kBAAA,CAAAC,EACA,eAAA,CAAAuI,CAAAA,CAAkB,CACpB,CAAA,CAAIwC,EACEE,CAAAA,CAAiBrF,CAAAA,GAAc,QAAa/F,CAAAA,GAAc,MAAA,CAC1DyB,EAASyJ,CAAAA,CAAc,MAAA,CAIvBG,CAAAA,CACJD,CAAAA,GACC3J,IAAWlK,CAAAA,EAAOkK,CAAAA,GAAWjK,MAC7B0T,CAAAA,CAAc,IAAA,EAAQ,CAACA,CAAAA,CAAc,OAAA,CAAA,CAElCI,CAAAA,CAAgB,CAAC,EACrBxF,CAAAA,EACA1I,CAAAA,EACAC,CAAAA,EACA+N,CAAAA,EACAD,GACAjL,CAAAA,EACAC,CAAAA,CAAAA,CAGEoL,CAAAA,CAA2B,IAAA,CAG3BD,IACFC,CAAAA,CAAY/H,EAAAA,CAAiB0H,CAAa,CAAA,CAAA,CAI5C,IAAIM,EAKO,IAAA,CAGX,GAAID,CAAAA,EAAaH,CAAAA,CAAgB,CAC/B,IAAMH,CAAAA,CAASpF,EAAAA,CAKb0F,CAAAA,CAAWxF,EAAWmF,CAAa,CAAA,CAErC,GAAID,CAAAA,CACF,OAAOA,CAAAA,CAIT,GAAIC,EAAc,UAAA,CAAY,CAC5B,IAAMO,CAAAA,CAAS,MAAMtG,EAAAA,CAAeoG,CAAAA,CAAWL,CAAa,CAAA,CACtDQ,CAAAA,CACJD,CAAAA,EACAE,EAAAA,CACEF,EAAO,IAAA,CACPF,CAAAA,CACAL,CACF,CAAA,CAGF,GACEQ,CAAAA,EACArG,EAAAA,CACEkG,EACA,CAAE,GAAGE,EAAQ,IAAA,CAAMC,CAAS,CAAA,CAC5BR,CAAAA,CAAc,UAChB,CAAA,CAEA,OAAOQ,CAEX,CAIER,CAAAA,CAAc,cAAgB,MAAA,EAC9B,CAAC7G,EAAAA,CAAakH,CAAS,GACvB,CAACnG,EAAAA,CAAgB8F,CAAa,CAAA,GAE9BM,CAAAA,CAAkBG,GAChB,CACE,IAAA,CAAMT,CAAAA,CAAc,WAAA,CACpB,OAAQ,GAAA,CACR,UAAA,CAAY,EAAA,CACZ,OAAA,CAAS,EACX,CAAA,CACAK,CAAAA,CACAL,CACF,GAEJ,CAGA,GAAIK,GAAalO,CAAAA,CAAY,CAC3B,IAAMuO,CAAAA,CAAW1N,EAAAA,CAEfqN,CAAAA,CAAWlO,CAAU,EAEvB,GAAIuO,CAAAA,CACF,OAAOA,CAEX,CAEA,IAAMC,EAAAA,CAAcX,CAAAA,CAAc,KAAA,EAAS,EAAC,CACtC,CAAE,QAAA1D,EAAAA,CAAU,CAAA,CAAG,aAAAsE,EAAa,CAAA,CAAID,EAAAA,CAGhCE,CAAAA,CAAab,EAAc,MAAA,CAG3Bc,EAAAA,CAAgB,MAAO/M,CAAAA,CAA8B+I,EAAU,CAAA,GAAM,CAEzE,IAAMiD,CAAAA,CACJI,GACAhH,EAAAA,CACEkH,CACF,EAKF,GAAI,CAACvD,EAAS,CAEZ,GAAIwD,CAAAA,CAAiB,CACnB,IAAMxP,CAAAA,CAAWwP,CAAAA,CAEjB,OAAAA,CAAAA,CAAkB,IAAA,CAEXxP,CACT,CAEIuP,CAAAA,EAAa,CAACtM,CAAAA,GACZe,EACoB6F,EAAAA,CACpB0F,CAAAA,CACAxF,EACAmF,CACF,CAAA,GAKE3G,GAASgH,CAAAA,CAAWR,EAAAA,CAAkBhF,CAAAA,CAAW/F,CAAS,EAC1DU,CAAAA,CAAkB6K,CAAAA,CAAWR,EAAgB,CAAA,CAAA,CAG/CrK,EAAkB6K,CAAAA,CAAWR,EAAgB,CAAA,CAAA,CAKjDG,CAAAA,CAAc,SAAWK,EAC3B,CAEA,IAAMvS,EAAAA,CAAMkS,CAAAA,CAAc,IAGpBrN,EAAAA,CAAaV,EAAAA,CACjBoO,CAAAA,CACAvS,EAAAA,CACAoE,EACAC,CAAAA,EAAc,CAAA,CACd,CAAC,CAAC8N,EAEF,CAAC,EAAE/N,CAAAA,GAAY,CAAC4K,GAAW8D,EAAAA,CAAAA,CAC7B,CAAA,CAIMtK,EAAgB0J,CAAAA,CAEtB1J,CAAAA,CAAc,OAAS3D,EAAAA,CAAW,MAAA,CAGlC,IAAM+L,EAAAA,CAAQ,IAAM/L,EAAAA,CAAW,KAAA,CAAMkO,CAAAA,CAAY,MAAM,EAEnDA,CAAAA,GACEA,CAAAA,CAAW,OAAA,CACbnC,EAAAA,GAEAmC,CAAAA,CAAW,gBAAA,CAAiB,QAASnC,EAAK,CAAA,CAAA,CAI9C,IAAI3D,EAAAA,CAMAjK,CAAAA,CAKO,IAAA,CAEX,GAAI,CACEkP,CAAAA,CAAc,SAAA,GAOZK,GAAalO,CAAAA,EAAc,CAAC2K,GAC9B,MAAM,IAAA,CAGR,MAAMvM,CAAAA,CAAkByP,EAAc,SAAA,CAAW1J,CAAa,GAIhE,IAAMjB,CAAAA,CAAK2K,EAAc,OAAA,CACnBe,CAAAA,CAAOC,EAAAA,CAAS1K,CAAAA,CAAeyJ,CAAM,CAAA,CAwB3C,GAtBAjP,CAAAA,CAAYuE,CAAAA,CACR,MAAMA,CAAAA,CACJvH,EAAAA,CACAiT,CACF,CAAA,CAEA,MAAOzK,CAAAA,CAAc,gBAAA,EAAoBA,EAAc,IAAA,CACnD+H,EAAAA,CAAwBvQ,GAAKwI,CAAa,CAAA,CAC1C,KAAA,CAAMxI,EAAAA,CAAKiT,CAAmB,CAAA,CAAA,CAQtCjQ,CAAAA,CAAWoO,EAAAA,CACTpO,CAAAA,CACAwF,EAAc,kBAChB,CAAA,CAGIvJ,CAAAA,CAAS+D,CAAQ,EAAG,CAGtB,GAAIiQ,IAASzK,CAAAA,EAAiBxF,CAAAA,CAAS,SAAW,GAAA,CAChD,OAAOiP,CAAAA,CAiCT,GAxBI,OAAO,QAAA,GAAa7T,CAAAA,EAAY4E,CAAAA,YAAoB,QAAA,CACtDA,EAAS,IAAA,CAAOwF,CAAAA,CAAc,MAAA,CAC1B,MAAMA,EAAc,MAAA,CAAOxF,CAAQ,EACnC,MAAMqK,EAAAA,CAAkBrK,EAAUwF,CAAAA,CAAc,YAAY,CAAA,CACvDjB,CAAAA,GAEH,SAAUvE,CAAAA,EAAY,MAAA,GAAUA,IAEpCA,CAAAA,CAAW,CAAE,KAAMA,CAAS,CAAA,CAAA,CAAA,CAYhCA,CAAAA,CAAS,MAAA,CAASwF,EAIdxF,CAAAA,CAAS,EAAA,GAAO,QAAa,CAACA,CAAAA,CAAS,GACzC,MAAM,IAAIC,EAAAA,CACRuF,CAAAA,CAAc,OACZ,MAAA,CACAxI,EAAAA,CACA,mBAAA,EACCgD,CAAAA,CAAS,QAAU,IAAA,CAAA,CACtBwF,CAAAA,CACAxF,CACF,CAEJ,CAEAiK,EAAAA,CAASS,EAAAA,CAKP1K,EAAUwF,CAAa,CAAA,CAEzB,IAAM2K,EAAAA,CAAajB,CAAAA,CAAc,UAAA,CAE7BiB,EAAAA,EACF,MAAM1Q,CAAAA,CAAkB0Q,EAAAA,CAAYlG,EAAM,EAE9C,OAASmG,CAAAA,CAAQ,CACf,IAAMhR,CAAAA,CAAQgR,EAQdtB,EAAAA,CACE1P,CAAAA,CACAY,EACAwF,CACF,CAAA,CAGAyE,GAASS,EAAAA,CAKP1K,CAAAA,CAAUwF,CAAAA,CAAepG,CAAK,EAClC,CAAA,OAAE,CACI2Q,CAAAA,EACFA,CAAAA,CAAW,oBAAoB,OAAA,CAASnC,EAAK,EAEjD,CAEA,OAAO3D,EACT,CAAA,CAKMoG,GACJ7E,EAAAA,CAAU,CAAA,CACLvI,GACCqI,EAAAA,CACE,CAACgF,CAAAA,CAAGtE,CAAAA,GAAYgE,GAAc/M,CAAAA,CAAqB+I,CAAO,EAC1D6D,EACF,CAAA,CACFG,GAEA,CAAE,aAAA,CAAAO,EAAAA,CAAe,cAAA,CAAAC,EAAe,CAAA,CAAItB,CAAAA,CAIpCnP,GACJwQ,EAAAA,EAAiBC,EAAAA,CACb,MAAOvN,CAAAA,EAAiC,CACtC,GAAIA,CAAAA,CACF,OAAOoN,EAAAA,CAAYpN,CAAmB,CAAA,CAGxC,IAAMtE,EAAQ,UAAA,CACZ,IAAMc,CAAAA,CAAkB8Q,EAAAA,CAAerB,CAAa,CAAA,CAAE,KAAA,CAAM9Q,CAAI,CAAA,CAChEoS,EACF,EAEA,GAAI,CACF,OAAO,MAAMH,GAAYpN,CAAmB,CAC9C,CAAA,OAAE,CACA,aAAatE,CAAK,EACpB,CACF,CAAA,CACA0R,GAEAI,EAAAA,CAA2B,CAACxN,EAAsB,KAAA,GACtDsL,EAAAA,CACEtL,EACAlD,EAAAA,CACAmP,CACF,CAAA,CAGIwB,EAAAA,CAAmBhE,EACrBD,EAAAA,CACEgE,EAAAA,CACA/D,CAAAA,CACAwC,CAAAA,CAAc,kBACdA,CAAAA,CAAc,kBAAA,CACdA,CAAAA,CAAc,YAAA,CACdA,EAAc,iBAAA,CACdA,CAAAA,CAAc,mBACda,CACF,CAAA,CACAU,IAAyB,CAG7B,OAAIlB,CAAAA,GACElO,CAAAA,EACFW,GAAmBuN,CAAAA,CAAWmB,EAAgB,GAI5C1M,CAAAA,EAAaE,CAAAA,EAAkBC,IACjCN,EAAAA,CACE0L,CAAAA,CACAkB,EAAAA,CACA,MAAA,CACAzM,EACAyM,EAAAA,CACA,CAAC,CAACvM,CAAAA,CACF,CAAC,CAACC,CAAAA,CACF+K,CAAAA,CAAc,qBAChB,CAAA,CAAA,CAIGwB,EACT,CAWA,SAASf,EAAAA,CACPF,CAAAA,CACA3F,EACArC,CAAAA,CAC0E,CAC1E,GAAI,CAEF,IAAMzH,CAAAA,CAAY,OAAO,WAAa5E,CAAAA,CAClC,IAAI,SAAS,IAAA,CAAMqU,CAAM,CAAA,CACzB,CACE,GAAI,CAAA,CAAA,CACJ,MAAA,CAAQA,CAAAA,CAAO,MAAA,CACf,WAAYA,CAAAA,CAAO,UAAA,CACnB,OAAA,CAASA,CAAAA,CAAO,OAClB,CAAA,CAOJzP,CAAAA,CAAS,KAAOyP,CAAAA,CAAO,IAAA,CACvBhI,EAAO,QAAA,CAAWqC,CAAAA,CAElB,IAAMG,CAAAA,CAASS,GAKb1K,CAAAA,CAAU,CACV,GAAGyH,CAAAA,CACH,OAAQ,KAAA,CAAA,CACR,eAAA,CAAiB,CAAA,CAAA,CACjB,eAAA,CAAiB,MACnB,CAAC,CAAA,CAED,OAAAwC,CAAAA,CAAO,MAAA,CAASxC,EAETwC,CACT,CAAA,KAAQ,CACN,OAAO,IACT,CACF,CAWA,SAASiG,EAAAA,CACPzI,CAAAA,CACAwH,EACe,CACf,IAAM0B,CAAAA,CAAO1B,CAAAA,EAAU,CAACA,CAAAA,CAAO,KAAA,EAASA,EAAO,OAAA,EAAWA,CAAAA,CAAO,QAAQ,IAAA,CACnEnQ,CAAAA,CAAU6R,CAAAA,EAAQ9R,CAAAA,CAAe4I,EAAO,OAAwB,CAAA,CAEtE,OAAO3I,CAAAA,EAAW,CAACA,CAAAA,CAAQ,eAAe,CAAA,CACtC,CAAE,GAAG2I,CAAAA,CAAQ,OAAA,CAAS,CAAE,GAAG3I,CAAAA,CAAS,gBAAiB6R,CAAK,CAAE,CAAA,CAC5DlJ,CACN,CCtiBA,SAASmJ,EAAAA,CAGPnJ,CAAAA,CAAyC,CACzC,IAAMoJ,CAAAA,CAAYpJ,CAAAA,CAAO,SAAA,CAQzB,eAAeqJ,EAAqBC,CAAAA,CAAqC,CACvE,eAAQ,KAAA,CAAM,MAAA,CAASA,EAAe,kBAAkB,CAAA,CAEjD,IACT,CAEA,IAAMC,CAAAA,CAAsD,CAC1D,MAAA,CAAAvJ,CAAAA,CACA,UAAAoJ,CAAAA,CASA,MAAM,OAAA,CAAQE,CAAAA,CAAcvL,EAAgB,EAAC,CAAG,CAG9C,IAAMyL,CAAAA,CAAiBrV,EAAOiV,CAAAA,CAAWE,CAAsB,CAAA,CAC3DF,CAAAA,CAAUE,CAAY,CAAA,CACtB,MAAA,CACEG,EACJD,CAAAA,EACC,CAAE,IAAK,MAAA,CAAOF,CAAY,CAAE,CAAA,CACzB/T,EAAMkU,CAAAA,CAAgB,GAAA,CAItBC,EAAcnU,CAAAA,CACjB,OAAA,CAAQ,YAAa,EAAE,CAAA,CAEvB,OAAA,CAAQ,eAAA,CAAiB,EAAE,CAAA,CAG9B,GAAI,WAAA,CAAY,IAAA,CAAKmU,CAAW,CAAA,CAC9B,MAAM,IAAI,KAAA,CAAM,qCAAqC,CAAA,CAKvD,IAAMC,EAAe,sBAAA,CAAuB,IAAA,CAAKD,CAAW,CAAA,CAExDF,CAAAA,EAAkBA,CAAAA,CAAe,GAAA,GAAQjU,EACvCkI,CAAAA,CAAagM,CAAAA,CAAiB1L,CAAa,CAAA,CAC3CA,EACFN,CAAAA,CAAaA,CAAAA,CAAauC,CAAAA,CAAQyJ,CAAe,EAAG1L,CAAa,CAAA,CAIrE,OAAOwJ,EAAAA,CAAOhS,CAAAA,CAAKoU,CAAY,CACjC,CACF,CAAA,CAOA,OAAO,IAAI,KAAA,CACTJ,CAAAA,CACA,CACE,GAAA,CAAIK,EAASC,CAAAA,CAAuB,CAClC,GAAIA,CAAAA,IAAQN,EACV,OAAOA,CAAAA,CAAWM,CAA0C,CAAA,CAK9D,GAAI,SAAOA,CAAAA,EAAS,QAAA,EAAYA,CAAAA,GAAS,MAAA,CAAA,CAKzC,OAAI1V,CAAAA,CAAOiV,CAAAA,CAAWS,CAAI,CAAA,CACjBN,CAAAA,CAAW,QAAQ,IAAA,CAAK,IAAA,CAAMM,CAAI,CAAA,CAGpCR,EAAqB,IAAA,CAAK,IAAA,CAAMQ,CAAI,CAC7C,CACF,CACF,CACF","file":"index.js","sourcesContent":["export const APPLICATION_CONTENT_TYPE = 'application/';\n\nexport const APPLICATION_JSON = APPLICATION_CONTENT_TYPE + 'json';\nexport const CHARSET_UTF_8 = 'charset=utf-8';\nexport const CONTENT_TYPE = 'Content-Type';\n\nexport const UNDEFINED = 'undefined';\nexport const OBJECT = 'object';\nexport const STRING = 'string';\nexport const FUNCTION = 'function';\n\nexport const ABORT_ERROR = 'AbortError';\nexport const TIMEOUT_ERROR = 'TimeoutError';\n\nexport const GET = 'GET';\nexport const HEAD = 'HEAD';\n\nexport const REJECT = 'reject';\n\n// Larger timer delays overflow and fire immediately in browsers and Node.js (~24.8 days)\nexport const MAX_DELAY_MS = 2147483647;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, MAX_DELAY_MS, OBJECT, STRING, UNDEFINED } from './constants';\nimport type {\n DefaultUrlParams,\n HeadersObject,\n QueryParams,\n UrlPathParams,\n} from './types';\n\n// Prevent stack overflow with recursion depth limit\nconst MAX_DEPTH = 10;\n\nexport const hasOwn = (o: any, k: string) =>\n Object.prototype.hasOwnProperty.call(o, k);\n\nexport function isSearchParams(data: unknown): boolean {\n return data instanceof URLSearchParams;\n}\n\n/**\n * Determines if a value is a non-null object.\n *\n * @param {any} value - The value to check.\n * @returns {boolean} - True if the value is a non-null object.\n */\nexport function isObject(value: any): value is Record {\n return value !== null && typeof value === OBJECT;\n}\n\n/**\n * Shallowly serializes an object by converting its key-value pairs into a string representation.\n * This function does not recursively serialize nested objects.\n *\n * @param obj - The object to serialize.\n * @returns A string representation of the object's top-level properties.\n */\nexport function shallowSerialize(obj: Record): string {\n let result = '';\n\n for (const key in obj) {\n if (hasOwn(obj, key)) {\n result += key + ':' + obj[key];\n }\n }\n\n return result;\n}\n\n/**\n * Removes properties that could lead to prototype pollution from an object.\n *\n * This function checks for dangerous properties like '__proto__', 'constructor',\n * and 'prototype'. If none are present, the object is returned as-is (zero-copy fast path).\n * Otherwise, a shallow copy is created with the dangerous properties removed.\n *\n * @param obj - The object to sanitize\n * @returns A safe object without dangerous properties\n */\nexport function sanitizeObject>(obj: T): T {\n const hasProto = hasOwn(obj, '__proto__');\n const hasCtor = hasOwn(obj, 'constructor');\n const hasPrototype = hasOwn(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n // Copy key by key, as a spread compiled to assignments would let \"__proto__\" set the prototype\n const safeObj = {} as Record;\n\n for (const key of Object.keys(obj)) {\n if (key !== '__proto__' && key !== 'constructor' && key !== 'prototype') {\n safeObj[key] = obj[key];\n }\n }\n\n return safeObj as T;\n}\n\n/**\n * Sorts the keys of an object and returns a new object with sorted keys.\n *\n * This function is optimized for performance by minimizing the number of object operations\n * and using a single pass to create the sorted object.\n *\n * @param {Object} obj - The object to be sorted by keys.\n * @returns {Object} - A new object with keys sorted in ascending order.\n */\nexport function sortObject(obj: Record): object {\n // Without a prototype, a \"__proto__\" key is kept as a regular property instead of setting the prototype\n const sortedObj = Object.create(null) as Record;\n\n Object.keys(obj)\n .sort()\n .forEach((k) => (sortedObj[k] = obj[k]));\n\n return sortedObj;\n}\n\n/**\n * Appends a query string to a URL, ensuring proper handling of existing query parameters.\n *\n * @param baseUrl - The base URL to which the query string will be appended.\n * @param queryString - The encoded query string to append.\n * @returns The URL with the appended query string, or the original URL if no query string is provided.\n */\nfunction appendQueryStringToUrl(baseUrl: string, queryString: string): string {\n if (!queryString) {\n return baseUrl;\n }\n\n return baseUrl + (baseUrl.includes('?') ? '&' : '?') + queryString;\n}\n\n/**\n * Appends query parameters to a given URL.\n *\n * @param {string} url - The base URL to which query parameters will be appended.\n * @param {QueryParams} params - An object containing the query parameters to append.\n * @returns {string} - The URL with the appended query parameters.\n */\nexport function appendQueryParams(url: string, params: QueryParams): string {\n if (!params) {\n return url;\n }\n\n // Check if `params` is an instance of URLSearchParams and bail early if it is\n if (isSearchParams(params)) {\n const encodedQueryString = params.toString();\n\n return appendQueryStringToUrl(url, encodedQueryString);\n }\n\n // This is exact copy of what JQ used to do. It works much better than URLSearchParams\n const s: string[] = [];\n const encode = encodeURIComponent;\n const add = (k: string, v: any) => {\n v = typeof v === FUNCTION ? v() : v;\n v = v === null || v === undefined ? '' : v;\n s[s.length] = encode(k) + '=' + encode(v);\n };\n\n const buildParams = (prefix: string, obj: any, depth = 0) => {\n // Stop recursion if maximum depth is reached\n if (depth >= MAX_DEPTH) {\n return s;\n }\n\n let i: number, len: number, key: string;\n\n if (prefix) {\n if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n buildParams(\n prefix + '[' + (typeof obj[i] === OBJECT && obj[i] ? i : '') + ']',\n obj[i],\n depth + 1,\n );\n }\n } else if (isObject(obj)) {\n for (key in obj) {\n buildParams(prefix + '[' + key + ']', obj[key], depth + 1);\n }\n } else {\n add(prefix, obj);\n }\n } else if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n add(obj[i].name, obj[i].value);\n }\n } else {\n for (key in obj) {\n buildParams(key, obj[key], depth + 1);\n }\n }\n return s;\n };\n\n const queryStringParts = buildParams('', params).join('&');\n\n // Encode special characters as per RFC 3986, https://datatracker.ietf.org/doc/html/rfc3986\n // This is for compatibility with server frameworks that expect the literal notation\n const encodedQueryString = queryStringParts.replace(/%5B%5D/g, '[]'); // Keep '[]' for arrays\n\n return appendQueryStringToUrl(url, encodedQueryString);\n}\n\n/**\n * Replaces dynamic URI parameters in a URL string with values from the provided `urlPathParams` object.\n * Parameters in the URL are denoted by `:` or `{}` (like in OpenAPI paths), where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:` or `{}`.\n * @param {Object} urlPathParams - An object containing the parameter values to replace placeholders.\n * @param {string} urlPathParams.paramName - The value to replace the placeholder `:` in the URL.\n * @returns {string} - The URL string with placeholders replaced by corresponding values from `urlPathParams`.\n */\nexport function replaceUrlPathParams(\n url: string,\n urlPathParams: UrlPathParams,\n): string {\n if (!urlPathParams || (url.indexOf(':') === -1 && url.indexOf('{') === -1)) {\n return url;\n }\n\n // Use a single RegExp and avoid unnecessary casts and function calls\n // Precompute keys for faster lookup\n const params = urlPathParams as DefaultUrlParams;\n\n // Use a replacer function that avoids extra work\n return url.replace(/:(\\w+)|\\{(\\w+)\\}/g, (match, colonKey, braceKey) => {\n const key = colonKey || braceKey;\n\n // Use hasOwnProperty for strict key existence check\n if (hasOwn(params, key)) {\n const value = params[key];\n\n // Only replace if value is not undefined or null\n if (value !== undefined && value !== null) {\n const encoded = encodeURIComponent(String(value));\n\n // These can't be encoded, and URL parsers would move the request to another path\n if (encoded === '.' || encoded === '..') {\n throw new Error('Path params \".\" and \"..\" not allowed.');\n }\n\n return encoded;\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL starts with a scheme (e.g., \"http://\", \"https://\").\n * A \"://\" appearing later, e.g. in a query string, does not make the URL absolute.\n *\n * @param url - The URL string to check.\n * @returns `true` if the URL is absolute, otherwise `false`.\n */\nexport function isAbsoluteUrl(url: string): boolean {\n return /^[a-z][a-z\\d+\\-.]*:\\/\\//i.test(url);\n}\n\nexport const timeNow = () => Date.now();\n\nexport const noop = () => {};\n\n/**\n * Checks if a value is JSON serializable.\n *\n * JSON serializable values include:\n * - Primitive types: string, number, boolean, null\n * - Arrays\n * - Plain objects (i.e., objects without special methods)\n * - Values with a `toJSON` method\n *\n * @param {any} value - The value to check for JSON serializability.\n * @returns {boolean} - Returns `true` if the value is JSON serializable, otherwise `false`.\n */\nexport function isJSONSerializable(value: any): boolean {\n const t = typeof value;\n\n if (value === undefined || value === null) {\n return false;\n }\n\n if (t === STRING || t === 'number' || t === 'boolean') {\n return true;\n }\n\n if (Array.isArray(value)) {\n return true;\n }\n\n if (\n typeof globalThis !== UNDEFINED &&\n typeof globalThis.Buffer !== UNDEFINED &&\n globalThis.Buffer.isBuffer(value)\n ) {\n return false;\n }\n\n if (value instanceof Date || isSearchParams(value)) {\n return false;\n }\n\n if (isObject(value)) {\n const proto = Object.getPrototypeOf(value);\n\n // Check if the prototype is `Object.prototype` (plain object)\n if (proto === Object.prototype) {\n return true;\n }\n\n // Check if the object has a toJSON method\n if (typeof value.toJSON === FUNCTION) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Waits for the given time. When a signal is passed, the wait ends early once it is aborted.\n *\n * @param {number} ms - The time to wait in milliseconds.\n * @param {AbortSignal} [signal] - An optional signal that ends the wait when aborted.\n * @returns {Promise} - A promise that resolves with `true` once the wait is over.\n */\nexport const delayInvocation = (\n ms: number,\n signal?: AbortSignal,\n): Promise =>\n new Promise((resolve) => {\n const done = () => {\n clearTimeout(timer);\n if (signal) {\n signal.removeEventListener('abort', done);\n }\n resolve(true);\n };\n const timer = setTimeout(done, Math.min(ms, MAX_DELAY_MS));\n\n if (signal) {\n if (signal.aborted) {\n done();\n } else {\n signal.addEventListener('abort', done);\n }\n }\n });\n\n/**\n * Recursively flattens the data object if it meets specific criteria.\n *\n * The method checks if the provided `data` is an object with exactly one property named `data`.\n * If so, it recursively flattens the `data` property. Otherwise, it returns the `data` as-is.\n *\n * @param {any} data - The data to be flattened. Can be of any type, including objects, arrays, or primitives.\n * @returns {any} - The flattened data if the criteria are met; otherwise, the original `data`.\n */\nexport function flattenData(data: any, depth = 0): any {\n if (depth >= MAX_DEPTH) {\n return data;\n }\n\n if (data && isObject(data) && typeof data.data !== UNDEFINED) {\n return flattenData(data.data, depth + 1);\n }\n\n return data;\n}\n\n/**\n * Processes headers and returns them as a normalized object.\n *\n * Handles both `Headers` instances and plain objects. Normalizes header keys to lowercase\n * as per RFC 2616 section 4.2.\n *\n * @param headers - The headers to process. Can be an instance of `Headers`, a plain object,\n * or `null`. If `null`, an empty object is returned.\n * @returns {HeadersObject} - A normalized headers object with lowercase keys.\n */\nexport function processHeaders(\n headers?: (HeadersObject & HeadersInit) | null | Headers,\n): HeadersObject {\n if (!headers) {\n return {};\n }\n\n const headersObject: HeadersObject = {};\n\n // Normalize keys to lowercase as per RFC 2616 4.2\n // https://datatracker.ietf.org/doc/html/rfc2616#section-4.2\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n headersObject[key.toLowerCase()] = value;\n });\n } else {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n // Assigning \"__proto__\" would set the prototype of the result\n if (hasOwn(headers, key) && key !== '__proto__') {\n headersObject[key.toLowerCase()] = headers[key];\n }\n }\n }\n\n return headersObject;\n}\n\n/**\n * Determines if the current environment is a browser.\n *\n * @returns {boolean} - True if running in a browser environment, false otherwise.\n */\nexport function isBrowser(): boolean {\n // For node and some mobile frameworks like React Native, `add/removeEventListener` doesn't exist on window!\n return (\n typeof window !== UNDEFINED && typeof window.addEventListener === FUNCTION\n );\n}\n\n/**\n * Creates an abort/timeout error compatible with all JS runtimes.\n * Falls back to a plain Error with the correct `name` when DOMException is unavailable (e.g. React Native).\n *\n * @param {string} message - The error message.\n * @param {string} name - The error name (e.g. 'AbortError', 'TimeoutError').\n * @returns {DOMException | Error} - An error object with the specified name.\n */\nexport function createAbortError(\n message: string,\n name: string,\n): DOMException | Error {\n if (typeof DOMException !== UNDEFINED) {\n return new DOMException(message, name);\n }\n\n const error = new Error(message);\n error.name = name;\n\n return error;\n}\n\n/**\n * Detects if the user is on a slow network connection\n * @returns {boolean} True if connection is slow, false otherwise or if detection unavailable\n */\nexport const isSlowConnection = (): boolean => {\n const conn = typeof navigator !== UNDEFINED && (navigator as any).connection;\n\n return conn && ['slow-2g', '2g', '3g'].includes(conn.effectiveType);\n};\n\n/**\n * Detects if the page is hidden, e.g. when its tab is in the background or the window is minimized\n * @returns {boolean} True if the page is hidden, false otherwise or outside browsers\n */\nexport const isPageHidden = (): boolean =>\n typeof document !== UNDEFINED && document.visibilityState === 'hidden';\n\n/**\n * Detects if the browser is offline\n * @returns {boolean} True if the browser is offline, false otherwise or if the connection state is unknown\n */\nexport const isOffline = (): boolean =>\n typeof navigator !== UNDEFINED && navigator.onLine === false;\n","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject, sanitizeObject } from './utils';\n\n/**\n * Applies interceptors to the object. Interceptors can be a single function or an array of functions.\n *\n * @template T - Type of the object.\n * @template Args - Type of additional arguments.\n * @template I - Type of interceptors.\n *\n * @param {InterceptorFunction | InterceptorFunction[]} [interceptors] - Interceptor function(s).\n * @param {T} data - The data object to process.\n * @param {...Args} args - Additional arguments to pass to interceptors.\n *\n * @returns {Promise} - Nothing as the function is non-idempotent.\n */\nexport async function applyInterceptors<\n T extends object,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Args extends any[] = any[],\n I = InterceptorFunction | InterceptorFunction[],\n>(interceptors: I | undefined, data: T, ...args: Args): Promise {\n if (!interceptors) {\n return;\n }\n\n const merge = (v: unknown) =>\n v &&\n isObject(data) &&\n isObject(v) &&\n Object.assign(data, sanitizeObject(v));\n\n if (typeof interceptors === FUNCTION) {\n merge(await (interceptors as InterceptorFunction)(data, ...args));\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n merge(await interceptor(data, ...args));\n }\n }\n}\n","import type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\n/**\n * This is a base error class\n */\nexport class FetchError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends Error {\n // Declared only, and set in the constructor, as class fields would need a helper in the ES2018 bundle\n declare status: number;\n declare statusText: string;\n declare config: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare isCancelled: boolean;\n declare request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null;\n\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.request = request;\n this.response = response;\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\n this.name = 'FetchError';\n }\n}\n","import { FetchError } from './fetch-error';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\nexport class ResponseError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends FetchError {\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message, request, response);\n\n this.name = 'ResponseError';\n }\n}\n","/**\n * @module timeout-wheel\n * @description\n * Ultra-minimal timing wheel implementation optimized for max performance & many requests.\n * For most of the cases it's 4-100x faster than setTimeout and setInterval alone.\n * Provides efficient scheduling and cancellation of timeouts using a circular array.\n *\n * Position 0 → 1 → 2 → ... → 599 → 0 → 1 → 2 ...\n * Time: 0s 1s 2s 599s 600s 601s 602s\n *\n * The timing wheel consists of 600 slots (one per second for 10 min).\n * Each slot contains a list of timeout items, each associated with a unique key and callback.\n * Timeouts are scheduled by placing them in the appropriate slot based on the delay in seconds.\n * The wheel advances every second, executing and removing callbacks as their timeouts expire.\n * Defaults to setTimeout if the delay doesn't fit in the wheel (~10 minutes) or is not divisible by 1000.\n *\n * @remarks\n * - Designed for minimal footprint and simplicity.\n * - Only supports second-level granularity (minimum timeout: 1 second).\n * - Timeouts never fire early, but may fire up to 1 second late.\n * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { MAX_DELAY_MS } from './constants';\nimport { noop, timeNow } from './utils';\n\ntype TimeoutCallback = () => unknown | Promise;\ntype TimeoutItem = [string, TimeoutCallback]; // [key, callback]\n\nconst WHEEL_SIZE = 600; // 600 slots for 10 min (1 slot per second)\nconst SECOND = 1000; // 1 second in milliseconds\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\nlet lastTick = 0; // Time when the wheel last advanced (or started)\nlet timer: NodeJS.Timeout | null = null;\n\nconst handleCallback = ([key, callback]: TimeoutItem): void => {\n keyMap.delete(key);\n\n try {\n const result = callback();\n if (result && result instanceof Promise) {\n // Silently ignore async errors to prevent wheel from stopping\n result.catch(noop);\n }\n } catch {\n // Ignore callback errors to prevent wheel from stopping\n }\n};\n\nexport const addTimeout = (\n key: string,\n cb: TimeoutCallback,\n ms: number,\n): void => {\n removeTimeout(key);\n\n // A running wheel is already part-way through its current second, so the timeout\n // waits one more slot to never fire early. A new wheel starts its first second now.\n const seconds = ms / SECOND + (timer && timeNow() !== lastTick ? 1 : 0);\n\n // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || seconds >= WHEEL_SIZE || ms % SECOND !== 0) {\n keyMap.set(key, [\n setTimeout(\n handleCallback.bind(null, [key, cb]),\n Math.min(ms, MAX_DELAY_MS),\n ),\n ]); // Store timeout ID instead of slot\n\n return;\n }\n\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n lastTick = timeNow();\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\n lastTick = timeNow();\n const slot = wheel[position];\n\n // Use slot.length directly (not cached) so mid-iteration mutations\n // from callbacks (e.g. removeTimeout) are handled correctly\n for (let i = 0; i < slot.length; i++) {\n handleCallback(slot[i]);\n }\n\n slot.length = 0; // Reuse array, avoid GC allocation\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }, SECOND);\n }\n};\n\nexport const removeTimeout = (key: string): void => {\n const slotOrTimeout = keyMap.get(key);\n\n if (slotOrTimeout !== undefined) {\n // It's a Timeout object from setTimeout\n if (Array.isArray(slotOrTimeout)) {\n clearTimeout(slotOrTimeout[0]);\n } else {\n const slotArr = wheel[slotOrTimeout];\n\n for (let i = 0; i < slotArr.length; i++) {\n if (slotArr[i][0] === key) {\n slotArr.splice(i, 1);\n break;\n }\n }\n }\n\n keyMap.delete(key);\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }\n};\n\nexport const clearAllTimeouts = () => {\n // Clear native setTimeout timeouts first!\n keyMap.forEach((value) => {\n if (Array.isArray(value)) {\n clearTimeout(value[0]);\n }\n });\n\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n\n keyMap.clear();\n\n for (let i = 0; i < WHEEL_SIZE; i++) {\n wheel[i].length = 0;\n }\n\n position = 0;\n};\n","/**\n * @module inflight-manager\n *\n * Manages in-flight asynchronous requests using unique keys to enable deduplication and cancellation.\n *\n * Provides utilities for:\n * - Deduplication of requests within a configurable time window (`dedupeTime`)\n * - Timeout management and automatic request abortion\n * - AbortController lifecycle and cancellation logic\n * - Concurrency control and request state tracking\n * - In-flight promise deduplication to prevent duplicate network calls\n *\n * @remarks\n * - Requests with the same key within the deduplication interval share the same AbortController and in-flight promise.\n * - Supports cancellation of previous requests when a new one with the same key is issued, if `isCancellable` is enabled.\n * - Timeout logic ensures requests are aborted after a specified duration, if enabled.\n * - Internal queue state is managed via a Map, keyed by request identifier.\n * - Polled requests are also marked as \"in-flight\" to prevent duplicate requests.\n */\n\nimport { ABORT_ERROR, TIMEOUT_ERROR } from './constants';\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { createAbortError, timeNow } from './utils';\n\nexport type InFlightItem = [\n AbortController, // AbortController for the request\n boolean, // Whether timeout is enabled for the request\n number, // Timestamp when the request was marked in-flight\n boolean, // isCancellable - whether the request can be cancelled\n Promise | null, // Optional in-flight promise for deduplication\n];\n\nconst inFlight: Map = new Map();\n\n/**\n * Adds a request to the queue if it's not already being processed within the dedupeTime interval.\n *\n * @param {string | null} key - Unique key for the request (e.g. cache key).\n * @param {string} url - The request URL (for error messages/timeouts).\n * @param {number} timeout - Timeout in milliseconds for the request.\n * @param {number} dedupeTime - Deduplication time in milliseconds.\n * @param {boolean} isCancellable - If true, then the previous request with same configuration should be aborted.\n * @param {boolean} isTimeoutEnabled - Whether timeout is enabled.\n * @returns {AbortController} - A promise that resolves to an AbortController.\n */\nexport function markInFlight(\n key: string | null,\n url: string,\n timeout: number | undefined,\n dedupeTime: number,\n isCancellable: boolean,\n isTimeoutEnabled: boolean,\n): AbortController {\n if (!key) {\n return new AbortController();\n }\n\n const now = timeNow();\n const item = inFlight.get(key);\n let prevPromise: Promise | null = null;\n\n // Previous request is in-flight, check if we can reuse it\n if (item) {\n const prevController = item[0];\n const prevIsCancellable = item[3];\n\n // If the request is already in the queue and within the dedupeTime, reuse the existing controller\n if (\n !prevIsCancellable &&\n now - item[2] < dedupeTime &&\n !prevController.signal.aborted\n ) {\n return prevController;\n }\n\n // If the request is too old, remove it and proceed to add a new one\n // Abort previous request, if applicable, and continue as usual\n if (prevIsCancellable) {\n prevController.abort(\n createAbortError('Aborted due to new request', ABORT_ERROR),\n );\n }\n\n removeTimeout(key);\n prevPromise = item[4];\n }\n\n const controller = new AbortController();\n\n inFlight.set(key, [\n controller,\n isTimeoutEnabled,\n now,\n isCancellable,\n prevPromise,\n ]);\n\n if (isTimeoutEnabled) {\n addTimeout(\n key,\n () => {\n abortRequest(\n key,\n createAbortError(url + ' aborted due to timeout', TIMEOUT_ERROR),\n );\n },\n timeout as number,\n );\n }\n\n return controller;\n}\n\n/**\n * Removes a request from the queue and clears its timeout.\n *\n * @param key - Unique key for the request.\n * @param {boolean} error - Optional error to abort the request with. If null, the request is simply removed but no abort sent.\n * @returns {Promise} - A promise that resolves when the request is aborted and removed.\n */\nexport async function abortRequest(\n key: string | null,\n error: DOMException | Error | null | string = null,\n): Promise {\n // If the key is not in the queue, there's nothing to remove\n if (key) {\n const item = inFlight.get(key);\n\n if (item) {\n // If the request is not yet aborted, abort it with the provided error\n if (error) {\n const controller = item[0];\n controller.abort(error);\n }\n\n removeInFlight(key);\n }\n }\n}\n\n/**\n * Removes a request from the in-flight queue without aborting or clearing timeout.\n *\n * @param key - Unique key for the request.\n */\nexport function removeInFlight(key: string | null): void {\n removeTimeout(key!);\n inFlight.delete(key!);\n}\n\n/**\n * Gets the AbortController for a request key.\n *\n * @param key - Unique key for the request.\n * @returns {AbortController | undefined} - The AbortController or undefined.\n */\nexport async function getController(\n key: string,\n): Promise {\n const item = inFlight.get(key);\n\n return item && item[0];\n}\n\n/**\n * Adds helpers for in-flight promise deduplication.\n *\n * @param key - Unique key for the request.\n * @param promise - The promise to store.\n */\nexport function setInFlightPromise(\n key: string,\n promise: Promise,\n): void {\n const item = inFlight.get(key);\n if (item) {\n // store the promise at index 4 — item is already the Map's reference, no need to re-set\n item[4] = promise;\n }\n}\n\n/**\n * Retrieves the in-flight promise for a request key if it exists and is within the dedupeTime interval.\n *\n * @param key - Unique key for the request.\n * @param dedupeTime - Deduplication time in milliseconds.\n * @returns {Promise | null} - The in-flight promise or null.\n */\nexport function getInFlightPromise(\n key: string | null,\n dedupeTime: number,\n): Promise | null {\n if (!key) {\n return null;\n }\n\n const prevReq = inFlight.get(key);\n\n if (\n prevReq &&\n // If the request is in-flight and has a promise\n prevReq[4] &&\n // If the request is cancellable, we will not reuse it\n !prevReq[3] &&\n // If the request is within the dedupeTime\n timeNow() - prevReq[2] < dedupeTime &&\n // If one request is cancelled, ALL deduped requests get cancelled\n !prevReq[0].signal.aborted\n ) {\n return prevReq[4] as Promise;\n }\n\n return null;\n}\n","const PRIME_MULTIPLIER = 31;\n\n/**\n * Computes a hash value for a given string using the variant of djb2 hash function.\n * This hash function is non-cryptographic and designed for speed.\n * @author Daniel J. Bernstein (of djb2)\n *\n * @param str Input string to hash\n * @returns {string} Hash\n */\nexport function hash(str: string): string {\n let hash = 0;\n\n for (let i = 0, len = str.length; i < len; i++) {\n const char = str.charCodeAt(i);\n hash = (hash * PRIME_MULTIPLIER + char) | 0;\n }\n\n return String(hash);\n}\n","/**\n * @module revalidator-manager\n *\n * Provides utilities for managing cache revalidation functions, including:\n * - Registering and unregistering revalidators for specific cache keys.\n * - Triggering revalidation for a given key.\n * - Enabling or disabling automatic revalidation on window focus and if user comes back online for specific keys.\n * - Attaching and removing global focus and online event handlers to trigger revalidation.\n *\n * Revalidators are functions that can be registered to revalidate cache entries when needed.\n * They are typically used to refresh data in the cache when the window gains focus or when specific actions occur.\n * @performance O(1) lookup by key makes it blazing fast to register, unregister, and revalidate cache entries.\n * - Designed for high performance: minimizes unnecessary re-renders and leverages fast cache key generation.\n * - Integrates with a global cache and pub/sub system for efficient state updates across contexts.\n * - Handles automatic revalidation, deduplication, retries, and cache management out of the box.\n * @remarks\n * - Designed to be used in various environments (Deno, Node.js, Bun, Browser, etc.) to ensure cache consistency and freshness.\n */\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { FetchResponse } from './types';\nimport { isBrowser, noop, timeNow } from './utils';\n\nexport type RevalidatorFn = (\n isStaleRevalidation?: boolean,\n) => Promise;\n\ntype EventType = 'focus' | 'online';\n\ntype RevalidatorEntry = [\n RevalidatorFn, // main revalidator\n number, // lastUsed\n number, // ttl\n number?, // staleTime\n RevalidatorFn?, // bgRevalidator\n boolean?, // refetchOnFocus\n boolean?, // refetchOnReconnect\n number?, // focusThrottleInterval\n];\n\nconst DEFAULT_TTL = 3 * 60 * 1000; // Default TTL of 3 minutes\nconst revalidators = new Map();\n\n/**\n * Stores cleanup functions for active event handlers (browser or custom providers).\n * Each entry removes the corresponding event listener when called.\n * @remarks\n * - Improves performance by reducing the number of event listeners.\n * - Enables efficient O(1) lookup and management of event handlers for revalidation.\n */\nconst eventHandlers = new Map void>();\n\n/** Subscribe to an event and return a cleanup function */\nexport type EventProvider = (handler: () => void) => () => void;\n\nconst customEventProviders = new Map();\n\n/**\n * Registers a custom event provider for 'focus' or 'online' events.\n * Useful for non-browser environments like React Native.\n *\n * @param type - The event type ('focus' or 'online').\n * @param provider - A function that subscribes to the event and returns a cleanup function.\n */\nexport function setEventProvider(\n type: EventType,\n provider: EventProvider,\n): void {\n customEventProviders.set(type, provider);\n\n // Re-register if already active\n if (eventHandlers.has(type)) {\n removeEventHandler(type);\n addEventHandler(type);\n }\n}\n\n/**\n * Triggers revalidation for all registered entries based on the given event type.\n * For example, if it's a 'focus' event, it will revalidate entries that have the `refetchOnFocus` flag set.\n * Updates the timestamp and invokes the revalidator function for each applicable entry.\n *\n * @param type - The type of event that caused the revalidation (e.g., 'focus' or 'online').\n * @param isStaleRevalidation - If `true`, uses background revalidator and doesn't mark as in-flight.\n * @param isThrottled - If `true`, skips entries that were requested or revalidated within their `focusThrottleInterval`.\n */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n isThrottled: boolean = false,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex] || (isThrottled && now - entry[1] < entry[7]!)) {\n return;\n }\n\n entry[1] = now;\n\n // If it's a stale revalidation, use the background revalidator function\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n if (revalidator) {\n Promise.resolve(revalidator(isStaleRevalidation)).catch(noop);\n }\n });\n}\n\n/**\n * Revalidates an entry by executing the registered revalidation function.\n *\n * @param key The unique identifier for the cache entry to revalidate. If `null`, no revalidation occurs.\n * @param isStaleRevalidation - If `true`, it does not mark revalidated requests as in-flight.\n * @returns A promise that resolves to the result of the revalidator function, or\n * `null` if no key or revalidator is found, or a `FetchResponse` if applicable.\n */\nexport async function revalidate(\n key: string | null,\n isStaleRevalidation: boolean = false,\n): Promise {\n // If no key is provided, no revalidation occurs\n if (!key) {\n return null;\n }\n\n const entry = revalidators.get(key);\n\n if (entry) {\n // Update only the lastUsed timestamp without resetting the whole array\n entry[1] = timeNow();\n\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n // If no revalidator function is registered, return null\n if (revalidator) {\n return await revalidator(isStaleRevalidation);\n }\n }\n\n // If no revalidator is registered for the key, return null\n return null;\n}\n\n/**\n * Removes all revalidators associated with the specified event type.\n *\n * @param type - The event type whose revalidators should be removed.\n */\nexport function removeRevalidators(type: EventType) {\n removeEventHandler(type);\n\n const flagIndex = type === 'focus' ? 5 : 6;\n\n // Clear all revalidators with this flag\n revalidators.forEach((entry, key) => {\n if (entry[flagIndex]) {\n removeRevalidator(key);\n }\n });\n}\n\n/**\n * Registers a generic revalidation event handler for the specified event type.\n * Supports browser window events and custom event providers (e.g. for React Native).\n * Ensures the handler is only added once.\n *\n * @param event - The type of event to listen for (e.g., 'focus', 'online').\n */\nfunction addEventHandler(event: EventType) {\n if (eventHandlers.has(event)) {\n return;\n }\n\n // Focus events are throttled, so that e.g. switching between tabs quickly doesn't revalidate every time\n const handler = revalidateAll.bind(null, event, true, event === 'focus');\n\n // Priority 1: Custom event provider (works in any environment including React Native)\n const customProvider = customEventProviders.get(event);\n\n if (customProvider) {\n const cleanup = customProvider(handler);\n\n eventHandlers.set(event, cleanup);\n\n return;\n }\n\n // Priority 2: Browser window events\n if (isBrowser()) {\n window.addEventListener(event, handler);\n\n eventHandlers.set(event, () => window.removeEventListener(event, handler));\n }\n}\n\n/**\n * Removes the event handler for the specified event type.\n *\n * @param event - The type of event whose handler should be removed.\n */\nfunction removeEventHandler(event: EventType) {\n const cleanup = eventHandlers.get(event);\n\n if (cleanup) {\n cleanup();\n eventHandlers.delete(event);\n }\n}\n\n/**\n * Registers a revalidation functions for a specific cache key.\n *\n * @param {string} key Cache key to utilize\n * @param {RevalidatorFn} revalidatorFn Main revalidation function (marks in-flight requests)\n * @param {number} [ttl] Time to live in milliseconds (default: 3 minutes)\n * @param {number} [staleTime] Time (in seconds) after which the cache entry is considered stale\n * @param {RevalidatorFn} [bgRevalidatorFn] For stale revalidation (does not mark in-flight requests)\n * @param {boolean} [refetchOnFocus] Whether to revalidate on window focus\n * @param {boolean} [refetchOnReconnect] Whether to revalidate on network reconnect\n * @param {number} [focusThrottleInterval] Time (in milliseconds) after a request or revalidation during which focus events don't revalidate it\n */\nexport function addRevalidator(\n key: string,\n revalidatorFn: RevalidatorFn, // Main revalidation function (marks in-flight requests)\n ttl?: number,\n staleTime?: number,\n bgRevalidatorFn?: RevalidatorFn, // For stale revalidation (does not mark in-flight requests)\n refetchOnFocus?: boolean,\n refetchOnReconnect?: boolean,\n focusThrottleInterval?: number,\n) {\n // Existing entries are updated in place\n const entry = revalidators.get(key) || ([] as unknown as RevalidatorEntry);\n\n entry[0] = revalidatorFn;\n entry[1] = timeNow();\n entry[2] = ttl ?? DEFAULT_TTL;\n entry[3] = staleTime;\n entry[4] = bgRevalidatorFn;\n entry[5] = refetchOnFocus;\n entry[6] = refetchOnReconnect;\n entry[7] = focusThrottleInterval;\n\n revalidators.set(key, entry);\n\n if (refetchOnFocus) {\n addEventHandler('focus');\n }\n\n if (refetchOnReconnect) {\n addEventHandler('online');\n }\n\n if (staleTime) {\n addTimeout('s:' + key, revalidate.bind(null, key, true), staleTime * 1000);\n }\n}\n\nexport function removeRevalidator(key: string) {\n revalidators.delete(key);\n\n // Clean up stale timer\n removeTimeout('s:' + key);\n}\n\n/**\n * Periodically cleans up expired revalidators from the registry.\n * Removes any revalidator whose TTL has expired.\n *\n * @param {number} intervalMs How often to run cleanup (default: 3 minutes)\n * @returns {() => void} A function to stop the periodic cleanup\n */\nexport function startRevalidatorCleanup(\n intervalMs: number = DEFAULT_TTL,\n): () => void {\n const intervalId = setInterval(() => {\n const now = timeNow();\n\n revalidators.forEach(\n ([, lastUsed, ttl, , , refetchOnFocus, refetchOnReconnect], key) => {\n // Skip focus-only or reconnect-only revalidators to keep them alive\n if (refetchOnFocus || refetchOnReconnect) {\n return;\n }\n\n if (ttl > 0 && now - lastUsed > ttl) {\n removeRevalidator(key);\n }\n },\n );\n }, intervalMs);\n\n return () => clearInterval(intervalId);\n}\n","/**\n * Manages a set of listeners (subscribers) for arbitrary string keys, allowing cross-context or cross-component\n * cache updates and synchronization. Provides functions to add, remove, and notify listeners, as well as a\n * convenient subscribe/unsubscribe API.\n *\n * @template T - The type of the response object passed to listeners.\n *\n * @remarks\n * - Listeners are grouped by a string key, which typically represents a cache key or resource identifier.\n * - When `notifySubscribers` is called for a key, all listeners registered for that key are invoked with the provided response.\n * - The `subscribe` function returns an unsubscribe function for convenient cleanup.\n *\n * @example\n * ```ts\n * const unsubscribe = subscribe('user:123', (response) => {\n * // handle updated data\n * });\n * // Later, to stop listening:\n * unsubscribe();\n * ```\n */\n\nimport { noop } from './utils';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Listener = (response: T) => void;\n\nconst listeners = new Map>();\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n let set = listeners.get(key);\n\n if (!set) {\n listeners.set(key, (set = new Set()));\n }\n\n set.add(fn);\n}\n\nexport function removeListener(key: string, fn: Listener) {\n const set = listeners.get(key);\n\n if (set) {\n set.delete(fn);\n\n // If the set is empty, remove the key from the listeners map\n if (set.size === 0) {\n listeners.delete(key);\n }\n }\n}\n\nexport function notifySubscribers(key: string, response: T) {\n const fns = listeners.get(key);\n\n if (fns) {\n if (fns.size === 1) {\n // If there's only one listener, call it directly\n const fn = fns.values().next().value;\n fn!(response);\n } else {\n fns.forEach((fn) => fn(response));\n }\n }\n}\n\nexport function subscribe(key: string | null, fn: (response: T) => void) {\n if (!key) {\n // No op if no key is provided\n return noop;\n }\n\n addListener(key, fn);\n\n // Return an unsubscribe function\n return () => {\n removeListener(key, fn);\n };\n}\n","import { processHeaders } from './utils';\nimport {\n GET,\n APPLICATION_JSON,\n HEAD,\n STRING,\n CHARSET_UTF_8,\n CONTENT_TYPE,\n REJECT,\n UNDEFINED,\n APPLICATION_CONTENT_TYPE,\n} from './constants';\nimport type {\n HeadersObject,\n Method,\n RequestConfig,\n} from './types/request-handler';\nimport {\n replaceUrlPathParams,\n appendQueryParams,\n isSearchParams,\n isJSONSerializable,\n isSlowConnection,\n isAbsoluteUrl,\n sanitizeObject,\n isObject,\n} from './utils';\n\nconst defaultTimeoutMs = (isSlowConnection() ? 60 : 30) * 1000;\n\nexport const defaultConfig: RequestConfig = {\n strategy: REJECT,\n timeout: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n loadingTimeout: defaultTimeoutMs / 10, // 3 seconds (6 on slow connections)\n focusThrottleInterval: 5000, // 5 seconds\n headers: {\n Accept: APPLICATION_JSON + ', text/plain, */*',\n 'Accept-Encoding': 'gzip, deflate, br',\n },\n retry: {\n delay: defaultTimeoutMs / 30, // 1 second (2 on slow connections)\n maxDelay: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n resetTimeout: true,\n backoff: 1.5,\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n retryOn: [\n 408, // Request Timeout\n 409, // Conflict\n 425, // Too Early\n 429, // Too Many Requests\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n ],\n\n // Idempotent methods, which can be repeated safely, unlike e.g. POST requests that create resources\n methods: [GET, HEAD, 'PUT', 'DELETE', 'OPTIONS', 'TRACE'],\n },\n};\n\n/**\n * Overwrites the default configuration with the provided custom configuration.\n *\n * @param {Partial} customConfig - The custom configuration to merge into the default config.\n * @returns {Partial} - The updated default configuration object.\n */\nexport function setDefaultConfig(\n customConfig: Partial,\n): Partial {\n const sanitized = sanitizeObject(customConfig);\n\n // Merge nested retry and headers settings into the current defaults instead of replacing them\n return mergeConfigs(\n { retry: defaultConfig.retry, headers: defaultConfig.headers },\n sanitized,\n defaultConfig,\n );\n}\n\n/**\n * Returns a shallow copy of the current default configuration.\n *\n * @returns {RequestConfig} - The current default configuration.\n */\nexport function getDefaultConfig(): RequestConfig {\n return { ...defaultConfig };\n}\n\n/**\n * Build request configuration from defaults and overrides.\n * This function merges the default configuration with the provided request configuration,\n * @param {string} url - Request url\n * @param {RequestConfig | null | undefined} reqConfig - Request configuration\n * @return {RequestConfig} - Merged request configuration\n */\nexport function buildConfig(\n url: string,\n reqConfig?: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null,\n): RequestConfig {\n // Merging gives the request its own copies of nested objects like headers, so that\n // mutations (e.g. by interceptors) never leak into the global defaults\n const merged = mergeConfigs(\n defaultConfig,\n reqConfig ? sanitizeObject(reqConfig) : {},\n );\n\n return buildFetcherConfig(url, merged);\n}\n\n/**\n * Builds the fetcher configuration by setting the method, body, headers, and URL.\n * It also handles query parameters and path parameters. This fn mutates the passed `requestConfig` object.\n * @param {string} url - The endpoint URL to which the request will be sent.\n * @param {RequestConfig} requestConfig - The request configuration object containing method, body, headers, and other options.\n * @return {RequestConfig} - The modified request configuration object with the URL, method, body, and headers set appropriately.\n **/\nexport function buildFetcherConfig(\n url: string,\n requestConfig: RequestConfig,\n): RequestConfig {\n let method = requestConfig.method as Method;\n method = method ? (method.toUpperCase() as Method) : GET;\n\n let body: RequestConfig['data'] | undefined;\n\n // Only applicable for request methods 'PUT', 'POST', 'DELETE', and 'PATCH'\n if (method !== GET && method !== HEAD) {\n body = requestConfig.body ?? requestConfig.data;\n\n // Automatically stringify request body, if possible and when not dealing with strings\n if (body && typeof body !== STRING && isJSONSerializable(body)) {\n body = JSON.stringify(body);\n }\n }\n\n setContentTypeIfNeeded(requestConfig.headers, body);\n\n // Native fetch compatible settings\n const credentials = requestConfig.withCredentials\n ? 'include'\n : requestConfig.credentials;\n\n // The explicitly passed query params\n const dynamicUrl = replaceUrlPathParams(url, requestConfig.urlPathParams);\n const urlPath = appendQueryParams(dynamicUrl, requestConfig.params);\n const isFullUrl = isAbsoluteUrl(url);\n const baseURL = isFullUrl\n ? ''\n : requestConfig.baseURL || requestConfig.apiUrl || '';\n\n // Join as a path, as plain concatenation could extend the host of the baseURL,\n // e.g. \"https://api.example.com\" + \".evil.com\" would point to another host\n const separator =\n baseURL && urlPath && !baseURL.endsWith('/') && !/^[/?#]/.test(urlPath)\n ? '/'\n : '';\n\n requestConfig.url = baseURL + separator + urlPath;\n requestConfig.method = method;\n requestConfig.credentials = credentials;\n requestConfig.body = body;\n\n return requestConfig;\n}\n\n/**\n * Ensures the `Content-Type` header is set to `application/json; charset=utf-8`\n * if it is not already present and the request method and body meet specific conditions.\n *\n * @param headers - The headers object to modify. Can be an instance of `Headers`\n * or a plain object conforming to `HeadersInit`.\n * @param body - The optional body of the request. If no body is provided and the\n * method is 'GET' or 'HEAD', the function exits without modifying headers.\n */\nfunction setContentTypeIfNeeded(\n headers?: HeadersInit | HeadersObject,\n body?: unknown,\n): void {\n // If no headers are provided, or if the body is not set and the method is PUT or DELETE, do nothing\n if (!headers || !body) {\n return;\n }\n\n // Types that should not have Content-Type set (browser handles these)\n if (\n body instanceof FormData || // Browser automatically sets multipart/form-data with boundary\n (typeof Blob !== UNDEFINED && body instanceof Blob) || // Blob/File (a File is a Blob) already have their own MIME types, don't override\n (typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream) // Stream type should be determined by the stream source\n ) {\n return;\n }\n\n let contentTypeValue: string;\n\n if (isSearchParams(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded';\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'octet-stream';\n } else if (isJSONSerializable(body)) {\n contentTypeValue = APPLICATION_JSON + ';' + CHARSET_UTF_8;\n } else {\n // Do not set Content-Type if content is not recognizable\n return;\n }\n\n if (headers instanceof Headers) {\n if (!headers.has(CONTENT_TYPE)) {\n headers.set(CONTENT_TYPE, contentTypeValue);\n }\n } else if (\n isObject(headers) &&\n !Array.isArray(headers) &&\n // Header names are case-insensitive, so check the normalized (lowercase) headers\n !processHeaders(headers as HeadersObject)[CONTENT_TYPE.toLowerCase()]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\n\n// The interceptors that are merged instead of replaced\nconst INTERCEPTORS = [\n 'onRequest',\n 'onResponse',\n 'onError',\n 'onLoadingSlow',\n] as const;\n\n/**\n * Merges two request configurations, applying overrides from the second config to the first.\n * Handles special merging for nested properties like 'retry' and 'headers' (deep merge),\n * and concatenates interceptor arrays for 'onRequest', 'onResponse', 'onError' and 'onLoadingSlow'.\n * If a target config is provided, it mutates that object; otherwise, creates a new one.\n *\n * @param {RequestConfig} baseConfig - The base configuration object to merge from.\n * @param {RequestConfig} overrideConfig - The override configuration object to apply on top of the base.\n * @param {RequestConfig} [targetConfig={}] - Optional target configuration object to merge into (mutated in place).\n * @returns {RequestConfig} The merged configuration object.\n *\n * @example\n * const base = { timeout: 5000, headers: { 'Accept': 'application/json' } };\n * const override = { timeout: 10000, headers: { 'Authorization': 'Bearer token' } };\n * const merged = mergeConfigs(base, override);\n * // Result: { timeout: 10000, headers: { Accept: 'application/json', Authorization: 'Bearer token' } }\n */\nexport function mergeConfigs(\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig = {},\n): RequestConfig {\n Object.assign(targetConfig, baseConfig, overrideConfig);\n\n // Ensure that retry and headers are merged correctly\n mergeConfig('retry', baseConfig, overrideConfig, targetConfig);\n mergeConfig('headers', baseConfig, overrideConfig, targetConfig);\n\n // Merge interceptors efficiently\n for (const property of INTERCEPTORS) {\n mergeInterceptors(property, baseConfig, overrideConfig, targetConfig);\n }\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends\n 'onRequest' | 'onResponse' | 'onError' | 'onRetry' | 'onLoadingSlow',\n>(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const baseInterceptor = baseConfig[property];\n const newInterceptor = overrideConfig[property];\n\n if (baseInterceptor && newInterceptor) {\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] = (\n property === 'onResponse'\n ? [].concat(newInterceptor as never, baseInterceptor as never)\n : [].concat(baseInterceptor as never, newInterceptor as never)\n ) as RequestConfig[K];\n } else if (baseInterceptor || newInterceptor) {\n targetConfig[property] = baseInterceptor || newInterceptor;\n }\n}\n\n/**\n * Merges the specified property from the base configuration and the override configuration into the target configuration.\n *\n * @param {K} property - The property key to merge from the base and override configurations. Must be a key of RequestConfig.\n * @param {RequestConfig} baseConfig - The base configuration object that provides default values.\n * @param {RequestConfig} overrideConfig - The override configuration object that contains user-specific settings to merge.\n * @param {RequestConfig} targetConfig - The configuration object that will receive the merged properties.\n */\nexport function mergeConfig(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n if (override) {\n if (property === 'headers') {\n // Handle Headers instances which don't expose entries as own enumerable properties\n const isInstance =\n (base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers;\n const merged: HeadersObject = isInstance\n ? processHeaders(base)\n : { ...(base as HeadersObject) };\n const overrides: HeadersObject = isInstance\n ? processHeaders(override)\n : sanitizeObject(override as HeadersObject);\n\n // Header names are case-insensitive, so replace existing entries instead of duplicating them\n for (const key of Object.keys(overrides)) {\n const lowerKey = key.toLowerCase();\n\n for (const existingKey in merged) {\n if (existingKey.toLowerCase() === lowerKey) {\n delete merged[existingKey];\n }\n }\n\n merged[key] = overrides[key];\n }\n\n targetConfig[property] = merged as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...sanitizeObject(override as Record),\n } as RequestConfig[K];\n }\n } else if (\n override === undefined &&\n isObject(base) &&\n !((base as Headers | HeadersObject) instanceof Headers)\n ) {\n // Copy so that mutating the merged config never changes the base config\n targetConfig[property] = { ...base } as RequestConfig[K];\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { hash } from './hash';\nimport type {\n CacheKeyFunction,\n DefaultResponse,\n FetchResponse,\n MutationSettings,\n RequestConfig,\n} from './types/request-handler';\nimport type {\n CacheEntry,\n CacheStore,\n StoredResponse,\n} from './types/cache-manager';\nimport { GET, STRING } from './constants';\nimport {\n isJSONSerializable,\n isObject,\n isSearchParams,\n noop,\n sanitizeObject,\n sortObject,\n timeNow,\n} from './utils';\nimport { revalidate } from './revalidator-manager';\nimport { notifySubscribers } from './pubsub-manager';\nimport type { DefaultPayload, DefaultParams, DefaultUrlParams } from './types';\nimport { removeInFlight } from './inflight-manager';\nimport { addTimeout } from './timeout-wheel';\nimport { defaultConfig } from './config-handler';\nimport { processHeaders } from './utils';\n\nexport const IMMEDIATE_DISCARD_CACHE_TIME = 0; // Use it for cache entries that need to be persistent until unused by components or manually deleted\n\nconst _cache = new Map>();\n// The cache stores that keep copies of cache entries, by cache key\nconst stores = new Map();\nconst DELIMITER = '|';\nconst MIN_LENGTH_TO_HASH = 64;\nconst CACHE_KEY_SANITIZE_PATTERN = /[^\\w\\-_|/:@.?=&~%#]/g;\nconst CACHE_KEY_NEEDS_SANITIZE = /[^\\w\\-_|/:@.?=&~%#]/; // Non-global for fast test\n\n/**\n * Headers that may affect HTTP response content and should be included in cache key generation.\n * Header names are matched case-insensitively.\n *\n * - Content negotiation: accept (response format, e.g. JSON or HTML), accept-language (localization), accept-encoding (compression)\n * - Authentication: authorization (access to protected resources)\n * - Request body metadata: content-type (how the request body is interpreted)\n * - Optional: referer (may influence behavior in some APIs), origin (CORS or tenant-specific APIs),\n * user-agent (if the server returns client-specific content), cookie (session-based responses; can fragment the cache heavily)\n * - Custom headers that may affect response content: x-api-key (token-based access), x-requested-with (AJAX requests),\n * x-client-id (per-client/partner identity), x-tenant-id (multi-tenant segmentation), x-user-id (explicit user context),\n * x-app-version (version-specific behavior), x-feature-flag (feature rollout), x-device-id (per device/app instance),\n * x-platform (e.g. 'ios', 'android', 'web'), x-session-id (if it affects the response directly), x-locale (like accept-language)\n */\nconst CACHE_KEY_HEADERS =\n /^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;\n\n/**\n * Generates a unique cache key for a given URL and fetch options, ensuring that key factors\n * like method, headers, body, and other options are included in the cache key.\n * Headers and other objects are sorted by key to ensure consistent cache keys.\n *\n * @param {RequestConfig} config - The fetch options that may affect the request. The most important are:\n * @property {string} [method=\"GET\"] - The HTTP method (GET, POST, etc.).\n * @property {HeadersInit} [headers={}] - The request headers.\n * @property {BodyInit | null} [body=\"\"] - The body of the request (only for methods like POST, PUT).\n * @property {RequestCredentials} [credentials=\"same-origin\"] - Whether to include credentials (include, same-origin, omit).\n * @property {RequestCache} [cache=\"default\"] - The cache mode (e.g., default, no-store, reload).\n * @returns {string} - A unique cache key string based on the provided options.\n *\n * @example\n * const cacheKey = generateCacheKey({\n * url: 'https://api.example.com/data',\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'Alice' }),\n * mode: 'cors',\n * credentials: 'include',\n * });\n * console.log(cacheKey);\n */\nexport function generateCacheKey(\n config: RequestConfig,\n cacheKeyCheck = true,\n): string {\n // This is super fast. Effectively a no-op if cacheKey is\n // a string or a function that returns a string.\n const key = config.cacheKey;\n\n if (key && cacheKeyCheck) {\n return typeof key === STRING\n ? (key as string)\n : (key as CacheKeyFunction)(config);\n }\n\n const {\n url = '',\n method = GET,\n headers = null,\n body = null,\n credentials = 'same-origin',\n } = config;\n\n // Sort headers and body + convert sorted to strings for hashing purposes\n // Native serializer is on avg. 3.5x faster than a Fast Hash or FNV-1a\n let headersString = '';\n if (headers) {\n let obj: Record;\n\n if (headers instanceof Headers) {\n obj = processHeaders(headers);\n } else {\n obj = headers as Record;\n }\n\n // Filter headers to only include those that affect request identity\n // Include only headers that affect request identity, not execution behavior\n const keys = Object.keys(obj);\n const len = keys.length;\n\n // Sort keys manually for fastest deterministic output\n if (len > 1) {\n keys.sort();\n }\n\n let str = '';\n for (let i = 0; i < len; ++i) {\n if (CACHE_KEY_HEADERS.test(keys[i])) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // Concatenate all key parts into a cache key string\n // Template literals are apparently slower\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n return sanitizeCacheKey(cacheStr);\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING || isSearchParams(body)) {\n const str = String(body);\n\n bodyString = str.length < MIN_LENGTH_TO_HASH ? str : hash(str); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Files can't be read synchronously, so they are identified by their object\n bodyString +=\n key +\n '=' +\n (typeof value === STRING ? value : 'F' + getObjectId(value as File)) +\n '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (isObject(body) && !isJSONSerializable(body)) {\n // Blobs, buffers, streams etc. can't be read synchronously, so they are identified by their object.\n // Two different bodies never share a key, while the same body object is still deduplicated.\n bodyString = 'B' + getObjectId(body);\n } else {\n const o = isObject(body)\n ? JSON.stringify(sortObject(body))\n : String(body);\n\n bodyString = o.length > MIN_LENGTH_TO_HASH ? hash(o) : o;\n }\n }\n\n return sanitizeCacheKey(cacheStr + DELIMITER + bodyString);\n}\n\nconst objectIds = new WeakMap();\nlet lastObjectId = 0;\n\n/**\n * Returns a unique id for an object, e.g. a request body that can't be serialized.\n *\n * @param {object} obj - The object to identify.\n * @returns {number} - The id of the object.\n */\nfunction getObjectId(obj: object): number {\n let id = objectIds.get(obj);\n\n if (!id) {\n objectIds.set(obj, (id = ++lastObjectId));\n }\n\n return id;\n}\n\n/**\n * Prevents cache poisoning by removal of control chars and unusual characters.\n * When anything is removed, a hash of the original key is appended so that keys\n * differing only in the removed characters (e.g. `?a[]=1` and `?a=1`) don't collide.\n *\n * @param {string} cacheStr - The raw cache key.\n * @returns {string} - The sanitized cache key.\n */\nfunction sanitizeCacheKey(cacheStr: string): string {\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '') +\n DELIMITER +\n hash(cacheStr)\n : cacheStr;\n}\n\n/**\n * Checks if the cache entry is expired based on its timestamp and the expiry time.\n *\n * @param {CacheEntry} entry - The cache entry to check.\n * @returns {boolean} - Returns true if the cache entry is expired, false otherwise.\n */\nfunction isCacheExpired(entry: CacheEntry): boolean {\n // No expiry time means the entry never expires\n if (!entry.expiry) {\n return false;\n }\n\n return timeNow() > entry.expiry;\n}\n\n/**\n * Retrieves a cached response from the internal cache using the provided key.\n *\n * @param key - The unique key identifying the cached entry. If null, returns null.\n * @returns The cached {@link FetchResponse} if found, otherwise null.\n */\nexport function getCacheData<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n key: string | null,\n): FetchResponse | null {\n if (!key) {\n return null;\n }\n\n const entry = _cache.get(key);\n\n return entry ? entry.data : null;\n}\n\n/**\n * Retrieves a cache entry if it exists and is not expired.\n *\n * @param {string} key Cache key to utilize\n * @returns {CacheEntry | null} - The cache entry if it exists and is not expired, null otherwise.\n */\nexport function getCache(\n key: string | null,\n):\n | CacheEntry<\n FetchResponse\n >\n | null\n | undefined {\n return _cache.get(key as string);\n}\n\n/**\n * Sets a new cache entry or updates an existing one, with optional TTL (time-to-live).\n *\n * @param {string} key Cache key to utilize\n * @param {T} data - The data to be cached.\n * @param {number} [ttl] - Optional TTL in seconds. If not provided, the cache entry will not expire.\n * @param {number} [staleTime] - Optional stale time in seconds. If provided, the cache entry will be considered stale after this time.\n */\nexport function setCache(\n key: string,\n data: T,\n ttl?: number,\n staleTime?: number,\n): void {\n if (ttl === 0) {\n deleteCache(key);\n return;\n }\n\n const time = timeNow();\n const ttlMs = ttl ? ttl * 1000 : 0;\n const staleTimeMs = staleTime ? staleTime * 1000 : 0; // Ensure default value for staleTime\n\n _cache.set(key, {\n data,\n time,\n stale: staleTimeMs > 0 ? time + staleTimeMs : undefined, // Use undefined if staleTime is not set\n expiry: ttl === -1 ? undefined : time + ttlMs,\n });\n\n if (ttlMs > 0) {\n scheduleExpiry(key, ttlMs);\n }\n}\n\n/**\n * Deletes a cache entry once it expires.\n *\n * @param {string} key Cache key to utilize\n * @param {number} ms - The time until the entry expires, in milliseconds.\n */\nfunction scheduleExpiry(key: string, ms: number): void {\n addTimeout('c:' + key, () => deleteCache(key, true), ms);\n}\n\n/**\n * Invalidates (deletes) a cache entry.\n *\n * @param {string} key Cache key to utilize\n * @param {boolean} [removeExpired=false] - If true, only deletes the cache entry if it is expired or stale.\n */\nexport function deleteCache(key: string, removeExpired: boolean = false): void {\n if (removeExpired) {\n const entry = getCache(key);\n\n // If the entry does not exist, or it is neither expired nor stale, do not delete\n if (!entry || !isCacheExpired(entry)) {\n return;\n }\n }\n\n _cache.delete(key);\n\n const store = stores.get(key);\n\n if (store) {\n stores.delete(key);\n callStore(() => store.delete(key));\n }\n}\n\n/**\n * Prunes the cache by removing entries that have expired based on the provided cache time.\n */\nexport function pruneCache(): void {\n _cache.clear();\n stores.clear();\n}\n\n/**\n * Calls a cache store method. Store errors, e.g. of a full localStorage, are ignored so that they can't break requests.\n *\n * @param {() => unknown} fn - The function calling the store.\n */\nfunction callStore(fn: () => unknown): void {\n try {\n Promise.resolve(fn()).catch(noop);\n } catch {\n // Ignored\n }\n}\n\n/**\n * Saves a copy of a cached response in a cache store, so that it can be restored later, e.g. after a page reload.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheStore} [store] - The cache store. If not provided, nothing is saved.\n */\nfunction persistCache(key: string, store?: CacheStore): void {\n const entry = _cache.get(key);\n\n if (store && entry) {\n const { data, status, statusText, headers } = entry.data as FetchResponse;\n\n stores.set(key, store);\n callStore(() =>\n store.set(key, { ...entry, data: { data, status, statusText, headers } }),\n );\n }\n}\n\n/**\n * Reads the entry of a cache key from the cache store of a request, e.g. one saved during a previous page load.\n * Expired entries are deleted from the store.\n *\n * @param {string} key Cache key to utilize\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {Promise | null>} - The stored entry, or null if there is no valid one or the in-memory cache has an entry already.\n */\nexport async function getStoredCache(\n key: string,\n requestConfig: RequestConfig,\n): Promise | null> {\n const store = requestConfig.cacheStore;\n\n if (!store || isCacheBypassed(requestConfig)) {\n return null;\n }\n\n let entry: CacheEntry | null | undefined;\n\n try {\n entry = await store.get(key);\n } catch {\n // A failing store is treated like an empty one\n return null;\n }\n\n // Another request may have cached a response in the meantime\n if (!entry || _cache.has(key)) {\n return null;\n }\n\n if (isCacheExpired(entry)) {\n callStore(() => store.delete(key));\n\n return null;\n }\n\n return entry;\n}\n\n/**\n * Caches a response restored from a cache store in memory, keeping its original stale and expiry times.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheEntry} entry - The cache entry with the restored response.\n * @param {CacheStore} store - The cache store that the response was restored from.\n * @returns {boolean} - True if the restored response is fresh, false if it's stale.\n */\nexport function restoreCache(\n key: string,\n entry: CacheEntry,\n store: CacheStore,\n): boolean {\n _cache.set(key, entry);\n stores.set(key, store);\n\n if (entry.expiry) {\n scheduleExpiry(key, entry.expiry - timeNow());\n }\n\n notifySubscribers(key, entry.data);\n\n return !entry.stale || timeNow() < entry.stale;\n}\n\n/**\n * Mutates a cache entry with new data and optionally revalidates it.\n *\n * @param {string | null} key Cache key to utilize. If null, no mutation occurs.\n * @param {ResponseData} newData - The new data to be cached.\n * @param {MutationSettings|undefined} settings - Mutation settings.\n */\nexport async function mutate<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n key: string | null,\n newData: ResponseData,\n settings?: MutationSettings,\n): Promise | null> {\n // If no key is provided, do nothing\n if (!key) {\n return null;\n }\n\n const entry = getCache(\n key,\n );\n\n if (!entry) {\n return null;\n }\n\n const updatedData = isObject(newData) ? sanitizeObject(newData) : newData;\n\n const updatedResponse = {\n ...entry.data,\n data: updatedData,\n };\n\n // The ETag belongs to the original data, so the changed data must not be revalidated with it\n const headers = updatedResponse.headers;\n\n if (headers && headers.etag) {\n updatedResponse.headers = { ...headers };\n delete updatedResponse.headers.etag;\n }\n\n const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n persistCache(key, stores.get(key));\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\n}\n\n/**\n * Checks whether a request should bypass the cache, because of its cache buster or `cache: 'reload'`.\n *\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {boolean} - True if the cache should be bypassed.\n */\nexport function isCacheBypassed(requestConfig: RequestConfig): boolean {\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n\n return (\n !!(buster && buster(requestConfig)) || requestConfig.cache === 'reload'\n );\n}\n\n/**\n * Retrieves a cached response if available and valid, otherwise returns null.\n *\n * @template ResponseData - The type of the response data.\n * @template RequestBody - The type of the request body.\n * @template QueryParams - The type of the query parameters.\n * @template PathParams - The type of the path parameters.\n * @param {string | null} cacheKey - The cache key to look up.\n * @param {number | undefined} cacheTime - The maximum time to cache entry.\n * @param {RequestConfig} requestConfig - The fetcher configuration.\n * @returns {FetchResponse | null} - The cached response or null.\n */\nexport function getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n cacheKey: string | null,\n cacheTime: number | undefined,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): FetchResponse | null {\n // If cache key or time is not provided, return null\n if (!cacheKey || cacheTime === undefined || cacheTime === null) {\n return null;\n }\n\n if (isCacheBypassed(requestConfig)) {\n return null;\n }\n\n // Retrieve the cached entry\n const entry = getCache(\n cacheKey,\n );\n\n if (!entry) {\n return null;\n }\n\n const isExpired = isCacheExpired(entry);\n\n // If completely expired, delete and return null\n if (isExpired) {\n deleteCache(cacheKey);\n return null;\n }\n\n const data = entry.data;\n\n // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n // The placeholder stored while a request is in flight is not a response, so treat it as a miss\n return data && data.isFetching ? null : data;\n}\n\n/**\n * Sets or deletes the response cache based on cache settings and notifies subscribers.\n *\n * @param {FetchResponse} output - The response to cache.\n * @param {RequestConfig} requestConfig - The request configuration.\n * @param {boolean} [isError=false] - Whether the response is an error.\n */\nexport function handleResponseCache<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n output: FetchResponse,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n isError: boolean = false,\n): void {\n // It is string as it is called once request is made\n const cacheKey = requestConfig.cacheKey as string;\n\n if (cacheKey) {\n const cacheTime = requestConfig.cacheTime;\n const skipCache = requestConfig.skipCache;\n\n // Fast path: only set cache if cacheTime is positive and not skipping cache\n if (\n cacheTime &&\n (!isError || requestConfig.cacheErrors) &&\n !(skipCache && skipCache(output, requestConfig))\n ) {\n setCache(cacheKey, output, cacheTime, requestConfig.staleTime);\n\n // Error responses are only cached in memory\n if (!isError) {\n persistCache(cacheKey, requestConfig.cacheStore);\n }\n } else {\n const entry = getCache(cacheKey);\n\n // Don't let the in-flight placeholder outlive a request whose result isn't cached\n if (entry && entry.data && entry.data.isFetching) {\n deleteCache(cacheKey);\n }\n }\n\n notifySubscribers(cacheKey, output);\n removeInFlight(cacheKey);\n\n const prevCacheKey = requestConfig._prevKey;\n\n if (prevCacheKey) {\n removeInFlight(prevCacheKey);\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { mutate } from './cache-manager';\nimport {\n APPLICATION_CONTENT_TYPE,\n APPLICATION_JSON,\n CONTENT_TYPE,\n FUNCTION,\n STRING,\n} from './constants';\nimport {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n ResponseError,\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n} from './types';\nimport { flattenData, isObject, processHeaders } from './utils';\n\n/**\n * Parses the response data based on the Content-Type header, or reads it as the given response type.\n *\n * @param response - The Response object to parse.\n * @param responseType - How to read the body regardless of its Content-Type, e.g. as a Blob, or `'stream'` to leave it unread.\n * @returns A Promise that resolves to the parsed data.\n */\nexport async function parseResponseData<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse,\n responseType?: RequestConfig['responseType'],\n): Promise {\n // Bail early if response is null or undefined\n if (!response) {\n return null;\n }\n\n // Get the content-type header once\n const headers = (response as Response).headers;\n let contentType = headers && headers.get(CONTENT_TYPE);\n\n if (contentType) {\n // Lowercase and trim for consistent matching\n contentType = contentType.toLowerCase().trim();\n } else {\n contentType = '';\n }\n\n // Split for mime type without charset\n const mimeType = contentType.split(';', 1)[0];\n\n let data;\n\n try {\n if (responseType) {\n // The body is read as requested, or left unread as a stream to be read by the caller\n data =\n responseType === 'stream'\n ? response.body\n : await response[responseType]();\n } else if (\n mimeType.includes(APPLICATION_JSON) ||\n mimeType.includes('+json')\n ) {\n data = await response.json(); // Parse JSON response\n } else if (\n (mimeType.includes('multipart/form-data') || // Parse as FormData\n mimeType.includes(\n APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded', // Handle URL-encoded forms\n )) &&\n typeof response.formData === FUNCTION\n ) {\n data = await response.formData();\n } else if (/^(image|video|audio)\\/|octet-stream|pdf|zip/.test(mimeType)) {\n data = await response.arrayBuffer(); // Parse as ArrayBuffer for binary types\n } else {\n data = await response.text();\n\n if (typeof data === STRING) {\n const trimmed = data.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n data = JSON.parse(trimmed);\n } catch {\n // leave as text if parsing fails\n }\n }\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (_error) {\n // Parsing failed, fallback to null\n data = null;\n }\n\n return data;\n}\n\n/**\n * Prepare response object with additional information.\n *\n * @param Response. It may be \"null\" in case of request being aborted.\n * @param {RequestConfig} config - Request config\n * @param error - whether the response is erroneous\n * @returns {FetchResponse} Response data\n */\nexport const prepareResponse = <\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n config: RequestConfig,\n error: ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null,\n): FetchResponse => {\n const defaultResponse = config.defaultResponse;\n const cacheKey = config.cacheKey;\n const mutatator = mutate.bind(null, cacheKey as string) as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >['mutate'];\n\n // This may happen when request is cancelled.\n if (!response) {\n return {\n ok: false,\n // Enhance the response with extra information\n error,\n data: defaultResponse ?? null,\n headers: null,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: false,\n isError: true,\n } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n const isNativeResponse =\n typeof Response === FUNCTION && response instanceof Response;\n\n let data = response.data;\n\n // Set the default response if the provided data is an empty object or array\n // Other objects, e.g. Blobs, buffers and streams, have no keys either, but aren't empty\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (/^\\[object (Object|Array)\\]$/.test(\n Object.prototype.toString.call(data),\n ) &&\n Object.keys(data).length === 0))\n ) {\n response.data = data = defaultResponse;\n }\n\n if (config.flattenResponse) {\n response.data = data = flattenData(data);\n }\n\n if (config.select) {\n response.data = data = config.select(data);\n }\n\n const headers = processHeaders(response.headers);\n\n // Native fetch Response extended by extra information\n if (isNativeResponse) {\n const output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > = {\n body: response.body,\n bodyUsed: response.bodyUsed,\n ok: response.ok,\n redirected: response.redirected,\n type: response.type,\n url: response.url,\n status: response.status,\n statusText: response.statusText,\n\n // Convert methods to use arrow functions to preserve correct return types\n // Lazily construct Blob from ArrayBuffer\n blob: async () =>\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n json: async () => data as ResponseData, // Return the already parsed JSON data\n text: async () => data as string, // Return the already parsed text data\n // The body was already read, so a copy of this response is returned instead of Response.clone()\n clone: () => ({ ...output }),\n arrayBuffer: async () =>\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0), // Return the ArrayBuffer directly\n formData: async () => (data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: async () =>\n new Uint8Array(data instanceof ArrayBuffer ? data : new ArrayBuffer(0)),\n // Enhance the response with extra information\n error,\n data,\n headers,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: response.ok && !error,\n isError: !!error,\n };\n\n return output;\n }\n\n // If it's a custom fetcher, and it does not return any Response instance, it may have its own internal handler\n if (isObject(response)) {\n Object.assign(response, {\n error,\n headers,\n isFetching: false,\n mutate: mutatator,\n isSuccess: response.ok && !error,\n isError: !!error,\n });\n }\n\n return response;\n};\n","import { applyInterceptors } from './interceptor-manager';\nimport type { FetchResponse, RetryConfig, RetryFunction } from './types';\nimport { delayInvocation, timeNow } from './utils';\nimport { generateCacheKey } from './cache-manager';\nimport { FUNCTION } from './constants';\n\nfunction getMsFromHttpDate(dateString: string): number | null {\n const ms = Date.parse(dateString) - timeNow();\n\n if (!isNaN(ms)) {\n return Math.max(0, Math.floor(ms));\n }\n return null;\n}\n\n/**\n * Calculates the number of milliseconds to wait before retrying a request,\n * based on the `Retry-After` HTTP header in the provided response.\n *\n * The function supports both numeric (seconds) and HTTP-date formats for the `Retry-After` header.\n * - If the header is a number, it is interpreted as seconds and converted to milliseconds.\n * - If the header is a date, the function calculates the difference between the date and the current time.\n *\n * @param extendedResponse - The response object containing headers, or `null`.\n * @returns The number of milliseconds to wait before retrying, or `null` if the header is not present or invalid.\n */\nexport function getRetryAfterMs(\n extendedResponse: FetchResponse | null,\n): number | null {\n if (!extendedResponse) {\n return null;\n }\n\n const headers = extendedResponse.headers || {};\n const retryAfter = headers['retry-after'];\n\n if (retryAfter) {\n // Try parsing as seconds\n const seconds = Number(retryAfter);\n\n if (!isNaN(seconds) && seconds >= 0) {\n return seconds * 1000;\n }\n\n const ms = getMsFromHttpDate(retryAfter);\n\n if (ms !== null) {\n return ms;\n }\n }\n\n // Headers are already in lowercase\n const RATELIMIT_RESET = 'ratelimit-reset';\n\n // Unix timestamp when the rate limit window resets (relative to current time)\n // Fallback to checking 'ratelimit-reset-after' OR 'x-ratelimit-reset-after' headers\n const rateLimitResetAfter =\n headers[RATELIMIT_RESET + '-after'] ||\n headers['x-' + RATELIMIT_RESET + '-after'];\n\n if (rateLimitResetAfter) {\n const seconds = Number(rateLimitResetAfter);\n\n if (!isNaN(seconds)) {\n return seconds * 1000;\n }\n }\n\n // ISO 8601 datetime when the rate limit resets\n // Fallback to checking 'ratelimit-reset-at' 'x-ratelimit-reset-at' headers\n const rateLimitResetAt =\n headers[RATELIMIT_RESET + '-at'] || headers['x-' + RATELIMIT_RESET + '-at'];\n\n if (rateLimitResetAt) {\n return getMsFromHttpDate(rateLimitResetAt);\n }\n\n return null;\n}\n\n/**\n * Executes a request function with retry logic according to the provided configuration.\n *\n * The function attempts the request up to the specified number of retries, applying delay and backoff strategies.\n * Retries can be triggered based on response status codes, custom logic, or the presence of a `Retry-After` header.\n * Optionally, an `onRetry` interceptor can be invoked before each retry attempt.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param requestFn - The function that performs the request. Receives `isStaleRevalidation` and `attempt` as arguments.\n * @param config - The retry configuration, including retry count, delay, backoff, retry conditions, and hooks.\n * @returns A promise resolving to the fetch response, or rejecting if all retries are exhausted.\n * @throws Error if the maximum number of retries is exceeded or a non-retriable error occurs.\n */\nexport async function withRetry<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation: boolean,\n attempt: number,\n ) => Promise<\n FetchResponse\n >,\n config: RetryConfig,\n): Promise> {\n const {\n retries = 0,\n delay = 0,\n backoff = 1,\n maxDelay,\n retryOn = [],\n shouldRetry,\n jitter,\n methods,\n } = config;\n\n let attempt = 0;\n let waitTime = delay;\n const maxRetries = retries > 0 ? retries : 0;\n let output: FetchResponse;\n\n while (attempt <= maxRetries) {\n // Subsequent attempts will have output defined, but the first attempt may not.\n // Let's apply onRetry interceptor and regenerate cache key if ot really changes.\n if (attempt > 0 && output!) {\n const cfg = output.config;\n const onRetry = cfg.onRetry;\n\n if (onRetry) {\n await applyInterceptors(onRetry, output, attempt);\n\n // If the key was automatically generated, we need to regenerate it as config may change.\n // We don't detect whether config changed for performance reasons.\n if (cfg._isAutoKey) {\n cfg._prevKey = cfg.cacheKey as string;\n cfg.cacheKey = generateCacheKey(cfg, false);\n }\n }\n }\n\n // Performance optimization: Call the request function with the current attempt number\n // If this is the first attempt, we pass `isStaleRevalidation` as `false`,\n // otherwise we pass `true` to indicate that this is a stale revalidation (no cache hit).\n output = await requestFn(attempt > 0, attempt);\n const error = output.error;\n\n // Stop unless a failed response should be retried according to the retry settings,\n // or a successful one according to shouldRetry\n if (\n error\n ? await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n methods,\n )\n : !(\n shouldRetry &&\n attempt < maxRetries &&\n (await shouldRetry(output, attempt))\n )\n ) {\n break;\n }\n\n // The delay before the next retry, randomized with jitter unless the server asks for one below\n let retryDelay = withJitter(waitTime, jitter);\n\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (error && (error.status === 429 || error.status === 503)) {\n // Try to extract the \"Retry-After\" value from the response headers\n const retryAfterMs = getRetryAfterMs(output);\n\n // If a valid retry-after value is found, override the wait time before next retry\n // Cap it with maxDelay so that a server can't make the client wait indefinitely\n if (retryAfterMs !== null) {\n retryDelay = waitTime = Math.min(\n retryAfterMs,\n maxDelay || retryAfterMs,\n );\n }\n }\n\n await delayInvocation(retryDelay);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n }\n\n return output!;\n}\n\n/**\n * Determines whether to stop retrying based on the error, current attempt count, and retry configuration.\n *\n * This function checks:\n * - If the maximum number of retries has been reached.\n * - If the request was aborted, e.g. with its signal or by a newer request. Aborted requests are never retried.\n * - If a custom `shouldRetry` callback is provided, its result is used to decide.\n * - If no custom logic is provided, falls back to checking if the error status is included in the `retryOn` list,\n * and the request method in the `methods` list, if any.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param output - The response object containing the error and request configuration.\n * @param attempt - The current retry attempt number.\n * @param maxRetries - The maximum number of retry attempts allowed.\n * @param shouldRetry - Optional custom function to determine if a retry should occur.\n * @param retryOn - Optional list of HTTP status codes that should trigger a retry.\n * @param methods - Optional list of request methods that are retried on the `retryOn` statuses. All methods are retried without it.\n * @returns A promise resolving to `true` if retrying should stop, or `false` to continue retrying.\n */\nexport async function getShouldStopRetrying<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n output: FetchResponse,\n attempt: number,\n maxRetries: number,\n shouldRetry?: RetryFunction<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n retryOn: number[] = [],\n methods?: string[],\n): Promise {\n // Safety first: always respect max retries\n // We check retries provided regardless of the shouldRetry being provided so to avoid infinite loops.\n // It is a fail-safe so to prevent excessive retry attempts even if custom retry logic suggests a retry.\n if (attempt === maxRetries) {\n return true;\n }\n\n // Aborted requests are never retried, as e.g. a retry of one cancelled by a newer request would cancel the newer one\n if (output.error?.isCancelled) {\n return true;\n }\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n\n if (result !== null) {\n return !result;\n }\n }\n\n return !(\n (retryOn || []).includes(output.error?.status ?? 0) &&\n (!methods ||\n methods.some((method) => method.toUpperCase() === output.config.method))\n );\n}\n\n/**\n * Randomizes a retry delay with jitter, so that clients that failed at the same time, e.g. during an outage, don't retry all at once.\n *\n * @param delay - The delay computed from the `delay`, `backoff` and `maxDelay` settings, in milliseconds.\n * @param jitter - `true` for a random delay between 0 and the computed one (\"full jitter\"), or a function that returns the delay to use.\n * @returns The delay to wait before the retry, in milliseconds.\n */\nfunction withJitter(delay: number, jitter: RetryConfig['jitter']): number {\n return typeof jitter === FUNCTION\n ? (jitter as (delay: number) => number)(delay)\n : jitter\n ? Math.random() * delay\n : delay;\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation, isOffline, isPageHidden } from './utils';\n\n/**\n * Executes a request function with polling, stopping when shouldStopPolling returns true,\n * pollingInterval is not set, or maxAttempts is reached.\n * Polling pauses while the page is hidden or the browser is offline, unless allowed by refreshWhenHidden or refreshWhenOffline.\n *\n * @template Output The type of the output returned by the request function.\n * @param requestFn - The function that performs a single request (with retries).\n * @param pollingInterval - Interval in ms between polling attempts.\n * @param shouldStopPolling - Function to determine if polling should stop.\n * @param maxAttempts - Maximum number of polling attempts, default: 0 (unlimited).\n * @param pollingDelay - Delay in ms before each polling attempt, default: 0.\n * @param refreshWhenHidden - Whether to keep polling while the page is hidden, default: false.\n * @param refreshWhenOffline - Whether to keep polling while the browser is offline, default: false.\n * @param signal - The signal passed to the request. Polling stops once it is aborted.\n * @returns The final output from the last request.\n */\nexport async function withPolling<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation?: boolean,\n attempt?: number,\n ) => Promise<\n FetchResponse\n >,\n pollingInterval?: RequestConfig['pollingInterval'],\n shouldStopPolling?: RequestConfig['shouldStopPolling'],\n maxAttempts = 0,\n pollingDelay = 0,\n refreshWhenHidden = false,\n refreshWhenOffline = false,\n signal?: AbortSignal,\n): Promise> {\n if (!pollingInterval) {\n return requestFn();\n }\n\n let pollingAttempt = 0;\n let output: FetchResponse;\n\n while (maxAttempts === 0 || pollingAttempt < maxAttempts) {\n if (pollingDelay > 0) {\n await delayInvocation(pollingDelay, signal);\n }\n\n output = await requestFn();\n\n pollingAttempt++;\n\n if (\n (maxAttempts > 0 && pollingAttempt >= maxAttempts) ||\n !pollingInterval ||\n (shouldStopPolling && shouldStopPolling(output, pollingAttempt))\n ) {\n break;\n }\n\n // Wait for the next attempt, and keep waiting while polling is paused\n do {\n await delayInvocation(pollingInterval, signal);\n\n // Aborting the signal of the request stops polling\n if (signal && signal.aborted) {\n return output;\n }\n } while (\n (!refreshWhenHidden && isPageHidden()) ||\n (!refreshWhenOffline && isOffline())\n );\n }\n\n return output!;\n}\n","import { ABORT_ERROR, UNDEFINED } from './constants';\nimport type { RequestConfig, UploadProgress } from './types';\nimport { createAbortError } from './utils';\n\n// Responses with these statuses can't have a body\nconst NULL_BODY_STATUSES = [204, 205, 304];\n\n// Headers that browsers don't let requests set. fetch() skips them silently, while\n// XMLHttpRequest logs errors for them, so they are skipped before sending.\nconst FORBIDDEN_HEADERS =\n /^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/;\n\n// ReadableStream is missing in some environments, e.g. React Native\nconst isStream = (body: unknown): body is ReadableStream =>\n typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream;\n\nexport const toProgress = (loaded: number, total?: number): UploadProgress => ({\n loaded,\n total,\n progress: total ? loaded / total : undefined,\n});\n\n/**\n * Sends a request and reports the upload progress of its body to `onUploadProgress`.\n * Browsers and React Native don't report the upload progress of fetch(), so XMLHttpRequest is used there.\n * Elsewhere, e.g. in Node.js, the body is streamed with fetch() and counted while it is sent.\n *\n * @param {string} url - The request URL.\n * @param {RequestConfig} config - The request configuration, with a body and `onUploadProgress`.\n * @returns {Promise} - The response.\n */\nexport function fetchWithUploadProgress(\n url: string,\n config: RequestConfig,\n): Promise {\n const body = config.body as BodyInit;\n\n return typeof XMLHttpRequest !== UNDEFINED && !isStream(body)\n ? sendWithXhr(url, config, body)\n : sendStreamed(url, config, body);\n}\n\nfunction sendWithXhr(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n // fetchf() always sets the signal, as it handles timeouts and cancellation with it\n const signal = config.signal!;\n const abort = () => xhr.abort();\n\n const settle = (fn: () => void) => {\n signal.removeEventListener('abort', abort);\n\n try {\n fn();\n } catch (error) {\n reject(error);\n }\n };\n\n xhr.open(config.method as string, url);\n xhr.responseType = 'blob';\n xhr.withCredentials = config.credentials === 'include';\n\n new Headers(config.headers).forEach(\n (value, name) =>\n FORBIDDEN_HEADERS.test(name) || xhr.setRequestHeader(name, value),\n );\n\n xhr.upload.onprogress = (event) =>\n config.onUploadProgress!(\n toProgress(\n event.loaded,\n event.lengthComputable ? event.total : undefined,\n ),\n );\n\n xhr.onload = () =>\n settle(() => {\n const headers = new Headers();\n\n for (const line of xhr.getAllResponseHeaders().split(/\\r?\\n/)) {\n const index = line.indexOf(':');\n\n if (index > 0) {\n headers.append(line.slice(0, index), line.slice(index + 1).trim());\n }\n }\n\n const response = new Response(\n NULL_BODY_STATUSES.includes(xhr.status) ? null : xhr.response,\n { status: xhr.status, statusText: xhr.statusText, headers },\n );\n\n // Like fetch(), the response tells its final URL, e.g. after redirects\n Object.defineProperty(response, 'url', { value: xhr.responseURL });\n\n resolve(response);\n });\n\n xhr.onerror = () =>\n settle(() => reject(new TypeError('Network request failed')));\n\n // Like fetch(), aborted requests reject with the reason of the abort signal\n const onAbort = () =>\n settle(() =>\n reject(\n signal.reason ||\n createAbortError('The request was aborted', ABORT_ERROR),\n ),\n );\n\n xhr.onabort = onAbort;\n\n if (signal.aborted) {\n return onAbort();\n }\n\n signal.addEventListener('abort', abort);\n\n xhr.send(body as XMLHttpRequestBodyInit);\n });\n}\n\nasync function sendStreamed(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n const headers = new Headers(config.headers);\n let stream = body as ReadableStream;\n let total: number | undefined;\n\n if (!isStream(body)) {\n // Serialize the body like fetch() would, to know its size and content type\n const blob = body instanceof Blob ? body : await new Response(body).blob();\n\n total = blob.size;\n stream = blob.stream();\n\n if (blob.type && !headers.has('content-type')) {\n headers.set('content-type', blob.type);\n }\n }\n\n let loaded = 0;\n\n return fetch(url, {\n ...config,\n headers,\n body: stream.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n config.onUploadProgress!(toProgress(loaded, total));\n controller.enqueue(chunk);\n },\n }),\n ),\n // Required by fetch() to send a stream\n duplex: 'half',\n } as RequestInit);\n}\n","import { FUNCTION } from './constants';\nimport type { DownloadProgress } from './types';\nimport { toProgress } from './upload-progress';\n\n/**\n * Reports the download progress of a response body to `onDownloadProgress` while the body is read.\n * The body is counted as it arrives, so the progress follows the download.\n *\n * @param {T} response - The response. Other than native responses with a body, e.g. responses of HEAD requests or custom fetchers, are returned as they are.\n * @param {Function} [onDownloadProgress] - The function called with the progress. Without it, the response is returned as it is.\n * @returns {T} - A copy of the response, whose body is counted while it's read.\n */\nexport function withDownloadProgress(\n response: T,\n onDownloadProgress?: (progress: DownloadProgress) => void,\n): T {\n // Response is missing in some environments, and response bodies e.g. in React Native\n if (\n !onDownloadProgress ||\n typeof Response !== FUNCTION ||\n !(response instanceof Response) ||\n !response.body\n ) {\n return response;\n }\n\n const headers = response.headers;\n // Content-Length is the size of the compressed body, so the size of a compressed one is unknown\n const total = headers.has('content-encoding')\n ? undefined\n : Number(headers.get('content-length')) || undefined;\n let loaded = 0;\n\n const counted = new Response(\n response.body.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n // Browsers may hide the Content-Encoding header of cross-origin responses, so the progress is capped at 1\n onDownloadProgress(\n toProgress(loaded, total && Math.max(total, loaded)),\n );\n controller.enqueue(chunk);\n },\n }),\n ),\n response,\n );\n\n // Like the original response, the copy tells its final URL, whether it was redirected and its type\n for (const key of ['url', 'redirected', 'type'] as const) {\n Object.defineProperty(counted, key, { value: response[key] });\n }\n\n return counted as T;\n}\n","import type { ResponseError } from './errors/response-error';\nimport type {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n} from './types/request-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { handleResponseCache } from './cache-manager';\nimport { ABORT_ERROR, REJECT } from './constants';\nimport {\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n HeadersObject,\n} from './types';\nimport { processHeaders } from './utils';\n\n/**\n * Handles final processing for both success and error responses\n * Applies error interceptors, caching, notifications, and error strategy\n */\nexport async function withErrorHandling<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n isStaleRevalidation: boolean,\n requestFn: (\n isStaleRevalidation: boolean,\n ) => Promise<\n FetchResponse\n >,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): Promise> {\n const output = await requestFn(isStaleRevalidation);\n const error = output.error;\n\n if (!error) {\n // SUCCESS PATH\n handleResponseCache(output, requestConfig);\n\n return output;\n }\n\n // ERROR PATH\n\n if (requestConfig.onError) {\n await applyInterceptors(requestConfig.onError, error);\n }\n\n // Timeouts and request cancellations using AbortController do not throw any errors unless rejectCancelled is true.\n // Only handle the error if the request was not cancelled, or if it was cancelled and rejectCancelled is true.\n const isCancelled = error.isCancelled;\n\n const logger = requestConfig.logger;\n\n if (!isCancelled && logger && logger.warn) {\n logger.warn('FETCH ERROR', redactError(error as ResponseError));\n }\n\n // The defaultResponse strategy returns the default response in place of the error data.\n // The original data stays available through error.response.\n if (requestConfig.strategy === 'defaultResponse') {\n output.data = (requestConfig.defaultResponse ?? null) as typeof output.data;\n }\n\n // Handle cache and notifications FIRST (before strategy)\n handleResponseCache(output, requestConfig, true);\n\n // handle error strategy as the last part\n const shouldHandleError = !isCancelled || requestConfig.rejectCancelled;\n\n if (shouldHandleError) {\n const strategy = requestConfig.strategy;\n // Reject the promise\n if (strategy === REJECT) {\n throw error;\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\n}\n\n// Credential headers that must not end up in logs\nconst SENSITIVE_HEADERS = [\n 'authorization',\n 'proxy-authorization',\n 'cookie',\n 'x-api-key',\n];\n\n/**\n * Creates a copy of the error for logging, with credential headers masked and the request body removed.\n * The error itself is left untouched.\n */\nfunction redactError(error: ResponseError): ResponseError {\n // Cache keys are dropped too, as they can contain short request bodies\n const config = {\n ...error.config,\n body: undefined,\n data: undefined,\n cacheKey: undefined,\n _prevKey: undefined,\n headers: processHeaders(error.config.headers as HeadersObject),\n };\n\n for (const name of SENSITIVE_HEADERS) {\n if (config.headers[name]) {\n config.headers[name] = '[REDACTED]';\n }\n }\n\n const copy = Object.assign(new Error(error.message), error, {\n config,\n request: config,\n response: error.response && { ...error.response, config },\n });\n\n copy.name = error.name;\n copy.stack = error.stack;\n\n return copy;\n}\n\nexport function enhanceError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): void {\n error.status = error.status || (response && response.status) || 0;\n error.statusText =\n error.statusText || (response && response.statusText) || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n HeadersObject,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport type { StoredResponse } from './types/cache-manager';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject, noop, processHeaders } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport {\n generateCacheKey,\n getCacheData,\n getCachedResponse,\n getStoredCache,\n isCacheBypassed,\n restoreCache,\n setCache,\n} from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { fetchWithUploadProgress } from './upload-progress';\nimport { withDownloadProgress } from './download-progress';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION, GET, HEAD } from './constants';\nimport { buildConfig } from './config-handler';\n\nconst inFlightResponse = Object.freeze({\n isFetching: true,\n});\n\n/**\n * Sends an HTTP request to the specified URL using the provided configuration and returns a typed response.\n *\n * @typeParam ResponseData - The expected shape of the response data. Defaults to `DefaultResponse`.\n * @typeParam RequestBody - The type of the request payload/body. Defaults to `DefaultPayload`.\n * @typeParam QueryParams - The type of the query parameters. Defaults to `DefaultParams`.\n * @typeParam PathParams - The type of the path parameters. Defaults to `DefaultUrlParams`.\n *\n * @param url - The endpoint URL to which the request will be sent.\n * @param config - Optional configuration object for the request, including headers, method, body, query, and path parameters.\n *\n * @returns A promise that resolves to a `FetchResponse` containing the typed response data and request metadata.\n *\n * @example\n * ```typescript\n * const { data } = await fetchf('/api/user', { method: 'GET' });\n * console.log(data);\n * ```\n */\nexport async function fetchf<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n url: string,\n reqConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null = null,\n): Promise> {\n // Ultra-fast early cache check if cacheKey is provided as a string\n // For workloads dominated by repeated requests, this string caching optimization\n // can potentially support millions of requests per second with minimal CPU overhead\n if (reqConfig && typeof reqConfig.cacheKey === 'string') {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(reqConfig.cacheKey, reqConfig.cacheTime, reqConfig);\n\n if (cached) {\n return cached;\n }\n }\n\n const fetcherConfig = buildConfig<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(url, reqConfig);\n\n const {\n timeout,\n cancellable,\n cacheKey,\n dedupeTime,\n cacheTime,\n staleTime,\n refetchOnFocus,\n refetchOnReconnect,\n pollingInterval = 0,\n } = fetcherConfig;\n const isCacheEnabled = cacheTime !== undefined || staleTime !== undefined;\n const method = fetcherConfig.method;\n\n // Cached responses of GET and HEAD requests are revalidated with their ETag.\n // Custom fetchers may not handle 304 responses, so they only send it when it's enabled for them.\n const isETagEnabled =\n isCacheEnabled &&\n (method === GET || method === HEAD) &&\n (fetcherConfig.etag ?? !fetcherConfig.fetcher);\n\n const needsCacheKey = !!(\n cacheKey ||\n timeout ||\n dedupeTime ||\n isCacheEnabled ||\n cancellable ||\n refetchOnFocus ||\n refetchOnReconnect\n );\n\n let _cacheKey: string | null = null;\n\n // Generate cache key if required\n if (needsCacheKey) {\n _cacheKey = generateCacheKey(fetcherConfig);\n }\n\n // The initial data, which is used as the first response instead of sending the request\n let initialResponse: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n // Cache handling logic\n if (_cacheKey && isCacheEnabled) {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(_cacheKey, cacheTime, fetcherConfig);\n\n if (cached) {\n return cached;\n }\n\n // Restore the response from the cache store, e.g. one saved during a previous page load\n if (fetcherConfig.cacheStore) {\n const stored = await getStoredCache(_cacheKey, fetcherConfig);\n const restored =\n stored &&\n toResponse(\n stored.data,\n _cacheKey,\n fetcherConfig,\n );\n\n // A stale response is shown until the request below revalidates it\n if (\n restored &&\n restoreCache(\n _cacheKey,\n { ...stored, data: restored },\n fetcherConfig.cacheStore,\n )\n ) {\n return restored;\n }\n }\n\n // While there's no cached response, the initial data, e.g. data rendered on the server, is cached as the response\n if (\n fetcherConfig.initialData !== undefined &&\n !getCacheData(_cacheKey) &&\n !isCacheBypassed(fetcherConfig)\n ) {\n initialResponse = toResponse(\n {\n data: fetcherConfig.initialData,\n status: 200,\n statusText: '',\n headers: {},\n },\n _cacheKey,\n fetcherConfig,\n );\n }\n }\n\n // Deduplication logic\n if (_cacheKey && dedupeTime) {\n const inflight = getInFlightPromise<\n FetchResponse\n >(_cacheKey, dedupeTime);\n\n if (inflight) {\n return inflight;\n }\n }\n\n const retryConfig = fetcherConfig.retry || {};\n const { retries = 0, resetTimeout } = retryConfig;\n\n // The signal passed to the request. Each attempt replaces it in the config with a signal of its own.\n const userSignal = fetcherConfig.signal;\n\n // The actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation: boolean, attempt = 0) => {\n // The cached response to revalidate. It's read before the cache is marked as fetching below.\n const cached =\n isETagEnabled &&\n getCacheData(\n _cacheKey,\n );\n\n // If cache key is specified, we will handle optimistic updates\n // and mark the request as in-flight, so to catch \"fetching\" state.\n // This is useful for Optimistic UI updates (e.g., showing loading spinners).\n if (!attempt) {\n // The initial data is only used once, as the first response\n if (initialResponse) {\n const response = initialResponse;\n\n initialResponse = null;\n\n return response;\n }\n\n if (_cacheKey && !isStaleRevalidation) {\n if (staleTime) {\n const existingCache = getCachedResponse(\n _cacheKey,\n cacheTime,\n fetcherConfig,\n );\n\n // Don't notify subscribers when cache exists\n // Let them continue showing stale data during background revalidation\n if (!existingCache) {\n setCache(_cacheKey, inFlightResponse, cacheTime, staleTime);\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n } else {\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n }\n\n // Attach cache key so that it can be reused in interceptors or in the final response\n fetcherConfig.cacheKey = _cacheKey;\n }\n\n const url = fetcherConfig.url as string;\n\n // Add the request to the queue. Make sure to handle deduplication, cancellation, timeouts in accordance to retry settings\n const controller = markInFlight(\n _cacheKey,\n url,\n timeout,\n dedupeTime || 0,\n !!cancellable,\n // Enable timeout either by default or when retries & resetTimeout are enabled\n !!(timeout && (!attempt || resetTimeout)),\n );\n\n // Do not create a shallow copy to maintain idempotency here.\n // This ensures the original object is mutated by interceptors whenever needed, including retry logic.\n const requestConfig = fetcherConfig;\n\n requestConfig.signal = controller.signal;\n\n // The request is aborted along with the signal passed to it, which may have been aborted already\n const abort = () => controller.abort(userSignal!.reason);\n\n if (userSignal) {\n if (userSignal.aborted) {\n abort();\n } else {\n userSignal.addEventListener('abort', abort);\n }\n }\n\n let output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n let response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n try {\n if (fetcherConfig.onRequest) {\n // Zero-allocation yield to microtask queue so the outer fetchf() can call setInFlightPromise()\n // before onRequest interceptors run. This ensures that if onRequest triggers\n // another fetchf() with the same cacheKey, getInFlightPromise() finds item[4].\n // On retries (attempt > 0), setInFlightPromise() was already called during the first attempt.\n // The promise stored in item[4] is the outer doRequestPromise which covers all retries.\n // So the race only matters on the very first attempt when the outer scope hasn't had a chance to call setInFlightPromise() yet.\n if (_cacheKey && dedupeTime && !attempt) {\n await null;\n }\n\n await applyInterceptors(fetcherConfig.onRequest, requestConfig);\n }\n\n // Custom fetcher\n const fn = fetcherConfig.fetcher;\n const init = withETag(requestConfig, cached);\n\n response = (fn\n ? await fn(\n url,\n init,\n )\n : // Uploads with onUploadProgress are sent in a way that reports their progress\n await (requestConfig.onUploadProgress && requestConfig.body\n ? fetchWithUploadProgress(url, requestConfig)\n : fetch(url, init as RequestInit))) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Reports the download progress while the body is read\n response = withDownloadProgress(\n response,\n requestConfig.onDownloadProgress,\n );\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\n // The server answered that the cached response is still valid, so it's reused instead of being sent again.\n // Like other cached responses, it has been parsed and transformed already.\n if (init !== requestConfig && response.status === 304) {\n return cached as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n // Case 1: Native Response instance\n if (typeof Response === FUNCTION && response instanceof Response) {\n response.data = requestConfig.parser\n ? await requestConfig.parser(response)\n : await parseResponseData(response, requestConfig.responseType);\n } else if (fn) {\n // Case 2: Custom fetcher that returns a response object\n if (!('data' in response && 'body' in response)) {\n // Case 3: Raw data, wrap it\n response = { data: response } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n }\n\n // Attach config and data to the response\n // This is useful for custom fetchers that do not return a Response instance\n // and for interceptors that may need to access the request config\n response.config = requestConfig;\n\n // Check if the response status is not outside the range 200-299 and if so, output error\n // This is the pattern for fetch responses as per spec, but custom fetchers may not follow it so we check for `ok` property\n if (response.ok !== undefined && !response.ok) {\n throw new ResponseError(\n requestConfig.method +\n ' to ' +\n url +\n ' failed! Status: ' +\n (response.status || null),\n requestConfig,\n response,\n );\n }\n }\n\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig);\n\n const onResponse = fetcherConfig.onResponse;\n\n if (onResponse) {\n await applyInterceptors(onResponse, output);\n }\n } catch (_error) {\n const error = _error as ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Append additional information to Network, CORS or any other fetch() errors\n enhanceError(\n error,\n response,\n requestConfig,\n );\n\n // Prepare Extended Response\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig, error);\n } finally {\n if (userSignal) {\n userSignal.removeEventListener('abort', abort);\n }\n }\n\n return output;\n };\n\n // Inline and minimize function wrappers for performance\n // When retries are enabled, forward isStaleRevalidation so the first attempt\n // of a background SWR revalidation doesn't incorrectly mark the request as in-flight\n const baseRequest =\n retries > 0\n ? (isStaleRevalidation: boolean) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const { onLoadingSlow, loadingTimeout } = fetcherConfig;\n\n // Calls onLoadingSlow once a request, including its retries, is still pending after loadingTimeout.\n // Background revalidations don't show a loading state, so they are never considered slow.\n const request =\n onLoadingSlow && loadingTimeout\n ? async (isStaleRevalidation: boolean) => {\n if (isStaleRevalidation) {\n return baseRequest(isStaleRevalidation);\n }\n\n const timer = setTimeout(\n () => applyInterceptors(onLoadingSlow, fetcherConfig).catch(noop),\n loadingTimeout,\n );\n\n try {\n return await baseRequest(isStaleRevalidation);\n } finally {\n clearTimeout(timer);\n }\n }\n : baseRequest;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n request,\n fetcherConfig,\n );\n\n // Avoid unnecessary function wrapping if polling is not enabled\n const doRequestPromise = pollingInterval\n ? withPolling(\n requestWithErrorHandling,\n pollingInterval,\n fetcherConfig.shouldStopPolling,\n fetcherConfig.maxPollingAttempts,\n fetcherConfig.pollingDelay,\n fetcherConfig.refreshWhenHidden,\n fetcherConfig.refreshWhenOffline,\n userSignal,\n )\n : requestWithErrorHandling();\n\n // If deduplication is enabled, store the in-flight promise immediately\n if (_cacheKey) {\n if (dedupeTime) {\n setInFlightPromise(_cacheKey, doRequestPromise);\n }\n\n // Only register revalidator when revalidation features are actually requested\n if (staleTime || refetchOnFocus || refetchOnReconnect) {\n addRevalidator(\n _cacheKey,\n requestWithErrorHandling,\n undefined,\n staleTime,\n requestWithErrorHandling,\n !!refetchOnFocus,\n !!refetchOnReconnect,\n fetcherConfig.focusThrottleInterval,\n );\n }\n }\n\n return doRequestPromise;\n}\n\n/**\n * Recreates a response from its copy in a cache store.\n * The data was transformed before it was stored, so it isn't transformed again.\n *\n * @param stored - The stored copy of the response.\n * @param cacheKey - The cache key of the request.\n * @param config - The request configuration.\n * @returns The response, or null if the stored copy is invalid, e.g. has an unknown status.\n */\nfunction toResponse(\n stored: StoredResponse,\n cacheKey: string,\n config: RequestConfig,\n): FetchResponse | null {\n try {\n // Without the Fetch API (e.g. with a custom fetcher in tests), a plain response object is used\n const response = (typeof Response === FUNCTION\n ? new Response(null, stored)\n : {\n ok: true,\n status: stored.status,\n statusText: stored.statusText,\n headers: stored.headers,\n }) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n response.data = stored.data as typeof response.data;\n config.cacheKey = cacheKey;\n\n const output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, {\n ...config,\n select: undefined,\n flattenResponse: false,\n defaultResponse: undefined,\n });\n\n output.config = config;\n\n return output;\n } catch {\n return null;\n }\n}\n\n/**\n * Asks the server whether a cached response is still valid, by sending its ETag in the If-None-Match header.\n * Then the server can answer 304 Not Modified instead of sending the response again.\n * Requests with an If-None-Match header of their own are sent as they are.\n *\n * @param config - The request configuration.\n * @param cached - The cached response of the request, if any.\n * @returns A copy of the configuration with the If-None-Match header, or the configuration itself if the cached response has no ETag.\n */\nfunction withETag(\n config: RequestConfig,\n cached: FetchResponse | null | false,\n): RequestConfig {\n const etag = cached && !cached.error && cached.headers && cached.headers.etag;\n const headers = etag && processHeaders(config.headers as HeadersObject);\n\n return headers && !headers['if-none-match']\n ? { ...config, headers: { ...headers, 'if-none-match': etag } }\n : config;\n}\n","import type {\n ApiHandlerConfig,\n ApiHandlerDefaultMethods,\n ApiHandlerMethods,\n RequestConfigUrlRequired,\n} from './types/api-handler';\nimport { fetchf } from '.';\nimport { mergeConfigs } from './config-handler';\nimport { hasOwn } from './utils';\n\n/**\n * Creates an instance of API Handler.\n * It creates an API fetcher function using native fetch() or a custom fetcher if passed as \"fetcher\".\n * @see https://github.com/MattCCC/fetchff#configuration\n *\n * @param {Object} config - Configuration object for the API fetcher (see link above for full options).\n * @param {Object} config.endpoints - An object containing endpoint definitions.\n * @param {string} [config.baseURL] - The base URL for the API.\n * @param {Object} [config.headers] - Optional default headers to include in every request.\n * @param {Function} [config.onError] - Optional callback function for handling errors.\n * @returns API handler functions and endpoints to call\n *\n * @example\n * // Define endpoint paths\n * const endpoints = {\n * getUser: '/user',\n * createPost: '/post',\n * };\n *\n * // Create the API fetcher with configuration\n * const api = createApiFetcher({\n * endpoints,\n * apiUrl: 'https://example.com/api',\n * onError(error) {\n * console.log('Request failed', error);\n * },\n * headers: {\n * 'my-auth-key': 'example-auth-key-32rjjfa',\n * },\n * });\n *\n * // Fetch user data\n * const response = await api.getUser({ userId: 1, ratings: [1, 2] })\n */\nfunction createApiFetcher<\n EndpointTypes extends object,\n EndpointsSettings = never,\n>(config: ApiHandlerConfig) {\n const endpoints = config.endpoints;\n\n /**\n * Triggered when trying to use non-existent endpoints\n *\n * @param endpointName Endpoint Name\n * @returns {Promise}\n */\n async function handleNonImplemented(endpointName: string): Promise {\n console.error('Add ' + endpointName + \" to 'endpoints'.\");\n\n return null;\n }\n\n const apiHandler: ApiHandlerDefaultMethods = {\n config,\n endpoints,\n /**\n * Handle Single API Request\n * It considers settings in following order: per-request settings, global per-endpoint settings, global settings.\n *\n * @param endpointName - The name of the API endpoint to call.\n * @param requestConfig - Additional configuration for the request.\n * @returns A promise that resolves with the response from the API provider.\n */\n async request(endpointName, requestConfig = {}) {\n // Use global and per-endpoint settings\n // Only own properties are endpoints, not ones inherited like \"constructor\"\n const endpointConfig = hasOwn(endpoints, endpointName as string)\n ? endpoints[endpointName]\n : undefined;\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // URL parsers ignore leading control characters and spaces, drop tabs and newlines,\n // and treat backslashes like slashes, so check the URL the way it will be resolved\n const resolvedUrl = url\n .replace(/[\\t\\n\\r]/g, '')\n // eslint-disable-next-line no-control-regex -- matching control characters is the point\n .replace(/^[\\x00-\\x20]+/, '');\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (/^[/\\\\]{2}/.test(resolvedUrl)) {\n throw new Error('Protocol-relative URLs not allowed.');\n }\n\n // Prevent potential Server-Side Request Forgery attack and leakage of credentials when same instance is used for external requests\n // Any scheme counts here, as e.g. \"http:\\\\host\" or \"http:host\" can also point to another host\n const mergedConfig = /^[a-z][a-z\\d+\\-.]*:/i.test(resolvedUrl)\n ? // Merge endpoints configs for absolute URLs only if urls match\n endpointConfig && endpointConfig.url === url\n ? mergeConfigs(_endpointConfig, requestConfig)\n : requestConfig\n : mergeConfigs(mergeConfigs(config, _endpointConfig), requestConfig);\n\n // We prevent potential Server-Side Request Forgery attack and leakage of credentials as the same instance is not used for external requests\n // Retrigger fetch to ensure completely new instance of handler being triggered for external URLs\n return fetchf(url, mergedConfig);\n },\n };\n\n /**\n * Maps all API requests using native Proxy\n *\n * @param {*} prop Caller\n */\n return new Proxy>(\n apiHandler as ApiHandlerMethods,\n {\n get(_target, prop: string | symbol) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Symbols (e.g. inspection hooks) are never endpoints, and returning a function\n // for \"then\" would make the instance a thenable that never settles when awaited\n if (typeof prop === 'symbol' || prop === 'then') {\n return undefined;\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (hasOwn(endpoints, prop)) {\n return apiHandler.request.bind(null, prop);\n }\n\n return handleNonImplemented.bind(null, prop);\n },\n },\n );\n}\n\nexport { createApiFetcher };\n"]} \ No newline at end of file +{"version":3,"sources":["../../src/constants.ts","../../src/utils.ts","../../src/interceptor-manager.ts","../../src/errors/fetch-error.ts","../../src/errors/response-error.ts","../../src/timeout-wheel.ts","../../src/inflight-manager.ts","../../src/hash.ts","../../src/revalidator-manager.ts","../../src/pubsub-manager.ts","../../src/config-handler.ts","../../src/cache-manager.ts","../../src/response-parser.ts","../../src/retry-handler.ts","../../src/polling-handler.ts","../../src/upload-progress.ts","../../src/download-progress.ts","../../src/error-handler.ts","../../src/request-handler.ts","../../src/api-handler.ts"],"names":["APPLICATION_CONTENT_TYPE","APPLICATION_JSON","CHARSET_UTF_8","CONTENT_TYPE","UNDEFINED","OBJECT","STRING","FUNCTION","ABORT_ERROR","TIMEOUT_ERROR","GET","HEAD","REJECT","MAX_DELAY_MS","MAX_DEPTH","hasOwn","o","k","isSearchParams","data","isObject","value","sanitizeObject","obj","hasProto","hasCtor","hasPrototype","safeObj","key","sortObject","sortedObj","appendQueryStringToUrl","baseUrl","queryString","appendQueryParams","url","params","encodedQueryString","s","encode","add","v","buildParams","prefix","depth","i","len","replaceUrlPathParams","urlPathParams","match","colonKey","braceKey","encoded","isAbsoluteUrl","timeNow","noop","isJSONSerializable","delayInvocation","ms","signal","resolve","done","timer","flattenData","processHeaders","headers","headersObject","isBrowser","createAbortError","message","name","error","isSlowConnection","conn","isPageHidden","isOffline","applyInterceptors","interceptors","args","merge","interceptor","FetchError","request","response","ResponseError","WHEEL_SIZE","SECOND","wheel","keyMap","position","lastTick","handleCallback","callback","result","addTimeout","cb","removeTimeout","seconds","slot","slotOrTimeout","slotArr","inFlight","markInFlight","timeout","dedupeTime","isCancellable","isTimeoutEnabled","now","item","prevPromise","prevController","prevIsCancellable","controller","abortRequest","removeInFlight","setInFlightPromise","promise","getInFlightPromise","prevReq","hash","str","char","DEFAULT_TTL","revalidators","eventHandlers","customEventProviders","setEventProvider","type","provider","removeEventHandler","addEventHandler","revalidateAll","isStaleRevalidation","isThrottled","flagIndex","entry","revalidator","revalidate","removeRevalidators","removeRevalidator","event","handler","customProvider","cleanup","addRevalidator","revalidatorFn","ttl","staleTime","bgRevalidatorFn","refetchOnFocus","refetchOnReconnect","focusThrottleInterval","listeners","addListener","fn","set","removeListener","notifySubscribers","fns","subscribe","defaultTimeoutMs","defaultConfig","setDefaultConfig","customConfig","sanitized","mergeConfigs","getDefaultConfig","buildConfig","reqConfig","merged","buildFetcherConfig","requestConfig","method","body","setContentTypeIfNeeded","credentials","dynamicUrl","urlPath","baseURL","separator","contentTypeValue","INTERCEPTORS","baseConfig","overrideConfig","targetConfig","mergeConfig","property","mergeInterceptors","baseInterceptor","newInterceptor","base","override","isInstance","overrides","lowerKey","existingKey","_cache","stores","DELIMITER","MIN_LENGTH_TO_HASH","CACHE_KEY_SANITIZE_PATTERN","CACHE_KEY_NEEDS_SANITIZE","CACHE_KEY_HEADERS","generateCacheKey","config","cacheKeyCheck","headersString","keys","cacheStr","sanitizeCacheKey","bodyString","getObjectId","objectIds","lastObjectId","id","isCacheExpired","getCacheData","getCache","setCache","deleteCache","time","ttlMs","staleTimeMs","scheduleExpiry","removeExpired","store","callStore","persistCache","status","statusText","getStoredCache","isCacheBypassed","restoreCache","mutate","newData","settings","updatedData","updatedResponse","updatedEntry","buster","getCachedResponse","cacheKey","cacheTime","handleResponseCache","output","isError","skipCache","prevCacheKey","parseResponseData","responseType","contentType","mimeType","trimmed","prepareResponse","defaultResponse","mutatator","isNativeResponse","getMsFromHttpDate","dateString","getRetryAfterMs","extendedResponse","retryAfter","RATELIMIT_RESET","rateLimitResetAfter","rateLimitResetAt","withRetry","requestFn","retries","delay","backoff","maxDelay","retryOn","shouldRetry","jitter","methods","attempt","waitTime","maxRetries","cfg","onRetry","getShouldStopRetrying","retryDelay","withJitter","retryAfterMs","withPolling","pollingInterval","shouldStopPolling","maxAttempts","pollingDelay","refreshWhenHidden","refreshWhenOffline","pollingAttempt","NULL_BODY_STATUSES","FORBIDDEN_HEADERS","isStream","toProgress","loaded","total","fetchWithUploadProgress","sendWithXhr","sendStreamed","reject","xhr","abort","settle","line","index","onAbort","stream","blob","chunk","withDownloadProgress","onDownloadProgress","counted","withErrorHandling","isCancelled","logger","redactError","strategy","SENSITIVE_HEADERS","copy","enhanceError","inFlightResponse","fetchf","cached","fetcherConfig","cancellable","isCacheEnabled","isETagEnabled","needsCacheKey","_cacheKey","initialResponse","stored","restored","toResponse","inflight","retryConfig","resetTimeout","userSignal","doRequestOnce","init","withETag","onResponse","_error","baseRequest","_","onLoadingSlow","loadingTimeout","requestWithErrorHandling","doRequestPromise","etag","createApiFetcher","endpoints","handleNonImplemented","endpointName","apiHandler","endpointConfig","_endpointConfig","resolvedUrl","mergedConfig","_target","prop"],"mappings":"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","file":"index.js","sourcesContent":["export const APPLICATION_CONTENT_TYPE = 'application/';\n\nexport const APPLICATION_JSON = APPLICATION_CONTENT_TYPE + 'json';\nexport const CHARSET_UTF_8 = 'charset=utf-8';\nexport const CONTENT_TYPE = 'Content-Type';\n\nexport const UNDEFINED = 'undefined';\nexport const OBJECT = 'object';\nexport const STRING = 'string';\nexport const FUNCTION = 'function';\n\nexport const ABORT_ERROR = 'AbortError';\nexport const TIMEOUT_ERROR = 'TimeoutError';\n\nexport const GET = 'GET';\nexport const HEAD = 'HEAD';\n\nexport const REJECT = 'reject';\n\n// Larger timer delays overflow and fire immediately in browsers and Node.js (~24.8 days)\nexport const MAX_DELAY_MS = 2147483647;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { FUNCTION, MAX_DELAY_MS, OBJECT, STRING, UNDEFINED } from './constants';\nimport type {\n DefaultUrlParams,\n HeadersObject,\n QueryParams,\n UrlPathParams,\n} from './types';\n\n// Prevent stack overflow with recursion depth limit\nconst MAX_DEPTH = 10;\n\nexport const hasOwn = (o: any, k: string) =>\n Object.prototype.hasOwnProperty.call(o, k);\n\nexport function isSearchParams(data: unknown): boolean {\n return data instanceof URLSearchParams;\n}\n\n/**\n * Determines if a value is a non-null object.\n *\n * @param {any} value - The value to check.\n * @returns {boolean} - True if the value is a non-null object.\n */\nexport function isObject(value: any): value is Record {\n return value !== null && typeof value === OBJECT;\n}\n\n/**\n * Shallowly serializes an object by converting its key-value pairs into a string representation.\n * This function does not recursively serialize nested objects.\n *\n * @param obj - The object to serialize.\n * @returns A string representation of the object's top-level properties.\n */\nexport function shallowSerialize(obj: Record): string {\n let result = '';\n\n for (const key in obj) {\n if (hasOwn(obj, key)) {\n result += key + ':' + obj[key];\n }\n }\n\n return result;\n}\n\n/**\n * Removes properties that could lead to prototype pollution from an object.\n *\n * This function checks for dangerous properties like '__proto__', 'constructor',\n * and 'prototype'. If none are present, the object is returned as-is (zero-copy fast path).\n * Otherwise, a shallow copy is created with the dangerous properties removed.\n *\n * @param obj - The object to sanitize\n * @returns A safe object without dangerous properties\n */\nexport function sanitizeObject>(obj: T): T {\n const hasProto = hasOwn(obj, '__proto__');\n const hasCtor = hasOwn(obj, 'constructor');\n const hasPrototype = hasOwn(obj, 'prototype');\n\n if (!hasProto && !hasCtor && !hasPrototype) {\n return obj;\n }\n\n // Copy key by key, as a spread compiled to assignments would let \"__proto__\" set the prototype\n const safeObj = {} as Record;\n\n for (const key of Object.keys(obj)) {\n if (key !== '__proto__' && key !== 'constructor' && key !== 'prototype') {\n safeObj[key] = obj[key];\n }\n }\n\n return safeObj as T;\n}\n\n/**\n * Sorts the keys of an object and returns a new object with sorted keys.\n *\n * This function is optimized for performance by minimizing the number of object operations\n * and using a single pass to create the sorted object.\n *\n * @param {Object} obj - The object to be sorted by keys.\n * @returns {Object} - A new object with keys sorted in ascending order.\n */\nexport function sortObject(obj: Record): object {\n // Without a prototype, a \"__proto__\" key is kept as a regular property instead of setting the prototype\n const sortedObj = Object.create(null) as Record;\n\n Object.keys(obj)\n .sort()\n .forEach((k) => (sortedObj[k] = obj[k]));\n\n return sortedObj;\n}\n\n/**\n * Appends a query string to a URL, ensuring proper handling of existing query parameters.\n *\n * @param baseUrl - The base URL to which the query string will be appended.\n * @param queryString - The encoded query string to append.\n * @returns The URL with the appended query string, or the original URL if no query string is provided.\n */\nfunction appendQueryStringToUrl(baseUrl: string, queryString: string): string {\n if (!queryString) {\n return baseUrl;\n }\n\n return baseUrl + (baseUrl.includes('?') ? '&' : '?') + queryString;\n}\n\n/**\n * Appends query parameters to a given URL.\n *\n * @param {string} url - The base URL to which query parameters will be appended.\n * @param {QueryParams} params - An object containing the query parameters to append.\n * @returns {string} - The URL with the appended query parameters.\n */\nexport function appendQueryParams(url: string, params: QueryParams): string {\n if (!params) {\n return url;\n }\n\n // Check if `params` is an instance of URLSearchParams and bail early if it is\n if (isSearchParams(params)) {\n const encodedQueryString = params.toString();\n\n return appendQueryStringToUrl(url, encodedQueryString);\n }\n\n // This is exact copy of what JQ used to do. It works much better than URLSearchParams\n const s: string[] = [];\n const encode = encodeURIComponent;\n const add = (k: string, v: any) => {\n v = typeof v === FUNCTION ? v() : v;\n v = v === null || v === undefined ? '' : v;\n s[s.length] = encode(k) + '=' + encode(v);\n };\n\n const buildParams = (prefix: string, obj: any, depth = 0) => {\n // Stop recursion if maximum depth is reached\n if (depth >= MAX_DEPTH) {\n return s;\n }\n\n let i: number, len: number, key: string;\n\n if (prefix) {\n if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n buildParams(\n prefix + '[' + (typeof obj[i] === OBJECT && obj[i] ? i : '') + ']',\n obj[i],\n depth + 1,\n );\n }\n } else if (isObject(obj)) {\n for (key in obj) {\n buildParams(prefix + '[' + key + ']', obj[key], depth + 1);\n }\n } else {\n add(prefix, obj);\n }\n } else if (Array.isArray(obj)) {\n for (i = 0, len = obj.length; i < len; i++) {\n add(obj[i].name, obj[i].value);\n }\n } else {\n for (key in obj) {\n buildParams(key, obj[key], depth + 1);\n }\n }\n return s;\n };\n\n const queryStringParts = buildParams('', params).join('&');\n\n // Encode special characters as per RFC 3986, https://datatracker.ietf.org/doc/html/rfc3986\n // This is for compatibility with server frameworks that expect the literal notation\n const encodedQueryString = queryStringParts.replace(/%5B%5D/g, '[]'); // Keep '[]' for arrays\n\n return appendQueryStringToUrl(url, encodedQueryString);\n}\n\n/**\n * Replaces dynamic URI parameters in a URL string with values from the provided `urlPathParams` object.\n * Parameters in the URL are denoted by `:` or `{}` (like in OpenAPI paths), where `` is a key in `urlPathParams`.\n *\n * @param {string} url - The URL string containing placeholders in the format `:` or `{}`.\n * @param {Object} urlPathParams - An object containing the parameter values to replace placeholders.\n * @param {string} urlPathParams.paramName - The value to replace the placeholder `:` in the URL.\n * @returns {string} - The URL string with placeholders replaced by corresponding values from `urlPathParams`.\n */\nexport function replaceUrlPathParams(\n url: string,\n urlPathParams: UrlPathParams,\n): string {\n if (!urlPathParams || (url.indexOf(':') === -1 && url.indexOf('{') === -1)) {\n return url;\n }\n\n // Use a single RegExp and avoid unnecessary casts and function calls\n // Precompute keys for faster lookup\n const params = urlPathParams as DefaultUrlParams;\n\n // Use a replacer function that avoids extra work\n return url.replace(/:(\\w+)|\\{(\\w+)\\}/g, (match, colonKey, braceKey) => {\n const key = colonKey || braceKey;\n\n // Use hasOwnProperty for strict key existence check\n if (hasOwn(params, key)) {\n const value = params[key];\n\n // Only replace if value is not undefined or null\n if (value !== undefined && value !== null) {\n const encoded = encodeURIComponent(String(value));\n\n // These can't be encoded, and URL parsers would move the request to another path\n if (encoded === '.' || encoded === '..') {\n throw new Error('Path params \".\" and \"..\" not allowed.');\n }\n\n return encoded;\n }\n }\n\n return match;\n });\n}\n\n/**\n * Determines whether the provided URL is absolute.\n *\n * An absolute URL starts with a scheme (e.g., \"http://\", \"https://\").\n * A \"://\" appearing later, e.g. in a query string, does not make the URL absolute.\n *\n * @param url - The URL string to check.\n * @returns `true` if the URL is absolute, otherwise `false`.\n */\nexport function isAbsoluteUrl(url: string): boolean {\n return /^[a-z][a-z\\d+\\-.]*:\\/\\//i.test(url);\n}\n\nexport const timeNow = () => Date.now();\n\nexport const noop = () => {};\n\n/**\n * Checks if a value is JSON serializable.\n *\n * JSON serializable values include:\n * - Primitive types: string, number, boolean, null\n * - Arrays\n * - Plain objects (i.e., objects without special methods)\n * - Values with a `toJSON` method\n *\n * @param {any} value - The value to check for JSON serializability.\n * @returns {boolean} - Returns `true` if the value is JSON serializable, otherwise `false`.\n */\nexport function isJSONSerializable(value: any): boolean {\n const t = typeof value;\n\n if (value === undefined || value === null) {\n return false;\n }\n\n if (t === STRING || t === 'number' || t === 'boolean') {\n return true;\n }\n\n if (Array.isArray(value)) {\n return true;\n }\n\n if (\n typeof globalThis !== UNDEFINED &&\n typeof globalThis.Buffer !== UNDEFINED &&\n globalThis.Buffer.isBuffer(value)\n ) {\n return false;\n }\n\n if (value instanceof Date || isSearchParams(value)) {\n return false;\n }\n\n if (isObject(value)) {\n const proto = Object.getPrototypeOf(value);\n\n // Check if the prototype is `Object.prototype` (plain object)\n if (proto === Object.prototype) {\n return true;\n }\n\n // Check if the object has a toJSON method\n if (typeof value.toJSON === FUNCTION) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Waits for the given time. When a signal is passed, the wait ends early once it is aborted.\n *\n * @param {number} ms - The time to wait in milliseconds.\n * @param {AbortSignal} [signal] - An optional signal that ends the wait when aborted.\n * @returns {Promise} - A promise that resolves with `true` once the wait is over.\n */\nexport const delayInvocation = (\n ms: number,\n signal?: AbortSignal,\n): Promise =>\n new Promise((resolve) => {\n const done = () => {\n clearTimeout(timer);\n if (signal) {\n signal.removeEventListener('abort', done);\n }\n resolve(true);\n };\n const timer = setTimeout(done, Math.min(ms, MAX_DELAY_MS));\n\n if (signal) {\n if (signal.aborted) {\n done();\n } else {\n signal.addEventListener('abort', done);\n }\n }\n });\n\n/**\n * Recursively flattens the data object if it meets specific criteria.\n *\n * The method checks if the provided `data` is an object with exactly one property named `data`.\n * If so, it recursively flattens the `data` property. Otherwise, it returns the `data` as-is.\n *\n * @param {any} data - The data to be flattened. Can be of any type, including objects, arrays, or primitives.\n * @returns {any} - The flattened data if the criteria are met; otherwise, the original `data`.\n */\nexport function flattenData(data: any, depth = 0): any {\n if (depth >= MAX_DEPTH) {\n return data;\n }\n\n if (data && isObject(data) && typeof data.data !== UNDEFINED) {\n return flattenData(data.data, depth + 1);\n }\n\n return data;\n}\n\n/**\n * Processes headers and returns them as a normalized object.\n *\n * Handles both `Headers` instances and plain objects. Normalizes header keys to lowercase\n * as per RFC 2616 section 4.2.\n *\n * @param headers - The headers to process. Can be an instance of `Headers`, a plain object,\n * or `null`. If `null`, an empty object is returned.\n * @returns {HeadersObject} - A normalized headers object with lowercase keys.\n */\nexport function processHeaders(\n headers?: (HeadersObject & HeadersInit) | null | Headers,\n): HeadersObject {\n if (!headers) {\n return {};\n }\n\n const headersObject: HeadersObject = {};\n\n // Normalize keys to lowercase as per RFC 2616 4.2\n // https://datatracker.ietf.org/doc/html/rfc2616#section-4.2\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n headersObject[key.toLowerCase()] = value;\n });\n } else {\n // Handle plain object — use for...in to avoid Object.entries() allocation\n for (const key in headers) {\n // Assigning \"__proto__\" would set the prototype of the result\n if (hasOwn(headers, key) && key !== '__proto__') {\n headersObject[key.toLowerCase()] = headers[key];\n }\n }\n }\n\n return headersObject;\n}\n\n/**\n * Determines if the current environment is a browser.\n *\n * @returns {boolean} - True if running in a browser environment, false otherwise.\n */\nexport function isBrowser(): boolean {\n // For node and some mobile frameworks like React Native, `add/removeEventListener` doesn't exist on window!\n return (\n typeof window !== UNDEFINED && typeof window.addEventListener === FUNCTION\n );\n}\n\n/**\n * Creates an abort/timeout error compatible with all JS runtimes.\n * Falls back to a plain Error with the correct `name` when DOMException is unavailable (e.g. React Native).\n *\n * @param {string} message - The error message.\n * @param {string} name - The error name (e.g. 'AbortError', 'TimeoutError').\n * @returns {DOMException | Error} - An error object with the specified name.\n */\nexport function createAbortError(\n message: string,\n name: string,\n): DOMException | Error {\n if (typeof DOMException !== UNDEFINED) {\n return new DOMException(message, name);\n }\n\n const error = new Error(message);\n error.name = name;\n\n return error;\n}\n\n/**\n * Detects if the user is on a slow network connection\n * @returns {boolean} True if connection is slow, false otherwise or if detection unavailable\n */\nexport const isSlowConnection = (): boolean => {\n const conn = typeof navigator !== UNDEFINED && (navigator as any).connection;\n\n return conn && ['slow-2g', '2g', '3g'].includes(conn.effectiveType);\n};\n\n/**\n * Detects if the page is hidden, e.g. when its tab is in the background or the window is minimized\n * @returns {boolean} True if the page is hidden, false otherwise or outside browsers\n */\nexport const isPageHidden = (): boolean =>\n typeof document !== UNDEFINED && document.visibilityState === 'hidden';\n\n/**\n * Detects if the browser is offline\n * @returns {boolean} True if the browser is offline, false otherwise or if the connection state is unknown\n */\nexport const isOffline = (): boolean =>\n typeof navigator !== UNDEFINED && navigator.onLine === false;\n","import { FUNCTION } from './constants';\nimport type { InterceptorFunction } from './types/interceptor-manager';\nimport { isObject, sanitizeObject } from './utils';\n\n/**\n * Applies interceptors to the object. Interceptors can be a single function or an array of functions.\n *\n * @template T - Type of the object.\n * @template Args - Type of additional arguments.\n * @template I - Type of interceptors.\n *\n * @param {InterceptorFunction | InterceptorFunction[]} [interceptors] - Interceptor function(s).\n * @param {T} data - The data object to process.\n * @param {...Args} args - Additional arguments to pass to interceptors.\n *\n * @returns {Promise} - Nothing as the function is non-idempotent.\n */\nexport async function applyInterceptors<\n T extends object,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Args extends any[] = any[],\n I = InterceptorFunction | InterceptorFunction[],\n>(interceptors: I | undefined, data: T, ...args: Args): Promise {\n if (!interceptors) {\n return;\n }\n\n const merge = (v: unknown) =>\n v &&\n isObject(data) &&\n isObject(v) &&\n Object.assign(data, sanitizeObject(v));\n\n if (typeof interceptors === FUNCTION) {\n merge(await (interceptors as InterceptorFunction)(data, ...args));\n } else if (Array.isArray(interceptors)) {\n for (const interceptor of interceptors) {\n merge(await interceptor(data, ...args));\n }\n }\n}\n","import type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\n/**\n * This is a base error class\n */\nexport class FetchError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends Error {\n // Declared only, and set in the constructor, as class fields would need a helper in the ES2018 bundle\n declare status: number;\n declare statusText: string;\n declare config: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare isCancelled: boolean;\n declare request: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >;\n declare response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null;\n\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message);\n\n this.request = request;\n this.response = response;\n this.status = response ? response.status : 0;\n this.statusText = response ? response.statusText : '';\n this.config = request;\n this.isCancelled = false;\n this.name = 'FetchError';\n }\n}\n","import { FetchError } from './fetch-error';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultResponse,\n DefaultUrlParams,\n FetchResponse,\n RequestConfig,\n} from '../types';\n\nexport class ResponseError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n> extends FetchError {\n constructor(\n message: string,\n request: RequestConfig,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n ) {\n super(message, request, response);\n\n this.name = 'ResponseError';\n }\n}\n","/**\n * @module timeout-wheel\n * @description\n * Ultra-minimal timing wheel implementation optimized for max performance & many requests.\n * For most of the cases it's 4-100x faster than setTimeout and setInterval alone.\n * Provides efficient scheduling and cancellation of timeouts using a circular array.\n *\n * Position 0 → 1 → 2 → ... → 599 → 0 → 1 → 2 ...\n * Time: 0s 1s 2s 599s 600s 601s 602s\n *\n * The timing wheel consists of 600 slots (one per second for 10 min).\n * Each slot contains a list of timeout items, each associated with a unique key and callback.\n * Timeouts are scheduled by placing them in the appropriate slot based on the delay in seconds.\n * The wheel advances every second, executing and removing callbacks as their timeouts expire.\n * Defaults to setTimeout if the delay doesn't fit in the wheel (~10 minutes) or is not divisible by 1000.\n *\n * @remarks\n * - Designed for minimal footprint and simplicity.\n * - Only supports second-level granularity (minimum timeout: 1 second).\n * - Timeouts never fire early, but may fire up to 1 second late.\n * - Automatically stops the internal timer when no timeouts remain.\n */\n\nimport { MAX_DELAY_MS } from './constants';\nimport { noop, timeNow } from './utils';\n\ntype TimeoutCallback = () => unknown | Promise;\ntype TimeoutItem = [string, TimeoutCallback]; // [key, callback]\n\nconst WHEEL_SIZE = 600; // 600 slots for 10 min (1 slot per second)\nconst SECOND = 1000; // 1 second in milliseconds\nconst wheel: TimeoutItem[][] = Array(WHEEL_SIZE)\n .fill(0)\n .map(() => []);\n\nconst keyMap = new Map();\nlet position = 0;\nlet lastTick = 0; // Time when the wheel last advanced (or started)\nlet timer: NodeJS.Timeout | null = null;\n\nconst handleCallback = ([key, callback]: TimeoutItem): void => {\n keyMap.delete(key);\n\n try {\n const result = callback();\n if (result && result instanceof Promise) {\n // Silently ignore async errors to prevent wheel from stopping\n result.catch(noop);\n }\n } catch {\n // Ignore callback errors to prevent wheel from stopping\n }\n};\n\nexport const addTimeout = (\n key: string,\n cb: TimeoutCallback,\n ms: number,\n): void => {\n removeTimeout(key);\n\n // A running wheel is already part-way through its current second, so the timeout\n // waits one more slot to never fire early. A new wheel starts its first second now.\n const seconds = ms / SECOND + (timer && timeNow() !== lastTick ? 1 : 0);\n\n // Fallback to setTimeout if wheel size is exceeded, ms is sub-second, or ms is not divisible by SECOND\n if (ms < SECOND || seconds >= WHEEL_SIZE || ms % SECOND !== 0) {\n keyMap.set(key, [\n setTimeout(\n handleCallback.bind(null, [key, cb]),\n Math.min(ms, MAX_DELAY_MS),\n ),\n ]); // Store timeout ID instead of slot\n\n return;\n }\n\n const slot = (position + seconds) % WHEEL_SIZE;\n\n wheel[slot].push([key, cb]);\n keyMap.set(key, slot);\n\n if (!timer) {\n lastTick = timeNow();\n timer = setInterval(() => {\n position = (position + 1) % WHEEL_SIZE;\n lastTick = timeNow();\n const slot = wheel[position];\n\n // Use slot.length directly (not cached) so mid-iteration mutations\n // from callbacks (e.g. removeTimeout) are handled correctly\n for (let i = 0; i < slot.length; i++) {\n handleCallback(slot[i]);\n }\n\n slot.length = 0; // Reuse array, avoid GC allocation\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }, SECOND);\n }\n};\n\nexport const removeTimeout = (key: string): void => {\n const slotOrTimeout = keyMap.get(key);\n\n if (slotOrTimeout !== undefined) {\n // It's a Timeout object from setTimeout\n if (Array.isArray(slotOrTimeout)) {\n clearTimeout(slotOrTimeout[0]);\n } else {\n const slotArr = wheel[slotOrTimeout];\n\n for (let i = 0; i < slotArr.length; i++) {\n if (slotArr[i][0] === key) {\n slotArr.splice(i, 1);\n break;\n }\n }\n }\n\n keyMap.delete(key);\n\n if (!keyMap.size && timer) {\n clearInterval(timer);\n timer = null;\n }\n }\n};\n\nexport const clearAllTimeouts = () => {\n // Clear native setTimeout timeouts first!\n keyMap.forEach((value) => {\n if (Array.isArray(value)) {\n clearTimeout(value[0]);\n }\n });\n\n if (timer) {\n clearInterval(timer);\n timer = null;\n }\n\n keyMap.clear();\n\n for (let i = 0; i < WHEEL_SIZE; i++) {\n wheel[i].length = 0;\n }\n\n position = 0;\n};\n","/**\n * @module inflight-manager\n *\n * Manages in-flight asynchronous requests using unique keys to enable deduplication and cancellation.\n *\n * Provides utilities for:\n * - Deduplication of requests within a configurable time window (`dedupeTime`)\n * - Timeout management and automatic request abortion\n * - AbortController lifecycle and cancellation logic\n * - Concurrency control and request state tracking\n * - In-flight promise deduplication to prevent duplicate network calls\n *\n * @remarks\n * - Requests with the same key within the deduplication interval share the same AbortController and in-flight promise.\n * - Supports cancellation of previous requests when a new one with the same key is issued, if `isCancellable` is enabled.\n * - Timeout logic ensures requests are aborted after a specified duration, if enabled.\n * - Internal queue state is managed via a Map, keyed by request identifier.\n * - Polled requests are also marked as \"in-flight\" to prevent duplicate requests.\n */\n\nimport { ABORT_ERROR, TIMEOUT_ERROR } from './constants';\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { createAbortError, timeNow } from './utils';\n\nexport type InFlightItem = [\n AbortController, // AbortController for the request\n boolean, // Whether timeout is enabled for the request\n number, // Timestamp when the request was marked in-flight\n boolean, // isCancellable - whether the request can be cancelled\n Promise | null, // Optional in-flight promise for deduplication\n];\n\nconst inFlight: Map = new Map();\n\n/**\n * Adds a request to the queue if it's not already being processed within the dedupeTime interval.\n *\n * @param {string | null} key - Unique key for the request (e.g. cache key).\n * @param {string} url - The request URL (for error messages/timeouts).\n * @param {number} timeout - Timeout in milliseconds for the request.\n * @param {number} dedupeTime - Deduplication time in milliseconds.\n * @param {boolean} isCancellable - If true, then the previous request with same configuration should be aborted.\n * @param {boolean} isTimeoutEnabled - Whether timeout is enabled.\n * @returns {AbortController} - A promise that resolves to an AbortController.\n */\nexport function markInFlight(\n key: string | null,\n url: string,\n timeout: number | undefined,\n dedupeTime: number,\n isCancellable: boolean,\n isTimeoutEnabled: boolean,\n): AbortController {\n if (!key) {\n return new AbortController();\n }\n\n const now = timeNow();\n const item = inFlight.get(key);\n let prevPromise: Promise | null = null;\n\n // Previous request is in-flight, check if we can reuse it\n if (item) {\n const prevController = item[0];\n const prevIsCancellable = item[3];\n\n // If the request is already in the queue and within the dedupeTime, reuse the existing controller\n if (\n !prevIsCancellable &&\n now - item[2] < dedupeTime &&\n !prevController.signal.aborted\n ) {\n return prevController;\n }\n\n // If the request is too old, remove it and proceed to add a new one\n // Abort previous request, if applicable, and continue as usual\n if (prevIsCancellable) {\n prevController.abort(\n createAbortError('Aborted due to new request', ABORT_ERROR),\n );\n }\n\n removeTimeout(key);\n prevPromise = item[4];\n }\n\n const controller = new AbortController();\n\n inFlight.set(key, [\n controller,\n isTimeoutEnabled,\n now,\n isCancellable,\n prevPromise,\n ]);\n\n if (isTimeoutEnabled) {\n addTimeout(\n key,\n () => {\n abortRequest(\n key,\n createAbortError(url + ' aborted due to timeout', TIMEOUT_ERROR),\n );\n },\n timeout as number,\n );\n }\n\n return controller;\n}\n\n/**\n * Removes a request from the queue and clears its timeout.\n *\n * @param key - Unique key for the request.\n * @param {boolean} error - Optional error to abort the request with. If null, the request is simply removed but no abort sent.\n * @returns {Promise} - A promise that resolves when the request is aborted and removed.\n */\nexport async function abortRequest(\n key: string | null,\n error: DOMException | Error | null | string = null,\n): Promise {\n // If the key is not in the queue, there's nothing to remove\n if (key) {\n const item = inFlight.get(key);\n\n if (item) {\n // If the request is not yet aborted, abort it with the provided error\n if (error) {\n const controller = item[0];\n controller.abort(error);\n }\n\n removeInFlight(key);\n }\n }\n}\n\n/**\n * Removes a request from the in-flight queue without aborting or clearing timeout.\n *\n * @param key - Unique key for the request.\n */\nexport function removeInFlight(key: string | null): void {\n removeTimeout(key!);\n inFlight.delete(key!);\n}\n\n/**\n * Gets the AbortController for a request key.\n *\n * @param key - Unique key for the request.\n * @returns {AbortController | undefined} - The AbortController or undefined.\n */\nexport async function getController(\n key: string,\n): Promise {\n const item = inFlight.get(key);\n\n return item && item[0];\n}\n\n/**\n * Adds helpers for in-flight promise deduplication.\n *\n * @param key - Unique key for the request.\n * @param promise - The promise to store.\n */\nexport function setInFlightPromise(\n key: string,\n promise: Promise,\n): void {\n const item = inFlight.get(key);\n if (item) {\n // store the promise at index 4 — item is already the Map's reference, no need to re-set\n item[4] = promise;\n }\n}\n\n/**\n * Retrieves the in-flight promise for a request key if it exists and is within the dedupeTime interval.\n *\n * @param key - Unique key for the request.\n * @param dedupeTime - Deduplication time in milliseconds.\n * @returns {Promise | null} - The in-flight promise or null.\n */\nexport function getInFlightPromise(\n key: string | null,\n dedupeTime: number,\n): Promise | null {\n if (!key) {\n return null;\n }\n\n const prevReq = inFlight.get(key);\n\n if (\n prevReq &&\n // If the request is in-flight and has a promise\n prevReq[4] &&\n // If the request is cancellable, we will not reuse it\n !prevReq[3] &&\n // If the request is within the dedupeTime\n timeNow() - prevReq[2] < dedupeTime &&\n // If one request is cancelled, ALL deduped requests get cancelled\n !prevReq[0].signal.aborted\n ) {\n return prevReq[4] as Promise;\n }\n\n return null;\n}\n","const PRIME_MULTIPLIER = 31;\n\n/**\n * Computes a hash value for a given string using the variant of djb2 hash function.\n * This hash function is non-cryptographic and designed for speed.\n * @author Daniel J. Bernstein (of djb2)\n *\n * @param str Input string to hash\n * @returns {string} Hash\n */\nexport function hash(str: string): string {\n let hash = 0;\n\n for (let i = 0, len = str.length; i < len; i++) {\n const char = str.charCodeAt(i);\n hash = (hash * PRIME_MULTIPLIER + char) | 0;\n }\n\n return String(hash);\n}\n","/**\n * @module revalidator-manager\n *\n * Provides utilities for managing cache revalidation functions, including:\n * - Registering and unregistering revalidators for specific cache keys.\n * - Triggering revalidation for a given key.\n * - Enabling or disabling automatic revalidation on window focus and if user comes back online for specific keys.\n * - Attaching and removing global focus and online event handlers to trigger revalidation.\n *\n * Revalidators are functions that can be registered to revalidate cache entries when needed.\n * They are typically used to refresh data in the cache when the window gains focus or when specific actions occur.\n * @performance O(1) lookup by key makes it blazing fast to register, unregister, and revalidate cache entries.\n * - Designed for high performance: minimizes unnecessary re-renders and leverages fast cache key generation.\n * - Integrates with a global cache and pub/sub system for efficient state updates across contexts.\n * - Handles automatic revalidation, deduplication, retries, and cache management out of the box.\n * @remarks\n * - Designed to be used in various environments (Deno, Node.js, Bun, Browser, etc.) to ensure cache consistency and freshness.\n */\nimport { addTimeout, removeTimeout } from './timeout-wheel';\nimport { FetchResponse } from './types';\nimport { isBrowser, noop, timeNow } from './utils';\n\nexport type RevalidatorFn = (\n isStaleRevalidation?: boolean,\n) => Promise;\n\ntype EventType = 'focus' | 'online';\n\ntype RevalidatorEntry = [\n RevalidatorFn, // main revalidator\n number, // lastUsed\n number, // ttl\n number?, // staleTime\n RevalidatorFn?, // bgRevalidator\n boolean?, // refetchOnFocus\n boolean?, // refetchOnReconnect\n number?, // focusThrottleInterval\n];\n\nconst DEFAULT_TTL = 3 * 60 * 1000; // Default TTL of 3 minutes\nconst revalidators = new Map();\n\n/**\n * Stores cleanup functions for active event handlers (browser or custom providers).\n * Each entry removes the corresponding event listener when called.\n * @remarks\n * - Improves performance by reducing the number of event listeners.\n * - Enables efficient O(1) lookup and management of event handlers for revalidation.\n */\nconst eventHandlers = new Map void>();\n\n/** Subscribe to an event and return a cleanup function */\nexport type EventProvider = (handler: () => void) => () => void;\n\nconst customEventProviders = new Map();\n\n/**\n * Registers a custom event provider for 'focus' or 'online' events.\n * Useful for non-browser environments like React Native.\n *\n * @param type - The event type ('focus' or 'online').\n * @param provider - A function that subscribes to the event and returns a cleanup function.\n */\nexport function setEventProvider(\n type: EventType,\n provider: EventProvider,\n): void {\n customEventProviders.set(type, provider);\n\n // Re-register if already active\n if (eventHandlers.has(type)) {\n removeEventHandler(type);\n addEventHandler(type);\n }\n}\n\n/**\n * Triggers revalidation for all registered entries based on the given event type.\n * For example, if it's a 'focus' event, it will revalidate entries that have the `refetchOnFocus` flag set.\n * Updates the timestamp and invokes the revalidator function for each applicable entry.\n *\n * @param type - The type of event that caused the revalidation (e.g., 'focus' or 'online').\n * @param isStaleRevalidation - If `true`, uses background revalidator and doesn't mark as in-flight.\n * @param isThrottled - If `true`, skips entries that were requested or revalidated within their `focusThrottleInterval`.\n */\nexport function revalidateAll(\n type: EventType,\n isStaleRevalidation: boolean = true,\n isThrottled: boolean = false,\n) {\n const flagIndex = type === 'focus' ? 5 : 6;\n const now = timeNow();\n\n revalidators.forEach((entry) => {\n if (!entry[flagIndex] || (isThrottled && now - entry[1] < entry[7]!)) {\n return;\n }\n\n entry[1] = now;\n\n // If it's a stale revalidation, use the background revalidator function\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n if (revalidator) {\n Promise.resolve(revalidator(isStaleRevalidation)).catch(noop);\n }\n });\n}\n\n/**\n * Revalidates an entry by executing the registered revalidation function.\n *\n * @param key The unique identifier for the cache entry to revalidate. If `null`, no revalidation occurs.\n * @param isStaleRevalidation - If `true`, it does not mark revalidated requests as in-flight.\n * @returns A promise that resolves to the result of the revalidator function, or\n * `null` if no key or revalidator is found, or a `FetchResponse` if applicable.\n */\nexport async function revalidate(\n key: string | null,\n isStaleRevalidation: boolean = false,\n): Promise {\n // If no key is provided, no revalidation occurs\n if (!key) {\n return null;\n }\n\n const entry = revalidators.get(key);\n\n if (entry) {\n // Update only the lastUsed timestamp without resetting the whole array\n entry[1] = timeNow();\n\n const revalidator = isStaleRevalidation ? entry[4] : entry[0];\n\n // If no revalidator function is registered, return null\n if (revalidator) {\n return await revalidator(isStaleRevalidation);\n }\n }\n\n // If no revalidator is registered for the key, return null\n return null;\n}\n\n/**\n * Removes all revalidators associated with the specified event type.\n *\n * @param type - The event type whose revalidators should be removed.\n */\nexport function removeRevalidators(type: EventType) {\n removeEventHandler(type);\n\n const flagIndex = type === 'focus' ? 5 : 6;\n\n // Clear all revalidators with this flag\n revalidators.forEach((entry, key) => {\n if (entry[flagIndex]) {\n removeRevalidator(key);\n }\n });\n}\n\n/**\n * Registers a generic revalidation event handler for the specified event type.\n * Supports browser window events and custom event providers (e.g. for React Native).\n * Ensures the handler is only added once.\n *\n * @param event - The type of event to listen for (e.g., 'focus', 'online').\n */\nfunction addEventHandler(event: EventType) {\n if (eventHandlers.has(event)) {\n return;\n }\n\n // Focus events are throttled, so that e.g. switching between tabs quickly doesn't revalidate every time\n const handler = revalidateAll.bind(null, event, true, event === 'focus');\n\n // Priority 1: Custom event provider (works in any environment including React Native)\n const customProvider = customEventProviders.get(event);\n\n if (customProvider) {\n const cleanup = customProvider(handler);\n\n eventHandlers.set(event, cleanup);\n\n return;\n }\n\n // Priority 2: Browser window events\n if (isBrowser()) {\n window.addEventListener(event, handler);\n\n eventHandlers.set(event, () => window.removeEventListener(event, handler));\n }\n}\n\n/**\n * Removes the event handler for the specified event type.\n *\n * @param event - The type of event whose handler should be removed.\n */\nfunction removeEventHandler(event: EventType) {\n const cleanup = eventHandlers.get(event);\n\n if (cleanup) {\n cleanup();\n eventHandlers.delete(event);\n }\n}\n\n/**\n * Registers a revalidation functions for a specific cache key.\n *\n * @param {string} key Cache key to utilize\n * @param {RevalidatorFn} revalidatorFn Main revalidation function (marks in-flight requests)\n * @param {number} [ttl] Time to live in milliseconds (default: 3 minutes)\n * @param {number} [staleTime] Time (in seconds) after which the cache entry is considered stale\n * @param {RevalidatorFn} [bgRevalidatorFn] For stale revalidation (does not mark in-flight requests)\n * @param {boolean} [refetchOnFocus] Whether to revalidate on window focus\n * @param {boolean} [refetchOnReconnect] Whether to revalidate on network reconnect\n * @param {number} [focusThrottleInterval] Time (in milliseconds) after a request or revalidation during which focus events don't revalidate it\n */\nexport function addRevalidator(\n key: string,\n revalidatorFn: RevalidatorFn, // Main revalidation function (marks in-flight requests)\n ttl?: number,\n staleTime?: number,\n bgRevalidatorFn?: RevalidatorFn, // For stale revalidation (does not mark in-flight requests)\n refetchOnFocus?: boolean,\n refetchOnReconnect?: boolean,\n focusThrottleInterval?: number,\n) {\n // Existing entries are updated in place\n const entry = revalidators.get(key) || ([] as unknown as RevalidatorEntry);\n\n entry[0] = revalidatorFn;\n entry[1] = timeNow();\n entry[2] = ttl ?? DEFAULT_TTL;\n entry[3] = staleTime;\n entry[4] = bgRevalidatorFn;\n entry[5] = refetchOnFocus;\n entry[6] = refetchOnReconnect;\n entry[7] = focusThrottleInterval;\n\n revalidators.set(key, entry);\n\n if (refetchOnFocus) {\n addEventHandler('focus');\n }\n\n if (refetchOnReconnect) {\n addEventHandler('online');\n }\n\n if (staleTime) {\n addTimeout('s:' + key, revalidate.bind(null, key, true), staleTime * 1000);\n }\n}\n\nexport function removeRevalidator(key: string) {\n revalidators.delete(key);\n\n // Clean up stale timer\n removeTimeout('s:' + key);\n}\n\n/**\n * Periodically cleans up expired revalidators from the registry.\n * Removes any revalidator whose TTL has expired.\n *\n * @param {number} intervalMs How often to run cleanup (default: 3 minutes)\n * @returns {() => void} A function to stop the periodic cleanup\n */\nexport function startRevalidatorCleanup(\n intervalMs: number = DEFAULT_TTL,\n): () => void {\n const intervalId = setInterval(() => {\n const now = timeNow();\n\n revalidators.forEach(\n ([, lastUsed, ttl, , , refetchOnFocus, refetchOnReconnect], key) => {\n // Skip focus-only or reconnect-only revalidators to keep them alive\n if (refetchOnFocus || refetchOnReconnect) {\n return;\n }\n\n if (ttl > 0 && now - lastUsed > ttl) {\n removeRevalidator(key);\n }\n },\n );\n }, intervalMs);\n\n return () => clearInterval(intervalId);\n}\n","/**\n * Manages a set of listeners (subscribers) for arbitrary string keys, allowing cross-context or cross-component\n * cache updates and synchronization. Provides functions to add, remove, and notify listeners, as well as a\n * convenient subscribe/unsubscribe API.\n *\n * @template T - The type of the response object passed to listeners.\n *\n * @remarks\n * - Listeners are grouped by a string key, which typically represents a cache key or resource identifier.\n * - When `notifySubscribers` is called for a key, all listeners registered for that key are invoked with the provided response.\n * - The `subscribe` function returns an unsubscribe function for convenient cleanup.\n *\n * @example\n * ```ts\n * const unsubscribe = subscribe('user:123', (response) => {\n * // handle updated data\n * });\n * // Later, to stop listening:\n * unsubscribe();\n * ```\n */\n\nimport { noop } from './utils';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype Listener = (response: T) => void;\n\nconst listeners = new Map>();\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function addListener(key: string, fn: Listener): void {\n let set = listeners.get(key);\n\n if (!set) {\n listeners.set(key, (set = new Set()));\n }\n\n set.add(fn);\n}\n\nexport function removeListener(key: string, fn: Listener) {\n const set = listeners.get(key);\n\n if (set) {\n set.delete(fn);\n\n // If the set is empty, remove the key from the listeners map\n if (set.size === 0) {\n listeners.delete(key);\n }\n }\n}\n\nexport function notifySubscribers(key: string, response: T) {\n const fns = listeners.get(key);\n\n if (fns) {\n if (fns.size === 1) {\n // If there's only one listener, call it directly\n const fn = fns.values().next().value;\n fn!(response);\n } else {\n fns.forEach((fn) => fn(response));\n }\n }\n}\n\nexport function subscribe(key: string | null, fn: (response: T) => void) {\n if (!key) {\n // No op if no key is provided\n return noop;\n }\n\n addListener(key, fn);\n\n // Return an unsubscribe function\n return () => {\n removeListener(key, fn);\n };\n}\n","import { processHeaders } from './utils';\nimport {\n GET,\n APPLICATION_JSON,\n HEAD,\n STRING,\n CHARSET_UTF_8,\n CONTENT_TYPE,\n REJECT,\n UNDEFINED,\n APPLICATION_CONTENT_TYPE,\n} from './constants';\nimport type {\n HeadersObject,\n Method,\n RequestConfig,\n} from './types/request-handler';\nimport {\n replaceUrlPathParams,\n appendQueryParams,\n isSearchParams,\n isJSONSerializable,\n isSlowConnection,\n isAbsoluteUrl,\n sanitizeObject,\n isObject,\n} from './utils';\n\nconst defaultTimeoutMs = (isSlowConnection() ? 60 : 30) * 1000;\n\nexport const defaultConfig: RequestConfig = {\n strategy: REJECT,\n timeout: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n loadingTimeout: defaultTimeoutMs / 10, // 3 seconds (6 on slow connections)\n focusThrottleInterval: 5000, // 5 seconds\n headers: {\n Accept: APPLICATION_JSON + ', text/plain, */*',\n 'Accept-Encoding': 'gzip, deflate, br',\n },\n retry: {\n delay: defaultTimeoutMs / 30, // 1 second (2 on slow connections)\n maxDelay: defaultTimeoutMs, // 30 seconds (60 on slow connections)\n resetTimeout: true,\n backoff: 1.5,\n\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status\n retryOn: [\n 408, // Request Timeout\n 409, // Conflict\n 425, // Too Early\n 429, // Too Many Requests\n 500, // Internal Server Error\n 502, // Bad Gateway\n 503, // Service Unavailable\n 504, // Gateway Timeout\n ],\n\n // Idempotent methods, which can be repeated safely, unlike e.g. POST requests that create resources\n methods: [GET, HEAD, 'PUT', 'DELETE', 'OPTIONS', 'TRACE'],\n },\n};\n\n/**\n * Overwrites the default configuration with the provided custom configuration.\n *\n * @param {Partial} customConfig - The custom configuration to merge into the default config.\n * @returns {Partial} - The updated default configuration object.\n */\nexport function setDefaultConfig(\n customConfig: Partial,\n): Partial {\n const sanitized = sanitizeObject(customConfig);\n\n // Merge nested retry and headers settings into the current defaults instead of replacing them\n return mergeConfigs(\n { retry: defaultConfig.retry, headers: defaultConfig.headers },\n sanitized,\n defaultConfig,\n );\n}\n\n/**\n * Returns a shallow copy of the current default configuration.\n *\n * @returns {RequestConfig} - The current default configuration.\n */\nexport function getDefaultConfig(): RequestConfig {\n return { ...defaultConfig };\n}\n\n/**\n * Build request configuration from defaults and overrides.\n * This function merges the default configuration with the provided request configuration,\n * @param {string} url - Request url\n * @param {RequestConfig | null | undefined} reqConfig - Request configuration\n * @return {RequestConfig} - Merged request configuration\n */\nexport function buildConfig(\n url: string,\n reqConfig?: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null,\n): RequestConfig {\n // Merging gives the request its own copies of nested objects like headers, so that\n // mutations (e.g. by interceptors) never leak into the global defaults\n const merged = mergeConfigs(\n defaultConfig,\n reqConfig ? sanitizeObject(reqConfig) : {},\n );\n\n return buildFetcherConfig(url, merged);\n}\n\n/**\n * Builds the fetcher configuration by setting the method, body, headers, and URL.\n * It also handles query parameters and path parameters. This fn mutates the passed `requestConfig` object.\n * @param {string} url - The endpoint URL to which the request will be sent.\n * @param {RequestConfig} requestConfig - The request configuration object containing method, body, headers, and other options.\n * @return {RequestConfig} - The modified request configuration object with the URL, method, body, and headers set appropriately.\n **/\nexport function buildFetcherConfig(\n url: string,\n requestConfig: RequestConfig,\n): RequestConfig {\n let method = requestConfig.method as Method;\n method = method ? (method.toUpperCase() as Method) : GET;\n\n let body: RequestConfig['data'] | undefined;\n\n // Only applicable for request methods 'PUT', 'POST', 'DELETE', and 'PATCH'\n if (method !== GET && method !== HEAD) {\n body = requestConfig.body ?? requestConfig.data;\n\n // Automatically stringify request body, if possible and when not dealing with strings\n if (body && typeof body !== STRING && isJSONSerializable(body)) {\n body = JSON.stringify(body);\n }\n }\n\n setContentTypeIfNeeded(requestConfig.headers, body);\n\n // Native fetch compatible settings\n const credentials = requestConfig.withCredentials\n ? 'include'\n : requestConfig.credentials;\n\n // The explicitly passed query params\n const dynamicUrl = replaceUrlPathParams(url, requestConfig.urlPathParams);\n const urlPath = appendQueryParams(dynamicUrl, requestConfig.params);\n const isFullUrl = isAbsoluteUrl(url);\n const baseURL = isFullUrl\n ? ''\n : requestConfig.baseURL || requestConfig.apiUrl || '';\n\n // Join as a path, as plain concatenation could extend the host of the baseURL,\n // e.g. \"https://api.example.com\" + \".evil.com\" would point to another host\n const separator =\n baseURL && urlPath && !baseURL.endsWith('/') && !/^[/?#]/.test(urlPath)\n ? '/'\n : '';\n\n requestConfig.url = baseURL + separator + urlPath;\n requestConfig.method = method;\n requestConfig.credentials = credentials;\n requestConfig.body = body;\n\n return requestConfig;\n}\n\n/**\n * Ensures the `Content-Type` header is set to `application/json; charset=utf-8`\n * if it is not already present and the request method and body meet specific conditions.\n *\n * @param headers - The headers object to modify. Can be an instance of `Headers`\n * or a plain object conforming to `HeadersInit`.\n * @param body - The optional body of the request. If no body is provided and the\n * method is 'GET' or 'HEAD', the function exits without modifying headers.\n */\nfunction setContentTypeIfNeeded(\n headers?: HeadersInit | HeadersObject,\n body?: unknown,\n): void {\n // If no headers are provided, or if the body is not set and the method is PUT or DELETE, do nothing\n if (!headers || !body) {\n return;\n }\n\n // Types that should not have Content-Type set (browser handles these)\n if (\n body instanceof FormData || // Browser automatically sets multipart/form-data with boundary\n (typeof Blob !== UNDEFINED && body instanceof Blob) || // Blob/File (a File is a Blob) already have their own MIME types, don't override\n (typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream) // Stream type should be determined by the stream source\n ) {\n return;\n }\n\n let contentTypeValue: string;\n\n if (isSearchParams(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded';\n } else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {\n contentTypeValue = APPLICATION_CONTENT_TYPE + 'octet-stream';\n } else if (isJSONSerializable(body)) {\n contentTypeValue = APPLICATION_JSON + ';' + CHARSET_UTF_8;\n } else {\n // Do not set Content-Type if content is not recognizable\n return;\n }\n\n if (headers instanceof Headers) {\n if (!headers.has(CONTENT_TYPE)) {\n headers.set(CONTENT_TYPE, contentTypeValue);\n }\n } else if (\n isObject(headers) &&\n !Array.isArray(headers) &&\n // Header names are case-insensitive, so check the normalized (lowercase) headers\n !processHeaders(headers as HeadersObject)[CONTENT_TYPE.toLowerCase()]\n ) {\n headers[CONTENT_TYPE] = contentTypeValue;\n }\n}\n\n// The interceptors that are merged instead of replaced\nconst INTERCEPTORS = [\n 'onRequest',\n 'onResponse',\n 'onError',\n 'onLoadingSlow',\n] as const;\n\n/**\n * Merges two request configurations, applying overrides from the second config to the first.\n * Handles special merging for nested properties like 'retry' and 'headers' (deep merge),\n * and concatenates interceptor arrays for 'onRequest', 'onResponse', 'onError' and 'onLoadingSlow'.\n * If a target config is provided, it mutates that object; otherwise, creates a new one.\n *\n * @param {RequestConfig} baseConfig - The base configuration object to merge from.\n * @param {RequestConfig} overrideConfig - The override configuration object to apply on top of the base.\n * @param {RequestConfig} [targetConfig={}] - Optional target configuration object to merge into (mutated in place).\n * @returns {RequestConfig} The merged configuration object.\n *\n * @example\n * const base = { timeout: 5000, headers: { 'Accept': 'application/json' } };\n * const override = { timeout: 10000, headers: { 'Authorization': 'Bearer token' } };\n * const merged = mergeConfigs(base, override);\n * // Result: { timeout: 10000, headers: { Accept: 'application/json', Authorization: 'Bearer token' } }\n */\nexport function mergeConfigs(\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig = {},\n): RequestConfig {\n Object.assign(targetConfig, baseConfig, overrideConfig);\n\n // Ensure that retry and headers are merged correctly\n mergeConfig('retry', baseConfig, overrideConfig, targetConfig);\n mergeConfig('headers', baseConfig, overrideConfig, targetConfig);\n\n // Merge interceptors efficiently\n for (const property of INTERCEPTORS) {\n mergeInterceptors(property, baseConfig, overrideConfig, targetConfig);\n }\n\n return targetConfig;\n}\n\n/**\n * Efficiently merges interceptor functions from base and new configs\n */\nfunction mergeInterceptors<\n K extends\n 'onRequest' | 'onResponse' | 'onError' | 'onRetry' | 'onLoadingSlow',\n>(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const baseInterceptor = baseConfig[property];\n const newInterceptor = overrideConfig[property];\n\n if (baseInterceptor && newInterceptor) {\n // This is the only LIFO interceptor, so we apply it after the response is prepared\n targetConfig[property] = (\n property === 'onResponse'\n ? [].concat(newInterceptor as never, baseInterceptor as never)\n : [].concat(baseInterceptor as never, newInterceptor as never)\n ) as RequestConfig[K];\n } else if (baseInterceptor || newInterceptor) {\n targetConfig[property] = baseInterceptor || newInterceptor;\n }\n}\n\n/**\n * Merges the specified property from the base configuration and the override configuration into the target configuration.\n *\n * @param {K} property - The property key to merge from the base and override configurations. Must be a key of RequestConfig.\n * @param {RequestConfig} baseConfig - The base configuration object that provides default values.\n * @param {RequestConfig} overrideConfig - The override configuration object that contains user-specific settings to merge.\n * @param {RequestConfig} targetConfig - The configuration object that will receive the merged properties.\n */\nexport function mergeConfig(\n property: K,\n baseConfig: RequestConfig,\n overrideConfig: RequestConfig,\n targetConfig: RequestConfig,\n): void {\n const base = baseConfig[property];\n const override = overrideConfig[property];\n\n if (override) {\n if (property === 'headers') {\n // Handle Headers instances which don't expose entries as own enumerable properties\n const isInstance =\n (base as Headers | (HeadersObject & HeadersInit)) instanceof Headers ||\n (override as Headers | (HeadersObject & HeadersInit)) instanceof\n Headers;\n const merged: HeadersObject = isInstance\n ? processHeaders(base)\n : { ...(base as HeadersObject) };\n const overrides: HeadersObject = isInstance\n ? processHeaders(override)\n : sanitizeObject(override as HeadersObject);\n\n // Header names are case-insensitive, so replace existing entries instead of duplicating them\n for (const key of Object.keys(overrides)) {\n const lowerKey = key.toLowerCase();\n\n for (const existingKey in merged) {\n if (existingKey.toLowerCase() === lowerKey) {\n delete merged[existingKey];\n }\n }\n\n merged[key] = overrides[key];\n }\n\n targetConfig[property] = merged as RequestConfig[K];\n } else {\n targetConfig[property] = {\n ...base,\n ...sanitizeObject(override as Record),\n } as RequestConfig[K];\n }\n } else if (\n override === undefined &&\n isObject(base) &&\n !((base as Headers | HeadersObject) instanceof Headers)\n ) {\n // Copy so that mutating the merged config never changes the base config\n targetConfig[property] = { ...base } as RequestConfig[K];\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { hash } from './hash';\nimport type {\n CacheKeyFunction,\n DefaultResponse,\n FetchResponse,\n MutationSettings,\n RequestConfig,\n} from './types/request-handler';\nimport type {\n CacheEntry,\n CacheStore,\n StoredResponse,\n} from './types/cache-manager';\nimport { GET, STRING } from './constants';\nimport {\n isJSONSerializable,\n isObject,\n isSearchParams,\n noop,\n sanitizeObject,\n sortObject,\n timeNow,\n} from './utils';\nimport { revalidate } from './revalidator-manager';\nimport { notifySubscribers } from './pubsub-manager';\nimport type { DefaultPayload, DefaultParams, DefaultUrlParams } from './types';\nimport { removeInFlight } from './inflight-manager';\nimport { addTimeout } from './timeout-wheel';\nimport { defaultConfig } from './config-handler';\nimport { processHeaders } from './utils';\n\nexport const IMMEDIATE_DISCARD_CACHE_TIME = 0; // Use it for cache entries that need to be persistent until unused by components or manually deleted\n\nconst _cache = new Map>();\n// The cache stores that keep copies of cache entries, by cache key\nconst stores = new Map();\nconst DELIMITER = '|';\nconst MIN_LENGTH_TO_HASH = 64;\nconst CACHE_KEY_SANITIZE_PATTERN = /[^\\w\\-_|/:@.?=&~%#]/g;\nconst CACHE_KEY_NEEDS_SANITIZE = /[^\\w\\-_|/:@.?=&~%#]/; // Non-global for fast test\n\n/**\n * Headers that may affect HTTP response content and should be included in cache key generation.\n * Header names are matched case-insensitively.\n *\n * - Content negotiation: accept (response format, e.g. JSON or HTML), accept-language (localization), accept-encoding (compression)\n * - Authentication: authorization (access to protected resources)\n * - Request body metadata: content-type (how the request body is interpreted)\n * - Optional: referer (may influence behavior in some APIs), origin (CORS or tenant-specific APIs),\n * user-agent (if the server returns client-specific content), cookie (session-based responses; can fragment the cache heavily)\n * - Custom headers that may affect response content: x-api-key (token-based access), x-requested-with (AJAX requests),\n * x-client-id (per-client/partner identity), x-tenant-id (multi-tenant segmentation), x-user-id (explicit user context),\n * x-app-version (version-specific behavior), x-feature-flag (feature rollout), x-device-id (per device/app instance),\n * x-platform (e.g. 'ios', 'android', 'web'), x-session-id (if it affects the response directly), x-locale (like accept-language)\n */\nconst CACHE_KEY_HEADERS =\n /^(accept(-language|-encoding)?|authorization|content-type|referer|origin|user-agent|cookie|x-(api-key|requested-with|client-id|tenant-id|user-id|app-version|feature-flag|device-id|platform|session-id|locale))$/i;\n\n/**\n * Generates a unique cache key for a given URL and fetch options, ensuring that key factors\n * like method, headers, body, and other options are included in the cache key.\n * Headers and other objects are sorted by key to ensure consistent cache keys.\n *\n * @param {RequestConfig} config - The fetch options that may affect the request. The most important are:\n * @property {string} [method=\"GET\"] - The HTTP method (GET, POST, etc.).\n * @property {HeadersInit} [headers={}] - The request headers.\n * @property {BodyInit | null} [body=\"\"] - The body of the request (only for methods like POST, PUT).\n * @property {RequestCredentials} [credentials=\"same-origin\"] - Whether to include credentials (include, same-origin, omit).\n * @property {RequestCache} [cache=\"default\"] - The cache mode (e.g., default, no-store, reload).\n * @returns {string} - A unique cache key string based on the provided options.\n *\n * @example\n * const cacheKey = generateCacheKey({\n * url: 'https://api.example.com/data',\n * method: 'POST',\n * headers: { 'Content-Type': 'application/json' },\n * body: JSON.stringify({ name: 'Alice' }),\n * mode: 'cors',\n * credentials: 'include',\n * });\n * console.log(cacheKey);\n */\nexport function generateCacheKey(\n config: RequestConfig,\n cacheKeyCheck = true,\n): string {\n // This is super fast. Effectively a no-op if cacheKey is\n // a string or a function that returns a string.\n const key = config.cacheKey;\n\n if (key && cacheKeyCheck) {\n return typeof key === STRING\n ? (key as string)\n : (key as CacheKeyFunction)(config);\n }\n\n const {\n url = '',\n method = GET,\n headers = null,\n body = null,\n credentials = 'same-origin',\n } = config;\n\n // Sort headers and body + convert sorted to strings for hashing purposes\n // Native serializer is on avg. 3.5x faster than a Fast Hash or FNV-1a\n let headersString = '';\n if (headers) {\n let obj: Record;\n\n if (headers instanceof Headers) {\n obj = processHeaders(headers);\n } else {\n obj = headers as Record;\n }\n\n // Filter headers to only include those that affect request identity\n // Include only headers that affect request identity, not execution behavior\n const keys = Object.keys(obj);\n const len = keys.length;\n\n // Sort keys manually for fastest deterministic output\n if (len > 1) {\n keys.sort();\n }\n\n let str = '';\n for (let i = 0; i < len; ++i) {\n if (CACHE_KEY_HEADERS.test(keys[i])) {\n str += keys[i] + ':' + obj[keys[i]] + ';';\n }\n }\n\n headersString = hash(str);\n }\n\n // Concatenate all key parts into a cache key string\n // Template literals are apparently slower\n const cacheStr =\n method +\n DELIMITER +\n url +\n DELIMITER +\n credentials +\n DELIMITER +\n headersString;\n\n // For GET requests, return early with shorter cache key\n if (method === GET) {\n return sanitizeCacheKey(cacheStr);\n }\n\n let bodyString = '';\n if (body) {\n if (typeof body === STRING || isSearchParams(body)) {\n const str = String(body);\n\n bodyString = str.length < MIN_LENGTH_TO_HASH ? str : hash(str); // hash only if large\n } else if (body instanceof FormData) {\n body.forEach((value, key) => {\n // Files can't be read synchronously, so they are identified by their object\n bodyString +=\n key +\n '=' +\n (typeof value === STRING ? value : 'F' + getObjectId(value as File)) +\n '&';\n });\n\n if (bodyString.length > MIN_LENGTH_TO_HASH) {\n bodyString = hash(bodyString);\n }\n } else if (isObject(body) && !isJSONSerializable(body)) {\n // Blobs, buffers, streams etc. can't be read synchronously, so they are identified by their object.\n // Two different bodies never share a key, while the same body object is still deduplicated.\n bodyString = 'B' + getObjectId(body);\n } else {\n const o = isObject(body)\n ? JSON.stringify(sortObject(body))\n : String(body);\n\n bodyString = o.length > MIN_LENGTH_TO_HASH ? hash(o) : o;\n }\n }\n\n return sanitizeCacheKey(cacheStr + DELIMITER + bodyString);\n}\n\nconst objectIds = new WeakMap();\nlet lastObjectId = 0;\n\n/**\n * Returns a unique id for an object, e.g. a request body that can't be serialized.\n *\n * @param {object} obj - The object to identify.\n * @returns {number} - The id of the object.\n */\nfunction getObjectId(obj: object): number {\n let id = objectIds.get(obj);\n\n if (!id) {\n objectIds.set(obj, (id = ++lastObjectId));\n }\n\n return id;\n}\n\n/**\n * Prevents cache poisoning by removal of control chars and unusual characters.\n * When anything is removed, a hash of the original key is appended so that keys\n * differing only in the removed characters (e.g. `?a[]=1` and `?a=1`) don't collide.\n *\n * @param {string} cacheStr - The raw cache key.\n * @returns {string} - The sanitized cache key.\n */\nfunction sanitizeCacheKey(cacheStr: string): string {\n return CACHE_KEY_NEEDS_SANITIZE.test(cacheStr)\n ? cacheStr.replace(CACHE_KEY_SANITIZE_PATTERN, '') +\n DELIMITER +\n hash(cacheStr)\n : cacheStr;\n}\n\n/**\n * Checks if the cache entry is expired based on its timestamp and the expiry time.\n *\n * @param {CacheEntry} entry - The cache entry to check.\n * @returns {boolean} - Returns true if the cache entry is expired, false otherwise.\n */\nfunction isCacheExpired(entry: CacheEntry): boolean {\n // No expiry time means the entry never expires\n if (!entry.expiry) {\n return false;\n }\n\n return timeNow() > entry.expiry;\n}\n\n/**\n * Retrieves a cached response from the internal cache using the provided key.\n *\n * @param key - The unique key identifying the cached entry. If null, returns null.\n * @returns The cached {@link FetchResponse} if found, otherwise null.\n */\nexport function getCacheData<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n key: string | null,\n): FetchResponse | null {\n if (!key) {\n return null;\n }\n\n const entry = _cache.get(key);\n\n return entry ? entry.data : null;\n}\n\n/**\n * Retrieves a cache entry if it exists and is not expired.\n *\n * @param {string} key Cache key to utilize\n * @returns {CacheEntry | null} - The cache entry if it exists and is not expired, null otherwise.\n */\nexport function getCache(\n key: string | null,\n):\n | CacheEntry<\n FetchResponse\n >\n | null\n | undefined {\n return _cache.get(key as string);\n}\n\n/**\n * Sets a new cache entry or updates an existing one, with optional TTL (time-to-live).\n *\n * @param {string} key Cache key to utilize\n * @param {T} data - The data to be cached.\n * @param {number} [ttl] - Optional TTL in seconds. If not provided, the cache entry will not expire.\n * @param {number} [staleTime] - Optional stale time in seconds. If provided, the cache entry will be considered stale after this time.\n */\nexport function setCache(\n key: string,\n data: T,\n ttl?: number,\n staleTime?: number,\n): void {\n if (ttl === 0) {\n deleteCache(key);\n return;\n }\n\n const time = timeNow();\n const ttlMs = ttl ? ttl * 1000 : 0;\n const staleTimeMs = staleTime ? staleTime * 1000 : 0; // Ensure default value for staleTime\n\n _cache.set(key, {\n data,\n time,\n stale: staleTimeMs > 0 ? time + staleTimeMs : undefined, // Use undefined if staleTime is not set\n expiry: ttl === -1 ? undefined : time + ttlMs,\n });\n\n if (ttlMs > 0) {\n scheduleExpiry(key, ttlMs);\n }\n}\n\n/**\n * Deletes a cache entry once it expires.\n *\n * @param {string} key Cache key to utilize\n * @param {number} ms - The time until the entry expires, in milliseconds.\n */\nfunction scheduleExpiry(key: string, ms: number): void {\n addTimeout('c:' + key, () => deleteCache(key, true), ms);\n}\n\n/**\n * Invalidates (deletes) a cache entry.\n *\n * @param {string} key Cache key to utilize\n * @param {boolean} [removeExpired=false] - If true, only deletes the cache entry if it is expired or stale.\n */\nexport function deleteCache(key: string, removeExpired: boolean = false): void {\n if (removeExpired) {\n const entry = getCache(key);\n\n // If the entry does not exist, or it is neither expired nor stale, do not delete\n if (!entry || !isCacheExpired(entry)) {\n return;\n }\n }\n\n _cache.delete(key);\n\n const store = stores.get(key);\n\n if (store) {\n stores.delete(key);\n callStore(() => store.delete(key));\n }\n}\n\n/**\n * Prunes the cache by removing entries that have expired based on the provided cache time.\n */\nexport function pruneCache(): void {\n _cache.clear();\n stores.clear();\n}\n\n/**\n * Calls a cache store method. Store errors, e.g. of a full localStorage, are ignored so that they can't break requests.\n *\n * @param {() => unknown} fn - The function calling the store.\n */\nfunction callStore(fn: () => unknown): void {\n try {\n Promise.resolve(fn()).catch(noop);\n } catch {\n // Ignored\n }\n}\n\n/**\n * Saves a copy of a cached response in a cache store, so that it can be restored later, e.g. after a page reload.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheStore} [store] - The cache store. If not provided, nothing is saved.\n */\nfunction persistCache(key: string, store?: CacheStore): void {\n const entry = _cache.get(key);\n\n if (store && entry) {\n const { data, status, statusText, headers } = entry.data as FetchResponse;\n\n stores.set(key, store);\n callStore(() =>\n store.set(key, { ...entry, data: { data, status, statusText, headers } }),\n );\n }\n}\n\n/**\n * Reads the entry of a cache key from the cache store of a request, e.g. one saved during a previous page load.\n * Expired entries are deleted from the store.\n *\n * @param {string} key Cache key to utilize\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {Promise | null>} - The stored entry, or null if there is no valid one or the in-memory cache has an entry already.\n */\nexport async function getStoredCache(\n key: string,\n requestConfig: RequestConfig,\n): Promise | null> {\n const store = requestConfig.cacheStore;\n\n if (!store || isCacheBypassed(requestConfig)) {\n return null;\n }\n\n let entry: CacheEntry | null | undefined;\n\n try {\n entry = await store.get(key);\n } catch {\n // A failing store is treated like an empty one\n return null;\n }\n\n // Another request may have cached a response in the meantime\n if (!entry || _cache.has(key)) {\n return null;\n }\n\n if (isCacheExpired(entry)) {\n callStore(() => store.delete(key));\n\n return null;\n }\n\n return entry;\n}\n\n/**\n * Caches a response restored from a cache store in memory, keeping its original stale and expiry times.\n *\n * @param {string} key Cache key to utilize\n * @param {CacheEntry} entry - The cache entry with the restored response.\n * @param {CacheStore} store - The cache store that the response was restored from.\n * @returns {boolean} - True if the restored response is fresh, false if it's stale.\n */\nexport function restoreCache(\n key: string,\n entry: CacheEntry,\n store: CacheStore,\n): boolean {\n _cache.set(key, entry);\n stores.set(key, store);\n\n if (entry.expiry) {\n scheduleExpiry(key, entry.expiry - timeNow());\n }\n\n notifySubscribers(key, entry.data);\n\n return !entry.stale || timeNow() < entry.stale;\n}\n\n/**\n * Mutates a cache entry with new data and optionally revalidates it.\n *\n * @param {string | null} key Cache key to utilize. If null, no mutation occurs.\n * @param {ResponseData} newData - The new data to be cached.\n * @param {MutationSettings|undefined} settings - Mutation settings.\n */\nexport async function mutate<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n key: string | null,\n newData: ResponseData,\n settings?: MutationSettings,\n): Promise | null> {\n // If no key is provided, do nothing\n if (!key) {\n return null;\n }\n\n const entry = getCache(\n key,\n );\n\n if (!entry) {\n return null;\n }\n\n const updatedData = isObject(newData) ? sanitizeObject(newData) : newData;\n\n const updatedResponse = {\n ...entry.data,\n data: updatedData,\n };\n\n // The ETag belongs to the original data, so the changed data must not be revalidated with it\n const headers = updatedResponse.headers;\n\n if (headers && headers.etag) {\n updatedResponse.headers = { ...headers };\n delete updatedResponse.headers.etag;\n }\n\n const updatedEntry = {\n ...entry,\n data: updatedResponse,\n };\n\n _cache.set(key, updatedEntry);\n persistCache(key, stores.get(key));\n notifySubscribers(key, updatedResponse);\n\n if (settings && settings.refetch) {\n return await revalidate(key);\n }\n\n return null;\n}\n\n/**\n * Checks whether a request should bypass the cache, because of its cache buster or `cache: 'reload'`.\n *\n * @param {RequestConfig} requestConfig - The request configuration.\n * @returns {boolean} - True if the cache should be bypassed.\n */\nexport function isCacheBypassed(requestConfig: RequestConfig): boolean {\n const buster = requestConfig.cacheBuster || defaultConfig.cacheBuster;\n\n return (\n !!(buster && buster(requestConfig)) || requestConfig.cache === 'reload'\n );\n}\n\n/**\n * Retrieves a cached response if available and valid, otherwise returns null.\n *\n * @template ResponseData - The type of the response data.\n * @template RequestBody - The type of the request body.\n * @template QueryParams - The type of the query parameters.\n * @template PathParams - The type of the path parameters.\n * @param {string | null} cacheKey - The cache key to look up.\n * @param {number | undefined} cacheTime - The maximum time to cache entry.\n * @param {RequestConfig} requestConfig - The fetcher configuration.\n * @returns {FetchResponse | null} - The cached response or null.\n */\nexport function getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n cacheKey: string | null,\n cacheTime: number | undefined,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): FetchResponse | null {\n // If cache key or time is not provided, return null\n if (!cacheKey || cacheTime === undefined || cacheTime === null) {\n return null;\n }\n\n if (isCacheBypassed(requestConfig)) {\n return null;\n }\n\n // Retrieve the cached entry\n const entry = getCache(\n cacheKey,\n );\n\n if (!entry) {\n return null;\n }\n\n const isExpired = isCacheExpired(entry);\n\n // If completely expired, delete and return null\n if (isExpired) {\n deleteCache(cacheKey);\n return null;\n }\n\n const data = entry.data;\n\n // Return data whether fresh or stale (SWR: serve stale, revalidation is timer-driven)\n // The placeholder stored while a request is in flight is not a response, so treat it as a miss\n return data && data.isFetching ? null : data;\n}\n\n/**\n * Sets or deletes the response cache based on cache settings and notifies subscribers.\n *\n * @param {FetchResponse} output - The response to cache.\n * @param {RequestConfig} requestConfig - The request configuration.\n * @param {boolean} [isError=false] - Whether the response is an error.\n */\nexport function handleResponseCache<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n output: FetchResponse,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n isError: boolean = false,\n): void {\n // It is string as it is called once request is made\n const cacheKey = requestConfig.cacheKey as string;\n\n if (cacheKey) {\n const cacheTime = requestConfig.cacheTime;\n const skipCache = requestConfig.skipCache;\n\n // Fast path: only set cache if cacheTime is positive and not skipping cache\n if (\n cacheTime &&\n (!isError || requestConfig.cacheErrors) &&\n !(skipCache && skipCache(output, requestConfig))\n ) {\n setCache(cacheKey, output, cacheTime, requestConfig.staleTime);\n\n // Error responses are only cached in memory\n if (!isError) {\n persistCache(cacheKey, requestConfig.cacheStore);\n }\n } else {\n const entry = getCache(cacheKey);\n\n // Don't let the in-flight placeholder outlive a request whose result isn't cached\n if (entry && entry.data && entry.data.isFetching) {\n deleteCache(cacheKey);\n }\n }\n\n notifySubscribers(cacheKey, output);\n removeInFlight(cacheKey);\n\n const prevCacheKey = requestConfig._prevKey;\n\n if (prevCacheKey) {\n removeInFlight(prevCacheKey);\n }\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { mutate } from './cache-manager';\nimport {\n APPLICATION_CONTENT_TYPE,\n APPLICATION_JSON,\n CONTENT_TYPE,\n FUNCTION,\n STRING,\n} from './constants';\nimport {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n ResponseError,\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n} from './types';\nimport { flattenData, isObject, processHeaders } from './utils';\n\n/**\n * Parses the response data based on the Content-Type header, or reads it as the given response type.\n *\n * @param response - The Response object to parse.\n * @param responseType - How to read the body regardless of its Content-Type, e.g. as a Blob, or `'stream'` to leave it unread.\n * @returns A Promise that resolves to the parsed data.\n */\nexport async function parseResponseData<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse,\n responseType?: RequestConfig['responseType'],\n): Promise {\n // Bail early if response is null or undefined\n if (!response) {\n return null;\n }\n\n // Get the content-type header once\n const headers = (response as Response).headers;\n let contentType = headers && headers.get(CONTENT_TYPE);\n\n if (contentType) {\n // Lowercase and trim for consistent matching\n contentType = contentType.toLowerCase().trim();\n } else {\n contentType = '';\n }\n\n // Split for mime type without charset\n const mimeType = contentType.split(';', 1)[0];\n\n let data;\n\n try {\n if (responseType) {\n // The body is read as requested, or left unread as a stream to be read by the caller\n data =\n responseType === 'stream'\n ? response.body\n : await response[responseType]();\n } else if (\n mimeType.includes(APPLICATION_JSON) ||\n mimeType.includes('+json')\n ) {\n data = await response.json(); // Parse JSON response\n } else if (\n (mimeType.includes('multipart/form-data') || // Parse as FormData\n mimeType.includes(\n APPLICATION_CONTENT_TYPE + 'x-www-form-urlencoded', // Handle URL-encoded forms\n )) &&\n typeof response.formData === FUNCTION\n ) {\n data = await response.formData();\n } else if (/^(image|video|audio)\\/|octet-stream|pdf|zip/.test(mimeType)) {\n data = await response.arrayBuffer(); // Parse as ArrayBuffer for binary types\n } else {\n data = await response.text();\n\n if (typeof data === STRING) {\n const trimmed = data.trim();\n if (\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'))\n ) {\n try {\n data = JSON.parse(trimmed);\n } catch {\n // leave as text if parsing fails\n }\n }\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (_error) {\n // Parsing failed, fallback to null\n data = null;\n }\n\n return data;\n}\n\n/**\n * Prepare response object with additional information.\n *\n * @param Response. It may be \"null\" in case of request being aborted.\n * @param {RequestConfig} config - Request config\n * @param error - whether the response is erroneous\n * @returns {FetchResponse} Response data\n */\nexport const prepareResponse = <\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n config: RequestConfig,\n error: ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null,\n): FetchResponse => {\n const defaultResponse = config.defaultResponse;\n const cacheKey = config.cacheKey;\n const mutatator = mutate.bind(null, cacheKey as string) as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >['mutate'];\n\n // This may happen when request is cancelled.\n if (!response) {\n return {\n ok: false,\n // Enhance the response with extra information\n error,\n data: defaultResponse ?? null,\n headers: null,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: false,\n isError: true,\n } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n const isNativeResponse =\n typeof Response === FUNCTION && response instanceof Response;\n\n let data = response.data;\n\n // Set the default response if the provided data is an empty object or array\n // Other objects, e.g. Blobs, buffers and streams, have no keys either, but aren't empty\n if (\n defaultResponse !== undefined &&\n (data === undefined ||\n data === null ||\n (/^\\[object (Object|Array)\\]$/.test(\n Object.prototype.toString.call(data),\n ) &&\n Object.keys(data).length === 0))\n ) {\n response.data = data = defaultResponse;\n }\n\n if (config.flattenResponse) {\n response.data = data = flattenData(data);\n }\n\n if (config.select) {\n response.data = data = config.select(data);\n }\n\n const headers = processHeaders(response.headers);\n\n // Native fetch Response extended by extra information\n if (isNativeResponse) {\n const output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > = {\n body: response.body,\n bodyUsed: response.bodyUsed,\n ok: response.ok,\n redirected: response.redirected,\n type: response.type,\n url: response.url,\n status: response.status,\n statusText: response.statusText,\n\n // Convert methods to use arrow functions to preserve correct return types\n // Lazily construct Blob from ArrayBuffer\n blob: async () =>\n data instanceof ArrayBuffer ? new Blob([data]) : new Blob(),\n json: async () => data as ResponseData, // Return the already parsed JSON data\n text: async () => data as string, // Return the already parsed text data\n // The body was already read, so a copy of this response is returned instead of Response.clone()\n clone: () => ({ ...output }),\n arrayBuffer: async () =>\n data instanceof ArrayBuffer ? data : new ArrayBuffer(0), // Return the ArrayBuffer directly\n formData: async () => (data instanceof FormData ? data : new FormData()), // Return the already parsed FormData\n bytes: async () =>\n new Uint8Array(data instanceof ArrayBuffer ? data : new ArrayBuffer(0)),\n // Enhance the response with extra information\n error,\n data,\n headers,\n config,\n mutate: mutatator,\n isFetching: false,\n isSuccess: response.ok && !error,\n isError: !!error,\n };\n\n return output;\n }\n\n // If it's a custom fetcher, and it does not return any Response instance, it may have its own internal handler\n if (isObject(response)) {\n // Assigned one by one, as Object.assign() with an object literal is measurably slower here\n response.error = error;\n response.headers = headers;\n response.isFetching = false;\n response.mutate = mutatator;\n response.isSuccess = response.ok && !error;\n response.isError = !!error;\n }\n\n return response;\n};\n","import { applyInterceptors } from './interceptor-manager';\nimport type { FetchResponse, RetryConfig, RetryFunction } from './types';\nimport { delayInvocation, timeNow } from './utils';\nimport { generateCacheKey } from './cache-manager';\nimport { FUNCTION } from './constants';\n\nfunction getMsFromHttpDate(dateString: string): number | null {\n const ms = Date.parse(dateString) - timeNow();\n\n if (!isNaN(ms)) {\n return Math.max(0, Math.floor(ms));\n }\n return null;\n}\n\n/**\n * Calculates the number of milliseconds to wait before retrying a request,\n * based on the `Retry-After` HTTP header in the provided response.\n *\n * The function supports both numeric (seconds) and HTTP-date formats for the `Retry-After` header.\n * - If the header is a number, it is interpreted as seconds and converted to milliseconds.\n * - If the header is a date, the function calculates the difference between the date and the current time.\n *\n * @param extendedResponse - The response object containing headers, or `null`.\n * @returns The number of milliseconds to wait before retrying, or `null` if the header is not present or invalid.\n */\nexport function getRetryAfterMs(\n extendedResponse: FetchResponse | null,\n): number | null {\n if (!extendedResponse) {\n return null;\n }\n\n const headers = extendedResponse.headers || {};\n const retryAfter = headers['retry-after'];\n\n if (retryAfter) {\n // Try parsing as seconds\n const seconds = Number(retryAfter);\n\n if (!isNaN(seconds) && seconds >= 0) {\n return seconds * 1000;\n }\n\n const ms = getMsFromHttpDate(retryAfter);\n\n if (ms !== null) {\n return ms;\n }\n }\n\n // Headers are already in lowercase\n const RATELIMIT_RESET = 'ratelimit-reset';\n\n // Unix timestamp when the rate limit window resets (relative to current time)\n // Fallback to checking 'ratelimit-reset-after' OR 'x-ratelimit-reset-after' headers\n const rateLimitResetAfter =\n headers[RATELIMIT_RESET + '-after'] ||\n headers['x-' + RATELIMIT_RESET + '-after'];\n\n if (rateLimitResetAfter) {\n const seconds = Number(rateLimitResetAfter);\n\n if (!isNaN(seconds)) {\n return seconds * 1000;\n }\n }\n\n // ISO 8601 datetime when the rate limit resets\n // Fallback to checking 'ratelimit-reset-at' 'x-ratelimit-reset-at' headers\n const rateLimitResetAt =\n headers[RATELIMIT_RESET + '-at'] || headers['x-' + RATELIMIT_RESET + '-at'];\n\n if (rateLimitResetAt) {\n return getMsFromHttpDate(rateLimitResetAt);\n }\n\n return null;\n}\n\n/**\n * Executes a request function with retry logic according to the provided configuration.\n *\n * The function attempts the request up to the specified number of retries, applying delay and backoff strategies.\n * Retries can be triggered based on response status codes, custom logic, or the presence of a `Retry-After` header.\n * Optionally, an `onRetry` interceptor can be invoked before each retry attempt.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param requestFn - The function that performs the request. Receives `isStaleRevalidation` and `attempt` as arguments.\n * @param config - The retry configuration, including retry count, delay, backoff, retry conditions, and hooks.\n * @returns A promise resolving to the fetch response, or rejecting if all retries are exhausted.\n * @throws Error if the maximum number of retries is exceeded or a non-retriable error occurs.\n */\nexport async function withRetry<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation: boolean,\n attempt: number,\n ) => Promise<\n FetchResponse\n >,\n config: RetryConfig,\n): Promise> {\n const {\n retries = 0,\n delay = 0,\n backoff = 1,\n maxDelay,\n retryOn = [],\n shouldRetry,\n jitter,\n methods,\n } = config;\n\n let attempt = 0;\n let waitTime = delay;\n const maxRetries = retries > 0 ? retries : 0;\n let output: FetchResponse;\n\n while (attempt <= maxRetries) {\n // Subsequent attempts will have output defined, but the first attempt may not.\n // Let's apply onRetry interceptor and regenerate cache key if ot really changes.\n if (attempt > 0 && output!) {\n const cfg = output.config;\n const onRetry = cfg.onRetry;\n\n if (onRetry) {\n await applyInterceptors(onRetry, output, attempt);\n\n // If the key was automatically generated, we need to regenerate it as config may change.\n // We don't detect whether config changed for performance reasons.\n if (cfg._isAutoKey) {\n cfg._prevKey = cfg.cacheKey as string;\n cfg.cacheKey = generateCacheKey(cfg, false);\n }\n }\n }\n\n // Performance optimization: Call the request function with the current attempt number\n // If this is the first attempt, we pass `isStaleRevalidation` as `false`,\n // otherwise we pass `true` to indicate that this is a stale revalidation (no cache hit).\n output = await requestFn(attempt > 0, attempt);\n const error = output.error;\n\n // Stop unless a failed response should be retried according to the retry settings,\n // or a successful one according to shouldRetry\n if (\n error\n ? await getShouldStopRetrying(\n output,\n attempt,\n maxRetries,\n shouldRetry,\n retryOn,\n methods,\n )\n : !(\n shouldRetry &&\n attempt < maxRetries &&\n (await shouldRetry(output, attempt))\n )\n ) {\n break;\n }\n\n // The delay before the next retry, randomized with jitter unless the server asks for one below\n let retryDelay = withJitter(waitTime, jitter);\n\n // Handle rate limiting if the error status is 429 (Too Many Requests) or 503 (Service Unavailable)\n if (error && (error.status === 429 || error.status === 503)) {\n // Try to extract the \"Retry-After\" value from the response headers\n const retryAfterMs = getRetryAfterMs(output);\n\n // If a valid retry-after value is found, override the wait time before next retry\n // Cap it with maxDelay so that a server can't make the client wait indefinitely\n if (retryAfterMs !== null) {\n retryDelay = waitTime = Math.min(\n retryAfterMs,\n maxDelay || retryAfterMs,\n );\n }\n }\n\n await delayInvocation(retryDelay);\n waitTime *= backoff || 1;\n waitTime = Math.min(waitTime, maxDelay || waitTime);\n attempt++;\n }\n\n return output!;\n}\n\n/**\n * Determines whether to stop retrying based on the error, current attempt count, and retry configuration.\n *\n * This function checks:\n * - If the maximum number of retries has been reached.\n * - If the request was aborted, e.g. with its signal or by a newer request. Aborted requests are never retried.\n * - If a custom `shouldRetry` callback is provided, its result is used to decide.\n * - If no custom logic is provided, falls back to checking if the error status is included in the `retryOn` list,\n * and the request method in the `methods` list, if any.\n *\n * @typeParam ResponseData - The type of the response data.\n * @typeParam RequestBody - The type of the request body.\n * @typeParam QueryParams - The type of the query parameters.\n * @typeParam PathParams - The type of the path parameters.\n * @param output - The response object containing the error and request configuration.\n * @param attempt - The current retry attempt number.\n * @param maxRetries - The maximum number of retry attempts allowed.\n * @param shouldRetry - Optional custom function to determine if a retry should occur.\n * @param retryOn - Optional list of HTTP status codes that should trigger a retry.\n * @param methods - Optional list of request methods that are retried on the `retryOn` statuses. All methods are retried without it.\n * @returns A promise resolving to `true` if retrying should stop, or `false` to continue retrying.\n */\nexport async function getShouldStopRetrying<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n output: FetchResponse,\n attempt: number,\n maxRetries: number,\n shouldRetry?: RetryFunction<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n retryOn: number[] = [],\n methods?: string[],\n): Promise {\n // Safety first: always respect max retries\n // We check retries provided regardless of the shouldRetry being provided so to avoid infinite loops.\n // It is a fail-safe so to prevent excessive retry attempts even if custom retry logic suggests a retry.\n if (attempt === maxRetries) {\n return true;\n }\n\n // Aborted requests are never retried, as e.g. a retry of one cancelled by a newer request would cancel the newer one\n if (output.error?.isCancelled) {\n return true;\n }\n\n // Get custom decision if shouldRetry is provided\n if (shouldRetry) {\n const result = await shouldRetry(output, attempt);\n\n if (result !== null) {\n return !result;\n }\n }\n\n return !(\n (retryOn || []).includes(output.error?.status ?? 0) &&\n (!methods ||\n methods.some((method) => method.toUpperCase() === output.config.method))\n );\n}\n\n/**\n * Randomizes a retry delay with jitter, so that clients that failed at the same time, e.g. during an outage, don't retry all at once.\n *\n * @param delay - The delay computed from the `delay`, `backoff` and `maxDelay` settings, in milliseconds.\n * @param jitter - `true` for a random delay between 0 and the computed one (\"full jitter\"), or a function that returns the delay to use.\n * @returns The delay to wait before the retry, in milliseconds.\n */\nfunction withJitter(delay: number, jitter: RetryConfig['jitter']): number {\n return typeof jitter === FUNCTION\n ? (jitter as (delay: number) => number)(delay)\n : jitter\n ? Math.random() * delay\n : delay;\n}\n","import type { RequestConfig, FetchResponse } from './types';\nimport { delayInvocation, isOffline, isPageHidden } from './utils';\n\n/**\n * Executes a request function with polling, stopping when shouldStopPolling returns true,\n * pollingInterval is not set, or maxAttempts is reached.\n * Polling pauses while the page is hidden or the browser is offline, unless allowed by refreshWhenHidden or refreshWhenOffline.\n *\n * @template Output The type of the output returned by the request function.\n * @param requestFn - The function that performs a single request (with retries).\n * @param pollingInterval - Interval in ms between polling attempts.\n * @param shouldStopPolling - Function to determine if polling should stop.\n * @param maxAttempts - Maximum number of polling attempts, default: 0 (unlimited).\n * @param pollingDelay - Delay in ms before each polling attempt, default: 0.\n * @param refreshWhenHidden - Whether to keep polling while the page is hidden, default: false.\n * @param refreshWhenOffline - Whether to keep polling while the browser is offline, default: false.\n * @param signal - The signal passed to the request. Polling stops once it is aborted.\n * @returns The final output from the last request.\n */\nexport async function withPolling<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams,\n>(\n requestFn: (\n isStaleRevalidation?: boolean,\n attempt?: number,\n ) => Promise<\n FetchResponse\n >,\n pollingInterval?: RequestConfig['pollingInterval'],\n shouldStopPolling?: RequestConfig['shouldStopPolling'],\n maxAttempts = 0,\n pollingDelay = 0,\n refreshWhenHidden = false,\n refreshWhenOffline = false,\n signal?: AbortSignal,\n): Promise> {\n if (!pollingInterval) {\n return requestFn();\n }\n\n let pollingAttempt = 0;\n let output: FetchResponse;\n\n while (maxAttempts === 0 || pollingAttempt < maxAttempts) {\n if (pollingDelay > 0) {\n await delayInvocation(pollingDelay, signal);\n }\n\n output = await requestFn();\n\n pollingAttempt++;\n\n if (\n (maxAttempts > 0 && pollingAttempt >= maxAttempts) ||\n !pollingInterval ||\n (shouldStopPolling && shouldStopPolling(output, pollingAttempt))\n ) {\n break;\n }\n\n // Wait for the next attempt, and keep waiting while polling is paused\n do {\n await delayInvocation(pollingInterval, signal);\n\n // Aborting the signal of the request stops polling\n if (signal && signal.aborted) {\n return output;\n }\n } while (\n (!refreshWhenHidden && isPageHidden()) ||\n (!refreshWhenOffline && isOffline())\n );\n }\n\n return output!;\n}\n","import { ABORT_ERROR, UNDEFINED } from './constants';\nimport type { RequestConfig, UploadProgress } from './types';\nimport { createAbortError } from './utils';\n\n// Responses with these statuses can't have a body\nconst NULL_BODY_STATUSES = [204, 205, 304];\n\n// Headers that browsers don't let requests set. fetch() skips them silently, while\n// XMLHttpRequest logs errors for them, so they are skipped before sending.\nconst FORBIDDEN_HEADERS =\n /^(accept-charset|accept-encoding|connection|content-length|cookie2?|date|dnt|expect|host|keep-alive|origin|referer|set-cookie|te|trailer|transfer-encoding|upgrade|via)$|^(proxy-|sec-|access-control-request-)/;\n\n// ReadableStream is missing in some environments, e.g. React Native\nconst isStream = (body: unknown): body is ReadableStream =>\n typeof ReadableStream !== UNDEFINED && body instanceof ReadableStream;\n\nexport const toProgress = (loaded: number, total?: number): UploadProgress => ({\n loaded,\n total,\n progress: total ? loaded / total : undefined,\n});\n\n/**\n * Sends a request and reports the upload progress of its body to `onUploadProgress`.\n * Browsers and React Native don't report the upload progress of fetch(), so XMLHttpRequest is used there.\n * Elsewhere, e.g. in Node.js, the body is streamed with fetch() and counted while it is sent.\n *\n * @param {string} url - The request URL.\n * @param {RequestConfig} config - The request configuration, with a body and `onUploadProgress`.\n * @returns {Promise} - The response.\n */\nexport function fetchWithUploadProgress(\n url: string,\n config: RequestConfig,\n): Promise {\n const body = config.body as BodyInit;\n\n return typeof XMLHttpRequest !== UNDEFINED && !isStream(body)\n ? sendWithXhr(url, config, body)\n : sendStreamed(url, config, body);\n}\n\nfunction sendWithXhr(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n // fetchf() always sets the signal, as it handles timeouts and cancellation with it\n const signal = config.signal!;\n const abort = () => xhr.abort();\n\n const settle = (fn: () => void) => {\n signal.removeEventListener('abort', abort);\n\n try {\n fn();\n } catch (error) {\n reject(error);\n }\n };\n\n xhr.open(config.method as string, url);\n xhr.responseType = 'blob';\n xhr.withCredentials = config.credentials === 'include';\n\n new Headers(config.headers).forEach(\n (value, name) =>\n FORBIDDEN_HEADERS.test(name) || xhr.setRequestHeader(name, value),\n );\n\n xhr.upload.onprogress = (event) =>\n config.onUploadProgress!(\n toProgress(\n event.loaded,\n event.lengthComputable ? event.total : undefined,\n ),\n );\n\n xhr.onload = () =>\n settle(() => {\n const headers = new Headers();\n\n for (const line of xhr.getAllResponseHeaders().split(/\\r?\\n/)) {\n const index = line.indexOf(':');\n\n if (index > 0) {\n headers.append(line.slice(0, index), line.slice(index + 1).trim());\n }\n }\n\n const response = new Response(\n NULL_BODY_STATUSES.includes(xhr.status) ? null : xhr.response,\n { status: xhr.status, statusText: xhr.statusText, headers },\n );\n\n // Like fetch(), the response tells its final URL, e.g. after redirects\n Object.defineProperty(response, 'url', { value: xhr.responseURL });\n\n resolve(response);\n });\n\n xhr.onerror = () =>\n settle(() => reject(new TypeError('Network request failed')));\n\n // Like fetch(), aborted requests reject with the reason of the abort signal\n const onAbort = () =>\n settle(() =>\n reject(\n signal.reason ||\n createAbortError('The request was aborted', ABORT_ERROR),\n ),\n );\n\n xhr.onabort = onAbort;\n\n if (signal.aborted) {\n return onAbort();\n }\n\n signal.addEventListener('abort', abort);\n\n xhr.send(body as XMLHttpRequestBodyInit);\n });\n}\n\nasync function sendStreamed(\n url: string,\n config: RequestConfig,\n body: BodyInit,\n): Promise {\n const headers = new Headers(config.headers);\n let stream = body as ReadableStream;\n let total: number | undefined;\n\n if (!isStream(body)) {\n // Serialize the body like fetch() would, to know its size and content type\n const blob = body instanceof Blob ? body : await new Response(body).blob();\n\n total = blob.size;\n stream = blob.stream();\n\n if (blob.type && !headers.has('content-type')) {\n headers.set('content-type', blob.type);\n }\n }\n\n let loaded = 0;\n\n return fetch(url, {\n ...config,\n headers,\n body: stream.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n config.onUploadProgress!(toProgress(loaded, total));\n controller.enqueue(chunk);\n },\n }),\n ),\n // Required by fetch() to send a stream\n duplex: 'half',\n } as RequestInit);\n}\n","import { FUNCTION } from './constants';\nimport type { DownloadProgress } from './types';\nimport { toProgress } from './upload-progress';\n\n/**\n * Reports the download progress of a response body to `onDownloadProgress` while the body is read.\n * The body is counted as it arrives, so the progress follows the download.\n *\n * @param {T} response - The response. Other than native responses with a body, e.g. responses of HEAD requests or custom fetchers, are returned as they are.\n * @param {Function} [onDownloadProgress] - The function called with the progress. Without it, the response is returned as it is.\n * @returns {T} - A copy of the response, whose body is counted while it's read.\n */\nexport function withDownloadProgress(\n response: T,\n onDownloadProgress?: (progress: DownloadProgress) => void,\n): T {\n // Response is missing in some environments, and response bodies e.g. in React Native\n if (\n !onDownloadProgress ||\n typeof Response !== FUNCTION ||\n !(response instanceof Response) ||\n !response.body\n ) {\n return response;\n }\n\n const headers = response.headers;\n // Content-Length is the size of the compressed body, so the size of a compressed one is unknown\n const total = headers.has('content-encoding')\n ? undefined\n : Number(headers.get('content-length')) || undefined;\n let loaded = 0;\n\n const counted = new Response(\n response.body.pipeThrough(\n new TransformStream({\n transform(chunk, controller) {\n loaded += chunk.byteLength;\n // Browsers may hide the Content-Encoding header of cross-origin responses, so the progress is capped at 1\n onDownloadProgress(\n toProgress(loaded, total && Math.max(total, loaded)),\n );\n controller.enqueue(chunk);\n },\n }),\n ),\n response,\n );\n\n // Like the original response, the copy tells its final URL, whether it was redirected and its type\n for (const key of ['url', 'redirected', 'type'] as const) {\n Object.defineProperty(counted, key, { value: response[key] });\n }\n\n return counted as T;\n}\n","import type { ResponseError } from './errors/response-error';\nimport type {\n DefaultResponse,\n FetchResponse,\n RequestConfig,\n} from './types/request-handler';\nimport { applyInterceptors } from './interceptor-manager';\nimport { handleResponseCache } from './cache-manager';\nimport { ABORT_ERROR, REJECT } from './constants';\nimport {\n DefaultParams,\n DefaultUrlParams,\n DefaultPayload,\n HeadersObject,\n} from './types';\nimport { processHeaders } from './utils';\n\n/**\n * Handles final processing for both success and error responses\n * Applies error interceptors, caching, notifications, and error strategy\n */\nexport async function withErrorHandling<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n isStaleRevalidation: boolean,\n requestFn: (\n isStaleRevalidation: boolean,\n ) => Promise<\n FetchResponse\n >,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): Promise> {\n const output = await requestFn(isStaleRevalidation);\n const error = output.error;\n\n if (!error) {\n // SUCCESS PATH\n handleResponseCache(output, requestConfig);\n\n return output;\n }\n\n // ERROR PATH\n\n if (requestConfig.onError) {\n await applyInterceptors(requestConfig.onError, error);\n }\n\n // Timeouts and request cancellations using AbortController do not throw any errors unless rejectCancelled is true.\n // Only handle the error if the request was not cancelled, or if it was cancelled and rejectCancelled is true.\n const isCancelled = error.isCancelled;\n\n const logger = requestConfig.logger;\n\n if (!isCancelled && logger && logger.warn) {\n logger.warn('FETCH ERROR', redactError(error as ResponseError));\n }\n\n // The defaultResponse strategy returns the default response in place of the error data.\n // The original data stays available through error.response.\n if (requestConfig.strategy === 'defaultResponse') {\n output.data = (requestConfig.defaultResponse ?? null) as typeof output.data;\n }\n\n // Handle cache and notifications FIRST (before strategy)\n handleResponseCache(output, requestConfig, true);\n\n // handle error strategy as the last part\n const shouldHandleError = !isCancelled || requestConfig.rejectCancelled;\n\n if (shouldHandleError) {\n const strategy = requestConfig.strategy;\n // Reject the promise\n if (strategy === REJECT) {\n throw error;\n }\n\n // Hang the promise\n if (strategy === 'silent') {\n await new Promise(() => null);\n }\n }\n\n return output;\n}\n\n// Credential headers that must not end up in logs\nconst SENSITIVE_HEADERS = [\n 'authorization',\n 'proxy-authorization',\n 'cookie',\n 'x-api-key',\n];\n\n/**\n * Creates a copy of the error for logging, with credential headers masked and the request body removed.\n * The error itself is left untouched.\n */\nfunction redactError(error: ResponseError): ResponseError {\n // Cache keys are dropped too, as they can contain short request bodies\n const config = {\n ...error.config,\n body: undefined,\n data: undefined,\n cacheKey: undefined,\n _prevKey: undefined,\n headers: processHeaders(error.config.headers as HeadersObject),\n };\n\n for (const name of SENSITIVE_HEADERS) {\n if (config.headers[name]) {\n config.headers[name] = '[REDACTED]';\n }\n }\n\n const copy = Object.assign(new Error(error.message), error, {\n config,\n request: config,\n response: error.response && { ...error.response, config },\n });\n\n copy.name = error.name;\n copy.stack = error.stack;\n\n return copy;\n}\n\nexport function enhanceError<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n error: any,\n response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null,\n requestConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n >,\n): void {\n error.status = error.status || (response && response.status) || 0;\n error.statusText =\n error.statusText || (response && response.statusText) || '';\n error.config = error.request = requestConfig;\n error.response = response;\n error.isCancelled = error.name === ABORT_ERROR;\n}\n","import type {\n DefaultResponse,\n RequestConfig,\n FetchResponse,\n HeadersObject,\n} from './types/request-handler';\nimport type {\n DefaultParams,\n DefaultPayload,\n DefaultUrlParams,\n} from './types/api-handler';\nimport type { StoredResponse } from './types/cache-manager';\nimport { applyInterceptors } from './interceptor-manager';\nimport { ResponseError } from './errors/response-error';\nimport { isObject, noop, processHeaders } from './utils';\nimport {\n markInFlight,\n setInFlightPromise,\n getInFlightPromise,\n} from './inflight-manager';\nimport { parseResponseData, prepareResponse } from './response-parser';\nimport {\n generateCacheKey,\n getCacheData,\n getCachedResponse,\n getStoredCache,\n isCacheBypassed,\n restoreCache,\n setCache,\n} from './cache-manager';\nimport { withRetry } from './retry-handler';\nimport { withPolling } from './polling-handler';\nimport { fetchWithUploadProgress } from './upload-progress';\nimport { withDownloadProgress } from './download-progress';\nimport { notifySubscribers } from './pubsub-manager';\nimport { addRevalidator } from './revalidator-manager';\nimport { enhanceError, withErrorHandling } from './error-handler';\nimport { FUNCTION, GET, HEAD } from './constants';\nimport { buildConfig } from './config-handler';\n\nconst inFlightResponse = Object.freeze({\n isFetching: true,\n});\n\n/**\n * Sends an HTTP request to the specified URL using the provided configuration and returns a typed response.\n *\n * @typeParam ResponseData - The expected shape of the response data. Defaults to `DefaultResponse`.\n * @typeParam RequestBody - The type of the request payload/body. Defaults to `DefaultPayload`.\n * @typeParam QueryParams - The type of the query parameters. Defaults to `DefaultParams`.\n * @typeParam PathParams - The type of the path parameters. Defaults to `DefaultUrlParams`.\n *\n * @param url - The endpoint URL to which the request will be sent.\n * @param config - Optional configuration object for the request, including headers, method, body, query, and path parameters.\n *\n * @returns A promise that resolves to a `FetchResponse` containing the typed response data and request metadata.\n *\n * @example\n * ```typescript\n * const { data } = await fetchf('/api/user', { method: 'GET' });\n * console.log(data);\n * ```\n */\nexport async function fetchf<\n ResponseData = DefaultResponse,\n RequestBody = DefaultPayload,\n QueryParams = DefaultParams,\n PathParams = DefaultUrlParams,\n>(\n url: string,\n reqConfig: RequestConfig<\n ResponseData,\n QueryParams,\n PathParams,\n RequestBody\n > | null = null,\n): Promise> {\n // Ultra-fast early cache check if cacheKey is provided as a string\n // For workloads dominated by repeated requests, this string caching optimization\n // can potentially support millions of requests per second with minimal CPU overhead\n if (reqConfig && typeof reqConfig.cacheKey === 'string') {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(reqConfig.cacheKey, reqConfig.cacheTime, reqConfig);\n\n if (cached) {\n return cached;\n }\n }\n\n const fetcherConfig = buildConfig<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(url, reqConfig);\n\n const {\n timeout,\n cancellable,\n cacheKey,\n dedupeTime,\n cacheTime,\n staleTime,\n refetchOnFocus,\n refetchOnReconnect,\n pollingInterval = 0,\n } = fetcherConfig;\n const isCacheEnabled = cacheTime !== undefined || staleTime !== undefined;\n const method = fetcherConfig.method;\n\n // Cached responses of GET and HEAD requests are revalidated with their ETag.\n // Custom fetchers may not handle 304 responses, so they only send it when it's enabled for them.\n const isETagEnabled =\n isCacheEnabled &&\n (method === GET || method === HEAD) &&\n (fetcherConfig.etag ?? !fetcherConfig.fetcher);\n\n const needsCacheKey = !!(\n cacheKey ||\n timeout ||\n dedupeTime ||\n isCacheEnabled ||\n cancellable ||\n refetchOnFocus ||\n refetchOnReconnect\n );\n\n let _cacheKey: string | null = null;\n\n // Generate cache key if required\n if (needsCacheKey) {\n _cacheKey = generateCacheKey(fetcherConfig);\n }\n\n // The initial data, which is used as the first response instead of sending the request\n let initialResponse: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n // Cache handling logic\n if (_cacheKey && isCacheEnabled) {\n const cached = getCachedResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(_cacheKey, cacheTime, fetcherConfig);\n\n if (cached) {\n return cached;\n }\n\n // Restore the response from the cache store, e.g. one saved during a previous page load\n if (fetcherConfig.cacheStore) {\n const stored = await getStoredCache(_cacheKey, fetcherConfig);\n const restored =\n stored &&\n toResponse(\n stored.data,\n _cacheKey,\n fetcherConfig,\n );\n\n // A stale response is shown until the request below revalidates it\n if (\n restored &&\n restoreCache(\n _cacheKey,\n { ...stored, data: restored },\n fetcherConfig.cacheStore,\n )\n ) {\n return restored;\n }\n }\n\n // While there's no cached response, the initial data, e.g. data rendered on the server, is cached as the response\n if (\n fetcherConfig.initialData !== undefined &&\n !getCacheData(_cacheKey) &&\n !isCacheBypassed(fetcherConfig)\n ) {\n initialResponse = toResponse(\n {\n data: fetcherConfig.initialData,\n status: 200,\n statusText: '',\n headers: {},\n },\n _cacheKey,\n fetcherConfig,\n );\n }\n }\n\n // Deduplication logic\n if (_cacheKey && dedupeTime) {\n const inflight = getInFlightPromise<\n FetchResponse\n >(_cacheKey, dedupeTime);\n\n if (inflight) {\n return inflight;\n }\n }\n\n const retryConfig = fetcherConfig.retry || {};\n const { retries = 0, resetTimeout } = retryConfig;\n\n // The signal passed to the request. Each attempt replaces it in the config with a signal of its own.\n const userSignal = fetcherConfig.signal;\n\n // The actual request logic as a function (one poll attempt, with retries)\n const doRequestOnce = async (isStaleRevalidation: boolean, attempt = 0) => {\n // The cached response to revalidate. It's read before the cache is marked as fetching below.\n const cached =\n isETagEnabled &&\n getCacheData(\n _cacheKey,\n );\n\n // If cache key is specified, we will handle optimistic updates\n // and mark the request as in-flight, so to catch \"fetching\" state.\n // This is useful for Optimistic UI updates (e.g., showing loading spinners).\n if (!attempt) {\n // The initial data is only used once, as the first response\n if (initialResponse) {\n const response = initialResponse;\n\n initialResponse = null;\n\n return response;\n }\n\n if (_cacheKey && !isStaleRevalidation) {\n if (staleTime) {\n const existingCache = getCachedResponse(\n _cacheKey,\n cacheTime,\n fetcherConfig,\n );\n\n // Don't notify subscribers when cache exists\n // Let them continue showing stale data during background revalidation\n if (!existingCache) {\n setCache(_cacheKey, inFlightResponse, cacheTime, staleTime);\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n } else {\n notifySubscribers(_cacheKey, inFlightResponse);\n }\n }\n\n // Attach cache key so that it can be reused in interceptors or in the final response\n fetcherConfig.cacheKey = _cacheKey;\n }\n\n const url = fetcherConfig.url as string;\n\n // Add the request to the queue. Make sure to handle deduplication, cancellation, timeouts in accordance to retry settings\n const controller = markInFlight(\n _cacheKey,\n url,\n timeout,\n dedupeTime || 0,\n !!cancellable,\n // Enable timeout either by default or when retries & resetTimeout are enabled\n !!(timeout && (!attempt || resetTimeout)),\n );\n\n // Do not create a shallow copy to maintain idempotency here.\n // This ensures the original object is mutated by interceptors whenever needed, including retry logic.\n const requestConfig = fetcherConfig;\n\n requestConfig.signal = controller.signal;\n\n // The request is aborted along with the signal passed to it, which may have been aborted already\n const abort = () => controller.abort(userSignal!.reason);\n\n if (userSignal) {\n if (userSignal.aborted) {\n abort();\n } else {\n userSignal.addEventListener('abort', abort);\n }\n }\n\n let output: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n let response: FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n > | null = null;\n\n try {\n if (fetcherConfig.onRequest) {\n // Zero-allocation yield to microtask queue so the outer fetchf() can call setInFlightPromise()\n // before onRequest interceptors run. This ensures that if onRequest triggers\n // another fetchf() with the same cacheKey, getInFlightPromise() finds item[4].\n // On retries (attempt > 0), setInFlightPromise() was already called during the first attempt.\n // The promise stored in item[4] is the outer doRequestPromise which covers all retries.\n // So the race only matters on the very first attempt when the outer scope hasn't had a chance to call setInFlightPromise() yet.\n if (_cacheKey && dedupeTime && !attempt) {\n await null;\n }\n\n await applyInterceptors(fetcherConfig.onRequest, requestConfig);\n }\n\n // Custom fetcher\n const fn = fetcherConfig.fetcher;\n const init = withETag(requestConfig, cached);\n\n response = (fn\n ? await fn(\n url,\n init,\n )\n : // Uploads with onUploadProgress are sent in a way that reports their progress\n await (requestConfig.onUploadProgress && requestConfig.body\n ? fetchWithUploadProgress(url, requestConfig)\n : fetch(url, init as RequestInit))) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Reports the download progress while the body is read\n response = withDownloadProgress(\n response,\n requestConfig.onDownloadProgress,\n );\n\n // Custom fetcher may return a raw data object instead of a Response instance\n if (isObject(response)) {\n // The server answered that the cached response is still valid, so it's reused instead of being sent again.\n // Like other cached responses, it has been parsed and transformed already.\n if (init !== requestConfig && response.status === 304) {\n return cached as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n\n // Case 1: Native Response instance\n if (typeof Response === FUNCTION && response instanceof Response) {\n response.data = requestConfig.parser\n ? await requestConfig.parser(response)\n : await parseResponseData(response, requestConfig.responseType);\n } else if (fn) {\n // Case 2: Custom fetcher that returns a response object\n if (!('data' in response && 'body' in response)) {\n // Case 3: Raw data, wrap it\n response = { data: response } as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n }\n }\n\n // Attach config and data to the response\n // This is useful for custom fetchers that do not return a Response instance\n // and for interceptors that may need to access the request config\n response.config = requestConfig;\n\n // Check if the response status is not outside the range 200-299 and if so, output error\n // This is the pattern for fetch responses as per spec, but custom fetchers may not follow it so we check for `ok` property\n if (response.ok !== undefined && !response.ok) {\n throw new ResponseError(\n requestConfig.method +\n ' to ' +\n url +\n ' failed! Status: ' +\n (response.status || null),\n requestConfig,\n response,\n );\n }\n }\n\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig);\n\n const onResponse = fetcherConfig.onResponse;\n\n if (onResponse) {\n await applyInterceptors(onResponse, output);\n }\n } catch (_error) {\n const error = _error as ResponseError<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n // Append additional information to Network, CORS or any other fetch() errors\n enhanceError(\n error,\n response,\n requestConfig,\n );\n\n // Prepare Extended Response\n output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, requestConfig, error);\n } finally {\n if (userSignal) {\n userSignal.removeEventListener('abort', abort);\n }\n }\n\n return output;\n };\n\n // Inline and minimize function wrappers for performance\n // When retries are enabled, forward isStaleRevalidation so the first attempt\n // of a background SWR revalidation doesn't incorrectly mark the request as in-flight\n const baseRequest =\n retries > 0\n ? (isStaleRevalidation: boolean) =>\n withRetry(\n (_, attempt) => doRequestOnce(isStaleRevalidation, attempt),\n retryConfig,\n )\n : doRequestOnce;\n\n const { onLoadingSlow, loadingTimeout } = fetcherConfig;\n\n // Calls onLoadingSlow once a request, including its retries, is still pending after loadingTimeout.\n // Background revalidations don't show a loading state, so they are never considered slow.\n const request =\n onLoadingSlow && loadingTimeout\n ? async (isStaleRevalidation: boolean) => {\n if (isStaleRevalidation) {\n return baseRequest(isStaleRevalidation);\n }\n\n const timer = setTimeout(\n () => applyInterceptors(onLoadingSlow, fetcherConfig).catch(noop),\n loadingTimeout,\n );\n\n try {\n return await baseRequest(isStaleRevalidation);\n } finally {\n clearTimeout(timer);\n }\n }\n : baseRequest;\n\n const requestWithErrorHandling = (isStaleRevalidation = false) =>\n withErrorHandling(\n isStaleRevalidation,\n request,\n fetcherConfig,\n );\n\n // Avoid unnecessary function wrapping if polling is not enabled\n const doRequestPromise = pollingInterval\n ? withPolling(\n requestWithErrorHandling,\n pollingInterval,\n fetcherConfig.shouldStopPolling,\n fetcherConfig.maxPollingAttempts,\n fetcherConfig.pollingDelay,\n fetcherConfig.refreshWhenHidden,\n fetcherConfig.refreshWhenOffline,\n userSignal,\n )\n : requestWithErrorHandling();\n\n // If deduplication is enabled, store the in-flight promise immediately\n if (_cacheKey) {\n if (dedupeTime) {\n setInFlightPromise(_cacheKey, doRequestPromise);\n }\n\n // Only register revalidator when revalidation features are actually requested\n if (staleTime || refetchOnFocus || refetchOnReconnect) {\n addRevalidator(\n _cacheKey,\n requestWithErrorHandling,\n undefined,\n staleTime,\n requestWithErrorHandling,\n !!refetchOnFocus,\n !!refetchOnReconnect,\n fetcherConfig.focusThrottleInterval,\n );\n }\n }\n\n return doRequestPromise;\n}\n\n/**\n * Recreates a response from its copy in a cache store.\n * The data was transformed before it was stored, so it isn't transformed again.\n *\n * @param stored - The stored copy of the response.\n * @param cacheKey - The cache key of the request.\n * @param config - The request configuration.\n * @returns The response, or null if the stored copy is invalid, e.g. has an unknown status.\n */\nfunction toResponse(\n stored: StoredResponse,\n cacheKey: string,\n config: RequestConfig,\n): FetchResponse | null {\n try {\n // Without the Fetch API (e.g. with a custom fetcher in tests), a plain response object is used\n const response = (typeof Response === FUNCTION\n ? new Response(null, stored)\n : {\n ok: true,\n status: stored.status,\n statusText: stored.statusText,\n headers: stored.headers,\n }) as unknown as FetchResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >;\n\n response.data = stored.data as typeof response.data;\n config.cacheKey = cacheKey;\n\n const output = prepareResponse<\n ResponseData,\n RequestBody,\n QueryParams,\n PathParams\n >(response, {\n ...config,\n select: undefined,\n flattenResponse: false,\n defaultResponse: undefined,\n });\n\n output.config = config;\n\n return output;\n } catch {\n return null;\n }\n}\n\n/**\n * Asks the server whether a cached response is still valid, by sending its ETag in the If-None-Match header.\n * Then the server can answer 304 Not Modified instead of sending the response again.\n * Requests with an If-None-Match header of their own are sent as they are.\n *\n * @param config - The request configuration.\n * @param cached - The cached response of the request, if any.\n * @returns A copy of the configuration with the If-None-Match header, or the configuration itself if the cached response has no ETag.\n */\nfunction withETag(\n config: RequestConfig,\n cached: FetchResponse | null | false,\n): RequestConfig {\n const etag = cached && !cached.error && cached.headers && cached.headers.etag;\n const headers = etag && processHeaders(config.headers as HeadersObject);\n\n return headers && !headers['if-none-match']\n ? { ...config, headers: { ...headers, 'if-none-match': etag } }\n : config;\n}\n","import type {\n ApiHandlerConfig,\n ApiHandlerDefaultMethods,\n ApiHandlerMethods,\n RequestConfigUrlRequired,\n} from './types/api-handler';\nimport { fetchf } from '.';\nimport { mergeConfigs } from './config-handler';\nimport { hasOwn } from './utils';\n\n/**\n * Creates an instance of API Handler.\n * It creates an API fetcher function using native fetch() or a custom fetcher if passed as \"fetcher\".\n * @see https://github.com/MattCCC/fetchff#configuration\n *\n * @param {Object} config - Configuration object for the API fetcher (see link above for full options).\n * @param {Object} config.endpoints - An object containing endpoint definitions.\n * @param {string} [config.baseURL] - The base URL for the API.\n * @param {Object} [config.headers] - Optional default headers to include in every request.\n * @param {Function} [config.onError] - Optional callback function for handling errors.\n * @returns API handler functions and endpoints to call\n *\n * @example\n * // Define endpoint paths\n * const endpoints = {\n * getUser: '/user',\n * createPost: '/post',\n * };\n *\n * // Create the API fetcher with configuration\n * const api = createApiFetcher({\n * endpoints,\n * apiUrl: 'https://example.com/api',\n * onError(error) {\n * console.log('Request failed', error);\n * },\n * headers: {\n * 'my-auth-key': 'example-auth-key-32rjjfa',\n * },\n * });\n *\n * // Fetch user data\n * const response = await api.getUser({ userId: 1, ratings: [1, 2] })\n */\nfunction createApiFetcher<\n EndpointTypes extends object,\n EndpointsSettings = never,\n>(config: ApiHandlerConfig) {\n const endpoints = config.endpoints;\n\n /**\n * Triggered when trying to use non-existent endpoints\n *\n * @param endpointName Endpoint Name\n * @returns {Promise}\n */\n async function handleNonImplemented(endpointName: string): Promise {\n console.error('Add ' + endpointName + \" to 'endpoints'.\");\n\n return null;\n }\n\n const apiHandler: ApiHandlerDefaultMethods = {\n config,\n endpoints,\n /**\n * Handle Single API Request\n * It considers settings in following order: per-request settings, global per-endpoint settings, global settings.\n *\n * @param endpointName - The name of the API endpoint to call.\n * @param requestConfig - Additional configuration for the request.\n * @returns A promise that resolves with the response from the API provider.\n */\n async request(endpointName, requestConfig = {}) {\n // Use global and per-endpoint settings\n // Only own properties are endpoints, not ones inherited like \"constructor\"\n const endpointConfig = hasOwn(endpoints, endpointName as string)\n ? endpoints[endpointName]\n : undefined;\n const _endpointConfig =\n endpointConfig ||\n ({ url: String(endpointName) } as RequestConfigUrlRequired);\n const url = _endpointConfig.url;\n\n // URL parsers ignore leading control characters and spaces, drop tabs and newlines,\n // and treat backslashes like slashes, so check the URL the way it will be resolved\n const resolvedUrl = url\n .replace(/[\\t\\n\\r]/g, '')\n // eslint-disable-next-line no-control-regex -- matching control characters is the point\n .replace(/^[\\x00-\\x20]+/, '');\n\n // Block Protocol-relative URLs as they could lead to SSRF (Server-Side Request Forgery)\n if (/^[/\\\\]{2}/.test(resolvedUrl)) {\n throw new Error('Protocol-relative URLs not allowed.');\n }\n\n // Prevent potential Server-Side Request Forgery attack and leakage of credentials when same instance is used for external requests\n // Any scheme counts here, as e.g. \"http:\\\\host\" or \"http:host\" can also point to another host\n const mergedConfig = /^[a-z][a-z\\d+\\-.]*:/i.test(resolvedUrl)\n ? // Merge endpoints configs for absolute URLs only if urls match\n endpointConfig && endpointConfig.url === url\n ? mergeConfigs(_endpointConfig, requestConfig)\n : requestConfig\n : mergeConfigs(mergeConfigs(config, _endpointConfig), requestConfig);\n\n // We prevent potential Server-Side Request Forgery attack and leakage of credentials as the same instance is not used for external requests\n // Retrigger fetch to ensure completely new instance of handler being triggered for external URLs\n return fetchf(url, mergedConfig);\n },\n };\n\n /**\n * Maps all API requests using native Proxy\n *\n * @param {*} prop Caller\n */\n return new Proxy>(\n apiHandler as ApiHandlerMethods,\n {\n get(_target, prop: string | symbol) {\n if (prop in apiHandler) {\n return apiHandler[prop as unknown as keyof typeof apiHandler];\n }\n\n // Symbols (e.g. inspection hooks) are never endpoints, and returning a function\n // for \"then\" would make the instance a thenable that never settles when awaited\n if (typeof prop === 'symbol' || prop === 'then') {\n return undefined;\n }\n\n // Prevent handler from triggering non-existent endpoints\n if (hasOwn(endpoints, prop)) {\n return apiHandler.request.bind(null, prop);\n }\n\n return handleNonImplemented.bind(null, prop);\n },\n },\n );\n}\n\nexport { createApiFetcher };\n"]} \ No newline at end of file diff --git a/src/response-parser.ts b/src/response-parser.ts index 9bf9004..2c7f3c4 100644 --- a/src/response-parser.ts +++ b/src/response-parser.ts @@ -236,14 +236,13 @@ export const prepareResponse = < // If it's a custom fetcher, and it does not return any Response instance, it may have its own internal handler if (isObject(response)) { - Object.assign(response, { - error, - headers, - isFetching: false, - mutate: mutatator, - isSuccess: response.ok && !error, - isError: !!error, - }); + // Assigned one by one, as Object.assign() with an object literal is measurably slower here + response.error = error; + response.headers = headers; + response.isFetching = false; + response.mutate = mutatator; + response.isSuccess = response.ok && !error; + response.isError = !!error; } return response;